Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Balazs Scheidler and committed by
Patrick McHardy
6c468622 aa976fc0

+49 -1
+4
include/linux/in6.h
··· 268 268 /* RFC5082: Generalized Ttl Security Mechanism */ 269 269 #define IPV6_MINHOPCOUNT 73 270 270 271 + #define IPV6_ORIGDSTADDR 74 272 + #define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR 273 + #define IPV6_TRANSPARENT 75 274 + 271 275 /* 272 276 * Multicast Routing: 273 277 * see include/linux/mroute6.h.
+3 -1
include/linux/ipv6.h
··· 341 341 odstopts:1, 342 342 rxflow:1, 343 343 rxtclass:1, 344 - rxpmtu:1; 344 + rxpmtu:1, 345 + rxorigdstaddr:1; 346 + /* 2 bits hole */ 345 347 } bits; 346 348 __u16 all; 347 349 } rxopt;
+19
net/ipv6/datagram.c
··· 577 577 u8 *ptr = nh + opt->dst1; 578 578 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr); 579 579 } 580 + if (np->rxopt.bits.rxorigdstaddr) { 581 + struct sockaddr_in6 sin6; 582 + u16 *ports = (u16 *) skb_transport_header(skb); 583 + 584 + if (skb_transport_offset(skb) + 4 <= skb->len) { 585 + /* All current transport protocols have the port numbers in the 586 + * first four bytes of the transport header and this function is 587 + * written with this assumption in mind. 588 + */ 589 + 590 + sin6.sin6_family = AF_INET6; 591 + ipv6_addr_copy(&sin6.sin6_addr, &ipv6_hdr(skb)->daddr); 592 + sin6.sin6_port = ports[1]; 593 + sin6.sin6_flowinfo = 0; 594 + sin6.sin6_scope_id = 0; 595 + 596 + put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6); 597 + } 598 + } 580 599 return 0; 581 600 } 582 601
+23
net/ipv6/ipv6_sockglue.c
··· 342 342 retv = 0; 343 343 break; 344 344 345 + case IPV6_TRANSPARENT: 346 + if (optlen < sizeof(int)) 347 + goto e_inval; 348 + /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */ 349 + inet_sk(sk)->transparent = valbool; 350 + retv = 0; 351 + break; 352 + 353 + case IPV6_RECVORIGDSTADDR: 354 + if (optlen < sizeof(int)) 355 + goto e_inval; 356 + np->rxopt.bits.rxorigdstaddr = valbool; 357 + retv = 0; 358 + break; 359 + 345 360 case IPV6_HOPOPTS: 346 361 case IPV6_RTHDRDSTOPTS: 347 362 case IPV6_RTHDR: ··· 1118 1103 return 0; 1119 1104 break; 1120 1105 } 1106 + 1107 + case IPV6_TRANSPARENT: 1108 + val = inet_sk(sk)->transparent; 1109 + break; 1110 + 1111 + case IPV6_RECVORIGDSTADDR: 1112 + val = np->rxopt.bits.rxorigdstaddr; 1113 + break; 1121 1114 1122 1115 case IPV6_UNICAST_HOPS: 1123 1116 case IPV6_MULTICAST_HOPS: