]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
route: move lwtunnel state to dst_entry
authorJiri Benc <jbenc@redhat.com>
Thu, 20 Aug 2015 11:56:25 +0000 (13:56 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 20 Aug 2015 22:42:36 +0000 (15:42 -0700)
Currently, the lwtunnel state resides in per-protocol data. This is
a problem if we encapsulate ipv6 traffic in an ipv4 tunnel (or vice versa).
The xmit function of the tunnel does not know whether the packet has been
routed to it by ipv4 or ipv6, yet it needs the lwtstate data. Moving the
lwtstate data to dst_entry makes such inter-protocol tunneling possible.

As a bonus, this brings a nice diffstat.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
17 files changed:
drivers/net/vrf.c
drivers/net/vxlan.c
include/net/dst.h
include/net/dst_metadata.h
include/net/ip6_fib.h
include/net/lwtunnel.h
include/net/route.h
net/core/dst.c
net/core/filter.c
net/core/lwtunnel.c
net/ipv4/ip_gre.c
net/ipv4/route.c
net/ipv6/ila.c
net/ipv6/ip6_fib.c
net/ipv6/route.c
net/mpls/mpls_iptunnel.c
net/openvswitch/vport-netdev.c

index dbeffe789185d7bf115abc8372fea919948af938..b3d9c5546c795768a7982092b23063a36b7749d9 100644 (file)
@@ -295,7 +295,6 @@ static struct rtable *vrf_rtable_create(struct net_device *dev)
                rth->rt_uses_gateway = 0;
                INIT_LIST_HEAD(&rth->rt_uncached);
                rth->rt_uncached_list = NULL;
-               rth->rt_lwtstate = NULL;
        }
 
        return rth;
index ebeb3def06c541d5af5e95d90d5cf2211ea2e1de..93613ffd8d7efd2ff9becd297b628dd736d4d132 100644 (file)
@@ -1909,7 +1909,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
        u32 flags = vxlan->flags;
 
        /* FIXME: Support IPv6 */
-       info = skb_tunnel_info(skb, AF_INET);
+       info = skb_tunnel_info(skb);
 
        if (rdst) {
                dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
@@ -2105,7 +2105,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
        struct vxlan_fdb *f;
 
        /* FIXME: Support IPv6 */
-       info = skb_tunnel_info(skb, AF_INET);
+       info = skb_tunnel_info(skb);
 
        skb_reset_mac_header(skb);
        eth = eth_hdr(skb);
index 2578811cef5167e94269bb9967f6b025c824084a..0a9a723f6c19ba28a268c0885c5a0b186bf45a4d 100644 (file)
@@ -44,6 +44,7 @@ struct dst_entry {
 #else
        void                    *__pad1;
 #endif
+       struct lwtunnel_state   *lwtstate;
        int                     (*input)(struct sk_buff *);
        int                     (*output)(struct sock *sk, struct sk_buff *skb);
 
@@ -89,7 +90,7 @@ struct dst_entry {
         * (L1_CACHE_SIZE would be too much)
         */
 #ifdef CONFIG_64BIT
-       long                    __pad_to_align_refcnt[2];
+       long                    __pad_to_align_refcnt[1];
 #endif
        /*
         * __refcnt wants to be on a different cache line from
index 075f523ff23f44f471261b8539a4f7e219b0e92f..2cb52d562272aa395be9186f676c4dbcaf3c1462 100644 (file)
@@ -23,22 +23,17 @@ static inline struct metadata_dst *skb_metadata_dst(struct sk_buff *skb)
        return NULL;
 }
 
-static inline struct ip_tunnel_info *skb_tunnel_info(struct sk_buff *skb,
-                                                    int family)
+static inline struct ip_tunnel_info *skb_tunnel_info(struct sk_buff *skb)
 {
        struct metadata_dst *md_dst = skb_metadata_dst(skb);
-       struct rtable *rt;
+       struct dst_entry *dst;
 
        if (md_dst)
                return &md_dst->u.tun_info;
 
-       switch (family) {
-       case AF_INET:
-               rt = (struct rtable *)skb_dst(skb);
-               if (rt && rt->rt_lwtstate)
-                       return lwt_tun_info(rt->rt_lwtstate);
-               break;
-       }
+       dst = skb_dst(skb);
+       if (dst && dst->lwtstate)
+               return lwt_tun_info(dst->lwtstate);
 
        return NULL;
 }
index 276328e3daa64a0d493a141e5690eb6dfe18c805..063d30474cf66077a7491ac8efbf4d400070c49e 100644 (file)
@@ -133,7 +133,6 @@ struct rt6_info {
        /* more non-fragment space at head required */
        unsigned short                  rt6i_nfheader_len;
        u8                              rt6i_protocol;
-       struct lwtunnel_state           *rt6i_lwtstate;
 };
 
 static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
index cfee53916ba554ff8a4f28c0c383e83158661538..84348988444839280e64026bd9c28a1af1cdfc45 100644 (file)
@@ -87,9 +87,7 @@ int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
 struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
 int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);
 int lwtunnel_output(struct sock *sk, struct sk_buff *skb);
-int lwtunnel_output6(struct sock *sk, struct sk_buff *skb);
 int lwtunnel_input(struct sk_buff *skb);
-int lwtunnel_input6(struct sk_buff *skb);
 
 #else
 
@@ -164,21 +162,11 @@ static inline int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
        return -EOPNOTSUPP;
 }
 
