aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin/src/mapme.h
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin/src/mapme.h')
-rw-r--r--hicn-plugin/src/mapme.h162
1 files changed, 90 insertions, 72 deletions
diff --git a/hicn-plugin/src/mapme.h b/hicn-plugin/src/mapme.h
index 63bd42610..c5567d1d4 100644
--- a/hicn-plugin/src/mapme.h
+++ b/hicn-plugin/src/mapme.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020 Cisco and/or its affiliates.
+ * Copyright (c) 2021 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:
@@ -21,9 +21,9 @@
#include <hicn/mapme.h>
#include "hicn.h"
-#include "route.h"
#include "strategy_dpo_ctx.h"
#include "strategy_dpo_manager.h" // dpo_is_hicn
+#include "udp_tunnels/udp_tunnel.h"
/**
* @file
@@ -61,11 +61,13 @@ typedef struct hicn_mapme_conf_s
{
hicn_mapme_conf_t conf;
bool remove_dpo; // FIXME used ?
+ fib_prefix_t default_route;
vlib_main_t *vm;
- vlib_log_class_t log_class;
} hicn_mapme_main_t;
+extern hicn_mapme_main_t *hicn_mapme_get_main ();
+
/**
* @brief List of event to signat to the procesing node (eventmgr)
*/
@@ -88,6 +90,21 @@ typedef enum
typedef hicn_dpo_ctx_t hicn_mapme_tfib_t;
+/**
+ * FIB Lookup Type
+ */
+#define foreach_hicn_mapme_fib_lookup_type \
+ _ (EPM) \
+ _ (LPM) \
+ _ (LESSPM)
+
+typedef enum
+{
+#define _(a) HICN_MAPME_FIB_LOOKUP_TYPE_##a,
+ foreach_hicn_mapme_fib_lookup_type
+#undef _
+} hicn_mapme_fib_lookup_type_t;
+
/*
* Ideally we might need to care about alignment, but this struct is only
* used for casting hicn_dpo_ctx_t.
@@ -100,65 +117,43 @@ STATIC_ASSERT (sizeof (hicn_mapme_tfib_t) <= sizeof (hicn_dpo_ctx_t),
#define TFIB(dpo_ctx) ((hicn_mapme_tfib_t *) (dpo_ctx))
-static_always_inline int
-hicn_mapme_nh_set (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id)
-{
- hicn_dpo_ctx_t *strategy_ctx = (hicn_dpo_ctx_t *) tfib;
- const fib_prefix_t *prefix =
- fib_entry_get_prefix (strategy_ctx->fib_entry_index);
-
- u32 n_entries = tfib->entry_count;
- /* Remove all the existing next hops and set the new one */
- for (int i = 0; i < n_entries; i++)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (strategy_ctx->next_hops[0]);
- ip_adjacency_t *adj = adj_get (face->dpo.dpoi_index);
- ip_nh_del_helper (face->dpo.dpoi_proto, prefix,
- &adj->sub_type.nbr.next_hop, face->sw_if);
- }
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- ip_nh_add_helper (face->dpo.dpoi_proto, prefix, &face->nat_addr,
- face->sw_if);
- return 0;
-}
-
/**
- * @brief Add a next hop iif it is not already a next hops
+ * @brief Check whether a face is already included in the TFIB.
+ *
+ * NOTE: linear scan on a contiguous small array should be the most efficient.
*/
static_always_inline int
-hicn_mapme_nh_add (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id)
+hicn_mapme_tfib_has (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id)
{
- for (u8 pos = 0; pos < tfib->entry_count; pos++)
- if (tfib->next_hops[pos] == face_id)
- return 0;
-
- /* Add the next hop in the vrf 0 which will add it to the entry in the hICN
- * vrf */
- hicn_dpo_ctx_t *strategy_ctx = (hicn_dpo_ctx_t *) tfib;
- const fib_prefix_t *prefix =
- fib_entry_get_prefix (strategy_ctx->fib_entry_index);
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- ip_nh_add_helper (face->dpo.dpoi_proto, prefix, &face->nat_addr,
- face->sw_if);
-
+ u8 pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count;
+ for (u8 pos2 = pos; pos2 < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos2++)
+ if (tfib->next_hops[pos2] == face_id)
+ return 1;
return 0;
}
/**
* Add a 'previous' hop to the TFIB
- *
- * XXX we should have the for look in the reverse order for simpler code.
*/
static_always_inline int
hicn_mapme_tfib_add (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id)
{
- u8 pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count;
+ // Don't add if it already exists
+ // (eg. an old IU received on a face on which we are retransmitting)
+ if (hicn_mapme_tfib_has (tfib, face_id))
+ {
+ HICN_DEBUG ("Found face %d in tfib.");
+ return 0;
+ }
- // XXX don 't add if it already exist
- // eg.an old IU received on a face on which we are retransmitting
- for (u8 pos2 = pos; pos2 < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos2++)
- if (tfib->next_hops[pos2] == face_id)
+ // If local face, do not put in in tfib
+ if (hicn_face_is_local (face_id))
+ {
+ HICN_DEBUG ("Do not add local face %d to TFIB.", face_id);
return 0;
+ }
+
+ u8 pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count;
// Make sure we have enough room
if (pos <= tfib->entry_count)
@@ -190,7 +185,6 @@ hicn_mapme_tfib_clear (hicn_mapme_tfib_t *tfib)
{
hicn_face_unlock_with_id (tfib->next_hops[pos]);
tfib->next_hops[pos] = invalid;
- break;
}
tfib->tfib_entry_count = 0;
@@ -208,9 +202,12 @@ hicn_mapme_tfib_del (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id)
*/
u8 start_pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count;
u8 pos = ~0;
+
for (pos = start_pos; pos < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos++)
if (tfib->next_hops[pos] == face_id)
{
+ HICN_DEBUG ("Deleted the face_id=%d from TFIB as we received an ack.",
+ face_id);
hicn_face_unlock_with_id (tfib->next_hops[pos]);
tfib->next_hops[pos] = invalid;
break;
@@ -230,30 +227,15 @@ hicn_mapme_tfib_del (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id)
}
/**
- * @brief Performs an Exact Prefix Match lookup on the FIB
+ * @brief Retrive DPO from fib entry
* @returns the corresponding DPO (hICN or IP LB), or NULL
*/
static_always_inline dpo_id_t *
-fib_epm_lookup (ip46_address_t *addr, u8 plen)
+dpo_from_fib_node_index (fib_node_index_t fib_entry_index)
{
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- u32 fib_index;
- dpo_id_t *dpo_id;
- load_balance_t *lb;
-
- const dpo_id_t *load_balance_dpo_id;
-
- /* At this point the face exists in the face table */
- fib_prefix_from_ip46_addr (addr, &fib_pfx);
- fib_pfx.fp_len = plen;
-
- /* Check if the route already exist in the fib : EPM */
- fib_index = fib_table_find (fib_pfx.fp_proto, HICN_FIB_TABLE);
-
- fib_entry_index = fib_table_lookup_exact_match (fib_index, &fib_pfx);
- if (fib_entry_index == FIB_NODE_INDEX_INVALID)
- return NULL;
+ const dpo_id_t *load_balance_dpo_id = NULL;
+ load_balance_t *lb = NULL;
+ dpo_id_t *dpo_id = NULL;
load_balance_dpo_id = fib_entry_contribute_ip_forwarding (fib_entry_index);
@@ -285,6 +267,46 @@ fib_epm_lookup (ip46_address_t *addr, u8 plen)
return (dpo_id_t *) load_balance_dpo_id;
}
+/**
+ * @brief Performs an Exact Prefix Match lookup on the FIB
+ * @returns the corresponding DPO (hICN or IP LB), or NULL
+ */
+static_always_inline dpo_id_t *
+fib_lookup (ip46_address_t *addr, u8 plen,
+ hicn_mapme_fib_lookup_type_t lookup_type)
+{
+ fib_prefix_t fib_pfx;
+ fib_node_index_t fib_entry_index;
+ u32 fib_index;
+
+ /* At this point the face exists in the face table */
+ fib_prefix_from_ip46_addr (addr, &fib_pfx);
+ fib_pfx.fp_len = plen;
+
+ /* Check if the route already exist in the fib : EPM */
+ fib_index = fib_table_find (fib_pfx.fp_proto, HICN_FIB_TABLE);
+
+ switch (lookup_type)
+ {
+ case HICN_MAPME_FIB_LOOKUP_TYPE_EPM:
+ fib_entry_index = fib_table_lookup_exact_match (fib_index, &fib_pfx);
+ break;
+ case HICN_MAPME_FIB_LOOKUP_TYPE_LPM:
+ fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
+ break;
+ case HICN_MAPME_FIB_LOOKUP_TYPE_LESSPM:
+ fib_entry_index = fib_table_get_less_specific (fib_index, &fib_pfx);
+ break;
+ default:
+ return NULL;
+ }
+
+ if (fib_entry_index == FIB_NODE_INDEX_INVALID)
+ return NULL;
+
+ return dpo_from_fib_node_index (fib_entry_index);
+}
+
/* DPO types */
extern dpo_type_t hicn_face_udp_type;
@@ -358,10 +380,6 @@ hicn_mapme_get_dpo_face_node (hicn_face_id_t face_id)
}
}
-#define DEBUG(...) // vlib_log_debug(mapme_main.log_class, __VA_ARGS__)
-#define WARN(...) // vlib_log_warn(mapme_main.log_class, __VA_ARGS__)
-#define ERROR(...) // vlib_log_err(mapme_main.log_class, __VA_ARGS__)
-
#endif /* __HICN_MAPME__ */
/*