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
36 serdes_fct write_fcts[GID_ADDR_TYPES] =
37 { ip_prefix_write, lcaf_write, mac_write, sd_write, nsh_write };
38 cast_fct cast_fcts[GID_ADDR_TYPES] =
39 { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast, nsh_cast };
40 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
41 { ip_prefix_length, lcaf_length, mac_length, sd_length, nsh_length };
42 copy_fct copy_fcts[GID_ADDR_TYPES] =
43 { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy, nsh_copy };
45 #define foreach_lcaf_type \
60 #define _(cond, name) \
61 u16 name ## _write (u8 * p, void * a); \
62 u16 name ## _parse (u8 * p, void * a); \
63 u16 name ## _size_to_write (void * a); \
64 void name ## _free (void * a); \
65 void name ## _copy (void * dst, void * src); \
66 u8 name ## _length (void * a); \
67 int name ## _cmp (void *, void *);
70 #define CONCAT(a,b) a##_##b
71 #define IF(c, t, e) CONCAT(IF, c)(t, e)
74 #define EXPAND_FCN(cond, fcn) \
76 cmp_fct lcaf_cmp_fcts[LCAF_TYPES] =
78 #define _(cond, name) \
79 EXPAND_FCN(cond, name##_cmp),
84 addr_len_fct lcaf_body_length_fcts[LCAF_TYPES] = {
85 #define _(cond, name) \
86 EXPAND_FCN(cond, name##_length),
91 copy_fct lcaf_copy_fcts[LCAF_TYPES] = {
92 #define _(cond, name) \
93 EXPAND_FCN(cond, name##_copy),
98 free_fct lcaf_free_fcts[LCAF_TYPES] = {
99 #define _(cond, name) \
100 EXPAND_FCN(cond, name##_free),
105 size_to_write_fct lcaf_size_to_write_fcts[LCAF_TYPES] = {
106 #define _(cond, name) \
107 EXPAND_FCN(cond, name##_size_to_write),
112 serdes_fct lcaf_write_fcts[LCAF_TYPES] = {
113 #define _(cond, name) \
114 EXPAND_FCN(cond, name##_write),
119 serdes_fct lcaf_parse_fcts[LCAF_TYPES] = {
120 #define _(cond, name) \
121 EXPAND_FCN(cond, name##_parse),
127 format_ip_address (u8 * s, va_list * args)
129 ip_address_t *a = va_arg (*args, ip_address_t *);
130 u8 ver = ip_addr_version (a);
133 return format (s, "%U", format_ip4_address, &ip_addr_v4 (a));
137 return format (s, "%U", format_ip6_address, &ip_addr_v6 (a));
141 clib_warning ("Can't format IP version %d!", ver);
147 unformat_ip_address (unformat_input_t * input, va_list * args)
149 ip_address_t *a = va_arg (*args, ip_address_t *);
151 memset (a, 0, sizeof (*a));
152 if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (a)))
153 ip_addr_version (a) = IP4;
154 else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6 (a)))
155 ip_addr_version (a) = IP6;
162 format_ip_prefix (u8 * s, va_list * args)
164 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
165 return format (s, "%U/%d", format_ip_address, &ip_prefix_addr (a),
170 unformat_ip_prefix (unformat_input_t * input, va_list * args)
172 ip_prefix_t *a = va_arg (*args, ip_prefix_t *);
173 if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr (a),
176 if ((ip_prefix_version (a) == IP4 && 32 < ip_prefix_len (a)) ||
177 (ip_prefix_version (a) == IP6 && 128 < ip_prefix_length (a)))
179 clib_warning ("Prefix length to big: %d!", ip_prefix_len (a));
182 ip_prefix_normalize (a);
190 unformat_mac_address (unformat_input_t * input, va_list * args)
192 u8 *a = va_arg (*args, u8 *);
193 return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
198 format_mac_address (u8 * s, va_list * args)
200 u8 *a = va_arg (*args, u8 *);
201 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
202 a[0], a[1], a[2], a[3], a[4], a[5]);
206 unformat_nsh_address (unformat_input_t * input, va_list * args)
208 nsh_t *a = va_arg (*args, nsh_t *);
209 return unformat (input, "SPI:%d SI:%d", &a->spi, &a->si);
213 format_nsh_address (u8 * s, va_list * args)
215 nsh_t *a = va_arg (*args, nsh_t *);
216 return format (s, "SPI:%d SI:%d", a->spi, a->si);
220 format_fid_address (u8 * s, va_list * args)
222 fid_address_t *a = va_arg (*args, fid_address_t *);
224 switch (fid_addr_type (a))
226 case FID_ADDR_IP_PREF:
227 return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
229 return format (s, "%U", format_mac_address, &fid_addr_mac (a));
231 return format (s, "%U", format_nsh_address, &fid_addr_nsh (a));
234 clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
241 format_gid_address (u8 * s, va_list * args)
243 gid_address_t *a = va_arg (*args, gid_address_t *);
244 u8 type = gid_address_type (a);
247 case GID_ADDR_IP_PREFIX:
248 return format (s, "[%d] %U", gid_address_vni (a), format_ip_prefix,
249 &gid_address_ippref (a));
250 case GID_ADDR_SRC_DST:
251 return format (s, "[%d] %U|%U", gid_address_vni (a),
252 format_fid_address, &gid_address_sd_src (a),
253 format_fid_address, &gid_address_sd_dst (a));
255 return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
256 &gid_address_mac (a));
258 return format (s, "%U", format_nsh_address, &gid_address_nsh (a));
260 clib_warning ("Can't format gid type %d", type);
267 unformat_fid_address (unformat_input_t * i, va_list * args)
269 fid_address_t *a = va_arg (*args, fid_address_t *);
274 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
276 fid_addr_type (a) = FID_ADDR_IP_PREF;
277 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
279 else if (unformat (i, "%U", unformat_mac_address, mac))
281 fid_addr_type (a) = FID_ADDR_MAC;
282 mac_copy (fid_addr_mac (a), mac);
284 else if (unformat (i, "%U", unformat_nsh_address, &nsh))
286 fid_addr_type (a) = FID_ADDR_NSH;
287 nsh_copy (&fid_addr_nsh (a), mac);
296 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
298 u32 *key_id = va_arg (*args, u32 *);
301 if (unformat (input, "%s", &s))
303 if (!strcmp ((char *) s, "sha1"))
304 key_id[0] = HMAC_SHA_1_96;
305 else if (!strcmp ((char *) s, "sha256"))
306 key_id[0] = HMAC_SHA_256_128;
309 clib_warning ("invalid key_id: '%s'", s);
310 key_id[0] = HMAC_NO_KEY;
321 unformat_gid_address (unformat_input_t * input, va_list * args)
323 gid_address_t *a = va_arg (*args, gid_address_t *);
326 fid_address_t sim1, sim2;
329 memset (&ippref, 0, sizeof (ippref));
330 memset (&sim1, 0, sizeof (sim1));
331 memset (&sim2, 0, sizeof (sim2));
333 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
334 unformat_fid_address, &sim2))
336 gid_address_sd_src (a) = sim1;
337 gid_address_sd_dst (a) = sim2;
338 gid_address_type (a) = GID_ADDR_SRC_DST;
340 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
342 ip_prefix_copy (&gid_address_ippref (a), &ippref);
343 gid_address_type (a) = GID_ADDR_IP_PREFIX;
345 else if (unformat (input, "%U", unformat_mac_address, mac))
347 mac_copy (gid_address_mac (a), mac);
348 gid_address_type (a) = GID_ADDR_MAC;
350 else if (unformat (input, "%U", unformat_nsh_address, &nsh))
352 nsh_copy (&gid_address_nsh (a), &nsh);
353 gid_address_type (a) = GID_ADDR_NSH;
362 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
364 u32 *action = va_arg (*args, u32 *);
367 if (unformat (input, "%s", &s))
369 if (!strcmp ((char *) s, "no-action"))
370 action[0] = LISP_NO_ACTION;
371 else if (!strcmp ((char *) s, "natively-forward"))
372 action[0] = LISP_FORWARD_NATIVE;
373 else if (!strcmp ((char *) s, "send-map-request"))
374 action[0] = LISP_SEND_MAP_REQUEST;
375 else if (!strcmp ((char *) s, "drop"))
376 action[0] = LISP_DROP;
379 clib_warning ("invalid action: '%s'", s);
380 action[0] = LISP_DROP;
391 format_hmac_key_id (u8 * s, va_list * args)
393 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
398 return format (0, "sha1");
399 case HMAC_SHA_256_128:
400 return format (0, "sha256");
409 format_negative_mapping_action (u8 * s, va_list * args)
411 lisp_action_e action = va_arg (*args, lisp_action_e);
416 s = format (s, "no-action");
418 case LISP_FORWARD_NATIVE:
419 s = format (s, "natively-forward");
421 case LISP_SEND_MAP_REQUEST:
422 s = format (s, "send-map-request");
426 s = format (s, "drop");
433 ip_address_size (const ip_address_t * a)
435 switch (ip_addr_version (a))
438 return sizeof (ip4_address_t);
441 return sizeof (ip6_address_t);
448 ip_version_to_size (u8 ver)
453 return sizeof (ip4_address_t);
456 return sizeof (ip6_address_t);
463 ip_version_to_max_plen (u8 ver)
477 always_inline lisp_afi_e
478 ip_version_to_iana_afi (u16 version)
493 ip_iana_afi_to_version (lisp_afi_e afi)
508 ip_address_size_to_write (ip_address_t * a)
510 return ip_address_size (a) + sizeof (u16);
514 ip_address_iana_afi (ip_address_t * a)
516 return ip_version_to_iana_afi (ip_addr_version (a));
520 ip_address_max_len (u8 version)
522 return version == IP4 ? 32 : 128;
526 ip4_address_size_to_put ()
528 // return sizeof(u16) + sizeof (ip4_address_t);
533 ip6_address_size_to_put ()
535 //return sizeof(u16) + sizeof (ip6_address_t);
540 ip4_address_put (u8 * b, ip4_address_t * a)
542 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
543 u8 *p = b + sizeof (u16);
544 clib_memcpy (p, a, sizeof (*a));
545 return ip4_address_size_to_put ();
549 ip6_address_put (u8 * b, ip6_address_t * a)
551 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
552 u8 *p = b + sizeof (u16);
553 clib_memcpy (p, a, sizeof (*a));
554 return ip6_address_size_to_put ();
558 ip_address_put (u8 * b, ip_address_t * a)
560 u32 len = ip_address_size (a);
561 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
562 u8 *p = b + sizeof (u16);
563 clib_memcpy (p, &ip_addr_addr (a), len);
564 return (len + sizeof (u16));
568 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
570 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
571 u8 size = ip_version_to_size (ip_addr_version (dst));
572 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
573 return (sizeof (u16) + size);
577 gid_to_dp_address (gid_address_t * g, dp_address_t * d)
579 switch (gid_address_type (g))
581 case GID_ADDR_SRC_DST:
582 switch (gid_address_sd_dst_type (g))
584 case FID_ADDR_IP_PREF:
585 ip_prefix_copy (&d->ippref, &gid_address_sd_dst_ippref (g));
586 d->type = FID_ADDR_IP_PREF;
589 mac_copy (&d->mac, &gid_address_sd_dst_mac (g));
590 d->type = FID_ADDR_MAC;
593 clib_warning ("Source/Dest address type %d not supported!",
594 gid_address_sd_dst_type (g));
598 case GID_ADDR_IP_PREFIX:
599 ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
600 d->type = FID_ADDR_IP_PREF;
603 mac_copy (&d->mac, &gid_address_mac (g));
604 d->type = FID_ADDR_MAC;
608 d->nsh = gid_address_nsh (g).spi << 8 | gid_address_nsh (g).si;
609 d->type = FID_ADDR_NSH;
615 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
617 lcaf_hdr_t *lh = offset;
618 lcaf->type = lh->type;
620 /* this is a bit of hack: since the LCAF Instance ID is the
621 only message that uses reserved2 field, we can set it here.
622 If any LCAF format starts using reserved2 field as well this needs
623 to be moved elsewhere */
624 lcaf_vni_len (lcaf) = lh->reserved2;
626 return sizeof (lh[0]);
630 iana_afi_to_fid_addr_type (u16 type)
636 return FID_ADDR_IP_PREF;
645 fid_addr_parse (u8 * p, fid_address_t * a)
647 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
648 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
649 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
651 switch (fid_addr_type (a))
654 return mac_parse (p, fid_addr_mac (a));
656 case FID_ADDR_IP_PREF:
657 return ip_address_parse (p, afi, ip_addr);
665 #define INC(dst, exp) \
668 if ((u16)~0 == _sum) \
674 sd_parse (u8 * p, void *a)
676 lcaf_src_dst_hdr_t *sd_hdr;
677 gid_address_t *g = a;
679 fid_address_t *src = &gid_address_sd_src (g);
680 fid_address_t *dst = &gid_address_sd_dst (g);
682 gid_address_type (g) = GID_ADDR_SRC_DST;
684 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
685 size += sizeof (sd_hdr[0]);
687 INC (size, fid_addr_parse (p + size, src));
688 INC (size, fid_addr_parse (p + size, dst));
690 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
692 ip_prefix_t *ippref = &fid_addr_ippref (src);
693 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
695 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
697 ip_prefix_t *ippref = &fid_addr_ippref (dst);
698 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
704 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
707 u16 size = sizeof (u16); /* skip AFI */
709 size += lcaf_hdr_parse (p + size, &lcaf);
711 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
714 INC (size, sd_parse (p + size, a));
719 vni_parse (u8 * p, void *a)
722 gid_address_t *g = a;
725 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
726 size += sizeof (u32);
727 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
729 /* nested LCAFs are not supported except of src/dst with vni - to handle
730 * such case look at the next AFI and process src/dest LCAF separately */
731 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
732 if (LISP_AFI_LCAF == afi)
734 INC (size, try_parse_src_dst_lcaf (p + size, g));
737 INC (size, gid_address_parse (p + size, g));
743 no_addr_parse (u8 * p, void *a)
750 lcaf_parse (void *offset, gid_address_t * addr)
753 offset += sizeof (u16);
754 lcaf_t *lcaf = &gid_address_lcaf (addr);
756 u32 size = lcaf_hdr_parse (offset, lcaf);
757 u8 type = lcaf_type (lcaf);
759 if (!lcaf_parse_fcts[type])
761 clib_warning ("Unsupported LCAF type: %u", type);
764 INC (size, (*lcaf_parse_fcts[type]) (offset + size, lcaf));
765 return sizeof (u16) + size;
772 gid_address_free (vni_gid (v));
773 clib_mem_free (vni_gid (v));
777 no_addr_free (void *a)
789 gid_address_free (gid_address_t * a)
791 if (gid_address_type (a) != GID_ADDR_LCAF)
794 lcaf_t *lcaf = &gid_address_lcaf (a);
795 u8 lcaf_type = lcaf_type (lcaf);
796 (*lcaf_free_fcts[lcaf_type]) (lcaf);
800 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
802 memset (g, 0, sizeof (g[0]));
803 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
804 gid_address_ippref_len (g) = 32;
808 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
811 if (ip_addr_version (ip1) != ip_addr_version (ip2))
814 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
825 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
827 if (IP4 == ip_addr_version (src))
829 /* don't copy any garbe from the union */
830 memset (dst, 0, sizeof (*dst));
831 dst->ip.v4 = src->ip.v4;
836 clib_memcpy (dst, src, sizeof (ip_address_t));
841 ip_address_copy_addr (void *dst, const ip_address_t * src)
843 clib_memcpy (dst, src, ip_address_size (src));
847 ip_address_set (ip_address_t * dst, const void *src, u8 version)
849 clib_memcpy (dst, src, ip_version_to_size (version));
850 ip_addr_version (dst) = version;
854 ip_address_to_46 (const ip_address_t * addr,
855 ip46_address_t * a, fib_protocol_t * proto)
857 *proto = (IP4 == ip_addr_version (addr) ?
858 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
861 case FIB_PROTOCOL_IP4:
862 ip46_address_set_ip4 (a, &addr->ip.v4);
864 case FIB_PROTOCOL_IP6:
865 a->ip6 = addr->ip.v6;
874 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
885 mask = pow2_mask (preflen) << (32 - preflen);
886 mask = clib_host_to_net_u32 (mask);
887 ip4->data_u32 &= mask;
891 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
899 memset (mask_6, 0, sizeof (mask_6));
908 m = (u32 *) & mask_6[0];
910 for (j = 0; j < i0; j++)
917 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
920 for (j = 0; j < sizeof (mask_6); j++)
922 ip6->as_u8[j] &= mask_6[j];
927 ip_prefix_normalize (ip_prefix_t * a)
929 u8 preflen = ip_prefix_len (a);
931 switch (ip_prefix_version (a))
934 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
938 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
947 ip_prefix_cast (gid_address_t * a)
949 return &gid_address_ippref (a);
953 ip_prefix_size_to_write (void *pref)
955 ip_prefix_t *a = (ip_prefix_t *) pref;
956 return ip_address_size_to_write (&ip_prefix_addr (a));
960 ip_prefix_write (u8 * p, void *gid)
962 gid_address_t *g = gid;
963 ip_prefix_t *a = &gid_address_ippref (g);
965 switch (ip_prefix_version (a))
968 return ip4_address_put (p, &ip_prefix_v4 (a));
971 return ip6_address_put (p, &ip_prefix_v6 (a));
978 ip_prefix_length (void *a)
980 return ip_prefix_len ((ip_prefix_t *) a);
984 ip_prefix_copy (void *dst, void *src)
986 clib_memcpy (dst, src, sizeof (ip_prefix_t));
990 mac_copy (void *dst, void *src)
992 clib_memcpy (dst, src, 6);
996 sd_copy (void *dst, void *src)
998 clib_memcpy (dst, src, sizeof (source_dest_t));
1002 nsh_copy (void *dst, void *src)
1004 clib_memcpy (dst, src, sizeof (nsh_t));
1008 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
1012 ip_prefix_normalize (p1);
1013 ip_prefix_normalize (p2);
1015 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
1018 if (ip_prefix_len (p1) < ip_prefix_len (p2))
1024 if (ip_prefix_len (p1) > ip_prefix_len (p2))
1032 no_addr_copy (void *dst, void *src)
1038 vni_copy (void *dst, void *src)
1043 clib_memcpy (vd, vs, sizeof (vd[0]));
1044 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
1045 gid_address_copy (vni_gid (vd), vni_gid (vs));
1049 lcaf_copy (void *dst, void *src)
1051 lcaf_t *lcaf_dst = dst;
1052 lcaf_t *lcaf_src = src;
1054 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
1055 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
1059 lcaf_length (void *a)
1065 mac_length (void *a)
1077 nsh_length (void *a)
1083 lcaf_cast (gid_address_t * a)
1085 return &gid_address_lcaf (a);
1089 mac_cast (gid_address_t * a)
1091 return &gid_address_mac (a);
1095 sd_cast (gid_address_t * a)
1097 return &gid_address_sd (a);
1101 nsh_cast (gid_address_t * a)
1103 return &gid_address_nsh (a);
1107 no_addr_length (void *a)
1113 vni_length (void *a)
1116 return (sizeof (u32) /* VNI size */
1117 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1121 lcaf_write (u8 * p, void *a)
1125 u8 type = lcaf_type (lcaf);
1126 lcaf_hdr_t _h, *h = &_h;
1128 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1129 size += sizeof (u16);
1130 memset (h, 0, sizeof (h[0]));
1131 LCAF_TYPE (h) = type;
1132 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1133 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1135 clib_memcpy (p + size, h, sizeof (h[0]));
1136 size += sizeof (h[0]);
1137 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1139 if ((u16) ~ 0 == len)
1146 mac_write (u8 * p, void *a)
1148 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1149 clib_memcpy (p + sizeof (u16), a, 6);
1150 return mac_size_to_write (a);
1154 fid_addr_write (u8 * p, fid_address_t * a)
1156 switch (fid_addr_type (a))
1158 case FID_ADDR_IP_PREF:
1159 return ip_prefix_write (p, &fid_addr_ippref (a));
1162 return mac_write (p, &fid_addr_mac (a));
1171 fid_address_length (fid_address_t * a)
1173 switch (fid_addr_type (a))
1175 case FID_ADDR_IP_PREF:
1176 return ip_prefix_length (&fid_addr_ippref (a));
1186 sd_write (u8 * p, void *a)
1188 source_dest_t *sd = a;
1190 lcaf_hdr_t _h, *h = &_h;
1191 lcaf_src_dst_hdr_t sd_hdr;
1193 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1194 size += sizeof (u16);
1195 memset (h, 0, sizeof (h[0]));
1196 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1197 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1198 + fid_addr_size_to_write (&sd_src (sd))
1199 + fid_addr_size_to_write (&sd_dst (sd));
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]);
1205 memset (&sd_hdr, 0, sizeof (sd_hdr));
1206 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1207 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1208 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1209 size += sizeof (sd_hdr);
1211 u16 len = fid_addr_write (p + size, &sd_src (sd));
1212 if ((u16) ~ 0 == len)
1216 len = fid_addr_write (p + size, &sd_dst (sd));
1217 if ((u16) ~ 0 == len)
1225 nsh_write (u8 * p, void *a)
1227 clib_warning ("not done");
1232 vni_write (u8 * p, void *a)
1234 lcaf_hdr_t _h, *h = &_h;
1235 gid_address_t *g = a;
1238 /* put lcaf header */
1239 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1240 size += sizeof (u16);
1241 memset (h, 0, sizeof (h[0]));
1242 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1243 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1244 + gid_address_size_to_put_no_vni (g);
1245 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1246 LCAF_RES2 (h) = gid_address_vni_mask (g);
1248 /* put vni header */
1249 clib_memcpy (p + size, h, sizeof (h[0]));
1250 size += sizeof (h[0]);
1252 u32 *afip = (u32 *) (p + size);
1253 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1254 size += sizeof (u32);
1256 if (GID_ADDR_SRC_DST == gid_address_type (g))
1257 /* write src/dst LCAF */
1259 len = sd_write (p + size, g);
1260 if ((u16) ~ 0 == len)
1264 /* write the actual address */
1265 len = gid_address_put_no_vni (p + size, g);
1267 if ((u16) ~ 0 == len)
1274 no_addr_write (u8 * p, void *a)
1276 /* do nothing; return AFI field size */
1277 return sizeof (u16);
1281 no_addr_size_to_write (void *a)
1283 return sizeof (u16); /* AFI field length */
1287 fid_addr_size_to_write (fid_address_t * a)
1289 switch (fid_addr_type (a))
1291 case FID_ADDR_IP_PREF:
1292 return ip_prefix_size_to_write (a);
1295 return mac_size_to_write (a);
1304 vni_size_to_write (void *a)
1306 gid_address_t *g = a;
1308 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1309 + sizeof (lcaf_hdr_t);
1311 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1312 /* special case where nested LCAF is supported */
1313 return lcaf_size + sd_size_to_write (g);
1315 return lcaf_size + gid_address_size_to_put_no_vni (g);
1319 lcaf_size_to_write (void *a)
1321 lcaf_t *lcaf = (lcaf_t *) a;
1323 u8 type = lcaf_type (lcaf);
1325 size += sizeof (u16); /* AFI size */
1327 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1335 sd_size_to_write (void *a)
1337 source_dest_t *sd = a;
1339 + sizeof (lcaf_hdr_t)
1340 + sizeof (lcaf_src_dst_hdr_t)
1341 + fid_addr_size_to_write (&sd_src (sd))
1342 + fid_addr_size_to_write (&sd_dst (sd));
1346 mac_size_to_write (void *a)
1348 return sizeof (u16) + 6;
1352 nsh_size_to_write (void *a)
1354 return sizeof (u16) + 4;
1358 gid_address_len (gid_address_t * a)
1360 gid_address_type_t type = gid_address_type (a);
1361 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1365 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1367 gid_address_type_t type = gid_address_type (gid);
1368 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1372 gid_address_put (u8 * b, gid_address_t * gid)
1374 if (0 != gid_address_vni (gid))
1375 return vni_write (b, gid);
1377 return gid_address_put_no_vni (b, gid);
1381 gid_address_size_to_put_no_vni (gid_address_t * gid)
1383 gid_address_type_t type = gid_address_type (gid);
1384 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1388 gid_address_size_to_put (gid_address_t * gid)
1390 if (0 != gid_address_vni (gid))
1391 return vni_size_to_write (gid);
1393 return gid_address_size_to_put_no_vni (gid);
1397 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1399 return (*cast_fcts[type]) (gid);
1403 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1405 gid_address_type_t type = gid_address_type (src);
1406 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1407 gid_address_type (dst) = type;
1408 gid_address_vni (dst) = gid_address_vni (src);
1409 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1413 mac_parse (u8 * offset, u8 * a)
1415 /* skip AFI field */
1416 offset += sizeof (u16);
1418 clib_memcpy (a, offset, 6);
1419 return sizeof (u16) + 6;
1423 gid_address_parse (u8 * offset, gid_address_t * a)
1430 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1431 * the gid address here */
1432 afi = clib_net_to_host_u16 (*((u16 *) offset));
1436 case LISP_AFI_NO_ADDR:
1438 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1441 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1442 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1443 /* this should be modified outside if needed */
1444 gid_address_ippref_len (a) = 32;
1447 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1448 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1449 /* this should be modified outside if needed */
1450 gid_address_ippref_len (a) = 128;
1453 gid_address_type (a) = GID_ADDR_LCAF;
1454 len = lcaf_parse (offset, a);
1457 len = mac_parse (offset, gid_address_mac (a));
1458 gid_address_type (a) = GID_ADDR_MAC;
1461 clib_warning ("LISP AFI %d not supported!", afi);
1464 return (len == (u16) ~ 0) ? ~0 : len;
1468 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1470 gid_address_ippref_len (dst) = ip_address_max_len (version);
1471 ip_address_set (&gid_address_ip (dst), src, version);
1475 no_addr_cmp (void *a1, void *a2)
1481 vni_cmp (void *a1, void *a2)
1486 if (vni_mask_len (v1) != vni_mask_len (v2))
1488 if (vni_vni (v1) != vni_vni (v2))
1490 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1494 mac_cmp (void *a1, void *a2)
1496 return memcmp (a1, a2, 6);
1500 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1502 if (fid_addr_type (a1) != fid_addr_type (a2))
1505 switch (fid_addr_type (a1))
1507 case FID_ADDR_IP_PREF:
1508 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1511 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1520 sd_cmp (void *a1, void *a2)
1522 source_dest_t *sd1 = a1;
1523 source_dest_t *sd2 = a2;
1525 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1527 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1532 /* Compare two gid_address_t.
1534 * -1: If they are from different afi
1535 * 0: Both address are the same
1536 * 1: Addr1 is bigger than addr2
1537 * 2: Addr2 is bigger than addr1
1540 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1542 lcaf_t *lcaf1, *lcaf2;
1546 if (gid_address_type (a1) != gid_address_type (a2))
1548 if (gid_address_vni (a1) != gid_address_vni (a2))
1551 /* TODO vni mask is not supported, disable comparing for now
1552 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1556 switch (gid_address_type (a1))
1558 case GID_ADDR_NO_ADDRESS:
1564 case GID_ADDR_IP_PREFIX:
1566 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1569 lcaf1 = &gid_address_lcaf (a1);
1570 lcaf2 = &gid_address_lcaf (a2);
1571 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1572 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1575 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1578 case GID_ADDR_SRC_DST:
1579 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1589 locator_parse (void *b, locator_t * loc)
1592 u8 status = 1; /* locator up */
1596 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1599 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1603 loc->state = status;
1605 loc->priority = LOC_PRIORITY (h);
1606 loc->weight = LOC_WEIGHT (h);
1607 loc->mpriority = LOC_MPRIORITY (h);
1608 loc->mweight = LOC_MWEIGHT (h);
1610 return sizeof (locator_hdr_t) + len;
1614 locator_copy (locator_t * dst, locator_t * src)
1616 /* TODO if gid become more complex, this will need to be changed! */
1617 clib_memcpy (dst, src, sizeof (*dst));
1619 gid_address_copy (&dst->address, &src->address);
1623 locator_cmp (locator_t * l1, locator_t * l2)
1626 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1629 if (l1->priority != l2->priority)
1631 if (l1->weight != l2->weight)
1633 if (l1->mpriority != l2->mpriority)
1635 if (l1->mweight != l2->mweight)
1641 locator_free (locator_t * l)
1644 gid_address_free (&l->address);
1648 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1650 memset (sd, 0, sizeof (*sd));
1651 gid_address_type (sd) = GID_ADDR_SRC_DST;
1652 gid_address_vni (sd) = gid_address_vni (dst);
1653 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1655 switch (gid_address_type (dst))
1657 case GID_ADDR_IP_PREFIX:
1658 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1659 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1660 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1661 &gid_address_ippref (src));
1662 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1663 &gid_address_ippref (dst));
1666 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1667 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1668 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1669 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1672 clib_warning ("Unsupported gid type %d while conversion!",
1673 gid_address_type (dst));
1679 * fd.io coding-style-patch-verification: ON
1682 * eval: (c-set-style "gnu")