-static inline int lwtunnel_output6(struct sock *sk, struct sk_buff *skb)
-{
-       return -EOPNOTSUPP;
-}
-
 static inline int lwtunnel_input(struct sk_buff *skb)
 {
        return -EOPNOTSUPP;
 }
 
-static inline int lwtunnel_input6(struct sk_buff *skb)
-{
-       return -EOPNOTSUPP;
-}
-
 #endif
 
 #endif /* __NET_LWTUNNEL_H */
index 6dda2c1bf8c6d12951b7e3d81273ca77d16a1720..395d79bb556cf11b62a929cfb03172e30b84d4b1 100644 (file)
@@ -66,7 +66,6 @@ struct rtable {
 
        struct list_head        rt_uncached;
        struct uncached_list    *rt_uncached_list;
-       struct lwtunnel_state   *rt_lwtstate;
 };
 
 static inline bool rt_is_input_route(const struct rtable *rt)
index f8694d1b8702e70db45a0eee94b5361ecb4214e0..50dcdbb0ee46edc40c4fc105dc91bc8dc55492b8 100644 (file)
@@ -20,6 +20,7 @@
 #include <net/net_namespace.h>
 #include <linux/sched.h>
 #include <linux/prefetch.h>
+#include <net/lwtunnel.h>
 
 #include <net/dst.h>
 #include <net/dst_metadata.h>
@@ -184,6 +185,7 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
 #ifdef CONFIG_IP_ROUTE_CLASSID
        dst->tclassid = 0;
 #endif
+       dst->lwtstate = NULL;
        atomic_set(&dst->__refcnt, initial_ref);
        dst->__use = 0;
        dst->lastuse = jiffies;
@@ -264,6 +266,7 @@ struct dst_entry *dst_destroy(struct dst_entry * dst)
                kfree(dst);
        else
                kmem_cache_free(dst->ops->kmem_cachep, dst);
+       lwtstate_put(dst->lwtstate);
 
        dst = child;
        if (dst) {
index 379568562ffb51499943dce759e2459dfa3f2513..b4adc961413ffa7b3b139f156ccec88c21ac7954 100644 (file)
@@ -1489,7 +1489,7 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)
 {
        struct sk_buff *skb = (struct sk_buff *) (long) r1;
        struct bpf_tunnel_key *to = (struct bpf_tunnel_key *) (long) r2;
-       struct ip_tunnel_info *info = skb_tunnel_info(skb, AF_INET);
+       struct ip_tunnel_info *info = skb_tunnel_info(skb);
 
        if (unlikely(size != sizeof(struct bpf_tunnel_key) || flags || !info))
                return -EINVAL;
index 3331585174d9dab0470a8119885c3d6c9b1537eb..e924c2e08554094e824449e3829d42f148906e4a 100644 (file)
@@ -179,14 +179,16 @@ int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b)
 }
 EXPORT_SYMBOL(lwtunnel_cmp_encap);
 
