diff options
author | Aaron Conole <aconole@redhat.com> | 2023-03-31 17:17:27 -0400 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2023-04-06 13:17:15 +0200 |
commit | 9d840923d32124fe427de76e8234c49d64e4bb77 (patch) | |
tree | 230e3688a4f4b772d916f98effd60adc81d76df9 /lib | |
parent | e41bdb17613ba2df284f0f6aed98dbb1c2e2e081 (diff) | |
download | openvswitch-9d840923d32124fe427de76e8234c49d64e4bb77.tar.gz |
ofproto-dpif-xlate: Always mask ip proto field.
The ofproto layer currently treats nw_proto field as overloaded to mean
both that a proper nw layer exists, as well as the value contained in
the header for the nw proto. However, this is incorrect behavior as
relevant standards permit that any value, including '0' should be treated
as a valid value.
Because of this overload, when the ofproto layer builds action list for
a packet with nw_proto of 0, it won't build the complete action list that
we expect to be built for the packet. That will cause a bad behavior
where all packets passing the datapath will fall into an incomplete
action set.
The fix here is to unwildcard nw_proto, allowing us to preserve setting
actions for protocols which we know have support for the actions we
program. This means that a traffic which contains nw_proto == 0 cannot
cause connectivity breakage with other traffic on the link.
Reported-by: David Marchand <dmarchand@redhat.com>
Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2134873
Acked-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Aaron Conole <aconole@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/meta-flow.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/meta-flow.c b/lib/meta-flow.c index c576ae620..474344194 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -3676,3 +3676,28 @@ mf_bitmap_not(struct mf_bitmap x) bitmap_not(x.bm, MFF_N_IDS); return x; } + +void +mf_set_mask_l3_prereqs(const struct mf_field *mf, const struct flow *fl, + struct flow_wildcards *wc) +{ + if (is_ip_any(fl) && + ((mf->id == MFF_IPV4_SRC) || + (mf->id == MFF_IPV4_DST) || + (mf->id == MFF_IPV6_SRC) || + (mf->id == MFF_IPV6_DST) || + (mf->id == MFF_IPV6_LABEL) || + (mf->id == MFF_IP_DSCP) || + (mf->id == MFF_IP_ECN) || + (mf->id == MFF_IP_TTL))) { + WC_MASK_FIELD(wc, nw_proto); + } else if ((fl->dl_type == htons(ETH_TYPE_ARP)) && + ((mf->id == MFF_ARP_OP) || + (mf->id == MFF_ARP_SHA) || + (mf->id == MFF_ARP_THA) || + (mf->id == MFF_ARP_SPA) || + (mf->id == MFF_ARP_TPA))) { + /* mask only the lower 8 bits. */ + wc->masks.nw_proto = 0xff; + } +} |