ip: Path MTU
[vpp.git] / src / vnet / dpo / dpo.h
index 304b433..e9976c2 100644 (file)
@@ -16,7 +16,7 @@
  * @brief
  * A Data-Path Object is an object that represents actions that are
  * applied to packets are they are switched through VPP's data-path.
- * 
+ *
  * The DPO can be considered to be like is a base class that is specialised
  * by other objects to provide concreate actions
  *
@@ -24,6 +24,8 @@
  * instances.
  */
 
+// clang-format off
+
 #ifndef __DPO_H__
 #define __DPO_H__
 
@@ -63,6 +65,7 @@ typedef enum dpo_proto_t_
     DPO_PROTO_IP6,
     DPO_PROTO_MPLS,
     DPO_PROTO_ETHERNET,
+    DPO_PROTO_BIER,
     DPO_PROTO_NSH,
 } __attribute__((packed)) dpo_proto_t;
 
@@ -75,6 +78,7 @@ typedef enum dpo_proto_t_
     [DPO_PROTO_ETHERNET]  = "ethernet", \
     [DPO_PROTO_MPLS] = "mpls", \
     [DPO_PROTO_NSH] = "nsh",    \
+    [DPO_PROTO_BIER] = "bier", \
 }
 
 #define FOR_EACH_DPO_PROTO(_proto)    \
@@ -109,13 +113,20 @@ typedef enum dpo_type_t_ {
     DPO_LOOKUP,
     DPO_LISP_CP,
     DPO_CLASSIFY,
-    DPO_MPLS_LABEL,
-    DPO_MPLS_DISPOSITION,
+    DPO_MPLS_DISPOSITION_PIPE,
+    DPO_MPLS_DISPOSITION_UNIFORM,
     DPO_MFIB_ENTRY,
     DPO_INTERFACE_RX,
     DPO_INTERFACE_TX,
-    DPO_L2_BRIDGE,
+    DPO_DVR,
     DPO_L3_PROXY,
+    DPO_BIER_TABLE,
+    DPO_BIER_FMASK,
+    DPO_BIER_IMP,
+    DPO_BIER_DISP_TABLE,
+    DPO_BIER_DISP_ENTRY,
+    DPO_IP6_LL,
+    DPO_PW_CW,
     DPO_LAST,
 } __attribute__((packed)) dpo_type_t;
 
