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_address (u8 * s, va_list * args)
239 fid_address_t *a = va_arg (*args, fid_address_t *);
241 switch (fid_addr_type (a))
243 case FID_ADDR_IP_PREF:
244 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
246 return format (s, "%U", format_mac_address, &fid_addr_mac (a));
248 return format (s, "%U", format_nsh_address, &fid_addr_nsh (a));
251 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
258 format_gid_address (u8 * s, va_list * args)
260 gid_address_t *a = va_arg (*args, gid_address_t *);
261 u8 type = gid_address_type (a);
264 case GID_ADDR_IP_PREFIX:
265 return format (s, "[%d] %U", gid_address_vni (a), format_ip_prefix,
266 &gid_address_ippref (a));
267 case GID_ADDR_SRC_DST:
268 return format (s, "[%d] %U|%U", gid_address_vni (a),
269 format_fid_address, &gid_address_sd_src (a),
270 format_fid_address, &gid_address_sd_dst (a));
272 return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
273 &gid_address_mac (a));
275 return format (s, "[%d, %U]", gid_address_arp_bd (a),
276 format_ip4_address, &gid_address_arp_ip4 (a));
278 return format (s, "%U", format_nsh_address, &gid_address_nsh (a));
281 clib_warning ("Can't format gid type %d", type);
288 unformat_fid_address (unformat_input_t * i, va_list * args)
290 fid_address_t *a = va_arg (*args, fid_address_t *);
295 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
297 fid_addr_type (a) = FID_ADDR_IP_PREF;
298 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
300 else if (unformat (i, "%U", unformat_mac_address, mac))
302 fid_addr_type (a) = FID_ADDR_MAC;
303 mac_copy (fid_addr_mac (a), mac);
305 else if (unformat (i, "%U", unformat_nsh_address, &nsh))
307 fid_addr_type (a) = FID_ADDR_NSH;
308 nsh_copy (&fid_addr_nsh (a), &nsh);
317 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
319 u32 *key_id = va_arg (*args, u32 *);
322 if (unformat (input, "%s", &s))
324 if (!strcmp ((char *) s, "sha1"))
325 key_id[0] = HMAC_SHA_1_96;
326 else if (!strcmp ((char *) s, "sha256"))
327 key_id[0] = HMAC_SHA_256_128;
330 clib_warning ("invalid key_id: '%s'", s);
331 key_id[0] = HMAC_NO_KEY;
342 unformat_gid_address (unformat_input_t * input, va_list * args)
344 gid_address_t *a = va_arg (*args, gid_address_t *);
347 fid_address_t sim1, sim2;
350 memset (&ippref, 0, sizeof (ippref));
351 memset (&sim1, 0, sizeof (sim1));
352 memset (&sim2, 0, sizeof (sim2));
354 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
355 unformat_fid_address, &sim2))
357 gid_address_sd_src (a) = sim1;
358 gid_address_sd_dst (a) = sim2;
359 gid_address_type (a) = GID_ADDR_SRC_DST;
361 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
363 ip_prefix_copy (&gid_address_ippref (a), &ippref);
364 gid_address_type (a) = GID_ADDR_IP_PREFIX;
366 else if (unformat (input, "%U", unformat_mac_address, mac))
368 mac_copy (gid_address_mac (a), mac);
369 gid_address_type (a) = GID_ADDR_MAC;
371 else if (unformat (input, "%U", unformat_nsh_address, &nsh))
373 nsh_copy (&gid_address_nsh (a), &nsh);
374 gid_address_type (a) = GID_ADDR_NSH;
383 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
385 u32 *action = va_arg (*args, u32 *);
388 if (unformat (input, "%s", &s))
390 if (!strcmp ((char *) s, "no-action"))
391 action[0] = LISP_NO_ACTION;
392 else if (!strcmp ((char *) s, "natively-forward"))
393 action[0] = LISP_FORWARD_NATIVE;
394 else if (!strcmp ((char *) s, "send-map-request"))
395 action[0] = LISP_SEND_MAP_REQUEST;
396 else if (!strcmp ((char *) s, "drop"))
397 action[0] = LISP_DROP;
400 clib_warning ("invalid action: '%s'", s);
401 action[0] = LISP_DROP;
412 format_hmac_key_id (u8 * s, va_list * args)
414 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
419 return format (0, "sha1");
420 case HMAC_SHA_256_128:
421 return format (0, "sha256");
430 format_negative_mapping_action (u8 * s, va_list * args)
432 lisp_action_e action = va_arg (*args, lisp_action_e);
437 s = format (s, "no-action");
439 case LISP_FORWARD_NATIVE:
440 s = format (s, "natively-forward");
442 case LISP_SEND_MAP_REQUEST:
443 s = format (s, "send-map-request");
447 s = format (s, "drop");
454 ip_address_size (const ip_address_t * a)
456 switch (ip_addr_version (a))
459 return sizeof (ip4_address_t);
462 return sizeof (ip6_address_t);
469 ip_version_to_size (u8 ver)
474 return sizeof (ip4_address_t);
477 return sizeof (ip6_address_t);
484 ip_version_to_max_plen (u8 ver)
498 always_inline lisp_afi_e
499 ip_version_to_iana_afi (u16 version)
514 ip_iana_afi_to_version (lisp_afi_e afi)
529 ip_address_size_to_write (ip_address_t * a)
531 return ip_address_size (a) + sizeof (u16);
535 ip_address_iana_afi (ip_address_t * a)
537 return ip_version_to_iana_afi (ip_addr_version (a));
541 ip_address_max_len (u8 version)
543 return version == IP4 ? 32 : 128;
547 ip4_address_size_to_put ()
549 // return sizeof(u16) + sizeof (ip4_address_t);
554 ip6_address_size_to_put ()
556 //return sizeof(u16) + sizeof (ip6_address_t);
561 ip4_address_put (u8 * b, ip4_address_t * a)
563 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
564 u8 *p = b + sizeof (u16);
565 clib_memcpy (p, a, sizeof (*a));
566 return ip4_address_size_to_put ();
570 ip6_address_put (u8 * b, ip6_address_t * a)
572 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
573 u8 *p = b + sizeof (u16);
574 clib_memcpy (p, a, sizeof (*a));
575 return ip6_address_size_to_put ();
579 ip_address_put (u8 * b, ip_address_t * a)
581 u32 len = ip_address_size (a);
582 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
583 u8 *p = b + sizeof (u16);
584 clib_memcpy (p, &ip_addr_addr (a), len);
585 return (len + sizeof (u16));
589 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
591 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
592 u8 size = ip_version_to_size (ip_addr_version (dst));
593 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
594 return (sizeof (u16) + size);
598 gid_to_dp_address (gid_address_t * g, dp_address_t * d)
600 switch (gid_address_type (g))
602 case GID_ADDR_SRC_DST:
603 switch (gid_address_sd_dst_type (g))
605 case FID_ADDR_IP_PREF:
606 ip_prefix_copy (&d->ippref, &gid_address_sd_dst_ippref (g));
607 d->type = FID_ADDR_IP_PREF;
610 mac_copy (&d->mac, &gid_address_sd_dst_mac (g));
611 d->type = FID_ADDR_MAC;
614 clib_warning ("Source/Dest address type %d not supported!",
615 gid_address_sd_dst_type (g));
619 case GID_ADDR_IP_PREFIX:
620 ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
621 d->type = FID_ADDR_IP_PREF;
624 mac_copy (&d->mac, &gid_address_mac (g));
625 d->type = FID_ADDR_MAC;
629 d->nsh = gid_address_nsh (g).spi << 8 | gid_address_nsh (g).si;
630 d->type = FID_ADDR_NSH;
636 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
638 lcaf_hdr_t *lh = offset;
639 lcaf->type = lh->type;
641 /* this is a bit of hack: since the LCAF Instance ID is the
642 only message that uses reserved2 field, we can set it here.
643 If any LCAF format starts using reserved2 field as well this needs
644 to be moved elsewhere */
645 lcaf_vni_len (lcaf) = lh->reserved2;
647 return sizeof (lh[0]);
651 iana_afi_to_fid_addr_type (u16 type)
657 return FID_ADDR_IP_PREF;
666 fid_addr_parse (u8 * p, fid_address_t * a)
668 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
669 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
670 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
672 switch (fid_addr_type (a))
675 return mac_parse (p, fid_addr_mac (a));
677 case FID_ADDR_IP_PREF:
678 return ip_address_parse (p, afi, ip_addr);
686 #define INC(dst, exp) \
689 if ((u16)~0 == _sum) \
701 nsh_parse (u8 * p, void *a)
703 lcaf_spi_hdr_t *h = (lcaf_spi_hdr_t *) p;
704 gid_address_t *g = a;
706 gid_address_type (g) = GID_ADDR_NSH;
707 gid_address_nsh_spi (g) = clib_net_to_host_u32 (LCAF_SPI_SI (h)) >> 8;
708 gid_address_nsh_si (g) = (u8) clib_net_to_host_u32 (LCAF_SPI_SI (h));
710 return sizeof (lcaf_spi_hdr_t);
714 nsh_cmp (void *a1, void *a2)
719 if (n1->spi != n2->spi)
721 if (n1->si != n2->si)
727 sd_parse (u8 * p, void *a)
729 lcaf_src_dst_hdr_t *sd_hdr;
730 gid_address_t *g = a;
732 fid_address_t *src = &gid_address_sd_src (g);
733 fid_address_t *dst = &gid_address_sd_dst (g);
735 gid_address_type (g) = GID_ADDR_SRC_DST;
737 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
738 size += sizeof (sd_hdr[0]);
740 INC (size, fid_addr_parse (p + size, src));
741 INC (size, fid_addr_parse (p + size, dst));
743 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
745 ip_prefix_t *ippref = &fid_addr_ippref (src);
746 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
748 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
750 ip_prefix_t *ippref = &fid_addr_ippref (dst);
751 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
757 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
760 u16 size = sizeof (u16); /* skip AFI */
762 size += lcaf_hdr_parse (p + size, &lcaf);
764 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
767 INC (size, sd_parse (p + size, a));
772 vni_parse (u8 * p, void *a)
775 gid_address_t *g = a;
778 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
779 size += sizeof (u32);
780 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
782 /* nested LCAFs are not supported except of src/dst with vni - to handle
783 * such case look at the next AFI and process src/dest LCAF separately */
784 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
785 if (LISP_AFI_LCAF == afi)
787 INC (size, try_parse_src_dst_lcaf (p + size, g));
790 INC (size, gid_address_parse (p + size, g));
796 no_addr_parse (u8 * p, void *a)
803 lcaf_parse (void *offset, gid_address_t * addr)
806 offset += sizeof (u16);
807 lcaf_t *lcaf = &gid_address_lcaf (addr);
809 u32 size = lcaf_hdr_parse (offset, lcaf);
810 u8 type = lcaf_type (lcaf);
812 if (!lcaf_parse_fcts[type])
814 clib_warning ("Unsupported LCAF type: %u", type);
817 INC (size, (*lcaf_parse_fcts[type]) (offset + size, lcaf));
818 return sizeof (u16) + size;
825 gid_address_free (vni_gid (v));
826 clib_mem_free (vni_gid (v));
830 no_addr_free (void *a)
842 gid_address_free (gid_address_t * a)
844 if (gid_address_type (a) != GID_ADDR_LCAF)
847 lcaf_t *lcaf = &gid_address_lcaf (a);
848 u8 lcaf_type = lcaf_type (lcaf);
849 (*lcaf_free_fcts[lcaf_type]) (lcaf);
853 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
855 memset (g, 0, sizeof (g[0]));
856 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
857 gid_address_ippref_len (g) = 32;
861 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
864 if (ip_addr_version (ip1) != ip_addr_version (ip2))
867 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
878 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
880 if (IP4 == ip_addr_version (src))
882 /* don't copy any garbe from the union */
883 memset (dst, 0, sizeof (*dst));
884 dst->ip.v4 = src->ip.v4;
889 clib_memcpy (dst, src, sizeof (ip_address_t));
894 ip_address_copy_addr (void *dst, const ip_address_t * src)
896 clib_memcpy (dst, src, ip_address_size (src));
900 ip_address_set (ip_address_t * dst, const void *src, u8 version)
902 clib_memcpy (dst, src, ip_version_to_size (version));
903 ip_addr_version (dst) = version;
907 ip_address_to_46 (const ip_address_t * addr,
908 ip46_address_t * a, fib_protocol_t * proto)
910 *proto = (IP4 == ip_addr_version (addr) ?
911 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
914 case FIB_PROTOCOL_IP4:
915 ip46_address_set_ip4 (a, &addr->ip.v4);
917 case FIB_PROTOCOL_IP6:
918 a->ip6 = addr->ip.v6;
927 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
938 mask = pow2_mask (preflen) << (32 - preflen);
939 mask = clib_host_to_net_u32 (mask);
940 ip4->data_u32 &= mask;
944 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
952 memset (mask_6, 0, sizeof (mask_6));
961 m = (u32 *) & mask_6[0];
963 for (j = 0; j < i0; j++)
970 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
973 for (j = 0; j < sizeof (mask_6); j++)
975 ip6->as_u8[j] &= mask_6[j];
980 ip_prefix_normalize (ip_prefix_t * a)
982 u8 preflen = ip_prefix_len (a);
984 switch (ip_prefix_version (a))
987 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
991 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
1000 ip_prefix_cast (gid_address_t * a)
1002 return &gid_address_ippref (a);
1006 ip_prefix_size_to_write (void *pref)
1008 ip_prefix_t *a = (ip_prefix_t *) pref;
1009 return ip_address_size_to_write (&ip_prefix_addr (a));
1013 ip_prefix_write (u8 * p, void *gid)
1015 gid_address_t *g = gid;
1016 ip_prefix_t *a = &gid_address_ippref (g);
1018 switch (ip_prefix_version (a))
1021 return ip4_address_put (p, &ip_prefix_v4 (a));
1024 return ip6_address_put (p, &ip_prefix_v6 (a));
1031 ip_prefix_length (void *a)
1033 return ip_prefix_len ((ip_prefix_t *) a);
1037 ip_prefix_copy (void *dst, void *src)
1039 clib_memcpy (dst, src, sizeof (ip_prefix_t));
1043 mac_copy (void *dst, void *src)
1045 clib_memcpy (dst, src, 6);
1049 sd_copy (void *dst, void *src)
1051 clib_memcpy (dst, src, sizeof (source_dest_t));
1055 nsh_copy (void *dst, void *src)
1057 clib_memcpy (dst, src, sizeof (nsh_t));
1061 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
1065 ip_prefix_normalize (p1);
1066 ip_prefix_normalize (p2);
1068 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
1071 if (ip_prefix_len (p1) < ip_prefix_len (p2))
1077 if (ip_prefix_len (p1) > ip_prefix_len (p2))
1085 no_addr_copy (void *dst, void *src)
1091 vni_copy (void *dst, void *src)
1096 clib_memcpy (vd, vs, sizeof (vd[0]));
1097 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
1098 gid_address_copy (vni_gid (vd), vni_gid (vs));
1102 lcaf_copy (void *dst, void *src)
1104 lcaf_t *lcaf_dst = dst;
1105 lcaf_t *lcaf_src = src;
1107 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
1108 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
1112 lcaf_length (void *a)
1118 mac_length (void *a)
1130 nsh_length (void *a)
1136 lcaf_cast (gid_address_t * a)
1138 return &gid_address_lcaf (a);
1142 mac_cast (gid_address_t * a)
1144 return &gid_address_mac (a);
1148 no_addr_cast (gid_address_t * a)
1154 sd_cast (gid_address_t * a)
1156 return &gid_address_sd (a);
1160 nsh_cast (gid_address_t * a)
1162 return &gid_address_nsh (a);
1166 no_addr_length (void *a)
1172 vni_length (void *a)
1175 return (sizeof (u32) /* VNI size */
1176 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1180 lcaf_write (u8 * p, void *a)
1184 u8 type = lcaf_type (lcaf);
1185 lcaf_hdr_t _h, *h = &_h;
1187 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1188 size += sizeof (u16);
1189 memset (h, 0, sizeof (h[0]));
1190 LCAF_TYPE (h) = type;
1191 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1192 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1194 clib_memcpy (p + size, h, sizeof (h[0]));
1195 size += sizeof (h[0]);
1196 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1198 if ((u16) ~ 0 == len)
1205 mac_write (u8 * p, void *a)
1207 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1208 clib_memcpy (p + sizeof (u16), a, 6);
1209 return mac_size_to_write (a);
1213 fid_addr_write (u8 * p, fid_address_t * a)
1215 switch (fid_addr_type (a))
1217 case FID_ADDR_IP_PREF:
1218 return ip_prefix_write (p, &fid_addr_ippref (a));
1221 return mac_write (p, &fid_addr_mac (a));
1230 fid_address_length (fid_address_t * a)
1232 switch (fid_addr_type (a))
1234 case FID_ADDR_IP_PREF:
1235 return ip_prefix_length (&fid_addr_ippref (a));
1245 sd_write (u8 * p, void *a)
1247 source_dest_t *sd = a;
1249 lcaf_hdr_t _h, *h = &_h;
1250 lcaf_src_dst_hdr_t sd_hdr;
1252 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1253 size += sizeof (u16);
1254 memset (h, 0, sizeof (h[0]));
1255 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1256 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1257 + fid_addr_size_to_write (&sd_src (sd))
1258 + fid_addr_size_to_write (&sd_dst (sd));
1259 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1261 clib_memcpy (p + size, h, sizeof (h[0]));
1262 size += sizeof (h[0]);
1264 memset (&sd_hdr, 0, sizeof (sd_hdr));
1265 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1266 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1267 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1268 size += sizeof (sd_hdr);
1270 u16 len = fid_addr_write (p + size, &sd_src (sd));
1271 if ((u16) ~ 0 == len)
1275 len = fid_addr_write (p + size, &sd_dst (sd));
1276 if ((u16) ~ 0 == len)
1284 nsh_write (u8 * p, void *a)
1288 gid_address_t *g = a;
1291 ASSERT (gid_address_type (g) == GID_ADDR_NSH);
1293 memset (&lcaf, 0, sizeof (lcaf));
1294 memset (&spi, 0, sizeof (spi));
1296 LCAF_TYPE (&lcaf) = LCAF_NSH;
1297 LCAF_LENGTH (&lcaf) = clib_host_to_net_u16 (sizeof (lcaf_spi_hdr_t));
1299 u32 s = clib_host_to_net_u32 (gid_address_nsh_spi (g) << 8 |
1300 gid_address_nsh_si (g));
1301 LCAF_SPI_SI (&spi) = s;
1303 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1304 size += sizeof (u16);
1306 clib_memcpy (p + size, &lcaf, sizeof (lcaf));
1307 size += sizeof (lcaf);
1309 clib_memcpy (p + size, &spi, sizeof (spi));
1310 size += sizeof (spi);
1316 vni_write (u8 * p, void *a)
1318 lcaf_hdr_t _h, *h = &_h;
1319 gid_address_t *g = a;
1322 /* put lcaf header */
1323 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1324 size += sizeof (u16);
1325 memset (h, 0, sizeof (h[0]));
1326 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1327 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1328 + gid_address_size_to_put_no_vni (g);
1329 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1330 LCAF_RES2 (h) = gid_address_vni_mask (g);
1332 /* put vni header */
1333 clib_memcpy (p + size, h, sizeof (h[0]));
1334 size += sizeof (h[0]);
1336 u32 *afip = (u32 *) (p + size);
1337 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1338 size += sizeof (u32);
1340 if (GID_ADDR_SRC_DST == gid_address_type (g))
1341 /* write src/dst LCAF */
1343 len = sd_write (p + size, g);
1344 if ((u16) ~ 0 == len)
1348 /* write the actual address */
1349 len = gid_address_put_no_vni (p + size, g);
1351 if ((u16) ~ 0 == len)
1358 no_addr_write (u8 * p, void *a)
1360 /* do nothing; return AFI field size */
1361 return sizeof (u16);
1365 no_addr_size_to_write (void *a)
1367 return sizeof (u16); /* AFI field length */
1371 fid_addr_size_to_write (fid_address_t * a)
1373 switch (fid_addr_type (a))
1375 case FID_ADDR_IP_PREF:
1376 return ip_prefix_size_to_write (a);
1379 return mac_size_to_write (a);
1388 vni_size_to_write (void *a)
1390 gid_address_t *g = a;
1392 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1393 + sizeof (lcaf_hdr_t);
1395 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1396 /* special case where nested LCAF is supported */
1397 return lcaf_size + sd_size_to_write (g);
1399 return lcaf_size + gid_address_size_to_put_no_vni (g);
1403 lcaf_size_to_write (void *a)
1405 lcaf_t *lcaf = (lcaf_t *) a;
1407 u8 type = lcaf_type (lcaf);
1409 size += sizeof (u16); /* AFI size */
1411 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1419 sd_size_to_write (void *a)
1421 source_dest_t *sd = a;
1423 + sizeof (lcaf_hdr_t)
1424 + sizeof (lcaf_src_dst_hdr_t)
1425 + fid_addr_size_to_write (&sd_src (sd))
1426 + fid_addr_size_to_write (&sd_dst (sd));
1430 mac_size_to_write (void *a)
1432 return sizeof (u16) + 6;
1436 nsh_size_to_write (void *a)
1438 return sizeof (u16) + sizeof (lcaf_hdr_t) + sizeof (lcaf_spi_hdr_t);
1442 gid_address_len (gid_address_t * a)
1444 gid_address_type_t type = gid_address_type (a);
1445 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1449 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1451 gid_address_type_t type = gid_address_type (gid);
1452 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1456 gid_address_put (u8 * b, gid_address_t * gid)
1458 if (0 != gid_address_vni (gid))
1459 return vni_write (b, gid);
1461 return gid_address_put_no_vni (b, gid);
1465 gid_address_size_to_put_no_vni (gid_address_t * gid)
1467 gid_address_type_t type = gid_address_type (gid);
1468 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1472 gid_address_size_to_put (gid_address_t * gid)
1474 if (0 != gid_address_vni (gid))
1475 return vni_size_to_write (gid);
1477 return gid_address_size_to_put_no_vni (gid);
1481 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1483 return (*cast_fcts[type]) (gid);
1487 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1489 gid_address_type_t type = gid_address_type (src);
1490 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1491 gid_address_type (dst) = type;
1492 gid_address_vni (dst) = gid_address_vni (src);
1493 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1497 mac_parse (u8 * offset, u8 * a)
1499 /* skip AFI field */
1500 offset += sizeof (u16);
1502 clib_memcpy (a, offset, 6);
1503 return sizeof (u16) + 6;
1507 gid_address_parse (u8 * offset, gid_address_t * a)
1514 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1515 * the gid address here */
1516 afi = clib_net_to_host_u16 (*((u16 *) offset));
1520 case LISP_AFI_NO_ADDR:
1522 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1525 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1526 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1527 /* this should be modified outside if needed */
1528 gid_address_ippref_len (a) = 32;
1531 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1532 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1533 /* this should be modified outside if needed */
1534 gid_address_ippref_len (a) = 128;
1537 gid_address_type (a) = GID_ADDR_LCAF;
1538 len = lcaf_parse (offset, a);
1541 len = mac_parse (offset, gid_address_mac (a));
1542 gid_address_type (a) = GID_ADDR_MAC;
1545 clib_warning ("LISP AFI %d not supported!", afi);
1548 return (len == (u16) ~ 0) ? ~0 : len;
1552 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1554 gid_address_ippref_len (dst) = ip_address_max_len (version);
1555 ip_address_set (&gid_address_ip (dst), src, version);
1559 no_addr_cmp (void *a1, void *a2)
1565 vni_cmp (void *a1, void *a2)
1570 if (vni_mask_len (v1) != vni_mask_len (v2))
1572 if (vni_vni (v1) != vni_vni (v2))
1574 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1578 mac_cmp (void *a1, void *a2)
1580 return memcmp (a1, a2, 6);
1584 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1586 if (fid_addr_type (a1) != fid_addr_type (a2))
1589 switch (fid_addr_type (a1))
1591 case FID_ADDR_IP_PREF:
1592 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1595 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1604 sd_cmp (void *a1, void *a2)
1606 source_dest_t *sd1 = a1;
1607 source_dest_t *sd2 = a2;
1609 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1611 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1616 /* Compare two gid_address_t.
1618 * -1: If they are from different afi
1619 * 0: Both address are the same
1620 * 1: Addr1 is bigger than addr2
1621 * 2: Addr2 is bigger than addr1
1624 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1626 lcaf_t *lcaf1, *lcaf2;
1630 if (gid_address_type (a1) != gid_address_type (a2))
1632 if (gid_address_vni (a1) != gid_address_vni (a2))
1635 /* TODO vni mask is not supported, disable comparing for now
1636 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1640 switch (gid_address_type (a1))
1642 case GID_ADDR_NO_ADDRESS:
1648 case GID_ADDR_IP_PREFIX:
1650 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1653 lcaf1 = &gid_address_lcaf (a1);
1654 lcaf2 = &gid_address_lcaf (a2);
1655 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1656 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1659 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1662 case GID_ADDR_SRC_DST:
1663 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1666 cmp = nsh_cmp (&gid_address_nsh (a1), &gid_address_nsh (a2));
1676 locator_parse (void *b, locator_t * loc)
1679 u8 status = 1; /* locator up */
1683 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1686 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1690 loc->state = status;
1692 loc->priority = LOC_PRIORITY (h);
1693 loc->weight = LOC_WEIGHT (h);
1694 loc->mpriority = LOC_MPRIORITY (h);
1695 loc->mweight = LOC_MWEIGHT (h);
1697 return sizeof (locator_hdr_t) + len;
1701 locator_copy (locator_t * dst, locator_t * src)
1703 /* TODO if gid become more complex, this will need to be changed! */
1704 clib_memcpy (dst, src, sizeof (*dst));
1706 gid_address_copy (&dst->address, &src->address);
1710 locator_cmp (locator_t * l1, locator_t * l2)
1713 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1716 if (l1->priority != l2->priority)
1718 if (l1->weight != l2->weight)
1720 if (l1->mpriority != l2->mpriority)
1722 if (l1->mweight != l2->mweight)
1728 locator_free (locator_t * l)
1731 gid_address_free (&l->address);
1735 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1737 memset (sd, 0, sizeof (*sd));
1738 gid_address_type (sd) = GID_ADDR_SRC_DST;
1739 gid_address_vni (sd) = gid_address_vni (dst);
1740 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1742 switch (gid_address_type (dst))
1744 case GID_ADDR_IP_PREFIX:
1745 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1746 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1747 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1748 &gid_address_ippref (src));
1749 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1750 &gid_address_ippref (dst));
1753 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1754 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1755 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1756 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1759 clib_warning ("Unsupported gid type %d while conversion!",
1760 gid_address_type (dst));
1766 * fd.io coding-style-patch-verification: ON
1769 * eval: (c-set-style "gnu")