unformat_ip_prefix (unformat_input_t * input, va_list * args)
{
ip_prefix_t * a = va_arg(*args, ip_prefix_t *);
- return unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr(a),
- &ip_prefix_len(a));
+ if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr(a),
+ &ip_prefix_len(a)))
+ {
+ if ((ip_prefix_version(a) == IP4 && 32 < ip_prefix_len(a)) ||
+ (ip_prefix_version(a) == IP6 && 128 < ip_prefix_length(a)))
+ {
+ clib_warning("Prefix length to big: %d!", ip_prefix_len(a));
+ return 0;
+ }
+ ip_prefix_normalize(a);
+ }
+ else
+ return 0;
+ return 1;
+}
+
+uword
+unformat_mac_address (unformat_input_t * input, va_list * args)
+{
+ u8 * a = va_arg(*args, u8 *);
+ return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
+ &a[4], &a[5]);
+}
+
+u8 *
+format_mac_address (u8 * s, va_list * args)
+{
+ u8 * a = va_arg (*args, u8 *);
+ return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
+ a[0], a[1], a[2], a[3], a[4], a[5]);
}
u8 *
return format (s, "[%d] %U|%U", gid_address_vni(a),
format_ip_prefix, &gid_address_sd_source_pref(a),
format_ip_prefix, &gid_address_sd_dest_pref(a));
+ case GID_ADDR_MAC:
+ return format (s, "[%d] %U", gid_address_vni(a), format_mac_address,
+ &gid_address_mac(a));
default:
clib_warning("Can't format gid type %d", type);
return 0;
uword
unformat_gid_address (unformat_input_t * input, va_list * args)
{
+ u32 vni;
gid_address_t * a = va_arg(*args, gid_address_t *);
- if (unformat (input, "%U", unformat_ip_prefix, &gid_address_ippref(a)))
- gid_address_type(a) = GID_ADDR_IP_PREFIX;
+ u8 mac[6] = {0};
+ ip_prefix_t ippref;
+
+ memset (&ippref, 0, sizeof (ippref));
+ memset(a, 0, sizeof(a[0]));
+
+ if (unformat (input, "%U", unformat_ip_prefix, &ippref))
+ {
+ clib_memcpy (&gid_address_ippref(a), &ippref, sizeof(ippref));
+ gid_address_type(a) = GID_ADDR_IP_PREFIX;
+ }
+ else if (unformat (input, "%U", unformat_mac_address, mac))
+ {
+ clib_memcpy (gid_address_mac(a), mac, sizeof(mac));
+ gid_address_type(a) = GID_ADDR_MAC;
+ }
+ else if (unformat (input, "[%d]", &vni))
+ gid_address_vni(a) = vni;
else
return 0;
+
+ return 1;
+}
+
+uword
+unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
+{
+ u32 * action = va_arg(*args, u32 *);
+ u8 * s = 0;
+
+ if (unformat (input, "%s", &s))
+ {
+ int len = vec_len(s);
+ clib_warning ("len = %d", len);
+ if (!strcmp ((char *) s, "no-action"))
+ action[0] = ACTION_NONE;
+ if (!strcmp ((char *) s, "natively-forward"))
+ action[0] = ACTION_NATIVELY_FORWARDED;
+ if (!strcmp ((char *) s, "send-map-request"))
+ action[0] = ACTION_SEND_MAP_REQUEST;
+ else if (!strcmp ((char *) s, "drop"))
+ action[0] = ACTION_DROP;
+ else
+ {
+ clib_warning("invalid action: '%s'", s);
+ action[0] = ACTION_DROP;
+ return 0;
+ }
+ }
+ else
+ return 0;
+
return 1;
}
ip_addr_version(dst) = version;
}
+void
+ip_prefix_normalize(ip_prefix_t * a)
+{
+ ip_address_t * ip;
+ ip4_address_t * ip4;
+ ip6_address_t * ip6;
+ int preflen = ip_prefix_len(a);
+ u32 mask = ~0;
+ u64 mask_6[2];
+ u32 * m;
+ u32 j, i0, i1;
+
+ ip = &ip_prefix_addr (a);
+ switch (ip_addr_version (ip))
+ {
+ case IP4:
+ if (32 <= preflen)
+ {
+ break;
+ }
+
+ ip4 = &ip_addr_v4 (ip);
+ mask = pow2_mask (preflen) << (32 - preflen);
+ mask = clib_host_to_net_u32 (mask);
+ ip4->data_u32 &= mask;
+ break;
+
+ case IP6:
+ if (128 <= preflen)
+ {
+ break;
+ }
+ ip6 = &ip_addr_v6 (ip);
+ memset(mask_6, 0, sizeof(mask_6));
+ m = (u32 * ) mask_6;
+
+ i0 = preflen / 32;
+ i1 = preflen % 32;
+ for (j = 0; j < i0; j++)
+ {
+ m[j] = ~0;
+ }
+
+ if (i1)
+ {
+ m[i0] = clib_host_to_net_u32 (pow2_mask(i1) << (32 - i1));
+ }
+
+ ip6->as_u64[0] &= mask_6[0];
+ ip6->as_u64[1] &= mask_6[1];
+ break;
+
+ default:
+ ASSERT(0);
+ }
+}
+
void *
ip_prefix_cast (gid_address_t * a)
{
ip_prefix_cmp(ip_prefix_t * p1, ip_prefix_t * p2)
{
int cmp = 0;
+
+ ip_prefix_normalize (p1);
+ ip_prefix_normalize (p2);
+
cmp = ip_address_cmp (&ip_prefix_addr(p1), &ip_prefix_addr(p2));
if (cmp == 0)
{
if (!a)
return 0;
+ /* NOTE: since gid_adress_parse may be called by vni_parse, we can't 0
+ * the gid address here */
afi = clib_net_to_host_u16 (*((u16 *) offset));
switch (afi)