From: Jiri Benc <jbenc@redhat.com>
To: Jarno Rajahalme <jarno@ovn.org>
Cc: netdev@vger.kernel.org, pshelar@ovn.org, e@erig.me
Subject: Re: [PATCH v3 net-next 3/3] openvswitch: Fix skb->protocol for vlan frames.
Date: Wed, 30 Nov 2016 15:30:41 +0100 [thread overview]
Message-ID: <20161130153041.7a9590ef@griffin> (raw)
In-Reply-To: <1480462253-114713-3-git-send-email-jarno@ovn.org>
On Tue, 29 Nov 2016 15:30:53 -0800, Jarno Rajahalme wrote:
> Do not always set skb->protocol to be the ethertype of the L3 header.
> For a packet with non-accelerated VLAN tags skb->protocol needs to be
> the ethertype of the outermost non-accelerated VLAN ethertype.
Well, the current handling of skb->protocol matches what used to be the
handling of the kernel net stack before Jiri Pirko cleaned up the vlan
code.
I'm not opposed to changing this but I'm afraid it needs much deeper
review. Because with this in place, no core kernel functions that
depend on skb->protocol may be called from within openvswitch.
> @@ -361,6 +362,11 @@ static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key)
> if (res <= 0)
> return res;
>
> + /* If the outer vlan tag was accelerated, skb->protocol should
> + * refelect the inner vlan type. */
> + if (!eth_type_vlan(skb->protocol))
> + skb->protocol = key->eth.cvlan.tpid;
This should not depend on the current value in skb->protocol which
could be arbitrary at this point (from the point of view of how this
patch understands the skb->protocol values). It's easy to fix, though -
just add a local bool variable tracking whether the skb->protocol has
been set.
> @@ -531,15 +544,16 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
> if (unlikely(parse_vlan(skb, key)))
> return -ENOMEM;
>
> - skb->protocol = parse_ethertype(skb);
> - if (unlikely(skb->protocol == htons(0)))
> + key->eth.type = parse_ethertype(skb);
> + if (unlikely(key->eth.type == htons(0)))
> return -ENOMEM;
>
> skb_reset_network_header(skb);
> __skb_push(skb, skb->data - skb_mac_header(skb));
> }
> skb_reset_mac_len(skb);
> - key->eth.type = skb->protocol;
> + if (!eth_type_vlan(skb->protocol))
> + skb->protocol = key->eth.type;
This leaves key->eth.type undefined for key->mac_proto ==
MAC_PROTO_NONE.
Plus the same problem as above with unknown value of skb->protocol. But
this is more complicated here, as skb->protocol may be either
uninitialized at this point or already initialized by parse_vlan.
>
> /* Network layer. */
> if (key->eth.type == htons(ETH_P_IP)) {
> @@ -800,29 +814,15 @@ int ovs_flow_key_extract_userspace(struct net *net, const struct nlattr *attr,
> if (err)
> return err;
>
> - if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) {
> - /* key_extract assumes that skb->protocol is set-up for
> - * layer 3 packets which is the case for other callers,
> - * in particular packets recieved from the network stack.
> - * Here the correct value can be set from the metadata
> - * extracted above.
> - */
> - skb->protocol = key->eth.type;
> - } else {
> - struct ethhdr *eth;
> -
> - skb_reset_mac_header(skb);
> - eth = eth_hdr(skb);
> -
> - /* Normally, setting the skb 'protocol' field would be
> - * handled by a call to eth_type_trans(), but it assumes
> - * there's a sending device, which we may not have.
> - */
> - if (eth_proto_is_802_3(eth->h_proto))
> - skb->protocol = eth->h_proto;
> - else
> - skb->protocol = htons(ETH_P_802_2);
> - }
> + /* key_extract assumes that skb->protocol is set-up for
> + * layer 3 packets which is the case for other callers,
> + * in particular packets recieved from the network stack.
> + * Here the correct value can be set from the metadata
> + * extracted above. For layer 2 packets we initialize
> + * skb->protocol to zero and set it in key_extract() while
> + * parsing the L2 headers.
> + */
> + skb->protocol = key->eth.type;
>
> return key_extract(skb, key);
> }
Interesting. This hunk looks safe even without the rest of the patch.
You should fix the comment indentation, though.
Jiri
next prev parent reply other threads:[~2016-11-30 14:30 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-29 23:30 [PATCH v3 net-next 1/3] openvswitch: Add a missing break statement Jarno Rajahalme
2016-11-29 23:30 ` [PATCH v3 net-next 2/3] openvswitch: Use is_skb_forwardable() for length check Jarno Rajahalme
2016-11-30 7:23 ` Pravin Shelar
2016-11-30 13:51 ` Jiri Benc
2016-11-30 21:30 ` Jarno Rajahalme
2016-12-01 19:50 ` Pravin Shelar
2016-12-02 9:25 ` Jiri Benc
2016-12-05 0:22 ` Pravin Shelar
2016-12-08 20:50 ` Eric Garver
2016-12-09 8:49 ` Jiri Benc
2016-11-29 23:30 ` [PATCH v3 net-next 3/3] openvswitch: Fix skb->protocol for vlan frames Jarno Rajahalme
2016-11-30 7:34 ` Pravin Shelar
2016-11-30 14:30 ` Jiri Benc [this message]
2016-12-01 20:31 ` Pravin Shelar
2016-12-02 9:42 ` Jiri Benc
2016-12-02 9:49 ` Jiri Benc
2016-12-05 0:58 ` Pravin Shelar
2016-12-14 5:07 ` [PATCH v3 net-next 1/3] openvswitch: Add a missing break statement Pravin Shelar
2016-12-20 1:07 ` Jarno Rajahalme
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161130153041.7a9590ef@griffin \
--to=jbenc@redhat.com \
--cc=e@erig.me \
--cc=jarno@ovn.org \
--cc=netdev@vger.kernel.org \
--cc=pshelar@ovn.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox