summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPim van Pelt <pim@ipng.nl>2021-08-10 23:44:44 +0200
committerNeale Ranns <neale@graphiant.com>2021-08-14 12:05:39 +0000
commit76b19ceafcf892b56a679d3d7fe5c6f4b93f7de7 (patch)
tree947c5d5f7dba6a2abc02ac63fc1772de5b6f0f8c
parent2a1783fd6ae7e17c994010fca414c180eb48bc40 (diff)
ip: Fix crash in ip address add on sub-int without exact-match
Type: fix Creating a sub-int without exact-match set, and subsequently adding an IPv4 or IPv6 address will crash VPP. This fix catches this situation and refuses to allow the caller to add an IPv4 or IPv6 address on an ethernet sub-int that does not have exact-match set. TESTED: Before this change, the following crashes VPP: ``` DBGvpp# cre sub TenGigabitEthernet3/0/0 1 dot1q 10 TenGigabitEthernet3/0/0.1 DBGvpp# set interface ip address TenGigabitEthernet3/0/0.1 2001:db8::1/64 <crash> ``` After the change, VPP refuses to act: ``` DBGvpp# cre sub TenGigabitEthernet3/0/0 1 dot1q 10 TenGigabitEthernet3/0/0.1 DBGvpp# set interface ip address TenGigabitEthernet3/0/0.1 192.0.2.1/30 set interface ip address: sub-interface without exact-match doesn't support IP addressing DBGvpp# set interface ip address TenGigabitEthernet3/0/0.1 2001:db8:1/64 set interface ip address: sub-interface without exact-match doesn't support IP addressing ``` Signed-off-by: Pim van Pelt <pim@ipng.nl> Change-Id: I42997db314225cd186ebb54013b5717ace7f7bd6
-rw-r--r--src/vnet/interface.c23
-rw-r--r--src/vnet/interface_funcs.h3
-rw-r--r--src/vnet/ip/ip4_forward.c9
-rw-r--r--src/vnet/ip/ip6_forward.c9
4 files changed, 32 insertions, 12 deletions
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index e79722d0461..20afce1fb6e 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -1335,6 +1335,29 @@ vnet_sw_interface_is_nbma (vnet_main_t * vnm, u32 sw_if_index)
}
clib_error_t *
+vnet_sw_interface_supports_addressing (vnet_main_t *vnm, u32 sw_if_index)
+{
+ if (sw_if_index == 0)
+ {
+ return clib_error_create (
+ "local0 interface doesn't support IP addressing");
+ }
+
+ if (vnet_sw_interface_is_sub (vnm, sw_if_index))
+ {
+ vnet_sw_interface_t *si;
+ si = vnet_get_sw_interface_or_null (vnm, sw_if_index);
+ if (si && si->type == VNET_SW_INTERFACE_TYPE_SUB &&
+ si->sub.eth.flags.exact_match == 0)
+ {
+ return clib_error_create (
+ "sub-interface without exact-match doesn't support IP addressing");
+ }
+ }
+ return NULL;
+}
+
+clib_error_t *
vnet_interface_init (vlib_main_t * vm)
{
vnet_main_t *vnm = vnet_get_main ();
diff --git a/src/vnet/interface_funcs.h b/src/vnet/interface_funcs.h
index 3db5a2d8c11..28312d4c85a 100644
--- a/src/vnet/interface_funcs.h
+++ b/src/vnet/interface_funcs.h
@@ -350,6 +350,9 @@ vnet_sw_interface_is_sub (vnet_main_t *vnm, u32 sw_if_index)
return (sw->sw_if_index != sw->sup_sw_if_index);
}
+clib_error_t *vnet_sw_interface_supports_addressing (vnet_main_t *vnm,
+ u32 sw_if_index);
+
always_inline vlib_frame_t *
vnet_get_frame_to_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
{
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index ea67005176f..57ad658b83f 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -653,12 +653,9 @@ ip4_add_del_interface_address_internal (vlib_main_t * vm,
u32 if_address_index;
ip4_address_fib_t ip4_af, *addr_fib = 0;
- /* local0 interface doesn't support IP addressing */
- if (sw_if_index == 0)
- {
- return
- clib_error_create ("local0 interface doesn't support IP addressing");
- }
+ error = vnet_sw_interface_supports_addressing (vnm, sw_if_index);
+ if (error)
+ return error;
vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
ip4_addr_fib_init (&ip4_af, address,
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index ba616ebc7c7..f1de446a504 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -308,12 +308,9 @@ ip6_add_del_interface_address (vlib_main_t * vm,
ip6_address_fib_t ip6_af, *addr_fib = 0;
const ip6_address_t *ll_addr;
- /* local0 interface doesn't support IP addressing */
- if (sw_if_index == 0)
- {
- return
- clib_error_create ("local0 interface doesn't support IP addressing");
- }
+ error = vnet_sw_interface_supports_addressing (vnm, sw_if_index);
+ if (error)
+ return error;
if (ip6_address_is_link_local_unicast (address))
{