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 return format (s, "[%d, %U]", gid_address_arp_bd (a),
261 format_ip4_address, &gid_address_arp_ip4 (a));
263 clib_warning ("Can't format gid type %d", type);
270 unformat_fid_address (unformat_input_t * i, va_list * args)
272 fid_address_t *a = va_arg (*args, fid_address_t *);
277 if (unformat (i, "%U", unformat_ip_prefix, &ippref))
279 fid_addr_type (a) = FID_ADDR_IP_PREF;
280 ip_prefix_copy (&fid_addr_ippref (a), &ippref);
282 else if (unformat (i, "%U", unformat_mac_address, mac))
284 fid_addr_type (a) = FID_ADDR_MAC;
285 mac_copy (fid_addr_mac (a), mac);
287 else if (unformat (i, "%U", unformat_nsh_address, &nsh))
289 fid_addr_type (a) = FID_ADDR_NSH;
290 nsh_copy (&fid_addr_nsh (a), mac);
299 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
301 u32 *key_id = va_arg (*args, u32 *);
304 if (unformat (input, "%s", &s))
306 if (!strcmp ((char *) s, "sha1"))
307 key_id[0] = HMAC_SHA_1_96;
308 else if (!strcmp ((char *) s, "sha256"))
309 key_id[0] = HMAC_SHA_256_128;
312 clib_warning ("invalid key_id: '%s'", s);
313 key_id[0] = HMAC_NO_KEY;
324 unformat_gid_address (unformat_input_t * input, va_list * args)
326 gid_address_t *a = va_arg (*args, gid_address_t *);
329 fid_address_t sim1, sim2;
332 memset (&ippref, 0, sizeof (ippref));
333 memset (&sim1, 0, sizeof (sim1));
334 memset (&sim2, 0, sizeof (sim2));
336 if (unformat (input, "%U|%U", unformat_fid_address, &sim1,
337 unformat_fid_address, &sim2))
339 gid_address_sd_src (a) = sim1;
340 gid_address_sd_dst (a) = sim2;
341 gid_address_type (a) = GID_ADDR_SRC_DST;
343 else if (unformat (input, "%U", unformat_ip_prefix, &ippref))
345 ip_prefix_copy (&gid_address_ippref (a), &ippref);
346 gid_address_type (a) = GID_ADDR_IP_PREFIX;
348 else if (unformat (input, "%U", unformat_mac_address, mac))
350 mac_copy (gid_address_mac (a), mac);
351 gid_address_type (a) = GID_ADDR_MAC;
353 else if (unformat (input, "%U", unformat_nsh_address, &nsh))
355 nsh_copy (&gid_address_nsh (a), &nsh);
356 gid_address_type (a) = GID_ADDR_NSH;
365 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
367 u32 *action = va_arg (*args, u32 *);
370 if (unformat (input, "%s", &s))
372 if (!strcmp ((char *) s, "no-action"))
373 action[0] = LISP_NO_ACTION;
374 else if (!strcmp ((char *) s, "natively-forward"))
375 action[0] = LISP_FORWARD_NATIVE;
376 else if (!strcmp ((char *) s, "send-map-request"))
377 action[0] = LISP_SEND_MAP_REQUEST;
378 else if (!strcmp ((char *) s, "drop"))
379 action[0] = LISP_DROP;
382 clib_warning ("invalid action: '%s'", s);
383 action[0] = LISP_DROP;
394 format_hmac_key_id (u8 * s, va_list * args)
396 lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
401 return format (0, "sha1");
402 case HMAC_SHA_256_128:
403 return format (0, "sha256");
412 format_negative_mapping_action (u8 * s, va_list * args)
414 lisp_action_e action = va_arg (*args, lisp_action_e);
419 s = format (s, "no-action");
421 case LISP_FORWARD_NATIVE:
422 s = format (s, "natively-forward");
424 case LISP_SEND_MAP_REQUEST:
425 s = format (s, "send-map-request");
429 s = format (s, "drop");
436 ip_address_size (const ip_address_t * a)
438 switch (ip_addr_version (a))
441 return sizeof (ip4_address_t);
444 return sizeof (ip6_address_t);
451 ip_version_to_size (u8 ver)
456 return sizeof (ip4_address_t);
459 return sizeof (ip6_address_t);
466 ip_version_to_max_plen (u8 ver)
480 always_inline lisp_afi_e
481 ip_version_to_iana_afi (u16 version)
496 ip_iana_afi_to_version (lisp_afi_e afi)
511 ip_address_size_to_write (ip_address_t * a)
513 return ip_address_size (a) + sizeof (u16);
517 ip_address_iana_afi (ip_address_t * a)
519 return ip_version_to_iana_afi (ip_addr_version (a));
523 ip_address_max_len (u8 version)
525 return version == IP4 ? 32 : 128;
529 ip4_address_size_to_put ()
531 // return sizeof(u16) + sizeof (ip4_address_t);
536 ip6_address_size_to_put ()
538 //return sizeof(u16) + sizeof (ip6_address_t);
543 ip4_address_put (u8 * b, ip4_address_t * a)
545 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP4));
546 u8 *p = b + sizeof (u16);
547 clib_memcpy (p, a, sizeof (*a));
548 return ip4_address_size_to_put ();
552 ip6_address_put (u8 * b, ip6_address_t * a)
554 *(u16 *) b = clib_host_to_net_u16 (ip_version_to_iana_afi (IP6));
555 u8 *p = b + sizeof (u16);
556 clib_memcpy (p, a, sizeof (*a));
557 return ip6_address_size_to_put ();
561 ip_address_put (u8 * b, ip_address_t * a)
563 u32 len = ip_address_size (a);
564 *(u16 *) b = clib_host_to_net_u16 (ip_address_iana_afi (a));
565 u8 *p = b + sizeof (u16);
566 clib_memcpy (p, &ip_addr_addr (a), len);
567 return (len + sizeof (u16));
571 ip_address_parse (void *offset, u16 iana_afi, ip_address_t * dst)
573 ip_addr_version (dst) = ip_iana_afi_to_version (iana_afi);
574 u8 size = ip_version_to_size (ip_addr_version (dst));
575 clib_memcpy (&ip_addr_addr (dst), offset + sizeof (u16), size);
576 return (sizeof (u16) + size);
580 gid_to_dp_address (gid_address_t * g, dp_address_t * d)
582 switch (gid_address_type (g))
584 case GID_ADDR_SRC_DST:
585 switch (gid_address_sd_dst_type (g))
587 case FID_ADDR_IP_PREF:
588 ip_prefix_copy (&d->ippref, &gid_address_sd_dst_ippref (g));
589 d->type = FID_ADDR_IP_PREF;
592 mac_copy (&d->mac, &gid_address_sd_dst_mac (g));
593 d->type = FID_ADDR_MAC;
596 clib_warning ("Source/Dest address type %d not supported!",
597 gid_address_sd_dst_type (g));
601 case GID_ADDR_IP_PREFIX:
602 ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
603 d->type = FID_ADDR_IP_PREF;
606 mac_copy (&d->mac, &gid_address_mac (g));
607 d->type = FID_ADDR_MAC;
611 d->nsh = gid_address_nsh (g).spi << 8 | gid_address_nsh (g).si;
612 d->type = FID_ADDR_NSH;
618 lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
620 lcaf_hdr_t *lh = offset;
621 lcaf->type = lh->type;
623 /* this is a bit of hack: since the LCAF Instance ID is the
624 only message that uses reserved2 field, we can set it here.
625 If any LCAF format starts using reserved2 field as well this needs
626 to be moved elsewhere */
627 lcaf_vni_len (lcaf) = lh->reserved2;
629 return sizeof (lh[0]);
633 iana_afi_to_fid_addr_type (u16 type)
639 return FID_ADDR_IP_PREF;
648 fid_addr_parse (u8 * p, fid_address_t * a)
650 u16 afi = clib_net_to_host_u16 (*(u16 *) p);
651 fid_addr_type (a) = iana_afi_to_fid_addr_type (afi);
652 ip_address_t *ip_addr = &ip_prefix_addr (&fid_addr_ippref (a));
654 switch (fid_addr_type (a))
657 return mac_parse (p, fid_addr_mac (a));
659 case FID_ADDR_IP_PREF:
660 return ip_address_parse (p, afi, ip_addr);
668 #define INC(dst, exp) \
671 if ((u16)~0 == _sum) \
677 sd_parse (u8 * p, void *a)
679 lcaf_src_dst_hdr_t *sd_hdr;
680 gid_address_t *g = a;
682 fid_address_t *src = &gid_address_sd_src (g);
683 fid_address_t *dst = &gid_address_sd_dst (g);
685 gid_address_type (g) = GID_ADDR_SRC_DST;
687 sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
688 size += sizeof (sd_hdr[0]);
690 INC (size, fid_addr_parse (p + size, src));
691 INC (size, fid_addr_parse (p + size, dst));
693 if (fid_addr_type (src) == FID_ADDR_IP_PREF)
695 ip_prefix_t *ippref = &fid_addr_ippref (src);
696 ip_prefix_len (ippref) = LCAF_SD_SRC_ML (sd_hdr);
698 if (fid_addr_type (dst) == FID_ADDR_IP_PREF)
700 ip_prefix_t *ippref = &fid_addr_ippref (dst);
701 ip_prefix_len (ippref) = LCAF_SD_DST_ML (sd_hdr);
707 try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
710 u16 size = sizeof (u16); /* skip AFI */
712 size += lcaf_hdr_parse (p + size, &lcaf);
714 if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
717 INC (size, sd_parse (p + size, a));
722 vni_parse (u8 * p, void *a)
725 gid_address_t *g = a;
728 gid_address_vni (g) = clib_net_to_host_u32 (*(u32 *) p);
729 size += sizeof (u32);
730 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
732 /* nested LCAFs are not supported except of src/dst with vni - to handle
733 * such case look at the next AFI and process src/dest LCAF separately */
734 u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
735 if (LISP_AFI_LCAF == afi)
737 INC (size, try_parse_src_dst_lcaf (p + size, g));
740 INC (size, gid_address_parse (p + size, g));
746 no_addr_parse (u8 * p, void *a)
753 lcaf_parse (void *offset, gid_address_t * addr)
756 offset += sizeof (u16);
757 lcaf_t *lcaf = &gid_address_lcaf (addr);
759 u32 size = lcaf_hdr_parse (offset, lcaf);
760 u8 type = lcaf_type (lcaf);
762 if (!lcaf_parse_fcts[type])
764 clib_warning ("Unsupported LCAF type: %u", type);
767 INC (size, (*lcaf_parse_fcts[type]) (offset + size, lcaf));
768 return sizeof (u16) + size;
775 gid_address_free (vni_gid (v));
776 clib_mem_free (vni_gid (v));
780 no_addr_free (void *a)
792 gid_address_free (gid_address_t * a)
794 if (gid_address_type (a) != GID_ADDR_LCAF)
797 lcaf_t *lcaf = &gid_address_lcaf (a);
798 u8 lcaf_type = lcaf_type (lcaf);
799 (*lcaf_free_fcts[lcaf_type]) (lcaf);
803 gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
805 memset (g, 0, sizeof (g[0]));
806 ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
807 gid_address_ippref_len (g) = 32;
811 ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
814 if (ip_addr_version (ip1) != ip_addr_version (ip2))
817 memcmp (&ip_addr_addr (ip1), &ip_addr_addr (ip2), ip_address_size (ip1));
828 ip_address_copy (ip_address_t * dst, const ip_address_t * src)
830 if (IP4 == ip_addr_version (src))
832 /* don't copy any garbe from the union */
833 memset (dst, 0, sizeof (*dst));
834 dst->ip.v4 = src->ip.v4;
839 clib_memcpy (dst, src, sizeof (ip_address_t));
844 ip_address_copy_addr (void *dst, const ip_address_t * src)
846 clib_memcpy (dst, src, ip_address_size (src));
850 ip_address_set (ip_address_t * dst, const void *src, u8 version)
852 clib_memcpy (dst, src, ip_version_to_size (version));
853 ip_addr_version (dst) = version;
857 ip_address_to_46 (const ip_address_t * addr,
858 ip46_address_t * a, fib_protocol_t * proto)
860 *proto = (IP4 == ip_addr_version (addr) ?
861 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
864 case FIB_PROTOCOL_IP4:
865 ip46_address_set_ip4 (a, &addr->ip.v4);
867 case FIB_PROTOCOL_IP6:
868 a->ip6 = addr->ip.v6;
877 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
888 mask = pow2_mask (preflen) << (32 - preflen);
889 mask = clib_host_to_net_u32 (mask);
890 ip4->data_u32 &= mask;
894 ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
902 memset (mask_6, 0, sizeof (mask_6));
911 m = (u32 *) & mask_6[0];
913 for (j = 0; j < i0; j++)
920 m[i0] = clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
923 for (j = 0; j < sizeof (mask_6); j++)
925 ip6->as_u8[j] &= mask_6[j];
930 ip_prefix_normalize (ip_prefix_t * a)
932 u8 preflen = ip_prefix_len (a);
934 switch (ip_prefix_version (a))
937 ip_prefix_normalize_ip4 (&ip_prefix_v4 (a), preflen);
941 ip_prefix_normalize_ip6 (&ip_prefix_v6 (a), preflen);
950 ip_prefix_cast (gid_address_t * a)
952 return &gid_address_ippref (a);
956 ip_prefix_size_to_write (void *pref)
958 ip_prefix_t *a = (ip_prefix_t *) pref;
959 return ip_address_size_to_write (&ip_prefix_addr (a));
963 ip_prefix_write (u8 * p, void *gid)
965 gid_address_t *g = gid;
966 ip_prefix_t *a = &gid_address_ippref (g);
968 switch (ip_prefix_version (a))
971 return ip4_address_put (p, &ip_prefix_v4 (a));
974 return ip6_address_put (p, &ip_prefix_v6 (a));
981 ip_prefix_length (void *a)
983 return ip_prefix_len ((ip_prefix_t *) a);
987 ip_prefix_copy (void *dst, void *src)
989 clib_memcpy (dst, src, sizeof (ip_prefix_t));
993 mac_copy (void *dst, void *src)
995 clib_memcpy (dst, src, 6);
999 sd_copy (void *dst, void *src)
1001 clib_memcpy (dst, src, sizeof (source_dest_t));
1005 nsh_copy (void *dst, void *src)
1007 clib_memcpy (dst, src, sizeof (nsh_t));
1011 ip_prefix_cmp (ip_prefix_t * p1, ip_prefix_t * p2)
1015 ip_prefix_normalize (p1);
1016 ip_prefix_normalize (p2);
1018 cmp = ip_address_cmp (&ip_prefix_addr (p1), &ip_prefix_addr (p2));
1021 if (ip_prefix_len (p1) < ip_prefix_len (p2))
1027 if (ip_prefix_len (p1) > ip_prefix_len (p2))
1035 no_addr_copy (void *dst, void *src)
1041 vni_copy (void *dst, void *src)
1046 clib_memcpy (vd, vs, sizeof (vd[0]));
1047 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
1048 gid_address_copy (vni_gid (vd), vni_gid (vs));
1052 lcaf_copy (void *dst, void *src)
1054 lcaf_t *lcaf_dst = dst;
1055 lcaf_t *lcaf_src = src;
1057 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
1058 (*lcaf_copy_fcts[lcaf_type (lcaf_src)]) (dst, src);
1062 lcaf_length (void *a)
1068 mac_length (void *a)
1080 nsh_length (void *a)
1086 lcaf_cast (gid_address_t * a)
1088 return &gid_address_lcaf (a);
1092 mac_cast (gid_address_t * a)
1094 return &gid_address_mac (a);
1098 sd_cast (gid_address_t * a)
1100 return &gid_address_sd (a);
1104 nsh_cast (gid_address_t * a)
1106 return &gid_address_nsh (a);
1110 no_addr_length (void *a)
1116 vni_length (void *a)
1119 return (sizeof (u32) /* VNI size */
1120 + gid_address_size_to_put (vni_gid (v)) /* vni body size */ );
1124 lcaf_write (u8 * p, void *a)
1128 u8 type = lcaf_type (lcaf);
1129 lcaf_hdr_t _h, *h = &_h;
1131 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1132 size += sizeof (u16);
1133 memset (h, 0, sizeof (h[0]));
1134 LCAF_TYPE (h) = type;
1135 u16 lcaf_len = (*lcaf_body_length_fcts[type]) (lcaf);
1136 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1138 clib_memcpy (p + size, h, sizeof (h[0]));
1139 size += sizeof (h[0]);
1140 len = (*lcaf_write_fcts[type]) (p + size, lcaf);
1142 if ((u16) ~ 0 == len)
1149 mac_write (u8 * p, void *a)
1151 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_MAC);
1152 clib_memcpy (p + sizeof (u16), a, 6);
1153 return mac_size_to_write (a);
1157 fid_addr_write (u8 * p, fid_address_t * a)
1159 switch (fid_addr_type (a))
1161 case FID_ADDR_IP_PREF:
1162 return ip_prefix_write (p, &fid_addr_ippref (a));
1165 return mac_write (p, &fid_addr_mac (a));
1174 fid_address_length (fid_address_t * a)
1176 switch (fid_addr_type (a))
1178 case FID_ADDR_IP_PREF:
1179 return ip_prefix_length (&fid_addr_ippref (a));
1189 sd_write (u8 * p, void *a)
1191 source_dest_t *sd = a;
1193 lcaf_hdr_t _h, *h = &_h;
1194 lcaf_src_dst_hdr_t sd_hdr;
1196 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1197 size += sizeof (u16);
1198 memset (h, 0, sizeof (h[0]));
1199 LCAF_TYPE (h) = LCAF_SOURCE_DEST;
1200 u16 lcaf_len = sizeof (lcaf_src_dst_hdr_t)
1201 + fid_addr_size_to_write (&sd_src (sd))
1202 + fid_addr_size_to_write (&sd_dst (sd));
1203 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1205 clib_memcpy (p + size, h, sizeof (h[0]));
1206 size += sizeof (h[0]);
1208 memset (&sd_hdr, 0, sizeof (sd_hdr));
1209 LCAF_SD_SRC_ML (&sd_hdr) = fid_address_length (&sd_src (sd));
1210 LCAF_SD_DST_ML (&sd_hdr) = fid_address_length (&sd_dst (sd));
1211 clib_memcpy (p + size, &sd_hdr, sizeof (sd_hdr));
1212 size += sizeof (sd_hdr);
1214 u16 len = fid_addr_write (p + size, &sd_src (sd));
1215 if ((u16) ~ 0 == len)
1219 len = fid_addr_write (p + size, &sd_dst (sd));
1220 if ((u16) ~ 0 == len)
1228 nsh_write (u8 * p, void *a)
1230 clib_warning ("not done");
1235 vni_write (u8 * p, void *a)
1237 lcaf_hdr_t _h, *h = &_h;
1238 gid_address_t *g = a;
1241 /* put lcaf header */
1242 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
1243 size += sizeof (u16);
1244 memset (h, 0, sizeof (h[0]));
1245 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
1246 u16 lcaf_len = sizeof (u32) /* Instance ID size */
1247 + gid_address_size_to_put_no_vni (g);
1248 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
1249 LCAF_RES2 (h) = gid_address_vni_mask (g);
1251 /* put vni header */
1252 clib_memcpy (p + size, h, sizeof (h[0]));
1253 size += sizeof (h[0]);
1255 u32 *afip = (u32 *) (p + size);
1256 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
1257 size += sizeof (u32);
1259 if (GID_ADDR_SRC_DST == gid_address_type (g))
1260 /* write src/dst LCAF */
1262 len = sd_write (p + size, g);
1263 if ((u16) ~ 0 == len)
1267 /* write the actual address */
1268 len = gid_address_put_no_vni (p + size, g);
1270 if ((u16) ~ 0 == len)
1277 no_addr_write (u8 * p, void *a)
1279 /* do nothing; return AFI field size */
1280 return sizeof (u16);
1284 no_addr_size_to_write (void *a)
1286 return sizeof (u16); /* AFI field length */
1290 fid_addr_size_to_write (fid_address_t * a)
1292 switch (fid_addr_type (a))
1294 case FID_ADDR_IP_PREF:
1295 return ip_prefix_size_to_write (a);
1298 return mac_size_to_write (a);
1307 vni_size_to_write (void *a)
1309 gid_address_t *g = a;
1311 u16 lcaf_size = sizeof (u32) + sizeof (u16) /* LCAF AFI field size */
1312 + sizeof (lcaf_hdr_t);
1314 if (gid_address_type (g) == GID_ADDR_SRC_DST)
1315 /* special case where nested LCAF is supported */
1316 return lcaf_size + sd_size_to_write (g);
1318 return lcaf_size + gid_address_size_to_put_no_vni (g);
1322 lcaf_size_to_write (void *a)
1324 lcaf_t *lcaf = (lcaf_t *) a;
1326 u8 type = lcaf_type (lcaf);
1328 size += sizeof (u16); /* AFI size */
1330 len = (*lcaf_size_to_write_fcts[type]) (lcaf);
1338 sd_size_to_write (void *a)
1340 source_dest_t *sd = a;
1342 + sizeof (lcaf_hdr_t)
1343 + sizeof (lcaf_src_dst_hdr_t)
1344 + fid_addr_size_to_write (&sd_src (sd))
1345 + fid_addr_size_to_write (&sd_dst (sd));
1349 mac_size_to_write (void *a)
1351 return sizeof (u16) + 6;
1355 nsh_size_to_write (void *a)
1357 return sizeof (u16) + 4;
1361 gid_address_len (gid_address_t * a)
1363 gid_address_type_t type = gid_address_type (a);
1364 return (*addr_len_fcts[type]) ((*cast_fcts[type]) (a));
1368 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
1370 gid_address_type_t type = gid_address_type (gid);
1371 return (*write_fcts[type]) (b, (*cast_fcts[type]) (gid));
1375 gid_address_put (u8 * b, gid_address_t * gid)
1377 if (0 != gid_address_vni (gid))
1378 return vni_write (b, gid);
1380 return gid_address_put_no_vni (b, gid);
1384 gid_address_size_to_put_no_vni (gid_address_t * gid)
1386 gid_address_type_t type = gid_address_type (gid);
1387 return (*size_to_write_fcts[type]) ((*cast_fcts[type]) (gid));
1391 gid_address_size_to_put (gid_address_t * gid)
1393 if (0 != gid_address_vni (gid))
1394 return vni_size_to_write (gid);
1396 return gid_address_size_to_put_no_vni (gid);
1400 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
1402 return (*cast_fcts[type]) (gid);
1406 gid_address_copy (gid_address_t * dst, gid_address_t * src)
1408 gid_address_type_t type = gid_address_type (src);
1409 (*copy_fcts[type]) ((*cast_fcts[type]) (dst), (*cast_fcts[type]) (src));
1410 gid_address_type (dst) = type;
1411 gid_address_vni (dst) = gid_address_vni (src);
1412 gid_address_vni_mask (dst) = gid_address_vni_mask (src);
1416 mac_parse (u8 * offset, u8 * a)
1418 /* skip AFI field */
1419 offset += sizeof (u16);
1421 clib_memcpy (a, offset, 6);
1422 return sizeof (u16) + 6;
1426 gid_address_parse (u8 * offset, gid_address_t * a)
1433 /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
1434 * the gid address here */
1435 afi = clib_net_to_host_u16 (*((u16 *) offset));
1439 case LISP_AFI_NO_ADDR:
1441 gid_address_type (a) = GID_ADDR_NO_ADDRESS;
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) = 32;
1450 len = ip_address_parse (offset, afi, &gid_address_ip (a));
1451 gid_address_type (a) = GID_ADDR_IP_PREFIX;
1452 /* this should be modified outside if needed */
1453 gid_address_ippref_len (a) = 128;
1456 gid_address_type (a) = GID_ADDR_LCAF;
1457 len = lcaf_parse (offset, a);
1460 len = mac_parse (offset, gid_address_mac (a));
1461 gid_address_type (a) = GID_ADDR_MAC;
1464 clib_warning ("LISP AFI %d not supported!", afi);
1467 return (len == (u16) ~ 0) ? ~0 : len;
1471 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
1473 gid_address_ippref_len (dst) = ip_address_max_len (version);
1474 ip_address_set (&gid_address_ip (dst), src, version);
1478 no_addr_cmp (void *a1, void *a2)
1484 vni_cmp (void *a1, void *a2)
1489 if (vni_mask_len (v1) != vni_mask_len (v2))
1491 if (vni_vni (v1) != vni_vni (v2))
1493 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
1497 mac_cmp (void *a1, void *a2)
1499 return memcmp (a1, a2, 6);
1503 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
1505 if (fid_addr_type (a1) != fid_addr_type (a2))
1508 switch (fid_addr_type (a1))
1510 case FID_ADDR_IP_PREF:
1511 return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
1514 return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
1523 sd_cmp (void *a1, void *a2)
1525 source_dest_t *sd1 = a1;
1526 source_dest_t *sd2 = a2;
1528 if (fid_addr_cmp (&sd_dst (sd1), &sd_dst (sd2)))
1530 if (fid_addr_cmp (&sd_src (sd1), &sd_src (sd2)))
1535 /* Compare two gid_address_t.
1537 * -1: If they are from different afi
1538 * 0: Both address are the same
1539 * 1: Addr1 is bigger than addr2
1540 * 2: Addr2 is bigger than addr1
1543 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
1545 lcaf_t *lcaf1, *lcaf2;
1549 if (gid_address_type (a1) != gid_address_type (a2))
1551 if (gid_address_vni (a1) != gid_address_vni (a2))
1554 /* TODO vni mask is not supported, disable comparing for now
1555 if (gid_address_vni_mask (a1) != gid_address_vni_mask (a2))
1559 switch (gid_address_type (a1))
1561 case GID_ADDR_NO_ADDRESS:
1567 case GID_ADDR_IP_PREFIX:
1569 ip_prefix_cmp (&gid_address_ippref (a1), &gid_address_ippref (a2));
1572 lcaf1 = &gid_address_lcaf (a1);
1573 lcaf2 = &gid_address_lcaf (a2);
1574 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
1575 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
1578 cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
1581 case GID_ADDR_SRC_DST:
1582 cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
1592 locator_parse (void *b, locator_t * loc)
1595 u8 status = 1; /* locator up */
1599 if (!LOC_REACHABLE (h) && LOC_LOCAL (h))
1602 len = gid_address_parse (LOC_ADDR (h), &loc->address);
1606 loc->state = status;
1608 loc->priority = LOC_PRIORITY (h);
1609 loc->weight = LOC_WEIGHT (h);
1610 loc->mpriority = LOC_MPRIORITY (h);
1611 loc->mweight = LOC_MWEIGHT (h);
1613 return sizeof (locator_hdr_t) + len;
1617 locator_copy (locator_t * dst, locator_t * src)
1619 /* TODO if gid become more complex, this will need to be changed! */
1620 clib_memcpy (dst, src, sizeof (*dst));
1622 gid_address_copy (&dst->address, &src->address);
1626 locator_cmp (locator_t * l1, locator_t * l2)
1629 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
1632 if (l1->priority != l2->priority)
1634 if (l1->weight != l2->weight)
1636 if (l1->mpriority != l2->mpriority)
1638 if (l1->mweight != l2->mweight)
1644 locator_free (locator_t * l)
1647 gid_address_free (&l->address);
1651 build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
1653 memset (sd, 0, sizeof (*sd));
1654 gid_address_type (sd) = GID_ADDR_SRC_DST;
1655 gid_address_vni (sd) = gid_address_vni (dst);
1656 gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
1658 switch (gid_address_type (dst))
1660 case GID_ADDR_IP_PREFIX:
1661 gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
1662 gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
1663 ip_prefix_copy (&gid_address_sd_src_ippref (sd),
1664 &gid_address_ippref (src));
1665 ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
1666 &gid_address_ippref (dst));
1669 gid_address_sd_src_type (sd) = FID_ADDR_MAC;
1670 gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
1671 mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
1672 mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
1675 clib_warning ("Unsupported gid type %d while conversion!",
1676 gid_address_type (dst));
1682 * fd.io coding-style-patch-verification: ON
1685 * eval: (c-set-style "gnu")