summaryrefslogtreecommitdiffstats
path: root/src/vnet/adj
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2021-10-08 07:30:47 +0000
committerBeno�t Ganne <bganne@cisco.com>2021-11-19 14:41:28 +0000
commit6fdcc3daa40ebfcb793998b6e4527dd6db03cfb7 (patch)
tree8b8afab4ef1f1d1f8381b388010e92e4d470022b /src/vnet/adj
parentad80663eb3fd954f42607168ad4babb91cb0edcc (diff)
fib: Don't use [midchain] adjacencies to change an interface's feature arc
Type: fix Using the adjacency to modify the interface's feature arc doesn't work, since there are potentially more than one adj per-interface. Instead have the interface, when it is created, register what the end node of the feature arc is. This end node is then also used as the interface's tx node (i.e. it is used as the adjacency's next-node). rename adj-midhcain-tx as 'tunnel-output', that's a bit more intuitive. There's also a fix in config string handling to: 1- prevent false sharing of strings when the end node of the arc is different. 2- call registered listeners when the end node is changed For IPSec the consequences are that one cannot provide per-adjacency behaviour using different end-nodes - this was previously done for the no-SA and an SA with no protection. These cases are no handled in the esp-encrypt node. Signed-off-by: Neale Ranns <neale@graphiant.com> Change-Id: If3a83d03a3000f28820d9a9cb4101d244803d084
Diffstat (limited to 'src/vnet/adj')
-rw-r--r--src/vnet/adj/adj.h10
-rw-r--r--src/vnet/adj/adj_internal.h4
-rw-r--r--src/vnet/adj/adj_midchain.c82
-rw-r--r--src/vnet/adj/adj_midchain_node.c35
-rw-r--r--src/vnet/adj/adj_nbr.c40
5 files changed, 81 insertions, 90 deletions
diff --git a/src/vnet/adj/adj.h b/src/vnet/adj/adj.h
index c1922c755ec..860193c04ad 100644
--- a/src/vnet/adj/adj.h
+++ b/src/vnet/adj/adj.h
@@ -165,14 +165,6 @@ typedef enum adj_attr_t_
ADJ_ATTR_SYNC_WALK_ACTIVE = 0,
/**
- * Packets TX through the midchain do not increment the interface
- * counters. This should be used when the adj is associated with an L2
- * interface and that L2 interface is in a bridge domain. In that case
- * the packet will have traversed the interface's TX node, and hence have
- * been counted, before it traverses ths midchain
- */
- ADJ_ATTR_MIDCHAIN_NO_COUNT,
- /**
* When stacking midchains on a fib-entry extract the choice from the
* load-balance returned based on an IP hash of the adj's rewrite
*/
@@ -195,7 +187,6 @@ typedef enum adj_attr_t_
#define ADJ_ATTR_NAMES { \
[ADJ_ATTR_SYNC_WALK_ACTIVE] = "walk-active", \
- [ADJ_ATTR_MIDCHAIN_NO_COUNT] = "midchain-no-count", \
[ADJ_ATTR_MIDCHAIN_IP_STACK] = "midchain-ip-stack", \
[ADJ_ATTR_MIDCHAIN_LOOPED] = "midchain-looped", \
[ADJ_ATTR_MIDCHAIN_FIXUP_IP4O4_HDR] = "midchain-ip4o4-hdr-fixup", \
@@ -214,7 +205,6 @@ typedef enum adj_flags_t_
{
ADJ_FLAG_NONE = 0,
ADJ_FLAG_SYNC_WALK_ACTIVE = (1 << ADJ_ATTR_SYNC_WALK_ACTIVE),
- ADJ_FLAG_MIDCHAIN_NO_COUNT = (1 << ADJ_ATTR_MIDCHAIN_NO_COUNT),
ADJ_FLAG_MIDCHAIN_IP_STACK = (1 << ADJ_ATTR_MIDCHAIN_IP_STACK),
ADJ_FLAG_MIDCHAIN_LOOPED = (1 << ADJ_ATTR_MIDCHAIN_LOOPED),
ADJ_FLAG_MIDCHAIN_FIXUP_IP4O4_HDR = (1 << ADJ_ATTR_MIDCHAIN_FIXUP_IP4O4_HDR),
diff --git a/src/vnet/adj/adj_internal.h b/src/vnet/adj/adj_internal.h
index 3dbf7e2a371..6842bc4147e 100644
--- a/src/vnet/adj/adj_internal.h
+++ b/src/vnet/adj/adj_internal.h
@@ -47,8 +47,7 @@
*/
extern vlib_node_registration_t adj_nsh_midchain_node;
extern vlib_node_registration_t adj_nsh_rewrite_node;
-extern vlib_node_registration_t adj_midchain_tx_no_count_node;
-extern vlib_node_registration_t adj_midchain_tx_node;
+extern vlib_node_registration_t adj_midchain_tx;
static inline u32
adj_get_rewrite_node (vnet_link_t linkt)
@@ -128,6 +127,7 @@ extern void adj_nbr_remove(adj_index_t ai,
vnet_link_t link_type,
const ip46_address_t *nh_addr,
u32 sw_if_index);
+extern u32 adj_nbr_get_n_adjs(vnet_link_t link_type, u32 sw_if_index);
extern void adj_glean_remove(ip_adjacency_t *adj);
extern void adj_mcast_remove(fib_protocol_t proto,
u32 sw_if_index);
diff --git a/src/vnet/adj/adj_midchain.c b/src/vnet/adj/adj_midchain.c
index 9f709ad13be..8e6a940befa 100644
--- a/src/vnet/adj/adj_midchain.c
+++ b/src/vnet/adj/adj_midchain.c
@@ -75,52 +75,37 @@ adj_get_midchain_node (vnet_link_t link)
}
static u8
-adj_midchain_get_feature_arc_index_for_link_type (const ip_adjacency_t *adj)
+adj_midchain_get_feature_arc_index (const ip_adjacency_t *adj)
{
- u8 arc = (u8) ~0;
switch (adj->ia_link)
{
case VNET_LINK_IP4:
- {
- arc = ip4_main.lookup_main.output_feature_arc_index;
- break;
- }
+ return ip4_main.lookup_main.output_feature_arc_index;
case VNET_LINK_IP6:
- {
- arc = ip6_main.lookup_main.output_feature_arc_index;
- break;
- }
+ return ip6_main.lookup_main.output_feature_arc_index;
case VNET_LINK_MPLS:
- {
- arc = mpls_main.output_feature_arc_index;
- break;
- }
+ return mpls_main.output_feature_arc_index;
case VNET_LINK_ETHERNET:
- {
- arc = ethernet_main.output_feature_arc_index;
- break;
- }
+ return ethernet_main.output_feature_arc_index;
case VNET_LINK_NSH:
- {
- arc = nsh_main_placeholder.output_feature_arc_index;
- break;
- }
case VNET_LINK_ARP:
- ASSERT(0);
break;
}
-
- ASSERT (arc != (u8) ~0);
-
- return (arc);
+ ASSERT (0);
+ return (0);
}
static u32
adj_nbr_midchain_get_tx_node (ip_adjacency_t *adj)
{
- return ((adj->ia_flags & ADJ_FLAG_MIDCHAIN_NO_COUNT) ?
- adj_midchain_tx_no_count_node.index :
- adj_midchain_tx_node.index);
+ return (adj_midchain_tx.index);
+}
+
+static u32
+adj_nbr_midchain_get_next_node (ip_adjacency_t *adj)
+{
+ return (vnet_feature_get_end_node(adj_midchain_get_feature_arc_index(adj),
+ adj->rewrite_header.sw_if_index));
}
/**
@@ -131,17 +116,7 @@ adj_nbr_midchain_get_tx_node (ip_adjacency_t *adj)
void
adj_midchain_teardown (ip_adjacency_t *adj)
{
- vlib_main_t *vm = vlib_get_main();
-
dpo_reset(&adj->sub_type.midchain.next_dpo);
-
- vlib_worker_thread_barrier_sync(vm);
- adj->ia_cfg_index = vnet_feature_modify_end_node(
- adj_midchain_get_feature_arc_index_for_link_type (adj),
- adj->rewrite_header.sw_if_index,
- vlib_get_node_by_name (vlib_get_main(),
- (u8*) "interface-output")->index);
- vlib_worker_thread_barrier_release(vm);
}
/**
@@ -155,9 +130,7 @@ adj_midchain_setup (adj_index_t adj_index,
const void *data,
adj_flags_t flags)
{
- vlib_main_t *vm = vlib_get_main();
ip_adjacency_t *adj;
- u32 tx_node;
ASSERT(ADJ_INDEX_INVALID != adj_index);
@@ -181,15 +154,6 @@ adj_midchain_setup (adj_index_t adj_index,
adj->rewrite_header.flags &= ~VNET_REWRITE_FIXUP_FLOW_HASH;
}
- tx_node = adj_nbr_midchain_get_tx_node(adj);
-
- vlib_worker_thread_barrier_sync(vm);
- adj->ia_cfg_index = vnet_feature_modify_end_node(
- adj_midchain_get_feature_arc_index_for_link_type (adj),
- adj->rewrite_header.sw_if_index,
- tx_node);
- vlib_worker_thread_barrier_release(vm);
-
/*
* stack the midchain on the drop so it's ready to forward in the adj-midchain-tx.
* The graph arc used/created here is from the midchain-tx node to the
@@ -197,7 +161,7 @@ adj_midchain_setup (adj_index_t adj_index,
* node are any output features, then the midchain-tx. from there we
* need to get to the stacked child's node.
*/
- dpo_stack_from_node(tx_node,
+ dpo_stack_from_node(adj_nbr_midchain_get_tx_node(adj),
&adj->sub_type.midchain.next_dpo,
drop_dpo_get(vnet_link_to_dpo_proto(adj->ia_link)));
}
@@ -238,7 +202,7 @@ adj_nbr_midchain_update_rewrite (adj_index_t adj_index,
adj_nbr_update_rewrite_internal(adj,
IP_LOOKUP_NEXT_MIDCHAIN,
adj_get_midchain_node(adj->ia_link),
- adj_nbr_midchain_get_tx_node(adj),
+ adj_nbr_midchain_get_next_node(adj),
rewrite);
}
@@ -260,11 +224,6 @@ adj_nbr_midchain_update_next_node (adj_index_t adj_index,
adj->ia_node_index,
next_node);
- adj->ia_cfg_index = vnet_feature_modify_end_node(
- adj_midchain_get_feature_arc_index_for_link_type (adj),
- adj->rewrite_header.sw_if_index,
- next_node);
-
vlib_worker_thread_barrier_release(vm);
}
@@ -284,12 +243,7 @@ adj_nbr_midchain_reset_next_node (adj_index_t adj_index)
adj->rewrite_header.next_index =
vlib_node_add_next(vlib_get_main(),
adj->ia_node_index,
- adj_nbr_midchain_get_tx_node(adj));
-
- adj->ia_cfg_index = vnet_feature_modify_end_node(
- adj_midchain_get_feature_arc_index_for_link_type (adj),
- adj->rewrite_header.sw_if_index,
- adj_nbr_midchain_get_tx_node(adj));
+ adj_nbr_midchain_get_next_node(adj));
vlib_worker_thread_barrier_release(vm);
}
diff --git a/src/vnet/adj/adj_midchain_node.c b/src/vnet/adj/adj_midchain_node.c
index 170ed19855e..fcc2c6c7647 100644
--- a/src/vnet/adj/adj_midchain_node.c
+++ b/src/vnet/adj/adj_midchain_node.c
@@ -202,16 +202,20 @@ format_adj_midchain_tx_trace (u8 * s, va_list * args)
return (s);
}
-static uword
-adj_midchain_tx (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (adj_midchain_tx) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return (adj_midchain_tx_inline(vm, node, frame, 1));
+}
+VLIB_NODE_FN (tunnel_output) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
return (adj_midchain_tx_inline(vm, node, frame, 1));
}
-VLIB_REGISTER_NODE (adj_midchain_tx_node) = {
- .function = adj_midchain_tx,
+VLIB_REGISTER_NODE (adj_midchain_tx) = {
.name = "adj-midchain-tx",
.vector_size = sizeof (u32),
@@ -222,20 +226,23 @@ VLIB_REGISTER_NODE (adj_midchain_tx_node) = {
[0] = "error-drop",
},
};
+VLIB_REGISTER_NODE (tunnel_output) = {
+ .name = "tunnel-output",
+ .vector_size = sizeof (u32),
+ .format_trace = format_adj_midchain_tx_trace,
+ .sibling_of = "adj-midchain-tx",
+};
-static uword
-adj_midchain_tx_no_count (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (tunnel_output_no_count) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
return (adj_midchain_tx_inline(vm, node, frame, 0));
}
-VLIB_REGISTER_NODE (adj_midchain_tx_no_count_node) = {
- .function = adj_midchain_tx_no_count,
- .name = "adj-midchain-tx-no-count",
+VLIB_REGISTER_NODE (tunnel_output_no_count) = {
+ .name = "tunnel-output-no-count",
.vector_size = sizeof (u32),
-
.format_trace = format_adj_midchain_tx_trace,
.sibling_of = "adj-midchain-tx",
};
diff --git a/src/vnet/adj/adj_nbr.c b/src/vnet/adj/adj_nbr.c
index 8524c6c83ae..293badefd7d 100644
--- a/src/vnet/adj/adj_nbr.c
+++ b/src/vnet/adj/adj_nbr.c
@@ -105,6 +105,46 @@ adj_nbr_remove (adj_index_t ai,
}
}
+typedef struct adj_nbr_get_n_adjs_walk_ctx_t_
+{
+ vnet_link_t linkt;
+ u32 count;
+} adj_nbr_get_n_adjs_walk_ctx_t;
+
+static adj_walk_rc_t
+adj_nbr_get_n_adjs_walk (adj_index_t ai,
+ void *data)
+{
+ adj_nbr_get_n_adjs_walk_ctx_t *ctx = data;
+ const ip_adjacency_t *adj;
+
+ adj = adj_get(ai);
+
+ if (ctx->linkt == adj->ia_link)
+ ctx->count++;
+
+ return (ADJ_WALK_RC_CONTINUE);
+}
+
+u32
+adj_nbr_get_n_adjs (vnet_link_t link_type, u32 sw_if_index)
+{
+ adj_nbr_get_n_adjs_walk_ctx_t ctx = {
+ .linkt = link_type,
+ };
+ fib_protocol_t fproto;
+
+ FOR_EACH_FIB_IP_PROTOCOL(fproto)
+ {
+ adj_nbr_walk (sw_if_index,
+ fproto,
+ adj_nbr_get_n_adjs_walk,
+ &ctx);
+ }
+
+ return (ctx.count);
+}
+
adj_index_t
adj_nbr_find (fib_protocol_t nh_proto,
vnet_link_t link_type,