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,
35 serdes_fct write_fcts[GID_ADDR_TYPES] =
36 { ip_prefix_write, lcaf_write, mac_write, sd_write };
37 cast_fct cast_fcts[GID_ADDR_TYPES] =
38 { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast };
39 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
40 { ip_prefix_length, lcaf_length, mac_length, sd_length };
41 copy_fct copy_fcts[GID_ADDR_TYPES] =
42 { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy };
44 #define foreach_lcaf_type \
59 #define _(cond, name) \
60 u16 name ## _write (u8 * p, void * a); \
61 u16 name ## _parse (u8 * p, void * a); \
62 u16 name ## _size_to_write (void * a); \
63 void name ## _free (void * a); \
64 void name ## _copy (void * dst, void * src); \
65 u8 name ## _length (void * a); \
66 int name ## _cmp (void *, void *);
70 #define CONCAT(a,b) a##_##b
71 #define IF(c, t, e) CONCAT(IF, c)(t, e)
75 #define EXPAND_FCN(cond, fcn) \
78 cmp_fct lcaf_cmp_fcts[LCAF_TYPES] =
80 #define _(cond, name) \
81 EXPAND_FCN(cond, name##_cmp),
86 addr_len_fct lcaf_body_length_fcts[LCAF_TYPES] =
88 #define _(cond, name) \
89 EXPAND_FCN(cond, name##_length),
94 copy_fct lcaf_copy_fcts[LCAF_TYPES] =
96 #define _(cond, name) \
97 EXPAND_FCN(cond, name##_copy),
102 free_fct lcaf_free_fcts[LCAF_TYPES] =
104 #define _(cond, name) \
105 EXPAND_FCN(cond, name##_free),
110 size_to_write_fct lcaf_size_to_write_fcts[LCAF_TYPES] =
112 #define _(cond, name) \
113 EXPAND_FCN(cond, name##_size_to_write),
118 serdes_fct lcaf_write_fcts[LCAF_TYPES] =
120 #define _(cond, name) \
121 EXPAND_FCN(cond, name##_write),
126 serdes_fct lcaf_parse_fcts[LCAF_TYPES] =
128 #define _(cond, name) \
129 EXPAND_FCN(cond, name##_parse),
135 format_ip_address (u8 * s, va_list * args)
137 ip_address_t * a = va_arg (*args, ip_address_t *);
138 u8 ver = ip_addr_version(a);
141 return format (s, "%U", format_ip4_address, &ip_addr_v4(a));
145 return format (s, "%U", format_ip6_address, &ip_addr_v6(a));
149 clib_warning ("Can't format IP version %d!", ver);
155 unformat_ip_address (unformat_input_t * input, va_list * args)
157 ip_address_t * a = va_arg(*args, ip_address_t *);
158 if (unformat(input, "%U", unformat_ip4_address, &ip_addr_v4(a)))
159 ip_addr_version(a) = IP4;
160 else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6(a)))
161 ip_addr_version(a) = IP6;
168 format_ip_prefix (u8 * s, va_list * args)
170 ip_prefix_t * a = va_arg (*args, ip_prefix_t *);
171 return format (s, "%U/%d", format_ip_address, &ip_prefix_addr(a), ip_prefix_len(a));
175 unformat_ip_prefix (unformat_input_t * input, va_list * args)
177 ip_prefix_t * a = va_arg(*args, ip_prefix_t *);
178 if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr(a),
181 if ((ip_prefix_version(a) == IP4 && 32 < ip_prefix_len(a)) ||
182 (ip_prefix_version(a) == IP6 && 128 < ip_prefix_length(a)))
184 clib_warning("Prefix length to big: %d!", ip_prefix_len(a));
187 ip_prefix_normalize(a);
195 unformat_mac_address (unformat_input_t * input, va_list * args)
197 u8 * a = va_arg(*args, u8 *);
198 return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
203 format_mac_address (u8 * s, va_list * args)
205 u8 * a = va_arg (*args, u8 *);
206 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
207 a[0], a[1], a[2], a[3], a[4], a[5]);
211 format_fid_address (u8 * s, va_list * args)
213 fid_address_t * a = va_arg(*args, fid_address_t *);
215 switch (fid_addr_type (a))
217 case FID_ADDR_IP_PREF:
218 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
221 return format (s, "%U", format_ip_prefix, &fid_addr_mac (a));
224 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
231 format_gid_address (u8 * s, va_list * args)
233 gid_address_t * a = va_arg(*args, gid_address_t *);
234 u8 type = gid_address_type(a);
237 case GID_ADDR_IP_PREFIX:
238 return format (s, "[%d] %U", gid_address_vni(a), format_ip_prefix,
239 &gid_address_ippref(a));
240 case GID_ADDR_SRC_DST:
241 return format (s, "[%d] %U|%U", gid_address_vni(a),
242 format_fid_address, &gid_address_sd_src(a),
243 format_fid_address, &gid_address_sd_dst(a));
245 return format (s, "[%d] %U", gid_address_vni(a), format_mac_address,
246 &gid_address_mac(a));
248 clib_warning("Can't format gid type %d", type);
255 unformat_fid_address (unformat_input_t * i, va_list * args)
257 fid_address_t * a = va_arg (*args, fid_address_t *);
261 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
263 fid_addr_type (a) = FID_ADDR_IP_PREF;
264 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
266 else if (unformat (i, "%U", unformat_mac_address, mac))
268 fid_addr_type (a) = FID_ADDR_MAC;
269 mac_copy (fid_addr_mac (a), mac);
278 unformat_gid_address (unformat_input_t * input, va_list * args)
280 gid_address_t * a = va_arg(*args, gid_address_t *);
283 fid_address_t sim1, sim2;
285 memset (&ippref, 0, sizeof (ippref));
286 memset (&sim1, 0, sizeof (sim1));
287 memset (&sim2, 0, sizeof (sim2));
289 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
290 unformat_fid_address, &sim2))
292 gid_address_sd_src(a) = sim1;
293 gid_address_sd_dst(a) = sim2;
294 gid_address_type(a) = GID_ADDR_SRC_DST;
296 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
298 ip_prefix_copy (&gid_address_ippref(a), &ippref);
299 gid_address_type(a) = GID_ADDR_IP_PREFIX;
301 else if (unformat (input, "%U", unformat_mac_address, mac))
303 mac_copy (gid_address_mac(a), mac);
304 gid_address_type(a) = GID_ADDR_MAC;
313 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
315 u32 * action = va_arg(*args, u32 *);
318 if (unformat (input, "%s", &s))
320 if (!strcmp ((char *) s, "no-action"))
321 action[0] = LISP_NO_ACTION;
322 else if (!strcmp ((char *) s, "natively-forward"))
323 action[0] = LISP_FORWARD_NATIVE;
324 else if (!strcmp ((char *) s, "send-map-request"))
325 action[0] = LISP_SEND_MAP_REQUEST;
326 else if (!strcmp ((char *) s, "drop"))
327 action[0] = LISP_DROP;
330 clib_warning("invalid action: '%s'", s);
331 action[0] = LISP_DROP;
342 ip_address_size (ip_address_t * a)
344 switch (ip_addr_version (a))
347 return sizeof(ip4_address_t);
350 return sizeof(ip6_address_t);
357 ip_version_to_size (u8 ver)
362 return sizeof(ip4_address_t);
365 return sizeof(ip6_address_t);
372 ip_version_to_max_plen (u8 ver)
386 always_inline lisp_afi_e
387 ip_version_to_iana_afi (u16 version)
402 ip_iana_afi_to_version (lisp_afi_e afi)
417 ip_address_size_to_write (ip_address_t * a)
419 return ip_address_size (a) + sizeof (u16);
423 ip_address_iana_afi(ip_address_t *a)
425 return ip_version_to_iana_afi(ip_addr_version(a));
429 ip_address_max_len (u8 version)
431 return version == IP4 ? 32 : 128;
435 ip4_address_size_to_put ()
437 // return sizeof(u16) + sizeof (ip4_address_t);
442 ip6_address_size_to_put ()
444 //return sizeof(u16) + sizeof (ip6_address_t);
449 ip4_address_put (u8 * b, ip4_address_t * a)
451 *(u16 *)b = clib_host_to_net_u16(ip_version_to_iana_afi(IP4));
452 u8 *p = b + sizeof (u16);
453 clib_memcpy (p, a, sizeof(*a));
454 return ip4_address_size_to_put();
458 ip6_address_put (u8 * b, ip6_address_t * a)
460 *(u16 *)b = clib_host_to_net_u16(ip_version_to_iana_afi(IP6));
461 u8 *p = b + sizeof (u16);
462 clib_memcpy (p, a, sizeof(*a));
463 return ip6_address_size_to_put();
467 ip_address_put (u8 * b, ip_address_t * a)
469 u32 len = ip_address_size (a);
470 *(u16 *) b = clib_host_to_net_u16(ip_address_iana_afi (a));
471 u8 * p = b + sizeof (u16);
472 clib_memcpy (p, &ip_addr_addr (a), len);
473 return (len + sizeof (u16));
477 ip_address_parse(void * offset, u16 iana_afi, ip_address_t *dst)
479 ip_addr_version(dst) = ip_iana_afi_to_version (iana_afi);
480 u8 size = ip_version_to_size (ip_addr_version(dst));
481 clib_memcpy (&ip_addr_addr(dst), offset + sizeof(u16), size);
482 return(sizeof(u16) + size);
486 lcaf_hdr_parse (void * offset, lcaf_t * lcaf)
488 lcaf_hdr_t * lh = offset;
489 lcaf->type = lh->type;
491 /* this is a bit of hack: since the LCAF Instance ID is the
492 only message that uses reserved2 field, we can set it here.
493 If any LCAF format starts using reserved2 field as well this needs
494 to be moved elsewhere */
495 lcaf_vni_len (lcaf) = lh->reserved2;
497 return sizeof (lh[0]);
501 iana_afi_to_fid_addr_type (u16 type)
507 return FID_ADDR_IP_PREF;
516 fid_addr_parse (u8 * p, fid_address_t * a)
518 u16 afi = clib_net_to_host_u16 ( *(u16 *) p);
519 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
520 ip_address_t * ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
522 switch (fid_addr_type (a))
525 return mac_parse (p, fid_addr_mac (a));
527 case FID_ADDR_IP_PREF:
528 return ip_address_parse (p, afi, ip_addr);
534 sd_parse (u8 * p, void * a)
536 lcaf_src_dst_hdr_t * sd_hdr;
537 gid_address_t * g = a;
539 fid_address_t * src = &gid_address_sd_src (g);
540 fid_address_t * dst = &gid_address_sd_dst (g);
542 gid_address_type (g) = GID_ADDR_SRC_DST;
544 sd_hdr = (lcaf_src_dst_hdr_t *)(p + size);
545 size += sizeof (sd_hdr[0]);
547 size += fid_addr_parse (p + size, src);
548 size += fid_addr_parse (p + size, dst);
550 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
552 ip_prefix_t * ippref = &fid_addr_ippref (src);
553 ip_prefix_len(ippref) = LCAF_SD_SRC_ML(sd_hdr);
555 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
557 ip_prefix_t * ippref = &fid_addr_ippref (dst);
558 ip_prefix_len(ippref) = LCAF_SD_DST_ML(sd_hdr);
564 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
567 u16 size = sizeof (u16); /* skip AFI */
569 size += lcaf_hdr_parse (p + size, &lcaf);
571 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
574 size += sd_parse (p + size, a);
579 vni_parse (u8 * p, void * a)
582 gid_address_t * g = a;
585 gid_address_vni (g) = clib_net_to_host_u32 ( *(u32 *) p);
586 size += sizeof (u32);
587 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
589 /* nested LCAFs are not supported except of src/dst with vni - to handle
590 * such case look at the next AFI and process src/dest LCAF separately */
591 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
592 if (LISP_AFI_LCAF == afi)
594 u16 len = try_parse_src_dst_lcaf (p + size, g);
600 size += gid_address_parse (p + size, g);
606 no_addr_parse (u8 * p, void * a)
613 lcaf_parse (void * offset, gid_address_t *addr)
616 offset += sizeof (u16);
617 lcaf_t * lcaf = &gid_address_lcaf (addr);
619 u32 size = lcaf_hdr_parse (offset, lcaf);
620 u8 type = lcaf_type (lcaf);
622 if (!lcaf_parse_fcts[type])
624 clib_warning ("Unsupported LCAF type: %u", type);
627 size += (*lcaf_parse_fcts[type])(offset + size, lcaf);
628 return sizeof (u16) + size;
635 gid_address_free (vni_gid (v));
636 clib_mem_free (vni_gid (v));
640 no_addr_free (void * a)
652 gid_address_free (gid_address_t *a)
654 if (gid_address_type (a) != GID_ADDR_LCAF)
657 lcaf_t * lcaf = &gid_address_lcaf (a);
658 u8 lcaf_type = lcaf_type (lcaf);
659 (*lcaf_free_fcts[lcaf_type])(lcaf);
663 ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2)
666 if (ip_addr_version (ip1) != ip_addr_version(ip2))
668 res = memcmp (&ip_addr_addr(ip1), &ip_addr_addr(ip2), ip_address_size (ip1));
679 ip_address_copy (ip_address_t * dst , ip_address_t * src)
681 clib_memcpy (dst, src, sizeof (ip_address_t));
685 ip_address_copy_addr (void * dst , ip_address_t * src)
687 clib_memcpy (dst, src, ip_address_size(src));
691 ip_address_set(ip_address_t * dst, void * src, u8 version)
693 clib_memcpy(dst, src, ip_version_to_size(version));
694 ip_addr_version(dst) = version;
698 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
709 mask = pow2_mask (preflen) << (32 - preflen);
710 mask = clib_host_to_net_u32 (mask);
711 ip4->data_u32 &= mask;
715 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
723 memset (mask_6, 0, sizeof (mask_6));
732 m = (u32 * ) &mask_6[0];
734 for (j = 0; j < i0; j++)
741 m[i0] = clib_host_to_net_u32 (pow2_mask(i1) << (32 - i1));
744 for (j = 0; j < sizeof(mask_6); j++)
746 ip6->as_u8[j] &= mask_6[j];
751 ip_prefix_normalize(ip_prefix_t * a)
753 u8 preflen = ip_prefix_len(a);
755 switch (ip_prefix_version (a))
758 ip_prefix_normalize_ip4(&ip_prefix_v4(a), preflen);
762 ip_prefix_normalize_ip6(&ip_prefix_v6(a), preflen);
771 ip_prefix_cast (gid_address_t * a)
773 return &gid_address_ippref(a);
777 ip_prefix_size_to_write (void * pref)
779 ip_prefix_t *a = (ip_prefix_t *) pref;
780 return ip_address_size_to_write (&ip_prefix_addr (a));
784 ip_prefix_write (u8 * p, void * gid)
786 gid_address_t * g = gid;
787 ip_prefix_t *a = &gid_address_ippref (g);
789 switch (ip_prefix_version (a))
792 return ip4_address_put (p, &ip_prefix_v4 (a));
795 return ip6_address_put (p, &ip_prefix_v6 (a));
802 ip_prefix_length (void *a)
804 return ip_prefix_len((ip_prefix_t *) a);
808 ip_prefix_copy (void * dst , void * src)
810 clib_memcpy (dst, src, sizeof (ip_prefix_t));
814 mac_copy (void * dst , void * src)
816 clib_memcpy (dst, src, 6);
820 sd_copy (void * dst , void * src)
822 clib_memcpy (dst, src, sizeof (source_dest_t));
826 ip_prefix_cmp(ip_prefix_t * p1, ip_prefix_t * p2)
830 ip_prefix_normalize (p1);
831 ip_prefix_normalize (p2);
833 cmp = ip_address_cmp (&ip_prefix_addr(p1), &ip_prefix_addr(p2));
836 if (ip_prefix_len(p1) < ip_prefix_len(p2))
842 if (ip_prefix_len(p1) > ip_prefix_len(p2))
850 no_addr_copy (void * dst, void * src)
856 vni_copy (void * dst, void * src)
861 clib_memcpy (vd, vs, sizeof (vd[0]));
862 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
863 gid_address_copy (vni_gid (vd), vni_gid (vs));
867 lcaf_copy (void * dst , void * src)
869 lcaf_t * lcaf_dst = dst;
870 lcaf_t * lcaf_src = src;
872 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
873 (*lcaf_copy_fcts[lcaf_type (lcaf_src)])(dst, src);
877 lcaf_length (void *a)
888 u8 sd_length (void * a)
894 lcaf_cast (gid_address_t * a)
896 return &gid_address_lcaf (a);
900 mac_cast (gid_address_t * a)
902 return &gid_address_mac (a);
906 sd_cast (gid_address_t * a)
908 return &gid_address_sd (a);
912 no_addr_length (void * a)
918 vni_length (void * a)
921 return (sizeof (u32) /* VNI size */
922 + gid_address_size_to_put (vni_gid (v)) /* vni body size*/);
926 lcaf_write (u8 * p, void * a)
930 u8 type = lcaf_type (lcaf);
931 lcaf_hdr_t _h, *h = &_h;
933 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
934 size += sizeof (u16);
935 memset (h, 0, sizeof (h[0]));
936 LCAF_TYPE (h) = type;
937 u16 lcaf_len = (*lcaf_body_length_fcts[type])(lcaf);
938 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
940 clib_memcpy (p + size, h, sizeof (h[0]));
941 size += sizeof (h[0]);
942 len = (*lcaf_write_fcts[type])(p + size, lcaf);
951 mac_write (u8 * p, void * a)
953 *(u16 *)p = clib_host_to_net_u16 (LISP_AFI_MAC);
954 clib_memcpy(p + sizeof (u16), a, 6);
955 return mac_size_to_write (a);
959 fid_addr_write (u8 * p, fid_address_t * a)
961 switch (fid_addr_type (a))
963 case FID_ADDR_IP_PREF:
964 return ip_prefix_write (p, &fid_addr_ippref (a));
967 return mac_write (p, &fid_addr_mac (a));
976 fid_address_length (fid_address_t * a)
978 switch (fid_addr_type (a))
980 case FID_ADDR_IP_PREF:
981 return ip_prefix_length (&fid_addr_ippref (a));
989 sd_write (u8 * p, void * a)
991 source_dest_t * sd = a;
993 lcaf_hdr_t _h, *h = &_h;
994 lcaf_src_dst_hdr_t sd_hdr;
996 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
997 size += sizeof (u16);
998 memset (h, 0, sizeof (h[0]));
999 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1000 u16 lcaf_len = 4 + sizeof (lcaf_src_dst_hdr_t)
1001 + fid_addr_size_to_write (&sd_src (sd))
1002 + fid_addr_size_to_write (&sd_dst (sd));
1003 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1005 clib_memcpy (p + size, h, sizeof (h[0]));
1006 size += sizeof (h[0]);
1008 memset (&sd_hdr, 0, sizeof (sd_hdr));
1009 LCAF_SD_SRC_ML(&sd_hdr) = fid_address_length (&sd_src (sd));
1010 LCAF_SD_DST_ML(&sd_hdr) = fid_address_length (&sd_dst (sd));
1011 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1012 size += sizeof (sd_hdr);
1014 u16 len = fid_addr_write (p + size, &sd_src (sd));
1019 len = fid_addr_write (p + size, &sd_dst (sd));
1028 vni_write (u8 * p, void * a)
1030 lcaf_hdr_t _h, *h = &_h;
1031 gid_address_t * g = a;
1034 /* put lcaf header */
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) = LCAF_INSTANCE_ID;
1039 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1040 + gid_address_size_to_put_no_vni (g);
1041 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1042 LCAF_RES2 (h) = gid_address_vni_mask (g);
1044 /* put vni header */
1045 clib_memcpy (p + size, h, sizeof (h[0]));
1046 size += sizeof (h[0]);
1048 u32 * afip = (u32 *)(p + size);
1049 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1050 size += sizeof (u32);
1052 if (GID_ADDR_SRC_DST == gid_address_type (g))
1053 /* write src/dst LCAF */
1055 len = sd_write (p + size, g);
1060 /* write the actual address */
1061 len = gid_address_put_no_vni (p + size, g);
1070 no_addr_write (u8 * p, void * a)
1072 /* do nothing; return AFI field size */
1073 return sizeof (u16);
1077 no_addr_size_to_write (void * a)
1079 return sizeof (u16); /* AFI field length */
1083 fid_addr_size_to_write (fid_address_t * a)
1085 switch (fid_addr_type (a))
1087 case FID_ADDR_IP_PREF:
1088 return ip_prefix_size_to_write (a);
1091 return mac_size_to_write (a);
1100 vni_size_to_write (void * a)
1102 gid_address_t * g = a;
1104 u16 lcaf_size = sizeof (u32)
1105 + sizeof (u16) /* LCAF AFI field size */
1106 + sizeof (lcaf_hdr_t);
1108 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1109 /* special case where nested LCAF is supported */
1110 return lcaf_size + sd_size_to_write (g);
1113 + gid_address_size_to_put_no_vni (g);
1117 lcaf_size_to_write (void * a)
1119 lcaf_t * lcaf = (lcaf_t *) a;
1121 u8 type = lcaf_type (lcaf);
1123 size += sizeof (u16); /* AFI size */
1125 len = (*lcaf_size_to_write_fcts[type])(lcaf);
1133 sd_size_to_write (void * a)
1135 source_dest_t * sd = a;
1137 + sizeof (lcaf_hdr_t)
1138 + sizeof (lcaf_src_dst_hdr_t)
1139 + fid_addr_size_to_write (&sd_src (sd))
1140 + fid_addr_size_to_write (&sd_dst (sd));
1144 mac_size_to_write (void * a)
1146 return sizeof (u16) + 6;
1150 gid_address_len (gid_address_t *a)
1152 gid_address_type_t type = gid_address_type (a);
1153 return (*addr_len_fcts[type])((*cast_fcts[type])(a));
1157 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1159 gid_address_type_t type = gid_address_type (gid);
1160 return (*write_fcts[type])(b, (*cast_fcts[type])(gid));
1164 gid_address_put (u8 * b, gid_address_t * gid)
1166 if (0 != gid_address_vni (gid))
1167 return vni_write (b, gid);
1169 return gid_address_put_no_vni (b, gid);
1173 gid_address_size_to_put_no_vni (gid_address_t * gid)
1175 gid_address_type_t type = gid_address_type (gid);
1176 return (*size_to_write_fcts[type])((*cast_fcts[type])(gid));
1180 gid_address_size_to_put (gid_address_t * gid)
1182 if (0 != gid_address_vni (gid))
1183 return vni_size_to_write (gid);
1185 return gid_address_size_to_put_no_vni (gid);
1189 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1191 return (*cast_fcts[type])(gid);
1195 gid_address_copy(gid_address_t * dst, gid_address_t * src)
1197 gid_address_type_t type = gid_address_type(src);
1198 (*copy_fcts[type])((*cast_fcts[type])(dst), (*cast_fcts[type])(src));
1199 gid_address_type(dst) = type;
1200 gid_address_vni(dst) = gid_address_vni(src);
1201 gid_address_vni_mask(dst) = gid_address_vni_mask(src);
1205 mac_parse (u8 * offset, u8 * a)
1207 /* skip AFI field */
1208 offset += sizeof (u16);
1210 clib_memcpy (a, offset, 6);
1211 return sizeof (u16) + 6;
1215 gid_address_parse (u8 * offset, gid_address_t *a)
1223 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1224 * the gid address here */
1225 afi = clib_net_to_host_u16 (*((u16 *) offset));
1229 case LISP_AFI_NO_ADDR:
1231 gid_address_type(a) = GID_ADDR_NO_ADDRESS;
1234 len = ip_address_parse (offset, afi, &gid_address_ip(a));
1235 gid_address_type(a) = GID_ADDR_IP_PREFIX;
1236 /* this should be modified outside if needed*/
1237 gid_address_ippref_len(a) = 32;
1240 len = ip_address_parse (offset, afi, &gid_address_ip(a));
1241 gid_address_type(a) = GID_ADDR_IP_PREFIX;
1242 /* this should be modified outside if needed*/
1243 gid_address_ippref_len(a) = 128;
1246 gid_address_type(a) = GID_ADDR_LCAF;
1247 len = lcaf_parse (offset, a);
1250 len = mac_parse (offset, gid_address_mac (a));
1251 gid_address_type(a) = GID_ADDR_MAC;
1254 clib_warning("LISP AFI %d not supported!", afi);
1261 gid_address_ip_set(gid_address_t * dst, void * src, u8 version)
1263 ip_address_set (&gid_address_ip(dst), src, version);
1267 no_addr_cmp (void * a1, void * a2)
1273 vni_cmp (void * a1, void * a2)
1278 if (vni_mask_len (v1) != vni_mask_len (v2))
1280 if (vni_vni (v1) != vni_vni (v2))
1282 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1286 fid_addr_cmp (fid_address_t * a1,
1289 if (fid_addr_type (a1) != fid_addr_type (a2))
1292 switch (fid_addr_type (a1))
1294 case FID_ADDR_IP_PREF:
1295 return ip_prefix_cmp (&fid_addr_ippref (a1),
1296 &fid_addr_ippref (a2));
1299 return memcmp (&fid_addr_mac (a1),
1300 &fid_addr_mac (a2), 6);
1309 sd_cmp (void * a1, void * a2)
1311 source_dest_t * sd1 = a1;
1312 source_dest_t * sd2 = a2;
1314 if (fid_addr_cmp (&sd_dst(sd1), &sd_dst(sd2)))
1316 if (fid_addr_cmp (&sd_src(sd1), &sd_src(sd2)))
1321 /* Compare two gid_address_t.
1323 * -1: If they are from different afi
1324 * 0: Both address are the same
1325 * 1: Addr1 is bigger than addr2
1326 * 2: Addr2 is bigger than addr1
1329 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1331 lcaf_t * lcaf1, * lcaf2;
1335 if (gid_address_type(a1) != gid_address_type(a2))
1337 if (gid_address_vni(a1) != gid_address_vni(a2))
1339 if (gid_address_vni_mask(a1) != gid_address_vni_mask(a2))
1342 switch (gid_address_type(a1))
1344 case GID_ADDR_NO_ADDRESS:
1350 case GID_ADDR_IP_PREFIX:
1351 cmp = ip_prefix_cmp (&gid_address_ippref(a1), &gid_address_ippref(a2));
1354 lcaf1 = &gid_address_lcaf (a1);
1355 lcaf2 = &gid_address_lcaf (a2);
1356 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1357 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)])(lcaf1, lcaf2);
1360 cmp = memcmp (gid_address_mac (a1), gid_address_mac (a2),
1361 sizeof (gid_address_mac (a1)));
1364 case GID_ADDR_SRC_DST:
1365 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1375 locator_parse (void * b, locator_t * loc)
1378 u8 status = 1; /* locator up */
1382 if (!LOC_REACHABLE(h) && LOC_LOCAL(h))
1385 len = gid_address_parse (LOC_ADDR(h), &loc->address);
1389 loc->state = status;
1391 loc->priority = LOC_PRIORITY(h);
1392 loc->weight = LOC_WEIGHT(h);
1393 loc->mpriority = LOC_MPRIORITY(h);
1394 loc->mweight = LOC_MWEIGHT(h);
1396 return sizeof(locator_hdr_t) + len;
1400 locator_copy (locator_t * dst, locator_t * src)
1402 /* TODO if gid become more complex, this will need to be changed! */
1403 clib_memcpy (dst, src, sizeof(*dst));
1405 gid_address_copy (&dst->address, &src->address);
1409 locator_cmp (locator_t * l1, locator_t * l2)
1412 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1415 if (l1->priority != l2->priority)
1417 if (l1->weight != l2->weight)
1419 if (l1->mpriority != l2->mpriority)
1421 if (l1->mweight != l2->mweight)
1427 locator_free (locator_t * l)
1430 gid_address_free (&l->address);