Example #1
0
 def _control_plane_icmpv6_handler(self, pkt_meta, ipv6_pkt, icmpv6_pkt):
     vlan = pkt_meta.vlan
     src_ip = ipaddress.IPv6Address(btos(ipv6_pkt.src))
     dst_ip = ipaddress.IPv6Address(btos(ipv6_pkt.dst))
     icmpv6_type = icmpv6_pkt.type_
     ofmsgs = []
     if vlan.ip_in_vip_subnet(src_ip):
         port = pkt_meta.port
         vid = self._vlan_vid(vlan, port)
         eth_src = pkt_meta.eth_src
         if icmpv6_type == icmpv6.ND_NEIGHBOR_SOLICIT:
             solicited_ip = btos(icmpv6_pkt.data.dst)
             if vlan.is_faucet_vip(ipaddress.ip_address(solicited_ip)):
                 ofmsgs.extend(
                     self._add_host_fib_route(vlan, src_ip))
                 ofmsgs.extend(self._update_nexthop(
                     vlan, port, eth_src, src_ip))
                 nd_reply = valve_packet.nd_advert(
                     vid, self.faucet_mac, eth_src,
                     solicited_ip, src_ip, ipv6_pkt.hop_limit)
                 ofmsgs.append(
                     valve_of.packetout(port.number, nd_reply.data))
                 self.logger.info(
                     'Responded to ND solicit for %s to %s (%s)',
                     solicited_ip, src_ip, eth_src)
         elif icmpv6_type == icmpv6.ND_NEIGHBOR_ADVERT:
             ofmsgs.extend(self._update_nexthop(
                 vlan, port, eth_src, src_ip))
             self.logger.info(
                 'ND advert %s (%s)', src_ip, eth_src)
         elif icmpv6_type == icmpv6.ND_ROUTER_SOLICIT:
             link_local_vips, other_vips = self._link_and_other_vips(vlan)
             for vip in link_local_vips:
                 if src_ip in vip.network:
                     ra_advert = valve_packet.router_advert(
                         vid, self.faucet_mac, eth_src,
                         vip.ip, src_ip, other_vips)
                     ofmsgs.append(
                         valve_of.packetout(port.number, ra_advert.data))
                     self.logger.info(
                         'Responded to RS solicit from %s (%s) to VIP %s',
                         src_ip, eth_src, vip)
                     break
         elif vlan.from_connected_to_vip(src_ip, dst_ip):
             if (icmpv6_type == icmpv6.ICMPV6_ECHO_REQUEST and
                     pkt_meta.eth_dst == self.faucet_mac):
                 icmpv6_echo_reply = valve_packet.icmpv6_echo_reply(
                     vid, self.faucet_mac, eth_src,
                     dst_ip, src_ip, ipv6_pkt.hop_limit,
                     icmpv6_pkt.data.id, icmpv6_pkt.data.seq,
                     icmpv6_pkt.data.data)
                 ofmsgs.append(
                     valve_of.packetout(port.number, icmpv6_echo_reply.data))
     return ofmsgs
Example #2
0
 def _control_plane_icmpv6_handler(self, pkt_meta, ipv6_pkt):
     ofmsgs = []
     src_ip = ipaddress.IPv6Address(btos(ipv6_pkt.src))
     dst_ip = ipaddress.IPv6Address(btos(ipv6_pkt.dst))
     vlan = pkt_meta.vlan
     if vlan.ip_in_vip_subnet(src_ip):
         # Must be ICMPv6 and have no extended headers.
         if ipv6_pkt.nxt != inet.IPPROTO_ICMPV6:
             return ofmsgs
         if ipv6_pkt.ext_hdrs:
             return ofmsgs
         # Explicitly ignore messages to all notes.
         if dst_ip == valve_packet.IPV6_ALL_NODES:
             return ofmsgs
         pkt_meta.reparse_ip(self.ETH_TYPE, payload=32)
         icmpv6_pkt = pkt_meta.pkt.get_protocol(icmpv6.icmpv6)
         if icmpv6_pkt is None:
             return ofmsgs
         icmpv6_type = icmpv6_pkt.type_
         if (ipv6_pkt.hop_limit != valve_packet.IPV6_MAX_HOP_LIM and
                 icmpv6_type != icmpv6.ICMPV6_ECHO_REQUEST):
             return ofmsgs
         port = pkt_meta.port
         vid = self._vlan_vid(vlan, port)
         eth_src = pkt_meta.eth_src
         if icmpv6_type == icmpv6.ND_NEIGHBOR_SOLICIT:
             solicited_ip = btos(icmpv6_pkt.data.dst)
             if vlan.is_faucet_vip(ipaddress.ip_address(solicited_ip)):
                 ofmsgs.extend(
                     self._add_host_fib_route(vlan, src_ip))
                 ofmsgs.extend(self._update_nexthop(
                     vlan, port, eth_src, src_ip))
                 nd_reply = valve_packet.nd_advert(
                     vid, vlan.faucet_mac, eth_src,
                     solicited_ip, src_ip)
                 ofmsgs.append(
                     valve_of.packetout(port.number, nd_reply.data))
                 self.logger.info(
                     'Responded to ND solicit for %s to %s (%s) on VLAN %u' % (
                         solicited_ip, src_ip, eth_src, vlan.vid))
         elif icmpv6_type == icmpv6.ND_NEIGHBOR_ADVERT:
             ofmsgs.extend(self._update_nexthop(
                 vlan, port, eth_src, src_ip))
             self.logger.info(
                 'ND advert %s (%s) on VLAN %u' % (
                     src_ip, eth_src, vlan.vid))
         elif icmpv6_type == icmpv6.ND_ROUTER_SOLICIT:
             link_local_vips, other_vips = self._link_and_other_vips(vlan)
             for vip in link_local_vips:
                 if src_ip in vip.network:
                     ofmsgs.extend(
                         self._add_host_fib_route(vlan, src_ip))
                     ofmsgs.extend(self._update_nexthop(
                         vlan, port, eth_src, src_ip))
                     ra_advert = valve_packet.router_advert(
                         vlan, vid, vlan.faucet_mac, eth_src,
                         vip.ip, src_ip, other_vips)
                     ofmsgs.append(
                         valve_of.packetout(port.number, ra_advert.data))
                     self.logger.info(
                         'Responded to RS solicit from %s (%s) to VIP %s on VLAN %u' % (
                             src_ip, eth_src, vip, vlan.vid))
                     break
         elif icmpv6_type == icmpv6.ICMPV6_ECHO_REQUEST:
             if (vlan.from_connected_to_vip(src_ip, dst_ip) and
                     pkt_meta.eth_dst == vlan.faucet_mac):
                 icmpv6_echo_reply = valve_packet.icmpv6_echo_reply(
                     vid, vlan.faucet_mac, eth_src,
                     dst_ip, src_ip, ipv6_pkt.hop_limit,
                     icmpv6_pkt.data.id, icmpv6_pkt.data.seq,
                     icmpv6_pkt.data.data)
                 ofmsgs.append(
                     valve_of.packetout(port.number, icmpv6_echo_reply.data))
     return ofmsgs