diff --git a/include/haproxy/receiver-t.h b/include/haproxy/receiver-t.h index 0ae441eb9..90f52aae5 100644 --- a/include/haproxy/receiver-t.h +++ b/include/haproxy/receiver-t.h @@ -37,6 +37,7 @@ #define RX_F_MWORKER 0x00000004 /* keep the FD open in the master but close it in the children */ #define RX_F_MUST_DUP 0x00000008 /* this receiver's fd must be dup() from a reference; ignore socket-level ops here */ #define RX_F_NON_SUSPENDABLE 0x00000010 /* this socket cannot be suspended hence must always be unbound */ +#define RX_F_PASS_PKTINFO 0x00000020 /* pass pktinfo in received messages */ /* Bit values for rx_settings->options */ #define RX_O_FOREIGN 0x00000001 /* receives on foreign addresses */ diff --git a/src/proto_udp.c b/src/proto_udp.c index 98559745c..7308e988b 100644 --- a/src/proto_udp.c +++ b/src/proto_udp.c @@ -155,6 +155,26 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen) if (global.tune.frontend_sndbuf) setsockopt(listener->rx.fd, SOL_SOCKET, SO_SNDBUF, &global.tune.frontend_sndbuf, sizeof(global.tune.frontend_sndbuf)); + if (listener->rx.flags & RX_F_PASS_PKTINFO) { + /* set IP_PKTINFO to retrieve destination address on recv */ + switch (listener->rx.addr.ss_family) { + case AF_INET: +#if defined(IP_PKTINFO) + setsockopt(listener->rx.fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)); +#elif defined(IP_RECVDSTADDR) + setsockopt(listener->rx.fd, IPPROTO_IP, IP_RECVDSTADDR, &one, sizeof(one)); +#endif /* IP_PKTINFO || IP_RECVDSTADDR */ + break; + case AF_INET6: +#ifdef IPV6_RECVPKTINFO + setsockopt(listener->rx.fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); +#endif + break; + default: + break; + } + } + listener_set_state(listener, LI_LISTEN); udp_return: