mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 09:53:10 +00:00
conf: forbid use of multicast mac addresses
A few times libvirt users manually setting mac addresses have complained of a networking failure that ends up being due to a multicast mac address being used for a guest interface. This patch prevents that by logging an error and failing if a multicast mac address is encountered in each of the three following cases: 1) domain xml <interface> mac address. 2) network xml bridge mac address. 3) network xml dhcp/host mac address. There are several other places where a mac address can be input that aren't controlled in this manner because failure to do so has no consequences (e.g., if the address will be used to search through existing interfaces for a match). The RNG has been updated to add multiMacAddr and uniMacAddr along with the existing macAddr, and macAddr was switched to uniMacAddr where appropriate.
This commit is contained in:
parent
43d635caf3
commit
0007237301
@ -55,9 +55,24 @@
|
|||||||
</define>
|
</define>
|
||||||
|
|
||||||
<!-- a 6 byte MAC address in ASCII-hex format, eg "12:34:56:78:9A:BC" -->
|
<!-- a 6 byte MAC address in ASCII-hex format, eg "12:34:56:78:9A:BC" -->
|
||||||
|
<!-- The lowest bit of the 1st byte is the "multicast" bit. a -->
|
||||||
|
<!-- uniMacAddr requires that bit to be 0, and a multiMacAddr -->
|
||||||
|
<!-- requires it to be 1. Plain macAddr will accept either. -->
|
||||||
|
<!-- Currently there is no use of multiMacAddr in libvirt, it -->
|
||||||
|
<!-- is included here for documentation/comparison purposes. -->
|
||||||
|
<define name="uniMacAddr">
|
||||||
|
<data type="string">
|
||||||
|
<param name="pattern">[a-fA-F0-9][02468aAcCeE](:[a-fA-F0-9]{2}){5}</param>
|
||||||
|
</data>
|
||||||
|
</define>
|
||||||
|
<define name="multiMacAddr">
|
||||||
|
<data type="string">
|
||||||
|
<param name="pattern">[a-fA-F0-9][13579bBdDfF](:[a-fA-F0-9]{2}){5}</param>
|
||||||
|
</data>
|
||||||
|
</define>
|
||||||
<define name="macAddr">
|
<define name="macAddr">
|
||||||
<data type="string">
|
<data type="string">
|
||||||
<param name="pattern">([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}</param>
|
<param name="pattern">[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5}</param>
|
||||||
</data>
|
</data>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
@ -1391,7 +1391,7 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<element name="mac">
|
<element name="mac">
|
||||||
<attribute name="address">
|
<attribute name="address">
|
||||||
<ref name="macAddr"/>
|
<ref name="uniMacAddr"/>
|
||||||
</attribute>
|
</attribute>
|
||||||
<empty/>
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
@ -1417,7 +1417,7 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<element name="mac">
|
<element name="mac">
|
||||||
<attribute name="address">
|
<attribute name="address">
|
||||||
<ref name="macAddr"/>
|
<ref name="uniMacAddr"/>
|
||||||
</attribute>
|
</attribute>
|
||||||
<empty/>
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
@ -1498,7 +1498,7 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<element name="mac">
|
<element name="mac">
|
||||||
<attribute name="address">
|
<attribute name="address">
|
||||||
<ref name="macAddr"/>
|
<ref name="uniMacAddr"/>
|
||||||
</attribute>
|
</attribute>
|
||||||
<empty/>
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
<!-- <mac> element -->
|
<!-- <mac> element -->
|
||||||
<optional>
|
<optional>
|
||||||
<element name="mac">
|
<element name="mac">
|
||||||
<attribute name="address"><ref name="macAddr"/></attribute>
|
<attribute name="address"><ref name="uniMacAddr"/></attribute>
|
||||||
<empty/>
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
@ -218,7 +218,7 @@
|
|||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
<element name="host">
|
<element name="host">
|
||||||
<attribute name="mac"><ref name="macAddr"/></attribute>
|
<attribute name="mac"><ref name="uniMacAddr"/></attribute>
|
||||||
<attribute name="name"><text/></attribute>
|
<attribute name="name"><text/></attribute>
|
||||||
<attribute name="ip"><ref name="ipv4Addr"/></attribute>
|
<attribute name="ip"><ref name="ipv4Addr"/></attribute>
|
||||||
</element>
|
</element>
|
||||||
|
@ -4416,11 +4416,17 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
|
|
||||||
if (macaddr) {
|
if (macaddr) {
|
||||||
if (virMacAddrParse((const char *)macaddr, def->mac) < 0) {
|
if (virMacAddrParse((const char *)macaddr, def->mac) < 0) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||||
_("unable to parse mac address '%s'"),
|
_("unable to parse mac address '%s'"),
|
||||||
(const char *)macaddr);
|
(const char *)macaddr);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (virMacAddrIsMulticast(def->mac)) {
|
||||||
|
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("expected unicast mac address, found multicast '%s'"),
|
||||||
|
(const char *)macaddr);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
virCapabilitiesGenerateMac(caps, def->mac);
|
virCapabilitiesGenerateMac(caps, def->mac);
|
||||||
}
|
}
|
||||||
|
@ -419,22 +419,30 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
|
|||||||
def->nranges++;
|
def->nranges++;
|
||||||
} else if (cur->type == XML_ELEMENT_NODE &&
|
} else if (cur->type == XML_ELEMENT_NODE &&
|
||||||
xmlStrEqual(cur->name, BAD_CAST "host")) {
|
xmlStrEqual(cur->name, BAD_CAST "host")) {
|
||||||
char *mac, *name, *ip;
|
char *mac = NULL, *name = NULL, *ip;
|
||||||
unsigned char addr[6];
|
unsigned char addr[6];
|
||||||
virSocketAddr inaddr;
|
virSocketAddr inaddr;
|
||||||
|
|
||||||
mac = virXMLPropString(cur, "mac");
|
mac = virXMLPropString(cur, "mac");
|
||||||
if ((mac != NULL) &&
|
if (mac != NULL) {
|
||||||
(virMacAddrParse(mac, &addr[0]) != 0)) {
|
if (virMacAddrParse(mac, &addr[0]) < 0) {
|
||||||
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
||||||
_("Cannot parse MAC address '%s' in network '%s'"),
|
_("Cannot parse MAC address '%s' in network '%s'"),
|
||||||
mac, networkName);
|
mac, networkName);
|
||||||
VIR_FREE(mac);
|
VIR_FREE(mac);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
if (virMacAddrIsMulticast(addr)) {
|
||||||
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("expected unicast mac address, found multicast '%s' in network '%s'"),
|
||||||
|
(const char *)mac, networkName);
|
||||||
|
VIR_FREE(mac);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
name = virXMLPropString(cur, "name");
|
name = virXMLPropString(cur, "name");
|
||||||
if ((name != NULL) && (!c_isalpha(name[0]))) {
|
if ((name != NULL) && (!c_isalpha(name[0]))) {
|
||||||
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
||||||
_("Cannot use name address '%s' in network '%s'"),
|
_("Cannot use name address '%s' in network '%s'"),
|
||||||
name, networkName);
|
name, networkName);
|
||||||
VIR_FREE(mac);
|
VIR_FREE(mac);
|
||||||
@ -991,6 +999,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
|||||||
VIR_FREE(tmp);
|
VIR_FREE(tmp);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (virMacAddrIsMulticast(def->mac)) {
|
||||||
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("Invalid multicast bridge mac address '%s' in network '%s'"),
|
||||||
|
tmp, def->name);
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
VIR_FREE(tmp);
|
VIR_FREE(tmp);
|
||||||
def->mac_specified = true;
|
def->mac_specified = true;
|
||||||
}
|
}
|
||||||
|
@ -1208,6 +1208,8 @@ virKeycodeValueTranslate;
|
|||||||
virMacAddrCompare;
|
virMacAddrCompare;
|
||||||
virMacAddrFormat;
|
virMacAddrFormat;
|
||||||
virMacAddrGenerate;
|
virMacAddrGenerate;
|
||||||
|
virMacAddrIsMulticast;
|
||||||
|
virMacAddrIsUnicast;
|
||||||
virMacAddrParse;
|
virMacAddrParse;
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,3 +126,16 @@ void virMacAddrGenerate(const unsigned char *prefix,
|
|||||||
addr[4] = virRandomBits(8);
|
addr[4] = virRandomBits(8);
|
||||||
addr[5] = virRandomBits(8);
|
addr[5] = virRandomBits(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The low order bit of the first byte is the "multicast" bit. */
|
||||||
|
bool
|
||||||
|
virMacAddrIsMulticast(const unsigned char *addr)
|
||||||
|
{
|
||||||
|
return !!(addr[0] & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
virMacAddrIsUnicast(const unsigned char *addr)
|
||||||
|
{
|
||||||
|
return !(addr[0] & 1);
|
||||||
|
}
|
||||||
|
@ -37,5 +37,6 @@ void virMacAddrGenerate(const unsigned char *prefix,
|
|||||||
unsigned char *addr);
|
unsigned char *addr);
|
||||||
int virMacAddrParse(const char* str,
|
int virMacAddrParse(const char* str,
|
||||||
unsigned char *addr) ATTRIBUTE_RETURN_CHECK;
|
unsigned char *addr) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
bool virMacAddrIsUnicast(const unsigned char *addr);
|
||||||
|
bool virMacAddrIsMulticast(const unsigned char *addr);
|
||||||
#endif /* __VIR_MACADDR_H__ */
|
#endif /* __VIR_MACADDR_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user