ip: Path MTU
[vpp.git] / src / vnet / dpo / dpo.h
index d3c2371..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__
 
@@ -168,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 "
@@ -328,7 +335,7 @@ 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.
@@ -341,7 +348,7 @@ extern void dpo_stack(dpo_type_t child_type,
  *
  * @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);
@@ -356,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
  */
@@ -383,6 +400,11 @@ 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
@@ -427,6 +449,10 @@ 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
      */
@@ -443,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.
@@ -497,4 +523,51 @@ 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