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/ethernet/ethernet.h>
17 #include <vnet/lisp-cp/lisp_types.h>
19 static u16 gid_address_put_no_vni (u8 * b, gid_address_t * gid);
20 static u16 gid_address_size_to_put_no_vni (gid_address_t * gid);
21 static u16 fid_addr_size_to_write (fid_address_t * a);
23 u32 mac_parse (u8 * offset, u8 * a);
25 typedef u16 (*size_to_write_fct) (void *);
26 typedef void *(*cast_fct) (gid_address_t *);
27 typedef u16 (*serdes_fct) (u8 *, void *);
28 typedef u8 (*addr_len_fct) (void *);
29 typedef void (*copy_fct) (void *, void *);
30 typedef void (*free_fct) (void *);
31 typedef int (*cmp_fct) (void *, void *);
33 size_to_write_fct size_to_write_fcts[GID_ADDR_TYPES] =
34 { ip_prefix_size_to_write, lcaf_size_to_write, mac_size_to_write,
35 sd_size_to_write, nsh_size_to_write, 0 /* arp */ , no_addr_size_to_write
38 serdes_fct write_fcts[GID_ADDR_TYPES] =
39 { ip_prefix_write, lcaf_write, mac_write, sd_write, nsh_write, 0 /* arp */ ,
43 cast_fct cast_fcts[GID_ADDR_TYPES] =
44 { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast, nsh_cast, 0 /* arp */ ,
48 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
49 { ip_prefix_length, lcaf_length, mac_length, sd_length, nsh_length,
50 0 /* arp */ , no_addr_length
53 copy_fct copy_fcts[GID_ADDR_TYPES] =
54 { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy, nsh_copy, 0 /* arp */ ,
58 #define foreach_lcaf_type \
78 #define _(cond, name) \
79 u16 name ## _write (u8 * p, void * a); \
80 u16 name ## _parse (u8 * p, void * a); \
81 u16 name ## _size_to_write (void * a); \
82 void name ## _free (void * a); \
83 void name ## _copy (void * dst, void * src); \
84 u8 name ## _length (void * a); \
85 int name ## _cmp (void *, void *);
88 #define CONCAT(a,b) a##_##b
89 #define IF(c, t, e) CONCAT(IF, c)(t, e)
92 #define EXPAND_FCN(cond, fcn) \
94 cmp_fct lcaf_cmp_fcts[LCAF_TYPES] =
96 #define _(cond, name) \
97 EXPAND_FCN(cond, name##_cmp),
102 addr_len_fct lcaf_body_length_fcts[LCAF_TYPES] = {
103 #define _(cond, name) \
104 EXPAND_FCN(cond, name##_length),
109 copy_fct lcaf_copy_fcts[LCAF_TYPES] = {
110 #define _(cond, name) \
111 EXPAND_FCN(cond, name##_copy),
116 free_fct lcaf_free_fcts[LCAF_TYPES] = {
117 #define _(cond, name) \
118 EXPAND_FCN(cond, name##_free),
123 size_to_write_fct lcaf_size_to_write_fcts[LCAF_TYPES] = {
124 #define _(cond, name) \
125 EXPAND_FCN(cond, name##_size_to_write),
130 serdes_fct lcaf_write_fcts[LCAF_TYPES] = {
131 #define _(cond, name) \
132 EXPAND_FCN(cond, name##_write),
137 serdes_fct lcaf_parse_fcts[LCAF_TYPES] = {
138 #define _(cond, name) \
139 EXPAND_FCN(cond, name##_parse),
145 format_ip_address (u8 * s, va_list * args)
147 ip_address_t *a = va_arg (*args, ip_address_t *);
148 u8 ver = ip_addr_version (a);
151 return format (s, "%U", format_ip4_address, &ip_addr_v4 (a));
155 return format (s, "%U", format_ip6_address, &ip_addr_v6 (a));
159 clib_warning ("Can't format IP version %d!", ver);
165 unformat_ip_address (unformat_input_t * input, va_list * args)
167 ip_address_t *a = va_arg (*args, ip_address_t *);
169 clib_memset (a, 0, sizeof (*a));
170 if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (a)))
171 ip_addr_version (a) = IP4;
172 else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6 (a)))
173 ip_addr_version (a) = IP6;
180 format_ip_prefix (u8 * s, va_list * args)
182 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
183 return format (s, "%U/%d", format_ip_address, &ip_prefix_addr (a),
188 unformat_ip_prefix (unformat_input_t * input, va_list * args)
190 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
191 if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr (a),
194 if ((ip_prefix_version (a) == IP4 && 32 < ip_prefix_len (a)) ||
195 (ip_prefix_version (a) == IP6 && 128 < ip_prefix_length (a)))
197 clib_warning ("Prefix length to big: %d!", ip_prefix_len (a));
200 ip_prefix_normalize (a);
208 unformat_nsh_address (unformat_input_t * input, va_list * args)
210 nsh_t *a = va_arg (*args, nsh_t *);
211 return unformat (input, "SPI:%d SI:%d", &a->spi, &a->si);
215 format_nsh_address (u8 * s, va_list * args)
217 nsh_t *a = va_arg (*args, nsh_t *);
218 return format (s, "SPI:%d SI:%d", a->spi, a->si);
222 format_fid_nsh_address (u8 * s, va_list * args)
224 u32 *a = va_arg (*args, u32 *);
225 return format (s, "SPI:%d SI:%d", *a >> 8, *a & 0xff);
229 format_fid_address (u8 * s, va_list * args)
231 fid_address_t *a = va_arg (*args, fid_address_t *);
233 switch (fid_addr_type (a))
235 case FID_ADDR_IP_PREF:
236 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
238 return format (s, "%U", format_mac_address, &fid_addr_mac (a));
240 return format (s, "%U", format_fid_nsh_address, &fid_addr_nsh (a));
243 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
250 format_gid_address (u8 * s, va_list * args)
252 gid_address_t *a = va_arg (*args, gid_address_t *);
253 u8 type = gid_address_type (a);
256 case GID_ADDR_IP_PREFIX:
257 return format (s, "[%d] %U", gid_address_vni (a), format_ip_prefix,
258 &gid_address_ippref (a));
259 case GID_ADDR_SRC_DST:
260 return format (s, "[%d] %U|%U", gid_address_vni (a),
261 format_fid_address, &gid_address_sd_src (a),
262 format_fid_address, &gid_address_sd_dst (a));
264 return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
265 &gid_address_mac (a));
268 return format (s, "[%d, %U]", gid_address_arp_ndp_bd (a),
269 format_ip_address, &gid_address_arp_ndp_ip (a));
271 return format (s, "%U", format_nsh_address, &gid_address_nsh (a));
274 clib_warning ("Can't format gid type %d", type);
281 unformat_fid_address (unformat_input_t * i, va_list * args)
283 fid_address_t *a = va_arg (*args, fid_address_t *);
288 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
290 fid_addr_type (a) = FID_ADDR_IP_PREF;
291 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
293 else if (unformat (i, "%U", unformat_mac_address, mac))
295 fid_addr_type (a) = FID_ADDR_MAC;
296 mac_copy (fid_addr_mac (a), mac);
298 else if (unformat (i, "%U", unformat_nsh_address, &nsh))
300 fid_addr_type (a) = FID_ADDR_NSH;
301 nsh_copy (&fid_addr_nsh (a), &nsh);
310 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
312 u32 *key_id = va_arg (*args, u32 *);
315 if (unformat (input, "%s", &s))
317 if (!strcmp ((char *) s, "sha1"))
318 key_id[0] = HMAC_SHA_1_96;
319 else if (!strcmp ((char *) s, "sha256"))
320 key_id[0] = HMAC_SHA_256_128;
323 clib_warning ("invalid key_id: '%s'", s);
324 key_id[0] = HMAC_NO_KEY;
335 unformat_gid_address (unformat_input_t * input, va_list * args)
337 gid_address_t *a = va_arg (*args, gid_address_t *);
340 fid_address_t sim1, sim2;
343 clib_memset (&ippref, 0, sizeof (ippref));
344 clib_memset (&sim1, 0, sizeof (sim1));
345 clib_memset (&sim2, 0, sizeof (sim2));
347 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
348 unformat_fid_address, &sim2))
350 gid_address_sd_src (a) = sim1;
351 gid_address_sd_dst (a) = sim2;
352 gid_address_type (a) = GID_ADDR_SRC_DST;
354 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
356 ip_prefix_copy (&gid_address_ippref (a), &ippref);
357 gid_address_type (a) = GID_ADDR_IP_PREFIX;
359 else if (unformat (input, "%U", unformat_mac_address, mac))
361 mac_copy (gid_address_mac (a), mac);
362 gid_address_type (a) = GID_ADDR_MAC;
364 else if (unformat (input, "%U", unformat_nsh_address, &nsh))
366 nsh_copy (&gid_address_nsh (a), &nsh);
367 gid_address_type (a) = GID_ADDR_NSH;
376 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
378 u32 *action = va_arg (*args, u32 *);
381 if (unformat (input, "%s", &s))
383 if (!strcmp ((char *) s, "no-action"))
384 action[0] = LISP_NO_ACTION;
385 else if (!strcmp ((char *) s, "natively-forward"))
386 action[0] = LISP_FORWARD_NATIVE;
387 else if (!strcmp ((char *) s, "send-map-request"))
388 action[0] = LISP_SEND_MAP_REQUEST;
389 else if (!strcmp ((char *) s, "drop"))
390 action[0] = LISP_DROP;
393 clib_warning ("invalid action: '%s'", s);
394 action[0] = LISP_DROP;
405 format_hmac_key_id (u8 * s, va_list * args)
407 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
412 return format (0, "sha1");
413 case HMAC_SHA_256_128:
414 return format (0, "sha256");
423 format_negative_mapping_action (u8 * s, va_list * args)
425 lisp_action_e action = va_arg (*args, lisp_action_e);
430 s = format (s, "no-action");
432 case LISP_FORWARD_NATIVE:
433 s = format (s, "natively-forward");
435 case LISP_SEND_MAP_REQUEST:
436 s = format (s, "send-map-request");
440 s = format (s, "drop");
447 ip_address_size (const ip_address_t * a)
449 switch (ip_addr_version (a))
452 return sizeof (ip4_address_t);
455 return sizeof (ip6_address_t);
462 ip_version_to_size (u8 ver)
467 return sizeof (ip4_address_t);
470 return sizeof (ip6_address_t);
477 ip_version_to_max_plen (u8 ver)
491 always_inline lisp_afi_e
492 ip_version_to_iana_afi (u16 version)
507 ip_iana_afi_to_version (lisp_afi_e afi)
522 ip_address_size_to_write (ip_address_t * a)
524 return ip_address_size (a) + sizeof (u16);
528 ip_address_iana_afi (ip_address_t * a)
530 return ip_version_to_iana_afi (ip_addr_version (a));
534 ip_address_max_len (u8 version)
536 return version == IP4 ? 32 : 128;
540 ip4_address_size_to_put ()
542 // return sizeof(u16) + sizeof (ip4_address_t);
547 ip6_address_size_to_put ()
549 //return sizeof(u16) + sizeof (ip6_address_t);
554 ip4_address_put (u8 * b, ip4_address_t * a)
556 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
557 u8 *p = b + sizeof (u16);
558 clib_memcpy (p, a, sizeof (*a));
559 return ip4_address_size_to_put ();
563 ip6_address_put (u8 * b, ip6_address_t * a)
565 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
566 u8 *p = b + sizeof (u16);
567 clib_memcpy (p, a, sizeof (*a));
568 return ip6_address_size_to_put ();
572 ip_address_put (u8 * b, ip_address_t * a)
574 u32 len = ip_address_size (a);
575 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
576 u8 *p = b + sizeof (u16);
577 clib_memcpy (p, &ip_addr_addr (a), len);
578 return (len + sizeof (u16));
582 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
584 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
585 u8 size = ip_version_to_size (ip_addr_version (dst));
586 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
587 return (sizeof (u16) + size);
591 gid_to_dp_address (gid_address_t * g, dp_address_t * d)
593 switch (gid_address_type (g))
595 case GID_ADDR_SRC_DST:
596 switch (gid_address_sd_dst_type (g))
598 case FID_ADDR_IP_PREF:
599 ip_prefix_copy (&d->ippref, &gid_address_sd_dst_ippref (g));
600 d->type = FID_ADDR_IP_PREF;
603 mac_copy (&d->mac, &gid_address_sd_dst_mac (g));
604 d->type = FID_ADDR_MAC;
607 clib_warning ("Source/Dest address type %d not supported!",
608 gid_address_sd_dst_type (g));
612 case GID_ADDR_IP_PREFIX:
613 ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
614 d->type = FID_ADDR_IP_PREF;
617 mac_copy (&d->mac, &gid_address_mac (g));
618 d->type = FID_ADDR_MAC;
622 d->nsh = gid_address_nsh (g).spi << 8 | gid_address_nsh (g).si;
623 d->type = FID_ADDR_NSH;
629 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
631 lcaf_hdr_t *lh = offset;
632 lcaf->type = lh->type;
634 /* this is a bit of hack: since the LCAF Instance ID is the
635 only message that uses reserved2 field, we can set it here.
636 If any LCAF format starts using reserved2 field as well this needs
637 to be moved elsewhere */
638 lcaf_vni_len (lcaf) = lh->reserved2;
640 return sizeof (lh[0]);
644 iana_afi_to_fid_addr_type (u16 type)
650 return FID_ADDR_IP_PREF;
659 fid_addr_parse (u8 * p, fid_address_t * a)
661 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
662 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
663 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
665 switch (fid_addr_type (a))
668 return mac_parse (p, fid_addr_mac (a));
670 case FID_ADDR_IP_PREF:
671 return ip_address_parse (p, afi, ip_addr);
679 #define INC(dst, exp) \
682 if ((u16)~0 == _sum) \
694 nsh_parse (u8 * p, void *a)
696 lcaf_spi_hdr_t *h = (lcaf_spi_hdr_t *) p;
697 gid_address_t *g = a;
699 gid_address_type (g) = GID_ADDR_NSH;
700 gid_address_nsh_spi (g) = clib_net_to_host_u32 (LCAF_SPI_SI (h)) >> 8;
701 gid_address_nsh_si (g) = (u8) clib_net_to_host_u32 (LCAF_SPI_SI (h));
703 return sizeof (lcaf_spi_hdr_t);
707 nsh_cmp (void *a1, void *a2)
712 if (n1->spi != n2->spi)
714 if (n1->si != n2->si)
720 sd_parse (u8 * p, void *a)
722 lcaf_src_dst_hdr_t *sd_hdr;
723 gid_address_t *g = a;
725 fid_address_t *src = &gid_address_sd_src (g);
726 fid_address_t *dst = &gid_address_sd_dst (g);
728 gid_address_type (g) = GID_ADDR_SRC_DST;
730 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
731 size += sizeof (sd_hdr[0]);
733 INC (size, fid_addr_parse (p + size, src));
734 INC (size, fid_addr_parse (p + size, dst));
736 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
738 ip_prefix_t *ippref = &fid_addr_ippref (src);
739 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
741 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
743 ip_prefix_t *ippref = &fid_addr_ippref (dst);
744 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
750 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
753 u16 size = sizeof (u16); /* skip AFI */
755 size += lcaf_hdr_parse (p + size, &lcaf);
757 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
760 INC (size, sd_parse (p + size, a));
765 vni_parse (u8 * p, void *a)
768 gid_address_t *g = a;
771 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
772 size += sizeof (u32);
773 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
775 /* nested LCAFs are not supported except of src/dst with vni - to handle
776 * such case look at the next AFI and process src/dest LCAF separately */
777 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
778 if (LISP_AFI_LCAF == afi)
780 INC (size, try_parse_src_dst_lcaf (p + size, g));
783 INC (size, gid_address_parse (p + size, g));
789 no_addr_parse (u8 * p, void *a)
796 lcaf_parse (void *offset, gid_address_t * addr)
799 offset += sizeof (u16);
800 lcaf_t *lcaf = &gid_address_lcaf (addr);
802 u32 size = lcaf_hdr_parse (offset, lcaf);
803 u8 type = lcaf_type (lcaf);
805 if (!lcaf_parse_fcts[type])
807 clib_warning ("Unsupported LCAF type: %u", type);
810 INC (size, (*lcaf_parse_fcts[type]) (offset + size, lcaf));
811 return sizeof (u16) + size;
818 gid_address_free (vni_gid (v));
819 clib_mem_free (vni_gid (v));
823 no_addr_free (void *a)
835 gid_address_free (gid_address_t * a)
837 if (gid_address_type (a) != GID_ADDR_LCAF)
840 lcaf_t *lcaf = &gid_address_lcaf (a);
841 u8 lcaf_type = lcaf_type (lcaf);
842 (*lcaf_free_fcts[lcaf_type]) (lcaf);
846 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
848 clib_memset (g, 0, sizeof (g[0]));
849 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
850 gid_address_ippref_len (g) = 32;
854 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
857 if (ip_addr_version (ip1) != ip_addr_version (ip2))
860 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
871 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
873 if (IP4 == ip_addr_version (src))
875 /* don't copy any garbage from the union */
876 clib_memset (dst, 0, sizeof (*dst));
877 dst->ip.v4 = src->ip.v4;
882 clib_memcpy (dst, src, sizeof (ip_address_t));
887 ip_address_copy_addr (void *dst, const ip_address_t * src)
889 clib_memcpy (dst, src, ip_address_size (src));
893 ip_address_set (ip_address_t * dst, const void *src, u8 version)
895 clib_memcpy (dst, src, ip_version_to_size (version));
896 ip_addr_version (dst) = version;
900 ip_address_to_46 (const ip_address_t * addr,
901 ip46_address_t * a, fib_protocol_t * proto)
903 *proto = (IP4 == ip_addr_version (addr) ?
904 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
907 case FIB_PROTOCOL_IP4:
908 ip46_address_set_ip4 (a, &addr->ip.v4);
910 case FIB_PROTOCOL_IP6:
911 a->ip6 = addr->ip.v6;
920 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
931 mask = pow2_mask (preflen) << (32 - preflen);
932 mask = clib_host_to_net_u32 (mask);
933 ip4->data_u32 &= mask;
937 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
945 clib_memset (mask_6, 0, sizeof (mask_6));
954 m = (u32 *) & mask_6[0];
956 for (j = 0; j < i0; j++)
963 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
966 for (j = 0; j < sizeof (mask_6); j++)
968 ip6->as_u8[j] &= mask_6[j];
973 ip_prefix_normalize (ip_prefix_t * a)
975 u8 preflen = ip_prefix_len (a);
977 switch (ip_prefix_version (a))
980 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
984 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
993 ip_prefix_cast (gid_address_t * a)
995 return &gid_address_ippref (a);
999 ip_prefix_size_to_write (void *pref)
1001 ip_prefix_t *a = (ip_prefix_t *) pref;
1002 return ip_address_size_to_write (&ip_prefix_addr (a));
1006 ip_prefix_write (u8 * p, void *gid)
1008 gid_address_t *g = gid;
1009 ip_prefix_t *a = &gid_address_ippref (g);
1011 switch (ip_prefix_version (a))
1014 return ip4_address_put (p, &ip_prefix_v4 (a));
1017 return ip6_address_put (p, &ip_prefix_v6 (a));
1024 ip_prefix_length (void *a)
1026 return ip_prefix_len ((ip_prefix_t *) a);
1030 ip_prefix_copy (void *dst, void *src)
1032 clib_memcpy (dst, src, sizeof (ip_prefix_t));
1036 mac_copy (void *dst, void *src)
1038 clib_memcpy (dst, src, 6);
1042 sd_copy (void *dst, void *src)
1044 clib_memcpy (dst, src, sizeof (source_dest_t));
1048 nsh_copy (void *dst, void *src)
1050 clib_memcpy (dst, src, sizeof (nsh_t));
1054 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
1058 ip_prefix_normalize (p1);
1059 ip_prefix_normalize (p2);
1061 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
1064 if (ip_prefix_len (p1) < ip_prefix_len (p2))
1070 if (ip_prefix_len (p1) > ip_prefix_len (p2))
1078 no_addr_copy (void *dst, void *src)
1084 vni_copy (void *dst, void *src)
1089 clib_memcpy (vd, vs, sizeof (vd[0]));
1090 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
1091 gid_address_copy (vni_gid (vd), vni_gid (vs));
1095 lcaf_copy (void *dst, void *src)
1097 lcaf_t *lcaf_dst = dst;
1098 lcaf_t *lcaf_src = src;
1100 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
1101 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
1105 lcaf_length (void *a)
1111 mac_length (void *a)
1123 nsh_length (void *a)
1129 lcaf_cast (gid_address_t * a)
1131 return &gid_address_lcaf (a);
1135 mac_cast (gid_address_t * a)
1137 return &gid_address_mac (a);
1141 no_addr_cast (gid_address_t * a)
1147 sd_cast (gid_address_t * a)
1149 return &gid_address_sd (a);
1153 nsh_cast (gid_address_t * a)
1155 return &gid_address_nsh (a);
1159 no_addr_length (void *a)
1165 vni_length (void *a)
1168 return (sizeof (u32) /* VNI size */
1169 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1173 lcaf_write (u8 * p, void *a)
1177 u8 type = lcaf_type (lcaf);
1178 lcaf_hdr_t _h, *h = &_h;
1180 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1181 size += sizeof (u16);
1182 clib_memset (h, 0, sizeof (h[0]));
1183 LCAF_TYPE (h) = type;
1184 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1185 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1187 clib_memcpy (p + size, h, sizeof (h[0]));
1188 size += sizeof (h[0]);
1189 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1191 if ((u16) ~ 0 == len)
1198 mac_write (u8 * p, void *a)
1200 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1201 clib_memcpy (p + sizeof (u16), a, 6);
1202 return mac_size_to_write (a);
1206 fid_addr_write (u8 * p, fid_address_t * a)
1208 switch (fid_addr_type (a))
1210 case FID_ADDR_IP_PREF:
1211 return ip_prefix_write (p, &fid_addr_ippref (a));
1214 return mac_write (p, &fid_addr_mac (a));
1223 fid_address_length (fid_address_t * a)
1225 switch (fid_addr_type (a))
1227 case FID_ADDR_IP_PREF:
1228 return ip_prefix_length (&fid_addr_ippref (a));
1238 sd_write (u8 * p, void *a)
1240 source_dest_t *sd = a;
1242 lcaf_hdr_t _h, *h = &_h;
1243 lcaf_src_dst_hdr_t sd_hdr;
1245 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1246 size += sizeof (u16);
1247 clib_memset (h, 0, sizeof (h[0]));
1248 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1249 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1250 + fid_addr_size_to_write (&sd_src (sd))
1251 + fid_addr_size_to_write (&sd_dst (sd));
1252 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1254 clib_memcpy (p + size, h, sizeof (h[0]));
1255 size += sizeof (h[0]);
1257 clib_memset (&sd_hdr, 0, sizeof (sd_hdr));
1258 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1259 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1260 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1261 size += sizeof (sd_hdr);
1263 u16 len = fid_addr_write (p + size, &sd_src (sd));
1264 if ((u16) ~ 0 == len)
1268 len = fid_addr_write (p + size, &sd_dst (sd));
1269 if ((u16) ~ 0 == len)
1277 nsh_write (u8 * p, void *a)
1281 gid_address_t *g = a;
1284 ASSERT (gid_address_type (g) == GID_ADDR_NSH);
1286 clib_memset (&lcaf, 0, sizeof (lcaf));
1287 clib_memset (&spi, 0, sizeof (spi));
1289 LCAF_TYPE (&lcaf) = LCAF_NSH;
1290 LCAF_LENGTH (&lcaf) = clib_host_to_net_u16 (sizeof (lcaf_spi_hdr_t));
1292 u32 s = clib_host_to_net_u32 (gid_address_nsh_spi (g) << 8 |
1293 gid_address_nsh_si (g));
1294 LCAF_SPI_SI (&spi) = s;
1296 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1297 size += sizeof (u16);
1299 clib_memcpy (p + size, &lcaf, sizeof (lcaf));
1300 size += sizeof (lcaf);
1302 clib_memcpy (p + size, &spi, sizeof (spi));
1303 size += sizeof (spi);
1309 vni_write (u8 * p, void *a)
1311 lcaf_hdr_t _h, *h = &_h;
1312 gid_address_t *g = a;
1315 /* put lcaf header */
1316 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1317 size += sizeof (u16);
1318 clib_memset (h, 0, sizeof (h[0]));
1319 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1320 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1321 + gid_address_size_to_put_no_vni (g);
1322 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1323 LCAF_RES2 (h) = gid_address_vni_mask (g);
1325 /* put vni header */
1326 clib_memcpy (p + size, h, sizeof (h[0]));
1327 size += sizeof (h[0]);
1329 u32 *afip = (u32 *) (p + size);
1330 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1331 size += sizeof (u32);
1333 if (GID_ADDR_SRC_DST == gid_address_type (g))
1334 /* write src/dst LCAF */
1336 len = sd_write (p + size, g);
1337 if ((u16) ~ 0 == len)
1341 /* write the actual address */
1342 len = gid_address_put_no_vni (p + size, g);
1344 if ((u16) ~ 0 == len)
1351 no_addr_write (u8 * p, void *a)
1353 /* do nothing; return AFI field size */
1354 return sizeof (u16);
1358 no_addr_size_to_write (void *a)
1360 return sizeof (u16); /* AFI field length */
1364 fid_addr_size_to_write (fid_address_t * a)
1366 switch (fid_addr_type (a))
1368 case FID_ADDR_IP_PREF:
1369 return ip_prefix_size_to_write (a);
1372 return mac_size_to_write (a);
1381 vni_size_to_write (void *a)
1383 gid_address_t *g = a;
1385 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1386 + sizeof (lcaf_hdr_t);
1388 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1389 /* special case where nested LCAF is supported */
1390 return lcaf_size + sd_size_to_write (g);
1392 return lcaf_size + gid_address_size_to_put_no_vni (g);
1396 lcaf_size_to_write (void *a)
1398 lcaf_t *lcaf = (lcaf_t *) a;
1400 u8 type = lcaf_type (lcaf);
1402 size += sizeof (u16); /* AFI size */
1404 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1412 sd_size_to_write (void *a)
1414 source_dest_t *sd = a;
1416 + sizeof (lcaf_hdr_t)
1417 + sizeof (lcaf_src_dst_hdr_t)
1418 + fid_addr_size_to_write (&sd_src (sd))
1419 + fid_addr_size_to_write (&sd_dst (sd));
1423 mac_size_to_write (void *a)
1425 return sizeof (u16) + 6;
1429 nsh_size_to_write (void *a)
1431 return sizeof (u16) + sizeof (lcaf_hdr_t) + sizeof (lcaf_spi_hdr_t);
1435 gid_address_len (gid_address_t * a)
1437 gid_address_type_t type = gid_address_type (a);
1438 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1442 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1444 gid_address_type_t type = gid_address_type (gid);
1445 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1449 gid_address_put (u8 * b, gid_address_t * gid)
1451 if (0 != gid_address_vni (gid))
1452 return vni_write (b, gid);
1454 return gid_address_put_no_vni (b, gid);
1458 gid_address_size_to_put_no_vni (gid_address_t * gid)
1460 gid_address_type_t type = gid_address_type (gid);
1461 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1465 gid_address_size_to_put (gid_address_t * gid)
1467 if (0 != gid_address_vni (gid))
1468 return vni_size_to_write (gid);
1470 return gid_address_size_to_put_no_vni (gid);
1474 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1476 return (*cast_fcts[type]) (gid);
1480 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1482 gid_address_type_t type = gid_address_type (src);
1483 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1484 gid_address_type (dst) = type;
1485 gid_address_vni (dst) = gid_address_vni (src);
1486 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1490 mac_parse (u8 * offset, u8 * a)
1492 /* skip AFI field */
1493 offset += sizeof (u16);
1495 clib_memcpy (a, offset, 6);
1496 return sizeof (u16) + 6;
1500 gid_address_parse (u8 * offset, gid_address_t * a)
1507 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1508 * the gid address here */
1509 afi = clib_net_to_host_u16 (*((u16 *) offset));
1513 case LISP_AFI_NO_ADDR:
1515 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1518 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1519 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1520 /* this should be modified outside if needed */
1521 gid_address_ippref_len (a) = 32;
1524 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1525 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1526 /* this should be modified outside if needed */
1527 gid_address_ippref_len (a) = 128;
1530 gid_address_type (a) = GID_ADDR_LCAF;
1531 len = lcaf_parse (offset, a);
1534 len = mac_parse (offset, gid_address_mac (a));
1535 gid_address_type (a) = GID_ADDR_MAC;
1538 clib_warning ("LISP AFI %d not supported!", afi);
1541 return (len == (u16) ~ 0) ? ~0 : len;
1545 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1547 gid_address_ippref_len (dst) = ip_address_max_len (version);
1548 ip_address_set (&gid_address_ip (dst), src, version);
1552 no_addr_cmp (void *a1, void *a2)
1558 vni_cmp (void *a1, void *a2)
1563 if (vni_mask_len (v1) != vni_mask_len (v2))
1565 if (vni_vni (v1) != vni_vni (v2))
1567 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1571 mac_cmp (void *a1, void *a2)
1573 return memcmp (a1, a2, 6);
1577 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1579 if (fid_addr_type (a1) != fid_addr_type (a2))
1582 switch (fid_addr_type (a1))
1584 case FID_ADDR_IP_PREF:
1585 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1588 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1597 sd_cmp (void *a1, void *a2)
1599 source_dest_t *sd1 = a1;
1600 source_dest_t *sd2 = a2;
1602 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1604 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1609 /* Compare two gid_address_t.
1611 * -1: If they are from different afi
1612 * 0: Both address are the same
1613 * 1: Addr1 is bigger than addr2
1614 * 2: Addr2 is bigger than addr1
1617 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1619 lcaf_t *lcaf1, *lcaf2;
1623 if (gid_address_type (a1) != gid_address_type (a2))
1625 if (gid_address_vni (a1) != gid_address_vni (a2))
1628 /* TODO vni mask is not supported, disable comparing for now
1629 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1633 switch (gid_address_type (a1))
1635 case GID_ADDR_NO_ADDRESS:
1641 case GID_ADDR_IP_PREFIX:
1643 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1646 lcaf1 = &gid_address_lcaf (a1);
1647 lcaf2 = &gid_address_lcaf (a2);
1648 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1649 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1652 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1655 case GID_ADDR_SRC_DST:
1656 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1659 cmp = nsh_cmp (&gid_address_nsh (a1), &gid_address_nsh (a2));
1669 locator_parse (void *b, locator_t * loc)
1672 u8 status = 1; /* locator up */
1676 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1679 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1683 loc->state = status;
1686 loc->priority = LOC_PRIORITY (h);
1687 loc->weight = LOC_WEIGHT (h);
1688 loc->mpriority = LOC_MPRIORITY (h);
1689 loc->mweight = LOC_MWEIGHT (h);
1691 return sizeof (locator_hdr_t) + len;
1695 locator_copy (locator_t * dst, locator_t * src)
1697 /* TODO if gid become more complex, this will need to be changed! */
1698 clib_memcpy (dst, src, sizeof (*dst));
1700 gid_address_copy (&dst->address, &src->address);
1704 locator_cmp (locator_t * l1, locator_t * l2)
1707 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1710 if (l1->priority != l2->priority)
1712 if (l1->weight != l2->weight)
1714 if (l1->mpriority != l2->mpriority)
1716 if (l1->mweight != l2->mweight)
1722 locator_free (locator_t * l)
1725 gid_address_free (&l->address);
1729 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1731 clib_memset (sd, 0, sizeof (*sd));
1732 gid_address_type (sd) = GID_ADDR_SRC_DST;
1733 gid_address_vni (sd) = gid_address_vni (dst);
1734 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1736 switch (gid_address_type (dst))
1738 case GID_ADDR_IP_PREFIX:
1739 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1740 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1741 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1742 &gid_address_ippref (src));
1743 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1744 &gid_address_ippref (dst));
1747 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1748 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1749 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1750 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1753 clib_warning ("Unsupported gid type %d while conversion!",
1754 gid_address_type (dst));
1760 * fd.io coding-style-patch-verification: ON
1763 * eval: (c-set-style "gnu")