summaryrefslogtreecommitdiffstats
path: root/src/vnet/dpo
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/dpo')
-rw-r--r--src/vnet/dpo/dpo.c1
-rw-r--r--src/vnet/dpo/dpo.h12
-rw-r--r--src/vnet/dpo/drop_dpo.c6
-rw-r--r--src/vnet/dpo/load_balance.c65
-rw-r--r--src/vnet/dpo/replicate_dpo.c14
5 files changed, 86 insertions, 12 deletions
diff --git a/src/vnet/dpo/dpo.c b/src/vnet/dpo/dpo.c
index 7658132d47a..1ee0727135d 100644
--- a/src/vnet/dpo/dpo.c
+++ b/src/vnet/dpo/dpo.c
@@ -122,6 +122,7 @@ dpo_proto_to_link (dpo_proto_t dp)
case DPO_PROTO_IP4:
return (VNET_LINK_IP4);
case DPO_PROTO_MPLS:
+ case DPO_PROTO_BIER:
return (VNET_LINK_MPLS);
case DPO_PROTO_ETHERNET:
return (VNET_LINK_ETHERNET);
diff --git a/src/vnet/dpo/dpo.h b/src/vnet/dpo/dpo.h
index 304b4331495..27c129ed444 100644
--- a/src/vnet/dpo/dpo.h
+++ b/src/vnet/dpo/dpo.h
@@ -63,6 +63,7 @@ typedef enum dpo_proto_t_
DPO_PROTO_IP6,
DPO_PROTO_MPLS,
DPO_PROTO_ETHERNET,
+ DPO_PROTO_BIER,
DPO_PROTO_NSH,
} __attribute__((packed)) dpo_proto_t;
@@ -75,6 +76,7 @@ typedef enum dpo_proto_t_
[DPO_PROTO_ETHERNET] = "ethernet", \
[DPO_PROTO_MPLS] = "mpls", \
[DPO_PROTO_NSH] = "nsh", \
+ [DPO_PROTO_BIER] = "bier", \
}
#define FOR_EACH_DPO_PROTO(_proto) \
@@ -116,6 +118,11 @@ typedef enum dpo_type_t_ {
DPO_INTERFACE_TX,
DPO_L2_BRIDGE,
DPO_L3_PROXY,
+ DPO_BIER_TABLE,
+ DPO_BIER_FMASK,
+ DPO_BIER_IMP,
+ DPO_BIER_DISP_TABLE,
+ DPO_BIER_DISP_ENTRY,
DPO_LAST,
} __attribute__((packed)) dpo_type_t;
@@ -145,6 +152,11 @@ typedef enum dpo_type_t_ {
[DPO_INTERFACE_TX] = "dpo-interface-tx", \
[DPO_L2_BRIDGE] = "dpo-l2-bridge", \
[DPO_L3_PROXY] = "dpo-l3-proxy", \
+ [DPO_BIER_TABLE] = "bier-table", \
+ [DPO_BIER_FMASK] = "bier-fmask", \
+ [DPO_BIER_IMP] = "bier-imposition", \
+ [DPO_BIER_DISP_ENTRY] = "bier-disp-entry", \
+ [DPO_BIER_DISP_TABLE] = "bier-disp-table", \
}
/**
diff --git a/src/vnet/dpo/drop_dpo.c b/src/vnet/dpo/drop_dpo.c
index a1821dddfcc..6bb3ff7d5e0 100644
--- a/src/vnet/dpo/drop_dpo.c
+++ b/src/vnet/dpo/drop_dpo.c
@@ -96,6 +96,11 @@ const static char* const drop_nsh_nodes[] =
"error-drop",
NULL,
};
+const static char* const drop_bier_nodes[] =
+{
+ "bier-drop",
+ NULL,
+};
const static char* const * const drop_nodes[DPO_PROTO_NUM] =
{
[DPO_PROTO_IP4] = drop_ip4_nodes,
@@ -103,6 +108,7 @@ const static char* const * const drop_nodes[DPO_PROTO_NUM] =
[DPO_PROTO_MPLS] = drop_mpls_nodes,
[DPO_PROTO_ETHERNET] = drop_ethernet_nodes,
[DPO_PROTO_NSH] = drop_nsh_nodes,
+ [DPO_PROTO_BIER] = drop_bier_nodes,
};
void
diff --git a/src/vnet/dpo/load_balance.c b/src/vnet/dpo/load_balance.c
index af054f1c3f4..b48702ae3f2 100644
--- a/src/vnet/dpo/load_balance.c
+++ b/src/vnet/dpo/load_balance.c
@@ -21,6 +21,7 @@
#include <vnet/adj/adj.h>
#include <vnet/adj/adj_internal.h>
#include <vnet/fib/fib_urpf_list.h>
+#include <vnet/bier/bier_hdr_inlines.h>
/*
* distribution error tolerance for load-balancing
@@ -814,6 +815,10 @@ const static char* const load_balance_l2_nodes[] =
const static char* const load_balance_nsh_nodes[] =
{
"nsh-load-balance",
+};
+const static char* const load_balance_bier_nodes[] =
+{
+ "bier-load-balance",
NULL,
};
const static char* const * const load_balance_nodes[DPO_PROTO_NUM] =
@@ -823,6 +828,7 @@ const static char* const * const load_balance_nodes[DPO_PROTO_NUM] =
[DPO_PROTO_MPLS] = load_balance_mpls_nodes,
[DPO_PROTO_ETHERNET] = load_balance_l2_nodes,
[DPO_PROTO_NSH] = load_balance_nsh_nodes,
+ [DPO_PROTO_BIER] = load_balance_bier_nodes,
};
void
@@ -935,10 +941,11 @@ typedef struct load_balance_trace_t_
index_t lb_index;
} load_balance_trace_t;
-static uword
-l2_load_balance (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+always_inline uword
+load_balance_inline (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame,
+ int is_l2)
{
u32 n_left_from, next_index, *from, *to_next;
@@ -973,7 +980,16 @@ l2_load_balance (vlib_main_t * vm,
lbi0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
lb0 = load_balance_get(lbi0);
- vnet_buffer(b0)->ip.flow_hash = l2_flow_hash(b0);
+ if (is_l2)
+ {
+ vnet_buffer(b0)->ip.flow_hash = l2_flow_hash(b0);
+ }
+ else
+ {
+ /* it's BIER */
+ const bier_hdr_t *bh0 = vlib_buffer_get_current(b0);
+ vnet_buffer(b0)->ip.flow_hash = bier_hdr_get_entropy(bh0);
+ }
dpo0 = load_balance_get_bucket_i(lb0,
vnet_buffer(b0)->ip.flow_hash &
@@ -998,6 +1014,14 @@ l2_load_balance (vlib_main_t * vm,
return frame->n_vectors;
}
+static uword
+l2_load_balance (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return (load_balance_inline(vm, node, frame, 1));
+}
+
static u8 *
format_l2_load_balance_trace (u8 * s, va_list * args)
{
@@ -1113,3 +1137,34 @@ VLIB_REGISTER_NODE (nsh_load_balance_node) = {
[0] = "error-drop",
},
};
+
+static u8 *
+format_bier_load_balance_trace (u8 * s, va_list * args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+ load_balance_trace_t *t = va_arg (*args, load_balance_trace_t *);
+
+ s = format (s, "BIER-load-balance: index %d", t->lb_index);
+ return s;
+}
+
+static uword
+bier_load_balance (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return (load_balance_inline(vm, node, frame, 0));
+}
+
+/**
+ * @brief
+ */
+VLIB_REGISTER_NODE (bier_load_balance_node) = {
+ .function = bier_load_balance,
+ .name = "bier-load-balance",
+ .vector_size = sizeof (u32),
+
+ .format_trace = format_bier_load_balance_trace,
+ .sibling_of = "mpls-load-balance",
+};
diff --git a/src/vnet/dpo/replicate_dpo.c b/src/vnet/dpo/replicate_dpo.c
index 9fdb9a05071..ae045f6a431 100644
--- a/src/vnet/dpo/replicate_dpo.c
+++ b/src/vnet/dpo/replicate_dpo.c
@@ -261,7 +261,7 @@ replicate_fill_buckets (replicate_t *rep,
u32 n_buckets)
{
load_balance_path_t * nh;
- u16 ii, bucket;
+ u16 bucket;
bucket = 0;
@@ -271,11 +271,8 @@ replicate_fill_buckets (replicate_t *rep,
*/
vec_foreach (nh, nhs)
{
- for (ii = 0; ii < nh->path_weight; ii++)
- {
- ASSERT(bucket < n_buckets);
- replicate_set_bucket_i(rep, bucket++, buckets, &nh->path_dpo);
- }
+ ASSERT(bucket < n_buckets);
+ replicate_set_bucket_i(rep, bucket++, buckets, &nh->path_dpo);
}
}
@@ -694,7 +691,10 @@ replicate_inline (vlib_main_t * vm,
if (PREDICT_FALSE(c0->flags & VLIB_BUFFER_IS_TRACED))
{
- replicate_trace_t *t = vlib_add_trace (vm, node, c0, sizeof (*t));
+ replicate_trace_t *t;
+
+ vlib_trace_buffer (vm, node, next0, c0, 0);
+ t = vlib_add_trace (vm, node, c0, sizeof (*t));
t->rep_index = repi0;
t->dpo = *dpo0;
}