diff options
-rw-r--r-- | doxygen/doxygen.cfg | 1 | ||||
-rw-r--r-- | vlib/vlib/buffer_node.h | 47 | ||||
-rw-r--r-- | vlib/vlib/node_funcs.h | 93 | ||||
-rw-r--r-- | vnet/vnet/ip/ip4_forward.c | 36 |
4 files changed, 176 insertions, 1 deletions
diff --git a/doxygen/doxygen.cfg b/doxygen/doxygen.cfg index ec4312c9..cc10a9d4 100644 --- a/doxygen/doxygen.cfg +++ b/doxygen/doxygen.cfg @@ -229,6 +229,7 @@ TAB_SIZE = 8 # newlines. ALIASES = +ALIASES += "node=@xrefitem nodes \"Node Identifier\" \"Node Identifiers\" @c " # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" diff --git a/vlib/vlib/buffer_node.h b/vlib/vlib/buffer_node.h index 0fa5c809..5985ccf5 100644 --- a/vlib/vlib/buffer_node.h +++ b/vlib/vlib/buffer_node.h @@ -40,6 +40,33 @@ #ifndef included_vlib_buffer_node_h #define included_vlib_buffer_node_h +/** \file + vlib buffer/node functions +*/ + +/** \brief Finish enqueueing two buffers forward in the graph. + Standard dual loop boilerplate element. This is a MACRO, + with MULTIPLE SIDE EFFECTS. In the ideal case, + <code>next_index == next0 == next1</code>, + which means that the speculative enqueue at the top of the dual loop + has correctly dealt with both packets. In that case, the macro does + nothing at all. + + @param vm vlib_main_t pointer, varies by thread + @param node current node vlib_node_runtime_t pointer + @param next_index speculated next index used for both packets + @param to_next speculated vector pointer used for both packets + @param n_left_to_next number of slots left in speculated vector + @param bi0 first buffer index + @param bi1 second buffer index + @param next0 actual next index to be used for the first packet + @param next1 actual next index to be used for the second packet + + @return @c next_index -- speculative next index to be used for future packets + @return @c to_next -- speculative frame to be used for future packets + @return @c n_left_to_next -- number of slots left in speculative frame +*/ + #define vlib_validate_buffer_enqueue_x2(vm,node,next_index,to_next,n_left_to_next,bi0,bi1,next0,next1) \ do { \ int enqueue_code = (next0 != next_index) + 2*(next1 != next_index); \ @@ -80,6 +107,26 @@ do { \ } \ } while (0) +/** \brief Finish enqueueing one buffer forward in the graph. + Standard single loop boilerplate element. This is a MACRO, + with MULTIPLE SIDE EFFECTS. In the ideal case, + <code>next_index == next0</code>, + which means that the speculative enqueue at the top of the single loop + has correctly dealt with the packet in hand. In that case, the macro does + nothing at all. + + @param vm vlib_main_t pointer, varies by thread + @param node current node vlib_node_runtime_t pointer + @param next_index speculated next index used for both packets + @param to_next speculated vector pointer used for both packets + @param n_left_to_next number of slots left in speculated vector + @param bi0 first buffer index + @param next0 actual next index to be used for the first packet + + @return @c next_index -- speculative next index to be used for future packets + @return @c to_next -- speculative frame to be used for future packets + @return @c n_left_to_next -- number of slots left in speculative frame +*/ #define vlib_validate_buffer_enqueue_x1(vm,node,next_index,to_next,n_left_to_next,bi0,next0) \ do { \ if (PREDICT_FALSE (next0 != next_index)) \ diff --git a/vlib/vlib/node_funcs.h b/vlib/vlib/node_funcs.h index 18342e26..f567ce54 100644 --- a/vlib/vlib/node_funcs.h +++ b/vlib/vlib/node_funcs.h @@ -37,15 +37,34 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/** \file + vlib node functions +*/ + + #ifndef included_vlib_node_funcs_h #define included_vlib_node_funcs_h #include <vppinfra/fifo.h> +/** \brief Get vlib node by index. + @warning This function will ASSERT if @c i is out of range. + @param vm vlib_main_t pointer, varies by thread + @param i node index. + @return pointer to the requested vlib_node_t. +*/ + always_inline vlib_node_t * vlib_get_node (vlib_main_t * vm, u32 i) { return vec_elt (vm->node_main.nodes, i); } +/** \brief Get vlib node by graph arc (next) index. + @param vm vlib_main_t pointer, varies by thread + @param node_index index of original node + @param next_index graph arc index + @return pointer to the vlib_node_t at the end of the indicated arc +*/ + always_inline vlib_node_t * vlib_get_next_node (vlib_main_t * vm, u32 node_index, u32 next_index) { @@ -57,6 +76,12 @@ vlib_get_next_node (vlib_main_t * vm, u32 node_index, u32 next_index) return vlib_get_node (vm, n->next_nodes[next_index]); } +/** \brief Get node runtime by node index. + @param vm vlib_main_t pointer, varies by thread + @param node_index index of node + @return pointer to the indicated vlib_node_runtime_t +*/ + always_inline vlib_node_runtime_t * vlib_node_get_runtime (vlib_main_t * vm, u32 node_index) { @@ -72,6 +97,12 @@ vlib_node_get_runtime (vlib_main_t * vm, u32 node_index) } } +/** \brief Get node runtime private data by node index. + @param vm vlib_main_t pointer, varies by thread + @param node_index index of the node + @return pointer to the indicated vlib_node_runtime_t private data +*/ + always_inline void * vlib_node_get_runtime_data (vlib_main_t * vm, u32 node_index) { @@ -79,6 +110,13 @@ vlib_node_get_runtime_data (vlib_main_t * vm, u32 node_index) return r->runtime_data; } +/** \brief Set node runtime private data. + @param vm vlib_main_t pointer, varies by thread + @param node_index index of the node + @param runtime_data arbitrary runtime private data + @param n_runtime_data_bytes size of runtime private data +*/ + always_inline void vlib_node_set_runtime_data (vlib_main_t * vm, u32 node_index, void * runtime_data, @@ -96,6 +134,11 @@ vlib_node_set_runtime_data (vlib_main_t * vm, u32 node_index, clib_memcpy (r->runtime_data, n->runtime_data, vec_len (n->runtime_data)); } +/** \brief Set node dispatch state. + @param vm vlib_main_t pointer, varies by thread + @param node_index index of the node + @param new_state new state for node, see vlib_node_state_t +*/ always_inline void vlib_node_set_state (vlib_main_t * vm, u32 node_index, vlib_node_state_t new_state) { @@ -198,13 +241,27 @@ vlib_frame_vector_byte_offset (u32 scalar_size) VLIB_FRAME_VECTOR_ALIGN); } +/** \brief Get pointer to frame vector data. + @param f vlib_frame_t pointer + @return pointer to first vector element in frame +*/ always_inline void * vlib_frame_vector_args (vlib_frame_t * f) { return (void *) f + vlib_frame_vector_byte_offset (f->scalar_size); } -/* Scalar data lies before aligned vector data. */ +/** \brief Get pointer to frame scalar data. + + @warning This is almost certainly not the function you wish to call. + See @ref vlib_frame_vector_args instead. + + @param f vlib_frame_t pointer + + @return arbitrary node scalar data + + @sa vlib_frame_vector_args +*/ always_inline void * vlib_frame_args (vlib_frame_t * f) { return vlib_frame_vector_args (f) - f->scalar_size; } @@ -232,6 +289,20 @@ vlib_node_runtime_get_next_frame (vlib_main_t * vm, return nf; } +/** \brief Get pointer to frame by (@c node_index, @c next_index). + + @warning This is not a function that you should call directly. + See @ref vlib_get_next_frame instead. + + @param vm vlib_main_t pointer, varies by thread + @param node_index index of the node + @param next_index graph arc index + + @return pointer to the requested vlib_next_frame_t + + @sa vlib_get_next_frame +*/ + always_inline vlib_next_frame_t * vlib_node_get_next_frame (vlib_main_t * vm, u32 node_index, @@ -262,6 +333,19 @@ do { \ (n_vectors_left) = VLIB_FRAME_SIZE - _n; \ } while (0) + +/** \brief Get pointer to next frame vector data by + (@c vlib_node_runtime_t, @c next_index). + Standard single/dual loop boilerplate element. + @attention This is a MACRO, with SIDE EFFECTS. + + @param vm vlib_main_t pointer, varies by thread + @param node current node vlib_node_runtime_t pointer + @param next_index requested graph arc index + + @return @c vectors -- pointer to next available vector slot + @return @c n_vectors_left -- number of vector slots available +*/ #define vlib_get_next_frame(vm,node,next_index,vectors,n_vectors_left) \ vlib_get_next_frame_macro (vm, node, next_index, \ vectors, n_vectors_left, \ @@ -272,6 +356,13 @@ do { \ vectors, n_vectors_left, \ /* alloc new frame */ 1) +/** \brief Release pointer to next frame vector data. + Standard single/dual loop boilerplate element. + @param vm vlib_main_t pointer, varies by thread + @param r current node vlib_node_runtime_t pointer + @param next_index graph arc index + @param n_packets_left number of slots still available in vector +*/ void vlib_put_next_frame (vlib_main_t * vm, vlib_node_runtime_t * r, diff --git a/vnet/vnet/ip/ip4_forward.c b/vnet/vnet/ip/ip4_forward.c index 939835ae..45699b12 100644 --- a/vnet/vnet/ip/ip4_forward.c +++ b/vnet/vnet/ip/ip4_forward.c @@ -45,6 +45,10 @@ #include <vnet/srp/srp.h> /* for srp_hw_interface_class */ #include <vnet/api_errno.h> /* for API error numbers */ +/** \file + vnet ip4 forwarding +*/ + /* This is really, really simple but stupid fib. */ u32 ip4_fib_lookup_with_table (ip4_main_t * im, u32 fib_index, @@ -1002,6 +1006,38 @@ ip4_lookup_inline (vlib_main_t * vm, return frame->n_vectors; } +/** \brief IPv4 lookup node. + @node ip4-lookup + + This is the main IPv4 lookup dispatch node. + + @param vm vlib_main_t corresponding to the current thread + @param node vlib_node_runtime_t + @param frame vlib_frame_t whose contents should be dispatched + + @par Graph mechanics: buffer metadata, next index usage + + @em Uses: + - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code> + - Indicates the @c sw_if_index value of the interface that the + packet was received on. + - <code>vnet_buffer(b)->sw_if_index[VLIB_TX]</code> + - When the value is @c ~0 then the node performs a longest prefix + match (LPM) for the packet destination address in the FIB attached + to the receive interface. + - Otherwise perform LPM for the packet destination address in the + indicated FIB. In this case <code>[VLIB_TX]</code> is a FIB index + value (0, 1, ...) and not a VRF id. + + @em Sets: + - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code> + - The lookup result adjacency index. + + <em>Next Index:</em> + - Dispatches the packet to the node index found in + ip_adjacency_t @c adj->lookup_next_index + (where @c adj is the lookup result adjacency). +*/ static uword ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node, |