nwfilter: convert IP address learning code to virNWFilterBindingDefPtr

Use the virNWFilterBindingDefPTr struct in the IP address learning code
directly.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2018-04-26 12:45:29 +01:00
parent d1a7c08eb1
commit 5b6c02e292
3 changed files with 33 additions and 94 deletions

View File

@ -626,12 +626,9 @@ virNWFilterDoInstantiate(virNWFilterTechDriverPtr techdriver,
} else if (STRCASEEQ(learning, "any")) { } else if (STRCASEEQ(learning, "any")) {
if (!virNWFilterHasLearnReq(ifindex)) { if (!virNWFilterHasLearnReq(ifindex)) {
rc = virNWFilterLearnIPAddress(techdriver, rc = virNWFilterLearnIPAddress(techdriver,
binding->portdevname, binding,
ifindex, ifindex,
binding->linkdevname, driver,
&binding->mac,
filter->name,
binding->filterparams, driver,
DETECT_DHCP|DETECT_STATIC); DETECT_DHCP|DETECT_STATIC);
} }
goto err_exit; goto err_exit;

View File

@ -138,12 +138,8 @@ typedef struct _virNWFilterIPAddrLearnReq virNWFilterIPAddrLearnReq;
typedef virNWFilterIPAddrLearnReq *virNWFilterIPAddrLearnReqPtr; typedef virNWFilterIPAddrLearnReq *virNWFilterIPAddrLearnReqPtr;
struct _virNWFilterIPAddrLearnReq { struct _virNWFilterIPAddrLearnReq {
virNWFilterTechDriverPtr techdriver; virNWFilterTechDriverPtr techdriver;
char ifname[IF_NAMESIZE];
int ifindex; int ifindex;
char linkdev[IF_NAMESIZE]; virNWFilterBindingDefPtr binding;
virMacAddr macaddr;
char *filtername;
virHashTablePtr filterparams;
virNWFilterDriverStatePtr driver; virNWFilterDriverStatePtr driver;
int howDetect; /* bitmask of enum howDetect */ int howDetect; /* bitmask of enum howDetect */
@ -233,8 +229,7 @@ virNWFilterIPAddrLearnReqFree(virNWFilterIPAddrLearnReqPtr req)
if (!req) if (!req)
return; return;
VIR_FREE(req->filtername); virNWFilterBindingDefFree(req->binding);
virHashFree(req->filterparams);
VIR_FREE(req); VIR_FREE(req);
} }
@ -405,8 +400,9 @@ learnIPAddressThread(void *arg)
virNWFilterIPAddrLearnReqPtr req = arg; virNWFilterIPAddrLearnReqPtr req = arg;
uint32_t vmaddr = 0, bcastaddr = 0; uint32_t vmaddr = 0, bcastaddr = 0;
unsigned int ethHdrSize; unsigned int ethHdrSize;
char *listen_if = (strlen(req->linkdev) != 0) ? req->linkdev char *listen_if = (req->binding->linkdevname ?
: req->ifname; req->binding->linkdevname :
req->binding->portdevname);
int dhcp_opts_len; int dhcp_opts_len;
char macaddr[VIR_MAC_STRING_BUFLEN]; char macaddr[VIR_MAC_STRING_BUFLEN];
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
@ -417,13 +413,13 @@ learnIPAddressThread(void *arg)
virNWFilterTechDriverPtr techdriver = req->techdriver; virNWFilterTechDriverPtr techdriver = req->techdriver;
struct pollfd fds[1]; struct pollfd fds[1];
if (virNWFilterLockIface(req->ifname) < 0) if (virNWFilterLockIface(req->binding->portdevname) < 0)
goto err_no_lock; goto err_no_lock;
req->status = 0; req->status = 0;
/* anything change to the VM's interface -- check at least once */ /* anything change to the VM's interface -- check at least once */
if (virNetDevValidateConfig(req->ifname, NULL, req->ifindex) <= 0) { if (virNetDevValidateConfig(req->binding->portdevname, NULL, req->ifindex) <= 0) {
virResetLastError(); virResetLastError();
req->status = ENODEV; req->status = ENODEV;
goto done; goto done;
@ -440,11 +436,11 @@ learnIPAddressThread(void *arg)
fds[0].fd = pcap_fileno(handle); fds[0].fd = pcap_fileno(handle);
fds[0].events = POLLIN | POLLERR; fds[0].events = POLLIN | POLLERR;
virMacAddrFormat(&req->macaddr, macaddr); virMacAddrFormat(&req->binding->mac, macaddr);
if (req->howDetect == DETECT_DHCP) { if (req->howDetect == DETECT_DHCP) {
if (techdriver->applyDHCPOnlyRules(req->ifname, if (techdriver->applyDHCPOnlyRules(req->binding->portdevname,
&req->macaddr, &req->binding->mac,
NULL, false) < 0) { NULL, false) < 0) {
VIR_DEBUG("Unable to apply DHCP only rules"); VIR_DEBUG("Unable to apply DHCP only rules");
req->status = EINVAL; req->status = EINVAL;
@ -452,8 +448,8 @@ learnIPAddressThread(void *arg)
} }
virBufferAddLit(&buf, "src port 67 and dst port 68"); virBufferAddLit(&buf, "src port 67 and dst port 68");
} else { } else {
if (techdriver->applyBasicRules(req->ifname, if (techdriver->applyBasicRules(req->binding->portdevname,
&req->macaddr) < 0) { &req->binding->mac) < 0) {
VIR_DEBUG("Unable to apply basic rules"); VIR_DEBUG("Unable to apply basic rules");
req->status = EINVAL; req->status = EINVAL;
goto done; goto done;
@ -524,7 +520,7 @@ learnIPAddressThread(void *arg)
} }
/* Again, already handled above, but lets be sure */ /* Again, already handled above, but lets be sure */
if (virNetDevValidateConfig(req->ifname, NULL, req->ifindex) <= 0) { if (virNetDevValidateConfig(req->binding->portdevname, NULL, req->ifindex) <= 0) {
virResetLastError(); virResetLastError();
req->status = ENODEV; req->status = ENODEV;
showError = false; showError = false;
@ -556,7 +552,7 @@ learnIPAddressThread(void *arg)
continue; continue;
} }
if (virMacAddrCmpRaw(&req->macaddr, ether_hdr->ether_shost) == 0) { if (virMacAddrCmpRaw(&req->binding->mac, ether_hdr->ether_shost) == 0) {
/* packets from the VM */ /* packets from the VM */
if (etherType == ETHERTYPE_IP && if (etherType == ETHERTYPE_IP &&
@ -595,7 +591,7 @@ learnIPAddressThread(void *arg)
break; break;
} }
} }
} else if (virMacAddrCmpRaw(&req->macaddr, } else if (virMacAddrCmpRaw(&req->binding->mac,
ether_hdr->ether_dhost) == 0 || ether_hdr->ether_dhost) == 0 ||
/* allow Broadcast replies from DHCP server */ /* allow Broadcast replies from DHCP server */
virMacAddrIsBroadcastRaw(ether_hdr->ether_dhost)) { virMacAddrIsBroadcastRaw(ether_hdr->ether_dhost)) {
@ -625,7 +621,7 @@ learnIPAddressThread(void *arg)
((char *)udphdr + sizeof(udphdr)); ((char *)udphdr + sizeof(udphdr));
if (dhcp->op == 2 /* BOOTREPLY */ && if (dhcp->op == 2 /* BOOTREPLY */ &&
virMacAddrCmpRaw( virMacAddrCmpRaw(
&req->macaddr, &req->binding->mac,
&dhcp->chaddr[0]) == 0) { &dhcp->chaddr[0]) == 0) {
dhcp_opts_len = header.len - dhcp_opts_len = header.len -
(ethHdrSize + iphdr->ihl * 4 + (ethHdrSize + iphdr->ihl * 4 +
@ -669,28 +665,19 @@ learnIPAddressThread(void *arg)
* Also it is safe to unlock interface here because we stopped * Also it is safe to unlock interface here because we stopped
* capturing and applied necessary rules on the interface, while * capturing and applied necessary rules on the interface, while
* instantiating a new filter doesn't require a locked interface.*/ * instantiating a new filter doesn't require a locked interface.*/
virNWFilterUnlockIface(req->ifname); virNWFilterUnlockIface(req->binding->portdevname);
if ((inetaddr = virSocketAddrFormat(&sa)) != NULL) { if ((inetaddr = virSocketAddrFormat(&sa)) != NULL) {
virNWFilterBindingDef binding = { if (virNWFilterIPAddrMapAddIPAddr(req->binding->portdevname, inetaddr) < 0) {
.portdevname = req->ifname,
.linkdevname = req->linkdev,
.mac = req->macaddr,
.filter = req->filtername,
.filterparams = req->filterparams,
.ownername = NULL,
.owneruuid = {0},
};
if (virNWFilterIPAddrMapAddIPAddr(req->ifname, inetaddr) < 0) {
VIR_ERROR(_("Failed to add IP address %s to IP address " VIR_ERROR(_("Failed to add IP address %s to IP address "
"cache for interface %s"), inetaddr, req->ifname); "cache for interface %s"), inetaddr, req->binding->portdevname);
} }
ret = virNWFilterInstantiateFilterLate(req->driver, ret = virNWFilterInstantiateFilterLate(req->driver,
&binding, req->binding,
req->ifindex); req->ifindex);
VIR_DEBUG("Result from applying firewall rules on " VIR_DEBUG("Result from applying firewall rules on "
"%s with IP addr %s : %d", req->ifname, inetaddr, ret); "%s with IP addr %s : %d", req->binding->portdevname, inetaddr, ret);
VIR_FREE(inetaddr); VIR_FREE(inetaddr);
} }
} else { } else {
@ -698,13 +685,13 @@ learnIPAddressThread(void *arg)
virReportSystemError(req->status, virReportSystemError(req->status,
_("encountered an error on interface %s " _("encountered an error on interface %s "
"index %d"), "index %d"),
req->ifname, req->ifindex); req->binding->portdevname, req->ifindex);
techdriver->applyDropAllRules(req->ifname); techdriver->applyDropAllRules(req->binding->portdevname);
virNWFilterUnlockIface(req->ifname); virNWFilterUnlockIface(req->binding->portdevname);
} }
VIR_DEBUG("pcap thread terminating for interface %s", req->ifname); VIR_DEBUG("pcap thread terminating for interface %s", req->binding->portdevname);
err_no_lock: err_no_lock:
@ -717,13 +704,8 @@ learnIPAddressThread(void *arg)
/** /**
* virNWFilterLearnIPAddress * virNWFilterLearnIPAddress
* @techdriver : driver to build firewalls * @techdriver : driver to build firewalls
* @ifname: the name of the interface * @binding: the network port binding information
* @ifindex: the index of the interface * @ifindex: the index of the interface
* @linkdev : the name of the link device; currently only used in case of a
* macvtap device
* @macaddr : the MAC address of the interface
* @filtername : the name of the top-level filter to apply to the interface
* once its IP address has been detected
* @driver : the network filter driver * @driver : the network filter driver
* @howDetect : the method on how the thread is supposed to detect the * @howDetect : the method on how the thread is supposed to detect the
* IP address; bitmask of "enum howDetect" flags. * IP address; bitmask of "enum howDetect" flags.
@ -737,19 +719,14 @@ learnIPAddressThread(void *arg)
*/ */
int int
virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver, virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
const char *ifname, virNWFilterBindingDefPtr binding,
int ifindex, int ifindex,
const char *linkdev,
const virMacAddr *macaddr,
const char *filtername,
virHashTablePtr filterparams,
virNWFilterDriverStatePtr driver, virNWFilterDriverStatePtr driver,
int howDetect) int howDetect)
{ {
int rc; int rc;
virThread thread; virThread thread;
virNWFilterIPAddrLearnReqPtr req = NULL; virNWFilterIPAddrLearnReqPtr req = NULL;
virHashTablePtr ht = NULL;
if (howDetect == 0) if (howDetect == 0)
return -1; return -1;
@ -765,37 +742,11 @@ virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
if (VIR_ALLOC(req) < 0) if (VIR_ALLOC(req) < 0)
goto err_no_req; goto err_no_req;
ht = virNWFilterHashTableCreate(0); if (!(req->binding = virNWFilterBindingDefCopy(binding)))
if (ht == NULL)
goto err_free_req; goto err_free_req;
if (virNWFilterHashTablePutAll(filterparams, ht) < 0)
goto err_free_ht;
if (VIR_STRDUP(req->filtername, filtername) < 0)
goto err_free_ht;
if (virStrcpyStatic(req->ifname, ifname) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Destination buffer for ifname ('%s') "
"not large enough"), ifname);
goto err_free_ht;
}
if (linkdev) {
if (virStrcpyStatic(req->linkdev, linkdev) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Destination buffer for linkdev ('%s') "
"not large enough"), linkdev);
goto err_free_ht;
}
}
req->ifindex = ifindex; req->ifindex = ifindex;
virMacAddrSet(&req->macaddr, macaddr);
req->driver = driver; req->driver = driver;
req->filterparams = ht;
ht = NULL;
req->howDetect = howDetect; req->howDetect = howDetect;
req->techdriver = techdriver; req->techdriver = techdriver;
@ -814,8 +765,6 @@ virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
err_dereg_req: err_dereg_req:
virNWFilterDeregisterLearnReq(ifindex); virNWFilterDeregisterLearnReq(ifindex);
err_free_ht:
virHashFree(ht);
err_free_req: err_free_req:
virNWFilterIPAddrLearnReqFree(req); virNWFilterIPAddrLearnReqFree(req);
err_no_req: err_no_req:
@ -826,12 +775,8 @@ virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
int int
virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver ATTRIBUTE_UNUSED, virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver ATTRIBUTE_UNUSED,
const char *ifname ATTRIBUTE_UNUSED, virNWFilterBindingDefPtr binding ATTRIBUTE_UNUSED,
int ifindex ATTRIBUTE_UNUSED, int ifindex ATTRIBUTE_UNUSED,
const char *linkdev ATTRIBUTE_UNUSED,
const virMacAddr *macaddr ATTRIBUTE_UNUSED,
const char *filtername ATTRIBUTE_UNUSED,
virHashTablePtr filterparams ATTRIBUTE_UNUSED,
virNWFilterDriverStatePtr driver ATTRIBUTE_UNUSED, virNWFilterDriverStatePtr driver ATTRIBUTE_UNUSED,
int howDetect ATTRIBUTE_UNUSED) int howDetect ATTRIBUTE_UNUSED)
{ {

View File

@ -28,6 +28,7 @@
# include "conf/nwfilter_params.h" # include "conf/nwfilter_params.h"
# include "nwfilter_tech_driver.h" # include "nwfilter_tech_driver.h"
# include "virnwfilterbindingdef.h"
# include <net/if.h> # include <net/if.h>
enum howDetect { enum howDetect {
@ -36,12 +37,8 @@ enum howDetect {
}; };
int virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver, int virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
const char *ifname, virNWFilterBindingDefPtr binding,
int ifindex, int ifindex,
const char *linkdev,
const virMacAddr *macaddr,
const char *filtername,
virHashTablePtr filterparams,
virNWFilterDriverStatePtr driver, virNWFilterDriverStatePtr driver,
int howDetect); int howDetect);