Example #1
0
 def _get_dhcp_port_arp_responder(self, lport):
     return arp_responder.ArpResponder(
         app=self,
         network_id=lport.lswitch.unique_key,
         interface_ip=lport.ip,
         interface_mac=lport.mac,
     )
Example #2
0
 def _remove_floatingip_arp_responder(self, floatingip):
     # install floatingip arp responder flow rules
     if netaddr.IPAddress(floatingip.get_ip_address()).version != 4:
         return
     arp_responder.ArpResponder(self, None, floatingip.get_ip_address(),
                                floatingip.get_mac_address(),
                                const.INGRESS_NAT_TABLE).remove()
Example #3
0
 def _create_arp_responder(self, mac):
     self._arp_responder = arp_responder.ArpResponder(
         self,
         None,
         const.METADATA_SERVICE_IP,
         mac
     )
     self._arp_responder.add()
Example #4
0
 def _remove_floatingip_arp_responder(self, floatingip):
     # install floatingip arp responder flow rules
     if floatingip.floating_ip_address.version != n_const.IP_VERSION_4:
         return
     floating_lport = self._get_floating_lport(floatingip)
     arp_responder.ArpResponder(self, None, floatingip.floating_ip_address,
                                floating_lport.mac,
                                const.INGRESS_NAT_TABLE).remove()
Example #5
0
 def _remove_arp_responder(self, lport):
     if not self.is_install_arp_responder:
         return
     ip = lport.get_ip()
     if netaddr.IPAddress(ip).version != 4:
         return
     network_id = lport.get_external_value('local_network_id')
     arp_responder.ArpResponder(self.get_datapath(), network_id,
                                ip).remove()
Example #6
0
 def _remove_arp_responder(self, lport):
     if not self.is_install_arp_responder:
         return
     if lport.get_device_owner() == common_const.DEVICE_OWNER_ROUTER_INTF:
         return
     ip = lport.get_ip()
     if netaddr.IPAddress(ip).version != 4:
         return
     network_id = lport.get_external_value('local_network_id')
     arp_responder.ArpResponder(self, network_id, ip).remove()
Example #7
0
 def _remove_arp_responder(self, host_ip, host_mac):
     # install host arp responder flow rules
     if netaddr.IPAddress(host_ip).version != n_const.IP_VERSION_4:
         return
     arp_responder.ArpResponder(
         self,
         None,
         host_ip,
         host_mac,
         const.INGRESS_NAT_TABLE).remove()
Example #8
0
 def _remove_l2_responders(self, lport):
     if not self.is_install_l2_responder:
         return
     ips = lport.ips
     network_id = lport.lswitch.unique_key
     for ip in ips:
         ip_version = ip.version
         if ip_version == common_const.IP_VERSION_4:
             arp_responder.ArpResponder(self, network_id, ip).remove()
         elif ip_version == common_const.IP_VERSION_6:
             nd_advertisers.NeighborAdvertiser(self, network_id,
                                               ip).remove()
Example #9
0
    def _delete_router_port(self, router, router_port):
        """
        Handle the removal of a router interface from a router. Undoes the
        actions in #_add_new_router_port.
        :param router:        The router on which the interface is removed
        :type router:         LogicalRouter model object
        :param router_port:   The router interface being removed
        :type router_port:    RouterInterface model object
        """
        LOG.info("Removing logical router interface = %s",
                 router_port)
        local_network_id = router_port.lswitch.unique_key

        parser = self.parser
        ofproto = self.ofproto
        router_unique_key = router.unique_key
        ip = router_port.network.ip
        mac = router_port.mac

        # Delete rule for making packets go from L2_LOOKUP_TABLE
        # to L3_LOOKUP_TABLE
        match = parser.OFPMatch()
        match.set_metadata(local_network_id)
        match.set_dl_dst(os_ken_mac_lib.haddr_to_bin(mac))
        self.mod_flow(
            table_id=const.L2_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_HIGH,
            match=match)

        # Delete ARP & ICMP responder for router interface
        if ip.version == common_const.IP_VERSION_4:
            arp_responder.ArpResponder(self, local_network_id, ip).remove()
            icmp_responder.ICMPResponder(self, ip,
                                         router_key=router_unique_key).remove()

        # Delete rule for packets whose destination is router interface.
        match = self._get_router_interface_match(router_unique_key, ip)
        self.mod_flow(
            table_id=const.L3_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_HIGH,
            match=match)

        # Delete rule for routing packets to subnet of this router port
        match = self._get_router_route_match(router_unique_key,
                                             router_port.network)
        self.mod_flow(
            table_id=const.L3_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_MEDIUM,
            match=match)
