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

Commit 6c468622 authored by Balazs Scheidler's avatar Balazs Scheidler Committed by Patrick McHardy
Browse files

tproxy: added tproxy sockopt interface in the IPV6 layer



Support for IPV6_RECVORIGDSTADDR sockopt for UDP sockets were contributed by
Harry Mason.

Signed-off-by: default avatarBalazs Scheidler <bazsi@balabit.hu>
Signed-off-by: default avatarKOVACS Krisztian <hidden@balabit.hu>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent aa976fc0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -268,6 +268,10 @@ struct in6_flowlabel_req {
/* RFC5082: Generalized Ttl Security Mechanism */
#define IPV6_MINHOPCOUNT		73

#define IPV6_ORIGDSTADDR        74
#define IPV6_RECVORIGDSTADDR    IPV6_ORIGDSTADDR
#define IPV6_TRANSPARENT        75

/*
 * Multicast Routing:
 * see include/linux/mroute6.h.
+3 −1
Original line number Diff line number Diff line
@@ -341,7 +341,9 @@ struct ipv6_pinfo {
				odstopts:1,
                                rxflow:1,
				rxtclass:1,
				rxpmtu:1;
				rxpmtu:1,
				rxorigdstaddr:1;
				/* 2 bits hole */
		} bits;
		__u16		all;
	} rxopt;
+19 −0
Original line number Diff line number Diff line
@@ -577,6 +577,25 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
		u8 *ptr = nh + opt->dst1;
		put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
	}
	if (np->rxopt.bits.rxorigdstaddr) {
		struct sockaddr_in6 sin6;
		u16 *ports = (u16 *) skb_transport_header(skb);

		if (skb_transport_offset(skb) + 4 <= skb->len) {
			/* All current transport protocols have the port numbers in the
			 * first four bytes of the transport header and this function is
			 * written with this assumption in mind.
			 */

			sin6.sin6_family = AF_INET6;
			ipv6_addr_copy(&sin6.sin6_addr, &ipv6_hdr(skb)->daddr);
			sin6.sin6_port = ports[1];
			sin6.sin6_flowinfo = 0;
			sin6.sin6_scope_id = 0;

			put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6);
		}
	}
	return 0;
}

+23 −0
Original line number Diff line number Diff line
@@ -342,6 +342,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
		retv = 0;
		break;

	case IPV6_TRANSPARENT:
		if (optlen < sizeof(int))
			goto e_inval;
		/* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */
		inet_sk(sk)->transparent = valbool;
		retv = 0;
		break;

	case IPV6_RECVORIGDSTADDR:
		if (optlen < sizeof(int))
			goto e_inval;
		np->rxopt.bits.rxorigdstaddr = valbool;
		retv = 0;
		break;

	case IPV6_HOPOPTS:
	case IPV6_RTHDRDSTOPTS:
	case IPV6_RTHDR:
@@ -1104,6 +1119,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
		break;
	}

	case IPV6_TRANSPARENT:
		val = inet_sk(sk)->transparent;
		break;

	case IPV6_RECVORIGDSTADDR:
		val = np->rxopt.bits.rxorigdstaddr;
		break;

	case IPV6_UNICAST_HOPS:
	case IPV6_MULTICAST_HOPS:
	{