def create_netns_host(create_io_worker, ingress_switch, ip_addr_str="", ip_format_str="10.%d.%d.2", get_switch_port=get_switchs_host_port, cmd='xterm'): ''' Create a host with a process running in a separate network namespace. The netns can only communicate with a single interface (for now) because it must correspond to the physical interface in the network namespace guest. Because there is only 1 logical interface possible, this means that there can only be 1 switch as well. - ip_addr_str must be a string! not a IpAddr object ''' if ip_addr_str == "": ip_addr_str = ip_format_str % (ingress_switch.dpid, get_switch_port(ingress_switch).port_no) host = NamespaceHost(HostInterface(None, ip_addr_str), create_io_worker, cmd=cmd) interface = host.interfaces[0] access_link = AccessLink(host, interface, ingress_switch, get_switch_port(ingress_switch)) return (host, [access_link] ) # single item list to be consistent with create_host
def migrate_host(self, old_ingress_dpid, old_ingress_portno, new_ingress_dpid, new_ingress_portno): ''' Migrate the host from the old (ingress switch, port) to the new (ingress switch, port). Note that the new port must not already be present, otherwise an exception will be thrown (we treat all switches as configurable software switches for convenience, rather than hardware switches with a fixed number of ports) ''' old_ingress_switch = self._get_switch_by_dpid(old_ingress_dpid) if old_ingress_portno not in old_ingress_switch.ports: raise ValueError("unknown old_ingress_portno %d" % old_ingress_portno) old_port = old_ingress_switch.ports[old_ingress_portno] (host, interface) = self(old_ingress_switch, old_port) # using __call__ if not (isinstance(host, Host) and isinstance(interface, HostInterface)): raise ValueError("(%s,%s) does not connect to a host!" % (str(old_ingress_switch), str(old_port))) new_ingress_switch = self._get_switch_by_dpid(new_ingress_dpid) if new_ingress_portno in new_ingress_switch.ports: raise RuntimeError("new ingress port %d already exists!" % new_ingress_portno) # now that we've verified everything, actually make the change! # first, drop the old mappings del self.port2access_link[old_port] del self.interface2access_link[interface] old_ingress_switch.take_port_down(old_port) # now add new mappings # For now, make the new port have the same ip address as the old port. # TODO(cs): this would break PORTLAND routing! Need to specify the # new mac and IP addresses new_ingress_port = ofp_phy_port(port_no=new_ingress_portno, hw_addr=old_port.hw_addr, name="eth%d" % new_ingress_portno, config=old_port.config, state=old_port.state, curr=old_port.curr, advertised=old_port.advertised, supported=old_port.supported, peer=old_port.peer) new_ingress_switch.bring_port_up(new_ingress_port) new_access_link = AccessLink(host, interface, new_ingress_switch, new_ingress_port) self.port2access_link[new_ingress_port] = new_access_link self.interface2access_link[interface] = new_access_link
def create_access_link(self, host, interface, switch, port): ''' Create an access link between a host and a switch If no interface is provided, an unused interface is used If no port is provided, an unused port is used ''' if interface is None: interface = self.find_unused_interface(host) if port is None: port = self.find_unused_port(switch) link = AccessLink(host, interface, switch, port) self.port2access_link[port] = link self.interface2access_link[interface] = link return link
def populate_from_topology(graph): ''' Take a pox.lib.graph.graph.Graph and generate arguments needed for the simulator ''' topology = Topology() topology.hosts = graph.find(is_a=Host) # TODO(cs): broken: can't set attribute topology.switches = graph.find(is_a=SoftwareSwitch) topology.access_links = [ AccessLink(host, switch[0], switch[1][0], switch[1][1]) for host in topology.hosts for switch in filter(lambda n: isinstance(n[1][0], SoftwareSwitch), graph.ports_for_node(host).iteritems()) ] return topology
def create_host(ingress_switch_or_switches, mac_or_macs=None, ip_or_ips=None, get_switch_port=get_switchs_host_port, ip_format_str="10.%d.%d.2"): ''' Create a Host, wired up to the given ingress switches ''' switches = ingress_switch_or_switches if type(switches) != list: switches = [ingress_switch_or_switches] macs = mac_or_macs if mac_or_macs and type(mac_or_macs) != list: macs = [mac_or_macs] ips = ip_or_ips if ip_or_ips and type(ip_or_ips) != list: ips = [ip_or_ips] interfaces = [] interface_switch_pairs = [] for switch in switches: port = get_switch_port(switch) if macs: mac = macs.pop(0) else: mac = EthAddr("12:34:56:78:%02x:%02x" % (switch.dpid, port.port_no)) if ips: ip_addr = ips.pop(0) else: ip_addr = IPAddr(ip_format_str % (switch.dpid, port.port_no)) name = "eth%d" % switch.dpid interface = HostInterface(mac, ip_addr, name) interface_switch_pairs.append((interface, switch)) interfaces.append(interface) name = "host:" + ",".join( map(lambda interface: "%s" % str(interface.ips), interfaces)) host = Host(interfaces, name) access_links = [ AccessLink(host, interface, switch, get_switch_port(switch)) for interface, switch in interface_switch_pairs ] return (host, access_links)