示例#1
0
    def __init__(self, *args, **kwargs):
        super(VRRPInterfaceMonitorNetworkDevice, self).__init__(*args,
                                                                **kwargs)
        self.__is_active = True
        config = self.config
        if config.is_ipv6:
            family = socket.AF_INET6
            ether_type = ether.ETH_TYPE_IPV6
            mac_address = vrrp.vrrp_ipv6_src_mac_address(config.vrid)
        else:
            family = socket.AF_INET
            ether_type = ether.ETH_TYPE_IP
            mac_address = vrrp.vrrp_ipv4_src_mac_address(config.vrid)
        # socket module doesn't define IPPROTO_VRRP
        self.ip_socket = socket.socket(family, socket.SOCK_RAW,
                                       inet.IPPROTO_VRRP)

        self.packet_socket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
                                           socket.htons(ether_type))
        self.packet_socket.bind((self.interface.device_name, ether_type,
                                 socket.PACKET_MULTICAST,
                                 arp.ARP_HW_TYPE_ETHERNET,
                                 addrconv.mac.text_to_bin(mac_address)))

        self.ifindex = if_nametoindex(self.interface.device_name)
示例#2
0
 def _drop_match(self, dp):
     kwargs = {}
     kwargs['in_port'] = self.interface.port_no
     kwargs['eth_dst'] = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid)
     if self.interface.vlan_id is not None:
         kwargs['vlan_vid'] = self.interface.vlan_id
     return dp.ofproto_parser.OFPMatch(**kwargs)
示例#3
0
 def _arp_match(self, dp):
     kwargs = {}
     kwargs['in_port'] = self.interface.port_no
     kwargs['eth_dst'] = mac_lib.BROADCAST_STR
     kwargs['eth_type'] = ether.ETH_TYPE_ARP
     if self.interface.vlan_id is not None:
         kwargs['vlan_vid'] = self.interface.vlan_id
     kwargs['arp_op'] = arp.ARP_REQUEST
     kwargs['arp_tpa'] = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid)
     return dp.ofproto_parser.OFPMatch(**kwargs)
示例#4
0
    def _garp_packet(self, ip_address):
        # prepare garp packet
        src_mac = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid)
        e = ethernet.ethernet(mac_lib.BROADCAST_STR, src_mac,
                              ether.ETH_TYPE_ARP)
        a = arp.arp_ip(arp.ARP_REQUEST, src_mac, ip_address,
                       mac_lib.DONTCARE_STR, ip_address)

        p = packet.Packet()
        p.add_protocol(e)
        utils.may_add_vlan(p, self.interface.vlan_id)
        p.add_protocol(a)
        p.serialize()
        return p
示例#5
0
 def _join_multicast_membership(self, join_leave):
     config = self.config
     if config.is_ipv6:
         mac_address = vrrp.vrrp_ipv6_src_mac_address(config.vrid)
     else:
         mac_address = vrrp.vrrp_ipv4_src_mac_address(config.vrid)
     if join_leave:
         add_drop = PACKET_ADD_MEMBERSHIP
     else:
         add_drop = PACKET_DROP_MEMBERSHIP
     packet_mreq = struct.pack('IHH8s', self.ifindex,
                               PACKET_MR_MULTICAST, 6,
                               addrconv.mac.text_to_bin(mac_address))
     self.packet_socket.setsockopt(SOL_PACKET, add_drop, packet_mreq)
示例#6
0
    def _arp_reply_packet(self, arp_req_sha, arp_req_spa, arp_req_tpa):
        if not (arp_req_tpa in self.config.ip_addresses or
                arp_req_tpa == self.config.primary_ip_address):
            return None

        src_mac = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid)
        e = ethernet.ethernet(arp_req_sha, src_mac, ether.ETH_TYPE_ARP)
        a = arp.arp_ip(arp.ARP_REPLY, src_mac, arp_req_tpa,
                       arp_req_sha, arp_req_spa)

        p = packet.Packet()
        p.add_protocol(e)
        utils.may_add_vlan(p, self.interface.vlan_id)
        p.add_protocol(a)
        p.serialize()
        self._transmit(p.data)
示例#7
0
    def _arp_process(self, data):
        dst_mac = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid)
        arp_sha = None
        arp_spa = None
        arp_tpa = None

        p = packet.Packet(data)
        for proto in p.protocols:
            if isinstance(proto, ethernet.ethernet):
                if proto.dst not in (mac_lib.BROADCAST_STR, dst_mac):
                    return None
                ethertype = proto.ethertype
                if not ((self.interface.vlan_id is None and
                         ethertype == ether.ETH_TYPE_ARP) or
                        (self.interface.vlan_id is not None and
                         ethertype == ether.ETH_TYPE_8021Q)):
                    return None
            elif isinstance(proto, vlan.vlan):
                if (proto.vid != self.interface.vlan_id or
                        proto.ethertype != ether.ETH_TYPE_ARP):
                    return None
            elif isinstance(proto, arp.arp):
                if (proto.hwtype != arp.ARP_HW_TYPE_ETHERNET or
                    proto.proto != ether.ETH_TYPE_IP or
                    proto.hlen != 6 or proto.plen != 4 or
                    proto.opcode != arp.ARP_REQUEST or
                        proto.dst_mac != dst_mac):
                    return None
                arp_sha = proto.src_mac
                arp_spa = proto.src_ip
                arp_tpa = proto.dst_ip
                break

        if arp_sha is None or arp_spa is None or arp_tpa is None:
            self.logger.debug('malformed arp request? arp_sha %s arp_spa %s',
                              arp_sha, arp_spa)
            return None

        self._arp_reply_packet(arp_sha, arp_spa, arp_tpa)
    def _ofp_match(self, ofproto_parser):
        is_ipv6 = vrrp.is_ipv6(self.config.ip_addresses[0])
        kwargs = {}
        kwargs['in_port'] = self.interface.port_no
        if is_ipv6:
            kwargs['eth_dst'] = vrrp.VRRP_IPV6_DST_MAC_ADDRESS
            kwargs['eth_src'] = \
                vrrp.vrrp_ipv6_src_mac_address(self.config.vrid)
            kwargs['eth_type'] = ether.ETH_TYPE_IPV6
            kwargs['ipv6_dst'] = vrrp.VRRP_IPV6_DST_ADDRESS
        else:
            kwargs['eth_dst'] = vrrp.VRRP_IPV4_DST_MAC_ADDRESS
            kwargs['eth_src'] = \
                vrrp.vrrp_ipv4_src_mac_address(self.config.vrid)
            kwargs['eth_type'] = ether.ETH_TYPE_IP
            kwargs['ipv4_dst'] = vrrp.VRRP_IPV4_DST_ADDRESS

        if self.interface.vlan_id is not None:
            kwargs['vlan_vid'] = self.interface.vlan_id
        kwargs['ip_proto'] = inet.IPPROTO_VRRP
        # OF1.2 doesn't support TTL match.
        # It needs to be checked by packet in handler

        return ofproto_parser.OFPMatch(**kwargs)