From 770930c45f9793151e2c39b5834b1c8e7210bbe6 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Thu, 13 Oct 2016 14:10:10 +0200 Subject: feature: rename vnet_ip_feature_* to vnet_feature_* Change-Id: Idf68266f705b0455e5ab0ac73d23c7e0f4120d5b Signed-off-by: Dave Barach Signed-off-by: Damjan Marion --- vnet/Makefile.am | 34 +-- vnet/vnet/ethernet/ethernet.h | 8 +- vnet/vnet/ip/feature_registration.c | 534 +++++++++++++++++++++++++++++++++ vnet/vnet/ip/feature_registration.h | 62 ++++ vnet/vnet/ip/ip4.h | 16 +- vnet/vnet/ip/ip6.h | 16 +- vnet/vnet/ip/ip_feature_registration.c | 534 --------------------------------- vnet/vnet/ip/ip_feature_registration.h | 62 ---- vnet/vnet/ip/lookup.h | 2 +- vnet/vnet/mpls/mpls.h | 10 +- 10 files changed, 639 insertions(+), 639 deletions(-) create mode 100644 vnet/vnet/ip/feature_registration.c create mode 100644 vnet/vnet/ip/feature_registration.h delete mode 100644 vnet/vnet/ip/ip_feature_registration.c delete mode 100644 vnet/vnet/ip/ip_feature_registration.h (limited to 'vnet') diff --git a/vnet/Makefile.am b/vnet/Makefile.am index f130d15aa33..bff8418fb6e 100644 --- a/vnet/Makefile.am +++ b/vnet/Makefile.am @@ -267,19 +267,18 @@ nobase_include_HEADERS += \ # Layer 3 protocol: IP v4/v6 ######################################## libvnet_la_SOURCES += \ + vnet/ip/feature_registration.c \ vnet/ip/format.c \ vnet/ip/icmp4.c \ vnet/ip/icmp6.c \ - vnet/ip/ip_feature_registration.c \ vnet/ip/ip46_cli.c \ - vnet/ip/ping.c \ vnet/ip/ip4_format.c \ vnet/ip/ip4_forward.c \ vnet/ip/ip4_input.c \ vnet/ip/ip4_mtrie.c \ vnet/ip/ip4_pg.c \ - vnet/ip/ip4_source_check.c \ vnet/ip/ip4_source_and_port_range_check.c \ + vnet/ip/ip4_source_check.c \ vnet/ip/ip6_format.c \ vnet/ip/ip6_forward.c \ vnet/ip/ip6_hop_by_hop.c \ @@ -287,45 +286,46 @@ libvnet_la_SOURCES += \ vnet/ip/ip6_neighbor.c \ vnet/ip/ip6_pg.c \ vnet/ip/ip_checksum.c \ + vnet/ip/ip_frag.c \ vnet/ip/ip.h \ vnet/ip/ip_init.c \ + vnet/ip/ip_input_acl.c \ vnet/ip/lookup.c \ + vnet/ip/ping.c \ + vnet/ip/punt.c \ vnet/ip/udp_format.c \ vnet/ip/udp_init.c \ vnet/ip/udp_local.c \ - vnet/ip/punt.c \ - vnet/ip/udp_pg.c \ - vnet/ip/ip_input_acl.c \ - vnet/ip/ip_frag.c + vnet/ip/udp_pg.c nobase_include_HEADERS += \ + vnet/ip/feature_registration.h \ vnet/ip/format.h \ vnet/ip/icmp46_packet.h \ vnet/ip/icmp4.h \ vnet/ip/icmp6.h \ vnet/ip/igmp_packet.h \ - vnet/ip/ip.h \ - vnet/ip/ip_feature_registration.h \ - vnet/ip/ip_source_and_port_range_check.h \ + vnet/ip/ip4_error.h \ vnet/ip/ip4.h \ vnet/ip/ip4_mtrie.h \ - vnet/ip/ip4_error.h \ vnet/ip/ip4_packet.h \ - vnet/ip/ip6.h \ vnet/ip/ip6_error.h \ + vnet/ip/ip6.h \ vnet/ip/ip6_hop_by_hop.h \ vnet/ip/ip6_hop_by_hop_packet.h \ vnet/ip/ip6_packet.h \ - vnet/ip/lookup.h \ + vnet/ip/ip.h \ vnet/ip/ip_packet.h \ + vnet/ip/ip_source_and_port_range_check.h \ + vnet/ip/lookup.h \ vnet/ip/ports.def \ vnet/ip/protocols.def \ + vnet/ip/punt_error.def \ + vnet/ip/punt.h \ vnet/ip/tcp_packet.h \ - vnet/ip/udp.h \ vnet/ip/udp_error.def \ - vnet/ip/udp_packet.h \ - vnet/ip/punt_error.def \ - vnet/ip/punt.h + vnet/ip/udp.h \ + vnet/ip/udp_packet.h ######################################## # Layer 3 protocol: IPSec diff --git a/vnet/vnet/ethernet/ethernet.h b/vnet/vnet/ethernet/ethernet.h index 728da522e3a..973ed58ce72 100644 --- a/vnet/vnet/ethernet/ethernet.h +++ b/vnet/vnet/ethernet/ethernet.h @@ -43,7 +43,7 @@ #include #include #include -#include +#include always_inline u64 ethernet_mac_address_u64 (u8 * a) @@ -267,7 +267,7 @@ typedef struct ip_config_main_t feature_config_mains[VNET_N_IP_FEAT]; /** Feature path configuration lists */ - vnet_ip_feature_registration_t *next_feature[VNET_N_IP_FEAT]; + vnet_feature_registration_t *next_feature[VNET_N_IP_FEAT]; /** Save results for show command */ char **feature_nodes[VNET_N_IP_FEAT]; @@ -279,7 +279,7 @@ typedef struct ethernet_main_t ethernet_main; #define VNET_ETHERNET_TX_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t tx_##x; \ + __VA_ARGS__ vnet_feature_registration_t tx_##x; \ static void __vnet_add_feature_registration_tx_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_tx_##x (void) \ @@ -288,7 +288,7 @@ static void __vnet_add_feature_registration_tx_##x (void) \ tx_##x.next = im->next_feature[VNET_IP_TX_FEAT]; \ im->next_feature[VNET_IP_TX_FEAT] = &tx_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t tx_##x +__VA_ARGS__ vnet_feature_registration_t tx_##x always_inline ethernet_type_info_t * diff --git a/vnet/vnet/ip/feature_registration.c b/vnet/vnet/ip/feature_registration.c new file mode 100644 index 00000000000..3964617b521 --- /dev/null +++ b/vnet/vnet/ip/feature_registration.c @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * 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 + +/** + * @file + * @brief IP Feature Subgraph Ordering. + + Dynamically compute IP feature subgraph ordering by performing a + topological sort across a set of "feature A before feature B" and + "feature C after feature B" constraints. + + Use the topological sort result to set up vnet_config_main_t's for + use at runtime. + + Feature subgraph arcs are simple enough. They start at specific + fixed nodes, and end at specific fixed nodes. In between, a + per-interface current feature configuration dictates which + additional nodes each packet visits. Each so-called feature node + can [of course] drop any specific packet. + + See ip4_forward.c, ip6_forward.c in this directory to see the + current rx-unicast, rx-multicast, and tx feature subgraph arc + definitions. + + Let's say that we wish to add a new feature to the ip4 unicast + feature subgraph arc, which needs to run before @c ip4-lookup. In + either base code or a plugin, +
+    \#include 
+    
+ + and add the new feature as shown: + +
+    VNET_IP4_UNICAST_FEATURE_INIT (ip4_lookup, static) =
+    {
+      .node_name = "my-ip4-unicast-feature",
+      .runs_before = ORDER_CONSTRAINTS {"ip4-lookup", 0}
+      .feature_index = &my_feature_index,
+    };
+    
+ + Here's the standard coding pattern to enable / disable + @c my-ip4-unicast-feature on an interface: + +
+    ip4_main_t *im = \&ip4_main;
+    ip_lookup_main_t *lm = &im->lookup_main;
+    ip_config_main_t *rx_cm =
+        &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
+
+    sw_if_index = 
+    ci = rx_cm->config_index_by_sw_if_index[sw_if_index];
+    ci = (is_add
+          ? vnet_config_add_feature
+          : vnet_config_del_feature)
+      (vm, &rx_cm->config_main,
+       ci,
+       my_feature_index,
+       0 / * &config struct if feature uses private config data * /,
+       0 / * sizeof config struct if feature uses private config data * /);
+    rx_cm->config_index_by_sw_if_index[sw_if_index] = ci;
+    
+ + For tx features, add this line after setting +
+    tx_cm->config_index_by_sw_if_index = ci.
+    
+ + This maintains a + per-interface "at least one TX feature enabled" bitmap: + +
+    vnet_config_update_tx_feature_count (lm, tx_cm, sw_if_index, is_add);
+    
+ + Here's how to obtain the correct next node index in packet + processing code, aka in the implementation of @c my-ip4-unicast-feature: + +
+    ip_lookup_main_t * lm = sm->ip4_lookup_main;
+    ip_config_main_t * cm = &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
+
+    Call @c vnet_get_config_data to set next0, and to advance
+    @c b0->current_config_index:
+
+    config_data0 = vnet_get_config_data (&cm->config_main,
+                                         &b0->current_config_index,
+                                         &next0,
+                                         0 / * sizeof config data * /);
+    
+ + Nodes are free to drop or otherwise redirect packets. Packets + which "pass" should be enqueued via the next0 arc computed by + vnet_get_config_data. +*/ + +static const char *vnet_cast_names[] = VNET_CAST_NAMES; + +static int +comma_split (u8 * s, u8 ** a, u8 ** b) +{ + *a = s; + + while (*s && *s != ',') + s++; + + if (*s == ',') + *s = 0; + else + return 1; + + *b = (u8 *) (s + 1); + return 0; +} + +/** + * @brief Initialize a feature graph arc + * @param vm vlib main structure pointer + * @param vcm vnet config main structure pointer + * @param feature_start_nodes names of start-nodes which use this + * feature graph arc + * @param num_feature_start_nodes number of start-nodes + * @param first_reg first element in + * [an __attribute__((constructor)) function built, or + * otherwise created] singly-linked list of feature registrations + * @param [out] in_feature_nodes returned vector of + * topologically-sorted feature node names, for use in + * show commands + * @returns 0 on success, otherwise an error message. Errors + * are fatal since they invariably involve mistyped node-names, or + * genuinely missing node-names + */ +clib_error_t * +vnet_feature_arc_init (vlib_main_t * vm, + vnet_config_main_t * vcm, + char **feature_start_nodes, + int num_feature_start_nodes, + vnet_feature_registration_t * first_reg, + char ***in_feature_nodes) +{ + uword *index_by_name; + uword *reg_by_index; + u8 **node_names = 0; + u8 *node_name; + char **these_constraints; + char *this_constraint_c; + u8 **constraints = 0; + u8 *constraint_tuple; + u8 *this_constraint; + u8 **orig, **closure; + uword *p; + int i, j, k; + u8 *a_name, *b_name; + int a_index, b_index; + int n_features; + u32 *result = 0; + vnet_feature_registration_t *this_reg = 0; + char **feature_nodes = 0; + hash_pair_t *hp; + u8 **keys_to_delete = 0; + + index_by_name = hash_create_string (0, sizeof (uword)); + reg_by_index = hash_create (0, sizeof (uword)); + + this_reg = first_reg; + + /* pass 1, collect feature node names, construct a before b pairs */ + while (this_reg) + { + node_name = format (0, "%s%c", this_reg->node_name, 0); + hash_set (reg_by_index, vec_len (node_names), (uword) this_reg); + + hash_set_mem (index_by_name, node_name, vec_len (node_names)); + + vec_add1 (node_names, node_name); + + these_constraints = this_reg->runs_before; + while (these_constraints && these_constraints[0]) + { + this_constraint_c = these_constraints[0]; + + constraint_tuple = format (0, "%s,%s%c", node_name, + this_constraint_c, 0); + vec_add1 (constraints, constraint_tuple); + these_constraints++; + } + + these_constraints = this_reg->runs_after; + while (these_constraints && these_constraints[0]) + { + this_constraint_c = these_constraints[0]; + + constraint_tuple = format (0, "%s,%s%c", + this_constraint_c, node_name, 0); + vec_add1 (constraints, constraint_tuple); + these_constraints++; + } + + this_reg = this_reg->next; + } + + n_features = vec_len (node_names); + orig = clib_ptclosure_alloc (n_features); + + for (i = 0; i < vec_len (constraints); i++) + { + this_constraint = constraints[i]; + + if (comma_split (this_constraint, &a_name, &b_name)) + return clib_error_return (0, "comma_split failed!"); + + p = hash_get_mem (index_by_name, a_name); + /* + * Note: the next two errors mean that the xxx_FEATURE_INIT macros are + * b0rked. As in: if you code "A depends on B," and you forget + * to define a FEATURE_INIT macro for B, you lose. + * Nonexistent graph nodes are tolerated. + */ + if (p == 0) + return clib_error_return (0, "feature node '%s' not found", a_name); + a_index = p[0]; + + p = hash_get_mem (index_by_name, b_name); + if (p == 0) + return clib_error_return (0, "feature node '%s' not found", b_name); + b_index = p[0]; + + /* add a before b to the original set of constraints */ + orig[a_index][b_index] = 1; + vec_free (this_constraint); + } + + /* Compute the positive transitive closure of the original constraints */ + closure = clib_ptclosure (orig); + + /* Compute a partial order across feature nodes, if one exists. */ +again: + for (i = 0; i < n_features; i++) + { + for (j = 0; j < n_features; j++) + { + if (closure[i][j]) + goto item_constrained; + } + /* Item i can be output */ + vec_add1 (result, i); + { + for (k = 0; k < n_features; k++) + closure[k][i] = 0; + /* + * Add a "Magic" a before a constraint. + * This means we'll never output it again + */ + closure[i][i] = 1; + goto again; + } + item_constrained: + ; + } + + /* see if we got a partial order... */ + if (vec_len (result) != n_features) + return clib_error_return (0, "%d feature_init_cast no partial order!"); + + /* + * We win. + * Bind the index variables, and output the feature node name vector + * using the partial order we just computed. Result is in stack + * order, because the entry with the fewest constraints (e.g. none) + * is output first, etc. + */ + + for (i = n_features - 1; i >= 0; i--) + { + p = hash_get (reg_by_index, result[i]); + ASSERT (p != 0); + this_reg = (vnet_feature_registration_t *) p[0]; + *this_reg->feature_index = n_features - (i + 1); + vec_add1 (feature_nodes, this_reg->node_name); + } + + /* Set up the config infrastructure */ + vnet_config_init (vm, vcm, + feature_start_nodes, + num_feature_start_nodes, + feature_nodes, vec_len (feature_nodes)); + + /* Save a copy for show command */ + *in_feature_nodes = feature_nodes; + + /* Finally, clean up all the shit we allocated */ + /* *INDENT-OFF* */ + hash_foreach_pair (hp, index_by_name, + ({ + vec_add1 (keys_to_delete, (u8 *)hp->key); + })); + /* *INDENT-ON* */ + hash_free (index_by_name); + for (i = 0; i < vec_len (keys_to_delete); i++) + vec_free (keys_to_delete[i]); + vec_free (keys_to_delete); + hash_free (reg_by_index); + vec_free (result); + clib_ptclosure_free (orig); + clib_ptclosure_free (closure); + return 0; +} + +#define foreach_af_cast \ +_(4, VNET_IP_RX_UNICAST_FEAT, "ip4 unicast") \ +_(4, VNET_IP_RX_MULTICAST_FEAT, "ip4 multicast") \ +_(4, VNET_IP_TX_FEAT, "ip4 output") \ +_(6, VNET_IP_RX_UNICAST_FEAT, "ip6 unicast") \ +_(6, VNET_IP_RX_MULTICAST_FEAT, "ip6 multicast") \ +_(6, VNET_IP_TX_FEAT, "ip6 output") + +/** Display the set of available ip features. + Useful for verifying that expected features are present +*/ + +static clib_error_t * +show_ip_features_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + ip4_main_t *im4 = &ip4_main; + ip6_main_t *im6 = &ip6_main; + int i; + char **features; + + vlib_cli_output (vm, "Available IP feature nodes"); + +#define _(a,c,s) \ + do { \ + features = im##a->feature_nodes[c]; \ + vlib_cli_output (vm, "%s:", s); \ + for (i = 0; i < vec_len(features); i++) \ + vlib_cli_output (vm, " %s\n", features[i]); \ + } while(0); + foreach_af_cast; +#undef _ + + return 0; +} + +/*? + * This command is used to display the set of available IP features. + * This can be useful for verifying that expected features are present. + * + * @cliexpar + * Example of how to display the set of available IP features: + * @cliexstart{show ip features} + * Available IP feature nodes + * ip4 unicast: + * ip4-inacl + * ip4-source-check-via-rx + * ip4-source-check-via-any + * ip4-source-and-port-range-check-rx + * ip4-policer-classify + * ipsec-input-ip4 + * vpath-input-ip4 + * snat-in2out + * snat-out2in + * ip4-lookup + * ip4 multicast: + * vpath-input-ip4 + * ip4-lookup-multicast + * ip4 output: + * ip4-source-and-port-range-check-tx + * interface-output + * ip6 unicast: + * ip6-inacl + * ip6-policer-classify + * ipsec-input-ip6 + * l2tp-decap + * vpath-input-ip6 + * sir-to-ila + * ip6-lookup + * ip6 multicast: + * vpath-input-ip6 + * ip6-lookup + * ip6 output: + * interface-output + * @cliexend +?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (show_ip_features_command, static) = { + .path = "show ip features", + .short_help = "show ip features", + .function = show_ip_features_command_fn, +}; +/* *INDENT-ON* */ + +/** Display the set of IP features configured on a specific interface + */ + +void +ip_interface_features_show (vlib_main_t * vm, + const char *pname, + ip_config_main_t * cm, u32 sw_if_index) +{ + u32 node_index, current_config_index; + vnet_cast_t cast; + vnet_config_main_t *vcm; + vnet_config_t *cfg; + u32 cfg_index; + vnet_config_feature_t *feat; + vlib_node_t *n; + int i; + + vlib_cli_output (vm, "%s feature paths configured on %U...", + pname, format_vnet_sw_if_index_name, + vnet_get_main (), sw_if_index); + + for (cast = VNET_IP_RX_UNICAST_FEAT; cast < VNET_N_IP_FEAT; cast++) + { + vcm = &(cm[cast].config_main); + + vlib_cli_output (vm, "\n%s %s:", pname, vnet_cast_names[cast]); + + if (NULL == cm[cast].config_index_by_sw_if_index || + vec_len (cm[cast].config_index_by_sw_if_index) < sw_if_index) + { + vlib_cli_output (vm, "none configured"); + continue; + } + + current_config_index = vec_elt (cm[cast].config_index_by_sw_if_index, + sw_if_index); + + ASSERT (current_config_index + < vec_len (vcm->config_pool_index_by_user_index)); + + cfg_index = vcm->config_pool_index_by_user_index[current_config_index]; + cfg = pool_elt_at_index (vcm->config_pool, cfg_index); + + for (i = 0; i < vec_len (cfg->features); i++) + { + feat = cfg->features + i; + node_index = feat->node_index; + n = vlib_get_node (vm, node_index); + vlib_cli_output (vm, " %v", n->name); + } + } +} + +static clib_error_t * +show_ip_interface_features_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + vnet_main_t *vnm = vnet_get_main (); + ip4_main_t *im4 = &ip4_main; + ip_lookup_main_t *lm4 = &im4->lookup_main; + ip6_main_t *im6 = &ip6_main; + ip_lookup_main_t *lm6 = &im6->lookup_main; + + ip_lookup_main_t *lm; + u32 sw_if_index, af; + + if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) + return clib_error_return (0, "Interface not specified..."); + + vlib_cli_output (vm, "IP feature paths configured on %U...", + format_vnet_sw_if_index_name, vnm, sw_if_index); + + for (af = 0; af < 2; af++) + { + if (af == 0) + lm = lm4; + else + lm = lm6; + + ip_interface_features_show (vm, (af == 0) ? "ip4" : "ip6", + lm->feature_config_mains, sw_if_index); + } + + return 0; +} + +/*? + * This command is used to display the set of IP features configured + * on a specific interface + * + * @cliexpar + * Example of how to display the set of available IP features on an interface: + * @cliexstart{show ip interface features GigabitEthernet2/0/0} + * IP feature paths configured on GigabitEthernet2/0/0... + * ipv4 unicast: + * ip4-lookup + * ipv4 multicast: + * ip4-lookup-multicast + * ipv4 multicast: + * interface-output + * ipv6 unicast: + * ip6-lookup + * ipv6 multicast: + * ip6-lookup + * ipv6 multicast: + * interface-output + * @cliexend +?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (show_ip_interface_features_command, static) = { + .path = "show ip interface features", + .short_help = "show ip interface features ", + .function = show_ip_interface_features_command_fn, +}; +/* *INDENT-ON* */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ip/feature_registration.h b/vnet/vnet/ip/feature_registration.h new file mode 100644 index 00000000000..ba7f97ce252 --- /dev/null +++ b/vnet/vnet/ip/feature_registration.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * 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 included_feature_registration_h +#define included_feature_registration_h + +/** feature registration object */ +typedef struct _vnet_feature_registration +{ + /** next registration in list of all registrations*/ + struct _vnet_feature_registration *next; + /** Graph node name */ + char *node_name; + /** Pointer to this feature index, filled in by vnet_feature_arc_init */ + u32 *feature_index; + /** Constraints of the form "this feature runs before X" */ + char **runs_before; + /** Constraints of the form "this feature runs after Y" */ + char **runs_after; +} vnet_feature_registration_t; + +typedef struct ip_config_main_t_ +{ + vnet_config_main_t config_main; + u32 *config_index_by_sw_if_index; +} ip_config_main_t; + +/** Syntactic sugar, the c-compiler won't initialize registrations without it */ +#define ORDER_CONSTRAINTS (char*[]) + +clib_error_t *vnet_feature_arc_init (vlib_main_t * vm, + vnet_config_main_t * vcm, + char **feature_start_nodes, + int num_feature_start_nodes, + vnet_feature_registration_t * + first_reg, char ***feature_nodes); + +void ip_interface_features_show (vlib_main_t * vm, + const char *pname, + ip_config_main_t * cm, u32 sw_if_index); + +#endif /* included_feature_registration_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ip/ip4.h b/vnet/vnet/ip/ip4.h index 441e32f4646..f00b6ca7968 100644 --- a/vnet/vnet/ip/ip4.h +++ b/vnet/vnet/ip/ip4.h @@ -43,7 +43,7 @@ #include #include #include -#include +#include typedef struct ip4_fib_t { /* Hash table for each prefix length mapping. */ @@ -117,7 +117,7 @@ typedef struct ip4_main_t { vlib_packet_template_t ip4_arp_request_packet_template; /** Feature path configuration lists */ - vnet_ip_feature_registration_t * next_feature[VNET_N_IP_FEAT]; + vnet_feature_registration_t * next_feature[VNET_N_IP_FEAT]; /** Built-in unicast feature path index, see @ref vnet_feature_arc_init() */ u32 ip4_unicast_rx_feature_check_access; @@ -175,7 +175,7 @@ typedef struct ip4_main_t { extern ip4_main_t ip4_main; #define VNET_IP4_UNICAST_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t uc_##x; \ + __VA_ARGS__ vnet_feature_registration_t uc_##x; \ static void __vnet_add_feature_registration_uc_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_uc_##x (void) \ @@ -184,10 +184,10 @@ static void __vnet_add_feature_registration_uc_##x (void) \ uc_##x.next = im->next_feature[VNET_IP_RX_UNICAST_FEAT]; \ im->next_feature[VNET_IP_RX_UNICAST_FEAT] = &uc_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t uc_##x +__VA_ARGS__ vnet_feature_registration_t uc_##x #define VNET_IP4_MULTICAST_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t mc_##x; \ + __VA_ARGS__ vnet_feature_registration_t mc_##x; \ static void __vnet_add_feature_registration_mc_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_mc_##x (void) \ @@ -196,10 +196,10 @@ static void __vnet_add_feature_registration_mc_##x (void) \ mc_##x.next = im->next_feature[VNET_IP_RX_MULTICAST_FEAT]; \ im->next_feature[VNET_IP_RX_MULTICAST_FEAT] = &mc_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t mc_##x +__VA_ARGS__ vnet_feature_registration_t mc_##x #define VNET_IP4_TX_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t tx_##x; \ + __VA_ARGS__ vnet_feature_registration_t tx_##x; \ static void __vnet_add_feature_registration_tx_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_tx_##x (void) \ @@ -208,7 +208,7 @@ static void __vnet_add_feature_registration_tx_##x (void) \ tx_##x.next = im->next_feature[VNET_IP_TX_FEAT]; \ im->next_feature[VNET_IP_TX_FEAT] = &tx_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t tx_##x +__VA_ARGS__ vnet_feature_registration_t tx_##x /** Global ip4 input node. Errors get attached to ip4 input node. */ diff --git a/vnet/vnet/ip/ip6.h b/vnet/vnet/ip/ip6.h index 13d8d5fdf37..ab0e650bef1 100644 --- a/vnet/vnet/ip/ip6.h +++ b/vnet/vnet/ip/ip6.h @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include @@ -161,7 +161,7 @@ typedef struct ip6_main_t { uword lookup_table_size; /* feature path configuration lists */ - vnet_ip_feature_registration_t * next_feature[VNET_N_IP_FEAT]; + vnet_feature_registration_t * next_feature[VNET_N_IP_FEAT]; /* Built-in unicast feature path indices, see vnet_feature_arc_init(...) */ u32 ip6_unicast_rx_feature_check_access; @@ -202,7 +202,7 @@ typedef struct ip6_main_t { extern ip6_main_t ip6_main; #define VNET_IP6_UNICAST_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t uc_##x; \ + __VA_ARGS__ vnet_feature_registration_t uc_##x; \ static void __vnet_add_feature_registration_uc_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_uc_##x (void) \ @@ -211,10 +211,10 @@ static void __vnet_add_feature_registration_uc_##x (void) \ uc_##x.next = im->next_feature[VNET_IP_RX_UNICAST_FEAT]; \ im->next_feature[VNET_IP_RX_UNICAST_FEAT] = &uc_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t uc_##x +__VA_ARGS__ vnet_feature_registration_t uc_##x #define VNET_IP6_MULTICAST_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t mc_##x; \ + __VA_ARGS__ vnet_feature_registration_t mc_##x; \ static void __vnet_add_feature_registration_mc_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_mc_##x (void) \ @@ -223,10 +223,10 @@ static void __vnet_add_feature_registration_mc_##x (void) \ mc_##x.next = im->next_feature[VNET_IP_RX_MULTICAST_FEAT]; \ im->next_feature[VNET_IP_RX_MULTICAST_FEAT] = &mc_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t mc_##x +__VA_ARGS__ vnet_feature_registration_t mc_##x #define VNET_IP6_TX_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t tx_##x; \ + __VA_ARGS__ vnet_feature_registration_t tx_##x; \ static void __vnet_add_feature_registration_tx_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_tx_##x (void) \ @@ -235,7 +235,7 @@ static void __vnet_add_feature_registration_tx_##x (void) \ tx_##x.next = im->next_feature[VNET_IP_TX_FEAT]; \ im->next_feature[VNET_IP_TX_FEAT] = &tx_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t tx_##x +__VA_ARGS__ vnet_feature_registration_t tx_##x /* Global ip6 input node. Errors get attached to ip6 input node. */ diff --git a/vnet/vnet/ip/ip_feature_registration.c b/vnet/vnet/ip/ip_feature_registration.c deleted file mode 100644 index 54d6c31b0e0..00000000000 --- a/vnet/vnet/ip/ip_feature_registration.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright (c) 2015 Cisco and/or its affiliates. - * 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 - -/** - * @file - * @brief IP Feature Subgraph Ordering. - - Dynamically compute IP feature subgraph ordering by performing a - topological sort across a set of "feature A before feature B" and - "feature C after feature B" constraints. - - Use the topological sort result to set up vnet_config_main_t's for - use at runtime. - - Feature subgraph arcs are simple enough. They start at specific - fixed nodes, and end at specific fixed nodes. In between, a - per-interface current feature configuration dictates which - additional nodes each packet visits. Each so-called feature node - can [of course] drop any specific packet. - - See ip4_forward.c, ip6_forward.c in this directory to see the - current rx-unicast, rx-multicast, and tx feature subgraph arc - definitions. - - Let's say that we wish to add a new feature to the ip4 unicast - feature subgraph arc, which needs to run before @c ip4-lookup. In - either base code or a plugin, -
-    \#include 
-    
- - and add the new feature as shown: - -
-    VNET_IP4_UNICAST_FEATURE_INIT (ip4_lookup, static) =
-    {
-      .node_name = "my-ip4-unicast-feature",
-      .runs_before = ORDER_CONSTRAINTS {"ip4-lookup", 0}
-      .feature_index = &my_feature_index,
-    };
-    
- - Here's the standard coding pattern to enable / disable - @c my-ip4-unicast-feature on an interface: - -
-    ip4_main_t *im = \&ip4_main;
-    ip_lookup_main_t *lm = &im->lookup_main;
-    ip_config_main_t *rx_cm =
-        &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
-
-    sw_if_index = 
-    ci = rx_cm->config_index_by_sw_if_index[sw_if_index];
-    ci = (is_add
-          ? vnet_config_add_feature
-          : vnet_config_del_feature)
-      (vm, &rx_cm->config_main,
-       ci,
-       my_feature_index,
-       0 / * &config struct if feature uses private config data * /,
-       0 / * sizeof config struct if feature uses private config data * /);
-    rx_cm->config_index_by_sw_if_index[sw_if_index] = ci;
-    
- - For tx features, add this line after setting -
-    tx_cm->config_index_by_sw_if_index = ci.
-    
- - This maintains a - per-interface "at least one TX feature enabled" bitmap: - -
-    vnet_config_update_tx_feature_count (lm, tx_cm, sw_if_index, is_add);
-    
- - Here's how to obtain the correct next node index in packet - processing code, aka in the implementation of @c my-ip4-unicast-feature: - -
-    ip_lookup_main_t * lm = sm->ip4_lookup_main;
-    ip_config_main_t * cm = &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
-
-    Call @c vnet_get_config_data to set next0, and to advance
-    @c b0->current_config_index:
-
-    config_data0 = vnet_get_config_data (&cm->config_main,
-                                         &b0->current_config_index,
-                                         &next0,
-                                         0 / * sizeof config data * /);
-    
- - Nodes are free to drop or otherwise redirect packets. Packets - which "pass" should be enqueued via the next0 arc computed by - vnet_get_config_data. -*/ - -static const char *vnet_cast_names[] = VNET_CAST_NAMES; - -static int -comma_split (u8 * s, u8 ** a, u8 ** b) -{ - *a = s; - - while (*s && *s != ',') - s++; - - if (*s == ',') - *s = 0; - else - return 1; - - *b = (u8 *) (s + 1); - return 0; -} - -/** - * @brief Initialize a feature graph arc - * @param vm vlib main structure pointer - * @param vcm vnet config main structure pointer - * @param feature_start_nodes names of start-nodes which use this - * feature graph arc - * @param num_feature_start_nodes number of start-nodes - * @param first_reg first element in - * [an __attribute__((constructor)) function built, or - * otherwise created] singly-linked list of feature registrations - * @param [out] in_feature_nodes returned vector of - * topologically-sorted feature node names, for use in - * show commands - * @returns 0 on success, otherwise an error message. Errors - * are fatal since they invariably involve mistyped node-names, or - * genuinely missing node-names - */ -clib_error_t * -vnet_feature_arc_init (vlib_main_t * vm, - vnet_config_main_t * vcm, - char **feature_start_nodes, - int num_feature_start_nodes, - vnet_ip_feature_registration_t * first_reg, - char ***in_feature_nodes) -{ - uword *index_by_name; - uword *reg_by_index; - u8 **node_names = 0; - u8 *node_name; - char **these_constraints; - char *this_constraint_c; - u8 **constraints = 0; - u8 *constraint_tuple; - u8 *this_constraint; - u8 **orig, **closure; - uword *p; - int i, j, k; - u8 *a_name, *b_name; - int a_index, b_index; - int n_features; - u32 *result = 0; - vnet_ip_feature_registration_t *this_reg = 0; - char **feature_nodes = 0; - hash_pair_t *hp; - u8 **keys_to_delete = 0; - - index_by_name = hash_create_string (0, sizeof (uword)); - reg_by_index = hash_create (0, sizeof (uword)); - - this_reg = first_reg; - - /* pass 1, collect feature node names, construct a before b pairs */ - while (this_reg) - { - node_name = format (0, "%s%c", this_reg->node_name, 0); - hash_set (reg_by_index, vec_len (node_names), (uword) this_reg); - - hash_set_mem (index_by_name, node_name, vec_len (node_names)); - - vec_add1 (node_names, node_name); - - these_constraints = this_reg->runs_before; - while (these_constraints && these_constraints[0]) - { - this_constraint_c = these_constraints[0]; - - constraint_tuple = format (0, "%s,%s%c", node_name, - this_constraint_c, 0); - vec_add1 (constraints, constraint_tuple); - these_constraints++; - } - - these_constraints = this_reg->runs_after; - while (these_constraints && these_constraints[0]) - { - this_constraint_c = these_constraints[0]; - - constraint_tuple = format (0, "%s,%s%c", - this_constraint_c, node_name, 0); - vec_add1 (constraints, constraint_tuple); - these_constraints++; - } - - this_reg = this_reg->next; - } - - n_features = vec_len (node_names); - orig = clib_ptclosure_alloc (n_features); - - for (i = 0; i < vec_len (constraints); i++) - { - this_constraint = constraints[i]; - - if (comma_split (this_constraint, &a_name, &b_name)) - return clib_error_return (0, "comma_split failed!"); - - p = hash_get_mem (index_by_name, a_name); - /* - * Note: the next two errors mean that the xxx_FEATURE_INIT macros are - * b0rked. As in: if you code "A depends on B," and you forget - * to define a FEATURE_INIT macro for B, you lose. - * Nonexistent graph nodes are tolerated. - */ - if (p == 0) - return clib_error_return (0, "feature node '%s' not found", a_name); - a_index = p[0]; - - p = hash_get_mem (index_by_name, b_name); - if (p == 0) - return clib_error_return (0, "feature node '%s' not found", b_name); - b_index = p[0]; - - /* add a before b to the original set of constraints */ - orig[a_index][b_index] = 1; - vec_free (this_constraint); - } - - /* Compute the positive transitive closure of the original constraints */ - closure = clib_ptclosure (orig); - - /* Compute a partial order across feature nodes, if one exists. */ -again: - for (i = 0; i < n_features; i++) - { - for (j = 0; j < n_features; j++) - { - if (closure[i][j]) - goto item_constrained; - } - /* Item i can be output */ - vec_add1 (result, i); - { - for (k = 0; k < n_features; k++) - closure[k][i] = 0; - /* - * Add a "Magic" a before a constraint. - * This means we'll never output it again - */ - closure[i][i] = 1; - goto again; - } - item_constrained: - ; - } - - /* see if we got a partial order... */ - if (vec_len (result) != n_features) - return clib_error_return (0, "%d feature_init_cast no partial order!"); - - /* - * We win. - * Bind the index variables, and output the feature node name vector - * using the partial order we just computed. Result is in stack - * order, because the entry with the fewest constraints (e.g. none) - * is output first, etc. - */ - - for (i = n_features - 1; i >= 0; i--) - { - p = hash_get (reg_by_index, result[i]); - ASSERT (p != 0); - this_reg = (vnet_ip_feature_registration_t *) p[0]; - *this_reg->feature_index = n_features - (i + 1); - vec_add1 (feature_nodes, this_reg->node_name); - } - - /* Set up the config infrastructure */ - vnet_config_init (vm, vcm, - feature_start_nodes, - num_feature_start_nodes, - feature_nodes, vec_len (feature_nodes)); - - /* Save a copy for show command */ - *in_feature_nodes = feature_nodes; - - /* Finally, clean up all the shit we allocated */ - /* *INDENT-OFF* */ - hash_foreach_pair (hp, index_by_name, - ({ - vec_add1 (keys_to_delete, (u8 *)hp->key); - })); - /* *INDENT-ON* */ - hash_free (index_by_name); - for (i = 0; i < vec_len (keys_to_delete); i++) - vec_free (keys_to_delete[i]); - vec_free (keys_to_delete); - hash_free (reg_by_index); - vec_free (result); - clib_ptclosure_free (orig); - clib_ptclosure_free (closure); - return 0; -} - -#define foreach_af_cast \ -_(4, VNET_IP_RX_UNICAST_FEAT, "ip4 unicast") \ -_(4, VNET_IP_RX_MULTICAST_FEAT, "ip4 multicast") \ -_(4, VNET_IP_TX_FEAT, "ip4 output") \ -_(6, VNET_IP_RX_UNICAST_FEAT, "ip6 unicast") \ -_(6, VNET_IP_RX_MULTICAST_FEAT, "ip6 multicast") \ -_(6, VNET_IP_TX_FEAT, "ip6 output") - -/** Display the set of available ip features. - Useful for verifying that expected features are present -*/ - -static clib_error_t * -show_ip_features_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - ip4_main_t *im4 = &ip4_main; - ip6_main_t *im6 = &ip6_main; - int i; - char **features; - - vlib_cli_output (vm, "Available IP feature nodes"); - -#define _(a,c,s) \ - do { \ - features = im##a->feature_nodes[c]; \ - vlib_cli_output (vm, "%s:", s); \ - for (i = 0; i < vec_len(features); i++) \ - vlib_cli_output (vm, " %s\n", features[i]); \ - } while(0); - foreach_af_cast; -#undef _ - - return 0; -} - -/*? - * This command is used to display the set of available IP features. - * This can be useful for verifying that expected features are present. - * - * @cliexpar - * Example of how to display the set of available IP features: - * @cliexstart{show ip features} - * Available IP feature nodes - * ip4 unicast: - * ip4-inacl - * ip4-source-check-via-rx - * ip4-source-check-via-any - * ip4-source-and-port-range-check-rx - * ip4-policer-classify - * ipsec-input-ip4 - * vpath-input-ip4 - * snat-in2out - * snat-out2in - * ip4-lookup - * ip4 multicast: - * vpath-input-ip4 - * ip4-lookup-multicast - * ip4 output: - * ip4-source-and-port-range-check-tx - * interface-output - * ip6 unicast: - * ip6-inacl - * ip6-policer-classify - * ipsec-input-ip6 - * l2tp-decap - * vpath-input-ip6 - * sir-to-ila - * ip6-lookup - * ip6 multicast: - * vpath-input-ip6 - * ip6-lookup - * ip6 output: - * interface-output - * @cliexend -?*/ -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (show_ip_features_command, static) = { - .path = "show ip features", - .short_help = "show ip features", - .function = show_ip_features_command_fn, -}; -/* *INDENT-ON* */ - -/** Display the set of IP features configured on a specific interface - */ - -void -ip_interface_features_show (vlib_main_t * vm, - const char *pname, - ip_config_main_t * cm, u32 sw_if_index) -{ - u32 node_index, current_config_index; - vnet_cast_t cast; - vnet_config_main_t *vcm; - vnet_config_t *cfg; - u32 cfg_index; - vnet_config_feature_t *feat; - vlib_node_t *n; - int i; - - vlib_cli_output (vm, "%s feature paths configured on %U...", - pname, format_vnet_sw_if_index_name, - vnet_get_main (), sw_if_index); - - for (cast = VNET_IP_RX_UNICAST_FEAT; cast < VNET_N_IP_FEAT; cast++) - { - vcm = &(cm[cast].config_main); - - vlib_cli_output (vm, "\n%s %s:", pname, vnet_cast_names[cast]); - - if (NULL == cm[cast].config_index_by_sw_if_index || - vec_len (cm[cast].config_index_by_sw_if_index) < sw_if_index) - { - vlib_cli_output (vm, "none configured"); - continue; - } - - current_config_index = vec_elt (cm[cast].config_index_by_sw_if_index, - sw_if_index); - - ASSERT (current_config_index - < vec_len (vcm->config_pool_index_by_user_index)); - - cfg_index = vcm->config_pool_index_by_user_index[current_config_index]; - cfg = pool_elt_at_index (vcm->config_pool, cfg_index); - - for (i = 0; i < vec_len (cfg->features); i++) - { - feat = cfg->features + i; - node_index = feat->node_index; - n = vlib_get_node (vm, node_index); - vlib_cli_output (vm, " %v", n->name); - } - } -} - -static clib_error_t * -show_ip_interface_features_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - vnet_main_t *vnm = vnet_get_main (); - ip4_main_t *im4 = &ip4_main; - ip_lookup_main_t *lm4 = &im4->lookup_main; - ip6_main_t *im6 = &ip6_main; - ip_lookup_main_t *lm6 = &im6->lookup_main; - - ip_lookup_main_t *lm; - u32 sw_if_index, af; - - if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) - return clib_error_return (0, "Interface not specified..."); - - vlib_cli_output (vm, "IP feature paths configured on %U...", - format_vnet_sw_if_index_name, vnm, sw_if_index); - - for (af = 0; af < 2; af++) - { - if (af == 0) - lm = lm4; - else - lm = lm6; - - ip_interface_features_show (vm, (af == 0) ? "ip4" : "ip6", - lm->feature_config_mains, sw_if_index); - } - - return 0; -} - -/*? - * This command is used to display the set of IP features configured - * on a specific interface - * - * @cliexpar - * Example of how to display the set of available IP features on an interface: - * @cliexstart{show ip interface features GigabitEthernet2/0/0} - * IP feature paths configured on GigabitEthernet2/0/0... - * ipv4 unicast: - * ip4-lookup - * ipv4 multicast: - * ip4-lookup-multicast - * ipv4 multicast: - * interface-output - * ipv6 unicast: - * ip6-lookup - * ipv6 multicast: - * ip6-lookup - * ipv6 multicast: - * interface-output - * @cliexend -?*/ -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (show_ip_interface_features_command, static) = { - .path = "show ip interface features", - .short_help = "show ip interface features ", - .function = show_ip_interface_features_command_fn, -}; -/* *INDENT-ON* */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/vnet/vnet/ip/ip_feature_registration.h b/vnet/vnet/ip/ip_feature_registration.h deleted file mode 100644 index 7829980739a..00000000000 --- a/vnet/vnet/ip/ip_feature_registration.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2015 Cisco and/or its affiliates. - * 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 included_ip_feature_registration_h -#define included_ip_feature_registration_h - -/** feature registration object */ -typedef struct _vnet_ip_feature_registration -{ - /** next registration in list of all registrations*/ - struct _vnet_ip_feature_registration *next; - /** Graph node name */ - char *node_name; - /** Pointer to this feature index, filled in by vnet_feature_arc_init */ - u32 *feature_index; - /** Constraints of the form "this feature runs before X" */ - char **runs_before; - /** Constraints of the form "this feature runs after Y" */ - char **runs_after; -} vnet_ip_feature_registration_t; - -typedef struct ip_config_main_t_ -{ - vnet_config_main_t config_main; - u32 *config_index_by_sw_if_index; -} ip_config_main_t; - -/** Syntactic sugar, the c-compiler won't initialize registrations without it */ -#define ORDER_CONSTRAINTS (char*[]) - -clib_error_t *vnet_feature_arc_init (vlib_main_t * vm, - vnet_config_main_t * vcm, - char **feature_start_nodes, - int num_feature_start_nodes, - vnet_ip_feature_registration_t * - first_reg, char ***feature_nodes); - -void ip_interface_features_show (vlib_main_t * vm, - const char *pname, - ip_config_main_t * cm, u32 sw_if_index); - -#endif /* included_ip_feature_registration_h */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/vnet/vnet/ip/lookup.h b/vnet/vnet/ip/lookup.h index d3a180fa192..84c4ffb2fd8 100644 --- a/vnet/vnet/ip/lookup.h +++ b/vnet/vnet/ip/lookup.h @@ -54,7 +54,7 @@ #include #include #include -#include +#include /** @brief Common (IP4/IP6) next index stored in adjacency. */ typedef enum { diff --git a/vnet/vnet/mpls/mpls.h b/vnet/vnet/mpls/mpls.h index 5a09e5a0103..e4737709561 100644 --- a/vnet/vnet/mpls/mpls.h +++ b/vnet/vnet/mpls/mpls.h @@ -155,7 +155,7 @@ typedef struct { u32 ip6_classify_mpls_policy_encap_next_index; /* feature path configuration lists */ - vnet_ip_feature_registration_t * next_feature[VNET_N_IP_FEAT]; + vnet_feature_registration_t * next_feature[VNET_N_IP_FEAT]; /* Save feature results for show command */ char **feature_nodes[VNET_N_IP_FEAT]; @@ -174,7 +174,7 @@ typedef struct { extern mpls_main_t mpls_main; #define VNET_MPLS_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t uc_##x; \ + __VA_ARGS__ vnet_feature_registration_t uc_##x; \ static void __vnet_add_feature_registration_uc_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_uc_##x (void) \ @@ -183,10 +183,10 @@ static void __vnet_add_feature_registration_uc_##x (void) \ uc_##x.next = mm->next_feature[VNET_IP_RX_UNICAST_FEAT]; \ mm->next_feature[VNET_IP_RX_UNICAST_FEAT] = &uc_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t uc_##x +__VA_ARGS__ vnet_feature_registration_t uc_##x #define VNET_MPLS_TX_FEATURE_INIT(x,...) \ - __VA_ARGS__ vnet_ip_feature_registration_t tx_##x; \ + __VA_ARGS__ vnet_feature_registration_t tx_##x; \ static void __vnet_add_feature_registration_tx_##x (void) \ __attribute__((__constructor__)) ; \ static void __vnet_add_feature_registration_tx_##x (void) \ @@ -195,7 +195,7 @@ static void __vnet_add_feature_registration_tx_##x (void) \ tx_##x.next = mm->next_feature[VNET_IP_TX_FEAT]; \ mm->next_feature[VNET_IP_TX_FEAT] = &tx_##x; \ } \ -__VA_ARGS__ vnet_ip_feature_registration_t tx_##x +__VA_ARGS__ vnet_feature_registration_t tx_##x extern clib_error_t * mpls_feature_init(vlib_main_t * vm); -- cgit 1.2.3-korg