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,
34 sd_size_to_write, nsh_size_to_write
36 serdes_fct write_fcts[GID_ADDR_TYPES] =
37 { ip_prefix_write, lcaf_write, mac_write, sd_write, nsh_write };
38 cast_fct cast_fcts[GID_ADDR_TYPES] =
39 { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast, nsh_cast };
40 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
41 { ip_prefix_length, lcaf_length, mac_length, sd_length, nsh_length };
42 copy_fct copy_fcts[GID_ADDR_TYPES] =
43 { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy, nsh_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 sd_copy (void *dst, void *src)
956 clib_memcpy (dst, src, sizeof (source_dest_t));
960 nsh_copy (void *dst, void *src)
962 clib_memcpy (dst, src, sizeof (nsh_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 nsh_length (void *a)
1041 lcaf_cast (gid_address_t * a)
1043 return &gid_address_lcaf (a);
1047 mac_cast (gid_address_t * a)
1049 return &gid_address_mac (a);
1053 sd_cast (gid_address_t * a)
1055 return &gid_address_sd (a);
1059 nsh_cast (gid_address_t * a)
1061 return &gid_address_nsh (a);
1065 no_addr_length (void *a)
1071 vni_length (void *a)
1074 return (sizeof (u32) /* VNI size */
1075 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1079 lcaf_write (u8 * p, void *a)
1083 u8 type = lcaf_type (lcaf);
1084 lcaf_hdr_t _h, *h = &_h;
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) = type;
1090 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1091 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1093 clib_memcpy (p + size, h, sizeof (h[0]));
1094 size += sizeof (h[0]);
1095 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1097 if ((u16) ~ 0 == len)
1104 mac_write (u8 * p, void *a)
1106 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1107 clib_memcpy (p + sizeof (u16), a, 6);
1108 return mac_size_to_write (a);
1112 fid_addr_write (u8 * p, fid_address_t * a)
1114 switch (fid_addr_type (a))
1116 case FID_ADDR_IP_PREF:
1117 return ip_prefix_write (p, &fid_addr_ippref (a));
1120 return mac_write (p, &fid_addr_mac (a));
1129 fid_address_length (fid_address_t * a)
1131 switch (fid_addr_type (a))
1133 case FID_ADDR_IP_PREF:
1134 return ip_prefix_length (&fid_addr_ippref (a));
1144 sd_write (u8 * p, void *a)
1146 source_dest_t *sd = a;
1148 lcaf_hdr_t _h, *h = &_h;
1149 lcaf_src_dst_hdr_t sd_hdr;
1151 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1152 size += sizeof (u16);
1153 memset (h, 0, sizeof (h[0]));
1154 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1155 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1156 + fid_addr_size_to_write (&sd_src (sd))
1157 + fid_addr_size_to_write (&sd_dst (sd));
1158 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1160 clib_memcpy (p + size, h, sizeof (h[0]));
1161 size += sizeof (h[0]);
1163 memset (&sd_hdr, 0, sizeof (sd_hdr));
1164 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1165 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1166 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1167 size += sizeof (sd_hdr);
1169 u16 len = fid_addr_write (p + size, &sd_src (sd));
1170 if ((u16) ~ 0 == len)
1174 len = fid_addr_write (p + size, &sd_dst (sd));
1175 if ((u16) ~ 0 == len)
1183 nsh_write (u8 * p, void *a)
1185 clib_warning ("not done");
1190 vni_write (u8 * p, void *a)
1192 lcaf_hdr_t _h, *h = &_h;
1193 gid_address_t *g = a;
1196 /* put lcaf header */
1197 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1198 size += sizeof (u16);
1199 memset (h, 0, sizeof (h[0]));
1200 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1201 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1202 + gid_address_size_to_put_no_vni (g);
1203 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1204 LCAF_RES2 (h) = gid_address_vni_mask (g);
1206 /* put vni header */
1207 clib_memcpy (p + size, h, sizeof (h[0]));
1208 size += sizeof (h[0]);
1210 u32 *afip = (u32 *) (p + size);
1211 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1212 size += sizeof (u32);
1214 if (GID_ADDR_SRC_DST == gid_address_type (g))
1215 /* write src/dst LCAF */
1217 len = sd_write (p + size, g);
1218 if ((u16) ~ 0 == len)
1222 /* write the actual address */
1223 len = gid_address_put_no_vni (p + size, g);
1225 if ((u16) ~ 0 == len)
1232 no_addr_write (u8 * p, void *a)
1234 /* do nothing; return AFI field size */
1235 return sizeof (u16);
1239 no_addr_size_to_write (void *a)
1241 return sizeof (u16); /* AFI field length */
1245 fid_addr_size_to_write (fid_address_t * a)
1247 switch (fid_addr_type (a))
1249 case FID_ADDR_IP_PREF:
1250 return ip_prefix_size_to_write (a);
1253 return mac_size_to_write (a);
1262 vni_size_to_write (void *a)
1264 gid_address_t *g = a;
1266 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1267 + sizeof (lcaf_hdr_t);
1269 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1270 /* special case where nested LCAF is supported */
1271 return lcaf_size + sd_size_to_write (g);
1273 return lcaf_size + gid_address_size_to_put_no_vni (g);
1277 lcaf_size_to_write (void *a)
1279 lcaf_t *lcaf = (lcaf_t *) a;
1281 u8 type = lcaf_type (lcaf);
1283 size += sizeof (u16); /* AFI size */
1285 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1293 sd_size_to_write (void *a)
1295 source_dest_t *sd = a;
1297 + sizeof (lcaf_hdr_t)
1298 + sizeof (lcaf_src_dst_hdr_t)
1299 + fid_addr_size_to_write (&sd_src (sd))
1300 + fid_addr_size_to_write (&sd_dst (sd));
1304 mac_size_to_write (void *a)
1306 return sizeof (u16) + 6;
1310 nsh_size_to_write (void *a)
1312 return sizeof (u16) + 4;
1316 gid_address_len (gid_address_t * a)
1318 gid_address_type_t type = gid_address_type (a);
1319 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1323 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1325 gid_address_type_t type = gid_address_type (gid);
1326 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1330 gid_address_put (u8 * b, gid_address_t * gid)
1332 if (0 != gid_address_vni (gid))
1333 return vni_write (b, gid);
1335 return gid_address_put_no_vni (b, gid);
1339 gid_address_size_to_put_no_vni (gid_address_t * gid)
1341 gid_address_type_t type = gid_address_type (gid);
1342 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1346 gid_address_size_to_put (gid_address_t * gid)
1348 if (0 != gid_address_vni (gid))
1349 return vni_size_to_write (gid);
1351 return gid_address_size_to_put_no_vni (gid);
1355 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1357 return (*cast_fcts[type]) (gid);
1361 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1363 gid_address_type_t type = gid_address_type (src);
1364 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1365 gid_address_type (dst) = type;
1366 gid_address_vni (dst) = gid_address_vni (src);
1367 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1371 mac_parse (u8 * offset, u8 * a)
1373 /* skip AFI field */
1374 offset += sizeof (u16);
1376 clib_memcpy (a, offset, 6);
1377 return sizeof (u16) + 6;
1381 gid_address_parse (u8 * offset, gid_address_t * a)
1389 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1390 * the gid address here */
1391 afi = clib_net_to_host_u16 (*((u16 *) offset));
1395 case LISP_AFI_NO_ADDR:
1397 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1400 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1401 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1402 /* this should be modified outside if needed */
1403 gid_address_ippref_len (a) = 32;
1406 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1407 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1408 /* this should be modified outside if needed */
1409 gid_address_ippref_len (a) = 128;
1412 gid_address_type (a) = GID_ADDR_LCAF;
1413 len = lcaf_parse (offset, a);
1416 len = mac_parse (offset, gid_address_mac (a));
1417 gid_address_type (a) = GID_ADDR_MAC;
1420 clib_warning ("LISP AFI %d not supported!", afi);
1427 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1429 gid_address_ippref_len (dst) = ip_address_max_len (version);
1430 ip_address_set (&gid_address_ip (dst), src, version);
1434 no_addr_cmp (void *a1, void *a2)
1440 vni_cmp (void *a1, void *a2)
1445 if (vni_mask_len (v1) != vni_mask_len (v2))
1447 if (vni_vni (v1) != vni_vni (v2))
1449 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1453 mac_cmp (void *a1, void *a2)
1455 return memcmp (a1, a2, 6);
1459 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1461 if (fid_addr_type (a1) != fid_addr_type (a2))
1464 switch (fid_addr_type (a1))
1466 case FID_ADDR_IP_PREF:
1467 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1470 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1479 sd_cmp (void *a1, void *a2)
1481 source_dest_t *sd1 = a1;
1482 source_dest_t *sd2 = a2;
1484 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1486 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1491 /* Compare two gid_address_t.
1493 * -1: If they are from different afi
1494 * 0: Both address are the same
1495 * 1: Addr1 is bigger than addr2
1496 * 2: Addr2 is bigger than addr1
1499 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1501 lcaf_t *lcaf1, *lcaf2;
1505 if (gid_address_type (a1) != gid_address_type (a2))
1507 if (gid_address_vni (a1) != gid_address_vni (a2))
1510 /* TODO vni mask is not supported, disable comparing for now
1511 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1515 switch (gid_address_type (a1))
1517 case GID_ADDR_NO_ADDRESS:
1523 case GID_ADDR_IP_PREFIX:
1525 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1528 lcaf1 = &gid_address_lcaf (a1);
1529 lcaf2 = &gid_address_lcaf (a2);
1530 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1531 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1534 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1537 case GID_ADDR_SRC_DST:
1538 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1548 locator_parse (void *b, locator_t * loc)
1551 u8 status = 1; /* locator up */
1555 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1558 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1562 loc->state = status;
1564 loc->priority = LOC_PRIORITY (h);
1565 loc->weight = LOC_WEIGHT (h);
1566 loc->mpriority = LOC_MPRIORITY (h);
1567 loc->mweight = LOC_MWEIGHT (h);
1569 return sizeof (locator_hdr_t) + len;
1573 locator_copy (locator_t * dst, locator_t * src)
1575 /* TODO if gid become more complex, this will need to be changed! */
1576 clib_memcpy (dst, src, sizeof (*dst));
1578 gid_address_copy (&dst->address, &src->address);
1582 locator_cmp (locator_t * l1, locator_t * l2)
1585 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1588 if (l1->priority != l2->priority)
1590 if (l1->weight != l2->weight)
1592 if (l1->mpriority != l2->mpriority)
1594 if (l1->mweight != l2->mweight)
1600 locator_free (locator_t * l)
1603 gid_address_free (&l->address);
1607 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1609 memset (sd, 0, sizeof (*sd));
1610 gid_address_type (sd) = GID_ADDR_SRC_DST;
1611 gid_address_vni (sd) = gid_address_vni (dst);
1612 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1614 switch (gid_address_type (dst))
1616 case GID_ADDR_IP_PREFIX:
1617 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1618 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1619 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1620 &gid_address_ippref (src));
1621 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1622 &gid_address_ippref (dst));
1625 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1626 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1627 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1628 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1631 clib_warning ("Unsupported gid type %d while conversion!",
1632 gid_address_type (dst));
1638 * fd.io coding-style-patch-verification: ON
1641 * eval: (c-set-style "gnu")