@@ -138,13 +149,20 @@ typedef enum dpo_type_t_ {
     [DPO_REPLICATE] = "dpo-replicate", \
     [DPO_LISP_CP] = "dpo-lisp-cp",     \
     [DPO_CLASSIFY] = "dpo-classify",   \
-    [DPO_MPLS_LABEL] = "dpo-mpls-label", \
-    [DPO_MPLS_DISPOSITION] = "dpo-mpls-diposition", \
-    [DPO_MFIB_ENTRY] = "dpo-mfib_entry", \
+    [DPO_MPLS_DISPOSITION_PIPE] = "dpo-mpls-diposition-pipe", \
+    [DPO_MPLS_DISPOSITION_UNIFORM] = "dpo-mpls-diposition-uniform", \
+    [DPO_MFIB_ENTRY] = "dpo-mfib-entry", \
     [DPO_INTERFACE_RX] = "dpo-interface-rx",   \
     [DPO_INTERFACE_TX] = "dpo-interface-tx",   \
-    [DPO_L2_BRIDGE] = "dpo-l2-bridge", \
+    [DPO_DVR] = "dpo-dvr",     \
     [DPO_L3_PROXY] = "dpo-l3-proxy",   \
+    [DPO_BIER_TABLE] = "bier-table",   \
+    [DPO_BIER_FMASK] = "bier-fmask",   \
+    [DPO_BIER_IMP] = "bier-imposition",        \
+    [DPO_BIER_DISP_ENTRY] = "bier-disp-entry", \
+    [DPO_BIER_DISP_TABLE] = "bier-disp-table", \
+    [DPO_IP6_LL] = "ip6-link-local",   \
+    [DPO_PW_CW] = "PW-CW",     \
 }
 
 /**
@@ -152,23 +170,28 @@ typedef enum dpo_type_t_ {
  * instance number/index of objects of that type
  */
 typedef struct dpo_id_t_ {
-    /**
-     * the type
-     */
-    dpo_type_t dpoi_type;
-    /**
-     * the data-path protocol of the type.
-     */
-    dpo_proto_t dpoi_proto;
-    /**
-     * The next VLIB node to follow.
-     */
-    u16 dpoi_next_node;
-    /**
-     * the index of objects of that type
-     */
-    index_t dpoi_index;
-} __attribute__ ((aligned(sizeof(u64)))) dpo_id_t;
+    union {
+        struct {
+            /**
+             * the type
+             */
+            dpo_type_t dpoi_type;
+            /**
+             * the data-path protocol of the type.
+             */
+            dpo_proto_t dpoi_proto;
+            /**
+             * The next VLIB node to follow.
+             */
+            u16 dpoi_next_node;
+            /**
+             * the index of objects of that type
+             */
+            index_t dpoi_index;
+        };
+        u64 as_u64;
+    };
+} dpo_id_t;
 
 STATIC_ASSERT(sizeof(dpo_id_t) <= sizeof(u64),
              "DPO ID is greater than sizeof u64 "
@@ -210,6 +233,14 @@ extern void dpo_lock(dpo_id_t *dpo);
  */
 extern void dpo_unlock(dpo_id_t *dpo);
 
+/**
+ * @brief
+ *  Make an interpose DPO from an original
+ */
+extern void dpo_mk_interpose(const dpo_id_t *original,
+                             const dpo_id_t *parent,
+                             dpo_id_t *clone);
+
 /**
  * @brief Set/create a DPO ID
  * The DPO will be locked.
@@ -260,12 +291,12 @@ extern void dpo_copy(dpo_id_t *dst,
 extern int dpo_is_adj(const dpo_id_t *dpo);
 
 /**
- * @biref Format a DPO_id_t oject
+ * @brief Format a DPO_id_t oject
  */
 extern u8 *format_dpo_id(u8 * s, va_list * args);
 
 /**
- * @biref format a DPO type
+ * @brief format a DPO type
  */
 extern u8 *format_dpo_type(u8 * s, va_list * args);
 
@@ -304,20 +335,20 @@ extern void dpo_stack(dpo_type_t child_type,
                       const dpo_id_t *parent_dpo);
 
 /**
- * @brief 
+ * @brief
  *  Set and stack a DPO.
  *  The DPO passed is set to the parent DPO and the necessary
  *  VLIB graph arcs are created, from the child_node passed.
  *
  * @param child_node
- *  The VLIB grpah node index to create an arc from to the parent
+ *  The VLIB graph node index to create an arc from to the parent
  *
  * @param dpo
  *  This is the DPO to stack and set.
  *
  * @param parent_dpo
  *  The parent DPO to stack onto.
- */ 
+ */
 extern void dpo_stack_from_node(u32 child_node,
                                 dpo_id_t *dpo,
                                 const dpo_id_t *parent);
@@ -332,6 +363,16 @@ extern void dpo_stack_from_node(u32 child_node,
  */
 extern u32 dpo_get_urpf(const dpo_id_t *dpo);
 
+/**
+ * Get the MTU DPO
+ *
+ * @param dpo
+ *  The DPO from which to get the MTU
+ *
+ * @return MTU (0xffff if something more usefull was unavailable)
+ */
+extern u16 dpo_get_mtu(const dpo_id_t *dpo);
+
 /**
  * @brief  A lock function registered for a DPO type
  */
@@ -359,6 +400,23 @@ typedef u32* (*dpo_get_next_node_t)(const dpo_id_t *dpo);
  */
 typedef u32 (*dpo_get_urpf_t)(const dpo_id_t *dpo);
 
+/**
+ * @brief Given a DPO instance return the MTU
+ */
+typedef u16 (*dpo_get_mtu_t)(const dpo_id_t *dpo);
+
+/**
+ * @brief Called during FIB interposition when the originally
+ * registered DPO is used to 'clone' an instance for interposition
+ * at a particular location in the FIB graph.
+ * The parent is the next DPO in the chain that the clone will
+ * be used instead of. The clone may then choose to stack itself
+ * on the parent.
+ */
+typedef void (*dpo_mk_interpose_t)(const dpo_id_t *original,
+                                   const dpo_id_t *parent,
+                                   dpo_id_t *clone);
+
 /**
  * @brief A virtual function table regisitered for a DPO type
  */
@@ -391,6 +449,14 @@ typedef struct dpo_vft_t_
      * Get uRPF interface
      */
     dpo_get_urpf_t dv_get_urpf;
+    /**
+     * Get MTU
+     */
+    dpo_get_mtu_t dv_get_mtu;
+    /**
+     * Signal on an interposed child that the parent has changed
+     */
+    dpo_mk_interpose_t dv_mk_interpose;
 } dpo_vft_t;
 
 
@@ -403,7 +469,7 @@ typedef struct dpo_vft_t_
  *     (see above).
  *
  * @param type
- *  The type being registered. 
+ *  The type being registered.
  *
  * @param vft
  *  The virtual function table to register for the type.
@@ -432,4 +498,76 @@ extern void dpo_register(dpo_type_t type,
 extern dpo_type_t dpo_register_new_type(const dpo_vft_t *vft,
                                        const char * const * const * nodes);
 
+/**
+ * @brief Return already stacked up next node index for a given
+ *        child_type/child_proto and parent_type/patent_proto.
+ *        The VLIB graph arc used is taken from the parent and child types
+ *        passed.
+ *
+ * @param child_type
+ *  Child DPO type.
+ *
+ * @param child_proto
+ *  Child DPO proto
+ *
+ * @param parent_type
+ *  Parent DPO type.
+ *
+ * @param parent_proto
+ *  Parent DPO proto
+ *
+ * @return The VLIB Graph node index
+ */
+extern u32
+dpo_get_next_node_by_type_and_proto (dpo_type_t   child_type,
+                                     dpo_proto_t  child_proto,
+                                     dpo_type_t   parent_type,
+                                     dpo_proto_t  parent_proto);
+
+
+/**
+ * @brief Barrier sync if a dpo pool is about to expand
+ *
+ * @param VM (output)
+ *  vlib_main_t *, invariably &vlib_global_main
+ *
+ * @param P
+ *  pool pointer
+ *
+ * @param YESNO (output)
+ *  typically a u8, 1 => expand will occur, worker barrier held
+ *                  0 => no expand, barrier not held
+ *
+ * @return YESNO set
+ */
+
+#define dpo_pool_barrier_sync(VM,P,YESNO)                               \
+do {                                                                    \
+    pool_get_aligned_will_expand ((P), YESNO, CLIB_CACHE_LINE_BYTES);   \
+                                                                        \
+    if (YESNO)                                                          \
+    {                                                                   \
+        VM = vlib_get_main();                                           \
+        ASSERT ((VM)->thread_index == 0);                               \
+        vlib_worker_thread_barrier_sync((VM));                          \
+    }                                                                   \
+} while(0);
+
+/**
+ * @brief Release barrier sync after dpo pool expansion
+ *
+ * @param VM
+ *  vlib_main_t pointer, must be &vlib_global_main
+ *
+ * @param YESNO
+ *  typically a u8, 1 => release required
+ *                  0 => no release required
+ * @return none
+ */
+
+#define dpo_pool_barrier_release(VM,YESNO) \
+    if ((YESNO)) vlib_worker_thread_barrier_release((VM));
+
 #endif
+
+// clang-format on