From nobody Thu May 2 23:39:08 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1528216979163217.76598728463875; Tue, 5 Jun 2018 09:42:59 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 02058307A299; Tue, 5 Jun 2018 16:42:57 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CAEB78E187; Tue, 5 Jun 2018 16:42:55 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id AC3CB18005DA; Tue, 5 Jun 2018 16:42:53 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w55GgV4J017755 for ; Tue, 5 Jun 2018 12:42:31 -0400 Received: by smtp.corp.redhat.com (Postfix) id EBD4A10F1C1A; Tue, 5 Jun 2018 16:42:30 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.79]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6322B10FFE73; Tue, 5 Jun 2018 16:42:30 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Tue, 5 Jun 2018 17:42:24 +0100 Message-Id: <20180605164225.7351-2-berrange@redhat.com> In-Reply-To: <20180605164225.7351-1-berrange@redhat.com> References: <20180605164225.7351-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 1/2] nwfilter: fix IP address learning X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Tue, 05 Jun 2018 16:42:58 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 In a previous commit: commit d4bf8f415074759baf051644559e04fe78888f8b Author: Daniel P. Berrang=C3=A9 Date: Wed Feb 14 09:43:59 2018 +0000 nwfilter: handle missing switch enum cases Ensure all enum cases are listed in switch statements, or cast away enum type in places where we don't wish to cover all cases. Reviewed-by: John Ferlan Signed-off-by: Daniel P. Berrang=C3=A9 we changed a switch in the nwfilter learning thread so that it had explict cases for all enum entries. Unfortunately the parameters in the method had been declared with incorrect type. The "howDetect" parameter does *not* accept "enum howDetect" values, rather it accepts a bitmask of "enum howDetect" values, so it should have been an "int" type. The caller always passes DETECT_STATIC|DETECT_DHCP, so essentially the IP addressing learning was completely broken by the above change, as it never matched any switch case, hitting the default leading to EINVAL. Stop using a typedef for the parameter name this this is a bitmask, not a plain enum value. Also stop using switch() since that's misleading with bitmasks too. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: John Ferlan --- src/nwfilter/nwfilter_learnipaddr.c | 18 +++++++----------- src/nwfilter/nwfilter_learnipaddr.h | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_le= arnipaddr.c index cc3bfd971c..085af7892e 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -144,7 +144,7 @@ struct _virNWFilterIPAddrLearnReq { char *filtername; virHashTablePtr filterparams; virNWFilterDriverStatePtr driver; - enum howDetect howDetect; + int howDetect; /* bitmask of enum howDetect */ =20 int status; volatile bool terminate; @@ -437,28 +437,24 @@ learnIPAddressThread(void *arg) =20 virMacAddrFormat(&req->macaddr, macaddr); =20 - switch (req->howDetect) { - case DETECT_DHCP: + if (req->howDetect =3D=3D DETECT_DHCP) { if (techdriver->applyDHCPOnlyRules(req->ifname, &req->macaddr, NULL, false) < 0) { + VIR_DEBUG("Unable to apply DHCP only rules"); req->status =3D EINVAL; goto done; } virBufferAddLit(&buf, "src port 67 and dst port 68"); - break; - case DETECT_STATIC: + } else { if (techdriver->applyBasicRules(req->ifname, &req->macaddr) < 0) { + VIR_DEBUG("Unable to apply basic rules"); req->status =3D EINVAL; goto done; } virBufferAsprintf(&buf, "ether host %s or ether dst ff:ff:ff:ff:ff= :ff", macaddr); - break; - default: - req->status =3D EINVAL; - goto done; } =20 if (virBufferError(&buf)) { @@ -693,7 +689,7 @@ learnIPAddressThread(void *arg) * once its IP address has been detected * @driver : the network filter driver * @howDetect : the method on how the thread is supposed to detect the - * IP address; must choose any of the available flags + * IP address; bitmask of "enum howDetect" flags. * * Instruct to learn the IP address being used on a given interface (ifnam= e). * Unless there already is a thread attempting to learn the IP address @@ -711,7 +707,7 @@ virNWFilterLearnIPAddress(virNWFilterTechDriverPtr tech= driver, const char *filtername, virHashTablePtr filterparams, virNWFilterDriverStatePtr driver, - enum howDetect howDetect) + int howDetect) { int rc; virThread thread; diff --git a/src/nwfilter/nwfilter_learnipaddr.h b/src/nwfilter/nwfilter_le= arnipaddr.h index 06fea5bff8..753aabc594 100644 --- a/src/nwfilter/nwfilter_learnipaddr.h +++ b/src/nwfilter/nwfilter_learnipaddr.h @@ -43,7 +43,7 @@ int virNWFilterLearnIPAddress(virNWFilterTechDriverPtr te= chdriver, const char *filtername, virHashTablePtr filterparams, virNWFilterDriverStatePtr driver, - enum howDetect howDetect); + int howDetect); =20 bool virNWFilterHasLearnReq(int ifindex); int virNWFilterTerminateLearnReq(const char *ifname); --=20 2.17.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 23:39:08 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1528216999375872.8022324425962; Tue, 5 Jun 2018 09:43:19 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6D2023002317; Tue, 5 Jun 2018 16:43:17 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2BC358B331; Tue, 5 Jun 2018 16:43:17 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B19DF4CA80; Tue, 5 Jun 2018 16:43:16 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w55GgWLQ017764 for ; Tue, 5 Jun 2018 12:42:32 -0400 Received: by smtp.corp.redhat.com (Postfix) id 0A637100295D; Tue, 5 Jun 2018 16:42:32 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.79]) by smtp.corp.redhat.com (Postfix) with ESMTP id 333CF10F1C1D; Tue, 5 Jun 2018 16:42:31 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Tue, 5 Jun 2018 17:42:25 +0100 Message-Id: <20180605164225.7351-3-berrange@redhat.com> In-Reply-To: <20180605164225.7351-1-berrange@redhat.com> References: <20180605164225.7351-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 2/2] nwfilter: directly use poll to wait for packets instead of pcap_next X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Tue, 05 Jun 2018 16:43:18 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 When a QEMU VM shuts down its TAP device gets deleted while nwfilter IP address learning thread is still capturing packets. It is seen that with TPACKET_V3 support in libcap, the pcap_next() call will not always exit its poll() when the NIC is removed. This prevents the learning thread from exiting which blocks the rest of libvirtd waiting on mutex acquisition. By switching to do poll() in libvirt code, we can ensure that we always exit the poll() at a time that is right for libvirt. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: John Ferlan --- src/nwfilter/nwfilter_learnipaddr.c | 37 +++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_le= arnipaddr.c index 085af7892e..52adc37389 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -31,6 +31,7 @@ =20 #include #include +#include =20 #include #include @@ -414,6 +415,7 @@ learnIPAddressThread(void *arg) bool showError =3D true; enum howDetect howDetected =3D 0; virNWFilterTechDriverPtr techdriver =3D req->techdriver; + struct pollfd fds[1]; =20 if (virNWFilterLockIface(req->ifname) < 0) goto err_no_lock; @@ -435,6 +437,9 @@ learnIPAddressThread(void *arg) goto done; } =20 + fds[0].fd =3D pcap_fileno(handle); + fds[0].events =3D POLLIN | POLLERR; + virMacAddrFormat(&req->macaddr, macaddr); =20 if (req->howDetect =3D=3D DETECT_DHCP) { @@ -480,17 +485,45 @@ learnIPAddressThread(void *arg) pcap_freecode(&fp); =20 while (req->status =3D=3D 0 && vmaddr =3D=3D 0) { + int n =3D poll(fds, ARRAY_CARDINALITY(fds), PKT_TIMEOUT_MS); + + if (n < 0) { + if (errno =3D=3D EAGAIN || errno =3D=3D EINTR) + continue; + + req->status =3D errno; + showError =3D true; + break; + } + + if (n =3D=3D 0) { + if (threadsTerminate || req->terminate) { + VIR_DEBUG("Terminate request seen, cancelling pcap"); + req->status =3D ECANCELED; + showError =3D false; + break; + } + continue; + } + + if (fds[0].revents & (POLLHUP | POLLERR)) { + VIR_DEBUG("Error from FD probably dev deleted"); + req->status =3D ENODEV; + showError =3D false; + break; + } + packet =3D pcap_next(handle, &header); =20 if (!packet) { - + /* Already handled with poll, but lets be sure */ if (threadsTerminate || req->terminate) { req->status =3D ECANCELED; showError =3D false; break; } =20 - /* check whether VM's dev is still there */ + /* Again, already handled above, but lets be sure */ if (virNetDevValidateConfig(req->ifname, NULL, req->ifindex) <= =3D 0) { virResetLastError(); req->status =3D ENODEV; --=20 2.17.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list