Add IP adjacency registration function
[vpp.git] / vnet / vnet / ip / lookup.h
index 30c1291..a66b9ed 100644 (file)
@@ -45,7 +45,7 @@
 #include <vnet/ip/ip4_packet.h>
 #include <vnet/ip/ip6_packet.h>
 
-/* Next index stored in adjacency. */
+/* Common (IP4/IP6) next index stored in adjacency. */
 typedef enum {
   /* Packet does not match any route in table. */
   IP_LOOKUP_NEXT_MISS,
@@ -76,22 +76,26 @@ typedef enum {
   /* This packet needs to go to MAP with Translation - RFC7599 */
   IP_LOOKUP_NEXT_MAP_T,
 
-  /* This packets needs to go to 6RD (RFC5969) */
-  IP_LOOKUP_NEXT_SIXRD,
-
   /* This packets needs to go to indirect next hop */
   IP_LOOKUP_NEXT_INDIRECT,
 
-  /* Hop-by-hop header handling */
-  IP_LOOKUP_NEXT_HOP_BY_HOP,
-  IP_LOOKUP_NEXT_ADD_HOP_BY_HOP,
-  IP_LOOKUP_NEXT_POP_HOP_BY_HOP,
-
   IP_LOOKUP_NEXT_ICMP_ERROR,
 
   IP_LOOKUP_N_NEXT,
 } ip_lookup_next_t;
 
+typedef enum {
+  IP4_LOOKUP_N_NEXT = IP_LOOKUP_N_NEXT,
+} ip4_lookup_next_t;
+
+typedef enum {
+  /* Hop-by-hop header handling */
+  IP6_LOOKUP_NEXT_HOP_BY_HOP = IP_LOOKUP_N_NEXT,
+  IP6_LOOKUP_NEXT_ADD_HOP_BY_HOP,
+  IP6_LOOKUP_NEXT_POP_HOP_BY_HOP,
+  IP6_LOOKUP_N_NEXT,
+} ip6_lookup_next_t;
+
 #define IP4_LOOKUP_NEXT_NODES {                                        \
     [IP_LOOKUP_NEXT_MISS] = "ip4-miss",                                \
     [IP_LOOKUP_NEXT_DROP] = "ip4-drop",                                \
@@ -102,10 +106,6 @@ typedef enum {
     [IP_LOOKUP_NEXT_CLASSIFY] = "ip4-classify",                        \
     [IP_LOOKUP_NEXT_MAP] = "ip4-map",                          \
     [IP_LOOKUP_NEXT_MAP_T] = "ip4-map-t",                      \
-    [IP_LOOKUP_NEXT_SIXRD] = "ip4-sixrd",                      \
-    [IP_LOOKUP_NEXT_HOP_BY_HOP] = "ip4-hop-by-hop",            \
-    [IP_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip4-add-hop-by-hop",    \
-    [IP_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip4-pop-hop-by-hop",    \
     [IP_LOOKUP_NEXT_INDIRECT] = "ip4-indirect",                        \
     [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip4-icmp-error",            \
 }
@@ -120,12 +120,11 @@ typedef enum {
     [IP_LOOKUP_NEXT_CLASSIFY] = "ip6-classify",                        \
     [IP_LOOKUP_NEXT_MAP] = "ip6-map",                          \
     [IP_LOOKUP_NEXT_MAP_T] = "ip6-map-t",                      \
-    [IP_LOOKUP_NEXT_SIXRD] = "ip6-sixrd",                      \
-    [IP_LOOKUP_NEXT_HOP_BY_HOP] = "ip6-hop-by-hop",            \
-    [IP_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip6-add-hop-by-hop",    \
-    [IP_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop",    \
     [IP_LOOKUP_NEXT_INDIRECT] = "ip6-indirect",                        \
     [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip6-icmp-error",            \
+    [IP6_LOOKUP_NEXT_HOP_BY_HOP] = "ip6-hop-by-hop",           \
+    [IP6_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip6-add-hop-by-hop",   \
+    [IP6_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop",   \
 }
 
 /* Flow hash configuration */
@@ -147,6 +146,7 @@ _(dport, IP_FLOW_HASH_DST_PORT)                 \
 _(proto, IP_FLOW_HASH_PROTO)                   \
 _(reverse, IP_FLOW_HASH_REVERSE_SRC_DST)
 
+#define IP_ADJACENCY_OPAQUE_SZ 16
 /* IP unicast adjacency. */
 typedef struct {
   CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
@@ -188,6 +188,7 @@ typedef struct {
     struct {
         ip46_address_t next_hop;
     } indirect;
+    u8 opaque[IP_ADJACENCY_OPAQUE_SZ];
   };
 
   STRUCT_MARK(signature_end);
@@ -349,6 +350,18 @@ typedef struct {
   u32 * config_index_by_sw_if_index;
 } ip_config_main_t;
 
+//Function type used to register formatting of a custom adjacency formatting
+typedef u8 *(* ip_adjacency_format_fn)(u8 * s,
+                                        struct ip_lookup_main_t * lm,
+                                        ip_adjacency_t *adj);
+
+typedef struct ip_adj_register_struct {
+  struct ip_adj_register_struct *next;
+  char *node_name; //Name of the node for this registered adjacency
+  ip_adjacency_format_fn fn; //Formatting function of this adjacency
+  u32 *next_index; //some place where the next index to be used will be put at init
+} ip_adj_register_t;
+
 typedef struct ip_lookup_main_t {
   /* Adjacency heap. */
   ip_adjacency_t * adjacency_heap;
@@ -421,6 +434,9 @@ typedef struct ip_lookup_main_t {
 
   /* IP_BUILTIN_PROTOCOL_{TCP,UDP,ICMP,OTHER} by protocol in IP header. */
   u8 builtin_protocol_by_ip_protocol[256];
+
+  /* Registered adjacencies */
+  ip_adj_register_t *registered_adjacencies;
 } ip_lookup_main_t;
 
 always_inline ip_adjacency_t *
@@ -442,6 +458,37 @@ do {                                                               \
   CLIB_PREFETCH (_adj, sizeof (_adj[0]), type);                        \
 } while (0)
 
+/* Adds a next node to ip4 or ip6 lookup node which can be then used in adjacencies.
+ * @param vlib_main pointer
+ * @param lm ip4_main.lookup_main or ip6_main.lookup_main
+ * @param reg registration structure
+ * @param next_node_index Returned index to be used in adjacencies.
+ * @return 0 on success. -1 on failure.
+ */
+int ip_register_adjacency(vlib_main_t *vm, u8 is_ip4,
+                          ip_adj_register_t *reg);
+
+/*
+ * Construction helpers to add IP adjacency at init.
+ */
+#define VNET_IP_REGISTER_ADJACENCY(ip,x,...)                     \
+  __VA_ARGS__ ip_adj_register_t ip##adj_##x;                     \
+static void __vnet_##ip##_register_adjacency_##x (void)          \
+  __attribute__((__constructor__)) ;                             \
+static void __vnet_##ip##_register_adjacency_##x (void)          \
+{                                                                \
+  ip_lookup_main_t *lm = &ip##_main.lookup_main;                 \
+  ip##adj_##x.next = lm->registered_adjacencies;                 \
+  lm->registered_adjacencies = &ip##adj_##x;                     \
+}                                                                \
+__VA_ARGS__ ip_adj_register_t ip##adj_##x
+
+#define VNET_IP4_REGISTER_ADJACENCY(x,...)                       \
+    VNET_IP_REGISTER_ADJACENCY(ip4, x, __VA_ARGS__)
+
+#define VNET_IP6_REGISTER_ADJACENCY(x,...)                       \
+    VNET_IP_REGISTER_ADJACENCY(ip6, x, __VA_ARGS__)
+
 static inline void
 ip_register_add_del_adjacency_callback(ip_lookup_main_t * lm,
                                       ip_add_del_adjacency_callback_t cb)
@@ -532,7 +579,7 @@ ip_interface_address_for_packet (ip_lookup_main_t * lm, vlib_buffer_t * b, u32 s
                      vec_elt (lm->if_address_pool_index_by_sw_if_index, sw_if_index)
                      : if_address_index);
 
-  return pool_elt_at_index (lm->if_address_pool, if_address_index);
+  return (if_address_index != ~0)?pool_elt_at_index (lm->if_address_pool, if_address_index):NULL;
 }
 
 #define foreach_ip_interface_address(lm,a,sw_if_index,loop,body)        \