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);
667 sd_parse (u8 * p, void *a)
669 lcaf_src_dst_hdr_t *sd_hdr;
670 gid_address_t *g = a;
672 fid_address_t *src = &gid_address_sd_src (g);
673 fid_address_t *dst = &gid_address_sd_dst (g);
675 gid_address_type (g) = GID_ADDR_SRC_DST;
677 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
678 size += sizeof (sd_hdr[0]);
680 size += fid_addr_parse (p + size, src);
681 size += fid_addr_parse (p + size, dst);
683 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
685 ip_prefix_t *ippref = &fid_addr_ippref (src);
686 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
688 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
690 ip_prefix_t *ippref = &fid_addr_ippref (dst);
691 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
697 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
700 u16 size = sizeof (u16); /* skip AFI */
702 size += lcaf_hdr_parse (p + size, &lcaf);
704 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
707 size += sd_parse (p + size, a);
712 vni_parse (u8 * p, void *a)
715 gid_address_t *g = a;
718 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
719 size += sizeof (u32);
720 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
722 /* nested LCAFs are not supported except of src/dst with vni - to handle
723 * such case look at the next AFI and process src/dest LCAF separately */
724 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
725 if (LISP_AFI_LCAF == afi)
727 u16 len = try_parse_src_dst_lcaf (p + size, g);
728 if ((u16) ~ 0 == len)
733 size += gid_address_parse (p + size, g);
739 no_addr_parse (u8 * p, void *a)
746 lcaf_parse (void *offset, gid_address_t * addr)
749 offset += sizeof (u16);
750 lcaf_t *lcaf = &gid_address_lcaf (addr);
752 u32 size = lcaf_hdr_parse (offset, lcaf);
753 u8 type = lcaf_type (lcaf);
755 if (!lcaf_parse_fcts[type])
757 clib_warning ("Unsupported LCAF type: %u", type);
760 size += (*lcaf_parse_fcts[type]) (offset + size, lcaf);
761 return sizeof (u16) + size;
768 gid_address_free (vni_gid (v));
769 clib_mem_free (vni_gid (v));
773 no_addr_free (void *a)
785 gid_address_free (gid_address_t * a)
787 if (gid_address_type (a) != GID_ADDR_LCAF)
790 lcaf_t *lcaf = &gid_address_lcaf (a);
791 u8 lcaf_type = lcaf_type (lcaf);
792 (*lcaf_free_fcts[lcaf_type]) (lcaf);
796 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
798 memset (g, 0, sizeof (g[0]));
799 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
800 gid_address_ippref_len (g) = 32;
804 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
807 if (ip_addr_version (ip1) != ip_addr_version (ip2))
810 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
821 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
823 if (IP4 == ip_addr_version (src))
825 /* don't copy any garbe from the union */
826 memset (dst, 0, sizeof (*dst));
827 dst->ip.v4 = src->ip.v4;
832 clib_memcpy (dst, src, sizeof (ip_address_t));
837 ip_address_copy_addr (void *dst, const ip_address_t * src)
839 clib_memcpy (dst, src, ip_address_size (src));
843 ip_address_set (ip_address_t * dst, const void *src, u8 version)
845 clib_memcpy (dst, src, ip_version_to_size (version));
846 ip_addr_version (dst) = version;
850 ip_address_to_46 (const ip_address_t * addr,
851 ip46_address_t * a, fib_protocol_t * proto)
853 *proto = (IP4 == ip_addr_version (addr) ?
854 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
857 case FIB_PROTOCOL_IP4:
858 ip46_address_set_ip4 (a, &addr->ip.v4);
860 case FIB_PROTOCOL_IP6:
861 a->ip6 = addr->ip.v6;
870 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
881 mask = pow2_mask (preflen) << (32 - preflen);
882 mask = clib_host_to_net_u32 (mask);
883 ip4->data_u32 &= mask;
887 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
895 memset (mask_6, 0, sizeof (mask_6));
904 m = (u32 *) & mask_6[0];
906 for (j = 0; j < i0; j++)
913 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
916 for (j = 0; j < sizeof (mask_6); j++)
918 ip6->as_u8[j] &= mask_6[j];
923 ip_prefix_normalize (ip_prefix_t * a)
925 u8 preflen = ip_prefix_len (a);
927 switch (ip_prefix_version (a))
930 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
934 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
943 ip_prefix_cast (gid_address_t * a)
945 return &gid_address_ippref (a);
949 ip_prefix_size_to_write (void *pref)
951 ip_prefix_t *a = (ip_prefix_t *) pref;
952 return ip_address_size_to_write (&ip_prefix_addr (a));
956 ip_prefix_write (u8 * p, void *gid)
958 gid_address_t *g = gid;
959 ip_prefix_t *a = &gid_address_ippref (g);
961 switch (ip_prefix_version (a))
964 return ip4_address_put (p, &ip_prefix_v4 (a));
967 return ip6_address_put (p, &ip_prefix_v6 (a));
974 ip_prefix_length (void *a)
976 return ip_prefix_len ((ip_prefix_t *) a);
980 ip_prefix_copy (void *dst, void *src)
982 clib_memcpy (dst, src, sizeof (ip_prefix_t));
986 mac_copy (void *dst, void *src)
988 clib_memcpy (dst, src, 6);
992 sd_copy (void *dst, void *src)
994 clib_memcpy (dst, src, sizeof (source_dest_t));
998 nsh_copy (void *dst, void *src)
1000 clib_memcpy (dst, src, sizeof (nsh_t));
1004 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
1008 ip_prefix_normalize (p1);
1009 ip_prefix_normalize (p2);
1011 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
1014 if (ip_prefix_len (p1) < ip_prefix_len (p2))
1020 if (ip_prefix_len (p1) > ip_prefix_len (p2))
1028 no_addr_copy (void *dst, void *src)
1034 vni_copy (void *dst, void *src)
1039 clib_memcpy (vd, vs, sizeof (vd[0]));
1040 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
1041 gid_address_copy (vni_gid (vd), vni_gid (vs));
1045 lcaf_copy (void *dst, void *src)
1047 lcaf_t *lcaf_dst = dst;
1048 lcaf_t *lcaf_src = src;
1050 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
1051 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
1055 lcaf_length (void *a)
1061 mac_length (void *a)
1073 nsh_length (void *a)
1079 lcaf_cast (gid_address_t * a)
1081 return &gid_address_lcaf (a);
1085 mac_cast (gid_address_t * a)
1087 return &gid_address_mac (a);
1091 sd_cast (gid_address_t * a)
1093 return &gid_address_sd (a);
1097 nsh_cast (gid_address_t * a)
1099 return &gid_address_nsh (a);
1103 no_addr_length (void *a)
1109 vni_length (void *a)
1112 return (sizeof (u32) /* VNI size */
1113 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1117 lcaf_write (u8 * p, void *a)
1121 u8 type = lcaf_type (lcaf);
1122 lcaf_hdr_t _h, *h = &_h;
1124 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1125 size += sizeof (u16);
1126 memset (h, 0, sizeof (h[0]));
1127 LCAF_TYPE (h) = type;
1128 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1129 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1131 clib_memcpy (p + size, h, sizeof (h[0]));
1132 size += sizeof (h[0]);
1133 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1135 if ((u16) ~ 0 == len)
1142 mac_write (u8 * p, void *a)
1144 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1145 clib_memcpy (p + sizeof (u16), a, 6);
1146 return mac_size_to_write (a);
1150 fid_addr_write (u8 * p, fid_address_t * a)
1152 switch (fid_addr_type (a))
1154 case FID_ADDR_IP_PREF:
1155 return ip_prefix_write (p, &fid_addr_ippref (a));
1158 return mac_write (p, &fid_addr_mac (a));
1167 fid_address_length (fid_address_t * a)
1169 switch (fid_addr_type (a))
1171 case FID_ADDR_IP_PREF:
1172 return ip_prefix_length (&fid_addr_ippref (a));
1182 sd_write (u8 * p, void *a)
1184 source_dest_t *sd = a;
1186 lcaf_hdr_t _h, *h = &_h;
1187 lcaf_src_dst_hdr_t sd_hdr;
1189 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1190 size += sizeof (u16);
1191 memset (h, 0, sizeof (h[0]));
1192 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1193 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1194 + fid_addr_size_to_write (&sd_src (sd))
1195 + fid_addr_size_to_write (&sd_dst (sd));
1196 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1198 clib_memcpy (p + size, h, sizeof (h[0]));
1199 size += sizeof (h[0]);
1201 memset (&sd_hdr, 0, sizeof (sd_hdr));
1202 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1203 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1204 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1205 size += sizeof (sd_hdr);
1207 u16 len = fid_addr_write (p + size, &sd_src (sd));
1208 if ((u16) ~ 0 == len)
1212 len = fid_addr_write (p + size, &sd_dst (sd));
1213 if ((u16) ~ 0 == len)
1221 nsh_write (u8 * p, void *a)
1223 clib_warning ("not done");
1228 vni_write (u8 * p, void *a)
1230 lcaf_hdr_t _h, *h = &_h;
1231 gid_address_t *g = a;
1234 /* put lcaf header */
1235 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1236 size += sizeof (u16);
1237 memset (h, 0, sizeof (h[0]));
1238 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1239 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1240 + gid_address_size_to_put_no_vni (g);
1241 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1242 LCAF_RES2 (h) = gid_address_vni_mask (g);
1244 /* put vni header */
1245 clib_memcpy (p + size, h, sizeof (h[0]));
1246 size += sizeof (h[0]);
1248 u32 *afip = (u32 *) (p + size);
1249 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1250 size += sizeof (u32);
1252 if (GID_ADDR_SRC_DST == gid_address_type (g))
1253 /* write src/dst LCAF */
1255 len = sd_write (p + size, g);
1256 if ((u16) ~ 0 == len)
1260 /* write the actual address */
1261 len = gid_address_put_no_vni (p + size, g);
1263 if ((u16) ~ 0 == len)
1270 no_addr_write (u8 * p, void *a)
1272 /* do nothing; return AFI field size */
1273 return sizeof (u16);
1277 no_addr_size_to_write (void *a)
1279 return sizeof (u16); /* AFI field length */
1283 fid_addr_size_to_write (fid_address_t * a)
1285 switch (fid_addr_type (a))
1287 case FID_ADDR_IP_PREF:
1288 return ip_prefix_size_to_write (a);
1291 return mac_size_to_write (a);
1300 vni_size_to_write (void *a)
1302 gid_address_t *g = a;
1304 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1305 + sizeof (lcaf_hdr_t);
1307 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1308 /* special case where nested LCAF is supported */
1309 return lcaf_size + sd_size_to_write (g);
1311 return lcaf_size + gid_address_size_to_put_no_vni (g);
1315 lcaf_size_to_write (void *a)
1317 lcaf_t *lcaf = (lcaf_t *) a;
1319 u8 type = lcaf_type (lcaf);
1321 size += sizeof (u16); /* AFI size */
1323 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1331 sd_size_to_write (void *a)
1333 source_dest_t *sd = a;
1335 + sizeof (lcaf_hdr_t)
1336 + sizeof (lcaf_src_dst_hdr_t)
1337 + fid_addr_size_to_write (&sd_src (sd))
1338 + fid_addr_size_to_write (&sd_dst (sd));
1342 mac_size_to_write (void *a)
1344 return sizeof (u16) + 6;
1348 nsh_size_to_write (void *a)
1350 return sizeof (u16) + 4;
1354 gid_address_len (gid_address_t * a)
1356 gid_address_type_t type = gid_address_type (a);
1357 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1361 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1363 gid_address_type_t type = gid_address_type (gid);
1364 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1368 gid_address_put (u8 * b, gid_address_t * gid)
1370 if (0 != gid_address_vni (gid))
1371 return vni_write (b, gid);
1373 return gid_address_put_no_vni (b, gid);
1377 gid_address_size_to_put_no_vni (gid_address_t * gid)
1379 gid_address_type_t type = gid_address_type (gid);
1380 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1384 gid_address_size_to_put (gid_address_t * gid)
1386 if (0 != gid_address_vni (gid))
1387 return vni_size_to_write (gid);
1389 return gid_address_size_to_put_no_vni (gid);
1393 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1395 return (*cast_fcts[type]) (gid);
1399 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1401 gid_address_type_t type = gid_address_type (src);
1402 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1403 gid_address_type (dst) = type;
1404 gid_address_vni (dst) = gid_address_vni (src);
1405 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1409 mac_parse (u8 * offset, u8 * a)
1411 /* skip AFI field */
1412 offset += sizeof (u16);
1414 clib_memcpy (a, offset, 6);
1415 return sizeof (u16) + 6;
1419 gid_address_parse (u8 * offset, gid_address_t * a)
1427 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1428 * the gid address here */
1429 afi = clib_net_to_host_u16 (*((u16 *) offset));
1433 case LISP_AFI_NO_ADDR:
1435 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
1438 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1439 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1440 /* this should be modified outside if needed */
1441 gid_address_ippref_len (a) = 32;
1444 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1445 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1446 /* this should be modified outside if needed */
1447 gid_address_ippref_len (a) = 128;
1450 gid_address_type (a) = GID_ADDR_LCAF;
1451 len = lcaf_parse (offset, a);
1454 len = mac_parse (offset, gid_address_mac (a));
1455 gid_address_type (a) = GID_ADDR_MAC;
1458 clib_warning ("LISP AFI %d not supported!", afi);
1465 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1467 gid_address_ippref_len (dst) = ip_address_max_len (version);
1468 ip_address_set (&gid_address_ip (dst), src, version);
1472 no_addr_cmp (void *a1, void *a2)
1478 vni_cmp (void *a1, void *a2)
1483 if (vni_mask_len (v1) != vni_mask_len (v2))
1485 if (vni_vni (v1) != vni_vni (v2))
1487 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1491 mac_cmp (void *a1, void *a2)
1493 return memcmp (a1, a2, 6);
1497 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1499 if (fid_addr_type (a1) != fid_addr_type (a2))
1502 switch (fid_addr_type (a1))
1504 case FID_ADDR_IP_PREF:
1505 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1508 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1517 sd_cmp (void *a1, void *a2)
1519 source_dest_t *sd1 = a1;
1520 source_dest_t *sd2 = a2;
1522 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1524 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1529 /* Compare two gid_address_t.
1531 * -1: If they are from different afi
1532 * 0: Both address are the same
1533 * 1: Addr1 is bigger than addr2
1534 * 2: Addr2 is bigger than addr1
1537 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1539 lcaf_t *lcaf1, *lcaf2;
1543 if (gid_address_type (a1) != gid_address_type (a2))
1545 if (gid_address_vni (a1) != gid_address_vni (a2))
1548 /* TODO vni mask is not supported, disable comparing for now
1549 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1553 switch (gid_address_type (a1))
1555 case GID_ADDR_NO_ADDRESS:
1561 case GID_ADDR_IP_PREFIX:
1563 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1566 lcaf1 = &gid_address_lcaf (a1);
1567 lcaf2 = &gid_address_lcaf (a2);
1568 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1569 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1572 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1575 case GID_ADDR_SRC_DST:
1576 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1586 locator_parse (void *b, locator_t * loc)
1589 u8 status = 1; /* locator up */
1593 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1596 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1600 loc->state = status;
1602 loc->priority = LOC_PRIORITY (h);
1603 loc->weight = LOC_WEIGHT (h);
1604 loc->mpriority = LOC_MPRIORITY (h);
1605 loc->mweight = LOC_MWEIGHT (h);
1607 return sizeof (locator_hdr_t) + len;
1611 locator_copy (locator_t * dst, locator_t * src)
1613 /* TODO if gid become more complex, this will need to be changed! */
1614 clib_memcpy (dst, src, sizeof (*dst));
1616 gid_address_copy (&dst->address, &src->address);
1620 locator_cmp (locator_t * l1, locator_t * l2)
1623 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1626 if (l1->priority != l2->priority)
1628 if (l1->weight != l2->weight)
1630 if (l1->mpriority != l2->mpriority)
1632 if (l1->mweight != l2->mweight)
1638 locator_free (locator_t * l)
1641 gid_address_free (&l->address);
1645 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1647 memset (sd, 0, sizeof (*sd));
1648 gid_address_type (sd) = GID_ADDR_SRC_DST;
1649 gid_address_vni (sd) = gid_address_vni (dst);
1650 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1652 switch (gid_address_type (dst))
1654 case GID_ADDR_IP_PREFIX:
1655 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1656 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1657 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1658 &gid_address_ippref (src));
1659 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1660 &gid_address_ippref (dst));
1663 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1664 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1665 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1666 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1669 clib_warning ("Unsupported gid type %d while conversion!",
1670 gid_address_type (dst));
1676 * fd.io coding-style-patch-verification: ON
1679 * eval: (c-set-style "gnu")