[ovs-dev] [PATCH 2/2] datapath: Add basic MPLS support to kernel
Simon Horman
horms at verge.net.au
Tue Mar 19 01:22:12 UTC 2013
On Mon, Mar 18, 2013 at 05:45:52PM -0700, Jesse Gross wrote:
> On Mon, Mar 18, 2013 at 12:37 AM, Simon Horman <horms at verge.net.au> wrote:
> > Allow datapath to recognize and extract MPLS labels into flow keys
> > and execute actions which push, pop, and set labels on packets.
> >
> > Based heavily on work by Leo Alterman and Ravi K.
> >
> > Cc: Ravi K <rkerur at gmail.com>
> > Cc: Leo Alterman <lalterman at nicira.com>
> > Reviewed-by: Isaku Yamahata <yamahata at valinux.co.jp>
> > Signed-off-by: Simon Horman <horms at verge.net.au>
>
> I got a sparse warning (although I think it is just an annotation problem):
> CHECK /home/jgross/openvswitch/datapath/linux/datapath.c
> /home/jgross/openvswitch/datapath/linux/datapath.c:777:42: warning:
> incorrect type in assignment (different base types)
> /home/jgross/openvswitch/datapath/linux/datapath.c:777:42: expected
> restricted __be16 [assigned] [usertype] current_eth_type
> /home/jgross/openvswitch/datapath/linux/datapath.c:777:42: got unsigned int
Strange. I always check sparse. Clearly not very well.
> > diff --git a/datapath/actions.c b/datapath/actions.c
> > index 0dac658..f272e8d 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;
> > + int err;
> > +
> > + err = make_writable(skb, skb->mac_len + MPLS_HLEN);
> > + if (unlikely(err))
> > + return err;
> > +
> > + if (skb_cow_head(skb, MPLS_HLEN) < 0)
> > + return -ENOMEM;
>
> Why do we need both make_writable() and skb_cow_head()?
My mistake, I'll remove skb_cow_head().
>
> > diff --git a/datapath/datapath.c b/datapath/datapath.c
> > index a40ff47..fa0214b 100644
> > --- a/datapath/datapath.c
> > +++ b/datapath/datapath.c
> > @@ -593,8 +594,7 @@ static int validate_set(const struct nlattr *a,
> > return -EINVAL;
> >
> > if (key_type > OVS_KEY_ATTR_MAX ||
> > - (ovs_key_lens[key_type] != nla_len(ovs_key) &&
> > - ovs_key_lens[key_type] != -1))
> > + ovs_flow_verify_key_len(key_type, ovs_key))
> > return -EINVAL;
>
> I think we could move the check for key_type > OVS_KEY_ATTR_MAX into
> ovs_flow_verify_key_len() as well.
Sure, will do.
> I don't think that we want to allow an array of MPLS labels at this
> point in time, since we'll just silently ignore the ones that we don't
> expect, which isn't good. However, we should define the interface in
> such a way that anticipates this extension. For example, I don't
> think that it's good to call the struct member mpls_top_lse if it is
> potentially a stack of labels.
I'm not sure that I understand what you want the interface to look like.
Of course we can change the name of the struct member, to say mpls_lse.
But my understanding was that you simply wanted an array of these structs,
which is what I have implemented.
I could add a check to reject a flow if the number of elements is
greater than zero. That would avoid silently ignoring subsequent members
while providing an interface that allows them. But I sense that this
is not what you have in mind.
> > @@ -755,6 +763,19 @@ static int validate_and_copy_actions(const struct nlattr *attr,
> > return -EINVAL;
> > break;
> >
> > + case OVS_ACTION_ATTR_PUSH_MPLS: {
> > + const struct ovs_action_push_mpls *mpls = nla_data(a);
> > + if (!eth_p_mpls(mpls->mpls_ethertype))
> > + return -EINVAL;
> > + current_eth_type = mpls->mpls_ethertype;
> > + break;
> > + }
> > +
> > + case OVS_ACTION_ATTR_POP_MPLS:
> > + if (!eth_p_mpls(current_eth_type))
> > + return -EINVAL;
> > + current_eth_type = nla_get_u32(a);
>
> I don't think it is safe to assume that the provided EtherType is
> correct: it's possible that the packet is not long enough to actually
> contain that protocol. Since all length checking happens at flow
> extraction time, a later set could write off the end of the packet.
I'm curious to know why this problem doesn't also exist
for other set actions. For example set ipv4.
> I think we also need to handle the sample action more robustly as
> well: effectively right now we're validating the not-taken sample path
> but we should validate the other path as well.
>
> > @@ -1189,8 +1211,10 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
> > if (!a[OVS_FLOW_ATTR_KEY])
> > goto error;
> > error = ovs_flow_from_nlattrs(&key, &key_len, a[OVS_FLOW_ATTR_KEY]);
> > - if (error)
> > + if (error) {
> > + printk("%s: ovs_flow_from_nlattrs failed\n", __func__);
>
> We should try to keep debugging log messages out of the final code.
Sorry, I will remove that.
More information about the dev
mailing list