/*
- * Copyright (c) 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
+ * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
}
+/* Appends a formatted representation of 'sv' to 's'. */
+void
+mf_subvalue_format(const union mf_subvalue *sv, struct ds *s)
+{
+ ds_put_hex(s, sv, sizeof *sv);
+}
+
/* Returns true if 'wc' wildcards all the bits in field 'mf', false if 'wc'
* specifies at least one bit in the field.
*
return !wc->masks.tunnel.ip_src;
case MFF_TUN_DST:
return !wc->masks.tunnel.ip_dst;
+ case MFF_TUN_IPV6_SRC:
+ return ipv6_mask_is_any(&wc->masks.tunnel.ipv6_src);
+ case MFF_TUN_IPV6_DST:
+ return ipv6_mask_is_any(&wc->masks.tunnel.ipv6_dst);
case MFF_TUN_ID:
return !wc->masks.tunnel.tun_id;
case MFF_TUN_TOS:
return !wc->masks.ct_state;
case MFF_CT_ZONE:
return !wc->masks.ct_zone;
+ case MFF_CT_MARK:
+ return !wc->masks.ct_mark;
+ case MFF_CT_LABEL:
+ return ovs_u128_is_zero(&wc->masks.ct_label);
CASE_MFF_REGS:
return !wc->masks.regs[mf->id - MFF_REG0];
CASE_MFF_XREGS:
case MFF_TUN_ID:
case MFF_TUN_SRC:
case MFF_TUN_DST:
+ case MFF_TUN_IPV6_SRC:
+ case MFF_TUN_IPV6_DST:
case MFF_TUN_TOS:
case MFF_TUN_TTL:
case MFF_TUN_GBP_ID:
case MFF_SKB_PRIORITY:
case MFF_PKT_MARK:
case MFF_CT_ZONE:
+ case MFF_CT_MARK:
+ case MFF_CT_LABEL:
CASE_MFF_REGS:
CASE_MFF_XREGS:
case MFF_ETH_SRC:
case MFF_TUN_DST:
value->be32 = flow->tunnel.ip_dst;
break;
+ case MFF_TUN_IPV6_SRC:
+ value->ipv6 = flow->tunnel.ipv6_src;
+ break;
+ case MFF_TUN_IPV6_DST:
+ value->ipv6 = flow->tunnel.ipv6_dst;
+ break;
case MFF_TUN_FLAGS:
value->be16 = htons(flow->tunnel.flags & FLOW_TNL_PUB_F_MASK);
break;
value->be16 = htons(flow->ct_zone);
break;
+ case MFF_CT_MARK:
+ value->be32 = htonl(flow->ct_mark);
+ break;
+
+ case MFF_CT_LABEL:
+ value->be128 = hton128(flow->ct_label);
+ break;
+
CASE_MFF_REGS:
value->be32 = htonl(flow->regs[mf->id - MFF_REG0]);
break;
case MFF_TUN_DST:
match_set_tun_dst(match, value->be32);
break;
+ case MFF_TUN_IPV6_SRC:
+ match_set_tun_ipv6_src(match, &value->ipv6);
+ break;
+ case MFF_TUN_IPV6_DST:
+ match_set_tun_ipv6_dst(match, &value->ipv6);
+ break;
case MFF_TUN_FLAGS:
match_set_tun_flags(match, ntohs(value->be16));
break;
match_set_ct_zone(match, ntohs(value->be16));
break;
+ case MFF_CT_MARK:
+ match_set_ct_mark(match, ntohl(value->be32));
+ break;
+
+ case MFF_CT_LABEL:
+ match_set_ct_label(match, ntoh128(value->be128));
+ break;
+
CASE_MFF_REGS:
match_set_reg(match, mf->id - MFF_REG0, ntohl(value->be32));
break;
case MFF_TUN_DST:
flow->tunnel.ip_dst = value->be32;
break;
+ case MFF_TUN_IPV6_SRC:
+ flow->tunnel.ipv6_src = value->ipv6;
+ break;
+ case MFF_TUN_IPV6_DST:
+ flow->tunnel.ipv6_dst = value->ipv6;
+ break;
case MFF_TUN_FLAGS:
flow->tunnel.flags = (flow->tunnel.flags & ~FLOW_TNL_PUB_F_MASK) |
ntohs(value->be16);
flow->ct_zone = ntohs(value->be16);
break;
+ case MFF_CT_MARK:
+ flow->ct_mark = ntohl(value->be32);
+ break;
+
+ case MFF_CT_LABEL:
+ flow->ct_label = ntoh128(value->be128);
+ break;
+
CASE_MFF_REGS:
flow->regs[mf->id - MFF_REG0] = ntohl(value->be32);
break;
case MFF_TUN_DST:
match_set_tun_dst_masked(match, htonl(0), htonl(0));
break;
+ case MFF_TUN_IPV6_SRC:
+ memset(&match->wc.masks.tunnel.ipv6_src, 0,
+ sizeof match->wc.masks.tunnel.ipv6_src);
+ memset(&match->flow.tunnel.ipv6_src, 0,
+ sizeof match->flow.tunnel.ipv6_src);
+ break;
+ case MFF_TUN_IPV6_DST:
+ memset(&match->wc.masks.tunnel.ipv6_dst, 0,
+ sizeof match->wc.masks.tunnel.ipv6_dst);
+ memset(&match->flow.tunnel.ipv6_dst, 0,
+ sizeof match->flow.tunnel.ipv6_dst);
+ break;
case MFF_TUN_FLAGS:
match_set_tun_flags_masked(match, 0, 0);
break;
match->wc.masks.ct_zone = 0;
break;
+ case MFF_CT_MARK:
+ match->flow.ct_mark = 0;
+ match->wc.masks.ct_mark = 0;
+ break;
+
+ case MFF_CT_LABEL:
+ memset(&match->flow.ct_label, 0, sizeof(match->flow.ct_label));
+ memset(&match->wc.masks.ct_label, 0, sizeof(match->wc.masks.ct_label));
+ break;
+
CASE_MFF_REGS:
match_set_reg_masked(match, mf->id - MFF_REG0, 0, 0);
break;
case MFF_TUN_DST:
match_set_tun_dst_masked(match, value->be32, mask->be32);
break;
+ case MFF_TUN_IPV6_SRC:
+ match_set_tun_ipv6_src_masked(match, &value->ipv6, &mask->ipv6);
+ break;
+ case MFF_TUN_IPV6_DST:
+ match_set_tun_ipv6_dst_masked(match, &value->ipv6, &mask->ipv6);
+ break;
case MFF_TUN_FLAGS:
match_set_tun_flags_masked(match, ntohs(value->be16), ntohs(mask->be16));
break;
match_set_ct_state_masked(match, ntohl(value->be32), ntohl(mask->be32));
break;
+ case MFF_CT_MARK:
+ match_set_ct_mark_masked(match, ntohl(value->be32), ntohl(mask->be32));
+ break;
+
+ case MFF_CT_LABEL:
+ match_set_ct_label_masked(match, ntoh128(value->be128),
+ mask ? ntoh128(mask->be128) : OVS_U128_MAX);
+ break;
+
case MFF_ETH_DST:
match_set_dl_dst_masked(match, value->mac, mask->mac);
break;
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 *
mf_from_ipv6_string(const struct mf_field *mf, const char *s,
- struct in6_addr *value, struct in6_addr *mask)
+ struct in6_addr *ipv6, struct in6_addr *mask)
{
- char *str = xstrdup(s);
- char *save_ptr = NULL;
- const char *name, *netmask;
- int retval;
-
- ovs_assert(mf->n_bytes == sizeof *value);
-
- name = strtok_r(str, "/", &save_ptr);
- retval = name ? lookup_ipv6(name, value) : EINVAL;
- if (retval) {
- char *err;
-
- err = xasprintf("%s: could not convert to IPv6 address", str);
- free(str);
-
- return err;
- }
-
- netmask = strtok_r(NULL, "/", &save_ptr);
- if (netmask) {
- if (inet_pton(AF_INET6, netmask, mask) != 1) {
- int prefix = atoi(netmask);
- if (prefix <= 0 || prefix > 128) {
- free(str);
- return xasprintf("%s: prefix bits not between 1 and 128", s);
- } else {
- *mask = ipv6_create_mask(prefix);
- }
- }
- } else {
- *mask = in6addr_exact;
- }
- free(str);
-
- return NULL;
+ ovs_assert(mf->n_bytes == sizeof *ipv6);
+ return ipv6_parse_masked(s, ipv6, mask);
}
static char *
break;
case MFS_IPV6:
- print_ipv6_masked(s, &value->ipv6, mask ? &mask->ipv6 : NULL);
+ ipv6_format_masked(&value->ipv6, mask ? &mask->ipv6 : NULL, s);
break;
case MFS_FRAG: