diff options
Diffstat (limited to 'src/vnet/ip')
-rw-r--r-- | src/vnet/ip/ip.api | 67 | ||||
-rw-r--r-- | src/vnet/ip/ip_api.c | 190 |
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 |