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_ip_prefix, &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_gid_address (unformat_input_t * input, va_list * args)
275 gid_address_t *a = va_arg (*args, gid_address_t *);
278 fid_address_t sim1, sim2;
280 memset (&ippref, 0, sizeof (ippref));
281 memset (&sim1, 0, sizeof (sim1));
282 memset (&sim2, 0, sizeof (sim2));
284 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
285 unformat_fid_address, &sim2))
287 gid_address_sd_src (a) = sim1;
288 gid_address_sd_dst (a) = sim2;
289 gid_address_type (a) = GID_ADDR_SRC_DST;
291 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
293 ip_prefix_copy (&gid_address_ippref (a), &ippref);
294 gid_address_type (a) = GID_ADDR_IP_PREFIX;
296 else if (unformat (input, "%U", unformat_mac_address, mac))
298 mac_copy (gid_address_mac (a), mac);
299 gid_address_type (a) = GID_ADDR_MAC;
308 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
310 u32 *action = va_arg (*args, u32 *);
313 if (unformat (input, "%s", &s))
315 if (!strcmp ((char *) s, "no-action"))
316 action[0] = LISP_NO_ACTION;
317 else if (!strcmp ((char *) s, "natively-forward"))
318 action[0] = LISP_FORWARD_NATIVE;
319 else if (!strcmp ((char *) s, "send-map-request"))
320 action[0] = LISP_SEND_MAP_REQUEST;
321 else if (!strcmp ((char *) s, "drop"))
322 action[0] = LISP_DROP;
325 clib_warning ("invalid action: '%s'", s);
326 action[0] = LISP_DROP;
337 format_negative_mapping_action (u8 * s, va_list * args)
339 lisp_action_e action = va_arg (*args, lisp_action_e);
344 s = format (s, "no-action");
346 case LISP_FORWARD_NATIVE:
347 s = format (s, "natively-forward");
349 case LISP_SEND_MAP_REQUEST:
350 s = format (s, "send-map-request");
354 s = format (s, "drop");
361 ip_address_size (const ip_address_t * a)
363 switch (ip_addr_version (a))
366 return sizeof (ip4_address_t);
369 return sizeof (ip6_address_t);
376 ip_version_to_size (u8 ver)
381 return sizeof (ip4_address_t);
384 return sizeof (ip6_address_t);
391 ip_version_to_max_plen (u8 ver)
405 always_inline lisp_afi_e
406 ip_version_to_iana_afi (u16 version)
421 ip_iana_afi_to_version (lisp_afi_e afi)
436 ip_address_size_to_write (ip_address_t * a)
438 return ip_address_size (a) + sizeof (u16);
442 ip_address_iana_afi (ip_address_t * a)
444 return ip_version_to_iana_afi (ip_addr_version (a));
448 ip_address_max_len (u8 version)
450 return version == IP4 ? 32 : 128;
454 ip4_address_size_to_put ()
456 // return sizeof(u16) + sizeof (ip4_address_t);
461 ip6_address_size_to_put ()
463 //return sizeof(u16) + sizeof (ip6_address_t);
468 ip4_address_put (u8 * b, ip4_address_t * a)
470 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
471 u8 *p = b + sizeof (u16);
472 clib_memcpy (p, a, sizeof (*a));
473 return ip4_address_size_to_put ();
477 ip6_address_put (u8 * b, ip6_address_t * a)
479 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
480 u8 *p = b + sizeof (u16);
481 clib_memcpy (p, a, sizeof (*a));
482 return ip6_address_size_to_put ();
486 ip_address_put (u8 * b, ip_address_t * a)
488 u32 len = ip_address_size (a);
489 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
490 u8 *p = b + sizeof (u16);
491 clib_memcpy (p, &ip_addr_addr (a), len);
492 return (len + sizeof (u16));
496 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
498 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
499 u8 size = ip_version_to_size (ip_addr_version (dst));
500 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
501 return (sizeof (u16) + size);
505 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
507 lcaf_hdr_t *lh = offset;
508 lcaf->type = lh->type;
510 /* this is a bit of hack: since the LCAF Instance ID is the
511 only message that uses reserved2 field, we can set it here.
512 If any LCAF format starts using reserved2 field as well this needs
513 to be moved elsewhere */
514 lcaf_vni_len (lcaf) = lh->reserved2;
516 return sizeof (lh[0]);
520 iana_afi_to_fid_addr_type (u16 type)
526 return FID_ADDR_IP_PREF;
535 fid_addr_parse (u8 * p, fid_address_t * a)
537 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
538 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
539 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
541 switch (fid_addr_type (a))
544 return mac_parse (p, fid_addr_mac (a));
546 case FID_ADDR_IP_PREF:
547 return ip_address_parse (p, afi, ip_addr);
553 sd_parse (u8 * p, void *a)
555 lcaf_src_dst_hdr_t *sd_hdr;
556 gid_address_t *g = a;
558 fid_address_t *src = &gid_address_sd_src (g);
559 fid_address_t *dst = &gid_address_sd_dst (g);
561 gid_address_type (g) = GID_ADDR_SRC_DST;
563 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
564 size += sizeof (sd_hdr[0]);
566 size += fid_addr_parse (p + size, src);
567 size += fid_addr_parse (p + size, dst);
569 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
571 ip_prefix_t *ippref = &fid_addr_ippref (src);
572 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
574 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
576 ip_prefix_t *ippref = &fid_addr_ippref (dst);
577 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
583 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
586 u16 size = sizeof (u16); /* skip AFI */
588 size += lcaf_hdr_parse (p + size, &lcaf);
590 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
593 size += sd_parse (p + size, a);
598 vni_parse (u8 * p, void *a)
601 gid_address_t *g = a;
604 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
605 size += sizeof (u32);
606 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
608 /* nested LCAFs are not supported except of src/dst with vni - to handle
609 * such case look at the next AFI and process src/dest LCAF separately */
610 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
611 if (LISP_AFI_LCAF == afi)
613 u16 len = try_parse_src_dst_lcaf (p + size, g);
614 if ((u16) ~ 0 == len)
619 size += gid_address_parse (p + size, g);
625 no_addr_parse (u8 * p, void *a)
632 lcaf_parse (void *offset, gid_address_t * addr)
635 offset += sizeof (u16);
636 lcaf_t *lcaf = &gid_address_lcaf (addr);
638 u32 size = lcaf_hdr_parse (offset, lcaf);
639 u8 type = lcaf_type (lcaf);
641 if (!lcaf_parse_fcts[type])
643 clib_warning ("Unsupported LCAF type: %u", type);
646 size += (*lcaf_parse_fcts[type]) (offset + size, lcaf);
647 return sizeof (u16) + size;
654 gid_address_free (vni_gid (v));
655 clib_mem_free (vni_gid (v));
659 no_addr_free (void *a)
671 gid_address_free (gid_address_t * a)
673 if (gid_address_type (a) != GID_ADDR_LCAF)
676 lcaf_t *lcaf = &gid_address_lcaf (a);
677 u8 lcaf_type = lcaf_type (lcaf);
678 (*lcaf_free_fcts[lcaf_type]) (lcaf);
682 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
685 if (ip_addr_version (ip1) != ip_addr_version (ip2))
688 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
699 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
701 clib_memcpy (dst, src, sizeof (ip_address_t));
705 ip_address_copy_addr (void *dst, const ip_address_t * src)
707 clib_memcpy (dst, src, ip_address_size (src));
711 ip_address_set (ip_address_t * dst, const void *src, u8 version)
713 clib_memcpy (dst, src, ip_version_to_size (version));
714 ip_addr_version (dst) = version;
718 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
729 mask = pow2_mask (preflen) << (32 - preflen);
730 mask = clib_host_to_net_u32 (mask);
731 ip4->data_u32 &= mask;
735 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
743 memset (mask_6, 0, sizeof (mask_6));
752 m = (u32 *) & mask_6[0];
754 for (j = 0; j < i0; j++)
761 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
764 for (j = 0; j < sizeof (mask_6); j++)
766 ip6->as_u8[j] &= mask_6[j];
771 ip_prefix_normalize (ip_prefix_t * a)
773 u8 preflen = ip_prefix_len (a);
775 switch (ip_prefix_version (a))
778 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
782 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
791 ip_prefix_cast (gid_address_t * a)
793 return &gid_address_ippref (a);
797 ip_prefix_size_to_write (void *pref)
799 ip_prefix_t *a = (ip_prefix_t *) pref;
800 return ip_address_size_to_write (&ip_prefix_addr (a));
804 ip_prefix_write (u8 * p, void *gid)
806 gid_address_t *g = gid;
807 ip_prefix_t *a = &gid_address_ippref (g);
809 switch (ip_prefix_version (a))
812 return ip4_address_put (p, &ip_prefix_v4 (a));
815 return ip6_address_put (p, &ip_prefix_v6 (a));
822 ip_prefix_length (void *a)
824 return ip_prefix_len ((ip_prefix_t *) a);
828 ip_prefix_copy (void *dst, void *src)
830 clib_memcpy (dst, src, sizeof (ip_prefix_t));
834 mac_copy (void *dst, void *src)
836 clib_memcpy (dst, src, 6);
840 sd_copy (void *dst, void *src)
842 clib_memcpy (dst, src, sizeof (source_dest_t));
846 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
850 ip_prefix_normalize (p1);
851 ip_prefix_normalize (p2);
853 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
856 if (ip_prefix_len (p1) < ip_prefix_len (p2))
862 if (ip_prefix_len (p1) > ip_prefix_len (p2))
870 no_addr_copy (void *dst, void *src)
876 vni_copy (void *dst, void *src)
881 clib_memcpy (vd, vs, sizeof (vd[0]));
882 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
883 gid_address_copy (vni_gid (vd), vni_gid (vs));
887 lcaf_copy (void *dst, void *src)
889 lcaf_t *lcaf_dst = dst;
890 lcaf_t *lcaf_src = src;
892 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
893 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
897 lcaf_length (void *a)
915 lcaf_cast (gid_address_t * a)
917 return &gid_address_lcaf (a);
921 mac_cast (gid_address_t * a)
923 return &gid_address_mac (a);
927 sd_cast (gid_address_t * a)
929 return &gid_address_sd (a);
933 no_addr_length (void *a)
942 return (sizeof (u32) /* VNI size */
943 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
947 lcaf_write (u8 * p, void *a)
951 u8 type = lcaf_type (lcaf);
952 lcaf_hdr_t _h, *h = &_h;
954 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
955 size += sizeof (u16);
956 memset (h, 0, sizeof (h[0]));
957 LCAF_TYPE (h) = type;
958 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
959 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
961 clib_memcpy (p + size, h, sizeof (h[0]));
962 size += sizeof (h[0]);
963 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
965 if ((u16) ~ 0 == len)
972 mac_write (u8 * p, void *a)
974 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
975 clib_memcpy (p + sizeof (u16), a, 6);
976 return mac_size_to_write (a);
980 fid_addr_write (u8 * p, fid_address_t * a)
982 switch (fid_addr_type (a))
984 case FID_ADDR_IP_PREF:
985 return ip_prefix_write (p, &fid_addr_ippref (a));
988 return mac_write (p, &fid_addr_mac (a));
997 fid_address_length (fid_address_t * a)
999 switch (fid_addr_type (a))
1001 case FID_ADDR_IP_PREF:
1002 return ip_prefix_length (&fid_addr_ippref (a));
1010 sd_write (u8 * p, void *a)
1012 source_dest_t *sd = a;
1014 lcaf_hdr_t _h, *h = &_h;
1015 lcaf_src_dst_hdr_t sd_hdr;
1017 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1018 size += sizeof (u16);
1019 memset (h, 0, sizeof (h[0]));
1020 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1021 u16 lcaf_len = 4 + sizeof (lcaf_src_dst_hdr_t)
1022 + fid_addr_size_to_write (&sd_src (sd))
1023 + fid_addr_size_to_write (&sd_dst (sd));
1024 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1026 clib_memcpy (p + size, h, sizeof (h[0]));
1027 size += sizeof (h[0]);
1029 memset (&sd_hdr, 0, sizeof (sd_hdr));
1030 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1031 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1032 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1033 size += sizeof (sd_hdr);
1035 u16 len = fid_addr_write (p + size, &sd_src (sd));
1036 if ((u16) ~ 0 == len)
1040 len = fid_addr_write (p + size, &sd_dst (sd));
1041 if ((u16) ~ 0 == len)
1049 vni_write (u8 * p, void *a)
1051 lcaf_hdr_t _h, *h = &_h;
1052 gid_address_t *g = a;
1055 /* put lcaf header */
1056 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1057 size += sizeof (u16);
1058 memset (h, 0, sizeof (h[0]));
1059 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1060 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1061 + gid_address_size_to_put_no_vni (g);
1062 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1063 LCAF_RES2 (h) = gid_address_vni_mask (g);
1065 /* put vni header */
1066 clib_memcpy (p + size, h, sizeof (h[0]));
1067 size += sizeof (h[0]);
1069 u32 *afip = (u32 *) (p + size);
1070 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1071 size += sizeof (u32);
1073 if (GID_ADDR_SRC_DST == gid_address_type (g))
1074 /* write src/dst LCAF */
1076 len = sd_write (p + size, g);
1077 if ((u16) ~ 0 == len)
1081 /* write the actual address */
1082 len = gid_address_put_no_vni (p + size, g);
1084 if ((u16) ~ 0 == len)
1091 no_addr_write (u8 * p, void *a)
1093 /* do nothing; return AFI field size */
1094 return sizeof (u16);
1098 no_addr_size_to_write (void *a)
1100 return sizeof (u16); /* AFI field length */
1104 fid_addr_size_to_write (fid_address_t * a)
1106 switch (fid_addr_type (a))
1108 case FID_ADDR_IP_PREF:
1109 return ip_prefix_size_to_write (a);
1112 return mac_size_to_write (a);
1121 vni_size_to_write (void *a)
1123 gid_address_t *g = a;
1125 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1126 + sizeof (lcaf_hdr_t);
1128 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1129 /* special case where nested LCAF is supported */
1130 return lcaf_size + sd_size_to_write (g);
1132 return lcaf_size + gid_address_size_to_put_no_vni (g);
1136 lcaf_size_to_write (void *a)
1138 lcaf_t *lcaf = (lcaf_t *) a;
1140 u8 type = lcaf_type (lcaf);
1142 size += sizeof (u16); /* AFI size */
1144 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1152 sd_size_to_write (void *a)
1154 source_dest_t *sd = a;
1156 + sizeof (lcaf_hdr_t)
1157 + sizeof (lcaf_src_dst_hdr_t)
1158 + fid_addr_size_to_write (&sd_src (sd))
1159 + fid_addr_size_to_write (&sd_dst (sd));
1163 mac_size_to_write (void *a)
1165 return sizeof (u16) + 6;
1169 gid_address_len (gid_address_t * a)
1171 gid_address_type_t type = gid_address_type (a);
1172 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1176 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1178 gid_address_type_t type = gid_address_type (gid);
1179 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1183 gid_address_put (u8 * b, gid_address_t * gid)
1185 if (0 != gid_address_vni (gid))
1186 return vni_write (b, gid);
1188 return gid_address_put_no_vni (b, gid);
1192 gid_address_size_to_put_no_vni (gid_address_t * gid)
1194 gid_address_type_t type = gid_address_type (gid);
1195 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1199 gid_address_size_to_put (gid_address_t * gid)
1201 if (0 != gid_address_vni (gid))
1202 return vni_size_to_write (gid);
1204 return gid_address_size_to_put_no_vni (gid);
1208 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1210 return (*cast_fcts[type]) (gid);
1214 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1216 gid_address_type_t type = gid_address_type (src);
1217 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1218 gid_address_type (dst) = type;
1219 gid_address_vni (dst) = gid_address_vni (src);
1220 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1224 mac_parse (u8 * offset, u8 * a)
1226 /* skip AFI field */
1227 offset += sizeof (u16);
1229 clib_memcpy (a, offset, 6);
1230 return sizeof (u16) + 6;
1234 gid_address_parse (u8 * offset, gid_address_t * a)
1242 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1243 * the gid address here */
1244 afi = clib_net_to_host_u16 (*((u16 *) offset));
1248 case LISP_AFI_NO_ADDR:
1250 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1253 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1254 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1255 /* this should be modified outside if needed */
1256 gid_address_ippref_len (a) = 32;
1259 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1260 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1261 /* this should be modified outside if needed */
1262 gid_address_ippref_len (a) = 128;
1265 gid_address_type (a) = GID_ADDR_LCAF;
1266 len = lcaf_parse (offset, a);
1269 len = mac_parse (offset, gid_address_mac (a));
1270 gid_address_type (a) = GID_ADDR_MAC;
1273 clib_warning ("LISP AFI %d not supported!", afi);
1280 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1282 gid_address_ippref_len (dst) = ip_address_max_len (version);
1283 ip_address_set (&gid_address_ip (dst), src, version);
1287 no_addr_cmp (void *a1, void *a2)
1293 vni_cmp (void *a1, void *a2)
1298 if (vni_mask_len (v1) != vni_mask_len (v2))
1300 if (vni_vni (v1) != vni_vni (v2))
1302 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1306 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1308 if (fid_addr_type (a1) != fid_addr_type (a2))
1311 switch (fid_addr_type (a1))
1313 case FID_ADDR_IP_PREF:
1314 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1317 return memcmp (&fid_addr_mac (a1), &fid_addr_mac (a2), 6);
1326 sd_cmp (void *a1, void *a2)
1328 source_dest_t *sd1 = a1;
1329 source_dest_t *sd2 = a2;
1331 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1333 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1338 /* Compare two gid_address_t.
1340 * -1: If they are from different afi
1341 * 0: Both address are the same
1342 * 1: Addr1 is bigger than addr2
1343 * 2: Addr2 is bigger than addr1
1346 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1348 lcaf_t *lcaf1, *lcaf2;
1352 if (gid_address_type (a1) != gid_address_type (a2))
1354 if (gid_address_vni (a1) != gid_address_vni (a2))
1356 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1359 switch (gid_address_type (a1))
1361 case GID_ADDR_NO_ADDRESS:
1367 case GID_ADDR_IP_PREFIX:
1369 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1372 lcaf1 = &gid_address_lcaf (a1);
1373 lcaf2 = &gid_address_lcaf (a2);
1374 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1375 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1378 cmp = memcmp (gid_address_mac (a1), gid_address_mac (a2),
1379 sizeof (gid_address_mac (a1)));
1382 case GID_ADDR_SRC_DST:
1383 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1393 locator_parse (void *b, locator_t * loc)
1396 u8 status = 1; /* locator up */
1400 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1403 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1407 loc->state = status;
1409 loc->priority = LOC_PRIORITY (h);
1410 loc->weight = LOC_WEIGHT (h);
1411 loc->mpriority = LOC_MPRIORITY (h);
1412 loc->mweight = LOC_MWEIGHT (h);
1414 return sizeof (locator_hdr_t) + len;
1418 locator_copy (locator_t * dst, locator_t * src)
1420 /* TODO if gid become more complex, this will need to be changed! */
1421 clib_memcpy (dst, src, sizeof (*dst));
1423 gid_address_copy (&dst->address, &src->address);
1427 locator_cmp (locator_t * l1, locator_t * l2)
1430 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1433 if (l1->priority != l2->priority)
1435 if (l1->weight != l2->weight)
1437 if (l1->mpriority != l2->mpriority)
1439 if (l1->mweight != l2->mweight)
1445 locator_free (locator_t * l)
1448 gid_address_free (&l->address);
1452 * fd.io coding-style-patch-verification: ON
1455 * eval: (c-set-style "gnu")