Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5715aea authored by KOVACS Krisztian's avatar KOVACS Krisztian Committed by David S. Miller
Browse files

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: default avatarKOVACS Krisztian <hidden@sch.bme.hu>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a210d01a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ struct in_addr {
#define IP_IPSEC_POLICY	16
#define IP_XFRM_POLICY	17
#define IP_PASSSEC	18
#define IP_TRANSPARENT	19

/* BSD compatibility */
#define IP_RECVRETOPTS	IP_RETOPTS
+2 −1
Original line number Diff line number Diff line
@@ -129,7 +129,8 @@ struct inet_sock {
				is_icsk:1,
				freebind:1,
				hdrincl:1,
				mc_loop:1;
				mc_loop:1,
				transparent:1;
	int			mc_index;
	__be32			mc_addr;
	struct ip_mc_socklist	*mc_list;
+2 −1
Original line number Diff line number Diff line
@@ -128,7 +128,8 @@ struct inet_timewait_sock {
	__be16			tw_dport;
	__u16			tw_num;
	/* And these are ours. */
	__u8			tw_ipv6only:1;
	__u8			tw_ipv6only:1,
				tw_transparent:1;
	/* 15 bits hole, try to pack */
	__u16			tw_ipv6_offset;
	unsigned long		tw_ttd;
+1 −0
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
		tw->tw_reuse	    = sk->sk_reuse;
		tw->tw_hash	    = sk->sk_hash;
		tw->tw_ipv6only	    = 0;
		tw->tw_transparent  = inet->transparent;
		tw->tw_prot	    = sk->sk_prot_creator;
		twsk_net_set(tw, hold_net(sock_net(sk)));
		atomic_set(&tw->tw_refcnt, 1);
+14 −1
Original line number Diff line number Diff line
@@ -419,7 +419,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
			     (1<<IP_TTL) | (1<<IP_HDRINCL) |
			     (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
			     (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
			     (1<<IP_PASSSEC))) ||
			     (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
	    optname == IP_MULTICAST_TTL ||
	    optname == IP_MULTICAST_LOOP) {
		if (optlen >= sizeof(int)) {
@@ -878,6 +878,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
		err = xfrm_user_policy(sk, optname, optval, optlen);
		break;

	case IP_TRANSPARENT:
		if (!capable(CAP_NET_ADMIN)) {
			err = -EPERM;
			break;
		}
		if (optlen < 1)
			goto e_inval;
		inet->transparent = !!val;
		break;

	default:
		err = -ENOPROTOOPT;
		break;
@@ -1130,6 +1140,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
	case IP_FREEBIND:
		val = inet->freebind;
		break;
	case IP_TRANSPARENT:
		val = inet->transparent;
		break;
	default:
		release_sock(sk);
		return -ENOPROTOOPT;