</optional>
</define>
+ <define name="link-speed-state">
+ <optional>
+ <element name="link">
+ <optional>
+ <attribute name="speed">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="state">
+ <choice>
+ <value>unknown</value>
+ <value>notpresent</value>
+ <value>down</value>
+ <value>lowerlayerdown</value>
+ <value>testing</value>
+ <value>dormant</value>
+ <value>up</value>
+ </choice>
+ </attribute>
+ </optional>
+ </element>
+ </optional>
+ </define>
+
</grammar>
<attribute name="address"><ref name="macAddr"/></attribute>
</element>
</optional>
+ <ref name="link-speed-state"/>
<!-- FIXME: Allow (some) ethtool options -->
</define>
"on",
"off")
+VIR_ENUM_IMPL(virInterfaceState,
+ VIR_INTERFACE_STATE_LAST,
+ "" /* value of zero means no state */,
+ "unknown", "notpresent",
+ "down", "lowerlayerdown",
+ "testing", "dormant", "up")
+
int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr)
{
/* PCI bus has 32 slots and 8 functions per slot */
}
return false;
}
+
+int
+virInterfaceLinkParseXML(xmlNodePtr node,
+ virInterfaceLinkPtr lnk)
+{
+ int ret = -1;
+ char *stateStr, *speedStr;
+ int state;
+
+ stateStr = virXMLPropString(node, "state");
+ speedStr = virXMLPropString(node, "speed");
+
+ if (stateStr) {
+ if ((state = virInterfaceStateTypeFromString(stateStr)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unknown link state: %s"),
+ stateStr);
+ goto cleanup;
+ }
+ lnk->state = state;
+ }
+
+ if (speedStr &&
+ virStrToLong_ui(speedStr, NULL, 10, &lnk->speed) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Unable to parse link speed: %s"),
+ speedStr);
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(stateStr);
+ VIR_FREE(speedStr);
+ return ret;
+}
+
+int
+virInterfaceLinkFormat(virBufferPtr buf,
+ const virInterfaceLink *lnk)
+{
+ if (!lnk->speed && !lnk->state) {
+ /* If there's nothing to format, return early. */
+ return 0;
+ }
+
+ virBufferAddLit(buf, "<link");
+ if (lnk->speed)
+ virBufferAsprintf(buf, " speed='%u'", lnk->speed);
+ if (lnk->state)
+ virBufferAsprintf(buf, " state='%s'",
+ virInterfaceStateTypeToString(lnk->state));
+ virBufferAddLit(buf, "/>\n");
+ return 0;
+}
VIR_DEVICE_ADDRESS_PCI_MULTI_LAST
} virDeviceAddressPCIMulti;
+VIR_ENUM_DECL(virDeviceAddressPCIMulti)
+
+typedef enum {
+ VIR_INTERFACE_STATE_UNKNOWN = 1,
+ VIR_INTERFACE_STATE_NOT_PRESENT,
+ VIR_INTERFACE_STATE_DOWN,
+ VIR_INTERFACE_STATE_LOWER_LAYER_DOWN,
+ VIR_INTERFACE_STATE_TESTING,
+ VIR_INTERFACE_STATE_DORMANT,
+ VIR_INTERFACE_STATE_UP,
+ VIR_INTERFACE_STATE_LAST
+} virInterfaceState;
+
+VIR_ENUM_DECL(virInterfaceState)
+
typedef struct _virDevicePCIAddress virDevicePCIAddress;
typedef virDevicePCIAddress *virDevicePCIAddressPtr;
struct _virDevicePCIAddress {
int multi; /* enum virDomainDeviceAddressPCIMulti */
};
+typedef struct _virInterfaceLink virInterfaceLink;
+typedef virInterfaceLink *virInterfaceLinkPtr;
+struct _virInterfaceLink {
+ virInterfaceState state; /* link state */
+ unsigned int speed; /* link speed in Mbits per second */
+};
+
int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr);
int virDevicePCIAddressParseXML(xmlNodePtr node,
bool virDevicePCIAddressEqual(virDevicePCIAddress *addr1,
virDevicePCIAddress *addr2);
+int virInterfaceLinkParseXML(xmlNodePtr node,
+ virInterfaceLinkPtr lnk);
-VIR_ENUM_DECL(virDeviceAddressPCIMulti)
+int virInterfaceLinkFormat(virBufferPtr buf,
+ const virInterfaceLink *lnk);
#endif /* __DEVICE_CONF_H__ */
}
def->type = type;
switch (type) {
- case VIR_INTERFACE_TYPE_ETHERNET:
+ case VIR_INTERFACE_TYPE_ETHERNET: {
+ xmlNodePtr lnk;
+
if (virInterfaceDefParseName(def, ctxt) < 0)
goto error;
tmp = virXPathString("string(./mac/@address)", ctxt);
if (tmp != NULL)
def->mac = tmp;
+
+ lnk = virXPathNode("./link", ctxt);
+ if (lnk && virInterfaceLinkParseXML(lnk, &def->lnk) < 0)
+ goto error;
+
if (parentIfType == VIR_INTERFACE_TYPE_LAST) {
/* only recognize these in toplevel bond interfaces */
if (virInterfaceDefParseStartMode(def, ctxt) < 0)
goto error;
}
break;
+ }
case VIR_INTERFACE_TYPE_BRIDGE: {
xmlNodePtr bridge;
virInterfaceStartmodeDefFormat(buf, def->startmode);
if (def->mac != NULL)
virBufferAsprintf(buf, "<mac address='%s'/>\n", def->mac);
+ virInterfaceLinkFormat(buf, &def->lnk);
if (def->mtu != 0)
virBufferAsprintf(buf, "<mtu size='%d'/>\n", def->mtu);
virInterfaceProtocolDefFormat(buf, def);
# include "internal.h"
# include "virutil.h"
# include "virthread.h"
+# include "device_conf.h"
/* There is currently 3 types of interfaces */
char *name; /* interface name */
unsigned int mtu; /* maximum transmit size in byte */
char *mac; /* MAC address */
+ virInterfaceLink lnk; /* interface link info */
virInterfaceStartMode startmode; /* how it is started */
virDevicePCIAddressFormat;
virDevicePCIAddressIsValid;
virDevicePCIAddressParseXML;
+virInterfaceLinkFormat;
+virInterfaceLinkParseXML;
+virInterfaceStateTypeFromString;
+virInterfaceStateTypeToString;
# conf/domain_addr.h
<bridge stp='off'>
<interface type='ethernet' name='eth0'>
<mac address='ab:bb:cc:dd:ee:ff'/>
+ <link speed='1000' state='up'/>
</interface>
<interface type='ethernet' name='eth1'>
</interface>
<bridge stp='off' delay='0.01'>
<interface type='ethernet' name='eth0'>
<mac address='ab:bb:cc:dd:ee:ff'/>
+ <link speed='10'/>
</interface>
<interface type='ethernet' name='eth1'>
</interface>
<interface type='ethernet' name='eth0'>
<start mode='none'/>
<mac address='aa:bb:cc:dd:ee:ff'/>
+ <link state='down'/>
<mtu size='1492'/>
<protocol family='ipv4'>
<dhcp peerdns='no'/>