Commit 4a19ec5800fc3bb64e2d87c4d9fdd9e636086fe0
Committed by
David S. Miller
1 parent
036c2e27bc
Exists in
master
and in
4 other branches
[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>
Showing 27 changed files with 65 additions and 0 deletions Side-by-side Diff
- include/asm-alpha/socket.h
- include/asm-arm/socket.h
- include/asm-avr32/socket.h
- include/asm-blackfin/socket.h
- include/asm-cris/socket.h
- include/asm-frv/socket.h
- include/asm-h8300/socket.h
- include/asm-ia64/socket.h
- include/asm-m32r/socket.h
- include/asm-m68k/socket.h
- include/asm-mips/socket.h
- include/asm-parisc/socket.h
- include/asm-powerpc/socket.h
- include/asm-s390/socket.h
- include/asm-sh/socket.h
- include/asm-sparc/socket.h
- include/asm-sparc64/socket.h
- include/asm-v850/socket.h
- include/asm-x86/socket.h
- include/asm-xtensa/socket.h
- include/net/route.h
- include/net/sock.h
- net/core/sock.c
- net/ipv4/ip_output.c
- net/ipv4/raw.c
- net/ipv6/ip6_output.c
- net/ipv6/raw.c
include/asm-alpha/socket.h
include/asm-arm/socket.h
include/asm-avr32/socket.h
include/asm-blackfin/socket.h
include/asm-cris/socket.h
include/asm-frv/socket.h
include/asm-h8300/socket.h
include/asm-ia64/socket.h
include/asm-m32r/socket.h
include/asm-m68k/socket.h
include/asm-mips/socket.h
include/asm-parisc/socket.h
include/asm-powerpc/socket.h
include/asm-s390/socket.h
include/asm-sh/socket.h
include/asm-sparc/socket.h
... | ... | @@ -52,6 +52,8 @@ |
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 |
include/asm-sparc64/socket.h
include/asm-v850/socket.h
include/asm-x86/socket.h
include/asm-xtensa/socket.h
include/net/route.h
... | ... | @@ -27,6 +27,7 @@ |
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> |
... | ... | @@ -149,6 +150,7 @@ |
149 | 150 | int flags) |
150 | 151 | { |
151 | 152 | struct flowi fl = { .oif = oif, |
153 | + .mark = sk->sk_mark, | |
152 | 154 | .nl_u = { .ip4_u = { .daddr = dst, |
153 | 155 | .saddr = src, |
154 | 156 | .tos = tos } }, |
include/net/sock.h
... | ... | @@ -262,6 +262,8 @@ |
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); |
net/core/sock.c
... | ... | @@ -667,6 +667,13 @@ |
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) */ |
... | ... | @@ -835,6 +842,10 @@ |
835 | 842 | |
836 | 843 | case SO_PEERSEC: |
837 | 844 | return security_socket_getpeersec_stream(sock, optval, optlen, len); |
845 | + | |
846 | + case SO_MARK: | |
847 | + v.val = sk->sk_mark; | |
848 | + break; | |
838 | 849 | |
839 | 850 | default: |
840 | 851 | return -ENOPROTOOPT; |
net/ipv4/ip_output.c
... | ... | @@ -168,6 +168,7 @@ |
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); |
... | ... | @@ -385,6 +386,7 @@ |
385 | 386 | (skb_shinfo(skb)->gso_segs ?: 1) - 1); |
386 | 387 | |
387 | 388 | skb->priority = sk->sk_priority; |
389 | + skb->mark = sk->sk_mark; | |
388 | 390 | |
389 | 391 | return ip_local_out(skb); |
390 | 392 | |
... | ... | @@ -1286,6 +1288,7 @@ |
1286 | 1288 | iph->daddr = rt->rt_dst; |
1287 | 1289 | |
1288 | 1290 | skb->priority = sk->sk_priority; |
1291 | + skb->mark = sk->sk_mark; | |
1289 | 1292 | skb->dst = dst_clone(&rt->u.dst); |
1290 | 1293 | |
1291 | 1294 | if (iph->protocol == IPPROTO_ICMP) |
net/ipv4/raw.c
... | ... | @@ -352,6 +352,7 @@ |
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); |
... | ... | @@ -544,6 +545,7 @@ |
544 | 545 | |
545 | 546 | { |
546 | 547 | struct flowi fl = { .oif = ipc.oif, |
548 | + .mark = sk->sk_mark, | |
547 | 549 | .nl_u = { .ip4_u = |
548 | 550 | { .daddr = daddr, |
549 | 551 | .saddr = saddr, |
net/ipv6/ip6_output.c
... | ... | @@ -257,6 +257,7 @@ |
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)) { |
... | ... | @@ -1439,6 +1440,7 @@ |
1439 | 1440 | ipv6_addr_copy(&hdr->daddr, final_dst); |
1440 | 1441 | |
1441 | 1442 | skb->priority = sk->sk_priority; |
1443 | + skb->mark = sk->sk_mark; | |
1442 | 1444 | |
1443 | 1445 | skb->dst = dst_clone(&rt->u.dst); |
1444 | 1446 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); |
net/ipv6/raw.c
... | ... | @@ -641,6 +641,7 @@ |
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); |
... | ... | @@ -766,6 +767,8 @@ |
766 | 767 | * Get and verify the address. |
767 | 768 | */ |
768 | 769 | memset(&fl, 0, sizeof(fl)); |
770 | + | |
771 | + fl.mark = sk->sk_mark; | |
769 | 772 | |
770 | 773 | if (sin6) { |
771 | 774 | if (addr_len < SIN6_LEN_RFC2133) |