diff options
Diffstat (limited to 'src/vnet/ip')
-rw-r--r-- | src/vnet/ip/format.h | 5 | ||||
-rw-r--r-- | src/vnet/ip/ip4_format.c | 36 | ||||
-rw-r--r-- | src/vnet/ip/ip4_packet.h | 5 | ||||
-rw-r--r-- | src/vnet/ip/ip6_format.c | 43 | ||||
-rw-r--r-- | src/vnet/ip/ip6_packet.h | 5 |
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 { |