summaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ip')
-rw-r--r--src/vnet/ip/format.h5
-rw-r--r--src/vnet/ip/ip4_format.c36
-rw-r--r--src/vnet/ip/ip4_packet.h5
-rw-r--r--src/vnet/ip/ip6_format.c43
-rw-r--r--src/vnet/ip/ip6_packet.h5
5 files changed, 94 insertions, 0 deletions
diff --git a/src/vnet/ip/format.h b/src/vnet/ip/format.h
index d527e31a05e..9ebcf084be3 100644
--- a/src/vnet/ip/format.h
+++ b/src/vnet/ip/format.h
@@ -74,10 +74,13 @@ unformat_function_t unformat_ip46_address;
/* Parse an IP4 address %d.%d.%d.%d. */
unformat_function_t unformat_ip4_address;
+/* Parse an IP4 address and mask %d.%d.%d.%d/%d.%d.%d.%d */
+unformat_function_t unformat_ip4_address_and_mask;
/* Format an IP4 address. */
format_function_t format_ip4_address;
format_function_t format_ip4_address_and_length;
+format_function_t format_ip4_address_and_mask;
/* Parse an IP4 header. */
unformat_function_t unformat_ip4_header;
@@ -92,8 +95,10 @@ unformat_function_t unformat_pg_ip4_header;
/* IP6 */
unformat_function_t unformat_ip6_address;
+unformat_function_t unformat_ip6_address_and_mask;
format_function_t format_ip6_address;
format_function_t format_ip6_address_and_length;
+format_function_t format_ip6_address_and_mask;
unformat_function_t unformat_ip6_header;
format_function_t format_ip6_header;
unformat_function_t unformat_pg_ip6_header;
diff --git a/src/vnet/ip/ip4_format.c b/src/vnet/ip/ip4_format.c
index 3f2221022c7..0a2d7d293d5 100644
--- a/src/vnet/ip/ip4_format.c
+++ b/src/vnet/ip/ip4_format.c
@@ -56,6 +56,21 @@ format_ip4_address_and_length (u8 * s, va_list * args)
return format (s, "%U/%d", format_ip4_address, a, l);
}
+u8 *
+format_ip4_address_and_mask (u8 * s, va_list * args)
+{
+ ip4_address_and_mask_t *am = va_arg (*args, ip4_address_and_mask_t *);
+
+ if (am->addr.as_u32 == 0 && am->mask.as_u32 == 0)
+ return format (s, "any");
+
+ if (am->mask.as_u32 == ~0)
+ return format (s, "%U", format_ip4_address, &am->addr);
+
+ return format (s, "%U/%U", format_ip4_address, &am->addr,
+ format_ip4_address, &am->mask);
+}
+
/* Parse an IP4 address %d.%d.%d.%d. */
uword
unformat_ip4_address (unformat_input_t * input, va_list * args)
@@ -77,6 +92,27 @@ unformat_ip4_address (unformat_input_t * input, va_list * args)
return 1;
}
+uword
+unformat_ip4_address_and_mask (unformat_input_t * input, va_list * args)
+{
+ ip4_address_and_mask_t *am = va_arg (*args, ip4_address_and_mask_t *);
+ u32 addr = 0, mask = 0;
+
+ if (unformat (input, "any"))
+ ;
+ else if (unformat (input, "%U/%U", unformat_ip4_address, &addr,
+ unformat_ip4_address, &mask))
+ ;
+ else if (unformat (input, "%U", unformat_ip4_address, &addr))
+ mask = ~0;
+ else
+ return 0;
+
+ am->addr.as_u32 = addr;
+ am->mask.as_u32 = mask;
+ return 1;
+}
+
/* Format an IP4 header. */
u8 *
format_ip4_header (u8 * s, va_list * args)
diff --git a/src/vnet/ip/ip4_packet.h b/src/vnet/ip/ip4_packet.h
index 1ff9fbdba13..2f0c75e4924 100644
--- a/src/vnet/ip/ip4_packet.h
+++ b/src/vnet/ip/ip4_packet.h
@@ -77,6 +77,11 @@ typedef struct
ip4_address_t src, dst;
} ip4_address_pair_t;
+typedef struct
+{
+ ip4_address_t addr, mask;
+} ip4_address_and_mask_t;
+
/* If address is a valid netmask, return length of mask. */
always_inline uword
ip4_address_netmask_length (ip4_address_t * a)
diff --git a/src/vnet/ip/ip6_format.c b/src/vnet/ip/ip6_format.c
index b7ae2ffae29..b1a8adf58de 100644
--- a/src/vnet/ip/ip6_format.c
+++ b/src/vnet/ip/ip6_format.c
@@ -117,6 +117,23 @@ format_ip6_address_and_length (u8 * s, va_list * args)
return format (s, "%U/%d", format_ip6_address, a, l);
}
+u8 *
+format_ip6_address_and_mask (u8 * s, va_list * args)
+{
+ ip6_address_and_mask_t *am = va_arg (*args, ip6_address_and_mask_t *);
+
+ if (am->addr.as_u64[0] == 0 && am->addr.as_u64[1] == 0 &&
+ am->mask.as_u64[0] == 0 && am->mask.as_u64[1] == 0)
+ return format (s, "any");
+
+ if (am->mask.as_u64[0] == ~0 && am->mask.as_u64[1] == ~0)
+ return format (s, "%U", format_ip4_address, &am->addr);
+
+ return format (s, "%U/%U", format_ip6_address, &am->addr,
+ format_ip4_address, &am->mask);
+}
+
+
/* Parse an IP6 address. */
uword
unformat_ip6_address (unformat_input_t * input, va_list * args)
@@ -212,6 +229,32 @@ unformat_ip6_address (unformat_input_t * input, va_list * args)
}
}
+uword
+unformat_ip6_address_and_mask (unformat_input_t * input, va_list * args)
+{
+ ip6_address_and_mask_t *am = va_arg (*args, ip6_address_and_mask_t *);
+ ip6_address_t addr, mask;
+
+ memset (&addr, 0, sizeof (ip6_address_t));
+ memset (&mask, 0, sizeof (ip6_address_t));
+
+ if (unformat (input, "any"))
+ ;
+ else if (unformat (input, "%U/%U", unformat_ip6_address, &addr,
+ unformat_ip6_address, &mask))
+ ;
+ else if (unformat (input, "%U", unformat_ip6_address, &addr))
+ mask.as_u64[0] = mask.as_u64[1] = ~0;
+ else
+ return 0;
+
+ am->addr.as_u64[0] = addr.as_u64[0];
+ am->addr.as_u64[1] = addr.as_u64[1];
+ am->mask.as_u64[0] = mask.as_u64[0];
+ am->mask.as_u64[1] = mask.as_u64[1];
+ return 1;
+}
+
/* Format an IP6 header. */
u8 *
format_ip6_header (u8 * s, va_list * args)
diff --git a/src/vnet/ip/ip6_packet.h b/src/vnet/ip/ip6_packet.h
index 70c3dab473d..b8f8d6e8657 100644
--- a/src/vnet/ip/ip6_packet.h
+++ b/src/vnet/ip/ip6_packet.h
@@ -53,6 +53,11 @@ typedef union
}
ip6_address_t;
+typedef struct
+{
+ ip6_address_t addr, mask;
+} ip6_address_and_mask_t;
+
/* Packed so that the mhash key doesn't include uninitialized pad bytes */
/* *INDENT-OFF* */
typedef CLIB_PACKED (struct {