-int __lwtunnel_output(struct sock *sk, struct sk_buff *skb,
-                     struct lwtunnel_state *lwtstate)
+int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
 {
+       struct dst_entry *dst = skb_dst(skb);
        const struct lwtunnel_encap_ops *ops;
+       struct lwtunnel_state *lwtstate;
        int ret = -EINVAL;
 
-       if (!lwtstate)
+       if (!dst)
                goto drop;
+       lwtstate = dst->lwtstate;
 
        if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
            lwtstate->type > LWTUNNEL_ENCAP_MAX)
@@ -209,47 +211,18 @@ int __lwtunnel_output(struct sock *sk, struct sk_buff *skb,
 
        return ret;
 }
-
-int lwtunnel_output6(struct sock *sk, struct sk_buff *skb)
-{
-       struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
-       struct lwtunnel_state *lwtstate = NULL;
-
-       if (rt) {
-               lwtstate = rt->rt6i_lwtstate;
-               skb->dev = rt->dst.dev;
-       }
-
-       skb->protocol = htons(ETH_P_IPV6);
-
-       return __lwtunnel_output(sk, skb, lwtstate);
-}
-EXPORT_SYMBOL(lwtunnel_output6);
-
-int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
-{
-       struct rtable *rt = (struct rtable *)skb_dst(skb);
-       struct lwtunnel_state *lwtstate = NULL;
-
-       if (rt) {
-               lwtstate = rt->rt_lwtstate;
-               skb->dev = rt->dst.dev;
-       }
-
-       skb->protocol = htons(ETH_P_IP);
-
-       return __lwtunnel_output(sk, skb, lwtstate);
-}
 EXPORT_SYMBOL(lwtunnel_output);
 
-int __lwtunnel_input(struct sk_buff *skb,
-                    struct lwtunnel_state *lwtstate)
+int lwtunnel_input(struct sk_buff *skb)
 {
+       struct dst_entry *dst = skb_dst(skb);
        const struct lwtunnel_encap_ops *ops;
+       struct lwtunnel_state *lwtstate;
        int ret = -EINVAL;
 
-       if (!lwtstate)
+       if (!dst)
                goto drop;
+       lwtstate = dst->lwtstate;
 
        if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
            lwtstate->type > LWTUNNEL_ENCAP_MAX)
@@ -272,27 +245,4 @@ int __lwtunnel_input(struct sk_buff *skb,
 
        return ret;
 }
-
-int lwtunnel_input6(struct sk_buff *skb)
-{
-       struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
-       struct lwtunnel_state *lwtstate = NULL;
-
-       if (rt)
-               lwtstate = rt->rt6i_lwtstate;
-
-       return __lwtunnel_input(skb, lwtstate);
-}
-EXPORT_SYMBOL(lwtunnel_input6);
-
-int lwtunnel_input(struct sk_buff *skb)
-{
-       struct rtable *rt = (struct rtable *)skb_dst(skb);
-       struct lwtunnel_state *lwtstate = NULL;
-
-       if (rt)
-               lwtstate = rt->rt_lwtstate;
-
-       return __lwtunnel_input(skb, lwtstate);
-}
 EXPORT_SYMBOL(lwtunnel_input);
index 5193618b2600e1beb9bf98c71f7cfd5e968cf6c2..1bf328182697bdaeb5bace4a8ac9e7c0d726a69d 100644 (file)
@@ -521,7 +521,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
        __be16 df, flags;
        int err;
 
