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_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 if (IP4 == ip_addr_version (src))
703 /* don't copy any garbe from the union */
704 memset (dst, 0, sizeof (*dst));
705 dst->ip.v4 = src->ip.v4;
710 clib_memcpy (dst, src, sizeof (ip_address_t));
715 ip_address_copy_addr (void *dst, const ip_address_t * src)
717 clib_memcpy (dst, src, ip_address_size (src));
721 ip_address_set (ip_address_t * dst, const void *src, u8 version)
723 clib_memcpy (dst, src, ip_version_to_size (version));
724 ip_addr_version (dst) = version;
728 ip_address_to_46 (const ip_address_t * addr,
729 ip46_address_t * a, fib_protocol_t * proto)
731 *proto = (IP4 == ip_addr_version (addr) ?
732 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
735 case FIB_PROTOCOL_IP4:
736 ip46_address_set_ip4 (a, &addr->ip.v4);
738 case FIB_PROTOCOL_IP6:
739 a->ip6 = addr->ip.v6;
748 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
759 mask = pow2_mask (preflen) << (32 - preflen);
760 mask = clib_host_to_net_u32 (mask);
761 ip4->data_u32 &= mask;
765 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
773 memset (mask_6, 0, sizeof (mask_6));
782 m = (u32 *) & mask_6[0];
784 for (j = 0; j < i0; j++)
791 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
794 for (j = 0; j < sizeof (mask_6); j++)
796 ip6->as_u8[j] &= mask_6[j];
801 ip_prefix_normalize (ip_prefix_t * a)
803 u8 preflen = ip_prefix_len (a);
805 switch (ip_prefix_version (a))
808 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
812 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
821 ip_prefix_cast (gid_address_t * a)
823 return &gid_address_ippref (a);
827 ip_prefix_size_to_write (void *pref)
829 ip_prefix_t *a = (ip_prefix_t *) pref;
830 return ip_address_size_to_write (&ip_prefix_addr (a));
834 ip_prefix_write (u8 * p, void *gid)
836 gid_address_t *g = gid;
837 ip_prefix_t *a = &gid_address_ippref (g);
839 switch (ip_prefix_version (a))
842 return ip4_address_put (p, &ip_prefix_v4 (a));
845 return ip6_address_put (p, &ip_prefix_v6 (a));
852 ip_prefix_length (void *a)
854 return ip_prefix_len ((ip_prefix_t *) a);
858 ip_prefix_copy (void *dst, void *src)
860 clib_memcpy (dst, src, sizeof (ip_prefix_t));
864 mac_copy (void *dst, void *src)
866 clib_memcpy (dst, src, 6);
870 sd_copy (void *dst, void *src)
872 clib_memcpy (dst, src, sizeof (source_dest_t));
876 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
880 ip_prefix_normalize (p1);
881 ip_prefix_normalize (p2);
883 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
886 if (ip_prefix_len (p1) < ip_prefix_len (p2))
892 if (ip_prefix_len (p1) > ip_prefix_len (p2))
900 no_addr_copy (void *dst, void *src)
906 vni_copy (void *dst, void *src)
911 clib_memcpy (vd, vs, sizeof (vd[0]));
912 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
913 gid_address_copy (vni_gid (vd), vni_gid (vs));
917 lcaf_copy (void *dst, void *src)
919 lcaf_t *lcaf_dst = dst;
920 lcaf_t *lcaf_src = src;
922 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
923 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
927 lcaf_length (void *a)
945 lcaf_cast (gid_address_t * a)
947 return &gid_address_lcaf (a);
951 mac_cast (gid_address_t * a)
953 return &gid_address_mac (a);
957 sd_cast (gid_address_t * a)
959 return &gid_address_sd (a);
963 no_addr_length (void *a)
972 return (sizeof (u32) /* VNI size */
973 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
977 lcaf_write (u8 * p, void *a)
981 u8 type = lcaf_type (lcaf);
982 lcaf_hdr_t _h, *h = &_h;
984 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
985 size += sizeof (u16);
986 memset (h, 0, sizeof (h[0]));
987 LCAF_TYPE (h) = type;
988 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
989 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
991 clib_memcpy (p + size, h, sizeof (h[0]));
992 size += sizeof (h[0]);
993 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
995 if ((u16) ~ 0 == len)
1002 mac_write (u8 * p, void *a)
1004 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1005 clib_memcpy (p + sizeof (u16), a, 6);
1006 return mac_size_to_write (a);
1010 fid_addr_write (u8 * p, fid_address_t * a)
1012 switch (fid_addr_type (a))
1014 case FID_ADDR_IP_PREF:
1015 return ip_prefix_write (p, &fid_addr_ippref (a));
1018 return mac_write (p, &fid_addr_mac (a));
1027 fid_address_length (fid_address_t * a)
1029 switch (fid_addr_type (a))
1031 case FID_ADDR_IP_PREF:
1032 return ip_prefix_length (&fid_addr_ippref (a));
1040 sd_write (u8 * p, void *a)
1042 source_dest_t *sd = a;
1044 lcaf_hdr_t _h, *h = &_h;
1045 lcaf_src_dst_hdr_t sd_hdr;
1047 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1048 size += sizeof (u16);
1049 memset (h, 0, sizeof (h[0]));
1050 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1051 u16 lcaf_len = 4 + sizeof (lcaf_src_dst_hdr_t)
1052 + fid_addr_size_to_write (&sd_src (sd))
1053 + fid_addr_size_to_write (&sd_dst (sd));
1054 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1056 clib_memcpy (p + size, h, sizeof (h[0]));
1057 size += sizeof (h[0]);
1059 memset (&sd_hdr, 0, sizeof (sd_hdr));
1060 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1061 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1062 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1063 size += sizeof (sd_hdr);
1065 u16 len = fid_addr_write (p + size, &sd_src (sd));
1066 if ((u16) ~ 0 == len)
1070 len = fid_addr_write (p + size, &sd_dst (sd));
1071 if ((u16) ~ 0 == len)
1079 vni_write (u8 * p, void *a)
1081 lcaf_hdr_t _h, *h = &_h;
1082 gid_address_t *g = a;
1085 /* put lcaf header */
1086 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1087 size += sizeof (u16);
1088 memset (h, 0, sizeof (h[0]));
1089 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1090 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1091 + gid_address_size_to_put_no_vni (g);
1092 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1093 LCAF_RES2 (h) = gid_address_vni_mask (g);
1095 /* put vni header */
1096 clib_memcpy (p + size, h, sizeof (h[0]));
1097 size += sizeof (h[0]);
1099 u32 *afip = (u32 *) (p + size);
1100 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1101 size += sizeof (u32);
1103 if (GID_ADDR_SRC_DST == gid_address_type (g))
1104 /* write src/dst LCAF */
1106 len = sd_write (p + size, g);
1107 if ((u16) ~ 0 == len)
1111 /* write the actual address */
1112 len = gid_address_put_no_vni (p + size, g);
1114 if ((u16) ~ 0 == len)
1121 no_addr_write (u8 * p, void *a)
1123 /* do nothing; return AFI field size */
1124 return sizeof (u16);
1128 no_addr_size_to_write (void *a)
1130 return sizeof (u16); /* AFI field length */
1134 fid_addr_size_to_write (fid_address_t * a)
1136 switch (fid_addr_type (a))
1138 case FID_ADDR_IP_PREF:
1139 return ip_prefix_size_to_write (a);
1142 return mac_size_to_write (a);
1151 vni_size_to_write (void *a)
1153 gid_address_t *g = a;
1155 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1156 + sizeof (lcaf_hdr_t);
1158 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1159 /* special case where nested LCAF is supported */
1160 return lcaf_size + sd_size_to_write (g);
1162 return lcaf_size + gid_address_size_to_put_no_vni (g);
1166 lcaf_size_to_write (void *a)
1168 lcaf_t *lcaf = (lcaf_t *) a;
1170 u8 type = lcaf_type (lcaf);
1172 size += sizeof (u16); /* AFI size */
1174 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1182 sd_size_to_write (void *a)
1184 source_dest_t *sd = a;
1186 + sizeof (lcaf_hdr_t)
1187 + sizeof (lcaf_src_dst_hdr_t)
1188 + fid_addr_size_to_write (&sd_src (sd))
1189 + fid_addr_size_to_write (&sd_dst (sd));
1193 mac_size_to_write (void *a)
1195 return sizeof (u16) + 6;
1199 gid_address_len (gid_address_t * a)
1201 gid_address_type_t type = gid_address_type (a);
1202 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1206 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1208 gid_address_type_t type = gid_address_type (gid);
1209 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1213 gid_address_put (u8 * b, gid_address_t * gid)
1215 if (0 != gid_address_vni (gid))
1216 return vni_write (b, gid);
1218 return gid_address_put_no_vni (b, gid);
1222 gid_address_size_to_put_no_vni (gid_address_t * gid)
1224 gid_address_type_t type = gid_address_type (gid);
1225 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1229 gid_address_size_to_put (gid_address_t * gid)
1231 if (0 != gid_address_vni (gid))
1232 return vni_size_to_write (gid);
1234 return gid_address_size_to_put_no_vni (gid);
1238 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1240 return (*cast_fcts[type]) (gid);
1244 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1246 gid_address_type_t type = gid_address_type (src);
1247 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1248 gid_address_type (dst) = type;
1249 gid_address_vni (dst) = gid_address_vni (src);
1250 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1254 mac_parse (u8 * offset, u8 * a)
1256 /* skip AFI field */
1257 offset += sizeof (u16);
1259 clib_memcpy (a, offset, 6);
1260 return sizeof (u16) + 6;
1264 gid_address_parse (u8 * offset, gid_address_t * a)
1272 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1273 * the gid address here */
1274 afi = clib_net_to_host_u16 (*((u16 *) offset));
1278 case LISP_AFI_NO_ADDR:
1280 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1283 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1284 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1285 /* this should be modified outside if needed */
1286 gid_address_ippref_len (a) = 32;
1289 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1290 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1291 /* this should be modified outside if needed */
1292 gid_address_ippref_len (a) = 128;
1295 gid_address_type (a) = GID_ADDR_LCAF;
1296 len = lcaf_parse (offset, a);
1299 len = mac_parse (offset, gid_address_mac (a));
1300 gid_address_type (a) = GID_ADDR_MAC;
1303 clib_warning ("LISP AFI %d not supported!", afi);
1310 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1312 gid_address_ippref_len (dst) = ip_address_max_len (version);
1313 ip_address_set (&gid_address_ip (dst), src, version);
1317 no_addr_cmp (void *a1, void *a2)
1323 vni_cmp (void *a1, void *a2)
1328 if (vni_mask_len (v1) != vni_mask_len (v2))
1330 if (vni_vni (v1) != vni_vni (v2))
1332 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1336 mac_cmp (void *a1, void *a2)
1338 return memcmp (a1, a2, 6);
1342 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1344 if (fid_addr_type (a1) != fid_addr_type (a2))
1347 switch (fid_addr_type (a1))
1349 case FID_ADDR_IP_PREF:
1350 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1353 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1362 sd_cmp (void *a1, void *a2)
1364 source_dest_t *sd1 = a1;
1365 source_dest_t *sd2 = a2;
1367 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1369 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1374 /* Compare two gid_address_t.
1376 * -1: If they are from different afi
1377 * 0: Both address are the same
1378 * 1: Addr1 is bigger than addr2
1379 * 2: Addr2 is bigger than addr1
1382 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1384 lcaf_t *lcaf1, *lcaf2;
1388 if (gid_address_type (a1) != gid_address_type (a2))
1390 if (gid_address_vni (a1) != gid_address_vni (a2))
1392 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1395 switch (gid_address_type (a1))
1397 case GID_ADDR_NO_ADDRESS:
1403 case GID_ADDR_IP_PREFIX:
1405 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1408 lcaf1 = &gid_address_lcaf (a1);
1409 lcaf2 = &gid_address_lcaf (a2);
1410 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1411 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1414 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1417 case GID_ADDR_SRC_DST:
1418 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1428 locator_parse (void *b, locator_t * loc)
1431 u8 status = 1; /* locator up */
1435 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1438 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1442 loc->state = status;
1444 loc->priority = LOC_PRIORITY (h);
1445 loc->weight = LOC_WEIGHT (h);
1446 loc->mpriority = LOC_MPRIORITY (h);
1447 loc->mweight = LOC_MWEIGHT (h);
1449 return sizeof (locator_hdr_t) + len;
1453 locator_copy (locator_t * dst, locator_t * src)
1455 /* TODO if gid become more complex, this will need to be changed! */
1456 clib_memcpy (dst, src, sizeof (*dst));
1458 gid_address_copy (&dst->address, &src->address);
1462 locator_cmp (locator_t * l1, locator_t * l2)
1465 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1468 if (l1->priority != l2->priority)
1470 if (l1->weight != l2->weight)
1472 if (l1->mpriority != l2->mpriority)
1474 if (l1->mweight != l2->mweight)
1480 locator_free (locator_t * l)
1483 gid_address_free (&l->address);
1487 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1489 memset (sd, 0, sizeof (*sd));
1490 gid_address_type (sd) = GID_ADDR_SRC_DST;
1491 gid_address_vni (sd) = gid_address_vni (dst);
1492 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1494 switch (gid_address_type (dst))
1496 case GID_ADDR_IP_PREFIX:
1497 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1498 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1499 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1500 &gid_address_ippref (src));
1501 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1502 &gid_address_ippref (dst));
1505 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1506 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1507 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1508 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1511 clib_warning ("Unsupported gid type %d while conversion!",
1512 gid_address_type (dst));
1518 * fd.io coding-style-patch-verification: ON
1521 * eval: (c-set-style "gnu")