def _process_inbound(self, pktin, intfs, iport, lointf): """Event handler for inbound ARP packets @param pktin packet in event to handle @param intfs dictionary of interfaces (with ip range) @param iport port no of local interface @param lointf local interface address (ip, mac) @return false """ try: ipr = intfs[pktin.match.in_port] except KeyError: output.vdbg("ARP packet received on unknown/uninitialized interface", self.__class__.__name__) return False flow = flows.exact_entry(pktin.match) if flow.buffer_id != pktin.pktin.buffer_id: output.warn("Buffered inbound ARP packet (cannot be rewritten properly)!", self.__class__.__name__) elif flow.match.nw_dst != ipr[0]: output.vdbg("Inbound ARP packet not destined for this host, ignored.", self.__class__.__name__) else: flow.add_output(iport) if pu.array2val(pktin.match.dl_dst) != 0xFFFFFFFFFFFF: ofpkt.dl_rewrite(pktin.dpkt, False, lointf[1]) ofpkt.nw_rewrite(pktin.dpkt, False, lointf[0]) self.get_conn().send(flow.get_packet_out().pack() + pktin.dpkt.pack()) return False
def _process_outbound(self, pktin, intfs, iport, lointf): """Event handler for outbound ARP packets @param pktin packet in event to handle @param intfs dictionary of interfaces (with ip range) @param iport port no of local interface @param lointf local interface address (ip, mac) @return false """ for portno, ipr in intfs.items(): if (ipr[0] & ipr[1]) == (pktin.match.nw_dst & ipr[1]): flow = flows.exact_entry(pktin.match) if flow.buffer_id != pktin.pktin.buffer_id: output.warn("Buffered outbound ARP packet (cannot be rewritten properly)!", self.__class__.__name__) else: flow.add_output(portno) ofpkt.dl_rewrite(pktin.dpkt, True, ipr[2]) ofpkt.nw_rewrite(pktin.dpkt, True, ipr[0]) self.get_conn().send(flow.get_packet_out().pack() + pktin.dpkt.pack()) output.vdbg( "ARP to " + pu.ip_val2string(pktin.match.nw_dst) + " sent to port " + str(portno), self.__class__.__name__, ) return False output.warn("ARP for " + pu.ip_val2string(pktin.match.nw_dst) + " unknown subnet", self.__class__.__name__) return False
def dl_rewrite(self, rewrite_src, addr): """Add rewrite for Ethernet address @param rewrite_src boolean for indicated rewrite src or dst @param addr address to rewrite to @return success or not """ if self.dpkt != None: pktact.dl_rewrite(rewrite_src, addr) return True return False
def _process_inbound(self, pktin, intfs, iport, lointf): """Event handler for inbound packet @param pktin packet in event to handle @param intfs dictionary of interfaces (with ip range) @param iport port no of local interface @param lointf local interface address (ip, mac) @return false """ try: ipr = intfs[pktin.match.in_port] except KeyError: output.vdbg("IP packet received on unknown/uninitialized interface", self.__class__.__name__) return False if ipr[2] != pktin.match.dl_dst: return False flow = flows.exact_entry(pktin.match) flow.add_nw_rewrite(False, lointf[0]) flow.add_dl_rewrite(False, lointf[1]) flow.add_output(iport) if pktin.pktin.buffer_id != flow.buffer_id: flow.set_buffer(pktin.pktin.buffer_id) self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 else: self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 ofpkt.nw_rewrite(pktin.dpkt, False, lointf[0]) ofpkt.dl_rewrite(pktin.dpkt, False, lointf[1]) self.get_conn().send(flow.get_packet_out(pyof.OFPFC_ADD).pack() + pktin.dpkt.pack()) gw = mc.get(nat.get_gw_key(flow.match.in_port)) gwmac = mc.get(nat.get_gw_mac_key(gw)) if gwmac == None: return False if (ipr[0] & ipr[1]) != (pktin.match.nw_src & ipr[1]): # Global address rflow = flow.reverse(iport) rflow.match.nw_src = lointf[0] rflow.match.dl_src = lointf[1] rflow.add_nw_rewrite(True, ipr[0]) rflow.add_dl_rewrite(True, ipr[2]) rflow.add_dl_rewrite(False, pu.hex_str2array(gwmac)) rflow.add_output(flow.match.in_port) if (rflow.match.wildcards & pyof.OFPFW_DL_TYPE) != 0: output.dbg(rflow.match.show(), self.__class__.__name__) self.get_conn().send(rflow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 return False
def processevent(self, event): """Event handler @param event event to handle @return True """ if isinstance(event, ofevents.pktin): self.check_timeout() iport = mc.get(bridge.SW_INNER_PORT) intfs = self.get_ext_intf() if iport == None: output.err("No inner port recorded! Are we connected?", self.__class__.__name__) return True flow = flows.exact_entry(event.match) # Indirection given? if flow.match.nw_src in self.m2m: from_ip = flow.match.nw_dst from_eth = flow.match.dl_dst[:] to_eth = flow.match.dl_src[:] to_ip = self.m2m[from_ip][0] flow.add_nw_rewrite(True, from_ip) flow.add_dl_rewrite(True, from_eth) flow.add_nw_rewrite(False, to_ip) flow.add_dl_rewrite(False, to_eth) ofpkt.nw_rewrite(event.dpkt, True, from_ip) ofpkt.dl_rewrite(event.dpkt, True, from_eth) ofpkt.nw_rewrite(event.dpkt, False, to_ip) ofpkt.dl_rewrite(event.dpkt, False, to_eth) flow.add_output(py.OFPP_IN_PORT) if flow.buffer_id != event.pktin.buffer_id: flow.set_buffer(event.pktin.buffer_id) self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD).pack()) else: self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD).pack()) self.get_conn().send(flow.get_packet_out(pyof.OFPFC_ADD).pack() + event.dpkt.pack()) output.dbg("Indirecting flow...", self.__class__.__name__) return False elif isinstance(event, udpjson.message): self._handle_json(event) return True
def _process_outbound(self, pktin, intfs, iport, lointf): """Event handler for outbound IP packet @param pktin packet in event to handle @param intfs dictionary of interfaces (with ip range) @param iport port no of local interface @param lointf local interface address (ip, mac) @return false if processed else true """ flow = flows.exact_entry(pktin.match) for portno, ipr in intfs.items(): if (ipr[0] & ipr[1]) == (pktin.match.nw_dst & ipr[1]): # Local address flow.set_buffer(pktin.pktin.buffer_id) flow.add_nw_rewrite(True, ipr[0]) flow.add_dl_rewrite(True, ipr[2]) flow.add_output(portno) if flow.buffer_id != pktin.pktin.buffer_id: flow.set_buffer(pktin.pktin.buffer_id) self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD).pack()) else: self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD).pack()) ofpkt.nw_rewrite(pktin.dpkt, True, ipr[0]) ofpkt.dl_rewrite(pktin.dpkt, True, ipr[2]) self.get_conn().send(flow.get_packet_out(pyof.OFPFC_ADD).pack() + pktin.dpkt.pack()) return False # Global address cportl = [] if ( (pktin.match.nw_proto == 17) and (pktin.match.tp_dst == 53) and (self.coin.config["dns_select_interface"] != None) ): output.dbg("DNS packet", self.__class__.__name__) tcport = self.dns_select_intf(intfs) if tcport != None: cportl.append(tcport) else: output.dbg("non-DNS packet", self.__class__.__name__) tcport = self.select_intf(intfs) if tcport != None: cportl.append(tcport) for cport in cportl: gw = mc.get(nat.get_gw_key(cport)) gwmac = mc.get(nat.get_gw_mac_key(gw)) ipr = intfs[cport] if (gw == None) or (gwmac == None): output.warn("Packet ignored since gateway for interface not found!", self.__class__.__name__) return False # Outbound flow.add_nw_rewrite(True, ipr[0]) flow.add_dl_rewrite(True, ipr[2]) flow.add_dl_rewrite(False, pu.hex_str2array(gwmac)) flow.add_output(cport) if pktin.pktin.buffer_id != flow.buffer_id: flow.set_buffer(pktin.pktin.buffer_id) self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 else: self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 ofpkt.nw_rewrite(pktin.dpkt, True, ipr[0]) ofpkt.dl_rewrite(pktin.dpkt, True, ipr[2]) ofpkt.dl_rewrite(pktin.dpkt, False, pu.hex_str2array(gwmac)) self.get_conn().send(flow.get_packet_out(pyof.OFPFC_ADD).pack() + pktin.dpkt.pack()) # Inbound rflow = flow.reverse(cport) rflow.match.nw_dst = ipr[0] rflow.match.dl_dst = ipr[2] rflow.add_nw_rewrite(False, lointf[0]) rflow.add_dl_rewrite(False, lointf[1]) rflow.add_output(iport) self.get_conn().send(rflow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 return False return True