Example #10
0
    def _delete_router_port(self, router_port):
        LOG.info(_LI("Removing logical router interface = %s"),
                 router_port)
        local_network_id = self.db_store.get_network_id(
            router_port.get_lswitch_id()
        )
        parser = self.get_datapath().ofproto_parser
        ofproto = self.get_datapath().ofproto
        tunnel_key = router_port.get_tunnel_key()
        ip = router_port.get_ip()
        mac = router_port.get_mac()

        if netaddr.IPAddress(ip).version == 4:
            arp_responder.ArpResponder(
                self.get_datapath(), local_network_id, ip).remove()
            icmp_responder.ICMPResponder(self.get_datapath(), ip, mac).remove()

        match = parser.OFPMatch()
        match.set_metadata(local_network_id)
        self.mod_flow(
            datapath=self.get_datapath(),
            table_id=const.L3_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_MEDIUM,
            out_port=ofproto.OFPP_ANY,
            out_group=ofproto.OFPG_ANY,
            match=match)

        match = parser.OFPMatch()
        match.set_metadata(local_network_id)
        match.set_dl_dst(haddr_to_bin(mac))
        self.mod_flow(
            datapath=self.get_datapath(),
            table_id=const.L2_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_HIGH,
            out_port=ofproto.OFPP_ANY,
            out_group=ofproto.OFPG_ANY,
            match=match)

        match = parser.OFPMatch()
        cookie = tunnel_key
        self.mod_flow(
            datapath=self.get_datapath(),
            cookie=cookie,
            cookie_mask=cookie,
            table_id=const.L3_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_MEDIUM,
            out_port=ofproto.OFPP_ANY,
            out_group=ofproto.OFPG_ANY,
            match=match)
Example #11
0
 def _add_l2_responders(self, lport):
     if not self.is_install_l2_responder:
         return
     ips = lport.ips
     network_id = lport.local_network_id
     mac = lport.mac
     for ip in ips:
         ip_version = ip.version
         if ip_version == common_const.IP_VERSION_4:
             arp_responder.ArpResponder(self,
                                        network_id, ip, mac).add()
         elif ip_version == common_const.IP_VERSION_6:
             nd_advertisers.NeighborAdvertiser(self,
                                               network_id, ip, mac).add()
Example #12
0
 def _get_arp_responder(self, floatingip):
     # ARP responder is placed in L2. This is needed to avoid the multicast
     # flow for provider network in L2 table.
     # The packet is egressed to EGRESS_TABLE so it can reach the provider
     # network.
     return arp_responder.ArpResponder(
         app=self,
         network_id=floatingip.floating_lport.lswitch.unique_key,
         interface_ip=floatingip.floating_lport.ip,
         interface_mac=floatingip.floating_lport.mac,
         table_id=const.L2_LOOKUP_TABLE,
         priority=const.PRIORITY_HIGH,
         goto_table_id=const.EGRESS_TABLE,
         source_port_key=floatingip.floating_lport.unique_key,
     )
Example #13
0
    def _uninstall_dhcp_port_responders(self, lport):
        ips_v4 = (ip for ip in lport.ips if ip.version == n_const.IP_VERSION_4)
        for ip in ips_v4:
            icmp_responder.ICMPResponder(
                app=self,
                network_id=lport.lswitch.unique_key,
                interface_ip=lport.ip,
                table_id=const.L2_LOOKUP_TABLE,
            ).remove()

            arp_responder.ArpResponder(
                app=self,
                network_id=lport.lswitch.unique_key,
                interface_ip=ip,
                interface_mac=lport.mac,
            ).remove()
