diff options
Diffstat (limited to 'utils/extras/rtinject')
-rw-r--r-- | utils/extras/rtinject/tap_inject.c | 380 | ||||
-rw-r--r-- | utils/extras/rtinject/tap_inject.h | 108 | ||||
-rw-r--r-- | utils/extras/rtinject/tap_inject_netlink.c | 285 | ||||
-rw-r--r-- | utils/extras/rtinject/tap_inject_node.c | 374 | ||||
-rw-r--r-- | utils/extras/rtinject/tap_inject_tap.c | 170 |
5 files changed, 0 insertions, 1317 deletions
diff --git a/utils/extras/rtinject/tap_inject.c b/utils/extras/rtinject/tap_inject.c deleted file mode 100644 index f41ae86c8..000000000 --- a/utils/extras/rtinject/tap_inject.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "tap_inject.h" - -#include <vnet/mfib/mfib_table.h> -#include <vnet/ip/ip.h> -#include <vnet/ip/lookup.h> -#include <vnet/fib/fib.h> - -static tap_inject_main_t tap_inject_main; -extern dpo_type_t tap_inject_dpo_type; - -tap_inject_main_t * -tap_inject_get_main (void) -{ - return &tap_inject_main; -} - -void -tap_inject_insert_tap (u32 sw_if_index, u32 tap_fd, u32 tap_if_index) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - vec_validate_init_empty (im->sw_if_index_to_tap_fd, sw_if_index, ~0); - vec_validate_init_empty (im->sw_if_index_to_tap_if_index, sw_if_index, ~0); - - vec_validate_init_empty (im->tap_fd_to_sw_if_index, tap_fd, ~0); - - im->sw_if_index_to_tap_fd[sw_if_index] = tap_fd; - im->sw_if_index_to_tap_if_index[sw_if_index] = tap_if_index; - - im->tap_fd_to_sw_if_index[tap_fd] = sw_if_index; - - hash_set (im->tap_if_index_to_sw_if_index, tap_if_index, sw_if_index); -} - -void -tap_inject_delete_tap (u32 sw_if_index) -{ - tap_inject_main_t * im = tap_inject_get_main (); - u32 tap_fd = im->sw_if_index_to_tap_fd[sw_if_index]; - u32 tap_if_index = im->sw_if_index_to_tap_if_index[sw_if_index]; - - im->sw_if_index_to_tap_if_index[sw_if_index] = ~0; - im->sw_if_index_to_tap_fd[sw_if_index] = ~0; - im->tap_fd_to_sw_if_index[tap_fd] = ~0; - - hash_unset (im->tap_if_index_to_sw_if_index, tap_if_index); -} - -u32 -tap_inject_lookup_tap_fd (u32 sw_if_index) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - vec_validate_init_empty (im->sw_if_index_to_tap_fd, sw_if_index, ~0); - return im->sw_if_index_to_tap_fd[sw_if_index]; -} - -u32 -tap_inject_lookup_sw_if_index_from_tap_fd (u32 tap_fd) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - vec_validate_init_empty (im->tap_fd_to_sw_if_index, tap_fd, ~0); - return im->tap_fd_to_sw_if_index[tap_fd]; -} - -u32 -tap_inject_lookup_sw_if_index_from_tap_if_index (u32 tap_if_index) -{ - tap_inject_main_t * im = tap_inject_get_main (); - uword * sw_if_index; - - sw_if_index = hash_get (im->tap_if_index_to_sw_if_index, tap_if_index); - return sw_if_index ? *(u32 *)sw_if_index : ~0; -} - -/* *INDENT-OFF* */ -VLIB_PLUGIN_REGISTER () = { - // .version = VPP_BUILD_VER, FIXME - .description = "router", -}; -/* *INDENT-ON* */ - - -static void -tap_inject_disable (void) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - im->flags &= ~TAP_INJECT_F_ENABLED; - - clib_warning ("tap-inject is not actually disabled."); -} - -static clib_error_t * -tap_inject_enable (void) -{ - vlib_main_t * vm = vlib_get_main (); - tap_inject_main_t * im = tap_inject_get_main (); - - if (tap_inject_is_enabled ()) - return 0; - - tap_inject_enable_netlink (); - - /* Only enable netlink? */ - if (im->flags & TAP_INJECT_F_CONFIG_NETLINK) - { - im->flags |= TAP_INJECT_F_ENABLED; - return 0; - } - - /* Register ARP and ICMP6 as neighbor nodes. */ - ethernet_register_input_type (vm, ETHERNET_TYPE_ARP, im->neighbor_node_index); - ip6_register_protocol (IP_PROTOCOL_ICMP6, im->neighbor_node_index); - - /* Register remaining protocols. */ - ip4_register_protocol (IP_PROTOCOL_ICMP, im->tx_node_index); - - ip4_register_protocol (IP_PROTOCOL_OSPF, im->tx_node_index); - ip4_register_protocol (IP_PROTOCOL_TCP, im->tx_node_index); - ip4_register_protocol (IP_PROTOCOL_UDP, im->tx_node_index); - - ip6_register_protocol (IP_PROTOCOL_OSPF, im->tx_node_index); - ip6_register_protocol (IP_PROTOCOL_TCP, im->tx_node_index); - ip6_register_protocol (IP_PROTOCOL_UDP, im->tx_node_index); - - { - dpo_id_t dpo = DPO_INVALID; - - const mfib_prefix_t pfx_224_0_0_0 = { - .fp_len = 24, - .fp_proto = FIB_PROTOCOL_IP4, - .fp_grp_addr = { - .ip4.as_u32 = clib_host_to_net_u32(0xe0000000), - }, - .fp_src_addr = { - .ip4.as_u32 = 0, - }, - }; - - dpo_set(&dpo, tap_inject_dpo_type, DPO_PROTO_IP4, ~0); - - index_t repi = replicate_create(1, DPO_PROTO_IP4); - replicate_set_bucket(repi, 0, &dpo); - - mfib_table_entry_special_add(0, - &pfx_224_0_0_0, - MFIB_SOURCE_API, - MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF, - repi); - - dpo_reset(&dpo); - } - - im->flags |= TAP_INJECT_F_ENABLED; - - return 0; -} - -static uword -tap_inject_iface_isr (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * f) -{ - tap_inject_main_t * im = tap_inject_get_main (); - vnet_hw_interface_t * hw; - u32 * hw_if_index; - clib_error_t * err = 0; - - vec_foreach (hw_if_index, im->interfaces_to_enable) - { - hw = vnet_get_hw_interface (vnet_get_main (), *hw_if_index); - - if (hw->hw_class_index == ethernet_hw_interface_class.index) - { - err = tap_inject_tap_connect (hw); - if (err) - break; - } - } - - vec_foreach (hw_if_index, im->interfaces_to_disable) - tap_inject_tap_disconnect (*hw_if_index); - - vec_free (im->interfaces_to_enable); - vec_free (im->interfaces_to_disable); - - return err ? -1 : 0; -} - -VLIB_REGISTER_NODE (tap_inject_iface_isr_node, static) = { - .function = tap_inject_iface_isr, - .name = "tap-inject-iface-isr", - .type = VLIB_NODE_TYPE_INPUT, - .state = VLIB_NODE_STATE_INTERRUPT, - .vector_size = sizeof (u32), -}; - - -static clib_error_t * -tap_inject_interface_add_del (struct vnet_main_t * vnet_main, u32 hw_if_index, - u32 add) -{ - vlib_main_t * vm = vlib_get_main (); - tap_inject_main_t * im = tap_inject_get_main (); - - if (!tap_inject_is_config_enabled ()) - return 0; - - tap_inject_enable (); - - if (add) - vec_add1 (im->interfaces_to_enable, hw_if_index); - else - vec_add1 (im->interfaces_to_disable, hw_if_index); - - vlib_node_set_interrupt_pending (vm, tap_inject_iface_isr_node.index); - - return 0; -} - -VNET_HW_INTERFACE_ADD_DEL_FUNCTION (tap_inject_interface_add_del); - - -static clib_error_t * -tap_inject_enable_disable_all_interfaces (int enable) -{ - vnet_main_t * vnet_main = vnet_get_main (); - tap_inject_main_t * im = tap_inject_get_main (); - vnet_hw_interface_t * interfaces; - vnet_hw_interface_t * hw; - u32 ** indices; - - if (enable) - tap_inject_enable (); - else - tap_inject_disable (); - - /* Collect all the interface indices. */ - interfaces = vnet_main->interface_main.hw_interfaces; - indices = enable ? &im->interfaces_to_enable : &im->interfaces_to_disable; - pool_foreach (hw, interfaces, vec_add1 (*indices, hw - interfaces)); - - if (tap_inject_iface_isr (vlib_get_main (), 0, 0)) - return clib_error_return (0, "tap-inject interface add del isr failed"); - - return 0; -} - -static clib_error_t * -tap_inject_cli (vlib_main_t * vm, unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - if (cmd->function_arg) - { - clib_error_t * err; - - if (tap_inject_is_config_disabled ()) - return clib_error_return (0, - "tap-inject is disabled in config, thus cannot be enabled."); - - /* Enable */ - err = tap_inject_enable_disable_all_interfaces (1); - if (err) - { - tap_inject_enable_disable_all_interfaces (0); - return err; - } - - im->flags |= TAP_INJECT_F_CONFIG_ENABLE; - } - else - { - /* Disable */ - tap_inject_enable_disable_all_interfaces (0); - im->flags &= ~TAP_INJECT_F_CONFIG_ENABLE; - } - - return 0; -} - -VLIB_CLI_COMMAND (tap_inject_enable_cmd, static) = { - .path = "enable tap-inject", - .short_help = "enable tap-inject", - .function = tap_inject_cli, - .function_arg = 1, -}; - -VLIB_CLI_COMMAND (tap_inject_disable_cmd, static) = { - .path = "disable tap-inject", - .short_help = "disable tap-inject", - .function = tap_inject_cli, - .function_arg = 0, -}; - - -static clib_error_t * -show_tap_inject (vlib_main_t * vm, unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - vnet_main_t * vnet_main = vnet_get_main (); - tap_inject_main_t * im = tap_inject_get_main (); - u32 k, v; - - if (tap_inject_is_config_disabled ()) - { - vlib_cli_output (vm, "tap-inject is disabled in config.\n"); - return 0; - } - - if (!tap_inject_is_enabled ()) - { - vlib_cli_output (vm, "tap-inject is not enabled.\n"); - return 0; - } - - hash_foreach (k, v, im->tap_if_index_to_sw_if_index, { - vlib_cli_output (vm, "%U -> %U", - format_vnet_sw_interface_name, vnet_main, - vnet_get_sw_interface (vnet_main, v), - format_tap_inject_tap_name, k); - }); - - return 0; -} - -VLIB_CLI_COMMAND (show_tap_inject_cmd, static) = { - .path = "show tap-inject", - .short_help = "show tap-inject", - .function = show_tap_inject, -}; - - -static clib_error_t * -tap_inject_config (vlib_main_t * vm, unformat_input_t * input) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "enable")) - im->flags |= TAP_INJECT_F_CONFIG_ENABLE; - - else if (unformat (input, "disable")) - im->flags |= TAP_INJECT_F_CONFIG_DISABLE; - - else if (unformat (input, "netlink-only")) - im->flags |= TAP_INJECT_F_CONFIG_NETLINK; - - else - return clib_error_return (0, "syntax error `%U'", - format_unformat_error, input); - } - - if (tap_inject_is_config_enabled () && tap_inject_is_config_disabled ()) - return clib_error_return (0, - "tap-inject cannot be both enabled and disabled."); - - return 0; -} - -VLIB_CONFIG_FUNCTION (tap_inject_config, "tap-inject"); diff --git a/utils/extras/rtinject/tap_inject.h b/utils/extras/rtinject/tap_inject.h deleted file mode 100644 index ec5121a09..000000000 --- a/utils/extras/rtinject/tap_inject.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _TAP_INJECT_H -#define _TAP_INJECT_H - -#include <vnet/plugin/plugin.h> -#include <vnet/ip/ip.h> - -#ifndef ETHER_ADDR_LEN -#define ETHER_ADDR_LEN 6 -#endif - -typedef struct { - /* - * tap-inject can be enabled or disabled in config file or during runtime. - * When disabled in config, it is not possible to enable during runtime. - * - * When the netlink-only option is used, netlink configuration is monitored - * and mirrored to the data plane but no traffic is passed between the host - * and the data plane. - */ -#define TAP_INJECT_F_CONFIG_ENABLE (1U << 0) -#define TAP_INJECT_F_CONFIG_DISABLE (1U << 1) -#define TAP_INJECT_F_CONFIG_NETLINK (1U << 2) -#define TAP_INJECT_F_ENABLED (1U << 3) - - u32 flags; - - u32 * sw_if_index_to_tap_fd; - u32 * sw_if_index_to_tap_if_index; - u32 * tap_fd_to_sw_if_index; - u32 * tap_if_index_to_sw_if_index; - - u32 * interfaces_to_enable; - u32 * interfaces_to_disable; - - u32 * rx_file_descriptors; - - u32 rx_node_index; - u32 tx_node_index; - u32 neighbor_node_index; - - u32 * rx_buffers; - -} tap_inject_main_t; - - -tap_inject_main_t * tap_inject_get_main (void); - -void tap_inject_insert_tap (u32 sw_if_index, u32 tap_fd, u32 tap_if_index); -void tap_inject_delete_tap (u32 sw_if_index); - -u32 tap_inject_lookup_tap_fd (u32 sw_if_index); -u32 tap_inject_lookup_sw_if_index_from_tap_fd (u32 tap_fd); -u32 tap_inject_lookup_sw_if_index_from_tap_if_index (u32 tap_if_index); - -static inline int -tap_inject_is_enabled (void) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - return !!(im->flags & TAP_INJECT_F_ENABLED); -} - -static inline int -tap_inject_is_config_enabled (void) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - return !!(im->flags & TAP_INJECT_F_CONFIG_ENABLE); -} - -static inline int -tap_inject_is_config_disabled (void) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - return !!(im->flags & TAP_INJECT_F_CONFIG_DISABLE); -} - - -/* Netlink */ - -void tap_inject_enable_netlink (void); - - -/* Tap */ - -clib_error_t * tap_inject_tap_connect (vnet_hw_interface_t * hw); -clib_error_t * tap_inject_tap_disconnect (u32 sw_if_index); - -u8 * format_tap_inject_tap_name (u8 * s, va_list * args); - -#endif /* _TAP_INJECT_H */ diff --git a/utils/extras/rtinject/tap_inject_netlink.c b/utils/extras/rtinject/tap_inject_netlink.c deleted file mode 100644 index c0e0ce995..000000000 --- a/utils/extras/rtinject/tap_inject_netlink.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "../devices/rtnetlink/netns.h" -#include <vlibmemory/api.h> -#include <vnet/ip/ip6_neighbor.h> -#include <vnet/ip/lookup.h> -#include <vnet/fib/fib.h> -#include <vnet/ethernet/arp.h> -#include <arpa/inet.h> -#include <linux/mpls.h> -#include <vnet/mpls/packet.h> - -#include "tap_inject.h" - -static void -add_del_addr (ns_addr_t * a, int is_del) -{ - vlib_main_t * vm = vlib_get_main (); - u32 sw_if_index; - - sw_if_index = tap_inject_lookup_sw_if_index_from_tap_if_index ( - a->ifaddr.ifa_index); - - if (sw_if_index == ~0) - return; - - if (a->ifaddr.ifa_family == AF_INET) - { - ip4_add_del_interface_address (vm, sw_if_index, - (ip4_address_t *) a->local, a->ifaddr.ifa_prefixlen, is_del); - } - else if (a->ifaddr.ifa_family == AF_INET6) - { - ip6_add_del_interface_address (vm, sw_if_index, - (ip6_address_t *) a->addr, a->ifaddr.ifa_prefixlen, is_del); - } -} - - -struct set_flags_args { - u32 index; - u8 flags; -}; - -static void -set_flags_cb (struct set_flags_args * a) -{ - vnet_sw_interface_set_flags (vnet_get_main (), a->index, a->flags); -} - -static void -add_del_link (ns_link_t * l, int is_del) -{ - struct set_flags_args args = { ~0, 0 }; - vnet_sw_interface_t * sw; - u8 flags = 0; - u32 sw_if_index; - - sw_if_index = tap_inject_lookup_sw_if_index_from_tap_if_index ( - l->ifi.ifi_index); - - if (sw_if_index == ~0) - return; - - sw = vnet_get_sw_interface (vnet_get_main (), sw_if_index); - - flags = sw->flags; - - if (l->ifi.ifi_flags & IFF_UP) - flags |= VNET_SW_INTERFACE_FLAG_ADMIN_UP; - else - flags &= ~VNET_SW_INTERFACE_FLAG_ADMIN_UP; - - args.index = sw_if_index; - args.flags = flags; - - vl_api_rpc_call_main_thread (set_flags_cb, (u8 *)&args, sizeof (args)); -} - - -static void -add_del_neigh (ns_neigh_t * n, int is_del) -{ - vnet_main_t * vnet_main = vnet_get_main (); - vlib_main_t * vm = vlib_get_main (); - u32 sw_if_index; - - sw_if_index = tap_inject_lookup_sw_if_index_from_tap_if_index ( - n->nd.ndm_ifindex); - - if (sw_if_index == ~0) - return; - - if (n->nd.ndm_family == AF_INET) - { - ethernet_arp_ip4_over_ethernet_address_t a; - - memset (&a, 0, sizeof (a)); - - clib_memcpy (&a.mac, n->lladdr, ETHER_ADDR_LEN); - clib_memcpy (&a.ip4, n->dst, sizeof (a.ip4)); - - - if (n->nd.ndm_state & NUD_REACHABLE) - { - vnet_arp_set_ip4_over_ethernet (vnet_main, sw_if_index, - &a, - IP_NEIGHBOR_FLAG_NO_FIB_ENTRY); - - } - else if (n->nd.ndm_state & NUD_FAILED) - { - vnet_arp_unset_ip4_over_ethernet (vnet_main, sw_if_index, &a); - } - } - else if (n->nd.ndm_family == AF_INET6) - { - if (n->nd.ndm_state & NUD_REACHABLE) - { - - mac_address_t * mac1; - mac1=malloc(sizeof(mac_address_t)); - memcpy (mac1, n->lladdr, ETHER_ADDR_LEN); - vnet_set_ip6_ethernet_neighbor (vm, sw_if_index, - (ip6_address_t *) n->dst, (mac_address_t *) mac1, - IP_NEIGHBOR_FLAG_NO_FIB_ENTRY); - } - else - vnet_unset_ip6_ethernet_neighbor (vm, sw_if_index, - (ip6_address_t *) n->dst); - } -} - - -#define TAP_INJECT_HOST_ROUTE_TABLE_MAIN 254 - -static void -get_mpls_label_stack(struct mpls_label *addr, u32* l) -{ - u32 entry = ntohl(addr[0].entry); - u32 label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT; - - for(int i = 1; label != 0; i++) { - *l++ = label; - if(entry & MPLS_LS_S_MASK) - return; - entry = ntohl(addr[i].entry); - label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT; - } -} - -static void -add_del_route (ns_route_t * r, int is_del) -{ - u32 sw_if_index; - - sw_if_index = tap_inject_lookup_sw_if_index_from_tap_if_index (r->oif); - - if (sw_if_index == ~0) - return; - - if (r->rtm.rtm_family == AF_INET) - { - u32 stack[MPLS_STACK_DEPTH] = {0}; - - fib_prefix_t prefix; - ip46_address_t nh; - - memset (&prefix, 0, sizeof (prefix)); - prefix.fp_len = r->rtm.rtm_dst_len; - prefix.fp_proto = FIB_PROTOCOL_IP4; - clib_memcpy (&prefix.fp_addr.ip4, r->dst, sizeof (prefix.fp_addr.ip4)); - get_mpls_label_stack(r->encap, stack); - memset (&nh, 0, sizeof (nh)); - clib_memcpy (&nh.ip4, r->gateway, sizeof (nh.ip4)); - if(*stack == 0) - fib_table_entry_path_add (0, &prefix, FIB_SOURCE_API, - FIB_ENTRY_FLAG_NONE, prefix.fp_proto, - &nh, sw_if_index, 0, - 0 /* weight */, NULL, - FIB_ROUTE_PATH_FLAG_NONE); - else { - fib_route_path_t *rpaths = NULL, rpath; - memset(&rpath, 0, sizeof(rpath)); - rpath.frp_weight = 1; - rpath.frp_proto = DPO_PROTO_IP4; - clib_memcpy(&rpath.frp_addr.ip4, r->gateway, sizeof(rpath.frp_addr.ip4)); - rpath.frp_sw_if_index = sw_if_index; - for(int i = 0; i < MPLS_STACK_DEPTH && stack[i] != 0; i++) { - fib_mpls_label_t fib_label = {stack[i],0,0,0}; - vec_add1(rpath.frp_label_stack, fib_label); - } - vec_add1(rpaths, rpath); - fib_table_entry_path_add2(0, - &prefix, - FIB_SOURCE_API, - FIB_ENTRY_FLAG_NONE, - rpaths); - } - } - else if (r->rtm.rtm_family == AF_INET6) - { - fib_prefix_t prefix; - ip46_address_t nh; - memset (&prefix, 0, sizeof (prefix)); - prefix.fp_len = r->rtm.rtm_dst_len; - prefix.fp_proto = FIB_PROTOCOL_IP6; - clib_memcpy (&prefix.fp_addr.ip6, r->dst, sizeof (prefix.fp_addr.ip6)); - memset (&nh, 0, sizeof (nh)); - clib_memcpy (&nh.ip6, r->gateway, sizeof (nh.ip6)); - fib_table_entry_path_add (0, &prefix, FIB_SOURCE_API, - FIB_ENTRY_FLAG_NONE, prefix.fp_proto, - &nh, sw_if_index, 0, - 0 /* weight */, NULL, - FIB_ROUTE_PATH_FLAG_NONE); - } -/* else if (r->rtm.rtm_family == AF_MPLS) - { - u32 dst_label; - get_mpls_label_stack((struct mpls_label*) r->dst, &dst_label); - struct rtvia *via = (struct rtvia*) r->via; - fib_prefix_t prefix; - fib_route_path_t *rpaths = NULL, rpath; - memset (&prefix, 0, sizeof (prefix)); - prefix.fp_len = 21; - prefix.fp_label = dst_label; - prefix.fp_proto = FIB_PROTOCOL_MPLS; - prefix.fp_payload_proto = DPO_PROTO_IP4; - memset(&rpath, 0, sizeof(rpath)); - clib_memcpy (&rpath.frp_addr.ip4, via->rtvia_addr, sizeof (rpath.frp_addr.ip4)); - rpath.frp_weight = 1; - rpath.frp_proto = DPO_PROTO_IP4; - rpath.frp_fib_index = 0; - rpath.frp_sw_if_index = sw_if_index; - vec_add1(rpaths, rpath); - fib_table_entry_path_add2(0, - &prefix, - FIB_SOURCE_API, - FIB_ENTRY_FLAG_NONE, - rpaths); - }*/ -} - - -static void -netns_notify_cb (void * obj, netns_type_t type, u32 flags, uword opaque) -{ - if (type == NETNS_TYPE_ADDR) - add_del_addr ((ns_addr_t *)obj, flags & NETNS_F_DEL); - - else if (type == NETNS_TYPE_LINK) - add_del_link ((ns_link_t *)obj, flags & NETNS_F_DEL); - - else if (type == NETNS_TYPE_NEIGH) - add_del_neigh ((ns_neigh_t *)obj, flags & NETNS_F_DEL); - - else if (type == NETNS_TYPE_ROUTE) - add_del_route ((ns_route_t *)obj, flags & NETNS_F_DEL); -} - -void -tap_inject_enable_netlink (void) -{ - char nsname = 0; - netns_sub_t sub = { - .notify = netns_notify_cb, - .opaque = 0, - }; - - netns_open (&nsname, &sub); -} diff --git a/utils/extras/rtinject/tap_inject_node.c b/utils/extras/rtinject/tap_inject_node.c deleted file mode 100644 index 73c296451..000000000 --- a/utils/extras/rtinject/tap_inject_node.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "tap_inject.h" -#include <sys/uio.h> -#include <netinet/in.h> -#include <vnet/ethernet/arp_packet.h> - -vlib_node_registration_t tap_inject_rx_node; -vlib_node_registration_t tap_inject_tx_node; -vlib_node_registration_t tap_inject_neighbor_node; - -enum { - NEXT_NEIGHBOR_ARP, - NEXT_NEIGHBOR_ICMP6, -}; - -/** - * @brief Dynamically added tap_inject DPO type - */ -dpo_type_t tap_inject_dpo_type; - -static inline void -tap_inject_tap_send_buffer (int fd, vlib_buffer_t * b) -{ - struct iovec iov; - ssize_t n_bytes; - - iov.iov_base = vlib_buffer_get_current (b); - iov.iov_len = b->current_length; - - n_bytes = writev (fd, &iov, 1); - - if (n_bytes < 0) - clib_warning ("writev failed"); - else if (n_bytes < b->current_length || b->flags & VLIB_BUFFER_NEXT_PRESENT) - clib_warning ("buffer truncated"); -} - -static uword -tap_inject_tx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f) -{ - vlib_buffer_t * b; - u32 * pkts; - u32 fd; - u32 i; - - pkts = vlib_frame_vector_args (f); - - for (i = 0; i < f->n_vectors; ++i) - { - b = vlib_get_buffer (vm, pkts[i]); - - fd = tap_inject_lookup_tap_fd (vnet_buffer (b)->sw_if_index[VLIB_RX]); - if (fd == ~0) - continue; - - /* Re-wind the buffer to the start of the Ethernet header. */ - vlib_buffer_advance (b, -b->current_data); - - tap_inject_tap_send_buffer (fd, b); - } - - vlib_buffer_free (vm, pkts, f->n_vectors); - return f->n_vectors; -} - -VLIB_REGISTER_NODE (tap_inject_tx_node) = { - .function = tap_inject_tx, - .name = "tap-inject-tx", - .vector_size = sizeof (u32), - .type = VLIB_NODE_TYPE_INTERNAL, -}; - - -static uword -tap_inject_neighbor (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * f) -{ - vlib_buffer_t * b; - u32 * pkts; - u32 fd; - u32 i; - u32 bi; - u32 next_index = node->cached_next_index; - u32 next = ~0; - u32 n_left; - u32 * to_next; - - pkts = vlib_frame_vector_args (f); - - for (i = 0; i < f->n_vectors; ++i) - { - bi = pkts[i]; - b = vlib_get_buffer (vm, bi); - - fd = tap_inject_lookup_tap_fd (vnet_buffer (b)->sw_if_index[VLIB_RX]); - if (fd == ~0) - { - vlib_buffer_free (vm, &bi, 1); - continue; - } - - /* Re-wind the buffer to the start of the Ethernet header. */ - vlib_buffer_advance (b, -b->current_data); - - tap_inject_tap_send_buffer (fd, b); - - /* Send the buffer to a neighbor node too? */ - { - ethernet_header_t * eth = vlib_buffer_get_current (b); - u16 ether_type = htons (eth->type); - - if (ether_type == ETHERNET_TYPE_ARP) - { - ethernet_arp_header_t * arp = (void *)(eth + 1); - - if (arp->opcode == ntohs (ETHERNET_ARP_OPCODE_reply)) - next = NEXT_NEIGHBOR_ARP; - } - else if (ether_type == ETHERNET_TYPE_IP6) - { - ip6_header_t * ip = (void *)(eth + 1); - icmp46_header_t * icmp = (void *)(ip + 1); - - if (ip->protocol == IP_PROTOCOL_ICMP6 && - icmp->type == ICMP6_neighbor_advertisement) - next = NEXT_NEIGHBOR_ICMP6; - } - } - - if (next == ~0) - { - vlib_buffer_free (vm, &bi, 1); - continue; - } - - /* ARP and ICMP6 expect to start processing after the Ethernet header. */ - vlib_buffer_advance (b, sizeof (ethernet_header_t)); - - vlib_get_next_frame (vm, node, next_index, to_next, n_left); - - *(to_next++) = bi; - --n_left; - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left, bi, next); - vlib_put_next_frame (vm, node, next_index, n_left); - } - - return f->n_vectors; -} - -VLIB_REGISTER_NODE (tap_inject_neighbor_node) = { - .function = tap_inject_neighbor, - .name = "tap-inject-neighbor", - .vector_size = sizeof (u32), - .type = VLIB_NODE_TYPE_INTERNAL, - .n_next_nodes = 2, - .next_nodes = { - [NEXT_NEIGHBOR_ARP] = "arp-input", - [NEXT_NEIGHBOR_ICMP6] = "icmp6-neighbor-solicitation", - }, -}; - - -#define MTU 1500 -#define MTU_BUFFERS ((MTU + vlib_buffer_get_default_data_size(vm) - 1) / vlib_buffer_get_default_data_size(vm)) -#define NUM_BUFFERS_TO_ALLOC 32 - -static inline uword -tap_rx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f, int fd) -{ - tap_inject_main_t * im = tap_inject_get_main (); - u32 sw_if_index; - struct iovec iov[MTU_BUFFERS]; - u32 bi[MTU_BUFFERS]; - vlib_buffer_t * b; - ssize_t n_bytes; - ssize_t n_bytes_left; - u32 i, j; - - sw_if_index = tap_inject_lookup_sw_if_index_from_tap_fd (fd); - if (sw_if_index == ~0) - return 0; - - /* Allocate buffers in bulk when there are less than enough to rx an MTU. */ - if (vec_len (im->rx_buffers) < MTU_BUFFERS) - { - u32 len = vec_len (im->rx_buffers); - - - u8 index = vlib_buffer_pool_get_default_for_numa (vm,0); - len = vlib_buffer_alloc_from_pool(vm, - &im->rx_buffers[len], NUM_BUFFERS_TO_ALLOC, - index); - - _vec_len (im->rx_buffers) += len; - - if (vec_len (im->rx_buffers) < MTU_BUFFERS) - { - clib_warning ("failed to allocate buffers"); - return 0; - } - } - - /* Fill buffers from the end of the list to make it easier to resize. */ - for (i = 0, j = vec_len (im->rx_buffers) - 1; i < MTU_BUFFERS; ++i, --j) - { - vlib_buffer_t * b; - - bi[i] = im->rx_buffers[j]; - - b = vlib_get_buffer (vm, bi[i]); - - iov[i].iov_base = b->data; - iov[i].iov_len = VLIB_BUFFER_DEFAULT_DATA_SIZE; - } - - n_bytes = readv (fd, iov, MTU_BUFFERS); - if (n_bytes < 0) - { - clib_warning ("readv failed"); - return 0; - } - - b = vlib_get_buffer (vm, bi[0]); - - vnet_buffer (b)->sw_if_index[VLIB_RX] = sw_if_index; - vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index; - - n_bytes_left = n_bytes - VLIB_BUFFER_DEFAULT_DATA_SIZE; - - if (n_bytes_left > 0) - { - b->total_length_not_including_first_buffer = n_bytes_left; - b->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID; - } - - b->current_length = n_bytes; - - /* If necessary, configure any remaining buffers in the chain. */ - for (i = 1; n_bytes_left > 0; ++i, n_bytes_left -= VLIB_BUFFER_DEFAULT_DATA_SIZE) - { - b = vlib_get_buffer (vm, bi[i - 1]); - b->current_length = VLIB_BUFFER_DEFAULT_DATA_SIZE; - b->flags |= VLIB_BUFFER_NEXT_PRESENT; - b->next_buffer = bi[i]; - - b = vlib_get_buffer (vm, bi[i]); - b->current_length = n_bytes_left; - } - - _vec_len (im->rx_buffers) -= i; - - /* Get the packet to the output node. */ - { - vnet_hw_interface_t * hw; - vlib_frame_t * new_frame; - u32 * to_next; - - hw = vnet_get_hw_interface (vnet_get_main (), sw_if_index); - - new_frame = vlib_get_frame_to_node (vm, hw->output_node_index); - to_next = vlib_frame_vector_args (new_frame); - to_next[0] = bi[0]; - new_frame->n_vectors = 1; - - vlib_put_frame_to_node (vm, hw->output_node_index, new_frame); - } - - return 1; -} - -static uword -tap_inject_rx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f) -{ - tap_inject_main_t * im = tap_inject_get_main (); - u32 * fd; - uword count = 0; - - vec_foreach (fd, im->rx_file_descriptors) - { - if (tap_rx (vm, node, f, *fd) != 1) - { - clib_warning ("rx failed"); - count = 0; - break; - } - ++count; - } - - vec_free (im->rx_file_descriptors); - - return count; -} - -VLIB_REGISTER_NODE (tap_inject_rx_node) = { - .function = tap_inject_rx, - .name = "tap-inject-rx", - .type = VLIB_NODE_TYPE_INPUT, - .state = VLIB_NODE_STATE_INTERRUPT, - .vector_size = sizeof (u32), -}; - -/** - * @brief no-op lock function. - */ -static void -tap_inject_dpo_lock (dpo_id_t * dpo) -{ -} - -/** - * @brief no-op unlock function. - */ -static void -tap_inject_dpo_unlock (dpo_id_t * dpo) -{ -} - -u8 * -format_tap_inject_dpo (u8 * s, va_list * args) -{ - return (format (s, "tap-inject:[%d]", 0)); -} - -const static dpo_vft_t tap_inject_vft = { - .dv_lock = tap_inject_dpo_lock, - .dv_unlock = tap_inject_dpo_unlock, - .dv_format = format_tap_inject_dpo, -}; - -const static char *const tap_inject_tx_nodes[] = { - "tap-inject-tx", - NULL, -}; - -const static char *const *const tap_inject_nodes[DPO_PROTO_NUM] = { - [DPO_PROTO_IP4] = tap_inject_tx_nodes, - [DPO_PROTO_IP6] = tap_inject_tx_nodes, -}; - -static clib_error_t * -tap_inject_init (vlib_main_t * vm) -{ - tap_inject_main_t * im = tap_inject_get_main (); - - im->rx_node_index = tap_inject_rx_node.index; - im->tx_node_index = tap_inject_tx_node.index; - im->neighbor_node_index = tap_inject_neighbor_node.index; - - tap_inject_dpo_type = dpo_register_new_type (&tap_inject_vft, tap_inject_nodes); - - vec_alloc (im->rx_buffers, NUM_BUFFERS_TO_ALLOC); - vec_reset_length (im->rx_buffers); - - return 0; -} - -VLIB_INIT_FUNCTION (tap_inject_init); diff --git a/utils/extras/rtinject/tap_inject_tap.c b/utils/extras/rtinject/tap_inject_tap.c deleted file mode 100644 index a3ec9ffef..000000000 --- a/utils/extras/rtinject/tap_inject_tap.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "tap_inject.h" - -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <linux/if.h> -#include <linux/if_arp.h> -#include <linux/if_ether.h> -#include <linux/if_tun.h> -#include <netinet/in.h> -#include <vnet/unix/tuntap.h> - -#include <vlib/unix/unix.h> - - -static clib_error_t * -tap_inject_tap_read (clib_file_t * f) -{ - vlib_main_t * vm = vlib_get_main (); - tap_inject_main_t * im = tap_inject_get_main (); - - vec_add1 (im->rx_file_descriptors, f->file_descriptor); - - vlib_node_set_interrupt_pending (vm, im->rx_node_index); - - return 0; -} - -#define TAP_INJECT_TAP_BASE_NAME "vpp" - -clib_error_t * -tap_inject_tap_connect (vnet_hw_interface_t * hw) -{ - vnet_main_t * vnet_main = vnet_get_main (); - vnet_sw_interface_t * sw = vnet_get_sw_interface (vnet_main, hw->hw_if_index); - static const int one = 1; - int fd; - struct ifreq ifr; - clib_file_t template; - u32 tap_fd; - u8 * name; - - memset (&ifr, 0, sizeof (ifr)); - memset (&template, 0, sizeof (template)); - - ASSERT (hw->hw_if_index == sw->sw_if_index); - - /* Create the tap. */ - tap_fd = open ("/dev/net/tun", O_RDWR); - - if ((int)tap_fd < 0) - return clib_error_return (0, "failed to open tun device"); - - name = format (0, TAP_INJECT_TAP_BASE_NAME "%u%c", hw->hw_instance, 0); - - strncpy (ifr.ifr_name, (char *) name, sizeof (ifr.ifr_name) - 1); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - - if (ioctl (tap_fd, TUNSETIFF, (void *)&ifr) < 0) - { - close (tap_fd); - return clib_error_return (0, "failed to create tap"); - } - - if (ioctl (tap_fd, FIONBIO, &one) < 0) - { - close (tap_fd); - return clib_error_return (0, "failed to set tap to non-blocking io"); - } - - /* Open a socket to configure the device. */ - fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); - - if (fd < 0) - { - close (tap_fd); - return clib_error_return (0, "failed to configure tap"); - } - - if (hw->hw_address) - clib_memcpy (ifr.ifr_hwaddr.sa_data, hw->hw_address, ETHER_ADDR_LEN); - - ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; - - /* Set the hardware address. */ - if (ioctl (fd, SIOCSIFHWADDR, &ifr) < 0) - { - close (tap_fd); - close (fd); - return clib_error_return (0, "failed to set tap hardware address"); - } - - /* Get the tap if index. */ - if (ioctl (fd, SIOCGIFINDEX, &ifr) < 0) - { - close (tap_fd); - close (fd); - return clib_error_return (0, "failed to procure tap if index"); - } - - close (fd); - - /* Get notified when the tap needs to be read. */ - template.read_function = tap_inject_tap_read; - template.file_descriptor = tap_fd; - - clib_file_add (&file_main, &template); - - tap_inject_insert_tap (sw->sw_if_index, tap_fd, ifr.ifr_ifindex); - - return 0; -} - -clib_error_t * -tap_inject_tap_disconnect (u32 sw_if_index) -{ - u32 tap_fd; - - tap_fd = tap_inject_lookup_tap_fd (sw_if_index); - if (tap_fd == ~0) - return clib_error_return (0, "failed to disconnect tap"); - - tap_inject_delete_tap (sw_if_index); - - close (tap_fd); - return 0; -} - - -u8 * -format_tap_inject_tap_name (u8 * s, va_list * args) -{ - int fd; - struct ifreq ifr; - - fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); - - if (fd < 0) - return 0; - - memset (&ifr, 0, sizeof (ifr)); - - ifr.ifr_ifindex = va_arg (*args, u32); - - if (ioctl (fd, SIOCGIFNAME, &ifr) < 0) - { - close (fd); - return 0; - } - - close (fd); - - return format (s, "%s", ifr.ifr_name); -} |