if (table_id != 0)
{
- ip_table_create (FIB_PROTOCOL_IP4, table_id, 0, 0);
+ ip_table_create (FIB_PROTOCOL_IP4, table_id, 0 /* is_api */,
+ 1 /* create_mfib */, 0);
ip_table_bind (FIB_PROTOCOL_IP4, *sw_if_index, table_id);
}
fib_index = fib_table_find (fproto, table_id);
mfib_index = mfib_table_find (fproto, table_id);
- if (~0 == fib_index || ~0 == mfib_index)
+ if (~0 == fib_index)
{
return (VNET_API_ERROR_NO_SUCH_FIB);
}
/* clang-format on */
fib_table_bind (fproto, sw_if_index, fib_index);
- mfib_table_bind (fproto, sw_if_index, mfib_index);
+ if (mfib_index != ~0)
+ mfib_table_bind (fproto, sw_if_index, mfib_index);
return (0);
}
vl_api_ip_table_t table;
};
+/** \brief Add / del table request - version 2
+ A table can be added multiple times, but need be deleted only once.
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param table - the FIB table to add or del
+ @param create_mfib - whether to create mfib or not
+ @param is_add - add or del
+*/
+autoreply define ip_table_add_del_v2
+{
+ u32 client_index;
+ u32 context;
+ vl_api_ip_table_t table;
+ bool create_mfib [default=true];
+ bool is_add [default=true];
+};
+
/** \brief Allocate an unused table
A table can be added multiple times.
If a large number of tables are in use (millions), this API might
extern vlib_node_registration_t ip6_inacl_node;
void ip_table_create (fib_protocol_t fproto, u32 table_id, u8 is_api,
- const u8 * name);
+ u8 create_mfib, const u8 *name);
void ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api);
if (mp->is_add)
{
- ip_table_create (fproto, table_id, 1, mp->table.name);
+ ip_table_create (fproto, table_id, 1 /* is_api */, 1 /* create_mfib */,
+ mp->table.name);
}
else
{
REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
}
+void
+vl_api_ip_table_add_del_v2_t_handler (vl_api_ip_table_add_del_v2_t *mp)
+{
+ vl_api_ip_table_add_del_v2_reply_t *rmp;
+ fib_protocol_t fproto =
+ (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ u32 table_id = ntohl (mp->table.table_id);
+ int rv = 0;
+
+ if (mp->is_add)
+ {
+ ip_table_create (fproto, table_id, 1 /* is_api */, mp->create_mfib,
+ mp->table.name);
+ }
+ else
+ {
+ ip_table_delete (fproto, table_id, 1);
+ }
+
+ REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_V2_REPLY);
+}
+
void
vl_api_ip_table_allocate_t_handler (vl_api_ip_table_allocate_t *mp)
{
if (~0 == table_id)
rv = VNET_API_ERROR_EAGAIN;
else
- ip_table_create (fproto, table_id, 1, mp->table.name);
+ ip_table_create (fproto, table_id, 1 /* is_api */, 1 /* create_mfib */,
+ mp->table.name);
REPLY_MACRO2 (VL_API_IP_TABLE_ALLOCATE_REPLY, {
clib_memcpy_fast (&rmp->table, &mp->table, sizeof (mp->table));
}
void
-ip_table_create (fib_protocol_t fproto,
- u32 table_id, u8 is_api, const u8 * name)
+ip_table_create (fib_protocol_t fproto, u32 table_id, u8 is_api,
+ u8 create_mfib, const u8 *name)
{
u32 fib_index, mfib_index;
vnet_main_t *vnm = vnet_get_main ();
* their own unicast tables.
*/
fib_index = fib_table_find (fproto, table_id);
- mfib_index = mfib_table_find (fproto, table_id);
-
/*
* Always try to re-lock in case the fib was deleted by an API call
* but was not yet freed because some other locks were held
*/
fib_table_find_or_create_and_lock_w_name (
fproto, table_id, (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI), name);
- mfib_table_find_or_create_and_lock_w_name (
- fproto, table_id, (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI), name);
+
+ if (create_mfib)
+ {
+ /* same for mfib, if needs be */
+ mfib_index = mfib_table_find (fproto, table_id);
+ mfib_table_find_or_create_and_lock_w_name (
+ fproto, table_id, (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI),
+ name);
+ }
+ else
+ mfib_index = 0;
if ((~0 == fib_index) || (~0 == mfib_index))
call_elf_section_ip_table_callbacks (vnm, table_id, 1 /* is_add */ ,
rv = VNET_API_ERROR_NO_SUCH_FIB;
else
{
+ u32 mfib_index = mfib_table_find (fproto, ntohl (mp->table.table_id));
fib_table_mark (fib_index, fproto, FIB_SOURCE_API);
- mfib_table_mark (mfib_table_find (fproto, ntohl (mp->table.table_id)),
- fproto, MFIB_SOURCE_API);
+ if (mfib_index != INDEX_INVALID)
+ mfib_table_mark (mfib_index, fproto, MFIB_SOURCE_API);
}
REPLY_MACRO (VL_API_IP_TABLE_REPLACE_BEGIN_REPLY);
}
rv = VNET_API_ERROR_NO_SUCH_FIB;
else
{
+ u32 mfib_index = mfib_table_find (fproto, ntohl (mp->table.table_id));
fib_table_sweep (fib_index, fproto, FIB_SOURCE_API);
- mfib_table_sweep (mfib_table_find
- (fproto, ntohl (mp->table.table_id)), fproto,
- MFIB_SOURCE_API);
+ if (mfib_index != INDEX_INVALID)
+ mfib_table_sweep (mfib_index, fproto, MFIB_SOURCE_API);
}
REPLY_MACRO (VL_API_IP_TABLE_REPLACE_END_REPLY);
}
vnet_main_t *vnm = vnet_get_main ();
vnet_interface_main_t *im = &vnm->interface_main;
vnet_sw_interface_t *si;
+ u32 mfib_index;
/* Shut down interfaces in this FIB / clean out intfc routes */
pool_foreach (si, im->sw_interfaces)
}
fib_table_flush (fib_index, fproto, FIB_SOURCE_API);
- mfib_table_flush (mfib_table_find (fproto, ntohl (mp->table.table_id)),
- fproto, MFIB_SOURCE_API);
+
+ mfib_index = mfib_table_find (fproto, ntohl (mp->table.table_id));
+ if (mfib_index != INDEX_INVALID)
+ mfib_table_flush (mfib_index, fproto, MFIB_SOURCE_API);
}
REPLY_MACRO (VL_API_IP_TABLE_FLUSH_REPLY);
return ret;
}
+static int
+api_ip_table_add_del_v2 (vat_main_t *vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ip_table_add_del_v2_t *mp;
+ u8 create_mfib = 1;
+ u32 table_id = ~0;
+ u8 is_ipv6 = 0;
+ u8 is_add = 1;
+ int ret = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "ipv6"))
+ is_ipv6 = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "add"))
+ is_add = 1;
+ else if (unformat (i, "table %d", &table_id))
+ ;
+ else if (unformat (i, "no-mfib"))
+ create_mfib = 0;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (~0 == table_id)
+ {
+ errmsg ("missing table-ID");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (IP_TABLE_ADD_DEL_V2, mp);
+
+ mp->table.table_id = ntohl (table_id);
+ mp->table.is_ip6 = is_ipv6;
+ mp->is_add = is_add;
+ mp->create_mfib = create_mfib;
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+
+ return ret;
+}
+
static int
api_ip_table_replace_begin (vat_main_t *vam)
{
unformat_input_t _line_input, *line_input = &_line_input;
clib_error_t *error = NULL;
u32 table_id, is_add;
+ u8 create_mfib;
u8 *name = NULL;
is_add = 1;
table_id = ~0;
+ create_mfib = 1;
/* Get a line of input. */
if (!unformat_user (main_input, unformat_line_input, line_input))
is_add = 1;
else if (unformat (line_input, "name %s", &name))
;
+ else if (unformat (line_input, "no-mfib"))
+ create_mfib = 0;
else
{
error = unformat_parse_error (line_input);
table_id = ip_table_get_unused_id (fproto);
vlib_cli_output (vm, "%u\n", table_id);
}
- ip_table_create (fproto, table_id, 0, name);
+ ip_table_create (fproto, table_id, 0 /* is_api */, create_mfib,
+ name);
}
else
{
for i in range(count):
vrf_id = i + start
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id})
self.logger.info("IPv4 VRF ID %d created" % vrf_id)
if vrf_id not in self.vrf_list:
self.vrf_list.append(vrf_id)
self.logger.info("IPv4 VRF ID %d reset finished" % vrf_id)
self.logger.debug(self.vapi.ppcli("show ip fib"))
self.logger.debug(self.vapi.ppcli("show ip neighbors"))
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id})
def create_stream(self, src_if, packet_sizes):
"""
"""
for i in range(count):
vrf_id = i + start
- self.vapi.ip_table_add_del(
+ self.vapi.ip_table_add_del_v2(
is_add=1, table={"table_id": vrf_id, "is_ip6": 1}
)
self.logger.info("IPv6 VRF ID %d created" % vrf_id)
self.vrf_list.remove(vrf_id)
if vrf_id in self.vrf_reset_list:
self.vrf_reset_list.remove(vrf_id)
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id, "is_ip6": 1})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id, "is_ip6": 1})
def create_stream(self, src_if, packet_sizes):
"""
@classmethod
def create_and_add_ip4_table(cls, i, table_id=0):
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": table_id})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": table_id})
i.set_table_ip4(table_id)
@classmethod
cls.configure_ip4_interface(i, hosts=3)
# test specific (test-multiple-vrf)
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 1})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 1})
# test specific (test-one-armed-nat44-static)
cls.pg4.generate_remote_hosts(2)
self.pg7.unconfig()
self.pg8.unconfig()
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id_in})
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id_out})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id_in})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id_out})
def test_dynamic_output_feature_vrf(self):
"""NAT44ED dynamic translation test: output-feature, VRF"""
self.pg7.unconfig()
self.pg8.unconfig()
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": new_vrf_id})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": new_vrf_id})
def test_next_src_nat(self):
"""NAT44ED On way back forward packet to nat44-in2out node."""
cls.pg1.configure_ipv4_neighbors()
cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 10})
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 20})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 10})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 20})
cls.pg4._local_ip4 = "172.16.255.1"
cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
self.pg0.unconfig_ip4()
self.pg1.unconfig_ip4()
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id1})
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id2})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id1})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id2})
self.pg0.set_table_ip4(vrf_id1)
self.pg1.set_table_ip4(vrf_id2)
self.pg0.config_ip4()
self.pg1.config_ip4()
self.pg0.resolve_arp()
self.pg1.resolve_arp()
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id1})
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id2})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id1})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id2})
def test_vrf_feature_independent(self):
"""NAT44EI tenant VRF independent address pool mode"""
self.pg1.unconfig_ip4()
self.pg2.unconfig_ip4()
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id1})
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id2})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id1})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id2})
self.pg1.set_table_ip4(vrf_id1)
self.pg2.set_table_ip4(vrf_id2)
self.pg1.config_ip4()
cls.pg1.configure_ipv4_neighbors()
cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 10})
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 20})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 10})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 20})
cls.pg4._local_ip4 = "172.16.255.1"
cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
cls.ip6_interfaces.append(cls.pg_interfaces[2])
cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
- cls.vapi.ip_table_add_del(
+ cls.vapi.ip_table_add_del_v2(
is_add=1, table={"table_id": cls.vrf1_id, "is_ip6": 1}
)
except Exception:
pass
try:
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": layer3["ip4_vrf"]})
+ self.vapi.ip_table_add_del_v2(
+ is_add=0, table={"table_id": layer3["ip4_vrf"]}
+ )
except Exception:
pass
try:
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": layer3["ip6_vrf"]})
+ self.vapi.ip_table_add_del_v2(
+ is_add=0, table={"table_id": layer3["ip6_vrf"]}
+ )
except Exception:
pass
try:
vrf_id -- vrf_id
"""
is_ipv6 = 0 if ip_version == 4 else 1
- self.vapi.ip_table_add_del(
+ self.vapi.ip_table_add_del_v2(
is_add=1, table={"table_id": vrf_id, "is_ip6": is_ipv6}
)
for sw_if_index, ip_prefix in if_idx_ip_prefixes:
class VppIpTable(VppObject):
- def __init__(self, test, table_id, is_ip6=0, register=True, name=""):
+ def __init__(
+ self, test, table_id, is_ip6=0, register=True, name="", create_mfib=True
+ ):
self._test = test
self.name = name
self.table_id = table_id
self.is_ip6 = is_ip6
self.register = register
+ self.create_mfib = True
def add_vpp_config(self):
- self._test.vapi.ip_table_add_del(
+ self._test.vapi.ip_table_add_del_v2(
is_add=1,
+ create_mfib=self.create_mfib,
table={"is_ip6": self.is_ip6, "table_id": self.table_id, "name": self.name},
)
if self.register:
return self
def remove_vpp_config(self):
- self._test.vapi.ip_table_add_del(
+ self._test.vapi.ip_table_add_del_v2(
is_add=0, table={"is_ip6": self.is_ip6, "table_id": self.table_id}
)