Example #14
0
    def _delete_router_port(self, router, router_port):
        LOG.info("Removing logical router interface = %s",
                 router_port)
        local_network_id = router_port.lswitch.unique_key

        parser = self.parser
        ofproto = self.ofproto
        router_unique_key = router.unique_key
        ip = router_port.network.ip
        mac = router_port.mac

        # Delete rule for making packets go from L2_LOOKUP_TABLE
        # to L3_LOOKUP_TABLE
        match = parser.OFPMatch()
        match.set_metadata(local_network_id)
        match.set_dl_dst(ryu_mac_lib.haddr_to_bin(mac))
        self.mod_flow(
            table_id=const.L2_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_HIGH,
            match=match)

        # Delete ARP & ICMP responder for router interface
        if ip.version == common_const.IP_VERSION_4:
            self.router_port_rarp_cache.pop(mac, None)

            arp_responder.ArpResponder(self, local_network_id, ip).remove()
            icmp_responder.ICMPResponder(self, ip,
                                         router_key=router_unique_key).remove()

        # Delete rule for packets whose destination is router interface.
        match = self._get_router_interface_match(router_unique_key, ip)
        self.mod_flow(
            table_id=const.L3_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_HIGH,
            match=match)

        # Delete rule for routing packets to subnet of this router port
        match = self._get_router_route_match(router_unique_key,
                                             router_port.network.network,
                                             router_port.network.netmask)
        self.mod_flow(
            table_id=const.L3_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_MEDIUM,
            match=match)
Example #15
0
    def _add_new_router_port(self, router, router_port):
        LOG.info(_LI("Adding new logical router interface = %s"), router_port)
        local_network_id = self.db_store.get_network_id(
            router_port.get_lswitch_id())
        datapath = self.get_datapath()
        parser = datapath.ofproto_parser
        ofproto = datapath.ofproto

        mac = router_port.get_mac()
        tunnel_key = router_port.get_tunnel_key()
        dst_ip = router_port.get_ip()

        # Add router ARP & ICMP responder for IPv4 Addresses
        is_ipv4 = netaddr.IPAddress(dst_ip).version == 4
        if is_ipv4:
            arp_responder.ArpResponder(datapath, local_network_id, dst_ip,
                                       mac).add()
            icmp_responder.ICMPResponder(datapath, dst_ip, mac).add()

        # If router interface IP, send to output table
        if is_ipv4:
            match = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP,
                                    metadata=local_network_id,
                                    ipv4_dst=dst_ip)
        else:
            match = parser.OFPMatch(eth_type=ether.ETH_TYPE_IPV6,
                                    metadata=local_network_id,
                                    ipv6_dst=dst_ip)

        actions = []
        actions.append(parser.OFPActionSetField(reg7=tunnel_key))
        action_inst = self.get_datapath().ofproto_parser.OFPInstructionActions(
            ofproto.OFPIT_APPLY_ACTIONS, actions)
        goto_inst = parser.OFPInstructionGotoTable(const.EGRESS_TABLE)
        inst = [action_inst, goto_inst]
        self.mod_flow(datapath,
                      inst=inst,
                      table_id=const.L3_LOOKUP_TABLE,
                      priority=const.PRIORITY_HIGH,
                      match=match)

        # Add router ip match go to output table
        self._install_flow_send_to_output_table(local_network_id, tunnel_key,
                                                dst_ip)

        #add dst_mac=gw_mac l2 goto l3 flow
        match = parser.OFPMatch()
        match.set_metadata(local_network_id)
        match.set_dl_dst(haddr_to_bin(mac))
        goto_inst = parser.OFPInstructionGotoTable(const.L3_LOOKUP_TABLE)
        inst = [goto_inst]
        self.mod_flow(self.get_datapath(),
                      inst=inst,
                      table_id=const.L2_LOOKUP_TABLE,
                      priority=const.PRIORITY_HIGH,
                      match=match)

        # Match all possible routeable traffic and send to proactive routing
        for port in router.get_ports():
            if port.get_id() != router_port.get_id():

                port_net_id = self.db_store.get_network_id(
                    port.get_lswitch_id(), )

                # From this router interface to all other interfaces
                self._add_subnet_send_to_proactive_routing(
                    local_network_id, port.get_cidr_network(),
                    port.get_cidr_netmask(), port.get_tunnel_key(),
                    port_net_id, port.get_mac())

                # From all the other interfaces to this new interface
                self._add_subnet_send_to_proactive_routing(
                    port_net_id, router_port.get_cidr_network(),
                    router_port.get_cidr_netmask(), tunnel_key,
                    local_network_id, router_port.get_mac())
