Esempio n. 1
0
    def _is_relevant_packet(self, event, packet):
        """ 
        Sanity check to make sure we deal with experimental traffic only.
        Otherwise, returns False.
        
        """
        mylog("zzzz inport =", event.port)

        if not self.transparent:
            if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered():
                self._drop(event)
                return False

        if event.port not in SWITCH_PORT_LIST:
            self._drop(event)
            return False

        if packet.dst.isMulticast():
            self._packet_out(event)
            return False

        outport = get_the_other_port(event.port)

        if outport == event.port:
            mylog(
                "Same port for packet from %s -> %s on %s. Drop." % (packet.src, packet.dst, outport),
                dpidToStr(event.dpid),
            )
            self._drop(event)
            return False

        return True
Esempio n. 2
0
 def _handle_PacketIn(self, event):
     """
     Handles packet in messages from the switch to implement above algorithm.
     """
     try:
         return self._handle_pkt_in_helper(event)
     except Exception:
         mylog("*" * 80)
         mylog("Pkt_in crashed:", traceback.format_exc())
Esempio n. 3
0
 def _packet_out(self, event):
     """ Floods the packet """
     if event.ofp.buffer_id == -1:
         mylog("Not flooding unbuffered packet on", dpidToStr(event.dpid))
         return
     msg = of.ofp_packet_out()
     msg.actions.append(of.ofp_action_output(port=get_the_other_port(event.port)))
     msg.buffer_id = event.ofp.buffer_id
     msg.in_port = event.port
     self.connection.send(msg)
Esempio n. 4
0
    def _install_rule(self, event, packet, outport, tp_dst=None, idle_timeout=IDLE_TIMEOUT):
        """
        Installs a rule for any incoming packet, doing what a learning switch
        should do.
        
        """
        msg = of.ofp_flow_mod()
        msg.match = of.ofp_match.from_packet(packet)
        msg.idle_timeout = idle_timeout
        msg.hard_timeout = HARD_TIMEOUT
        msg.actions.append(of.ofp_action_output(port=outport))

        with exp_control.lock:
            exp_control.flow_mod_count += 1
            install_bogus_rules = exp_control.install_bogus_rules

        # Install a rule with a randomly generated dest mac address that no
        # one will ever match against.
        if install_bogus_rules:
            # mac_addr_list = ['0' + str(random.randint(1,9)) for _ in range(6)]
            # msg.match.dl_src = EthAddr(':'.join(mac_addr_list))
            msg.match.tp_dst = random.randint(10, 65000)
            msg.match.tp_src = random.randint(10, 65000)
            msg.buffer_id = event.ofp.buffer_id
            mylog("Installing a bogus flow.")

        # Create a rule that matches with the incoming packet. When buffer ID is
        # specified, the flow mod command is automatically followed by a packet-
        # out command.
        elif tp_dst is None:
            msg.buffer_id = event.ofp.buffer_id
            with exp_control.lock:
                exp_control.pkt_out_count += 1
            mylog("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, outport))

        # Create a rule with a specific dest port.
        else:
            msg.match.tp_dst = tp_dst
            mylog("Installing rule for tp_dst =", tp_dst)

        current_time = time.time()
        with exp_control.lock:
            if exp_control.flow_mod_start_time is None:
                exp_control.flow_mod_start_time = current_time
            exp_control.flow_mod_end_time = current_time

        mylog("Flow_mod:", pretty_dict(dictify(msg)))
        self.connection.send(msg)
Esempio n. 5
0
    def _handle_pkt_in_helper(self, event):

        packet = event.parse()
        current_time = time.time()

        with exp_control.lock:
            flow_stat_interval = exp_control.flow_stat_interval

        # Obtain flow stats once in a while.
        if flow_stat_interval:
            if current_time - self.last_flow_stat_time > flow_stat_interval:
                self.last_flow_stat_time = current_time
                self.connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request()))

        # There are just packets that we don't care.
        if not self._is_relevant_packet(event, packet):
            mylog("pkt_in: Rejected packet:", packet, repr(packet), dictify(packet))
            return

        # Throttle packet-in events if need be.
        if exp_control.emulate_hp_switch:
            if not self.limiter_pkt_in.to_forward_packet():
                return

        # Count packet-in events.
        with exp_control.lock:
            learning_switch = exp_control.learning
            exp_control.pkt_in_count += 1
            if exp_control.pkt_in_start_time is None:
                exp_control.pkt_in_start_time = current_time
            exp_control.pkt_in_end_time = current_time

        # Count number of packet-out events if the switch does not install
        # rules.
        if not learning_switch:
            with exp_control.lock:
                exp_control.pkt_out_count += 1
            self._drop(event)
            return

        outport = get_the_other_port(event.port)

        # Throttle flow-mod events and pkt-out events if need be.
        if exp_control.emulate_hp_switch:
            if self.limiter_flow_mod.to_forward_packet():
                # flow-mod and pkt-out at 50 pps
                pass
            else:
                # pkt-out at 50 pps, so regardless, total pkt-out at 100 pps
                if self.limiter_pkt_out.to_forward_packet():
                    self._packet_out(event)
                return

        # Automatically learns new flows, as a normal learning switch would do.
        if exp_control.auto_install_rules:
            self._install_rule(event, packet, outport)
            return

        # Manually install rules in the port range.
        with exp_control.lock:
            tp_dst_range = exp_control.manual_install_tp_dst_range[:]
            gap_ms = exp_control.manual_install_gap_ms

        for tp_dst in range(*tp_dst_range):

            # Keep going until the exp_control client decides to stop it.
            with exp_control.lock:
                manual_active = exp_control.manual_install_active
            if not manual_active:
                break

            self._install_rule(event, packet, outport, tp_dst)
            time.sleep(gap_ms / 1000.0)