def __route_check(self, o): """Check route @param o route check object (dictionary) """ gw = self.get_if_route(mif=o["mif"]) if gw == None: o["tried"] += 1 if o["tried"] < MAX_RETRY: rc = yapc.priv_callback(self, o) self.server.post_event(rc, 1) else: no = self.switch.if_name2dpid_port_mac(o["if"])[1] mc.set(nat.get_gw_key(no), gw) output.info("Gateway of " + o["if"] + " is " + gw, self.__class__.__name__) # Check for route self.check_default_route() # Register ip range ipv4addr = self.ifmgr.ipv4_addr_n_mask(o["mif"]) if ipv4addr == None: return ipr = ( pu.ip_string2val(ipv4addr["addr"]), pu.ip_string2val(ipv4addr["netmask"]), pu.hex_str2array(self.ifmgr.ethernet_addr(o["mif"])), ) mc.set(nat.get_ip_range_key(no), ipr) output.info( o["if"] + "(" + str(no) + ") has IP address %x and netmask %x" % (ipr[0], ipr[1]), self.__class__.__name__, ) # Call for ARP rc = yapc.priv_callback(self, {"type": "arp", "tried": 0, "ip": gw, "if": o["mif"]}) self.server.post_event(rc, 0)
def setup(self, interfaces, inner_addr=LOCAL_IP, gw=LOCAL_GW, gw_mac=None): """Add interfaces @param interfaces list of interfaces @param inner_addr IP to give COIN's client side interface @param gw gateway to use for COIN's interface @param gw_mac gateway mac address """ # Set up interfaces self.loif = self.add_loif("local") self.add_interfaces(interfaces) # Get IP addresses on the interfaces self.ifmgr.set_ipv4_addr(self.loif.client_intf, inner_addr) mc.set( nat.SW_INNER_PORT_ADDR, (pu.ip_string2val(inner_addr), pu.hex_str2array(self.ifmgr.ethernet_addr(self.loif.client_intf))), ) for i in range(0, len(interfaces)): self.ifmgr.up(interfaces[i]) # Setup route self.ifmgr.add_route("default", gw=gw, iface=self.loif.client_intf) if gw_mac == None: gw_mac = self.ifmgr.ethernet_addr(self.loif.switch_intf) self.ifmgr.set_ip_mac(gw, gw_mac) self.check_default_route()
def processevent(self, event): """Process authentication event """ if (event.host == None): return True if (isinstance(event, owevent.authenticated)): output.dbg( pu.array2hex_str(event.host) + " is authenticated", self.__class__.__name__) mcutil.set(host_auth.get_key(event.host), event.openid, MAX_AUTH_TIMEOUT) elif (isinstance(event, owevent.unauthenticated)): output.dbg( pu.array2hex_str(event.host) + " is unauthenticated", self.__class__.__name__) mcutil.delete(host_auth.get_key(event.host)) mcutil.delete(host_auth.get_auth_key(event.host)) elif (isinstance(event, owevent.going_to_auth)): output.dbg( pu.array2hex_str(event.host) + " is going to authenticate", self.__class__.__name__) mcutil.set(host_auth.get_auth_key(event.host), event.server(), AUTH_TIMEOUT) return True
def processevent(self, event): """Process OpenFlow message for config reply @param event OpenFlow message event to process @return True """ if isinstance(event, ofevents.features_reply): # Get config getconfig = pyof.ofp_header() getconfig.type = pyof.OFPT_GET_CONFIG_REQUEST self.conn.send(event.sock, getconfig.pack()) elif isinstance(event, ofevents.config_reply): # Check if I should set config desired_flags = (event.config.flags | self.default_on_config_flags) & ~self.default_off_config_flags desired_miss_send_len = event.config.miss_send_len if self.default_miss_send_len != None: desired_miss_send_len = self.default_miss_send_len if (event.config.flags != desired_flags) or (desired_miss_send_len != event.config.miss_send_len): # Change config to desired output.dbg( "Set config to desired with flag %x " % desired_flags + "and miss_send_len " + str(desired_miss_send_len), self.__class__.__name__, ) setconfig = pyof.ofp_switch_config() setconfig.header.type = pyof.OFPT_SET_CONFIG setconfig.flags = desired_flags setconfig.miss_send_len = desired_miss_send_len self.conn.send(event.sock, setconfig.pack()) # Get config again after set getconfig = pyof.ofp_header() getconfig.type = pyof.OFPT_GET_CONFIG_REQUEST self.conn.send(event.sock, getconfig.pack()) else: # Remember config key = self.get_key(event.sock) mc.set(key, event.config) output.dbg("Updated config with key " + key, self.__class__.__name__) elif isinstance(event, comm.event): # Socket close, so remove config if event.event == comm.event.SOCK_CLOSE: key = self.get_key(event.sock) c = mc.get(key) if c != None: mc.delete(key) return True
def __arp_check(self, o): """Check ARP @param o arp check object (dictionary) """ mac = self.get_ip_mac(o["ip"], self.loif.client_intf) if mac == None: o["tried"] += 1 if o["tried"] < MAX_RETRY: rc = yapc.priv_callback(self, o) self.server.post_event(rc, 1) else: mc.set(nat.get_gw_mac_key(o["ip"]), mac.mac) output.info("ARP of " + o["ip"] + " is " + str(mac.mac), self.__class__.__name__)
def update_sw_feature(self): """Update switch feature in memcache """ sf = self.switch.get_sw_feature() if sf == None: output.warn("No switch features!!!", self.__class__.__name__) else: output.dbg("Set switch feature as " + sf.show(), self.__class__.__name__) mc.set(bridge.SW_FEATURE, sf) iport = self.switch.if_name2dpid_port_mac(self.loif.switch_intf)[1] if iport == None: output.warn("No inner port!!!", self.__class__.__name__) else: output.dbg("Set inner port as " + str(iport), self.__class__.__name__) mc.set(bridge.SW_INNER_PORT, iport)
def processevent(self, event): """Process OpenFlow message for switch status @param event OpenFlow message event to process @return True """ if isinstance(event, ofevents.features_reply): # Maintain list of datapath socket key = self.get_key(event.sock) dpidsl = mc.get(dp_features.DP_SOCK_LIST) if dpidsl == None: dpidsl = [] if key not in dpidsl: dpidsl.append(key) mc.set(dp_features.DP_SOCK_LIST, dpidsl) # Maintain dp features in memcache mc.set(key, event.features) elif isinstance(event, ofevents.port_status): # Port status if event.header.type == pyof.OFPT_PORT_STATUS: key = self.get_key(event.sock) sw = mc.get(key) if sw == None: output.warn("Port status from unknown datapath", self.__class__.__name__) else: output.dbg("Received port status:\n" + event.port.show("\t"), self.__class__.__name__) if event.port.reason == pyof.OFPPR_DELETE or event.port.reason == pyof.OFPPR_MODIFY: for p in sw.ports: if p.port_no == event.port.desc.port_no: sw.ports.remove(p) if event.port.reason == pyof.OFPPR_ADD or event.port.reason == pyof.OFPPR_MODIFY: sw.ports.append(event.port.desc) output.dbg("Updated switch features:\n" + sw.show("\t"), self.__class__.__name__) mc.set(key, sw) elif isinstance(event, comm.event): # Socket close if event.event == comm.event.SOCK_CLOSE: key = self.get_key(event.sock) sw = mc.get(key) if sw != None: output.info("Datapath %x leaves" % sw.datapath_id, self.__class__.__name__) # Maintain list of datapath socket dpidsl = mc.get(dp_features.DP_SOCK_LIST) if dpidsl != None: if key in dpidsl: dpidsl.remove(key) mc.set(dp_features.DP_SOCK_LIST, dpidsl) # Remove features mc.delete(key) return True
def processevent(self, event): """Event handler @param event event to handle """ key = self.get_key(event.sock, event.match.dl_src) #Broadcast mac if (pu.is_multicast_mac(event.match.dl_src)): return True mc.set(key, event.pktin.in_port, mac2sw_binding.TIMEOUT) output.vdbg("Learn that %x " % pu.array2val(event.match.dl_src) +\ "is connected to port " + \ str(event.pktin.in_port)+" of switch with "+\ str(event.sock), self.__class__.__name__) return True
def processevent(self, event): """Process authentication event """ if (event.host == None): return True if (isinstance(event, owevent.authenticated)): output.dbg(pu.array2hex_str(event.host)+" is authenticated", self.__class__.__name__) mcutil.set(host_auth.get_key(event.host), event.openid, MAX_AUTH_TIMEOUT) elif (isinstance(event, owevent.unauthenticated)): output.dbg(pu.array2hex_str(event.host)+" is unauthenticated", self.__class__.__name__) mcutil.delete(host_auth.get_key(event.host)) mcutil.delete(host_auth.get_auth_key(event.host)) elif (isinstance(event, owevent.going_to_auth)): output.dbg(pu.array2hex_str(event.host)+" is going to authenticate", self.__class__.__name__) mcutil.set(host_auth.get_auth_key(event.host), event.server(), AUTH_TIMEOUT) return True
def set_ifconfig(self, msg): """Does manual ifconfig """ intf = msg["name"] ip = msg["ipaddr"] mask = msg["netmask"] gw = msg["gwaddr"] gwmac = msg["gwmac"] no = self.switch.if_name2dpid_port_mac(intf)[1] # Register gateway mc.set(nat.get_gw_key(no), gw) output.info("Gateway of " + intf + " is " + gw, self.__class__.__name__) # Register ip range ipr = (pu.ip_string2val(ip), pu.ip_string2val(mask), pu.hex_str2array(self.ifmgr.ethernet_addr(intf))) mc.set(nat.get_ip_range_key(no), ipr) output.info( intf + "(" + str(no) + ") has IP address %x and netmask %x" % (ipr[0], ipr[1]), self.__class__.__name__ ) # Regsiter mac address mc.set(nat.get_gw_mac_key(gw), gwmac) output.info("ARP of " + gw + " is " + str(gwmac), self.__class__.__name__)
def processevent(self, event): """Handle event to sniff domain name-IP address binding """ if (isinstance(event, ofevents.pktin)): if (event.match.tp_src == 53): try: dnsreply = dpkt.dns.DNS(event.dpkt["data"]["data"]["data"]) except: return True nameaddr = {} for rr in dnsreply["an"]: if (rr["type"] == 1): #Record address for domain name if (rr["name"] not in nameaddr): nameaddr[rr["name"]] = [] nameaddr[rr["name"]].append(rr["rdata"]) #Record domain name for address mc.set(host_dns.get_addr_key(rr["rdata"]), rr["name"], rr["ttl"]) output.vdbg("AN: "+socket.inet_ntoa(rr["rdata"])+" set to "+rr["name"]+\ " with TTL "+str(rr["ttl"]), self.__class__.__name__) for rr in dnsreply["ar"]: if (rr["type"] == 1): #Record domain name for address mc.set(host_dns.get_addr_key(rr["rdata"]), rr["name"], rr["ttl"]) output.vdbg("AR: "+socket.inet_ntoa(rr["rdata"])+" set to "+rr["name"]+\ " with TTL "+str(rr["ttl"]), self.__class__.__name__) for name,val in nameaddr.items(): if (len(val) != 0): mc.set(host_dns.get_name_key(event.match.dl_src, name), val) output.dbg(name+"=>"+str(len(val))+" IP addresses", self.__class__.__name__) return True