diff --git a/CMakeLists.txt b/CMakeLists.txt index 45d9a2e..9e35132 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ add_vpp_plugin(lcpng_if lcpng_if_api.c lcpng_if_cli.c lcpng_if_node.c + lcpng_if_sync.c API_FILES lcpng_if.api diff --git a/lcpng.c b/lcpng.c index 2ffd611..b627d67 100644 --- a/lcpng.c +++ b/lcpng.c @@ -23,9 +23,7 @@ lcp_main_t lcp_main; -u8 * -lcp_get_default_ns (void) -{ +u8 *lcp_get_default_ns(void) { lcp_main_t *lcpm = &lcp_main; if (lcpm->default_namespace[0] == 0) @@ -33,9 +31,7 @@ lcp_get_default_ns (void) return lcpm->default_namespace; } -int -lcp_get_default_ns_fd (void) -{ +int lcp_get_default_ns_fd(void) { lcp_main_t *lcpm = &lcp_main; return lcpm->default_ns_fd; @@ -44,9 +40,7 @@ lcp_get_default_ns_fd (void) /* * ns is expected to be or look like a NUL-terminated C string. */ -int -lcp_set_default_ns (u8 *ns) -{ +int lcp_set_default_ns(u8 *ns) { lcp_main_t *lcpm = &lcp_main; char *p; int len; @@ -59,21 +53,20 @@ lcp_set_default_ns (u8 *ns) if (!p || *p == 0) { - clib_memset (lcpm->default_namespace, 0, - sizeof (lcpm->default_namespace)); - if (lcpm->default_ns_fd > 0) - close (lcpm->default_ns_fd); - lcpm->default_ns_fd = 0; - return 0; + clib_memset(lcpm->default_namespace, 0, sizeof(lcpm->default_namespace)); + if (lcpm->default_ns_fd > 0) + close(lcpm->default_ns_fd); + lcpm->default_ns_fd = 0; + return 0; } - clib_strncpy ((char *) lcpm->default_namespace, p, LCP_NS_LEN - 1); + clib_strncpy((char *)lcpm->default_namespace, p, LCP_NS_LEN - 1); - s = format (0, "/var/run/netns/%s%c", (char *) lcpm->default_namespace, 0); - lcpm->default_ns_fd = open ((char *) s, O_RDONLY); - vec_free (s); + s = format(0, "/var/run/netns/%s%c", (char *)lcpm->default_namespace, 0); + lcpm->default_ns_fd = open((char *)s, O_RDONLY); + vec_free(s); - return 0; + return 0; } /* diff --git a/lcpng.h b/lcpng.h index efddec3..900f0a1 100644 --- a/lcpng.h +++ b/lcpng.h @@ -33,9 +33,9 @@ extern lcp_main_t lcp_main; /** * Get/Set the default namespace for LCP host taps. */ -int lcp_set_default_ns (u8 *ns); -u8 *lcp_get_default_ns (void); /* Returns NULL or shared string */ -int lcp_get_default_ns_fd (void); +int lcp_set_default_ns(u8 *ns); +u8 *lcp_get_default_ns(void); /* Returns NULL or shared string */ +int lcp_get_default_ns_fd(void); #endif diff --git a/lcpng_adj.c b/lcpng_adj.c index 2d7bf6c..0b8aa77 100644 --- a/lcpng_adj.c +++ b/lcpng_adj.c @@ -185,17 +185,17 @@ lcp_adj_show_cmd (vlib_main_t *vm, unformat_input_t *input, if (unformat (input, "verbose")) verbose = 1; - vlib_cli_output (vm, "lcp Adjs:\n%U", BV (format_bihash), &lcp_adj_tbl, - verbose); + vlib_cli_output(vm, "lcp Adjs:\n%U", BV(format_bihash), &lcp_adj_tbl, + verbose); return 0; } -VLIB_CLI_COMMAND (lcp_itf_pair_show_cmd_node, static) = { - .path = "show lcp adj", - .function = lcp_adj_show_cmd, - .short_help = "show lcp adj", - .is_mp_safe = 1, +VLIB_CLI_COMMAND(lcp_itf_pair_show_cmd_node, static) = { + .path = "show lcp adj", + .function = lcp_adj_show_cmd, + .short_help = "show lcp adj", + .is_mp_safe = 1, }; const adj_delegate_vft_t lcp_adj_vft = { @@ -210,7 +210,7 @@ lcp_adj_init (vlib_main_t *vm) { adj_type = adj_delegate_register_new_type (&lcp_adj_vft); - BV (clib_bihash_init) (&lcp_adj_tbl, "lcp ADJ table", 1024, 1 << 24); + BV(clib_bihash_init)(&lcp_adj_tbl, "lcp ADJ table", 1024, 1 << 24); BV (clib_bihash_set_kvp_format_fn) (&lcp_adj_tbl, format_lcp_adj_kvp); return (NULL); diff --git a/lcpng_if_api.c b/lcpng_if_api.c index ba504d1..3b34d99 100644 --- a/lcpng_if_api.c +++ b/lcpng_if_api.c @@ -169,20 +169,18 @@ vl_api_lcp_itf_pair_get_t_handler (vl_api_lcp_itf_pair_get_t *mp) } static void -vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp) -{ +vl_api_lcp_default_ns_set_t_handler(vl_api_lcp_default_ns_set_t *mp) { vl_api_lcp_default_ns_set_reply_t *rmp; int rv; mp->namespace[LCP_NS_LEN - 1] = 0; - rv = lcp_set_default_ns (mp->namespace); + rv = lcp_set_default_ns(mp->namespace); - REPLY_MACRO (VL_API_LCP_DEFAULT_NS_SET_REPLY); + REPLY_MACRO(VL_API_LCP_DEFAULT_NS_SET_REPLY); } static void -vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp) -{ +vl_api_lcp_default_ns_get_t_handler(vl_api_lcp_default_ns_get_t *mp) { lcp_main_t *lcpm = &lcp_main; vl_api_lcp_default_ns_get_reply_t *rmp; vl_api_registration_t *reg; @@ -197,7 +195,7 @@ vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp) rmp->_vl_msg_id = (VL_API_LCP_DEFAULT_NS_GET_REPLY + lcpm->msg_id_base); rmp->context = mp->context; - ns = (char *) lcp_get_default_ns (); + ns = (char *)lcp_get_default_ns(); if (ns) clib_strncpy ((char *) rmp->namespace, ns, LCP_NS_LEN - 1); diff --git a/lcpng_if_cli.c b/lcpng_if_cli.c index dd3f2bf..1173652 100644 --- a/lcpng_if_cli.c +++ b/lcpng_if_cli.c @@ -99,55 +99,53 @@ lcp_itf_pair_create_command_fn (vlib_main_t *vm, unformat_input_t *input, vec_free (ns); if (r) - return clib_error_return (0, "lcp pair creation failed (%d)", r); + return clib_error_return(0, "lcp pair creation failed (%d)", r); return 0; } -VLIB_CLI_COMMAND (lcp_itf_pair_create_command, static) = { - .path = "lcp create", - .short_help = "lcp create | host-if " - "netns [tun]", - .function = lcp_itf_pair_create_command_fn, +VLIB_CLI_COMMAND(lcp_itf_pair_create_command, static) = { + .path = "lcp create", + .short_help = "lcp create | host-if " + "netns [tun]", + .function = lcp_itf_pair_create_command_fn, }; -static clib_error_t * -lcp_default_netns_command_fn (vlib_main_t *vm, unformat_input_t *input, - vlib_cli_command_t *cmd) -{ +static clib_error_t *lcp_default_netns_command_fn(vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) { unformat_input_t _line_input, *line_input = &_line_input; u8 *ns; int r; - if (!unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user(input, unformat_line_input, line_input)) return 0; ns = 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "netns %s", &ns)) - ; - else if (unformat (line_input, "clear netns")) - ; - } + while (unformat_check_input(line_input) != UNFORMAT_END_OF_INPUT) { + if (unformat(line_input, "netns %s", &ns)) + ; + else if (unformat(line_input, "clear netns")) + ; + } - unformat_free (line_input); + unformat_free(line_input); - vlib_cli_output (vm, "lcp set default netns '%s'\n", (char *) ns); + vlib_cli_output(vm, "lcp set default netns '%s'\n", (char *)ns); - r = lcp_set_default_ns (ns); + r = lcp_set_default_ns(ns); if (r) - return clib_error_return (0, "linux-cp set default netns failed (%d)", r); + return clib_error_return(0, "linux-cp set default netns failed (%d)", r); return 0; } -VLIB_CLI_COMMAND (lcp_default_netns_command, static) = { - .path = "lcp default", - .short_help = "lcp default netns []", - .function = lcp_default_netns_command_fn, +VLIB_CLI_COMMAND(lcp_default_netns_command, static) = { + .path = "lcp default", + .short_help = "lcp default netns []", + .function = lcp_default_netns_command_fn, }; static clib_error_t * @@ -184,14 +182,14 @@ lcp_itf_pair_delete_command_fn (vlib_main_t *vm, unformat_input_t *input, r = lcp_itf_pair_delete (sw_if_index); if (r) - return clib_error_return (0, "lcp pair deletion failed (%d)", r); + return clib_error_return(0, "lcp pair deletion failed (%d)", r); return 0; } -VLIB_CLI_COMMAND (lcp_itf_pair_delete_command, static) = { - .path = "lcp delete", - .short_help = "lcp delete |", - .function = lcp_itf_pair_delete_command_fn, +VLIB_CLI_COMMAND(lcp_itf_pair_delete_command, static) = { + .path = "lcp delete", + .short_help = "lcp delete |", + .function = lcp_itf_pair_delete_command_fn, }; static clib_error_t * @@ -218,11 +216,11 @@ lcp_itf_pair_show_cmd (vlib_main_t *vm, unformat_input_t *input, return 0; } -VLIB_CLI_COMMAND (lcp_itf_pair_show_cmd_node, static) = { - .path = "show lcp", - .function = lcp_itf_pair_show_cmd, - .short_help = "show lcp [phy ]", - .is_mp_safe = 1, +VLIB_CLI_COMMAND(lcp_itf_pair_show_cmd_node, static) = { + .path = "show lcp", + .function = lcp_itf_pair_show_cmd, + .short_help = "show lcp [phy ]", + .is_mp_safe = 1, }; clib_error_t * diff --git a/lcpng_if_node.c b/lcpng_if_node.c index d324932..f2b1e56 100644 --- a/lcpng_if_node.c +++ b/lcpng_if_node.c @@ -144,17 +144,18 @@ VLIB_NODE_FN (lip_punt_node) return frame->n_vectors; } -VLIB_REGISTER_NODE (lip_punt_node) = { - .name = "linux-cp-punt", - .vector_size = sizeof (u32), - .format_trace = format_lip_punt_trace, - .type = VLIB_NODE_TYPE_INTERNAL, +VLIB_REGISTER_NODE(lip_punt_node) = { + .name = "linux-cp-punt", + .vector_size = sizeof(u32), + .format_trace = format_lip_punt_trace, + .type = VLIB_NODE_TYPE_INTERNAL, - .n_next_nodes = LIP_PUNT_N_NEXT, - .next_nodes = { - [LIP_PUNT_NEXT_DROP] = "error-drop", - [LIP_PUNT_NEXT_IO] = "interface-output", - }, + .n_next_nodes = LIP_PUNT_N_NEXT, + .next_nodes = + { + [LIP_PUNT_NEXT_DROP] = "error-drop", + [LIP_PUNT_NEXT_IO] = "interface-output", + }, }; #define foreach_lcp_punt_l3 _ (DROP, "unknown error") @@ -180,7 +181,7 @@ format_lcp_punt_l3_trace (u8 *s, va_list *args) CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); lcp_punt_l3_trace_t *t = va_arg (*args, lcp_punt_l3_trace_t *); - s = format (s, "linux-cp-punt-l3: %u", t->phy_sw_if_index); + s = format(s, "linux-cp-punt-l3: %u", t->phy_sw_if_index); return s; } @@ -247,28 +248,29 @@ VLIB_NODE_FN (lcp_punt_l3_node) return frame->n_vectors; } -VLIB_REGISTER_NODE (lcp_punt_l3_node) = { - .name = "linux-cp-punt-l3", - .vector_size = sizeof (u32), - .format_trace = format_lcp_punt_l3_trace, - .type = VLIB_NODE_TYPE_INTERNAL, +VLIB_REGISTER_NODE(lcp_punt_l3_node) = { + .name = "linux-cp-punt-l3", + .vector_size = sizeof(u32), + .format_trace = format_lcp_punt_l3_trace, + .type = VLIB_NODE_TYPE_INTERNAL, - .n_next_nodes = 1, - .next_nodes = { - [LCP_LOCAL_NEXT_DROP] = "error-drop", - }, + .n_next_nodes = 1, + .next_nodes = + { + [LCP_LOCAL_NEXT_DROP] = "error-drop", + }, }; -VNET_FEATURE_INIT (lcp_punt_l3_ip4, static) = { - .arc_name = "ip4-punt", - .node_name = "linux-cp-punt-l3", - .runs_before = VNET_FEATURES ("ip4-punt-redirect"), +VNET_FEATURE_INIT(lcp_punt_l3_ip4, static) = { + .arc_name = "ip4-punt", + .node_name = "linux-cp-punt-l3", + .runs_before = VNET_FEATURES("ip4-punt-redirect"), }; -VNET_FEATURE_INIT (lip_punt_l3_ip6, static) = { - .arc_name = "ip6-punt", - .node_name = "linux-cp-punt-l3", - .runs_before = VNET_FEATURES ("ip6-punt-redirect"), +VNET_FEATURE_INIT(lip_punt_l3_ip6, static) = { + .arc_name = "ip6-punt", + .node_name = "linux-cp-punt-l3", + .runs_before = VNET_FEATURES("ip6-punt-redirect"), }; #define foreach_lcp_xc \ @@ -406,34 +408,34 @@ VLIB_NODE_FN (lcp_xc_ip6) return (lcp_xc_inline (vm, node, frame, AF_IP6)); } -VLIB_REGISTER_NODE (lcp_xc_ip4) = { .name = "linux-cp-xc-ip4", - .vector_size = sizeof (u32), - .format_trace = format_lcp_xc_trace, - .type = VLIB_NODE_TYPE_INTERNAL, - .sibling_of = "ip4-rewrite" }; +VLIB_REGISTER_NODE(lcp_xc_ip4) = {.name = "linux-cp-xc-ip4", + .vector_size = sizeof(u32), + .format_trace = format_lcp_xc_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + .sibling_of = "ip4-rewrite"}; -VNET_FEATURE_INIT (lcp_xc_ip4_ucast_node, static) = { - .arc_name = "ip4-unicast", - .node_name = "linux-cp-xc-ip4", +VNET_FEATURE_INIT(lcp_xc_ip4_ucast_node, static) = { + .arc_name = "ip4-unicast", + .node_name = "linux-cp-xc-ip4", }; -VNET_FEATURE_INIT (lcp_xc_ip4_mcast_node, static) = { - .arc_name = "ip4-multicast", - .node_name = "linux-cp-xc-ip4", +VNET_FEATURE_INIT(lcp_xc_ip4_mcast_node, static) = { + .arc_name = "ip4-multicast", + .node_name = "linux-cp-xc-ip4", }; -VLIB_REGISTER_NODE (lcp_xc_ip6) = { .name = "linux-cp-xc-ip6", - .vector_size = sizeof (u32), - .format_trace = format_lcp_xc_trace, - .type = VLIB_NODE_TYPE_INTERNAL, - .sibling_of = "ip6-rewrite" }; +VLIB_REGISTER_NODE(lcp_xc_ip6) = {.name = "linux-cp-xc-ip6", + .vector_size = sizeof(u32), + .format_trace = format_lcp_xc_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + .sibling_of = "ip6-rewrite"}; -VNET_FEATURE_INIT (lcp_xc_ip6_ucast_node, static) = { - .arc_name = "ip6-unicast", - .node_name = "linux-cp-xc-ip6", +VNET_FEATURE_INIT(lcp_xc_ip6_ucast_node, static) = { + .arc_name = "ip6-unicast", + .node_name = "linux-cp-xc-ip6", }; -VNET_FEATURE_INIT (lcp_xc_ip6_mcast_node, static) = { - .arc_name = "ip6-multicast", - .node_name = "linux-cp-xc-ip6", +VNET_FEATURE_INIT(lcp_xc_ip6_mcast_node, static) = { + .arc_name = "ip6-multicast", + .node_name = "linux-cp-xc-ip6", }; typedef enum @@ -525,48 +527,50 @@ VLIB_NODE_FN (lcp_xc_l3_ip6_node) return (lcp_xc_l3_inline (vm, node, frame, AF_IP6)); } -VLIB_REGISTER_NODE (lcp_xc_l3_ip4_node) = { - .name = "linux-cp-xc-l3-ip4", - .vector_size = sizeof (u32), - .format_trace = format_lcp_xc_trace, - .type = VLIB_NODE_TYPE_INTERNAL, +VLIB_REGISTER_NODE(lcp_xc_l3_ip4_node) = { + .name = "linux-cp-xc-l3-ip4", + .vector_size = sizeof(u32), + .format_trace = format_lcp_xc_trace, + .type = VLIB_NODE_TYPE_INTERNAL, - .n_next_nodes = LCP_XC_L3_N_NEXT, - .next_nodes = { - [LCP_XC_L3_NEXT_XC] = "ip4-midchain", - }, + .n_next_nodes = LCP_XC_L3_N_NEXT, + .next_nodes = + { + [LCP_XC_L3_NEXT_XC] = "ip4-midchain", + }, }; -VNET_FEATURE_INIT (lcp_xc_node_l3_ip4_unicast, static) = { - .arc_name = "ip4-unicast", - .node_name = "linux-cp-xc-l3-ip4", +VNET_FEATURE_INIT(lcp_xc_node_l3_ip4_unicast, static) = { + .arc_name = "ip4-unicast", + .node_name = "linux-cp-xc-l3-ip4", }; -VNET_FEATURE_INIT (lcp_xc_node_l3_ip4_multicaast, static) = { - .arc_name = "ip4-multicast", - .node_name = "linux-cp-xc-l3-ip4", +VNET_FEATURE_INIT(lcp_xc_node_l3_ip4_multicaast, static) = { + .arc_name = "ip4-multicast", + .node_name = "linux-cp-xc-l3-ip4", }; -VLIB_REGISTER_NODE (lcp_xc_l3_ip6_node) = { - .name = "linux-cp-xc-l3-ip6", - .vector_size = sizeof (u32), - .format_trace = format_lcp_xc_trace, - .type = VLIB_NODE_TYPE_INTERNAL, +VLIB_REGISTER_NODE(lcp_xc_l3_ip6_node) = { + .name = "linux-cp-xc-l3-ip6", + .vector_size = sizeof(u32), + .format_trace = format_lcp_xc_trace, + .type = VLIB_NODE_TYPE_INTERNAL, - .n_next_nodes = LCP_XC_L3_N_NEXT, - .next_nodes = { - [LCP_XC_L3_NEXT_XC] = "ip6-midchain", - }, + .n_next_nodes = LCP_XC_L3_N_NEXT, + .next_nodes = + { + [LCP_XC_L3_NEXT_XC] = "ip6-midchain", + }, }; -VNET_FEATURE_INIT (lcp_xc_node_l3_ip6_unicast, static) = { - .arc_name = "ip6-unicast", - .node_name = "linux-cp-xc-l3-ip6", +VNET_FEATURE_INIT(lcp_xc_node_l3_ip6_unicast, static) = { + .arc_name = "ip6-unicast", + .node_name = "linux-cp-xc-l3-ip6", }; -VNET_FEATURE_INIT (lcp_xc_node_l3_ip6_multicast, static) = { - .arc_name = "ip6-multicast", - .node_name = "linux-cp-xc-l3-ip6", +VNET_FEATURE_INIT(lcp_xc_node_l3_ip6_multicast, static) = { + .arc_name = "ip6-multicast", + .node_name = "linux-cp-xc-l3-ip6", }; #define foreach_lcp_arp \ @@ -799,26 +803,27 @@ VLIB_NODE_FN (lcp_arp_phy_node) return frame->n_vectors; } -VLIB_REGISTER_NODE (lcp_arp_phy_node) = { - .name = "linux-cp-arp-phy", - .vector_size = sizeof (u32), - .format_trace = format_lcp_arp_trace, - .type = VLIB_NODE_TYPE_INTERNAL, +VLIB_REGISTER_NODE(lcp_arp_phy_node) = { + .name = "linux-cp-arp-phy", + .vector_size = sizeof(u32), + .format_trace = format_lcp_arp_trace, + .type = VLIB_NODE_TYPE_INTERNAL, - .n_errors = LINUXCP_N_ERROR, - .error_counters = linuxcp_error_counters, + .n_errors = LINUXCP_N_ERROR, + .error_counters = linuxcp_error_counters, - .n_next_nodes = LCP_ARP_N_NEXT, - .next_nodes = { - [LCP_ARP_NEXT_DROP] = "error-drop", - [LCP_ARP_NEXT_IO] = "interface-output", - }, + .n_next_nodes = LCP_ARP_N_NEXT, + .next_nodes = + { + [LCP_ARP_NEXT_DROP] = "error-drop", + [LCP_ARP_NEXT_IO] = "interface-output", + }, }; -VNET_FEATURE_INIT (lcp_arp_phy_arp_feat, static) = { - .arc_name = "arp", - .node_name = "linux-cp-arp-phy", - .runs_before = VNET_FEATURES ("arp-reply"), +VNET_FEATURE_INIT(lcp_arp_phy_arp_feat, static) = { + .arc_name = "arp", + .node_name = "linux-cp-arp-phy", + .runs_before = VNET_FEATURES("arp-reply"), }; /** @@ -883,26 +888,27 @@ VLIB_NODE_FN (lcp_arp_host_node) return frame->n_vectors; } -VLIB_REGISTER_NODE (lcp_arp_host_node) = { - .name = "linux-cp-arp-host", - .vector_size = sizeof (u32), - .format_trace = format_lcp_arp_trace, - .type = VLIB_NODE_TYPE_INTERNAL, +VLIB_REGISTER_NODE(lcp_arp_host_node) = { + .name = "linux-cp-arp-host", + .vector_size = sizeof(u32), + .format_trace = format_lcp_arp_trace, + .type = VLIB_NODE_TYPE_INTERNAL, - .n_errors = LINUXCP_N_ERROR, - .error_counters = linuxcp_error_counters, + .n_errors = LINUXCP_N_ERROR, + .error_counters = linuxcp_error_counters, - .n_next_nodes = LCP_ARP_N_NEXT, - .next_nodes = { - [LCP_ARP_NEXT_DROP] = "error-drop", - [LCP_ARP_NEXT_IO] = "interface-output", - }, + .n_next_nodes = LCP_ARP_N_NEXT, + .next_nodes = + { + [LCP_ARP_NEXT_DROP] = "error-drop", + [LCP_ARP_NEXT_IO] = "interface-output", + }, }; -VNET_FEATURE_INIT (lcp_arp_host_arp_feat, static) = { - .arc_name = "arp", - .node_name = "linux-cp-arp-host", - .runs_before = VNET_FEATURES ("arp-reply"), +VNET_FEATURE_INIT(lcp_arp_host_arp_feat, static) = { + .arc_name = "arp", + .node_name = "linux-cp-arp-host", + .runs_before = VNET_FEATURES("arp-reply"), }; /* diff --git a/lcpng_if_sync.c b/lcpng_if_sync.c new file mode 100644 index 0000000..5389bfb --- /dev/null +++ b/lcpng_if_sync.c @@ -0,0 +1,72 @@ +/* Hey Emacs use -*- mode: C -*- */ +/* + * Copyright 2021 Pim van Pelt + * + * 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 +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +static clib_error_t * +lcp_itf_admin_state_change (vnet_main_t * vnm, u32 sw_if_index, u32 flags) +{ + const lcp_itf_pair_t *lip; + vnet_hw_interface_t *hi; + vnet_sw_interface_t *si; + + LCP_ITF_PAIR_DBG ("admin_state_change: sw %U %u", + format_vnet_sw_if_index_name, vnm, sw_if_index, + flags); + + // Sync interface state changes into host + lip = lcp_itf_pair_get (lcp_itf_pair_find_by_phy (sw_if_index)); + if (!lip) return NULL; + + LCP_ITF_PAIR_INFO ("admin_state_change: %U flags %u", format_lcp_itf_pair, lip, flags); + lcp_itf_set_link_state (lip, (flags & VNET_HW_INTERFACE_FLAG_LINK_UP)); + + // Sync PHY carrier changes into TAP + hi = vnet_get_hw_interface_or_null (vnm, sw_if_index); + si = vnet_get_sw_interface_or_null (vnm, lip->lip_host_sw_if_index); + if (!si || !hi) return NULL; + LCP_ITF_PAIR_INFO ("admin_state_change: hi %U si %U %u", + format_vnet_sw_if_index_name, vnm, hi->hw_if_index, + format_vnet_sw_if_index_name, vnm, si->sw_if_index, + flags); + + tap_set_carrier (si->hw_if_index, (flags & VNET_HW_INTERFACE_FLAG_LINK_UP)); + /* TODO(pim): is this right? see tap_set_speed() "Cannot open netns" error + if (flags & VNET_HW_INTERFACE_FLAG_LINK_UP) { + tap_set_speed (si->hw_if_index, hi->link_speed); + } + */ + return NULL; +} + +VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(lcp_itf_admin_state_change); diff --git a/lcpng_interface.c b/lcpng_interface.c index 61bffb1..487b193 100644 --- a/lcpng_interface.c +++ b/lcpng_interface.c @@ -39,7 +39,7 @@ #include #include -static vlib_log_class_t lcp_itf_pair_logger; +vlib_log_class_t lcp_itf_pair_logger; /** * Pool of LIP objects @@ -73,15 +73,6 @@ lcp_itf_pair_register_vft (lcp_itf_pair_vft_t *lcp_itf_vft) vec_add1 (lcp_itf_vfts, *lcp_itf_vft); } -#define LCP_ITF_PAIR_DBG(...) \ - vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__); - -#define LCP_ITF_PAIR_INFO(...) \ - vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__); - -#define LCP_ITF_PAIR_ERR(...) \ - vlib_log_err (lcp_itf_pair_logger, __VA_ARGS__); - u8 * format_lcp_itf_pair (u8 *s, va_list *args) { @@ -137,7 +128,7 @@ lcp_itf_pair_show (u32 phy_sw_if_index) index_t api; vm = vlib_get_main (); - ns = lcp_get_default_ns (); + ns = lcp_get_default_ns(); vlib_cli_output (vm, "lcpng netns '%s'\n", ns ? (char *) ns : ""); @@ -157,6 +148,7 @@ lcp_itf_pair_t * lcp_itf_pair_get (u32 index) { if (!lcp_itf_pair_pool) return NULL; + if (index == INDEX_INVALID) return NULL; return pool_elt_at_index (lcp_itf_pair_pool, index); } @@ -192,14 +184,16 @@ lcp_itf_pair_add_sub (u32 vif, u8 *host_if_name, u32 sub_sw_if_index, } const char *lcp_itf_l3_feat_names[N_LCP_ITF_HOST][N_AF] = { - [LCP_ITF_HOST_TAP] = { - [AF_IP4] = "linux-cp-xc-ip4", - [AF_IP6] = "linux-cp-xc-ip6", - }, - [LCP_ITF_HOST_TUN] = { - [AF_IP4] = "linux-cp-xc-l3-ip4", - [AF_IP6] = "linux-cp-xc-l3-ip6", - }, + [LCP_ITF_HOST_TAP] = + { + [AF_IP4] = "linux-cp-xc-ip4", + [AF_IP6] = "linux-cp-xc-ip6", + }, + [LCP_ITF_HOST_TUN] = + { + [AF_IP4] = "linux-cp-xc-l3-ip4", + [AF_IP6] = "linux-cp-xc-l3-ip6", + }, }; const fib_route_path_flags_t lcp_itf_route_path_flags[N_LCP_ITF_HOST] = { @@ -318,17 +312,17 @@ lcp_itf_pair_add (u32 host_sw_if_index, u32 phy_sw_if_index, u8 *host_name, /* enable ARP feature node for broadcast interfaces */ if (lip->lip_host_type != LCP_ITF_HOST_TUN) { - vnet_feature_enable_disable ("arp", "linux-cp-arp-phy", - lip->lip_phy_sw_if_index, 1, NULL, 0); - vnet_feature_enable_disable ("arp", "linux-cp-arp-host", - lip->lip_host_sw_if_index, 1, NULL, 0); + vnet_feature_enable_disable("arp", "linux-cp-arp-phy", + lip->lip_phy_sw_if_index, 1, NULL, 0); + vnet_feature_enable_disable("arp", "linux-cp-arp-host", + lip->lip_host_sw_if_index, 1, NULL, 0); } else { - vnet_feature_enable_disable ("ip4-punt", "linux-cp-punt-l3", 0, 1, NULL, - 0); - vnet_feature_enable_disable ("ip6-punt", "linux-cp-punt-l3", 0, 1, NULL, - 0); + vnet_feature_enable_disable("ip4-punt", "linux-cp-punt-l3", 0, 1, NULL, + 0); + vnet_feature_enable_disable("ip6-punt", "linux-cp-punt-l3", 0, 1, NULL, + 0); } /* invoke registered callbacks for pair addition */ @@ -448,17 +442,17 @@ lcp_itf_pair_del (u32 phy_sw_if_index) /* disable ARP feature node for broadcast interfaces */ if (lip->lip_host_type != LCP_ITF_HOST_TUN) { - vnet_feature_enable_disable ("arp", "linux-cp-arp-phy", - lip->lip_phy_sw_if_index, 0, NULL, 0); - vnet_feature_enable_disable ("arp", "linux-cp-arp-host", - lip->lip_host_sw_if_index, 0, NULL, 0); + vnet_feature_enable_disable("arp", "linux-cp-arp-phy", + lip->lip_phy_sw_if_index, 0, NULL, 0); + vnet_feature_enable_disable("arp", "linux-cp-arp-host", + lip->lip_host_sw_if_index, 0, NULL, 0); } else { - vnet_feature_enable_disable ("ip4-punt", "linux-cp-punt-l3", 0, 0, NULL, - 0); - vnet_feature_enable_disable ("ip6-punt", "linux-cp-punt-l3", 0, 0, NULL, - 0); + vnet_feature_enable_disable("ip4-punt", "linux-cp-punt-l3", 0, 0, NULL, + 0); + vnet_feature_enable_disable("ip6-punt", "linux-cp-punt-l3", 0, 0, NULL, + 0); } lip_db_by_phy[phy_sw_if_index] = INDEX_INVALID; @@ -538,13 +532,12 @@ lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input) if (unformat (input, "netns %v", &netns)) { vec_add1 (netns, 0); - if (lcp_set_default_ns (netns) < 0) - { - return clib_error_return (0, - "lcpng namespace must be less than %d characters", - LCP_NS_LEN); - } - } + if (lcp_set_default_ns(netns) < 0) { + return clib_error_return( + 0, "lcpng namespace must be less than %d characters", + LCP_NS_LEN); + } + } else return clib_error_return (0, "interfaces not found"); } @@ -594,22 +587,24 @@ lcp_validate_if_name (u8 *name) return 1; } -static void -lcp_itf_set_vif_link_state (u32 vif_index, u8 up, u8 *ns) +void +lcp_itf_set_link_state (const lcp_itf_pair_t *lip, u8 state) { int curr_ns_fd, vif_ns_fd; + if (!lip) return; + curr_ns_fd = vif_ns_fd = -1; - if (ns) + if (lip->lip_namespace) { curr_ns_fd = clib_netns_open (NULL /* self */); - vif_ns_fd = clib_netns_open (ns); + vif_ns_fd = clib_netns_open (lip->lip_namespace); if (vif_ns_fd != -1) clib_setns (vif_ns_fd); } - vnet_netlink_set_link_state (vif_index, up); + vnet_netlink_set_link_state (lip->lip_vif_index, state); if (vif_ns_fd != -1) close (vif_ns_fd); @@ -619,6 +614,8 @@ lcp_itf_set_vif_link_state (u32 vif_index, u8 up, u8 *ns) clib_setns (curr_ns_fd); close (curr_ns_fd); } + + return; } typedef struct @@ -639,7 +636,7 @@ lcp_itf_pair_find_walk (vnet_main_t *vnm, u32 sw_if_index, void *arg) sw = vnet_get_sw_interface_or_null (vnm, sw_if_index); if (sw && (sw->sub.eth.inner_vlan_id == 0) && (sw->sub.eth.outer_vlan_id == match->vlan) && (sw->sub.eth.flags.dot1ad == match->dot1ad)) { - LCP_ITF_PAIR_ERR ("pair_create: found match %U outer %d dot1ad %d inner-dot1q %d", + LCP_ITF_PAIR_DBG ("pair_create: found match %U outer %d dot1ad %d inner-dot1q %d", format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index, sw->sub.eth.outer_vlan_id, sw->sub.eth.flags.dot1ad, sw->sub.eth.inner_vlan_id); match->matched_sw_if_index = sw_if_index; @@ -678,6 +675,7 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, u32 vif_index = 0, host_sw_if_index; const vnet_sw_interface_t *sw; const vnet_hw_interface_t *hw; + const lcp_itf_pair_t *lip; if (!vnet_sw_if_index_is_api_valid (phy_sw_if_index)) { LCP_ITF_PAIR_ERR ("pair_create: invalid phy index %u", phy_sw_if_index); @@ -703,12 +701,12 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, * Otherwise, use netns if defined, otherwise use the OS default. */ if (ns == 0 || ns[0] == 0) - ns = lcp_get_default_ns (); + ns = lcp_get_default_ns(); /* sub interfaces do not need a tap created */ if (vnet_sw_interface_is_sub (vnm, phy_sw_if_index)) { - const lcp_itf_pair_t *lip, *llip; + const lcp_itf_pair_t *llip; index_t parent_if_index, linux_parent_if_index; int orig_ns_fd, ns_fd; clib_error_t *err; @@ -771,8 +769,8 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, return VNET_API_ERROR_INVALID_ARGUMENT; } - LCP_ITF_PAIR_ERR ("pair_create: parent %U", format_lcp_itf_pair, lip); - LCP_ITF_PAIR_ERR ("pair_create: linux parent %U", format_lcp_itf_pair, llip); + LCP_ITF_PAIR_DBG ("pair_create: parent %U", format_lcp_itf_pair, lip); + LCP_ITF_PAIR_DBG ("pair_create: linux parent %U", format_lcp_itf_pair, llip); /* * see if the requested host interface has already been created @@ -895,20 +893,11 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, */ hw = vnet_get_sup_hw_interface (vnm, args.sw_if_index); - /* - * Copy the link state from VPP inon the host side. - * This controls whether the host can RX/TX. - */ virtio_main_t *mm = &virtio_main; virtio_if_t *vif = pool_elt_at_index (mm->interfaces, hw->dev_instance); - - lcp_itf_set_vif_link_state (vif->ifindex, sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP, - args.host_namespace); + vif_index = vif->ifindex; /* - * Leave the TAP permanently up on the VPP side. - * This TAP will be shared by many sub-interface. - * Therefore we can't use it to manage admin state. * force the tap in promiscuous mode. */ if (host_if_type == LCP_ITF_HOST_TAP) @@ -917,7 +906,6 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, ei->flags |= ETHERNET_INTERFACE_FLAG_STATUS_L3; } - vif_index = vif->ifindex; host_sw_if_index = args.sw_if_index; } @@ -930,15 +918,28 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, return -1; } - vnet_sw_interface_admin_up (vnm, host_sw_if_index); - lcp_itf_pair_add (host_sw_if_index, phy_sw_if_index, host_if_name, vif_index, - host_if_type, ns); - LCP_ITF_PAIR_INFO ("pair create: {%U, %U, %s}", format_vnet_sw_if_index_name, vnet_get_main (), phy_sw_if_index, format_vnet_sw_if_index_name, vnet_get_main (), host_sw_if_index, host_if_name); + lcp_itf_pair_add (host_sw_if_index, phy_sw_if_index, host_if_name, vif_index, + host_if_type, ns); + + /* + * Copy the link state from VPP inon the host side. + * The TAP is shared by many interfaces, always keep it up. + * This controls whether the host can RX/TX. + */ + vnet_sw_interface_admin_up (vnm, host_sw_if_index); + lip = lcp_itf_pair_get (lcp_itf_pair_find_by_vif(vif_index)); + LCP_ITF_PAIR_INFO ("pair_create: copy link state %u from %U to %U", + sw->flags, + format_vnet_sw_if_index_name, vnet_get_main (), sw->sw_if_index, + format_lcp_itf_pair, lip); + lcp_itf_set_link_state (lip, sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP); + + if (host_sw_if_indexp) *host_sw_if_indexp = host_sw_if_index; @@ -1047,51 +1048,14 @@ lcp_itf_phy_add (vnet_main_t *vnm, u32 sw_if_index, u32 is_create) VNET_SW_INTERFACE_ADD_DEL_FUNCTION (lcp_itf_phy_add); -static clib_error_t * -lcp_itf_pair_link_up_down (vnet_main_t *vnm, u32 hw_if_index, u32 flags) -{ - vnet_hw_interface_t *hi; - vnet_sw_interface_t *si; - index_t lipi; - lcp_itf_pair_t *lip; - - hi = vnet_get_hw_interface_or_null (vnm, hw_if_index); - if (!hi) - return 0; - - lipi = lcp_itf_pair_find_by_phy (hi->sw_if_index); - if (lipi == INDEX_INVALID) - return 0; - - lip = lcp_itf_pair_get (lipi); - si = vnet_get_sw_interface_or_null (vnm, lip->lip_host_sw_if_index); - if (!si) - return 0; - - if (!lcp_main.test_mode) - { - tap_set_carrier (si->hw_if_index, - (flags & VNET_HW_INTERFACE_FLAG_LINK_UP)); - - if (flags & VNET_HW_INTERFACE_FLAG_LINK_UP) - { - tap_set_speed (si->hw_if_index, hi->link_speed / 1000); - } - } - - return 0; -} - -VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (lcp_itf_pair_link_up_down); - static clib_error_t * lcp_itf_pair_init (vlib_main_t *vm) { - vlib_punt_hdl_t punt_hdl = vlib_punt_client_register ("linux-cp"); + vlib_punt_hdl_t punt_hdl = vlib_punt_client_register("linux-cp"); /* punt IKE */ - vlib_punt_register (punt_hdl, ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0], - "linux-cp-punt"); + vlib_punt_register(punt_hdl, ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0], + "linux-cp-punt"); /* punt all unknown ports */ udp_punt_unknown (vm, 0, 1); @@ -1099,7 +1063,7 @@ lcp_itf_pair_init (vlib_main_t *vm) tcp_punt_unknown (vm, 0, 1); tcp_punt_unknown (vm, 1, 1); - lcp_itf_pair_logger = vlib_log_register_class ("linux-cp", "if"); + lcp_itf_pair_logger = vlib_log_register_class("linux-cp", "if"); return NULL; } diff --git a/lcpng_interface.h b/lcpng_interface.h index e02aba3..28fb280 100644 --- a/lcpng_interface.h +++ b/lcpng_interface.h @@ -21,6 +21,18 @@ #include +extern vlib_log_class_t lcp_itf_pair_logger; + +#define LCP_ITF_PAIR_DBG(...) \ + vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__); + +#define LCP_ITF_PAIR_INFO(...) \ + vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__); + +#define LCP_ITF_PAIR_ERR(...) \ + vlib_log_err (lcp_itf_pair_logger, __VA_ARGS__); + + #define foreach_lcp_itf_pair_flag _ (STALE, 0, "stale") typedef enum lip_flag_t_ @@ -154,6 +166,10 @@ typedef struct lcp_itf_pair_vft } lcp_itf_pair_vft_t; void lcp_itf_pair_register_vft (lcp_itf_pair_vft_t *lcp_itf_vft); + +/* Set TAP and Linux host link state */ +void lcp_itf_set_link_state (const lcp_itf_pair_t *lip, u8 state); + /* * fd.io coding-style-patch-verification: ON *