From 2b082d875d6c6899ef71024c2efd4380a5678c1e Mon Sep 17 00:00:00 2001 From: Erik Skultety Date: Thu, 30 Jan 2020 13:51:30 +0100 Subject: [PATCH] nwfilter: Use immediate packet delivery mode rather than buffering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our nwfilter code doesn't set any timeout on the pcap packet buffer which means that when DHCP snooping is enabled on a guest interface and libvirt is trying to learn the IP address from guest's DHCP traffic, it takes up to 4x longer to ping a guest successfully compared to a case where nwfilter isn't enabled at all or libvirt uses the cached nwfilter leases to populate the corresponding rules to ebtables. With the pcap filter and rate limiting already in place, we should be able to afford enabling the immediate packet delivery, FWIW immediate mode was actually the default prior libpcap-1.5.0 (CentOS 6) regardless of whether a buffer was requested. The lack of any kind of timeout on the pcap buffer messed with the libvirt TCK test suite which, even with a generous timeout in place, timeouts every single time simply because it takes a while until guest actually starts producing any kind of traffic to fill up the buffer in place (apart from the DHCP traffic which happens fairly early on). Signed-off-by: Erik Skultety Reviewed-by: Daniel P. Berrangé --- src/nwfilter/nwfilter_dhcpsnoop.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c index 10567e9cd3..a1c0c0189e 100644 --- a/src/nwfilter/nwfilter_dhcpsnoop.c +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -242,23 +242,6 @@ struct _virNWFilterDHCPDecodeJob { # define DHCP_PKT_BURST 50 /* pkts/sec */ # define DHCP_BURST_INTERVAL_S 10 /* sec */ -/* - * NB: Any libpcap built with HAVE_TPACKET3 will require - * PCAP_BUFFERSIZE to be at least 262144 (although - * pcap_set_buffer_size() with a lower value will succeed, and the - * error will only show up later when pcap_setfilter() is called). - * - * It is possible that in the future libpcap could increase the - * minimum size even further, but due to the fact that each guest - * using dhcp snooping keeps 2 pcap sockets open (and thus 2 buffers - * allocated) for the life of the guest, we want to minimize the - * length of the buffer, so instead of leaving it at the default size - * (2MB), we are setting it to the minimum viable size and including - * this clue in the source to help quickly resolve the problem when/if - * it reoccurs. - */ -# define PCAP_BUFFERSIZE (256 * 1024) - # define MAX_QUEUED_JOBS (DHCP_PKT_BURST + 2 * DHCP_PKT_RATE) typedef struct _virNWFilterSnoopRateLimitConf virNWFilterSnoopRateLimitConf; @@ -1098,13 +1081,8 @@ virNWFilterSnoopDHCPOpen(const char *ifname, virMacAddr *mac, goto cleanup_nohandle; } - /* IMPORTANT: If there is any failure of *any* pcap_* function - * during setup of the socket, look to the comment where - * PCAP_BUFFERSIZE is defined. It may be too small, even if the - * generated error doesn't imply that. - */ if (pcap_set_snaplen(handle, PCAP_PBUFSIZE) < 0 || - pcap_set_buffer_size(handle, PCAP_BUFFERSIZE) < 0 || + pcap_set_immediate_mode(handle, 1) < 0 || pcap_activate(handle) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("setup of pcap handle failed: %s"),