Example #1
0
File: nat.py Project: yapkke/yapc
    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
Example #2
0
File: nat.py Project: yapkke/yapc
    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
Example #3
0
File: flows.py Project: yapkke/yapc
    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
Example #4
0
File: nat.py Project: yapkke/yapc
    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
Example #5
0
    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
Example #6
0
File: nat.py Project: yapkke/yapc
    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