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 unformat_nsh_address (unformat_input_t * input, va_list * args)
208 nsh_t *a = va_arg (*args, nsh_t *);
209 return unformat (input, "SPI:%d SI:%d", &a->spi, &a->si);
213 format_nsh_address (u8 * s, va_list * args)
215 nsh_t *a = va_arg (*args, nsh_t *);
216 return format (s, "SPI:%d SI:%d", a->spi, a->si);
220 format_fid_address (u8 * s, va_list * args)
222 fid_address_t *a = va_arg (*args, fid_address_t *);
224 switch (fid_addr_type (a))
226 case FID_ADDR_IP_PREF:
227 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
229 return format (s, "%U", format_mac_address, &fid_addr_mac (a));
231 return format (s, "%U", format_nsh_address, &fid_addr_nsh (a));
234 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
241 format_gid_address (u8 * s, va_list * args)
243 gid_address_t *a = va_arg (*args, gid_address_t *);
244 u8 type = gid_address_type (a);
247 case GID_ADDR_IP_PREFIX:
248 return format (s, "[%d] %U", gid_address_vni (a), format_ip_prefix,
249 &gid_address_ippref (a));
250 case GID_ADDR_SRC_DST:
251 return format (s, "[%d] %U|%U", gid_address_vni (a),
252 format_fid_address, &gid_address_sd_src (a),
253 format_fid_address, &gid_address_sd_dst (a));
255 return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
256 &gid_address_mac (a));
258 return format (s, "%U", format_nsh_address, &gid_address_nsh (a));
260 clib_warning ("Can't format gid type %d", type);
267 unformat_fid_address (unformat_input_t * i, va_list * args)
269 fid_address_t *a = va_arg (*args, fid_address_t *);
274 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
276 fid_addr_type (a) = FID_ADDR_IP_PREF;
277 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
279 else if (unformat (i, "%U", unformat_mac_address, mac))
281 fid_addr_type (a) = FID_ADDR_MAC;
282 mac_copy (fid_addr_mac (a), mac);
284 else if (unformat (i, "%U", unformat_nsh_address, &nsh))
286 fid_addr_type (a) = FID_ADDR_NSH;
287 nsh_copy (&fid_addr_nsh (a), mac);
296 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
298 u32 *key_id = va_arg (*args, u32 *);
301 if (unformat (input, "%s", &s))
303 if (!strcmp ((char *) s, "sha1"))
304 key_id[0] = HMAC_SHA_1_96;
305 else if (!strcmp ((char *) s, "sha256"))
306 key_id[0] = HMAC_SHA_256_128;
309 clib_warning ("invalid key_id: '%s'", s);
310 key_id[0] = HMAC_NO_KEY;
321 unformat_gid_address (unformat_input_t * input, va_list * args)
323 gid_address_t *a = va_arg (*args, gid_address_t *);
326 fid_address_t sim1, sim2;
329 memset (&ippref, 0, sizeof (ippref));
330 memset (&sim1, 0, sizeof (sim1));
331 memset (&sim2, 0, sizeof (sim2));
333 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
334 unformat_fid_address, &sim2))
336 gid_address_sd_src (a) = sim1;
337 gid_address_sd_dst (a) = sim2;
338 gid_address_type (a) = GID_ADDR_SRC_DST;
340 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
342 ip_prefix_copy (&gid_address_ippref (a), &ippref);
343 gid_address_type (a) = GID_ADDR_IP_PREFIX;
345 else if (unformat (input, "%U", unformat_mac_address, mac))
347 mac_copy (gid_address_mac (a), mac);
348 gid_address_type (a) = GID_ADDR_MAC;
350 else if (unformat (input, "%U", unformat_nsh_address, &nsh))
352 nsh_copy (&gid_address_nsh (a), &nsh);
353 gid_address_type (a) = GID_ADDR_NSH;
362 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
364 u32 *action = va_arg (*args, u32 *);
367 if (unformat (input, "%s", &s))
369 if (!strcmp ((char *) s, "no-action"))
370 action[0] = LISP_NO_ACTION;
371 else if (!strcmp ((char *) s, "natively-forward"))
372 action[0] = LISP_FORWARD_NATIVE;
373 else if (!strcmp ((char *) s, "send-map-request"))
374 action[0] = LISP_SEND_MAP_REQUEST;
375 else if (!strcmp ((char *) s, "drop"))
376 action[0] = LISP_DROP;
379 clib_warning ("invalid action: '%s'", s);
380 action[0] = LISP_DROP;
391 format_hmac_key_id (u8 * s, va_list * args)
393 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
398 return format (0, "sha1");
399 case HMAC_SHA_256_128:
400 return format (0, "sha256");
409 format_negative_mapping_action (u8 * s, va_list * args)
411 lisp_action_e action = va_arg (*args, lisp_action_e);
416 s = format (s, "no-action");
418 case LISP_FORWARD_NATIVE:
419 s = format (s, "natively-forward");
421 case LISP_SEND_MAP_REQUEST:
422 s = format (s, "send-map-request");
426 s = format (s, "drop");
433 ip_address_size (const ip_address_t * a)
435 switch (ip_addr_version (a))
438 return sizeof (ip4_address_t);
441 return sizeof (ip6_address_t);
448 ip_version_to_size (u8 ver)
453 return sizeof (ip4_address_t);
456 return sizeof (ip6_address_t);
463 ip_version_to_max_plen (u8 ver)
477 always_inline lisp_afi_e
478 ip_version_to_iana_afi (u16 version)
493 ip_iana_afi_to_version (lisp_afi_e afi)
508 ip_address_size_to_write (ip_address_t * a)
510 return ip_address_size (a) + sizeof (u16);
514 ip_address_iana_afi (ip_address_t * a)
516 return ip_version_to_iana_afi (ip_addr_version (a));
520 ip_address_max_len (u8 version)
522 return version == IP4 ? 32 : 128;
526 ip4_address_size_to_put ()
528 // return sizeof(u16) + sizeof (ip4_address_t);
533 ip6_address_size_to_put ()
535 //return sizeof(u16) + sizeof (ip6_address_t);
540 ip4_address_put (u8 * b, ip4_address_t * a)
542 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
543 u8 *p = b + sizeof (u16);
544 clib_memcpy (p, a, sizeof (*a));
545 return ip4_address_size_to_put ();
549 ip6_address_put (u8 * b, ip6_address_t * a)
551 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
552 u8 *p = b + sizeof (u16);
553 clib_memcpy (p, a, sizeof (*a));
554 return ip6_address_size_to_put ();
558 ip_address_put (u8 * b, ip_address_t * a)
560 u32 len = ip_address_size (a);
561 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
562 u8 *p = b + sizeof (u16);
563 clib_memcpy (p, &ip_addr_addr (a), len);
564 return (len + sizeof (u16));
568 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
570 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
571 u8 size = ip_version_to_size (ip_addr_version (dst));
572 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
573 return (sizeof (u16) + size);
577 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
579 lcaf_hdr_t *lh = offset;
580 lcaf->type = lh->type;
582 /* this is a bit of hack: since the LCAF Instance ID is the
583 only message that uses reserved2 field, we can set it here.
584 If any LCAF format starts using reserved2 field as well this needs
585 to be moved elsewhere */
586 lcaf_vni_len (lcaf) = lh->reserved2;
588 return sizeof (lh[0]);
592 iana_afi_to_fid_addr_type (u16 type)
598 return FID_ADDR_IP_PREF;
607 fid_addr_parse (u8 * p, fid_address_t * a)
609 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
610 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
611 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
613 switch (fid_addr_type (a))
616 return mac_parse (p, fid_addr_mac (a));
618 case FID_ADDR_IP_PREF:
619 return ip_address_parse (p, afi, ip_addr);
629 sd_parse (u8 * p, void *a)
631 lcaf_src_dst_hdr_t *sd_hdr;
632 gid_address_t *g = a;
634 fid_address_t *src = &gid_address_sd_src (g);
635 fid_address_t *dst = &gid_address_sd_dst (g);
637 gid_address_type (g) = GID_ADDR_SRC_DST;
639 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
640 size += sizeof (sd_hdr[0]);
642 size += fid_addr_parse (p + size, src);
643 size += fid_addr_parse (p + size, dst);
645 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
647 ip_prefix_t *ippref = &fid_addr_ippref (src);
648 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
650 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
652 ip_prefix_t *ippref = &fid_addr_ippref (dst);
653 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
659 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
662 u16 size = sizeof (u16); /* skip AFI */
664 size += lcaf_hdr_parse (p + size, &lcaf);
666 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
669 size += sd_parse (p + size, a);
674 vni_parse (u8 * p, void *a)
677 gid_address_t *g = a;
680 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
681 size += sizeof (u32);
682 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
684 /* nested LCAFs are not supported except of src/dst with vni - to handle
685 * such case look at the next AFI and process src/dest LCAF separately */
686 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
687 if (LISP_AFI_LCAF == afi)
689 u16 len = try_parse_src_dst_lcaf (p + size, g);
690 if ((u16) ~ 0 == len)
695 size += gid_address_parse (p + size, g);
701 no_addr_parse (u8 * p, void *a)
708 lcaf_parse (void *offset, gid_address_t * addr)
711 offset += sizeof (u16);
712 lcaf_t *lcaf = &gid_address_lcaf (addr);
714 u32 size = lcaf_hdr_parse (offset, lcaf);
715 u8 type = lcaf_type (lcaf);
717 if (!lcaf_parse_fcts[type])
719 clib_warning ("Unsupported LCAF type: %u", type);
722 size += (*lcaf_parse_fcts[type]) (offset + size, lcaf);
723 return sizeof (u16) + size;
730 gid_address_free (vni_gid (v));
731 clib_mem_free (vni_gid (v));
735 no_addr_free (void *a)
747 gid_address_free (gid_address_t * a)
749 if (gid_address_type (a) != GID_ADDR_LCAF)
752 lcaf_t *lcaf = &gid_address_lcaf (a);
753 u8 lcaf_type = lcaf_type (lcaf);
754 (*lcaf_free_fcts[lcaf_type]) (lcaf);
758 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
760 memset (g, 0, sizeof (g[0]));
761 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
762 gid_address_ippref_len (g) = 32;
766 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
769 if (ip_addr_version (ip1) != ip_addr_version (ip2))
772 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
783 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
785 if (IP4 == ip_addr_version (src))
787 /* don't copy any garbe from the union */
788 memset (dst, 0, sizeof (*dst));
789 dst->ip.v4 = src->ip.v4;
794 clib_memcpy (dst, src, sizeof (ip_address_t));
799 ip_address_copy_addr (void *dst, const ip_address_t * src)
801 clib_memcpy (dst, src, ip_address_size (src));
805 ip_address_set (ip_address_t * dst, const void *src, u8 version)
807 clib_memcpy (dst, src, ip_version_to_size (version));
808 ip_addr_version (dst) = version;
812 ip_address_to_46 (const ip_address_t * addr,
813 ip46_address_t * a, fib_protocol_t * proto)
815 *proto = (IP4 == ip_addr_version (addr) ?
816 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
819 case FIB_PROTOCOL_IP4:
820 ip46_address_set_ip4 (a, &addr->ip.v4);
822 case FIB_PROTOCOL_IP6:
823 a->ip6 = addr->ip.v6;
832 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
843 mask = pow2_mask (preflen) << (32 - preflen);
844 mask = clib_host_to_net_u32 (mask);
845 ip4->data_u32 &= mask;
849 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
857 memset (mask_6, 0, sizeof (mask_6));
866 m = (u32 *) & mask_6[0];
868 for (j = 0; j < i0; j++)
875 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
878 for (j = 0; j < sizeof (mask_6); j++)
880 ip6->as_u8[j] &= mask_6[j];
885 ip_prefix_normalize (ip_prefix_t * a)
887 u8 preflen = ip_prefix_len (a);
889 switch (ip_prefix_version (a))
892 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
896 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
905 ip_prefix_cast (gid_address_t * a)
907 return &gid_address_ippref (a);
911 ip_prefix_size_to_write (void *pref)
913 ip_prefix_t *a = (ip_prefix_t *) pref;
914 return ip_address_size_to_write (&ip_prefix_addr (a));
918 ip_prefix_write (u8 * p, void *gid)
920 gid_address_t *g = gid;
921 ip_prefix_t *a = &gid_address_ippref (g);
923 switch (ip_prefix_version (a))
926 return ip4_address_put (p, &ip_prefix_v4 (a));
929 return ip6_address_put (p, &ip_prefix_v6 (a));
936 ip_prefix_length (void *a)
938 return ip_prefix_len ((ip_prefix_t *) a);
942 ip_prefix_copy (void *dst, void *src)
944 clib_memcpy (dst, src, sizeof (ip_prefix_t));
948 mac_copy (void *dst, void *src)
950 clib_memcpy (dst, src, 6);
954 nsh_copy (void *dst, void *src)
956 clib_memcpy (dst, src, sizeof (nsh_t));
960 sd_copy (void *dst, void *src)
962 clib_memcpy (dst, src, sizeof (source_dest_t));
966 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
970 ip_prefix_normalize (p1);
971 ip_prefix_normalize (p2);
973 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
976 if (ip_prefix_len (p1) < ip_prefix_len (p2))
982 if (ip_prefix_len (p1) > ip_prefix_len (p2))
990 no_addr_copy (void *dst, void *src)
996 vni_copy (void *dst, void *src)
1001 clib_memcpy (vd, vs, sizeof (vd[0]));
1002 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
1003 gid_address_copy (vni_gid (vd), vni_gid (vs));
1007 lcaf_copy (void *dst, void *src)
1009 lcaf_t *lcaf_dst = dst;
1010 lcaf_t *lcaf_src = src;
1012 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
1013 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
1017 lcaf_length (void *a)
1023 mac_length (void *a)
1035 lcaf_cast (gid_address_t * a)
1037 return &gid_address_lcaf (a);
1041 mac_cast (gid_address_t * a)
1043 return &gid_address_mac (a);
1047 sd_cast (gid_address_t * a)
1049 return &gid_address_sd (a);
1053 no_addr_length (void *a)
1059 vni_length (void *a)
1062 return (sizeof (u32) /* VNI size */
1063 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1067 lcaf_write (u8 * p, void *a)
1071 u8 type = lcaf_type (lcaf);
1072 lcaf_hdr_t _h, *h = &_h;
1074 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1075 size += sizeof (u16);
1076 memset (h, 0, sizeof (h[0]));
1077 LCAF_TYPE (h) = type;
1078 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1079 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1081 clib_memcpy (p + size, h, sizeof (h[0]));
1082 size += sizeof (h[0]);
1083 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1085 if ((u16) ~ 0 == len)
1092 mac_write (u8 * p, void *a)
1094 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1095 clib_memcpy (p + sizeof (u16), a, 6);
1096 return mac_size_to_write (a);
1100 fid_addr_write (u8 * p, fid_address_t * a)
1102 switch (fid_addr_type (a))
1104 case FID_ADDR_IP_PREF:
1105 return ip_prefix_write (p, &fid_addr_ippref (a));
1108 return mac_write (p, &fid_addr_mac (a));
1117 fid_address_length (fid_address_t * a)
1119 switch (fid_addr_type (a))
1121 case FID_ADDR_IP_PREF:
1122 return ip_prefix_length (&fid_addr_ippref (a));
1132 sd_write (u8 * p, void *a)
1134 source_dest_t *sd = a;
1136 lcaf_hdr_t _h, *h = &_h;
1137 lcaf_src_dst_hdr_t sd_hdr;
1139 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1140 size += sizeof (u16);
1141 memset (h, 0, sizeof (h[0]));
1142 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1143 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1144 + fid_addr_size_to_write (&sd_src (sd))
1145 + fid_addr_size_to_write (&sd_dst (sd));
1146 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1148 clib_memcpy (p + size, h, sizeof (h[0]));
1149 size += sizeof (h[0]);
1151 memset (&sd_hdr, 0, sizeof (sd_hdr));
1152 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1153 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1154 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1155 size += sizeof (sd_hdr);
1157 u16 len = fid_addr_write (p + size, &sd_src (sd));
1158 if ((u16) ~ 0 == len)
1162 len = fid_addr_write (p + size, &sd_dst (sd));
1163 if ((u16) ~ 0 == len)
1171 vni_write (u8 * p, void *a)
1173 lcaf_hdr_t _h, *h = &_h;
1174 gid_address_t *g = a;
1177 /* put lcaf header */
1178 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1179 size += sizeof (u16);
1180 memset (h, 0, sizeof (h[0]));
1181 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1182 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1183 + gid_address_size_to_put_no_vni (g);
1184 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1185 LCAF_RES2 (h) = gid_address_vni_mask (g);
1187 /* put vni header */
1188 clib_memcpy (p + size, h, sizeof (h[0]));
1189 size += sizeof (h[0]);
1191 u32 *afip = (u32 *) (p + size);
1192 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1193 size += sizeof (u32);
1195 if (GID_ADDR_SRC_DST == gid_address_type (g))
1196 /* write src/dst LCAF */
1198 len = sd_write (p + size, g);
1199 if ((u16) ~ 0 == len)
1203 /* write the actual address */
1204 len = gid_address_put_no_vni (p + size, g);
1206 if ((u16) ~ 0 == len)
1213 no_addr_write (u8 * p, void *a)
1215 /* do nothing; return AFI field size */
1216 return sizeof (u16);
1220 no_addr_size_to_write (void *a)
1222 return sizeof (u16); /* AFI field length */
1226 fid_addr_size_to_write (fid_address_t * a)
1228 switch (fid_addr_type (a))
1230 case FID_ADDR_IP_PREF:
1231 return ip_prefix_size_to_write (a);
1234 return mac_size_to_write (a);
1243 vni_size_to_write (void *a)
1245 gid_address_t *g = a;
1247 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1248 + sizeof (lcaf_hdr_t);
1250 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1251 /* special case where nested LCAF is supported */
1252 return lcaf_size + sd_size_to_write (g);
1254 return lcaf_size + gid_address_size_to_put_no_vni (g);
1258 lcaf_size_to_write (void *a)
1260 lcaf_t *lcaf = (lcaf_t *) a;
1262 u8 type = lcaf_type (lcaf);
1264 size += sizeof (u16); /* AFI size */
1266 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1274 sd_size_to_write (void *a)
1276 source_dest_t *sd = a;
1278 + sizeof (lcaf_hdr_t)
1279 + sizeof (lcaf_src_dst_hdr_t)
1280 + fid_addr_size_to_write (&sd_src (sd))
1281 + fid_addr_size_to_write (&sd_dst (sd));
1285 mac_size_to_write (void *a)
1287 return sizeof (u16) + 6;
1291 gid_address_len (gid_address_t * a)
1293 gid_address_type_t type = gid_address_type (a);
1294 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1298 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1300 gid_address_type_t type = gid_address_type (gid);
1301 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1305 gid_address_put (u8 * b, gid_address_t * gid)
1307 if (0 != gid_address_vni (gid))
1308 return vni_write (b, gid);
1310 return gid_address_put_no_vni (b, gid);
1314 gid_address_size_to_put_no_vni (gid_address_t * gid)
1316 gid_address_type_t type = gid_address_type (gid);
1317 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1321 gid_address_size_to_put (gid_address_t * gid)
1323 if (0 != gid_address_vni (gid))
1324 return vni_size_to_write (gid);
1326 return gid_address_size_to_put_no_vni (gid);
1330 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1332 return (*cast_fcts[type]) (gid);
1336 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1338 gid_address_type_t type = gid_address_type (src);
1339 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1340 gid_address_type (dst) = type;
1341 gid_address_vni (dst) = gid_address_vni (src);
1342 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1346 mac_parse (u8 * offset, u8 * a)
1348 /* skip AFI field */
1349 offset += sizeof (u16);
1351 clib_memcpy (a, offset, 6);
1352 return sizeof (u16) + 6;
1356 gid_address_parse (u8 * offset, gid_address_t * a)
1364 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1365 * the gid address here */
1366 afi = clib_net_to_host_u16 (*((u16 *) offset));
1370 case LISP_AFI_NO_ADDR:
1372 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1375 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1376 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1377 /* this should be modified outside if needed */
1378 gid_address_ippref_len (a) = 32;
1381 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1382 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1383 /* this should be modified outside if needed */
1384 gid_address_ippref_len (a) = 128;
1387 gid_address_type (a) = GID_ADDR_LCAF;
1388 len = lcaf_parse (offset, a);
1391 len = mac_parse (offset, gid_address_mac (a));
1392 gid_address_type (a) = GID_ADDR_MAC;
1395 clib_warning ("LISP AFI %d not supported!", afi);
1402 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1404 gid_address_ippref_len (dst) = ip_address_max_len (version);
1405 ip_address_set (&gid_address_ip (dst), src, version);
1409 no_addr_cmp (void *a1, void *a2)
1415 vni_cmp (void *a1, void *a2)
1420 if (vni_mask_len (v1) != vni_mask_len (v2))
1422 if (vni_vni (v1) != vni_vni (v2))
1424 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1428 mac_cmp (void *a1, void *a2)
1430 return memcmp (a1, a2, 6);
1434 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1436 if (fid_addr_type (a1) != fid_addr_type (a2))
1439 switch (fid_addr_type (a1))
1441 case FID_ADDR_IP_PREF:
1442 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1445 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1454 sd_cmp (void *a1, void *a2)
1456 source_dest_t *sd1 = a1;
1457 source_dest_t *sd2 = a2;
1459 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1461 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1466 /* Compare two gid_address_t.
1468 * -1: If they are from different afi
1469 * 0: Both address are the same
1470 * 1: Addr1 is bigger than addr2
1471 * 2: Addr2 is bigger than addr1
1474 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1476 lcaf_t *lcaf1, *lcaf2;
1480 if (gid_address_type (a1) != gid_address_type (a2))
1482 if (gid_address_vni (a1) != gid_address_vni (a2))
1485 /* TODO vni mask is not supported, disable comparing for now
1486 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1490 switch (gid_address_type (a1))
1492 case GID_ADDR_NO_ADDRESS:
1498 case GID_ADDR_IP_PREFIX:
1500 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1503 lcaf1 = &gid_address_lcaf (a1);
1504 lcaf2 = &gid_address_lcaf (a2);
1505 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1506 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1509 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1512 case GID_ADDR_SRC_DST:
1513 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1523 locator_parse (void *b, locator_t * loc)
1526 u8 status = 1; /* locator up */
1530 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1533 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1537 loc->state = status;
1539 loc->priority = LOC_PRIORITY (h);
1540 loc->weight = LOC_WEIGHT (h);
1541 loc->mpriority = LOC_MPRIORITY (h);
1542 loc->mweight = LOC_MWEIGHT (h);
1544 return sizeof (locator_hdr_t) + len;
1548 locator_copy (locator_t * dst, locator_t * src)
1550 /* TODO if gid become more complex, this will need to be changed! */
1551 clib_memcpy (dst, src, sizeof (*dst));
1553 gid_address_copy (&dst->address, &src->address);
1557 locator_cmp (locator_t * l1, locator_t * l2)
1560 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1563 if (l1->priority != l2->priority)
1565 if (l1->weight != l2->weight)
1567 if (l1->mpriority != l2->mpriority)
1569 if (l1->mweight != l2->mweight)
1575 locator_free (locator_t * l)
1578 gid_address_free (&l->address);
1582 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1584 memset (sd, 0, sizeof (*sd));
1585 gid_address_type (sd) = GID_ADDR_SRC_DST;
1586 gid_address_vni (sd) = gid_address_vni (dst);
1587 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1589 switch (gid_address_type (dst))
1591 case GID_ADDR_IP_PREFIX:
1592 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1593 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1594 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1595 &gid_address_ippref (src));
1596 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1597 &gid_address_ippref (dst));
1600 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1601 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1602 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1603 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1606 clib_warning ("Unsupported gid type %d while conversion!",
1607 gid_address_type (dst));
1613 * fd.io coding-style-patch-verification: ON
1616 * eval: (c-set-style "gnu")