ip: Fix crash in ip address add on sub-int without exact-match 44/33444/5
authorPim van Pelt <pim@ipng.nl>
Tue, 10 Aug 2021 21:44:44 +0000 (23:44 +0200)
committerNeale Ranns <neale@graphiant.com>
Sat, 14 Aug 2021 12:05:39 +0000 (12:05 +0000)
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

src/vnet/interface.c
src/vnet/interface_funcs.h
src/vnet/ip/ip4_forward.c
src/vnet/ip/ip6_forward.c

index e79722d..20afce1 100644 (file)
@@ -1334,6 +1334,29 @@ vnet_sw_interface_is_nbma (vnet_main_t * vnm, u32 sw_if_index)
   return (hc->flags & VNET_HW_INTERFACE_CLASS_FLAG_NBMA);
 }
 
+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)
 {
index 3db5a2d..28312d4 100644 (file)
@@ -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)
 {
index ea67005..57ad658 100644 (file)
@@ -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,
index ba616eb..f1de446 100644 (file)
@@ -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))
     {