Adjacency Delegate updates

- Register new type (for use from puglins)
- Memory for delegate is provided by delegate provider

Change-Id: I5ece86b1fe84e3028a5c853871476c4ba015b2eb
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
diff --git a/src/vnet/adj/adj_delegate.h b/src/vnet/adj/adj_delegate.h
index 9f7d8c6..b57900b 100644
--- a/src/vnet/adj/adj_delegate.h
+++ b/src/vnet/adj/adj_delegate.h
@@ -12,6 +12,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+/**
+ * A Delagate is a means to implement the Delagation design pattern;
+ * the extension of an object's functionality through the composition of,
+ * and delgation to, other objects.
+ * These 'other' objects are delegates. Delagates are thus attached to
+ * ADJ objects to extend their functionality.
+ */
 
 #ifndef __ADJ_DELEGATE_T__
 #define __ADJ_DELEGATE_T__
@@ -19,7 +26,10 @@
 #include <vnet/adj/adj.h>
 
 /**
- * Delegate types
+ * Built-in delegate types.
+ * When adding new types, if your code is within the vnet subsystem, then add a
+ * new  type here. If not then use the adj_delegate_register_new_type API to
+ * register a new type.
  */
 typedef enum adj_delegate_type_t_ {
     /**
@@ -28,35 +38,12 @@
     ADJ_DELEGATE_BFD,
 } adj_delegate_type_t;
 
-#define FOR_EACH_ADJ_DELEGATE(_adj, _adt, _aed, _body)        \
-{                                                             \
-    for (_adt = ADJ_DELEGATE_BFD;                             \
-         _adt <= ADJ_DELEGATE_BFD;                            \
-         _adt++)                                              \
-    {                                                         \
-        _aed = adj_delegate_get(_adj, _adt);                  \
-        if (NULL != _aed) {                                   \
-            _body;                                            \
-        }                                                     \
-    }                                                         \
-}
-
 /**
- * Distillation of the BFD session states into a go/no-go for using
- * the associated tracked adjacency
- */
-typedef enum adj_bfd_state_t_
-{
-    ADJ_BFD_STATE_DOWN,
-    ADJ_BFD_STATE_UP,
-} adj_bfd_state_t;
-
-/**
- * A Delagate is a means to implement the Delagation design pattern;
- * the extension of an object's functionality through the composition of,
- * and delgation to, other objects.
- * These 'other' objects are delegates. Delagates are thus attached to
- * ADJ objects to extend their functionality.
+ * Adj delegate. This object should be contained within all type specific
+ * delegates.  i.e. this is the base class to all type specific derived classes.
+ * With this model the delegate provider is free to manage the memory of the
+ * delegate in the way it chooses. Specifically it can assign them from its own
+ * pools and thus, for example, add the delegates to the FIB node graph.
  */
 typedef struct adj_delegate_t_
 {
@@ -69,47 +56,69 @@
      * The delagate type
      */
     adj_delegate_type_t ad_type;
-
-    /**
-     * A union of data for the different delegate types
-     */
-    union
-    {
-        /**
-         * BFD delegate daa
-         */
-        struct {
-            /**
-             * BFD session state
-             */
-            adj_bfd_state_t ad_bfd_state;
-            /**
-             * BFD session index
-             */
-            u32 ad_bfd_index;
-        };
-    };
 } adj_delegate_t;
 
 /**
+ * Indication that the adjacency has been deleted. The delegate provider should free
+ * the delegate.
+ */
+typedef void (*adj_delegate_adj_deleted_t)(adj_delegate_t *aed);
+
+/**
+ * Format function for the delegate
+ */
+typedef u8 * (*adj_delegate_format_t)(const adj_delegate_t *aed, u8 *s);
+
+/**
  * An ADJ delegate virtual function table
  */
-typedef void (*adj_delegate_last_lock_gone_t)(ip_adjacency_t *adj, adj_delegate_t *aed);
-typedef u8 * (*adj_delegate_format_t)(const adj_delegate_t *aed, u8 *s);
 typedef struct adj_delegate_vft_t_ {
-  adj_delegate_format_t adv_format;
-  adj_delegate_last_lock_gone_t adv_last_lock;
+    adj_delegate_format_t adv_format;
+    adj_delegate_adj_deleted_t adv_adj_deleted;
 } adj_delegate_vft_t;
 
-extern void adj_delegate_remove(ip_adjacency_t *adj,
+/**
+ * @brief Remove a delegate from an adjacency
+ *
+ * @param ai The adjacency to remove the delegate from
+ * @param type The type of delegate being removed
+ */
+extern void adj_delegate_remove(adj_index_t ai,
                                 adj_delegate_type_t type);
 
-extern adj_delegate_t *adj_delegate_find_or_add(ip_adjacency_t *adj,
-                                                adj_delegate_type_t fdt);
+/**
+ * @brief Add a delegate to an adjacency
+ *
+ * @param ai The adjacency to add the delegate to
+ * @param type The type of delegate being added
+ * @param ad The delegate. The provider should allocate memory for this object
+ *                         Typically this is a 'derived' class with the
+ *                         adj_delegate_t struct embedded within.
+ */
+extern int adj_delegate_add(ip_adjacency_t *adj,
+                            adj_delegate_type_t fdt,
+                            adj_delegate_t *ad);
+
+
+/**
+ * @brief Get a delegate from an adjacency
+ *
+ * @param ai The adjacency to get the delegate from
+ * @param type The type of delegate being sought
+ */
 extern adj_delegate_t *adj_delegate_get(const ip_adjacency_t *adj,
                                         adj_delegate_type_t type);
 
-extern u8 *format_adj_delegate(u8 * s, va_list * args);
-extern void adj_delegate_register_type(adj_delegate_type_t type, const adj_delegate_vft_t *vft);
+/**
+ * @brief Register a VFT for one of the built-in types
+ */
+extern void adj_delegate_register_type(adj_delegate_type_t type,
+                                       const adj_delegate_vft_t *vft);
+
+/**
+ * @brief create a new delegate type and register a new VFT
+ */
+extern adj_delegate_type_t adj_delegate_register_new_type(
+    const adj_delegate_vft_t *vft);
 
 #endif