+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*/
+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;
+
+ ip4_main.lookup_main.if_address_pool_index_by_sw_if_index
+ [unnumbered_sw_if_index] =
+ ip4_main.
+ lookup_main.if_address_pool_index_by_sw_if_index[ip_sw_if_index];
+ ip6_main.
+ lookup_main.if_address_pool_index_by_sw_if_index
+ [unnumbered_sw_if_index] =
+ ip6_main.
+ lookup_main.if_address_pool_index_by_sw_if_index[ip_sw_if_index];
+ }
+ else
+ {
+ /*
+ * Unless the interface is actually unnumbered, don't
+ * smash e.g. if_address_pool_index_by_sw_if_index
+ */
+ if (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
+ {
+ si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
+ si->unnumbered_sw_if_index = (u32) ~0;
+
+ ip4_main.lookup_main
+ .if_address_pool_index_by_sw_if_index[unnumbered_sw_if_index] = ~0;
+ ip6_main.lookup_main
+ .if_address_pool_index_by_sw_if_index[unnumbered_sw_if_index] = ~0;
+ }
+ }
+
+ if (was_unnum != (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
+ {
+ ip4_sw_interface_enable_disable (unnumbered_sw_if_index, enable);
+ ip6_sw_interface_enable_disable (unnumbered_sw_if_index, enable);
+ }
+
+ return 0;
+}
+