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

Pravin Shelar pshelar at nicira.com
Wed Mar 25 21:52:34 UTC 2015


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