}
 
 #if IS_ENABLED(CONFIG_IPV6)
-static int vxlan6_xmit_skb(struct dst_entry *dst, struct sk_buff *skb,
+static int vxlan6_xmit_skb(struct dst_entry *dst, struct sock *sk,
+                          struct sk_buff *skb,
                           struct net_device *dev, struct in6_addr *saddr,
                           struct in6_addr *daddr, __u8 prio, __u8 ttl,
                           __be16 src_port, __be16 dst_port,
 
        skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
-       udp_tunnel6_xmit_skb(dst, skb, dev, saddr, daddr, prio,
+       udp_tunnel6_xmit_skb(dst, sk, skb, dev, saddr, daddr, prio,
                             ttl, src_port, dst_port,
                             !!(vxflags & VXLAN_F_UDP_ZERO_CSUM6_TX));
        return 0;
 }
 #endif
 
-int vxlan_xmit_skb(struct rtable *rt, struct sk_buff *skb,
+int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
                   __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
                   __be16 src_port, __be16 dst_port,
                   struct vxlan_metadata *md, bool xnet, u32 vxflags)
 
        skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
-       return udp_tunnel_xmit_skb(rt, skb, src, dst, tos,
+       return udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos,
                                   ttl, df, src_port, dst_port, xnet,
                                   !(vxflags & VXLAN_F_UDP_CSUM));
 }
                           struct vxlan_rdst *rdst, bool did_rsc)
 {
        struct vxlan_dev *vxlan = netdev_priv(dev);
+       struct sock *sk = vxlan->vn_sock->sock->sk;
        struct rtable *rt = NULL;
        const struct iphdr *old_iph;
        struct flowi4 fl4;
                md.vni = htonl(vni << 8);
                md.gbp = skb->mark;
 
-               err = vxlan_xmit_skb(rt, skb, fl4.saddr,
+               err = vxlan_xmit_skb(rt, sk, skb, fl4.saddr,
                                     dst->sin.sin_addr.s_addr, tos, ttl, df,
                                     src_port, dst_port, &md,
                                     !net_eq(vxlan->net, dev_net(vxlan->dev)),
                md.vni = htonl(vni << 8);
                md.gbp = skb->mark;
 
-               err = vxlan6_xmit_skb(ndst, skb, dev, &fl6.saddr, &fl6.daddr,
+               err = vxlan6_xmit_skb(ndst, sk, skb, dev, &fl6.saddr, &fl6.daddr,
                                      0, ttl, src_port, dst_port, &md,
                                      !net_eq(vxlan->net, dev_net(vxlan->dev)),
                                      vxlan->flags);
 
 struct net *ip6_tnl_get_link_net(const struct net_device *dev);
 int ip6_tnl_get_iflink(const struct net_device *dev);
 
-static inline void ip6tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
+static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
+                                 struct net_device *dev)
 {
        struct net_device_stats *stats = &dev->stats;
        int pkt_len, err;
 
        pkt_len = skb->len;
-       err = ip6_local_out(skb);
+       err = ip6_local_out_sk(sk, skb);
 
        if (net_xmit_eval(err) == 0) {
                struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
 
 int ip6_mc_input(struct sk_buff *skb);
 
 int __ip6_local_out(struct sk_buff *skb);
+int ip6_local_out_sk(struct sock *sk, struct sk_buff *skb);
 int ip6_local_out(struct sk_buff *skb);
 
 /*
 
                           struct udp_tunnel_sock_cfg *sock_cfg);
 
 /* Transmit the skb using UDP encapsulation. */
-int udp_tunnel_xmit_skb(struct rtable *rt, struct sk_buff *skb,
+int udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
                        __be32 src, __be32 dst, __u8 tos, __u8 ttl,
                        __be16 df, __be16 src_port, __be16 dst_port,
                        bool xnet, bool nocheck);
 
 #if IS_ENABLED(CONFIG_IPV6)
-int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sk_buff *skb,
+int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
+                        struct sk_buff *skb,
                         struct net_device *dev, struct in6_addr *saddr,
                         struct in6_addr *daddr,
                         __u8 prio, __u8 ttl, __be16 src_port,
 
 
 void vxlan_sock_release(struct vxlan_sock *vs);
 
-int vxlan_xmit_skb(struct rtable *rt, struct sk_buff *skb,
+int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
                   __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
                   __be16 src_port, __be16 dst_port, struct vxlan_metadata *md,
                   bool xnet, u32 vxflags);
 
 
        skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
-       return udp_tunnel_xmit_skb(rt, skb, src, dst,
+       return udp_tunnel_xmit_skb(rt, gs->sock->sk, skb, src, dst,
                                   tos, ttl, df, src_port, dst_port, xnet,
                                   !csum);
 }
 
                return;
        }
 
-       err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, protocol,
+       err = iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol,
                            tos, ttl, df, !net_eq(tunnel->net, dev_net(dev)));
        iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
 
 
 }
 EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
 
-int udp_tunnel_xmit_skb(struct rtable *rt, struct sk_buff *skb,
+int udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
                        __be32 src, __be32 dst, __u8 tos, __u8 ttl,
                        __be16 df, __be16 src_port, __be16 dst_port,
                        bool xnet, bool nocheck)
 
        udp_set_csum(nocheck, skb, src, dst, skb->len);
 
-       return iptunnel_xmit(skb->sk, rt, skb, src, dst, IPPROTO_UDP,
+       return iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP,
                             tos, ttl, df, xnet);
 }
 EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
 
 
        skb_set_inner_protocol(skb, protocol);
 
-       ip6tunnel_xmit(skb, dev);
+       ip6tunnel_xmit(NULL, skb, dev);
        if (ndst)
                ip6_tnl_dst_store(tunnel, ndst);
        return 0;
 
        ipv6h->nexthdr = proto;
        ipv6h->saddr = fl6->saddr;
        ipv6h->daddr = fl6->daddr;
-       ip6tunnel_xmit(skb, dev);
+       ip6tunnel_xmit(NULL, skb, dev);
        if (ndst)
                ip6_tnl_dst_store(t, ndst);
        return 0;
 
 }
 EXPORT_SYMBOL_GPL(udp_sock_create6);
 
