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 *);
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;
162 format_ip_prefix (u8 * s, va_list * args)
164 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
165 return format (s, "%U/%d", format_ip_address, &ip_prefix_addr (a),
170 unformat_ip_prefix (unformat_input_t * input, va_list * args)
172 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
173 if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr (a),
176 if ((ip_prefix_version (a) == IP4 && 32 < ip_prefix_len (a)) ||
177 (ip_prefix_version (a) == IP6 && 128 < ip_prefix_length (a)))
179 clib_warning ("Prefix length to big: %d!", ip_prefix_len (a));
182 ip_prefix_normalize (a);
190 unformat_mac_address (unformat_input_t * input, va_list * args)
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],
198 format_mac_address (u8 * s, va_list * args)
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]);
206 format_fid_address (u8 * s, va_list * args)
208 fid_address_t *a = va_arg (*args, fid_address_t *);
210 switch (fid_addr_type (a))
212 case FID_ADDR_IP_PREF:
213 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
216 return format (s, "%U", format_mac_address, &fid_addr_mac (a));
219 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
226 format_gid_address (u8 * s, va_list * args)
228 gid_address_t *a = va_arg (*args, gid_address_t *);
229 u8 type = gid_address_type (a);
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));
240 return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
241 &gid_address_mac (a));
243 clib_warning ("Can't format gid type %d", type);
250 unformat_fid_address (unformat_input_t * i, va_list * args)
252 fid_address_t *a = va_arg (*args, fid_address_t *);
256 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
258 fid_addr_type (a) = FID_ADDR_IP_PREF;
259 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
261 else if (unformat (i, "%U", unformat_mac_address, mac))
263 fid_addr_type (a) = FID_ADDR_MAC;
264 mac_copy (fid_addr_mac (a), mac);
273 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
275 u32 *key_id = va_arg (*args, u32 *);
278 if (unformat (input, "%s", &s))
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;
286 clib_warning ("invalid key_id: '%s'", s);
287 key_id[0] = HMAC_NO_KEY;
298 unformat_gid_address (unformat_input_t * input, va_list * args)
300 gid_address_t *a = va_arg (*args, gid_address_t *);
303 fid_address_t sim1, sim2;
305 memset (&ippref, 0, sizeof (ippref));
306 memset (&sim1, 0, sizeof (sim1));
307 memset (&sim2, 0, sizeof (sim2));
309 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
310 unformat_fid_address, &sim2))
312 gid_address_sd_src (a) = sim1;
313 gid_address_sd_dst (a) = sim2;
314 gid_address_type (a) = GID_ADDR_SRC_DST;
316 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
318 ip_prefix_copy (&gid_address_ippref (a), &ippref);
319 gid_address_type (a) = GID_ADDR_IP_PREFIX;
321 else if (unformat (input, "%U", unformat_mac_address, mac))
323 mac_copy (gid_address_mac (a), mac);
324 gid_address_type (a) = GID_ADDR_MAC;
333 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
335 u32 *action = va_arg (*args, u32 *);
338 if (unformat (input, "%s", &s))
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;
350 clib_warning ("invalid action: '%s'", s);
351 action[0] = LISP_DROP;
362 format_hmac_key_id (u8 * s, va_list * args)
364 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
369 return format (0, "sha1");
370 case HMAC_SHA_256_128:
371 return format (0, "sha256");
380 format_negative_mapping_action (u8 * s, va_list * args)
382 lisp_action_e action = va_arg (*args, lisp_action_e);
387 s = format (s, "no-action");
389 case LISP_FORWARD_NATIVE:
390 s = format (s, "natively-forward");
392 case LISP_SEND_MAP_REQUEST:
393 s = format (s, "send-map-request");
397 s = format (s, "drop");
404 ip_address_size (const ip_address_t * a)
406 switch (ip_addr_version (a))
409 return sizeof (ip4_address_t);
412 return sizeof (ip6_address_t);
419 ip_version_to_size (u8 ver)
424 return sizeof (ip4_address_t);
427 return sizeof (ip6_address_t);
434 ip_version_to_max_plen (u8 ver)
448 always_inline lisp_afi_e
449 ip_version_to_iana_afi (u16 version)
464 ip_iana_afi_to_version (lisp_afi_e afi)
479 ip_address_size_to_write (ip_address_t * a)
481 return ip_address_size (a) + sizeof (u16);
485 ip_address_iana_afi (ip_address_t * a)
487 return ip_version_to_iana_afi (ip_addr_version (a));
491 ip_address_max_len (u8 version)
493 return version == IP4 ? 32 : 128;
497 ip4_address_size_to_put ()
499 // return sizeof(u16) + sizeof (ip4_address_t);
504 ip6_address_size_to_put ()
506 //return sizeof(u16) + sizeof (ip6_address_t);
511 ip4_address_put (u8 * b, ip4_address_t * a)
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 ();
520 ip6_address_put (u8 * b, ip6_address_t * a)
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 ();
529 ip_address_put (u8 * b, ip_address_t * a)
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));
539 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
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);
548 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
550 lcaf_hdr_t *lh = offset;
551 lcaf->type = lh->type;
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;
559 return sizeof (lh[0]);
563 iana_afi_to_fid_addr_type (u16 type)
569 return FID_ADDR_IP_PREF;
578 fid_addr_parse (u8 * p, fid_address_t * a)
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));
584 switch (fid_addr_type (a))
587 return mac_parse (p, fid_addr_mac (a));
589 case FID_ADDR_IP_PREF:
590 return ip_address_parse (p, afi, ip_addr);
596 sd_parse (u8 * p, void *a)
598 lcaf_src_dst_hdr_t *sd_hdr;
599 gid_address_t *g = a;
601 fid_address_t *src = &gid_address_sd_src (g);
602 fid_address_t *dst = &gid_address_sd_dst (g);
604 gid_address_type (g) = GID_ADDR_SRC_DST;
606 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
607 size += sizeof (sd_hdr[0]);
609 size += fid_addr_parse (p + size, src);
610 size += fid_addr_parse (p + size, dst);
612 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
614 ip_prefix_t *ippref = &fid_addr_ippref (src);
615 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
617 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
619 ip_prefix_t *ippref = &fid_addr_ippref (dst);
620 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
626 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
629 u16 size = sizeof (u16); /* skip AFI */
631 size += lcaf_hdr_parse (p + size, &lcaf);
633 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
636 size += sd_parse (p + size, a);
641 vni_parse (u8 * p, void *a)
644 gid_address_t *g = a;
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);
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)
656 u16 len = try_parse_src_dst_lcaf (p + size, g);
657 if ((u16) ~ 0 == len)
662 size += gid_address_parse (p + size, g);
668 no_addr_parse (u8 * p, void *a)
675 lcaf_parse (void *offset, gid_address_t * addr)
678 offset += sizeof (u16);
679 lcaf_t *lcaf = &gid_address_lcaf (addr);
681 u32 size = lcaf_hdr_parse (offset, lcaf);
682 u8 type = lcaf_type (lcaf);
684 if (!lcaf_parse_fcts[type])
686 clib_warning ("Unsupported LCAF type: %u", type);
689 size += (*lcaf_parse_fcts[type]) (offset + size, lcaf);
690 return sizeof (u16) + size;
697 gid_address_free (vni_gid (v));
698 clib_mem_free (vni_gid (v));
702 no_addr_free (void *a)
714 gid_address_free (gid_address_t * a)
716 if (gid_address_type (a) != GID_ADDR_LCAF)
719 lcaf_t *lcaf = &gid_address_lcaf (a);
720 u8 lcaf_type = lcaf_type (lcaf);
721 (*lcaf_free_fcts[lcaf_type]) (lcaf);
725 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
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;
733 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
736 if (ip_addr_version (ip1) != ip_addr_version (ip2))
739 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
750 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
752 if (IP4 == ip_addr_version (src))
754 /* don't copy any garbe from the union */
755 memset (dst, 0, sizeof (*dst));
756 dst->ip.v4 = src->ip.v4;
761 clib_memcpy (dst, src, sizeof (ip_address_t));
766 ip_address_copy_addr (void *dst, const ip_address_t * src)
768 clib_memcpy (dst, src, ip_address_size (src));
772 ip_address_set (ip_address_t * dst, const void *src, u8 version)
774 clib_memcpy (dst, src, ip_version_to_size (version));
775 ip_addr_version (dst) = version;
779 ip_address_to_46 (const ip_address_t * addr,
780 ip46_address_t * a, fib_protocol_t * proto)
782 *proto = (IP4 == ip_addr_version (addr) ?
783 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
786 case FIB_PROTOCOL_IP4:
787 ip46_address_set_ip4 (a, &addr->ip.v4);
789 case FIB_PROTOCOL_IP6:
790 a->ip6 = addr->ip.v6;
799 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
810 mask = pow2_mask (preflen) << (32 - preflen);
811 mask = clib_host_to_net_u32 (mask);
812 ip4->data_u32 &= mask;
816 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
824 memset (mask_6, 0, sizeof (mask_6));
833 m = (u32 *) & mask_6[0];
835 for (j = 0; j < i0; j++)
842 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
845 for (j = 0; j < sizeof (mask_6); j++)
847 ip6->as_u8[j] &= mask_6[j];
852 ip_prefix_normalize (ip_prefix_t * a)
854 u8 preflen = ip_prefix_len (a);
856 switch (ip_prefix_version (a))
859 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
863 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
872 ip_prefix_cast (gid_address_t * a)
874 return &gid_address_ippref (a);
878 ip_prefix_size_to_write (void *pref)
880 ip_prefix_t *a = (ip_prefix_t *) pref;
881 return ip_address_size_to_write (&ip_prefix_addr (a));
885 ip_prefix_write (u8 * p, void *gid)
887 gid_address_t *g = gid;
888 ip_prefix_t *a = &gid_address_ippref (g);
890 switch (ip_prefix_version (a))
893 return ip4_address_put (p, &ip_prefix_v4 (a));
896 return ip6_address_put (p, &ip_prefix_v6 (a));
903 ip_prefix_length (void *a)
905 return ip_prefix_len ((ip_prefix_t *) a);
909 ip_prefix_copy (void *dst, void *src)
911 clib_memcpy (dst, src, sizeof (ip_prefix_t));
915 mac_copy (void *dst, void *src)
917 clib_memcpy (dst, src, 6);
921 sd_copy (void *dst, void *src)
923 clib_memcpy (dst, src, sizeof (source_dest_t));
927 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
931 ip_prefix_normalize (p1);
932 ip_prefix_normalize (p2);
934 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
937 if (ip_prefix_len (p1) < ip_prefix_len (p2))
943 if (ip_prefix_len (p1) > ip_prefix_len (p2))
951 no_addr_copy (void *dst, void *src)
957 vni_copy (void *dst, void *src)
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));
968 lcaf_copy (void *dst, void *src)
970 lcaf_t *lcaf_dst = dst;
971 lcaf_t *lcaf_src = src;
973 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
974 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
978 lcaf_length (void *a)
996 lcaf_cast (gid_address_t * a)
998 return &gid_address_lcaf (a);
1002 mac_cast (gid_address_t * a)
1004 return &gid_address_mac (a);
1008 sd_cast (gid_address_t * a)
1010 return &gid_address_sd (a);
1014 no_addr_length (void *a)
1020 vni_length (void *a)
1023 return (sizeof (u32) /* VNI size */
1024 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1028 lcaf_write (u8 * p, void *a)
1032 u8 type = lcaf_type (lcaf);
1033 lcaf_hdr_t _h, *h = &_h;
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);
1042 clib_memcpy (p + size, h, sizeof (h[0]));
1043 size += sizeof (h[0]);
1044 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1046 if ((u16) ~ 0 == len)
1053 mac_write (u8 * p, void *a)
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);
1061 fid_addr_write (u8 * p, fid_address_t * a)
1063 switch (fid_addr_type (a))
1065 case FID_ADDR_IP_PREF:
1066 return ip_prefix_write (p, &fid_addr_ippref (a));
1069 return mac_write (p, &fid_addr_mac (a));
1078 fid_address_length (fid_address_t * a)
1080 switch (fid_addr_type (a))
1082 case FID_ADDR_IP_PREF:
1083 return ip_prefix_length (&fid_addr_ippref (a));
1091 sd_write (u8 * p, void *a)
1093 source_dest_t *sd = a;
1095 lcaf_hdr_t _h, *h = &_h;
1096 lcaf_src_dst_hdr_t sd_hdr;
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);
1107 clib_memcpy (p + size, h, sizeof (h[0]));
1108 size += sizeof (h[0]);
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);
1116 u16 len = fid_addr_write (p + size, &sd_src (sd));
1117 if ((u16) ~ 0 == len)
1121 len = fid_addr_write (p + size, &sd_dst (sd));
1122 if ((u16) ~ 0 == len)
1130 vni_write (u8 * p, void *a)
1132 lcaf_hdr_t _h, *h = &_h;
1133 gid_address_t *g = a;
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);
1146 /* put vni header */
1147 clib_memcpy (p + size, h, sizeof (h[0]));
1148 size += sizeof (h[0]);
1150 u32 *afip = (u32 *) (p + size);
1151 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1152 size += sizeof (u32);
1154 if (GID_ADDR_SRC_DST == gid_address_type (g))
1155 /* write src/dst LCAF */
1157 len = sd_write (p + size, g);
1158 if ((u16) ~ 0 == len)
1162 /* write the actual address */
1163 len = gid_address_put_no_vni (p + size, g);
1165 if ((u16) ~ 0 == len)
1172 no_addr_write (u8 * p, void *a)
1174 /* do nothing; return AFI field size */
1175 return sizeof (u16);
1179 no_addr_size_to_write (void *a)
1181 return sizeof (u16); /* AFI field length */
1185 fid_addr_size_to_write (fid_address_t * a)
1187 switch (fid_addr_type (a))
1189 case FID_ADDR_IP_PREF:
1190 return ip_prefix_size_to_write (a);
1193 return mac_size_to_write (a);
1202 vni_size_to_write (void *a)
1204 gid_address_t *g = a;
1206 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1207 + sizeof (lcaf_hdr_t);
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);
1213 return lcaf_size + gid_address_size_to_put_no_vni (g);
1217 lcaf_size_to_write (void *a)
1219 lcaf_t *lcaf = (lcaf_t *) a;
1221 u8 type = lcaf_type (lcaf);
1223 size += sizeof (u16); /* AFI size */
1225 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1233 sd_size_to_write (void *a)
1235 source_dest_t *sd = a;
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));
1244 mac_size_to_write (void *a)
1246 return sizeof (u16) + 6;
1250 gid_address_len (gid_address_t * a)
1252 gid_address_type_t type = gid_address_type (a);
1253 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1257 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1259 gid_address_type_t type = gid_address_type (gid);
1260 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1264 gid_address_put (u8 * b, gid_address_t * gid)
1266 if (0 != gid_address_vni (gid))
1267 return vni_write (b, gid);
1269 return gid_address_put_no_vni (b, gid);
1273 gid_address_size_to_put_no_vni (gid_address_t * gid)
1275 gid_address_type_t type = gid_address_type (gid);
1276 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1280 gid_address_size_to_put (gid_address_t * gid)
1282 if (0 != gid_address_vni (gid))
1283 return vni_size_to_write (gid);
1285 return gid_address_size_to_put_no_vni (gid);
1289 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1291 return (*cast_fcts[type]) (gid);
1295 gid_address_copy (gid_address_t * dst, gid_address_t * src)
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);
1305 mac_parse (u8 * offset, u8 * a)
1307 /* skip AFI field */
1308 offset += sizeof (u16);
1310 clib_memcpy (a, offset, 6);
1311 return sizeof (u16) + 6;
1315 gid_address_parse (u8 * offset, gid_address_t * a)
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));
1329 case LISP_AFI_NO_ADDR:
1331 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
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;
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;
1346 gid_address_type (a) = GID_ADDR_LCAF;
1347 len = lcaf_parse (offset, a);
1350 len = mac_parse (offset, gid_address_mac (a));
1351 gid_address_type (a) = GID_ADDR_MAC;
1354 clib_warning ("LISP AFI %d not supported!", afi);
1361 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1363 gid_address_ippref_len (dst) = ip_address_max_len (version);
1364 ip_address_set (&gid_address_ip (dst), src, version);
1368 no_addr_cmp (void *a1, void *a2)
1374 vni_cmp (void *a1, void *a2)
1379 if (vni_mask_len (v1) != vni_mask_len (v2))
1381 if (vni_vni (v1) != vni_vni (v2))
1383 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1387 mac_cmp (void *a1, void *a2)
1389 return memcmp (a1, a2, 6);
1393 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1395 if (fid_addr_type (a1) != fid_addr_type (a2))
1398 switch (fid_addr_type (a1))
1400 case FID_ADDR_IP_PREF:
1401 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1404 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1413 sd_cmp (void *a1, void *a2)
1415 source_dest_t *sd1 = a1;
1416 source_dest_t *sd2 = a2;
1418 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1420 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1425 /* Compare two gid_address_t.
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
1433 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1435 lcaf_t *lcaf1, *lcaf2;
1439 if (gid_address_type (a1) != gid_address_type (a2))
1441 if (gid_address_vni (a1) != gid_address_vni (a2))
1443 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1446 switch (gid_address_type (a1))
1448 case GID_ADDR_NO_ADDRESS:
1454 case GID_ADDR_IP_PREFIX:
1456 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
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);
1465 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1468 case GID_ADDR_SRC_DST:
1469 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1479 locator_parse (void *b, locator_t * loc)
1482 u8 status = 1; /* locator up */
1486 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1489 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1493 loc->state = status;
1495 loc->priority = LOC_PRIORITY (h);
1496 loc->weight = LOC_WEIGHT (h);
1497 loc->mpriority = LOC_MPRIORITY (h);
1498 loc->mweight = LOC_MWEIGHT (h);
1500 return sizeof (locator_hdr_t) + len;
1504 locator_copy (locator_t * dst, locator_t * src)
1506 /* TODO if gid become more complex, this will need to be changed! */
1507 clib_memcpy (dst, src, sizeof (*dst));
1509 gid_address_copy (&dst->address, &src->address);
1513 locator_cmp (locator_t * l1, locator_t * l2)
1516 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1519 if (l1->priority != l2->priority)
1521 if (l1->weight != l2->weight)
1523 if (l1->mpriority != l2->mpriority)
1525 if (l1->mweight != l2->mweight)
1531 locator_free (locator_t * l)
1534 gid_address_free (&l->address);
1538 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
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);
1545 switch (gid_address_type (dst))
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));
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));
1562 clib_warning ("Unsupported gid type %d while conversion!",
1563 gid_address_type (dst));
1569 * fd.io coding-style-patch-verification: ON
1572 * eval: (c-set-style "gnu")