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));
283 return format (s, "[%d, %U]", gid_address_arp_ndp_bd (a),
284 format_ip_address, &gid_address_arp_ndp_ip (a));
286 return format (s, "%U", format_nsh_address, &gid_address_nsh (a));
289 clib_warning ("Can't format gid type %d", type);
296 unformat_fid_address (unformat_input_t * i, va_list * args)
298 fid_address_t *a = va_arg (*args, fid_address_t *);
303 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
305 fid_addr_type (a) = FID_ADDR_IP_PREF;
306 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
308 else if (unformat (i, "%U", unformat_mac_address, mac))
310 fid_addr_type (a) = FID_ADDR_MAC;
311 mac_copy (fid_addr_mac (a), mac);
313 else if (unformat (i, "%U", unformat_nsh_address, &nsh))
315 fid_addr_type (a) = FID_ADDR_NSH;
316 nsh_copy (&fid_addr_nsh (a), &nsh);
325 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
327 u32 *key_id = va_arg (*args, u32 *);
330 if (unformat (input, "%s", &s))
332 if (!strcmp ((char *) s, "sha1"))
333 key_id[0] = HMAC_SHA_1_96;
334 else if (!strcmp ((char *) s, "sha256"))
335 key_id[0] = HMAC_SHA_256_128;
338 clib_warning ("invalid key_id: '%s'", s);
339 key_id[0] = HMAC_NO_KEY;
350 unformat_gid_address (unformat_input_t * input, va_list * args)
352 gid_address_t *a = va_arg (*args, gid_address_t *);
355 fid_address_t sim1, sim2;
358 memset (&ippref, 0, sizeof (ippref));
359 memset (&sim1, 0, sizeof (sim1));
360 memset (&sim2, 0, sizeof (sim2));
362 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
363 unformat_fid_address, &sim2))
365 gid_address_sd_src (a) = sim1;
366 gid_address_sd_dst (a) = sim2;
367 gid_address_type (a) = GID_ADDR_SRC_DST;
369 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
371 ip_prefix_copy (&gid_address_ippref (a), &ippref);
372 gid_address_type (a) = GID_ADDR_IP_PREFIX;
374 else if (unformat (input, "%U", unformat_mac_address, mac))
376 mac_copy (gid_address_mac (a), mac);
377 gid_address_type (a) = GID_ADDR_MAC;
379 else if (unformat (input, "%U", unformat_nsh_address, &nsh))
381 nsh_copy (&gid_address_nsh (a), &nsh);
382 gid_address_type (a) = GID_ADDR_NSH;
391 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
393 u32 *action = va_arg (*args, u32 *);
396 if (unformat (input, "%s", &s))
398 if (!strcmp ((char *) s, "no-action"))
399 action[0] = LISP_NO_ACTION;
400 else if (!strcmp ((char *) s, "natively-forward"))
401 action[0] = LISP_FORWARD_NATIVE;
402 else if (!strcmp ((char *) s, "send-map-request"))
403 action[0] = LISP_SEND_MAP_REQUEST;
404 else if (!strcmp ((char *) s, "drop"))
405 action[0] = LISP_DROP;
408 clib_warning ("invalid action: '%s'", s);
409 action[0] = LISP_DROP;
420 format_hmac_key_id (u8 * s, va_list * args)
422 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
427 return format (0, "sha1");
428 case HMAC_SHA_256_128:
429 return format (0, "sha256");
438 format_negative_mapping_action (u8 * s, va_list * args)
440 lisp_action_e action = va_arg (*args, lisp_action_e);
445 s = format (s, "no-action");
447 case LISP_FORWARD_NATIVE:
448 s = format (s, "natively-forward");
450 case LISP_SEND_MAP_REQUEST:
451 s = format (s, "send-map-request");
455 s = format (s, "drop");
462 ip_address_size (const ip_address_t * a)
464 switch (ip_addr_version (a))
467 return sizeof (ip4_address_t);
470 return sizeof (ip6_address_t);
477 ip_version_to_size (u8 ver)
482 return sizeof (ip4_address_t);
485 return sizeof (ip6_address_t);
492 ip_version_to_max_plen (u8 ver)
506 always_inline lisp_afi_e
507 ip_version_to_iana_afi (u16 version)
522 ip_iana_afi_to_version (lisp_afi_e afi)
537 ip_address_size_to_write (ip_address_t * a)
539 return ip_address_size (a) + sizeof (u16);
543 ip_address_iana_afi (ip_address_t * a)
545 return ip_version_to_iana_afi (ip_addr_version (a));
549 ip_address_max_len (u8 version)
551 return version == IP4 ? 32 : 128;
555 ip4_address_size_to_put ()
557 // return sizeof(u16) + sizeof (ip4_address_t);
562 ip6_address_size_to_put ()
564 //return sizeof(u16) + sizeof (ip6_address_t);
569 ip4_address_put (u8 * b, ip4_address_t * a)
571 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
572 u8 *p = b + sizeof (u16);
573 clib_memcpy (p, a, sizeof (*a));
574 return ip4_address_size_to_put ();
578 ip6_address_put (u8 * b, ip6_address_t * a)
580 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
581 u8 *p = b + sizeof (u16);
582 clib_memcpy (p, a, sizeof (*a));
583 return ip6_address_size_to_put ();
587 ip_address_put (u8 * b, ip_address_t * a)
589 u32 len = ip_address_size (a);
590 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
591 u8 *p = b + sizeof (u16);
592 clib_memcpy (p, &ip_addr_addr (a), len);
593 return (len + sizeof (u16));
597 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
599 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
600 u8 size = ip_version_to_size (ip_addr_version (dst));
601 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
602 return (sizeof (u16) + size);
606 gid_to_dp_address (gid_address_t * g, dp_address_t * d)
608 switch (gid_address_type (g))
610 case GID_ADDR_SRC_DST:
611 switch (gid_address_sd_dst_type (g))
613 case FID_ADDR_IP_PREF:
614 ip_prefix_copy (&d->ippref, &gid_address_sd_dst_ippref (g));
615 d->type = FID_ADDR_IP_PREF;
618 mac_copy (&d->mac, &gid_address_sd_dst_mac (g));
619 d->type = FID_ADDR_MAC;
622 clib_warning ("Source/Dest address type %d not supported!",
623 gid_address_sd_dst_type (g));
627 case GID_ADDR_IP_PREFIX:
628 ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
629 d->type = FID_ADDR_IP_PREF;
632 mac_copy (&d->mac, &gid_address_mac (g));
633 d->type = FID_ADDR_MAC;
637 d->nsh = gid_address_nsh (g).spi << 8 | gid_address_nsh (g).si;
638 d->type = FID_ADDR_NSH;
644 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
646 lcaf_hdr_t *lh = offset;
647 lcaf->type = lh->type;
649 /* this is a bit of hack: since the LCAF Instance ID is the
650 only message that uses reserved2 field, we can set it here.
651 If any LCAF format starts using reserved2 field as well this needs
652 to be moved elsewhere */
653 lcaf_vni_len (lcaf) = lh->reserved2;
655 return sizeof (lh[0]);
659 iana_afi_to_fid_addr_type (u16 type)
665 return FID_ADDR_IP_PREF;
674 fid_addr_parse (u8 * p, fid_address_t * a)
676 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
677 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
678 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
680 switch (fid_addr_type (a))
683 return mac_parse (p, fid_addr_mac (a));
685 case FID_ADDR_IP_PREF:
686 return ip_address_parse (p, afi, ip_addr);
694 #define INC(dst, exp) \
697 if ((u16)~0 == _sum) \
709 nsh_parse (u8 * p, void *a)
711 lcaf_spi_hdr_t *h = (lcaf_spi_hdr_t *) p;
712 gid_address_t *g = a;
714 gid_address_type (g) = GID_ADDR_NSH;
715 gid_address_nsh_spi (g) = clib_net_to_host_u32 (LCAF_SPI_SI (h)) >> 8;
716 gid_address_nsh_si (g) = (u8) clib_net_to_host_u32 (LCAF_SPI_SI (h));
718 return sizeof (lcaf_spi_hdr_t);
722 nsh_cmp (void *a1, void *a2)
727 if (n1->spi != n2->spi)
729 if (n1->si != n2->si)
735 sd_parse (u8 * p, void *a)
737 lcaf_src_dst_hdr_t *sd_hdr;
738 gid_address_t *g = a;
740 fid_address_t *src = &gid_address_sd_src (g);
741 fid_address_t *dst = &gid_address_sd_dst (g);
743 gid_address_type (g) = GID_ADDR_SRC_DST;
745 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
746 size += sizeof (sd_hdr[0]);
748 INC (size, fid_addr_parse (p + size, src));
749 INC (size, fid_addr_parse (p + size, dst));
751 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
753 ip_prefix_t *ippref = &fid_addr_ippref (src);
754 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
756 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
758 ip_prefix_t *ippref = &fid_addr_ippref (dst);
759 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
765 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
768 u16 size = sizeof (u16); /* skip AFI */
770 size += lcaf_hdr_parse (p + size, &lcaf);
772 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
775 INC (size, sd_parse (p + size, a));
780 vni_parse (u8 * p, void *a)
783 gid_address_t *g = a;
786 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
787 size += sizeof (u32);
788 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
790 /* nested LCAFs are not supported except of src/dst with vni - to handle
791 * such case look at the next AFI and process src/dest LCAF separately */
792 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
793 if (LISP_AFI_LCAF == afi)
795 INC (size, try_parse_src_dst_lcaf (p + size, g));
798 INC (size, gid_address_parse (p + size, g));
804 no_addr_parse (u8 * p, void *a)
811 lcaf_parse (void *offset, gid_address_t * addr)
814 offset += sizeof (u16);
815 lcaf_t *lcaf = &gid_address_lcaf (addr);
817 u32 size = lcaf_hdr_parse (offset, lcaf);
818 u8 type = lcaf_type (lcaf);
820 if (!lcaf_parse_fcts[type])
822 clib_warning ("Unsupported LCAF type: %u", type);
825 INC (size, (*lcaf_parse_fcts[type]) (offset + size, lcaf));
826 return sizeof (u16) + size;
833 gid_address_free (vni_gid (v));
834 clib_mem_free (vni_gid (v));
838 no_addr_free (void *a)
850 gid_address_free (gid_address_t * a)
852 if (gid_address_type (a) != GID_ADDR_LCAF)
855 lcaf_t *lcaf = &gid_address_lcaf (a);
856 u8 lcaf_type = lcaf_type (lcaf);
857 (*lcaf_free_fcts[lcaf_type]) (lcaf);
861 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
863 memset (g, 0, sizeof (g[0]));
864 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
865 gid_address_ippref_len (g) = 32;
869 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
872 if (ip_addr_version (ip1) != ip_addr_version (ip2))
875 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
886 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
888 if (IP4 == ip_addr_version (src))
890 /* don't copy any garbe from the union */
891 memset (dst, 0, sizeof (*dst));
892 dst->ip.v4 = src->ip.v4;
897 clib_memcpy (dst, src, sizeof (ip_address_t));
902 ip_address_copy_addr (void *dst, const ip_address_t * src)
904 clib_memcpy (dst, src, ip_address_size (src));
908 ip_address_set (ip_address_t * dst, const void *src, u8 version)
910 clib_memcpy (dst, src, ip_version_to_size (version));
911 ip_addr_version (dst) = version;
915 ip_address_to_46 (const ip_address_t * addr,
916 ip46_address_t * a, fib_protocol_t * proto)
918 *proto = (IP4 == ip_addr_version (addr) ?
919 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
922 case FIB_PROTOCOL_IP4:
923 ip46_address_set_ip4 (a, &addr->ip.v4);
925 case FIB_PROTOCOL_IP6:
926 a->ip6 = addr->ip.v6;
935 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
946 mask = pow2_mask (preflen) << (32 - preflen);
947 mask = clib_host_to_net_u32 (mask);
948 ip4->data_u32 &= mask;
952 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
960 memset (mask_6, 0, sizeof (mask_6));
969 m = (u32 *) & mask_6[0];
971 for (j = 0; j < i0; j++)
978 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
981 for (j = 0; j < sizeof (mask_6); j++)
983 ip6->as_u8[j] &= mask_6[j];
988 ip_prefix_normalize (ip_prefix_t * a)
990 u8 preflen = ip_prefix_len (a);
992 switch (ip_prefix_version (a))
995 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
999 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
1008 ip_prefix_cast (gid_address_t * a)
1010 return &gid_address_ippref (a);
1014 ip_prefix_size_to_write (void *pref)
1016 ip_prefix_t *a = (ip_prefix_t *) pref;
1017 return ip_address_size_to_write (&ip_prefix_addr (a));
1021 ip_prefix_write (u8 * p, void *gid)
1023 gid_address_t *g = gid;
1024 ip_prefix_t *a = &gid_address_ippref (g);
1026 switch (ip_prefix_version (a))
1029 return ip4_address_put (p, &ip_prefix_v4 (a));
1032 return ip6_address_put (p, &ip_prefix_v6 (a));
1039 ip_prefix_length (void *a)
1041 return ip_prefix_len ((ip_prefix_t *) a);
1045 ip_prefix_copy (void *dst, void *src)
1047 clib_memcpy (dst, src, sizeof (ip_prefix_t));
1051 mac_copy (void *dst, void *src)
1053 clib_memcpy (dst, src, 6);
1057 sd_copy (void *dst, void *src)
1059 clib_memcpy (dst, src, sizeof (source_dest_t));
1063 nsh_copy (void *dst, void *src)
1065 clib_memcpy (dst, src, sizeof (nsh_t));
1069 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
1073 ip_prefix_normalize (p1);
1074 ip_prefix_normalize (p2);
1076 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
1079 if (ip_prefix_len (p1) < ip_prefix_len (p2))
1085 if (ip_prefix_len (p1) > ip_prefix_len (p2))
1093 no_addr_copy (void *dst, void *src)
1099 vni_copy (void *dst, void *src)
1104 clib_memcpy (vd, vs, sizeof (vd[0]));
1105 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
1106 gid_address_copy (vni_gid (vd), vni_gid (vs));
1110 lcaf_copy (void *dst, void *src)
1112 lcaf_t *lcaf_dst = dst;
1113 lcaf_t *lcaf_src = src;
1115 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
1116 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
1120 lcaf_length (void *a)
1126 mac_length (void *a)
1138 nsh_length (void *a)
1144 lcaf_cast (gid_address_t * a)
1146 return &gid_address_lcaf (a);
1150 mac_cast (gid_address_t * a)
1152 return &gid_address_mac (a);
1156 no_addr_cast (gid_address_t * a)
1162 sd_cast (gid_address_t * a)
1164 return &gid_address_sd (a);
1168 nsh_cast (gid_address_t * a)
1170 return &gid_address_nsh (a);
1174 no_addr_length (void *a)
1180 vni_length (void *a)
1183 return (sizeof (u32) /* VNI size */
1184 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1188 lcaf_write (u8 * p, void *a)
1192 u8 type = lcaf_type (lcaf);
1193 lcaf_hdr_t _h, *h = &_h;
1195 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1196 size += sizeof (u16);
1197 memset (h, 0, sizeof (h[0]));
1198 LCAF_TYPE (h) = type;
1199 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1200 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1202 clib_memcpy (p + size, h, sizeof (h[0]));
1203 size += sizeof (h[0]);
1204 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1206 if ((u16) ~ 0 == len)
1213 mac_write (u8 * p, void *a)
1215 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1216 clib_memcpy (p + sizeof (u16), a, 6);
1217 return mac_size_to_write (a);
1221 fid_addr_write (u8 * p, fid_address_t * a)
1223 switch (fid_addr_type (a))
1225 case FID_ADDR_IP_PREF:
1226 return ip_prefix_write (p, &fid_addr_ippref (a));
1229 return mac_write (p, &fid_addr_mac (a));
1238 fid_address_length (fid_address_t * a)
1240 switch (fid_addr_type (a))
1242 case FID_ADDR_IP_PREF:
1243 return ip_prefix_length (&fid_addr_ippref (a));
1253 sd_write (u8 * p, void *a)
1255 source_dest_t *sd = a;
1257 lcaf_hdr_t _h, *h = &_h;
1258 lcaf_src_dst_hdr_t sd_hdr;
1260 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1261 size += sizeof (u16);
1262 memset (h, 0, sizeof (h[0]));
1263 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1264 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1265 + fid_addr_size_to_write (&sd_src (sd))
1266 + fid_addr_size_to_write (&sd_dst (sd));
1267 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1269 clib_memcpy (p + size, h, sizeof (h[0]));
1270 size += sizeof (h[0]);
1272 memset (&sd_hdr, 0, sizeof (sd_hdr));
1273 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1274 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1275 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1276 size += sizeof (sd_hdr);
1278 u16 len = fid_addr_write (p + size, &sd_src (sd));
1279 if ((u16) ~ 0 == len)
1283 len = fid_addr_write (p + size, &sd_dst (sd));
1284 if ((u16) ~ 0 == len)
1292 nsh_write (u8 * p, void *a)
1296 gid_address_t *g = a;
1299 ASSERT (gid_address_type (g) == GID_ADDR_NSH);
1301 memset (&lcaf, 0, sizeof (lcaf));
1302 memset (&spi, 0, sizeof (spi));
1304 LCAF_TYPE (&lcaf) = LCAF_NSH;
1305 LCAF_LENGTH (&lcaf) = clib_host_to_net_u16 (sizeof (lcaf_spi_hdr_t));
1307 u32 s = clib_host_to_net_u32 (gid_address_nsh_spi (g) << 8 |
1308 gid_address_nsh_si (g));
1309 LCAF_SPI_SI (&spi) = s;
1311 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1312 size += sizeof (u16);
1314 clib_memcpy (p + size, &lcaf, sizeof (lcaf));
1315 size += sizeof (lcaf);
1317 clib_memcpy (p + size, &spi, sizeof (spi));
1318 size += sizeof (spi);
1324 vni_write (u8 * p, void *a)
1326 lcaf_hdr_t _h, *h = &_h;
1327 gid_address_t *g = a;
1330 /* put lcaf header */
1331 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1332 size += sizeof (u16);
1333 memset (h, 0, sizeof (h[0]));
1334 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1335 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1336 + gid_address_size_to_put_no_vni (g);
1337 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1338 LCAF_RES2 (h) = gid_address_vni_mask (g);
1340 /* put vni header */
1341 clib_memcpy (p + size, h, sizeof (h[0]));
1342 size += sizeof (h[0]);
1344 u32 *afip = (u32 *) (p + size);
1345 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1346 size += sizeof (u32);
1348 if (GID_ADDR_SRC_DST == gid_address_type (g))
1349 /* write src/dst LCAF */
1351 len = sd_write (p + size, g);
1352 if ((u16) ~ 0 == len)
1356 /* write the actual address */
1357 len = gid_address_put_no_vni (p + size, g);
1359 if ((u16) ~ 0 == len)
1366 no_addr_write (u8 * p, void *a)
1368 /* do nothing; return AFI field size */
1369 return sizeof (u16);
1373 no_addr_size_to_write (void *a)
1375 return sizeof (u16); /* AFI field length */
1379 fid_addr_size_to_write (fid_address_t * a)
1381 switch (fid_addr_type (a))
1383 case FID_ADDR_IP_PREF:
1384 return ip_prefix_size_to_write (a);
1387 return mac_size_to_write (a);
1396 vni_size_to_write (void *a)
1398 gid_address_t *g = a;
1400 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1401 + sizeof (lcaf_hdr_t);
1403 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1404 /* special case where nested LCAF is supported */
1405 return lcaf_size + sd_size_to_write (g);
1407 return lcaf_size + gid_address_size_to_put_no_vni (g);
1411 lcaf_size_to_write (void *a)
1413 lcaf_t *lcaf = (lcaf_t *) a;
1415 u8 type = lcaf_type (lcaf);
1417 size += sizeof (u16); /* AFI size */
1419 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1427 sd_size_to_write (void *a)
1429 source_dest_t *sd = a;
1431 + sizeof (lcaf_hdr_t)
1432 + sizeof (lcaf_src_dst_hdr_t)
1433 + fid_addr_size_to_write (&sd_src (sd))
1434 + fid_addr_size_to_write (&sd_dst (sd));
1438 mac_size_to_write (void *a)
1440 return sizeof (u16) + 6;
1444 nsh_size_to_write (void *a)
1446 return sizeof (u16) + sizeof (lcaf_hdr_t) + sizeof (lcaf_spi_hdr_t);
1450 gid_address_len (gid_address_t * a)
1452 gid_address_type_t type = gid_address_type (a);
1453 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1457 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1459 gid_address_type_t type = gid_address_type (gid);
1460 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1464 gid_address_put (u8 * b, gid_address_t * gid)
1466 if (0 != gid_address_vni (gid))
1467 return vni_write (b, gid);
1469 return gid_address_put_no_vni (b, gid);
1473 gid_address_size_to_put_no_vni (gid_address_t * gid)
1475 gid_address_type_t type = gid_address_type (gid);
1476 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1480 gid_address_size_to_put (gid_address_t * gid)
1482 if (0 != gid_address_vni (gid))
1483 return vni_size_to_write (gid);
1485 return gid_address_size_to_put_no_vni (gid);
1489 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1491 return (*cast_fcts[type]) (gid);
1495 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1497 gid_address_type_t type = gid_address_type (src);
1498 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1499 gid_address_type (dst) = type;
1500 gid_address_vni (dst) = gid_address_vni (src);
1501 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1505 mac_parse (u8 * offset, u8 * a)
1507 /* skip AFI field */
1508 offset += sizeof (u16);
1510 clib_memcpy (a, offset, 6);
1511 return sizeof (u16) + 6;
1515 gid_address_parse (u8 * offset, gid_address_t * a)
1522 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1523 * the gid address here */
1524 afi = clib_net_to_host_u16 (*((u16 *) offset));
1528 case LISP_AFI_NO_ADDR:
1530 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1533 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1534 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1535 /* this should be modified outside if needed */
1536 gid_address_ippref_len (a) = 32;
1539 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1540 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1541 /* this should be modified outside if needed */
1542 gid_address_ippref_len (a) = 128;
1545 gid_address_type (a) = GID_ADDR_LCAF;
1546 len = lcaf_parse (offset, a);
1549 len = mac_parse (offset, gid_address_mac (a));
1550 gid_address_type (a) = GID_ADDR_MAC;
1553 clib_warning ("LISP AFI %d not supported!", afi);
1556 return (len == (u16) ~ 0) ? ~0 : len;
1560 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1562 gid_address_ippref_len (dst) = ip_address_max_len (version);
1563 ip_address_set (&gid_address_ip (dst), src, version);
1567 no_addr_cmp (void *a1, void *a2)
1573 vni_cmp (void *a1, void *a2)
1578 if (vni_mask_len (v1) != vni_mask_len (v2))
1580 if (vni_vni (v1) != vni_vni (v2))
1582 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1586 mac_cmp (void *a1, void *a2)
1588 return memcmp (a1, a2, 6);
1592 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1594 if (fid_addr_type (a1) != fid_addr_type (a2))
1597 switch (fid_addr_type (a1))
1599 case FID_ADDR_IP_PREF:
1600 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1603 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1612 sd_cmp (void *a1, void *a2)
1614 source_dest_t *sd1 = a1;
1615 source_dest_t *sd2 = a2;
1617 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1619 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1624 /* Compare two gid_address_t.
1626 * -1: If they are from different afi
1627 * 0: Both address are the same
1628 * 1: Addr1 is bigger than addr2
1629 * 2: Addr2 is bigger than addr1
1632 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1634 lcaf_t *lcaf1, *lcaf2;
1638 if (gid_address_type (a1) != gid_address_type (a2))
1640 if (gid_address_vni (a1) != gid_address_vni (a2))
1643 /* TODO vni mask is not supported, disable comparing for now
1644 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1648 switch (gid_address_type (a1))
1650 case GID_ADDR_NO_ADDRESS:
1656 case GID_ADDR_IP_PREFIX:
1658 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1661 lcaf1 = &gid_address_lcaf (a1);
1662 lcaf2 = &gid_address_lcaf (a2);
1663 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1664 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1667 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1670 case GID_ADDR_SRC_DST:
1671 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1674 cmp = nsh_cmp (&gid_address_nsh (a1), &gid_address_nsh (a2));
1684 locator_parse (void *b, locator_t * loc)
1687 u8 status = 1; /* locator up */
1691 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1694 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1698 loc->state = status;
1700 loc->priority = LOC_PRIORITY (h);
1701 loc->weight = LOC_WEIGHT (h);
1702 loc->mpriority = LOC_MPRIORITY (h);
1703 loc->mweight = LOC_MWEIGHT (h);
1705 return sizeof (locator_hdr_t) + len;
1709 locator_copy (locator_t * dst, locator_t * src)
1711 /* TODO if gid become more complex, this will need to be changed! */
1712 clib_memcpy (dst, src, sizeof (*dst));
1714 gid_address_copy (&dst->address, &src->address);
1718 locator_cmp (locator_t * l1, locator_t * l2)
1721 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1724 if (l1->priority != l2->priority)
1726 if (l1->weight != l2->weight)
1728 if (l1->mpriority != l2->mpriority)
1730 if (l1->mweight != l2->mweight)
1736 locator_free (locator_t * l)
1739 gid_address_free (&l->address);
1743 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1745 memset (sd, 0, sizeof (*sd));
1746 gid_address_type (sd) = GID_ADDR_SRC_DST;
1747 gid_address_vni (sd) = gid_address_vni (dst);
1748 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1750 switch (gid_address_type (dst))
1752 case GID_ADDR_IP_PREFIX:
1753 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1754 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1755 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1756 &gid_address_ippref (src));
1757 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1758 &gid_address_ippref (dst));
1761 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1762 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1763 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1764 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1767 clib_warning ("Unsupported gid type %d while conversion!",
1768 gid_address_type (dst));
1774 * fd.io coding-style-patch-verification: ON
1777 * eval: (c-set-style "gnu")