Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[NET]: Introducing socket mark socket option.

A userspace program may wish to set the mark for each packets its send
without using the netfilter MARK target. Changing the mark can be used
for mark based routing without netfilter or for packet filtering.

It requires CAP_NET_ADMIN capability.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Laszlo Attila Toth and committed by
David S. Miller
4a19ec58 036c2e27

+65
+2
include/asm-alpha/socket.h
··· 60 60 #define SO_SECURITY_ENCRYPTION_TRANSPORT 20 61 61 #define SO_SECURITY_ENCRYPTION_NETWORK 21 62 62 63 + #define SO_MARK 36 64 + 63 65 #endif /* _ASM_SOCKET_H */
+2
include/asm-arm/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* _ASM_SOCKET_H */
+2
include/asm-avr32/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* __ASM_AVR32_SOCKET_H */
+3
include/asm-blackfin/socket.h
··· 50 50 #define SO_PASSSEC 34 51 51 #define SO_TIMESTAMPNS 35 52 52 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 53 + 54 + #define SO_MARK 36 55 + 53 56 #endif /* _ASM_SOCKET_H */
+2
include/asm-cris/socket.h
··· 54 54 #define SO_TIMESTAMPNS 35 55 55 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 56 56 57 + #define SO_MARK 36 58 + 57 59 #endif /* _ASM_SOCKET_H */ 58 60 59 61
+2
include/asm-frv/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* _ASM_SOCKET_H */ 56 58
+2
include/asm-h8300/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* _ASM_SOCKET_H */
+2
include/asm-ia64/socket.h
··· 61 61 #define SO_TIMESTAMPNS 35 62 62 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 63 63 64 + #define SO_MARK 36 65 + 64 66 #endif /* _ASM_IA64_SOCKET_H */
+2
include/asm-m32r/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* _ASM_M32R_SOCKET_H */
+2
include/asm-m68k/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* _ASM_SOCKET_H */
+2
include/asm-mips/socket.h
··· 73 73 #define SO_TIMESTAMPNS 35 74 74 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 75 75 76 + #define SO_MARK 36 77 + 76 78 #ifdef __KERNEL__ 77 79 78 80 /** sock_type - Socket types
+2
include/asm-parisc/socket.h
··· 52 52 #define SO_PEERSEC 0x401d 53 53 #define SO_PASSSEC 0x401e 54 54 55 + #define SO_MARK 0x401f 56 + 55 57 #endif /* _ASM_SOCKET_H */
+2
include/asm-powerpc/socket.h
··· 59 59 #define SO_TIMESTAMPNS 35 60 60 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 61 61 62 + #define SO_MARK 36 63 + 62 64 #endif /* _ASM_POWERPC_SOCKET_H */
+2
include/asm-s390/socket.h
··· 60 60 #define SO_TIMESTAMPNS 35 61 61 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 62 62 63 + #define SO_MARK 36 64 + 63 65 #endif /* _ASM_SOCKET_H */
+2
include/asm-sh/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* __ASM_SH_SOCKET_H */
+2
include/asm-sparc/socket.h
··· 52 52 #define SO_TIMESTAMPNS 0x0021 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 0x0022 56 + 55 57 /* Security levels - as per NRL IPv6 - don't actually do anything */ 56 58 #define SO_SECURITY_AUTHENTICATION 0x5001 57 59 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
+1
include/asm-sparc64/socket.h
··· 57 57 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 58 58 #define SO_SECURITY_ENCRYPTION_NETWORK 0x5004 59 59 60 + #define SO_MARK 0x0022 60 61 #endif /* _ASM_SOCKET_H */
+2
include/asm-v850/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* __V850_SOCKET_H__ */
+2
include/asm-x86/socket.h
··· 52 52 #define SO_TIMESTAMPNS 35 53 53 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 54 54 55 + #define SO_MARK 36 56 + 55 57 #endif /* _ASM_SOCKET_H */
+2
include/asm-xtensa/socket.h
··· 63 63 #define SO_TIMESTAMPNS 35 64 64 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS 65 65 66 + #define SO_MARK 36 67 + 66 68 #endif /* _XTENSA_SOCKET_H */
+2
include/net/route.h
··· 27 27 #include <net/dst.h> 28 28 #include <net/inetpeer.h> 29 29 #include <net/flow.h> 30 + #include <net/sock.h> 30 31 #include <linux/in_route.h> 31 32 #include <linux/rtnetlink.h> 32 33 #include <linux/route.h> ··· 150 149 int flags) 151 150 { 152 151 struct flowi fl = { .oif = oif, 152 + .mark = sk->sk_mark, 153 153 .nl_u = { .ip4_u = { .daddr = dst, 154 154 .saddr = src, 155 155 .tos = tos } },
+2
include/net/sock.h
··· 262 262 __u32 sk_sndmsg_off; 263 263 int sk_write_pending; 264 264 void *sk_security; 265 + __u32 sk_mark; 266 + /* XXX 4 bytes hole on 64 bit */ 265 267 void (*sk_state_change)(struct sock *sk); 266 268 void (*sk_data_ready)(struct sock *sk, int bytes); 267 269 void (*sk_write_space)(struct sock *sk);
+11
net/core/sock.c
··· 667 667 else 668 668 clear_bit(SOCK_PASSSEC, &sock->flags); 669 669 break; 670 + case SO_MARK: 671 + if (!capable(CAP_NET_ADMIN)) 672 + ret = -EPERM; 673 + else { 674 + sk->sk_mark = val; 675 + } 676 + break; 670 677 671 678 /* We implement the SO_SNDLOWAT etc to 672 679 not be settable (1003.1g 5.3) */ ··· 842 835 843 836 case SO_PEERSEC: 844 837 return security_socket_getpeersec_stream(sock, optval, optlen, len); 838 + 839 + case SO_MARK: 840 + v.val = sk->sk_mark; 841 + break; 845 842 846 843 default: 847 844 return -ENOPROTOOPT;
+3
net/ipv4/ip_output.c
··· 168 168 } 169 169 170 170 skb->priority = sk->sk_priority; 171 + skb->mark = sk->sk_mark; 171 172 172 173 /* Send it out. */ 173 174 return ip_local_out(skb); ··· 386 385 (skb_shinfo(skb)->gso_segs ?: 1) - 1); 387 386 388 387 skb->priority = sk->sk_priority; 388 + skb->mark = sk->sk_mark; 389 389 390 390 return ip_local_out(skb); 391 391 ··· 1288 1286 iph->daddr = rt->rt_dst; 1289 1287 1290 1288 skb->priority = sk->sk_priority; 1289 + skb->mark = sk->sk_mark; 1291 1290 skb->dst = dst_clone(&rt->u.dst); 1292 1291 1293 1292 if (iph->protocol == IPPROTO_ICMP)
+2
net/ipv4/raw.c
··· 352 352 skb_reserve(skb, hh_len); 353 353 354 354 skb->priority = sk->sk_priority; 355 + skb->mark = sk->sk_mark; 355 356 skb->dst = dst_clone(&rt->u.dst); 356 357 357 358 skb_reset_network_header(skb); ··· 545 544 546 545 { 547 546 struct flowi fl = { .oif = ipc.oif, 547 + .mark = sk->sk_mark, 548 548 .nl_u = { .ip4_u = 549 549 { .daddr = daddr, 550 550 .saddr = saddr,
+2
net/ipv6/ip6_output.c
··· 257 257 ipv6_addr_copy(&hdr->daddr, first_hop); 258 258 259 259 skb->priority = sk->sk_priority; 260 + skb->mark = sk->sk_mark; 260 261 261 262 mtu = dst_mtu(dst); 262 263 if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) { ··· 1440 1439 ipv6_addr_copy(&hdr->daddr, final_dst); 1441 1440 1442 1441 skb->priority = sk->sk_priority; 1442 + skb->mark = sk->sk_mark; 1443 1443 1444 1444 skb->dst = dst_clone(&rt->u.dst); 1445 1445 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
+3
net/ipv6/raw.c
··· 641 641 skb_reserve(skb, hh_len); 642 642 643 643 skb->priority = sk->sk_priority; 644 + skb->mark = sk->sk_mark; 644 645 skb->dst = dst_clone(&rt->u.dst); 645 646 646 647 skb_put(skb, length); ··· 767 766 * Get and verify the address. 768 767 */ 769 768 memset(&fl, 0, sizeof(fl)); 769 + 770 + fl.mark = sk->sk_mark; 770 771 771 772 if (sin6) { 772 773 if (addr_len < SIN6_LEN_RFC2133)