Пример #1
0
 def compare_bpdu_info(my_priority, my_times, rcv_priority, rcv_times):
     """ Check received BPDU is superior to currently held BPDU
          by the following comparison.
          - root bridge ID value
          - root path cost
          - designated bridge ID value
          - designated port ID value
          - times """
     if my_priority is None:
         result = SUPERIOR
     else:
         result = Stp._cmp_value(rcv_priority.root_id.value,
                                 my_priority.root_id.value)
         if not result:
             result = Stp.compare_root_path(
                 rcv_priority.root_path_cost,
                 my_priority.root_path_cost,
                 rcv_priority.designated_bridge_id.value,
                 my_priority.designated_bridge_id.value,
                 rcv_priority.designated_port_id.value,
                 my_priority.designated_port_id.value)
             if not result:
                 result1 = Stp._cmp_value(
                     rcv_priority.designated_bridge_id.value,
                     mac.haddr_to_int(
                         my_priority.designated_bridge_id.mac_addr))
                 result2 = Stp._cmp_value(
                     rcv_priority.designated_port_id.value,
                     my_priority.designated_port_id.port_no)
                 if not result1 and not result2:
                     result = SUPERIOR
                 else:
                     result = Stp._cmp_obj(rcv_times, my_times)
     return result
Пример #2
0
 def compare_bpdu_info(my_priority, my_times, rcv_priority, rcv_times):
     """ Check received BPDU is superior to currently held BPDU
          by the following comparison.
          - root bridge ID value
          - root path cost
          - designated bridge ID value
          - designated port ID value
          - times """
     if my_priority is None:
         result = SUPERIOR
     else:
         result = Stp._cmp_value(rcv_priority.root_id.value,
                                 my_priority.root_id.value)
         if not result:
             result = Stp.compare_root_path(
                 rcv_priority.root_path_cost,
                 my_priority.root_path_cost,
                 rcv_priority.designated_bridge_id.value,
                 my_priority.designated_bridge_id.value,
                 rcv_priority.designated_port_id.value,
                 my_priority.designated_port_id.value)
             if not result:
                 result1 = Stp._cmp_value(
                     rcv_priority.designated_bridge_id.value,
                     mac.haddr_to_int(
                         my_priority.designated_bridge_id.mac_addr))
                 result2 = Stp._cmp_value(
                     rcv_priority.designated_port_id.value,
                     my_priority.designated_port_id.port_no)
                 if not result1 and not result2:
                     result = SUPERIOR
                 else:
                     result = Stp._cmp_obj(rcv_times, my_times)
     return result
Пример #3
0
    def generate_arp_reply(self, dst_ip, dst_mac):
        self.logger.info("Generating ARP Reply Packet")
        self.logger.info("ARP request client ip: " + dst_ip +
                         ", client mac: " + dst_mac)
        arp_target_ip = dst_ip  # the sender ip
        arp_target_mac = dst_mac  # the sender mac
        # Making the load balancer IP as source IP
        src_ip = self.VIRTUAL_IP

        if haddr_to_int(arp_target_mac) % 2 == 1:
            src_mac = self.SERVER1_MAC
        else:
            src_mac = self.SERVER2_MAC
        self.logger.info("Selected server MAC: " + src_mac)

        pkt = packet.Packet()
        pkt.add_protocol(
            ethernet.ethernet(dst=dst_mac,
                              src=src_mac,
                              ethertype=ether_types.ETH_TYPE_ARP))
        pkt.add_protocol(
            arp.arp(opcode=arp.ARP_REPLY,
                    src_mac=src_mac,
                    src_ip=src_ip,
                    dst_mac=arp_target_mac,
                    dst_ip=arp_target_ip))
        pkt.serialize()
        self.logger.info("Done with processing the ARP reply packet")
        return pkt
    def generate_arp_reply(self, dst_ip, dst_mac):
        """
        An ARP reply is generated in the controller code with the source address as load
        balancers and destination as client address and passed to the switch which transmits it
        back to the client.

        For the future, a flow is created (load balancer to client) and inserted
        in the switch that modifies the packet header and changes the destination MAC to that
        of the client and source MAC to load balancers. So, further ARP requests from the same client on that
        in port will automatically be replied to by the switch at line rate speed.

        To the client which started the connection it would look like the server (load balancer) has replied
        with its MAC.

        For successive ARP connections:

        After the first encounter, the controller inserts the flow table entries into the switch so the switch
        would match the packet with a flow and according to priority take the corresponding action at line rate
        speed just like a legacy switch.
        """
        self.logger.info("Generating ARP Reply Packet")
        self.logger.info("ARP request client ip: " + dst_ip +
                         ", client mac: " + dst_mac)
        arp_target_ip = dst_ip  # the sender ip
        arp_target_mac = dst_mac  # the sender mac
        # Making the load balancer IP as source IP
        src_ip = self.VIRTUAL_IP

        if haddr_to_int(arp_target_mac) % 2 == 1:
            src_mac = self.SERVER1_MAC
        else:
            src_mac = self.SERVER2_MAC
        self.logger.info("Selected server MAC: " + src_mac)

        pkt = packet.Packet()
        pkt.add_protocol(
            ethernet.ethernet(dst=dst_mac,
                              src=src_mac,
                              ethertype=ether_types.ETH_TYPE_ARP))
        pkt.add_protocol(
            arp.arp(opcode=arp.ARP_REPLY,
                    src_mac=src_mac,
                    src_ip=src_ip,
                    dst_mac=arp_target_mac,
                    dst_ip=arp_target_ip))
        pkt.serialize()
        self.logger.info("Done with processing the ARP reply packet")
        return pkt