-       tun_info = skb_tunnel_info(skb, AF_INET);
+       tun_info = skb_tunnel_info(skb);
        if (unlikely(!tun_info || tun_info->mode != IP_TUNNEL_INFO_TX))
                goto err_free_skb;
 
index 2403e85107f028fcff8bdcfd9bc5f72fcfb6bf69..f3087aaa6dd86c7aad92814b53aa6cc6494292a1 100644 (file)
@@ -1359,7 +1359,6 @@ static void ipv4_dst_destroy(struct dst_entry *dst)
                list_del(&rt->rt_uncached);
                spin_unlock_bh(&ul->lock);
        }
-       lwtstate_put(rt->rt_lwtstate);
 }
 
 void rt_flush_dev(struct net_device *dev)
@@ -1408,7 +1407,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
 #ifdef CONFIG_IP_ROUTE_CLASSID
                rt->dst.tclassid = nh->nh_tclassid;
 #endif
-               rt->rt_lwtstate = lwtstate_get(nh->nh_lwtstate);
+               rt->dst.lwtstate = lwtstate_get(nh->nh_lwtstate);
                if (unlikely(fnhe))
                        cached = rt_bind_exception(rt, fnhe, daddr);
                else if (!(rt->dst.flags & DST_NOCACHE))
@@ -1494,7 +1493,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        rth->rt_gateway = 0;
        rth->rt_uses_gateway = 0;
        INIT_LIST_HEAD(&rth->rt_uncached);
