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
ip_addr_version(dst) = version;
}
+static void
+ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
+{
+ u32 mask = ~0;
+
+ ASSERT (ip4);
+
+ if (32 <= preflen)
+ {
+ return;
+ }
+
+ mask = pow2_mask (preflen) << (32 - preflen);
+ mask = clib_host_to_net_u32 (mask);
+ ip4->data_u32 &= mask;
+}
+
+static void
+ip_prefix_normalize_ip6 (ip6_address_t * ip6, u8 preflen)
+{
+ u8 mask_6[16];
+ u32 * m;
+ u8 j ,i0, i1;
+
+ ASSERT (ip6);
+
+ memset (mask_6, 0, sizeof (mask_6));
+
+ if (128 <= preflen)
+ {
+ return;
+ }
+
+ i1 = preflen % 32;
+ i0 = preflen / 32;
+ m = (u32 * ) &mask_6[0];
+
+ for (j = 0; j < i0; j++)
+ {
+ m[j] = ~0;
+ }
+
+ if (i1)
+ {
+ m[i0] = clib_host_to_net_u32 (pow2_mask(i1) << (32 - i1));
+ }
+
+ for (j = 0; j < sizeof(mask_6); j++)
+ {
+ ip6->as_u8[j] &= mask_6[j];
+ }
+}
+
+void
+ip_prefix_normalize(ip_prefix_t * a)
+{
+ u8 preflen = ip_prefix_len(a);
+
+ switch (ip_prefix_version (a))
+ {
+ case IP4:
+ ip_prefix_normalize_ip4(&ip_prefix_v4(a), preflen);
+ break;
+
+ case IP6:
+ ip_prefix_normalize_ip6(&ip_prefix_v6(a), preflen);
+ 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)
{