aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-03-08 05:17:22 -0800
committerDamjan Marion <dmarion.lists@gmail.com>2017-03-09 15:34:14 +0000
commitb3b2de71ceea0cc7ce18f89cc8180ed4a42e355d (patch)
treeda9a025096839fef6d749459c28f786327226d13 /src/vnet
parent8082380922c65702251d5242058f7b5f35011574 (diff)
IMplementation for option to not create a FIB table entry when adding a neighbor entry
Change-Id: I952039e101031ee6a06e63f4c73d8eb359423e1a Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/ethernet/arp.c61
-rw-r--r--src/vnet/ethernet/arp_packet.h11
-rw-r--r--src/vnet/ethernet/ethernet.h3
-rw-r--r--src/vnet/ip/ip6_neighbor.c59
-rw-r--r--src/vnet/ip/ip6_neighbor.h14
-rw-r--r--src/vnet/ip/ip_api.c6
6 files changed, 98 insertions, 56 deletions
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index 222415b0..d8ae8443 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -100,6 +100,7 @@ typedef struct
u32 sw_if_index;
ethernet_arp_ip4_over_ethernet_address_t a;
int is_static;
+ int is_no_fib_entry;
int flags;
#define ETHERNET_ARP_ARGS_REMOVE (1<<0)
#define ETHERNET_ARP_ARGS_FLUSH (1<<1)
@@ -254,6 +255,9 @@ format_ethernet_arp_ip4_entry (u8 * s, va_list * va)
if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC)
flags = format (flags, "D");
+ if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_NO_FIB_ENTRY)
+ flags = format (flags, "N");
+
s = format (s, "%=12U%=16U%=6s%=20U%=24U",
format_vlib_cpu_time, vnm->vlib_main, e->cpu_time_last_updated,
format_ip4_address, &e->ip4_address,
@@ -525,6 +529,7 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
ethernet_arp_interface_t *arp_int;
int is_static = args->is_static;
u32 sw_if_index = args->sw_if_index;
+ int is_no_fib_entry = args->is_no_fib_entry;
vec_validate (am->ethernet_arp_by_sw_if_index, sw_if_index);
@@ -546,16 +551,6 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
if (make_new_arp_cache_entry)
{
- fib_prefix_t pfx = {
- .fp_len = 32,
- .fp_proto = FIB_PROTOCOL_IP4,
- .fp_addr = {
- .ip4 = a->ip4,
- }
- ,
- };
- u32 fib_index;
-
pool_get (am->ip4_entry_pool, e);
if (NULL == arp_int->arp_entries)
@@ -570,17 +565,25 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
clib_memcpy (e->ethernet_address,
a->ethernet, sizeof (e->ethernet_address));
- fib_index = ip4_fib_table_get_index_for_sw_if_index (e->sw_if_index);
- e->fib_entry_index =
- fib_table_entry_update_one_path (fib_index,
- &pfx,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &pfx.fp_addr,
- e->sw_if_index,
- ~0,
- 1, NULL, FIB_ROUTE_PATH_FLAG_NONE);
+ if (!is_no_fib_entry)
+ {
+ fib_prefix_t pfx = {
+ .fp_len = 32,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr.ip4 = a->ip4,
+ };
+ u32 fib_index;
+
+ fib_index =
+ ip4_fib_table_get_index_for_sw_if_index (e->sw_if_index);
+ e->fib_entry_index =
+ fib_table_entry_update_one_path (fib_index, &pfx, FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4, &pfx.fp_addr,
+ e->sw_if_index, ~0, 1, NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ e->flags |= ETHERNET_ARP_IP4_ENTRY_FLAG_NO_FIB_ENTRY;
+ }
}
else
{
@@ -1142,7 +1145,7 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
vnet_arp_set_ip4_over_ethernet (vnm, sw_if_index0,
&arp0->ip4_over_ethernet[0],
- 0 /* is_static */ );
+ 0 /* is_static */ , 0);
error0 = ETHERNET_ARP_ERROR_l3_src_address_learned;
}
@@ -1658,6 +1661,8 @@ arp_entry_free (ethernet_arp_interface_t * eai, ethernet_arp_ip4_entry_t * e)
{
ethernet_arp_main_t *am = &ethernet_arp_main;
+ /* it's safe to delete the ADJ source on the FIB entry, even if it
+ * was added */
fib_table_entry_delete_index (e->fib_entry_index, FIB_SOURCE_ADJ);
hash_unset (eai->arp_entries, e->ip4_address.as_u32);
pool_put (am->ip4_entry_pool, e);
@@ -1828,13 +1833,15 @@ increment_ip4_and_mac_address (ethernet_arp_ip4_over_ethernet_address_t * a)
int
vnet_arp_set_ip4_over_ethernet (vnet_main_t * vnm,
- u32 sw_if_index, void *a_arg, int is_static)
+ u32 sw_if_index, void *a_arg,
+ int is_static, int is_no_fib_entry)
{
ethernet_arp_ip4_over_ethernet_address_t *a = a_arg;
vnet_arp_set_ip4_over_ethernet_rpc_args_t args;
args.sw_if_index = sw_if_index;
args.is_static = is_static;
+ args.is_no_fib_entry = is_no_fib_entry;
args.flags = 0;
clib_memcpy (&args.a, a, sizeof (*a));
@@ -1931,6 +1938,7 @@ ip_arp_add_del_command_fn (vlib_main_t * vm,
u32 fib_index = 0;
u32 fib_id;
int is_static = 0;
+ int is_no_fib_entry = 0;
int is_proxy = 0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -1948,6 +1956,9 @@ ip_arp_add_del_command_fn (vlib_main_t * vm,
else if (unformat (input, "static"))
is_static = 1;
+ else if (unformat (input, "no-fib-entry"))
+ is_no_fib_entry = 1;
+
else if (unformat (input, "count %d", &count))
;
@@ -1991,7 +2002,7 @@ ip_arp_add_del_command_fn (vlib_main_t * vm,
1 /* type */ , 0 /* data */ );
vnet_arp_set_ip4_over_ethernet
- (vnm, sw_if_index, &addr, is_static);
+ (vnm, sw_if_index, &addr, is_static, is_no_fib_entry);
vlib_process_wait_for_event (vm);
event_type = vlib_process_get_events (vm, &event_data);
@@ -2046,7 +2057,7 @@ ip_arp_add_del_command_fn (vlib_main_t * vm,
VLIB_CLI_COMMAND (ip_arp_add_del_command, static) = {
.path = "set ip arp",
.short_help =
- "set ip arp [del] <intfc> <ip-address> <mac-address> [static] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
+ "set ip arp [del] <intfc> <ip-address> <mac-address> [static] [no-fib-entry] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
.function = ip_arp_add_del_command_fn,
};
/* *INDENT-ON* */
diff --git a/src/vnet/ethernet/arp_packet.h b/src/vnet/ethernet/arp_packet.h
index e762ffa4..17e64f43 100644
--- a/src/vnet/ethernet/arp_packet.h
+++ b/src/vnet/ethernet/arp_packet.h
@@ -140,6 +140,13 @@ typedef struct
};
} ethernet_arp_header_t;
+typedef enum ethernet_arp_entry_flags_t_
+{
+ ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC = (1 << 0),
+ ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC = (1 << 1),
+ ETHERNET_ARP_IP4_ENTRY_FLAG_NO_FIB_ENTRY = (1 << 2),
+} __attribute__ ((packed)) ethernet_arp_entry_flags_t;
+
typedef struct
{
u32 sw_if_index;
@@ -147,9 +154,7 @@ typedef struct
u8 ethernet_address[6];
- u16 flags;
-#define ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC (1 << 0)
-#define ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC (1 << 1)
+ ethernet_arp_entry_flags_t flags;
u64 cpu_time_last_updated;
diff --git a/src/vnet/ethernet/ethernet.h b/src/vnet/ethernet/ethernet.h
index ba84c69c..dcc656a7 100644
--- a/src/vnet/ethernet/ethernet.h
+++ b/src/vnet/ethernet/ethernet.h
@@ -403,7 +403,8 @@ void ethernet_set_rx_redirect (vnet_main_t * vnm, vnet_hw_interface_t * hi,
int
vnet_arp_set_ip4_over_ethernet (vnet_main_t * vnm,
- u32 sw_if_index, void *a_arg, int is_static);
+ u32 sw_if_index, void *a_arg,
+ int is_static, int is_no_fib_entry);
int
vnet_arp_unset_ip4_over_ethernet (vnet_main_t * vnm,
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index 715891b8..8d355ab2 100644
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -235,6 +235,9 @@ format_ip6_neighbor_ip6_entry (u8 * s, va_list * va)
if (n->flags & IP6_NEIGHBOR_FLAG_STATIC)
flags = format (flags, "S");
+ if (n->flags & IP6_NEIGHBOR_FLAG_NO_FIB_ENTRY)
+ flags = format (flags, "N");
+
si = vnet_get_sw_interface (vnm, n->key.sw_if_index);
s = format (s, "%=12U%=20U%=6s%=20U%=40U",
format_vlib_cpu_time, vm, n->cpu_time_last_updated,
@@ -317,6 +320,7 @@ typedef struct
{
u8 is_add;
u8 is_static;
+ u8 is_no_fib_entry;
u8 link_layer_address[6];
u32 sw_if_index;
ip6_address_t addr;
@@ -328,7 +332,8 @@ static void ip6_neighbor_set_unset_rpc_callback
static void set_unset_ip6_neighbor_rpc
(vlib_main_t * vm,
u32 sw_if_index,
- ip6_address_t * a, u8 * link_layer_address, int is_add, int is_static)
+ ip6_address_t * a, u8 * link_layer_address, int is_add, int is_static,
+ int is_no_fib_entry)
{
ip6_neighbor_set_unset_rpc_args_t args;
void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
@@ -336,6 +341,7 @@ static void set_unset_ip6_neighbor_rpc
args.sw_if_index = sw_if_index;
args.is_add = is_add;
args.is_static = is_static;
+ args.is_no_fib_entry = is_no_fib_entry;
clib_memcpy (&args.addr, a, sizeof (*a));
if (NULL != link_layer_address)
clib_memcpy (args.link_layer_address, link_layer_address, 6);
@@ -565,7 +571,7 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
ip6_address_t * a,
u8 * link_layer_address,
uword n_bytes_link_layer_address,
- int is_static)
+ int is_static, int is_no_fib_entry)
{
ip6_neighbor_main_t *nm = &ip6_neighbor_main;
ip6_neighbor_key_t k;
@@ -578,7 +584,8 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
if (os_get_cpu_number ())
{
set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, link_layer_address,
- 1 /* set new neighbor */ , is_static);
+ 1 /* set new neighbor */ , is_static,
+ is_no_fib_entry);
return 0;
}
@@ -598,16 +605,6 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
if (make_new_nd_cache_entry)
{
- fib_prefix_t pfx = {
- .fp_len = 128,
- .fp_proto = FIB_PROTOCOL_IP6,
- .fp_addr = {
- .ip6 = k.ip6_address,
- }
- ,
- };
- u32 fib_index;
-
pool_get (nm->neighbor_pool, n);
mhash_set (&nm->neighbor_index_by_key, &k, n - nm->neighbor_pool,
/* old value */ 0);
@@ -619,9 +616,25 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
/*
* create the adj-fib. the entry in the FIB table for and to the peer.
*/
- fib_index = ip6_main.fib_index_by_sw_if_index[n->key.sw_if_index];
- n->fib_entry_index = fib_table_entry_update_one_path (fib_index, &pfx, FIB_SOURCE_ADJ, FIB_ENTRY_FLAG_NONE, FIB_PROTOCOL_IP6, &pfx.fp_addr, n->key.sw_if_index, ~0, 1, NULL, // no label stack
- FIB_ROUTE_PATH_FLAG_NONE);
+ if (!is_no_fib_entry)
+ {
+ fib_prefix_t pfx = {
+ .fp_len = 128,
+ .fp_proto = FIB_PROTOCOL_IP6,
+ .fp_addr.ip6 = k.ip6_address,
+ };
+ u32 fib_index;
+
+ fib_index = ip6_main.fib_index_by_sw_if_index[n->key.sw_if_index];
+ n->fib_entry_index =
+ fib_table_entry_update_one_path (fib_index, &pfx,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_NONE,
+ FIB_PROTOCOL_IP6, &pfx.fp_addr,
+ n->key.sw_if_index, ~0, 1, NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ n->flags |= IP6_NEIGHBOR_FLAG_NO_FIB_ENTRY;
+ }
}
else
{
@@ -712,7 +725,7 @@ vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
if (os_get_cpu_number ())
{
set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, link_layer_address,
- 0 /* unset */ , 0);
+ 0 /* unset */ , 0, 0);
return 0;
}
@@ -746,7 +759,8 @@ static void ip6_neighbor_set_unset_rpc_callback
vlib_main_t *vm = vlib_get_main ();
if (a->is_add)
vnet_set_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr,
- a->link_layer_address, 6, a->is_static);
+ a->link_layer_address, 6, a->is_static,
+ a->is_no_fib_entry);
else
vnet_unset_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr,
a->link_layer_address, 6);
@@ -850,6 +864,7 @@ set_ip6_neighbor (vlib_main_t * vm,
int addr_valid = 0;
int is_del = 0;
int is_static = 0;
+ int is_no_fib_entry = 0;
u32 sw_if_index;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -865,6 +880,8 @@ set_ip6_neighbor (vlib_main_t * vm,
is_del = 1;
else if (unformat (input, "static"))
is_static = 1;
+ else if (unformat (input, "no-fib-entry"))
+ is_no_fib_entry = 1;
else
break;
}
@@ -875,7 +892,7 @@ set_ip6_neighbor (vlib_main_t * vm,
if (!is_del)
vnet_set_ip6_ethernet_neighbor (vm, sw_if_index, &addr,
mac_address, sizeof (mac_address),
- is_static);
+ is_static, is_no_fib_entry);
else
vnet_unset_ip6_ethernet_neighbor (vm, sw_if_index, &addr,
mac_address, sizeof (mac_address));
@@ -1023,7 +1040,7 @@ icmp6_neighbor_solicitation_or_advertisement (vlib_main_t * vm,
&h0->target_address,
o0->ethernet_address,
sizeof (o0->ethernet_address),
- 0);
+ 0, 0);
}
if (is_solicitation && error0 == ICMP6_ERROR_NONE)
@@ -1338,7 +1355,7 @@ icmp6_router_solicitation (vlib_main_t * vm,
&ip0->src_address,
o0->ethernet_address,
sizeof (o0->ethernet_address),
- 0);
+ 0, 0);
}
/* default is to drop */
diff --git a/src/vnet/ip/ip6_neighbor.h b/src/vnet/ip/ip6_neighbor.h
index 3d256316..ef1e84c2 100644
--- a/src/vnet/ip/ip6_neighbor.h
+++ b/src/vnet/ip/ip6_neighbor.h
@@ -28,13 +28,18 @@ typedef struct
u32 pad;
} ip6_neighbor_key_t;
+typedef enum ip6_neighbor_flags_t_
+{
+ IP6_NEIGHBOR_FLAG_STATIC = (1 << 0),
+ IP6_NEIGHBOR_FLAG_DYNAMIC = (1 << 1),
+ IP6_NEIGHBOR_FLAG_NO_FIB_ENTRY = (1 << 2),
+} __attribute__ ((packed)) ip6_neighbor_flags_t;
+
typedef struct
{
ip6_neighbor_key_t key;
u8 link_layer_address[8];
- u16 flags;
-#define IP6_NEIGHBOR_FLAG_STATIC (1 << 0)
-#define IP6_NEIGHBOR_FLAG_DYNAMIC (2 << 0)
+ ip6_neighbor_flags_t flags;
u64 cpu_time_last_updated;
fib_node_index_t fib_entry_index;
} ip6_neighbor_t;
@@ -69,7 +74,8 @@ extern int vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
ip6_address_t * a,
u8 * link_layer_address,
uword n_bytes_link_layer_address,
- int is_static);
+ int is_static,
+ int is_no_fib_entry);
extern int vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
u32 sw_if_index,
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c
index 0ca058ab..e3a1fee8 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -655,7 +655,8 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
rv = vnet_set_ip6_ethernet_neighbor
(vm, ntohl (mp->sw_if_index),
(ip6_address_t *) (mp->dst_address),
- mp->mac_address, sizeof (mp->mac_address), mp->is_static);
+ mp->mac_address, sizeof (mp->mac_address), mp->is_static,
+ mp->is_no_adj_fib);
else
rv = vnet_unset_ip6_ethernet_neighbor
(vm, ntohl (mp->sw_if_index),
@@ -671,7 +672,8 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
if (mp->is_add)
rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
- &a, mp->is_static);
+ &a, mp->is_static,
+ mp->is_no_adj_fib);
else
rv =
vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);