Commit 4c8d587b authored by Tarun Prabhu's avatar Tarun Prabhu
Browse files

Changed the request rspec parser to deal with fixed interfaces properly. Fixed...

Changed the request rspec parser to deal with fixed interfaces properly. Fixed a few bugs in the annotater.

The rspec-request.rnc was modified slightly to represent the mapping in a better way.
parent fd9ef830
......@@ -4,7 +4,7 @@
* All rights reserved.
*/
static const char rcsid[] = "$Id: annotate_rspec.cc,v 1.6 2009-10-06 23:53:10 duerig Exp $";
static const char rcsid[] = "$Id: annotate_rspec.cc,v 1.7 2009-10-08 00:31:59 tarunp Exp $";
#ifdef WITH_XML
......@@ -150,11 +150,14 @@ DOMElement* annotate_rspec::create_component_hop (const DOMElement* plink, DOMEl
// If the source interface is an end point
if (endpoint_interface == SOURCE || endpoint_interface == BOTH)
set_interface_as_link_endpoint(plink_src_iface_clone, XStr(vlink_src_iface->getAttribute(XStr("virtual_node_id").x())).c());
set_interface_as_link_endpoint(plink_src_iface_clone,
XStr(vlink_src_iface->getAttribute(XStr("virtual_node_id").x())).c(), XStr(vlink_src_iface->getAttribute(XStr("virtual_interface_id").x())).c());
// If the destination interface is an end point
if (endpoint_interface == DESTINATION || endpoint_interface == BOTH)
set_interface_as_link_endpoint(plink_dst_iface_clone, XStr(vlink_dst_iface->getAttribute(XStr("virtual_node_id").x())).c());
set_interface_as_link_endpoint(plink_dst_iface_clone,
XStr(vlink_dst_iface->getAttribute(XStr("virtual_node_id").x())).c(),
XStr(vlink_dst_iface->getAttribute(XStr("virtual_interface_id").x())).c());
// Add interface specifications to the link in the single hop element
component_hop->appendChild(plink_src_iface_clone);
......@@ -182,15 +185,15 @@ void annotate_rspec::annotate_interface (const DOMElement* plink, DOMElement* vl
p_iface = getElementByAttributeValue(plink, "interface_ref", "component_node_urn", node_component_uuid.c());
}
vlink_iface->setAttribute(XStr("component_node_uuid").x(), p_iface->getAttribute(XStr("component_node_uuid").x()));
vlink_iface->setAttribute(XStr("component_interface_id").x(), p_iface->getAttribute(XStr("component_interface_id").x()));
// vlink_iface->setAttribute(XStr("component_node_uuid").x(), p_iface->getAttribute(XStr("component_node_uuid").x()));
// vlink_iface->setAttribute(XStr("component_interface_id").x(), p_iface->getAttribute(XStr("component_interface_id").x()));
XStr component_interface_name (vlink_iface->getAttribute(XStr("component_interface_id").x()));
XStr virtual_interface_name (vlink_iface->getAttribute(XStr("virtual_interface_id").x()));
XStr component_interface_id (vlink_iface->getAttribute(XStr("component_interface_id").x()));
XStr virtual_interface_id (vlink_iface->getAttribute(XStr("virtual_interface_id").x()));
// Get the interface for the node and update
DOMElement* vnode_iface_decl = getElementByAttributeValue(vnode, "interface", "virtual_id", virtual_interface_name.c());
vnode_iface_decl->setAttribute (XStr("component_name").x(), component_interface_name.x());
DOMElement* vnode_iface_decl = getElementByAttributeValue(vnode, "interface", "virtual_id", virtual_interface_id.c());
vnode_iface_decl->setAttribute (XStr("component_id").x(), component_interface_id.x());
}
// Copies the component spec from the source to the destination
......@@ -203,9 +206,10 @@ void annotate_rspec::copy_component_spec(const DOMElement* src, DOMElement* dst)
}
// If the interface belongs to an end point of the link, and additional virtual_id attribute has to be added to it
void annotate_rspec::set_interface_as_link_endpoint (DOMElement* interface, const char* virtual_id)
void annotate_rspec::set_interface_as_link_endpoint (DOMElement* interface, const char* virtual_node_id, const char* virtual_interface_id)
{
interface->setAttribute(XStr("virtual_id").x(), XStr(virtual_id).x());
interface->setAttribute(XStr("virtual_node_id").x(), XStr(virtual_node_id).x());
interface->setAttribute(XStr("virtual_interface_id").x(), XStr(virtual_interface_id).x());
}
// Finds the next link in the path returned by assign
......
......@@ -46,8 +46,8 @@ class annotate_rspec : public annotate
// Creates a hop from a switch till the next end point. Adds the hop to the vlink and returns the hop element that was created
xercesc::DOMElement* create_component_hop (const xercesc::DOMElement* plink, xercesc::DOMElement* vlink, int endpoint_interface, const xercesc::DOMElement* prev_component_hop);
// If the interface is the end point of a link/path, add an additional attribute to it
void set_interface_as_link_endpoint (xercesc::DOMElement* interface, const char* _id);
// If the interface is the end point of a link/path, add two additional attributes to it
void set_interface_as_link_endpoint (xercesc::DOMElement* interface, const char* virtual_node_id, const char* virtual_interface_id);
// Finds the next link in the path returned by assign
xercesc::DOMElement* find_next_link_in_path (xercesc::DOMElement *prev, std::list<const char*>* links);
......
......@@ -8,7 +8,7 @@
* XML Parser for RSpec ptop files
*/
static const char rcsid[] = "$Id: parse_advertisement_rspec.cc,v 1.5 2009-07-20 08:14:00 ricci Exp $";
static const char rcsid[] = "$Id: parse_advertisement_rspec.cc,v 1.6 2009-10-08 00:31:59 tarunp Exp $";
#ifdef WITH_XML
......@@ -344,9 +344,7 @@ bool populate_nodes_rspec(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
if( !strcmp( exclusive, "false" ) )
p->features.push_front( tb_node_featuredesire( feature,
1.0,
true,
featuredesire::FD_TYPE_NORMAL) );
1.0, true, featuredesire::FD_TYPE_NORMAL) );
}
/*
......@@ -524,6 +522,7 @@ bool populate_links_rspec(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
src_iface = source.component_interface_name;
dst_node = dest.component_node_uuid;
dst_iface = dest.component_interface_name;
if (src_node.compare("") == 0 || src_iface.compare("") == 0)
{
cerr << "Physical link " << str_component_uuid << " must have a component uuid and component interface name specified for the source node" << endl;
......
......@@ -8,7 +8,7 @@
* XML Parser for RSpec ptop files
*/
static const char rcsid[] = "$Id: parse_request_rspec.cc,v 1.14 2009-10-07 20:48:27 stoller Exp $";
static const char rcsid[] = "$Id: parse_request_rspec.cc,v 1.15 2009-10-08 00:31:59 tarunp Exp $";
#ifdef WITH_XML
......@@ -62,8 +62,8 @@ int bind_vtop_subnodes(tb_vgraph &vg);
* These are not meant to be used outside of this file, so they are only
* declared in here
*/
bool populate_nodes_rspec(DOMElement *root, tb_vgraph &vg);
bool populate_links_rspec(DOMElement *root, tb_vgraph &vg);
bool populate_nodes_rspec(DOMElement *root, tb_vgraph &vg, map< pair<string, string>, pair<string, string> >* fixed_interfaces);
bool populate_links_rspec(DOMElement *root, tb_vgraph &vg, map< pair<string, string>, pair<string, string> >* fixed_interfaces);
bool populate_vclasses_rspec (DOMElement *root, tb_vgraph &vg);
bool hasComponentSpec (DOMElement* element);
......@@ -134,24 +134,27 @@ int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
XStr generated (request_root->getAttribute(XStr("generated").x()));
XStr valid_until(request_root->getAttribute(XStr("valid_until").x()));
map< pair<string, string>, pair<string, string> > fixed_interfaces;
//map< pair<string, string>, pair<string, string> >();
/*
* These three calls do the real work of populating the assign data
* structures
*/
// clock_t startNode = clock();
XMLDEBUG("starting node population" << endl);
if (!populate_nodes_rspec(request_root,vg)) {
cerr << "Error reading nodes from virtual topology " << filename << endl;
exit(EXIT_FATAL);
if (!populate_nodes_rspec(request_root,vg, &fixed_interfaces)) {
cerr << "Error reading nodes from virtual topology " << filename << endl;
exit(EXIT_FATAL);
}
XMLDEBUG("finishing node population" << endl);
// //cerr << "Time taken : " << (clock() - startNode) / CLOCKS_PER_SEC << endl;
// clock_t startLink = clock();
XMLDEBUG("starting link population" << endl);
if (!populate_links_rspec(request_root,vg)) {
cerr << "Error reading links from virtual topology " << filename << endl;
exit(EXIT_FATAL);
if (!populate_links_rspec(request_root,vg, &fixed_interfaces)) {
cerr << "Error reading links from virtual topology " << filename << endl;
exit(EXIT_FATAL);
}
XMLDEBUG("finishing link population" << endl);
// //cerr << "Time taken : " << (clock() - startLink) / CLOCKS_PER_SEC << endl;
......@@ -172,7 +175,7 @@ int parse_vtop_rspec(tb_vgraph &vg, char *filename) {
/*
* Pull nodes from the document, and populate assign's own data structures
*/
bool populate_nodes_rspec(DOMElement *root, tb_vgraph &vg) {
bool populate_nodes_rspec(DOMElement *root, tb_vgraph &vg, map< pair<string, string>, pair<string, string> >* fixed_interfaces) {
bool is_ok = true;
/*
* Get a list of all nodes in this document
......@@ -218,18 +221,40 @@ bool populate_nodes_rspec(DOMElement *root, tb_vgraph &vg) {
if (str_virtual_uuid == "")
{
cerr << "Every node must have a virtual_id" << endl;
cerr << "ERROR: Every node must have a virtual_id" << endl;
is_ok = false;
continue;
}
DOMNodeList *interfaces = elt->getElementsByTagName(XStr("interface").x());
string *str_virtual_interface_names = new string [interfaces->getLength()];
string *str_component_interface_names = new string [interfaces->getLength()];
string *str_interface_virtual_ids = new string [interfaces->getLength()];
string *str_interface_component_ids = new string [interfaces->getLength()];
for (int index = 0; index < interfaces->getLength(); ++index)
{
str_virtual_interface_names[index] = string(XStr((dynamic_cast<DOMElement*>(interfaces->item(index)))->getAttribute(XStr("virtual_id").x())).c());
str_component_interface_names[index] = string(XStr((dynamic_cast<DOMElement*>(interfaces->item(index)))->getAttribute(XStr("component_id").x())).c());
DOMElement* interface = dynamic_cast<DOMElement*>(interfaces->item(index));
str_interface_virtual_ids[index] = string(XStr(interface->getAttribute(XStr("virtual_id").x())).c());
if (interface->hasAttribute(XStr("component_id").x()))
{
string component_id = string(XStr(interface->getAttribute(XStr("component_id").x())).c());
string component_uuid = str_component_uuid;
if (component_uuid == "")
{
cerr << "ERROR: Found a fixed interface (" << str_interface_virtual_ids[index] << ") on an unfixed node (" << str_virtual_uuid << ")" << endl;
is_ok = false;
continue;
}
pair<map< pair<string, string>, pair<string, string> > :: iterator, bool> rv
= fixed_interfaces->insert(make_pair(
make_pair(str_virtual_uuid, str_interface_virtual_ids[index]),
make_pair(str_component_uuid, component_id)));
if (rv.second == false)
{
is_ok = false;
cerr << "The node-interface pair (" << str_virtual_uuid << "," << str_interface_virtual_ids[index] << ") was not unique.";
cerr << "Interfaces within a node must have unique identifiers."<< endl;
continue;
}
}
}
/* Deal with the location tag */
......@@ -429,7 +454,7 @@ bool populate_nodes_rspec(DOMElement *root, tb_vgraph &vg) {
/*
* Pull the links from the ptop file, and populate assign's own data sturctures
*/
bool populate_links_rspec(DOMElement *root, tb_vgraph &vg) {
bool populate_links_rspec(DOMElement *root, tb_vgraph &vg, map< pair<string, string>, pair<string, string> >* fixed_interfaces) {
bool is_ok = true;
......@@ -562,11 +587,32 @@ bool populate_links_rspec(DOMElement *root, tb_vgraph &vg) {
bool allow_delayed = true;
//bool allow_trivial = false;
bool allow_trivial = true;
map< pair<string,string>, pair<string,string> >::iterator it;
bool fix_src_iface = false;
bool fix_dst_iface = false;
fstring fixed_src_iface = "";
it = fixed_interfaces->find(pair<string,string>(src_node.c_str(), src_iface.c_str()));
if (it != fixed_interfaces->end())
{
cerr << "Found fixed source interface (" << (it->second).first << "," << (it->second).second << ") on (" << (it->first).first << "," << (it->first).second << ")" << endl;
fix_src_iface = true;
fixed_src_iface = (it->second).second;
}
bool fix_dst_iface = false;
fstring fixed_dst_iface = "";
it = fixed_interfaces->find(make_pair(dst_node, src_iface));
if (it != fixed_interfaces->end())
{
cerr << "Found fixed destination interface (" << (it->second).first << "," << (it->second).second << ") on (" << (it->first).first << "," << (it->first).second << ")" << endl;
fix_dst_iface = true;
fixed_dst_iface = (it->second).second;
}
/* bool allow_trivial = false;
#ifdef ALLOW_TRIVIAL_DEFAULT
......
......@@ -97,6 +97,10 @@
</xs:simpleType>
</xs:element>
<xs:element name="packet_loss">
<xs:annotation>
<xs:documentation>Static packet loss probability of the link as a fraction
(ie. 0.01 == 1%)</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:float">
<xs:minInclusive value="0.0"/>
......
......@@ -24,6 +24,10 @@
</xs:annotation>
</xs:attribute>
<xs:attribute name="type_slots" use="required">
<xs:annotation>
<xs:documentation>How many virtual nodes of this type this physical node can
handle.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:union>
<xs:simpleType>
......@@ -40,6 +44,14 @@
</xs:simpleType>
</xs:attribute>
<xs:attribute name="static">
<xs:annotation>
<xs:documentation>element unlimited { empty }?,
A flag that indicates that this physical node *always*
has this type - a node is only allowed to have one dynamic
(ie. not flagged as static) type at a time, but any number
of static types at a time
element static { empty }?</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="true"/>
......@@ -56,6 +68,15 @@
</xs:sequence>
</xs:complexType>
<xs:group name="LinkTypeSpec">
<xs:annotation>
<xs:documentation>Link types are currently just a siple string. They will almost certainly
have to get more complicated, for two reasons:
First, I want to allow virtual links to specify more than one type, so
that we can ask for links that are, say, 'ethernet or loopback'
Second, I want to have a lot more control over links that get mapped to
multi-hop paths
TODO: MAYBE this should be combined with NodeTypeSpec</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="link_type">
<xs:complexType>
......@@ -65,6 +86,10 @@
</xs:sequence>
</xs:group>
<xs:group name="LinkEndPoints">
<xs:annotation>
<xs:documentation>A link has two endpoints. Right now, they are order
independent. But they might become order-dependant later.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element ref="rspec:source_interface"/>
<xs:element ref="rspec:destination_interface"/>
......@@ -81,6 +106,11 @@
</xs:annotation>
</xs:element>
<xs:group name="LinkCharacteristics">
<xs:annotation>
<xs:documentation>Link characterstics which affect traffic.
TODO: In the future, the bandwidth, latency, and packet loss will be
moved to features and/or properties</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element ref="rspec:bandwidth"/>
<xs:element ref="rspec:latency"/>
......@@ -89,9 +119,24 @@
</xs:group>
<xs:element name="fd">
<xs:complexType>
<xs:attribute name="fd_name" use="required"/>
<xs:attribute name="fd_weight" use="required"/>
<xs:attribute name="fd_name" use="required">
<xs:annotation>
<xs:documentation>Name of this feature or desire
element fd_name { text },</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="fd_weight" use="required">
<xs:annotation>
<xs:documentation>Weight assocated with the feature or desire
element fd_weight { xsd:float },</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="violatable">
<xs:annotation>
<xs:documentation>A flag indicating whether or not a failure to match the desire with a
a feature is a constraint violation
element violatable { empty }?,</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="true"/>
......@@ -116,6 +161,11 @@
</xs:complexType>
</xs:element>
<xs:attributeGroup name="GlobalSpec">
<xs:annotation>
<xs:documentation>GlobalSpec = element global {
element operator { "OnceOnly" | "FirstFree" }
}</xs:documentation>
</xs:annotation>
<xs:attribute name="global_operator" use="required">
<xs:simpleType>
<xs:restriction base="xs:token">
......@@ -126,6 +176,12 @@
</xs:attribute>
</xs:attributeGroup>
<xs:attributeGroup name="LocalSpec">
<xs:annotation>
<xs:documentation>LocalSpec = element local {
element operator { "+" }
attribute local_operator { "+" }
}</xs:documentation>
</xs:annotation>
<xs:attribute name="local_operator" use="required">
<xs:simpleType>
<xs:restriction base="xs:token">
......@@ -135,6 +191,10 @@
</xs:attribute>
</xs:attributeGroup>
<xs:complexType name="InterfaceSpec">
<xs:annotation>
<xs:documentation>Interfaces
InterfaceSpec = element interface { InterfaceContents }</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="rspec:property"/>
</xs:sequence>
......@@ -194,7 +254,12 @@
<xs:documentation>Name of this property</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="property_value" type="xs:string"/>
<xs:element name="property_value" type="xs:string">
<xs:annotation>
<xs:documentation>Value associated with this property
TODO: Add ranges and other types from rspec</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="property_penalty">
<xs:annotation>
<xs:documentation>The penalty associated with this property</xs:documentation>
......
......@@ -94,6 +94,10 @@
</xs:simpleType>
</xs:element>
<xs:element name="packet_loss">
<xs:annotation>
<xs:documentation>Static packet loss probability of the link as a fraction
(ie. 0.01 == 1%)</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:float">
<xs:minInclusive value="0.0"/>
......
......@@ -24,6 +24,10 @@
</xs:annotation>
</xs:attribute>
<xs:attribute name="type_slots" use="required">
<xs:annotation>
<xs:documentation>How many virtual nodes of this type this physical node can
handle.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:union>
<xs:simpleType>
......@@ -40,6 +44,14 @@
</xs:simpleType>
</xs:attribute>
<xs:attribute name="static">
<xs:annotation>
<xs:documentation>element unlimited { empty }?,
A flag that indicates that this physical node *always*
has this type - a node is only allowed to have one dynamic
(ie. not flagged as static) type at a time, but any number
of static types at a time
element static { empty }?</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="true"/>
......@@ -56,6 +68,15 @@
</xs:sequence>
</xs:complexType>
<xs:group name="LinkTypeSpec">
<xs:annotation>
<xs:documentation>Link types are currently just a siple string. They will almost certainly
have to get more complicated, for two reasons:
First, I want to allow virtual links to specify more than one type, so
that we can ask for links that are, say, 'ethernet or loopback'
Second, I want to have a lot more control over links that get mapped to
multi-hop paths
TODO: MAYBE this should be combined with NodeTypeSpec</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="link_type">
<xs:complexType>
......@@ -65,6 +86,10 @@
</xs:sequence>
</xs:group>
<xs:group name="LinkEndPoints">
<xs:annotation>
<xs:documentation>A link has two endpoints. Right now, they are order
independent. But they might become order-dependant later.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element ref="rspec:source_interface"/>
<xs:element ref="rspec:destination_interface"/>
......@@ -81,6 +106,11 @@
</xs:annotation>
</xs:element>
<xs:group name="LinkCharacteristics">
<xs:annotation>
<xs:documentation>Link characterstics which affect traffic.
TODO: In the future, the bandwidth, latency, and packet loss will be
moved to features and/or properties</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element ref="rspec:bandwidth"/>
<xs:element ref="rspec:latency"/>
......@@ -89,9 +119,24 @@
</xs:group>
<xs:element name="fd">
<xs:complexType>
<xs:attribute name="fd_name" use="required"/>
<xs:attribute name="fd_weight" use="required"/>
<xs:attribute name="fd_name" use="required">
<xs:annotation>
<xs:documentation>Name of this feature or desire
element fd_name { text },</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="fd_weight" use="required">
<xs:annotation>
<xs:documentation>Weight assocated with the feature or desire
element fd_weight { xsd:float },</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="violatable">
<xs:annotation>
<xs:documentation>A flag indicating whether or not a failure to match the desire with a
a feature is a constraint violation
element violatable { empty }?,</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="true"/>
......@@ -116,6 +161,11 @@
</xs:complexType>
</xs:element>
<xs:attributeGroup name="GlobalSpec">
<xs:annotation>
<xs:documentation>GlobalSpec = element global {
element operator { "OnceOnly" | "FirstFree" }
}</xs:documentation>
</xs:annotation>
<xs:attribute name="global_operator" use="required">
<xs:simpleType>
<xs:restriction base="xs:token">
......@@ -126,6 +176,12 @@
</xs:attribute>
</xs:attributeGroup>
<xs:attributeGroup name="LocalSpec">
<xs:annotation>
<xs:documentation>LocalSpec = element local {
element operator { "+" }
attribute local_operator { "+" }
}</xs:documentation>
</xs:annotation>
<xs:attribute name="local_operator" use="required">
<xs:simpleType>
<xs:restriction base="xs:token">
......@@ -135,6 +191,10 @@
</xs:attribute>
</xs:attributeGroup>
<xs:complexType name="InterfaceSpec">
<xs:annotation>
<xs:documentation>Interfaces
InterfaceSpec = element interface { InterfaceContents }</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="rspec:property"/>
</xs:sequence>
......@@ -194,7 +254,12 @@
<xs:documentation>Name of this property</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="property_value" type="xs:string"/>
<xs:element name="property_value" type="xs:string">
<xs:annotation>
<xs:documentation>Value associated with this property
TODO: Add ranges and other types from rspec</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="property_penalty">
<xs:annotation>
<xs:documentation>The penalty associated with this property</xs:documentation>
......
......@@ -52,13 +52,18 @@ RSpecContents &=
LinkMapping =
element component_hop { ComponentName, InterfaceMapping* }+
VirtualInterfaceRefName =
(attribute virtual_node_id { text } &
attribute virtual_interface_id { text })
# Each interface represents a particular physical interface. If that
# interface is one of the link end points, it is also mapped to that
# virtual interface name.
InterfaceMapping = element interface_ref {
ComponentInterfaceRefName |
(attribute virtual_node_id { text } &
attribute virtual_interface_id { text })
ComponentInterfaceRefName &
VirtualInterfaceRefName?
# (attribute virtual_node_id { text } &
# attribute virtual_interface_id { text })?
# VirtualName ?
}
......
......@@ -34,6 +34,10 @@
<xs:attributeGroup ref="rspec:ComponentName"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="VirtualInterfaceRefName">
<xs:attribute name="virtual_node_id" use="required"/>
<xs:attribute name="virtual_interface_id" use="required"/>
</xs:attributeGroup>
<!--
Each interface represents a particular physical interface. If that
interface is one of the link end points, it is also mapped to that
......@@ -43,9 +47,7 @@
<xs:sequence>
<xs:element name="interface_ref">
<xs:complexType>
<xs:attribute name="component_node_uuid"/>
<xs:attribute name="component_node_urn"/>
<xs:attribute name="component_interface_id"/>
<xs:attributeGroup ref="rspec:ComponentInterfaceRefName"/>
<xs:attribute name="virtual_node_id"/>
<xs:attribute name="virtual_interface_id"/>
</xs:complexType>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment