[libvirt] [libvirt PATCHv8 1/1] add DHCP snooping
This patch adds DHCP snooping support to libvirt. The learning method for IP addresses is specified by setting the "ip_learning" variable to one of "any" [default] (existing IP learning code), "none" (static only addresses) or "dhcp" (DHCP snooping). Active leases are saved in a lease file and reloaded on restart or HUP. Changes since v7: - renamed functions as suggested - collected local state into "virNWFilterSnoopState" struct - cleaned up include file list - misc code cleanups per review comments Signed-off-by: David L Stevens --- docs/formatnwfilter.html.in| 17 + po/POTFILES.in |1 + src/Makefile.am|2 + src/nwfilter/nwfilter_dhcpsnoop.c | 1197 src/nwfilter/nwfilter_dhcpsnoop.h | 38 + src/nwfilter/nwfilter_driver.c |6 + src/nwfilter/nwfilter_gentech_driver.c | 59 ++- 7 files changed, 1307 insertions(+), 13 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in index 9cb7644..ad10765 100644 --- a/docs/formatnwfilter.html.in +++ b/docs/formatnwfilter.html.in @@ -2189,6 +2189,23 @@ In case a VM is resumed after suspension or migrated, IP address detection will be restarted. + + Variable ip_learning may be used to specify + the IP address learning method. Valid values are any, dhcp, + or none. The default value is any, meaning that libvirt + may use any packet to determine the address in use by a VM. A value of + dhcp specifies that libvirt should only honor DHCP server-assigned + addresses with valid leases. If ip_learning is set to none, + libvirt does not do address learning and referencing IP without + assigning it an explicit value is an error. + + Use of ip_learning=dhcp (DHCP snooping) provides additional + anti-spoofing security, especially when combined with a filter allowing + only trusted DHCP servers to assign addresses. If the DHCP lease expires, + the VM will no longer be able to use the IP address until it acquires a + new, valid lease from a DHCP server. If the VM is migrated, it must get + a new valid DHCP lease to use an IP address (e.g., by + bringing the VM interface down and up again). VM Migration diff --git a/po/POTFILES.in b/po/POTFILES.in index 88be04e..d4b0a86 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -51,6 +51,7 @@ src/node_device/node_device_hal.c src/node_device/node_device_linux_sysfs.c src/node_device/node_device_udev.c src/nodeinfo.c +src/nwfilter/nwfilter_dhcpsnoop.c src/nwfilter/nwfilter_driver.c src/nwfilter/nwfilter_ebiptables_driver.c src/nwfilter/nwfilter_gentech_driver.c diff --git a/src/Makefile.am b/src/Makefile.am index a2aae9d..4382caf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -509,6 +509,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..8c2ff50 --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,1197 @@ +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_L
[libvirt] [libvirt PATCHv7 1/1] add DHCP snooping
This patch adds DHCP snooping support to libvirt. The learning method for IP addresses is specified by setting the "ip_learning" variable to one of "any" [default] (existing IP learning code), "none" (static only addresses) or "dhcp" (DHCP snooping). Active leases are saved in a lease file and reloaded on restart or HUP. Changes since v6: - replace pthread_cancel() with synchronous cancelation method Signed-off-by: David L Stevens --- docs/formatnwfilter.html.in| 17 + src/Makefile.am|2 + src/nwfilter/nwfilter_dhcpsnoop.c | 1139 src/nwfilter/nwfilter_dhcpsnoop.h | 38 ++ src/nwfilter/nwfilter_driver.c |6 + src/nwfilter/nwfilter_gentech_driver.c | 59 ++- 6 files changed, 1248 insertions(+), 13 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in index 9cb7644..ad10765 100644 --- a/docs/formatnwfilter.html.in +++ b/docs/formatnwfilter.html.in @@ -2189,6 +2189,23 @@ In case a VM is resumed after suspension or migrated, IP address detection will be restarted. + + Variable ip_learning may be used to specify + the IP address learning method. Valid values are any, dhcp, + or none. The default value is any, meaning that libvirt + may use any packet to determine the address in use by a VM. A value of + dhcp specifies that libvirt should only honor DHCP server-assigned + addresses with valid leases. If ip_learning is set to none, + libvirt does not do address learning and referencing IP without + assigning it an explicit value is an error. + + Use of ip_learning=dhcp (DHCP snooping) provides additional + anti-spoofing security, especially when combined with a filter allowing + only trusted DHCP servers to assign addresses. If the DHCP lease expires, + the VM will no longer be able to use the IP address until it acquires a + new, valid lease from a DHCP server. If the VM is migrated, it must get + a new valid DHCP lease to use an IP address (e.g., by + bringing the VM interface down and up again). VM Migration diff --git a/src/Makefile.am b/src/Makefile.am index a2aae9d..4382caf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -509,6 +509,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..8e5dcc5 --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,1139 @@ +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_LIBPCAP +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "datatypes.h" +#include "virterror_internal.h" +#include "threads.h" +#include "conf/nwfilter_params.h" +#include "conf/domain_conf.h" +#include "nwfilter_gentech_driver.h" +#include "nwfilter_ebiptables_driver.h" +#incl
[libvirt] [libvirt PATCHv6 1/1] add DHCP snooping
This patch adds DHCP snooping support to libvirt. The learning method for IP addresses is specified by setting the "ip_learning" variable to one of "any" [default] (existing IP learning code), "none" (static only addresses) or "dhcp" (DHCP snooping). Active leases are saved in a lease file and reloaded on restart or HUP. Changes since v5: - use VMUUID+MAC to identify interfaces for leases - use direct pthread_cancel to kill snooper threads to avoid races with re-used host interfaces Signed-off-by: David L Stevens --- docs/formatnwfilter.html.in| 17 + src/Makefile.am|2 + src/nwfilter/nwfilter_dhcpsnoop.c | 1078 src/nwfilter/nwfilter_dhcpsnoop.h | 38 ++ src/nwfilter/nwfilter_driver.c |6 + src/nwfilter/nwfilter_gentech_driver.c | 59 ++- 6 files changed, 1187 insertions(+), 13 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in index 9cb7644..ad10765 100644 --- a/docs/formatnwfilter.html.in +++ b/docs/formatnwfilter.html.in @@ -2189,6 +2189,23 @@ In case a VM is resumed after suspension or migrated, IP address detection will be restarted. + + Variable ip_learning may be used to specify + the IP address learning method. Valid values are any, dhcp, + or none. The default value is any, meaning that libvirt + may use any packet to determine the address in use by a VM. A value of + dhcp specifies that libvirt should only honor DHCP server-assigned + addresses with valid leases. If ip_learning is set to none, + libvirt does not do address learning and referencing IP without + assigning it an explicit value is an error. + + Use of ip_learning=dhcp (DHCP snooping) provides additional + anti-spoofing security, especially when combined with a filter allowing + only trusted DHCP servers to assign addresses. If the DHCP lease expires, + the VM will no longer be able to use the IP address until it acquires a + new, valid lease from a DHCP server. If the VM is migrated, it must get + a new valid DHCP lease to use an IP address (e.g., by + bringing the VM interface down and up again). VM Migration diff --git a/src/Makefile.am b/src/Makefile.am index e57eca2..4dc1609 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -508,6 +508,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..682a4ab --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,1078 @@ +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_LIBPCAP +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "datatypes.h" +#include "virterror_internal.h" +#include "threads.h" +#include "conf/nwfilter_params.h" +#include "conf/domain_conf.h" +#include "nwfilter_g
[libvirt] [libvirt PATCHv5 2/2] add leasefile support
This patch adds support for saving DHCP snooping leases to an on-disk file and restoring saved leases that are still active on restart. Signed-off-by: David L Stevens --- src/nwfilter/nwfilter_dhcpsnoop.c | 270 + 1 files changed, 243 insertions(+), 27 deletions(-) diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c index 8a37a6f..918ad7b 100644 --- a/src/nwfilter/nwfilter_dhcpsnoop.c +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -55,10 +55,18 @@ #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_dhcpsnoop.h" +#include "virfile.h" +#include "configmake.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER #ifdef HAVE_LIBPCAP + +#define LEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.leases" +#define TMPLEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.ltmp" +static int lease_fd = -1; +static int nleases = 0; /* number of active leases */ +static int wleases = 0; /* number of written leases */ static virHashTablePtr SnoopReqs; static pthread_mutex_t SnoopLock; @@ -76,6 +84,7 @@ struct virNWFilterSnoopReq { const char *filtername; virNWFilterHashTablePtr vars; virNWFilterDriverStatePtr driver; +bool running; /* start and end of lease list, ordered by lease time */ struct iplease *start; struct iplease *end; @@ -96,7 +105,15 @@ struct iplease { static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); static void ipl_update(struct iplease *pl, uint32_t timeout); + +static struct virNWFilterSnoopReq *newreq(const char *ifname); +static void lease_open(void); +static void lease_close(void); +static void lease_load(void); +static void lease_save(struct iplease *ipl); +static void lease_restore(struct virNWFilterSnoopReq *req); +static void lease_refresh(void); /* * ipl_ladd - add an IP lease to a list @@ -187,7 +204,7 @@ ipl_install(struct iplease *ipl) * ipl_add - create or update an IP lease */ static void -ipl_add(struct iplease *plnew) +ipl_add(struct iplease *plnew, bool update_leasefile) { struct iplease *pl; struct virNWFilterSnoopReq *req = plnew->ipl_req; @@ -195,6 +212,8 @@ ipl_add(struct iplease *plnew) pl = ipl_getbyip(req->start, plnew->ipl_ipaddr); if (pl) { ipl_update(pl, plnew->ipl_timeout); +if (update_leasefile) +lease_save(pl); return; } /* support for multiple addresses requires the ability to add filters @@ -212,11 +231,14 @@ ipl_add(struct iplease *plnew) } *pl = *plnew; -if (ipl_install(pl) < 0) { +if (req->running && ipl_install(pl) < 0) { VIR_FREE(pl); return; } ipl_tadd(pl); +nleases++; +if (update_leasefile) +lease_save(pl); } /* @@ -252,7 +274,7 @@ ipl_tdel(struct iplease *ipl) * ipl_del - delete an IP lease */ static void -ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr) +ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr, bool update_leasefile) { struct iplease *ipl; @@ -262,13 +284,18 @@ ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr) ipl_tdel(ipl); -/* for multiple address support, this needs to remove those rules - * referencing "IP" with ipl's ip value. - */ -if (req->techdriver->applyDHCPOnlyRules(req->ifname, req->macaddr, NULL)) { -virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "ipl_ldel failed"); +if (update_leasefile) { +lease_save(ipl); + +/* + * for multiple address support, this needs to remove those rules + * referencing "IP" with ipl's ip value. + */ +if (req->techdriver->applyDHCPOnlyRules(req->ifname,req->macaddr,NULL)) +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "ipl_ldel failed"); } VIR_FREE(ipl); +nleases--; } /* @@ -308,7 +335,7 @@ ipl_trun(struct virNWFilterSnoopReq *req) now = time(0); while (req->start && req->start->ipl_timeout <= now) -ipl_del(req, req->start->ipl_ipaddr); +ipl_del(req, req->start->ipl_ipaddr, 1); return 0; } @@ -467,11 +494,11 @@ dhcpdecode(struct virNWFilterSnoopReq *req, struct eth *pep, int len) switch (mtype) { case DHCPACK: -ipl_add(&ipl); +ipl_add(&ipl, 1); break; case DHCPDECLINE: case DHCPRELEASE: -ipl_del(req, ipl.ipl_ipaddr); +ipl_del(req, ipl.ipl_ipaddr, 1); break; default: break; @@ -521,7 +548,7 @@ snoopReqFree(struct virNWFilterSnoopReq *req) /* free all leases */ snoop_lock(); for (ipl
[libvirt] [libvirt PATCHv5 0/2] add DHCP Snooping support for libvirt
These patches add DHCP snooping support to libvirt. The learning method for IP addresses is specified by setting the "ip_learning" variable to one of "any" [default] (existing IP learning code), "none" (static only addresses) or "dhcp" (DHCP snooping). Differences from v4: - added documentation of "ip_learning" - added support for kill -HUP reloading - simplified lease file handling David L Stevens (2): add DHCP snooping add leasefile support docs/formatnwfilter.html.in | 17 + examples/xml/nwfilter/no-ip-spoofing.xml |5 + src/Makefile.am |2 + src/nwfilter/nwfilter_dhcpsnoop.c| 961 ++ src/nwfilter/nwfilter_dhcpsnoop.h| 38 ++ src/nwfilter/nwfilter_driver.c |6 + src/nwfilter/nwfilter_gentech_driver.c | 53 ++- 7 files changed, 1069 insertions(+), 13 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv5 1/2] add DHCP snooping
This patch adds DHCP Snooping support to libvirt. Signed-off-by: David L Stevens --- docs/formatnwfilter.html.in | 17 + examples/xml/nwfilter/no-ip-spoofing.xml |5 + src/Makefile.am |2 + src/nwfilter/nwfilter_dhcpsnoop.c| 745 ++ src/nwfilter/nwfilter_dhcpsnoop.h| 38 ++ src/nwfilter/nwfilter_driver.c |6 + src/nwfilter/nwfilter_gentech_driver.c | 53 ++- 7 files changed, 853 insertions(+), 13 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in index 8df4a93..8003320 100644 --- a/docs/formatnwfilter.html.in +++ b/docs/formatnwfilter.html.in @@ -1775,6 +1775,23 @@ In case a VM is resumed after suspension or migrated, IP address detection will be restarted. + + Variable ip_learning may be used to specify + the IP address learning method. Valid values are any, dhcp, + or none. The default value is any, meaning that libvirt + may use any packet to determine the address in use by a VM. A value of + dhcp specifies that libvirt should only honor DHCP server-assigned + addresses with valid leases. If ip_learning is set to none, + libvirt does not do address learning and referencing IP without + assigning it an explicit value is an error. + + Use of ip_learning=dhcp (DHCP snooping) provides additional + anti-spoofing security, especially when combined with a filter allowing + only trusted DHCP servers to assign addresses. If the DHCP lease expires, + the VM will no longer be able to use the IP address until it acquires a + new, valid lease from a DHCP server. If the VM is migrated, it must get + a new valid DHCP lease to use an IP address (e.g., by + bringing the VM interface down and up again). VM Migration diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index b8c94c8..7c7fd46 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -1,5 +1,10 @@ + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 87d91ed..c948cbf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -481,6 +481,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..8a37a6f --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,745 @@ +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_LIBPCAP +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "datatypes.h" +#include "interface.h" +#include "virterror_internal.h" +#include "threads.h" +#include "conf/nwfilter_params.h" +#include "conf/domain_conf.h" +#include "nwfilter_gentech_driver.h" +#include "nwfilter_ebiptables_driver.h" +#include "nwfilte
[libvirt] [libvirt PATCHv4 0/2] DHCP Snooping support for libvirt
These patches add DHCP snooping support to libvirt. The learning method for IP addresses is specified by setting the "ip_learning" variable to one of "any" [default] (existing IP learning code), "none" (static only addresses) or "dhcp" (DHCP snooping). Differences from v3: removed support for multiple IP addresses. This version, like this existing code, allows only one IP address per interface. David L Stevens (2): add DHCP snooping add leasefile support examples/xml/nwfilter/no-ip-spoofing.xml |5 + src/Makefile.am |2 + src/nwfilter/nwfilter_dhcpsnoop.c| 1005 ++ src/nwfilter/nwfilter_dhcpsnoop.h| 38 ++ src/nwfilter/nwfilter_driver.c |5 + src/nwfilter/nwfilter_gentech_driver.c | 51 ++- 6 files changed, 1093 insertions(+), 13 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv4 1/2] add DHCP snooping
This patch adds DHCP Snooping support to libvirt. Signed-off-by: David L Stevens --- examples/xml/nwfilter/no-ip-spoofing.xml |5 + src/Makefile.am |2 + src/nwfilter/nwfilter_dhcpsnoop.c| 705 ++ src/nwfilter/nwfilter_dhcpsnoop.h| 38 ++ src/nwfilter/nwfilter_driver.c |5 + src/nwfilter/nwfilter_gentech_driver.c | 51 ++- 6 files changed, 793 insertions(+), 13 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index b8c94c8..e5969a0 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,4 +4,9 @@ + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 87d91ed..c948cbf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -481,6 +481,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..b77e2b0 --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,705 @@ +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_LIBPCAP +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "datatypes.h" +#include "interface.h" +#include "virterror_internal.h" +#include "threads.h" +#include "conf/nwfilter_params.h" +#include "conf/domain_conf.h" +#include "nwfilter_gentech_driver.h" +#include "nwfilter_ebiptables_driver.h" +#include "nwfilter_dhcpsnoop.h" + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +#ifdef HAVE_LIBPCAP + +static virHashTablePtr SnoopReqs; +static pthread_mutex_t SnoopLock; + +#define snoop_lock(){ pthread_mutex_lock(&SnoopLock); } +#define snoop_unlock() { pthread_mutex_unlock(&SnoopLock); } + +struct virNWFilterSnoopReq { +virNWFilterTechDriverPtr techdriver; +const char *ifname; +int ifindex; +const char *linkdev; +enum virDomainNetType nettype; +unsigned char macaddr[VIR_MAC_STRING_BUFLEN]; +const char *filtername; +virNWFilterHashTablePtr vars; +virNWFilterDriverStatePtr driver; +pthread_t thread; +/* start and end of lease list, ordered by lease time */ +struct iplease *start; +struct iplease *end; +bool die; +}; + +#define POLL_INTERVAL10*1000 /* 10 secs */ + +struct iplease { +uint32_tipl_ipaddr; +uint32_tipl_server; +struct virNWFilterSnoopReq *ipl_req; +unsigned intipl_timeout; +/* timer list */ +struct iplease *ipl_prev; +struct iplease *ipl_next; +}; + +static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); +static void ipl_update(struct iplease *pl, uint32_t timeout); + + +/* + * ipl_ladd -
[libvirt] [libvirt PATCHv4 2/2] add leasefile support
This patch adds support for saving DHCP snooping leases to an on-disk file and restoring saved leases that are still active on restart. Signed-off-by: David L Stevens --- src/nwfilter/nwfilter_dhcpsnoop.c | 312 - 1 files changed, 306 insertions(+), 6 deletions(-) diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c index b77e2b0..b2e6326 100644 --- a/src/nwfilter/nwfilter_dhcpsnoop.c +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -55,10 +55,18 @@ #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_dhcpsnoop.h" +#include "virfile.h" +#include "configmake.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER #ifdef HAVE_LIBPCAP + +#define LEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.leases" +#define TMPLEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.ltmp" +static int lease_fd = -1; +static int nleases = 0; /* number of active leases */ +static int wleases = 0; /* number of written leases */ static virHashTablePtr SnoopReqs; static pthread_mutex_t SnoopLock; @@ -97,7 +105,14 @@ struct iplease { static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); static void ipl_update(struct iplease *pl, uint32_t timeout); - + +static struct iflease *getiflease(const char *ifname); +static void lease_open(void); +static void lease_close(void); +static void lease_load(void); +static void lease_save(struct iplease *ipl); +static void lease_refresh(void); +static void lease_restore(struct virNWFilterSnoopReq *req); /* * ipl_ladd - add an IP lease to a list @@ -209,6 +224,8 @@ ipl_add(struct iplease *plnew) return; } ipl_tadd(pl); +nleases++; +lease_save(pl); } /* @@ -254,6 +271,7 @@ ipl_del(struct iplease *ipl) req = ipl->ipl_req; ipl_tdel(ipl); +lease_save(ipl); /* for multiple address support, this needs to remove those rules * referencing "IP" with ipl's ip value. @@ -262,6 +280,7 @@ ipl_del(struct iplease *ipl) virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "ipl_ldel failed"); } VIR_FREE(ipl); +nleases--; } /* @@ -273,6 +292,7 @@ ipl_update(struct iplease *ipl, uint32_t timeout) ipl_tdel(ipl); ipl->ipl_timeout = timeout; ipl_tadd(ipl); +lease_save(ipl); return; } @@ -289,8 +309,6 @@ ipl_getbyip(struct iplease *start, uint32_t ipaddr) return pl; } -#define GRACE 5 - /* * ipl_trun - run the IP lease timeout list */ @@ -484,6 +502,9 @@ snoopReqFree(struct virNWFilterSnoopReq *req) { struct iplease *ipl; +if (!req) +return; + /* free all leases */ snoop_lock(); for (ipl = req->start; ipl; ipl = req->start) @@ -514,6 +535,11 @@ virNWFilterDHCPSnoop(void *req0) handle = dhcpopen(req->ifname); if (!handle) return 0; + +/* restore any saved leases for this interface */ +snoop_lock(); +lease_restore(req); +snoop_unlock(); ifindex = if_nametoindex(req->ifname); @@ -637,6 +663,20 @@ freeReq(void *req0, const void *name ATTRIBUTE_UNUSED) req->die = 1; } +static void +lease_close(void) +{ +VIR_FORCE_CLOSE(lease_fd); +} + +static void +lease_open(void) +{ +lease_close(); + +lease_fd = open(LEASEFILE, O_CREAT|O_RDWR|O_APPEND, 0644); +} + int virNWFilterDHCPSnoopInit(void) { @@ -654,6 +694,8 @@ virNWFilterDHCPSnoopInit(void) virReportOOMError(); return -1; } +lease_load(); +lease_open(); snoop_unlock(); return 0; } @@ -666,13 +708,271 @@ virNWFilterDHCPSnoopEnd(const char *ifname) snoop_unlock(); return; } -if (ifname) -virHashRemoveEntry(SnoopReqs, ifname); -else/* free all of them */ +if (!ifname) { virHashFree(SnoopReqs); +lease_refresh(); +} else +virHashRemoveEntry(SnoopReqs, ifname); +lease_close(); snoop_unlock(); } + +/* lease file handling */ + +struct iflease { +char *ifl_ifname; +struct iplease *ifl_start; +struct iplease *ifl_end; +struct iflease *ifl_prev; +struct iflease *ifl_next; +}; + +struct iflease *leases; + +static int +lease_write(int lfd, const char *ifname, struct iplease *ipl) +{ +char lbuf[256],ipstr[16],dhcpstr[16]; + +if (inet_ntop(AF_INET, &ipl->ipl_ipaddr, ipstr, sizeof ipstr) == 0) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, + _("inet_ntop(0x%08X) failed"), ipl->ipl_ipaddr); +return -1; +} +if (inet_ntop(AF_INET, &ipl->ipl_server, dhcpstr, sizeof dhcpstr) == 0) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, + _("inet_ntop(0x%08X) failed"), ipl->ipl_server); +re
[libvirt] [libvirt PATCH] support continue/return targets in nwfilter
This patch adds support for "continue" and "return" actions in filter rules. Signed-off-by: David L Stevens diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 04bfa22..3e28806 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -55,12 +55,16 @@ VIR_ENUM_IMPL(virNWFilterRuleAction, VIR_NWFILTER_RULE_ACTION_LAST, "drop", "accept", - "reject"); + "reject", + "return", + "continue"); VIR_ENUM_IMPL(virNWFilterJumpTarget, VIR_NWFILTER_RULE_ACTION_LAST, "DROP", "ACCEPT", - "REJECT"); + "REJECT", + "RETURN", + "CONTINUE"); VIR_ENUM_IMPL(virNWFilterRuleDirection, VIR_NWFILTER_RULE_DIRECTION_LAST, "in", diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 5306403..c96851a 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -299,6 +299,8 @@ enum virNWFilterRuleActionType { VIR_NWFILTER_RULE_ACTION_DROP = 0, VIR_NWFILTER_RULE_ACTION_ACCEPT, VIR_NWFILTER_RULE_ACTION_REJECT, +VIR_NWFILTER_RULE_ACTION_RETURN, +VIR_NWFILTER_RULE_ACTION_CONTINUE, VIR_NWFILTER_RULE_ACTION_LAST, }; -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv3 02/10] allow required ARP packets
The ARP protocol requires processing of packets that may not be explicitly addressed to a host and only defines request and reply. This patch removes the filtering of ARP requests not explicitly addressed to a VM to allow for proper ARP cache updates for entries based on any traffic and removes the unnecessary check for arpop of request or reply. Signed-off-by: David L Stevens --- examples/xml/nwfilter/no-arp-spoofing.xml | 23 ++- 1 files changed, 2 insertions(+), 21 deletions(-) diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index 96c58c1..3c83acd 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -12,25 +12,6 @@ - - - - - - - - - - - - - - - - - - - - - + + -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv3 03/10] reverse sense of address matching
This patch changes rules of the form: if ! addr drop accept to: if addr return ... drop The patch adds a "mac" chain to do a mac address list and separates the "arp" chain into separate "arpmac" and "arpip" chains that can check multiple MAC or IP addresses in any combination. This patch itself does not support multiple addresses via the MAC and IP variables, but only changes the form of the rules to allow multiple addresses in the future. Signed-off-by: David L Stevens --- examples/xml/nwfilter/Makefile.am |4 ++ examples/xml/nwfilter/allow-arp.xml |5 ++- examples/xml/nwfilter/allow-arpip.xml |3 ++ examples/xml/nwfilter/allow-arpmac.xml|3 ++ examples/xml/nwfilter/clean-traffic.xml |6 ++-- examples/xml/nwfilter/no-arp-spoofing.xml | 19 ++ examples/xml/nwfilter/no-arpip-spoofing.xml | 12 ++ examples/xml/nwfilter/no-arpmac-spoofing.xml |7 examples/xml/nwfilter/no-ip-spoofing.xml |6 ++- examples/xml/nwfilter/no-mac-spoofing.xml | 12 -- examples/xml/nwfilter/no-other-l2-traffic.xml | 13 +-- src/conf/nwfilter_conf.c |4 ++- src/conf/nwfilter_conf.h |4 ++- src/nwfilter/nwfilter_ebiptables_driver.c | 48 +--- 14 files changed, 99 insertions(+), 47 deletions(-) create mode 100644 examples/xml/nwfilter/allow-arpip.xml create mode 100644 examples/xml/nwfilter/allow-arpmac.xml create mode 100644 examples/xml/nwfilter/no-arpip-spoofing.xml create mode 100644 examples/xml/nwfilter/no-arpmac-spoofing.xml diff --git a/examples/xml/nwfilter/Makefile.am b/examples/xml/nwfilter/Makefile.am index 23fd753..84aaa3c 100644 --- a/examples/xml/nwfilter/Makefile.am +++ b/examples/xml/nwfilter/Makefile.am @@ -3,12 +3,16 @@ FILTERS = \ allow-arp.xml \ + allow-arpip.xml \ + allow-arpmac.xml \ allow-dhcp-server.xml \ allow-dhcp.xml \ allow-incoming-ipv4.xml \ allow-ipv4.xml \ clean-traffic.xml \ no-arp-spoofing.xml \ + no-arpmac-spoofing.xml \ + no-arpip-spoofing.xml \ no-ip-multicast.xml \ no-ip-spoofing.xml \ no-mac-broadcast.xml \ diff --git a/examples/xml/nwfilter/allow-arp.xml b/examples/xml/nwfilter/allow-arp.xml index 63a92b2..6271ae4 100644 --- a/examples/xml/nwfilter/allow-arp.xml +++ b/examples/xml/nwfilter/allow-arp.xml @@ -1,3 +1,4 @@ - - + + + diff --git a/examples/xml/nwfilter/allow-arpip.xml b/examples/xml/nwfilter/allow-arpip.xml new file mode 100644 index 000..6ddb6fe --- /dev/null +++ b/examples/xml/nwfilter/allow-arpip.xml @@ -0,0 +1,3 @@ + + + diff --git a/examples/xml/nwfilter/allow-arpmac.xml b/examples/xml/nwfilter/allow-arpmac.xml new file mode 100644 index 000..54f6714 --- /dev/null +++ b/examples/xml/nwfilter/allow-arpmac.xml @@ -0,0 +1,3 @@ + + + diff --git a/examples/xml/nwfilter/clean-traffic.xml b/examples/xml/nwfilter/clean-traffic.xml index 40f0ecb..9cee799 100644 --- a/examples/xml/nwfilter/clean-traffic.xml +++ b/examples/xml/nwfilter/clean-traffic.xml @@ -11,10 +11,10 @@ - - - + + + diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index 3c83acd..1979b20 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -1,17 +1,4 @@ - - f88f1932-debf-4aa1-9fbe-f10d3aa4bc95 - - - - - - - - - - - - - - + + + diff --git a/examples/xml/nwfilter/no-arpip-spoofing.xml b/examples/xml/nwfilter/no-arpip-spoofing.xml new file mode 100644 index 000..ee42d40 --- /dev/null +++ b/examples/xml/nwfilter/no-arpip-spoofing.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/examples/xml/nwfilter/no-arpmac-spoofing.xml b/examples/xml/nwfilter/no-arpmac-spoofing.xml new file mode 100644 index 000..90499d3 --- /dev/null +++ b/examples/xml/nwfilter/no-arpmac-spoofing.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index b8c94c8..84e8a5e 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -1,7 +1,9 @@ - - + + + + diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/examples/xml/nwfilter/no-mac-spoofing.xml index f210623..aee56c7 100644 --- a/examples/xml/nwfilter/no-mac-spoofing.xml +++ b/examples/xml/nwfilter/no-mac-spoofing.xml @@ -1,5 +1,9 @@ - - - - + + + + + + + + diff --git a/examples/xml/nwfilter/no-other-l2-traffic.xml b/examples/xml/nwfilter/no-other-l2-traffic.xml index 8bad86e..0501b1a 100644 --- a/examp
[libvirt] [libvirt PATCHv3 09/10] add leasefile support
This patch adds support for saving DHCP snooping leases to an on-disk file and restoring saved leases that are still active on restart. Signed-off-by: David L Stevens --- src/nwfilter/nwfilter_dhcpsnoop.c | 370 +++-- 1 files changed, 353 insertions(+), 17 deletions(-) diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c index f784a29..eedf550 100644 --- a/src/nwfilter/nwfilter_dhcpsnoop.c +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -56,10 +56,21 @@ #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_dhcpsnoop.h" +#include "configmake.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER +#define LEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.leases" +#define TMPLEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.ltmp" +static int lease_fd = -1; +static int nleases = 0; /* number of active leases */ +static int wleases = 0; /* number of written leases */ + static virHashTablePtr SnoopReqs; +static pthread_mutex_t SnoopLock; + +#define snoop_lock(){ pthread_mutex_lock(&SnoopLock); } +#define snoop_unlock() { pthread_mutex_unlock(&SnoopLock); } struct virNWFilterSnoopReq { virConnectPtr conn; @@ -90,7 +101,14 @@ struct iplease { static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); static void ipl_update(struct iplease *pl, uint32_t timeout); - + +static struct iflease *getiflease(const char *ifname); +static void lease_open(void); +static void lease_close(void); +static void lease_load(void); +static void lease_save(struct iplease *ipl); +static void lease_refresh(void); +static void lease_restore(struct virNWFilterSnoopReq *req); /* * ipl_ladd - add an IP lease to a list @@ -150,6 +168,7 @@ ipl_add(struct iplease *plnew) ipl_update(pl, plnew->ipl_timeout); return; } +nleases++; if (VIR_ALLOC(pl) < 0) { virReportOOMError(); return; @@ -184,6 +203,7 @@ ipl_add(struct iplease *plnew) return; } ipl_tadd(pl); +lease_save(pl); } /* @@ -231,6 +251,7 @@ ipl_del(struct iplease *ipl) req = ipl->ipl_req; ipl_tdel(ipl); +lease_save(ipl); if (inet_ntop(AF_INET, &ipl->ipl_ipaddr, ipbuf, sizeof(ipbuf))) { ipstr = strdup(ipbuf); @@ -248,6 +269,7 @@ ipl_del(struct iplease *ipl) _("ipl_del inet_ntop " "failed (0x%08X)"), ipl->ipl_ipaddr); VIR_FREE(ipl); +nleases--; } /* @@ -259,6 +281,7 @@ ipl_update(struct iplease *ipl, uint32_t timeout) ipl_tdel(ipl); ipl->ipl_timeout = timeout; ipl_tadd(ipl); +lease_save(ipl); return; } @@ -275,8 +298,6 @@ ipl_getbyip(struct iplease *start, uint32_t ipaddr) return pl; } -#define GRACE 5 - /* * ipl_trun - run the IP lease timeout list */ @@ -465,6 +486,19 @@ dhcpopen(const char *intf) return handle; } +/* + * snoopReqFree - release a snoop Req + */ +static void +snoopReqFree(struct virNWFilterSnoopReq *req) +{ +if (req->ifname) +VIR_FREE(req->ifname); +if (req->vars) +virNWFilterHashTableFree(req->vars); +VIR_FREE(req); +} + static void * virNWFilterDHCPSnoop(void *req0) { @@ -479,12 +513,19 @@ virNWFilterDHCPSnoop(void *req0) if (!handle) return 0; +/* restore any saved leases for this interface */ +snoop_lock(); +lease_restore(req); +snoop_unlock(); + ifindex = if_nametoindex(req->ifname); while (1) { if (req->die) break; +snoop_lock(); ipl_trun(req); +snoop_unlock(); packet = (struct eth *) pcap_next(handle, &hdr); @@ -494,16 +535,18 @@ virNWFilterDHCPSnoop(void *req0) continue; } +snoop_lock(); dhcpdecode(req, packet, hdr.caplen); +snoop_unlock(); } + +snoop_lock(); /* free all leases */ for (ipl = req->start; ipl; ipl = req->start) ipl_del(ipl); +snoop_unlock(); -/* free all req data */ -VIR_FREE(req->ifname); -virNWFilterHashTableFree(req->vars); -VIR_FREE(req); +snoopReqFree(req); return 0; } @@ -518,9 +561,12 @@ virNWFilterDHCPSnoopReq(virConnectPtr conn, { struct virNWFilterSnoopReq *req; +snoop_lock(); req = virHashLookup(SnoopReqs, ifname); -if (req) +snoop_unlock(); +if (req) { return 0; +} if (VIR_ALLOC(req) < 0) { virReportOOMError(); return 1; @@ -533,28 +579,30 @@ virNWFilterDHCPSnoopReq(virConnectPtr conn, req->ifname = strdup(ifname); req->vars = virNWFilterHashTableCreate(0); if (!req->vars) { +snoopReqFree(req); v
[libvirt] [libvirt PATCHv3 00/10] DHCP snooping support for libvirt
This series of patches adds DHCP snooping support to libvirt. This version saves leases on disk for restoration after a libvirtd restart and allows selection of different ip_learning methods by setting filter parameter "ip_learning" to one of "any" (existing IP learning code) "none" (static only addresses) or "DHCP" (DHCP Snooping). This code does not (yet) support passing lease information across a migration. A migrated guest requires a DHCP ACK (e.g., via ifdown/ifup on the guest) to send/receive traffic for DHCP-learned addresses after a migration. Differences from v2: added support for multiple static IP addresses using a comma-separated list. David L Stevens (10): support continue/return allow required ARP packets reverse sense of address matching make default chain policy "DROP" allow chain modification support addRules support variable value changing add DHCP snooping add leasefile support support multiple static IP addresses examples/xml/nwfilter/Makefile.am |5 +- examples/xml/nwfilter/allow-arp.xml |5 +- examples/xml/nwfilter/allow-arpip.xml |3 + examples/xml/nwfilter/allow-arpmac.xml |3 + examples/xml/nwfilter/clean-traffic.xml |6 +- examples/xml/nwfilter/no-arp-spoofing.xml | 38 +- examples/xml/nwfilter/no-arpip-spoofing.xml | 10 + examples/xml/nwfilter/no-arpmac-spoofing.xml|5 + examples/xml/nwfilter/no-ip-spoofing.xml|9 +- examples/xml/nwfilter/no-mac-spoofing.xml | 10 +- examples/xml/nwfilter/no-other-l2-traffic.xml | 13 +- examples/xml/nwfilter/no-other-rarp-traffic.xml |3 - examples/xml/nwfilter/qemu-announce-self.xml|1 - src/Makefile.am |2 + src/conf/nwfilter_conf.c| 12 +- src/conf/nwfilter_conf.h| 16 +- src/nwfilter/nwfilter_dhcpsnoop.c | 938 +++ src/nwfilter/nwfilter_dhcpsnoop.h | 36 + src/nwfilter/nwfilter_driver.c |5 + src/nwfilter/nwfilter_ebiptables_driver.c | 225 +-- src/nwfilter/nwfilter_gentech_driver.c | 225 +- src/nwfilter/nwfilter_gentech_driver.h | 11 + 22 files changed, 1445 insertions(+), 136 deletions(-) create mode 100644 examples/xml/nwfilter/allow-arpip.xml create mode 100644 examples/xml/nwfilter/allow-arpmac.xml create mode 100644 examples/xml/nwfilter/no-arpip-spoofing.xml create mode 100644 examples/xml/nwfilter/no-arpmac-spoofing.xml delete mode 100644 examples/xml/nwfilter/no-other-rarp-traffic.xml create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv3 06/10] support addRules
This patch adds the capability of adding individual rules to existing chains. Signed-off-by: David L Stevens --- src/conf/nwfilter_conf.h |6 ++ src/nwfilter/nwfilter_ebiptables_driver.c | 73 + 2 files changed, 79 insertions(+), 0 deletions(-) diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 4348378..12d1e0f 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -540,6 +540,11 @@ typedef int (*virNWFilterRuleTeardownNewRules)(virConnectPtr conn, typedef int (*virNWFilterRuleTeardownOldRules)(virConnectPtr conn, const char *ifname); +typedef int (*virNWFilterRuleAddRules)(virConnectPtr conn, + const char *ifname, + int nruleInstances, + void **_inst); + typedef int (*virNWFilterRuleRemoveRules)(virConnectPtr conn, const char *ifname, int nruleInstances, @@ -580,6 +585,7 @@ struct _virNWFilterTechDriver { virNWFilterRuleApplyNewRules applyNewRules; virNWFilterRuleTeardownNewRules tearNewRules; virNWFilterRuleTeardownOldRules tearOldRules; +virNWFilterRuleAddRules addRules; virNWFilterRuleRemoveRules removeRules; virNWFilterRuleAllTeardown allTeardown; virNWFilterRuleFreeInstanceData freeRuleInstance; diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 918625c..1169e5a 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -3695,6 +3695,78 @@ err_exit: return rc; } +/** + * ebiptablesAddRules: + * @conn : pointer to virConnect object + * @ifname : the name of the interface to which the rules apply + * @nRuleInstance : the number of given rules + * @_inst : array of rule instantiation data + * + * Add all rules one after the other + * + * Return 0 on success, 1 if execution of one or more cleanup + * commands failed. + */ +static int +ebiptablesAddRules(virConnectPtr conn, + const char *ifname, + int nruleInstances, + void **_inst) +{ +int i; +int cli_status; +ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst; +virBuffer buf = VIR_BUFFER_INITIALIZER; +bool haveIptables = false; +bool haveIp6tables = false; + +for (i = 0; i < nruleInstances; i++) { +sa_assert (inst); +switch (inst[i]->ruleType) { +case RT_EBTABLES: +ebiptablesInstCommand(&buf, + inst[i]->commandTemplate, + 'A', -1, 1); +break; +case RT_IPTABLES: +if (inst[i]->ruleType == RT_IPTABLES) +iptablesInstCommand(&buf, +inst[i]->commandTemplate, +'A', -1, 1); +haveIptables = true; +break; +case RT_IP6TABLES: +if (inst[i]->ruleType == RT_IP6TABLES) +iptablesInstCommand(&buf, +inst[i]->commandTemplate, +'A', -1, 1); +haveIp6tables = true; +break; +} +} + +if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0) +goto err_exit; + +if (haveIptables) +iptablesCheckBridgeNFCallEnabled(false); + +if (haveIp6tables) +iptablesCheckBridgeNFCallEnabled(true); + +return 0; + +err_exit: +(void) ebiptablesRemoveRules(conn, ifname, nruleInstances, _inst); + +virNWFilterReportError(VIR_ERR_BUILD_FIREWALL, + _("Some rules could not be created for " + "interface %s."), + ifname); + +return 1; +} + /** * ebiptablesAllTeardown: @@ -3751,6 +3823,7 @@ virNWFilterTechDriver ebiptables_driver = { .tearNewRules= ebiptablesTearNewRules, .tearOldRules= ebiptablesTearOldRules, .allTeardown = ebiptablesAllTeardown, +.addRules= ebiptablesAddRules, .removeRules = ebiptablesRemoveRules, .freeRuleInstance= ebiptablesFreeRuleInstance, .displayRuleInstance = ebiptablesDisplayRuleInstance, -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv3 10/10] support multiple static IP addresses
This patch adds support for multiple static IP addresses in a comma-separated list. For example: ... Signed-off-by: David L Stevens --- src/nwfilter/nwfilter_gentech_driver.c | 26 ++ 1 files changed, 26 insertions(+), 0 deletions(-) diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 577b48d..8f74a01 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -920,6 +920,8 @@ __virNWFilterInstantiateFilter(virConnectPtr conn, char *str_macaddr = NULL; const char *ipaddr; char *str_ipaddr = NULL; +char *ipaddrlist = NULL; +char *sep; techdriver = virNWFilterTechDriverForName(drvname); @@ -983,6 +985,17 @@ __virNWFilterInstantiateFilter(virConnectPtr conn, goto err_exit_vars1; } +ipaddr = virHashLookup(filterparams->hashTable, NWFILTER_STD_VAR_IP); +if (ipaddr) { +sep = strchr(ipaddr, ','); +if (sep) { +str_ipaddr = strndup(ipaddr, sep-ipaddr); +ipaddrlist = strdup(sep + 1); +virNWFilterHashTablePut(vars, NWFILTER_STD_VAR_IP, str_ipaddr, 1); +} +} +str_ipaddr = NULL; + filter = obj->def; switch (useNewFilter) { @@ -1011,6 +1024,19 @@ __virNWFilterInstantiateFilter(virConnectPtr conn, driver, forceWithPendingReq); +/* add the rest of the IP list */ +for (ipaddr = ipaddrlist; ipaddr; ipaddr = sep) { +sep = strchr(ipaddr, ','); +if (sep) { +str_ipaddr = strndup(ipaddr, sep-ipaddr); +sep++; /* skip ',' */ +} else +str_ipaddr = strdup(ipaddr); +virNWFilterChangeVar(conn, techdriver, nettype, filter, ifname, vars, + driver, NWFILTER_STD_VAR_IP, str_ipaddr, 0); + +} +str_ipaddr = NULL; virNWFilterHashTableFree(vars); err_exit_vars1: -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv3 05/10] allow chain modification
This patch adds the internal capability to add rules to existing chains instead of using temporary chains and to generate placeholders for chains that are referenced without generating a rule for them immediately. Finally, it includes variable matching for filter instantiation (i.e., instantiate only when a given variable is present in a filter, or only when it is not). Signed-off-by: David L Stevens --- src/conf/nwfilter_conf.h |4 +- src/nwfilter/nwfilter_ebiptables_driver.c | 93 + src/nwfilter/nwfilter_gentech_driver.c| 32 +- 3 files changed, 100 insertions(+), 29 deletions(-) diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 17e954e..4348378 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -525,7 +525,9 @@ typedef int (*virNWFilterRuleCreateInstance)(virConnectPtr conn, virNWFilterRuleDefPtr rule, const char *ifname, virNWFilterHashTablePtr vars, - virNWFilterRuleInstPtr res); + virNWFilterRuleInstPtr res, + bool usetemp, + bool dummy); typedef int (*virNWFilterRuleApplyNewRules)(virConnectPtr conn, const char *ifname, diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index e6a4880..918625c 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -1136,6 +1136,7 @@ iptablesEnforceDirection(int directionIn, * @isIPv6 : Whether this is an IPv6 rule * @maySkipICMP : whether this rule may under certain circumstances skip * the ICMP rule from being created + * @dummy : generate rule placeholder without installing * * Convert a single rule into its representation for later instantiation * @@ -1154,7 +1155,8 @@ _iptablesCreateRuleInstance(int directionIn, const char *match, bool defMatch, const char *accept_target, bool isIPv6, -bool maySkipICMP) +bool maySkipICMP, +bool dummy) { char chain[MAX_CHAINNAME_LENGTH]; char number[20]; @@ -1181,6 +1183,13 @@ _iptablesCreateRuleInstance(int directionIn, PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); +if (dummy) { +virBufferAsprintf(&buf, CMD_DEF_PRE "%s -- %s -%%c %s %%s", + "echo", iptables_cmd, chain); +bufUsed = virBufferUse(&buf); +goto prskip; +} + switch (rule->prtclType) { case VIR_NWFILTER_RULE_PROTOCOL_TCP: case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: @@ -1521,6 +1530,8 @@ _iptablesCreateRuleInstance(int directionIn, return -1; } +prskip: + if ((srcMacSkipped && bufUsed == virBufferUse(&buf)) || skipRule) { virBufferFreeAndReset(&buf); @@ -1636,7 +1647,9 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, const char *ifname, virNWFilterHashTablePtr vars, virNWFilterRuleInstPtr res, -bool isIPv6) +bool isIPv6, +bool usetemp, +bool dummy) { int rc; int directionIn = 0; @@ -1668,7 +1681,7 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, return 1; } -chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP; +chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_IN; if (create) { rc = _iptablesCreateRuleInstance(directionIn, chainPrefix, @@ -1680,7 +1693,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, matchState, false, "RETURN", isIPv6, - maySkipICMP); + maySkipICMP, + dummy); VIR_FREE(matchState); if (rc) @@ -1700,7 +1714,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, return 1; } -chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP; +chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_OUT_TEMP : + CHAINPREFIX_HOST_OUT; if (create) { rc = _iptablesCreateRuleInstance(!direction
[libvirt] [libvirt PATCHv3 04/10] make default chain policy "DROP"
This patch simplifies the table rules by setting the protocol chains policy to be "DROP" and removes the explicit "-j DROP" entries that the protocol rules had previously. It also makes "no-other-rarp-traffic.xml" obsolete. Signed-off-by: David L Stevens --- examples/xml/nwfilter/Makefile.am |1 - examples/xml/nwfilter/no-arpip-spoofing.xml |2 -- examples/xml/nwfilter/no-arpmac-spoofing.xml|2 -- examples/xml/nwfilter/no-ip-spoofing.xml|2 -- examples/xml/nwfilter/no-mac-spoofing.xml |2 -- examples/xml/nwfilter/no-other-rarp-traffic.xml |3 --- examples/xml/nwfilter/qemu-announce-self.xml|1 - src/nwfilter/nwfilter_ebiptables_driver.c | 11 +-- 8 files changed, 1 insertions(+), 23 deletions(-) delete mode 100644 examples/xml/nwfilter/no-other-rarp-traffic.xml diff --git a/examples/xml/nwfilter/Makefile.am b/examples/xml/nwfilter/Makefile.am index 84aaa3c..67085fa 100644 --- a/examples/xml/nwfilter/Makefile.am +++ b/examples/xml/nwfilter/Makefile.am @@ -18,7 +18,6 @@ FILTERS = \ no-mac-broadcast.xml \ no-mac-spoofing.xml \ no-other-l2-traffic.xml \ - no-other-rarp-traffic.xml \ qemu-announce-self.xml \ qemu-announce-self-rarp.xml diff --git a/examples/xml/nwfilter/no-arpip-spoofing.xml b/examples/xml/nwfilter/no-arpip-spoofing.xml index ee42d40..7ef6f0f 100644 --- a/examples/xml/nwfilter/no-arpip-spoofing.xml +++ b/examples/xml/nwfilter/no-arpip-spoofing.xml @@ -7,6 +7,4 @@ - - diff --git a/examples/xml/nwfilter/no-arpmac-spoofing.xml b/examples/xml/nwfilter/no-arpmac-spoofing.xml index 90499d3..3834047 100644 --- a/examples/xml/nwfilter/no-arpmac-spoofing.xml +++ b/examples/xml/nwfilter/no-arpmac-spoofing.xml @@ -2,6 +2,4 @@ - - diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index 84e8a5e..2fccd12 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,6 +4,4 @@ - - diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/examples/xml/nwfilter/no-mac-spoofing.xml index aee56c7..e2e8c03 100644 --- a/examples/xml/nwfilter/no-mac-spoofing.xml +++ b/examples/xml/nwfilter/no-mac-spoofing.xml @@ -4,6 +4,4 @@ - - diff --git a/examples/xml/nwfilter/no-other-rarp-traffic.xml b/examples/xml/nwfilter/no-other-rarp-traffic.xml deleted file mode 100644 index 7729996..000 --- a/examples/xml/nwfilter/no-other-rarp-traffic.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/examples/xml/nwfilter/qemu-announce-self.xml b/examples/xml/nwfilter/qemu-announce-self.xml index 352db50..12957b5 100644 --- a/examples/xml/nwfilter/qemu-announce-self.xml +++ b/examples/xml/nwfilter/qemu-announce-self.xml @@ -8,6 +8,5 @@ - diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 3c6fca7..e6a4880 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -2791,7 +2791,7 @@ ebtablesCreateTmpSubChain(virBufferPtr buf, protostr[0] = '\0'; virBufferAsprintf(buf, - CMD_DEF("%s -t %s -N %s") CMD_SEPARATOR + CMD_DEF("%s -t %s -N %s -P DROP") CMD_SEPARATOR CMD_EXEC "%s" CMD_DEF("%s -t %s -A %s %s -j %s") CMD_SEPARATOR @@ -3015,15 +3015,6 @@ ebtablesApplyBasicRules(const char *ifname, PRINT_ROOT_CHAIN(chain, chainPrefix, ifname); virBufferAsprintf(&buf, - CMD_DEF("%s -t %s -A %s -s ! %s -j DROP") CMD_SEPARATOR - CMD_EXEC - "%s", - - ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, - chain, macaddr_str, - CMD_STOPONERR(1)); - -virBufferAsprintf(&buf, CMD_DEF("%s -t %s -A %s -p IPv4 -j ACCEPT") CMD_SEPARATOR CMD_EXEC "%s", -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv3 07/10] support variable value changing
This patch adds a function that applies or deletes filter rules to existing chains. Rules referencing the given variable are instantiated with the given value, or optionally deleted. For example, passing variable "IP" with different values will install rules using the IP variable with each of the different values. These rules can later be removed by calling this function with the same variable and value and "delete" argument set to "1". Signed-off-by: David L Stevens --- src/nwfilter/nwfilter_gentech_driver.c | 86 src/nwfilter/nwfilter_gentech_driver.h | 11 2 files changed, 97 insertions(+), 0 deletions(-) diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 79350ac..563a1f3 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -620,6 +620,92 @@ virNWFilterRuleInstancesToArray(int nEntries, /** + * virNWFilterChangeVar: + * @conn: pointer to virConnect object + * @techdriver: The driver to use for instantiation + * @filter: The filter to instantiate + * @ifname: The name of the interface to apply the rules to + * @vars: A map holding variable names and values used for instantiating + * the filter and its subfilters. + * @var: name of variable to change + * @value: value of variable to change + * @delete: =0 to create or =1 to delete the rules + * + * Returns 0 on success, a value otherwise. + * + * Instantiate or delete a filter and all subfilters with variable "var" + * set to value "value". + * The name of the interface to which the rules belong must be + * provided. + * + * Call this function while holding the NWFilter filter update lock + */ +int +virNWFilterChangeVar(virConnectPtr conn, +virNWFilterTechDriverPtr techdriver, +enum virDomainNetType nettype, +virNWFilterDefPtr filter, +const char *ifname, +virNWFilterHashTablePtr vars, +virNWFilterDriverStatePtr driver, +const char *var, +char *value, +bool delete) +{ +int rc; +int j, nptrs; +int nEntries = 0; +virNWFilterRuleInstPtr *insts = NULL; +void **ptrs = NULL; +bool foundNewFilter = 0; + +if (virNWFilterHashTablePut(vars, var, value, 1)) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Cound not add " + "variable \"%s\" to hashmap"), var); +return 1; +} +rc = _virNWFilterInstantiateRec(conn, +techdriver, +nettype, +filter, +ifname, +vars, +NWFILTER_STD_VAR_IP, 0, +&nEntries, &insts, +INSTANTIATE_ALWAYS, &foundNewFilter, +driver); + if (rc) + goto err_exit; + rc = virNWFilterRuleInstancesToArray(nEntries, insts, &ptrs, &nptrs); + if (rc) + goto err_exit; + +if (virNWFilterHashTableRemoveEntry(vars, var) < 0) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Could not remove " + "variable \"%s\" from hashmap"), var); +return 1; +} + +if (virNWFilterLockIface(ifname)) + goto err_exit; + + if (delete) + rc = techdriver->removeRules(conn, ifname, nptrs, ptrs); + else + rc = techdriver->addRules(conn, ifname, nptrs, ptrs); + virNWFilterUnlockIface(ifname); + VIR_FREE(ptrs); + +err_exit: + +for (j = 0; j < nEntries; j++) + virNWFilterRuleInstFree(insts[j]); +VIR_FREE(insts); +return rc; +} + + +/** * virNWFilterInstantiate: * @conn: pointer to virConnect object * @techdriver: The driver to use for instantiation diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h index fa86030..34e95c7 100644 --- a/src/nwfilter/nwfilter_gentech_driver.h +++ b/src/nwfilter/nwfilter_gentech_driver.h @@ -48,6 +48,17 @@ int virNWFilterRollbackUpdateFilter(virConnectPtr conn, int virNWFilterTearOldFilter(virConnectPtr conn, const virDomainNetDefPtr net); +int virNWFilterChangeVar(virConnectPtr conn, +virNWFilterTechDriverPtr techdriver, +enum virDomainNetType nettype, +virNWFilterDefPtr filter, +const char *ifname, +virNWFilterHashTablePtr vars, +virNWFilterDriverStatePtr driver, +const char *var, +char *value, +
[libvirt] [libvirt PATCHv3 01/10] support continue/return
This patch adds support for "continue" and "return" actions in filter rules. Signed-off-by: David L Stevens --- src/conf/nwfilter_conf.c |8 ++-- src/conf/nwfilter_conf.h |2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 08ede48..e0c2fb6 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -55,12 +55,16 @@ VIR_ENUM_IMPL(virNWFilterRuleAction, VIR_NWFILTER_RULE_ACTION_LAST, "drop", "accept", - "reject"); + "reject", + "return", + "continue"); VIR_ENUM_IMPL(virNWFilterJumpTarget, VIR_NWFILTER_RULE_ACTION_LAST, "DROP", "ACCEPT", - "REJECT"); + "REJECT", + "RETURN", + "CONTINUE"); VIR_ENUM_IMPL(virNWFilterRuleDirection, VIR_NWFILTER_RULE_DIRECTION_LAST, "in", diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 5306403..c96851a 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -299,6 +299,8 @@ enum virNWFilterRuleActionType { VIR_NWFILTER_RULE_ACTION_DROP = 0, VIR_NWFILTER_RULE_ACTION_ACCEPT, VIR_NWFILTER_RULE_ACTION_REJECT, +VIR_NWFILTER_RULE_ACTION_RETURN, +VIR_NWFILTER_RULE_ACTION_CONTINUE, VIR_NWFILTER_RULE_ACTION_LAST, }; -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt PATCHv3 08/10] add DHCP snooping
This patch adds DHCP Snooping support to libvirt. Signed-off-by: David L Stevens --- examples/xml/nwfilter/no-ip-spoofing.xml |5 + src/Makefile.am |2 + src/nwfilter/nwfilter_dhcpsnoop.c| 602 ++ src/nwfilter/nwfilter_dhcpsnoop.h| 36 ++ src/nwfilter/nwfilter_driver.c |5 + src/nwfilter/nwfilter_gentech_driver.c | 83 +++-- 6 files changed, 708 insertions(+), 25 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index 2fccd12..2ae9500 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,4 +4,9 @@ + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 738ee91..f6d3fdd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -473,6 +473,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..f784a29 --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,602 @@ + +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_LIBPCAP +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "datatypes.h" +#include "interface.h" +#include "virterror_internal.h" +#include "threads.h" +#include "conf/nwfilter_params.h" +#include "conf/domain_conf.h" +#include "nwfilter_gentech_driver.h" +#include "nwfilter_ebiptables_driver.h" +#include "nwfilter_dhcpsnoop.h" + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +static virHashTablePtr SnoopReqs; + +struct virNWFilterSnoopReq { +virConnectPtr conn; +virNWFilterTechDriverPtr techdriver; +enum virDomainNetType nettype; +virNWFilterDefPtr filter; +const char *ifname; +virNWFilterHashTablePtr vars; +virNWFilterDriverStatePtr driver; +pthread_t thread; +/* start and end of lease list, ordered by lease time */ +struct iplease *start; +struct iplease *end; +bool die; +}; + +#define POLL_INTERVAL10*1000 /* 10 secs */ + +struct iplease { +uint32_tipl_ipaddr; +uint32_tipl_server; +struct virNWFilterSnoopReq *ipl_req; +unsigned intipl_timeout; +/* timer list */ +struct iplease *ipl_prev; +struct iplease *ipl_next; +}; + +static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); +static void ipl_update(struct iplease *pl, uint32_t timeout); + + +/* + * ipl_ladd - add an IP lease to a list + */ +static void +ipl_ladd(struct iplease *plnew, struct iplease **start, struct iplease **end) +{ +struct iplease *pl; + +plnew->ipl_next = plnew->ipl_prev = 0; +if (!*start) { +plnew->ipl_prev = plnew->ipl_next = 0; +
[libvirt] [RFC PATCHv2 9/9] add leasefile support
This patch adds support for saving DHCP snooping leases to an on-disk file and restoring saved leases that are still active on restart. Signed-off-by: David L Stevens --- src/nwfilter/nwfilter_dhcpsnoop.c | 370 +++-- 1 files changed, 353 insertions(+), 17 deletions(-) diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c index f784a29..eedf550 100644 --- a/src/nwfilter/nwfilter_dhcpsnoop.c +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -56,10 +56,21 @@ #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_dhcpsnoop.h" +#include "configmake.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER +#define LEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.leases" +#define TMPLEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.ltmp" +static int lease_fd = -1; +static int nleases = 0; /* number of active leases */ +static int wleases = 0; /* number of written leases */ + static virHashTablePtr SnoopReqs; +static pthread_mutex_t SnoopLock; + +#define snoop_lock(){ pthread_mutex_lock(&SnoopLock); } +#define snoop_unlock() { pthread_mutex_unlock(&SnoopLock); } struct virNWFilterSnoopReq { virConnectPtr conn; @@ -90,7 +101,14 @@ struct iplease { static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); static void ipl_update(struct iplease *pl, uint32_t timeout); - + +static struct iflease *getiflease(const char *ifname); +static void lease_open(void); +static void lease_close(void); +static void lease_load(void); +static void lease_save(struct iplease *ipl); +static void lease_refresh(void); +static void lease_restore(struct virNWFilterSnoopReq *req); /* * ipl_ladd - add an IP lease to a list @@ -150,6 +168,7 @@ ipl_add(struct iplease *plnew) ipl_update(pl, plnew->ipl_timeout); return; } +nleases++; if (VIR_ALLOC(pl) < 0) { virReportOOMError(); return; @@ -184,6 +203,7 @@ ipl_add(struct iplease *plnew) return; } ipl_tadd(pl); +lease_save(pl); } /* @@ -231,6 +251,7 @@ ipl_del(struct iplease *ipl) req = ipl->ipl_req; ipl_tdel(ipl); +lease_save(ipl); if (inet_ntop(AF_INET, &ipl->ipl_ipaddr, ipbuf, sizeof(ipbuf))) { ipstr = strdup(ipbuf); @@ -248,6 +269,7 @@ ipl_del(struct iplease *ipl) _("ipl_del inet_ntop " "failed (0x%08X)"), ipl->ipl_ipaddr); VIR_FREE(ipl); +nleases--; } /* @@ -259,6 +281,7 @@ ipl_update(struct iplease *ipl, uint32_t timeout) ipl_tdel(ipl); ipl->ipl_timeout = timeout; ipl_tadd(ipl); +lease_save(ipl); return; } @@ -275,8 +298,6 @@ ipl_getbyip(struct iplease *start, uint32_t ipaddr) return pl; } -#define GRACE 5 - /* * ipl_trun - run the IP lease timeout list */ @@ -465,6 +486,19 @@ dhcpopen(const char *intf) return handle; } +/* + * snoopReqFree - release a snoop Req + */ +static void +snoopReqFree(struct virNWFilterSnoopReq *req) +{ +if (req->ifname) +VIR_FREE(req->ifname); +if (req->vars) +virNWFilterHashTableFree(req->vars); +VIR_FREE(req); +} + static void * virNWFilterDHCPSnoop(void *req0) { @@ -479,12 +513,19 @@ virNWFilterDHCPSnoop(void *req0) if (!handle) return 0; +/* restore any saved leases for this interface */ +snoop_lock(); +lease_restore(req); +snoop_unlock(); + ifindex = if_nametoindex(req->ifname); while (1) { if (req->die) break; +snoop_lock(); ipl_trun(req); +snoop_unlock(); packet = (struct eth *) pcap_next(handle, &hdr); @@ -494,16 +535,18 @@ virNWFilterDHCPSnoop(void *req0) continue; } +snoop_lock(); dhcpdecode(req, packet, hdr.caplen); +snoop_unlock(); } + +snoop_lock(); /* free all leases */ for (ipl = req->start; ipl; ipl = req->start) ipl_del(ipl); +snoop_unlock(); -/* free all req data */ -VIR_FREE(req->ifname); -virNWFilterHashTableFree(req->vars); -VIR_FREE(req); +snoopReqFree(req); return 0; } @@ -518,9 +561,12 @@ virNWFilterDHCPSnoopReq(virConnectPtr conn, { struct virNWFilterSnoopReq *req; +snoop_lock(); req = virHashLookup(SnoopReqs, ifname); -if (req) +snoop_unlock(); +if (req) { return 0; +} if (VIR_ALLOC(req) < 0) { virReportOOMError(); return 1; @@ -533,28 +579,30 @@ virNWFilterDHCPSnoopReq(virConnectPtr conn, req->ifname = strdup(ifname); req->vars = virNWFilterHashTableCreate(0); if (!req->vars) { +snoopReqFree(req); v
[libvirt] [RFC PATCHv2 6/9] support addRules
This patch adds the capability of adding individual rules to existing chains. Signed-off-by: David L Stevens --- src/conf/nwfilter_conf.h |6 ++ src/nwfilter/nwfilter_ebiptables_driver.c | 73 + 2 files changed, 79 insertions(+), 0 deletions(-) diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 4348378..12d1e0f 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -540,6 +540,11 @@ typedef int (*virNWFilterRuleTeardownNewRules)(virConnectPtr conn, typedef int (*virNWFilterRuleTeardownOldRules)(virConnectPtr conn, const char *ifname); +typedef int (*virNWFilterRuleAddRules)(virConnectPtr conn, + const char *ifname, + int nruleInstances, + void **_inst); + typedef int (*virNWFilterRuleRemoveRules)(virConnectPtr conn, const char *ifname, int nruleInstances, @@ -580,6 +585,7 @@ struct _virNWFilterTechDriver { virNWFilterRuleApplyNewRules applyNewRules; virNWFilterRuleTeardownNewRules tearNewRules; virNWFilterRuleTeardownOldRules tearOldRules; +virNWFilterRuleAddRules addRules; virNWFilterRuleRemoveRules removeRules; virNWFilterRuleAllTeardown allTeardown; virNWFilterRuleFreeInstanceData freeRuleInstance; diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 918625c..1169e5a 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -3695,6 +3695,78 @@ err_exit: return rc; } +/** + * ebiptablesAddRules: + * @conn : pointer to virConnect object + * @ifname : the name of the interface to which the rules apply + * @nRuleInstance : the number of given rules + * @_inst : array of rule instantiation data + * + * Add all rules one after the other + * + * Return 0 on success, 1 if execution of one or more cleanup + * commands failed. + */ +static int +ebiptablesAddRules(virConnectPtr conn, + const char *ifname, + int nruleInstances, + void **_inst) +{ +int i; +int cli_status; +ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst; +virBuffer buf = VIR_BUFFER_INITIALIZER; +bool haveIptables = false; +bool haveIp6tables = false; + +for (i = 0; i < nruleInstances; i++) { +sa_assert (inst); +switch (inst[i]->ruleType) { +case RT_EBTABLES: +ebiptablesInstCommand(&buf, + inst[i]->commandTemplate, + 'A', -1, 1); +break; +case RT_IPTABLES: +if (inst[i]->ruleType == RT_IPTABLES) +iptablesInstCommand(&buf, +inst[i]->commandTemplate, +'A', -1, 1); +haveIptables = true; +break; +case RT_IP6TABLES: +if (inst[i]->ruleType == RT_IP6TABLES) +iptablesInstCommand(&buf, +inst[i]->commandTemplate, +'A', -1, 1); +haveIp6tables = true; +break; +} +} + +if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0) +goto err_exit; + +if (haveIptables) +iptablesCheckBridgeNFCallEnabled(false); + +if (haveIp6tables) +iptablesCheckBridgeNFCallEnabled(true); + +return 0; + +err_exit: +(void) ebiptablesRemoveRules(conn, ifname, nruleInstances, _inst); + +virNWFilterReportError(VIR_ERR_BUILD_FIREWALL, + _("Some rules could not be created for " + "interface %s."), + ifname); + +return 1; +} + /** * ebiptablesAllTeardown: @@ -3751,6 +3823,7 @@ virNWFilterTechDriver ebiptables_driver = { .tearNewRules= ebiptablesTearNewRules, .tearOldRules= ebiptablesTearOldRules, .allTeardown = ebiptablesAllTeardown, +.addRules= ebiptablesAddRules, .removeRules = ebiptablesRemoveRules, .freeRuleInstance= ebiptablesFreeRuleInstance, .displayRuleInstance = ebiptablesDisplayRuleInstance, -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCHv2 5/9] allow chain modification
This patch adds the internal capability to add rules to existing chains instead of using temporary chains and to generate placeholders for chains that are referenced without generating a rule for them immediately. Finally, it includes variable matching for filter instantiation (i.e., instantiate only when a given variable is present in a filter, or only when it is not). Signed-off-by: David L Stevens --- src/conf/nwfilter_conf.h |4 +- src/nwfilter/nwfilter_ebiptables_driver.c | 93 + src/nwfilter/nwfilter_gentech_driver.c| 32 +- 3 files changed, 100 insertions(+), 29 deletions(-) diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 17e954e..4348378 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -525,7 +525,9 @@ typedef int (*virNWFilterRuleCreateInstance)(virConnectPtr conn, virNWFilterRuleDefPtr rule, const char *ifname, virNWFilterHashTablePtr vars, - virNWFilterRuleInstPtr res); + virNWFilterRuleInstPtr res, + bool usetemp, + bool dummy); typedef int (*virNWFilterRuleApplyNewRules)(virConnectPtr conn, const char *ifname, diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index e6a4880..918625c 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -1136,6 +1136,7 @@ iptablesEnforceDirection(int directionIn, * @isIPv6 : Whether this is an IPv6 rule * @maySkipICMP : whether this rule may under certain circumstances skip * the ICMP rule from being created + * @dummy : generate rule placeholder without installing * * Convert a single rule into its representation for later instantiation * @@ -1154,7 +1155,8 @@ _iptablesCreateRuleInstance(int directionIn, const char *match, bool defMatch, const char *accept_target, bool isIPv6, -bool maySkipICMP) +bool maySkipICMP, +bool dummy) { char chain[MAX_CHAINNAME_LENGTH]; char number[20]; @@ -1181,6 +1183,13 @@ _iptablesCreateRuleInstance(int directionIn, PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); +if (dummy) { +virBufferAsprintf(&buf, CMD_DEF_PRE "%s -- %s -%%c %s %%s", + "echo", iptables_cmd, chain); +bufUsed = virBufferUse(&buf); +goto prskip; +} + switch (rule->prtclType) { case VIR_NWFILTER_RULE_PROTOCOL_TCP: case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: @@ -1521,6 +1530,8 @@ _iptablesCreateRuleInstance(int directionIn, return -1; } +prskip: + if ((srcMacSkipped && bufUsed == virBufferUse(&buf)) || skipRule) { virBufferFreeAndReset(&buf); @@ -1636,7 +1647,9 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, const char *ifname, virNWFilterHashTablePtr vars, virNWFilterRuleInstPtr res, -bool isIPv6) +bool isIPv6, +bool usetemp, +bool dummy) { int rc; int directionIn = 0; @@ -1668,7 +1681,7 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, return 1; } -chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP; +chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_IN; if (create) { rc = _iptablesCreateRuleInstance(directionIn, chainPrefix, @@ -1680,7 +1693,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, matchState, false, "RETURN", isIPv6, - maySkipICMP); + maySkipICMP, + dummy); VIR_FREE(matchState); if (rc) @@ -1700,7 +1714,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, return 1; } -chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP; +chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_OUT_TEMP : + CHAINPREFIX_HOST_OUT; if (create) { rc = _iptablesCreateRuleInstance(!direction
[libvirt] [RFC PATCHv2 1/9] support continue/return
This patch adds support for "continue" and "return" actions in filter rules. Signed-off-by: David L Stevens --- src/conf/nwfilter_conf.c |8 ++-- src/conf/nwfilter_conf.h |2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 08ede48..e0c2fb6 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -55,12 +55,16 @@ VIR_ENUM_IMPL(virNWFilterRuleAction, VIR_NWFILTER_RULE_ACTION_LAST, "drop", "accept", - "reject"); + "reject", + "return", + "continue"); VIR_ENUM_IMPL(virNWFilterJumpTarget, VIR_NWFILTER_RULE_ACTION_LAST, "DROP", "ACCEPT", - "REJECT"); + "REJECT", + "RETURN", + "CONTINUE"); VIR_ENUM_IMPL(virNWFilterRuleDirection, VIR_NWFILTER_RULE_DIRECTION_LAST, "in", diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 5306403..c96851a 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -299,6 +299,8 @@ enum virNWFilterRuleActionType { VIR_NWFILTER_RULE_ACTION_DROP = 0, VIR_NWFILTER_RULE_ACTION_ACCEPT, VIR_NWFILTER_RULE_ACTION_REJECT, +VIR_NWFILTER_RULE_ACTION_RETURN, +VIR_NWFILTER_RULE_ACTION_CONTINUE, VIR_NWFILTER_RULE_ACTION_LAST, }; -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCHv2 7/9] support variable value changing
This patch adds a function that applies or deletes filter rules to existing chains. Rules referencing the given variable are instantiated with the given value, or optionally deleted. For example, passing variable "IP" with different values will install rules using the IP variable with each of the different values. These rules can later be removed by calling this function with the same variable and value and "delete" argument set to "1". Signed-off-by: David L Stevens --- src/nwfilter/nwfilter_gentech_driver.c | 86 src/nwfilter/nwfilter_gentech_driver.h | 11 2 files changed, 97 insertions(+), 0 deletions(-) diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 79350ac..563a1f3 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -620,6 +620,92 @@ virNWFilterRuleInstancesToArray(int nEntries, /** + * virNWFilterChangeVar: + * @conn: pointer to virConnect object + * @techdriver: The driver to use for instantiation + * @filter: The filter to instantiate + * @ifname: The name of the interface to apply the rules to + * @vars: A map holding variable names and values used for instantiating + * the filter and its subfilters. + * @var: name of variable to change + * @value: value of variable to change + * @delete: =0 to create or =1 to delete the rules + * + * Returns 0 on success, a value otherwise. + * + * Instantiate or delete a filter and all subfilters with variable "var" + * set to value "value". + * The name of the interface to which the rules belong must be + * provided. + * + * Call this function while holding the NWFilter filter update lock + */ +int +virNWFilterChangeVar(virConnectPtr conn, +virNWFilterTechDriverPtr techdriver, +enum virDomainNetType nettype, +virNWFilterDefPtr filter, +const char *ifname, +virNWFilterHashTablePtr vars, +virNWFilterDriverStatePtr driver, +const char *var, +char *value, +bool delete) +{ +int rc; +int j, nptrs; +int nEntries = 0; +virNWFilterRuleInstPtr *insts = NULL; +void **ptrs = NULL; +bool foundNewFilter = 0; + +if (virNWFilterHashTablePut(vars, var, value, 1)) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Cound not add " + "variable \"%s\" to hashmap"), var); +return 1; +} +rc = _virNWFilterInstantiateRec(conn, +techdriver, +nettype, +filter, +ifname, +vars, +NWFILTER_STD_VAR_IP, 0, +&nEntries, &insts, +INSTANTIATE_ALWAYS, &foundNewFilter, +driver); + if (rc) + goto err_exit; + rc = virNWFilterRuleInstancesToArray(nEntries, insts, &ptrs, &nptrs); + if (rc) + goto err_exit; + +if (virNWFilterHashTableRemoveEntry(vars, var) < 0) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Could not remove " + "variable \"%s\" from hashmap"), var); +return 1; +} + +if (virNWFilterLockIface(ifname)) + goto err_exit; + + if (delete) + rc = techdriver->removeRules(conn, ifname, nptrs, ptrs); + else + rc = techdriver->addRules(conn, ifname, nptrs, ptrs); + virNWFilterUnlockIface(ifname); + VIR_FREE(ptrs); + +err_exit: + +for (j = 0; j < nEntries; j++) + virNWFilterRuleInstFree(insts[j]); +VIR_FREE(insts); +return rc; +} + + +/** * virNWFilterInstantiate: * @conn: pointer to virConnect object * @techdriver: The driver to use for instantiation diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h index fa86030..34e95c7 100644 --- a/src/nwfilter/nwfilter_gentech_driver.h +++ b/src/nwfilter/nwfilter_gentech_driver.h @@ -48,6 +48,17 @@ int virNWFilterRollbackUpdateFilter(virConnectPtr conn, int virNWFilterTearOldFilter(virConnectPtr conn, const virDomainNetDefPtr net); +int virNWFilterChangeVar(virConnectPtr conn, +virNWFilterTechDriverPtr techdriver, +enum virDomainNetType nettype, +virNWFilterDefPtr filter, +const char *ifname, +virNWFilterHashTablePtr vars, +virNWFilterDriverStatePtr driver, +const char *var, +char *value, +
[libvirt] [RFC PATCHv2 8/9] add DHCP snooping
This patch adds DHCP Snooping support to libvirt. Signed-off-by: David L Stevens --- examples/xml/nwfilter/no-ip-spoofing.xml |5 + src/Makefile.am |2 + src/nwfilter/nwfilter_dhcpsnoop.c| 602 ++ src/nwfilter/nwfilter_dhcpsnoop.h| 36 ++ src/nwfilter/nwfilter_driver.c |5 + src/nwfilter/nwfilter_gentech_driver.c | 83 +++-- 6 files changed, 708 insertions(+), 25 deletions(-) create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index 2fccd12..2ae9500 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,4 +4,9 @@ + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 738ee91..f6d3fdd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -473,6 +473,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..f784a29 --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,602 @@ + +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_LIBPCAP +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "datatypes.h" +#include "interface.h" +#include "virterror_internal.h" +#include "threads.h" +#include "conf/nwfilter_params.h" +#include "conf/domain_conf.h" +#include "nwfilter_gentech_driver.h" +#include "nwfilter_ebiptables_driver.h" +#include "nwfilter_dhcpsnoop.h" + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +static virHashTablePtr SnoopReqs; + +struct virNWFilterSnoopReq { +virConnectPtr conn; +virNWFilterTechDriverPtr techdriver; +enum virDomainNetType nettype; +virNWFilterDefPtr filter; +const char *ifname; +virNWFilterHashTablePtr vars; +virNWFilterDriverStatePtr driver; +pthread_t thread; +/* start and end of lease list, ordered by lease time */ +struct iplease *start; +struct iplease *end; +bool die; +}; + +#define POLL_INTERVAL10*1000 /* 10 secs */ + +struct iplease { +uint32_tipl_ipaddr; +uint32_tipl_server; +struct virNWFilterSnoopReq *ipl_req; +unsigned intipl_timeout; +/* timer list */ +struct iplease *ipl_prev; +struct iplease *ipl_next; +}; + +static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); +static void ipl_update(struct iplease *pl, uint32_t timeout); + + +/* + * ipl_ladd - add an IP lease to a list + */ +static void +ipl_ladd(struct iplease *plnew, struct iplease **start, struct iplease **end) +{ +struct iplease *pl; + +plnew->ipl_next = plnew->ipl_prev = 0; +if (!*start) { +plnew->ipl_prev = plnew->ipl_next = 0; +
[libvirt] [RFC PATCHv2 2/9] allow required ARP packets
The ARP protocol requires processing of packets that may not be explicitly addressed to a host and only defines request and reply. This patch removes the filtering of ARP requests not explicitly addressed to a VM to allow for proper ARP cache updates for entries based on any traffic and removes the unnecessary check for arpop of request or reply. Signed-off-by: David L Stevens --- examples/xml/nwfilter/no-arp-spoofing.xml | 23 ++- 1 files changed, 2 insertions(+), 21 deletions(-) diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index 96c58c1..3c83acd 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -12,25 +12,6 @@ - - - - - - - - - - - - - - - - - - - - - + + -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCHv2 4/9] make default chain policy "DROP"
This patch simplifies the table rules by setting the protocol chains policy to be "DROP" and removes the explicit "-j DROP" entries that the protocol rules had previously. It also makes "no-other-rarp-traffic.xml" obsolete. Signed-off-by: David L Stevens --- examples/xml/nwfilter/Makefile.am |1 - examples/xml/nwfilter/no-arpip-spoofing.xml |2 -- examples/xml/nwfilter/no-arpmac-spoofing.xml|2 -- examples/xml/nwfilter/no-ip-spoofing.xml|2 -- examples/xml/nwfilter/no-mac-spoofing.xml |2 -- examples/xml/nwfilter/no-other-rarp-traffic.xml |3 --- examples/xml/nwfilter/qemu-announce-self.xml|1 - src/nwfilter/nwfilter_ebiptables_driver.c | 11 +-- 8 files changed, 1 insertions(+), 23 deletions(-) delete mode 100644 examples/xml/nwfilter/no-other-rarp-traffic.xml diff --git a/examples/xml/nwfilter/Makefile.am b/examples/xml/nwfilter/Makefile.am index 84aaa3c..67085fa 100644 --- a/examples/xml/nwfilter/Makefile.am +++ b/examples/xml/nwfilter/Makefile.am @@ -18,7 +18,6 @@ FILTERS = \ no-mac-broadcast.xml \ no-mac-spoofing.xml \ no-other-l2-traffic.xml \ - no-other-rarp-traffic.xml \ qemu-announce-self.xml \ qemu-announce-self-rarp.xml diff --git a/examples/xml/nwfilter/no-arpip-spoofing.xml b/examples/xml/nwfilter/no-arpip-spoofing.xml index ee42d40..7ef6f0f 100644 --- a/examples/xml/nwfilter/no-arpip-spoofing.xml +++ b/examples/xml/nwfilter/no-arpip-spoofing.xml @@ -7,6 +7,4 @@ - - diff --git a/examples/xml/nwfilter/no-arpmac-spoofing.xml b/examples/xml/nwfilter/no-arpmac-spoofing.xml index 90499d3..3834047 100644 --- a/examples/xml/nwfilter/no-arpmac-spoofing.xml +++ b/examples/xml/nwfilter/no-arpmac-spoofing.xml @@ -2,6 +2,4 @@ - - diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index 84e8a5e..2fccd12 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,6 +4,4 @@ - - diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/examples/xml/nwfilter/no-mac-spoofing.xml index aee56c7..e2e8c03 100644 --- a/examples/xml/nwfilter/no-mac-spoofing.xml +++ b/examples/xml/nwfilter/no-mac-spoofing.xml @@ -4,6 +4,4 @@ - - diff --git a/examples/xml/nwfilter/no-other-rarp-traffic.xml b/examples/xml/nwfilter/no-other-rarp-traffic.xml deleted file mode 100644 index 7729996..000 --- a/examples/xml/nwfilter/no-other-rarp-traffic.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/examples/xml/nwfilter/qemu-announce-self.xml b/examples/xml/nwfilter/qemu-announce-self.xml index 352db50..12957b5 100644 --- a/examples/xml/nwfilter/qemu-announce-self.xml +++ b/examples/xml/nwfilter/qemu-announce-self.xml @@ -8,6 +8,5 @@ - diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 3c6fca7..e6a4880 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -2791,7 +2791,7 @@ ebtablesCreateTmpSubChain(virBufferPtr buf, protostr[0] = '\0'; virBufferAsprintf(buf, - CMD_DEF("%s -t %s -N %s") CMD_SEPARATOR + CMD_DEF("%s -t %s -N %s -P DROP") CMD_SEPARATOR CMD_EXEC "%s" CMD_DEF("%s -t %s -A %s %s -j %s") CMD_SEPARATOR @@ -3015,15 +3015,6 @@ ebtablesApplyBasicRules(const char *ifname, PRINT_ROOT_CHAIN(chain, chainPrefix, ifname); virBufferAsprintf(&buf, - CMD_DEF("%s -t %s -A %s -s ! %s -j DROP") CMD_SEPARATOR - CMD_EXEC - "%s", - - ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, - chain, macaddr_str, - CMD_STOPONERR(1)); - -virBufferAsprintf(&buf, CMD_DEF("%s -t %s -A %s -p IPv4 -j ACCEPT") CMD_SEPARATOR CMD_EXEC "%s", -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCHv2 3/9] reverse sense of address matching
This patch changes rules of the form: if ! addr drop accept to: if addr return ... drop The patch adds a "mac" chain to do a mac address list and separates the "arp" chain into separate "arpmac" and "arpip" chains that can check multiple MAC or IP addresses in any combination. This patch itself does not support multiple addresses via the MAC and IP variables, but only changes the form of the rules to allow multiple addresses in the future. Signed-off-by: David L Stevens --- examples/xml/nwfilter/Makefile.am |4 ++ examples/xml/nwfilter/allow-arp.xml |5 ++- examples/xml/nwfilter/allow-arpip.xml |3 ++ examples/xml/nwfilter/allow-arpmac.xml|3 ++ examples/xml/nwfilter/clean-traffic.xml |6 ++-- examples/xml/nwfilter/no-arp-spoofing.xml | 19 ++ examples/xml/nwfilter/no-arpip-spoofing.xml | 12 ++ examples/xml/nwfilter/no-arpmac-spoofing.xml |7 examples/xml/nwfilter/no-ip-spoofing.xml |6 ++- examples/xml/nwfilter/no-mac-spoofing.xml | 12 -- examples/xml/nwfilter/no-other-l2-traffic.xml | 13 +-- src/conf/nwfilter_conf.c |4 ++- src/conf/nwfilter_conf.h |4 ++- src/nwfilter/nwfilter_ebiptables_driver.c | 48 +--- 14 files changed, 99 insertions(+), 47 deletions(-) create mode 100644 examples/xml/nwfilter/allow-arpip.xml create mode 100644 examples/xml/nwfilter/allow-arpmac.xml create mode 100644 examples/xml/nwfilter/no-arpip-spoofing.xml create mode 100644 examples/xml/nwfilter/no-arpmac-spoofing.xml diff --git a/examples/xml/nwfilter/Makefile.am b/examples/xml/nwfilter/Makefile.am index 23fd753..84aaa3c 100644 --- a/examples/xml/nwfilter/Makefile.am +++ b/examples/xml/nwfilter/Makefile.am @@ -3,12 +3,16 @@ FILTERS = \ allow-arp.xml \ + allow-arpip.xml \ + allow-arpmac.xml \ allow-dhcp-server.xml \ allow-dhcp.xml \ allow-incoming-ipv4.xml \ allow-ipv4.xml \ clean-traffic.xml \ no-arp-spoofing.xml \ + no-arpmac-spoofing.xml \ + no-arpip-spoofing.xml \ no-ip-multicast.xml \ no-ip-spoofing.xml \ no-mac-broadcast.xml \ diff --git a/examples/xml/nwfilter/allow-arp.xml b/examples/xml/nwfilter/allow-arp.xml index 63a92b2..6271ae4 100644 --- a/examples/xml/nwfilter/allow-arp.xml +++ b/examples/xml/nwfilter/allow-arp.xml @@ -1,3 +1,4 @@ - - + + + diff --git a/examples/xml/nwfilter/allow-arpip.xml b/examples/xml/nwfilter/allow-arpip.xml new file mode 100644 index 000..6ddb6fe --- /dev/null +++ b/examples/xml/nwfilter/allow-arpip.xml @@ -0,0 +1,3 @@ + + + diff --git a/examples/xml/nwfilter/allow-arpmac.xml b/examples/xml/nwfilter/allow-arpmac.xml new file mode 100644 index 000..54f6714 --- /dev/null +++ b/examples/xml/nwfilter/allow-arpmac.xml @@ -0,0 +1,3 @@ + + + diff --git a/examples/xml/nwfilter/clean-traffic.xml b/examples/xml/nwfilter/clean-traffic.xml index 40f0ecb..9cee799 100644 --- a/examples/xml/nwfilter/clean-traffic.xml +++ b/examples/xml/nwfilter/clean-traffic.xml @@ -11,10 +11,10 @@ - - - + + + diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index 3c83acd..1979b20 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -1,17 +1,4 @@ - - f88f1932-debf-4aa1-9fbe-f10d3aa4bc95 - - - - - - - - - - - - - - + + + diff --git a/examples/xml/nwfilter/no-arpip-spoofing.xml b/examples/xml/nwfilter/no-arpip-spoofing.xml new file mode 100644 index 000..ee42d40 --- /dev/null +++ b/examples/xml/nwfilter/no-arpip-spoofing.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/examples/xml/nwfilter/no-arpmac-spoofing.xml b/examples/xml/nwfilter/no-arpmac-spoofing.xml new file mode 100644 index 000..90499d3 --- /dev/null +++ b/examples/xml/nwfilter/no-arpmac-spoofing.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index b8c94c8..84e8a5e 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -1,7 +1,9 @@ - - + + + + diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/examples/xml/nwfilter/no-mac-spoofing.xml index f210623..aee56c7 100644 --- a/examples/xml/nwfilter/no-mac-spoofing.xml +++ b/examples/xml/nwfilter/no-mac-spoofing.xml @@ -1,5 +1,9 @@ - - - - + + + + + + + + diff --git a/examples/xml/nwfilter/no-other-l2-traffic.xml b/examples/xml/nwfilter/no-other-l2-traffic.xml index 8bad86e..0501b1a 100644 --- a/examp
[libvirt] [RFC PATCHv2 0/9] DHCP snooping support for libvirt.
This series of patches adds DHCP snooping support to libvirt. This version saves leases on disk for restoration after a libvirtd restart and allows selection of different ip_learning methods by setting filter parameter "ip_learning" to one of "any" (existing IP learning code) "none" (static only addresses) or "DHCP" (DHCP Snooping). This code does not (yet) support passing lease information across a migration. A migrated guest requires a DHCP ACK (e.g., via ifdown/ifup on the guest) to send/receive traffic for DHCP-learned addresses after a migration. David L Stevens (9): support continue/return allow required ARP packets reverse sense of address matching make default chain policy "DROP" allow chain modification support addRules support variable value changing add DHCP snooping add leasefile support examples/xml/nwfilter/Makefile.am |5 +- examples/xml/nwfilter/allow-arp.xml |5 +- examples/xml/nwfilter/allow-arpip.xml |3 + examples/xml/nwfilter/allow-arpmac.xml |3 + examples/xml/nwfilter/clean-traffic.xml |6 +- examples/xml/nwfilter/no-arp-spoofing.xml | 38 +- examples/xml/nwfilter/no-arpip-spoofing.xml | 10 + examples/xml/nwfilter/no-arpmac-spoofing.xml|5 + examples/xml/nwfilter/no-ip-spoofing.xml|9 +- examples/xml/nwfilter/no-mac-spoofing.xml | 10 +- examples/xml/nwfilter/no-other-l2-traffic.xml | 13 +- examples/xml/nwfilter/no-other-rarp-traffic.xml |3 - examples/xml/nwfilter/qemu-announce-self.xml|1 - src/Makefile.am |2 + src/conf/nwfilter_conf.c| 12 +- src/conf/nwfilter_conf.h| 16 +- src/nwfilter/nwfilter_dhcpsnoop.c | 938 +++ src/nwfilter/nwfilter_dhcpsnoop.h | 36 + src/nwfilter/nwfilter_driver.c |5 + src/nwfilter/nwfilter_ebiptables_driver.c | 225 +-- src/nwfilter/nwfilter_gentech_driver.c | 199 - src/nwfilter/nwfilter_gentech_driver.h | 11 + 22 files changed, 1419 insertions(+), 136 deletions(-) create mode 100644 examples/xml/nwfilter/allow-arpip.xml create mode 100644 examples/xml/nwfilter/allow-arpmac.xml create mode 100644 examples/xml/nwfilter/no-arpip-spoofing.xml create mode 100644 examples/xml/nwfilter/no-arpmac-spoofing.xml delete mode 100644 examples/xml/nwfilter/no-other-rarp-traffic.xml create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 8/9] add DHCP snooping support to nwfilter
This patch adds DHCP Snooping support to libvirt. Signed-off-by: David L Stevens diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index 2fccd12..2ae9500 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,4 +4,9 @@ + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 1eaa7d1..3da0797 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -386,6 +386,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..af83149 --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,582 @@ + +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_LIBPCAP +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "datatypes.h" +#include "interface.h" +#include "virterror_internal.h" +#include "threads.h" +#include "conf/nwfilter_params.h" +#include "conf/domain_conf.h" +#include "nwfilter_gentech_driver.h" +#include "nwfilter_ebiptables_driver.h" +#include "nwfilter_dhcpsnoop.h" + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +static virHashTablePtr SnoopReqs; + +struct virNWFilterSnoopReq { +virConnectPtr conn; +virNWFilterTechDriverPtr techdriver; +enum virDomainNetType nettype; +virNWFilterDefPtr filter; +const char *ifname; +virNWFilterHashTablePtr vars; +virNWFilterDriverStatePtr driver; +pthread_t thread; +/* start and end of lease list, ordered by lease time */ +struct iplease *start; +struct iplease *end; +bool die; +}; + +#define POLL_INTERVAL10*1000 /* 10 secs */ + +struct iplease { +uint32_tipl_ipaddr; +uint32_tipl_server; +struct virNWFilterSnoopReq *ipl_req; +unsigned intipl_timeout; +/* timer list */ +struct iplease *ipl_prev; +struct iplease *ipl_next; +}; + +static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); +static void ipl_update(struct iplease *pl, uint32_t timeout); + + +/* + * ipl_tadd - add an IP lease to the timer list + */ +static void +ipl_tadd(struct iplease *plnew) +{ +struct virNWFilterSnoopReq *req = plnew->ipl_req; +struct iplease *pl; + +plnew->ipl_next = plnew->ipl_prev = 0; +if (!req->start) { +plnew->ipl_prev = plnew->ipl_next = 0; +req->start = req->end = plnew; +return; +} +for (pl = req->end; pl && plnew->ipl_timeout < pl->ipl_timeout; + pl = pl->ipl_prev) +/* empty */ ; +if (!pl) { +plnew->ipl_next = req->start; +req->start = plnew; +} else { +plnew->ipl_next = pl->ipl_next; +pl->ipl_next = plnew; +} +plnew->ipl_prev = pl; +if (plnew->ipl_next) +plnew->
[libvirt] [PATCH 9/9] add DHCP snooping support to nwfilter
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 7/9] add DHCP snooping support to nwfilter
This patch adds a function that applies or deletes filter rules to existing chains. Rules referencing the given variable are instantiated with the given value, or optionally deleted. For example, passing variable "IP" with different values will install rules using the IP variable with each of the different values. These rules can later be removed by calling this function with the same variable and value and "delete" argument set to "1". Signed-off-by: David L Stevens diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 0bc3537..a36edbc 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -558,6 +558,92 @@ virNWFilterRuleInstancesToArray(int nEntries, /** + * virNWFilterChangeVar: + * @conn: pointer to virConnect object + * @techdriver: The driver to use for instantiation + * @filter: The filter to instantiate + * @ifname: The name of the interface to apply the rules to + * @vars: A map holding variable names and values used for instantiating + * the filter and its subfilters. + * @var: name of variable to change + * @value: value of variable to change + * @delete: =0 to create or =1 to delete the rules + * + * Returns 0 on success, a value otherwise. + * + * Instantiate or delete a filter and all subfilters with variable "var" + * set to value "value". + * The name of the interface to which the rules belong must be + * provided. + * + * Call this function while holding the NWFilter filter update lock + */ +int +virNWFilterChangeVar(virConnectPtr conn, +virNWFilterTechDriverPtr techdriver, +enum virDomainNetType nettype, +virNWFilterDefPtr filter, +const char *ifname, +virNWFilterHashTablePtr vars, +virNWFilterDriverStatePtr driver, +const char *var, +char *value, +bool delete) +{ +int rc; +int j, nptrs; +int nEntries = 0; +virNWFilterRuleInstPtr *insts = NULL; +void **ptrs = NULL; +bool foundNewFilter = 0; + +if (virNWFilterHashTablePut(vars, var, value, 1)) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Cound not add " + "variable \"%s\" to hashmap"), var); +return 1; +} +rc = _virNWFilterInstantiateRec(conn, +techdriver, +nettype, +filter, +ifname, +vars, +NWFILTER_STD_VAR_IP, 0, +&nEntries, &insts, +INSTANTIATE_ALWAYS, &foundNewFilter, +driver); + if (rc) + goto err_exit; + rc = virNWFilterRuleInstancesToArray(nEntries, insts, &ptrs, &nptrs); + if (rc) + goto err_exit; + +if (virNWFilterHashTableRemoveEntry(vars, var) < 0) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Cound not remove " + "variable \"%s\" from hashmap"), var); +return 1; +} + +if (virNWFilterLockIface(ifname)) + goto err_exit; + + if (delete) + rc = techdriver->removeRules(conn, ifname, nptrs, ptrs); + else + rc = techdriver->addRules(conn, ifname, nptrs, ptrs); + virNWFilterUnlockIface(ifname); + VIR_FREE(ptrs); + +err_exit: + +for (j = 0; j < nEntries; j++) + virNWFilterRuleInstFree(insts[j]); +VIR_FREE(insts); +return rc; +} + + +/** * virNWFilterInstantiate: * @conn: pointer to virConnect object * @techdriver: The driver to use for instantiation diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h index fa86030..48e87d6 100644 --- a/src/nwfilter/nwfilter_gentech_driver.h +++ b/src/nwfilter/nwfilter_gentech_driver.h @@ -48,6 +48,17 @@ int virNWFilterRollbackUpdateFilter(virConnectPtr conn, int virNWFilterTearOldFilter(virConnectPtr conn, const virDomainNetDefPtr net); +int virNWFilterChangeVar(virConnectPtr conn, +virNWFilterTechDriverPtr techdriver, +enum virDomainNetType nettype, +virNWFilterDefPtr filter, +const char *ifname, +virNWFilterHashTablePtr vars, +virNWFilterDriverStatePtr driver, +const char *var, +char *value, +bool delete); + int virNWFilterInstantiateFilterLate(virConnectPtr conn, const char *ifname, int ifindex, -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 9/9] add DHCP snooping support to nwfilter
This patch removes remaining pieces of IP address learning. diff --git a/src/Makefile.am b/src/Makefile.am index 3da0797..53cdc00 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -389,9 +389,7 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_dhcpsnoop.c \ nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ - nwfilter/nwfilter_ebiptables_driver.h \ - nwfilter/nwfilter_learnipaddr.c \ - nwfilter/nwfilter_learnipaddr.h + nwfilter/nwfilter_ebiptables_driver.h # Security framework and drivers for various models diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 2e20e59..3a73fa4 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -40,7 +40,6 @@ #include "configmake.h" #include "nwfilter_dhcpsnoop.h" -#include "nwfilter_learnipaddr.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER @@ -69,8 +68,6 @@ nwfilterDriverStartup(int privileged) { if (virNWFilterDHCPSnoopInit() < 0) return -1; -if (virNWFilterLearnInit() < 0) -return -1; virNWFilterTechDriversInit(privileged); @@ -131,7 +128,6 @@ alloc_err_exit: conf_init_err: virNWFilterTechDriversShutdown(); virNWFilterDHCPSnoopEnd(0); -virNWFilterLearnShutdown(); return -1; } @@ -154,7 +150,7 @@ nwfilterDriverReload(void) { if (conn) { /* shut down all threads -- they will be restarted if necessary */ -virNWFilterLearnThreadsTerminate(true); +virNWFilterDHCPSnoopEnd(0); nwfilterDriverLock(driverState); virNWFilterCallbackDriversLock(); @@ -206,7 +202,6 @@ nwfilterDriverShutdown(void) { virNWFilterConfLayerShutdown(); virNWFilterTechDriversShutdown(); virNWFilterDHCPSnoopEnd(0); -virNWFilterLearnShutdown(); nwfilterDriverLock(driverState); diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index c6e6600..42fd965 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -34,7 +34,6 @@ #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_dhcpsnoop.h" -#include "nwfilter_learnipaddr.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER @@ -625,14 +624,10 @@ virNWFilterChangeVar(virConnectPtr conn, return 1; } -if (virNWFilterLockIface(ifname)) - goto err_exit; - if (delete) rc = techdriver->removeRules(conn, ifname, nptrs, ptrs); else rc = techdriver->addRules(conn, ifname, nptrs, ptrs); - virNWFilterUnlockIface(ifname); VIR_FREE(ptrs); err_exit: @@ -755,9 +750,6 @@ virNWFilterInstantiate(virConnectPtr conn, if (rc) goto err_exit; -if (virNWFilterLockIface(ifname)) -goto err_exit; - rc = techdriver->applyNewRules(conn, ifname, nptrs, ptrs); if (teardownOld && rc == 0) @@ -768,8 +760,6 @@ virNWFilterInstantiate(virConnectPtr conn, techdriver->allTeardown(ifname); rc = 1; } - -virNWFilterUnlockIface(ifname); } err_exit: @@ -811,7 +801,6 @@ __virNWFilterInstantiateFilter(virConnectPtr conn, virNWFilterDefPtr filter; char vmmacaddr[VIR_MAC_STRING_BUFLEN] = {0}; char *str_macaddr = NULL; -const char *ipaddr; char *str_ipaddr = NULL; techdriver = virNWFilterTechDriverForName(drvname); @@ -850,16 +839,6 @@ __virNWFilterInstantiateFilter(virConnectPtr conn, goto err_exit; } -ipaddr = virNWFilterGetIpAddrForIfname(ifname); -if (ipaddr) { -str_ipaddr = strdup(ipaddr); -if (!str_ipaddr) { -virReportOOMError(); -rc = 1; -goto err_exit; -} -} - vars1 = virNWFilterCreateVarHashmap(str_macaddr, str_ipaddr); if (!vars1) { rc = 1; @@ -1031,7 +1010,6 @@ int virNWFilterRollbackUpdateFilter(virConnectPtr conn, const virDomainNetDefPtr net) { const char *drvname = EBIPTABLES_DRIVER_ID; -int ifindex; virNWFilterTechDriverPtr techdriver; techdriver = virNWFilterTechDriverForName(drvname); @@ -1043,11 +1021,6 @@ int virNWFilterRollbackUpdateFilter(virConnectPtr conn, return 1; } -/* don't tear anything while the address is being learned */ -if (ifaceGetIndex(true, net->ifname, &ifindex) == 0 && -virNWFilterLookupLearnReq(ifindex) != NULL) -return 0; - return techdriver->tearNewRules(conn, net->ifname); } @@ -1057,7 +1030,6 @@ virNWFilterTearOldFilter(virConnectPtr conn, virDomainNetDefPtr net) { const char *drvname = EBIPTABLES_DRIVER_ID; -
[libvirt] [PATCH 7/9] add DHCP snooping support to nwfilter
This patch adds a function that applies or deletes filter rules to existing chains. Rules referencing the given variable are instantiated with the given value, or optionally deleted. For example, passing variable "IP" with different values will install rules using the IP variable with each of the different values. These rules can later be removed by calling this function with the same variable and value and "delete" argument set to "1". Signed-off-by: David L Stevens diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 0bc3537..a36edbc 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -558,6 +558,92 @@ virNWFilterRuleInstancesToArray(int nEntries, /** + * virNWFilterChangeVar: + * @conn: pointer to virConnect object + * @techdriver: The driver to use for instantiation + * @filter: The filter to instantiate + * @ifname: The name of the interface to apply the rules to + * @vars: A map holding variable names and values used for instantiating + * the filter and its subfilters. + * @var: name of variable to change + * @value: value of variable to change + * @delete: =0 to create or =1 to delete the rules + * + * Returns 0 on success, a value otherwise. + * + * Instantiate or delete a filter and all subfilters with variable "var" + * set to value "value". + * The name of the interface to which the rules belong must be + * provided. + * + * Call this function while holding the NWFilter filter update lock + */ +int +virNWFilterChangeVar(virConnectPtr conn, +virNWFilterTechDriverPtr techdriver, +enum virDomainNetType nettype, +virNWFilterDefPtr filter, +const char *ifname, +virNWFilterHashTablePtr vars, +virNWFilterDriverStatePtr driver, +const char *var, +char *value, +bool delete) +{ +int rc; +int j, nptrs; +int nEntries = 0; +virNWFilterRuleInstPtr *insts = NULL; +void **ptrs = NULL; +bool foundNewFilter = 0; + +if (virNWFilterHashTablePut(vars, var, value, 1)) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Cound not add " + "variable \"%s\" to hashmap"), var); +return 1; +} +rc = _virNWFilterInstantiateRec(conn, +techdriver, +nettype, +filter, +ifname, +vars, +NWFILTER_STD_VAR_IP, 0, +&nEntries, &insts, +INSTANTIATE_ALWAYS, &foundNewFilter, +driver); + if (rc) + goto err_exit; + rc = virNWFilterRuleInstancesToArray(nEntries, insts, &ptrs, &nptrs); + if (rc) + goto err_exit; + +if (virNWFilterHashTableRemoveEntry(vars, var) < 0) { +virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Cound not remove " + "variable \"%s\" from hashmap"), var); +return 1; +} + +if (virNWFilterLockIface(ifname)) + goto err_exit; + + if (delete) + rc = techdriver->removeRules(conn, ifname, nptrs, ptrs); + else + rc = techdriver->addRules(conn, ifname, nptrs, ptrs); + virNWFilterUnlockIface(ifname); + VIR_FREE(ptrs); + +err_exit: + +for (j = 0; j < nEntries; j++) + virNWFilterRuleInstFree(insts[j]); +VIR_FREE(insts); +return rc; +} + + +/** * virNWFilterInstantiate: * @conn: pointer to virConnect object * @techdriver: The driver to use for instantiation diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h index fa86030..48e87d6 100644 --- a/src/nwfilter/nwfilter_gentech_driver.h +++ b/src/nwfilter/nwfilter_gentech_driver.h @@ -48,6 +48,17 @@ int virNWFilterRollbackUpdateFilter(virConnectPtr conn, int virNWFilterTearOldFilter(virConnectPtr conn, const virDomainNetDefPtr net); +int virNWFilterChangeVar(virConnectPtr conn, +virNWFilterTechDriverPtr techdriver, +enum virDomainNetType nettype, +virNWFilterDefPtr filter, +const char *ifname, +virNWFilterHashTablePtr vars, +virNWFilterDriverStatePtr driver, +const char *var, +char *value, +bool delete); + int virNWFilterInstantiateFilterLate(virConnectPtr conn, const char *ifname, int ifindex, -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 8/9] add DHCP snooping support to nwfilter
This patch adds DHCP Snooping support to libvirt. Signed-off-by: David L Stevens diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index 2fccd12..2ae9500 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,4 +4,9 @@ + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 1eaa7d1..3da0797 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -386,6 +386,8 @@ NWFILTER_DRIVER_SOURCES = \ nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \ nwfilter/nwfilter_gentech_driver.c \ nwfilter/nwfilter_gentech_driver.h \ + nwfilter/nwfilter_dhcpsnoop.c \ + nwfilter/nwfilter_dhcpsnoop.h \ nwfilter/nwfilter_ebiptables_driver.c \ nwfilter/nwfilter_ebiptables_driver.h \ nwfilter/nwfilter_learnipaddr.c \ diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c new file mode 100644 index 000..af83149 --- /dev/null +++ b/src/nwfilter/nwfilter_dhcpsnoop.c @@ -0,0 +1,582 @@ + +/* + * nwfilter_dhcpsnoop.c: support for DHCP snooping used by a VM + * on an interface + * + * Copyright (C) 2011 IBM Corp. + * Copyright (C) 2011 David L Stevens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: David L Stevens + * Based in part on work by Stefan Berger + */ + +#include + +#ifdef HAVE_LIBPCAP +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "datatypes.h" +#include "interface.h" +#include "virterror_internal.h" +#include "threads.h" +#include "conf/nwfilter_params.h" +#include "conf/domain_conf.h" +#include "nwfilter_gentech_driver.h" +#include "nwfilter_ebiptables_driver.h" +#include "nwfilter_dhcpsnoop.h" + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +static virHashTablePtr SnoopReqs; + +struct virNWFilterSnoopReq { +virConnectPtr conn; +virNWFilterTechDriverPtr techdriver; +enum virDomainNetType nettype; +virNWFilterDefPtr filter; +const char *ifname; +virNWFilterHashTablePtr vars; +virNWFilterDriverStatePtr driver; +pthread_t thread; +/* start and end of lease list, ordered by lease time */ +struct iplease *start; +struct iplease *end; +bool die; +}; + +#define POLL_INTERVAL10*1000 /* 10 secs */ + +struct iplease { +uint32_tipl_ipaddr; +uint32_tipl_server; +struct virNWFilterSnoopReq *ipl_req; +unsigned intipl_timeout; +/* timer list */ +struct iplease *ipl_prev; +struct iplease *ipl_next; +}; + +static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr); +static void ipl_update(struct iplease *pl, uint32_t timeout); + + +/* + * ipl_tadd - add an IP lease to the timer list + */ +static void +ipl_tadd(struct iplease *plnew) +{ +struct virNWFilterSnoopReq *req = plnew->ipl_req; +struct iplease *pl; + +plnew->ipl_next = plnew->ipl_prev = 0; +if (!req->start) { +plnew->ipl_prev = plnew->ipl_next = 0; +req->start = req->end = plnew; +return; +} +for (pl = req->end; pl && plnew->ipl_timeout < pl->ipl_timeout; + pl = pl->ipl_prev) +/* empty */ ; +if (!pl) { +plnew->ipl_next = req->start; +req->start = plnew; +} else { +plnew->ipl_next = pl->ipl_next; +pl->ipl_next = plnew; +} +plnew->ipl_prev = pl; +if (plnew->ipl_next) +plnew->
[libvirt] [PATCH 6/9] add DHCP snooping support to nwfilter
This patch adds the capability of adding individual rules to existing chains. Signed-off-by: David L Stevens diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 25f7b60..4b6759a 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -532,6 +532,11 @@ typedef int (*virNWFilterRuleTeardownNewRules)(virConnectPtr conn, typedef int (*virNWFilterRuleTeardownOldRules)(virConnectPtr conn, const char *ifname); +typedef int (*virNWFilterRuleAddRules)(virConnectPtr conn, + const char *ifname, + int nruleInstances, + void **_inst); + typedef int (*virNWFilterRuleRemoveRules)(virConnectPtr conn, const char *ifname, int nruleInstances, @@ -572,6 +577,7 @@ struct _virNWFilterTechDriver { virNWFilterRuleApplyNewRules applyNewRules; virNWFilterRuleTeardownNewRules tearNewRules; virNWFilterRuleTeardownOldRules tearOldRules; +virNWFilterRuleAddRules addRules; virNWFilterRuleRemoveRules removeRules; virNWFilterRuleAllTeardown allTeardown; virNWFilterRuleFreeInstanceData freeRuleInstance; diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index f74f63b..0cb4d00 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -3686,6 +3686,78 @@ err_exit: return rc; } +/** + * ebiptablesAddRules: + * @conn : pointer to virConnect object + * @ifname : the name of the interface to which the rules apply + * @nRuleInstance : the number of given rules + * @_inst : array of rule instantiation data + * + * Add all rules one after the other + * + * Return 0 on success, 1 if execution of one or more cleanup + * commands failed. + */ +static int +ebiptablesAddRules(virConnectPtr conn, + const char *ifname, + int nruleInstances, + void **_inst) +{ +int i; +int cli_status; +ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst; +virBuffer buf = VIR_BUFFER_INITIALIZER; +bool haveIptables = false; +bool haveIp6tables = false; + +for (i = 0; i < nruleInstances; i++) { +sa_assert (inst); +switch (inst[i]->ruleType) { +case RT_EBTABLES: +ebiptablesInstCommand(&buf, + inst[i]->commandTemplate, + 'A', -1, 1); +break; +case RT_IPTABLES: +if (inst[i]->ruleType == RT_IPTABLES) +iptablesInstCommand(&buf, +inst[i]->commandTemplate, +'A', -1, 1); +haveIptables = true; +break; +case RT_IP6TABLES: +if (inst[i]->ruleType == RT_IP6TABLES) +iptablesInstCommand(&buf, +inst[i]->commandTemplate, +'A', -1, 1); +haveIp6tables = true; +break; +} +} + +if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0) +goto err_exit; + +if (haveIptables) +iptablesCheckBridgeNFCallEnabled(false); + +if (haveIp6tables) +iptablesCheckBridgeNFCallEnabled(true); + +return 0; + +err_exit: +(void) ebiptablesRemoveRules(conn, ifname, nruleInstances, _inst); + +virNWFilterReportError(VIR_ERR_BUILD_FIREWALL, + _("Some rules could not be created for " + "interface %s."), + ifname); + +return 1; +} + /** * ebiptablesAllTeardown: @@ -3742,6 +3814,7 @@ virNWFilterTechDriver ebiptables_driver = { .tearNewRules= ebiptablesTearNewRules, .tearOldRules= ebiptablesTearOldRules, .allTeardown = ebiptablesAllTeardown, +.addRules= ebiptablesAddRules, .removeRules = ebiptablesRemoveRules, .freeRuleInstance= ebiptablesFreeRuleInstance, .displayRuleInstance = ebiptablesDisplayRuleInstance, -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 6/9] add DHCP snooping support to nwfilter
This patch adds the capability of adding individual rules to existing chains. Signed-off-by: David L Stevens diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 25f7b60..4b6759a 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -532,6 +532,11 @@ typedef int (*virNWFilterRuleTeardownNewRules)(virConnectPtr conn, typedef int (*virNWFilterRuleTeardownOldRules)(virConnectPtr conn, const char *ifname); +typedef int (*virNWFilterRuleAddRules)(virConnectPtr conn, + const char *ifname, + int nruleInstances, + void **_inst); + typedef int (*virNWFilterRuleRemoveRules)(virConnectPtr conn, const char *ifname, int nruleInstances, @@ -572,6 +577,7 @@ struct _virNWFilterTechDriver { virNWFilterRuleApplyNewRules applyNewRules; virNWFilterRuleTeardownNewRules tearNewRules; virNWFilterRuleTeardownOldRules tearOldRules; +virNWFilterRuleAddRules addRules; virNWFilterRuleRemoveRules removeRules; virNWFilterRuleAllTeardown allTeardown; virNWFilterRuleFreeInstanceData freeRuleInstance; diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index f74f63b..0cb4d00 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -3686,6 +3686,78 @@ err_exit: return rc; } +/** + * ebiptablesAddRules: + * @conn : pointer to virConnect object + * @ifname : the name of the interface to which the rules apply + * @nRuleInstance : the number of given rules + * @_inst : array of rule instantiation data + * + * Add all rules one after the other + * + * Return 0 on success, 1 if execution of one or more cleanup + * commands failed. + */ +static int +ebiptablesAddRules(virConnectPtr conn, + const char *ifname, + int nruleInstances, + void **_inst) +{ +int i; +int cli_status; +ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst; +virBuffer buf = VIR_BUFFER_INITIALIZER; +bool haveIptables = false; +bool haveIp6tables = false; + +for (i = 0; i < nruleInstances; i++) { +sa_assert (inst); +switch (inst[i]->ruleType) { +case RT_EBTABLES: +ebiptablesInstCommand(&buf, + inst[i]->commandTemplate, + 'A', -1, 1); +break; +case RT_IPTABLES: +if (inst[i]->ruleType == RT_IPTABLES) +iptablesInstCommand(&buf, +inst[i]->commandTemplate, +'A', -1, 1); +haveIptables = true; +break; +case RT_IP6TABLES: +if (inst[i]->ruleType == RT_IP6TABLES) +iptablesInstCommand(&buf, +inst[i]->commandTemplate, +'A', -1, 1); +haveIp6tables = true; +break; +} +} + +if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0) +goto err_exit; + +if (haveIptables) +iptablesCheckBridgeNFCallEnabled(false); + +if (haveIp6tables) +iptablesCheckBridgeNFCallEnabled(true); + +return 0; + +err_exit: +(void) ebiptablesRemoveRules(conn, ifname, nruleInstances, _inst); + +virNWFilterReportError(VIR_ERR_BUILD_FIREWALL, + _("Some rules could not be created for " + "interface %s."), + ifname); + +return 1; +} + /** * ebiptablesAllTeardown: @@ -3742,6 +3814,7 @@ virNWFilterTechDriver ebiptables_driver = { .tearNewRules= ebiptablesTearNewRules, .tearOldRules= ebiptablesTearOldRules, .allTeardown = ebiptablesAllTeardown, +.addRules= ebiptablesAddRules, .removeRules = ebiptablesRemoveRules, .freeRuleInstance= ebiptablesFreeRuleInstance, .displayRuleInstance = ebiptablesDisplayRuleInstance, -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/9] add DHCP snooping support to nwfilter
This patch simplifies the table rules by setting the protocol chains policy to be "DROP" and removes the explicit "-j DROP" entries that the protocol rules had previously. It also makes "no-other-rarp-traffic.xml" obsolete. Signed-off-by: David L Stevens diff --git a/examples/xml/nwfilter/Makefile.am b/examples/xml/nwfilter/Makefile.am index 8ef9a71..60301c9 100644 --- a/examples/xml/nwfilter/Makefile.am +++ b/examples/xml/nwfilter/Makefile.am @@ -14,7 +14,6 @@ FILTERS = \ no-mac-broadcast.xml \ no-mac-spoofing.xml \ no-other-l2-traffic.xml \ - no-other-rarp-traffic.xml \ qemu-announce-self.xml \ qemu-announce-self-rarp.xml diff --git a/examples/xml/nwfilter/no-arpip-spoofing.xml b/examples/xml/nwfilter/no-arpip-spoofing.xml index ee42d40..7ef6f0f 100644 --- a/examples/xml/nwfilter/no-arpip-spoofing.xml +++ b/examples/xml/nwfilter/no-arpip-spoofing.xml @@ -7,6 +7,4 @@ - - diff --git a/examples/xml/nwfilter/no-arpmac-spoofing.xml b/examples/xml/nwfilter/no-arpmac-spoofing.xml index 90499d3..3834047 100644 --- a/examples/xml/nwfilter/no-arpmac-spoofing.xml +++ b/examples/xml/nwfilter/no-arpmac-spoofing.xml @@ -2,6 +2,4 @@ - - diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index 84e8a5e..2fccd12 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,6 +4,4 @@ - - diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/examples/xml/nwfilter/no-mac-spoofing.xml index aee56c7..e2e8c03 100644 --- a/examples/xml/nwfilter/no-mac-spoofing.xml +++ b/examples/xml/nwfilter/no-mac-spoofing.xml @@ -4,6 +4,4 @@ - - diff --git a/examples/xml/nwfilter/no-other-rarp-traffic.xml b/examples/xml/nwfilter/no-other-rarp-traffic.xml deleted file mode 100644 index 7729996..000 --- a/examples/xml/nwfilter/no-other-rarp-traffic.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/examples/xml/nwfilter/qemu-announce-self.xml b/examples/xml/nwfilter/qemu-announce-self.xml index 352db50..12957b5 100644 --- a/examples/xml/nwfilter/qemu-announce-self.xml +++ b/examples/xml/nwfilter/qemu-announce-self.xml @@ -8,6 +8,5 @@ - diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index fa6f719..dc0ad2e 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -2783,7 +2783,7 @@ ebtablesCreateTmpSubChain(virBufferPtr buf, protostr[0] = '\0'; virBufferVSprintf(buf, - CMD_DEF("%s -t %s -N %s") CMD_SEPARATOR + CMD_DEF("%s -t %s -N %s -P DROP") CMD_SEPARATOR CMD_EXEC "%s" CMD_DEF("%s -t %s -A %s %s -j %s") CMD_SEPARATOR @@ -3006,14 +3006,6 @@ ebtablesApplyBasicRules(const char *ifname, ebtablesCreateTmpRootChain(&buf, 1, ifname, 1); PRINT_ROOT_CHAIN(chain, chainPrefix, ifname); -virBufferVSprintf(&buf, - CMD_DEF("%s -t %s -A %s -s ! %s -j DROP") CMD_SEPARATOR - CMD_EXEC - "%s", - - ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, - chain, macaddr_str, - CMD_STOPONERR(1)); virBufferVSprintf(&buf, CMD_DEF("%s -t %s -A %s -p IPv4 -j ACCEPT") CMD_SEPARATOR -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 5/9] add DHCP snooping support to nwfilter
This patch adds the internal capability to add rules to existing chains instead of using temporary chains and to generate placeholders for chains that are referenced without generating a rule for them immediately. Finally, it includes variable matching for filter instantiation (i.e., instantiate only when a given variable is present in a filter, or only when it is not). Signed-off-by: David L Stevens diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 72bdade..25f7b60 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -517,7 +517,9 @@ typedef int (*virNWFilterRuleCreateInstance)(virConnectPtr conn, virNWFilterRuleDefPtr rule, const char *ifname, virNWFilterHashTablePtr vars, - virNWFilterRuleInstPtr res); + virNWFilterRuleInstPtr res, + bool usetemp, + bool dummy); typedef int (*virNWFilterRuleApplyNewRules)(virConnectPtr conn, const char *ifname, diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index f16a143..f74f63b 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -1134,6 +1134,7 @@ iptablesEnforceDirection(int directionIn, * @isIPv6 : Whether this is an IPv6 rule * @maySkipICMP : whether this rule may under certain circumstances skip * the ICMP rule from being created + * @dummy : generate rule placeholder without installing * * Convert a single rule into its representation for later instantiation * @@ -1152,7 +1153,8 @@ _iptablesCreateRuleInstance(int directionIn, const char *match, bool defMatch, const char *accept_target, bool isIPv6, -bool maySkipICMP) +bool maySkipICMP, +bool dummy) { char chain[MAX_CHAINNAME_LENGTH]; char number[20]; @@ -1179,6 +1181,13 @@ _iptablesCreateRuleInstance(int directionIn, PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); +if (dummy) { +virBufferVSprintf(&buf, CMD_DEF_PRE "%s -- %s -%%c %s %%s", + "echo", iptables_cmd, chain); +bufUsed = virBufferUse(&buf); +goto prskip; +} + switch (rule->prtclType) { case VIR_NWFILTER_RULE_PROTOCOL_TCP: case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: @@ -1510,6 +1519,8 @@ _iptablesCreateRuleInstance(int directionIn, return -1; } +prskip: + if ((srcMacSkipped && bufUsed == virBufferUse(&buf)) || skipRule) { virBufferFreeAndReset(&buf); @@ -1625,7 +1636,9 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, const char *ifname, virNWFilterHashTablePtr vars, virNWFilterRuleInstPtr res, -bool isIPv6) +bool isIPv6, +bool usetemp, +bool dummy) { int rc; int directionIn = 0, directionOut = 0; @@ -1658,7 +1671,7 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, return 1; } -chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP; +chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_IN; if (create) { rc = _iptablesCreateRuleInstance(directionIn, chainPrefix, @@ -1670,7 +1683,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, matchState, false, "RETURN", isIPv6, - maySkipICMP); + maySkipICMP, + dummy); VIR_FREE(matchState); if (rc) @@ -1690,7 +1704,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, return 1; } -chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP; +chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_OUT_TEMP : + CHAINPREFIX_HOST_OUT; if (create) { rc = _iptablesCreateRuleInstance(!directionIn, chainPrefix, @@ -1702,7 +1717,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, matchState,
[libvirt] [PATCH 4/9] add DHCP snooping support to nwfilter
This patch simplifies the table rules by setting the protocol chains policy to be "DROP" and removes the explicit "-j DROP" entries that the protocol rules had previously. It also makes "no-other-rarp-traffic.xml" obsolete. Signed-off-by: David L Stevens diff --git a/examples/xml/nwfilter/Makefile.am b/examples/xml/nwfilter/Makefile.am index 8ef9a71..60301c9 100644 --- a/examples/xml/nwfilter/Makefile.am +++ b/examples/xml/nwfilter/Makefile.am @@ -14,7 +14,6 @@ FILTERS = \ no-mac-broadcast.xml \ no-mac-spoofing.xml \ no-other-l2-traffic.xml \ - no-other-rarp-traffic.xml \ qemu-announce-self.xml \ qemu-announce-self-rarp.xml diff --git a/examples/xml/nwfilter/no-arpip-spoofing.xml b/examples/xml/nwfilter/no-arpip-spoofing.xml index ee42d40..7ef6f0f 100644 --- a/examples/xml/nwfilter/no-arpip-spoofing.xml +++ b/examples/xml/nwfilter/no-arpip-spoofing.xml @@ -7,6 +7,4 @@ - - diff --git a/examples/xml/nwfilter/no-arpmac-spoofing.xml b/examples/xml/nwfilter/no-arpmac-spoofing.xml index 90499d3..3834047 100644 --- a/examples/xml/nwfilter/no-arpmac-spoofing.xml +++ b/examples/xml/nwfilter/no-arpmac-spoofing.xml @@ -2,6 +2,4 @@ - - diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index 84e8a5e..2fccd12 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -4,6 +4,4 @@ - - diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/examples/xml/nwfilter/no-mac-spoofing.xml index aee56c7..e2e8c03 100644 --- a/examples/xml/nwfilter/no-mac-spoofing.xml +++ b/examples/xml/nwfilter/no-mac-spoofing.xml @@ -4,6 +4,4 @@ - - diff --git a/examples/xml/nwfilter/no-other-rarp-traffic.xml b/examples/xml/nwfilter/no-other-rarp-traffic.xml deleted file mode 100644 index 7729996..000 --- a/examples/xml/nwfilter/no-other-rarp-traffic.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/examples/xml/nwfilter/qemu-announce-self.xml b/examples/xml/nwfilter/qemu-announce-self.xml index 352db50..12957b5 100644 --- a/examples/xml/nwfilter/qemu-announce-self.xml +++ b/examples/xml/nwfilter/qemu-announce-self.xml @@ -8,6 +8,5 @@ - diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index fa6f719..dc0ad2e 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -2783,7 +2783,7 @@ ebtablesCreateTmpSubChain(virBufferPtr buf, protostr[0] = '\0'; virBufferVSprintf(buf, - CMD_DEF("%s -t %s -N %s") CMD_SEPARATOR + CMD_DEF("%s -t %s -N %s -P DROP") CMD_SEPARATOR CMD_EXEC "%s" CMD_DEF("%s -t %s -A %s %s -j %s") CMD_SEPARATOR @@ -3006,14 +3006,6 @@ ebtablesApplyBasicRules(const char *ifname, ebtablesCreateTmpRootChain(&buf, 1, ifname, 1); PRINT_ROOT_CHAIN(chain, chainPrefix, ifname); -virBufferVSprintf(&buf, - CMD_DEF("%s -t %s -A %s -s ! %s -j DROP") CMD_SEPARATOR - CMD_EXEC - "%s", - - ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, - chain, macaddr_str, - CMD_STOPONERR(1)); virBufferVSprintf(&buf, CMD_DEF("%s -t %s -A %s -p IPv4 -j ACCEPT") CMD_SEPARATOR -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 5/9] add DHCP snooping support to nwfilter
This patch adds the internal capability to add rules to existing chains instead of using temporary chains and to generate placeholders for chains that are referenced without generating a rule for them immediately. Finally, it includes variable matching for filter instantiation (i.e., instantiate only when a given variable is present in a filter, or only when it is not). Signed-off-by: David L Stevens diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 72bdade..25f7b60 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -517,7 +517,9 @@ typedef int (*virNWFilterRuleCreateInstance)(virConnectPtr conn, virNWFilterRuleDefPtr rule, const char *ifname, virNWFilterHashTablePtr vars, - virNWFilterRuleInstPtr res); + virNWFilterRuleInstPtr res, + bool usetemp, + bool dummy); typedef int (*virNWFilterRuleApplyNewRules)(virConnectPtr conn, const char *ifname, diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index f16a143..f74f63b 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -1134,6 +1134,7 @@ iptablesEnforceDirection(int directionIn, * @isIPv6 : Whether this is an IPv6 rule * @maySkipICMP : whether this rule may under certain circumstances skip * the ICMP rule from being created + * @dummy : generate rule placeholder without installing * * Convert a single rule into its representation for later instantiation * @@ -1152,7 +1153,8 @@ _iptablesCreateRuleInstance(int directionIn, const char *match, bool defMatch, const char *accept_target, bool isIPv6, -bool maySkipICMP) +bool maySkipICMP, +bool dummy) { char chain[MAX_CHAINNAME_LENGTH]; char number[20]; @@ -1179,6 +1181,13 @@ _iptablesCreateRuleInstance(int directionIn, PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); +if (dummy) { +virBufferVSprintf(&buf, CMD_DEF_PRE "%s -- %s -%%c %s %%s", + "echo", iptables_cmd, chain); +bufUsed = virBufferUse(&buf); +goto prskip; +} + switch (rule->prtclType) { case VIR_NWFILTER_RULE_PROTOCOL_TCP: case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: @@ -1510,6 +1519,8 @@ _iptablesCreateRuleInstance(int directionIn, return -1; } +prskip: + if ((srcMacSkipped && bufUsed == virBufferUse(&buf)) || skipRule) { virBufferFreeAndReset(&buf); @@ -1625,7 +1636,9 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, const char *ifname, virNWFilterHashTablePtr vars, virNWFilterRuleInstPtr res, -bool isIPv6) +bool isIPv6, +bool usetemp, +bool dummy) { int rc; int directionIn = 0, directionOut = 0; @@ -1658,7 +1671,7 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, return 1; } -chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP; +chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_IN; if (create) { rc = _iptablesCreateRuleInstance(directionIn, chainPrefix, @@ -1670,7 +1683,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, matchState, false, "RETURN", isIPv6, - maySkipICMP); + maySkipICMP, + dummy); VIR_FREE(matchState); if (rc) @@ -1690,7 +1704,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, return 1; } -chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP; +chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_OUT_TEMP : + CHAINPREFIX_HOST_OUT; if (create) { rc = _iptablesCreateRuleInstance(!directionIn, chainPrefix, @@ -1702,7 +1717,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter, matchState,
[libvirt] [PATCH 3/9] add DHCP snooping support to nwfilter
This patch changes rules of the form: if ! addr drop accept to: if addr return ... drop The patch adds a "mac" chain to do a mac address list and separates the "arp" chain into separate "arpmac" and "arpip" chains that can check multiple MAC or IP addresses in any combination. This patch itself does not support multiple addresses via the MAC and IP variables, but only changes the form of the rules to allow multiple addresses in the future. Signed-off-by: David L Stevens diff --git a/examples/xml/nwfilter/Makefile.am b/examples/xml/nwfilter/Makefile.am index 439e7b8..8ef9a71 100644 --- a/examples/xml/nwfilter/Makefile.am +++ b/examples/xml/nwfilter/Makefile.am @@ -7,6 +7,8 @@ FILTERS = \ allow-ipv4.xml \ clean-traffic.xml \ no-arp-spoofing.xml \ + no-arpmac-spoofing.xml \ + no-arpip-spoofing.xml \ no-ip-multicast.xml \ no-ip-spoofing.xml \ no-mac-broadcast.xml \ diff --git a/examples/xml/nwfilter/allow-arp.xml b/examples/xml/nwfilter/allow-arp.xml index 63a92b2..006bb54 100644 --- a/examples/xml/nwfilter/allow-arp.xml +++ b/examples/xml/nwfilter/allow-arp.xml @@ -1,3 +1,6 @@ - + + + + diff --git a/examples/xml/nwfilter/clean-traffic.xml b/examples/xml/nwfilter/clean-traffic.xml index 40f0ecb..9cee799 100644 --- a/examples/xml/nwfilter/clean-traffic.xml +++ b/examples/xml/nwfilter/clean-traffic.xml @@ -11,10 +11,10 @@ - - - + + + diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index fdd4e60..1979b20 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -1,17 +1,4 @@ - - f88f1932-debf-4aa1-9fbe-f10d3aa4bc95 - - - - - - - - - - - - - - + + + diff --git a/examples/xml/nwfilter/no-arpip-spoofing.xml b/examples/xml/nwfilter/no-arpip-spoofing.xml new file mode 100644 index 000..ee42d40 --- /dev/null +++ b/examples/xml/nwfilter/no-arpip-spoofing.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/examples/xml/nwfilter/no-arpmac-spoofing.xml b/examples/xml/nwfilter/no-arpmac-spoofing.xml new file mode 100644 index 000..90499d3 --- /dev/null +++ b/examples/xml/nwfilter/no-arpmac-spoofing.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index b8c94c8..84e8a5e 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -1,7 +1,9 @@ - - + + + + diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/examples/xml/nwfilter/no-mac-spoofing.xml index f210623..aee56c7 100644 --- a/examples/xml/nwfilter/no-mac-spoofing.xml +++ b/examples/xml/nwfilter/no-mac-spoofing.xml @@ -1,5 +1,9 @@ - - - - + + + + + + + + diff --git a/examples/xml/nwfilter/no-other-l2-traffic.xml b/examples/xml/nwfilter/no-other-l2-traffic.xml index 8bad86e..0501b1a 100644 --- a/examples/xml/nwfilter/no-other-l2-traffic.xml +++ b/examples/xml/nwfilter/no-other-l2-traffic.xml @@ -1,7 +1,12 @@ - + - - + + + + + + + + diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index c5705c1..df1a012 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -82,7 +82,9 @@ VIR_ENUM_IMPL(virNWFilterEbtablesTable, VIR_NWFILTER_EBTABLES_TABLE_LAST, VIR_ENUM_IMPL(virNWFilterChainSuffix, VIR_NWFILTER_CHAINSUFFIX_LAST, "root", - "arp", + "mac", + "arpmac", + "arpip", "rarp", "ipv4", "ipv6"); diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index ef60b6b..4d60751 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -425,7 +425,9 @@ struct _virNWFilterEntry { enum virNWFilterChainSuffixType { VIR_NWFILTER_CHAINSUFFIX_ROOT = 0, -VIR_NWFILTER_CHAINSUFFIX_ARP, +VIR_NWFILTER_CHAINSUFFIX_MAC, +VIR_NWFILTER_CHAINSUFFIX_ARPMAC, +VIR_NWFILTER_CHAINSUFFIX_ARPIP, VIR_NWFILTER_CHAINSUFFIX_RARP, VIR_NWFILTER_CHAINSUFFIX_IPv4, VIR_NWFILTER_CHAINSUFFIX_IPv6, diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 39bd4a5..fa6f719 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -129,20 +129,24 @@ struct ushort_map { enum l3_proto_idx { -L3_PROTO_IPV4_IDX = 0, -L3_PROTO_IPV6_IDX, -L3_PROTO_ARP_IDX, +L3_PROTO_MAC_IDX = 0, +L3_PROTO_ARPMAC_IDX, +L3_PROTO_ARPIP_IDX, L3_PROTO
[libvirt] [PATCH 3/9] add DHCP snooping support to nwfilter
This patch changes rules of the form: if ! addr drop accept to: if addr return ... drop The patch adds a "mac" chain to do a mac address list and separates the "arp" chain into separate "arpmac" and "arpip" chains that can check multiple MAC or IP addresses in any combination. This patch itself does not support multiple addresses via the MAC and IP variables, but only changes the form of the rules to allow multiple addresses in the future. Signed-off-by: David L Stevens diff --git a/examples/xml/nwfilter/Makefile.am b/examples/xml/nwfilter/Makefile.am index 439e7b8..8ef9a71 100644 --- a/examples/xml/nwfilter/Makefile.am +++ b/examples/xml/nwfilter/Makefile.am @@ -7,6 +7,8 @@ FILTERS = \ allow-ipv4.xml \ clean-traffic.xml \ no-arp-spoofing.xml \ + no-arpmac-spoofing.xml \ + no-arpip-spoofing.xml \ no-ip-multicast.xml \ no-ip-spoofing.xml \ no-mac-broadcast.xml \ diff --git a/examples/xml/nwfilter/allow-arp.xml b/examples/xml/nwfilter/allow-arp.xml index 63a92b2..006bb54 100644 --- a/examples/xml/nwfilter/allow-arp.xml +++ b/examples/xml/nwfilter/allow-arp.xml @@ -1,3 +1,6 @@ - + + + + diff --git a/examples/xml/nwfilter/clean-traffic.xml b/examples/xml/nwfilter/clean-traffic.xml index 40f0ecb..9cee799 100644 --- a/examples/xml/nwfilter/clean-traffic.xml +++ b/examples/xml/nwfilter/clean-traffic.xml @@ -11,10 +11,10 @@ - - - + + + diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index fdd4e60..1979b20 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -1,17 +1,4 @@ - - f88f1932-debf-4aa1-9fbe-f10d3aa4bc95 - - - - - - - - - - - - - - + + + diff --git a/examples/xml/nwfilter/no-arpip-spoofing.xml b/examples/xml/nwfilter/no-arpip-spoofing.xml new file mode 100644 index 000..ee42d40 --- /dev/null +++ b/examples/xml/nwfilter/no-arpip-spoofing.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/examples/xml/nwfilter/no-arpmac-spoofing.xml b/examples/xml/nwfilter/no-arpmac-spoofing.xml new file mode 100644 index 000..90499d3 --- /dev/null +++ b/examples/xml/nwfilter/no-arpmac-spoofing.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/xml/nwfilter/no-ip-spoofing.xml b/examples/xml/nwfilter/no-ip-spoofing.xml index b8c94c8..84e8a5e 100644 --- a/examples/xml/nwfilter/no-ip-spoofing.xml +++ b/examples/xml/nwfilter/no-ip-spoofing.xml @@ -1,7 +1,9 @@ - - + + + + diff --git a/examples/xml/nwfilter/no-mac-spoofing.xml b/examples/xml/nwfilter/no-mac-spoofing.xml index f210623..aee56c7 100644 --- a/examples/xml/nwfilter/no-mac-spoofing.xml +++ b/examples/xml/nwfilter/no-mac-spoofing.xml @@ -1,5 +1,9 @@ - - - - + + + + + + + + diff --git a/examples/xml/nwfilter/no-other-l2-traffic.xml b/examples/xml/nwfilter/no-other-l2-traffic.xml index 8bad86e..0501b1a 100644 --- a/examples/xml/nwfilter/no-other-l2-traffic.xml +++ b/examples/xml/nwfilter/no-other-l2-traffic.xml @@ -1,7 +1,12 @@ - + - - + + + + + + + + diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index c5705c1..df1a012 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -82,7 +82,9 @@ VIR_ENUM_IMPL(virNWFilterEbtablesTable, VIR_NWFILTER_EBTABLES_TABLE_LAST, VIR_ENUM_IMPL(virNWFilterChainSuffix, VIR_NWFILTER_CHAINSUFFIX_LAST, "root", - "arp", + "mac", + "arpmac", + "arpip", "rarp", "ipv4", "ipv6"); diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index ef60b6b..4d60751 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -425,7 +425,9 @@ struct _virNWFilterEntry { enum virNWFilterChainSuffixType { VIR_NWFILTER_CHAINSUFFIX_ROOT = 0, -VIR_NWFILTER_CHAINSUFFIX_ARP, +VIR_NWFILTER_CHAINSUFFIX_MAC, +VIR_NWFILTER_CHAINSUFFIX_ARPMAC, +VIR_NWFILTER_CHAINSUFFIX_ARPIP, VIR_NWFILTER_CHAINSUFFIX_RARP, VIR_NWFILTER_CHAINSUFFIX_IPv4, VIR_NWFILTER_CHAINSUFFIX_IPv6, diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 39bd4a5..fa6f719 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -129,20 +129,24 @@ struct ushort_map { enum l3_proto_idx { -L3_PROTO_IPV4_IDX = 0, -L3_PROTO_IPV6_IDX, -L3_PROTO_ARP_IDX, +L3_PROTO_MAC_IDX = 0, +L3_PROTO_ARPMAC_IDX, +L3_PROTO_ARPIP_IDX, L3_P
[libvirt] [PATCH 2/9] add DHCP snooping support to nwfilter
The ARP protocol requires processing of packets that may not be explicitly addressed to a host and only defines request and reply. This patch removes the filtering of gratuitous ARPs and ARP requests which must update a VMs patch for correct function and removes the unnecessary check for arpop of request or reply. Signed-off-by: David L Stevens diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index c6c858d..fdd4e60 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -12,21 +12,6 @@ - - - - - - - - - - - - - - - - + -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/9] add DHCP snooping support to nwfilter
The following series of patches replaces IP address learning in network filtering with DHCP snooping. The existing address learning capability does not provide security since it relies on addresses used in initial packets sent by the guest to determine an IP address. A spoofing guest can simply arrange to send packets using the target address early on. With DHCP snooping, only addresses acknowledged by a DHCP server can be used by the guest, and only for the given lease time if the address lease is not renewed. The patches also add support for multiple IP addresses per interface. The split: p1 -add return & continue support Add support for "return" and "continue" in filters. p2 -fix ARP input checks Fix a bug that breaks correct use of ARP by overfiltering. p3 -add MAC check; split ARP intp ARPMAC and ARPIP Support for multiple IP addresses in ARP checks, and allow for multiple MAC addresses in the future. p4 -set default protocol policy to "DROP"; edit filters Change default protocol policy to "DROP", rather than adding explicit "DROP" rules at the end of all of them. This is for multiple address support. p5 -optional "modify" (don't use temp, generate placeholder rules) Add support to dynamically add and remove filters without re-installing an entire chain. p6 -addRules Add support for adding new rules to a chain incrementally. Remove support was already there. p7 -ChangeVar support Add support to change chains that have a matching variable substitution to either add or delete rules with the given variable value (e.g., "IP") p8 -add DHCP snooping The DHCP snooping code itself. p9 -delete learnipaddr Clean up remaining learnipaddr infrastructure. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/9] add DHCP snooping support to nwfilter
This patch adds support for "continue" and "return" actions in filter rules. Signed-off-by: David L Stevens diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 13b5b38..6a15f04 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -54,12 +54,16 @@ VIR_ENUM_IMPL(virNWFilterRuleAction, VIR_NWFILTER_RULE_ACTION_LAST, "drop", "accept", - "reject"); + "reject", + "return", + "continue"); VIR_ENUM_IMPL(virNWFilterJumpTarget, VIR_NWFILTER_RULE_ACTION_LAST, "DROP", "ACCEPT", - "REJECT"); + "REJECT", + "RETURN", + "CONTINUE"); VIR_ENUM_IMPL(virNWFilterRuleDirection, VIR_NWFILTER_RULE_DIRECTION_LAST, "in", diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 40da8c3..ab9d4c1 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -291,6 +291,8 @@ enum virNWFilterRuleActionType { VIR_NWFILTER_RULE_ACTION_DROP = 0, VIR_NWFILTER_RULE_ACTION_ACCEPT, VIR_NWFILTER_RULE_ACTION_REJECT, +VIR_NWFILTER_RULE_ACTION_RETURN, +VIR_NWFILTER_RULE_ACTION_CONTINUE, VIR_NWFILTER_RULE_ACTION_LAST, }; -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list