diff options
author | KOVACS Krisztian <hidden@sch.bme.hu> | 2008-10-01 10:30:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-01 10:30:02 -0400 |
commit | f5715aea4564f233767ea1d944b2637a5fd7cd2e (patch) | |
tree | e74e56e56dff19940ba3a5002355ba1bfc73f573 /net | |
parent | a210d01ae3ee006b59e54e772a7f212486e0f021 (diff) |
ipv4: Implement IP_TRANSPARENT socket option
This patch introduces the IP_TRANSPARENT socket option: enabling that
will make the IPv4 routing omit the non-local source address check on
output. Setting IP_TRANSPARENT requires NET_ADMIN capability.
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/inet_timewait_sock.c | 1 | ||||
-rw-r--r-- | net/ipv4/ip_sockglue.c | 15 |
2 files changed, 15 insertions, 1 deletions
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 743f011b9a84..1c5fd38f8824 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
@@ -126,6 +126,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat | |||
126 | tw->tw_reuse = sk->sk_reuse; | 126 | tw->tw_reuse = sk->sk_reuse; |
127 | tw->tw_hash = sk->sk_hash; | 127 | tw->tw_hash = sk->sk_hash; |
128 | tw->tw_ipv6only = 0; | 128 | tw->tw_ipv6only = 0; |
129 | tw->tw_transparent = inet->transparent; | ||
129 | tw->tw_prot = sk->sk_prot_creator; | 130 | tw->tw_prot = sk->sk_prot_creator; |
130 | twsk_net_set(tw, hold_net(sock_net(sk))); | 131 | twsk_net_set(tw, hold_net(sock_net(sk))); |
131 | atomic_set(&tw->tw_refcnt, 1); | 132 | atomic_set(&tw->tw_refcnt, 1); |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 105d92a039b9..465abf0a9869 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -419,7 +419,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
419 | (1<<IP_TTL) | (1<<IP_HDRINCL) | | 419 | (1<<IP_TTL) | (1<<IP_HDRINCL) | |
420 | (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | | 420 | (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | |
421 | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | | 421 | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | |
422 | (1<<IP_PASSSEC))) || | 422 | (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) || |
423 | optname == IP_MULTICAST_TTL || | 423 | optname == IP_MULTICAST_TTL || |
424 | optname == IP_MULTICAST_LOOP) { | 424 | optname == IP_MULTICAST_LOOP) { |
425 | if (optlen >= sizeof(int)) { | 425 | if (optlen >= sizeof(int)) { |
@@ -878,6 +878,16 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
878 | err = xfrm_user_policy(sk, optname, optval, optlen); | 878 | err = xfrm_user_policy(sk, optname, optval, optlen); |
879 | break; | 879 | break; |
880 | 880 | ||
881 | case IP_TRANSPARENT: | ||
882 | if (!capable(CAP_NET_ADMIN)) { | ||
883 | err = -EPERM; | ||
884 | break; | ||
885 | } | ||
886 | if (optlen < 1) | ||
887 | goto e_inval; | ||
888 | inet->transparent = !!val; | ||
889 | break; | ||
890 | |||
881 | default: | 891 | default: |
882 | err = -ENOPROTOOPT; | 892 | err = -ENOPROTOOPT; |
883 | break; | 893 | break; |
@@ -1130,6 +1140,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1130 | case IP_FREEBIND: | 1140 | case IP_FREEBIND: |
1131 | val = inet->freebind; | 1141 | val = inet->freebind; |
1132 | break; | 1142 | break; |
1143 | case IP_TRANSPARENT: | ||
1144 | val = inet->transparent; | ||
1145 | break; | ||
1133 | default: | 1146 | default: |
1134 | release_sock(sk); | 1147 | release_sock(sk); |
1135 | return -ENOPROTOOPT; | 1148 | return -ENOPROTOOPT; |