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, 0 /* arp */ , no_addr_size_to_write
37 serdes_fct write_fcts[GID_ADDR_TYPES] =
38 { ip_prefix_write, lcaf_write, mac_write, sd_write, nsh_write, 0 /* arp */ ,
42 cast_fct cast_fcts[GID_ADDR_TYPES] =
43 { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast, nsh_cast, 0 /* arp */ ,
47 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
48 { ip_prefix_length, lcaf_length, mac_length, sd_length, nsh_length,
49 0 /* arp */ , no_addr_length
52 copy_fct copy_fcts[GID_ADDR_TYPES] =
53 { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy, nsh_copy, 0 /* arp */ ,
57 #define foreach_lcaf_type \
77 #define _(cond, name) \
78 u16 name ## _write (u8 * p, void * a); \
79 u16 name ## _parse (u8 * p, void * a); \
80 u16 name ## _size_to_write (void * a); \
81 void name ## _free (void * a); \
82 void name ## _copy (void * dst, void * src); \
83 u8 name ## _length (void * a); \
84 int name ## _cmp (void *, void *);
87 #define CONCAT(a,b) a##_##b
88 #define IF(c, t, e) CONCAT(IF, c)(t, e)
91 #define EXPAND_FCN(cond, fcn) \
93 cmp_fct lcaf_cmp_fcts[LCAF_TYPES] =
95 #define _(cond, name) \
96 EXPAND_FCN(cond, name##_cmp),
101 addr_len_fct lcaf_body_length_fcts[LCAF_TYPES] = {
102 #define _(cond, name) \
103 EXPAND_FCN(cond, name##_length),
108 copy_fct lcaf_copy_fcts[LCAF_TYPES] = {
109 #define _(cond, name) \
110 EXPAND_FCN(cond, name##_copy),
115 free_fct lcaf_free_fcts[LCAF_TYPES] = {
116 #define _(cond, name) \
117 EXPAND_FCN(cond, name##_free),
122 size_to_write_fct lcaf_size_to_write_fcts[LCAF_TYPES] = {
123 #define _(cond, name) \
124 EXPAND_FCN(cond, name##_size_to_write),
129 serdes_fct lcaf_write_fcts[LCAF_TYPES] = {
130 #define _(cond, name) \
131 EXPAND_FCN(cond, name##_write),
136 serdes_fct lcaf_parse_fcts[LCAF_TYPES] = {
137 #define _(cond, name) \
138 EXPAND_FCN(cond, name##_parse),
144 format_ip_address (u8 * s, va_list * args)
146 ip_address_t *a = va_arg (*args, ip_address_t *);
147 u8 ver = ip_addr_version (a);
150 return format (s, "%U", format_ip4_address, &ip_addr_v4 (a));
154 return format (s, "%U", format_ip6_address, &ip_addr_v6 (a));
158 clib_warning ("Can't format IP version %d!", ver);
164 unformat_ip_address (unformat_input_t * input, va_list * args)
166 ip_address_t *a = va_arg (*args, ip_address_t *);
168 memset (a, 0, sizeof (*a));
169 if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (a)))
170 ip_addr_version (a) = IP4;
171 else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6 (a)))
172 ip_addr_version (a) = IP6;
179 format_ip_prefix (u8 * s, va_list * args)
181 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
182 return format (s, "%U/%d", format_ip_address, &ip_prefix_addr (a),
187 unformat_ip_prefix (unformat_input_t * input, va_list * args)
189 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
190 if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr (a),
193 if ((ip_prefix_version (a) == IP4 && 32 < ip_prefix_len (a)) ||
194 (ip_prefix_version (a) == IP6 && 128 < ip_prefix_length (a)))
196 clib_warning ("Prefix length to big: %d!", ip_prefix_len (a));
199 ip_prefix_normalize (a);
207 unformat_mac_address (unformat_input_t * input, va_list * args)
209 u8 *a = va_arg (*args, u8 *);
210 return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
215 format_mac_address (u8 * s, va_list * args)
217 u8 *a = va_arg (*args, u8 *);
218 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
219 a[0], a[1], a[2], a[3], a[4], a[5]);
223 unformat_nsh_address (unformat_input_t * input, va_list * args)
225 nsh_t *a = va_arg (*args, nsh_t *);
226 return unformat (input, "SPI:%d SI:%d", &a->spi, &a->si);
230 format_nsh_address (u8 * s, va_list * args)
232 nsh_t *a = va_arg (*args, nsh_t *);
233 return format (s, "SPI:%d SI:%d", a->spi, a->si);
237 format_fid_nsh_address (u8 * s, va_list * args)
239 u32 *a = va_arg (*args, u32 *);
240 return format (s, "SPI:%d SI:%d", *a >> 8, *a & 0xff);
244 format_fid_address (u8 * s, va_list * args)
246 fid_address_t *a = va_arg (*args, fid_address_t *);
248 switch (fid_addr_type (a))
250 case FID_ADDR_IP_PREF:
251 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
253 return format (s, "%U", format_mac_address, &fid_addr_mac (a));
255 return format (s, "%U", format_fid_nsh_address, &fid_addr_nsh (a));
258 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
265 format_gid_address (u8 * s, va_list * args)
267 gid_address_t *a = va_arg (*args, gid_address_t *);
268 u8 type = gid_address_type (a);
271 case GID_ADDR_IP_PREFIX:
272 return format (s, "[%d] %U", gid_address_vni (a), format_ip_prefix,
273 &gid_address_ippref (a));
274 case GID_ADDR_SRC_DST:
275 return format (s, "[%d] %U|%U", gid_address_vni (a),
276 format_fid_address, &gid_address_sd_src (a),
277 format_fid_address, &gid_address_sd_dst (a));
279 return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
280 &gid_address_mac (a));
282 return format (s, "[%d, %U]", gid_address_arp_bd (a),
283 format_ip4_address, &gid_address_arp_ip4 (a));
285 return format (s, "%U", format_nsh_address, &gid_address_nsh (a));
288 clib_warning ("Can't format gid type %d", type);
295 unformat_fid_address (unformat_input_t * i, va_list * args)
297 fid_address_t *a = va_arg (*args, fid_address_t *);
302 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
304 fid_addr_type (a) = FID_ADDR_IP_PREF;
305 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
307 else if (unformat (i, "%U", unformat_mac_address, mac))
309 fid_addr_type (a) = FID_ADDR_MAC;
310 mac_copy (fid_addr_mac (a), mac);
312 else if (unformat (i, "%U", unformat_nsh_address, &nsh))
314 fid_addr_type (a) = FID_ADDR_NSH;
315 nsh_copy (&fid_addr_nsh (a), &nsh);
324 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
326 u32 *key_id = va_arg (*args, u32 *);
329 if (unformat (input, "%s", &s))
331 if (!strcmp ((char *) s, "sha1"))
332 key_id[0] = HMAC_SHA_1_96;
333 else if (!strcmp ((char *) s, "sha256"))
334 key_id[0] = HMAC_SHA_256_128;
337 clib_warning ("invalid key_id: '%s'", s);
338 key_id[0] = HMAC_NO_KEY;
349 unformat_gid_address (unformat_input_t * input, va_list * args)
351 gid_address_t *a = va_arg (*args, gid_address_t *);
354 fid_address_t sim1, sim2;
357 memset (&ippref, 0, sizeof (ippref));
358 memset (&sim1, 0, sizeof (sim1));
359 memset (&sim2, 0, sizeof (sim2));
361 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
362 unformat_fid_address, &sim2))
364 gid_address_sd_src (a) = sim1;
365 gid_address_sd_dst (a) = sim2;
366 gid_address_type (a) = GID_ADDR_SRC_DST;
368 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
370 ip_prefix_copy (&gid_address_ippref (a), &ippref);
371 gid_address_type (a) = GID_ADDR_IP_PREFIX;
373 else if (unformat (input, "%U", unformat_mac_address, mac))
375 mac_copy (gid_address_mac (a), mac);
376 gid_address_type (a) = GID_ADDR_MAC;
378 else if (unformat (input, "%U", unformat_nsh_address, &nsh))
380 nsh_copy (&gid_address_nsh (a), &nsh);
381 gid_address_type (a) = GID_ADDR_NSH;
390 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
392 u32 *action = va_arg (*args, u32 *);
395 if (unformat (input, "%s", &s))
397 if (!strcmp ((char *) s, "no-action"))
398 action[0] = LISP_NO_ACTION;
399 else if (!strcmp ((char *) s, "natively-forward"))
400 action[0] = LISP_FORWARD_NATIVE;
401 else if (!strcmp ((char *) s, "send-map-request"))
402 action[0] = LISP_SEND_MAP_REQUEST;
403 else if (!strcmp ((char *) s, "drop"))
404 action[0] = LISP_DROP;
407 clib_warning ("invalid action: '%s'", s);
408 action[0] = LISP_DROP;
419 format_hmac_key_id (u8 * s, va_list * args)
421 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
426 return format (0, "sha1");
427 case HMAC_SHA_256_128:
428 return format (0, "sha256");
437 format_negative_mapping_action (u8 * s, va_list * args)
439 lisp_action_e action = va_arg (*args, lisp_action_e);
444 s = format (s, "no-action");
446 case LISP_FORWARD_NATIVE:
447 s = format (s, "natively-forward");
449 case LISP_SEND_MAP_REQUEST:
450 s = format (s, "send-map-request");
454 s = format (s, "drop");
461 ip_address_size (const ip_address_t * a)
463 switch (ip_addr_version (a))
466 return sizeof (ip4_address_t);
469 return sizeof (ip6_address_t);
476 ip_version_to_size (u8 ver)
481 return sizeof (ip4_address_t);
484 return sizeof (ip6_address_t);
491 ip_version_to_max_plen (u8 ver)
505 always_inline lisp_afi_e
506 ip_version_to_iana_afi (u16 version)
521 ip_iana_afi_to_version (lisp_afi_e afi)
536 ip_address_size_to_write (ip_address_t * a)
538 return ip_address_size (a) + sizeof (u16);
542 ip_address_iana_afi (ip_address_t * a)
544 return ip_version_to_iana_afi (ip_addr_version (a));
548 ip_address_max_len (u8 version)
550 return version == IP4 ? 32 : 128;
554 ip4_address_size_to_put ()
556 // return sizeof(u16) + sizeof (ip4_address_t);
561 ip6_address_size_to_put ()
563 //return sizeof(u16) + sizeof (ip6_address_t);
568 ip4_address_put (u8 * b, ip4_address_t * a)
570 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
571 u8 *p = b + sizeof (u16);
572 clib_memcpy (p, a, sizeof (*a));
573 return ip4_address_size_to_put ();
577 ip6_address_put (u8 * b, ip6_address_t * a)
579 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
580 u8 *p = b + sizeof (u16);
581 clib_memcpy (p, a, sizeof (*a));
582 return ip6_address_size_to_put ();
586 ip_address_put (u8 * b, ip_address_t * a)
588 u32 len = ip_address_size (a);
589 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
590 u8 *p = b + sizeof (u16);
591 clib_memcpy (p, &ip_addr_addr (a), len);
592 return (len + sizeof (u16));
596 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
598 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
599 u8 size = ip_version_to_size (ip_addr_version (dst));
600 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
601 return (sizeof (u16) + size);
605 gid_to_dp_address (gid_address_t * g, dp_address_t * d)
607 switch (gid_address_type (g))
609 case GID_ADDR_SRC_DST:
610 switch (gid_address_sd_dst_type (g))
612 case FID_ADDR_IP_PREF:
613 ip_prefix_copy (&d->ippref, &gid_address_sd_dst_ippref (g));
614 d->type = FID_ADDR_IP_PREF;
617 mac_copy (&d->mac, &gid_address_sd_dst_mac (g));
618 d->type = FID_ADDR_MAC;
621 clib_warning ("Source/Dest address type %d not supported!",
622 gid_address_sd_dst_type (g));
626 case GID_ADDR_IP_PREFIX:
627 ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
628 d->type = FID_ADDR_IP_PREF;
631 mac_copy (&d->mac, &gid_address_mac (g));
632 d->type = FID_ADDR_MAC;
636 d->nsh = gid_address_nsh (g).spi << 8 | gid_address_nsh (g).si;
637 d->type = FID_ADDR_NSH;
643 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
645 lcaf_hdr_t *lh = offset;
646 lcaf->type = lh->type;
648 /* this is a bit of hack: since the LCAF Instance ID is the
649 only message that uses reserved2 field, we can set it here.
650 If any LCAF format starts using reserved2 field as well this needs
651 to be moved elsewhere */
652 lcaf_vni_len (lcaf) = lh->reserved2;
654 return sizeof (lh[0]);
658 iana_afi_to_fid_addr_type (u16 type)
664 return FID_ADDR_IP_PREF;
673 fid_addr_parse (u8 * p, fid_address_t * a)
675 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
676 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
677 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
679 switch (fid_addr_type (a))
682 return mac_parse (p, fid_addr_mac (a));
684 case FID_ADDR_IP_PREF:
685 return ip_address_parse (p, afi, ip_addr);
693 #define INC(dst, exp) \
696 if ((u16)~0 == _sum) \
708 nsh_parse (u8 * p, void *a)
710 lcaf_spi_hdr_t *h = (lcaf_spi_hdr_t *) p;
711 gid_address_t *g = a;
713 gid_address_type (g) = GID_ADDR_NSH;
714 gid_address_nsh_spi (g) = clib_net_to_host_u32 (LCAF_SPI_SI (h)) >> 8;
715 gid_address_nsh_si (g) = (u8) clib_net_to_host_u32 (LCAF_SPI_SI (h));
717 return sizeof (lcaf_spi_hdr_t);
721 nsh_cmp (void *a1, void *a2)
726 if (n1->spi != n2->spi)
728 if (n1->si != n2->si)
734 sd_parse (u8 * p, void *a)
736 lcaf_src_dst_hdr_t *sd_hdr;
737 gid_address_t *g = a;
739 fid_address_t *src = &gid_address_sd_src (g);
740 fid_address_t *dst = &gid_address_sd_dst (g);
742 gid_address_type (g) = GID_ADDR_SRC_DST;
744 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
745 size += sizeof (sd_hdr[0]);
747 INC (size, fid_addr_parse (p + size, src));
748 INC (size, fid_addr_parse (p + size, dst));
750 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
752 ip_prefix_t *ippref = &fid_addr_ippref (src);
753 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
755 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
757 ip_prefix_t *ippref = &fid_addr_ippref (dst);
758 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
764 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
767 u16 size = sizeof (u16); /* skip AFI */
769 size += lcaf_hdr_parse (p + size, &lcaf);
771 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
774 INC (size, sd_parse (p + size, a));
779 vni_parse (u8 * p, void *a)
782 gid_address_t *g = a;
785 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
786 size += sizeof (u32);
787 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
789 /* nested LCAFs are not supported except of src/dst with vni - to handle
790 * such case look at the next AFI and process src/dest LCAF separately */
791 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
792 if (LISP_AFI_LCAF == afi)
794 INC (size, try_parse_src_dst_lcaf (p + size, g));
797 INC (size, gid_address_parse (p + size, g));
803 no_addr_parse (u8 * p, void *a)
810 lcaf_parse (void *offset, gid_address_t * addr)
813 offset += sizeof (u16);
814 lcaf_t *lcaf = &gid_address_lcaf (addr);
816 u32 size = lcaf_hdr_parse (offset, lcaf);
817 u8 type = lcaf_type (lcaf);
819 if (!lcaf_parse_fcts[type])
821 clib_warning ("Unsupported LCAF type: %u", type);
824 INC (size, (*lcaf_parse_fcts[type]) (offset + size, lcaf));
825 return sizeof (u16) + size;
832 gid_address_free (vni_gid (v));
833 clib_mem_free (vni_gid (v));
837 no_addr_free (void *a)
849 gid_address_free (gid_address_t * a)
851 if (gid_address_type (a) != GID_ADDR_LCAF)
854 lcaf_t *lcaf = &gid_address_lcaf (a);
855 u8 lcaf_type = lcaf_type (lcaf);
856 (*lcaf_free_fcts[lcaf_type]) (lcaf);
860 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
862 memset (g, 0, sizeof (g[0]));
863 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
864 gid_address_ippref_len (g) = 32;
868 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
871 if (ip_addr_version (ip1) != ip_addr_version (ip2))
874 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
885 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
887 if (IP4 == ip_addr_version (src))
889 /* don't copy any garbe from the union */
890 memset (dst, 0, sizeof (*dst));
891 dst->ip.v4 = src->ip.v4;
896 clib_memcpy (dst, src, sizeof (ip_address_t));
901 ip_address_copy_addr (void *dst, const ip_address_t * src)
903 clib_memcpy (dst, src, ip_address_size (src));
907 ip_address_set (ip_address_t * dst, const void *src, u8 version)
909 clib_memcpy (dst, src, ip_version_to_size (version));
910 ip_addr_version (dst) = version;
914 ip_address_to_46 (const ip_address_t * addr,
915 ip46_address_t * a, fib_protocol_t * proto)
917 *proto = (IP4 == ip_addr_version (addr) ?
918 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
921 case FIB_PROTOCOL_IP4:
922 ip46_address_set_ip4 (a, &addr->ip.v4);
924 case FIB_PROTOCOL_IP6:
925 a->ip6 = addr->ip.v6;
934 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
945 mask = pow2_mask (preflen) << (32 - preflen);
946 mask = clib_host_to_net_u32 (mask);
947 ip4->data_u32 &= mask;
951 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
959 memset (mask_6, 0, sizeof (mask_6));
968 m = (u32 *) & mask_6[0];
970 for (j = 0; j < i0; j++)
977 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
980 for (j = 0; j < sizeof (mask_6); j++)
982 ip6->as_u8[j] &= mask_6[j];
987 ip_prefix_normalize (ip_prefix_t * a)
989 u8 preflen = ip_prefix_len (a);
991 switch (ip_prefix_version (a))
994 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
998 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
1007 ip_prefix_cast (gid_address_t * a)
1009 return &gid_address_ippref (a);
1013 ip_prefix_size_to_write (void *pref)
1015 ip_prefix_t *a = (ip_prefix_t *) pref;
1016 return ip_address_size_to_write (&ip_prefix_addr (a));
1020 ip_prefix_write (u8 * p, void *gid)
1022 gid_address_t *g = gid;
1023 ip_prefix_t *a = &gid_address_ippref (g);
1025 switch (ip_prefix_version (a))
1028 return ip4_address_put (p, &ip_prefix_v4 (a));
1031 return ip6_address_put (p, &ip_prefix_v6 (a));
1038 ip_prefix_length (void *a)
1040 return ip_prefix_len ((ip_prefix_t *) a);
1044 ip_prefix_copy (void *dst, void *src)
1046 clib_memcpy (dst, src, sizeof (ip_prefix_t));
1050 mac_copy (void *dst, void *src)
1052 clib_memcpy (dst, src, 6);
1056 sd_copy (void *dst, void *src)
1058 clib_memcpy (dst, src, sizeof (source_dest_t));
1062 nsh_copy (void *dst, void *src)
1064 clib_memcpy (dst, src, sizeof (nsh_t));
1068 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
1072 ip_prefix_normalize (p1);
1073 ip_prefix_normalize (p2);
1075 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
1078 if (ip_prefix_len (p1) < ip_prefix_len (p2))
1084 if (ip_prefix_len (p1) > ip_prefix_len (p2))
1092 no_addr_copy (void *dst, void *src)
1098 vni_copy (void *dst, void *src)
1103 clib_memcpy (vd, vs, sizeof (vd[0]));
1104 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
1105 gid_address_copy (vni_gid (vd), vni_gid (vs));
1109 lcaf_copy (void *dst, void *src)
1111 lcaf_t *lcaf_dst = dst;
1112 lcaf_t *lcaf_src = src;
1114 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
1115 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
1119 lcaf_length (void *a)
1125 mac_length (void *a)
1137 nsh_length (void *a)
1143 lcaf_cast (gid_address_t * a)
1145 return &gid_address_lcaf (a);
1149 mac_cast (gid_address_t * a)
1151 return &gid_address_mac (a);
1155 no_addr_cast (gid_address_t * a)
1161 sd_cast (gid_address_t * a)
1163 return &gid_address_sd (a);
1167 nsh_cast (gid_address_t * a)
1169 return &gid_address_nsh (a);
1173 no_addr_length (void *a)
1179 vni_length (void *a)
1182 return (sizeof (u32) /* VNI size */
1183 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1187 lcaf_write (u8 * p, void *a)
1191 u8 type = lcaf_type (lcaf);
1192 lcaf_hdr_t _h, *h = &_h;
1194 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1195 size += sizeof (u16);
1196 memset (h, 0, sizeof (h[0]));
1197 LCAF_TYPE (h) = type;
1198 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1199 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1201 clib_memcpy (p + size, h, sizeof (h[0]));
1202 size += sizeof (h[0]);
1203 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1205 if ((u16) ~ 0 == len)
1212 mac_write (u8 * p, void *a)
1214 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1215 clib_memcpy (p + sizeof (u16), a, 6);
1216 return mac_size_to_write (a);
1220 fid_addr_write (u8 * p, fid_address_t * a)
1222 switch (fid_addr_type (a))
1224 case FID_ADDR_IP_PREF:
1225 return ip_prefix_write (p, &fid_addr_ippref (a));
1228 return mac_write (p, &fid_addr_mac (a));
1237 fid_address_length (fid_address_t * a)
1239 switch (fid_addr_type (a))
1241 case FID_ADDR_IP_PREF:
1242 return ip_prefix_length (&fid_addr_ippref (a));
1252 sd_write (u8 * p, void *a)
1254 source_dest_t *sd = a;
1256 lcaf_hdr_t _h, *h = &_h;
1257 lcaf_src_dst_hdr_t sd_hdr;
1259 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1260 size += sizeof (u16);
1261 memset (h, 0, sizeof (h[0]));
1262 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1263 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1264 + fid_addr_size_to_write (&sd_src (sd))
1265 + fid_addr_size_to_write (&sd_dst (sd));
1266 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1268 clib_memcpy (p + size, h, sizeof (h[0]));
1269 size += sizeof (h[0]);
1271 memset (&sd_hdr, 0, sizeof (sd_hdr));
1272 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1273 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1274 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1275 size += sizeof (sd_hdr);
1277 u16 len = fid_addr_write (p + size, &sd_src (sd));
1278 if ((u16) ~ 0 == len)
1282 len = fid_addr_write (p + size, &sd_dst (sd));
1283 if ((u16) ~ 0 == len)
1291 nsh_write (u8 * p, void *a)
1295 gid_address_t *g = a;
1298 ASSERT (gid_address_type (g) == GID_ADDR_NSH);
1300 memset (&lcaf, 0, sizeof (lcaf));
1301 memset (&spi, 0, sizeof (spi));
1303 LCAF_TYPE (&lcaf) = LCAF_NSH;
1304 LCAF_LENGTH (&lcaf) = clib_host_to_net_u16 (sizeof (lcaf_spi_hdr_t));
1306 u32 s = clib_host_to_net_u32 (gid_address_nsh_spi (g) << 8 |
1307 gid_address_nsh_si (g));
1308 LCAF_SPI_SI (&spi) = s;
1310 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1311 size += sizeof (u16);
1313 clib_memcpy (p + size, &lcaf, sizeof (lcaf));
1314 size += sizeof (lcaf);
1316 clib_memcpy (p + size, &spi, sizeof (spi));
1317 size += sizeof (spi);
1323 vni_write (u8 * p, void *a)
1325 lcaf_hdr_t _h, *h = &_h;
1326 gid_address_t *g = a;
1329 /* put lcaf header */
1330 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1331 size += sizeof (u16);
1332 memset (h, 0, sizeof (h[0]));
1333 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1334 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1335 + gid_address_size_to_put_no_vni (g);
1336 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1337 LCAF_RES2 (h) = gid_address_vni_mask (g);
1339 /* put vni header */
1340 clib_memcpy (p + size, h, sizeof (h[0]));
1341 size += sizeof (h[0]);
1343 u32 *afip = (u32 *) (p + size);
1344 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1345 size += sizeof (u32);
1347 if (GID_ADDR_SRC_DST == gid_address_type (g))
1348 /* write src/dst LCAF */
1350 len = sd_write (p + size, g);
1351 if ((u16) ~ 0 == len)
1355 /* write the actual address */
1356 len = gid_address_put_no_vni (p + size, g);
1358 if ((u16) ~ 0 == len)
1365 no_addr_write (u8 * p, void *a)
1367 /* do nothing; return AFI field size */
1368 return sizeof (u16);
1372 no_addr_size_to_write (void *a)
1374 return sizeof (u16); /* AFI field length */
1378 fid_addr_size_to_write (fid_address_t * a)
1380 switch (fid_addr_type (a))
1382 case FID_ADDR_IP_PREF:
1383 return ip_prefix_size_to_write (a);
1386 return mac_size_to_write (a);
1395 vni_size_to_write (void *a)
1397 gid_address_t *g = a;
1399 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1400 + sizeof (lcaf_hdr_t);
1402 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1403 /* special case where nested LCAF is supported */
1404 return lcaf_size + sd_size_to_write (g);
1406 return lcaf_size + gid_address_size_to_put_no_vni (g);
1410 lcaf_size_to_write (void *a)
1412 lcaf_t *lcaf = (lcaf_t *) a;
1414 u8 type = lcaf_type (lcaf);
1416 size += sizeof (u16); /* AFI size */
1418 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1426 sd_size_to_write (void *a)
1428 source_dest_t *sd = a;
1430 + sizeof (lcaf_hdr_t)
1431 + sizeof (lcaf_src_dst_hdr_t)
1432 + fid_addr_size_to_write (&sd_src (sd))
1433 + fid_addr_size_to_write (&sd_dst (sd));
1437 mac_size_to_write (void *a)
1439 return sizeof (u16) + 6;
1443 nsh_size_to_write (void *a)
1445 return sizeof (u16) + sizeof (lcaf_hdr_t) + sizeof (lcaf_spi_hdr_t);
1449 gid_address_len (gid_address_t * a)
1451 gid_address_type_t type = gid_address_type (a);
1452 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1456 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1458 gid_address_type_t type = gid_address_type (gid);
1459 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1463 gid_address_put (u8 * b, gid_address_t * gid)
1465 if (0 != gid_address_vni (gid))
1466 return vni_write (b, gid);
1468 return gid_address_put_no_vni (b, gid);
1472 gid_address_size_to_put_no_vni (gid_address_t * gid)
1474 gid_address_type_t type = gid_address_type (gid);
1475 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1479 gid_address_size_to_put (gid_address_t * gid)
1481 if (0 != gid_address_vni (gid))
1482 return vni_size_to_write (gid);
1484 return gid_address_size_to_put_no_vni (gid);
1488 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1490 return (*cast_fcts[type]) (gid);
1494 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1496 gid_address_type_t type = gid_address_type (src);
1497 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1498 gid_address_type (dst) = type;
1499 gid_address_vni (dst) = gid_address_vni (src);
1500 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1504 mac_parse (u8 * offset, u8 * a)
1506 /* skip AFI field */
1507 offset += sizeof (u16);
1509 clib_memcpy (a, offset, 6);
1510 return sizeof (u16) + 6;
1514 gid_address_parse (u8 * offset, gid_address_t * a)
1521 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1522 * the gid address here */
1523 afi = clib_net_to_host_u16 (*((u16 *) offset));
1527 case LISP_AFI_NO_ADDR:
1529 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1532 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1533 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1534 /* this should be modified outside if needed */
1535 gid_address_ippref_len (a) = 32;
1538 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1539 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1540 /* this should be modified outside if needed */
1541 gid_address_ippref_len (a) = 128;
1544 gid_address_type (a) = GID_ADDR_LCAF;
1545 len = lcaf_parse (offset, a);
1548 len = mac_parse (offset, gid_address_mac (a));
1549 gid_address_type (a) = GID_ADDR_MAC;
1552 clib_warning ("LISP AFI %d not supported!", afi);
1555 return (len == (u16) ~ 0) ? ~0 : len;
1559 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1561 gid_address_ippref_len (dst) = ip_address_max_len (version);
1562 ip_address_set (&gid_address_ip (dst), src, version);
1566 no_addr_cmp (void *a1, void *a2)
1572 vni_cmp (void *a1, void *a2)
1577 if (vni_mask_len (v1) != vni_mask_len (v2))
1579 if (vni_vni (v1) != vni_vni (v2))
1581 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1585 mac_cmp (void *a1, void *a2)
1587 return memcmp (a1, a2, 6);
1591 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1593 if (fid_addr_type (a1) != fid_addr_type (a2))
1596 switch (fid_addr_type (a1))
1598 case FID_ADDR_IP_PREF:
1599 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1602 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1611 sd_cmp (void *a1, void *a2)
1613 source_dest_t *sd1 = a1;
1614 source_dest_t *sd2 = a2;
1616 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1618 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1623 /* Compare two gid_address_t.
1625 * -1: If they are from different afi
1626 * 0: Both address are the same
1627 * 1: Addr1 is bigger than addr2
1628 * 2: Addr2 is bigger than addr1
1631 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1633 lcaf_t *lcaf1, *lcaf2;
1637 if (gid_address_type (a1) != gid_address_type (a2))
1639 if (gid_address_vni (a1) != gid_address_vni (a2))
1642 /* TODO vni mask is not supported, disable comparing for now
1643 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1647 switch (gid_address_type (a1))
1649 case GID_ADDR_NO_ADDRESS:
1655 case GID_ADDR_IP_PREFIX:
1657 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1660 lcaf1 = &gid_address_lcaf (a1);
1661 lcaf2 = &gid_address_lcaf (a2);
1662 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1663 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1666 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1669 case GID_ADDR_SRC_DST:
1670 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1673 cmp = nsh_cmp (&gid_address_nsh (a1), &gid_address_nsh (a2));
1683 locator_parse (void *b, locator_t * loc)
1686 u8 status = 1; /* locator up */
1690 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1693 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1697 loc->state = status;
1699 loc->priority = LOC_PRIORITY (h);
1700 loc->weight = LOC_WEIGHT (h);
1701 loc->mpriority = LOC_MPRIORITY (h);
1702 loc->mweight = LOC_MWEIGHT (h);
1704 return sizeof (locator_hdr_t) + len;
1708 locator_copy (locator_t * dst, locator_t * src)
1710 /* TODO if gid become more complex, this will need to be changed! */
1711 clib_memcpy (dst, src, sizeof (*dst));
1713 gid_address_copy (&dst->address, &src->address);
1717 locator_cmp (locator_t * l1, locator_t * l2)
1720 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1723 if (l1->priority != l2->priority)
1725 if (l1->weight != l2->weight)
1727 if (l1->mpriority != l2->mpriority)
1729 if (l1->mweight != l2->mweight)
1735 locator_free (locator_t * l)
1738 gid_address_free (&l->address);
1742 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1744 memset (sd, 0, sizeof (*sd));
1745 gid_address_type (sd) = GID_ADDR_SRC_DST;
1746 gid_address_vni (sd) = gid_address_vni (dst);
1747 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1749 switch (gid_address_type (dst))
1751 case GID_ADDR_IP_PREFIX:
1752 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1753 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1754 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1755 &gid_address_ippref (src));
1756 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1757 &gid_address_ippref (dst));
1760 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1761 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1762 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1763 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1766 clib_warning ("Unsupported gid type %d while conversion!",
1767 gid_address_type (dst));
1773 * fd.io coding-style-patch-verification: ON
1776 * eval: (c-set-style "gnu")