FD.io VPP  v17.07.01-10-g3be13f0
Vector Packet Processing
gid_dictionary.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 
17 
18 typedef struct
19 {
20  void *arg;
21  ip_prefix_t src;
23  union
24  {
27  };
29 
30 static u32 ip4_lookup (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key);
31 
32 static u32 ip6_lookup (gid_ip6_table_t * db, u32 vni, ip_prefix_t * key);
33 
34 static void
35 foreach_sfib4_subprefix (BVT (clib_bihash_kv) * kvp, void *arg)
36 {
37  sfib_entry_arg_t *a = arg;
38  u32 ip = (u32) kvp->key[0];
39  ip4_address_t *mask;
40  u8 plen = ip_prefix_len (&a->src);
41 
42  ASSERT (plen <= 32);
43  mask = &a->ip4_table->ip4_fib_masks[plen];
44 
45  u32 src_ip = ip_prefix_v4 (&a->src).as_u32;
46  src_ip &= mask->as_u32;
47  ip &= mask->as_u32;
48 
49  if (src_ip == ip)
50  {
51  /* found sub-prefix of src prefix */
52  (a->cb) (kvp->value, a->arg);
53  }
54 }
55 
56 static void
58  ip_prefix_t * src, ip_prefix_t * dst,
59  foreach_subprefix_match_cb_t cb, void *arg)
60 {
61  u32 sfi;
62  gid_ip4_table_t *sfib4;
64 
65  sfi = ip4_lookup (&db->dst_ip4_table, vni, dst);
66  if (GID_LOOKUP_MISS == sfi)
67  return;
68 
69  sfib4 = pool_elt_at_index (db->src_ip4_table_pool, sfi);
70 
71  a.arg = arg;
72  a.cb = cb;
73  a.src = src[0];
74  a.ip4_table = sfib4;
75 
76  BV (clib_bihash_foreach_key_value_pair) (&sfib4->ip4_lookup_table,
78 }
79 
80 static void
81 foreach_sfib6_subprefix (BVT (clib_bihash_kv) * kvp, void *arg)
82 {
83  sfib_entry_arg_t *a = arg;
84  ip6_address_t ip;
85  ip6_address_t *mask;
86  u8 plen = ip_prefix_len (&a->src);
87 
88  mask = &a->ip6_table->ip6_fib_masks[plen];
89  ip.as_u64[0] = kvp->key[0];
90  ip.as_u64[1] = kvp->key[1];
91 
92  if (ip6_address_is_equal_masked (&ip_prefix_v6 (&a->src), &ip, mask))
93  {
94  /* found sub-prefix of src prefix */
95  (a->cb) (kvp->value, a->arg);
96  }
97 }
98 
99 static void
101  ip_prefix_t * src, ip_prefix_t * dst,
102  foreach_subprefix_match_cb_t cb, void *arg)
103 {
104  u32 sfi;
105  gid_ip6_table_t *sfib6;
107 
108  sfi = ip6_lookup (&db->dst_ip6_table, vni, dst);
109  if (GID_LOOKUP_MISS == sfi)
110  return;
111 
112  sfib6 = pool_elt_at_index (db->src_ip6_table_pool, sfi);
113 
114  a.arg = arg;
115  a.cb = cb;
116  a.src = src[0];
117  a.ip6_table = sfib6;
118 
119  BV (clib_bihash_foreach_key_value_pair) (&sfib6->ip6_lookup_table,
121 }
122 
123 void
125  foreach_subprefix_match_cb_t cb, void *arg)
126 {
127  ip_prefix_t *ippref = &gid_address_sd_dst_ippref (eid);
128 
129  if (IP4 == ip_prefix_version (ippref))
132  &gid_address_sd_dst_ippref (eid), cb,
133  arg);
134  else
137  &gid_address_sd_dst_ippref (eid), cb,
138  arg);
139 }
140 
141 void
143  (BVT (clib_bihash_kv) * kvp, void *arg),
144  void *ht)
145 {
146  gid_l2_arp_table_t *tab = &db->arp_table;
147  BV (clib_bihash_foreach_key_value_pair) (&tab->arp_lookup_table, cb, ht);
148 }
149 
150 static void
151 make_mac_sd_key (BVT (clib_bihash_kv) * kv, u32 vni, u8 src_mac[6],
152  u8 dst_mac[6])
153 {
154  kv->key[0] = (u64) vni;
155  kv->key[1] = mac_to_u64 (dst_mac);
156  kv->key[2] = src_mac ? mac_to_u64 (src_mac) : (u64) 0;
157 }
158 
159 static u32
160 mac_sd_lookup (gid_mac_table_t * db, u32 vni, u8 * dst, u8 * src)
161 {
162  int rv;
163  BVT (clib_bihash_kv) kv, value;
164 
165  make_mac_sd_key (&kv, vni, src, dst);
166  rv = BV (clib_bihash_search_inline_2) (&db->mac_lookup_table, &kv, &value);
167 
168  /* no match, try with src 0, catch all for dst */
169  if (rv != 0)
170  {
171  kv.key[2] = 0;
172  rv = BV (clib_bihash_search_inline_2) (&db->mac_lookup_table, &kv,
173  &value);
174  if (rv == 0)
175  return value.value;
176  }
177  else
178  return value.value;
179 
180  return GID_LOOKUP_MISS;
181 }
182 
183 static u32
184 ip4_lookup_exact_match (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key)
185 {
186  int rv;
187  BVT (clib_bihash_kv) kv, value;
188 
189  ip4_address_t *mask;
190 
191  mask = &db->ip4_fib_masks[ip_prefix_len (key)];
192 
193  kv.key[0] = ((u64) vni << 32) | (ip_prefix_v4 (key).as_u32 & mask->as_u32);
194  kv.key[1] = 0;
195  kv.key[2] = 0;
196 
197  rv = BV (clib_bihash_search_inline_2) (&db->ip4_lookup_table, &kv, &value);
198  if (rv == 0)
199  return value.value;
200 
201  return GID_LOOKUP_MISS;
202 }
203 
204 static u32
205 ip4_lookup (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key)
206 {
207  int i, len;
208  int rv;
209  BVT (clib_bihash_kv) kv, value;
210 
212 
213  for (i = 0; i < len; i++)
214  {
215  int dst_address_length = db->ip4_prefix_lengths_in_search_order[i];
216  ip4_address_t *mask;
217 
218  ASSERT (dst_address_length >= 0 && dst_address_length <= 32);
219 
220  mask = &db->ip4_fib_masks[dst_address_length];
221 
222  kv.key[0] =
223  ((u64) vni << 32) | (ip_prefix_v4 (key).as_u32 & mask->as_u32);
224  kv.key[1] = 0;
225  kv.key[2] = 0;
226 
227  rv =
228  BV (clib_bihash_search_inline_2) (&db->ip4_lookup_table, &kv, &value);
229  if (rv == 0)
230  return value.value;
231  }
232 
233  return GID_LOOKUP_MISS;
234 }
235 
236 static u32
237 ip6_lookup_exact_match (gid_ip6_table_t * db, u32 vni, ip_prefix_t * key)
238 {
239  int rv;
240  BVT (clib_bihash_kv) kv, value;
241 
242  ip6_address_t *mask;
243  mask = &db->ip6_fib_masks[ip_prefix_len (key)];
244 
245  kv.key[0] = ip_prefix_v6 (key).as_u64[0] & mask->as_u64[0];
246  kv.key[1] = ip_prefix_v6 (key).as_u64[1] & mask->as_u64[1];
247  kv.key[2] = (u64) vni;
248 
249  rv = BV (clib_bihash_search_inline_2) (&db->ip6_lookup_table, &kv, &value);
250  if (rv == 0)
251  return value.value;
252 
253  return GID_LOOKUP_MISS;
254 }
255 
256 static u32
257 ip6_lookup (gid_ip6_table_t * db, u32 vni, ip_prefix_t * key)
258 {
259  int i, len;
260  int rv;
261  BVT (clib_bihash_kv) kv, value;
262 
264 
265  for (i = 0; i < len; i++)
266  {
267  int dst_address_length = db->ip6_prefix_lengths_in_search_order[i];
268  ip6_address_t *mask;
269 
270  ASSERT (dst_address_length >= 0 && dst_address_length <= 128);
271 
272  mask = &db->ip6_fib_masks[dst_address_length];
273 
274  kv.key[0] = ip_prefix_v6 (key).as_u64[0] & mask->as_u64[0];
275  kv.key[1] = ip_prefix_v6 (key).as_u64[1] & mask->as_u64[1];
276  kv.key[2] = (u64) vni;
277 
278  rv =
279  BV (clib_bihash_search_inline_2) (&db->ip6_lookup_table, &kv, &value);
280  if (rv == 0)
281  return value.value;
282  }
283 
284  return GID_LOOKUP_MISS;
285 }
286 
287 static u32
288 ip_sd_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst,
289  ip_prefix_t * src)
290 {
291  u32 sfi;
292  gid_ip4_table_t *sfib4;
293  gid_ip6_table_t *sfib6;
294 
295  switch (ip_prefix_version (dst))
296  {
297  case IP4:
298  sfi = ip4_lookup (&db->dst_ip4_table, vni, dst);
299  if (GID_LOOKUP_MISS != sfi)
300  sfib4 = pool_elt_at_index (db->src_ip4_table_pool, sfi);
301  else
302  return GID_LOOKUP_MISS;
303 
304  if (!src)
305  {
306  ip_prefix_t sp;
307  memset (&sp, 0, sizeof (sp));
308  return ip4_lookup_exact_match (sfib4, 0, &sp);
309  }
310  else
311  return ip4_lookup (sfib4, 0, src);
312 
313  break;
314  case IP6:
315  sfi = ip6_lookup (&db->dst_ip6_table, vni, dst);
316  if (GID_LOOKUP_MISS != sfi)
317  sfib6 = pool_elt_at_index (db->src_ip6_table_pool, sfi);
318  else
319  return GID_LOOKUP_MISS;
320 
321  if (!src)
322  {
323  ip_prefix_t sp;
324  memset (&sp, 0, sizeof (sp));
325  ip_prefix_version (&sp) = IP6;
326  return ip6_lookup_exact_match (sfib6, 0, &sp);
327  }
328  else
329  return ip6_lookup (sfib6, 0, src);
330 
331  break;
332  default:
333  clib_warning ("address type %d not supported!",
334  ip_prefix_version (dst));
335  break;
336  }
337  return GID_LOOKUP_MISS;
338 }
339 
340 static void
341 make_arp_key (BVT (clib_bihash_kv) * kv, u32 bd, ip4_address_t * addr)
342 {
343  kv->key[0] = (u64) bd;
344  kv->key[1] = (u64) addr->as_u32;
345  kv->key[2] = (u64) 0;
346 }
347 
348 static void
349 make_nsh_key (BVT (clib_bihash_kv) * kv, u32 vni, u32 spi, u8 si)
350 {
351  kv->key[0] = (u64) vni;
352  kv->key[1] = (u64) spi;
353  kv->key[2] = (u64) si;
354 }
355 
356 static u64
358 {
359  int rv;
360  BVT (clib_bihash_kv) kv, value;
361 
362  make_arp_key (&kv, bd, key);
363  rv = BV (clib_bihash_search_inline_2) (&db->arp_lookup_table, &kv, &value);
364 
365  if (rv == 0)
366  return value.value;
367 
368  return GID_LOOKUP_MISS_L2;
369 }
370 
371 static u32
372 nsh_lookup (gid_nsh_table_t * db, u32 vni, u32 spi, u8 si)
373 {
374  int rv;
375  BVT (clib_bihash_kv) kv, value;
376 
377  make_nsh_key (&kv, vni, spi, si);
378  rv = BV (clib_bihash_search_inline_2) (&db->nsh_lookup_table, &kv, &value);
379 
380  if (rv == 0)
381  return value.value;
382 
383  return GID_LOOKUP_MISS;
384 }
385 
386 u64
388 {
389  switch (gid_address_type (key))
390  {
391  case GID_ADDR_IP_PREFIX:
392  return ip_sd_lookup (db, gid_address_vni (key),
393  &gid_address_ippref (key), 0);
394  case GID_ADDR_MAC:
395  return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (key),
396  gid_address_mac (key), 0);
397  case GID_ADDR_SRC_DST:
398  switch (gid_address_sd_dst_type (key))
399  {
400  case FID_ADDR_IP_PREF:
401  return ip_sd_lookup (db, gid_address_vni (key),
404  break;
405  case FID_ADDR_MAC:
406  return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (key),
408  gid_address_sd_src_mac (key));
409  break;
410  default:
411  clib_warning ("Source/Dest address type %d not supported!",
413  break;
414  }
415  break;
416  case GID_ADDR_ARP:
417  return arp_lookup (&db->arp_table, gid_address_arp_bd (key),
418  &gid_address_arp_ip4 (key));
419  case GID_ADDR_NSH:
420  return nsh_lookup (&db->nsh_table, gid_address_vni (key),
422  default:
423  clib_warning ("address type %d not supported!", gid_address_type (key));
424  break;
425  }
426  return GID_LOOKUP_MISS;
427 }
428 
429 u32
431  gid_address_t * src)
432 {
433  switch (gid_address_type (dst))
434  {
435  case GID_ADDR_IP_PREFIX:
436  return ip_sd_lookup (db, gid_address_vni (dst),
437  &gid_address_ippref (dst),
438  &gid_address_ippref (src));
439  case GID_ADDR_MAC:
440  return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (dst),
441  gid_address_mac (dst), gid_address_mac (src));
442  case GID_ADDR_SRC_DST:
443  switch (gid_address_sd_dst_type (dst))
444  {
445  case FID_ADDR_IP_PREF:
446  return ip_sd_lookup (db, gid_address_vni (dst),
449  break;
450  case FID_ADDR_MAC:
451  return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (dst),
453  gid_address_sd_src_mac (dst));
454  break;
455  default:
456  clib_warning ("Source/Dest address type %d not supported!",
458  break;
459  }
460  break;
461  case GID_ADDR_NSH:
462  return gid_dictionary_lookup (db, dst);
463  break;
464  default:
465  clib_warning ("address type %d not supported!", gid_address_type (dst));
466  break;
467  }
468  return GID_LOOKUP_MISS;
469 }
470 
471 static void
473 {
474  int i;
476  /* Note: bitmap reversed so this is in fact a longest prefix match */
477 
478  /* *INDENT-OFF* */
480  ({
481  int dst_address_length = 32 - i;
482  vec_add1 (db->ip4_prefix_lengths_in_search_order, dst_address_length);
483  }));
484  /* *INDENT-ON* */
485 
486 }
487 
488 static u32
489 add_del_ip4_key (gid_ip4_table_t * db, u32 vni, ip_prefix_t * pref, u32 val,
490  u8 is_add)
491 {
492  BVT (clib_bihash_kv) kv, value;
493  u32 old_val = ~0;
494  ip4_address_t key;
495  u8 plen = ip_prefix_len (pref);
496 
497  clib_memcpy (&key, &ip_prefix_v4 (pref), sizeof (key));
498  key.as_u32 &= db->ip4_fib_masks[plen].as_u32;
499  if (is_add)
500  {
503  32 - plen, 1);
505 
506  db->ip4_prefix_len_refcount[plen]++;
507  }
508  else
509  {
510  ASSERT (db->ip4_prefix_len_refcount[plen] != 0);
511 
512  db->ip4_prefix_len_refcount[plen]--;
513 
514  if (db->ip4_prefix_len_refcount[plen] == 0)
515  {
518  32 - plen, 0);
520  }
521  }
522 
523  kv.key[0] = ((u64) vni << 32) | key.as_u32;
524  kv.key[1] = 0;
525  kv.key[2] = 0;
526 
527  if (BV (clib_bihash_search) (&db->ip4_lookup_table, &kv, &value) == 0)
528  old_val = value.value;
529 
530  if (!is_add)
531  {
532  BV (clib_bihash_add_del) (&db->ip4_lookup_table, &kv, 0 /* is_add */ );
533  db->count--;
534  }
535  else
536  {
537  kv.value = val;
538  BV (clib_bihash_add_del) (&db->ip4_lookup_table, &kv, 1 /* is_add */ );
539  db->count++;
540  }
541  return old_val;
542 }
543 
544 static void
546 {
547  uword i;
548 
549  memset (db->ip4_prefix_len_refcount, 0,
550  sizeof (db->ip4_prefix_len_refcount));
551 
552  for (i = 0; i < ARRAY_LEN (db->ip4_fib_masks); i++)
553  {
554  u32 m;
555 
556  if (i < 32)
557  m = pow2_mask (i) << (32 - i);
558  else
559  m = ~0;
560  db->ip4_fib_masks[i].as_u32 = clib_host_to_net_u32 (m);
561  }
562  if (db->ip4_lookup_table_nbuckets == 0)
564 
567 
568  if (db->ip4_lookup_table_size == 0)
570 
571  BV (clib_bihash_init) (&db->ip4_lookup_table, "ip4 lookup table",
574 }
575 
576 static u32
577 add_del_sd_ip4_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref,
578  ip_prefix_t * src_pref, u32 val, u8 is_add)
579 {
580  u32 sfi, old_val = ~0;
581  gid_ip4_table_t *sfib;
582 
583  sfi = ip4_lookup_exact_match (&db->dst_ip4_table, vni, dst_pref);
584 
585  if (is_add)
586  {
587  if (GID_LOOKUP_MISS == sfi)
588  {
589  pool_get (db->src_ip4_table_pool, sfib);
590  ip4_lookup_init (sfib);
591  add_del_ip4_key (&db->dst_ip4_table, vni, dst_pref,
592  sfib - db->src_ip4_table_pool, is_add);
593  if (src_pref)
594  add_del_ip4_key (sfib, 0 /* vni */ , src_pref, val, is_add);
595  else
596  {
597  ip_prefix_t sp;
598  memset (&sp, 0, sizeof (sp));
599  add_del_ip4_key (sfib, 0 /* vni */ , &sp, val, is_add);
600  }
601  }
602  else
603  {
605  sfib = pool_elt_at_index (db->src_ip4_table_pool, sfi);
606  if (src_pref)
607  {
608  old_val = ip4_lookup_exact_match (sfib, 0, src_pref);
609  add_del_ip4_key (sfib, 0 /* vni */ , src_pref, val, is_add);
610  }
611  else
612  {
613  ip_prefix_t sp;
614  memset (&sp, 0, sizeof (sp));
615  old_val =
616  add_del_ip4_key (sfib, 0 /* vni */ , &sp, val, is_add);
617  }
618  }
619  }
620  else
621  {
622  if (GID_LOOKUP_MISS != sfi)
623  {
624  sfib = pool_elt_at_index (db->src_ip4_table_pool, sfi);
625  if (src_pref)
626  old_val = add_del_ip4_key (sfib, 0, src_pref, 0, is_add);
627  else
628  {
629  ip_prefix_t sp;
630  memset (&sp, 0, sizeof (sp));
631  old_val = add_del_ip4_key (sfib, 0, &sp, 0, is_add);
632  }
633 
634  if (sfib->count == 0)
635  add_del_ip4_key (&db->dst_ip4_table, vni, dst_pref, 0, is_add);
636  }
637  else
638  clib_warning ("cannot delete dst mapping %U!", format_ip_prefix,
639  dst_pref);
640  }
641  return old_val;
642 }
643 
644 static void
646 {
647  int i;
649  /* Note: bitmap reversed so this is in fact a longest prefix match */
650 
651  /* *INDENT-OFF* */
653  ({
654  int dst_address_length = 128 - i;
655  vec_add1 (db->ip6_prefix_lengths_in_search_order, dst_address_length);
656  }));
657  /* *INDENT-ON* */
658 }
659 
660 static u32
661 add_del_ip6_key (gid_ip6_table_t * db, u32 vni, ip_prefix_t * pref, u32 val,
662  u8 is_add)
663 {
664  BVT (clib_bihash_kv) kv, value;
665  u32 old_val = ~0;
666  ip6_address_t key;
667  u8 plen = ip_prefix_len (pref);
668 
669  clib_memcpy (&key, &ip_prefix_v6 (pref), sizeof (key));
670  ip6_address_mask (&key, &db->ip6_fib_masks[plen]);
671  if (is_add)
672  {
675  128 - plen, 1);
677  db->ip6_prefix_len_refcount[plen]++;
678  }
679  else
680  {
681  ASSERT (db->ip6_prefix_len_refcount[plen] != 0);
682 
683  db->ip6_prefix_len_refcount[plen]--;
684 
685  if (db->ip6_prefix_len_refcount[plen] == 0)
686  {
689  128 - plen, 0);
691  }
692  }
693 
694  kv.key[0] = key.as_u64[0];
695  kv.key[1] = key.as_u64[1];
696  kv.key[2] = (u64) vni;
697 // kv.key[2] = ((u64)((fib - im->fibs))<<32) | ip_prefix_len(key);
698 
699  if (BV (clib_bihash_search) (&db->ip6_lookup_table, &kv, &value) == 0)
700  old_val = value.value;
701 
702  if (!is_add)
703  {
704  BV (clib_bihash_add_del) (&db->ip6_lookup_table, &kv, 0 /* is_add */ );
705  db->count--;
706  }
707  else
708  {
709  kv.value = val;
710  BV (clib_bihash_add_del) (&db->ip6_lookup_table, &kv, 1 /* is_add */ );
711  db->count++;
712  }
713  return old_val;
714 }
715 
716 static u32
717 add_del_mac (gid_mac_table_t * db, u32 vni, u8 * dst_mac, u8 * src_mac,
718  u32 val, u8 is_add)
719 {
720  BVT (clib_bihash_kv) kv, value;
721  u32 old_val = ~0;
722 
723  make_mac_sd_key (&kv, vni, src_mac, dst_mac);
724 
725  if (BV (clib_bihash_search) (&db->mac_lookup_table, &kv, &value) == 0)
726  old_val = value.value;
727 
728  if (!is_add)
729  {
730  BV (clib_bihash_add_del) (&db->mac_lookup_table, &kv, 0 /* is_add */ );
731  db->count--;
732  }
733  else
734  {
735  kv.value = val;
736  BV (clib_bihash_add_del) (&db->mac_lookup_table, &kv, 1 /* is_add */ );
737  db->count++;
738  }
739  return old_val;
740 }
741 
742 static void
744 {
745  uword i;
746 
747  memset (db->ip6_prefix_len_refcount, 0,
748  sizeof (db->ip6_prefix_len_refcount));
749 
750  for (i = 0; i < ARRAY_LEN (db->ip6_fib_masks); i++)
751  {
752  u32 j, i0, i1;
753 
754  i0 = i / 32;
755  i1 = i % 32;
756 
757  for (j = 0; j < i0; j++)
758  db->ip6_fib_masks[i].as_u32[j] = ~0;
759 
760  if (i1)
761  db->ip6_fib_masks[i].as_u32[i0] =
762  clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
763  }
764 
765  if (db->ip6_lookup_table_nbuckets == 0)
767 
770 
771  if (db->ip6_lookup_table_size == 0)
773 
774  BV (clib_bihash_init) (&db->ip6_lookup_table, "ip6 lookup table",
777 }
778 
779 static u32
780 add_del_sd_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref,
781  ip_prefix_t * src_pref, u32 val, u8 is_add)
782 {
783  u32 sfi, old_val = ~0;
784  gid_ip6_table_t *sfib;
785 
786  sfi = ip6_lookup_exact_match (&db->dst_ip6_table, vni, dst_pref);
787 
788  if (is_add)
789  {
790  if (GID_LOOKUP_MISS == sfi)
791  {
792  pool_get (db->src_ip6_table_pool, sfib);
793  ip6_lookup_init (sfib);
794  add_del_ip6_key (&db->dst_ip6_table, vni, dst_pref,
795  sfib - db->src_ip6_table_pool, is_add);
796  if (src_pref)
797  add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add);
798  else
799  {
800  ip_prefix_t sp;
801  memset (&sp, 0, sizeof (sp));
802  ip_prefix_version (&sp) = IP6;
803  add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add);
804  }
805  }
806  else
807  {
809  sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi);
810  if (src_pref)
811  {
812  old_val = ip6_lookup_exact_match (sfib, 0, src_pref);
813  add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add);
814  }
815  else
816  {
817  ip_prefix_t sp;
818  memset (&sp, 0, sizeof (sp));
819  ip_prefix_version (&sp) = IP6;
820  old_val =
821  add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add);
822  }
823  }
824  }
825  else
826  {
827  if (GID_LOOKUP_MISS != sfi)
828  {
829  sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi);
830  if (src_pref)
831  old_val = add_del_ip6_key (sfib, 0, src_pref, 0, is_add);
832  else
833  {
834  ip_prefix_t sp;
835  memset (&sp, 0, sizeof (sp));
836  ip_prefix_version (&sp) = IP6;
837  old_val = add_del_ip6_key (sfib, 0, &sp, 0, is_add);
838  }
839 
840  if (sfib->count == 0)
841  add_del_ip6_key (&db->dst_ip6_table, vni, dst_pref, 0, is_add);
842  }
843  else
844  clib_warning ("cannot delete dst mapping %U!", format_ip_prefix,
845  dst_pref);
846  }
847  return old_val;
848 }
849 
850 static u32
851 add_del_ip (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_key,
852  ip_prefix_t * src_key, u32 value, u8 is_add)
853 {
854  switch (ip_prefix_version (dst_key))
855  {
856  case IP4:
857  return add_del_sd_ip4_key (db, vni, dst_key, src_key, value, is_add);
858  break;
859  case IP6:
860  return add_del_sd_ip6_key (db, vni, dst_key, src_key, value, is_add);
861  break;
862  default:
863  clib_warning ("address type %d not supported!",
864  ip_prefix_version (dst_key));
865  break;
866  }
867  return ~0;
868 }
869 
870 static u32
872  u8 is_add)
873 {
874  switch (sd_dst_type (key))
875  {
876  case FID_ADDR_IP_PREF:
877  add_del_ip (db, vni, &sd_dst_ippref (key), &sd_src_ippref (key),
878  value, is_add);
879 
880  case FID_ADDR_MAC:
881  return add_del_mac (&db->sd_mac_table, vni, sd_dst_mac (key),
882  sd_src_mac (key), value, is_add);
883 
884  default:
885  clib_warning ("SD address type %d not supprted!", sd_dst_type (key));
886  break;
887  }
888 
889  return ~0;
890 }
891 
892 static u64
894  u8 is_add)
895 {
896  BVT (clib_bihash_kv) kv, result;
897  u32 old_val = ~0;
898 
899  make_arp_key (&kv, bd, key);
900  if (BV (clib_bihash_search) (&db->arp_lookup_table, &kv, &result) == 0)
901  old_val = result.value;
902 
903  if (is_add)
904  {
905  kv.value = value;
906  BV (clib_bihash_add_del) (&db->arp_lookup_table, &kv, 1 /* is_add */ );
907  db->count++;
908  }
909  else
910  {
911  BV (clib_bihash_add_del) (&db->arp_lookup_table, &kv, 0 /* is_add */ );
912  db->count--;
913  }
914  return old_val;
915 }
916 
917 static u32
918 add_del_nsh (gid_nsh_table_t * db, u32 vni, u32 spi, u8 si, u32 value,
919  u8 is_add)
920 {
921  BVT (clib_bihash_kv) kv, result;
922  u32 old_val = ~0;
923 
924  make_nsh_key (&kv, vni, spi, si);
925  if (BV (clib_bihash_search) (&db->nsh_lookup_table, &kv, &result) == 0)
926  old_val = result.value;
927 
928  if (is_add)
929  {
930  kv.value = value;
931  BV (clib_bihash_add_del) (&db->nsh_lookup_table, &kv, 1 /* is_add */ );
932  db->count++;
933  }
934  else
935  {
936  BV (clib_bihash_add_del) (&db->nsh_lookup_table, &kv, 0 /* is_add */ );
937  db->count--;
938  }
939  return old_val;
940 }
941 
942 u32
944  u8 is_add)
945 {
946  switch (gid_address_type (key))
947  {
948  case GID_ADDR_IP_PREFIX:
949  return add_del_ip (db, gid_address_vni (key), &gid_address_ippref (key),
950  0, (u32) value, is_add);
951  case GID_ADDR_MAC:
952  return add_del_mac (&db->sd_mac_table, gid_address_vni (key),
953  gid_address_mac (key), 0, (u32) value, is_add);
954  case GID_ADDR_SRC_DST:
955  return add_del_sd (db, gid_address_vni (key), &gid_address_sd (key),
956  (u32) value, is_add);
957  case GID_ADDR_ARP:
958  return add_del_arp (&db->arp_table, gid_address_arp_bd (key),
959  &gid_address_arp_ip4 (key), value, is_add);
960  case GID_ADDR_NSH:
961  return add_del_nsh (&db->nsh_table, gid_address_vni (key),
963  value, is_add);
964 
965  default:
966  clib_warning ("address type %d not supported!", gid_address_type (key));
967  break;
968  }
969  return ~0;
970 }
971 
972 static void
974 {
975  if (db->mac_lookup_table_nbuckets == 0)
977 
980 
981  if (db->mac_lookup_table_size == 0)
983 
984  BV (clib_bihash_init) (&db->mac_lookup_table, "mac lookup table",
987 }
988 
989 static void
991 {
992  if (db->arp_lookup_table_nbuckets == 0)
994 
997 
998  if (db->arp_lookup_table_size == 0)
1000 
1001  BV (clib_bihash_init) (&db->arp_lookup_table, "arp lookup table",
1003  db->arp_lookup_table_size);
1004 }
1005 
1006 static void
1008 {
1009  if (db->nsh_lookup_table_nbuckets == 0)
1011 
1014 
1015  if (db->nsh_lookup_table_size == 0)
1017 
1018  BV (clib_bihash_init) (&db->nsh_lookup_table, "nsh lookup table",
1020  db->nsh_lookup_table_size);
1021 }
1022 
1023 void
1025 {
1029  arp_lookup_init (&db->arp_table);
1030  nsh_lookup_init (&db->nsh_table);
1031 }
1032 
1033 /*
1034  * fd.io coding-style-patch-verification: ON
1035  *
1036  * Local Variables:
1037  * eval: (c-set-style "gnu")
1038  * End:
1039  */
#define ip_prefix_v4(_a)
Definition: lisp_types.h:74
static u32 add_del_ip(gid_dictionary_t *db, u32 vni, ip_prefix_t *dst_key, ip_prefix_t *src_key, u32 value, u8 is_add)
static void ip6_address_mask(ip6_address_t *a, ip6_address_t *mask)
Definition: ip6_packet.h:235
#define IP6_LOOKUP_DEFAULT_HASH_NUM_BUCKETS
#define gid_address_arp_bd(_a)
Definition: lisp_types.h:280
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
gid_ip4_table_t * src_ip4_table_pool
pool of source IP LPM ip4 lookup tables
#define gid_address_type(_a)
Definition: lisp_types.h:257
#define sd_dst_mac(_a)
Definition: lisp_types.h:149
a
Definition: bitmap.h:516
ip4_address_t ip4_fib_masks[33]
gid_l2_arp_table_t arp_table
L2 ARP table.
static void make_nsh_key(BVT(clib_bihash_kv)*kv, u32 vni, u32 spi, u8 si)
static u32 mac_sd_lookup(gid_mac_table_t *db, u32 vni, u8 *dst, u8 *src)
static void make_arp_key(BVT(clib_bihash_kv)*kv, u32 bd, ip4_address_t *addr)
static void gid_dict_foreach_ip4_subprefix(gid_dictionary_t *db, u32 vni, ip_prefix_t *src, ip_prefix_t *dst, foreach_subprefix_match_cb_t cb, void *arg)
void * arg
u64 as_u64[2]
Definition: ip6_packet.h:51
static void mac_lookup_init(gid_mac_table_t *db)
u32 mac_lookup_table_nbuckets
static void gid_dict_foreach_ip6_subprefix(gid_dictionary_t *db, u32 vni, ip_prefix_t *src, ip_prefix_t *dst, foreach_subprefix_match_cb_t cb, void *arg)
#define MAC_LOOKUP_DEFAULT_HASH_NUM_BUCKETS
static u32 add_del_nsh(gid_nsh_table_t *db, u32 vni, u32 spi, u8 si, u32 value, u8 is_add)
static void ip6_compute_prefix_lengths_in_search_order(gid_ip6_table_t *db)
#define gid_address_sd_src_mac(_a)
Definition: lisp_types.h:272
#define ip_prefix_len(_a)
Definition: lisp_types.h:73
static void nsh_lookup_init(gid_nsh_table_t *db)
#define gid_address_sd(_a)
Definition: lisp_types.h:273
u32 ip4_prefix_len_refcount[33]
void gid_dict_foreach_l2_arp_entry(gid_dictionary_t *db, void(*cb)(BVT(clib_bihash_kv)*kvp, void *arg), void *ht)
#define IP4_LOOKUP_DEFAULT_HASH_NUM_BUCKETS
#define gid_address_sd_src_ippref(_a)
Definition: lisp_types.h:270
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
u32 nsh_lookup_table_nbuckets
static uword ip6_address_is_equal_masked(ip6_address_t *a, ip6_address_t *b, ip6_address_t *mask)
Definition: ip6_packet.h:218
#define gid_address_sd_dst_mac(_a)
Definition: lisp_types.h:271
#define IP4_LOOKUP_DEFAULT_HASH_MEMORY_SIZE
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
#define ip_prefix_version(_a)
Definition: lisp_types.h:72
gid_ip4_table_t dst_ip4_table
destination IP LPM ip4 lookup table
static u32 ip4_lookup(gid_ip4_table_t *db, u32 vni, ip_prefix_t *key)
void gid_dictionary_init(gid_dictionary_t *db)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static u32 add_del_sd_ip6_key(gid_dictionary_t *db, u32 vni, ip_prefix_t *dst_pref, ip_prefix_t *src_pref, u32 val, u8 is_add)
u32 gid_dictionary_add_del(gid_dictionary_t *db, gid_address_t *key, u64 value, u8 is_add)
int clib_bihash_add_del(clib_bihash *h, clib_bihash_kv *add_v, int is_add)
Add or delete a (key,value) pair from a bi-hash table.
static u64 add_del_arp(gid_l2_arp_table_t *db, u32 bd, ip4_address_t *key, u64 value, u8 is_add)
static uword pow2_mask(uword x)
Definition: clib.h:257
static u32 add_del_sd(gid_dictionary_t *db, u32 vni, source_dest_t *key, u32 value, u8 is_add)
static BVT(clib_bihash)
Definition: adj_nbr.c:26
static void foreach_sfib6_subprefix(BVT(clib_bihash_kv)*kvp, void *arg)
unsigned long u64
Definition: types.h:89
ip_prefix_t src
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
void gid_dict_foreach_subprefix(gid_dictionary_t *db, gid_address_t *eid, foreach_subprefix_match_cb_t cb, void *arg)
#define gid_address_mac(_a)
Definition: lisp_types.h:263
#define ip_prefix_v6(_a)
Definition: lisp_types.h:75
static u32 ip6_lookup_exact_match(gid_ip6_table_t *db, u32 vni, ip_prefix_t *key)
#define gid_address_sd_dst_type(_a)
Definition: lisp_types.h:277
gid_ip6_table_t * src_ip6_table_pool
pool of source IP LPM ip6 lookup tables
gid_ip6_table_t dst_ip6_table
destination IP LPM ip6 lookup table
static void arp_lookup_init(gid_l2_arp_table_t *db)
static void make_mac_sd_key(BVT(clib_bihash_kv)*kv, u32 vni, u8 src_mac[6], u8 dst_mac[6])
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
u32 ip4_lookup_table_nbuckets
static void foreach_sfib4_subprefix(BVT(clib_bihash_kv)*kvp, void *arg)
#define gid_address_ippref(_a)
Definition: lisp_types.h:258
u32 as_u32[4]
Definition: ip6_packet.h:50
void clib_bihash_foreach_key_value_pair(clib_bihash *h, void *callback, void *arg)
Visit active (key,value) pairs in a bi-hash table.
#define sd_src_ippref(_a)
Definition: lisp_types.h:146
u32 ip6_lookup_table_nbuckets
u8 * ip6_prefix_lengths_in_search_order
static u32 add_del_ip4_key(gid_ip4_table_t *db, u32 vni, ip_prefix_t *pref, u32 val, u8 is_add)
uword nsh_lookup_table_size
uword ip6_lookup_table_size
#define clib_warning(format, args...)
Definition: error.h:59
static u32 ip4_lookup_exact_match(gid_ip4_table_t *db, u32 vni, ip_prefix_t *key)
#define clib_memcpy(a, b, c)
Definition: string.h:69
u8 * ip4_prefix_lengths_in_search_order
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:238
#define ARRAY_LEN(x)
Definition: clib.h:59
#define gid_address_nsh_si(_a)
Definition: lisp_types.h:266
void(* foreach_subprefix_match_cb_t)(u32, void *)
#define sd_src_mac(_a)
Definition: lisp_types.h:148
struct _gid_address_t gid_address_t
#define ASSERT(truth)
#define IP6_LOOKUP_DEFAULT_HASH_MEMORY_SIZE
unsigned int u32
Definition: types.h:88
#define GID_LOOKUP_MISS
int clib_bihash_search(clib_bihash *h, clib_bihash_kv *search_v, clib_bihash_kv *return_v)
Search a bi-hash table.
u32 gid_dictionary_sd_lookup(gid_dictionary_t *db, gid_address_t *dst, gid_address_t *src)
#define sd_dst_type(_a)
Definition: lisp_types.h:151
gid_nsh_table_t nsh_table
NSH lookup table.
u64 ip6_prefix_len_refcount[129]
static u32 add_del_sd_ip4_key(gid_dictionary_t *db, u32 vni, ip_prefix_t *dst_pref, ip_prefix_t *src_pref, u32 val, u8 is_add)
static u64 mac_to_u64(u8 *m)
Definition: load_balance.c:901
#define gid_address_sd_dst_ippref(_a)
Definition: lisp_types.h:269
u64 gid_dictionary_lookup(gid_dictionary_t *db, gid_address_t *key)
static void ip4_compute_prefix_lengths_in_search_order(gid_ip4_table_t *db)
static void ip6_lookup_init(gid_ip6_table_t *db)
u8 * format_ip_prefix(u8 *s, va_list *args)
Definition: lisp_types.c:179
u64 uword
Definition: types.h:112
uword mac_lookup_table_size
uword ip4_lookup_table_size
foreach_subprefix_match_cb_t cb
#define gid_address_vni(_a)
Definition: lisp_types.h:267
gid_mac_table_t sd_mac_table
flat source/dest mac lookup table
uword * ip4_non_empty_dst_address_length_bitmap
static void ip4_lookup_init(gid_ip4_table_t *db)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
static u32 ip_sd_lookup(gid_dictionary_t *db, u32 vni, ip_prefix_t *dst, ip_prefix_t *src)
#define GID_LOOKUP_MISS_L2
static uword max_log2(uword x)
Definition: clib.h:228
static u32 add_del_mac(gid_mac_table_t *db, u32 vni, u8 *dst_mac, u8 *src_mac, u32 val, u8 is_add)
#define ARP_LOOKUP_DEFAULT_HASH_NUM_BUCKETS
#define gid_address_nsh_spi(_a)
Definition: lisp_types.h:265
gid_ip6_table_t * ip6_table
Definition: lisp_types.h:37
static u32 add_del_ip6_key(gid_ip6_table_t *db, u32 vni, ip_prefix_t *pref, u32 val, u8 is_add)
gid_ip4_table_t * ip4_table
#define ARP_LOOKUP_DEFAULT_HASH_MEMORY_SIZE
static u64 arp_lookup(gid_l2_arp_table_t *db, u32 bd, ip4_address_t *key)
ip6_address_t ip6_fib_masks[129]
vhost_vring_addr_t addr
Definition: vhost-user.h:82
#define gid_address_arp_ip4(_a)
Definition: lisp_types.h:279
static u32 ip6_lookup(gid_ip6_table_t *db, u32 vni, ip_prefix_t *key)
Definition: lisp_types.h:38
#define MAC_LOOKUP_DEFAULT_HASH_MEMORY_SIZE
static u32 nsh_lookup(gid_nsh_table_t *db, u32 vni, u32 spi, u8 si)
uword * ip6_non_empty_dst_address_length_bitmap
#define sd_dst_ippref(_a)
Definition: lisp_types.h:147