-       rth->rt_lwtstate = NULL;
        if (our) {
                rth->dst.input= ip_local_deliver;
                rth->rt_flags |= RTCF_LOCAL;
@@ -1624,19 +1622,18 @@ static int __mkroute_input(struct sk_buff *skb,
        rth->rt_gateway = 0;
        rth->rt_uses_gateway = 0;
        INIT_LIST_HEAD(&rth->rt_uncached);
-       rth->rt_lwtstate = NULL;
        RT_CACHE_STAT_INC(in_slow_tot);
 
        rth->dst.input = ip_forward;
        rth->dst.output = ip_output;
 
        rt_set_nexthop(rth, daddr, res, fnhe, res->fi, res->type, itag);
-       if (lwtunnel_output_redirect(rth->rt_lwtstate)) {
-               rth->rt_lwtstate->orig_output = rth->dst.output;
+       if (lwtunnel_output_redirect(rth->dst.lwtstate)) {
+               rth->dst.lwtstate->orig_output = rth->dst.output;
                rth->dst.output = lwtunnel_output;
        }
-       if (lwtunnel_input_redirect(rth->rt_lwtstate)) {
-               rth->rt_lwtstate->orig_input = rth->dst.input;
+       if (lwtunnel_input_redirect(rth->dst.lwtstate)) {
+               rth->dst.lwtstate->orig_input = rth->dst.input;
                rth->dst.input = lwtunnel_input;
        }
        skb_dst_set(skb, &rth->dst);
@@ -1695,7 +1692,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
           by fib_lookup.
         */
 
-       tun_info = skb_tunnel_info(skb, AF_INET);
+       tun_info = skb_tunnel_info(skb);
        if (tun_info && tun_info->mode == IP_TUNNEL_INFO_RX)
                fl4.flowi4_tun_key.tun_id = tun_info->key.tun_id;
        else
@@ -1815,7 +1812,6 @@ out:      return err;
        rth->rt_gateway = 0;
        rth->rt_uses_gateway = 0;
        INIT_LIST_HEAD(&rth->rt_uncached);
-       rth->rt_lwtstate = NULL;
 
        RT_CACHE_STAT_INC(in_slow_tot);
        if (res.type == RTN_UNREACHABLE) {
@@ -2006,7 +2002,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
        rth->rt_gateway = 0;
        rth->rt_uses_gateway = 0;
        INIT_LIST_HEAD(&rth->rt_uncached);
-       rth->rt_lwtstate = NULL;
        RT_CACHE_STAT_INC(out_slow_tot);
 
        if (flags & RTCF_LOCAL)
@@ -2029,7 +2024,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
        }
 
        rt_set_nexthop(rth, fl4->daddr, res, fnhe, fi, type, 0);
-       if (lwtunnel_output_redirect(rth->rt_lwtstate))
+       if (lwtunnel_output_redirect(rth->dst.lwtstate))
                rth->dst.output = lwtunnel_output;
 
        return rth;
@@ -2293,7 +2288,6 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
                rt->rt_uses_gateway = ort->rt_uses_gateway;
 
                INIT_LIST_HEAD(&rt->rt_uncached);
-               rt->rt_lwtstate = NULL;
                dst_free(new);
        }
 
index 2540ab4b76d15d9776721d2e2f6204df9ce1f59b..f011c3d5ca40c3fb46cc4d3e6eada952c6536c9a 100644 (file)
@@ -89,16 +89,13 @@ static void update_ipv6_locator(struct sk_buff *skb, struct ila_params *p)
 static int ila_output(struct sock *sk, struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
-       struct rt6_info *rt6 = NULL;
 
        if (skb->protocol != htons(ETH_P_IPV6))
                goto drop;
 
-       rt6 = (struct rt6_info *)dst;
+       update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate));
 
-       update_ipv6_locator(skb, ila_params_lwtunnel(rt6->rt6i_lwtstate));
-
-       return rt6->rt6i_lwtstate->orig_output(sk, skb);
+       return dst->lwtstate->orig_output(sk, skb);
 
 drop:
        kfree_skb(skb);
@@ -108,16 +105,13 @@ static int ila_output(struct sock *sk, struct sk_buff *skb)
 static int ila_input(struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
-       struct rt6_info *rt6 = NULL;
 
        if (skb->protocol != htons(ETH_P_IPV6))
                goto drop;
 
-       rt6 = (struct rt6_info *)dst;
-
-       update_ipv6_locator(skb, ila_params_lwtunnel(rt6->rt6i_lwtstate));
+       update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate));
 
-       return rt6->rt6i_lwtstate->orig_input(skb);
+       return dst->lwtstate->orig_input(skb);
 
 drop:
        kfree_skb(skb);
index 5693b5eb84820fceb7feb2f87345cd38b2613c6e..865e777ae20cbd7d8b17b94ee56bfe28de23c96e 100644 (file)
@@ -178,7 +178,6 @@ static void rt6_free_pcpu(struct rt6_info *non_pcpu_rt)
 static void rt6_release(struct rt6_info *rt)
 {
        if (atomic_dec_and_test(&rt->rt6i_ref)) {
-               lwtstate_put(rt->rt6i_lwtstate);
                rt6_free_pcpu(rt);
                dst_free(&rt->dst);
        }
index c3733049715ebb83cd1cb629d5c07a7a4a8b4595..e6bbcdee7707aba4e8cd219df234103c8d0c537d 100644 (file)
@@ -1784,14 +1784,14 @@ int ip6_route_add(struct fib6_config *cfg)
                                           cfg->fc_encap, &lwtstate);
                if (err)
                        goto out;
-               rt->rt6i_lwtstate = lwtstate_get(lwtstate);
-               if (lwtunnel_output_redirect(rt->rt6i_lwtstate)) {
-                       rt->rt6i_lwtstate->orig_output = rt->dst.output;
-                       rt->dst.output = lwtunnel_output6;
+               rt->dst.lwtstate = lwtstate_get(lwtstate);
+               if (lwtunnel_output_redirect(rt->dst.lwtstate)) {
+                       rt->dst.lwtstate->orig_output = rt->dst.output;
+                       rt->dst.output = lwtunnel_output;
                }
-               if (lwtunnel_input_redirect(rt->rt6i_lwtstate)) {
-                       rt->rt6i_lwtstate->orig_input = rt->dst.input;
-                       rt->dst.input = lwtunnel_input6;
+               if (lwtunnel_input_redirect(rt->dst.lwtstate)) {
+                       rt->dst.lwtstate->orig_input = rt->dst.input;
+                       rt->dst.input = lwtunnel_input;
                }
        }
 
@@ -2174,7 +2174,7 @@ static void ip6_rt_copy_init(struct rt6_info *rt, struct rt6_info *ort)
 #endif
        rt->rt6i_prefsrc = ort->rt6i_prefsrc;
        rt->rt6i_table = ort->rt6i_table;
-       rt->rt6i_lwtstate = lwtstate_get(ort->rt6i_lwtstate);
+       rt->dst.lwtstate = lwtstate_get(ort->dst.lwtstate);
 }
 
 #ifdef CONFIG_IPV6_ROUTE_INFO
@@ -2838,7 +2838,7 @@ static inline size_t rt6_nlmsg_size(struct rt6_info *rt)
               + nla_total_size(sizeof(struct rta_cacheinfo))
               + nla_total_size(TCP_CA_NAME_MAX) /* RTAX_CC_ALGO */
               + nla_total_size(1) /* RTA_PREF */
-              + lwtunnel_get_encap_size(rt->rt6i_lwtstate);
+              + lwtunnel_get_encap_size(rt->dst.lwtstate);
 }
 
 static int rt6_fill_node(struct net *net,
@@ -2991,7 +2991,7 @@ static int rt6_fill_node(struct net *net,
        if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->rt6i_flags)))
                goto nla_put_failure;
 
