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: Balazs Scheidler <bazsi@balabit.hu> Signed-off-by: KOVACS Krisztian <hidden@balabit.hu> Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
aa976fc011
commit
6c46862280
4 changed files with 49 additions and 1 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue