While sending packet over tunnel it can get segmented or reallocated. In that case we loose OVS_CB(). But some tunneling protocol implementation needs OVS_CB(), e.g. vxlan needs OVS_CB()->flow which leads to kernel panic. Following patch set flow before calling tnl_ops->build_header() and fixes OVS_CB(skb)->tun_key access.
Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- datapath/tunnel.c | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-) diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 83d2c41..2ca3e9a 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -221,27 +221,29 @@ u16 ovs_tnl_get_src_port(struct sk_buff *skb) int ovs_tnl_send(struct vport *vport, struct sk_buff *skb) { struct tnl_vport *tnl_vport = tnl_vport_priv(vport); + struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->tun_key; + struct sw_flow *flow = OVS_CB(skb)->flow; struct rtable *rt; __be32 saddr; int sent_len = 0; int tunnel_hlen; - if (unlikely(!OVS_CB(skb)->tun_key)) + if (unlikely(!tun_key)) goto error_free; /* Route lookup */ saddr = OVS_CB(skb)->tun_key->ipv4_src; rt = find_route(ovs_dp_get_net(vport->dp), &saddr, - OVS_CB(skb)->tun_key->ipv4_dst, + tun_key->ipv4_dst, tnl_vport->tnl_ops->ipproto, - OVS_CB(skb)->tun_key->ipv4_tos, + tun_key->ipv4_tos, skb_get_mark(skb)); if (IS_ERR(rt)) goto error_free; /* Offloading */ - tunnel_hlen = tnl_vport->tnl_ops->hdr_len(OVS_CB(skb)->tun_key); + tunnel_hlen = tnl_vport->tnl_ops->hdr_len(tun_key); tunnel_hlen += sizeof(struct iphdr); skb = handle_offloads(skb, rt, tunnel_hlen); @@ -263,6 +265,7 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb) int err; skb->next = NULL; + OVS_CB(skb)->flow = flow; if (unlikely(vlan_deaccel_tag(skb))) goto next; @@ -285,11 +288,11 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb) iph->version = 4; iph->ihl = sizeof(struct iphdr) >> 2; iph->protocol = tnl_vport->tnl_ops->ipproto; - iph->daddr = OVS_CB(skb)->tun_key->ipv4_dst; + iph->daddr = tun_key->ipv4_dst; iph->saddr = saddr; - iph->tos = OVS_CB(skb)->tun_key->ipv4_tos; - iph->ttl = OVS_CB(skb)->tun_key->ipv4_ttl; - iph->frag_off = OVS_CB(skb)->tun_key->tun_flags & + iph->tos = tun_key->ipv4_tos; + iph->ttl = tun_key->ipv4_ttl; + iph->frag_off = tun_key->tun_flags & OVS_TNL_F_DONT_FRAGMENT ? htons(IP_DF) : 0; ip_select_ident(iph, &rt_dst(rt), NULL); -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev