> @@ -3597,26 +3589,44 @@ 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) > + struct flow_wildcards *wc, > + bool use_masked) > { > - struct ovs_key_ethernet eth_key; > + struct ovs_key_ethernet key, mask; > + bool fully_masked; > > - if (eth_addr_equals(base->dl_src, flow->dl_src) && > - eth_addr_equals(base->dl_dst, flow->dl_dst)) { > + /* 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. */ > + if ((eth_addr_equals(flow->dl_src, base->dl_src) && > + eth_addr_equals(flow->dl_dst, base->dl_dst))) {
extra parens? > @@ -3719,93 +3729,155 @@ 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) > -{ > - struct ovs_key_ipv4 ipv4_key; > - > - 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) { > + struct ofpbuf *odp_actions, struct flow_wildcards *wc, > + bool use_masked) > +{ > + struct ovs_key_ipv4 key, mask; > + > + /* Check that non-masked bits are intact, and that nw_proto and nw_frag > + * remain unchanged. */ > + ovs_assert(!((flow->nw_src ^ base->nw_src) & ~wc->masks.nw_src) > + && !((flow->nw_dst ^ base->nw_dst) & ~wc->masks.nw_dst) > + && !((flow->nw_tos ^ base->nw_tos) & ~wc->masks.nw_tos) > + && !((flow->nw_ttl ^ base->nw_ttl) & ~wc->masks.nw_ttl) > + && flow->nw_proto == base->nw_proto > + && flow->nw_frag == base->nw_frag); push_mpls can change nw_proto and nw_frag. > +/* 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) > + struct ofpbuf *odp_actions, struct flow_wildcards *wc, > + bool use_masked) > { > - if (!is_ip_any(base) || (!base->tp_src && !base->tp_dst)) { > - return; > - } > + enum ovs_key_attr key_type; > + struct ovs_key_tcp key, mask; /* Used for UDP and SCTP, too. */ > + > + ovs_assert(!((flow->tp_src ^ base->tp_src) & ~wc->masks.tp_src) && > + !((flow->tp_dst ^ base->tp_dst) & ~wc->masks.tp_dst)); push_mpls can change these without setting masks. IMO compose_mpls_push_action should update base flow as well to avoid confusing these commit routines. YAMAMOTO Takashi _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev