aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin/src/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin/src/route.c')
-rw-r--r--hicn-plugin/src/route.c725
1 files changed, 377 insertions, 348 deletions
diff --git a/hicn-plugin/src/route.c b/hicn-plugin/src/route.c
index 3b774cd82..fa95f7265 100644
--- a/hicn-plugin/src/route.c
+++ b/hicn-plugin/src/route.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2023 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:
@@ -33,21 +33,23 @@
#include "strategies/dpo_mw.h"
#include "infra.h"
#include "udp_tunnels/udp_tunnel.h"
+#include "mapme.h"
+#include "pg.h"
-#define FIB_SOURCE_HICN 0x04 //Right after the FIB_SOURCE_INTERFACE priority
+#define FIB_SOURCE_HICN 0x04 // Right after the FIB_SOURCE_INTERFACE priority
fib_source_t hicn_fib_src;
fib_node_type_t hicn_fib_node_type;
-ip4_address_t localhost4 = {0};
-ip6_address_t localhost6 = {0};
+ip4_address_t localhost4 = { 0 };
+ip6_address_t localhost6 = { 0 };
int
-hicn_route_get_dpo (const fib_prefix_t * prefix,
- const dpo_id_t ** hicn_dpo, u32 * fib_index)
+hicn_route_get_dpo (const fib_prefix_t *prefix, const dpo_id_t **hicn_dpo,
+ u32 *fib_index)
{
- //fib_prefix_t fib_pfx;
+ // fib_prefix_t fib_pfx;
const dpo_id_t *load_balance_dpo_id;
const dpo_id_t *former_dpo_id;
int found = 0, ret = HICN_ERROR_ROUTE_NOT_FOUND;
@@ -58,9 +60,8 @@ hicn_route_get_dpo (const fib_prefix_t * prefix,
* ASSUMPTION: we use table 0 which is the default table and it is
* already existing and locked
*/
- *fib_index = fib_table_find_or_create_and_lock (prefix->fp_proto,
- HICN_FIB_TABLE,
- hicn_fib_src);
+ *fib_index = fib_table_find_or_create_and_lock (
+ prefix->fp_proto, HICN_FIB_TABLE, hicn_fib_src);
fib_entry_index = fib_table_lookup_exact_match (*fib_index, prefix);
if (fib_entry_index != FIB_NODE_INDEX_INVALID)
@@ -103,288 +104,276 @@ hicn_route_get_dpo (const fib_prefix_t * prefix,
}
int
-hicn_route_set_strategy (fib_prefix_t * prefix, u8 strategy_id)
+hicn_route_set_strategy (fib_prefix_t *prefix, u8 strategy_id)
{
const dpo_id_t *hicn_dpo_id;
- dpo_id_t new_dpo_id = DPO_INVALID;
int ret;
- hicn_dpo_ctx_t *old_hicn_dpo_ctx;
- const hicn_dpo_vft_t *new_dpo_vft;
- index_t new_hicn_dpo_idx;
+ hicn_dpo_ctx_t *hicn_dpo_ctx;
u32 fib_index;
ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
if (ret == HICN_ERROR_NONE)
{
- old_hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index);
+ hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index);
+ const hicn_dpo_vft_t *dpo_vft = hicn_dpo_get_vft_from_id (strategy_id);
- new_dpo_vft = hicn_dpo_get_vft_from_id (strategy_id);
-
- if (new_dpo_vft == NULL || old_hicn_dpo_ctx == NULL)
+ if (hicn_dpo_ctx == NULL || dpo_vft == NULL)
return HICN_ERROR_STRATEGY_NOT_FOUND;
- /* Create a new dpo for the new strategy */
- new_dpo_vft->hicn_dpo_create (hicn_dpo_id->dpoi_proto,
- old_hicn_dpo_ctx->next_hops,
- old_hicn_dpo_ctx->entry_count,
- &new_hicn_dpo_idx);
-
- /* the value we got when we registered */
- dpo_set (&new_dpo_id,
- new_dpo_vft->hicn_dpo_get_type (),
- (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
- DPO_PROTO_IP6), new_hicn_dpo_idx);
-
- /* Here is where we create the "via" like route */
- /*
- * For the moment we use the global one the prefix you want
- * to match Neale suggested -- FIB_SOURCE_HICN the client
- * that is adding them -- no easy explanation at this time…
- */
- fib_node_index_t new_fib_node_index =
- fib_table_entry_special_dpo_update (fib_index,
- prefix,
- hicn_fib_src,
- FIB_ENTRY_FLAG_EXCLUSIVE,
- &new_dpo_id);
-
- dpo_unlock (&new_dpo_id);
- ret =
- (new_fib_node_index !=
- FIB_NODE_INDEX_INVALID) ? HICN_ERROR_NONE :
- HICN_ERROR_ROUTE_NOT_UPDATED;
+ dpo_vft->hicn_dpo_update_type (hicn_dpo_ctx);
}
- //Remember to remove the lock from the table when removing the entry
+ // Remember to remove the lock from the table when removing the entry
return ret;
-
}
-int
-ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if)
+static int
+ip_nh_add_del_helper (fib_protocol_t fib_proto, const fib_prefix_t *rpfx,
+ ip46_address_t *nh, u32 sw_if, u32 udp_encap_id,
+ dpo_proto_t proto, u8 is_add)
{
fib_route_path_t *rpaths = NULL, rpath;
- u32 fib_index = fib_table_find(fib_proto, 0);
+ u32 fib_index = fib_table_find (fib_proto, 0);
+ clib_memset (&rpath, 0, sizeof (rpath));
+
+ if (nh)
+ {
+ rpath.frp_addr = *nh;
+ rpath.frp_sw_if_index = sw_if;
+ }
+ else if (udp_encap_id != ~0)
+ {
+ rpath.frp_udp_encap_id = udp_encap_id;
+ rpath.frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
+ }
- clib_memset(&rpath, 0, sizeof(rpath));
rpath.frp_weight = 1;
- rpath.frp_sw_if_index = sw_if;
- rpath.frp_addr = *nh;
- rpath.frp_proto = ip46_address_is_ip4(nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6;
+ rpath.frp_proto = proto;
- vec_add1(rpaths, rpath);
+ vec_add1 (rpaths, rpath);
+
+ if (is_add)
+ fib_table_entry_path_add2 (fib_index, rpfx, FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE, rpaths);
+ else
+ fib_table_entry_path_remove2 (fib_index, rpfx, FIB_SOURCE_API, rpaths);
- fib_table_entry_path_add2 (fib_index,
- rpfx,
- FIB_SOURCE_CLI,
- FIB_ENTRY_FLAG_NONE, rpaths);
return 0;
}
int
-ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if)
+ip_nh_adj_add_del_helper (fib_protocol_t fib_proto, const fib_prefix_t *rpfx,
+ ip46_address_t *nh, u32 sw_if, u8 is_add)
{
- fib_route_path_t *rpaths = NULL, rpath;
-
- u32 fib_index = fib_table_find(fib_proto, 0);
-
- clib_memset(&rpath, 0, sizeof(rpath));
- rpath.frp_weight = 1;
- rpath.frp_sw_if_index = sw_if;
- rpath.frp_addr = *nh;
- rpath.frp_proto = ip46_address_is_ip4(nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6;
-
- vec_add1(rpaths, rpath);
-
- fib_table_entry_path_remove2 (fib_index,
- rpfx,
- FIB_SOURCE_CLI,
- rpaths);
- return 0;
+ return ip_nh_add_del_helper (
+ fib_proto, rpfx, nh, sw_if, ~0,
+ ip46_address_is_ip4 (nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6, is_add);
}
+int
+ip_nh_udp_tunnel_add_del_helper (fib_protocol_t fib_proto,
+ const fib_prefix_t *rpfx, u32 uei,
+ dpo_proto_t proto, u8 is_add)
+{
+ return ip_nh_add_del_helper (fib_proto, rpfx, NULL, ~0, uei, proto, is_add);
+}
-static ip46_address_t * get_address(ip46_address_t * nh, u32 sw_if, fib_protocol_t proto)
+static ip46_address_t *
+get_address (ip46_address_t *nh, u32 sw_if, fib_protocol_t proto)
{
- ip46_address_t * local_address = calloc(1, sizeof(ip46_address_t));
+ ip46_address_t *local_address = calloc (1, sizeof (ip46_address_t));
if (proto == FIB_PROTOCOL_IP4)
{
ip_interface_address_t *interface_address;
- ip4_address_t *addr =
- ip4_interface_address_matching_destination (&ip4_main,
- &nh->ip4,
- sw_if,
- &interface_address);
+ ip4_address_t *addr = ip4_interface_address_matching_destination (
+ &ip4_main, &nh->ip4, sw_if, &interface_address);
if (addr == NULL)
- addr = ip4_interface_first_address (&ip4_main,
- sw_if,
- &interface_address);
+ addr =
+ ip4_interface_first_address (&ip4_main, sw_if, &interface_address);
if (addr != NULL)
- ip46_address_set_ip4 (local_address, addr);
+ ip46_address_set_ip4 (local_address, addr);
}
else if (proto == FIB_PROTOCOL_IP6)
{
ip_interface_address_t *interface_address;
- ip6_interface_address_matching_destination (&ip6_main,
- &nh->ip6,
- sw_if,
- &interface_address);
+ ip6_interface_address_matching_destination (&ip6_main, &nh->ip6, sw_if,
+ &interface_address);
ip6_address_t *addr = NULL;
if (interface_address != NULL)
- addr =
- (ip6_address_t *)
- ip_interface_address_get_address (&ip6_main.lookup_main,
- interface_address);
+ addr = (ip6_address_t *) ip_interface_address_get_address (
+ &ip6_main.lookup_main, interface_address);
if (addr == NULL)
- addr = ip6_interface_first_address (&ip6_main, sw_if);
+ addr = ip6_interface_first_address (&ip6_main, sw_if);
if (addr != NULL)
- ip46_address_set_ip6 (local_address, addr);
+ ip46_address_set_ip6 (local_address, addr);
}
return local_address;
}
static void
-sync_hicn_fib_entry(hicn_dpo_ctx_t *fib_entry)
+sync_hicn_fib_entry (hicn_dpo_ctx_t *fib_entry, hicn_face_id_t **pvec_faces)
{
- const dpo_id_t * dpo_loadbalance = fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index);
- const load_balance_t *lb0 = load_balance_get(dpo_loadbalance->dpoi_index);
- index_t hicn_fib_entry_index = hicn_strategy_dpo_ctx_get_index(fib_entry);
- hicn_face_id_t * vec_faces = 0;
+ hicn_face_id_t *vec_faces = NULL;
+ const dpo_id_t *dpo_loadbalance =
+ fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index);
+ const fib_entry_t *_fib_entry = fib_entry_get (fib_entry->fib_entry_index);
+ const load_balance_t *lb0 = load_balance_get (dpo_loadbalance->dpoi_index);
+ index_t hicn_fib_entry_index = hicn_strategy_dpo_ctx_get_index (fib_entry);
dpo_id_t temp = DPO_INVALID;
const dpo_id_t *former_dpo = &temp;
int index = 0;
- for (int j = 0; j < lb0->lb_n_buckets; j++) {
- const dpo_id_t * dpo = load_balance_get_bucket_i(lb0,j);
-
- int dpo_comparison = dpo_cmp(former_dpo, dpo);
- former_dpo = dpo;
- /*
- * Loadbalancing in ip replicate the dpo in multiple buckets
- * in order to honor the assigned weights.
- */
- if (dpo_comparison == 0)
- continue;
-
- u32 sw_if = ~0;
- ip46_address_t * nh = NULL;
- hicn_face_id_t face_id = HICN_FACE_NULL;
-
- if (dpo_is_adj(dpo))
- {
- ip_adjacency_t * adj = adj_get (dpo->dpoi_index);
- sw_if = adj->rewrite_header.sw_if_index;
- nh = get_address (&(adj->sub_type.nbr.next_hop), sw_if, fib_entry->proto);
- }
- else if (dpo->dpoi_type == dpo_type_udp_ip4 || dpo->dpoi_type == dpo_type_udp_ip6)
- {
- u8 proto = dpo->dpoi_type == dpo_type_udp_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
- nh = calloc (1, sizeof(ip46_address_t));
- switch (dpo->dpoi_proto)
- {
- case FIB_PROTOCOL_IP6:
- nh = calloc (1, sizeof(ip46_address_t));
- ip46_address_set_ip6(nh, &localhost6);
- break;
- case FIB_PROTOCOL_IP4:
- nh = calloc (1, sizeof(ip46_address_t));
- ip46_address_set_ip4(nh, &localhost4);
- break;
- default:
- nh = calloc (1, sizeof(ip46_address_t));
- }
- udp_tunnel_add_existing (dpo->dpoi_index, proto);
- }
- else //if (dpo_is_drop(dpo))
- {
- sw_if = dpo_get_urpf(dpo);
- nh = calloc (1, sizeof(ip46_address_t));
- }
-
- /* Careful, this adds a lock on the face if it exists */
- hicn_face_add(dpo, nh, sw_if, &face_id, 0);
-
- vec_validate(vec_faces, index);
- vec_faces[index] = face_id;
- index++;
-
- /* Face creation can realloc load_balance_t? Seem the fib_tracking does so. */
- dpo_loadbalance = fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index);
- lb0 = load_balance_get(dpo_loadbalance->dpoi_index);
- }
-
- const hicn_dpo_vft_t * strategy_vft = hicn_dpo_get_vft(fib_entry->dpo_type);
+
+#define ADD_FACE(nh, dpo_proto) \
+ do \
+ { \
+ /* Careful, this adds a lock on the face if it exists */ \
+ hicn_face_add (dpo, nh, sw_if, &face_id, dpo_proto); \
+ ASSERT (face_id != HICN_FACE_NULL); \
+ vec_validate (vec_faces, index); \
+ vec_faces[index] = face_id; \
+ (index)++; \
+ \
+ /* Face creation can realloc load_balance_t? Seem the fib_tracking does \
+ * so. */ \
+ dpo_loadbalance = \
+ fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index); \
+ lb0 = load_balance_get (dpo_loadbalance->dpoi_index); \
+ } \
+ while (0)
+
+ for (int j = 0; j < lb0->lb_n_buckets; j++)
+ {
+ const dpo_id_t *dpo = load_balance_get_bucket_i (lb0, j);
+
+ int dpo_comparison = dpo_cmp (former_dpo, dpo);
+ former_dpo = dpo;
+ /*
+ * Loadbalancing in ip replicate the dpo in multiple buckets
+ * in order to honor the assigned weights.
+ */
+ if (dpo_comparison == 0)
+ continue;
+
+ u32 sw_if = ~0;
+ ip46_address_t *nh = NULL;
+ hicn_face_id_t face_id = HICN_FACE_NULL;
+
+ if (dpo_is_adj (dpo))
+ {
+ ip_adjacency_t *adj = adj_get (dpo->dpoi_index);
+ sw_if = adj->rewrite_header.sw_if_index;
+ nh = get_address (&(adj->sub_type.nbr.next_hop), sw_if,
+ fib_entry->proto);
+ ADD_FACE (nh, dpo->dpoi_proto);
+ HICN_DEBUG ("Added new HICN face: %d because of route prefix %U",
+ face_id, format_fib_prefix, &_fib_entry->fe_prefix);
+ }
+ else if (dpo_is_udp_encap (dpo))
+ {
+ dpo_proto_t proto = dpo_udp_encap_get_proto (dpo);
+ ip46_address_t _nh = { 0 };
+ nh = &_nh;
+ switch (_fib_entry->fe_prefix.fp_proto)
+ {
+ case FIB_PROTOCOL_IP6:
+ ip46_address_set_ip6 (nh, &localhost6);
+ ADD_FACE (nh, DPO_PROTO_IP6);
+ break;
+ case FIB_PROTOCOL_IP4:
+ ip46_address_set_ip4 (nh, &localhost4);
+ ADD_FACE (nh, DPO_PROTO_IP4);
+ break;
+ default:
+ continue;
+ }
+ HICN_DEBUG ("Added new UDP face: %d because of route prefix %U",
+ face_id, format_fib_prefix, &_fib_entry->fe_prefix);
+ udp_tunnel_add_existing (dpo->dpoi_index, proto);
+ udp_tunnel_set_face (face_id, proto == DPO_PROTO_IP4);
+ }
+ else if (dpo_is_pgserver (dpo))
+ {
+ hicnpg_server_t *pg_server = hicnpg_server_get (dpo->dpoi_index);
+ ADD_FACE (&pg_server->hicn_locator, dpo->dpoi_proto);
+ }
+ }
+
+ const hicn_dpo_vft_t *strategy_vft = hicn_dpo_get_vft (fib_entry->dpo_type);
int i = 0;
while (i < fib_entry->entry_count)
{
- u32 idx_nh = vec_search(vec_faces, fib_entry->next_hops[i]);
+ u32 idx_nh = vec_search (vec_faces, fib_entry->next_hops[i]);
if (idx_nh == ~0)
- {
- strategy_vft->hicn_dpo_del_nh(fib_entry->next_hops[i], hicn_fib_entry_index);
- }
+ {
+ strategy_vft->hicn_dpo_del_nh (fib_entry->next_hops[i],
+ hicn_fib_entry_index);
+ }
else
- {
- vec_del1(vec_faces, idx_nh);
+ {
+ vec_del1 (vec_faces, idx_nh);
- /* Remove the lock added by hicn_face_add */
- hicn_face_unlock_with_id (fib_entry->next_hops[i]);
- i++;
- }
+ /* Remove the lock added by hicn_face_add */
+ hicn_face_unlock_with_id (fib_entry->next_hops[i]);
+ i++;
+ }
}
hicn_face_id_t *face_id;
- vec_foreach(face_id, vec_faces)
+ vec_foreach (face_id, vec_faces)
{
- strategy_vft->hicn_dpo_add_update_nh(*face_id, hicn_fib_entry_index);
+ strategy_vft->hicn_dpo_add_update_nh (*face_id, hicn_fib_entry_index);
/* Remove the lock added by hicn_face_add */
hicn_face_unlock_with_id (*face_id);
-
}
- vec_free(vec_faces);
+
+ *pvec_faces = vec_faces;
}
static void
enable_disable_data_receiving (fib_protocol_t proto, u32 sw_if, u8 is_enable)
{
if (proto == FIB_PROTOCOL_IP4 && sw_if != ~0)
- vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
- sw_if, is_enable, 0, 0);
+ vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4", sw_if,
+ is_enable, 0, 0);
else if (proto == FIB_PROTOCOL_IP6 && sw_if != ~0)
- vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
- sw_if, is_enable, 0, 0);
-
+ vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6", sw_if,
+ is_enable, 0, 0);
}
-walk_rc_t enable_data_receiving_new_fib_entry (vnet_main_t * vnm,
- vnet_sw_interface_t * si,
- void *ctx)
+walk_rc_t
+enable_data_receiving_new_fib_entry (vnet_main_t *vnm, vnet_sw_interface_t *si,
+ void *ctx)
{
fib_protocol_t *proto = (fib_protocol_t *) ctx;
- enable_disable_data_receiving(*proto, si->sw_if_index, 1);
+ enable_disable_data_receiving (*proto, si->sw_if_index, 1);
return (WALK_CONTINUE);
}
-walk_rc_t disable_data_receiving_rm_fib_entry (vnet_main_t * vnm,
- vnet_sw_interface_t * si,
- void *ctx)
+walk_rc_t
+disable_data_receiving_rm_fib_entry (vnet_main_t *vnm, vnet_sw_interface_t *si,
+ void *ctx)
{
fib_protocol_t *proto = (fib_protocol_t *) ctx;
- enable_disable_data_receiving(*proto, si->sw_if_index, 0);
+ enable_disable_data_receiving (*proto, si->sw_if_index, 0);
return (WALK_CONTINUE);
- }
+}
int
-hicn_route_enable (fib_prefix_t *prefix) {
+hicn_route_enable (const fib_prefix_t *prefix,
+ fib_node_index_t *hicn_fib_node_index,
+ hicn_face_id_t **pvec_faces)
+{
int ret = HICN_ERROR_NONE;
fib_node_index_t fib_entry_index;
@@ -394,7 +383,7 @@ hicn_route_enable (fib_prefix_t *prefix) {
* ASSUMPTION: we use table 0 which is the default table and it is
* already existing and locked
*/
- u32 fib_index = fib_table_find(prefix->fp_proto, 0);
+ u32 fib_index = fib_table_find (prefix->fp_proto, 0);
fib_entry_index = fib_table_lookup_exact_match (fib_index, prefix);
@@ -402,43 +391,51 @@ hicn_route_enable (fib_prefix_t *prefix) {
{
fib_entry_index = fib_table_lookup (fib_index, prefix);
- fib_route_path_t * paths = fib_entry_encode(fib_entry_index);
+ fib_route_path_t *paths = fib_entry_encode (fib_entry_index);
- fib_table_entry_path_add2(fib_index, prefix, FIB_SOURCE_CLI, FIB_ENTRY_FLAG_NONE, paths);
+ fib_table_entry_path_add2 (fib_index, prefix, FIB_SOURCE_CLI,
+ FIB_ENTRY_FLAG_NONE, paths);
}
/* Check if the prefix is already enabled */
- u32 fib_hicn_index = fib_table_find(prefix->fp_proto, HICN_FIB_TABLE);
+ u32 fib_hicn_index = fib_table_find (prefix->fp_proto, HICN_FIB_TABLE);
- fib_node_index_t fib_hicn_entry_index = fib_table_lookup_exact_match (fib_hicn_index, prefix);
+ *hicn_fib_node_index = fib_table_lookup_exact_match (fib_hicn_index, prefix);
- if (fib_hicn_entry_index == FIB_NODE_INDEX_INVALID)
+ if (*hicn_fib_node_index == FIB_NODE_INDEX_INVALID)
{
+ HICN_DEBUG (
+ "No route found for %U. Creating DPO and tracking fib prefix.",
+ format_fib_prefix, prefix);
dpo_id_t dpo = DPO_INVALID;
- index_t dpo_idx;
- default_dpo.hicn_dpo_create (prefix->fp_proto, 0, NEXT_HOP_INVALID,
- &dpo_idx);
+ index_t dpo_idx = ~0;
+ default_dpo.hicn_dpo_create (prefix->fp_proto, 0, 0, &dpo_idx);
+ HICN_DEBUG ("Created new DPO_MW_CTX_T: %d.", dpo_idx);
/* the value we got when we registered */
/*
* This should be taken from the name?!? the index of the
* object
*/
- dpo_set (&dpo,
- default_dpo.hicn_dpo_get_type (),
- (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
- DPO_PROTO_IP6), dpo_idx);
+ dpo_set (&dpo, default_dpo.hicn_dpo_get_type (),
+ (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
+ DPO_PROTO_IP6),
+ dpo_idx);
+ HICN_DEBUG (
+ "dpo_set called with parameters: type=%d, proto=%s, index=%d",
+ default_dpo.hicn_dpo_get_type (),
+ ip46_address_is_ip4 (&prefix->fp_addr) ? "DPO_PROTO_IP4" :
+ "DPO_PROTO_IP6",
+ dpo_idx);
- hicn_dpo_ctx_t * fib_entry = hicn_strategy_dpo_ctx_get(dpo_idx);
+ hicn_dpo_ctx_t *fib_entry = hicn_strategy_dpo_ctx_get (dpo_idx);
fib_node_init (&fib_entry->fib_node, hicn_fib_node_type);
fib_node_lock (&fib_entry->fib_node);
- fib_entry->fib_entry_index = fib_entry_track (fib_index,
- prefix,
- hicn_fib_node_type,
- dpo_idx, &fib_entry->fib_sibling);
-
+ fib_entry->fib_entry_index =
+ fib_entry_track (fib_index, prefix, hicn_fib_node_type, dpo_idx,
+ &fib_entry->fib_sibling);
/* Here is where we create the "via" like route */
/*
@@ -446,94 +443,104 @@ hicn_route_enable (fib_prefix_t *prefix) {
* to match Neale suggested -- FIB_SOURCE_HICN the client
* that is adding them -- no easy explanation at this time…
*/
- CLIB_UNUSED (fib_node_index_t new_fib_node_index) =
- fib_table_entry_special_dpo_add (fib_hicn_index,
- prefix,
- hicn_fib_src,
- (FIB_ENTRY_FLAG_EXCLUSIVE |
- FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
- &dpo);
+ *hicn_fib_node_index = fib_table_entry_special_dpo_add (
+ fib_hicn_index, prefix, hicn_fib_src,
+ (FIB_ENTRY_FLAG_EXCLUSIVE | FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT), &dpo);
- sync_hicn_fib_entry(fib_entry);
+ HICN_DEBUG ("Calling sync_hicn_fib_entry");
+ sync_hicn_fib_entry (fib_entry, pvec_faces);
/* We added a route, therefore add one lock to the table */
fib_table_lock (fib_index, prefix->fp_proto, hicn_fib_src);
- /* Enable the feature to punt data packet every time we enable a new hicn route
- * For each enable there must be a disable to defenitely disable the feature
+ /* Enable the feature to punt data packet every time we enable a new hicn
+ * route For each enable there must be a disable to defenitely disable
+ * the feature
*
- * We cannot enable only the interfaces on which we send out interest because
- * Data packet might be coming on in different interfaces, as in che case of mpls
- * tunnels (packets are received from the physical nic, not the mpls tunnel interface).
+ * We cannot enable only the interfaces on which we send out interest
+ * because Data packet might be coming on in different interfaces, as in
+ * che case of mpls tunnels (packets are received from the physical nic,
+ * not the mpls tunnel interface).
*/
- vnet_main_t * vnm = vnet_get_main ();
- vnet_sw_interface_walk(vnm, enable_data_receiving_new_fib_entry, &(prefix->fp_proto));
+ vnet_main_t *vnm = vnet_get_main ();
+ vnet_sw_interface_walk (vnm, enable_data_receiving_new_fib_entry,
+ (void *) (&prefix->fp_proto));
dpo_unlock (&dpo);
}
else
{
+ HICN_DEBUG ("Found a route for %U. Updating DPO.", format_fib_prefix,
+ prefix);
const dpo_id_t *load_balance_dpo_id;
const dpo_id_t *strategy_dpo_id;
/* Route already existing. We need to update the dpo. */
load_balance_dpo_id =
- fib_entry_contribute_ip_forwarding (fib_hicn_entry_index);
+ fib_entry_contribute_ip_forwarding (*hicn_fib_node_index);
/* The dpo is not a load balance dpo as expected */
if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
- {
- ret = HICN_ERROR_ROUTE_NO_LD;
- goto done;
- }
+ {
+ ret = HICN_ERROR_ROUTE_NO_LD;
+ HICN_ERROR ("DPO is not a load balance.");
+ goto done;
+ }
else
{
load_balance_t *lb =
load_balance_get (load_balance_dpo_id->dpoi_index);
- strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
+ strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
- if (!dpo_is_hicn (strategy_dpo_id))
- {
- ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
- goto done;
- }
+ if (!dpo_is_hicn (strategy_dpo_id))
+ {
+ ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
+ HICN_ERROR ("DPO is not hicn.");
+ goto done;
+ }
- if (lb->lb_n_buckets > 1)
- {
- ret = HICN_ERROR_ROUTE_MLT_LD;
- goto done;
- }
+ if (lb->lb_n_buckets > 1)
+ {
+ ret = HICN_ERROR_ROUTE_MLT_LD;
+ HICN_ERROR ("Too many load balance buckets.");
+ goto done;
+ }
- hicn_dpo_ctx_t * hicn_fib_entry = hicn_strategy_dpo_ctx_get(strategy_dpo_id->dpoi_index);
+ hicn_dpo_ctx_t *hicn_fib_entry =
+ hicn_strategy_dpo_ctx_get (strategy_dpo_id->dpoi_index);
- sync_hicn_fib_entry(hicn_fib_entry);
- }
+ HICN_DEBUG ("Calling sync_hicn_fib_entry");
+ sync_hicn_fib_entry (hicn_fib_entry, pvec_faces);
+ }
}
- done:
+done:
return ret;
}
int
-hicn_route_disable (fib_prefix_t *prefix) {
+hicn_route_disable (fib_prefix_t *prefix)
+{
int ret = HICN_ERROR_NONE;
/* Check if the prefix is already enabled */
- u32 fib_hicn_index = fib_table_find(prefix->fp_proto, HICN_FIB_TABLE);
+ u32 fib_hicn_index = fib_table_find (prefix->fp_proto, HICN_FIB_TABLE);
- fib_node_index_t fib_hicn_entry_index = fib_table_lookup_exact_match (fib_hicn_index, prefix);
+ fib_node_index_t fib_hicn_entry_index =
+ fib_table_lookup_exact_match (fib_hicn_index, prefix);
if (fib_hicn_entry_index == FIB_NODE_INDEX_INVALID)
{
- return HICN_ERROR_ROUTE_NOT_FOUND;
+ HICN_ERROR ("Route %U not found", format_fib_prefix, prefix);
+ ret = HICN_ERROR_ROUTE_NOT_FOUND;
}
else
{
const dpo_id_t *load_balance_dpo_id;
const dpo_id_t *strategy_dpo_id;
- hicn_dpo_ctx_t * hicn_fib_entry;
+ hicn_dpo_ctx_t *hicn_fib_entry;
/* Route already existing. We need to update the dpo. */
load_balance_dpo_id =
@@ -541,57 +548,87 @@ hicn_route_disable (fib_prefix_t *prefix) {
/* The dpo is not a load balance dpo as expected */
if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
- {
- ret = HICN_ERROR_ROUTE_NO_LD;
- goto done;
- }
+ {
+ HICN_ERROR ("DPO for route %U is not a load balance.",
+ format_ip_prefix, prefix);
+ ret = HICN_ERROR_ROUTE_NO_LD;
+ goto done;
+ }
else
{
load_balance_t *lb =
load_balance_get (load_balance_dpo_id->dpoi_index);
- strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
+ strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
+
+ if (!dpo_is_hicn (strategy_dpo_id))
+ {
+ HICN_ERROR ("ERROR: DPO for route %U is not a hicn.",
+ format_ip_prefix, prefix);
+ ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
+ goto done;
+ }
+
+ if (lb->lb_n_buckets > 1)
+ {
+ HICN_ERROR ("DPO for route %U contains multiple next hops.",
+ format_ip_prefix, prefix);
+ ret = HICN_ERROR_ROUTE_MLT_LD;
+ goto done;
+ }
- if (!dpo_is_hicn (strategy_dpo_id))
- {
- ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
- goto done;
- }
+ hicn_fib_entry =
+ hicn_strategy_dpo_ctx_get (strategy_dpo_id->dpoi_index);
- if (lb->lb_n_buckets > 1)
- {
- ret = HICN_ERROR_ROUTE_MLT_LD;
- goto done;
- }
+ HICN_DEBUG ("Found from hicn_strategy_dpo_ctx_get with index %d: %p",
+ strategy_dpo_id->dpoi_index, hicn_fib_entry);
- hicn_fib_entry = hicn_strategy_dpo_ctx_get(strategy_dpo_id->dpoi_index);
+ if (PREDICT_FALSE (!hicn_fib_entry))
+ {
+ HICN_ERROR (
+ "hicn_strategy_dpo_ctx_get for index %d returned NULL",
+ strategy_dpo_id->dpoi_index);
+ ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
+ goto done;
+ }
- for (int i = 0; i < hicn_fib_entry->entry_count; i++)
- {
- hicn_strategy_dpo_ctx_del_nh(hicn_fib_entry->next_hops[i], hicn_fib_entry);
- }
- }
+ for (int i = 0; i < hicn_fib_entry->entry_count; i++)
+ {
+ hicn_strategy_dpo_ctx_del_nh (hicn_fib_entry->next_hops[i],
+ hicn_fib_entry);
+ }
- fib_entry_untrack(hicn_fib_entry->fib_entry_index, hicn_fib_entry->fib_sibling);
+ hicn_mapme_tfib_clear ((hicn_mapme_tfib_t *) hicn_fib_entry);
+ }
+
+ HICN_DEBUG (
+ "Calling fib_entry_untrack and fib_table_entry_special_remove "
+ "for route %U.",
+ format_fib_prefix, prefix);
+
+ fib_entry_untrack (hicn_fib_entry->fib_entry_index,
+ hicn_fib_entry->fib_sibling);
fib_table_entry_special_remove (fib_hicn_index, prefix, hicn_fib_src);
+ fib_node_unlock (&hicn_fib_entry->fib_node);
- /* Disable the feature to punt data packet every time we enable a new hicn route */
- vnet_main_t * vnm = vnet_get_main ();
- vnet_sw_interface_walk(vnm, disable_data_receiving_rm_fib_entry, &(prefix->fp_proto));
+ /* Disable the feature to punt data packet every time we enable a new
+ * hicn route */
+ vnet_main_t *vnm = vnet_get_main ();
+ vnet_sw_interface_walk (vnm, disable_data_receiving_rm_fib_entry,
+ &(prefix->fp_proto));
}
- done:
+done:
return ret;
}
-
static fib_node_t *
hicn_ctx_node_get (fib_node_index_t index)
{
- hicn_dpo_ctx_t * hicn_ctx;
+ hicn_dpo_ctx_t *hicn_ctx;
- hicn_ctx = hicn_strategy_dpo_ctx_get(index);
+ hicn_ctx = hicn_strategy_dpo_ctx_get (index);
return (&hicn_ctx->fib_node);
}
@@ -602,20 +639,23 @@ hicn_fib_last_lock_gone (fib_node_t *node)
}
static hicn_dpo_ctx_t *
-hicn_ctx_from_fib_node (fib_node_t * node)
+hicn_ctx_from_fib_node (fib_node_t *node)
{
return ((hicn_dpo_ctx_t *) (((char *) node) -
- STRUCT_OFFSET_OF (hicn_dpo_ctx_t, fib_node)));
+ STRUCT_OFFSET_OF (hicn_dpo_ctx_t, fib_node)));
}
static fib_node_back_walk_rc_t
-hicn_fib_back_walk_notify (fib_node_t *node,
- fib_node_back_walk_ctx_t *ctx)
+hicn_fib_back_walk_notify (fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
{
hicn_dpo_ctx_t *fib_entry = hicn_ctx_from_fib_node (node);
- sync_hicn_fib_entry(fib_entry);
+ hicn_face_id_t *vec_faces = NULL;
+ HICN_DEBUG ("Calling sync_hicn_fib_entry from hicn_fib_back_walk_notify");
+ sync_hicn_fib_entry (fib_entry, &vec_faces);
+ if (vec_faces != NULL)
+ vec_free (vec_faces);
return (FIB_NODE_BACK_WALK_CONTINUE);
}
@@ -625,25 +665,22 @@ hicn_fib_show_memory (void)
{
}
-
-static const fib_node_vft_t hicn_fib_vft =
-{
- .fnv_get = hicn_ctx_node_get,
- .fnv_last_lock = hicn_fib_last_lock_gone,
- .fnv_back_walk = hicn_fib_back_walk_notify,
- .fnv_mem_show = hicn_fib_show_memory,
+static const fib_node_vft_t hicn_fib_vft = {
+ .fnv_get = hicn_ctx_node_get,
+ .fnv_last_lock = hicn_fib_last_lock_gone,
+ .fnv_back_walk = hicn_fib_back_walk_notify,
+ .fnv_mem_show = hicn_fib_show_memory,
};
-fib_table_walk_rc_t enable_data_on_existing_hicn(fib_node_index_t fei,
- void *ctx)
+fib_table_walk_rc_t
+enable_data_on_existing_hicn (fib_node_index_t fei, void *ctx)
{
- u32 sw_if = *(u32 *)ctx;
+ u32 sw_if = *(u32 *) ctx;
const dpo_id_t *load_balance_dpo_id;
const dpo_id_t *strategy_dpo_id;
/* Route already existing. We need to update the dpo. */
- load_balance_dpo_id =
- fib_entry_contribute_ip_forwarding (fei);
+ load_balance_dpo_id = fib_entry_contribute_ip_forwarding (fei);
/* The dpo is not a load balance dpo as expected */
if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
@@ -652,99 +689,89 @@ fib_table_walk_rc_t enable_data_on_existing_hicn(fib_node_index_t fei,
}
else
{
- load_balance_t *lb =
- load_balance_get (load_balance_dpo_id->dpoi_index);
+ load_balance_t *lb = load_balance_get (load_balance_dpo_id->dpoi_index);
strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
if (!dpo_is_hicn (strategy_dpo_id))
- {
- goto done;
- }
+ {
+ goto done;
+ }
- enable_disable_data_receiving (strategy_dpo_id->dpoi_proto, sw_if, 1);
+ enable_disable_data_receiving (
+ (fib_protocol_t) strategy_dpo_id->dpoi_proto, sw_if, 1);
}
- done:
+done:
return (FIB_TABLE_WALK_CONTINUE);
}
static clib_error_t *
-set_table_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
+set_table_interface_add_del (vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
{
if (!is_add)
- return HICN_ERROR_NONE;
-
- vnet_sw_interface_t * sw_int = vnet_get_sw_interface(vnm, sw_if_index);
- vnet_hw_interface_t * hw_int = vnet_get_hw_interface(vnm, sw_int->hw_if_index);
-
- char * mpls = "mpls";
- if (strstr((char *)hw_int->name, mpls) == NULL)
- return 0;
+ return NULL;
- int rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, HICN_FIB_TABLE, 1);
+ int rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, HICN_FIB_TABLE);
if (!rv)
{
- rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, HICN_FIB_TABLE, 1);
+ rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, HICN_FIB_TABLE);
if (rv)
- {
- /* An error occurred. Bind the interface back to the default fib */
- ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, 0, 1);
- }
+ {
+ /* An error occurred. Bind the interface back to the default fib */
+ ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, 0);
+ }
}
- u32 fib_index = fib_table_find(FIB_PROTOCOL_IP4,
- HICN_FIB_TABLE);
+ u32 fib_index = fib_table_find (FIB_PROTOCOL_IP4, HICN_FIB_TABLE);
if (fib_index != ~0)
{
/*
* Walk the ip4 and ip6 fib tables to discover existing hicn fib entries.
* For each of them we need to enable the feature to punt data packets.
*/
- fib_table_walk(fib_index,
- FIB_PROTOCOL_IP4,
- enable_data_on_existing_hicn,
- &sw_if_index);
+ fib_table_walk (fib_index, FIB_PROTOCOL_IP4,
+ enable_data_on_existing_hicn, &sw_if_index);
}
- fib_index = fib_table_find(FIB_PROTOCOL_IP6,
- HICN_FIB_TABLE);
+ fib_index = fib_table_find (FIB_PROTOCOL_IP6, HICN_FIB_TABLE);
if (fib_index != ~0)
{
- fib_table_walk(fib_index,
- FIB_PROTOCOL_IP6,
- enable_data_on_existing_hicn,
- &sw_if_index);
+ fib_table_walk (fib_index, FIB_PROTOCOL_IP6,
+ enable_data_on_existing_hicn, &sw_if_index);
}
- return rv ? clib_error_return (0, "unable to add hicn table to interface") : 0;
+ return rv ? clib_error_return (0, "unable to add hicn table to interface") :
+ 0;
}
-VNET_SW_INTERFACE_ADD_DEL_FUNCTION (set_table_interface_add_del);
+VNET_SW_INTERFACE_ADD_DEL_FUNCTION_PRIO (set_table_interface_add_del,
+ VNET_ITF_FUNC_PRIORITY_HIGH);
void
hicn_route_init ()
{
- vnet_main_t * vnm = vnet_get_main ();
- vlib_main_t * vm = vlib_get_main ();
- hicn_fib_src = fib_source_allocate ("hicn",
- FIB_SOURCE_HICN, FIB_SOURCE_BH_API);
+ vnet_main_t *vnm = vnet_get_main ();
+ vlib_main_t *vm = vlib_get_main ();
+ hicn_fib_src =
+ fib_source_allocate ("hicn", FIB_SOURCE_HICN, FIB_SOURCE_BH_API);
- hicn_fib_node_type = fib_node_register_new_type(&hicn_fib_vft);
+ hicn_fib_node_type =
+ fib_node_register_new_type ("hicn_route_fib_node", &hicn_fib_vft);
- ip_table_create(FIB_PROTOCOL_IP4, HICN_FIB_TABLE, 1, (const u8 *)"hicn4");
- ip_table_create(FIB_PROTOCOL_IP6, HICN_FIB_TABLE, 1, (const u8 *)"hicn6");
+ ip_table_create (FIB_PROTOCOL_IP4, HICN_FIB_TABLE, 1, (const u8 *) "hicn4");
+ ip_table_create (FIB_PROTOCOL_IP6, HICN_FIB_TABLE, 1, (const u8 *) "hicn6");
u32 sw_if_index;
u8 mac_address[6];
u8 is_specified = 0;
u32 user_instance = 0;
- vnet_create_loopback_interface (&sw_if_index, mac_address,
- is_specified, user_instance);
+ vnet_create_loopback_interface (&sw_if_index, mac_address, is_specified,
+ user_instance);
localhost4.as_u8[0] = 127;
localhost4.as_u8[3] = 1;
@@ -752,8 +779,10 @@ hicn_route_init ()
localhost6.as_u8[15] = 1;
- ip4_add_del_interface_address (vm, sw_if_index, &localhost4, length4, is_del);
- ip6_add_del_interface_address (vm, sw_if_index, &localhost6, length6, is_del);
+ ip4_add_del_interface_address (vm, sw_if_index, &localhost4, length4,
+ is_del);
+ ip6_add_del_interface_address (vm, sw_if_index, &localhost6, length6,
+ is_del);
flags |= VNET_SW_INTERFACE_FLAG_ADMIN_UP;
vnet_sw_interface_set_flags (vnm, sw_if_index, flags);