FD.io VPP  v16.12-rc0-308-g931be3a
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 = clib_host_to_net_u32 (ip_prefix_v4 (&a->src).as_u32);
46  src_ip &= mask->as_u32;
47  if (src_ip == ip)
48  {
49  /* found sub-prefix of src prefix */
50  (a->cb) (kvp->value, a->arg);
51  }
52 }
53 
54 static void
56  ip_prefix_t * src, ip_prefix_t * dst,
57  foreach_subprefix_match_cb_t cb, void *arg)
58 {
59  u32 sfi;
60  gid_ip4_table_t *sfib4;
62 
63  sfi = ip4_lookup (&db->dst_ip4_table, vni, dst);
64  if (GID_LOOKUP_MISS == sfi)
65  return;
66 
67  sfib4 = pool_elt_at_index (db->src_ip4_table_pool, sfi);
68 
69  a.arg = arg;
70  a.cb = cb;
71  a.src = src[0];
72  a.ip4_table = sfib4;
73 
74  BV (clib_bihash_foreach_key_value_pair) (&sfib4->ip4_lookup_table,
76 }
77 
78 static void
79 foreach_sfib6_subprefix (BVT (clib_bihash_kv) * kvp, void *arg)
80 {
81  sfib_entry_arg_t *a = arg;
82  ip6_address_t ip;
83  ip6_address_t *mask;
84  u8 plen = ip_prefix_len (&a->src);
85 
86  mask = &a->ip6_table->ip6_fib_masks[plen];
87  ip.as_u64[0] = kvp->key[0];
88  ip.as_u64[1] = kvp->key[1];
89 
90  if (ip6_address_is_equal_masked (&ip_prefix_v6 (&a->src), &ip, mask))
91  {
92  /* found sub-prefix of src prefix */
93  (a->cb) (kvp->value, a->arg);
94  }
95 }
96 
97 static void
99  ip_prefix_t * src, ip_prefix_t * dst,
100  foreach_subprefix_match_cb_t cb, void *arg)
101 {
102  u32 sfi;
103  gid_ip6_table_t *sfib6;
105 
106  sfi = ip6_lookup (&db->dst_ip6_table, vni, dst);
107  if (GID_LOOKUP_MISS == sfi)
108  return;
109 
110  sfib6 = pool_elt_at_index (db->src_ip6_table_pool, sfi);
111 
112  a.arg = arg;
113  a.cb = cb;
114  a.src = src[0];
115  a.ip6_table = sfib6;
116 
117  BV (clib_bihash_foreach_key_value_pair) (&sfib6->ip6_lookup_table,
119 }
120 
121 void
123  foreach_subprefix_match_cb_t cb, void *arg)
124 {
125  ip_prefix_t *ippref = &gid_address_sd_dst_ippref (eid);
126 
127  if (IP4 == ip_prefix_version (ippref))
130  &gid_address_sd_dst_ippref (eid), cb,
131  arg);
132  else
135  &gid_address_sd_dst_ippref (eid), cb,
136  arg);
137 }
138 
139 static void
140 make_mac_sd_key (BVT (clib_bihash_kv) * kv, u32 vni, u8 src_mac[6],
141  u8 dst_mac[6])
142 {
143  kv->key[0] = (u64) vni;
144  kv->key[1] = mac_to_u64 (dst_mac);
145  kv->key[2] = src_mac ? mac_to_u64 (src_mac) : (u64) 0;
146 }
147 
148 static u32
149 mac_sd_lookup (gid_mac_table_t * db, u32 vni, u8 * dst, u8 * src)
150 {
151  int rv;
152  BVT (clib_bihash_kv) kv, value;
153 
154  make_mac_sd_key (&kv, vni, src, dst);
155  rv = BV (clib_bihash_search_inline_2) (&db->mac_lookup_table, &kv, &value);
156 
157  /* no match, try with src 0, catch all for dst */
158  if (rv != 0)
159  {
160  kv.key[2] = 0;
161  rv = BV (clib_bihash_search_inline_2) (&db->mac_lookup_table, &kv,
162  &value);
163  if (rv == 0)
164  return value.value;
165  }
166  else
167  return value.value;
168 
169  return GID_LOOKUP_MISS;
170 }
171 
172 static u32
173 ip4_lookup_exact_match (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key)
174 {
175  int rv;
176  BVT (clib_bihash_kv) kv, value;
177 
178  ip4_address_t *mask;
179 
180  mask = &db->ip4_fib_masks[ip_prefix_len (key)];
181 
182  kv.key[0] = ((u64) vni << 32) | (ip_prefix_v4 (key).as_u32 & mask->as_u32);
183  kv.key[1] = 0;
184  kv.key[2] = 0;
185 
186  rv = BV (clib_bihash_search_inline_2) (&db->ip4_lookup_table, &kv, &value);
187  if (rv == 0)
188  return value.value;
189 
190  return GID_LOOKUP_MISS;
191 }
192 
193 static u32
194 ip4_lookup (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key)
195 {
196  int i, len;
197  int rv;
198  BVT (clib_bihash_kv) kv, value;
199 
201 
202  for (i = 0; i < len; i++)
203  {
204  int dst_address_length = db->ip4_prefix_lengths_in_search_order[i];
205  ip4_address_t *mask;
206 
207  ASSERT (dst_address_length >= 0 && dst_address_length <= 32);
208 
209  mask = &db->ip4_fib_masks[dst_address_length];
210 
211  kv.key[0] =
212  ((u64) vni << 32) | (ip_prefix_v4 (key).as_u32 & mask->as_u32);
213  kv.key[1] = 0;
214  kv.key[2] = 0;
215 
216  rv =
217  BV (clib_bihash_search_inline_2) (&db->ip4_lookup_table, &kv, &value);
218  if (rv == 0)
219  return value.value;
220  }
221 
222  return GID_LOOKUP_MISS;
223 }
224 
225 static u32
226 ip6_lookup_exact_match (gid_ip6_table_t * db, u32 vni, ip_prefix_t * key)
227 {
228  int rv;
229  BVT (clib_bihash_kv) kv, value;
230 
231  ip6_address_t *mask;
232  mask = &db->ip6_fib_masks[ip_prefix_len (key)];
233 
234  kv.key[0] = ip_prefix_v6 (key).as_u64[0] & mask->as_u64[0];
235  kv.key[1] = ip_prefix_v6 (key).as_u64[1] & mask->as_u64[1];
236  kv.key[2] = (u64) vni;
237 
238  rv = BV (clib_bihash_search_inline_2) (&db->ip6_lookup_table, &kv, &value);
239  if (rv == 0)
240  return value.value;
241 
242  return GID_LOOKUP_MISS;
243 }
244 
245 static u32
246 ip6_lookup (gid_ip6_table_t * db, u32 vni, ip_prefix_t * key)
247 {
248  int i, len;
249  int rv;
250  BVT (clib_bihash_kv) kv, value;
251 
253 
254  for (i = 0; i < len; i++)
255  {
256  int dst_address_length = db->ip6_prefix_lengths_in_search_order[i];
257  ip6_address_t *mask;
258 
259  ASSERT (dst_address_length >= 0 && dst_address_length <= 128);
260 
261  mask = &db->ip6_fib_masks[dst_address_length];
262 
263  kv.key[0] = ip_prefix_v6 (key).as_u64[0] & mask->as_u64[0];
264  kv.key[1] = ip_prefix_v6 (key).as_u64[1] & mask->as_u64[1];
265  kv.key[2] = (u64) vni;
266 
267  rv =
268  BV (clib_bihash_search_inline_2) (&db->ip6_lookup_table, &kv, &value);
269  if (rv == 0)
270  return value.value;
271  }
272 
273  return GID_LOOKUP_MISS;
274 }
275 
276 static u32
277 ip_sd_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst,
278  ip_prefix_t * src)
279 {
280  u32 sfi;
281  gid_ip4_table_t *sfib4;
282  gid_ip6_table_t *sfib6;
283 
284  switch (ip_prefix_version (dst))
285  {
286  case IP4:
287  sfi = ip4_lookup (&db->dst_ip4_table, vni, dst);
288  if (GID_LOOKUP_MISS != sfi)
289  sfib4 = pool_elt_at_index (db->src_ip4_table_pool, sfi);
290  else
291  return GID_LOOKUP_MISS;
292 
293  if (!src)
294  {
295  ip_prefix_t sp;
296  memset (&sp, 0, sizeof (sp));
297  return ip4_lookup_exact_match (sfib4, 0, &sp);
298  }
299  else
300  return ip4_lookup (sfib4, 0, src);
301 
302  break;
303  case IP6:
304  sfi = ip6_lookup (&db->dst_ip6_table, vni, dst);
305  if (GID_LOOKUP_MISS != sfi)
306  sfib6 = pool_elt_at_index (db->src_ip6_table_pool, sfi);
307  else
308  return GID_LOOKUP_MISS;
309 
310  if (!src)
311  {
312  ip_prefix_t sp;
313  memset (&sp, 0, sizeof (sp));
314  ip_prefix_version (&sp) = IP6;
315  return ip6_lookup_exact_match (sfib6, 0, &sp);
316  }
317  else
318  return ip6_lookup (sfib6, 0, src);
319 
320  break;
321  default:
322  clib_warning ("address type %d not supported!",
323  ip_prefix_version (dst));
324  break;
325  }
326  return GID_LOOKUP_MISS;
327 }
328 
329 u32
331 {
332  switch (gid_address_type (key))
333  {
334  case GID_ADDR_IP_PREFIX:
335  return ip_sd_lookup (db, gid_address_vni (key),
336  &gid_address_ippref (key), 0);
337  case GID_ADDR_MAC:
338  return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (key),
339  gid_address_mac (key), 0);
340  case GID_ADDR_SRC_DST:
341  switch (gid_address_sd_dst_type (key))
342  {
343  case FID_ADDR_IP_PREF:
344  return ip_sd_lookup (db, gid_address_vni (key),
347  break;
348  case FID_ADDR_MAC:
349  return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (key),
351  gid_address_sd_src_mac (key));
352  break;
353  default:
354  clib_warning ("Source/Dest address type %d not supported!",
356  break;
357  }
358  break;
359  default:
360  clib_warning ("address type %d not supported!", gid_address_type (key));
361  break;
362  }
363  return GID_LOOKUP_MISS;
364 }
365 
366 u32
368  gid_address_t * src)
369 {
370  switch (gid_address_type (dst))
371  {
372  case GID_ADDR_IP_PREFIX:
373  return ip_sd_lookup (db, gid_address_vni (dst),
374  &gid_address_ippref (dst),
375  &gid_address_ippref (src));
376  case GID_ADDR_MAC:
377  return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (dst),
378  gid_address_mac (dst), gid_address_mac (src));
379  case GID_ADDR_SRC_DST:
380  switch (gid_address_sd_dst_type (dst))
381  {
382  case FID_ADDR_IP_PREF:
383  return ip_sd_lookup (db, gid_address_vni (dst),
386  break;
387  case FID_ADDR_MAC:
388  return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (dst),
390  gid_address_sd_src_mac (dst));
391  break;
392  default:
393  clib_warning ("Source/Dest address type %d not supported!",
395  break;
396  }
397  break;
398  default:
399  clib_warning ("address type %d not supported!", gid_address_type (dst));
400  break;
401  }
402  return GID_LOOKUP_MISS;
403 }
404 
405 static void
407 {
408  int i;
410  /* Note: bitmap reversed so this is in fact a longest prefix match */
411 
412  /* *INDENT-OFF* */
414  ({
415  int dst_address_length = 32 - i;
416  vec_add1 (db->ip4_prefix_lengths_in_search_order, dst_address_length);
417  }));
418  /* *INDENT-ON* */
419 
420 }
421 
422 static u32
423 add_del_ip4_key (gid_ip4_table_t * db, u32 vni, ip_prefix_t * pref, u32 val,
424  u8 is_add)
425 {
426  BVT (clib_bihash_kv) kv, value;
427  u32 old_val = ~0;
428  ip4_address_t key;
429  u8 plen = ip_prefix_len (pref);
430 
431  clib_memcpy (&key, &ip_prefix_v4 (pref), sizeof (key));
432  key.as_u32 &= db->ip4_fib_masks[plen].as_u32;
433  if (is_add)
434  {
437  32 - plen, 1);
439 
440  db->ip4_prefix_len_refcount[plen]++;
441  }
442  else
443  {
444  ASSERT (db->ip4_prefix_len_refcount[plen] != 0);
445 
446  db->ip4_prefix_len_refcount[plen]--;
447 
448  if (db->ip4_prefix_len_refcount[plen] == 0)
449  {
452  32 - plen, 0);
454  }
455  }
456 
457  kv.key[0] = ((u64) vni << 32) | key.as_u32;
458  kv.key[1] = 0;
459  kv.key[2] = 0;
460 
461  if (BV (clib_bihash_search) (&db->ip4_lookup_table, &kv, &value) == 0)
462  old_val = value.value;
463 
464  if (!is_add)
465  BV (clib_bihash_add_del) (&db->ip4_lookup_table, &kv, 0 /* is_add */ );
466  else
467  {
468  kv.value = val;
469  BV (clib_bihash_add_del) (&db->ip4_lookup_table, &kv, 1 /* is_add */ );
470  }
471  return old_val;
472 }
473 
474 static void
476 {
477  uword i;
478 
479  memset (db->ip4_prefix_len_refcount, 0,
480  sizeof (db->ip4_prefix_len_refcount));
481 
482  for (i = 0; i < ARRAY_LEN (db->ip4_fib_masks); i++)
483  {
484  u32 m;
485 
486  if (i < 32)
487  m = pow2_mask (i) << (32 - i);
488  else
489  m = ~0;
490  db->ip4_fib_masks[i].as_u32 = clib_host_to_net_u32 (m);
491  }
492  if (db->ip4_lookup_table_nbuckets == 0)
494 
497 
498  if (db->ip4_lookup_table_size == 0)
500 
501  BV (clib_bihash_init) (&db->ip4_lookup_table, "ip4 lookup table",
504 }
505 
506 static u32
507 add_del_sd_ip4_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref,
508  ip_prefix_t * src_pref, u32 val, u8 is_add)
509 {
510  u32 sfi, old_val = ~0;
511  gid_ip4_table_t *sfib;
512 
513  sfi = ip4_lookup_exact_match (&db->dst_ip4_table, vni, dst_pref);
514 
515  if (is_add)
516  {
517  if (GID_LOOKUP_MISS == sfi)
518  {
519  pool_get (db->src_ip4_table_pool, sfib);
520  ip4_lookup_init (sfib);
521  add_del_ip4_key (&db->dst_ip4_table, vni, dst_pref,
522  sfib - db->src_ip4_table_pool, is_add);
523  if (src_pref)
524  add_del_ip4_key (sfib, 0 /* vni */ , src_pref, val, is_add);
525  else
526  {
527  ip_prefix_t sp;
528  memset (&sp, 0, sizeof (sp));
529  add_del_ip4_key (sfib, 0 /* vni */ , &sp, val, is_add);
530  }
531  }
532  else
533  {
535  sfib = pool_elt_at_index (db->src_ip4_table_pool, sfi);
536  if (src_pref)
537  {
538  old_val = ip4_lookup_exact_match (sfib, 0, src_pref);
539  add_del_ip4_key (sfib, 0 /* vni */ , src_pref, val, is_add);
540  }
541  else
542  {
543  ip_prefix_t sp;
544  memset (&sp, 0, sizeof (sp));
545  old_val =
546  add_del_ip4_key (sfib, 0 /* vni */ , &sp, val, is_add);
547  }
548  }
549  }
550  else
551  {
552  if (GID_LOOKUP_MISS != sfi)
553  {
554  add_del_ip4_key (&db->dst_ip4_table, vni, dst_pref, 0, is_add);
555  sfib = pool_elt_at_index (db->src_ip4_table_pool, sfi);
556  if (src_pref)
557  old_val = add_del_ip4_key (sfib, 0, src_pref, 0, is_add);
558  else
559  {
560  ip_prefix_t sp;
561  memset (&sp, 0, sizeof (sp));
562  old_val = add_del_ip4_key (sfib, 0, &sp, 0, is_add);
563  }
564  }
565  else
566  clib_warning ("cannot delete dst mapping %U!", format_ip_prefix,
567  dst_pref);
568  }
569  return old_val;
570 }
571 
572 static void
574 {
575  int i;
577  /* Note: bitmap reversed so this is in fact a longest prefix match */
578 
579  /* *INDENT-OFF* */
581  ({
582  int dst_address_length = 128 - i;
583  vec_add1 (db->ip6_prefix_lengths_in_search_order, dst_address_length);
584  }));
585  /* *INDENT-ON* */
586 }
587 
588 static u32
589 add_del_ip6_key (gid_ip6_table_t * db, u32 vni, ip_prefix_t * pref, u32 val,
590  u8 is_add)
591 {
592  BVT (clib_bihash_kv) kv, value;
593  u32 old_val = ~0;
594  ip6_address_t key;
595  u8 plen = ip_prefix_len (pref);
596 
597  clib_memcpy (&key, &ip_prefix_v6 (pref), sizeof (key));
598  ip6_address_mask (&key, &db->ip6_fib_masks[plen]);
599  if (is_add)
600  {
603  128 - plen, 1);
605  db->ip6_prefix_len_refcount[plen]++;
606  }
607  else
608  {
609  ASSERT (db->ip6_prefix_len_refcount[plen] != 0);
610 
611  db->ip6_prefix_len_refcount[plen]--;
612 
613  if (db->ip6_prefix_len_refcount[plen] == 0)
614  {
617  128 - plen, 0);
619  }
620  }
621 
622  kv.key[0] = key.as_u64[0];
623  kv.key[1] = key.as_u64[1];
624  kv.key[2] = (u64) vni;
625 // kv.key[2] = ((u64)((fib - im->fibs))<<32) | ip_prefix_len(key);
626 
627  if (BV (clib_bihash_search) (&db->ip6_lookup_table, &kv, &value) == 0)
628  old_val = value.value;
629 
630  if (!is_add)
631  BV (clib_bihash_add_del) (&db->ip6_lookup_table, &kv, 0 /* is_add */ );
632  else
633  {
634  kv.value = val;
635  BV (clib_bihash_add_del) (&db->ip6_lookup_table, &kv, 1 /* is_add */ );
636  }
637  return old_val;
638 }
639 
640 static u32
641 add_del_mac (gid_mac_table_t * db, u32 vni, u8 * dst_mac, u8 * src_mac,
642  u32 val, u8 is_add)
643 {
644  BVT (clib_bihash_kv) kv, value;
645  u32 old_val = ~0;
646 
647  make_mac_sd_key (&kv, vni, src_mac, dst_mac);
648 
649  if (BV (clib_bihash_search) (&db->mac_lookup_table, &kv, &value) == 0)
650  old_val = value.value;
651 
652  if (!is_add)
653  BV (clib_bihash_add_del) (&db->mac_lookup_table, &kv, 0 /* is_add */ );
654  else
655  {
656  kv.value = val;
657  BV (clib_bihash_add_del) (&db->mac_lookup_table, &kv, 1 /* is_add */ );
658  }
659  return old_val;
660 }
661 
662 static void
664 {
665  uword i;
666 
667  memset (db->ip6_prefix_len_refcount, 0,
668  sizeof (db->ip6_prefix_len_refcount));
669 
670  for (i = 0; i < ARRAY_LEN (db->ip6_fib_masks); i++)
671  {
672  u32 j, i0, i1;
673 
674  i0 = i / 32;
675  i1 = i % 32;
676 
677  for (j = 0; j < i0; j++)
678  db->ip6_fib_masks[i].as_u32[j] = ~0;
679 
680  if (i1)
681  db->ip6_fib_masks[i].as_u32[i0] =
682  clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
683  }
684 
685  if (db->ip6_lookup_table_nbuckets == 0)
687 
690 
691  if (db->ip6_lookup_table_size == 0)
693 
694  BV (clib_bihash_init) (&db->ip6_lookup_table, "ip6 lookup table",
697 }
698 
699 static u32
700 add_del_sd_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref,
701  ip_prefix_t * src_pref, u32 val, u8 is_add)
702 {
703  u32 sfi, old_val = ~0;
704  gid_ip6_table_t *sfib;
705 
706  sfi = ip6_lookup_exact_match (&db->dst_ip6_table, vni, dst_pref);
707 
708  if (is_add)
709  {
710  if (GID_LOOKUP_MISS == sfi)
711  {
712  pool_get (db->src_ip6_table_pool, sfib);
713  ip6_lookup_init (sfib);
714  add_del_ip6_key (&db->dst_ip6_table, vni, dst_pref,
715  sfib - db->src_ip6_table_pool, is_add);
716  if (src_pref)
717  add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add);
718  else
719  {
720  ip_prefix_t sp;
721  memset (&sp, 0, sizeof (sp));
722  ip_prefix_version (&sp) = IP6;
723  add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add);
724  }
725  }
726  else
727  {
729  sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi);
730  if (src_pref)
731  {
732  old_val = ip6_lookup_exact_match (sfib, 0, src_pref);
733  add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add);
734  }
735  else
736  {
737  ip_prefix_t sp;
738  memset (&sp, 0, sizeof (sp));
739  ip_prefix_version (&sp) = IP6;
740  old_val =
741  add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add);
742  }
743  }
744  }
745  else
746  {
747  if (GID_LOOKUP_MISS != sfi)
748  {
749  add_del_ip6_key (&db->dst_ip6_table, vni, dst_pref, 0, is_add);
750  sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi);
751  if (src_pref)
752  old_val = add_del_ip6_key (sfib, 0, src_pref, 0, is_add);
753  else
754  {
755  ip_prefix_t sp;
756  memset (&sp, 0, sizeof (sp));
757  ip_prefix_version (&sp) = IP6;
758  old_val = add_del_ip6_key (sfib, 0, &sp, 0, is_add);
759  }
760  }
761  else
762  clib_warning ("cannot delete dst mapping %U!", format_ip_prefix,
763  dst_pref);
764  }
765  return old_val;
766 }
767 
768 static u32
769 add_del_ip (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_key,
770  ip_prefix_t * src_key, u32 value, u8 is_add)
771 {
772  switch (ip_prefix_version (dst_key))
773  {
774  case IP4:
775  return add_del_sd_ip4_key (db, vni, dst_key, src_key, value, is_add);
776  break;
777  case IP6:
778  return add_del_sd_ip6_key (db, vni, dst_key, src_key, value, is_add);
779  break;
780  default:
781  clib_warning ("address type %d not supported!",
782  ip_prefix_version (dst_key));
783  break;
784  }
785  return ~0;
786 }
787 
788 static u32
790  u8 is_add)
791 {
792  switch (sd_dst_type (key))
793  {
794  case FID_ADDR_IP_PREF:
795  add_del_ip (db, vni, &sd_dst_ippref (key), &sd_src_ippref (key),
796  value, is_add);
797 
798  case FID_ADDR_MAC:
799  return add_del_mac (&db->sd_mac_table, vni, sd_dst_mac (key),
800  sd_src_mac (key), value, is_add);
801 
802  default:
803  clib_warning ("SD address type %d not supprted!", sd_dst_type (key));
804  break;
805  }
806 
807  return ~0;
808 }
809 
810 u32
812  u8 is_add)
813 {
814  switch (gid_address_type (key))
815  {
816  case GID_ADDR_IP_PREFIX:
817  return add_del_ip (db, gid_address_vni (key), &gid_address_ippref (key),
818  0, value, is_add);
819  case GID_ADDR_MAC:
820  return add_del_mac (&db->sd_mac_table, gid_address_vni (key),
821  gid_address_mac (key), 0, value, is_add);
822  case GID_ADDR_SRC_DST:
823  return add_del_sd (db, gid_address_vni (key), &gid_address_sd (key),
824  value, is_add);
825  default:
826  clib_warning ("address type %d not supported!", gid_address_type (key));
827  break;
828  }
829  return ~0;
830 }
831 
832 static void
834 {
835  if (db->mac_lookup_table_nbuckets == 0)
837 
840 
841  if (db->mac_lookup_table_size == 0)
843 
844  BV (clib_bihash_init) (&db->mac_lookup_table, "mac lookup table",
847 }
848 
849 void
851 {
855 }
856 
857 /*
858  * fd.io coding-style-patch-verification: ON
859  *
860  * Local Variables:
861  * eval: (c-set-style "gnu")
862  * End:
863  */
#define ip_prefix_v4(_a)
Definition: lisp_types.h:61
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:203
#define IP6_LOOKUP_DEFAULT_HASH_NUM_BUCKETS
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
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:215
#define sd_dst_mac(_a)
Definition: lisp_types.h:128
a
Definition: bitmap.h:516
ip4_address_t ip4_fib_masks[33]
static u32 mac_sd_lookup(gid_mac_table_t *db, u32 vni, u8 *dst, u8 *src)
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:50
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 void ip6_compute_prefix_lengths_in_search_order(gid_ip6_table_t *db)
#define gid_address_sd_src_mac(_a)
Definition: lisp_types.h:227
#define ip_prefix_len(_a)
Definition: lisp_types.h:60
#define gid_address_sd(_a)
Definition: lisp_types.h:228
u32 ip4_prefix_len_refcount[33]
#define IP4_LOOKUP_DEFAULT_HASH_NUM_BUCKETS
#define gid_address_sd_src_ippref(_a)
Definition: lisp_types.h:225
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
static uword ip6_address_is_equal_masked(ip6_address_t *a, ip6_address_t *b, ip6_address_t *mask)
Definition: ip6_packet.h:186
#define gid_address_sd_dst_mac(_a)
Definition: lisp_types.h:226
#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:59
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)
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 uword pow2_mask(uword x)
Definition: clib.h:251
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)
#define clib_warning(format, args...)
Definition: error.h:59
unsigned long u64
Definition: types.h:89
ip_prefix_t src
u32 gid_dictionary_lookup(gid_dictionary_t *db, gid_address_t *key)
#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:369
void gid_dict_foreach_subprefix(gid_dictionary_t *db, gid_address_t *eid, foreach_subprefix_match_cb_t cb, void *arg)
u32 gid_dictionary_add_del(gid_dictionary_t *db, gid_address_t *key, u32 value, u8 is_add)
#define gid_address_mac(_a)
Definition: lisp_types.h:221
#define ip_prefix_v6(_a)
Definition: lisp_types.h:62
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:232
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 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:216
u32 as_u32[4]
Definition: ip6_packet.h:49
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:125
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 ip6_lookup_table_size
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:64
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:211
#define ARRAY_LEN(x)
Definition: clib.h:59
void(* foreach_subprefix_match_cb_t)(u32, void *)
#define sd_src_mac(_a)
Definition: lisp_types.h:127
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:130
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:826
#define gid_address_sd_dst_ippref(_a)
Definition: lisp_types.h:224
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:162
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:222
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)
static uword max_log2(uword x)
Definition: clib.h:222
static u32 add_del_mac(gid_mac_table_t *db, u32 vni, u8 *dst_mac, u8 *src_mac, u32 val, u8 is_add)
gid_ip6_table_t * ip6_table
Definition: lisp_types.h:24
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
ip6_address_t ip6_fib_masks[129]
static u32 ip6_lookup(gid_ip6_table_t *db, u32 vni, ip_prefix_t *key)
Definition: lisp_types.h:25
#define MAC_LOOKUP_DEFAULT_HASH_MEMORY_SIZE
uword * ip6_non_empty_dst_address_length_bitmap
#define sd_dst_ippref(_a)
Definition: lisp_types.h:126