-int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sk_buff *skb,
+int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
+                        struct sk_buff *skb,
                         struct net_device *dev, struct in6_addr *saddr,
                         struct in6_addr *daddr,
                         __u8 prio, __u8 ttl, __be16 src_port,
        ip6h->daddr       = *daddr;
        ip6h->saddr       = *saddr;
 
-       ip6tunnel_xmit(skb, dev);
+       ip6tunnel_xmit(sk, skb, dev);
        return 0;
 }
 EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
 
 EXPORT_SYMBOL(ip6_dst_hoplimit);
 #endif
 
-int __ip6_local_out(struct sk_buff *skb)
+static int __ip6_local_out_sk(struct sock *sk, struct sk_buff *skb)
 {
        int len;
 
        ipv6_hdr(skb)->payload_len = htons(len);
        IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
 
-       return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb->sk, skb,
+       return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, sk, skb,
                       NULL, skb_dst(skb)->dev, dst_output_sk);
 }
+
+int __ip6_local_out(struct sk_buff *skb)
+{
+       return __ip6_local_out_sk(skb->sk, skb);
+}
 EXPORT_SYMBOL_GPL(__ip6_local_out);
 
-int ip6_local_out(struct sk_buff *skb)
+int ip6_local_out_sk(struct sock *sk, struct sk_buff *skb)
 {
        int err;
 
-       err = __ip6_local_out(skb);
+       err = __ip6_local_out_sk(sk, skb);
        if (likely(err == 1))
-               err = dst_output(skb);
+               err = dst_output_sk(sk, skb);
 
        return err;
 }
+EXPORT_SYMBOL_GPL(ip6_local_out_sk);
+
+int ip6_local_out(struct sk_buff *skb)
+{
+       return ip6_local_out_sk(skb->sk, skb);
+}
 EXPORT_SYMBOL_GPL(ip6_local_out);
 
 {
        struct net *net = ovs_dp_get_net(vport->dp);
        struct vxlan_port *vxlan_port = vxlan_vport(vport);
-       __be16 dst_port = inet_sk(vxlan_port->vs->sock->sk)->inet_sport;
+       struct sock *sk = vxlan_port->vs->sock->sk;
+       __be16 dst_port = inet_sk(sk)->inet_sport;
        const struct ovs_key_ipv4_tunnel *tun_key;
        struct vxlan_metadata md = {0};
        struct rtable *rt;
        vxflags = vxlan_port->exts |
                      (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0);
 
-       err = vxlan_xmit_skb(rt, skb, fl.saddr, tun_key->ipv4_dst,
+       err = vxlan_xmit_skb(rt, sk, skb, fl.saddr, tun_key->ipv4_dst,
                             tun_key->ipv4_tos, tun_key->ipv4_ttl, df,
                             src_port, dst_port,
                             &md, false, vxflags);
 
                        goto tx_error;
                }
                ttl = ip4_dst_hoplimit(&rt->dst);
-               err = udp_tunnel_xmit_skb(rt, clone, src->ipv4.s_addr,
+               err = udp_tunnel_xmit_skb(rt, ub->ubsock->sk, clone,
+                                         src->ipv4.s_addr,
                                          dst->ipv4.s_addr, 0, ttl, 0,
                                          src->udp_port, dst->udp_port,
                                          false, true);
                if (err)
                        goto tx_error;
                ttl = ip6_dst_hoplimit(ndst);
-               err = udp_tunnel6_xmit_skb(ndst, clone, ndst->dev, &src->ipv6,
+               err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, clone,
+                                          ndst->dev, &src->ipv6,
                                           &dst->ipv6, 0, ttl, src->udp_port,
                                           dst->udp_port, false);
 #endif