def _add_faucet_vip_nd(self, vlan, priority, faucet_vip, faucet_vip_host): faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast( valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip)) controller_and_flood = [ valve_of.apply_actions([valve_of.output_controller()]), valve_of.goto_table(self.flood_table)] ofmsgs = [] ofmsgs.append(self.eth_src_table.flowmod( self.eth_src_table.match( eth_type=self.ETH_TYPE, eth_dst=faucet_vip_host_nd_mcast, vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT), priority=priority, inst=controller_and_flood)) ofmsgs.append(self.eth_src_table.flowcontroller( self.eth_src_table.match( eth_type=self.ETH_TYPE, eth_dst=vlan.faucet_mac, vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT), priority=priority)) if faucet_vip.ip in valve_packet.IPV6_LINK_LOCAL: ofmsgs.append(self.eth_src_table.flowmod( self.eth_src_table.match( eth_type=self.ETH_TYPE, eth_dst=valve_packet.IPV6_ALL_ROUTERS_MCAST, vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_ROUTER_SOLICIT), priority=priority, inst=controller_and_flood)) return ofmsgs
def _add_faucet_vip_nd(self, vlan, priority, faucet_vip, faucet_vip_host): faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast( valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip)) ofmsgs = [] # RA if this is a link local FAUCET VIP if faucet_vip.ip.is_link_local: ofmsgs.append(self.classification_table.flowmod( self.classification_table.match( eth_type=self.ETH_TYPE, eth_dst=valve_packet.IPV6_ALL_ROUTERS_MCAST, vlan=vlan), priority=priority, inst=[self.classification_table.goto(self.vip_table)])) ofmsgs.append(self.vip_table.flowmod( self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=valve_packet.IPV6_ALL_ROUTERS_MCAST, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_ROUTER_SOLICIT), priority=priority, inst=self._controller_and_flood())) # IPv6 ping unicast to FAUCET ofmsgs.append(self.vip_table.flowcontroller( self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=vlan.faucet_mac, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ICMPV6_ECHO_REQUEST), priority=priority, max_len=self.ICMP_SIZE)) # IPv6 NA unicast to FAUCET. ofmsgs.append(self.vip_table.flowcontroller( self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=vlan.faucet_mac, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT), priority=priority, max_len=self.ICMP_SIZE)) # IPv6 NS for FAUCET VIP ofmsgs.append(self.classification_table.flowmod( self.classification_table.match( eth_type=self.ETH_TYPE, eth_dst=faucet_vip_host_nd_mcast, vlan=vlan), priority=priority, inst=[self.classification_table.goto(self.vip_table)])) ofmsgs.append(self.vip_table.flowmod( self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=faucet_vip_host_nd_mcast, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT), priority=priority, inst=self._controller_and_flood())) return ofmsgs
def _add_faucet_vip_nd(self, vlan, priority, faucet_vip, faucet_vip_host): faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast( valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip)) controller_and_flood = [ valve_of.apply_actions([valve_of.output_controller()]), self.vip_table.goto(self.output_table) ] ofmsgs = [] ofmsgs.append( self.vip_table.flowcontroller(self.vip_table.match( eth_type=self.ETH_TYPE, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ICMPV6_ECHO_REQUEST), priority=priority, max_len=self.MAX_LEN)) # IPv6 ND for FAUCET VIP ofmsgs.append( self.eth_src_table.flowmod( self.eth_src_table.match(eth_type=self.ETH_TYPE, eth_dst=faucet_vip_host_nd_mcast, vlan=vlan), priority=priority, inst=[self.eth_src_table.goto(self.vip_table)])) ofmsgs.append( self.vip_table.flowmod(self.vip_table.match( eth_type=self.ETH_TYPE, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT), priority=priority, inst=controller_and_flood)) # IPv6 ND for connected hosts. ofmsgs.append( self.vip_table.flowcontroller(self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=vlan.faucet_mac, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT), priority=priority, max_len=self.MAX_LEN)) if faucet_vip.ip.is_link_local: ofmsgs.append( self.eth_src_table.flowmod( self.eth_src_table.match( eth_type=self.ETH_TYPE, eth_dst=valve_packet.IPV6_ALL_ROUTERS_MCAST, vlan=vlan), priority=priority, inst=[self.eth_src_table.goto(self.vip_table)])) ofmsgs.append( self.vip_table.flowmod(self.vip_table.match( eth_type=self.ETH_TYPE, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_ROUTER_SOLICIT), priority=priority, inst=controller_and_flood)) return ofmsgs
def _add_faucet_vip_nd(self, vlan, priority, faucet_vip, faucet_vip_host): faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast( valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip)) ofmsgs = [] # RA if this is a link local FAUCET VIP if faucet_vip.ip.is_link_local: match = { 'eth_type': self.ETH_TYPE, 'eth_dst': valve_packet.IPV6_ALL_ROUTERS_MCAST, 'vlan': vlan } ofmsgs.extend(self.pipeline.select_packets(self.vip_table, match)) ofmsgs.append( self.vip_table.flowmod(self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=valve_packet.IPV6_ALL_ROUTERS_MCAST, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_ROUTER_SOLICIT), priority=priority, inst=self._controller_and_flood())) # IPv6 ping unicast to FAUCET ofmsgs.append( self.vip_table.flowcontroller(self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=vlan.faucet_mac, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ICMPV6_ECHO_REQUEST), priority=priority, max_len=self.ICMP6_ECHO_SIZE)) # IPv6 NA unicast to FAUCET. ofmsgs.append( self.vip_table.flowcontroller(self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=vlan.faucet_mac, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT), priority=priority, max_len=self.ICMP_SIZE)) # IPv6 NS for FAUCET VIP match = { 'eth_type': self.ETH_TYPE, 'eth_dst': faucet_vip_host_nd_mcast, 'vlan': vlan } ofmsgs.extend(self.pipeline.select_packets(self.vip_table, match)) ofmsgs.append( self.vip_table.flowmod(self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=faucet_vip_host_nd_mcast, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT), priority=priority, inst=self._controller_and_flood())) return ofmsgs
def add_faucet_vip(self, vlan, faucet_vip): ofmsgs = [] max_prefixlen = faucet_vip.ip.max_prefixlen faucet_vip_host = self._host_from_faucet_vip(faucet_vip) priority = self.route_priority + max_prefixlen faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast( valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip)) ofmsgs.append(self.valve_flowmod( self.eth_src_table, self.valve_in_match( self.eth_src_table, eth_type=self._eth_type(), vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, eth_dst=faucet_vip_host_nd_mcast, icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT), priority=priority, inst=[ valve_of.apply_actions([valve_of.output_controller()]), valve_of.goto_table(self.flood_table)])) ofmsgs.append(self.valve_flowmod( self.eth_src_table, self.valve_in_match( self.eth_src_table, eth_type=self._eth_type(), eth_dst=self.faucet_mac, vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT), priority=priority, inst=[valve_of.apply_actions([valve_of.output_controller()])])) # Initialize IPv6 FIB ofmsgs.append(self.valve_flowmod( self.eth_src_table, self.valve_in_match( self.eth_src_table, eth_type=self._eth_type(), eth_dst=self.faucet_mac, vlan=vlan), priority=self.route_priority, inst=[valve_of.goto_table(self.fib_table)])) ofmsgs.append(self.valve_flowcontroller( self.fib_table, self.valve_in_match( self.fib_table, eth_type=self._eth_type(), vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, nw_dst=faucet_vip_host, icmpv6_type=icmpv6.ICMPV6_ECHO_REQUEST), priority=priority)) return ofmsgs
def test_nd_for_controller(self): """IPv6 ND for controller VIP.""" dst_ip = ipaddress.IPv6Address('fc00::1:254') nd_mac = valve_packet.ipv6_link_eth_mcast(dst_ip) ip_gw_mcast = valve_packet.ipv6_solicited_node_from_ucast(dst_ip) nd_replies = self.rcv_packet(2, 0x200, { 'eth_src': self.P2_V200_MAC, 'eth_dst': nd_mac, 'vid': 0x200, 'ipv6_src': 'fc00::1:1', 'ipv6_dst': str(ip_gw_mcast), 'neighbor_solicit_ip': str(dst_ip)}) # TODO: check ND reply is valid self.assertTrue(self.packet_outs_from_flows(nd_replies))