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 unformat_nsh_address (unformat_input_t * input, va_list * args)
147 nsh_t *a = va_arg (*args, nsh_t *);
148 return unformat (input, "SPI:%d SI:%d", &a->spi, &a->si);
152 format_nsh_address (u8 * s, va_list * args)
154 nsh_t *a = va_arg (*args, nsh_t *);
155 return format (s, "SPI:%d SI:%d", a->spi, a->si);
159 format_fid_nsh_address (u8 * s, va_list * args)
161 u32 *a = va_arg (*args, u32 *);
162 return format (s, "SPI:%d SI:%d", *a >> 8, *a & 0xff);
166 format_fid_address (u8 * s, va_list * args)
168 fid_address_t *a = va_arg (*args, fid_address_t *);
170 switch (fid_addr_type (a))
172 case FID_ADDR_IP_PREF:
173 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
175 return format (s, "%U", format_mac_address, &fid_addr_mac (a));
177 return format (s, "%U", format_fid_nsh_address, &fid_addr_nsh (a));
180 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
187 format_gid_address (u8 * s, va_list * args)
189 gid_address_t *a = va_arg (*args, gid_address_t *);
190 u8 type = gid_address_type (a);
193 case GID_ADDR_IP_PREFIX:
194 return format (s, "[%d] %U", gid_address_vni (a), format_ip_prefix,
195 &gid_address_ippref (a));
196 case GID_ADDR_SRC_DST:
197 return format (s, "[%d] %U|%U", gid_address_vni (a),
198 format_fid_address, &gid_address_sd_src (a),
199 format_fid_address, &gid_address_sd_dst (a));
201 return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
202 &gid_address_mac (a));
205 return format (s, "[%d, %U]", gid_address_arp_ndp_bd (a),
206 format_ip_address, &gid_address_arp_ndp_ip (a));
208 return format (s, "%U", format_nsh_address, &gid_address_nsh (a));
211 clib_warning ("Can't format gid type %d", type);
218 unformat_fid_address (unformat_input_t * i, va_list * args)
220 fid_address_t *a = va_arg (*args, fid_address_t *);
225 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
227 fid_addr_type (a) = FID_ADDR_IP_PREF;
228 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
230 else if (unformat (i, "%U", unformat_mac_address, mac))
232 fid_addr_type (a) = FID_ADDR_MAC;
233 mac_copy (fid_addr_mac (a), mac);
235 else if (unformat (i, "%U", unformat_nsh_address, &nsh))
237 fid_addr_type (a) = FID_ADDR_NSH;
238 nsh_copy (&fid_addr_nsh (a), &nsh);
247 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
249 u32 *key_id = va_arg (*args, u32 *);
252 if (unformat (input, "%s", &s))
254 if (!strcmp ((char *) s, "sha1"))
255 key_id[0] = HMAC_SHA_1_96;
256 else if (!strcmp ((char *) s, "sha256"))
257 key_id[0] = HMAC_SHA_256_128;
260 clib_warning ("invalid key_id: '%s'", s);
261 key_id[0] = HMAC_NO_KEY;
272 unformat_gid_address (unformat_input_t * input, va_list * args)
274 gid_address_t *a = va_arg (*args, gid_address_t *);
277 fid_address_t sim1, sim2;
280 clib_memset (&ippref, 0, sizeof (ippref));
281 clib_memset (&sim1, 0, sizeof (sim1));
282 clib_memset (&sim2, 0, sizeof (sim2));
284 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
285 unformat_fid_address, &sim2))
287 gid_address_sd_src (a) = sim1;
288 gid_address_sd_dst (a) = sim2;
289 gid_address_type (a) = GID_ADDR_SRC_DST;
291 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
293 ip_prefix_copy (&gid_address_ippref (a), &ippref);
294 gid_address_type (a) = GID_ADDR_IP_PREFIX;
296 else if (unformat (input, "%U", unformat_mac_address, mac))
298 mac_copy (gid_address_mac (a), mac);
299 gid_address_type (a) = GID_ADDR_MAC;
301 else if (unformat (input, "%U", unformat_nsh_address, &nsh))
303 nsh_copy (&gid_address_nsh (a), &nsh);
304 gid_address_type (a) = GID_ADDR_NSH;
313 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
315 u32 *action = va_arg (*args, u32 *);
318 if (unformat (input, "%s", &s))
320 if (!strcmp ((char *) s, "no-action"))
321 action[0] = LISP_NO_ACTION;
322 else if (!strcmp ((char *) s, "natively-forward"))
323 action[0] = LISP_FORWARD_NATIVE;
324 else if (!strcmp ((char *) s, "send-map-request"))
325 action[0] = LISP_SEND_MAP_REQUEST;
326 else if (!strcmp ((char *) s, "drop"))
327 action[0] = LISP_DROP;
330 clib_warning ("invalid action: '%s'", s);
331 action[0] = LISP_DROP;
342 format_hmac_key_id (u8 * s, va_list * args)
344 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
349 return format (0, "sha1");
350 case HMAC_SHA_256_128:
351 return format (0, "sha256");
360 format_negative_mapping_action (u8 * s, va_list * args)
362 lisp_action_e action = va_arg (*args, lisp_action_e);
367 s = format (s, "no-action");
369 case LISP_FORWARD_NATIVE:
370 s = format (s, "natively-forward");
372 case LISP_SEND_MAP_REQUEST:
373 s = format (s, "send-map-request");
377 s = format (s, "drop");
384 ip_prefix_length (void *a)
386 return ip_prefix_len ((ip_prefix_t *) a);
389 always_inline lisp_afi_e
390 ip_version_to_iana_afi (u16 version)
405 ip_iana_afi_to_version (lisp_afi_e afi)
420 ip_address_size_to_write (ip_address_t * a)
422 return ip_address_size (a) + sizeof (u16);
426 ip_address_iana_afi (ip_address_t * a)
428 return ip_version_to_iana_afi (ip_addr_version (a));
432 ip_address_max_len (u8 version)
434 return version == AF_IP4 ? 32 : 128;
438 ip4_address_size_to_put ()
440 // return sizeof(u16) + sizeof (ip4_address_t);
445 ip6_address_size_to_put ()
447 //return sizeof(u16) + sizeof (ip6_address_t);
452 ip4_address_put (u8 * b, ip4_address_t * a)
454 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (AF_IP4));
455 u8 *p = b + sizeof (u16);
456 clib_memcpy (p, a, sizeof (*a));
457 return ip4_address_size_to_put ();
461 ip6_address_put (u8 * b, ip6_address_t * a)
463 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (AF_IP6));
464 u8 *p = b + sizeof (u16);
465 clib_memcpy (p, a, sizeof (*a));
466 return ip6_address_size_to_put ();
470 ip_address_put (u8 * b, ip_address_t * a)
472 u32 len = ip_address_size (a);
473 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
474 u8 *p = b + sizeof (u16);
475 clib_memcpy (p, ip_addr_bytes (a), len);
476 return (len + sizeof (u16));
480 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
482 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
483 u8 size = ip_version_to_size (ip_addr_version (dst));
484 clib_memcpy (ip_addr_bytes (dst), offset + sizeof (u16), size);
485 return (sizeof (u16) + size);
489 gid_to_dp_address (gid_address_t * g, dp_address_t * d)
491 switch (gid_address_type (g))
493 case GID_ADDR_SRC_DST:
494 switch (gid_address_sd_dst_type (g))
496 case FID_ADDR_IP_PREF:
497 ip_prefix_copy (&d->ippref, &gid_address_sd_dst_ippref (g));
498 d->type = FID_ADDR_IP_PREF;
501 mac_copy (&d->mac, &gid_address_sd_dst_mac (g));
502 d->type = FID_ADDR_MAC;
505 clib_warning ("Source/Dest address type %d not supported!",
506 gid_address_sd_dst_type (g));
510 case GID_ADDR_IP_PREFIX:
511 ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
512 d->type = FID_ADDR_IP_PREF;
515 mac_copy (&d->mac, &gid_address_mac (g));
516 d->type = FID_ADDR_MAC;
520 d->nsh = gid_address_nsh (g).spi << 8 | gid_address_nsh (g).si;
521 d->type = FID_ADDR_NSH;
527 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
529 lcaf_hdr_t *lh = offset;
530 lcaf->type = lh->type;
532 /* this is a bit of hack: since the LCAF Instance ID is the
533 only message that uses reserved2 field, we can set it here.
534 If any LCAF format starts using reserved2 field as well this needs
535 to be moved elsewhere */
536 lcaf_vni_len (lcaf) = lh->reserved2;
538 return sizeof (lh[0]);
542 iana_afi_to_fid_addr_type (u16 type)
548 return FID_ADDR_IP_PREF;
557 fid_addr_parse (u8 * p, fid_address_t * a)
559 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
560 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
561 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
563 switch (fid_addr_type (a))
566 return mac_parse (p, fid_addr_mac (a));
568 case FID_ADDR_IP_PREF:
569 return ip_address_parse (p, afi, ip_addr);
577 #define INC(dst, exp) \
580 if ((u16)~0 == _sum) \
592 nsh_parse (u8 * p, void *a)
594 lcaf_spi_hdr_t *h = (lcaf_spi_hdr_t *) p;
595 gid_address_t *g = a;
597 gid_address_type (g) = GID_ADDR_NSH;
598 gid_address_nsh_spi (g) = clib_net_to_host_u32 (LCAF_SPI_SI (h)) >> 8;
599 gid_address_nsh_si (g) = (u8) clib_net_to_host_u32 (LCAF_SPI_SI (h));
601 return sizeof (lcaf_spi_hdr_t);
605 nsh_cmp (void *a1, void *a2)
610 if (n1->spi != n2->spi)
612 if (n1->si != n2->si)
618 sd_parse (u8 * p, void *a)
620 lcaf_src_dst_hdr_t *sd_hdr;
621 gid_address_t *g = a;
623 fid_address_t *src = &gid_address_sd_src (g);
624 fid_address_t *dst = &gid_address_sd_dst (g);
626 gid_address_type (g) = GID_ADDR_SRC_DST;
628 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
629 size += sizeof (sd_hdr[0]);
631 INC (size, fid_addr_parse (p + size, src));
632 INC (size, fid_addr_parse (p + size, dst));
634 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
636 ip_prefix_t *ippref = &fid_addr_ippref (src);
637 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
639 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
641 ip_prefix_t *ippref = &fid_addr_ippref (dst);
642 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
648 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
651 u16 size = sizeof (u16); /* skip AFI */
653 size += lcaf_hdr_parse (p + size, &lcaf);
655 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
658 INC (size, sd_parse (p + size, a));
663 vni_parse (u8 * p, void *a)
666 gid_address_t *g = a;
669 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
670 size += sizeof (u32);
671 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
673 /* nested LCAFs are not supported except of src/dst with vni - to handle
674 * such case look at the next AFI and process src/dest LCAF separately */
675 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
676 if (LISP_AFI_LCAF == afi)
678 INC (size, try_parse_src_dst_lcaf (p + size, g));
681 INC (size, gid_address_parse (p + size, g));
687 no_addr_parse (u8 * p, void *a)
694 lcaf_parse (void *offset, gid_address_t * addr)
697 offset += sizeof (u16);
698 lcaf_t *lcaf = &gid_address_lcaf (addr);
700 u32 size = lcaf_hdr_parse (offset, lcaf);
701 u8 type = lcaf_type (lcaf);
703 if (!lcaf_parse_fcts[type])
705 clib_warning ("Unsupported LCAF type: %u", type);
708 INC (size, (*lcaf_parse_fcts[type]) (offset + size, lcaf));
709 return sizeof (u16) + size;
716 gid_address_free (vni_gid (v));
717 clib_mem_free (vni_gid (v));
721 no_addr_free (void *a)
733 gid_address_free (gid_address_t * a)
735 if (gid_address_type (a) != GID_ADDR_LCAF)
738 lcaf_t *lcaf = &gid_address_lcaf (a);
739 u8 lcaf_type = lcaf_type (lcaf);
740 (*lcaf_free_fcts[lcaf_type]) (lcaf);
744 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
746 clib_memset (g, 0, sizeof (g[0]));
747 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
748 gid_address_ippref_len (g) = 32;
752 ip_prefix_cast (gid_address_t * a)
754 return &gid_address_ippref (a);
758 ip_prefix_size_to_write (void *pref)
760 ip_prefix_t *a = (ip_prefix_t *) pref;
761 return ip_address_size_to_write (&ip_prefix_addr (a));
765 ip_prefix_write (u8 * p, void *gid)
767 gid_address_t *g = gid;
768 ip_prefix_t *a = &gid_address_ippref (g);
770 switch (ip_prefix_version (a))
773 return ip4_address_put (p, &ip_prefix_v4 (a));
776 return ip6_address_put (p, &ip_prefix_v6 (a));
783 mac_copy (void *dst, void *src)
785 clib_memcpy (dst, src, 6);
789 sd_copy (void *dst, void *src)
791 clib_memcpy (dst, src, sizeof (source_dest_t));
795 nsh_copy (void *dst, void *src)
797 clib_memcpy (dst, src, sizeof (nsh_t));
801 no_addr_copy (void *dst, void *src)
807 vni_copy (void *dst, void *src)
812 clib_memcpy (vd, vs, sizeof (vd[0]));
813 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
814 gid_address_copy (vni_gid (vd), vni_gid (vs));
818 lcaf_copy (void *dst, void *src)
820 lcaf_t *lcaf_dst = dst;
821 lcaf_t *lcaf_src = src;
823 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
824 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
828 lcaf_length (void *a)
852 lcaf_cast (gid_address_t * a)
854 return &gid_address_lcaf (a);
858 mac_cast (gid_address_t * a)
860 return &gid_address_mac (a);
864 no_addr_cast (gid_address_t * a)
870 sd_cast (gid_address_t * a)
872 return &gid_address_sd (a);
876 nsh_cast (gid_address_t * a)
878 return &gid_address_nsh (a);
882 no_addr_length (void *a)
891 return (sizeof (u32) /* VNI size */
892 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
896 lcaf_write (u8 * p, void *a)
900 u8 type = lcaf_type (lcaf);
901 lcaf_hdr_t _h, *h = &_h;
903 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
904 size += sizeof (u16);
905 clib_memset (h, 0, sizeof (h[0]));
906 LCAF_TYPE (h) = type;
907 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
908 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
910 clib_memcpy (p + size, h, sizeof (h[0]));
911 size += sizeof (h[0]);
912 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
914 if ((u16) ~ 0 == len)
921 mac_write (u8 * p, void *a)
923 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
924 clib_memcpy (p + sizeof (u16), a, 6);
925 return mac_size_to_write (a);
929 fid_addr_write (u8 * p, fid_address_t * a)
931 switch (fid_addr_type (a))
933 case FID_ADDR_IP_PREF:
934 return ip_prefix_write (p, &fid_addr_ippref (a));
937 return mac_write (p, &fid_addr_mac (a));
946 fid_address_length (fid_address_t * a)
948 switch (fid_addr_type (a))
950 case FID_ADDR_IP_PREF:
951 return ip_prefix_length (&fid_addr_ippref (a));
961 sd_write (u8 * p, void *a)
963 source_dest_t *sd = a;
965 lcaf_hdr_t _h, *h = &_h;
966 lcaf_src_dst_hdr_t sd_hdr;
968 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
969 size += sizeof (u16);
970 clib_memset (h, 0, sizeof (h[0]));
971 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
972 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
973 + fid_addr_size_to_write (&sd_src (sd))
974 + fid_addr_size_to_write (&sd_dst (sd));
975 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
977 clib_memcpy (p + size, h, sizeof (h[0]));
978 size += sizeof (h[0]);
980 clib_memset (&sd_hdr, 0, sizeof (sd_hdr));
981 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
982 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
983 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
984 size += sizeof (sd_hdr);
986 u16 len = fid_addr_write (p + size, &sd_src (sd));
987 if ((u16) ~ 0 == len)
991 len = fid_addr_write (p + size, &sd_dst (sd));
992 if ((u16) ~ 0 == len)
1000 nsh_write (u8 * p, void *a)
1004 gid_address_t *g = a;
1007 ASSERT (gid_address_type (g) == GID_ADDR_NSH);
1009 clib_memset (&lcaf, 0, sizeof (lcaf));
1010 clib_memset (&spi, 0, sizeof (spi));
1012 LCAF_TYPE (&lcaf) = LCAF_NSH;
1013 LCAF_LENGTH (&lcaf) = clib_host_to_net_u16 (sizeof (lcaf_spi_hdr_t));
1015 u32 s = clib_host_to_net_u32 (gid_address_nsh_spi (g) << 8 |
1016 gid_address_nsh_si (g));
1017 LCAF_SPI_SI (&spi) = s;
1019 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1020 size += sizeof (u16);
1022 clib_memcpy (p + size, &lcaf, sizeof (lcaf));
1023 size += sizeof (lcaf);
1025 clib_memcpy (p + size, &spi, sizeof (spi));
1026 size += sizeof (spi);
1032 vni_write (u8 * p, void *a)
1034 lcaf_hdr_t _h, *h = &_h;
1035 gid_address_t *g = a;
1038 /* put lcaf header */
1039 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1040 size += sizeof (u16);
1041 clib_memset (h, 0, sizeof (h[0]));
1042 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1043 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1044 + gid_address_size_to_put_no_vni (g);
1045 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1046 LCAF_RES2 (h) = gid_address_vni_mask (g);
1048 /* put vni header */
1049 clib_memcpy (p + size, h, sizeof (h[0]));
1050 size += sizeof (h[0]);
1052 u32 *afip = (u32 *) (p + size);
1053 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1054 size += sizeof (u32);
1056 if (GID_ADDR_SRC_DST == gid_address_type (g))
1057 /* write src/dst LCAF */
1059 len = sd_write (p + size, g);
1060 if ((u16) ~ 0 == len)
1064 /* write the actual address */
1065 len = gid_address_put_no_vni (p + size, g);
1067 if ((u16) ~ 0 == len)
1074 no_addr_write (u8 * p, void *a)
1076 /* do nothing; return AFI field size */
1077 return sizeof (u16);
1081 no_addr_size_to_write (void *a)
1083 return sizeof (u16); /* AFI field length */
1087 fid_addr_size_to_write (fid_address_t * a)
1089 switch (fid_addr_type (a))
1091 case FID_ADDR_IP_PREF:
1092 return ip_prefix_size_to_write (a);
1095 return mac_size_to_write (a);
1104 vni_size_to_write (void *a)
1106 gid_address_t *g = a;
1108 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1109 + sizeof (lcaf_hdr_t);
1111 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1112 /* special case where nested LCAF is supported */
1113 return lcaf_size + sd_size_to_write (g);
1115 return lcaf_size + gid_address_size_to_put_no_vni (g);
1119 lcaf_size_to_write (void *a)
1121 lcaf_t *lcaf = (lcaf_t *) a;
1123 u8 type = lcaf_type (lcaf);
1125 size += sizeof (u16); /* AFI size */
1127 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1135 sd_size_to_write (void *a)
1137 source_dest_t *sd = a;
1139 + sizeof (lcaf_hdr_t)
1140 + sizeof (lcaf_src_dst_hdr_t)
1141 + fid_addr_size_to_write (&sd_src (sd))
1142 + fid_addr_size_to_write (&sd_dst (sd));
1146 mac_size_to_write (void *a)
1148 return sizeof (u16) + 6;
1152 nsh_size_to_write (void *a)
1154 return sizeof (u16) + sizeof (lcaf_hdr_t) + sizeof (lcaf_spi_hdr_t);
1158 gid_address_len (gid_address_t * a)
1160 gid_address_type_t type = gid_address_type (a);
1161 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1165 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1167 gid_address_type_t type = gid_address_type (gid);
1168 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1172 gid_address_put (u8 * b, gid_address_t * gid)
1174 if (0 != gid_address_vni (gid))
1175 return vni_write (b, gid);
1177 return gid_address_put_no_vni (b, gid);
1181 gid_address_size_to_put_no_vni (gid_address_t * gid)
1183 gid_address_type_t type = gid_address_type (gid);
1184 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1188 gid_address_size_to_put (gid_address_t * gid)
1190 if (0 != gid_address_vni (gid))
1191 return vni_size_to_write (gid);
1193 return gid_address_size_to_put_no_vni (gid);
1197 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1199 return (*cast_fcts[type]) (gid);
1203 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1205 gid_address_type_t type = gid_address_type (src);
1206 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1207 gid_address_type (dst) = type;
1208 gid_address_vni (dst) = gid_address_vni (src);
1209 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1213 mac_parse (u8 * offset, u8 * a)
1215 /* skip AFI field */
1216 offset += sizeof (u16);
1218 clib_memcpy (a, offset, 6);
1219 return sizeof (u16) + 6;
1223 gid_address_parse (u8 * offset, gid_address_t * a)
1230 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1231 * the gid address here */
1232 afi = clib_net_to_host_u16 (*((u16 *) offset));
1236 case LISP_AFI_NO_ADDR:
1238 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1241 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1242 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1243 /* this should be modified outside if needed */
1244 gid_address_ippref_len (a) = 32;
1247 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1248 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1249 /* this should be modified outside if needed */
1250 gid_address_ippref_len (a) = 128;
1253 gid_address_type (a) = GID_ADDR_LCAF;
1254 len = lcaf_parse (offset, a);
1257 len = mac_parse (offset, gid_address_mac (a));
1258 gid_address_type (a) = GID_ADDR_MAC;
1261 clib_warning ("LISP AFI %d not supported!", afi);
1264 return (len == (u16) ~ 0) ? ~0 : len;
1268 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1270 gid_address_ippref_len (dst) = ip_address_max_len (version);
1271 ip_address_set (&gid_address_ip (dst), src, version);
1275 no_addr_cmp (void *a1, void *a2)
1281 vni_cmp (void *a1, void *a2)
1286 if (vni_mask_len (v1) != vni_mask_len (v2))
1288 if (vni_vni (v1) != vni_vni (v2))
1290 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1294 mac_cmp (void *a1, void *a2)
1296 return memcmp (a1, a2, 6);
1300 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1302 if (fid_addr_type (a1) != fid_addr_type (a2))
1305 switch (fid_addr_type (a1))
1307 case FID_ADDR_IP_PREF:
1308 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1311 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1320 sd_cmp (void *a1, void *a2)
1322 source_dest_t *sd1 = a1;
1323 source_dest_t *sd2 = a2;
1325 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1327 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1332 /* Compare two gid_address_t.
1334 * -1: If they are from different afi
1335 * 0: Both address are the same
1336 * 1: Addr1 is bigger than addr2
1337 * 2: Addr2 is bigger than addr1
1340 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1342 lcaf_t *lcaf1, *lcaf2;
1346 if (gid_address_type (a1) != gid_address_type (a2))
1348 if (gid_address_vni (a1) != gid_address_vni (a2))
1351 /* TODO vni mask is not supported, disable comparing for now
1352 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1356 switch (gid_address_type (a1))
1358 case GID_ADDR_NO_ADDRESS:
1364 case GID_ADDR_IP_PREFIX:
1366 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1369 lcaf1 = &gid_address_lcaf (a1);
1370 lcaf2 = &gid_address_lcaf (a2);
1371 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1372 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1375 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1378 case GID_ADDR_SRC_DST:
1379 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1382 cmp = nsh_cmp (&gid_address_nsh (a1), &gid_address_nsh (a2));
1392 locator_parse (void *b, locator_t * loc)
1395 u8 status = 1; /* locator up */
1399 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1402 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1406 loc->state = status;
1409 loc->priority = LOC_PRIORITY (h);
1410 loc->weight = LOC_WEIGHT (h);
1411 loc->mpriority = LOC_MPRIORITY (h);
1412 loc->mweight = LOC_MWEIGHT (h);
1414 return sizeof (locator_hdr_t) + len;
1418 locator_copy (locator_t * dst, locator_t * src)
1420 /* TODO if gid become more complex, this will need to be changed! */
1421 clib_memcpy (dst, src, sizeof (*dst));
1423 gid_address_copy (&dst->address, &src->address);
1427 locator_cmp (locator_t * l1, locator_t * l2)
1430 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1433 if (l1->priority != l2->priority)
1435 if (l1->weight != l2->weight)
1437 if (l1->mpriority != l2->mpriority)
1439 if (l1->mweight != l2->mweight)
1445 locator_free (locator_t * l)
1448 gid_address_free (&l->address);
1452 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1454 clib_memset (sd, 0, sizeof (*sd));
1455 gid_address_type (sd) = GID_ADDR_SRC_DST;
1456 gid_address_vni (sd) = gid_address_vni (dst);
1457 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1459 switch (gid_address_type (dst))
1461 case GID_ADDR_IP_PREFIX:
1462 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1463 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1464 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1465 &gid_address_ippref (src));
1466 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1467 &gid_address_ippref (dst));
1470 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1471 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1472 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1473 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1476 clib_warning ("Unsupported gid type %d while conversion!",
1477 gid_address_type (dst));
1483 * fd.io coding-style-patch-verification: ON
1486 * eval: (c-set-style "gnu")