aboutsummaryrefslogtreecommitdiffstats
path: root/vpp
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2016-08-25 15:29:12 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2016-09-21 17:37:39 +0000
commit0bfe5d8c792abcdbcf27bfcc7b7b353fba04aee2 (patch)
treed600b0e2e693e766e722936744930d3bebac493c /vpp
parent60537f3d83e83d0ce10a620ca99aad4eddf85f5e (diff)
A Protocol Independent Hierarchical FIB (VPP-352)
Main Enhancements: - Protocol Independent FIB API - Hierarchical FIB entries. Dynamic recursive route resolution. - Extranet Support. - Integration of IP and MPLS forwarding. - Separation of FIB and Adjacency databases. - Data-Plane Object forwarding model. Change-Id: I52dc815c0d0aa8b493e3cf6b978568f3cc82296c Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'vpp')
-rw-r--r--vpp/app/vpe_cli.c66
-rw-r--r--vpp/stats/stats.c362
-rw-r--r--vpp/vpp-api/api.c847
-rw-r--r--vpp/vpp-api/custom_dump.c5
-rw-r--r--vpp/vpp-api/vpe.api28
-rw-r--r--vpp/vpp-api/vpp_get_metrics.c8
6 files changed, 483 insertions, 833 deletions
diff --git a/vpp/app/vpe_cli.c b/vpp/app/vpe_cli.c
index b9f796881be..3b24c26f3e6 100644
--- a/vpp/app/vpe_cli.c
+++ b/vpp/app/vpe_cli.c
@@ -14,6 +14,8 @@
*/
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
+#include <vnet/adj/adj.h>
+#include <vnet/fib/fib_table.h>
typedef struct
{
@@ -27,20 +29,25 @@ virtual_ip_cmd_fn_command_fn (vlib_main_t * vm,
{
unformat_input_t _line_input, *line_input = &_line_input;
vnet_main_t *vnm = vnet_get_main ();
- ip4_main_t *im = &ip4_main;
- ip_lookup_main_t *lm = &im->lookup_main;
- ip4_address_t ip_addr, next_hop;
+ ip46_address_t next_hop, *next_hops;
+ fib_route_path_t *rpaths;
+ fib_prefix_t prefix;
u8 mac_addr[6];
mac_addr_t *mac_addrs = 0;
u32 sw_if_index;
- u32 i, f;
+ u32 i;
+
+ next_hops = NULL;
+ rpaths = NULL;
+ prefix.fp_len = 32;
+ prefix.fp_proto = FIB_PROTOCOL_IP4;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
if (!unformat (line_input, "%U %U",
- unformat_ip4_address, &ip_addr,
+ unformat_ip4_address, &prefix.fp_addr.ip4,
unformat_vnet_sw_interface, vnm, &sw_if_index))
goto barf;
@@ -53,6 +60,11 @@ virtual_ip_cmd_fn_command_fn (vlib_main_t * vm,
vec_add2 (mac_addrs, ma, 1);
clib_memcpy (ma, mac_addr, sizeof (mac_addr));
}
+ else if (unformat (line_input, "next-hop %U",
+ unformat_ip4_address, &next_hop.ip4))
+ {
+ vec_add1 (next_hops, next_hop);
+ }
else
{
barf:
@@ -60,37 +72,37 @@ virtual_ip_cmd_fn_command_fn (vlib_main_t * vm,
format_unformat_error, input);
}
}
- if (vec_len (mac_addrs) == 0)
+ if (vec_len (mac_addrs) == 0 ||
+ vec_len (next_hops) == 0 || vec_len (mac_addrs) != vec_len (next_hops))
goto barf;
/* Create / delete special interface route /32's */
- next_hop.as_u32 = 0;
for (i = 0; i < vec_len (mac_addrs); i++)
{
- ip_adjacency_t adj;
- u32 adj_index;
-
- memset (&adj, 0, sizeof (adj));
- adj.lookup_next_index = IP_LOOKUP_NEXT_REWRITE;
-
- vnet_rewrite_for_sw_interface (vnm, VNET_L3_PACKET_TYPE_IP4, sw_if_index, ip4_rewrite_node.index, &mac_addrs[i], /* destination address */
- &adj.rewrite_header,
- sizeof (adj.rewrite_data));
-
- ip_add_adjacency (lm, &adj, 1 /* one adj */ ,
- &adj_index);
-
- f =
- (i + 1 < vec_len (mac_addrs)) ? IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP : 0;
- ip4_add_del_route_next_hop (im, IP4_ROUTE_FLAG_ADD | f, &ip_addr,
- 32 /* insert /32's */ ,
- &next_hop, sw_if_index, 1 /* weight */ ,
- adj_index,
- (u32) ~ 0 /* explicit fib index */ );
+ fib_route_path_t *rpath;
+
+ adj_nbr_add_or_lock_w_rewrite (FIB_PROTOCOL_IP4,
+ FIB_LINK_IP4,
+ &next_hops[i],
+ sw_if_index, mac_addrs[i].mac_addr);
+
+ vec_add2 (rpaths, rpath, 1);
+
+ rpath->frp_proto = FIB_PROTOCOL_IP4;
+ rpath->frp_addr = next_hops[i];
+ rpath->frp_sw_if_index = sw_if_index;
+ rpath->frp_fib_index = ~0;
+ rpath->frp_weight = 1;
+ rpath->frp_label = MPLS_LABEL_INVALID;
}
+ fib_table_entry_path_add2 (0, // default FIB table
+ &prefix,
+ FIB_SOURCE_CLI, FIB_ENTRY_FLAG_NONE, rpaths);
+
vec_free (mac_addrs);
+ vec_free (next_hops);
return 0;
}
diff --git a/vpp/stats/stats.c b/vpp/stats/stats.c
index 823e0641c39..ee9a6a6d919 100644
--- a/vpp/stats/stats.c
+++ b/vpp/stats/stats.c
@@ -15,6 +15,9 @@
#include <stats/stats.h>
#include <signal.h>
#include <vlib/threads.h>
+#include <vnet/fib/fib_entry.h>
+#include <vnet/fib/fib_table.h>
+#include <vnet/dpo/load_balance.h>
#define STATS_DEBUG 0
@@ -250,7 +253,7 @@ do_ip4_fibs (stats_main_t * sm)
unix_shared_memory_queue_t *q = shmem_hdr->vl_input_queue;
static ip4_route_t *routes;
ip4_route_t *r;
- ip4_fib_t *fib;
+ fib_table_t *fib;
ip_lookup_main_t *lm = &im4->lookup_main;
static uword *results;
vl_api_vnet_ip4_fib_counters_t *mp = 0;
@@ -260,8 +263,9 @@ do_ip4_fibs (stats_main_t * sm)
int i;
again:
- vec_foreach (fib, im4->fibs)
- {
+ /* *INDENT-OFF* */
+ pool_foreach (fib, im4->fibs,
+ ({
/* We may have bailed out due to control-plane activity */
while ((fib - im4->fibs) < start_at_fib_index)
continue;
@@ -274,14 +278,14 @@ again:
items_this_message * sizeof (vl_api_ip4_fib_counter_t));
mp->_vl_msg_id = ntohs (VL_API_VNET_IP4_FIB_COUNTERS);
mp->count = 0;
- mp->vrf_id = ntohl (fib->table_id);
+ mp->vrf_id = ntohl (fib->ft_table_id);
ctrp = (vl_api_ip4_fib_counter_t *) mp->c;
}
else
{
/* happens if the last FIB was empty... */
ASSERT (mp->count == 0);
- mp->vrf_id = ntohl (fib->table_id);
+ mp->vrf_id = ntohl (fib->ft_table_id);
}
dslock (sm, 0 /* release hint */ , 1 /* tag */ );
@@ -289,15 +293,14 @@ again:
vec_reset_length (routes);
vec_reset_length (results);
- for (i = 0; i < ARRAY_LEN (fib->adj_index_by_dst_address); i++)
+ for (i = 0; i < ARRAY_LEN (fib->v4.fib_entry_by_dst_address); i++)
{
- uword *hash = fib->adj_index_by_dst_address[i];
+ uword *hash = fib->v4.fib_entry_by_dst_address[i];
hash_pair_t *p;
ip4_route_t x;
x.address_length = i;
- /* *INDENT-OFF* */
hash_foreach_pair (p, hash,
({
x.address.data_u32 = p->key;
@@ -321,114 +324,71 @@ again:
goto again;
}
}));
- /* *INDENT-ON* */
}
vec_foreach (r, routes)
- {
- vlib_counter_t c, sum;
- uword i, j, n_left, n_nhs, adj_index, *result = 0;
- ip_adjacency_t *adj;
- ip_multipath_next_hop_t *nhs, tmp_nhs[1];
-
- adj_index = r->index;
- if (lm->fib_result_n_words > 1)
- {
- result = vec_elt_at_index (results, adj_index);
- adj_index = result[0];
- }
-
- adj = ip_get_adjacency (lm, adj_index);
- if (adj->n_adj == 1)
- {
- nhs = &tmp_nhs[0];
- nhs[0].next_hop_adj_index = ~0; /* not used */
- nhs[0].weight = 1;
- n_nhs = 1;
- }
- else
- {
- ip_multipath_adjacency_t *madj;
- madj = vec_elt_at_index (lm->multipath_adjacencies,
- adj->heap_handle);
- nhs = heap_elt_at_index
- (lm->next_hop_heap, madj->normalized_next_hops.heap_offset);
- n_nhs = madj->normalized_next_hops.count;
- }
+ {
+ vlib_counter_t c;
+
+ vlib_get_combined_counter (&load_balance_main.lbm_to_counters,
+ r->index, &c);
+ /*
+ * If it has actually
+ * seen at least one packet, send it.
+ */
+ if (c.packets > 0)
+ {
- n_left = nhs[0].weight;
- vlib_counter_zero (&sum);
- for (i = j = 0; i < adj->n_adj; i++)
- {
- n_left -= 1;
- vlib_get_combined_counter (&lm->adjacency_counters,
- adj_index + i, &c);
- vlib_counter_add (&sum, &c);
- /*
- * If we're done with this adj and it has actually
- * seen at least one packet, send it.
- */
- if (n_left == 0 && sum.packets > 0)
- {
-
- /* already in net byte order */
- ctrp->address = r->address.as_u32;
- ctrp->address_length = r->address_length;
- ctrp->packets = clib_host_to_net_u64 (sum.packets);
- ctrp->bytes = clib_host_to_net_u64 (sum.bytes);
- mp->count++;
- ctrp++;
-
- if (mp->count == items_this_message)
- {
- mp->count = htonl (items_this_message);
- /*
- * If the main thread's input queue is stuffed,
- * drop the data structure lock (which the main thread
- * may want), and take a pause.
- */
- unix_shared_memory_queue_lock (q);
- if (unix_shared_memory_queue_is_full (q))
- {
- dsunlock (sm);
- vl_msg_api_send_shmem_nolock (q, (u8 *) & mp);
- unix_shared_memory_queue_unlock (q);
- mp = 0;
- ip46_fib_stats_delay (sm, 0 /* sec */ ,
- STATS_RELEASE_DELAY_NS);
- goto again;
- }
- vl_msg_api_send_shmem_nolock (q, (u8 *) & mp);
- unix_shared_memory_queue_unlock (q);
-
- items_this_message = IP4_FIB_COUNTER_BATCH_SIZE;
- mp = vl_msg_api_alloc_as_if_client
- (sizeof (*mp) +
- items_this_message * sizeof (vl_api_ip4_fib_counter_t));
- mp->_vl_msg_id = ntohs (VL_API_VNET_IP4_FIB_COUNTERS);
- mp->count = 0;
- mp->vrf_id = ntohl (fib->table_id);
- ctrp = (vl_api_ip4_fib_counter_t *) mp->c;
- }
-
- j++;
- if (j < n_nhs)
- {
- n_left = nhs[j].weight;
- vlib_counter_zero (&sum);
- }
- }
- } /* for each (mp or single) adj */
- if (sm->data_structure_lock->release_hint)
- {
- start_at_fib_index = fib - im4->fibs;
- dsunlock (sm);
- ip46_fib_stats_delay (sm, 0 /* sec */ , STATS_RELEASE_DELAY_NS);
- mp->count = 0;
- ctrp = (vl_api_ip4_fib_counter_t *) mp->c;
- goto again;
- }
- } /* vec_foreach (routes) */
+ /* already in net byte order */
+ ctrp->address = r->address.as_u32;
+ ctrp->address_length = r->address_length;
+ ctrp->packets = clib_host_to_net_u64 (c.packets);
+ ctrp->bytes = clib_host_to_net_u64 (c.bytes);
+ mp->count++;
+ ctrp++;
+
+ if (mp->count == items_this_message)
+ {
+ mp->count = htonl (items_this_message);
+ /*
+ * If the main thread's input queue is stuffed,
+ * drop the data structure lock (which the main thread
+ * may want), and take a pause.
+ */
+ unix_shared_memory_queue_lock (q);
+ if (unix_shared_memory_queue_is_full (q))
+ {
+ dsunlock (sm);
+ vl_msg_api_send_shmem_nolock (q, (u8 *) & mp);
+ unix_shared_memory_queue_unlock (q);
+ mp = 0;
+ ip46_fib_stats_delay (sm, 0 /* sec */ ,
+ STATS_RELEASE_DELAY_NS);
+ goto again;
+ }
+ vl_msg_api_send_shmem_nolock (q, (u8 *) & mp);
+ unix_shared_memory_queue_unlock (q);
+
+ items_this_message = IP4_FIB_COUNTER_BATCH_SIZE;
+ mp = vl_msg_api_alloc_as_if_client
+ (sizeof (*mp) +
+ items_this_message * sizeof (vl_api_ip4_fib_counter_t));
+ mp->_vl_msg_id = ntohs (VL_API_VNET_IP4_FIB_COUNTERS);
+ mp->count = 0;
+ mp->vrf_id = ntohl (fib->ft_table_id);
+ ctrp = (vl_api_ip4_fib_counter_t *) mp->c;
+ }
+ } /* for each (mp or single) adj */
+ if (sm->data_structure_lock->release_hint)
+ {
+ start_at_fib_index = fib - im4->fibs;
+ dsunlock (sm);
+ ip46_fib_stats_delay (sm, 0 /* sec */ , STATS_RELEASE_DELAY_NS);
+ mp->count = 0;
+ ctrp = (vl_api_ip4_fib_counter_t *) mp->c;
+ goto again;
+ }
+ } /* vec_foreach (routes) */
dsunlock (sm);
@@ -439,7 +399,9 @@ again:
vl_msg_api_send_shmem (q, (u8 *) & mp);
mp = 0;
}
- } /* vec_foreach (fib) */
+ }));
+ /* *INDENT-ON* */
+
/* If e.g. the last FIB had no reportable routes, free the buffer */
if (mp)
vl_msg_api_free (mp);
@@ -489,19 +451,19 @@ do_ip6_fibs (stats_main_t * sm)
unix_shared_memory_queue_t *q = shmem_hdr->vl_input_queue;
static ip6_route_t *routes;
ip6_route_t *r;
- ip6_fib_t *fib;
- ip_lookup_main_t *lm = &im6->lookup_main;
+ fib_table_t *fib;
static uword *results;
vl_api_vnet_ip6_fib_counters_t *mp = 0;
u32 items_this_message;
vl_api_ip6_fib_counter_t *ctrp = 0;
u32 start_at_fib_index = 0;
- BVT (clib_bihash) * h = &im6->ip6_lookup_table;
+ BVT (clib_bihash) * h = &im6->ip6_table[IP6_FIB_TABLE_FWDING].ip6_hash;
add_routes_in_fib_arg_t _a, *a = &_a;
again:
- vec_foreach (fib, im6->fibs)
- {
+ /* *INDENT-OFF* */
+ pool_foreach (fib, im6->fibs,
+ ({
/* We may have bailed out due to control-plane activity */
while ((fib - im6->fibs) < start_at_fib_index)
continue;
@@ -514,7 +476,7 @@ again:
items_this_message * sizeof (vl_api_ip6_fib_counter_t));
mp->_vl_msg_id = ntohs (VL_API_VNET_IP6_FIB_COUNTERS);
mp->count = 0;
- mp->vrf_id = ntohl (fib->table_id);
+ mp->vrf_id = ntohl (fib->ft_table_id);
ctrp = (vl_api_ip6_fib_counter_t *) mp->c;
}
@@ -544,105 +506,67 @@ again:
vec_foreach (r, routes)
{
- vlib_counter_t c, sum;
- uword i, j, n_left, n_nhs, adj_index, *result = 0;
- ip_adjacency_t *adj;
- ip_multipath_next_hop_t *nhs, tmp_nhs[1];
-
- adj_index = r->index;
- if (lm->fib_result_n_words > 1)
- {
- result = vec_elt_at_index (results, adj_index);
- adj_index = result[0];
- }
-
- adj = ip_get_adjacency (lm, adj_index);
- if (adj->n_adj == 1)
- {
- nhs = &tmp_nhs[0];
- nhs[0].next_hop_adj_index = ~0; /* not used */
- nhs[0].weight = 1;
- n_nhs = 1;
- }
- else
- {
- ip_multipath_adjacency_t *madj;
- madj = vec_elt_at_index (lm->multipath_adjacencies,
- adj->heap_handle);
- nhs = heap_elt_at_index
- (lm->next_hop_heap, madj->normalized_next_hops.heap_offset);
- n_nhs = madj->normalized_next_hops.count;
- }
+ vlib_counter_t c;
+
+ vlib_get_combined_counter (&load_balance_main.lbm_to_counters,
+ r->index, &c);
+ /*
+ * If it has actually
+ * seen at least one packet, send it.
+ */
+ if (c.packets > 0)
+ {
+ /* already in net byte order */
+ ctrp->address[0] = r->address.as_u64[0];
+ ctrp->address[1] = r->address.as_u64[1];
+ ctrp->address_length = (u8) r->address_length;
+ ctrp->packets = clib_host_to_net_u64 (c.packets);
+ ctrp->bytes = clib_host_to_net_u64 (c.bytes);
+ mp->count++;
+ ctrp++;
+
+ if (mp->count == items_this_message)
+ {
+ mp->count = htonl (items_this_message);
+ /*
+ * If the main thread's input queue is stuffed,
+ * drop the data structure lock (which the main thread
+ * may want), and take a pause.
+ */
+ unix_shared_memory_queue_lock (q);
+ if (unix_shared_memory_queue_is_full (q))
+ {
+ dsunlock (sm);
+ vl_msg_api_send_shmem_nolock (q, (u8 *) & mp);
+ unix_shared_memory_queue_unlock (q);
+ mp = 0;
+ ip46_fib_stats_delay (sm, 0 /* sec */ ,
+ STATS_RELEASE_DELAY_NS);
+ goto again;
+ }
+ vl_msg_api_send_shmem_nolock (q, (u8 *) & mp);
+ unix_shared_memory_queue_unlock (q);
+
+ items_this_message = IP6_FIB_COUNTER_BATCH_SIZE;
+ mp = vl_msg_api_alloc_as_if_client
+ (sizeof (*mp) +
+ items_this_message * sizeof (vl_api_ip6_fib_counter_t));
+ mp->_vl_msg_id = ntohs (VL_API_VNET_IP6_FIB_COUNTERS);
+ mp->count = 0;
+ mp->vrf_id = ntohl (fib->ft_table_id);
+ ctrp = (vl_api_ip6_fib_counter_t *) mp->c;
+ }
+ }
- n_left = nhs[0].weight;
- vlib_counter_zero (&sum);
- for (i = j = 0; i < adj->n_adj; i++)
- {
- n_left -= 1;
- vlib_get_combined_counter (&lm->adjacency_counters,
- adj_index + i, &c);
- vlib_counter_add (&sum, &c);
- if (n_left == 0 && sum.packets > 0)
- {
-
- /* already in net byte order */
- ctrp->address[0] = r->address.as_u64[0];
- ctrp->address[1] = r->address.as_u64[1];
- ctrp->address_length = (u8) r->address_length;
- ctrp->packets = clib_host_to_net_u64 (sum.packets);
- ctrp->bytes = clib_host_to_net_u64 (sum.bytes);
- mp->count++;
- ctrp++;
-
- if (mp->count == items_this_message)
- {
- mp->count = htonl (items_this_message);
- /*
- * If the main thread's input queue is stuffed,
- * drop the data structure lock (which the main thread
- * may want), and take a pause.
- */
- unix_shared_memory_queue_lock (q);
- if (unix_shared_memory_queue_is_full (q))
- {
- dsunlock (sm);
- vl_msg_api_send_shmem_nolock (q, (u8 *) & mp);
- unix_shared_memory_queue_unlock (q);
- mp = 0;
- ip46_fib_stats_delay (sm, 0 /* sec */ ,
- STATS_RELEASE_DELAY_NS);
- goto again;
- }
- vl_msg_api_send_shmem_nolock (q, (u8 *) & mp);
- unix_shared_memory_queue_unlock (q);
-
- items_this_message = IP6_FIB_COUNTER_BATCH_SIZE;
- mp = vl_msg_api_alloc_as_if_client
- (sizeof (*mp) +
- items_this_message * sizeof (vl_api_ip6_fib_counter_t));
- mp->_vl_msg_id = ntohs (VL_API_VNET_IP6_FIB_COUNTERS);
- mp->count = 0;
- mp->vrf_id = ntohl (fib->table_id);
- ctrp = (vl_api_ip6_fib_counter_t *) mp->c;
- }
-
- j++;
- if (j < n_nhs)
- {
- n_left = nhs[j].weight;
- vlib_counter_zero (&sum);
- }
- }
- } /* for each (mp or single) adj */
- if (sm->data_structure_lock->release_hint)
- {
- start_at_fib_index = fib - im6->fibs;
- dsunlock (sm);
- ip46_fib_stats_delay (sm, 0 /* sec */ , STATS_RELEASE_DELAY_NS);
- mp->count = 0;
- ctrp = (vl_api_ip6_fib_counter_t *) mp->c;
- goto again;
- }
+ if (sm->data_structure_lock->release_hint)
+ {
+ start_at_fib_index = fib - im6->fibs;
+ dsunlock (sm);
+ ip46_fib_stats_delay (sm, 0 /* sec */ , STATS_RELEASE_DELAY_NS);
+ mp->count = 0;
+ ctrp = (vl_api_ip6_fib_counter_t *) mp->c;
+ goto again;
+ }
} /* vec_foreach (routes) */
dsunlock (sm);
@@ -654,7 +578,9 @@ again:
vl_msg_api_send_shmem (q, (u8 *) & mp);
mp = 0;
}
- } /* vec_foreach (fib) */
+ }));
+ /* *INDENT-ON* */
+
/* If e.g. the last FIB had no reportable routes, free the buffer */
if (mp)
vl_msg_api_free (mp);
diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c
index 663096062ef..1a46eb9cf09 100644
--- a/vpp/vpp-api/api.c
+++ b/vpp/vpp-api/api.c
@@ -54,7 +54,7 @@
#include <vnet/ip/ip6.h>
#include <vnet/unix/tuntap.h>
#include <vnet/unix/tapcli.h>
-#include <vnet/mpls-gre/mpls.h>
+#include <vnet/mpls/mpls.h>
#include <vnet/dhcp/proxy.h>
#include <vnet/dhcp/client.h>
#if IPV6SR > 0
@@ -107,6 +107,13 @@
#include <vnet/l2/l2_bd.h>
#include <vpp-api/vpe_msg_enum.h>
+#include <vnet/fib/ip6_fib.h>
+#include <vnet/fib/ip4_fib.h>
+#include <vnet/dpo/drop_dpo.h>
+#include <vnet/dpo/receive_dpo.h>
+#include <vnet/dpo/lookup_dpo.h>
+#include <vnet/dpo/classify_dpo.h>
+
#define f64_endian(a)
#define f64_print(a,b)
@@ -244,6 +251,7 @@ _(IP_ADD_DEL_ROUTE, ip_add_del_route) \
_(IS_ADDRESS_REACHABLE, is_address_reachable) \
_(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \
_(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \
+_(SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable) \
_(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
_(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
_(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
@@ -979,251 +987,165 @@ VLIB_REGISTER_NODE (vpe_resolver_process_node,static) = {
/* *INDENT-ON* */
static int
-ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
+ u32 fib_index,
+ const fib_prefix_t * prefix,
+ const ip46_address_t * next_hop,
+ u32 next_hop_sw_if_index,
+ u32 next_hop_fib_index, u32 next_hop_weight)
{
- ip4_main_t *im = &ip4_main;
- ip_lookup_main_t *lm = &im->lookup_main;
vnet_classify_main_t *cm = &vnet_classify_main;
+ fib_protocol_t proto = prefix->fp_proto;
stats_main_t *sm = &stats_main;
- ip4_add_del_route_args_t a;
- ip4_address_t next_hop_address;
- u32 fib_index;
- vpe_api_main_t *vam = &vpe_api_main;
- vnet_main_t *vnm = vam->vnet_main;
- vlib_main_t *vm = vlib_get_main ();
- pending_route_t *pr;
- vl_api_ip_add_del_route_t *adr;
- uword *p;
- clib_error_t *e;
- u32 ai;
- ip_adjacency_t *adj;
-
- p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
- if (!p)
- {
- if (mp->create_vrf_if_needed)
- {
- ip4_fib_t *f;
- f = find_ip4_fib_by_table_index_or_id (im, ntohl (mp->vrf_id),
- 0 /* flags */ );
- fib_index = f->index;
- }
- else
- {
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
- }
- else
- {
- fib_index = p[0];
- }
-
- if (~0 != mp->next_hop_sw_if_index &&
- pool_is_free_index (vnm->interface_main.sw_interfaces,
- ntohl (mp->next_hop_sw_if_index)))
- return VNET_API_ERROR_NO_MATCHING_INTERFACE;
-
- clib_memcpy (next_hop_address.data, mp->next_hop_address,
- sizeof (next_hop_address.data));
-
- /* Arp for the next_hop if necessary */
- if (mp->is_add && mp->resolve_if_needed && ~0 != mp->next_hop_sw_if_index)
- {
- u32 lookup_result;
- ip_adjacency_t *adj;
-
- lookup_result = ip4_fib_lookup_with_table
- (im, fib_index, &next_hop_address, 1 /* disable default route */ );
-
- adj = ip_get_adjacency (lm, lookup_result);
-
- if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
- {
- pool_get (vam->pending_routes, pr);
- pr->resolve_type = RESOLVE_IP4_ADD_DEL_ROUTE;
- adr = &pr->r;
- clib_memcpy (adr, mp, sizeof (*adr));
- /* recursion block, "just in case" */
- adr->resolve_if_needed = 0;
- adr->resolve_attempts = ntohl (mp->resolve_attempts);
- vnet_register_ip4_arp_resolution_event
- (vnm, &next_hop_address, vpe_resolver_process_node.index,
- RESOLUTION_EVENT, pr - vam->pending_routes);
-
- vlib_process_signal_event
- (vm, vpe_resolver_process_node.index,
- RESOLUTION_PENDING_EVENT, 0 /* data */ );
-
- /* The interface may be down, etc. */
- e = ip4_probe_neighbor
- (vm, (ip4_address_t *) & (mp->next_hop_address),
- ntohl (mp->next_hop_sw_if_index));
-
- if (e)
- clib_error_report (e);
-
- return VNET_API_ERROR_IN_PROGRESS;
- }
- }
if (mp->is_multipath)
{
- u32 flags;
+ fib_route_path_flags_t path_flags = FIB_ROUTE_PATH_FLAG_NONE;
dslock (sm, 1 /* release hint */ , 10 /* tag */ );
+ if (mp->is_resolve_host)
+ path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
+ if (mp->is_resolve_attached)
+ path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
+
if (mp->is_add)
- flags = IP4_ROUTE_FLAG_ADD;
+ fib_table_entry_path_add (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ prefix->fp_proto,
+ next_hop,
+ next_hop_sw_if_index,
+ next_hop_fib_index,
+ next_hop_weight,
+ MPLS_LABEL_INVALID, path_flags);
else
- flags = IP4_ROUTE_FLAG_DEL;
-
- if (mp->not_last)
- flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
-
- ip4_add_del_route_next_hop (im, flags,
- (ip4_address_t *) mp->dst_address,
- (u32) mp->dst_address_length,
- (ip4_address_t *) mp->next_hop_address,
- ntohl (mp->next_hop_sw_if_index),
- (u32) mp->next_hop_weight,
- ~0 /* adj_index */ ,
- fib_index);
+ fib_table_entry_path_remove (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ prefix->fp_proto,
+ next_hop,
+ next_hop_sw_if_index,
+ next_hop_fib_index,
+ next_hop_weight, path_flags);
+
dsunlock (sm);
return 0;
}
- memset (&a, 0, sizeof (a));
- clib_memcpy (a.dst_address.data, mp->dst_address,
- sizeof (a.dst_address.data));
-
- a.dst_address_length = mp->dst_address_length;
-
- a.flags = (mp->is_add ? IP4_ROUTE_FLAG_ADD : IP4_ROUTE_FLAG_DEL);
- a.flags |= IP4_ROUTE_FLAG_FIB_INDEX;
- a.table_index_or_table_id = fib_index;
- a.add_adj = 0;
- a.n_add_adj = 0;
-
- if (mp->not_last)
- a.flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
-
dslock (sm, 1 /* release hint */ , 2 /* tag */ );
- if (mp->is_add)
+ if (mp->is_drop || mp->is_local || mp->is_classify || mp->lookup_in_vrf)
{
- if (mp->is_drop)
- ai = lm->drop_adj_index;
- else if (mp->is_local)
- ai = lm->local_adj_index;
- else if (mp->is_classify)
+ /*
+ * special route types that link directly to the adj
+ */
+ if (mp->is_add)
{
- if (pool_is_free_index
- (cm->tables, ntohl (mp->classify_table_index)))
+ dpo_id_t dpo = DPO_NULL;
+ dpo_proto_t dproto;
+
+ dproto = fib_proto_to_dpo (prefix->fp_proto);
+
+ if (mp->is_drop)
+ dpo_copy (&dpo, drop_dpo_get (dproto));
+ else if (mp->is_local)
+ receive_dpo_add_or_lock (dproto, ~0, NULL, &dpo);
+ else if (mp->is_classify)
{
- dsunlock (sm);
- return VNET_API_ERROR_NO_SUCH_TABLE;
- }
- adj = ip_add_adjacency (lm,
- /* template */ 0,
- /* block size */ 1,
- &ai);
+ if (pool_is_free_index (cm->tables,
+ ntohl (mp->classify_table_index)))
+ {
+ dsunlock (sm);
+ return VNET_API_ERROR_NO_SUCH_TABLE;
+ }
- adj->lookup_next_index = IP_LOOKUP_NEXT_CLASSIFY;
- adj->classify.table_index = ntohl (mp->classify_table_index);
- }
- else if (mp->lookup_in_vrf)
- {
- p = hash_get (im->fib_index_by_table_id, ntohl (mp->lookup_in_vrf));
- if (p)
+ dpo_set (&dpo, DPO_CLASSIFY, proto,
+ classify_dpo_create (prefix->fp_proto,
+ ntohl
+ (mp->classify_table_index)));
+ }
+ else if (mp->lookup_in_vrf)
{
- adj = ip_add_adjacency (lm,
- /* template */ 0,
- /* block size */ 1,
- &ai);
- adj->explicit_fib_index = p[0];
+ next_hop_fib_index =
+ fib_table_id_find_fib_index (dproto,
+ ntohl (mp->lookup_in_vrf));
+ if (~0 == next_hop_fib_index)
+ {
+ dsunlock (sm);
+ return VNET_API_ERROR_NO_SUCH_INNER_FIB;
+ }
+
+ lookup_dpo_add_or_lock_w_fib_index (next_hop_fib_index,
+ dproto,
+ LOOKUP_INPUT_DST_ADDR,
+ LOOKUP_TABLE_FROM_CONFIG,
+ &dpo);
}
else
{
dsunlock (sm);
- return VNET_API_ERROR_NO_SUCH_INNER_FIB;
+ return VNET_API_ERROR_NO_SUCH_TABLE;
}
+
+ fib_table_entry_special_dpo_add (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
+ dpo_reset (&dpo);
}
else
- ai = ip4_route_get_next_hop_adj (im,
- fib_index,
- &next_hop_address,
- ntohl (mp->next_hop_sw_if_index),
- fib_index);
-
- if (ai == lm->miss_adj_index)
{
- dsunlock (sm);
- return VNET_API_ERROR_NO_SUCH_INNER_FIB;
+ fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API);
}
}
else
{
- ip_adjacency_t *adj;
- int disable_default_route = 1;
-
- /* Trying to delete the default route? */
- if (a.dst_address.as_u32 == 0 && a.dst_address_length == 0)
- disable_default_route = 0;
-
- ai = ip4_fib_lookup_with_table
- (im, fib_index, &a.dst_address, disable_default_route);
- if (ai == lm->miss_adj_index)
+ if (mp->is_add)
{
- dsunlock (sm);
- return VNET_API_ERROR_UNKNOWN_DESTINATION;
+ fib_route_path_flags_t path_flags = FIB_ROUTE_PATH_FLAG_NONE;
+
+ if (mp->is_resolve_host)
+ path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
+ if (mp->is_resolve_attached)
+ path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
+
+ fib_table_entry_update_one_path (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ prefix->fp_proto,
+ next_hop,
+ next_hop_sw_if_index,
+ next_hop_fib_index,
+ next_hop_weight,
+ MPLS_LABEL_INVALID, path_flags);
}
-
- adj = ip_get_adjacency (lm, ai);
- if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
+ else
{
- dsunlock (sm);
- return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
+ fib_table_entry_delete (fib_index, prefix, FIB_SOURCE_API);
}
}
- a.adj_index = ai;
- ip4_add_del_route (im, &a);
-
dsunlock (sm);
- return 0;
+ return (0);
}
static int
-ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
{
- ip6_main_t *im = &ip6_main;
- ip_lookup_main_t *lm = &im->lookup_main;
- vnet_main_t *vnm = vnet_get_main ();
- vlib_main_t *vm = vlib_get_main ();
vpe_api_main_t *vam = &vpe_api_main;
- stats_main_t *sm = &stats_main;
- ip6_add_del_route_args_t a;
- ip6_address_t next_hop_address;
- pending_route_t *pr;
- vl_api_ip_add_del_route_t *adr;
-
+ vnet_main_t *vnm = vam->vnet_main;
u32 fib_index;
- uword *p;
- clib_error_t *e;
- ip_adjacency_t *adj = 0;
- u32 ai;
-
- p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
- if (!p)
+ fib_index = ip4_fib_index_from_table_id (ntohl (mp->vrf_id));
+ if (~0 == fib_index)
{
if (mp->create_vrf_if_needed)
{
- ip6_fib_t *f;
- f = find_ip6_fib_by_table_index_or_id (im, ntohl (mp->vrf_id),
- 0 /* flags */ );
- fib_index = f->index;
+ fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
+ ntohl (mp->vrf_id));
}
else
{
@@ -1231,160 +1153,66 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
return VNET_API_ERROR_NO_SUCH_FIB;
}
}
- else
- {
- fib_index = p[0];
- }
- if (~0 != mp->next_hop_sw_if_index &&
+ if (~0 != ntohl (mp->next_hop_sw_if_index) &&
pool_is_free_index (vnm->interface_main.sw_interfaces,
ntohl (mp->next_hop_sw_if_index)))
return VNET_API_ERROR_NO_MATCHING_INTERFACE;
- clib_memcpy (next_hop_address.as_u8, mp->next_hop_address,
- sizeof (next_hop_address.as_u8));
-
- /* Arp for the next_hop if necessary */
- if (mp->is_add && mp->resolve_if_needed && ~0 != mp->next_hop_sw_if_index)
- {
- u32 lookup_result;
- ip_adjacency_t *adj;
-
- lookup_result = ip6_fib_lookup_with_table
- (im, fib_index, &next_hop_address);
-
- adj = ip_get_adjacency (lm, lookup_result);
-
- if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
- {
- pool_get (vam->pending_routes, pr);
- adr = &pr->r;
- pr->resolve_type = RESOLVE_IP6_ADD_DEL_ROUTE;
- clib_memcpy (adr, mp, sizeof (*adr));
- /* recursion block, "just in case" */
- adr->resolve_if_needed = 0;
- adr->resolve_attempts = ntohl (mp->resolve_attempts);
- vnet_register_ip6_neighbor_resolution_event
- (vnm, &next_hop_address, vpe_resolver_process_node.index,
- RESOLUTION_EVENT, pr - vam->pending_routes);
-
- vlib_process_signal_event
- (vm, vpe_resolver_process_node.index,
- RESOLUTION_PENDING_EVENT, 0 /* data */ );
-
- /* The interface may be down, etc. */
- e = ip6_probe_neighbor
- (vm, (ip6_address_t *) & (mp->next_hop_address),
- ntohl (mp->next_hop_sw_if_index));
-
- if (e)
- clib_error_report (e);
-
- return VNET_API_ERROR_IN_PROGRESS;
- }
- }
-
- if (mp->is_multipath)
- {
- u32 flags;
-
- dslock (sm, 1 /* release hint */ , 11 /* tag */ );
-
- if (mp->is_add)
- flags = IP6_ROUTE_FLAG_ADD;
- else
- flags = IP6_ROUTE_FLAG_DEL;
-
- if (mp->not_last)
- flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
-
- ip6_add_del_route_next_hop (im, flags,
- (ip6_address_t *) mp->dst_address,
- (u32) mp->dst_address_length,
- (ip6_address_t *) mp->next_hop_address,
- ntohl (mp->next_hop_sw_if_index),
- (u32) mp->next_hop_weight,
- ~0 /* adj_index */ ,
- fib_index);
- dsunlock (sm);
- return 0;
- }
-
- memset (&a, 0, sizeof (a));
- clib_memcpy (a.dst_address.as_u8, mp->dst_address,
- sizeof (a.dst_address.as_u8));
-
- a.dst_address_length = mp->dst_address_length;
+ fib_prefix_t pfx = {
+ .fp_len = mp->dst_address_length,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ };
+ clib_memcpy (&pfx.fp_addr.ip4, mp->dst_address, sizeof (pfx.fp_addr.ip4));
- a.flags = (mp->is_add ? IP6_ROUTE_FLAG_ADD : IP6_ROUTE_FLAG_DEL);
- a.flags |= IP6_ROUTE_FLAG_FIB_INDEX;
- a.table_index_or_table_id = fib_index;
- a.add_adj = 0;
- a.n_add_adj = 0;
+ ip46_address_t nh;
+ memset (&nh, 0, sizeof (nh));
+ memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
- if (mp->not_last)
- a.flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
+ return (ip_add_del_route_t_handler (mp, fib_index, &pfx, &nh,
+ ntohl (mp->next_hop_sw_if_index),
+ fib_index, (u32) mp->next_hop_weight));
+}
- dslock (sm, 1 /* release hint */ , 3 /* tag */ );
+static int
+ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ u32 fib_index;
- if (mp->is_add)
+ fib_index = ip6_fib_index_from_table_id (ntohl (mp->vrf_id));
+ if (~0 == fib_index)
{
- if (mp->is_drop)
- ai = lm->drop_adj_index;
- else if (mp->is_local)
- ai = lm->local_adj_index;
- else if (mp->lookup_in_vrf)
+ if (mp->create_vrf_if_needed)
{
- p = hash_get (im->fib_index_by_table_id, ntohl (mp->lookup_in_vrf));
- if (p)
- {
- adj = ip_add_adjacency (lm,
- /* template */ 0,
- /* block size */ 1,
- &ai);
- adj->explicit_fib_index = p[0];
- }
- else
- {
- dsunlock (sm);
- return VNET_API_ERROR_NO_SUCH_INNER_FIB;
- }
+ fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6,
+ ntohl (mp->vrf_id));
}
else
- ai = ip6_route_get_next_hop_adj (im,
- fib_index,
- &next_hop_address,
- ntohl (mp->next_hop_sw_if_index),
- fib_index);
- if (ai == lm->miss_adj_index)
{
- dsunlock (sm);
- return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
+ /* No such VRF, and we weren't asked to create one */
+ return VNET_API_ERROR_NO_SUCH_FIB;
}
}
- else
- {
- ip_adjacency_t *adj;
- ai = ip6_fib_lookup_with_table (im, fib_index, &a.dst_address);
- if (ai == lm->miss_adj_index)
- {
- dsunlock (sm);
- return VNET_API_ERROR_UNKNOWN_DESTINATION;
- }
- adj = ip_get_adjacency (lm, ai);
- if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
- {
- dsunlock (sm);
- return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
- }
- }
+ if (~0 != ntohl (mp->next_hop_sw_if_index) &&
+ pool_is_free_index (vnm->interface_main.sw_interfaces,
+ ntohl (mp->next_hop_sw_if_index)))
+ return VNET_API_ERROR_NO_MATCHING_INTERFACE;
+
+ fib_prefix_t pfx = {
+ .fp_len = mp->dst_address_length,
+ .fp_proto = FIB_PROTOCOL_IP6,
+ };
+ clib_memcpy (&pfx.fp_addr.ip6, mp->dst_address, sizeof (pfx.fp_addr.ip6));
- a.adj_index = ai;
- ip6_add_del_route (im, &a);
+ ip46_address_t nh;
+ memset (&nh, 0, sizeof (nh));
+ memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
- dsunlock (sm);
- return 0;
+ return (ip_add_del_route_t_handler (mp, fib_index, &pfx,
+ &nh, ntohl (mp->next_hop_sw_if_index),
+ fib_index, (u32) mp->next_hop_weight));
}
void
@@ -1406,48 +1234,6 @@ vl_api_ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY);
}
-void
-api_config_default_ip_route (u8 is_ipv6, u8 is_add, u32 vrf_id,
- u32 sw_if_index, u8 * next_hop_addr)
-{
- vl_api_ip_add_del_route_t mp;
- int rv;
-
- memset (&mp, 0, sizeof (vl_api_ip_add_del_route_t));
-
- /*
- * Configure default IP route:
- * - ip route add 0.0.0.0/1 via <GW IP>
- * - ip route add 128.0.0.0/1 via <GW IP>
- */
- mp.next_hop_sw_if_index = ntohl (sw_if_index);
- mp.vrf_id = vrf_id;
- mp.resolve_attempts = ~0;
- mp.resolve_if_needed = 1;
- mp.is_add = is_add;
- mp.is_ipv6 = is_ipv6;
- mp.next_hop_weight = 1;
-
- clib_memcpy (&mp.next_hop_address[0], next_hop_addr, 16);
-
- if (is_ipv6)
- rv = ip6_add_del_route_t_handler (&mp);
- else
- {
- mp.dst_address_length = 1;
-
- mp.dst_address[0] = 0;
- rv = ip4_add_del_route_t_handler (&mp);
-
- mp.dst_address[0] = 128;
- rv |= ip4_add_del_route_t_handler (&mp);
- }
-
- if (rv)
- clib_error_return (0, "failed to config default IP route");
-
-}
-
static void
vl_api_sw_interface_add_del_address_t_handler
(vl_api_sw_interface_add_del_address_t * mp)
@@ -1485,6 +1271,7 @@ vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t * mp)
u32 sw_if_index = ntohl (mp->sw_if_index);
vl_api_sw_interface_set_table_reply_t *rmp;
stats_main_t *sm = &stats_main;
+ u32 fib_index;
VALIDATE_SW_IF_INDEX (mp);
@@ -1492,35 +1279,20 @@ vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t * mp)
if (mp->is_ipv6)
{
- ip6_main_t *im = &ip6_main;
- ip6_fib_t *fib = find_ip6_fib_by_table_index_or_id (im, table_id,
- IP6_ROUTE_FLAG_TABLE_ID);
- if (fib)
- {
- vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
- im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
- }
- else
- {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- }
+ fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6,
+ table_id);
+
+ vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index);
+ ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
}
else
{
- ip4_main_t *im = &ip4_main;
- ip4_fib_t *fib = find_ip4_fib_by_table_index_or_id
- (im, table_id, IP4_ROUTE_FLAG_TABLE_ID);
- /* Truthfully this can't fail */
- if (fib)
- {
- vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
- im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
- }
- else
- {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- }
+ fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
+ table_id);
+
+ vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index);
+ ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
}
dsunlock (sm);
@@ -2303,10 +2075,11 @@ static int mpls_ethernet_add_del_tunnel_2_t_handler
if (inner_fib_index == outer_fib_index)
return VNET_API_ERROR_INVALID_VALUE;
- lookup_result = ip4_fib_lookup_with_table
- (im, outer_fib_index,
- (ip4_address_t *) mp->next_hop_ip4_address_in_outer_vrf,
- 1 /* disable default route */ );
+ // FIXME not an ADJ
+ lookup_result = ip4_fib_table_lookup_lb (ip4_fib_get (outer_fib_index),
+ (ip4_address_t *)
+ mp->
+ next_hop_ip4_address_in_outer_vrf);
adj = ip_get_adjacency (lm, lookup_result);
tx_sw_if_index = adj->rewrite_header.sw_if_index;
@@ -2489,14 +2262,18 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
{
vl_api_ip_neighbor_add_del_reply_t *rmp;
vnet_main_t *vnm = vnet_get_main ();
- u32 fib_index;
- int rv = 0;
stats_main_t *sm = &stats_main;
+ int rv = 0;
VALIDATE_SW_IF_INDEX (mp);
dslock (sm, 1 /* release hint */ , 7 /* tag */ );
+ /*
+ * there's no validation here of the ND/ARP entry being added.
+ * The expectation is that the FIB will ensure that nothing bad
+ * will come of adding bogus entries.
+ */
if (mp->is_ipv6)
{
if (mp->is_add)
@@ -2512,56 +2289,21 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
}
else
{
- ip4_main_t *im = &ip4_main;
- ip_lookup_main_t *lm = &im->lookup_main;
ethernet_arp_ip4_over_ethernet_address_t a;
- u32 ai;
- ip_adjacency_t *nh_adj;
-
- uword *p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
- if (!p)
- {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- goto out;
- }
- fib_index = p[0];
-
- /*
- * Unfortunately, folks have a penchant for
- * adding interface addresses to the ARP cache, and
- * wondering why the forwarder eventually ASSERTs...
- */
- ai = ip4_fib_lookup_with_table
- (im, fib_index, (ip4_address_t *) (mp->dst_address),
- 1 /* disable default route */ );
-
- if (ai != 0)
- {
- nh_adj = ip_get_adjacency (lm, ai);
- /* Never allow manipulation of a local adj! */
- if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_LOCAL)
- {
- clib_warning ("%U matches local adj",
- format_ip4_address,
- (ip4_address_t *) (mp->dst_address));
- rv = VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
- goto out;
- }
- }
clib_memcpy (&a.ethernet, mp->mac_address, 6);
clib_memcpy (&a.ip4, mp->dst_address, 4);
if (mp->is_add)
rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
- fib_index, &a, mp->is_static);
+ &a, mp->is_static);
else
- rv = vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
- fib_index, &a);
+ rv =
+ vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);
}
BAD_SW_IF_INDEX_LABEL;
-out:
+
dsunlock (sm);
REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
}
@@ -2604,6 +2346,7 @@ vl_api_is_address_reachable_t_handler (vl_api_is_address_reachable_t * mp)
else
{
lm = &im4->lookup_main;
+ // FIXME NOT an ADJ
adj_index = ip4_fib_lookup (im4, sw_if_index, &addr.ip4);
}
if (adj_index == ~0)
@@ -2672,6 +2415,22 @@ vl_api_sw_interface_set_flags_t_handler (vl_api_sw_interface_set_flags_t * mp)
}
static void
+ vl_api_sw_interface_set_mpls_enable_t_handler
+ (vl_api_sw_interface_set_mpls_enable_t * mp)
+{
+ vl_api_sw_interface_set_mpls_enable_reply_t *rmp;
+ int rv = 0;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ mpls_sw_interface_enable_disable (&mpls_main,
+ ntohl (mp->sw_if_index), mp->enable);
+
+ BAD_SW_IF_INDEX_LABEL;
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_MPLS_ENABLE_REPLY);
+}
+
+static void
vl_api_sw_interface_clear_stats_t_handler (vl_api_sw_interface_clear_stats_t *
mp)
{
@@ -2999,10 +2758,9 @@ ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
vnet_main_t *vnm = vnet_get_main ();
vnet_interface_main_t *im = &vnm->interface_main;
ip4_main_t *im4 = &ip4_main;
- static ip4_route_t *routes;
static u32 *sw_if_indices_to_shut;
stats_main_t *sm = &stats_main;
- ip4_route_t *r;
+ fib_table_t *fib_table;
ip4_fib_t *fib;
u32 sw_if_index;
int i;
@@ -3011,9 +2769,11 @@ ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
dslock (sm, 1 /* release hint */ , 8 /* tag */ );
- vec_foreach (fib, im4->fibs)
- {
- vnet_sw_interface_t *si;
+ /* *INDENT-OFF* */
+ pool_foreach (fib_table, im4->fibs,
+ ({
+ fib = &fib_table->v4;
+ vnet_sw_interface_t * si;
if (fib->table_id != target_fib_id)
continue;
@@ -3033,100 +2793,37 @@ ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
vec_reset_length (sw_if_indices_to_shut);
/* Shut down interfaces in this FIB / clean out intfc routes */
- /* *INDENT-OFF* */
pool_foreach (si, im->sw_interfaces,
({
u32 sw_if_index = si->sw_if_index;
if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
&& (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
- fib - im4->fibs))
+ fib->index))
vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
}));
- /* *INDENT-ON* */
- for (i = 0; i < vec_len (sw_if_indices_to_shut); i++)
- {
- sw_if_index = sw_if_indices_to_shut[i];
- // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
-
- u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
- flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
- vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
- }
+ for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
+ sw_if_index = sw_if_indices_to_shut[i];
+ // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
- vec_reset_length (routes);
-
- for (i = 0; i < ARRAY_LEN (fib->adj_index_by_dst_address); i++)
- {
- uword *hash = fib->adj_index_by_dst_address[i];
- hash_pair_t *p;
- ip4_route_t x;
-
- x.address_length = i;
-
- /* *INDENT-OFF* */
- hash_foreach_pair (p, hash,
- ({
- x.address.data_u32 = p->key;
- vec_add1 (routes, x);
- }));
- /* *INDENT-ON* */
- }
-
- vec_foreach (r, routes)
- {
- ip4_add_del_route_args_t a;
+ u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
+ flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
+ vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
+ }
- memset (&a, 0, sizeof (a));
- a.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_DEL;
- a.table_index_or_table_id = fib - im4->fibs;
- a.dst_address = r->address;
- a.dst_address_length = r->address_length;
- a.adj_index = ~0;
+ fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
+ fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_INTERFACE);
- ip4_add_del_route (im4, &a);
- ip4_maybe_remap_adjacencies (im4, fib - im4->fibs,
- IP4_ROUTE_FLAG_FIB_INDEX);
- }
rv = 0;
break;
- } /* vec_foreach (fib) */
+ })); /* pool_foreach (fib) */
+ /* *INDENT-ON* */
dsunlock (sm);
return rv;
}
-typedef struct
-{
- ip6_address_t address;
- u32 address_length;
- u32 index;
-} ip6_route_t;
-
-typedef struct
-{
- u32 fib_index;
- ip6_route_t **routep;
-} add_routes_in_fib_arg_t;
-
-static void
-add_routes_in_fib (clib_bihash_kv_24_8_t * kvp, void *arg)
-{
- add_routes_in_fib_arg_t *ap = arg;
-
- if (kvp->key[2] >> 32 == ap->fib_index)
- {
- ip6_address_t *addr;
- ip6_route_t *r;
- addr = (ip6_address_t *) kvp;
- vec_add2 (*ap->routep, r, 1);
- r->address = addr[0];
- r->address_length = kvp->key[2] & 0xFF;
- r->index = kvp->value;
- }
-}
-
static int
ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
{
@@ -3134,22 +2831,21 @@ ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
vnet_interface_main_t *im = &vnm->interface_main;
ip6_main_t *im6 = &ip6_main;
stats_main_t *sm = &stats_main;
- static ip6_route_t *routes;
static u32 *sw_if_indices_to_shut;
- ip6_route_t *r;
+ fib_table_t *fib_table;
ip6_fib_t *fib;
u32 sw_if_index;
int i;
int rv = VNET_API_ERROR_NO_SUCH_FIB;
u32 target_fib_id = ntohl (mp->vrf_id);
- add_routes_in_fib_arg_t _a, *a = &_a;
- clib_bihash_24_8_t *h = &im6->ip6_lookup_table;
dslock (sm, 1 /* release hint */ , 9 /* tag */ );
- vec_foreach (fib, im6->fibs)
- {
- vnet_sw_interface_t *si;
+ /* *INDENT-OFF* */
+ pool_foreach (fib_table, im6->fibs,
+ ({
+ vnet_sw_interface_t * si;
+ fib = &(fib_table->v6);
if (fib->table_id != target_fib_id)
continue;
@@ -3157,52 +2853,29 @@ ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
vec_reset_length (sw_if_indices_to_shut);
/* Shut down interfaces in this FIB / clean out intfc routes */
- /* *INDENT-OFF* */
pool_foreach (si, im->sw_interfaces,
- ({
- if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
- fib - im6->fibs)
- vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
- }));
- /* *INDENT-ON* */
+ ({
+ if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
+ fib->index)
+ vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
+ }));
- for (i = 0; i < vec_len (sw_if_indices_to_shut); i++)
- {
- sw_if_index = sw_if_indices_to_shut[i];
- // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
-
- u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
- flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
- vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
- }
+ for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
+ sw_if_index = sw_if_indices_to_shut[i];
+ // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
- vec_reset_length (routes);
-
- a->fib_index = fib - im6->fibs;
- a->routep = &routes;
-
- clib_bihash_foreach_key_value_pair_24_8 (h, add_routes_in_fib, a);
-
- vec_foreach (r, routes)
- {
- ip6_add_del_route_args_t a;
+ u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
+ flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
+ vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
+ }
- memset (&a, 0, sizeof (a));
- a.flags = IP6_ROUTE_FLAG_FIB_INDEX | IP6_ROUTE_FLAG_DEL;
- a.table_index_or_table_id = fib - im6->fibs;
- a.dst_address = r->address;
- a.dst_address_length = r->address_length;
- a.adj_index = ~0;
+ fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
+ fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_INTERFACE);
- ip6_add_del_route (im6, &a);
- ip6_maybe_remap_adjacencies (im6, fib - im6->fibs,
- IP6_ROUTE_FLAG_FIB_INDEX);
- }
rv = 0;
- /* Reinstall the neighbor / router discovery routes */
- vnet_ip6_fib_init (im6, fib - im6->fibs);
break;
- } /* vec_foreach (fib) */
+ })); /* pool_foreach (fib) */
+ /* *INDENT-ON* */
dsunlock (sm);
return rv;
@@ -3519,7 +3192,7 @@ set_ip4_flow_hash (vl_api_set_ip_flow_hash_t * mp)
vl_api_set_ip_flow_hash_reply_t *rmp;
int rv;
u32 table_id;
- u32 flow_hash_config = 0;
+ flow_hash_config_t flow_hash_config = 0;
table_id = ntohl (mp->vrf_id);
@@ -3580,11 +3253,15 @@ static void vl_api_sw_interface_set_unnumbered_t_handler
{
si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
si->unnumbered_sw_if_index = sw_if_index;
+ ip4_sw_interface_enable_disable (sw_if_index, 1);
+ ip6_sw_interface_enable_disable (sw_if_index, 1);
}
else
{
si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
si->unnumbered_sw_if_index = (u32) ~ 0;
+ ip4_sw_interface_enable_disable (sw_if_index, 0);
+ ip6_sw_interface_enable_disable (sw_if_index, 0);
}
done:
@@ -3769,7 +3446,7 @@ vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t * mp)
static void vl_api_sr_tunnel_add_del_t_handler
(vl_api_sr_tunnel_add_del_t * mp)
{
-#if IPV6SR == 0
+#if IP6SR == 0
clib_warning ("unimplemented");
#else
ip6_sr_add_del_tunnel_args_t _a, *a = &_a;
@@ -3832,7 +3509,7 @@ out:
static void vl_api_sr_policy_add_del_t_handler
(vl_api_sr_policy_add_del_t * mp)
{
-#if IPV6SR == 0
+#if IP6SR == 0
clib_warning ("unimplemented");
#else
ip6_sr_add_del_policy_args_t _a, *a = &_a;
@@ -3886,7 +3563,7 @@ out:
static void vl_api_sr_multicast_map_add_del_t_handler
(vl_api_sr_multicast_map_add_del_t * mp)
{
-#if IPV6SR == 0
+#if IP6SR == 0
clib_warning ("unimplemented");
#else
ip6_sr_add_del_multicastmap_args_t _a, *a = &_a;
@@ -4906,13 +4583,13 @@ static void send_vxlan_tunnel_details
{
memcpy (rmp->src_address, &(t->src.ip6), 16);
memcpy (rmp->dst_address, &(t->dst.ip6), 16);
- rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].table_id);
+ rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id);
}
else
{
memcpy (rmp->src_address, &(t->src.ip4), 4);
memcpy (rmp->dst_address, &(t->dst.ip4), 4);
- rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].table_id);
+ rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
}
rmp->vni = htonl (t->vni);
rmp->decap_next_index = htonl (t->decap_next_index);
@@ -5018,7 +4695,7 @@ static void send_gre_tunnel_details
rmp->_vl_msg_id = ntohs (VL_API_GRE_TUNNEL_DETAILS);
clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
- rmp->outer_fib_id = htonl (im->fibs[t->outer_fib_index].table_id);
+ rmp->outer_fib_id = htonl (im->fibs[t->outer_fib_index].ft_table_id);
rmp->teb = t->teb;
rmp->sw_if_index = htonl (t->sw_if_index);
rmp->context = context;
@@ -5178,15 +4855,15 @@ static void send_vxlan_gpe_tunnel_details
{
memcpy (rmp->local, &(t->local.ip6), 16);
memcpy (rmp->remote, &(t->remote.ip6), 16);
- rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].table_id);
- rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].table_id);
+ rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id);
+ rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].ft_table_id);
}
else
{
memcpy (rmp->local, &(t->local.ip4), 4);
memcpy (rmp->remote, &(t->remote.ip4), 4);
- rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].table_id);
- rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].table_id);
+ rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
+ rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].ft_table_id);
}
rmp->vni = htonl (t->vni);
rmp->protocol = t->protocol;
@@ -7630,7 +7307,6 @@ vl_api_mpls_fib_encap_dump_t_handler (vl_api_mpls_fib_encap_dump_t * mp)
show_mpls_fib_t *records = 0;
show_mpls_fib_t *s;
mpls_main_t *mm = &mpls_main;
- ip4_main_t *im = &ip4_main;
ip4_fib_t *rx_fib;
q = vl_api_client_index_to_input_queue (mp->client_index);
@@ -7660,7 +7336,7 @@ vl_api_mpls_fib_encap_dump_t_handler (vl_api_mpls_fib_encap_dump_t * mp)
vlib_cli_output (vm, "%=6s%=16s%=16s", "Table", "Dest address", "Labels");
vec_foreach (s, records)
{
- rx_fib = vec_elt_at_index (im->fibs, s->fib_index);
+ rx_fib = ip4_fib_get (s->fib_index);
vlib_cli_output (vm, "%=6d%=16U%=16U", rx_fib->table_id,
format_ip4_address, &s->dest, format_mpls_encap_index,
mm, s->entry_index);
@@ -7715,7 +7391,6 @@ vl_api_mpls_fib_decap_dump_t_handler (vl_api_mpls_fib_decap_dump_t * mp)
show_mpls_fib_t *records = 0;
show_mpls_fib_t *s;
mpls_main_t *mm = &mpls_main;
- ip4_main_t *im = &ip4_main;
ip4_fib_t *rx_fib;
ip4_fib_t *tx_fib;
u32 tx_table_id;
@@ -7750,9 +7425,9 @@ vl_api_mpls_fib_decap_dump_t_handler (vl_api_mpls_fib_decap_dump_t * mp)
{
mpls_decap_t *d;
d = pool_elt_at_index (mm->decaps, s->entry_index);
- if (d->next_index == MPLS_INPUT_NEXT_IP4_INPUT)
+ if (d->next_index == MPLS_LOOKUP_NEXT_IP4_INPUT)
{
- tx_fib = vec_elt_at_index (im->fibs, d->tx_fib_index);
+ tx_fib = ip4_fib_get (d->tx_fib_index);
tx_table_id = tx_fib->table_id;
swif_tag = " ";
}
@@ -7761,7 +7436,7 @@ vl_api_mpls_fib_decap_dump_t_handler (vl_api_mpls_fib_decap_dump_t * mp)
tx_table_id = d->tx_fib_index;
swif_tag = "(i) ";
}
- rx_fib = vec_elt_at_index (im->fibs, s->fib_index);
+ rx_fib = ip4_fib_get (s->fib_index);
vlib_cli_output (vm, "%=10d%=10d%=5s%=6d%=6d", rx_fib->table_id,
tx_table_id, swif_tag, s->label, s->s_bit);
@@ -8104,7 +7779,7 @@ vl_api_ipfix_exporter_dump_t_handler (vl_api_ipfix_exporter_dump_t * mp)
if (frm->fib_index == ~0)
vrf_id = ~0;
else
- vrf_id = im->fibs[frm->fib_index].table_id;
+ vrf_id = im->fibs[frm->fib_index].ft_table_id;
rmp->vrf_id = htonl (vrf_id);
rmp->path_mtu = htonl (frm->path_mtu);
rmp->template_interval = htonl (frm->template_interval);
diff --git a/vpp/vpp-api/custom_dump.c b/vpp/vpp-api/custom_dump.c
index cc37368de10..98598ce3b77 100644
--- a/vpp/vpp-api/custom_dump.c
+++ b/vpp/vpp-api/custom_dump.c
@@ -20,7 +20,7 @@
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/unix/tuntap.h>
-#include <vnet/mpls-gre/mpls.h>
+#include <vnet/mpls/mpls.h>
#include <vnet/dhcp/proxy.h>
#include <vnet/dhcpv6/proxy.h>
#include <vnet/l2tp/l2tp.h>
@@ -1416,6 +1416,9 @@ static void *vl_api_vxlan_add_del_tunnel_t_print
if (mp->is_add == 0)
s = format (s, "del ");
+ if (mp->is_add == 0)
+ s = format (s, "del ");
+
FINISH;
}
diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api
index 2434517e8cc..5c75986f0c6 100644
--- a/vpp/vpp-api/vpe.api
+++ b/vpp/vpp-api/vpe.api
@@ -215,6 +215,30 @@ define sw_interface_set_table_reply
i32 retval;
};
+/** \brief Enable or Disable MPLS on and interface
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param sw_if_index - index of the interface
+ @param enable - if non-zero enable, else disable
+*/
+define sw_interface_set_mpls_enable
+{
+ u32 client_index;
+ u32 context;
+ u32 sw_if_index;
+ u8 enable;
+};
+
+/** \brief Reply for MPLS state on an interface
+ @param context - returned sender context, to match reply w/ request
+ @param retval - return code
+*/
+define sw_interface_set_mpls_enable_reply
+{
+ u32 context;
+ i32 retval;
+};
+
/** \brief Initialize a new tap interface with the given paramters
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@@ -381,8 +405,10 @@ define ip_add_del_route
u8 is_ipv6;
u8 is_local;
u8 is_classify;
- /* Is last/not-last message in group of multiple add/del messages. */
u8 is_multipath;
+ u8 is_resolve_host;
+ u8 is_resolve_attached;
+ /* Is last/not-last message in group of multiple add/del messages. */
u8 not_last;
u8 next_hop_weight;
u8 dst_address_length;
diff --git a/vpp/vpp-api/vpp_get_metrics.c b/vpp/vpp-api/vpp_get_metrics.c
index 19771e21832..bbfa605a5e4 100644
--- a/vpp/vpp-api/vpp_get_metrics.c
+++ b/vpp/vpp-api/vpp_get_metrics.c
@@ -243,3 +243,11 @@ main (int argc, char **argv)
* eval: (c-set-style "gnu")
* End:
*/
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */