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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <vnet/lisp-cp/lisp_types.h>
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);
22 u32 mac_parse (u8 * offset, u8 * a);
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 *);
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,
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 };
45 #define foreach_lcaf_type \
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 *);
70 #define CONCAT(a,b) a##_##b
71 #define IF(c, t, e) CONCAT(IF, c)(t, e)
74 #define EXPAND_FCN(cond, fcn) \
76 cmp_fct lcaf_cmp_fcts[LCAF_TYPES] =
78 #define _(cond, name) \
79 EXPAND_FCN(cond, name##_cmp),
84 addr_len_fct lcaf_body_length_fcts[LCAF_TYPES] = {
85 #define _(cond, name) \
86 EXPAND_FCN(cond, name##_length),
91 copy_fct lcaf_copy_fcts[LCAF_TYPES] = {
92 #define _(cond, name) \
93 EXPAND_FCN(cond, name##_copy),
98 free_fct lcaf_free_fcts[LCAF_TYPES] = {
99 #define _(cond, name) \
100 EXPAND_FCN(cond, name##_free),
105 size_to_write_fct lcaf_size_to_write_fcts[LCAF_TYPES] = {
106 #define _(cond, name) \
107 EXPAND_FCN(cond, name##_size_to_write),
112 serdes_fct lcaf_write_fcts[LCAF_TYPES] = {
113 #define _(cond, name) \
114 EXPAND_FCN(cond, name##_write),
119 serdes_fct lcaf_parse_fcts[LCAF_TYPES] = {
120 #define _(cond, name) \
121 EXPAND_FCN(cond, name##_parse),
127 format_ip_address (u8 * s, va_list * args)
129 ip_address_t *a = va_arg (*args, ip_address_t *);
130 u8 ver = ip_addr_version (a);
133 return format (s, "%U", format_ip4_address, &ip_addr_v4 (a));
137 return format (s, "%U", format_ip6_address, &ip_addr_v6 (a));
141 clib_warning ("Can't format IP version %d!", ver);
147 unformat_ip_address (unformat_input_t * input, va_list * args)
149 ip_address_t *a = va_arg (*args, ip_address_t *);
150 if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (a)))
151 ip_addr_version (a) = IP4;
152 else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6 (a)))
153 ip_addr_version (a) = IP6;
160 format_ip_prefix (u8 * s, va_list * args)
162 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
163 return format (s, "%U/%d", format_ip_address, &ip_prefix_addr (a),
168 unformat_ip_prefix (unformat_input_t * input, va_list * args)
170 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
171 if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr (a),
174 if ((ip_prefix_version (a) == IP4 && 32 < ip_prefix_len (a)) ||
175 (ip_prefix_version (a) == IP6 && 128 < ip_prefix_length (a)))
177 clib_warning ("Prefix length to big: %d!", ip_prefix_len (a));
180 ip_prefix_normalize (a);
188 unformat_mac_address (unformat_input_t * input, va_list * args)
190 u8 *a = va_arg (*args, u8 *);
191 return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
196 format_mac_address (u8 * s, va_list * args)
198 u8 *a = va_arg (*args, u8 *);
199 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
200 a[0], a[1], a[2], a[3], a[4], a[5]);
204 format_fid_address (u8 * s, va_list * args)
206 fid_address_t *a = va_arg (*args, fid_address_t *);
208 switch (fid_addr_type (a))
210 case FID_ADDR_IP_PREF:
211 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
214 return format (s, "%U", format_ip_prefix, &fid_addr_mac (a));
217 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
224 format_gid_address (u8 * s, va_list * args)
226 gid_address_t *a = va_arg (*args, gid_address_t *);
227 u8 type = gid_address_type (a);
230 case GID_ADDR_IP_PREFIX:
231 return format (s, "[%d] %U", gid_address_vni (a), format_ip_prefix,
232 &gid_address_ippref (a));
233 case GID_ADDR_SRC_DST:
234 return format (s, "[%d] %U|%U", gid_address_vni (a),
235 format_fid_address, &gid_address_sd_src (a),
236 format_fid_address, &gid_address_sd_dst (a));
238 return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
239 &gid_address_mac (a));
241 clib_warning ("Can't format gid type %d", type);
248 unformat_fid_address (unformat_input_t * i, va_list * args)
250 fid_address_t *a = va_arg (*args, fid_address_t *);
254 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
256 fid_addr_type (a) = FID_ADDR_IP_PREF;
257 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
259 else if (unformat (i, "%U", unformat_mac_address, mac))
261 fid_addr_type (a) = FID_ADDR_MAC;
262 mac_copy (fid_addr_mac (a), mac);
271 unformat_gid_address (unformat_input_t * input, va_list * args)
273 gid_address_t *a = va_arg (*args, gid_address_t *);
276 fid_address_t sim1, sim2;
278 memset (&ippref, 0, sizeof (ippref));
279 memset (&sim1, 0, sizeof (sim1));
280 memset (&sim2, 0, sizeof (sim2));
282 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
283 unformat_fid_address, &sim2))
285 gid_address_sd_src (a) = sim1;
286 gid_address_sd_dst (a) = sim2;
287 gid_address_type (a) = GID_ADDR_SRC_DST;
289 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
291 ip_prefix_copy (&gid_address_ippref (a), &ippref);
292 gid_address_type (a) = GID_ADDR_IP_PREFIX;
294 else if (unformat (input, "%U", unformat_mac_address, mac))
296 mac_copy (gid_address_mac (a), mac);
297 gid_address_type (a) = GID_ADDR_MAC;
306 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
308 u32 *action = va_arg (*args, u32 *);
311 if (unformat (input, "%s", &s))
313 if (!strcmp ((char *) s, "no-action"))
314 action[0] = LISP_NO_ACTION;
315 else if (!strcmp ((char *) s, "natively-forward"))
316 action[0] = LISP_FORWARD_NATIVE;
317 else if (!strcmp ((char *) s, "send-map-request"))
318 action[0] = LISP_SEND_MAP_REQUEST;
319 else if (!strcmp ((char *) s, "drop"))
320 action[0] = LISP_DROP;
323 clib_warning ("invalid action: '%s'", s);
324 action[0] = LISP_DROP;
335 ip_address_size (ip_address_t * a)
337 switch (ip_addr_version (a))
340 return sizeof (ip4_address_t);
343 return sizeof (ip6_address_t);
350 ip_version_to_size (u8 ver)
355 return sizeof (ip4_address_t);
358 return sizeof (ip6_address_t);
365 ip_version_to_max_plen (u8 ver)
379 always_inline lisp_afi_e
380 ip_version_to_iana_afi (u16 version)
395 ip_iana_afi_to_version (lisp_afi_e afi)
410 ip_address_size_to_write (ip_address_t * a)
412 return ip_address_size (a) + sizeof (u16);
416 ip_address_iana_afi (ip_address_t * a)
418 return ip_version_to_iana_afi (ip_addr_version (a));
422 ip_address_max_len (u8 version)
424 return version == IP4 ? 32 : 128;
428 ip4_address_size_to_put ()
430 // return sizeof(u16) + sizeof (ip4_address_t);
435 ip6_address_size_to_put ()
437 //return sizeof(u16) + sizeof (ip6_address_t);
442 ip4_address_put (u8 * b, ip4_address_t * a)
444 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
445 u8 *p = b + sizeof (u16);
446 clib_memcpy (p, a, sizeof (*a));
447 return ip4_address_size_to_put ();
451 ip6_address_put (u8 * b, ip6_address_t * a)
453 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
454 u8 *p = b + sizeof (u16);
455 clib_memcpy (p, a, sizeof (*a));
456 return ip6_address_size_to_put ();
460 ip_address_put (u8 * b, ip_address_t * a)
462 u32 len = ip_address_size (a);
463 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
464 u8 *p = b + sizeof (u16);
465 clib_memcpy (p, &ip_addr_addr (a), len);
466 return (len + sizeof (u16));
470 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
472 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
473 u8 size = ip_version_to_size (ip_addr_version (dst));
474 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
475 return (sizeof (u16) + size);
479 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
481 lcaf_hdr_t *lh = offset;
482 lcaf->type = lh->type;
484 /* this is a bit of hack: since the LCAF Instance ID is the
485 only message that uses reserved2 field, we can set it here.
486 If any LCAF format starts using reserved2 field as well this needs
487 to be moved elsewhere */
488 lcaf_vni_len (lcaf) = lh->reserved2;
490 return sizeof (lh[0]);
494 iana_afi_to_fid_addr_type (u16 type)
500 return FID_ADDR_IP_PREF;
509 fid_addr_parse (u8 * p, fid_address_t * a)
511 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
512 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
513 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
515 switch (fid_addr_type (a))
518 return mac_parse (p, fid_addr_mac (a));
520 case FID_ADDR_IP_PREF:
521 return ip_address_parse (p, afi, ip_addr);
527 sd_parse (u8 * p, void *a)
529 lcaf_src_dst_hdr_t *sd_hdr;
530 gid_address_t *g = a;
532 fid_address_t *src = &gid_address_sd_src (g);
533 fid_address_t *dst = &gid_address_sd_dst (g);
535 gid_address_type (g) = GID_ADDR_SRC_DST;
537 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
538 size += sizeof (sd_hdr[0]);
540 size += fid_addr_parse (p + size, src);
541 size += fid_addr_parse (p + size, dst);
543 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
545 ip_prefix_t *ippref = &fid_addr_ippref (src);
546 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
548 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
550 ip_prefix_t *ippref = &fid_addr_ippref (dst);
551 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
557 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
560 u16 size = sizeof (u16); /* skip AFI */
562 size += lcaf_hdr_parse (p + size, &lcaf);
564 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
567 size += sd_parse (p + size, a);
572 vni_parse (u8 * p, void *a)
575 gid_address_t *g = a;
578 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
579 size += sizeof (u32);
580 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
582 /* nested LCAFs are not supported except of src/dst with vni - to handle
583 * such case look at the next AFI and process src/dest LCAF separately */
584 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
585 if (LISP_AFI_LCAF == afi)
587 u16 len = try_parse_src_dst_lcaf (p + size, g);
588 if ((u16) ~ 0 == len)
593 size += gid_address_parse (p + size, g);
599 no_addr_parse (u8 * p, void *a)
606 lcaf_parse (void *offset, gid_address_t * addr)
609 offset += sizeof (u16);
610 lcaf_t *lcaf = &gid_address_lcaf (addr);
612 u32 size = lcaf_hdr_parse (offset, lcaf);
613 u8 type = lcaf_type (lcaf);
615 if (!lcaf_parse_fcts[type])
617 clib_warning ("Unsupported LCAF type: %u", type);
620 size += (*lcaf_parse_fcts[type]) (offset + size, lcaf);
621 return sizeof (u16) + size;
628 gid_address_free (vni_gid (v));
629 clib_mem_free (vni_gid (v));
633 no_addr_free (void *a)
645 gid_address_free (gid_address_t * a)
647 if (gid_address_type (a) != GID_ADDR_LCAF)
650 lcaf_t *lcaf = &gid_address_lcaf (a);
651 u8 lcaf_type = lcaf_type (lcaf);
652 (*lcaf_free_fcts[lcaf_type]) (lcaf);
656 ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2)
659 if (ip_addr_version (ip1) != ip_addr_version (ip2))
662 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
673 ip_address_copy (ip_address_t * dst, ip_address_t * src)
675 clib_memcpy (dst, src, sizeof (ip_address_t));
679 ip_address_copy_addr (void *dst, ip_address_t * src)
681 clib_memcpy (dst, src, ip_address_size (src));
685 ip_address_set (ip_address_t * dst, void *src, u8 version)
687 clib_memcpy (dst, src, ip_version_to_size (version));
688 ip_addr_version (dst) = version;
692 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
703 mask = pow2_mask (preflen) << (32 - preflen);
704 mask = clib_host_to_net_u32 (mask);
705 ip4->data_u32 &= mask;
709 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
717 memset (mask_6, 0, sizeof (mask_6));
726 m = (u32 *) & mask_6[0];
728 for (j = 0; j < i0; j++)
735 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
738 for (j = 0; j < sizeof (mask_6); j++)
740 ip6->as_u8[j] &= mask_6[j];
745 ip_prefix_normalize (ip_prefix_t * a)
747 u8 preflen = ip_prefix_len (a);
749 switch (ip_prefix_version (a))
752 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
756 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
765 ip_prefix_cast (gid_address_t * a)
767 return &gid_address_ippref (a);
771 ip_prefix_size_to_write (void *pref)
773 ip_prefix_t *a = (ip_prefix_t *) pref;
774 return ip_address_size_to_write (&ip_prefix_addr (a));
778 ip_prefix_write (u8 * p, void *gid)
780 gid_address_t *g = gid;
781 ip_prefix_t *a = &gid_address_ippref (g);
783 switch (ip_prefix_version (a))
786 return ip4_address_put (p, &ip_prefix_v4 (a));
789 return ip6_address_put (p, &ip_prefix_v6 (a));
796 ip_prefix_length (void *a)
798 return ip_prefix_len ((ip_prefix_t *) a);
802 ip_prefix_copy (void *dst, void *src)
804 clib_memcpy (dst, src, sizeof (ip_prefix_t));
808 mac_copy (void *dst, void *src)
810 clib_memcpy (dst, src, 6);
814 sd_copy (void *dst, void *src)
816 clib_memcpy (dst, src, sizeof (source_dest_t));
820 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
824 ip_prefix_normalize (p1);
825 ip_prefix_normalize (p2);
827 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
830 if (ip_prefix_len (p1) < ip_prefix_len (p2))
836 if (ip_prefix_len (p1) > ip_prefix_len (p2))
844 no_addr_copy (void *dst, void *src)
850 vni_copy (void *dst, void *src)
855 clib_memcpy (vd, vs, sizeof (vd[0]));
856 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
857 gid_address_copy (vni_gid (vd), vni_gid (vs));
861 lcaf_copy (void *dst, void *src)
863 lcaf_t *lcaf_dst = dst;
864 lcaf_t *lcaf_src = src;
866 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
867 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
871 lcaf_length (void *a)
889 lcaf_cast (gid_address_t * a)
891 return &gid_address_lcaf (a);
895 mac_cast (gid_address_t * a)
897 return &gid_address_mac (a);
901 sd_cast (gid_address_t * a)
903 return &gid_address_sd (a);
907 no_addr_length (void *a)
916 return (sizeof (u32) /* VNI size */
917 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
921 lcaf_write (u8 * p, void *a)
925 u8 type = lcaf_type (lcaf);
926 lcaf_hdr_t _h, *h = &_h;
928 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
929 size += sizeof (u16);
930 memset (h, 0, sizeof (h[0]));
931 LCAF_TYPE (h) = type;
932 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
933 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
935 clib_memcpy (p + size, h, sizeof (h[0]));
936 size += sizeof (h[0]);
937 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
939 if ((u16) ~ 0 == len)
946 mac_write (u8 * p, void *a)
948 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
949 clib_memcpy (p + sizeof (u16), a, 6);
950 return mac_size_to_write (a);
954 fid_addr_write (u8 * p, fid_address_t * a)
956 switch (fid_addr_type (a))
958 case FID_ADDR_IP_PREF:
959 return ip_prefix_write (p, &fid_addr_ippref (a));
962 return mac_write (p, &fid_addr_mac (a));
971 fid_address_length (fid_address_t * a)
973 switch (fid_addr_type (a))
975 case FID_ADDR_IP_PREF:
976 return ip_prefix_length (&fid_addr_ippref (a));
984 sd_write (u8 * p, void *a)
986 source_dest_t *sd = a;
988 lcaf_hdr_t _h, *h = &_h;
989 lcaf_src_dst_hdr_t sd_hdr;
991 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
992 size += sizeof (u16);
993 memset (h, 0, sizeof (h[0]));
994 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
995 u16 lcaf_len = 4 + sizeof (lcaf_src_dst_hdr_t)
996 + fid_addr_size_to_write (&sd_src (sd))
997 + fid_addr_size_to_write (&sd_dst (sd));
998 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1000 clib_memcpy (p + size, h, sizeof (h[0]));
1001 size += sizeof (h[0]);
1003 memset (&sd_hdr, 0, sizeof (sd_hdr));
1004 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1005 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1006 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1007 size += sizeof (sd_hdr);
1009 u16 len = fid_addr_write (p + size, &sd_src (sd));
1010 if ((u16) ~ 0 == len)
1014 len = fid_addr_write (p + size, &sd_dst (sd));
1015 if ((u16) ~ 0 == len)
1023 vni_write (u8 * p, void *a)
1025 lcaf_hdr_t _h, *h = &_h;
1026 gid_address_t *g = a;
1029 /* put lcaf header */
1030 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1031 size += sizeof (u16);
1032 memset (h, 0, sizeof (h[0]));
1033 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1034 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1035 + gid_address_size_to_put_no_vni (g);
1036 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1037 LCAF_RES2 (h) = gid_address_vni_mask (g);
1039 /* put vni header */
1040 clib_memcpy (p + size, h, sizeof (h[0]));
1041 size += sizeof (h[0]);
1043 u32 *afip = (u32 *) (p + size);
1044 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1045 size += sizeof (u32);
1047 if (GID_ADDR_SRC_DST == gid_address_type (g))
1048 /* write src/dst LCAF */
1050 len = sd_write (p + size, g);
1051 if ((u16) ~ 0 == len)
1055 /* write the actual address */
1056 len = gid_address_put_no_vni (p + size, g);
1058 if ((u16) ~ 0 == len)
1065 no_addr_write (u8 * p, void *a)
1067 /* do nothing; return AFI field size */
1068 return sizeof (u16);
1072 no_addr_size_to_write (void *a)
1074 return sizeof (u16); /* AFI field length */
1078 fid_addr_size_to_write (fid_address_t * a)
1080 switch (fid_addr_type (a))
1082 case FID_ADDR_IP_PREF:
1083 return ip_prefix_size_to_write (a);
1086 return mac_size_to_write (a);
1095 vni_size_to_write (void *a)
1097 gid_address_t *g = a;
1099 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1100 + sizeof (lcaf_hdr_t);
1102 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1103 /* special case where nested LCAF is supported */
1104 return lcaf_size + sd_size_to_write (g);
1106 return lcaf_size + gid_address_size_to_put_no_vni (g);
1110 lcaf_size_to_write (void *a)
1112 lcaf_t *lcaf = (lcaf_t *) a;
1114 u8 type = lcaf_type (lcaf);
1116 size += sizeof (u16); /* AFI size */
1118 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1126 sd_size_to_write (void *a)
1128 source_dest_t *sd = a;
1130 + sizeof (lcaf_hdr_t)
1131 + sizeof (lcaf_src_dst_hdr_t)
1132 + fid_addr_size_to_write (&sd_src (sd))
1133 + fid_addr_size_to_write (&sd_dst (sd));
1137 mac_size_to_write (void *a)
1139 return sizeof (u16) + 6;
1143 gid_address_len (gid_address_t * a)
1145 gid_address_type_t type = gid_address_type (a);
1146 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1150 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1152 gid_address_type_t type = gid_address_type (gid);
1153 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1157 gid_address_put (u8 * b, gid_address_t * gid)
1159 if (0 != gid_address_vni (gid))
1160 return vni_write (b, gid);
1162 return gid_address_put_no_vni (b, gid);
1166 gid_address_size_to_put_no_vni (gid_address_t * gid)
1168 gid_address_type_t type = gid_address_type (gid);
1169 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1173 gid_address_size_to_put (gid_address_t * gid)
1175 if (0 != gid_address_vni (gid))
1176 return vni_size_to_write (gid);
1178 return gid_address_size_to_put_no_vni (gid);
1182 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1184 return (*cast_fcts[type]) (gid);
1188 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1190 gid_address_type_t type = gid_address_type (src);
1191 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1192 gid_address_type (dst) = type;
1193 gid_address_vni (dst) = gid_address_vni (src);
1194 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1198 mac_parse (u8 * offset, u8 * a)
1200 /* skip AFI field */
1201 offset += sizeof (u16);
1203 clib_memcpy (a, offset, 6);
1204 return sizeof (u16) + 6;
1208 gid_address_parse (u8 * offset, gid_address_t * a)
1216 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1217 * the gid address here */
1218 afi = clib_net_to_host_u16 (*((u16 *) offset));
1222 case LISP_AFI_NO_ADDR:
1224 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1227 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1228 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1229 /* this should be modified outside if needed */
1230 gid_address_ippref_len (a) = 32;
1233 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1234 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1235 /* this should be modified outside if needed */
1236 gid_address_ippref_len (a) = 128;
1239 gid_address_type (a) = GID_ADDR_LCAF;
1240 len = lcaf_parse (offset, a);
1243 len = mac_parse (offset, gid_address_mac (a));
1244 gid_address_type (a) = GID_ADDR_MAC;
1247 clib_warning ("LISP AFI %d not supported!", afi);
1254 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1256 ip_address_set (&gid_address_ip (dst), src, version);
1260 no_addr_cmp (void *a1, void *a2)
1266 vni_cmp (void *a1, void *a2)
1271 if (vni_mask_len (v1) != vni_mask_len (v2))
1273 if (vni_vni (v1) != vni_vni (v2))
1275 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1279 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1281 if (fid_addr_type (a1) != fid_addr_type (a2))
1284 switch (fid_addr_type (a1))
1286 case FID_ADDR_IP_PREF:
1287 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1290 return memcmp (&fid_addr_mac (a1), &fid_addr_mac (a2), 6);
1299 sd_cmp (void *a1, void *a2)
1301 source_dest_t *sd1 = a1;
1302 source_dest_t *sd2 = a2;
1304 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1306 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1311 /* Compare two gid_address_t.
1313 * -1: If they are from different afi
1314 * 0: Both address are the same
1315 * 1: Addr1 is bigger than addr2
1316 * 2: Addr2 is bigger than addr1
1319 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1321 lcaf_t *lcaf1, *lcaf2;
1325 if (gid_address_type (a1) != gid_address_type (a2))
1327 if (gid_address_vni (a1) != gid_address_vni (a2))
1329 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1332 switch (gid_address_type (a1))
1334 case GID_ADDR_NO_ADDRESS:
1340 case GID_ADDR_IP_PREFIX:
1342 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1345 lcaf1 = &gid_address_lcaf (a1);
1346 lcaf2 = &gid_address_lcaf (a2);
1347 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1348 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1351 cmp = memcmp (gid_address_mac (a1), gid_address_mac (a2),
1352 sizeof (gid_address_mac (a1)));
1355 case GID_ADDR_SRC_DST:
1356 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1366 locator_parse (void *b, locator_t * loc)
1369 u8 status = 1; /* locator up */
1373 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1376 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1380 loc->state = status;
1382 loc->priority = LOC_PRIORITY (h);
1383 loc->weight = LOC_WEIGHT (h);
1384 loc->mpriority = LOC_MPRIORITY (h);
1385 loc->mweight = LOC_MWEIGHT (h);
1387 return sizeof (locator_hdr_t) + len;
1391 locator_copy (locator_t * dst, locator_t * src)
1393 /* TODO if gid become more complex, this will need to be changed! */
1394 clib_memcpy (dst, src, sizeof (*dst));
1396 gid_address_copy (&dst->address, &src->address);
1400 locator_cmp (locator_t * l1, locator_t * l2)
1403 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1406 if (l1->priority != l2->priority)
1408 if (l1->weight != l2->weight)
1410 if (l1->mpriority != l2->mpriority)
1412 if (l1->mweight != l2->mweight)
1418 locator_free (locator_t * l)
1421 gid_address_free (&l->address);
1425 * fd.io coding-style-patch-verification: ON
1428 * eval: (c-set-style "gnu")