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>
This commit is contained in:
committed by
Damjan Marion
parent
8082380922
commit
b3b2de71ce
@@ -7132,6 +7132,7 @@ api_ip_neighbor_add_del (vat_main_t * vam)
|
||||
u8 sw_if_index_set = 0;
|
||||
u8 is_add = 1;
|
||||
u8 is_static = 0;
|
||||
u8 is_no_fib_entry = 0;
|
||||
u8 mac_address[6];
|
||||
u8 mac_set = 0;
|
||||
u8 v4_address_set = 0;
|
||||
@@ -7158,6 +7159,8 @@ api_ip_neighbor_add_del (vat_main_t * vam)
|
||||
sw_if_index_set = 1;
|
||||
else if (unformat (i, "is_static"))
|
||||
is_static = 1;
|
||||
else if (unformat (i, "no-fib-entry"))
|
||||
is_no_fib_entry = 1;
|
||||
else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
|
||||
v4_address_set = 1;
|
||||
else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
|
||||
@@ -7191,6 +7194,7 @@ api_ip_neighbor_add_del (vat_main_t * vam)
|
||||
mp->sw_if_index = ntohl (sw_if_index);
|
||||
mp->is_add = is_add;
|
||||
mp->is_static = is_static;
|
||||
mp->is_no_adj_fib = is_no_fib_entry;
|
||||
if (mac_set)
|
||||
clib_memcpy (mp->mac_address, mac_address, 6);
|
||||
if (v6_address_set)
|
||||
|
||||
+36
-25
@@ -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 = ðernet_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* */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
+38
-21
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -593,6 +593,9 @@ static void *vl_api_ip_neighbor_add_del_t_print
|
||||
if (mp->is_static)
|
||||
s = format (s, "is_static ");
|
||||
|
||||
if (mp->is_no_adj_fib)
|
||||
s = format (s, "is_no_fib_entry ");
|
||||
|
||||
if (memcmp (mp->mac_address, null_mac, 6))
|
||||
s = format (s, "mac %U ", format_ethernet_address, mp->mac_address);
|
||||
|
||||
|
||||
+26
-2
@@ -6,8 +6,8 @@ from socket import AF_INET6
|
||||
from framework import VppTestCase, VppTestRunner
|
||||
from vpp_sub_interface import VppSubInterface, VppDot1QSubint
|
||||
from vpp_pg_interface import is_ipv6_misc
|
||||
from vpp_neighbor import find_nbr
|
||||
from vpp_ip_route import VppIpRoute, VppRoutePath
|
||||
from vpp_ip_route import VppIpRoute, VppRoutePath, find_route
|
||||
from vpp_neighbor import find_nbr, VppNeighbor
|
||||
|
||||
from scapy.packet import Raw
|
||||
from scapy.layers.l2 import Ether, Dot1Q
|
||||
@@ -351,6 +351,30 @@ class TestIPv6(TestIPv6ND):
|
||||
self.send_and_assert_no_replies(self.pg0, pkts,
|
||||
"No response to NS for unknown target")
|
||||
|
||||
#
|
||||
# A neighbor entry that has no associated FIB-entry
|
||||
#
|
||||
self.pg0.generate_remote_hosts(4)
|
||||
nd_entry = VppNeighbor(self,
|
||||
self.pg0.sw_if_index,
|
||||
self.pg0.remote_hosts[2].mac,
|
||||
self.pg0.remote_hosts[2].ip6,
|
||||
af=AF_INET6,
|
||||
is_no_fib_entry=1)
|
||||
nd_entry.add_vpp_config()
|
||||
|
||||
#
|
||||
# check we have the neighbor, but no route
|
||||
#
|
||||
self.assertTrue(find_nbr(self,
|
||||
self.pg0.sw_if_index,
|
||||
self.pg0._remote_hosts[2].ip6,
|
||||
inet=AF_INET6))
|
||||
self.assertFalse(find_route(self,
|
||||
self.pg0._remote_hosts[2].ip6,
|
||||
128,
|
||||
inet=AF_INET6))
|
||||
|
||||
def validate_ra(self, intf, rx, dst_ip=None, mtu=9000, pi_opt=None):
|
||||
if not dst_ip:
|
||||
dst_ip = intf.remote_ip6
|
||||
|
||||
+21
-2
@@ -5,7 +5,7 @@ from socket import AF_INET, AF_INET6, inet_pton
|
||||
|
||||
from framework import VppTestCase, VppTestRunner
|
||||
from vpp_neighbor import VppNeighbor, find_nbr
|
||||
from vpp_ip_route import VppIpRoute, VppRoutePath
|
||||
from vpp_ip_route import VppIpRoute, VppRoutePath, find_route
|
||||
|
||||
from scapy.packet import Raw
|
||||
from scapy.layers.l2 import Ether, ARP
|
||||
@@ -115,7 +115,7 @@ class ARPTestCase(VppTestCase):
|
||||
#
|
||||
# Generate some hosts on the LAN
|
||||
#
|
||||
self.pg1.generate_remote_hosts(4)
|
||||
self.pg1.generate_remote_hosts(5)
|
||||
|
||||
#
|
||||
# Send IP traffic to one of these unresolved hosts.
|
||||
@@ -301,6 +301,25 @@ class ARPTestCase(VppTestCase):
|
||||
"ARP req for non-local source")
|
||||
|
||||
#
|
||||
# A neighbor entry that has no associated FIB-entry
|
||||
#
|
||||
arp_no_fib = VppNeighbor(self,
|
||||
self.pg1.sw_if_index,
|
||||
self.pg1.remote_hosts[4].mac,
|
||||
self.pg1.remote_hosts[4].ip4,
|
||||
is_no_fib_entry=1)
|
||||
arp_no_fib.add_vpp_config()
|
||||
|
||||
#
|
||||
# check we have the neighbor, but no route
|
||||
#
|
||||
self.assertTrue(find_nbr(self,
|
||||
self.pg1.sw_if_index,
|
||||
self.pg1._remote_hosts[4].ip4))
|
||||
self.assertFalse(find_route(self,
|
||||
self.pg1._remote_hosts[4].ip4,
|
||||
32))
|
||||
#
|
||||
# cleanup
|
||||
#
|
||||
dyn_arp.remove_vpp_config()
|
||||
|
||||
+44
-34
@@ -4,14 +4,31 @@
|
||||
object abstractions for representing IP routes in VPP
|
||||
"""
|
||||
|
||||
import socket
|
||||
from vpp_object import *
|
||||
from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
|
||||
|
||||
# from vnet/vnet/mpls/mpls_types.h
|
||||
MPLS_IETF_MAX_LABEL = 0xfffff
|
||||
MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
|
||||
|
||||
|
||||
def find_route(test, ip_addr, len, table_id=0, inet=AF_INET):
|
||||
if inet == AF_INET:
|
||||
s = 4
|
||||
routes = test.vapi.ip_fib_dump()
|
||||
else:
|
||||
s = 16
|
||||
routes = test.vapi.ip6_fib_dump()
|
||||
|
||||
route_addr = inet_pton(inet, ip_addr)
|
||||
for e in routes:
|
||||
if route_addr == e.address[:s] \
|
||||
and len == e.address_length \
|
||||
and table_id == e.table_id:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class VppRoutePath(object):
|
||||
|
||||
def __init__(
|
||||
@@ -27,9 +44,9 @@ class VppRoutePath(object):
|
||||
self.nh_via_label = nh_via_label
|
||||
self.nh_labels = labels
|
||||
if is_ip6:
|
||||
self.nh_addr = socket.inet_pton(socket.AF_INET6, nh_addr)
|
||||
self.nh_addr = inet_pton(AF_INET6, nh_addr)
|
||||
else:
|
||||
self.nh_addr = socket.inet_pton(socket.AF_INET, nh_addr)
|
||||
self.nh_addr = inet_pton(AF_INET, nh_addr)
|
||||
|
||||
|
||||
class VppMRoutePath(VppRoutePath):
|
||||
@@ -56,17 +73,18 @@ class VppIpRoute(VppObject):
|
||||
self.is_local = is_local
|
||||
self.is_unreach = is_unreach
|
||||
self.is_prohibit = is_prohibit
|
||||
self.dest_addr_p = dest_addr
|
||||
if is_ip6:
|
||||
self.dest_addr = socket.inet_pton(socket.AF_INET6, dest_addr)
|
||||
self.dest_addr = inet_pton(AF_INET6, dest_addr)
|
||||
else:
|
||||
self.dest_addr = socket.inet_pton(socket.AF_INET, dest_addr)
|
||||
self.dest_addr = inet_pton(AF_INET, dest_addr)
|
||||
|
||||
def add_vpp_config(self):
|
||||
if self.is_local or self.is_unreach or self.is_prohibit:
|
||||
self._test.vapi.ip_add_del_route(
|
||||
self.dest_addr,
|
||||
self.dest_addr_len,
|
||||
socket.inet_pton(socket.AF_INET6, "::"),
|
||||
inet_pton(AF_INET6, "::"),
|
||||
0xffffffff,
|
||||
is_local=self.is_local,
|
||||
is_unreach=self.is_unreach,
|
||||
@@ -93,7 +111,7 @@ class VppIpRoute(VppObject):
|
||||
self._test.vapi.ip_add_del_route(
|
||||
self.dest_addr,
|
||||
self.dest_addr_len,
|
||||
socket.inet_pton(socket.AF_INET6, "::"),
|
||||
inet_pton(AF_INET6, "::"),
|
||||
0xffffffff,
|
||||
is_local=self.is_local,
|
||||
is_unreach=self.is_unreach,
|
||||
@@ -111,28 +129,20 @@ class VppIpRoute(VppObject):
|
||||
is_add=0)
|
||||
|
||||
def query_vpp_config(self):
|
||||
dump = self._test.vapi.ip_fib_dump()
|
||||
for e in dump:
|
||||
if self.dest_addr == e.address \
|
||||
and self.dest_addr_len == e.address_length \
|
||||
and self.table_id == e.table_id:
|
||||
return True
|
||||
return False
|
||||
return find_route(self._test,
|
||||
self.dest_addr_p,
|
||||
self.dest_addr_len,
|
||||
self.table_id,
|
||||
inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
|
||||
|
||||
def __str__(self):
|
||||
return self.object_id()
|
||||
|
||||
def object_id(self):
|
||||
if self.is_ip6:
|
||||
return ("%d:%s/%d"
|
||||
% (self.table_id,
|
||||
socket.inet_ntop(socket.AF_INET6, self.dest_addr),
|
||||
self.dest_addr_len))
|
||||
else:
|
||||
return ("%d:%s/%d"
|
||||
% (self.table_id,
|
||||
socket.inet_ntop(socket.AF_INET, self.dest_addr),
|
||||
self.dest_addr_len))
|
||||
return ("%d:%s/%d"
|
||||
% (self.table_id,
|
||||
self.dest_addr_p,
|
||||
self.dest_addr_len))
|
||||
|
||||
|
||||
class VppIpMRoute(VppObject):
|
||||
@@ -150,11 +160,11 @@ class VppIpMRoute(VppObject):
|
||||
self.is_ip6 = is_ip6
|
||||
|
||||
if is_ip6:
|
||||
self.grp_addr = socket.inet_pton(socket.AF_INET6, grp_addr)
|
||||
self.src_addr = socket.inet_pton(socket.AF_INET6, src_addr)
|
||||
self.grp_addr = inet_pton(AF_INET6, grp_addr)
|
||||
self.src_addr = inet_pton(AF_INET6, src_addr)
|
||||
else:
|
||||
self.grp_addr = socket.inet_pton(socket.AF_INET, grp_addr)
|
||||
self.src_addr = socket.inet_pton(socket.AF_INET, src_addr)
|
||||
self.grp_addr = inet_pton(AF_INET, grp_addr)
|
||||
self.src_addr = inet_pton(AF_INET, src_addr)
|
||||
|
||||
def add_vpp_config(self):
|
||||
for path in self.paths:
|
||||
@@ -221,14 +231,14 @@ class VppIpMRoute(VppObject):
|
||||
if self.is_ip6:
|
||||
return ("%d:(%s,%s/%d)"
|
||||
% (self.table_id,
|
||||
socket.inet_ntop(socket.AF_INET6, self.src_addr),
|
||||
socket.inet_ntop(socket.AF_INET6, self.grp_addr),
|
||||
inet_ntop(AF_INET6, self.src_addr),
|
||||
inet_ntop(AF_INET6, self.grp_addr),
|
||||
self.grp_addr_len))
|
||||
else:
|
||||
return ("%d:(%s,%s/%d)"
|
||||
% (self.table_id,
|
||||
socket.inet_ntop(socket.AF_INET, self.src_addr),
|
||||
socket.inet_ntop(socket.AF_INET, self.grp_addr),
|
||||
inet_ntop(AF_INET, self.src_addr),
|
||||
inet_ntop(AF_INET, self.grp_addr),
|
||||
self.grp_addr_len))
|
||||
|
||||
|
||||
@@ -261,7 +271,7 @@ class VppMplsIpBind(VppObject):
|
||||
def __init__(self, test, local_label, dest_addr, dest_addr_len,
|
||||
table_id=0, ip_table_id=0):
|
||||
self._test = test
|
||||
self.dest_addr = socket.inet_pton(socket.AF_INET, dest_addr)
|
||||
self.dest_addr = inet_pton(AF_INET, dest_addr)
|
||||
self.dest_addr_len = dest_addr_len
|
||||
self.local_label = local_label
|
||||
self.table_id = table_id
|
||||
@@ -298,7 +308,7 @@ class VppMplsIpBind(VppObject):
|
||||
% (self.table_id,
|
||||
self.local_label,
|
||||
self.ip_table_id,
|
||||
socket.inet_ntop(socket.AF_INET, self.dest_addr),
|
||||
inet_ntop(AF_INET, self.dest_addr),
|
||||
self.dest_addr_len))
|
||||
|
||||
|
||||
|
||||
@@ -31,12 +31,13 @@ class VppNeighbor(VppObject):
|
||||
"""
|
||||
|
||||
def __init__(self, test, sw_if_index, mac_addr, nbr_addr,
|
||||
af=AF_INET, is_static=False):
|
||||
af=AF_INET, is_static=False, is_no_fib_entry=False):
|
||||
self._test = test
|
||||
self.sw_if_index = sw_if_index
|
||||
self.mac_addr = mactobinary(mac_addr)
|
||||
self.af = af
|
||||
self.is_static = is_static
|
||||
self.is_no_fib_entry = is_no_fib_entry
|
||||
self.nbr_addr = inet_pton(af, nbr_addr)
|
||||
|
||||
def add_vpp_config(self):
|
||||
@@ -46,7 +47,8 @@ class VppNeighbor(VppObject):
|
||||
self.nbr_addr,
|
||||
is_add=1,
|
||||
is_ipv6=1 if AF_INET6 == self.af else 0,
|
||||
is_static=self.is_static)
|
||||
is_static=self.is_static,
|
||||
is_no_adj_fib=self.is_no_fib_entry)
|
||||
self._test.registry.register(self, self._test.logger)
|
||||
|
||||
def remove_vpp_config(self):
|
||||
|
||||
@@ -663,6 +663,7 @@ class VppPapiProvider(object):
|
||||
is_add=1,
|
||||
is_ipv6=0,
|
||||
is_static=0,
|
||||
is_no_adj_fib=0,
|
||||
):
|
||||
""" Add neighbor MAC to IPv4 or IPv6 address.
|
||||
|
||||
@@ -672,6 +673,7 @@ class VppPapiProvider(object):
|
||||
:param is_add: (Default value = 1)
|
||||
:param is_ipv6: (Default value = 0)
|
||||
:param is_static: (Default value = 0)
|
||||
:param is_no_adj_fib: (Default value = 0)
|
||||
"""
|
||||
|
||||
return self.api(
|
||||
@@ -680,6 +682,7 @@ class VppPapiProvider(object):
|
||||
'is_add': is_add,
|
||||
'is_ipv6': is_ipv6,
|
||||
'is_static': is_static,
|
||||
'is_no_adj_fib': is_no_adj_fib,
|
||||
'mac_address': mac_address,
|
||||
'dst_address': dst_address
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user