Report information
The Basics
Id:
41998
Status:
open
Priority:
Low/Low
Queue:

People
Owner:
Nobody in particular
Cc:
AdminCc:

BugTracker
Version Fixed:
(no value)
Version Found:
(no value)
Versions Affected:
(no value)
Versions Planned:
(no value)
Priority:
P2 Normal
Severity:
S2 Normal
CVSS Score:
(no value)
CVE ID:
(no value)
Component:
DHCP Infrastructure
Area:
feature

Dates
Created:Tue, 22 Mar 2016 04:35:51 -0400
Updated:Wed, 13 Dec 2017 11:20:46 -0500
Closed:Not set



This bug tracker is no longer active.

Please go to our Gitlab to submit issues (both feature requests and bug reports) for active projects maintained by Internet Systems Consortium (ISC).

Due to security and confidentiality requirements, full access is limited to the primary maintainers.

Subject: [PATCH net] add support for mixed LPF/SOCKET mode
Date: Tue, 22 Mar 2016 09:34:14 +0100
To: dhcp-suggest@isc.org
From: "Paolo Abeni" <pabeni@redhat.com>
This patch introduces an additional configuration flag, '--enable-use-lpf-socket', which allows using LPF for xmitting packets and BSD socket APIs to receive packets. In such mode, the packet socket used for transmission is not bound to the used device and the egress interface is specified on xmit via sendmsg. In the above scenario, the Linux kernel does not add an RX packet hook on the used device and this removes a lot of overhead for non-DHCP traffic processing compared to plain LPF mode. --- common/lpf.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- common/socket.c | 10 +++++++++- configure.ac | 17 +++++++++++++++++ includes/dhcpd.h | 4 ++++ includes/osdep.h | 7 +++++++ 5 files changed, 89 insertions(+), 2 deletions(-) diff --git a/common/lpf.c b/common/lpf.c index ee3820b..27943f0 100644 --- a/common/lpf.c +++ b/common/lpf.c @@ -75,10 +75,12 @@ int if_register_lpf (info) struct interface_info *info; { int sock; +#ifdef USE_LPF_RECEIVE union { struct sockaddr_ll ll; struct sockaddr common; } sa; +#endif struct ifreq ifr; /* Make an LPF socket. */ @@ -103,6 +105,8 @@ int if_register_lpf (info) if (ioctl (sock, SIOCGIFINDEX, &ifr)) log_fatal ("Failed to get interface index: %m"); + /* don't need to bind to send the packets */ +#ifdef USE_LPF_RECEIVE /* Bind to the interface name */ memset (&sa, 0, sizeof sa); sa.ll.sll_family = AF_PACKET; @@ -121,7 +125,9 @@ int if_register_lpf (info) log_fatal ("Bind socket to interface: %m"); } - +#else + info -> index = ifr.ifr_ifindex; +#endif get_hw_addr(info->name, &info->hw_address); return sock; @@ -324,6 +330,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) struct sockaddr_in *to; struct hardware *hto; { +#ifndef USE_LPF_RECEIVE + struct msghdr m; + struct sockaddr_ll ll; + struct iovec v; +#endif unsigned hbufp = 0, ibufp = 0; double hh [16]; double ih [1536 / sizeof (double)]; @@ -347,7 +358,34 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) to -> sin_addr.s_addr, to -> sin_port, (unsigned char *)raw, len); memcpy (buf + ibufp, raw, len); + +#ifdef USE_LPF_RECEIVE result = write(interface->wfdesc, buf + fudge, ibufp + len - fudge); +#else + /* The packet socket is unbound, the egress interface must be + * specified via sendmsg */ + memset(&m, 0, sizeof(m)); + + /* Set the target interface */ + memset (&ll, 0, sizeof ll); + ll.sll_family = AF_PACKET; + ll.sll_protocol = SOCK_RAW; + ll.sll_ifindex = interface->index; + m.msg_name = &ll; + m.msg_namelen = sizeof(ll); + + /* + * Set the data buffer we're sending. (Using this wacky + * "scatter-gather" stuff... we only have a single chunk + * of data to send, so we declare a single vector entry.) + */ + v.iov_base = (char *) buf + fudge; + v.iov_len = ibufp + len - fudge; + m.msg_iov = &v; + m.msg_iovlen = 1; + + result = sendmsg(interface->wfdesc, &m, 0); +#endif if (result < 0) log_error ("send_packet: %m"); return result; @@ -469,25 +507,38 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) memcpy(buf, &ibuf[bufix], paylen); return paylen; } +#endif +#if defined (USE_LPF_SEND) int can_unicast_without_arp (ip) struct interface_info *ip; { return 1; } +#endif +#if defined (USE_LPF_RECEIVE) int can_receive_unicast_unconfigured (ip) struct interface_info *ip; { return 1; } +#endif + +#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_SOCKETS) int supports_multiple_interfaces (ip) struct interface_info *ip; { +#if defined (USE_LPF_SOCKETS) + if (!supports_multiple_interfaces_socket(ip)) + return 0; +#endif return 1; } +#endif +#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_SOCKETS) void maybe_setup_fallback () { isc_result_t status; diff --git a/common/socket.c b/common/socket.c index 494528e..dafb634 100644 --- a/common/socket.c +++ b/common/socket.c @@ -55,6 +55,9 @@ # define if_reinitialize_send if_reinitialize_fallback # endif #endif +#ifdef USE_LPF_SOCKETS +# define supports_multiple_interfaces supports_multiple_interfaces_socket +#endif #if defined(DHCPv6) /* @@ -1101,7 +1104,9 @@ int can_unicast_without_arp (ip) { return 0; } +#endif +#if defined (USE_SOCKET_RECEIVE) int can_receive_unicast_unconfigured (ip) struct interface_info *ip; { @@ -1111,7 +1116,9 @@ int can_receive_unicast_unconfigured (ip) return 0; #endif } +#endif +#if defined (USE_SOCKET_SEND) || defined (USE_LPF_SOCKETS) int supports_multiple_interfaces (ip) struct interface_info *ip; { @@ -1123,10 +1130,11 @@ int supports_multiple_interfaces (ip) return(0); #endif } +#endif /* If we have SO_BINDTODEVICE, set up a fallback interface; otherwise, do not. */ - +#if defined (USE_SOCKET_SEND) void maybe_setup_fallback () { #if defined (USE_SOCKET_FALLBACK) diff --git a/configure.ac b/configure.ac index 3cabf64..9ea729a 100644 --- a/configure.ac +++ b/configure.ac @@ -203,6 +203,16 @@ if test "$enable_use_sockets" = "yes"; then [Define to 1 to use the standard BSD socket API.]) fi +AC_ARG_ENABLE(use_lpf_sockets, + AS_HELP_STRING([--enable-use-lpf-sockets],[use the standard BSD socket API for rx and LPF for send (default is no)])) + +if test "$enable_use_lpf_sockets" = "yes"; then + if test "$enable_use_sockets" = "yes"; then + AC_MSG_ERROR([please specify only one of --enable-use-lbf-sockets and --enable-use-sockets]) + fi +fi + + # Try to hnadle incorrect byte order for secs field # This is off by default AC_ARG_ENABLE(secs_byteorder, @@ -523,7 +533,14 @@ if test -n "$DO_LPF" then AC_DEFINE([HAVE_LPF], [1], [Define to 1 to use the Linux Packet Filter interface code.]) + if test "$enable_use_lpf_sockets" = "yes"; then + AC_DEFINE([USE_LPF_SOCKETS], [1], + [Define to 1 to use the LP socket for sending packets and BSD ABI receiving them.]) + fi else + if test "$enable_use_lpf_socket" = "yes"; then + AC_MSG_ERROR([use_lpf_sockets only supported with LPF and LPF not present]) + fi AC_CHECK_HEADER(sys/dlpi.h, DO_DLPI=1) if test -n "$DO_DLPI" then diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 6b212be..ec00b29 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -2635,6 +2635,10 @@ int supports_multiple_interfaces (struct interface_info *); void maybe_setup_fallback (void); #endif +#if defined (USE_LPF_SOCKETS) +int supports_multiple_interfaces_socket (struct interface_info *); +#endif + void if_register6(struct interface_info *info, int do_multicast); void if_register_linklocal6(struct interface_info *info); ssize_t receive_packet6(struct interface_info *interface, diff --git a/includes/osdep.h b/includes/osdep.h index cfae90b..5d6fb6a 100644 --- a/includes/osdep.h +++ b/includes/osdep.h @@ -55,6 +55,7 @@ #if !defined (USE_SOCKETS) && \ !defined (USE_SOCKET_SEND) && \ !defined (USE_SOCKET_RECEIVE) && \ + !defined (USE_LPF_SOCKETS) && \ !defined (USE_RAW_SOCKETS) && \ !defined (USE_RAW_SEND) && \ !defined (USE_SOCKET_RECEIVE) && \ @@ -109,6 +110,12 @@ # endif #endif +#ifdef USE_LPF_SOCKETS +# define USE_LPF_SEND +# define USE_SOCKET_RECEIVE +# define USE_LPF_HWADDR +#endif + #ifdef USE_RAW_SOCKETS # define USE_RAW_SEND # define USE_SOCKET_RECEIVE -- 1.8.3.1
Subject: [ISC-Bugs #41998] issue status
Date: Thu, 31 Mar 2016 16:19:46 +0200
To: dhcp-suggest@isc.org
From: "Paolo Abeni" <pabeni@redhat.com>
Hi all, I'm looking after any feedback on the proposed change. I looked for some public issue tracker interface, but I was unable to find it. Can you please give any indication on the issue status ? Is pooling needed to get further updates ? Thank you, Paolo
On Thu Mar 31 14:19:55 2016, pabeni@redhat.com wrote: > Hi all, > > I'm looking after any feedback on the proposed change. I looked for some > public issue tracker interface, but I was unable to find it. > > Can you please give any indication on the issue status ? > Is pooling needed to get further updates ? > > Thank you, > > Paolo > > We are now in the process of deciding what to work on for the next set of releases and will be deciding shortly if we will try to add your patch to the work. Thank your for the patch submission, Shawn