diff options
-rw-r--r-- | vnet/vnet/lisp-gpe/decap.c | 21 | ||||
-rw-r--r-- | vnet/vnet/lisp-gpe/dir.dox | 26 | ||||
-rw-r--r-- | vnet/vnet/lisp-gpe/interface.c | 64 | ||||
-rw-r--r-- | vnet/vnet/lisp-gpe/ip_forward.c | 170 | ||||
-rw-r--r-- | vnet/vnet/lisp-gpe/lisp_gpe.c | 136 | ||||
-rw-r--r-- | vnet/vnet/lisp-gpe/lisp_gpe.h | 111 | ||||
-rw-r--r-- | vnet/vnet/lisp-gpe/lisp_gpe_packet.h | 6 |
7 files changed, 485 insertions, 49 deletions
diff --git a/vnet/vnet/lisp-gpe/decap.c b/vnet/vnet/lisp-gpe/decap.c index 2d051af49db..9c1fb88a6f2 100644 --- a/vnet/vnet/lisp-gpe/decap.c +++ b/vnet/vnet/lisp-gpe/decap.c @@ -12,7 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/** + * @file + * @brief L2 LISP-GPE decap code. + * + */ #include <vlib/vlib.h> #include <vnet/pg/pg.h> #include <vnet/lisp-gpe/lisp_gpe.h> @@ -118,6 +122,21 @@ incr_decap_stats (vnet_main_t * vnm, u32 cpu_index, u32 length, } } +/** + * @brief LISP-GPE decap dispatcher. + * @node lisp_gpe_input_inline + * + * LISP-GPE decap dispatcher. + * + * Decaps IP-UDP-LISP-GPE header and based on the next protocol and in the + * GPE header and the vni decides the next node to forward the packet to. + * + * @param[in] vm vlib_main_t corresponding to current thread. + * @param[in] node vlib_node_runtime_t data for this node. + * @param[in] frame vlib_frame_t whose contents should be dispatched. + * + * @return number of vectors in frame. + */ static uword lisp_gpe_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame, u8 is_v4) diff --git a/vnet/vnet/lisp-gpe/dir.dox b/vnet/vnet/lisp-gpe/dir.dox new file mode 100644 index 00000000000..afa6da9ab2c --- /dev/null +++ b/vnet/vnet/lisp-gpe/dir.dox @@ -0,0 +1,26 @@ +/* + * + * Copyright (c) 2013 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + @dir + @brief LISP-GPE code. + + An implementation of LISP-GPE as per: + rfc-6830 + draft-lewis-lisp-gpe-02 + + See file: rfc.txt + +*/
\ No newline at end of file diff --git a/vnet/vnet/lisp-gpe/interface.c b/vnet/vnet/lisp-gpe/interface.c index cc12c9ff288..abfdfdb89f2 100644 --- a/vnet/vnet/lisp-gpe/interface.c +++ b/vnet/vnet/lisp-gpe/interface.c @@ -13,6 +13,12 @@ * limitations under the License. */ +/** + * @file + * @brief Common utility functions for LISP-GPE interfaces. + * + */ + #include <vppinfra/error.h> #include <vppinfra/hash.h> #include <vnet/vnet.h> @@ -193,6 +199,22 @@ encap_two_inline (lisp_gpe_main_t * lgm, vlib_buffer_t * b0, #define is_v4_packet(_h) ((*(u8*) _h) & 0xF0) == 0x40 +/** + * @brief LISP-GPE interface TX (encap) function. + * @node lisp_gpe_interface_tx + * + * The LISP-GPE interface TX (encap) function. + * + * Looks up the associated tunnel based on the adjacency hit in the SD FIB + * and if the tunnel is multihomed it uses the flow hash to determine + * sub-tunnel, and rewrite string, to be used to encapsulate the packet. + * + * @param[in] vm vlib_main_t corresponding to the current thread. + * @param[in] node vlib_node_runtime_t data for this node. + * @param[in] frame vlib_frame_t whose contents should be dispatched. + * + * @return number of vectors in frame. + */ static uword lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) @@ -649,6 +671,23 @@ l2_process_two (lisp_gpe_main_t * lgm, vlib_buffer_t * b0, vlib_buffer_t * b1, } } +/** + * @brief LISP-GPE interface TX (encap) function for L2 overlays. + * @node l2_lisp_gpe_interface_tx + * + * The L2 LISP-GPE interface TX (encap) function. + * + * Uses bridge domain index, source and destination ethernet addresses to + * lookup tunnel. If the tunnel is multihomed a flow has is used to determine + * the sub-tunnel and therefore the rewrite string to be used to encapsulate + * the packets. + * + * @param[in] vm vlib_main_t corresponding to the current thread. + * @param[in] node vlib_node_runtime_t data for this node. + * @param[in] frame vlib_frame_t whose contents should be dispatched. + * + * @return number of vectors in frame. + */ static uword l2_lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) @@ -914,6 +953,19 @@ remove_lisp_gpe_iface (lisp_gpe_main_t * lgm, u32 hi_index, u32 dp_table, hash_unset (tuns->vni_by_sw_if_index, hi->sw_if_index); } +/** + * @brief Add/del LISP-GPE L3 interface. + * + * Creates LISP-GPE interface, sets ingress arcs from lisp_gpeX_lookup, + * installs default routes that attract all traffic with no more specific + * routes to lgpe-ipx-lookup, set egress arcs to ipx-lookup, sets + * the interface in the right vrf and enables it. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[in] a Parameters to create interface. + * + * @return number of vectors in frame. + */ static int lisp_gpe_add_del_l3_iface (lisp_gpe_main_t * lgm, vnet_lisp_gpe_add_del_iface_args_t * a) @@ -995,6 +1047,17 @@ lisp_gpe_add_del_l3_iface (lisp_gpe_main_t * lgm, return 0; } +/** + * @brief Add/del LISP-GPE L2 interface. + * + * Creates LISP-GPE interface, sets it in L2 mode in the appropriate + * bridge domain, sets egress arcs and enables it. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[in] a Parameters to create interface. + * + * @return number of vectors in frame. + */ static int lisp_gpe_add_del_l2_iface (lisp_gpe_main_t * lgm, vnet_lisp_gpe_add_del_iface_args_t * a) @@ -1056,6 +1119,7 @@ lisp_gpe_add_del_l2_iface (lisp_gpe_main_t * lgm, return 0; } +/** Add/del L2 or L3 LISP-GPE interface. */ int vnet_lisp_gpe_add_del_iface (vnet_lisp_gpe_add_del_iface_args_t * a, u32 * hw_if_indexp) diff --git a/vnet/vnet/lisp-gpe/ip_forward.c b/vnet/vnet/lisp-gpe/ip_forward.c index d8ddfd8f016..bd9951acefa 100644 --- a/vnet/vnet/lisp-gpe/ip_forward.c +++ b/vnet/vnet/lisp-gpe/ip_forward.c @@ -12,10 +12,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/** + * @file + * @brief LISP-GPE overlay IP forwarding logic and lookup data structures. + * + * Provides an implementation of a Source/Dest (SD) IP FIB that leverages the + * existing destination only FIB. Lookups are done in two stages, first the + * destination FIB looks up a packet's destination address and then if a + * an SD entry is hit, the destination adjacency will point to the second + * stage, the source FIB, where the packet's source is looked up. Note that a + * miss in the source FIB does not result in an overall SD lookup retry with + * a less specific entry from the destination FIB. + */ #include <vnet/lisp-gpe/lisp_gpe.h> -/* avoids calling route callbacks for src fib */ +/** Sets adj index for destination address in IP4 FIB. Similar to the function + * in ip4_forward but this one avoids calling route callbacks */ static void ip4_sd_fib_set_adj_index (lisp_gpe_main_t * lgm, ip4_fib_t * fib, u32 flags, u32 dst_address_u32, u32 dst_address_length, @@ -42,7 +54,8 @@ ip4_sd_fib_set_adj_index (lisp_gpe_main_t * lgm, ip4_fib_t * fib, u32 flags, fib->adj_index_by_dst_address[dst_address_length] = hash; } -/* copied from ip4_forward since it's static */ +/** Initialize the adjacency index by destination address vector for IP4 FIB. + * Copied from ip4_forward since it's static */ static void ip4_fib_init_adj_index_by_dst_address (ip_lookup_main_t * lm, ip4_fib_t * fib, u32 address_length) @@ -68,6 +81,7 @@ ip4_fib_init_adj_index_by_dst_address (ip_lookup_main_t * lm, vec_validate_init_empty (fib->old_hash_values, max_index, ~0); } +/** Add/del src route to IP4 SD FIB. */ static void ip4_sd_fib_add_del_src_route (lisp_gpe_main_t * lgm, ip4_add_del_route_args_t * a) @@ -125,6 +139,7 @@ ip4_sd_fib_add_del_src_route (lisp_gpe_main_t * lgm, ip_del_adjacency (lm, old_adj_index); } +/** Get src route from IP4 SD FIB. */ static void * ip4_sd_get_src_route (lisp_gpe_main_t * lgm, u32 src_fib_index, ip4_address_t * src, u32 address_length) @@ -145,6 +160,7 @@ typedef CLIB_PACKED (struct ip4_route { }) ip4_route_t; /* *INDENT-ON* */ +/** Remove all routes from src IP4 FIB */ void ip4_sd_fib_clear_src_fib (lisp_gpe_main_t * lgm, ip4_fib_t * fib) { @@ -186,6 +202,7 @@ ip4_sd_fib_clear_src_fib (lisp_gpe_main_t * lgm, ip4_fib_t * fib) } } +/** Test if IP4 FIB is empty */ static u8 ip4_fib_is_empty (ip4_fib_t * fib) { @@ -206,6 +223,25 @@ ip4_fib_is_empty (ip4_fib_t * fib) return fib_is_empty; } +/** + * @brief Add/del route to IP4 SD FIB. + * + * Adds/remove routes to both destination and source FIBs. Entries added + * to destination FIB are associated to adjacencies that point to the source + * FIB and store the index of the particular source FIB associated to the + * destination. Source FIBs are locally managed (see @ref lgm->ip4_src_fibs + * and @ref lgm->ip6_src_fibs), but the adjacencies are allocated out of the + * global adjacency pool. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[out] dst_prefix Destination IP4 prefix. + * @param[in] src_prefix Source IP4 prefix. + * @param[in] table_id Table id. + * @param[in] add_adj Pointer to the adjacency to be added. + * @param[in] is_add Add/del flag. + * + * @return 0 on success. + */ static int ip4_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, ip_prefix_t * src_prefix, u32 table_id, @@ -351,6 +387,21 @@ ip4_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, return 0; } +/** + * @brief Retrieve IP4 SD FIB entry. + * + * Looks up SD IP4 route by first looking up the destination in VPP's main FIB + * and subsequently the source in the src FIB. The index of the source FIB is + * stored in the dst adjacency's rewrite_header.sw_if_index. If source is 0 + * do search with 0/0 src. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[out] dst_prefix Destination IP4 prefix. + * @param[in] src_prefix Source IP4 prefix. + * @param[in] table_id Table id. + * + * @return pointer to the adjacency if route found. + */ static void * ip4_sd_fib_get_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, ip_prefix_t * src_prefix, u32 table_id) @@ -378,6 +429,7 @@ ip4_sd_fib_get_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, src_address_length); } +/** Get src route from IP6 SD FIB. */ static u32 ip6_sd_get_src_route (lisp_gpe_main_t * lgm, u32 src_fib_index, ip6_address_t * src, u32 address_length) @@ -418,7 +470,8 @@ compute_prefix_lengths_in_search_order (ip6_src_fib_t * fib) /* *INDENT-ON* */ } -/* Rewrite of ip6_add_del_route() because it uses im6 to find the fib */ +/** Add/del src route to IP6 SD FIB. Rewrite of ip6_add_del_route() because + * it uses im6 to find the FIB .*/ static void ip6_sd_fib_add_del_src_route (lisp_gpe_main_t * lgm, ip6_add_del_route_args_t * a) @@ -542,6 +595,25 @@ ip6_src_fib_init (ip6_src_fib_t * fib) } +/** + * @brief Add/del route to IP6 SD FIB. + * + * Adds/remove routes to both destination and source FIBs. Entries added + * to destination FIB are associated to adjacencies that point to the source + * FIB and store the index of the particular source FIB associated to the + * destination. Source FIBs are locally managed (see @ref lgm->ip4_src_fibs + * and @ref lgm->ip6_src_fibs), but the adjacencies are allocated out of the + * global adjacency pool. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[out] dst_prefix Destination IP6 prefix. + * @param[in] src_prefix Source IP6 prefix. + * @param[in] table_id Table id. + * @param[in] add_adj Pointer to the adjacency to be added. + * @param[in] is_add Add/del flag. + * + * @return 0 on success. + */ static int ip6_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, ip_prefix_t * src_prefix, u32 table_id, @@ -688,6 +760,21 @@ ip6_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, return 0; } +/** + * @brief Retrieve IP6 SD FIB entry. + * + * Looks up SD IP6 route by first looking up the destination in VPP's main FIB + * and subsequently the source in the src FIB. The index of the source FIB is + * stored in the dst adjacency's @ref rewrite_header.sw_if_index. If source is + * 0 do search with ::/0 src. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[out] dst_prefix Destination IP6 prefix. + * @param[in] src_prefix Source IP6 prefix. + * @param[in] table_id Table id. + * + * @return adjacency index if route found. + */ static u32 ip6_sd_fib_get_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, ip_prefix_t * src_prefix, u32 table_id) @@ -715,6 +802,25 @@ ip6_sd_fib_get_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, src_address_length); } +/** + * @brief Add/del route to IP4 or IP6 SD FIB. + * + * Adds/remove routes to both destination and source FIBs. Entries added + * to destination FIB are associated to adjacencies that point to the source + * FIB and store the index of the particular source FIB associated to the + * destination. Source FIBs are locally managed (see @ref lgm->ip4_src_fibs + * and @ref lgm->ip6_src_fibs), but the adjacencies are allocated out of the + * global adjacency pool. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[out] dst_prefix Destination IP prefix. + * @param[in] src_prefix Source IP prefix. + * @param[in] table_id Table id. + * @param[in] add_adj Pointer to the adjacency to be added. + * @param[in] is_add Add/del flag. + * + * @return 0 on success. + */ int ip_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, ip_prefix_t * src_prefix, u32 table_id, @@ -729,6 +835,21 @@ ip_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, is_add); } +/** + * @brief Retrieve IP4 or IP6 SD FIB entry. + * + * Looks up SD IP route by first looking up the destination in VPP's main FIB + * and subsequently the source in the src FIB. The index of the source FIB is + * stored in the dst adjacency's @ref rewrite_header.sw_if_index. If source is + * 0 do search with ::/0 src. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[out] dst_prefix Destination IP prefix. + * @param[in] src_prefix Source IP prefix. + * @param[in] table_id Table id. + * + * @return adjacency index if route found. + */ u32 ip_sd_fib_get_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix, ip_prefix_t * src_prefix, u32 table_id) @@ -815,6 +936,27 @@ ip4_src_fib_lookup_two (lisp_gpe_main_t * lgm, u32 src_fib_index0, } } +/** + * @brief IPv4 src lookup node. + * @node lgpe-ip4-lookup + * + * The LISP IPv4 source lookup dispatch node. + * + * This is the IPv4 source lookup dispatch node. It first looks up the + * adjacency hit in the main (destination) FIB and then uses its + * <code>rewrite_header.sw_if_index</code>to find the source FIB wherein + * the source IP is subsequently looked up. Data in the resulting adjacency + * is used to decide the next node (the lisp_gpe interface) and if a flow + * hash must be computed, when traffic can be load balanced over multiple + * tunnels. + * + * + * @param[in] vm vlib_main_t corresponding to current thread. + * @param[in] node vlib_node_runtime_t data for this node. + * @param[in] frame vlib_frame_t whose contents should be dispatched. + * + * @return number of vectors in frame. + */ always_inline uword lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) @@ -1107,6 +1249,26 @@ ip6_src_fib_lookup_two (lisp_gpe_main_t * lgm, u32 src_fib_index0, } } +/** + * @brief IPv6 src lookup node. + * @node lgpe-ip6-lookup + * + * The LISP IPv6 source lookup dispatch node. + * + * This is the IPv6 source lookup dispatch node. It first looks up the + * adjacency hit in the main (destination) FIB and then uses its + * <code>rewrite_header.sw_if_index</code>to find the source FIB wherein + * the source IP is subsequently looked up. Data in the resulting adjacency + * is used to decide the next node (the lisp_gpe interface) and if a flow + * hash must be computed, when traffic can be load balanced over multiple + * tunnels. + * + * @param[in] vm vlib_main_t corresponding to current thread. + * @param[in] node vlib_node_runtime_t data for this node. + * @param[in] frame vlib_frame_t whose contents should be dispatched. + * + * @return number of vectors in frame. + */ always_inline uword lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) diff --git a/vnet/vnet/lisp-gpe/lisp_gpe.c b/vnet/vnet/lisp-gpe/lisp_gpe.c index 60358ec8c4a..579422b484b 100644 --- a/vnet/vnet/lisp-gpe/lisp_gpe.c +++ b/vnet/vnet/lisp-gpe/lisp_gpe.c @@ -12,12 +12,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/** + * @file + * @brief Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels. + * + */ #include <vnet/lisp-gpe/lisp_gpe.h> #include <vppinfra/math.h> +/** LISP-GPE global state */ lisp_gpe_main_t lisp_gpe_main; +/** + * @brief Compute IP-UDP-GPE sub-tunnel encap/rewrite header. + * + * @param[in] t Parent of the sub-tunnel. + * @param[in] st Sub-tunnel. + * @param[in] lp Local and remote locators used in the encap header. + * + * @return 0 on success. + */ static int lisp_gpe_rewrite (lisp_gpe_tunnel_t * t, lisp_gpe_sub_tunnel_t * st, locator_pair_t * lp) @@ -103,9 +118,16 @@ weight_cmp (normalized_sub_tunnel_weights_t * a, ? a->sub_tunnel_index - b->sub_tunnel_index : (cmp > 0 ? -1 : 1)); } -/** Computes sub tunnel load balancing vector. +/** + * @brief Computes sub-tunnel load balancing vector. + * * Algorithm is identical to that used for building unequal-cost multipath - * adjacencies */ + * adjacencies. Saves normalized sub-tunnel weights and builds load-balancing + * vector consisting of list of sub-tunnel indexes replicated according to + * weight. + * + * @param[in] t Tunnel for which load balancing vector is computed. + */ static void compute_sub_tunnels_balancing_vector (lisp_gpe_tunnel_t * t) { @@ -191,6 +213,8 @@ build_lbv: t->norm_sub_tunnel_weights = nsts; } +/** Create sub-tunnels and load-balancing vector for all locator pairs + * associated to a tunnel.*/ static void create_sub_tunnels (lisp_gpe_main_t * lgm, lisp_gpe_tunnel_t * t) { @@ -222,6 +246,18 @@ _(decap_next_index) \ _(vni) \ _(action) +/** + * @brief Create/delete IP encapsulated tunnel. + * + * Builds GPE tunnel for L2 or L3 packets and populates tunnel pool + * @ref lisp_gpe_tunnel_by_key in @ref lisp_gpe_main_t. + * + * @param[in] a Tunnel parameters. + * @param[in] is_l2 Flag indicating if encapsulated content is l2. + * @param[out] tun_index_res Tunnel index. + * + * @return 0 on success. + */ static int add_del_ip_tunnel (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, u8 is_l2, u32 * tun_index_res) @@ -315,6 +351,27 @@ add_del_ip_tunnel (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, u8 is_l2, return 0; } +/** + * @brief Build IP adjacency for LISP Source/Dest FIB. + * + * Because LISP forwarding does not follow typical IP forwarding path, the + * adjacency's fields are overloaded (i.e., hijacked) to carry LISP specific + * data concerning the lisp-gpe interface the packets hitting the adjacency + * should be sent to and the tunnel that should be used. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[out] adj Adjacency to be populated. + * @param[in] table_id VRF for adjacency. + * @param[in] vni Virtual Network identifier (tenant id). + * @param[in] tun_index Tunnel index. + * @param[in] n_sub_tun Number of sub-tunnels. + * @param[in] is_negative Flag to indicate if the adjacency is for a + * negative mapping. + * @param[in] action Action to be taken for negative mapping. + * @param[in] ip_ver IP version for the adjacency. + * + * @return 0 on success. + */ static int build_ip_adjacency (lisp_gpe_main_t * lgm, ip_adjacency_t * adj, u32 table_id, u32 vni, u32 tun_index, u32 n_sub_tun, u8 is_negative, @@ -385,6 +442,18 @@ build_ip_adjacency (lisp_gpe_main_t * lgm, ip_adjacency_t * adj, u32 table_id, return 0; } +/** + * @brief Add/Delete LISP IP forwarding entry. + * + * Coordinates the creation/removal of forwarding entries for IP LISP overlay: + * creates lisp-gpe tunnel, builds tunnel customized forwarding entry and + * injects new route in Source/Dest FIB. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[in] a Parameters for building the forwarding entry. + * + * @return 0 on success. + */ static int add_del_ip_fwd_entry (lisp_gpe_main_t * lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t * a) @@ -454,6 +523,19 @@ make_mac_fib_key (BVT (clib_bihash_kv) * kv, u16 bd_index, u8 src_mac[6], kv->key[2] = 0; } +/** + * @brief Lookup L2 SD FIB entry + * + * Does a vni + dest + source lookup in the L2 LISP FIB. If the lookup fails + * it tries a second time with source set to 0 (i.e., a simple dest lookup). + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[in] bd_index Bridge domain index. + * @param[in] src_mac Source mac address. + * @param[in] dst_mac Destination mac address. + * + * @return index of mapping matching the lookup key. + */ u32 lisp_l2_fib_lookup (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6], u8 dst_mac[6]) @@ -476,6 +558,21 @@ lisp_l2_fib_lookup (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6], return ~0; } +/** + * @brief Add/del L2 SD FIB entry + * + * Inserts value in L2 FIB keyed by vni + dest + source. If entry is + * overwritten the associated value is returned. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[in] bd_index Bridge domain index. + * @param[in] src_mac Source mac address. + * @param[in] dst_mac Destination mac address. + * @param[in] val Value to add. + * @param[in] is_add Add/del flag. + * + * @return ~0 or value of overwritten entry. + */ u32 lisp_l2_fib_add_del_entry (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6], u8 dst_mac[6], u32 val, u8 is_add) @@ -506,6 +603,17 @@ l2_fib_init (lisp_gpe_main_t * lgm) L2_FIB_DEFAULT_HASH_MEMORY_SIZE); } +/** + * @brief Add/Delete LISP L2 forwarding entry. + * + * Coordinates the creation/removal of forwarding entries for L2 LISP overlay: + * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB. + * + * @param[in] lgm Reference to @ref lisp_gpe_main_t. + * @param[in] a Parameters for building the forwarding entry. + * + * @return 0 on success. + */ static int add_del_l2_fwd_entry (lisp_gpe_main_t * lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t * a) @@ -534,7 +642,16 @@ add_del_l2_fwd_entry (lisp_gpe_main_t * lgm, return 0; } - +/** + * @brief Forwarding entry create/remove dispatcher. + * + * Calls l2 or l3 forwarding entry add/del function based on input data. + * + * @param[in] a Forwarding entry parameters. + * @param[out] hw_if_indexp NOT USED + * + * @return 0 on success. + */ int vnet_lisp_gpe_add_del_fwd_entry (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, u32 * hw_if_indexp) @@ -561,6 +678,7 @@ vnet_lisp_gpe_add_del_fwd_entry (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, } } +/** CLI command to add/del forwarding entry. */ static clib_error_t * lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -691,11 +809,13 @@ done: VLIB_CLI_COMMAND (lisp_gpe_add_del_fwd_entry_command, static) = { .path = "lisp gpe tunnel", .short_help = "lisp gpe tunnel add/del vni <vni> vrf <vrf> [leid <leid>]" - "reid <reid> [lloc <sloc> rloc <rloc>] [negative action <action>]", + "reid <reid> [loc-pair <lloc> <rloc> p <priority> w <weight>] " + "[negative action <action>]", .function = lisp_gpe_add_del_fwd_entry_command_fn, }; /* *INDENT-ON* */ +/** Format LISP-GPE next indexes. */ static u8 * format_decap_next (u8 * s, va_list * args) { @@ -715,6 +835,7 @@ format_decap_next (u8 * s, va_list * args) return s; } +/** Format LISP-GPE tunnel. */ u8 * format_lisp_gpe_tunnel (u8 * s, va_list * args) { @@ -756,6 +877,7 @@ format_lisp_gpe_tunnel (u8 * s, va_list * args) return s; } +/** CLI command to show LISP-GPE tunnels. */ static clib_error_t * show_lisp_gpe_tunnel_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -785,6 +907,7 @@ VLIB_CLI_COMMAND (show_lisp_gpe_tunnel_command, static) = }; /* *INDENT-ON* */ +/** Check if LISP-GPE is enabled. */ u8 vnet_lisp_gpe_enable_disable_status (void) { @@ -793,6 +916,7 @@ vnet_lisp_gpe_enable_disable_status (void) return lgm->is_en; } +/** Enable/disable LISP-GPE. */ clib_error_t * vnet_lisp_gpe_enable_disable (vnet_lisp_gpe_enable_disable_args_t * a) { @@ -902,6 +1026,7 @@ vnet_lisp_gpe_enable_disable (vnet_lisp_gpe_enable_disable_args_t * a) return 0; } +/** CLI command to enable/disable LISP-GPE. */ static clib_error_t * lisp_gpe_enable_disable_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -939,6 +1064,7 @@ VLIB_CLI_COMMAND (enable_disable_lisp_gpe_command, static) = { }; /* *INDENT-ON* */ +/** CLI command to show LISP-GPE interfaces. */ static clib_error_t * lisp_show_iface_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -975,6 +1101,7 @@ VLIB_CLI_COMMAND (lisp_show_iface_command) = { }; /* *INDENT-ON* */ +/** Format LISP-GPE status. */ u8 * format_vnet_lisp_gpe_status (u8 * s, va_list * args) { @@ -982,6 +1109,7 @@ format_vnet_lisp_gpe_status (u8 * s, va_list * args) return format (s, "%s", lgm->is_en ? "enabled" : "disabled"); } +/** LISP-GPE init function. */ clib_error_t * lisp_gpe_init (vlib_main_t * vm) { diff --git a/vnet/vnet/lisp-gpe/lisp_gpe.h b/vnet/vnet/lisp-gpe/lisp_gpe.h index 28acab651c4..4a8bdfe7f93 100644 --- a/vnet/vnet/lisp-gpe/lisp_gpe.h +++ b/vnet/vnet/lisp-gpe/lisp_gpe.h @@ -12,6 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/** + * @file + * @brief LISP-GPE definitions. + */ #ifndef included_vnet_lisp_gpe_h #define included_vnet_lisp_gpe_h @@ -27,7 +31,7 @@ #include <vnet/lisp-cp/lisp_types.h> #include <vnet/lisp-gpe/lisp_gpe_packet.h> -/* encap headers */ +/** IP4-UDP-LISP encap header */ /* *INDENT-OFF* */ typedef CLIB_PACKED (struct { ip4_header_t ip4; /* 20 bytes */ @@ -36,6 +40,7 @@ typedef CLIB_PACKED (struct { }) ip4_udp_lisp_gpe_header_t; /* *INDENT-ON* */ +/** IP6-UDP-LISP encap header */ /* *INDENT-OFF* */ typedef CLIB_PACKED (struct { ip6_header_t ip6; /* 40 bytes */ @@ -44,6 +49,7 @@ typedef CLIB_PACKED (struct { }) ip6_udp_lisp_gpe_header_t; /* *INDENT-ON* */ +/** LISP-GPE tunnel key */ typedef struct { union @@ -60,7 +66,7 @@ typedef struct typedef struct lisp_gpe_sub_tunnel { - /* Rewrite string. $$$$ embed vnet_rewrite header */ + /** Rewrite string. $$$$ embed vnet_rewrite header */ u8 *rewrite; u32 parent_index; u32 locator_pair_index; @@ -74,42 +80,43 @@ typedef struct nomalized_sub_tunnel u8 weight; } normalized_sub_tunnel_weights_t; +/** LISP-GPE tunnel structure */ typedef struct { - /* tunnel src and dst addresses */ + /** tunnel src and dst addresses */ locator_pair_t *locator_pairs; - /* locator-pairs with best priority become sub-tunnels */ + /** locator-pairs with best priority become sub-tunnels */ lisp_gpe_sub_tunnel_t *sub_tunnels; - /* sub-tunnels load balancing vector: contains list of sub-tunnel + /** sub-tunnels load balancing vector: contains list of sub-tunnel * indexes replicated according to weight */ u32 *sub_tunnels_lbv; - /* number of entries in load balancing vector */ + /** number of entries in load balancing vector */ u32 sub_tunnels_lbv_count; - /* normalized sub tunnel weights */ + /** normalized sub tunnel weights */ normalized_sub_tunnel_weights_t *norm_sub_tunnel_weights; - /* decap next index */ + /** decap next index */ u32 decap_next_index; /* TODO remove */ ip_address_t src, dst; - /* FIB indices */ + /** FIB indices */ u32 encap_fib_index; /* tunnel partner lookup here */ u32 decap_fib_index; /* inner IP lookup here */ - /* vnet intfc hw/sw_if_index */ + /** vnet intfc hw/sw_if_index */ u32 hw_if_index; u32 sw_if_index; - /* action for 'negative' tunnels */ + /** action for 'negative' tunnels */ u8 action; - /* LISP header fields in HOST byte order */ + /** LISP header fields in HOST byte order */ u8 flags; u8 ver_res; u8 res; @@ -123,6 +130,7 @@ _(IP4_INPUT, "ip4-input") \ _(IP6_INPUT, "ip6-input") \ _(L2_INPUT, "l2-input") +/** Enum of possible next nodes post LISP-GPE decap */ typedef enum { #define _(s,n) LISP_GPE_INPUT_NEXT_##s, @@ -139,45 +147,50 @@ typedef enum LISP_GPE_N_ERROR, } lisp_gpe_error_t; -/* As a first step, reuse v4 fib. The goal of the typedef is to shield - * consumers from future updates that may result in the lisp ip4 fib diverging - * from ip4 fib */ +/** IP4 source FIB. + * As a first step, reuse v4 fib. The goal of the typedef is + * to shield consumers from future updates that may result in the lisp ip4 fib + * diverging from ip4 fib + */ typedef ip4_fib_t ip4_src_fib_t; +/** IP6 source FIB */ typedef struct ip6_src_fib { BVT (clib_bihash) ip6_lookup_table; - /* bitmap/vector of mask widths to search */ + /** bitmap/vector of mask widths to search */ uword *non_empty_dst_address_length_bitmap; u8 *prefix_lengths_in_search_order; ip6_address_t fib_masks[129]; i32 dst_address_length_refcounts[129]; - /* ip6 lookup table config parameters */ + /** ip6 lookup table config parameters */ u32 lookup_table_nbuckets; uword lookup_table_size; } ip6_src_fib_t; +/** Tunnel lookup structure for L2 and L3 tunnels */ typedef struct tunnel_lookup { - /* Lookup lisp-gpe interfaces by dp table (eg. vrf/bridge index) */ + /** Lookup lisp-gpe interfaces by dp table (eg. vrf/bridge index) */ uword *hw_if_index_by_dp_table; - /* lookup decap tunnel termination sw_if_index by vni and vice versa */ + /** lookup decap tunnel termination sw_if_index by vni and vice versa */ uword *sw_if_index_by_vni; uword *vni_by_sw_if_index; } tunnel_lookup_t; +/** LISP-GPE global state*/ typedef struct lisp_gpe_main { - /* pool of encap tunnel instances */ + /** pool of encap tunnel instances */ lisp_gpe_tunnel_t *tunnels; - /* lookup tunnel by key */ + /** lookup tunnel by key */ mhash_t lisp_gpe_tunnel_by_key; - /* Free vlib hw_if_indices */ + /** Free vlib hw_if_indices */ u32 *free_tunnel_hw_if_indices; u8 is_en; @@ -185,29 +198,29 @@ typedef struct lisp_gpe_main /* L3 data structures * ================== */ - /* Pool of src fibs that are paired with dst fibs */ + /** Pool of src fibs that are paired with dst fibs */ ip4_src_fib_t *ip4_src_fibs; ip6_src_fib_t *ip6_src_fibs; tunnel_lookup_t l3_ifaces; - /* Lookup lgpe_ipX_lookup_next by vrf */ + /** Lookup lgpe_ipX_lookup_next by vrf */ uword *lgpe_ip4_lookup_next_index_by_table_id; uword *lgpe_ip6_lookup_next_index_by_table_id; - /* next node indexes that point ip4/6 lookup to lisp gpe ip lookup */ + /** next node indexes that point ip4/6 lookup to lisp gpe ip lookup */ u32 ip4_lookup_next_lgpe_ip4_lookup; u32 ip6_lookup_next_lgpe_ip6_lookup; /* L2 data structures * ================== */ - /* l2 lisp fib */ + /** L2 LISP FIB */ BVT (clib_bihash) l2_fib; tunnel_lookup_t l2_ifaces; - /* convenience */ + /** convenience */ vlib_main_t *vlib_main; vnet_main_t *vnet_main; ip4_main_t *im4; @@ -216,6 +229,7 @@ typedef struct lisp_gpe_main ip_lookup_main_t *lm6; } lisp_gpe_main_t; +/** LISP-GPE global state*/ lisp_gpe_main_t lisp_gpe_main; always_inline lisp_gpe_main_t * @@ -231,25 +245,31 @@ extern vlib_node_registration_t lisp_gpe_ip6_input_node; u8 *format_lisp_gpe_header_with_length (u8 * s, va_list * args); +/** Arguments to add an L2/L3 LISP-GPE interface*/ typedef struct { u8 is_add; union { - /* vrf */ + /** vrf */ u32 table_id; - /* bridge domain */ + /** bridge domain */ u16 bd_id; - /* generic access */ + /** generic access */ u32 dp_table; }; u8 is_l2; - u32 vni; /* host byte order */ + + /** virtual network identifier in host byte order */ + u32 vni; } vnet_lisp_gpe_add_del_iface_args_t; +/** Read LISP-GPE status */ u8 vnet_lisp_gpe_enable_disable_status (void); + +/** Add/del LISP-GPE interface. */ int vnet_lisp_gpe_add_del_iface (vnet_lisp_gpe_add_del_iface_args_t * a, u32 * hw_if_indexp); @@ -262,37 +282,48 @@ typedef struct clib_error_t * vnet_lisp_gpe_enable_disable (vnet_lisp_gpe_enable_disable_args_t * a); +/** */ typedef struct { u8 is_add; - /* type of mapping */ + /** type of mapping */ u8 is_negative; + + /** action for negative mappings */ u8 action; - /* local and remote eids */ + /** local eid */ gid_address_t lcl_eid; + + /** remote eid */ gid_address_t rmt_eid; - /* vector of locator pairs */ + /** vector of locator pairs */ locator_pair_t *locator_pairs; - /* FIB indices to lookup remote locator at encap and inner IP at decap */ + /** FIB index to lookup remote locator at encap */ u32 encap_fib_index; + + /** FIB index to lookup inner IP at decap */ u32 decap_fib_index; - u32 decap_next_index; /* TODO is this really needed? */ + /* TODO remove */ + u32 decap_next_index; - /* VNI/tenant id in HOST byte order */ + /** VNI/tenant id in HOST byte order */ u32 vni; - /* vrf or bd where fwd entry should be inserted */ + /** vrf or bd where fwd entry should be inserted */ union { + /** table (vrf) id */ u32 table_id; + + /** bridge domain id */ u16 bd_id; - /* generic access */ + /** generic access */ u32 dp_table; }; } vnet_lisp_gpe_add_del_fwd_entry_args_t; @@ -321,7 +352,7 @@ typedef enum lgpe_ip4_lookup_next LGPE_IP4_LOOKUP_N_NEXT, } lgpe_ip4_lookup_next_t; -#define foreach_lgpe_ip6_lookup_next \ +#define foreach_lgpe_ip6_lookup_next \ _(DROP, "error-drop") \ _(LISP_CP_LOOKUP, "lisp-cp-lookup") diff --git a/vnet/vnet/lisp-gpe/lisp_gpe_packet.h b/vnet/vnet/lisp-gpe/lisp_gpe_packet.h index 352cc5d3b0e..62ac9bd7015 100644 --- a/vnet/vnet/lisp-gpe/lisp_gpe_packet.h +++ b/vnet/vnet/lisp-gpe/lisp_gpe_packet.h @@ -12,6 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/** + * @file + * @brief LISP-GPE packet header structure + * + */ #ifndef included_lisp_gpe_packet_h #define included_lisp_gpe_packet_h @@ -91,6 +96,7 @@ * 0x4: Network Service Header */ +/** LISP-GPE header */ typedef struct { u8 flags; |