if (len < 0)
return -2; /* invalid packet length */
+ /*
+ * some DHCP servers send their responses as MAC broadcast replies
+ * filter messages from the server also by the destination MAC
+ * inside the DHCP response
+ */
+ if (!fromVM) {
+ if (virMacAddrCmpRaw(&req->macaddr,
+ (unsigned char *)&pd->d_chaddr) != 0)
+ return -2;
+ }
+
if (virNWFilterSnoopDHCPGetOpt(pd, len, &mtype, &leasetime) < 0)
return -2;
char pcap_errbuf[PCAP_ERRBUF_SIZE];
char *ext_filter = NULL;
char macaddr[VIR_MAC_STRING_BUFLEN];
- const char *ext;
virMacAddrFormat(mac, macaddr);
* extend the filter with the macaddr of the VM; filter the
* more unlikely parameters first, then go for the MAC
*/
- ext = "and ether src";
+ if (virAsprintf(&ext_filter,
+ "%s and ether src %s", filter, macaddr) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
} else {
- ext = "and ether dst";
- }
-
- if (virAsprintf(&ext_filter, "%s %s %s", filter, ext, macaddr) < 0) {
- virReportOOMError();
- return NULL;
+ /*
+ * Some DHCP servers respond via MAC broadcast; we rely on later
+ * filtering of responses by comparing the MAC address inside the
+ * DHCP response against the one of the VM. Assuming that the
+ * bridge learns the VM's MAC address quickly this should not
+ * generate much more traffic than if we filtered by VM and
+ * braodcast MAC as well
+ */
+ if (virAsprintf(&ext_filter, "%s", filter) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
}
handle = pcap_create(ifname, pcap_errbuf);
while (true) {
char *srcIPParam = NULL;
+ int ctr;
if (idx < num_dhcpsrvrs) {
const char *dhcpserver;
}
}
- virBufferAsprintf(&buf,
- CMD_DEF("$EBT -t nat -A %s"
- " -d %s"
- " -p ipv4 --ip-protocol udp"
- " %s"
- " --ip-sport 67 --ip-dport 68"
- " -j ACCEPT") CMD_SEPARATOR
- CMD_EXEC
- "%s",
-
- chain_out,
- macaddr_str,
- srcIPParam != NULL ? srcIPParam : "",
- CMD_STOPONERR(1));
+ /*
+ * create two rules allowing response to MAC address of VM
+ * or to broadcast MAC address
+ */
+ for (ctr = 0; ctr < 2; ctr++) {
+ virBufferAsprintf(&buf,
+ CMD_DEF("$EBT -t nat -A %s"
+ " -d %s"
+ " -p ipv4 --ip-protocol udp"
+ " %s"
+ " --ip-sport 67 --ip-dport 68"
+ " -j ACCEPT") CMD_SEPARATOR
+ CMD_EXEC
+ "%s",
+
+ chain_out,
+ (ctr == 0) ? macaddr_str : "ff:ff:ff:ff:ff:ff",
+ srcIPParam != NULL ? srcIPParam : "",
+ CMD_STOPONERR(1));
+ }
VIR_FREE(srcIPParam);