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);
21 typedef u16 (*size_to_write_fct)(void *);
22 typedef void * (*cast_fct)(gid_address_t *);
23 typedef u16 (*serdes_fct)(u8 *, void *);
24 typedef u8 (*addr_len_fct)(void *);
25 typedef void (*copy_fct)(void *, void *);
26 typedef void (*free_fct)(void *);
27 typedef int (*cmp_fct)(void *, void *);
29 u16 vni_write (u8 * p, void * a);
30 u16 vni_parse (u8 * p, void * a);
31 u16 vni_size_to_write (void * a);
32 void vni_free (void * a);
33 void vni_copy (void * dst, void * src);
34 u16 vni_length (void * a);
35 int vni_cmp (void *, void *);
37 u16 no_addr_size_to_write (void *);
38 u16 no_addr_write (u8 * p, void * a);
39 u16 no_addr_parse (u8 * p, void * a);
40 void no_addr_free (void * a);
41 void no_addr_copy (void *, void *);
42 u16 no_addr_length (void * a);
43 int no_addr_cmp (void * a1, void * a2);
45 size_to_write_fct size_to_write_fcts[GID_ADDR_TYPES] =
46 { ip_prefix_size_to_write, lcaf_size_to_write, mac_size_to_write };
47 serdes_fct write_fcts[GID_ADDR_TYPES] =
48 { ip_prefix_write, lcaf_write, mac_write };
49 cast_fct cast_fcts[GID_ADDR_TYPES] =
50 { ip_prefix_cast, lcaf_cast, mac_cast };
51 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
52 { ip_prefix_length, lcaf_length, mac_length };
53 copy_fct copy_fcts[GID_ADDR_TYPES] =
54 { ip_prefix_copy, lcaf_copy, mac_copy };
56 cmp_fct lcaf_cmp_fcts[LCAF_TYPES] =
63 size_to_write_fct lcaf_body_length_fcts[LCAF_TYPES] =
70 copy_fct lcaf_copy_fcts[LCAF_TYPES] =
77 free_fct lcaf_free_fcts[LCAF_TYPES] =
84 size_to_write_fct lcaf_size_to_write_fcts[LCAF_TYPES] =
86 no_addr_size_to_write,
91 serdes_fct lcaf_write_fcts[LCAF_TYPES] =
98 serdes_fct lcaf_parse_fcts[LCAF_TYPES] =
106 format_ip_address (u8 * s, va_list * args)
108 ip_address_t * a = va_arg (*args, ip_address_t *);
109 u8 ver = ip_addr_version(a);
112 return format (s, "%U", format_ip4_address, &ip_addr_v4(a));
116 return format (s, "%U", format_ip6_address, &ip_addr_v6(a));
120 clib_warning ("Can't format IP version %d!", ver);
126 unformat_ip_address (unformat_input_t * input, va_list * args)
128 ip_address_t * a = va_arg(*args, ip_address_t *);
129 if (unformat(input, "%U", unformat_ip4_address, &ip_addr_v4(a)))
130 ip_addr_version(a) = IP4;
131 else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6(a)))
132 ip_addr_version(a) = IP6;
139 format_ip_prefix (u8 * s, va_list * args)
141 ip_prefix_t * a = va_arg (*args, ip_prefix_t *);
142 return format (s, "%U/%d", format_ip_address, &ip_prefix_addr(a), ip_prefix_len(a));
146 unformat_ip_prefix (unformat_input_t * input, va_list * args)
148 ip_prefix_t * a = va_arg(*args, ip_prefix_t *);
149 return unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr(a),
154 unformat_mac_address (unformat_input_t * input, va_list * args)
156 u8 * a = va_arg(*args, u8 *);
157 return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
162 format_mac_address (u8 * s, va_list * args)
164 u8 * a = va_arg (*args, u8 *);
165 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
166 a[0], a[1], a[2], a[3], a[4], a[5]);
170 format_gid_address (u8 * s, va_list * args)
172 gid_address_t * a = va_arg(*args, gid_address_t *);
173 u8 type = gid_address_type(a);
176 case GID_ADDR_IP_PREFIX:
177 return format (s, "[%d] %U", gid_address_vni(a), format_ip_prefix,
178 &gid_address_ippref(a));
179 case GID_ADDR_SRC_DST:
180 return format (s, "[%d] %U|%U", gid_address_vni(a),
181 format_ip_prefix, &gid_address_sd_source_pref(a),
182 format_ip_prefix, &gid_address_sd_dest_pref(a));
184 return format (s, "[%d] %U", gid_address_vni(a), format_mac_address,
185 &gid_address_mac(a));
187 clib_warning("Can't format gid type %d", type);
193 unformat_gid_address (unformat_input_t * input, va_list * args)
196 gid_address_t * a = va_arg(*args, gid_address_t *);
200 memset (&ippref, 0, sizeof (ippref));
201 memset(a, 0, sizeof(a[0]));
203 if (unformat (input, "%U", unformat_ip_prefix, &ippref))
205 clib_memcpy (&gid_address_ippref(a), &ippref, sizeof(ippref));
206 gid_address_type(a) = GID_ADDR_IP_PREFIX;
208 else if (unformat (input, "%U", unformat_mac_address, mac))
210 clib_memcpy (gid_address_mac(a), mac, sizeof(mac));
211 gid_address_type(a) = GID_ADDR_MAC;
213 else if (unformat (input, "[%d]", &vni))
214 gid_address_vni(a) = vni;
222 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
224 u32 * action = va_arg(*args, u32 *);
227 if (unformat (input, "%s", &s))
229 int len = vec_len(s);
230 clib_warning ("len = %d", len);
231 if (!strcmp ((char *) s, "no-action"))
232 action[0] = ACTION_NONE;
233 if (!strcmp ((char *) s, "natively-forward"))
234 action[0] = ACTION_NATIVELY_FORWARDED;
235 if (!strcmp ((char *) s, "send-map-request"))
236 action[0] = ACTION_SEND_MAP_REQUEST;
237 else if (!strcmp ((char *) s, "drop"))
238 action[0] = ACTION_DROP;
241 clib_warning("invalid action: '%s'", s);
242 action[0] = ACTION_DROP;
253 ip_address_size (ip_address_t * a)
255 switch (ip_addr_version (a))
258 return sizeof(ip4_address_t);
261 return sizeof(ip6_address_t);
268 ip_version_to_size (u8 ver)
273 return sizeof(ip4_address_t);
276 return sizeof(ip6_address_t);
283 ip_version_to_max_plen (u8 ver)
297 always_inline lisp_afi_e
298 ip_version_to_iana_afi (u16 version)
313 ip_iana_afi_to_version (lisp_afi_e afi)
328 ip_address_size_to_write (ip_address_t * a)
330 return ip_address_size (a) + sizeof (u16);
334 ip_address_iana_afi(ip_address_t *a)
336 return ip_version_to_iana_afi(ip_addr_version(a));
340 ip_address_max_len (u8 version)
342 return version == IP4 ? 32 : 128;
346 ip4_address_size_to_put ()
348 // return sizeof(u16) + sizeof (ip4_address_t);
353 ip6_address_size_to_put ()
355 //return sizeof(u16) + sizeof (ip6_address_t);
360 ip4_address_put (u8 * b, ip4_address_t * a)
362 *(u16 *)b = clib_host_to_net_u16(ip_version_to_iana_afi(IP4));
363 u8 *p = b + sizeof (u16);
364 clib_memcpy (p, a, sizeof(*a));
365 return ip4_address_size_to_put();
369 ip6_address_put (u8 * b, ip6_address_t * a)
371 *(u16 *)b = clib_host_to_net_u16(ip_version_to_iana_afi(IP6));
372 u8 *p = b + sizeof (u16);
373 clib_memcpy (p, a, sizeof(*a));
374 return ip6_address_size_to_put();
378 ip_address_put (u8 * b, ip_address_t * a)
380 u32 len = ip_address_size (a);
381 *(u16 *) b = clib_host_to_net_u16(ip_address_iana_afi (a));
382 u8 * p = b + sizeof (u16);
383 clib_memcpy (p, &ip_addr_addr (a), len);
384 return (len + sizeof (u16));
388 ip_address_parse(void * offset, u16 iana_afi, ip_address_t *dst)
390 ip_addr_version(dst) = ip_iana_afi_to_version (iana_afi);
391 u8 size = ip_version_to_size (ip_addr_version(dst));
392 clib_memcpy (&ip_addr_addr(dst), offset + sizeof(u16), size);
393 return(sizeof(u16) + size);
397 lcaf_hdr_parse (void * offset, lcaf_t * lcaf)
399 lcaf_hdr_t * lh = offset;
400 lcaf->type = lh->type;
402 /* this is a bit of hack: since the LCAF Instance ID is the
403 only message that uses reserved2 field, we can set it here.
404 If any LCAF format starts using reserved2 field as well this needs
405 to be moved elsewhere */
406 lcaf_vni_len (lcaf) = lh->reserved2;
408 return sizeof (lh[0]);
412 vni_parse (u8 * p, void * a)
415 gid_address_t * g = a;
418 gid_address_vni (g) = clib_net_to_host_u32 ( *(u32 *) p);
419 size += sizeof (u32);
420 gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
422 /* nested LCAFs are not supported - it is expected that nested AFI type is
424 size += gid_address_parse (p + size, g);
429 no_addr_parse (u8 * p, void * a)
436 lcaf_parse (void * offset, gid_address_t *addr)
439 offset += sizeof (u16);
440 lcaf_t * lcaf = &gid_address_lcaf (addr);
442 u32 size = lcaf_hdr_parse (offset, lcaf);
443 u8 type = lcaf_type (lcaf);
445 if (!lcaf_parse_fcts[type])
447 clib_warning ("Unsupported LCAF type: %u", type);
450 size += (*lcaf_parse_fcts[type])(offset + size, lcaf);
451 return sizeof (u16) + size;
458 gid_address_free (vni_gid (v));
459 clib_mem_free (vni_gid (v));
463 no_addr_free (void * a)
469 gid_address_free (gid_address_t *a)
471 if (gid_address_type (a) != GID_ADDR_LCAF)
474 lcaf_t * lcaf = &gid_address_lcaf (a);
475 u8 lcaf_type = lcaf_type (lcaf);
476 (*lcaf_free_fcts[lcaf_type])(lcaf);
480 ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2)
483 if (ip_addr_version (ip1) != ip_addr_version(ip2))
485 res = memcmp (&ip_addr_addr(ip1), &ip_addr_addr(ip2), ip_address_size (ip1));
496 ip_address_copy (ip_address_t * dst , ip_address_t * src)
498 clib_memcpy (dst, src, sizeof (ip_address_t));
502 ip_address_copy_addr (void * dst , ip_address_t * src)
504 clib_memcpy (dst, src, ip_address_size(src));
508 ip_address_set(ip_address_t * dst, void * src, u8 version)
510 clib_memcpy(dst, src, ip_version_to_size(version));
511 ip_addr_version(dst) = version;
515 ip_prefix_cast (gid_address_t * a)
517 return &gid_address_ippref(a);
521 ip_prefix_size_to_write (void * pref)
523 ip_prefix_t *a = (ip_prefix_t *) pref;
524 return ip_address_size_to_write (&ip_prefix_addr (a));
528 ip_prefix_write (u8 * p, void * gid)
530 gid_address_t * g = gid;
531 ip_prefix_t *a = &gid_address_ippref (g);
533 switch (ip_prefix_version (a))
536 return ip4_address_put (p, &ip_prefix_v4 (a));
539 return ip6_address_put (p, &ip_prefix_v6 (a));
546 ip_prefix_length (void *a)
548 return ip_prefix_len((ip_prefix_t *) a);
552 ip_prefix_copy (void * dst , void * src)
554 clib_memcpy (dst, src, sizeof (ip_prefix_t));
558 mac_copy (void * dst , void * src)
560 clib_memcpy (dst, src, 6);
564 ip_prefix_cmp(ip_prefix_t * p1, ip_prefix_t * p2)
567 cmp = ip_address_cmp (&ip_prefix_addr(p1), &ip_prefix_addr(p2));
570 if (ip_prefix_len(p1) < ip_prefix_len(p2))
576 if (ip_prefix_len(p1) > ip_prefix_len(p2))
584 no_addr_copy (void * dst, void * src)
590 vni_copy (void * dst, void * src)
595 clib_memcpy (vd, vs, sizeof (vd[0]));
596 vni_gid (vd) = clib_mem_alloc (sizeof (gid_address_t));
597 gid_address_copy (vni_gid (vd), vni_gid (vs));
601 lcaf_copy (void * dst , void * src)
603 lcaf_t * lcaf_dst = dst;
604 lcaf_t * lcaf_src = src;
606 lcaf_type (lcaf_dst) = lcaf_type (lcaf_src);
607 (*lcaf_copy_fcts[lcaf_type (lcaf_src)])(dst, src);
611 lcaf_length (void *a)
623 lcaf_cast (gid_address_t * a)
625 return &gid_address_lcaf (a);
629 mac_cast (gid_address_t * a)
631 return &gid_address_mac (a);
635 no_addr_length (void * a)
641 vni_length (void * a)
644 return (sizeof (u32) /* VNI size */
645 + gid_address_size_to_put (vni_gid (v)) /* vni body size*/);
649 lcaf_write (u8 * p, void * a)
653 u8 type = lcaf_type (lcaf);
654 lcaf_hdr_t _h, *h = &_h;
656 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
657 size += sizeof (u16);
658 memset (h, 0, sizeof (h[0]));
659 LCAF_TYPE (h) = type;
660 u16 lcaf_len = (*lcaf_body_length_fcts[type])(lcaf);
661 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
663 clib_memcpy (p + size, h, sizeof (h[0]));
664 size += sizeof (h[0]);
665 len = (*lcaf_write_fcts[type])(p + size, lcaf);
674 mac_write (u8 * p, void * a)
676 *(u16 *)p = clib_host_to_net_u16 (LISP_AFI_MAC);
677 clib_memcpy(p + sizeof (u16), a, 6);
678 return mac_size_to_write (a);
682 vni_write (u8 * p, void * a)
684 lcaf_hdr_t _h, *h = &_h;
685 gid_address_t * g = a;
688 /* put lcaf header */
689 *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
690 size += sizeof (u16);
691 memset (h, 0, sizeof (h[0]));
692 LCAF_TYPE (h) = LCAF_INSTANCE_ID;
693 u16 lcaf_len = sizeof (u32) /* Instance ID size */
694 + gid_address_size_to_put_no_vni (g);
695 LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
696 LCAF_RES2 (h) = gid_address_vni_mask (g);
699 clib_memcpy (p + size, h, sizeof (h[0]));
700 size += sizeof (h[0]);
702 u32 * afip = (u32 *)(p + size);
703 afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
704 size += sizeof (u32);
706 /* write the actual address */
707 len = gid_address_put_no_vni (p + size, g);
716 no_addr_write (u8 * p, void * a)
718 /* do nothing; return AFI field size */
723 no_addr_size_to_write (void * a)
725 return sizeof (u16); /* AFI field length */
729 vni_size_to_write (void * a)
731 gid_address_t * g = a;
732 return (sizeof (u32) /* vni size */
733 + sizeof (u16) /* LCAF AFI field size */
734 + sizeof (lcaf_hdr_t)
735 + gid_address_size_to_put_no_vni (g));
739 lcaf_size_to_write (void * a)
741 lcaf_t * lcaf = (lcaf_t *) a;
743 u8 type = lcaf_type (lcaf);
745 size += sizeof (u16); /* AFI size */
747 len = (*lcaf_size_to_write_fcts[type])(lcaf);
755 mac_size_to_write (void * a)
757 return sizeof (u16) + 6;
761 gid_address_len (gid_address_t *a)
763 gid_address_type_t type = gid_address_type (a);
764 return (*addr_len_fcts[type])((*cast_fcts[type])(a));
768 gid_address_put_no_vni (u8 * b, gid_address_t * gid)
770 gid_address_type_t type = gid_address_type (gid);
771 return (*write_fcts[type])(b, (*cast_fcts[type])(gid));
775 gid_address_put (u8 * b, gid_address_t * gid)
777 if (0 != gid_address_vni (gid))
778 return vni_write (b, gid);
780 return gid_address_put_no_vni (b, gid);
784 gid_address_size_to_put_no_vni (gid_address_t * gid)
786 gid_address_type_t type = gid_address_type (gid);
787 return (*size_to_write_fcts[type])((*cast_fcts[type])(gid));
791 gid_address_size_to_put (gid_address_t * gid)
793 if (0 != gid_address_vni (gid))
794 return vni_size_to_write (gid);
796 return gid_address_size_to_put_no_vni (gid);
800 gid_address_cast (gid_address_t * gid, gid_address_type_t type)
802 return (*cast_fcts[type])(gid);
806 gid_address_copy(gid_address_t * dst, gid_address_t * src)
808 gid_address_type_t type = gid_address_type(src);
809 (*copy_fcts[type])((*cast_fcts[type])(dst), (*cast_fcts[type])(src));
810 gid_address_type(dst) = type;
811 gid_address_vni(dst) = gid_address_vni(src);
812 gid_address_vni_mask(dst) = gid_address_vni_mask(src);
816 mac_parse (u8 * offset, gid_address_t * a)
819 offset += sizeof (u16);
821 memcpy (gid_address_mac (a), offset, sizeof (gid_address_mac (a)));
822 return (sizeof (u16) + sizeof (gid_address_mac (a)));
826 gid_address_parse (u8 * offset, gid_address_t *a)
834 /* NOTE: since gid_adress_parse may be called by vni_parse, we can't 0
835 * the gid address here */
836 afi = clib_net_to_host_u16 (*((u16 *) offset));
840 case LISP_AFI_NO_ADDR:
842 gid_address_type(a) = GID_ADDR_NO_ADDRESS;
845 len = ip_address_parse (offset, afi, &gid_address_ip(a));
846 gid_address_type(a) = GID_ADDR_IP_PREFIX;
847 /* this should be modified outside if needed*/
848 gid_address_ippref_len(a) = 32;
851 len = ip_address_parse (offset, afi, &gid_address_ip(a));
852 gid_address_type(a) = GID_ADDR_IP_PREFIX;
853 /* this should be modified outside if needed*/
854 gid_address_ippref_len(a) = 128;
857 gid_address_type(a) = GID_ADDR_LCAF;
858 len = lcaf_parse (offset, a);
861 len = mac_parse (offset, a);
862 gid_address_type(a) = GID_ADDR_MAC;
865 clib_warning("LISP AFI %d not supported!", afi);
872 no_addr_cmp (void * a1, void * a2)
878 vni_cmp (void * a1, void * a2)
883 if (vni_mask_len (v1) != vni_mask_len (v2))
885 if (vni_vni (v1) != vni_vni (v2))
887 return gid_address_cmp (vni_gid (v1), vni_gid (v2));
890 /* Compare two gid_address_t.
892 * -1: If they are from different afi
893 * 0: Both address are the same
894 * 1: Addr1 is bigger than addr2
895 * 2: Addr2 is bigger than addr1
898 gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
900 lcaf_t * lcaf1, * lcaf2;
904 if (gid_address_type(a1) != gid_address_type(a2))
906 if (gid_address_vni(a1) != gid_address_vni(a2))
908 if (gid_address_vni_mask(a1) != gid_address_vni_mask(a2))
911 switch (gid_address_type(a1))
913 case GID_ADDR_NO_ADDRESS:
919 case GID_ADDR_IP_PREFIX:
920 cmp = ip_prefix_cmp (&gid_address_ippref(a1), &gid_address_ippref(a2));
923 lcaf1 = &gid_address_lcaf (a1);
924 lcaf2 = &gid_address_lcaf (a2);
925 if (lcaf_type (lcaf1) == lcaf_type (lcaf2))
926 cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)])(lcaf1, lcaf2);
929 cmp = memcmp (gid_address_mac (a1), gid_address_mac (a2),
930 sizeof (gid_address_mac (a1)));
941 locator_parse (void * b, locator_t * loc)
944 u8 status = 1; /* locator up */
948 if (!LOC_REACHABLE(h) && LOC_LOCAL(h))
951 len = gid_address_parse (LOC_ADDR(h), &loc->address);
957 loc->priority = LOC_PRIORITY(h);
958 loc->weight = LOC_WEIGHT(h);
959 loc->mpriority = LOC_MPRIORITY(h);
960 loc->mweight = LOC_MWEIGHT(h);
962 return sizeof(locator_hdr_t) + len;
966 locator_copy (locator_t * dst, locator_t * src)
968 /* TODO if gid become more complex, this will need to be changed! */
969 clib_memcpy (dst, src, sizeof(*dst));
971 gid_address_copy (&dst->address, &src->address);
975 locator_cmp (locator_t * l1, locator_t * l2)
978 if ((ret = gid_address_cmp (&l1->address, &l2->address)) != 0)
981 if (l1->priority != l2->priority)
983 if (l1->weight != l2->weight)
985 if (l1->mpriority != l2->mpriority)
987 if (l1->mweight != l2->mweight)
993 locator_free (locator_t * l)
996 gid_address_free (&l->address);