dpdk: Add support for Mellanox ConnectX-4 devices
[vpp.git] / src / vnet / lisp-cp / lisp_types.c
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
16 #include <vnet/lisp-cp/lisp_types.h>
17
18 static u16 gid_address_put_no_vni (u8 * b, gid_address_t * gid);
19 static u16 gid_address_size_to_put_no_vni (gid_address_t * gid);
20 static u16 fid_addr_size_to_write (fid_address_t * a);
21
22 u32 mac_parse (u8 * offset, u8 * a);
23
24 typedef u16 (*size_to_write_fct) (void *);
25 typedef void *(*cast_fct) (gid_address_t *);
26 typedef u16 (*serdes_fct) (u8 *, void *);
27 typedef u8 (*addr_len_fct) (void *);
28 typedef void (*copy_fct) (void *, void *);
29 typedef void (*free_fct) (void *);
30 typedef int (*cmp_fct) (void *, void *);
31
32 size_to_write_fct size_to_write_fcts[GID_ADDR_TYPES] =
33   { ip_prefix_size_to_write, lcaf_size_to_write, mac_size_to_write,
34   sd_size_to_write
35 };
36 serdes_fct write_fcts[GID_ADDR_TYPES] =
37   { ip_prefix_write, lcaf_write, mac_write, sd_write };
38 cast_fct cast_fcts[GID_ADDR_TYPES] =
39   { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast };
40 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
41   { ip_prefix_length, lcaf_length, mac_length, sd_length };
42 copy_fct copy_fcts[GID_ADDR_TYPES] =
43   { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy };
44
45 #define foreach_lcaf_type \
46   _(1, no_addr)      \
47   _(0, NULL)         \
48   _(1, vni)          \
49   _(0, NULL)         \
50   _(0, NULL)         \
51   _(0, NULL)         \
52   _(0, NULL)         \
53   _(0, NULL)         \
54   _(0, NULL)         \
55   _(0, NULL)         \
56   _(0, NULL)         \
57   _(0, NULL)         \
58   _(1, sd)
59
60 #define _(cond, name)                             \
61   u16 name ## _write (u8 * p, void * a);          \
62   u16 name ## _parse (u8 * p, void * a);          \
63   u16 name ## _size_to_write (void * a);          \
64   void name ## _free (void * a);                  \
65   void name ## _copy (void * dst, void * src);    \
66   u8 name ## _length (void * a);                  \
67   int name ## _cmp (void *, void *);
68 foreach_lcaf_type
69 #undef _
70 #define CONCAT(a,b) a##_##b
71 #define IF(c, t, e) CONCAT(IF, c)(t, e)
72 #define IF_0(t, e) e
73 #define IF_1(t, e) t
74 #define EXPAND_FCN(cond, fcn)                           \
75   IF(cond, fcn, NULL)
76   cmp_fct lcaf_cmp_fcts[LCAF_TYPES] =
77 {
78 #define _(cond, name)                                   \
79     EXPAND_FCN(cond, name##_cmp),
80   foreach_lcaf_type
81 #undef _
82 };
83
84 addr_len_fct lcaf_body_length_fcts[LCAF_TYPES] = {
85 #define _(cond, name)                                   \
86     EXPAND_FCN(cond, name##_length),
87   foreach_lcaf_type
88 #undef _
89 };
90
91 copy_fct lcaf_copy_fcts[LCAF_TYPES] = {
92 #define _(cond, name)                                   \
93     EXPAND_FCN(cond, name##_copy),
94   foreach_lcaf_type
95 #undef _
96 };
97
98 free_fct lcaf_free_fcts[LCAF_TYPES] = {
99 #define _(cond, name)                                   \
100     EXPAND_FCN(cond, name##_free),
101   foreach_lcaf_type
102 #undef _
103 };
104
105 size_to_write_fct lcaf_size_to_write_fcts[LCAF_TYPES] = {
106 #define _(cond, name)                                   \
107     EXPAND_FCN(cond, name##_size_to_write),
108   foreach_lcaf_type
109 #undef _
110 };
111
112 serdes_fct lcaf_write_fcts[LCAF_TYPES] = {
113 #define _(cond, name)                                   \
114     EXPAND_FCN(cond, name##_write),
115   foreach_lcaf_type
116 #undef _
117 };
118
119 serdes_fct lcaf_parse_fcts[LCAF_TYPES] = {
120 #define _(cond, name)                                   \
121     EXPAND_FCN(cond, name##_parse),
122   foreach_lcaf_type
123 #undef _
124 };
125
126 u8 *
127 format_ip_address (u8 * s, va_list * args)
128 {
129   ip_address_t *a = va_arg (*args, ip_address_t *);
130   u8 ver = ip_addr_version (a);
131   if (ver == IP4)
132     {
133       return format (s, "%U", format_ip4_address, &ip_addr_v4 (a));
134     }
135   else if (ver == IP6)
136     {
137       return format (s, "%U", format_ip6_address, &ip_addr_v6 (a));
138     }
139   else
140     {
141       clib_warning ("Can't format IP version %d!", ver);
142       return 0;
143     }
144 }
145
146 uword
147 unformat_ip_address (unformat_input_t * input, va_list * args)
148 {
149   ip_address_t *a = va_arg (*args, ip_address_t *);
150
151   memset (a, 0, sizeof (*a));
152   if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (a)))
153     ip_addr_version (a) = IP4;
154   else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6 (a)))
155     ip_addr_version (a) = IP6;
156   else
157     return 0;
158   return 1;
159 }
160
161 u8 *
162 format_ip_prefix (u8 * s, va_list * args)
163 {
164   ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
165   return format (s, "%U/%d", format_ip_address, &ip_prefix_addr (a),
166                  ip_prefix_len (a));
167 }
168
169 uword
170 unformat_ip_prefix (unformat_input_t * input, va_list * args)
171 {
172   ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
173   if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr (a),
174                 &ip_prefix_len (a)))
175     {
176       if ((ip_prefix_version (a) == IP4 && 32 < ip_prefix_len (a)) ||
177           (ip_prefix_version (a) == IP6 && 128 < ip_prefix_length (a)))
178         {
179           clib_warning ("Prefix length to big: %d!", ip_prefix_len (a));
180           return 0;
181         }
182       ip_prefix_normalize (a);
183     }
184   else
185     return 0;
186   return 1;
187 }
188
189 uword
190 unformat_mac_address (unformat_input_t * input, va_list * args)
191 {
192   u8 *a = va_arg (*args, u8 *);
193   return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
194                    &a[4], &a[5]);
195 }
196
197 u8 *
198 format_mac_address (u8 * s, va_list * args)
199 {
200   u8 *a = va_arg (*args, u8 *);
201   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
202                  a[0], a[1], a[2], a[3], a[4], a[5]);
203 }
204
205 u8 *
206 format_fid_address (u8 * s, va_list * args)
207 {
208   fid_address_t *a = va_arg (*args, fid_address_t *);
209
210   switch (fid_addr_type (a))
211     {
212     case FID_ADDR_IP_PREF:
213       return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
214
215     case FID_ADDR_MAC:
216       return format (s, "%U", format_mac_address, &fid_addr_mac (a));
217
218     default:
219       clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
220       return 0;
221     }
222   return 0;
223 }
224
225 u8 *
226 format_gid_address (u8 * s, va_list * args)
227 {
228   gid_address_t *a = va_arg (*args, gid_address_t *);
229   u8 type = gid_address_type (a);
230   switch (type)
231     {
232     case GID_ADDR_IP_PREFIX:
233       return format (s, "[%d] %U", gid_address_vni (a), format_ip_prefix,
234                      &gid_address_ippref (a));
235     case GID_ADDR_SRC_DST:
236       return format (s, "[%d] %U|%U", gid_address_vni (a),
237                      format_fid_address, &gid_address_sd_src (a),
238                      format_fid_address, &gid_address_sd_dst (a));
239     case GID_ADDR_MAC:
240       return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
241                      &gid_address_mac (a));
242     default:
243       clib_warning ("Can't format gid type %d", type);
244       return 0;
245     }
246   return 0;
247 }
248
249 uword
250 unformat_fid_address (unformat_input_t * i, va_list * args)
251 {
252   fid_address_t *a = va_arg (*args, fid_address_t *);
253   ip_prefix_t ippref;
254   u8 mac[6] = { 0 };
255
256   if (unformat (i, "%U", unformat_ip_prefix, &ippref))
257     {
258       fid_addr_type (a) = FID_ADDR_IP_PREF;
259       ip_prefix_copy (&fid_addr_ippref (a), &ippref);
260     }
261   else if (unformat (i, "%U", unformat_mac_address, mac))
262     {
263       fid_addr_type (a) = FID_ADDR_MAC;
264       mac_copy (fid_addr_mac (a), mac);
265     }
266   else
267     return 0;
268
269   return 1;
270 }
271
272 uword
273 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
274 {
275   u32 *key_id = va_arg (*args, u32 *);
276   u8 *s = 0;
277
278   if (unformat (input, "%s", &s))
279     {
280       if (!strcmp ((char *) s, "sha1"))
281         key_id[0] = HMAC_SHA_1_96;
282       else if (!strcmp ((char *) s, "sha256"))
283         key_id[0] = HMAC_SHA_256_128;
284       else
285         {
286           clib_warning ("invalid key_id: '%s'", s);
287           key_id[0] = HMAC_NO_KEY;
288         }
289     }
290   else
291     return 0;
292
293   vec_free (s);
294   return 1;
295 }
296
297 uword
298 unformat_gid_address (unformat_input_t * input, va_list * args)
299 {
300   gid_address_t *a = va_arg (*args, gid_address_t *);
301   u8 mac[6] = { 0 };
302   ip_prefix_t ippref;
303   fid_address_t sim1, sim2;
304
305   memset (&ippref, 0, sizeof (ippref));
306   memset (&sim1, 0, sizeof (sim1));
307   memset (&sim2, 0, sizeof (sim2));
308
309   if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
310                 unformat_fid_address, &sim2))
311     {
312       gid_address_sd_src (a) = sim1;
313       gid_address_sd_dst (a) = sim2;
314       gid_address_type (a) = GID_ADDR_SRC_DST;
315     }
316   else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
317     {
318       ip_prefix_copy (&gid_address_ippref (a), &ippref);
319       gid_address_type (a) = GID_ADDR_IP_PREFIX;
320     }
321   else if (unformat (input, "%U", unformat_mac_address, mac))
322     {
323       mac_copy (gid_address_mac (a), mac);
324       gid_address_type (a) = GID_ADDR_MAC;
325     }
326   else
327     return 0;
328
329   return 1;
330 }
331
332 uword
333 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
334 {
335   u32 *action = va_arg (*args, u32 *);
336   u8 *s = 0;
337
338   if (unformat (input, "%s", &s))
339     {
340       if (!strcmp ((char *) s, "no-action"))
341         action[0] = LISP_NO_ACTION;
342       else if (!strcmp ((char *) s, "natively-forward"))
343         action[0] = LISP_FORWARD_NATIVE;
344       else if (!strcmp ((char *) s, "send-map-request"))
345         action[0] = LISP_SEND_MAP_REQUEST;
346       else if (!strcmp ((char *) s, "drop"))
347         action[0] = LISP_DROP;
348       else
349         {
350           clib_warning ("invalid action: '%s'", s);
351           action[0] = LISP_DROP;
352         }
353     }
354   else
355     return 0;
356
357   vec_free (s);
358   return 1;
359 }
360
361 u8 *
362 format_hmac_key_id (u8 * s, va_list * args)
363 {
364   lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
365
366   switch (key_id)
367     {
368     case HMAC_SHA_1_96:
369       return format (0, "sha1");
370     case HMAC_SHA_256_128:
371       return format (0, "sha256");
372     default:
373       return 0;
374     }
375
376   return 0;
377 }
378
379 u8 *
380 format_negative_mapping_action (u8 * s, va_list * args)
381 {
382   lisp_action_e action = va_arg (*args, lisp_action_e);
383
384   switch (action)
385     {
386     case LISP_NO_ACTION:
387       s = format (s, "no-action");
388       break;
389     case LISP_FORWARD_NATIVE:
390       s = format (s, "natively-forward");
391       break;
392     case LISP_SEND_MAP_REQUEST:
393       s = format (s, "send-map-request");
394       break;
395     case LISP_DROP:
396     default:
397       s = format (s, "drop");
398       break;
399     }
400   return (s);
401 }
402
403 u16
404 ip_address_size (const ip_address_t * a)
405 {
406   switch (ip_addr_version (a))
407     {
408     case IP4:
409       return sizeof (ip4_address_t);
410       break;
411     case IP6:
412       return sizeof (ip6_address_t);
413       break;
414     }
415   return 0;
416 }
417
418 u16
419 ip_version_to_size (u8 ver)
420 {
421   switch (ver)
422     {
423     case IP4:
424       return sizeof (ip4_address_t);
425       break;
426     case IP6:
427       return sizeof (ip6_address_t);
428       break;
429     }
430   return 0;
431 }
432
433 u8
434 ip_version_to_max_plen (u8 ver)
435 {
436   switch (ver)
437     {
438     case IP4:
439       return 32;
440       break;
441     case IP6:
442       return 128;
443       break;
444     }
445   return 0;
446 }
447
448 always_inline lisp_afi_e
449 ip_version_to_iana_afi (u16 version)
450 {
451   switch (version)
452     {
453     case IP4:
454       return LISP_AFI_IP;
455     case IP6:
456       return LISP_AFI_IP6;
457     default:
458       return 0;
459     }
460   return 0;
461 }
462
463 always_inline u8
464 ip_iana_afi_to_version (lisp_afi_e afi)
465 {
466   switch (afi)
467     {
468     case LISP_AFI_IP:
469       return IP4;
470     case LISP_AFI_IP6:
471       return IP6;
472     default:
473       return 0;
474     }
475   return 0;
476 }
477
478 u16
479 ip_address_size_to_write (ip_address_t * a)
480 {
481   return ip_address_size (a) + sizeof (u16);
482 }
483
484 u16
485 ip_address_iana_afi (ip_address_t * a)
486 {
487   return ip_version_to_iana_afi (ip_addr_version (a));
488 }
489
490 u8
491 ip_address_max_len (u8 version)
492 {
493   return version == IP4 ? 32 : 128;
494 }
495
496 u16
497 ip4_address_size_to_put ()
498 {
499   // return sizeof(u16) + sizeof (ip4_address_t);
500   return 6;
501 }
502
503 u16
504 ip6_address_size_to_put ()
505 {
506   //return sizeof(u16) + sizeof (ip6_address_t);
507   return 18;
508 }
509
510 u32
511 ip4_address_put (u8 * b, ip4_address_t * a)
512 {
513   *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
514   u8 *p = b + sizeof (u16);
515   clib_memcpy (p, a, sizeof (*a));
516   return ip4_address_size_to_put ();
517 }
518
519 u32
520 ip6_address_put (u8 * b, ip6_address_t * a)
521 {
522   *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
523   u8 *p = b + sizeof (u16);
524   clib_memcpy (p, a, sizeof (*a));
525   return ip6_address_size_to_put ();
526 }
527
528 u32
529 ip_address_put (u8 * b, ip_address_t * a)
530 {
531   u32 len = ip_address_size (a);
532   *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
533   u8 *p = b + sizeof (u16);
534   clib_memcpy (p, &ip_addr_addr (a), len);
535   return (len + sizeof (u16));
536 }
537
538 u32
539 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
540 {
541   ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
542   u8 size = ip_version_to_size (ip_addr_version (dst));
543   clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
544   return (sizeof (u16) + size);
545 }
546
547 u32
548 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
549 {
550   lcaf_hdr_t *lh = offset;
551   lcaf->type = lh->type;
552
553   /* this is a bit of hack: since the LCAF Instance ID is the
554      only message that uses reserved2 field, we can set it here.
555      If any LCAF format starts using reserved2 field as well this needs
556      to be moved elsewhere */
557   lcaf_vni_len (lcaf) = lh->reserved2;
558
559   return sizeof (lh[0]);
560 }
561
562 static u8
563 iana_afi_to_fid_addr_type (u16 type)
564 {
565   switch (type)
566     {
567     case LISP_AFI_IP:
568     case LISP_AFI_IP6:
569       return FID_ADDR_IP_PREF;
570
571     case LISP_AFI_MAC:
572       return FID_ADDR_MAC;
573     }
574   return ~0;
575 }
576
577 static u16
578 fid_addr_parse (u8 * p, fid_address_t * a)
579 {
580   u16 afi = clib_net_to_host_u16 (*(u16 *) p);
581   fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
582   ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
583
584   switch (fid_addr_type (a))
585     {
586     case FID_ADDR_MAC:
587       return mac_parse (p, fid_addr_mac (a));
588
589     case FID_ADDR_IP_PREF:
590       return ip_address_parse (p, afi, ip_addr);
591     }
592   return ~0;
593 }
594
595 u16
596 sd_parse (u8 * p, void *a)
597 {
598   lcaf_src_dst_hdr_t *sd_hdr;
599   gid_address_t *g = a;
600   u16 size = 0;
601   fid_address_t *src = &gid_address_sd_src (g);
602   fid_address_t *dst = &gid_address_sd_dst (g);
603
604   gid_address_type (g) = GID_ADDR_SRC_DST;
605
606   sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
607   size += sizeof (sd_hdr[0]);
608
609   size += fid_addr_parse (p + size, src);
610   size += fid_addr_parse (p + size, dst);
611
612   if (fid_addr_type (src) == FID_ADDR_IP_PREF)
613     {
614       ip_prefix_t *ippref = &fid_addr_ippref (src);
615       ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
616     }
617   if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
618     {
619       ip_prefix_t *ippref = &fid_addr_ippref (dst);
620       ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
621     }
622   return size;
623 }
624
625 u16
626 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
627 {
628   lcaf_t lcaf;
629   u16 size = sizeof (u16);      /* skip AFI */
630
631   size += lcaf_hdr_parse (p + size, &lcaf);
632
633   if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
634     return ~0;
635
636   size += sd_parse (p + size, a);
637   return size;
638 }
639
640 u16
641 vni_parse (u8 * p, void *a)
642 {
643   lcaf_t *lcaf = a;
644   gid_address_t *g = a;
645   u16 size = 0;
646
647   gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
648   size += sizeof (u32);
649   gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
650
651   /* nested LCAFs are not supported except of src/dst with vni - to handle
652    * such case look at the next AFI and process src/dest LCAF separately */
653   u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
654   if (LISP_AFI_LCAF == afi)
655     {
656       u16 len = try_parse_src_dst_lcaf (p + size, g);
657       if ((u16) ~ 0 == len)
658         return ~0;
659       size += len;
660     }
661   else
662     size += gid_address_parse (p + size, g);
663
664   return size;
665 }
666
667 u16
668 no_addr_parse (u8 * p, void *a)
669 {
670   /* do nothing */
671   return 0;
672 }
673
674 u32
675 lcaf_parse (void *offset, gid_address_t * addr)
676 {
677   /* skip AFI type */
678   offset += sizeof (u16);
679   lcaf_t *lcaf = &gid_address_lcaf (addr);
680
681   u32 size = lcaf_hdr_parse (offset, lcaf);
682   u8 type = lcaf_type (lcaf);
683
684   if (!lcaf_parse_fcts[type])
685     {
686       clib_warning ("Unsupported LCAF type: %u", type);
687       return ~0;
688     }
689   size += (*lcaf_parse_fcts[type]) (offset + size, lcaf);
690   return sizeof (u16) + size;
691 }
692
693 void
694 vni_free (void *a)
695 {
696   vni_t *v = a;
697   gid_address_free (vni_gid (v));
698   clib_mem_free (vni_gid (v));
699 }
700
701 void
702 no_addr_free (void *a)
703 {
704   /* nothing to do */
705 }
706
707 void
708 sd_free (void *a)
709 {
710   /* nothing */
711 }
712
713 void
714 gid_address_free (gid_address_t * a)
715 {
716   if (gid_address_type (a) != GID_ADDR_LCAF)
717     return;
718
719   lcaf_t *lcaf = &gid_address_lcaf (a);
720   u8 lcaf_type = lcaf_type (lcaf);
721   (*lcaf_free_fcts[lcaf_type]) (lcaf);
722 }
723
724 void
725 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
726 {
727   memset (g, 0, sizeof (g[0]));
728   ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
729   gid_address_ippref_len (g) = 32;
730 }
731
732 int
733 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
734 {
735   int res = 0;
736   if (ip_addr_version (ip1) != ip_addr_version (ip2))
737     return -1;
738   res =
739     memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
740
741   if (res < 0)
742     res = 2;
743   else if (res > 0)
744     res = 1;
745
746   return res;
747 }
748
749 void
750 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
751 {
752   if (IP4 == ip_addr_version (src))
753     {
754       /* don't copy any garbe from the union */
755       memset (dst, 0, sizeof (*dst));
756       dst->ip.v4 = src->ip.v4;
757       dst->version = IP4;
758     }
759   else
760     {
761       clib_memcpy (dst, src, sizeof (ip_address_t));
762     }
763 }
764
765 void
766 ip_address_copy_addr (void *dst, const ip_address_t * src)
767 {
768   clib_memcpy (dst, src, ip_address_size (src));
769 }
770
771 void
772 ip_address_set (ip_address_t * dst, const void *src, u8 version)
773 {
774   clib_memcpy (dst, src, ip_version_to_size (version));
775   ip_addr_version (dst) = version;
776 }
777
778 void
779 ip_address_to_46 (const ip_address_t * addr,
780                   ip46_address_t * a, fib_protocol_t * proto)
781 {
782   *proto = (IP4 == ip_addr_version (addr) ?
783             FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
784   switch (*proto)
785     {
786     case FIB_PROTOCOL_IP4:
787       ip46_address_set_ip4 (a, &addr->ip.v4);
788       break;
789     case FIB_PROTOCOL_IP6:
790       a->ip6 = addr->ip.v6;
791       break;
792     default:
793       ASSERT (0);
794       break;
795     }
796 }
797
798 static void
799 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
800 {
801   u32 mask = ~0;
802
803   ASSERT (ip4);
804
805   if (32 <= preflen)
806     {
807       return;
808     }
809
810   mask = pow2_mask (preflen) << (32 - preflen);
811   mask = clib_host_to_net_u32 (mask);
812   ip4->data_u32 &= mask;
813 }
814
815 static void
816 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
817 {
818   u8 mask_6[16];
819   u32 *m;
820   u8 j, i0, i1;
821
822   ASSERT (ip6);
823
824   memset (mask_6, 0, sizeof (mask_6));
825
826   if (128 <= preflen)
827     {
828       return;
829     }
830
831   i1 = preflen % 32;
832   i0 = preflen / 32;
833   m = (u32 *) & mask_6[0];
834
835   for (j = 0; j < i0; j++)
836     {
837       m[j] = ~0;
838     }
839
840   if (i1)
841     {
842       m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
843     }
844
845   for (j = 0; j < sizeof (mask_6); j++)
846     {
847       ip6->as_u8[j] &= mask_6[j];
848     }
849 }
850
851 void
852 ip_prefix_normalize (ip_prefix_t * a)
853 {
854   u8 preflen = ip_prefix_len (a);
855
856   switch (ip_prefix_version (a))
857     {
858     case IP4:
859       ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
860       break;
861
862     case IP6:
863       ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
864       break;
865
866     default:
867       ASSERT (0);
868     }
869 }
870
871 void *
872 ip_prefix_cast (gid_address_t * a)
873 {
874   return &gid_address_ippref (a);
875 }
876
877 u16
878 ip_prefix_size_to_write (void *pref)
879 {
880   ip_prefix_t *a = (ip_prefix_t *) pref;
881   return ip_address_size_to_write (&ip_prefix_addr (a));
882 }
883
884 u16
885 ip_prefix_write (u8 * p, void *gid)
886 {
887   gid_address_t *g = gid;
888   ip_prefix_t *a = &gid_address_ippref (g);
889
890   switch (ip_prefix_version (a))
891     {
892     case IP4:
893       return ip4_address_put (p, &ip_prefix_v4 (a));
894       break;
895     case IP6:
896       return ip6_address_put (p, &ip_prefix_v6 (a));
897       break;
898     }
899   return 0;
900 }
901
902 u8
903 ip_prefix_length (void *a)
904 {
905   return ip_prefix_len ((ip_prefix_t *) a);
906 }
907
908 void
909 ip_prefix_copy (void *dst, void *src)
910 {
911   clib_memcpy (dst, src, sizeof (ip_prefix_t));
912 }
913
914 void
915 mac_copy (void *dst, void *src)
916 {
917   clib_memcpy (dst, src, 6);
918 }
919
920 void
921 sd_copy (void *dst, void *src)
922 {
923   clib_memcpy (dst, src, sizeof (source_dest_t));
924 }
925
926 int
927 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
928 {
929   int cmp = 0;
930
931   ip_prefix_normalize (p1);
932   ip_prefix_normalize (p2);
933
934   cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
935   if (cmp == 0)
936     {
937       if (ip_prefix_len (p1) < ip_prefix_len (p2))
938         {
939           cmp = 1;
940         }
941       else
942         {
943           if (ip_prefix_len (p1) > ip_prefix_len (p2))
944             cmp = 2;
945         }
946     }
947   return cmp;
948 }
949
950 void
951 no_addr_copy (void *dst, void *src)
952 {
953   /* nothing to do */
954 }
955
956 void
957 vni_copy (void *dst, void *src)
958 {
959   vni_t *vd = dst;
960   vni_t *vs = src;
961
962   clib_memcpy (vd, vs, sizeof (vd[0]));
963   vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
964   gid_address_copy (vni_gid (vd), vni_gid (vs));
965 }
966
967 void
968 lcaf_copy (void *dst, void *src)
969 {
970   lcaf_t *lcaf_dst = dst;
971   lcaf_t *lcaf_src = src;
972
973   lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
974   (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
975 }
976
977 u8
978 lcaf_length (void *a)
979 {
980   return 0;
981 }
982
983 u8
984 mac_length (void *a)
985 {
986   return 0;
987 }
988
989 u8
990 sd_length (void *a)
991 {
992   return 0;
993 }
994
995 void *
996 lcaf_cast (gid_address_t * a)
997 {
998   return &gid_address_lcaf (a);
999 }
1000
1001 void *
1002 mac_cast (gid_address_t * a)
1003 {
1004   return &gid_address_mac (a);
1005 }
1006
1007 void *
1008 sd_cast (gid_address_t * a)
1009 {
1010   return &gid_address_sd (a);
1011 }
1012
1013 u8
1014 no_addr_length (void *a)
1015 {
1016   return 0;
1017 }
1018
1019 u8
1020 vni_length (void *a)
1021 {
1022   vni_t *v = a;
1023   return (sizeof (u32)          /* VNI size */
1024           + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1025 }
1026
1027 u16
1028 lcaf_write (u8 * p, void *a)
1029 {
1030   u16 size = 0, len;
1031   lcaf_t *lcaf = a;
1032   u8 type = lcaf_type (lcaf);
1033   lcaf_hdr_t _h, *h = &_h;
1034
1035   *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1036   size += sizeof (u16);
1037   memset (h, 0, sizeof (h[0]));
1038   LCAF_TYPE (h) = type;
1039   u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1040   LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1041
1042   clib_memcpy (p + size, h, sizeof (h[0]));
1043   size += sizeof (h[0]);
1044   len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1045
1046   if ((u16) ~ 0 == len)
1047     return ~0;
1048
1049   return size + len;
1050 }
1051
1052 u16
1053 mac_write (u8 * p, void *a)
1054 {
1055   *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1056   clib_memcpy (p + sizeof (u16), a, 6);
1057   return mac_size_to_write (a);
1058 }
1059
1060 static u16
1061 fid_addr_write (u8 * p, fid_address_t * a)
1062 {
1063   switch (fid_addr_type (a))
1064     {
1065     case FID_ADDR_IP_PREF:
1066       return ip_prefix_write (p, &fid_addr_ippref (a));
1067
1068     case FID_ADDR_MAC:
1069       return mac_write (p, &fid_addr_mac (a));
1070
1071     default:
1072       return ~0;
1073     }
1074   return ~0;
1075 }
1076
1077 static u8
1078 fid_address_length (fid_address_t * a)
1079 {
1080   switch (fid_addr_type (a))
1081     {
1082     case FID_ADDR_IP_PREF:
1083       return ip_prefix_length (&fid_addr_ippref (a));
1084     case FID_ADDR_MAC:
1085       return 0;
1086     }
1087   return 0;
1088 }
1089
1090 u16
1091 sd_write (u8 * p, void *a)
1092 {
1093   source_dest_t *sd = a;
1094   u16 size = 0;
1095   lcaf_hdr_t _h, *h = &_h;
1096   lcaf_src_dst_hdr_t sd_hdr;
1097
1098   *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1099   size += sizeof (u16);
1100   memset (h, 0, sizeof (h[0]));
1101   LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1102   u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1103     + fid_addr_size_to_write (&sd_src (sd))
1104     + fid_addr_size_to_write (&sd_dst (sd));
1105   LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1106
1107   clib_memcpy (p + size, h, sizeof (h[0]));
1108   size += sizeof (h[0]);
1109
1110   memset (&sd_hdr, 0, sizeof (sd_hdr));
1111   LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1112   LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1113   clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1114   size += sizeof (sd_hdr);
1115
1116   u16 len = fid_addr_write (p + size, &sd_src (sd));
1117   if ((u16) ~ 0 == len)
1118     return ~0;
1119   size += len;
1120
1121   len = fid_addr_write (p + size, &sd_dst (sd));
1122   if ((u16) ~ 0 == len)
1123     return ~0;
1124   size += len;
1125
1126   return size;
1127 }
1128
1129 u16
1130 vni_write (u8 * p, void *a)
1131 {
1132   lcaf_hdr_t _h, *h = &_h;
1133   gid_address_t *g = a;
1134   u16 size = 0, len;
1135
1136   /* put lcaf header */
1137   *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1138   size += sizeof (u16);
1139   memset (h, 0, sizeof (h[0]));
1140   LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1141   u16 lcaf_len = sizeof (u32)   /* Instance ID size */
1142     + gid_address_size_to_put_no_vni (g);
1143   LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1144   LCAF_RES2 (h) = gid_address_vni_mask (g);
1145
1146   /* put vni header */
1147   clib_memcpy (p + size, h, sizeof (h[0]));
1148   size += sizeof (h[0]);
1149
1150   u32 *afip = (u32 *) (p + size);
1151   afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1152   size += sizeof (u32);
1153
1154   if (GID_ADDR_SRC_DST == gid_address_type (g))
1155     /* write src/dst LCAF */
1156     {
1157       len = sd_write (p + size, g);
1158       if ((u16) ~ 0 == len)
1159         return ~0;
1160     }
1161   else
1162     /* write the actual address */
1163     len = gid_address_put_no_vni (p + size, g);
1164
1165   if ((u16) ~ 0 == len)
1166     return ~0;
1167
1168   return size + len;
1169 }
1170
1171 u16
1172 no_addr_write (u8 * p, void *a)
1173 {
1174   /* do nothing; return AFI field size */
1175   return sizeof (u16);
1176 }
1177
1178 u16
1179 no_addr_size_to_write (void *a)
1180 {
1181   return sizeof (u16);          /* AFI field length */
1182 }
1183
1184 static u16
1185 fid_addr_size_to_write (fid_address_t * a)
1186 {
1187   switch (fid_addr_type (a))
1188     {
1189     case FID_ADDR_IP_PREF:
1190       return ip_prefix_size_to_write (a);
1191
1192     case FID_ADDR_MAC:
1193       return mac_size_to_write (a);
1194
1195     default:
1196       break;
1197     }
1198   return 0;
1199 }
1200
1201 u16
1202 vni_size_to_write (void *a)
1203 {
1204   gid_address_t *g = a;
1205
1206   u16 lcaf_size = sizeof (u32) + sizeof (u16)   /* LCAF AFI field size */
1207     + sizeof (lcaf_hdr_t);
1208
1209   if (gid_address_type (g) == GID_ADDR_SRC_DST)
1210     /* special case where nested LCAF is supported */
1211     return lcaf_size + sd_size_to_write (g);
1212   else
1213     return lcaf_size + gid_address_size_to_put_no_vni (g);
1214 }
1215
1216 u16
1217 lcaf_size_to_write (void *a)
1218 {
1219   lcaf_t *lcaf = (lcaf_t *) a;
1220   u32 size = 0, len;
1221   u8 type = lcaf_type (lcaf);
1222
1223   size += sizeof (u16);         /* AFI size */
1224
1225   len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1226   if (~0 == len)
1227     return ~0;
1228
1229   return size + len;
1230 }
1231
1232 u16
1233 sd_size_to_write (void *a)
1234 {
1235   source_dest_t *sd = a;
1236   return sizeof (u16)
1237     + sizeof (lcaf_hdr_t)
1238     + sizeof (lcaf_src_dst_hdr_t)
1239     + fid_addr_size_to_write (&sd_src (sd))
1240     + fid_addr_size_to_write (&sd_dst (sd));
1241 }
1242
1243 u16
1244 mac_size_to_write (void *a)
1245 {
1246   return sizeof (u16) + 6;
1247 }
1248
1249 u8
1250 gid_address_len (gid_address_t * a)
1251 {
1252   gid_address_type_t type = gid_address_type (a);
1253   return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1254 }
1255
1256 static u16
1257 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1258 {
1259   gid_address_type_t type = gid_address_type (gid);
1260   return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1261 }
1262
1263 u16
1264 gid_address_put (u8 * b, gid_address_t * gid)
1265 {
1266   if (0 != gid_address_vni (gid))
1267     return vni_write (b, gid);
1268
1269   return gid_address_put_no_vni (b, gid);
1270 }
1271
1272 static u16
1273 gid_address_size_to_put_no_vni (gid_address_t * gid)
1274 {
1275   gid_address_type_t type = gid_address_type (gid);
1276   return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1277 }
1278
1279 u16
1280 gid_address_size_to_put (gid_address_t * gid)
1281 {
1282   if (0 != gid_address_vni (gid))
1283     return vni_size_to_write (gid);
1284
1285   return gid_address_size_to_put_no_vni (gid);
1286 }
1287
1288 void *
1289 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1290 {
1291   return (*cast_fcts[type]) (gid);
1292 }
1293
1294 void
1295 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1296 {
1297   gid_address_type_t type = gid_address_type (src);
1298   (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1299   gid_address_type (dst) = type;
1300   gid_address_vni (dst) = gid_address_vni (src);
1301   gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1302 }
1303
1304 u32
1305 mac_parse (u8 * offset, u8 * a)
1306 {
1307   /* skip AFI field */
1308   offset += sizeof (u16);
1309
1310   clib_memcpy (a, offset, 6);
1311   return sizeof (u16) + 6;
1312 }
1313
1314 u32
1315 gid_address_parse (u8 * offset, gid_address_t * a)
1316 {
1317   lisp_afi_e afi;
1318   int len = 0;
1319
1320   if (!a)
1321     return 0;
1322
1323   /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1324    * the gid address here */
1325   afi = clib_net_to_host_u16 (*((u16 *) offset));
1326
1327   switch (afi)
1328     {
1329     case LISP_AFI_NO_ADDR:
1330       len = sizeof (u16);
1331       gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1332       break;
1333     case LISP_AFI_IP:
1334       len = ip_address_parse (offset, afi, &gid_address_ip (a));
1335       gid_address_type (a) = GID_ADDR_IP_PREFIX;
1336       /* this should be modified outside if needed */
1337       gid_address_ippref_len (a) = 32;
1338       break;
1339     case LISP_AFI_IP6:
1340       len = ip_address_parse (offset, afi, &gid_address_ip (a));
1341       gid_address_type (a) = GID_ADDR_IP_PREFIX;
1342       /* this should be modified outside if needed */
1343       gid_address_ippref_len (a) = 128;
1344       break;
1345     case LISP_AFI_LCAF:
1346       gid_address_type (a) = GID_ADDR_LCAF;
1347       len = lcaf_parse (offset, a);
1348       break;
1349     case LISP_AFI_MAC:
1350       len = mac_parse (offset, gid_address_mac (a));
1351       gid_address_type (a) = GID_ADDR_MAC;
1352       break;
1353     default:
1354       clib_warning ("LISP AFI %d not supported!", afi);
1355       return ~0;
1356     }
1357   return len;
1358 }
1359
1360 void
1361 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1362 {
1363   gid_address_ippref_len (dst) = ip_address_max_len (version);
1364   ip_address_set (&gid_address_ip (dst), src, version);
1365 }
1366
1367 int
1368 no_addr_cmp (void *a1, void *a2)
1369 {
1370   return 0;
1371 }
1372
1373 int
1374 vni_cmp (void *a1, void *a2)
1375 {
1376   vni_t *v1 = a1;
1377   vni_t *v2 = a2;
1378
1379   if (vni_mask_len (v1) != vni_mask_len (v2))
1380     return -1;
1381   if (vni_vni (v1) != vni_vni (v2))
1382     return -1;
1383   return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1384 }
1385
1386 static int
1387 mac_cmp (void *a1, void *a2)
1388 {
1389   return memcmp (a1, a2, 6);
1390 }
1391
1392 static int
1393 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1394 {
1395   if (fid_addr_type (a1) != fid_addr_type (a2))
1396     return -1;
1397
1398   switch (fid_addr_type (a1))
1399     {
1400     case FID_ADDR_IP_PREF:
1401       return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1402
1403     case FID_ADDR_MAC:
1404       return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1405
1406     default:
1407       return -1;
1408     }
1409   return -1;
1410 }
1411
1412 int
1413 sd_cmp (void *a1, void *a2)
1414 {
1415   source_dest_t *sd1 = a1;
1416   source_dest_t *sd2 = a2;
1417
1418   if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1419     return -1;
1420   if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1421     return -1;
1422   return 0;
1423 }
1424
1425 /* Compare two gid_address_t.
1426  * Returns:
1427  *        -1: If they are from different afi
1428  *             0: Both address are the same
1429  *             1: Addr1 is bigger than addr2
1430  *             2: Addr2 is bigger than addr1
1431  */
1432 int
1433 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1434 {
1435   lcaf_t *lcaf1, *lcaf2;
1436   int cmp = -1;
1437   if (!a1 || !a2)
1438     return -1;
1439   if (gid_address_type (a1) != gid_address_type (a2))
1440     return -1;
1441   if (gid_address_vni (a1) != gid_address_vni (a2))
1442     return -1;
1443   if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1444     return -1;
1445
1446   switch (gid_address_type (a1))
1447     {
1448     case GID_ADDR_NO_ADDRESS:
1449       if (a1 == a2)
1450         cmp = 0;
1451       else
1452         cmp = 2;
1453       break;
1454     case GID_ADDR_IP_PREFIX:
1455       cmp =
1456         ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1457       break;
1458     case GID_ADDR_LCAF:
1459       lcaf1 = &gid_address_lcaf (a1);
1460       lcaf2 = &gid_address_lcaf (a2);
1461       if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1462         cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1463       break;
1464     case GID_ADDR_MAC:
1465       cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1466       break;
1467
1468     case GID_ADDR_SRC_DST:
1469       cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1470       break;
1471     default:
1472       break;
1473     }
1474
1475   return cmp;
1476 }
1477
1478 u32
1479 locator_parse (void *b, locator_t * loc)
1480 {
1481   locator_hdr_t *h;
1482   u8 status = 1;                /* locator up */
1483   int len;
1484
1485   h = b;
1486   if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1487     status = 0;
1488
1489   len = gid_address_parse (LOC_ADDR (h), &loc->address);
1490   if (len == ~0)
1491     return len;
1492
1493   loc->state = status;
1494   loc->local = 0;
1495   loc->priority = LOC_PRIORITY (h);
1496   loc->weight = LOC_WEIGHT (h);
1497   loc->mpriority = LOC_MPRIORITY (h);
1498   loc->mweight = LOC_MWEIGHT (h);
1499
1500   return sizeof (locator_hdr_t) + len;
1501 }
1502
1503 void
1504 locator_copy (locator_t * dst, locator_t * src)
1505 {
1506   /* TODO if gid become more complex, this will need to be changed! */
1507   clib_memcpy (dst, src, sizeof (*dst));
1508   if (!src->local)
1509     gid_address_copy (&dst->address, &src->address);
1510 }
1511
1512 u32
1513 locator_cmp (locator_t * l1, locator_t * l2)
1514 {
1515   u32 ret = 0;
1516   if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1517     return 1;
1518
1519   if (l1->priority != l2->priority)
1520     return 1;
1521   if (l1->weight != l2->weight)
1522     return 1;
1523   if (l1->mpriority != l2->mpriority)
1524     return 1;
1525   if (l1->mweight != l2->mweight)
1526     return 1;
1527   return 0;
1528 }
1529
1530 void
1531 locator_free (locator_t * l)
1532 {
1533   if (!l->local)
1534     gid_address_free (&l->address);
1535 }
1536
1537 void
1538 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1539 {
1540   memset (sd, 0, sizeof (*sd));
1541   gid_address_type (sd) = GID_ADDR_SRC_DST;
1542   gid_address_vni (sd) = gid_address_vni (dst);
1543   gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1544
1545   switch (gid_address_type (dst))
1546     {
1547     case GID_ADDR_IP_PREFIX:
1548       gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1549       gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1550       ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1551                       &gid_address_ippref (src));
1552       ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1553                       &gid_address_ippref (dst));
1554       break;
1555     case GID_ADDR_MAC:
1556       gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1557       gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1558       mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1559       mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1560       break;
1561     default:
1562       clib_warning ("Unsupported gid type %d while conversion!",
1563                     gid_address_type (dst));
1564       break;
1565     }
1566 }
1567
1568 /*
1569  * fd.io coding-style-patch-verification: ON
1570  *
1571  * Local Variables:
1572  * eval: (c-set-style "gnu")
1573  * End:
1574  */