Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
face.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2020 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef __HICN_FACE_H__
17 #define __HICN_FACE_H__
18 
19 #include <vnet/fib/fib_node.h>
20 #include <vnet/vnet.h>
21 #include <vlib/vlib.h>
22 #include <vnet/ip/ip46_address.h>
23 #include <vnet/dpo/dpo.h>
24 #include <vnet/adj/adj_types.h>
25 #include <vppinfra/bihash_8_8.h>
26 #include <vnet/adj/adj_midchain.h>
27 
28 #include "../error.h"
29 typedef u8 hicn_face_flags_t;
30 typedef index_t hicn_face_id_t;
31 
82 typedef struct __attribute__ ((packed)) hicn_face_s
83 {
84  /* Flags to idenfity if the face is incomplete (iface), complete (face) */
85  /* And a network or application face (1B) */
86  hicn_face_flags_t flags;
87 
88  /* Align the upcoming fields */
89  u8 align;
90 
91  /* Path label (2B) */
92  u16 pl_id;
93 
94  /* Number of dpo holding a reference to the dpoi (4B) */
95  u32 locks;
96 
97  /* Dpo for the adjacency (8B) */
98  union
99  {
100  dpo_id_t dpo;
101  u64 align_dpo;
102  };
103 
104  /* Local address of the interface sw_if */
105  ip46_address_t nat_addr;
106 
107  /* local interface for the local ip address */
108  u32 sw_if;
109 
110  fib_node_t fib_node;
111 
112  fib_node_index_t fib_entry_index;
113 
114  u32 fib_sibling;
115 } hicn_face_t;
116 
117 /* Pool of faces */
118 extern hicn_face_t *hicn_dpoi_face_pool;
119 
120 /* Flags */
121 /* A face is complete and it stores all the information. A iface lacks of the
122  adj index, therefore sending a packet through a iface require a lookup in
123  the FIB. */
124 #define HICN_FACE_FLAGS_DEFAULT 0x00
125 #define HICN_FACE_FLAGS_FACE 0x01
126 #define HICN_FACE_FLAGS_IFACE 0x02
127 #define HICN_FACE_FLAGS_APPFACE_PROD \
128  0x04 /* Currently only IP face can be appface */
129 #define HICN_FACE_FLAGS_APPFACE_CONS \
130  0x08 /* Currently only IP face can be appface */
131 #define HICN_FACE_FLAGS_DELETED 0x10
132 
133 #define HICN_FACE_NULL (hicn_face_id_t) ~0
134 
135 #define HICN_FACE_FLAGS_APPFACE_PROD_BIT 2
136 #define HICN_FACE_FLAGS_APPFACE_CONS_BIT 3
137 
138 #define HICN_BUFFER_FLAGS_DEFAULT 0x00
139 #define HICN_BUFFER_FLAGS_FACE_IS_APP 0x01
140 
141 STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_PROD_BIT) ==
142  HICN_FACE_FLAGS_APPFACE_PROD,
143  "HICN_FACE_FLAGS_APPFACE_PROD_BIT and "
144  "HICN_FACE_FLAGS_APPFACE_PROD must correspond");
145 
146 STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_CONS_BIT) ==
147  HICN_FACE_FLAGS_APPFACE_CONS,
148  "HICN_FACE_FLAGS_APPFACE_CONS_BIT and "
149  "HICN_FACE_FLAGS_APPFACE_CONS must correspond");
150 
151 STATIC_ASSERT (
152  (HICN_FACE_FLAGS_APPFACE_PROD >> HICN_FACE_FLAGS_APPFACE_PROD_BIT) ==
153  HICN_BUFFER_FLAGS_FACE_IS_APP,
154  "hicn buffer app flag does not correspond to HICN_FACE_FLAGS_APPFACE_PROD");
155 
156 STATIC_ASSERT (
157  (HICN_FACE_FLAGS_APPFACE_CONS >> HICN_FACE_FLAGS_APPFACE_CONS_BIT) ==
158  HICN_BUFFER_FLAGS_FACE_IS_APP,
159  "hicn buffer app flag does not correspond to HICN_FACE_FLAGS_APPFACE_PROD");
160 
164 typedef struct hicn_face_vft_s
165 {
166  u8 *(*format_face) (u8 *s, va_list *args);
168  int (*hicn_face_del) (hicn_face_id_t face_id);
169  void (*hicn_face_get_dpo) (hicn_face_t *face, dpo_id_t *dpo);
171 
172 #define foreach_hicn_face_counter \
173  _ (INTEREST_RX, 0, "Interest rx") \
174  _ (INTEREST_TX, 1, "Interest tx") \
175  _ (DATA_RX, 2, "Data rx") \
176  _ (DATA_TX, 3, "Data tx")
177 
178 typedef enum
179 {
180 #define _(a, b, c) HICN_FACE_COUNTERS_##a = (b),
181  foreach_hicn_face_counter
182 #undef _
183  HICN_N_COUNTER
184 } hicn_face_counters_t;
185 
186 extern mhash_t hicn_face_hashtb;
187 
188 extern const char *HICN_FACE_CTRX_STRING[];
189 
190 #define get_face_counter_string(ctrxno) \
191  (char *) (HICN_FACE_CTRX_STRING[ctrxno])
192 
193 /* Vector maintaining a dpo per face */
194 extern dpo_id_t *face_dpo_vec;
195 extern hicn_face_vft_t *face_vft_vec;
196 
197 /* Vector holding the set of face names */
198 extern char **face_type_names_vec;
199 
200 /* Pathlabel counter */
201 extern u8 pl_index;
202 
203 /* First face type registered in the sytem.*/
204 extern dpo_type_t first_type;
205 
206 /* Per-face counters */
207 extern vlib_combined_counter_main_t *counters;
208 
215 always_inline hicn_face_id_t
216 hicn_dpoi_get_index (hicn_face_t *face_dpoi)
217 {
218  return face_dpoi - hicn_dpoi_face_pool;
219 }
220 
228 always_inline hicn_face_t *
229 hicn_dpoi_get_from_idx_safe (hicn_face_id_t dpoi_index)
230 {
231  if (!pool_is_free_index (hicn_dpoi_face_pool, dpoi_index))
232  return (hicn_face_t *) pool_elt_at_index (hicn_dpoi_face_pool, dpoi_index);
233  else
234  return NULL;
235 }
236 
243 always_inline hicn_face_t *
244 hicn_dpoi_get_from_idx (hicn_face_id_t dpoi_index)
245 {
246  return (hicn_face_t *) pool_elt_at_index (hicn_dpoi_face_pool, dpoi_index);
247 }
248 
252 always_inline int
253 hicn_dpoi_idx_is_valid (hicn_face_id_t face_id)
254 {
255  return pool_len (hicn_dpoi_face_pool) > face_id &&
256  !pool_is_free_index (hicn_dpoi_face_pool, face_id);
257 }
258 
264 always_inline void
265 hicn_face_lock_with_id (hicn_face_id_t face_id)
266 {
267  hicn_face_t *face;
268  face = hicn_dpoi_get_from_idx (face_id);
269  face->locks++;
270 }
271 
277 always_inline void
278 hicn_face_unlock_with_id (hicn_face_id_t face_id)
279 {
280  hicn_face_t *face;
281  face = hicn_dpoi_get_from_idx (face_id);
282  face->locks--;
283 }
284 
290 always_inline void
291 hicn_face_lock (dpo_id_t *dpo)
292 {
293  hicn_face_lock_with_id (dpo->dpoi_index);
294 }
295 
302 always_inline void
303 hicn_face_unlock (dpo_id_t *dpo)
304 {
305  hicn_face_unlock_with_id (dpo->dpoi_index);
306 }
307 
313 void hicn_face_module_init (vlib_main_t *vm);
314 
315 u8 *format_hicn_face (u8 *s, va_list *args);
316 
324 u8 *format_hicn_face_all (u8 *s, int n, ...);
325 
333 int hicn_face_del (hicn_face_id_t face_id);
334 
339 typedef hicn_face_id_t *hicn_face_vec_t;
340 
341 typedef struct hicn_input_faces_s_
342 {
343  /* Vector of all possible input faces */
344  u32 vec_id;
345 
346  /* Preferred face. If an prod_app face is in the vector it will be the
347  * preferred one. */
348  /* It's not possible to have multiple prod_app face in the same vector, they
349  * would have */
350  /* the same local address. Every prod_app face is a point-to-point face
351  * between the forwarder */
352  /* and the application. */
353  hicn_face_id_t face_id;
354 
356 
361 
366 extern mhash_t hicn_face_vec_hashtb;
367 
388 typedef struct __attribute__ ((packed)) hicn_face_key_s
389 {
390  ip46_address_t addr;
391  union
392  {
393  dpo_id_t dpo;
394  u64 align_dpo;
395  };
396  u32 sw_if;
397 } hicn_face_key_t;
398 
407 always_inline void
408 hicn_face_get_key (const ip46_address_t *addr, u32 sw_if, const dpo_id_t *dpo,
409  hicn_face_key_t *key)
410 {
411  key->dpo = *dpo;
412  key->addr = *addr;
413  key->sw_if = sw_if;
414 }
415 
426 always_inline hicn_face_t *
427 hicn_face_get (const ip46_address_t *addr, u32 sw_if, mhash_t *hashtb,
428  index_t adj_index)
429 {
430  hicn_face_key_t key;
431 
432  dpo_id_t dpo = DPO_INVALID;
433 
434  dpo.dpoi_index = adj_index;
435 
436  hicn_face_get_key (addr, sw_if, &dpo, &key);
437 
438  hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb, &key);
439 
440  if (dpoi_index != NULL)
441  {
442  hicn_face_lock_with_id (*dpoi_index);
443  return hicn_dpoi_get_from_idx (*dpoi_index);
444  }
445 
446  return NULL;
447 }
448 
460 always_inline hicn_face_t *
461 hicn_face_get_with_dpo (const ip46_address_t *addr, u32 sw_if,
462  const dpo_id_t *dpo, mhash_t *hashtb)
463 {
464  hicn_face_key_t key;
465 
466  hicn_face_get_key (addr, sw_if, dpo, &key);
467 
468  hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb, &key);
469 
470  if (dpoi_index != NULL)
471  {
472  hicn_face_lock_with_id (*dpoi_index);
473  return hicn_dpoi_get_from_idx (*dpoi_index);
474  }
475 
476  return NULL;
477 }
478 
490 always_inline hicn_face_input_faces_t *
491 hicn_face_get_vec (const ip46_address_t *addr, mhash_t *hashtb)
492 {
493  hicn_face_key_t key;
494 
495  dpo_id_t dpo = DPO_INVALID;
496 
497  hicn_face_get_key (addr, 0, &dpo, &key);
498  return (hicn_face_input_faces_t *) mhash_get (hashtb, &key);
499 }
500 
514 int hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address,
515  int sw_if, hicn_face_id_t *pfaceid, u8 is_app_prod);
516 
527 always_inline void
528 hicn_iface_add (ip46_address_t *nat_address, int sw_if,
529  hicn_face_id_t *pfaceid, dpo_proto_t proto, u32 adj_index)
530 {
531  hicn_face_t *face;
532  pool_get (hicn_dpoi_face_pool, face);
533 
534  clib_memcpy (&(face->nat_addr), nat_address, sizeof (ip46_address_t));
535  face->sw_if = sw_if;
536 
537  face->dpo.dpoi_type = DPO_FIRST;
538  face->dpo.dpoi_proto = DPO_PROTO_NONE;
539  face->dpo.dpoi_index = adj_index;
540  face->dpo.dpoi_next_node = 0;
541  face->pl_id = pl_index++;
542  face->flags = HICN_FACE_FLAGS_IFACE;
543  face->locks = 1;
544 
545  hicn_face_key_t key;
546  hicn_face_get_key (nat_address, sw_if, &face->dpo, &key);
547  *pfaceid = hicn_dpoi_get_index (face);
548 
549  mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, 0);
550 
551  for (int i = 0; i < HICN_N_COUNTER; i++)
552  {
553  vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
554  i);
555  vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
556  }
557 }
558 
559 /**** Helpers to manipulate faces and ifaces from the face/iface input nodes
560  * ****/
561 
576 always_inline int
577 hicn_face_ip4_lock (hicn_face_id_t *face_id, u32 *in_faces_vec_id,
578  u8 *hicnb_flags, const ip4_address_t *nat_addr)
579 {
580  ip46_address_t ip_address = { 0 };
581  ip46_address_set_ip4 (&ip_address, nat_addr);
582  hicn_face_input_faces_t *in_faces_vec =
583  hicn_face_get_vec (&ip_address, &hicn_face_vec_hashtb);
584 
585  if (PREDICT_FALSE (in_faces_vec == NULL))
586  return HICN_ERROR_FACE_NOT_FOUND;
587 
588  *in_faces_vec_id = in_faces_vec->vec_id;
589  hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
590 
591  *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
592  *hicnb_flags |= (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
593  HICN_FACE_FLAGS_APPFACE_PROD_BIT;
594 
595  *face_id = in_faces_vec->face_id;
596 
597  return HICN_ERROR_NONE;
598 }
599 
613 always_inline int
614 hicn_face_ip6_lock (hicn_face_id_t *face_id, u32 *in_faces_vec_id,
615  u8 *hicnb_flags, const ip6_address_t *nat_addr)
616 {
617  hicn_face_input_faces_t *in_faces_vec =
619 
620  if (PREDICT_FALSE (in_faces_vec == NULL))
621  return HICN_ERROR_FACE_NOT_FOUND;
622 
623  *in_faces_vec_id = in_faces_vec->vec_id;
624  hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
625 
626  *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
627  *hicnb_flags |= (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
628  HICN_FACE_FLAGS_APPFACE_PROD_BIT;
629 
630  *face_id = in_faces_vec->face_id;
631 
632  return HICN_ERROR_NONE;
633 }
634 
638 static adj_walk_rc_t
639 hicn4_iface_adj_walk_cb (adj_index_t ai, void *ctx)
640 {
641 
642  hicn_face_t *face = (hicn_face_t *) ctx;
643 
644  dpo_set (&face->dpo, DPO_ADJACENCY_MIDCHAIN, DPO_PROTO_IP4, ai);
645  adj_nbr_midchain_stack (ai, &face->dpo);
646 
647  return (ADJ_WALK_RC_CONTINUE);
648 }
649 
661 always_inline void
662 hicn_iface_ip4_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags,
663  const ip4_address_t *nat_addr, u32 sw_if,
664  u32 adj_index, u32 node_index)
665 {
666  /*All (complete) faces are indexed by remote addess as well */
667 
668  ip46_address_t ip_address = { 0 };
669  ip46_address_set_ip4 (&ip_address, nat_addr);
670 
671  /* if the face exists, it adds a lock */
672  hicn_face_t *face =
673  hicn_face_get (&ip_address, sw_if, &hicn_face_hashtb, adj_index);
674 
675  if (face == NULL)
676  {
677  hicn_face_id_t idx;
678  hicn_iface_add (&ip_address, sw_if, &idx, DPO_PROTO_IP4, adj_index);
679 
680  face = hicn_dpoi_get_from_idx (idx);
681 
682  face->dpo.dpoi_type = DPO_FIRST;
683  face->dpo.dpoi_proto = DPO_PROTO_IP4;
684  face->dpo.dpoi_index = adj_index;
685  face->dpo.dpoi_next_node = node_index;
686 
687  /* if (nat_addr->as_u32 == 0) */
688  /* { */
689  adj_nbr_walk (face->sw_if, FIB_PROTOCOL_IP4, hicn4_iface_adj_walk_cb,
690  face);
691  /* } */
692 
693  *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
694 
695  *index = idx;
696  return;
697  }
698  else
699  {
700  /* unlock the face. We don't take a lock on each interest we receive */
701  hicn_face_id_t face_id = hicn_dpoi_get_index (face);
702  hicn_face_unlock_with_id (face_id);
703  }
704 
705  /* Code replicated on purpose */
706  *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
707  *hicnb_flags |= (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
708  HICN_FACE_FLAGS_APPFACE_PROD_BIT;
709 
710  *index = hicn_dpoi_get_index (face);
711 }
712 
716 static adj_walk_rc_t
717 hicn6_iface_adj_walk_cb (adj_index_t ai, void *ctx)
718 {
719 
720  hicn_face_t *face = (hicn_face_t *) ctx;
721 
722  ip_adjacency_t *adj = adj_get (ai);
723  if ((adj->lookup_next_index == IP_LOOKUP_NEXT_MIDCHAIN) ||
724  (adj->lookup_next_index == IP_LOOKUP_NEXT_MCAST_MIDCHAIN))
725  {
726  dpo_set (&face->dpo, DPO_ADJACENCY_MIDCHAIN, adj->ia_nh_proto, ai);
727  adj_nbr_midchain_stack (ai, &face->dpo);
728  }
729 
730  return (ADJ_WALK_RC_CONTINUE);
731 }
732 
744 always_inline void
745 hicn_iface_ip6_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags,
746  const ip6_address_t *nat_addr, u32 sw_if,
747  u32 adj_index, u32 node_index)
748 {
749  /*All (complete) faces are indexed by remote addess as well */
750  /* if the face exists, it adds a lock */
751  hicn_face_t *face = hicn_face_get ((ip46_address_t *) nat_addr, sw_if,
752  &hicn_face_hashtb, adj_index);
753 
754  if (face == NULL)
755  {
756  hicn_face_id_t idx;
757  hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, DPO_PROTO_IP6,
758  adj_index);
759 
760  face = hicn_dpoi_get_from_idx (idx);
761 
762  face->dpo.dpoi_type = DPO_FIRST;
763  face->dpo.dpoi_proto = DPO_PROTO_IP6;
764  face->dpo.dpoi_index = adj_index;
765  face->dpo.dpoi_next_node = node_index;
766 
767  adj_nbr_walk (face->sw_if, FIB_PROTOCOL_IP6, hicn6_iface_adj_walk_cb,
768  face);
769 
770  *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
771 
772  *index = idx;
773 
774  return;
775  }
776  else
777  {
778  /* unlock the face. We don't take a lock on each interest we receive */
779  hicn_face_id_t face_id = hicn_dpoi_get_index (face);
780  hicn_face_unlock_with_id (face_id);
781  }
782 
783  /* Code replicated on purpose */
784  *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
785  *hicnb_flags |= (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
786  HICN_FACE_FLAGS_APPFACE_PROD_BIT;
787 
788  *index = hicn_dpoi_get_index (face);
789 }
790 
791 #endif // __HICN_FACE_H__
792 
793 /*
794  * fd.io coding-style-patch-verification: ON
795  *
796  * Local Variables:
797  * eval: (c-set-style "gnu")
798  * End:
799  */
hicn_face_get_key
always_inline void hicn_face_get_key(const ip46_address_t *addr, u32 sw_if, const dpo_id_t *dpo, hicn_face_key_t *key)
Create the key object for the mhash. Fill in the key object with the expected values.
Definition: face.h:408
hicn_face_get
always_inline hicn_face_t * hicn_face_get(const ip46_address_t *addr, u32 sw_if, mhash_t *hashtb, index_t adj_index)
Get the face obj from the nat address. Does not add any lock.
Definition: face.h:427
hicn_face_vec_hashtb
mhash_t hicn_face_vec_hashtb
ip6_address_t
Definition: common.h:173
hicn_face_vec_t
hicn_face_id_t * hicn_face_vec_t
Definition: face.h:339
hicn_vec_pool
hicn_face_vec_t * hicn_vec_pool
hicn_iface_ip4_add_and_lock
always_inline void hicn_iface_ip4_add_and_lock(hicn_face_id_t *index, u8 *hicnb_flags, const ip4_address_t *nat_addr, u32 sw_if, u32 adj_index, u32 node_index)
Retrieve, or create if it doesn't exist, a face from the ip6 local address and returns its dpo....
Definition: face.h:662
hicn_face_unlock
always_inline void hicn_face_unlock(dpo_id_t *dpo)
Remove a lock to the face through its dpo. Deallocate the face id locks == 0.
Definition: face.h:303
hicn_face_module_init
void hicn_face_module_init(vlib_main_t *vm)
Init the internal structures of the face module.
hicn_face_lock
always_inline void hicn_face_lock(dpo_id_t *dpo)
Add a lock to the face through its dpo.
Definition: face.h:291
hicn_dpoi_get_from_idx
always_inline hicn_face_t * hicn_dpoi_get_from_idx(hicn_face_id_t dpoi_index)
Return the face from the face id. Face id must be valid.
Definition: face.h:244
hicn_dpoi_get_index
always_inline hicn_face_id_t hicn_dpoi_get_index(hicn_face_t *face_dpoi)
Return the face id from the face object.
Definition: face.h:216
hicn_face_vft_s
Definition of the virtual functin table for an hICN FACE DPO.
Definition: face.h:164
hicn_face_get_vec
always_inline hicn_face_input_faces_t * hicn_face_get_vec(const ip46_address_t *addr, mhash_t *hashtb)
Get the vector of faces from the ip v4 address. Does not add any lock.
Definition: face.h:491
hicn_face_unlock_with_id
always_inline void hicn_face_unlock_with_id(hicn_face_id_t face_id)
Remove a lock to the face dpo. Deallocate the face id locks == 0.
Definition: face.h:278
hicn_face_del
int hicn_face_del(hicn_face_id_t face_id)
Delete a face.
hicn_face_ip4_lock
always_inline int hicn_face_ip4_lock(hicn_face_id_t *face_id, u32 *in_faces_vec_id, u8 *hicnb_flags, const ip4_address_t *nat_addr)
Retrieve a vector of faces from the ip4 local address and returns its index.
Definition: face.h:577
hicn_face_get_with_dpo
always_inline hicn_face_t * hicn_face_get_with_dpo(const ip46_address_t *addr, u32 sw_if, const dpo_id_t *dpo, mhash_t *hashtb)
Get the face obj from the nat address and the dpo. Does not add any lock.
Definition: face.h:461
ip4_address_t
Definition: common.h:167
format_hicn_face_all
u8 * format_hicn_face_all(u8 *s, int n,...)
Format all the existing faces.
hicn_iface_ip6_add_and_lock
always_inline void hicn_iface_ip6_add_and_lock(hicn_face_id_t *index, u8 *hicnb_flags, const ip6_address_t *nat_addr, u32 sw_if, u32 adj_index, u32 node_index)
Retrieve, or create if it doesn't exist, a face from the ip6 local address and returns its dpo....
Definition: face.h:745
hicn_iface_add
always_inline void hicn_iface_add(ip46_address_t *nat_address, int sw_if, hicn_face_id_t *pfaceid, dpo_proto_t proto, u32 adj_index)
Create a new incomplete face ip. (Meant to be used by the data plane)
Definition: face.h:528
hicn_input_faces_s_
Definition: face.h:341
hicn_face_vft_t
struct hicn_face_vft_s hicn_face_vft_t
Definition of the virtual functin table for an hICN FACE DPO.
hicn_face_lock_with_id
always_inline void hicn_face_lock_with_id(hicn_face_id_t face_id)
Add a lock to the face dpo.
Definition: face.h:265
hicn_dpoi_get_from_idx_safe
always_inline hicn_face_t * hicn_dpoi_get_from_idx_safe(hicn_face_id_t dpoi_index)
Return the face object from the face id. This method is robust to invalid face id.
Definition: face.h:229
hicn_dpoi_idx_is_valid
always_inline int hicn_dpoi_idx_is_valid(hicn_face_id_t face_id)
Return true if the face id belongs to an existing face.
Definition: face.h:253
hicn_face_ip6_lock
always_inline int hicn_face_ip6_lock(hicn_face_id_t *face_id, u32 *in_faces_vec_id, u8 *hicnb_flags, const ip6_address_t *nat_addr)
Retrieve a face from the ip6 local address and returns its dpo. This method adds a lock on the face s...
Definition: face.h:614
hicn_face_add
int hicn_face_add(const dpo_id_t *dpo_nh, ip46_address_t *nat_address, int sw_if, hicn_face_id_t *pfaceid, u8 is_app_prod)
Create a new face ip. API for other modules (e.g., routing)
ip46_address_t
Definition: common.h:181