tcp: Allow accepting session to send custom packet
[vpp.git] / src / vnet / interface.c
index 44ea52a..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)
 {
@@ -1610,20 +1633,58 @@ vnet_hw_interface_change_mac_address (vnet_main_t * vnm, u32 hw_if_index,
     (vnm, hw_if_index, mac_address);
 }
 
+static int
+vnet_sw_interface_check_table_same (u32 unnumbered_sw_if_index,
+                                   u32 ip_sw_if_index)
+{
+  vec_validate (ip4_main.fib_index_by_sw_if_index, unnumbered_sw_if_index);
+  vec_validate (ip4_main.mfib_index_by_sw_if_index, unnumbered_sw_if_index);
+  vec_validate (ip6_main.fib_index_by_sw_if_index, unnumbered_sw_if_index);
+  vec_validate (ip6_main.mfib_index_by_sw_if_index, unnumbered_sw_if_index);
+
+  vec_validate (ip4_main.fib_index_by_sw_if_index, ip_sw_if_index);
+  vec_validate (ip4_main.mfib_index_by_sw_if_index, ip_sw_if_index);
+  vec_validate (ip6_main.fib_index_by_sw_if_index, ip_sw_if_index);
+  vec_validate (ip6_main.mfib_index_by_sw_if_index, ip_sw_if_index);
+
+  if (ip4_main.fib_index_by_sw_if_index[unnumbered_sw_if_index] !=
+      ip4_main.fib_index_by_sw_if_index[ip_sw_if_index])
+    return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
+
+  if (ip4_main.mfib_index_by_sw_if_index[unnumbered_sw_if_index] !=
+      ip4_main.mfib_index_by_sw_if_index[ip_sw_if_index])
+    return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
+
+  if (ip6_main.fib_index_by_sw_if_index[unnumbered_sw_if_index] !=
+      ip6_main.fib_index_by_sw_if_index[ip_sw_if_index])
+    return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
+
+  if (ip6_main.mfib_index_by_sw_if_index[unnumbered_sw_if_index] !=
+      ip6_main.mfib_index_by_sw_if_index[ip_sw_if_index])
+    return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
+
+  return 0;
+}
+
 /* update the unnumbered state of an interface*/
-void
+int
 vnet_sw_interface_update_unnumbered (u32 unnumbered_sw_if_index,
                                     u32 ip_sw_if_index, u8 enable)
 {
   vnet_main_t *vnm = vnet_get_main ();
   vnet_sw_interface_t *si;
   u32 was_unnum;
+  int rv = 0;
 
   si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
   was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED);
 
   if (enable)
     {
+      rv = vnet_sw_interface_check_table_same (unnumbered_sw_if_index,
+                                              ip_sw_if_index);
+      if (rv != 0)
+       return rv;
       si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
       si->unnumbered_sw_if_index = ip_sw_if_index;
 
@@ -1660,6 +1721,8 @@ vnet_sw_interface_update_unnumbered (u32 unnumbered_sw_if_index,
       ip4_sw_interface_enable_disable (unnumbered_sw_if_index, enable);
       ip6_sw_interface_enable_disable (unnumbered_sw_if_index, enable);
     }
+
+  return 0;
 }
 
 vnet_l3_packet_type_t