-
- netmask = strtok_r(NULL, "/", &save_ptr);
- if (netmask) {
- uint8_t o[4];
- if (sscanf(netmask, "%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8,
- &o[0], &o[1], &o[2], &o[3]) == 4) {
- mask = htonl((o[0] << 24) | (o[1] << 16) | (o[2] << 8) | o[3]);
- } else {
- int prefix = atoi(netmask);
- if (prefix <= 0 || prefix > 32) {
- ovs_fatal(0, "%s: network prefix bits not between 1 and 32",
- str);
- } else if (prefix == 32) {
- mask = htonl(UINT32_MAX);
- } else {
- mask = htonl(((1u << prefix) - 1) << (32 - prefix));
- }
- }
- } else {
- mask = htonl(UINT32_MAX);
- }
- *ip &= mask;
-
- if (maskp) {
- *maskp = mask;
- } else {
- if (mask != htonl(UINT32_MAX)) {
- ovs_fatal(0, "%s: netmask not allowed here", str_);
- }
- }
-
- free(str);
-}
-
-static void
-str_to_tun_id(const char *str, ovs_be64 *tun_idp, ovs_be64 *maskp)
-{
- uint64_t tun_id, mask;
- char *tail;
-
- errno = 0;
- tun_id = strtoull(str, &tail, 0);
- if (errno || (*tail != '\0' && *tail != '/')) {
- goto error;
- }
-
- if (*tail == '/') {
- mask = strtoull(tail + 1, &tail, 0);
- if (errno || *tail != '\0') {
- goto error;
- }
- } else {
- mask = UINT64_MAX;
- }
-
- *tun_idp = htonll(tun_id);
- *maskp = htonll(mask);
- return;
-
-error:
- ovs_fatal(0, "%s: bad syntax for tunnel id", str);
-}
-
-static void
-str_to_vlan_tci(const char *str, ovs_be16 *vlan_tcip, ovs_be16 *maskp)
-{
- uint16_t vlan_tci, mask;
- char *tail;
-
- errno = 0;
- vlan_tci = strtol(str, &tail, 0);
- if (errno || (*tail != '\0' && *tail != '/')) {
- goto error;
- }
-
- if (*tail == '/') {
- mask = strtol(tail + 1, &tail, 0);
- if (errno || *tail != '\0') {
- goto error;
- }
- } else {
- mask = UINT16_MAX;
- }
-
- *vlan_tcip = htons(vlan_tci);
- *maskp = htons(mask);
- return;
-
-error:
- ovs_fatal(0, "%s: bad syntax for vlan_tci", str);
-}
-
-static void
-str_to_ipv6(const char *str_, struct in6_addr *addrp, struct in6_addr *maskp)
-{
- char *str = xstrdup(str_);
- char *save_ptr = NULL;
- const char *name, *netmask;
- struct in6_addr addr, mask;
- int retval;
-
- name = strtok_r(str, "/", &save_ptr);
- retval = name ? lookup_ipv6(name, &addr) : EINVAL;
- if (retval) {
- ovs_fatal(0, "%s: could not convert to IPv6 address", str);
- }
-
- netmask = strtok_r(NULL, "/", &save_ptr);
- if (netmask) {
- int prefix = atoi(netmask);
- if (prefix <= 0 || prefix > 128) {
- ovs_fatal(0, "%s: network prefix bits not between 1 and 128",
- str);
- } else {
- mask = ipv6_create_mask(prefix);
- }
- } else {
- mask = in6addr_exact;
- }
- *addrp = ipv6_addr_bitand(&addr, &mask);
-
- if (maskp) {
- *maskp = mask;
- } else {
- if (!ipv6_mask_is_exact(&mask)) {
- ovs_fatal(0, "%s: netmask not allowed here", str_);
- }
- }
-
- free(str);
-}
-
-static void *
-put_action(struct ofpbuf *b, size_t size, uint16_t type)
-{
- struct ofp_action_header *ah = ofpbuf_put_zeros(b, size);
- ah->type = htons(type);
- ah->len = htons(size);
- return ah;
-}
-
-static struct ofp_action_output *
-put_output_action(struct ofpbuf *b, uint16_t port)
-{
- struct ofp_action_output *oao = put_action(b, sizeof *oao, OFPAT_OUTPUT);
- oao->port = htons(port);
- return oao;