[ovs-dev] [PATCH v5 08/13] lib/odp: Use masked set actions.
Jarno Rajahalme
jrajahalme at nicira.com
Fri Sep 5 23:05:15 UTC 2014
Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
v5: Using pattern with less code duplication suggested by Ben.
lib/odp-util.c | 487 ++++++++++++++++++++++++++----------------
lib/odp-util.h | 5 +-
ofproto/ofproto-dpif-xlate.c | 15 +-
tests/ofproto-dpif.at | 66 +++---
tests/tunnel.at | 8 +-
5 files changed, 344 insertions(+), 237 deletions(-)
diff --git a/lib/odp-util.c b/lib/odp-util.c
index b5c8c2b..8ac43c5 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -1167,43 +1167,67 @@ odp_mask_attr_is_wildcard(const struct nlattr *ma)
}
static bool
-odp_mask_attr_is_exact(const struct nlattr *ma)
+odp_mask_is_exact(enum ovs_key_attr attr, const void *mask, size_t size)
{
- bool is_exact;
- enum ovs_key_attr attr = nl_attr_type(ma);
-
if (attr == OVS_KEY_ATTR_TCP_FLAGS) {
- is_exact = TCP_FLAGS(nl_attr_get_be16(ma)) == TCP_FLAGS(OVS_BE16_MAX);
- } else if (attr == OVS_KEY_ATTR_IPV6) {
- const struct ovs_key_ipv6 *mask = nl_attr_get(ma);
+ return TCP_FLAGS(*(ovs_be16 *)mask) == TCP_FLAGS(OVS_BE16_MAX);
+ }
+ if (attr == OVS_KEY_ATTR_IPV6) {
+ const struct ovs_key_ipv6 *ipv6_mask = mask;
- is_exact =
- ((mask->ipv6_label & htonl(IPV6_LABEL_MASK))
+ return
+ ((ipv6_mask->ipv6_label & htonl(IPV6_LABEL_MASK))
== htonl(IPV6_LABEL_MASK))
- && mask->ipv6_proto == UINT8_MAX
- && mask->ipv6_tclass == UINT8_MAX
- && mask->ipv6_hlimit == UINT8_MAX
- && mask->ipv6_frag == UINT8_MAX
- && ipv6_mask_is_exact((const struct in6_addr *)mask->ipv6_src)
- && ipv6_mask_is_exact((const struct in6_addr *)mask->ipv6_dst);
- } else if (attr == OVS_KEY_ATTR_TUNNEL) {
- struct flow_tnl tun_mask;
+ && ipv6_mask->ipv6_proto == UINT8_MAX
+ && ipv6_mask->ipv6_tclass == UINT8_MAX
+ && ipv6_mask->ipv6_hlimit == UINT8_MAX
+ && ipv6_mask->ipv6_frag == UINT8_MAX
+ && ipv6_mask_is_exact((const struct in6_addr *)ipv6_mask->ipv6_src)
+ && ipv6_mask_is_exact((const struct in6_addr *)ipv6_mask->ipv6_dst);
+ }
+ if (attr == OVS_KEY_ATTR_TUNNEL) {
+ const struct flow_tnl *tun_mask = mask;
+
+ return tun_mask->flags == FLOW_TNL_F_MASK
+ && tun_mask->tun_id == OVS_BE64_MAX
+ && tun_mask->ip_src == OVS_BE32_MAX
+ && tun_mask->ip_dst == OVS_BE32_MAX
+ && tun_mask->ip_tos == UINT8_MAX
+ && tun_mask->ip_ttl == UINT8_MAX
+ && tun_mask->tp_src == OVS_BE16_MAX
+ && tun_mask->tp_dst == OVS_BE16_MAX;
+ }
+
+ if (attr == OVS_KEY_ATTR_ARP) {
+ /* ARP key has padding, ignore it. */
+ BUILD_ASSERT_DECL(sizeof(struct ovs_key_arp) == 24);
+ BUILD_ASSERT_DECL(offsetof(struct ovs_key_arp, arp_tha) == 10 + 6);
+ size = offsetof(struct ovs_key_arp, arp_tha) + ETH_ADDR_LEN;
+ ovs_assert(((uint16_t *)mask)[size/2] == 0);
+ }
+ return is_all_ones(mask, size);
+}
+
+static bool
+odp_mask_attr_is_exact(const struct nlattr *ma)
+{
+ struct flow_tnl tun_mask;
+ enum ovs_key_attr attr = nl_attr_type(ma);
+ const void *mask;
+ size_t size;
+
+ if (attr == OVS_KEY_ATTR_TUNNEL) {
memset(&tun_mask, 0, sizeof tun_mask);
odp_tun_key_from_attr(ma, &tun_mask);
- is_exact = tun_mask.flags == FLOW_TNL_F_MASK
- && tun_mask.tun_id == OVS_BE64_MAX
- && tun_mask.ip_src == OVS_BE32_MAX
- && tun_mask.ip_dst == OVS_BE32_MAX
- && tun_mask.ip_tos == UINT8_MAX
- && tun_mask.ip_ttl == UINT8_MAX
- && tun_mask.tp_src == OVS_BE16_MAX
- && tun_mask.tp_dst == OVS_BE16_MAX;
+ mask = &tun_mask;
+ size = sizeof tun_mask;
} else {
- is_exact = is_all_ones(nl_attr_get(ma), nl_attr_get_size(ma));
+ mask = nl_attr_get(ma);
+ size = nl_attr_get_size(ma);
}
- return is_exact;
+ return odp_mask_is_exact(attr, mask, size);
}
void
@@ -3525,14 +3549,6 @@ commit_masked_set_action(struct ofpbuf *odp_actions,
nl_msg_end_nested(odp_actions, offset);
}
-void
-odp_put_pkt_mark_action(const uint32_t pkt_mark,
- struct ofpbuf *odp_actions)
-{
- commit_set_action(odp_actions, OVS_KEY_ATTR_SKB_MARK, &pkt_mark,
- sizeof(pkt_mark));
-}
-
/* If any of the flow key data that ODP actions can modify are different in
* 'base->tunnel' and 'flow->tunnel', appends a set_tunnel ODP action to
* 'odp_actions' that change the flow tunneling information in key from
@@ -3553,29 +3569,63 @@ commit_odp_tunnel_action(const struct flow *flow, struct flow *base,
}
}
-static void
-commit_set_ether_addr_action(const struct flow *flow, struct flow *base,
- struct ofpbuf *odp_actions,
- struct flow_wildcards *wc)
+static bool
+commit(enum ovs_key_attr attr, bool use_masked_set,
+ const void *key, void *base, void *mask, size_t size,
+ struct ofpbuf *odp_actions)
{
- struct ovs_key_ethernet eth_key;
+ if (memcmp(key, base, size)) {
+ bool fully_masked = odp_mask_is_exact(attr, mask, size);
- if (eth_addr_equals(base->dl_src, flow->dl_src) &&
- eth_addr_equals(base->dl_dst, flow->dl_dst)) {
- return;
+ if (use_masked_set && !fully_masked) {
+ commit_masked_set_action(odp_actions, attr, key, mask, size);
+ } else {
+ if (!fully_masked) {
+ memset(mask, 0xff, size);
+ }
+ commit_set_action(odp_actions, attr, key, size);
+ }
+ memcpy(base, key, size);
+ return true;
+ } else {
+ /* Mask bits are set when we have either read or set the corresponding
+ * values. Masked bits will be exact-matched, no need to set them
+ * if the value did not actually change. */
+ return false;
}
+}
- memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src);
- memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
+static void
+get_ethernet_key(const struct flow *flow, struct ovs_key_ethernet *eth)
+{
+ memcpy(eth->eth_src, flow->dl_src, ETH_ADDR_LEN);
+ memcpy(eth->eth_dst, flow->dl_dst, ETH_ADDR_LEN);
+}
- memcpy(base->dl_src, flow->dl_src, ETH_ADDR_LEN);
- memcpy(base->dl_dst, flow->dl_dst, ETH_ADDR_LEN);
+static void
+put_ethernet_key(const struct ovs_key_ethernet *eth, struct flow *flow)
+{
+ memcpy(flow->dl_src, eth->eth_src, ETH_ADDR_LEN);
+ memcpy(flow->dl_dst, eth->eth_dst, ETH_ADDR_LEN);
+}
- memcpy(eth_key.eth_src, base->dl_src, ETH_ADDR_LEN);
- memcpy(eth_key.eth_dst, base->dl_dst, ETH_ADDR_LEN);
+static void
+commit_set_ether_addr_action(const struct flow *flow, struct flow *base_flow,
+ struct ofpbuf *odp_actions,
+ struct flow_wildcards *wc,
+ bool use_masked)
+{
+ struct ovs_key_ethernet key, base, mask;
- commit_set_action(odp_actions, OVS_KEY_ATTR_ETHERNET,
- ð_key, sizeof(eth_key));
+ get_ethernet_key(flow, &key);
+ get_ethernet_key(base_flow, &base);
+ get_ethernet_key(&wc->masks, &mask);
+
+ if (commit(OVS_KEY_ATTR_ETHERNET, use_masked,
+ &key, &base, &mask, sizeof key, odp_actions)) {
+ put_ethernet_key(&base, base_flow);
+ put_ethernet_key(&mask, &wc->masks);
+ }
}
static void
@@ -3677,115 +3727,157 @@ commit_mpls_action(const struct flow *flow, struct flow *base,
}
static void
-commit_set_ipv4_action(const struct flow *flow, struct flow *base,
- struct ofpbuf *odp_actions, struct flow_wildcards *wc)
+get_ipv4_key(const struct flow *flow, struct ovs_key_ipv4 *ipv4)
{
- struct ovs_key_ipv4 ipv4_key;
+ ipv4->ipv4_src = flow->nw_src;
+ ipv4->ipv4_dst = flow->nw_dst;
+ ipv4->ipv4_proto = flow->nw_proto;
+ ipv4->ipv4_tos = flow->nw_tos;
+ ipv4->ipv4_ttl = flow->nw_ttl;
+ ipv4->ipv4_frag = ovs_to_odp_frag(flow->nw_frag);
+}
- if (base->nw_src == flow->nw_src &&
- base->nw_dst == flow->nw_dst &&
- base->nw_tos == flow->nw_tos &&
- base->nw_ttl == flow->nw_ttl &&
- base->nw_frag == flow->nw_frag) {
- return;
- }
+static void
+put_ipv4_key(const struct ovs_key_ipv4 *ipv4, struct flow *flow)
+{
+ flow->nw_src = ipv4->ipv4_src;
+ flow->nw_dst = ipv4->ipv4_dst;
+ flow->nw_proto = ipv4->ipv4_proto;
+ flow->nw_tos = ipv4->ipv4_tos;
+ flow->nw_ttl = ipv4->ipv4_ttl;
+ if (ipv4->ipv4_frag == 0xff) {
+ flow->nw_frag = 0xff;
+ } else {
+ odp_to_ovs_frag(ipv4->ipv4_frag, flow);
+ }
+}
+
+static void
+commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow,
+ struct ofpbuf *odp_actions, struct flow_wildcards *wc,
+ bool use_masked)
+{
+ struct ovs_key_ipv4 key, mask, base;
- memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
- memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
- memset(&wc->masks.nw_tos, 0xff, sizeof wc->masks.nw_tos);
- memset(&wc->masks.nw_ttl, 0xff, sizeof wc->masks.nw_ttl);
- memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
- memset(&wc->masks.nw_frag, 0xff, sizeof wc->masks.nw_frag);
+ /* Check that nw_proto and nw_frag remain unchanged. */
+ ovs_assert(flow->nw_proto == base_flow->nw_proto &&
+ flow->nw_frag == base_flow->nw_frag);
- ipv4_key.ipv4_src = base->nw_src = flow->nw_src;
- ipv4_key.ipv4_dst = base->nw_dst = flow->nw_dst;
- ipv4_key.ipv4_tos = base->nw_tos = flow->nw_tos;
- ipv4_key.ipv4_ttl = base->nw_ttl = flow->nw_ttl;
- ipv4_key.ipv4_proto = base->nw_proto;
- ipv4_key.ipv4_frag = ovs_to_odp_frag(base->nw_frag);
+ get_ipv4_key(flow, &key);
+ get_ipv4_key(base_flow, &base);
+ get_ipv4_key(&wc->masks, &mask);
+ mask.ipv4_proto = 0; /* Not writeable. */
+ mask.ipv4_frag = 0; /* Not writable. */
- commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4,
- &ipv4_key, sizeof(ipv4_key));
+ if (commit(OVS_KEY_ATTR_IPV4, use_masked, &key, &base, &mask, sizeof key,
+ odp_actions)) {
+ put_ipv4_key(&base, base_flow);
+ if (mask.ipv4_proto != 0) { /* Mask was changed by commit(). */
+ put_ipv4_key(&mask, &wc->masks);
+ }
+ }
}
static void
-commit_set_ipv6_action(const struct flow *flow, struct flow *base,
- struct ofpbuf *odp_actions, struct flow_wildcards *wc)
+get_ipv6_key(const struct flow *flow, struct ovs_key_ipv6 *ipv6)
{
- struct ovs_key_ipv6 ipv6_key;
+ memcpy(ipv6->ipv6_src, &flow->ipv6_src, sizeof ipv6->ipv6_src);
+ memcpy(ipv6->ipv6_dst, &flow->ipv6_dst, sizeof ipv6->ipv6_dst);
+ ipv6->ipv6_label = flow->ipv6_label;
+ ipv6->ipv6_proto = flow->nw_proto;
+ ipv6->ipv6_tclass = flow->nw_tos;
+ ipv6->ipv6_hlimit = flow->nw_ttl;
+ ipv6->ipv6_frag = ovs_to_odp_frag(flow->nw_frag);
+}
- if (ipv6_addr_equals(&base->ipv6_src, &flow->ipv6_src) &&
- ipv6_addr_equals(&base->ipv6_dst, &flow->ipv6_dst) &&
- base->ipv6_label == flow->ipv6_label &&
- base->nw_tos == flow->nw_tos &&
- base->nw_ttl == flow->nw_ttl &&
- base->nw_frag == flow->nw_frag) {
- return;
- }
+static void
+put_ipv6_key(const struct ovs_key_ipv6 *ipv6, struct flow *flow)
+{
+ memcpy(&flow->ipv6_src, ipv6->ipv6_src, sizeof flow->ipv6_src);
+ memcpy(&flow->ipv6_dst, ipv6->ipv6_dst, sizeof flow->ipv6_dst);
+ flow->ipv6_label = ipv6->ipv6_label;
+ flow->nw_proto = ipv6->ipv6_proto;
+ flow->nw_tos = ipv6->ipv6_tclass;
+ flow->nw_ttl = ipv6->ipv6_hlimit;
+ if (ipv6->ipv6_frag == 0xff) {
+ flow->nw_frag = 0xff;
+ } else {
+ odp_to_ovs_frag(ipv6->ipv6_frag, flow);
+ }
+}
- memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src);
- memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
- memset(&wc->masks.ipv6_label, 0xff, sizeof wc->masks.ipv6_label);
- memset(&wc->masks.nw_tos, 0xff, sizeof wc->masks.nw_tos);
- memset(&wc->masks.nw_ttl, 0xff, sizeof wc->masks.nw_ttl);
- memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
- memset(&wc->masks.nw_frag, 0xff, sizeof wc->masks.nw_frag);
+static void
+commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow,
+ struct ofpbuf *odp_actions, struct flow_wildcards *wc,
+ bool use_masked)
+{
+ struct ovs_key_ipv6 key, mask, base;
- base->ipv6_src = flow->ipv6_src;
- memcpy(&ipv6_key.ipv6_src, &base->ipv6_src, sizeof(ipv6_key.ipv6_src));
- base->ipv6_dst = flow->ipv6_dst;
- memcpy(&ipv6_key.ipv6_dst, &base->ipv6_dst, sizeof(ipv6_key.ipv6_dst));
+ /* Check that nw_proto and nw_frag remain unchanged. */
+ ovs_assert(flow->nw_proto == base_flow->nw_proto &&
+ flow->nw_frag == base_flow->nw_frag);
- ipv6_key.ipv6_label = base->ipv6_label = flow->ipv6_label;
- ipv6_key.ipv6_tclass = base->nw_tos = flow->nw_tos;
- ipv6_key.ipv6_hlimit = base->nw_ttl = flow->nw_ttl;
- ipv6_key.ipv6_proto = base->nw_proto;
- ipv6_key.ipv6_frag = ovs_to_odp_frag(base->nw_frag);
+ get_ipv6_key(flow, &key);
+ get_ipv6_key(base_flow, &base);
+ get_ipv6_key(&wc->masks, &mask);
+ mask.ipv6_proto = 0; /* Not writeable. */
+ mask.ipv6_frag = 0; /* Not writable. */
- commit_set_action(odp_actions, OVS_KEY_ATTR_IPV6,
- &ipv6_key, sizeof(ipv6_key));
+ if (commit(OVS_KEY_ATTR_IPV6, use_masked, &key, &base, &mask, sizeof key,
+ odp_actions)) {
+ put_ipv6_key(&base, base_flow);
+ if (mask.ipv6_proto != 0) { /* Mask was changed by commit(). */
+ put_ipv6_key(&mask, &wc->masks);
+ }
+ }
}
-static enum slow_path_reason
-commit_set_arp_action(const struct flow *flow, struct flow *base,
- struct ofpbuf *odp_actions, struct flow_wildcards *wc)
+static void
+get_arp_key(const struct flow *flow, struct ovs_key_arp *arp)
{
- struct ovs_key_arp arp_key;
+ /* ARP key has padding, clear it. */
+ memset(arp, 0, sizeof *arp);
- if (base->nw_src == flow->nw_src &&
- base->nw_dst == flow->nw_dst &&
- base->nw_proto == flow->nw_proto &&
- eth_addr_equals(base->arp_sha, flow->arp_sha) &&
- eth_addr_equals(base->arp_tha, flow->arp_tha)) {
- return 0;
- }
-
- memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
- memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
- memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
- memset(&wc->masks.arp_sha, 0xff, sizeof wc->masks.arp_sha);
- memset(&wc->masks.arp_tha, 0xff, sizeof wc->masks.arp_tha);
+ arp->arp_sip = flow->nw_src;
+ arp->arp_tip = flow->nw_dst;
+ arp->arp_op = htons(flow->nw_proto);
+ memcpy(arp->arp_sha, flow->arp_sha, ETH_ADDR_LEN);
+ memcpy(arp->arp_tha, flow->arp_tha, ETH_ADDR_LEN);
+}
- base->nw_src = flow->nw_src;
- base->nw_dst = flow->nw_dst;
- base->nw_proto = flow->nw_proto;
- memcpy(base->arp_sha, flow->arp_sha, ETH_ADDR_LEN);
- memcpy(base->arp_tha, flow->arp_tha, ETH_ADDR_LEN);
+static void
+put_arp_key(const struct ovs_key_arp *arp, struct flow *flow)
+{
+ flow->nw_src = arp->arp_sip;
+ flow->nw_dst = arp->arp_tip;
+ flow->nw_proto = ntohs(arp->arp_op);
+ memcpy(flow->arp_sha, arp->arp_sha, ETH_ADDR_LEN);
+ memcpy(flow->arp_tha, arp->arp_tha, ETH_ADDR_LEN);
+}
- arp_key.arp_sip = base->nw_src;
- arp_key.arp_tip = base->nw_dst;
- arp_key.arp_op = htons(base->nw_proto);
- memcpy(arp_key.arp_sha, flow->arp_sha, ETH_ADDR_LEN);
- memcpy(arp_key.arp_tha, flow->arp_tha, ETH_ADDR_LEN);
+static enum slow_path_reason
+commit_set_arp_action(const struct flow *flow, struct flow *base_flow,
+ struct ofpbuf *odp_actions, struct flow_wildcards *wc)
+{
+ struct ovs_key_arp key, mask, base;
- commit_set_action(odp_actions, OVS_KEY_ATTR_ARP, &arp_key, sizeof arp_key);
+ get_arp_key(flow, &key);
+ get_arp_key(base_flow, &base);
+ get_arp_key(&wc->masks, &mask);
- return SLOW_ACTION;
+ if (commit(OVS_KEY_ATTR_ARP, true, &key, &base, &mask, sizeof key,
+ odp_actions)) {
+ put_arp_key(&base, base_flow);
+ put_arp_key(&mask, &wc->masks);
+ return SLOW_ACTION;
+ }
+ return 0;
}
static enum slow_path_reason
commit_set_nw_action(const struct flow *flow, struct flow *base,
- struct ofpbuf *odp_actions, struct flow_wildcards *wc)
+ struct ofpbuf *odp_actions, struct flow_wildcards *wc,
+ bool use_masked)
{
/* Check if 'flow' really has an L3 header. */
if (!flow->nw_proto) {
@@ -3794,11 +3886,11 @@ commit_set_nw_action(const struct flow *flow, struct flow *base,
switch (ntohs(base->dl_type)) {
case ETH_TYPE_IP:
- commit_set_ipv4_action(flow, base, odp_actions, wc);
+ commit_set_ipv4_action(flow, base, odp_actions, wc, use_masked);
break;
case ETH_TYPE_IPV6:
- commit_set_ipv6_action(flow, base, odp_actions, wc);
+ commit_set_ipv6_action(flow, base, odp_actions, wc, use_masked);
break;
case ETH_TYPE_ARP:
@@ -3808,84 +3900,98 @@ commit_set_nw_action(const struct flow *flow, struct flow *base,
return 0;
}
+/* TCP, UDP, and SCTP keys have the same layout. */
+BUILD_ASSERT_DECL(sizeof(struct ovs_key_tcp) == sizeof(struct ovs_key_udp) &&
+ sizeof(struct ovs_key_tcp) == sizeof(struct ovs_key_sctp));
+
static void
-commit_set_port_action(const struct flow *flow, struct flow *base,
- struct ofpbuf *odp_actions, struct flow_wildcards *wc)
+get_tp_key(const struct flow *flow, struct ovs_key_tcp *tp)
{
+ tp->tcp_src = flow->tp_src;
+ tp->tcp_dst = flow->tp_dst;
+}
+
+static void
+put_tp_key(const struct ovs_key_tcp *tp, struct flow *flow)
+{
+ flow->tp_src = tp->tcp_src;
+ flow->tp_dst = tp->tcp_dst;
+}
+
+static void
+commit_set_port_action(const struct flow *flow, struct flow *base_flow,
+ struct ofpbuf *odp_actions, struct flow_wildcards *wc,
+ bool use_masked)
+{
+ enum ovs_key_attr key_type;
+ struct ovs_key_tcp key, mask, base; /* Used for UDP and SCTP, too. */
+
/* Check if 'flow' really has an L3 header. */
if (!flow->nw_proto) {
return;
}
- if (!is_ip_any(base) || (!base->tp_src && !base->tp_dst)) {
+ if (!is_ip_any(base_flow)) {
return;
}
- if (base->tp_src == flow->tp_src &&
- base->tp_dst == flow->tp_dst) {
- return;
- }
-
- memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
- memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
-
if (flow->nw_proto == IPPROTO_TCP) {
- struct ovs_key_tcp port_key;
-
- port_key.tcp_src = base->tp_src = flow->tp_src;
- port_key.tcp_dst = base->tp_dst = flow->tp_dst;
-
- commit_set_action(odp_actions, OVS_KEY_ATTR_TCP,
- &port_key, sizeof(port_key));
-
+ key_type = OVS_KEY_ATTR_TCP;
} else if (flow->nw_proto == IPPROTO_UDP) {
- struct ovs_key_udp port_key;
-
- port_key.udp_src = base->tp_src = flow->tp_src;
- port_key.udp_dst = base->tp_dst = flow->tp_dst;
-
- commit_set_action(odp_actions, OVS_KEY_ATTR_UDP,
- &port_key, sizeof(port_key));
+ key_type = OVS_KEY_ATTR_UDP;
} else if (flow->nw_proto == IPPROTO_SCTP) {
- struct ovs_key_sctp port_key;
+ key_type = OVS_KEY_ATTR_SCTP;
+ } else {
+ return;
+ }
- port_key.sctp_src = base->tp_src = flow->tp_src;
- port_key.sctp_dst = base->tp_dst = flow->tp_dst;
+ get_tp_key(flow, &key);
+ get_tp_key(base_flow, &base);
+ get_tp_key(&wc->masks, &mask);
- commit_set_action(odp_actions, OVS_KEY_ATTR_SCTP,
- &port_key, sizeof(port_key));
+ if (commit(key_type, use_masked, &key, &base, &mask, sizeof key,
+ odp_actions)) {
+ put_tp_key(&base, base_flow);
+ put_tp_key(&mask, &wc->masks);
}
}
static void
-commit_set_priority_action(const struct flow *flow, struct flow *base,
+commit_set_priority_action(const struct flow *flow, struct flow *base_flow,
struct ofpbuf *odp_actions,
- struct flow_wildcards *wc)
+ struct flow_wildcards *wc,
+ bool use_masked)
{
- if (base->skb_priority == flow->skb_priority) {
- return;
- }
+ ovs_be32 key, mask, base;
- memset(&wc->masks.skb_priority, 0xff, sizeof wc->masks.skb_priority);
- base->skb_priority = flow->skb_priority;
+ key = flow->skb_priority;
+ base = base_flow->skb_priority;
+ mask = wc->masks.skb_priority;
- commit_set_action(odp_actions, OVS_KEY_ATTR_PRIORITY,
- &base->skb_priority, sizeof(base->skb_priority));
+ if (commit(OVS_KEY_ATTR_PRIORITY, use_masked, &key, &base, &mask,
+ sizeof key, odp_actions)) {
+ base_flow->skb_priority = base;
+ wc->masks.skb_priority = mask;
+ }
}
static void
-commit_set_pkt_mark_action(const struct flow *flow, struct flow *base,
+commit_set_pkt_mark_action(const struct flow *flow, struct flow *base_flow,
struct ofpbuf *odp_actions,
- struct flow_wildcards *wc)
+ struct flow_wildcards *wc,
+ bool use_masked)
{
- if (base->pkt_mark == flow->pkt_mark) {
- return;
- }
+ ovs_be32 key, mask, base;
- memset(&wc->masks.pkt_mark, 0xff, sizeof wc->masks.pkt_mark);
- base->pkt_mark = flow->pkt_mark;
+ key = flow->pkt_mark;
+ base = base_flow->pkt_mark;
+ mask = wc->masks.pkt_mark;
- odp_put_pkt_mark_action(base->pkt_mark, odp_actions);
+ if (commit(OVS_KEY_ATTR_SKB_MARK, use_masked, &key, &base, &mask,
+ sizeof key, odp_actions)) {
+ base_flow->pkt_mark = base;
+ wc->masks.pkt_mark = mask;
+ }
}
/* If any of the flow key data that ODP actions can modify are different in
@@ -3899,17 +4005,18 @@ commit_set_pkt_mark_action(const struct flow *flow, struct flow *base,
* slow path, if there is one, otherwise 0. */
enum slow_path_reason
commit_odp_actions(const struct flow *flow, struct flow *base,
- struct ofpbuf *odp_actions, struct flow_wildcards *wc)
+ struct ofpbuf *odp_actions, struct flow_wildcards *wc,
+ bool use_masked)
{
enum slow_path_reason slow;
- commit_set_ether_addr_action(flow, base, odp_actions, wc);
- slow = commit_set_nw_action(flow, base, odp_actions, wc);
- commit_set_port_action(flow, base, odp_actions, wc);
+ commit_set_ether_addr_action(flow, base, odp_actions, wc, use_masked);
+ slow = commit_set_nw_action(flow, base, odp_actions, wc, use_masked);
+ commit_set_port_action(flow, base, odp_actions, wc, use_masked);
commit_mpls_action(flow, base, odp_actions, wc);
commit_vlan_action(flow->vlan_tci, base, odp_actions, wc);
- commit_set_priority_action(flow, base, odp_actions, wc);
- commit_set_pkt_mark_action(flow, base, odp_actions, wc);
+ commit_set_priority_action(flow, base, odp_actions, wc, use_masked);
+ commit_set_pkt_mark_action(flow, base, odp_actions, wc, use_masked);
return slow;
}
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 458b813..11b54dd 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -197,7 +197,8 @@ void commit_masked_set_action(struct ofpbuf *odp_actions,
enum slow_path_reason commit_odp_actions(const struct flow *,
struct flow *base,
struct ofpbuf *odp_actions,
- struct flow_wildcards *wc);
+ struct flow_wildcards *wc,
+ bool use_masked);
/* ofproto-dpif interface.
*
@@ -252,7 +253,5 @@ size_t odp_put_userspace_action(uint32_t pid,
struct ofpbuf *odp_actions);
void odp_put_tunnel_action(const struct flow_tnl *tunnel,
struct ofpbuf *odp_actions);
-void odp_put_pkt_mark_action(const uint32_t pkt_mark,
- struct ofpbuf *odp_actions);
#endif /* odp-util.h */
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 02b9538..c79f105 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2551,7 +2551,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
if (out_port != ODPP_NONE) {
ctx->xout->slow |= commit_odp_actions(flow, &ctx->base_flow,
ctx->xout->odp_actions,
- &ctx->xout->wc);
+ &ctx->xout->wc,
+ ctx->xbridge->masked_set_action);
if (ctx->use_recirc) {
struct ovs_action_hash *act_hash;
@@ -2941,7 +2942,8 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow,
ctx->xout->odp_actions,
- &ctx->xout->wc);
+ &ctx->xout->wc,
+ ctx->xbridge->masked_set_action);
odp_execute_actions(NULL, &packet, 1, false, &md,
ofpbuf_data(ctx->xout->odp_actions),
@@ -3037,7 +3039,8 @@ compose_recirculate_action(struct xlate_ctx *ctx,
ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow,
ctx->xout->odp_actions,
- &ctx->xout->wc);
+ &ctx->xout->wc,
+ ctx->xbridge->masked_set_action);
nl_msg_put_u32(ctx->xout->odp_actions, OVS_ACTION_ATTR_RECIRC, id);
}
@@ -3054,7 +3057,8 @@ compose_mpls_push_action(struct xlate_ctx *ctx, struct ofpact_push_mpls *mpls)
if (!n) {
ctx->xout->slow |= commit_odp_actions(flow, &ctx->base_flow,
ctx->xout->odp_actions,
- &ctx->xout->wc);
+ &ctx->xout->wc,
+ ctx->xbridge->masked_set_action);
} else if (n >= FLOW_MAX_MPLS_LABELS) {
if (ctx->xin->packet != NULL) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
@@ -3414,7 +3418,8 @@ xlate_sample_action(struct xlate_ctx *ctx,
ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow,
ctx->xout->odp_actions,
- &ctx->xout->wc);
+ &ctx->xout->wc,
+ ctx->xbridge->masked_set_action);
compose_flow_sample_cookie(os->probability, os->collector_set_id,
os->obs_domain_id, os->obs_point_id, &cookie);
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 1cd9d40..1f0ac0f 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -192,8 +192,8 @@ table=2 ip actions=set_field:192.168.3.91->ip_src,output(11)
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,icmp,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=128
-Datapath actions: 10,set(ipv4(src=192.168.3.91,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no)),11,set(ipv4(src=192.168.3.90,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no)),13
+ [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
+Datapath actions: 10,set(ipv4(src=192.168.3.91)),11,set(ipv4(src=192.168.3.90)),13
])
OVS_VSWITCHD_STOP
AT_CLEANUP
@@ -208,8 +208,8 @@ table=1 tcp actions=set_field:91->tp_src,output(11),clear_actions
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=9'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,tcp,in_port=1,nw_frag=no,tp_src=8,tp_dst=9
-Datapath actions: 10,set(tcp(src=91,dst=9)),11
+ [Megaflow: recirc_id=0,skb_priority=0,tcp,in_port=1,nw_frag=no,tp_src=8
+Datapath actions: 10,set(tcp(src=91)),11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
@@ -231,9 +231,11 @@ ADD_OF_PORTS([br0], [1], [10], [11])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=all,bucket=output:10,set_field:192.168.3.90->ip_src,bucket=output:11'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=group:1234'])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
+# Must match on the source address to be able to restore it's value for
+# the second bucket
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,icmp,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=128
-Datapath actions: set(ipv4(src=192.168.3.90,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no)),10,set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no)),11
+ [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
+Datapath actions: set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
@@ -256,9 +258,11 @@ ADD_OF_PORTS([br0], [1], [10], [11])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=all,bucket=output:10,set_field:192.168.3.90->ip_src,bucket=output:11'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=write_actions(group:1234)'])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
+# Must match on the source address to be able to restore it's value for
+# the third bucket
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,icmp,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=128
-Datapath actions: set(ipv4(src=192.168.3.90,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no)),10,set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no)),11
+ [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
+Datapath actions: set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
@@ -438,8 +442,8 @@ AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=all,bucket=o
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=write_actions(load:0xffffffff->NXM_NX_REG1[[]],move:NXM_NX_REG1[[]]->NXM_NX_REG2[[]],group:1234)'])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,icmp,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=128
-Datapath actions: set(ipv4(src=255.255.255.255,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no)),10,set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no)),11
+ [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
+Datapath actions: set(ipv4(src=255.255.255.255)),10,set(ipv4(src=192.168.0.1)),11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
@@ -514,20 +518,20 @@ table=1 in_port=1 action=dec_ttl,output:3
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=111,tos=0,ttl=2,frag=no)' -generate], [0], [stdout])
AT_CHECK([tail -4 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=111,nw_tos=0,nw_ecn=0,nw_ttl=2
-Datapath actions: set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=111,tos=0,ttl=1,frag=no)),2,4
+ [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=1,nw_ttl=2,nw_frag=no
+Datapath actions: set(ipv4(ttl=1)),2,4
This flow is handled by the userspace slow path because it:
- Sends "packet-in" messages to the OpenFlow controller.
])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=111,tos=0,ttl=3,frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=111,nw_tos=0,nw_ecn=0,nw_ttl=3
-Datapath actions: set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=111,tos=0,ttl=2,frag=no)),2,set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=111,tos=0,ttl=1,frag=no)),3,4
+ [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=1,nw_ttl=3,nw_frag=no
+Datapath actions: set(ipv4(ttl=2)),2,set(ipv4(ttl=1)),3,4
])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x86dd),ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=128,frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,ipv6,in_port=1,ipv6_src=::1,ipv6_dst=::2,ipv6_label=0x00000,nw_proto=10,nw_tos=112,nw_ecn=0,nw_ttl=128
-Datapath actions: set(ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=127,frag=no)),2,set(ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=126,frag=no)),3,4
+ [Megaflow: recirc_id=0,skb_priority=0,ipv6,in_port=1,nw_ttl=128,nw_frag=no
+Datapath actions: set(ipv6(hlimit=127)),2,set(ipv6(hlimit=126)),3,4
])
AT_CAPTURE_FILE([ofctl_monitor.log])
@@ -624,16 +628,15 @@ AT_CHECK([ovs-vsctl -- \
--id=@q2 create Queue dscp=2], [0], [ignore])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(9),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0xff,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,icmp,in_port=9,nw_src=1.1.1.1,nw_dst=2.2.2.2,nw_tos=252,nw_ecn=3,nw_ttl=128
+ [Megaflow: recirc_id=0,skb_priority=0,ip,in_port=9,nw_tos=252,nw_frag=no
Datapath actions: dnl
100,dnl
-set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0x7,ttl=128,frag=no)),set(skb_priority(0x1)),1,dnl
-set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0xb,ttl=128,frag=no)),set(skb_priority(0x2)),1,dnl
+set(ipv4(tos=0x4/0xfc)),set(skb_priority(0x1)),1,dnl
+set(ipv4(tos=0x8/0xfc)),set(skb_priority(0x2)),1,dnl
1,dnl
-set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0x7,ttl=128,frag=no)),set(skb_priority(0x1)),1,dnl
-set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0xff,ttl=128,frag=no)),set(skb_priority(0)),1,dnl
-set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0x3,ttl=128,frag=no)),1,dnl
-100
+set(ipv4(tos=0x4/0xfc)),set(skb_priority(0x1)),1,dnl
+set(ipv4(tos=0xfc/0xfc)),set(skb_priority(0)),1,dnl
+set(ipv4(tos=0/0xfc)),1,100
])
OVS_VSWITCHD_STOP
AT_CLEANUP
@@ -5267,7 +5270,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:
AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
sleep 1
AT_CHECK([cat ovs-vswitchd.log | FILTER_FLOW_INSTALL | STRIP_XOUT], [0], [dnl
-recirc_id=0,skb_priority=0,icmp,in_port=1,nw_src=10.0.0.4,nw_dst=10.0.0.3,nw_tos=0,nw_ecn=0,nw_ttl=64, actions: <del>
+recirc_id=0,skb_priority=0,icmp,in_port=1,nw_src=10.0.0.4,nw_ttl=64,nw_frag=no, actions: <del>
recirc_id=0,skb_priority=0,ip,in_port=1,nw_src=10.0.0.2/0.0.0.2,nw_frag=no, actions: <del>
])
OVS_VSWITCHD_STOP
@@ -5284,19 +5287,12 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
sleep 1
-dnl The megaflows do not match the same fields, since the first packet
-dnl is essentially a no-op. (The new destination MAC is the same as the
-dnl original.) The ofproto-dpif library un-wildcards the destination MAC
-dnl so that a packet that doesn't need its MAC address changed doesn't
-dnl hide one that does. Since the first entry doesn't need to change,
-dnl only the destination MAC address is matched (as decided by
-dnl ofproto-dpif). The second entry actually updates the destination
-dnl MAC, so both the source and destination MAC addresses are
-dnl un-wildcarded, since the ODP commit functions update both the source
-dnl and destination MAC addresses.
+dnl The first packet is essentially a no-op, as the new destination MAC is the
+dnl same as the original. The second entry actually updates the destination
+dnl MAC.
AT_CHECK([cat ovs-vswitchd.log | FILTER_FLOW_INSTALL | STRIP_USED], [0], [dnl
recirc_id=0,skb_priority=0,ip,in_port=1,dl_dst=50:54:00:00:00:0a,nw_frag=no, actions:2
-recirc_id=0,skb_priority=0,ip,in_port=1,dl_src=50:54:00:00:00:0b,dl_dst=50:54:00:00:00:0c,nw_frag=no, actions:set(eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0a)),2
+recirc_id=0,skb_priority=0,ip,in_port=1,dl_dst=50:54:00:00:00:0c,nw_frag=no, actions:set(eth(dst=50:54:00:00:00:0a)),2
])
OVS_VSWITCHD_STOP
AT_CLEANUP
diff --git a/tests/tunnel.at b/tests/tunnel.at
index 8343e55..be1269d 100644
--- a/tests/tunnel.at
+++ b/tests/tunnel.at
@@ -88,15 +88,15 @@ Datapath actions: 2
dnl Tunnel CE and encapsulated packet ECT(1)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0x0,src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,tp_src=0,tp_dst=0,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=1,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: pkt_mark=0,recirc_id=0,skb_priority=0,tcp,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=1,nw_ttl=64
-Datapath actions: set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0x3,ttl=64,frag=no)),2
+ [Megaflow: pkt_mark=0,recirc_id=0,skb_priority=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,,in_port=1,nw_ecn=1,nw_frag=no
+Datapath actions: set(ipv4(tos=0x3/0x3)),2
])
dnl Tunnel CE and encapsulated packet ECT(2)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0x0,src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,tp_src=0,tp_dst=0,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=2,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: pkt_mark=0,recirc_id=0,skb_priority=0,tcp,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=2,nw_ttl=64
-Datapath actions: set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0x3,ttl=64,frag=no)),2
+ [Megaflow: pkt_mark=0,recirc_id=0,skb_priority=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,,in_port=1,nw_ecn=2,nw_frag=no
+Datapath actions: set(ipv4(tos=0x3/0x3)),2
])
dnl Tunnel CE and encapsulated packet Non-ECT
--
1.7.10.4
More information about the dev
mailing list