diff options
author | Ben Pfaff <blp@nicira.com> | 2015-10-16 13:54:45 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2015-10-16 23:52:41 -0700 |
commit | 614404518f67812dbf35d30aca2686ebfd8f6aaa (patch) | |
tree | 79dd23c11be6824bed65141ba3b190dec1f518e5 | |
parent | 8e3eb50e93ce19bca9dc9331db061fcc9ac28420 (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.c | 19 | ||||
-rw-r--r-- | lib/packets.c | 28 | ||||
-rw-r--r-- | lib/packets.h | 2 |
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) |