-       lwtunnel_fill_encap(skb, rt->rt6i_lwtstate);
+       lwtunnel_fill_encap(skb, rt->dst.lwtstate);
 
        nlmsg_end(skb, nlh);
        return 0;
index 276f8c9922184ada1e505cd31cf028552906f217..3da5ca3ba5638e2cbc30b875c2e0ccae347de954 100644 (file)
@@ -48,7 +48,6 @@ int mpls_output(struct sock *sk, struct sk_buff *skb)
        struct dst_entry *dst = skb_dst(skb);
        struct rtable *rt = NULL;
        struct rt6_info *rt6 = NULL;
-       struct lwtunnel_state *lwtstate = NULL;
        int err = 0;
        bool bos;
        int i;
@@ -58,11 +57,9 @@ int mpls_output(struct sock *sk, struct sk_buff *skb)
        if (skb->protocol == htons(ETH_P_IP)) {
                ttl = ip_hdr(skb)->ttl;
                rt = (struct rtable *)dst;
-               lwtstate = rt->rt_lwtstate;
        } else if (skb->protocol == htons(ETH_P_IPV6)) {
                ttl = ipv6_hdr(skb)->hop_limit;
                rt6 = (struct rt6_info *)dst;
-               lwtstate = rt6->rt6i_lwtstate;
        } else {
                goto drop;
        }
@@ -72,12 +69,12 @@ int mpls_output(struct sock *sk, struct sk_buff *skb)
        /* Find the output device */
        out_dev = dst->dev;
        if (!mpls_output_possible(out_dev) ||
-           !lwtstate || skb_warn_if_lro(skb))
+           !dst->lwtstate || skb_warn_if_lro(skb))
                goto drop;
 
        skb_forward_csum(skb);
 
-       tun_encap_info = mpls_lwtunnel_encap(lwtstate);
+       tun_encap_info = mpls_lwtunnel_encap(dst->lwtstate);
 
        /* Verify the destination can hold the packet */
        new_header_size = mpls_encap_size(tun_encap_info);
index 4b70aaa4a746d8815b08d784dfa7147f7fb75601..a75011505039222c85332b364dec8cd014934f2d 100644 (file)
@@ -57,7 +57,7 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
        skb_push(skb, ETH_HLEN);
        ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
 
-       ovs_vport_receive(vport, skb, skb_tunnel_info(skb, AF_INET));
+       ovs_vport_receive(vport, skb, skb_tunnel_info(skb));
        return;
 
 error: