[ovs-discuss] User space tunneling doesn't support setting tunnel key (e.g. tunnel id for VxLAN) by flow

Li, Ricky ricky.li at intel.com
Thu Mar 26 13:27:14 UTC 2015


Hi,

I have sent the patch to dev at openvswitch.org, the title of the mail:
[PATCH] Bug fixed: User space tunneling doesn't support setting tunnel key by flow

Regards,
Ricky

-----Original Message-----
From: Pravin Shelar [mailto:pshelar at nicira.com] 
Sent: Thursday, March 26, 2015 5:53 AM
To: Li, Ricky
Cc: discuss at openvswitch.org
Subject: Re: [ovs-discuss] User space tunneling doesn't support setting tunnel key (e.g. tunnel id for VxLAN) by flow

On Tue, Mar 24, 2015 at 7:23 PM, Li, Ricky <ricky.li at intel.com> wrote:
> Hi,
>
>
>
> I tried to test user space tunneling according to this guide:
>
> README-native-tunneling.md
>
>
>
> Everything works in this guide, but when I tried to specify the tunnel 
> ID with flow as below, there is a problem:
>
> ovs-vsctl add-port int-br vxlan0 -- set interface vxlan0 type=vxlan
> options:remote_ip=172.168.1.2 options:out_key=flow
>
>
>
> I try to add an option: out_key=flow to make OVS specify the tunnel ID 
> by flow as below:
>
> ovs-ofctl add-flow int-br “in_port=LOCAL, icmp, actions=set_tunnel:3,
> output:1”     (1 is the port# of vxlan0)
>
>
>
> But this setup doesn’t work, because the output tunnel ID is still 0 
> (the default tunnel ID) but not 3.
>
> I also tried the same flow with kernel space Datapath and it works, 
> the tunnel ID will be changed by flow.
>
>
>
> Then I looked up the source code related to user space tunneling and I 
> can find when OVS tries to encapsulate the tunnel header, it will 
> firstly try to build the tunnel header:
>
>
>
> In ofproto-dpif-xlate.c: compose_output_action__()
>
>>
>             if (tnl_push_pop_send) {
>
>                 build_tunnel_send(ctx, xport, flow, odp_port);
>
>                 flow->tunnel = flow_tnl; /* Restore tunnel metadata */
>
>             }
>
>>
> tnl_push_pop_send is the flag for user space tunneling, and it will 
> try to build tunnel header in lib/tunnel.c:
>
>
>
>
>
> In tunnel.c: tnl_port_build_header()
>
>
>
> int
>
> tnl_port_build_header(const struct ofport_dpif *ofport,
>
>                       const struct flow *tnl_flow,
>
>                       uint8_t dmac[ETH_ADDR_LEN],
>
>                       uint8_t smac[ETH_ADDR_LEN],
>
>                       ovs_be32 ip_src, struct ovs_action_push_tnl 
> *data)
>
> {
>
>>
> res = netdev_build_header(tnl_port->netdev, data);
>
>>
> }
>
>
>
> We can find it calls the Netdev API “netdev_build_header” to build the 
> tunnel header. If the tunnel ID is set by flow, it should be saved in 
> the object “tnl_flow” (tnl_flow->tunnel->tun_id), but it’s not passed 
> into the Netdev API.
>
>
>
> In netdev-vport.c: netdev_vxlan_build_header()
>
>>
> put_16aligned_be32(&vxh->vx_vni, htonl(ntohll(tnl_cfg->out_key) << 
> 8));
>
>>
>
>
> The tunnel id (VNI) is directly set by tunnel port configuration 
> (tnl_cfg), then I think the “options:out_key=flow” will never works because of this?
> The tunnel ID will always set with the tunnel configuration when we 
> initiate it.
>
>
>
> One suggestion is to add one more input for the Netdev API:
>
> Int netdev_build_header(const struct netdev *netdev, struct 
> ovs_action_push_tnl *data, const struct flow *tnl_flow)
>
>
>
> The new input “const struct flow *tnl_flow” can be passed to the 
> callback for building tunnel header, e.g. for VxLAN:
>
>>
> put_16aligned_be32(&vxh->vx_vni, htonl(ntohll(tnl_flow->tunnel.tun_id) 
> << 8));
>
>>
>
>
> Similar changes can be made for other tunnel ports like GRE. This 
> patch can work on my side with some simple experiments. I want to 
> check if my understanding is right, and hope for any advices and inputs.
>
>
>
Your analysis looks correct. Can you send patch and test case (tests/tunnel-push-pop.at). So that it does not break in future.

Thanks.


More information about the discuss mailing list