Example #16
0
    def _add_new_router_port(self, router, router_port):
        LOG.info("Adding new logical router interface = %r",
                 router_port)
        local_network_id = router_port.lswitch.unique_key

        parser = self.parser
        ofproto = self.ofproto

        mac = router_port.mac
        router_unique_key = router.unique_key
        dst_ip = router_port.network.ip
        is_ipv4 = (netaddr.IPAddress(dst_ip).version ==
                   common_const.IP_VERSION_4)

        # Add rule for making packets go from L2_LOOKUP_TABLE
        # to L3_LOOKUP_TABLE
        match = parser.OFPMatch()
        match.set_metadata(local_network_id)
        match.set_dl_dst(ryu_mac_lib.haddr_to_bin(mac))
        actions = [parser.OFPActionSetField(reg5=router_unique_key)]
        action_inst = parser.OFPInstructionActions(
            ofproto.OFPIT_APPLY_ACTIONS, actions)
        goto_inst = parser.OFPInstructionGotoTable(const.L3_LOOKUP_TABLE)
        inst = [action_inst, goto_inst]
        self.mod_flow(
            inst=inst,
            table_id=const.L2_LOOKUP_TABLE,
            priority=const.PRIORITY_HIGH,
            match=match)

        # Add router ARP & ICMP responder for IPv4 Addresses
        if is_ipv4:
            self.router_port_rarp_cache[mac] = dst_ip
            arp_responder.ArpResponder(self,
                                       local_network_id,
                                       dst_ip, mac).add()
            icmp_responder.ICMPResponder(self,
                                         dst_ip,
                                         router_key=router_unique_key).add()

        # If router interface is not concrete, send to local controller. local
        # controller will create icmp unreachable mesage. A virtual router
        # interface will not be in local cache, as it doesn't have chassis
        # information.
        lport = self.db_store2.get_one(l2.LogicalPort(id=router_port.id))
        if not lport:
            match = self._get_router_interface_match(router_unique_key, dst_ip)
            actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                              ofproto.OFPCML_NO_BUFFER)]
            action_inst = parser.OFPInstructionActions(
                ofproto.OFPIT_APPLY_ACTIONS, actions)
            self.mod_flow(
                inst=[action_inst],
                table_id=const.L3_LOOKUP_TABLE,
                priority=const.PRIORITY_HIGH,
                match=match)
        else:
            self._add_concrete_router_interface(lport, router=router)

        # Add rule for routing packets to subnet of this router port
        match = self._get_router_route_match(router_unique_key,
                                             router_port.network.network,
                                             router_port.network.netmask)
        self._add_subnet_send_to_route(match, local_network_id, router_port)
Example #17
0
    def _delete_router_port(self, router_port):
        LOG.info(_LI("Removing logical router interface = %s"),
                 router_port)
        local_network_id = self.db_store.get_network_id(
            router_port.get_lswitch_id()
        )

        parser = self.get_datapath().ofproto_parser
        ofproto = self.get_datapath().ofproto
        tunnel_key = router_port.get_tunnel_key()
        ip = router_port.get_ip()
        mac = router_port.get_mac()

        if netaddr.IPAddress(ip).version == 4:
            arp_responder.ArpResponder(self,
                                       local_network_id, ip).remove()
            icmp_responder.ICMPResponder(self, ip, mac).remove()

        match = parser.OFPMatch()
        match.set_metadata(local_network_id)
        self.mod_flow(
            datapath=self.get_datapath(),
            table_id=const.L3_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_MEDIUM,
            match=match)

        match = parser.OFPMatch()
        match.set_metadata(local_network_id)
        match.set_dl_dst(haddr_to_bin(mac))
        self.mod_flow(
            datapath=self.get_datapath(),
            table_id=const.L2_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_HIGH,
            match=match)

        match = parser.OFPMatch()
        cookie = tunnel_key
        self.mod_flow(
            datapath=self.get_datapath(),
            cookie=cookie,
            cookie_mask=cookie,
            table_id=const.L3_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_MEDIUM,
            match=match)

        # Remove router port ip proactive flow
        if netaddr.IPAddress(router_port.get_ip()).version == 4:
            match = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP,
                                    metadata=local_network_id,
                                    ipv4_dst=router_port.get_ip())
        else:
            match = parser.OFPMatch(eth_type=ether.ETH_TYPE_IPV6,
                                    metadata=local_network_id,
                                    ipv6_dst=router_port.get_ip())
        self.mod_flow(
            datapath=self.get_datapath(),
            table_id=const.L3_PROACTIVE_LOOKUP_TABLE,
            command=ofproto.OFPFC_DELETE,
            priority=const.PRIORITY_HIGH,
            match=match)