aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2015-10-16 13:54:45 -0700
committerBen Pfaff <blp@nicira.com>2015-10-16 23:52:41 -0700
commit614404518f67812dbf35d30aca2686ebfd8f6aaa (patch)
tree79dd23c11be6824bed65141ba3b190dec1f518e5
parent8e3eb50e93ce19bca9dc9331db061fcc9ac28420 (diff)
packets: New function ip_parse_masked().
Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Justin Pettit <jpettit@nicira.com>
-rw-r--r--lib/meta-flow.c19
-rw-r--r--lib/packets.c28
-rw-r--r--lib/packets.h2
3 files changed, 31 insertions, 18 deletions
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 05878ac15..eaf4ca885 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -2042,25 +2042,8 @@ static char *
mf_from_ipv4_string(const struct mf_field *mf, const char *s,
ovs_be32 *ip, ovs_be32 *mask)
{
- int prefix;
-
ovs_assert(mf->n_bytes == sizeof *ip);
-
- if (ovs_scan(s, IP_SCAN_FMT"/"IP_SCAN_FMT,
- IP_SCAN_ARGS(ip), IP_SCAN_ARGS(mask))) {
- /* OK. */
- } else if (ovs_scan(s, IP_SCAN_FMT"/%d", IP_SCAN_ARGS(ip), &prefix)) {
- if (prefix <= 0 || prefix > 32) {
- return xasprintf("%s: network prefix bits not between 0 and "
- "32", s);
- }
- *mask = be32_prefix_mask(prefix);
- } else if (ovs_scan(s, IP_SCAN_FMT, IP_SCAN_ARGS(ip))) {
- *mask = OVS_BE32_MAX;
- } else {
- return xasprintf("%s: invalid IP address", s);
- }
- return NULL;
+ return ip_parse_masked(s, ip, mask);
}
static char *
diff --git a/lib/packets.c b/lib/packets.c
index 2915c7440..e7d0cb31f 100644
--- a/lib/packets.c
+++ b/lib/packets.c
@@ -404,6 +404,34 @@ ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *s)
}
}
+/* Parses string 's', which must be an IP address with an optional netmask or
+ * CIDR prefix length. Stores the IP address into '*ip' and the netmask into
+ * '*mask'. (If 's' does not contain a netmask, 255.255.255.255 is
+ * assumed.)
+ *
+ * Returns NULL if successful, otherwise an error message that the caller must
+ * free(). */
+char * OVS_WARN_UNUSED_RESULT
+ip_parse_masked(const char *s, ovs_be32 *ip, ovs_be32 *mask)
+{
+ int prefix;
+
+ if (ovs_scan(s, IP_SCAN_FMT"/"IP_SCAN_FMT,
+ IP_SCAN_ARGS(ip), IP_SCAN_ARGS(mask))) {
+ /* OK. */
+ } else if (ovs_scan(s, IP_SCAN_FMT"/%d", IP_SCAN_ARGS(ip), &prefix)) {
+ if (prefix <= 0 || prefix > 32) {
+ return xasprintf("%s: network prefix bits not between 0 and "
+ "32", s);
+ }
+ *mask = be32_prefix_mask(prefix);
+ } else if (ovs_scan(s, IP_SCAN_FMT, IP_SCAN_ARGS(ip))) {
+ *mask = OVS_BE32_MAX;
+ } else {
+ return xasprintf("%s: invalid IP address", s);
+ }
+ return NULL;
+}
/* Stores the string representation of the IPv6 address 'addr' into the
* character array 'addr_str', which must be at least INET6_ADDRSTRLEN
diff --git a/lib/packets.h b/lib/packets.h
index 586a16475..67f635ed2 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -566,6 +566,8 @@ ip_is_local_multicast(ovs_be32 ip)
}
int ip_count_cidr_bits(ovs_be32 netmask);
void ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *);
+char *ip_parse_masked(const char *s, ovs_be32 *ip, ovs_be32 *mask)
+ OVS_WARN_UNUSED_RESULT;
#define IP_VER(ip_ihl_ver) ((ip_ihl_ver) >> 4)
#define IP_IHL(ip_ihl_ver) ((ip_ihl_ver) & 15)