Commit 6ce7b1ad authored by Tarun Prabhu's avatar Tarun Prabhu
Browse files

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/users/tarunp/emulab-devel

parents 8149d4cb 3e5b07d6
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2009 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
......@@ -271,7 +271,6 @@ system("$OPENSSL ca -batch -policy policy_sslxmlrpc ".
" -infiles syscert_req.pem $outline") == 0
or fatal("Could not sign certificate request");
$UID = $SAVEUID;
TBScriptUnlock();
#
# Combine the key and the certificate into one file
......@@ -288,6 +287,7 @@ else {
system("cat syscert_key.pem syscert_cert.pem") == 0
or fatal("Could not combine cert and key");
}
TBScriptUnlock();
exit(0);
sub fatal($) {
......
......@@ -37,11 +37,13 @@ CXXFLAGS += -I/sw/include
ifeq ($(HAVE_XERCES),yes)
CXXFLAGS += -DWITH_XML
LIBS += -L/usr/local/lib -lxerces-c
OBJS += parse_ptop_xml.o parse_vtop_xml.o parse_policy_xml.o parse_error_handler.o xmlhelpers.o parse_advertisement_rspec.o parse_request_rspec.o annotate_rspec.o annotate_vtop.o annotate.o rspec_parser_helper.o rspec_parser.o rspec_parser_v1.o rspec_parser_v2.o emulab_extensions_parser.o
OBJS += parse_ptop_xml.o parse_vtop_xml.o parse_policy_xml.o parse_error_handler.o xmlhelpers.o parse_advertisement_rspec.o parse_request_rspec.o annotate_rspec_v2.o annotate_rspec.o annotate_vtop.o annotate.o rspec_parser_helper.o rspec_parser.o rspec_parser_v1.o rspec_parser_v2.o emulab_extensions_parser.o
endif
# Pick either this
CXXFLAGS += -O3
# XXX: Get rid of this once done testing
# CXXFLAGS += -g
# or this
#CXXFLAGS += -O0 -g -Wall -DVERBOSE
# and then zero or more of these
......@@ -114,6 +116,7 @@ anneal.o: anneal.cc anneal.h port.h delay.h physical.h common.h fstring.h \
solution.h vclass.h neighborhood.h
annotate.o: annotate.cc
annotate_rspec.o: annotate_rspec.cc
annotate_rspec_v2.o: annotate_rspec_v2.cc
annotate_vtop.o: annotate_vtop.cc
assign.o: assign.cc port.h common.h fstring.h delay.h physical.h \
featuredesire.h forwarding.h virtual.h vclass.h pclass.h score.h \
......
......@@ -8,8 +8,6 @@
* Base class for the annotater.
*/
/* This is ugly, but we only really need this file if we are building with XML support */
#ifdef WITH_XML
#ifndef __ANNOTATE_H
......@@ -25,26 +23,34 @@
class annotate
{
protected:
//xercesc::DOMDocument* doc;
xercesc::DOMElement* virtual_root;
std::map<std::string, xercesc::DOMElement*> *physical_elements;
public:
// Annotates nodes and direct links in the rspec
virtual void annotate_element(const char* v_name, const char* p_name) = 0;
// Annotates intraswitch and interswitch links in the rspec
virtual void annotate_element(const char* v_name, std::list<const char*>* links) = 0;
// 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
virtual xercesc::DOMElement* create_component_hop (const xercesc::DOMElement* plink, xercesc::DOMElement* vlink, int endpoint_interface, const xercesc::DOMElement* prev_component_hop) = 0;
// Finds the next link in the path returned by assign
virtual xercesc::DOMElement* find_next_link_in_path (xercesc::DOMElement *prev, std::list<const char*>* links) = 0;
// Writes the annotated xml to disk
void write_annotated_file(const char* filename);
protected:
//xercesc::DOMDocument* doc;
xercesc::DOMElement* virtual_root;
std::map<std::string, xercesc::DOMElement*> *physical_elements;
public:
// Annotates nodes and direct links in the rspec
virtual void annotate_element(const char* v_name, const char* p_name) = 0;
// Annotates intraswitch and interswitch links in the rspec
virtual void annotate_element(const char* v_name,
std::list<const char*>* links) = 0;
// 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
virtual xercesc::DOMElement*
create_component_hop (const xercesc::DOMElement* plink,
xercesc::DOMElement* vlink,
int endpoint_interface,
const xercesc::DOMElement* prev_component_hop) = 0;
// Finds the next link in the path returned by assign
virtual xercesc::DOMElement*
find_next_link_in_path (xercesc::DOMElement *prev,
std::list<const char*>* links) = 0;
// Writes the annotated xml to disk
void write_annotated_file(const char* filename);
};
#endif // for __ANNOTATE_H
......
......@@ -25,89 +25,89 @@
class annotate_rspec : public annotate
{
private:
// Enumeration of which interface in a hop
// is an interface to a link end point
enum endpoint_interface_enum { NEITHER, SOURCE, DESTINATION, BOTH };
std::map< std::string, std::set<std::string> > lan_links_map;
public:
annotate_rspec ();
~annotate_rspec () { ; }
// Annotates nodes and direct links in the rspec
void annotate_element(const char* v_name, const char* p_name);
// Annotates intraswitch and interswitch links in the rspec
void annotate_element(const char* v_name,
std::list<const char*>* links);
// Annotate a trivial link
void annotate_element(const char* v_name);
// Annotates an interface element on a link
void annotate_interface (const xercesc::DOMElement* plink,
const xercesc::DOMElement* vlink,
int interface_number,
bool is_trivial_link);
// Annotates an interface element on a non-trivial link
void annotate_interface (const xercesc::DOMElement* plink,
const xercesc::DOMElement* vlink,
int interface_number);
// Annotates an interface element on a trivial link
void annotate_interface (const xercesc::DOMElement* vlink,
int interface_number);
// Creates a hop from a switch till the next end point.
// Adds the hop to the vlink
// 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_hop);
// Creates a component_hop for a trivial link
// Adds the hop to the vlink
// Returns the hop element that was created
xercesc::DOMElement* create_component_hop (xercesc::DOMElement* vlink);
// 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);
// Copies the component spec from the source to the destination
void copy_component_spec(const xercesc::DOMElement* src,
xercesc::DOMElement* dst);
// Copies the component hop from the auto-generated link
// to the requested link
void copy_component_hop(xercesc::DOMElement* requested_link,
xercesc::DOMElement* component_hop);
// Checks if the link contains an interface with
// virtual_interface_id = id
bool has_interface_with_id (std::string link_id, std::string id);
// Removes all extra tags and generated elements from the XML document
void cleanup ();
// Checks whether an element of type tag
// with attr_name = attr_value is a generated element
bool is_generated_element (const char* tag,
const char* attr_name,
const char* attr_value);
private:
// Enumeration of which interface in a hop
// is an interface to a link end point
enum endpoint_interface_enum { NEITHER, SOURCE, DESTINATION, BOTH };
std::map< std::string, std::set<std::string> > lan_links_map;
public:
annotate_rspec ();
~annotate_rspec () { ; }
// Annotates nodes and direct links in the rspec
virtual void annotate_element(const char* v_name, const char* p_name);
// Annotates intraswitch and interswitch links in the rspec
virtual void annotate_element(const char* v_name,
std::list<const char*>* links);
// Annotate a trivial link
virtual void annotate_element(const char* v_name);
// Annotates an interface element on a link
virtual void annotate_interface (const xercesc::DOMElement* plink,
const xercesc::DOMElement* vlink,
int interface_number,
bool is_trivial_link);
// Annotates an interface element on a non-trivial link
virtual void annotate_interface (const xercesc::DOMElement* plink,
const xercesc::DOMElement* vlink,
int interface_number);
// Annotates an interface element on a trivial link
virtual void annotate_interface (const xercesc::DOMElement* vlink,
int interface_number);
// Creates a hop from a switch till the next end point.
// Adds the hop to the vlink
// Returns the hop element that was created
virtual xercesc::DOMElement*
create_component_hop (const xercesc::DOMElement* plink,
xercesc::DOMElement* vlink,
int endpoint_interface,
const xercesc::DOMElement* prev_hop);
// Creates a component_hop for a trivial link
// Adds the hop to the vlink
// Returns the hop element that was created
virtual xercesc::DOMElement* create_component_hop (xercesc::DOMElement* vlink);
// If the interface is the end point of a link/path,
// add two additional attributes to it
virtual 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
virtual xercesc::DOMElement* find_next_link_in_path
(xercesc::DOMElement *prev,
std::list<const char*>* links);
// Copies the component spec from the source to the destination
virtual void copy_component_spec(const xercesc::DOMElement* src,
xercesc::DOMElement* dst);
// Copies the component hop from the auto-generated link
// to the requested link
virtual void copy_component_hop(xercesc::DOMElement* requested_link,
xercesc::DOMElement* component_hop);
// Checks if the link contains an interface with
// virtual_interface_id = id
virtual bool has_interface_with_id (std::string link_id, std::string id);
// Removes all extra tags and generated elements from the XML document
virtual void cleanup ();
// Checks whether an element of type tag
// with attr_name = attr_value is a generated element
virtual bool is_generated_element (const char* tag,
const char* attr_name,
const char* attr_value);
};
#endif //for __ANNOTATE_RSPEC_H
#endif // for WITH_XML
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2003-2009 University of Utah and the Flux Group.
* All rights reserved.
*/
static const char rcsid[] = "$Id: annotate_rspec_v2.cc,v 1.9 2009-10-21 20:49:26 tarunp Exp $";
#ifdef WITH_XML
#include "annotate.h"
#include "annotate_rspec_v2.h"
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include "xstr.h"
#include "xmlhelpers.h"
#include <iostream>
#include <utility>
#include <list>
#include <string>
#define XMLDEBUG(x) (cerr << x);
extern DOMDocument* doc;
extern DOMElement* request_root;
extern map<string, DOMElement*>* advertisement_elements;
XERCES_CPP_NAMESPACE_USE
using namespace std;
annotate_rspec_v2 :: annotate_rspec_v2 ()
{
this->virtual_root = request_root;
this->physical_elements = advertisement_elements;
vector<DOMElement*> lan_links
= getElementsHavingAttribute(this->virtual_root, "link", "is_lan");
vector<DOMElement*>::iterator it;
for (it = lan_links.begin(); it < lan_links.end(); it++) {
DOMElement* lan_link = *it;
// Removing annotations inserted earlier
lan_link->removeAttribute(XStr("is_lan").x());
string lan_link_id
= string(XStr(lan_link->getAttribute(XStr("client_id").x())).c());
set<string> virtual_interface_ids;
DOMNodeList* interfaces
= lan_link->getElementsByTagName(XStr("interface_ref").x());
for (int j = 0; j < interfaces->getLength(); j++) {
DOMElement* interface = dynamic_cast<DOMElement*>(interfaces->item(j));
virtual_interface_ids.insert
(string(XStr(interface->getAttribute
(XStr("virtual_interface_id").x())).c()));
}
this->lan_links_map.insert
(pair< string, set<string> >(lan_link_id, virtual_interface_ids));
}
}
// Annotate a trivial link
void annotate_rspec_v2::annotate_element (const char* v_name)
{
DOMElement* vlink
= getElementByAttributeValue(this->virtual_root,
"link", "client_id", v_name);
annotate_interface (vlink, 0);
annotate_interface (vlink, 1);
create_component_hop(vlink);
}
// This will get called when a node or a direct link needs to be annotated
void annotate_rspec_v2::annotate_element (const char* v_name, const char* p_name)
{
DOMElement* vnode
= getElementByAttributeValue(this->virtual_root,
"node", "client_id", v_name);
// If a vnode by that name was found, then go ahead.
// If not, that element should be a link
// We are not terribly concerned about
// having to scan the entire physical topology twice
// because direct links are never really going to happen
if (vnode != NULL) {
if (!vnode->hasAttribute(XStr("generated_by_assign").x())) {
DOMElement* pnode = (this->physical_elements->find(p_name))->second;
vnode->setAttribute(XStr("component_id").x(),
pnode->getAttribute(XStr("component_id").x()));
vnode->setAttribute(XStr("component_manager_id").x(),
pnode->getAttribute(XStr("component_manager_id").x()));
}
}
else {
DOMElement* vlink
= getElementByAttributeValue(this->virtual_root,
"link", "client_id", v_name);
DOMElement* plink = (this->physical_elements->find(p_name))->second;
// If plink is NULL, then it must be a trivial link
if (plink == NULL) {
}
annotate_interface (plink, vlink, 0);
annotate_interface (plink, vlink, 1);
create_component_hop(plink, vlink, BOTH, NULL);
if (vlink->hasAttribute(XStr("generated_by_assign").x())) {
string str_lan_link
= string(XStr(vlink->getAttribute(XStr("lan_link").x())).c());
DOMElement* lan_link
= getElementByAttributeValue(this->virtual_root, "link",
"client_id",
str_lan_link.c_str());
DOMNodeList* component_hops
= vlink->getElementsByTagName(XStr("component_hop").x());
for (int i = 0; i < component_hops->getLength(); i++) {
DOMElement* component_hop
= dynamic_cast<DOMElement*>(component_hops->item(i));
copy_component_hop(lan_link, component_hop);
}
}
}
}
// This is called when an intraswitch or interswitch link has to be annotated
void annotate_rspec_v2::annotate_element (const char* v_name,
list<const char*>* links)
{
// These are the paths from the source to the first switch
// and from the last switch to the destination
const char* psrc_name = links->front();
const char* pdst_name = links->back();
DOMElement* p_src_switch_link
= (this->physical_elements->find(psrc_name))->second;
DOMElement* p_switch_dst_link
= (this->physical_elements->find(pdst_name))->second;
// Remove these links from the list
// If it is an intra-switch link, the list should now be empty.
links->pop_front();
links->pop_back();
DOMElement* vlink
= getElementByAttributeValue (this->virtual_root, "link",
"client_id", v_name);
annotate_interface(p_src_switch_link, vlink, 0);
annotate_interface(p_switch_dst_link, vlink, 1);
DOMElement* prev_component_hop
= create_component_hop (p_src_switch_link, vlink, SOURCE, NULL);
#if 0
for (DOMElement *prev_link_in_path = p_src_switch_link; !links->empty(); ) {
DOMElement* p_switch_switch_link
= find_next_link_in_path (prev_link_in_path, links);
prev_component_hop
= create_component_hop (p_switch_switch_link,
vlink, NEITHER, prev_component_hop);
prev_link_in_path = p_switch_switch_link;
}
#else
{
static int gave_apology;
if( !links->empty() && !gave_apology ) {
gave_apology = 1;
cerr << "Warning: unable to locate interfaces on "
"switch/switch links; omitting those\n";
}
}
#endif
{
create_component_hop (p_switch_dst_link,
vlink, DESTINATION, prev_component_hop);
}
}
// Creates a component_hop for a trivial link
// Adds the hop to the vlink and returns the hop element that was created
DOMElement* annotate_rspec_v2::create_component_hop (DOMElement* vlink)
{
DOMNodeList* interfaces
= vlink->getElementsByTagName(XStr("interface_ref").x());
DOMElement* src_iface = dynamic_cast<DOMElement*>(interfaces->item(0));
DOMElement* dst_iface = dynamic_cast<DOMElement*>(interfaces->item(1));
const char* src_id
= XStr(src_iface->getAttribute(XStr("virtual_node_id").x())).c();
const char* dst_id
= XStr(dst_iface->getAttribute(XStr("virtual_node_id").x())).c();
DOMElement* src_vnode
= getElementByAttributeValue(this->virtual_root,
"node", "client_id", src_id);
DOMElement* dst_vnode
= getElementByAttributeValue(this->virtual_root,
"node", "client_id", dst_id);
XStr src_component_id (find_urn(src_vnode, "component"));
XStr dst_component_id (find_urn(dst_vnode, "component"));
DOMElement* component_hop = doc->createElement(XStr("component_hop").x());
DOMElement* src_iface_clone
= dynamic_cast<DOMElement*>
(doc->importNode(dynamic_cast<DOMNode*>(src_iface),true));
src_iface_clone->setAttribute(XStr("component_node_id").x(),
src_component_id.x());
src_iface_clone->setAttribute(XStr("component_interface_id").x(),
XStr("loopback").x());
cerr << src_component_id.c() << " AND " << dst_component_id.c() << endl;
DOMElement* dst_iface_clone
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(dst_iface),true));
dst_iface_clone->setAttribute(XStr("component_node_id").x(),
dst_component_id.x());
dst_iface_clone->setAttribute(XStr("component_interface_id").x(),
XStr("loopback").x());
component_hop->appendChild(src_iface_clone);
component_hop->appendChild(dst_iface_clone);
vlink->appendChild(component_hop);
return component_hop;
}
// 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
DOMElement*
annotate_rspec_v2::create_component_hop (const DOMElement* plink,
DOMElement* vlink,
int endpoint_interface,
const DOMElement* prev_component_hop)
{
// Create a single_hop_link element
DOMElement* component_hop = doc->createElement(XStr("component_hop").x());
copy_component_spec(plink, component_hop);
DOMElement* component_hop_interface
= doc->createElement(XStr("interface").x());
// We assume the first interface is the source and the second the dest
DOMNodeList* pinterfaces
= plink->getElementsByTagName(XStr("interface_ref").x());
DOMElement* plink_src_iface =dynamic_cast<DOMElement*>(pinterfaces->item(0));
DOMElement* plink_dst_iface =dynamic_cast<DOMElement*>(pinterfaces->item(1));
DOMNodeList* vinterfaces
= vlink->getElementsByTagName(XStr("interface_ref").x());
DOMElement* vlink_src_iface =dynamic_cast<DOMElement*>(vinterfaces->item(0));
DOMElement* vlink_dst_iface =dynamic_cast<DOMElement*>(vinterfaces->item(1));
// If the previous component hop is not specified (NULL),
// then the link is either direct
// or the direction is guaranteed to be from the node to the switch
DOMElement* plink_src_iface_clone
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(plink_src_iface),true));
DOMElement* plink_dst_iface_clone
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(plink_dst_iface),true));
// If the previous component is specified,
// the link specification could be the opposite of what we need
if (prev_component_hop != NULL) {
// Find the destination of the previous component hop
DOMElement* prev_hop_dst_iface
= dynamic_cast<DOMElement*>((prev_component_hop->getElementsByTagName
(XStr("interface_ref").x()))->item(1));
XStr prev_hop_dst_uuid (find_urn(prev_hop_dst_iface, "component_node"));
// We need to do this because in advertisements,
// all links are from nodes to switches
// and we need to reverse this for the last hop of a multi-hop path
// This is slightly more expensive,
// but definitely more robust than checking based on
// whether a destination interface was specified
if (strcmp(prev_hop_dst_uuid.c(),
XStr(find_urn(plink_dst_iface,
"component_node")).c()) == 0) {
plink_src_iface_clone
= dynamic_cast<DOMElement*>
(doc->importNode(dynamic_cast<DOMNode*>
(plink_dst_iface), true));
plink_dst_iface_clone
= dynamic_cast<DOMElement*>
(doc->importNode(dynamic_cast<DOMNode*>
(plink_src_iface), true));
}
}
// 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(),
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(),
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);
component_hop->appendChild(plink_dst_iface_clone);
vlink->appendChild(component_hop);
return (component_hop);
}
// Copies the component_hop from the generated_link to the requsted_link
// Also strips the unnecessary annotations from the component_hop after copying
// The "unnecessary annotations"
// specify the end point of the link to be the auto-generated lan node
// We could just assume that the second interface_ref in the hop contains these
// "unnecessary annotations" since we have generated it in the first place
// and we can sure that it will always be in exactly that same position,
// but it sounds like a dirty way of doing it and is not exactly robust,
// so we shall use the slower, but more robust method