Thread (6 messages) 6 messages, 3 authors, 2014-05-21

Re: [PATCH v2.57] datapath: Add basic MPLS support to kernel

flat view

From: Simon Horman <horms@verge.net.au>
Date: 2014-05-20 10:48:22

Possibly related (same subject, not in this thread)

On Mon, May 19, 2014 at 06:34:05PM -0700, Jesse Gross wrote:
I have some miscellaneous comments on things that I noticed, all of
which are pretty small. I will probably have a few more tomorrow but
my hope is that we can get this in soon.

On Thu, May 15, 2014 at 4:07 PM, Simon Horman [off-list ref] wrote:
quoted
diff --git a/datapath/actions.c b/datapath/actions.c
index 603c7cb..7c3ae0c 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
+static int push_mpls(struct sk_buff *skb,
+                    const struct ovs_action_push_mpls *mpls)
+{
+       __be32 *new_mpls_lse;
+       struct ethhdr *hdr;
+
+       if (skb_cow_head(skb, MPLS_HLEN) < 0) {
+               kfree_skb(skb);
+               return -ENOMEM;
+       }
I think it would be better to not free the skb on error here - it
introduces an exception case in the call to push_mpls() that would be
otherwise handled if we didn't free it.
Thanks, I have fixed it up as you suggest.
When we set the EtherType at the bottom of the function, I don't think
that it is correct in the presence of VLAN tags because it will set
the outer EtherType.
I believe this comes back to the problem we have with tag ordering. A
problem which after the most recent discussion of this topic I planned to
kick into the long grass by only allowing push MPLS actions on packets with
a well defined tag order.

This is the purpose of the white list in ovs_nla_copy_actions__().  It is
supposed to only push MPLS actions for flows with an IPv4, IPv6, ARP, RARP
or MPLS ethtype.  However, I now think that the white list likely does not
work for VLAN packets as their flow's ethtype will be the inner-ethtype
(the one inside the VLAN tag) rather than a VLAN ethtype.

I'm unsure how you would like to handle this but one possibility would be
simply for push_mpls() to return an error if it is called on an skb with a
VLAN tag present or if the ethtype doesn't match a white list. Another is
to set the inner ethtype.
quoted
+static int pop_mpls(struct sk_buff *skb, const __be16 ethertype)
+{
+       struct ethhdr *hdr;
+       int err;
+
+       if (unlikely(skb->len < skb->mac_len + MPLS_HLEN))
+               return -EINVAL;
I don't think this check is necessary since we would have rejected
such packets at flow validation time.
Thanks, I have removed it.
quoted
+static int set_mpls(struct sk_buff *skb, const __be32 *mpls_lse)
+{
+       __be32 *stack = (__be32 *)mac_header_end(skb);
+       int err;
+
+       err = make_writable(skb, skb->mac_len + MPLS_HLEN);
+       if (unlikely(err))
+               return err;
+
+       if (skb->ip_summed == CHECKSUM_COMPLETE) {
+               __be32 diff[] = { ~(*stack), *mpls_lse };
+               skb->csum = ~csum_partial((char *)diff, sizeof(diff),
+                                         ~skb->csum);
+       }
Is it possible to use csum_replace4() to simplify this?
I'm not sure that it can be due to its use of csum_fold() and csum_unfold().
In particular I notice that inet_proto_csum_replace4() uses code
similar to the above rather than csum_replace4().
quoted
@@ -701,6 +815,8 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, bool recirc)
                goto out_loop;
        }

+       ovs_skb_init_inner_protocol(skb);
I think we talked about some time ago but it seems like this will get
reset by recirculation (although maybe it's unlikely that
recirculation will get used on output).
Thanks, I think that can be fixed as follows:

	if (!recirc)
		ovs_skb_init_inner_protocol(skb);
Also, maybe I'm missing something but I don't see where we actually
set the inner protocol.
Thanks, I noticed that too. I have added the following back into push_mpls(),
just before skb->protocol is updated.

	if (!ovs_skb_get_inner_protocol(skb))
		ovs_skb_set_inner_protocol(skb, skb->protocol);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help