summaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ip')
-rw-r--r--src/vnet/ip/ip.api67
-rw-r--r--src/vnet/ip/ip_api.c190
2 files changed, 126 insertions, 131 deletions
diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api
index 69c7b88f2e6..b37530ef955 100644
--- a/src/vnet/ip/ip.api
+++ b/src/vnet/ip/ip.api
@@ -65,6 +65,59 @@ define ip_table_dump
u32 context;
};
+/** \brief IP table replace being
+
+ The use-case is that, for some unspecified reason, the control plane
+ has a very different set of entries it wants in the table than VPP
+ currently has. The CP would thus like to 'replace' VPP's current table
+ only by specifying what the new set of entries shall be, i.e. it is not
+ going to delete anything that already eixts.
+ the CP delcartes the start of this procedure with this begin_replace
+ API Call, and when it has populated all the entries it wants, it calls
+ the below end_replace API. From this point on it is of coursce free
+ to add and delete entries as usual.
+ The underlying mechanism by which VPP implements this replace is
+ purposefully left unspecified.
+
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param table - The table to resync
+*/
+autoreply define ip_table_replace_begin
+{
+ u32 client_index;
+ u32 context;
+ vl_api_ip_table_t table;
+};
+
+/** \brief IP table replace end
+
+ see replace start/
+
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param table - The table that has converged
+*/
+autoreply define ip_table_replace_end
+{
+ u32 client_index;
+ u32 context;
+ vl_api_ip_table_t table;
+};
+
+/** \brief IP table flush
+ Flush a table of all routes
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param table - The table to flush
+*/
+autoreply define ip_table_flush
+{
+ u32 client_index;
+ u32 context;
+ vl_api_ip_table_t table;
+};
+
/** \brief IP FIB table response
@param context - sender context
@param table - description of the table
@@ -957,20 +1010,6 @@ define proxy_arp_intfc_details
u32 sw_if_index;
};
-/** \brief Reset fib table request
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param vrf_id - vrf/table id of the fib table to reset
- @param is_ipv6 - an ipv6 fib to reset if non-zero, else ipv4
-*/
-autoreply define reset_fib
-{
- u32 client_index;
- u32 context;
- u32 vrf_id;
- u8 is_ipv6;
-};
-
/** \brief Set max allowed ARP or ip6 neighbor entries request
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c
index 322a3ed115a..0f9e3709643 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -92,7 +92,9 @@ _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
_(PROXY_ARP_DUMP, proxy_arp_dump) \
_(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
_(PROXY_ARP_INTFC_DUMP, proxy_arp_intfc_dump) \
-_(RESET_FIB, reset_fib) \
+_(IP_TABLE_REPLACE_BEGIN, ip_table_replace_begin) \
+_(IP_TABLE_REPLACE_END, ip_table_replace_end) \
+_(IP_TABLE_FLUSH, ip_table_flush) \
_(IP_ROUTE_ADD_DEL, ip_route_add_del) \
_(IP_TABLE_ADD_DEL, ip_table_add_del) \
_(IP_PUNT_POLICE, ip_punt_police) \
@@ -313,6 +315,7 @@ send_ip_route_details (vpe_api_main_t * am,
}
vl_api_send_msg (reg, (u8 *) mp);
+ vec_free (rpaths);
}
typedef struct apt_ip6_fib_show_ctx_t_
@@ -399,14 +402,14 @@ typedef struct vl_api_ip_mfib_dump_ctx_t_
fib_node_index_t *entries;
} vl_api_ip_mfib_dump_ctx_t;
-static int
+static walk_rc_t
mfib_route_dump_walk (fib_node_index_t fei, void *arg)
{
vl_api_ip_mfib_dump_ctx_t *ctx = arg;
vec_add1 (ctx->entries, fei);
- return (0);
+ return (WALK_CONTINUE);
}
static void
@@ -2572,137 +2575,90 @@ static void
REPLY_MACRO (VL_API_IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY);
}
-static int
-ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
+static void
+vl_api_ip_table_replace_begin_t_handler (vl_api_ip_table_replace_begin_t * mp)
{
- vnet_main_t *vnm = vnet_get_main ();
- vnet_interface_main_t *im = &vnm->interface_main;
- ip4_main_t *im4 = &ip4_main;
- static u32 *sw_if_indices_to_shut;
- fib_table_t *fib_table;
- ip4_fib_t *fib;
- u32 sw_if_index;
- int i;
- int rv = VNET_API_ERROR_NO_SUCH_FIB;
- u32 target_fib_id = ntohl (mp->vrf_id);
-
- /* *INDENT-OFF* */
- pool_foreach (fib_table, im4->fibs,
- ({
- vnet_sw_interface_t * si;
-
- fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index);
-
- if (fib->table_id != target_fib_id)
- continue;
-
- /* remove any mpls encap/decap labels */
- mpls_fib_reset_labels (fib->table_id);
-
- /* remove any proxy arps in this fib */
- vnet_proxy_arp_fib_reset (fib->table_id);
-
- /* Set the flow hash for this fib to the default */
- vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
-
- vec_reset_length (sw_if_indices_to_shut);
-
- /* Shut down interfaces in this FIB / clean out intfc routes */
- pool_foreach (si, im->sw_interfaces,
- ({
- u32 sw_if_index = si->sw_if_index;
-
- if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
- && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
- fib->index))
- vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
- }));
+ vl_api_ip_table_replace_begin_reply_t *rmp;
+ fib_protocol_t fproto;
+ u32 fib_index;
+ int rv = 0;
- for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
- sw_if_index = sw_if_indices_to_shut[i];
+ fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
- u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
- flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
- vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
+ if (INDEX_INVALID == fib_index)
+ rv = VNET_API_ERROR_NO_SUCH_FIB;
+ else
+ {
+ 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);
}
-
- fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
-
- rv = 0;
- break;
- })); /* pool_foreach (fib) */
- /* *INDENT-ON* */
-
- return rv;
+ REPLY_MACRO (VL_API_IP_TABLE_REPLACE_BEGIN_REPLY);
}
-static int
-ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
+static void
+vl_api_ip_table_replace_end_t_handler (vl_api_ip_table_replace_end_t * mp)
{
- vnet_main_t *vnm = vnet_get_main ();
- vnet_interface_main_t *im = &vnm->interface_main;
- ip6_main_t *im6 = &ip6_main;
- static u32 *sw_if_indices_to_shut;
- fib_table_t *fib_table;
- ip6_fib_t *fib;
- u32 sw_if_index;
- int i;
- int rv = VNET_API_ERROR_NO_SUCH_FIB;
- u32 target_fib_id = ntohl (mp->vrf_id);
-
- /* *INDENT-OFF* */
- pool_foreach (fib_table, im6->fibs,
- ({
- vnet_sw_interface_t * si;
-
- fib = pool_elt_at_index (im6->v6_fibs, fib_table->ft_index);
-
- if (fib->table_id != target_fib_id)
- continue;
-
- vec_reset_length (sw_if_indices_to_shut);
-
- /* Set the flow hash for this fib to the default */
- vnet_set_ip6_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
-
- /* Shut down interfaces in this FIB / clean out intfc routes */
- pool_foreach (si, im->sw_interfaces,
- ({
- if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
- fib->index)
- vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
- }));
+ vl_api_ip_table_replace_end_reply_t *rmp;
+ fib_protocol_t fproto;
+ u32 fib_index;
+ int rv = 0;
- for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
- sw_if_index = sw_if_indices_to_shut[i];
+ fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
- u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
- flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
- vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
+ if (INDEX_INVALID == fib_index)
+ rv = VNET_API_ERROR_NO_SUCH_FIB;
+ else
+ {
+ 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);
}
-
- fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
-
- rv = 0;
- break;
- })); /* pool_foreach (fib) */
- /* *INDENT-ON* */
-
- return rv;
+ REPLY_MACRO (VL_API_IP_TABLE_REPLACE_END_REPLY);
}
static void
-vl_api_reset_fib_t_handler (vl_api_reset_fib_t * mp)
+vl_api_ip_table_flush_t_handler (vl_api_ip_table_flush_t * mp)
{
- int rv;
- vl_api_reset_fib_reply_t *rmp;
+ vl_api_ip_table_flush_reply_t *rmp;
+ fib_protocol_t fproto;
+ u32 fib_index;
+ int rv = 0;
- if (mp->is_ipv6)
- rv = ip6_reset_fib_t_handler (mp);
+ fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
+
+ if (INDEX_INVALID == fib_index)
+ rv = VNET_API_ERROR_NO_SUCH_FIB;
else
- rv = ip4_reset_fib_t_handler (mp);
+ {
+ vnet_main_t *vnm = vnet_get_main ();
+ vnet_interface_main_t *im = &vnm->interface_main;
+ vnet_sw_interface_t *si;
+
+ /* Shut down interfaces in this FIB / clean out intfc routes */
+ /* *INDENT-OFF* */
+ pool_foreach (si, im->sw_interfaces,
+ ({
+ if (fib_index == fib_table_get_index_for_sw_if_index (fproto,
+ si->sw_if_index))
+ {
+ u32 flags = si->flags;
+ flags &= ~VNET_SW_INTERFACE_FLAG_ADMIN_UP;
+ vnet_sw_interface_set_flags (vnm, si->sw_if_index, flags);
+ }
+ }));
+ /* *INDENT-ON* */
+
+ 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);
+ }
- REPLY_MACRO (VL_API_RESET_FIB_REPLY);
+ REPLY_MACRO (VL_API_IP_TABLE_FLUSH_REPLY);
}
static void