aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/dpo
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/dpo')
-rw-r--r--src/vnet/dpo/dpo.c53
-rw-r--r--src/vnet/dpo/dpo.h24
-rw-r--r--src/vnet/dpo/load_balance.c20
-rw-r--r--src/vnet/dpo/mpls_label_dpo.c33
-rw-r--r--src/vnet/dpo/replicate_dpo.h10
5 files changed, 114 insertions, 26 deletions
diff --git a/src/vnet/dpo/dpo.c b/src/vnet/dpo/dpo.c
index 85f2c5d3622..19e3714c536 100644
--- a/src/vnet/dpo/dpo.c
+++ b/src/vnet/dpo/dpo.c
@@ -153,20 +153,22 @@ format_dpo_id (u8 * s, va_list * args)
if (NULL != dpo_vfts[dpo->dpoi_type].dv_format)
{
- return (format(s, "%U",
- dpo_vfts[dpo->dpoi_type].dv_format,
- dpo->dpoi_index,
- indent));
+ s = format(s, "%U",
+ dpo_vfts[dpo->dpoi_type].dv_format,
+ dpo->dpoi_index,
+ indent);
}
-
- switch (dpo->dpoi_type)
+ else
{
- case DPO_FIRST:
- s = format(s, "unset");
- break;
- default:
- s = format(s, "unknown");
- break;
+ switch (dpo->dpoi_type)
+ {
+ case DPO_FIRST:
+ s = format(s, "unset");
+ break;
+ default:
+ s = format(s, "unknown");
+ break;
+ }
}
return (s);
}
@@ -303,6 +305,18 @@ dpo_default_get_next_node (const dpo_id_t *dpo)
return (node_indices);
}
+/**
+ * A default variant of the make interpose function that just returns
+ * the original
+ */
+static void
+dpo_default_mk_interpose (const dpo_id_t *original,
+ const dpo_id_t *parent,
+ dpo_id_t *clone)
+{
+ dpo_copy(clone, original);
+}
+
void
dpo_register (dpo_type_t type,
const dpo_vft_t *vft,
@@ -314,6 +328,10 @@ dpo_register (dpo_type_t type,
{
dpo_vfts[type].dv_get_next_node = dpo_default_get_next_node;
}
+ if (NULL == dpo_vfts[type].dv_mk_interpose)
+ {
+ dpo_vfts[type].dv_mk_interpose = dpo_default_mk_interpose;
+ }
vec_validate(dpo_nodes, type);
dpo_nodes[type] = nodes;
@@ -331,6 +349,17 @@ dpo_register_new_type (const dpo_vft_t *vft,
}
void
+dpo_mk_interpose (const dpo_id_t *original,
+ const dpo_id_t *parent,
+ dpo_id_t *clone)
+{
+ if (!dpo_id_is_valid(original))
+ return;
+
+ dpo_vfts[original->dpoi_type].dv_mk_interpose(original, parent, clone);
+}
+
+void
dpo_lock (dpo_id_t *dpo)
{
if (!dpo_id_is_valid(dpo))
diff --git a/src/vnet/dpo/dpo.h b/src/vnet/dpo/dpo.h
index 21a2ae2a33d..0eeca67b74b 100644
--- a/src/vnet/dpo/dpo.h
+++ b/src/vnet/dpo/dpo.h
@@ -225,6 +225,14 @@ extern void dpo_lock(dpo_id_t *dpo);
extern void dpo_unlock(dpo_id_t *dpo);
/**
+ * @brief
+ * Make an interpose DPO from an original
+ */
+extern void dpo_mk_interpose(const dpo_id_t *original,
+ const dpo_id_t *parent,
+ dpo_id_t *clone);
+
+/**
* @brief Set/create a DPO ID
* The DPO will be locked.
*
@@ -374,6 +382,18 @@ typedef u32* (*dpo_get_next_node_t)(const dpo_id_t *dpo);
typedef u32 (*dpo_get_urpf_t)(const dpo_id_t *dpo);
/**
+ * @brief Called during FIB interposition when the originally
+ * registered DPO is used to 'clone' an instance for interposition
+ * at a particular location in the FIB graph.
+ * The parent is the next DPO in the chain that the clone will
+ * be used instead of. The clone may then choose to stack itself
+ * on the parent.
+ */
+typedef void (*dpo_mk_interpose_t)(const dpo_id_t *original,
+ const dpo_id_t *parent,
+ dpo_id_t *clone);
+
+/**
* @brief A virtual function table regisitered for a DPO type
*/
typedef struct dpo_vft_t_
@@ -405,6 +425,10 @@ typedef struct dpo_vft_t_
* Get uRPF interface
*/
dpo_get_urpf_t dv_get_urpf;
+ /**
+ * Signal on an interposed child that the parent has changed
+ */
+ dpo_mk_interpose_t dv_mk_interpose;
} dpo_vft_t;
diff --git a/src/vnet/dpo/load_balance.c b/src/vnet/dpo/load_balance.c
index db0ebcdceb8..bb38233a55e 100644
--- a/src/vnet/dpo/load_balance.c
+++ b/src/vnet/dpo/load_balance.c
@@ -198,16 +198,6 @@ load_balance_create (u32 n_buckets,
return (load_balance_get_index(load_balance_create_i(n_buckets, lb_proto, fhc)));
}
-u16
-load_balance_n_buckets (index_t lbi)
-{
- load_balance_t *lb;
-
- lb = load_balance_get(lbi);
-
- return (lb->lb_n_buckets);
-}
-
static inline void
load_balance_set_bucket_i (load_balance_t *lb,
u32 bucket,
@@ -250,6 +240,16 @@ load_balance_is_drop (const dpo_id_t *dpo)
return (0);
}
+u16
+load_balance_n_buckets (index_t lbi)
+{
+ load_balance_t *lb;
+
+ lb = load_balance_get(lbi);
+
+ return (lb->lb_n_buckets);
+}
+
void
load_balance_set_fib_entry_flags (index_t lbi,
fib_entry_flag_t flags)
diff --git a/src/vnet/dpo/mpls_label_dpo.c b/src/vnet/dpo/mpls_label_dpo.c
index ebbbbec9b64..0a7063cc99a 100644
--- a/src/vnet/dpo/mpls_label_dpo.c
+++ b/src/vnet/dpo/mpls_label_dpo.c
@@ -1204,11 +1204,44 @@ mpls_label_dpo_mem_show (void)
sizeof(mpls_label_dpo_t));
}
+/**
+ * Interpose a label DPO. used in the FIB unit tests
+ */
+static void
+mpls_label_interpose (const dpo_id_t *original,
+ const dpo_id_t *parent,
+ dpo_id_t *clone)
+{
+ mpls_label_dpo_t *mld, *mld_clone;
+
+ mld_clone = mpls_label_dpo_alloc();
+ mld = mpls_label_dpo_get(original->dpoi_index);
+
+ mld_clone->mld_locks = 0;
+ clib_memcpy(&mld_clone->mld_hdr,
+ &mld->mld_hdr,
+ sizeof(mld_clone->mld_hdr));
+ mld_clone->mld_payload_proto = mld->mld_payload_proto;
+ mld_clone->mld_n_labels = mld->mld_n_labels;
+ mld_clone->mld_n_hdr_bytes = mld->mld_n_hdr_bytes;
+
+ dpo_stack(mpls_label_dpo_types[MPLS_LABEL_DPO_FLAG_NONE],
+ mld_clone->mld_payload_proto,
+ &mld_clone->mld_dpo,
+ parent);
+
+ dpo_set(clone,
+ mpls_label_dpo_types[MPLS_LABEL_DPO_FLAG_NONE],
+ mld_clone->mld_payload_proto,
+ mpls_label_dpo_get_index(mld_clone));
+}
+
const static dpo_vft_t mld_vft = {
.dv_lock = mpls_label_dpo_lock,
.dv_unlock = mpls_label_dpo_unlock,
.dv_format = format_mpls_label_dpo,
.dv_mem_show = mpls_label_dpo_mem_show,
+ .dv_mk_interpose = mpls_label_interpose,
};
const static char* const mpls_label_imp_pipe_ip4_nodes[] =
diff --git a/src/vnet/dpo/replicate_dpo.h b/src/vnet/dpo/replicate_dpo.h
index 7383184a2ea..ccb25630e16 100644
--- a/src/vnet/dpo/replicate_dpo.h
+++ b/src/vnet/dpo/replicate_dpo.h
@@ -53,7 +53,7 @@ extern replicate_main_t replicate_main;
*/
typedef struct replicate_t_ {
/**
- * number of buckets in the load-balance. always a power of 2.
+ * number of buckets in the replicate.
*/
u16 rep_n_buckets;
@@ -104,15 +104,17 @@ extern void replicate_multipath_update(
load_balance_path_t *next_hops);
extern void replicate_set_bucket(index_t repi,
- u32 bucket,
- const dpo_id_t *next);
+ u32 bucket,
+ const dpo_id_t *next);
extern u8* format_replicate(u8 * s, va_list * args);
extern const dpo_id_t *replicate_get_bucket(index_t repi,
- u32 bucket);
+ u32 bucket);
extern int replicate_is_drop(const dpo_id_t *dpo);
+extern u16 replicate_n_buckets(index_t repi);
+
/**
* The encapsulation breakages are for fast DP access
*/