aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKOVACS Krisztian <hidden@sch.bme.hu>2008-10-01 10:30:02 -0400
committerDavid S. Miller <davem@davemloft.net>2008-10-01 10:30:02 -0400
commitf5715aea4564f233767ea1d944b2637a5fd7cd2e (patch)
treee74e56e56dff19940ba3a5002355ba1bfc73f573
parenta210d01ae3ee006b59e54e772a7f212486e0f021 (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>
-rw-r--r--include/linux/in.h1
-rw-r--r--include/net/inet_sock.h3
-rw-r--r--include/net/inet_timewait_sock.h3
-rw-r--r--net/ipv4/inet_timewait_sock.c1
-rw-r--r--net/ipv4/ip_sockglue.c15
5 files changed, 20 insertions, 3 deletions
diff --git a/include/linux/in.h b/include/linux/in.h
index 4065313cd7ee..db458beef19d 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -75,6 +75,7 @@ struct in_addr {
75#define IP_IPSEC_POLICY 16 75#define IP_IPSEC_POLICY 16
76#define IP_XFRM_POLICY 17 76#define IP_XFRM_POLICY 17
77#define IP_PASSSEC 18 77#define IP_PASSSEC 18
78#define IP_TRANSPARENT 19
78 79
79/* BSD compatibility */ 80/* BSD compatibility */
80#define IP_RECVRETOPTS IP_RETOPTS 81#define IP_RECVRETOPTS IP_RETOPTS
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 643e26be058e..e97b66e2a9d0 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -129,7 +129,8 @@ struct inet_sock {
129 is_icsk:1, 129 is_icsk:1,
130 freebind:1, 130 freebind:1,
131 hdrincl:1, 131 hdrincl:1,
132 mc_loop:1; 132 mc_loop:1,
133 transparent:1;
133 int mc_index; 134 int mc_index;
134 __be32 mc_addr; 135 __be32 mc_addr;
135 struct ip_mc_socklist *mc_list; 136 struct ip_mc_socklist *mc_list;
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 91324908fccd..80e4977631b8 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -128,7 +128,8 @@ struct inet_timewait_sock {
128 __be16 tw_dport; 128 __be16 tw_dport;
129 __u16 tw_num; 129 __u16 tw_num;
130 /* And these are ours. */ 130 /* And these are ours. */
131 __u8 tw_ipv6only:1; 131 __u8 tw_ipv6only:1,
132 tw_transparent:1;
132 /* 15 bits hole, try to pack */ 133 /* 15 bits hole, try to pack */
133 __u16 tw_ipv6_offset; 134 __u16 tw_ipv6_offset;
134 unsigned long tw_ttd; 135 unsigned long tw_ttd;
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;