Пример #5
0
 def get_expected_dest_address(self, src_mac):
     return Server(self.server_ip1, self.server_mac1,
                   1) if haddr_to_int(src_mac) % 2 == 1 else Server(
                       self.server_ip2, self.server_mac2, 2)
Пример #6
0
    def match(flow, pkt, in_port, ofp, in_phy_port=None):
        """
        
            Args:
                flow: 
                pkt: 
                in_port: 
                ofp: 
                in_phy_port: 
    
            Returns:

        """
        eth = pkt[0]
        vlan = pkt[1]

        print flow
        if 'in_port' in flow:
            if flow['in_port'] != in_port:
                return False

        if 'in_phy_port' in flow:
            if flow['in_phy_port'] != in_phy_port:
                return False

        if 'eth_dst' in flow:
            eth_dst = flow['eth_dst']
            if isinstance(eth_dst, tuple):
                edst, mask = map(mac.haddr_to_int, eth_dst)
                if edst & mask != mac.haddr_to_int(eth.dst) & mask:
                    return False
            else:
                if eth_dst != eth.dst:
                    return False

        if 'eth_src' in flow:
            eth_src = flow['eth_src']
            if isinstance(eth_src, tuple):
                esrc, mask = map(mac.haddr_to_int, eth_src)
                if esrc & mask != mac.haddr_to_int(eth.src) & mask:
                    return False
            else:
                if eth_src != eth.src:
                    return False

        if 'eth_type' in flow:
            if flow['eth_type'] != vlan.ethertype:
                return False

        def test_vid(vid):
            if vid == ofp.OFPVID_NONE and vlan.vid:
                return False
            if vid != vlan.vid | ofp.OFPVID_PRESENT:
                return False
            return True

        if 'vlan_vid' in flow:
            vlan_vid = flow['vlan_vid']
            if isinstance(vlan_vid, tuple):
                vid, mask = vlan_vid
                if vid == mask == ofp.OFPVID_PRESENT and not vlan.vid:
                    return False
                else:
                    test_vid(vid)
            else:
                vid = vlan_vid
                if not test_vid(vid):
                    return False

        if 'vlan_pcp' in flow:
            if flow['vlan_pcp'] != vlan.vid:
                return False

        ip_dscp = None
        ip_ecn = None
        ip_proto = None

        if vlan.ethertype == 0x0800:
            ip4 = pkt[2]
            tp = pkt[3]

            ip_dscp = ip4.tos >> 2
            ip_ecn = ip4.tos & 0x03
            ip_proto = ip4.proto

            if 'ipv4_src' in flow:
                ipv4_src = flow['ipv4_src']
                if isinstance(ipv4_src, tuple):
                    ipsrc, mask = map(ip.ipv4_to_int, ipv4_src)
                    if ipsrc & mask != ip.ipv4_to_int(ip4.src) & mask:
                        return False
                else:
                    if ipv4_src != ip4.src:
                        return False

            if 'ipv4_dst' in flow:
                ipv4_dst = flow['ipv4_dst']
                if isinstance(ipv4_dst, tuple):
                    ipsrc, mask = map(ip.ipv4_to_int, ipv4_dst)
                    if ipsrc & mask != ip.ipv4_to_int(ip4.dst) & mask:
                        return False
                else:
                    if ipv4_dst != ip4.dst:
                        return False

        if vlan.ethertype == 0x86dd:
            ip6 = pkt[2]
            tp = pkt[3]

            ip_dscp = ip6.traffic_class >> 2
            ip_ecn = ip6.traffic_class & 0x03
            ip_proto = ip6.nxt

            if 'ipv6_src' in flow:
                ipv6_src = flow['ipv6_src']
                if isinstance(ipv6_src, tuple):
                    ipsrc, mask = map(ip.ipv6_to_int, ipv6_src)
                    if ipsrc & mask != ip.ipv6_to_int(ip6.src) & mask:
                        return False
                else:
                    if ipv6_src != ip6.src:
                        return False

            if 'ipv6_dst' in flow:
                ipv6_dst = flow['ipv64_dst']
                if isinstance(ipv6_dst, tuple):
                    ipsrc, mask = map(ip.ipv6_to_int, ipv6_dst)
                    if ipsrc & mask != ip.ipv6_to_int(ip6.dst) & mask:
                        return False
                else:
                    if ipv6_dst != ip6.dst:
                        return False

        if 'ip_dscp' in flow and ip_dscp is not None:
            if flow['ip_dscp'] != ip_dscp:
                return False

        if 'ip_ecn' in flow and ip_ecn is not None:
            if flow['ip_ecn'] != ip_ecn:
                return False

        if 'ip_proto' in flow and ip_proto is not None:
            if flow['ip_proto'] != ip_proto:
                return False

        if ip_proto == 6:  # TCP
            if 'tcp_src' in flow:
                if flow['tcp_src'] != tp.src_port:
                    return False

            if 'tcp_dst' in flow:
                if flow['tcp_dst'] != tp.dst_port:
                    return False

        if ip_proto == 17:  # UDP
            if 'udp_src' in flow:
                if flow['udp_src'] != tp.src_port:
                    return False

            if 'udp_dst' in flow:
                if flow['udp_dst'] != tp.dst_port:
                    return False

        if ip_proto == 132:  # SCTP
            if 'sctp_src' in flow:
                if flow['sctp_src'] != tp.src_port:
                    return False

            if 'sctp_dst' in flow:
                if flow['sctp_dst'] != tp.dst_port:
                    return False

        return True
Пример #7
0
 def get_expected_dest_address(self, src_mac):
     return self.H1_ip if haddr_to_int(src_mac) % 2 == 1 else self.H2_ip