Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / net / ipv4 / route.c
index b5b47a2..654a9af 100644 (file)
@@ -1252,7 +1252,9 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
                        mtu = 576;
        }
 
-       return min_t(unsigned int, mtu, IP_MAX_MTU);
+       mtu = min_t(unsigned int, mtu, IP_MAX_MTU);
+
+       return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
 }
 
 static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr)
@@ -1835,7 +1837,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
         *      Now we are ready to route packet.
         */
        fl4.flowi4_oif = 0;
-       fl4.flowi4_iif = l3mdev_fib_oif_rcu(dev);
+       fl4.flowi4_iif = dev->ifindex;
        fl4.flowi4_mark = skb->mark;
        fl4.flowi4_tos = tos;
        fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
@@ -2022,7 +2024,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
                return ERR_PTR(-EINVAL);
 
        if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev)))
-               if (ipv4_is_loopback(fl4->saddr) && !(dev_out->flags & IFF_LOOPBACK))
+               if (ipv4_is_loopback(fl4->saddr) &&
+                   !(dev_out->flags & IFF_LOOPBACK) &&
+                   !netif_is_l3_master(dev_out))
                        return ERR_PTR(-EINVAL);
 
        if (ipv4_is_lbcast(fl4->daddr))
@@ -2152,7 +2156,6 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
        unsigned int flags = 0;
        struct fib_result res;
        struct rtable *rth;
-       int master_idx;
        int orig_oif;
        int err = -ENETUNREACH;
 
@@ -2162,9 +2165,6 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
 
        orig_oif = fl4->flowi4_oif;
 
-       master_idx = l3mdev_master_ifindex_by_index(net, fl4->flowi4_oif);
-       if (master_idx)
-               fl4->flowi4_oif = master_idx;
        fl4->flowi4_iif = LOOPBACK_IFINDEX;
        fl4->flowi4_tos = tos & IPTOS_RT_MASK;
        fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
@@ -2248,10 +2248,6 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
                                fl4->saddr = inet_select_addr(dev_out, 0,
                                                              RT_SCOPE_HOST);
                }
-
-               rth = l3mdev_get_rtable(dev_out, fl4);
-               if (rth)
-                       goto out;
        }
 
        if (!fl4->daddr) {
@@ -2269,8 +2265,7 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
        if (err) {
                res.fi = NULL;
                res.table = NULL;
-               if (fl4->flowi4_oif &&
-                   !netif_index_is_l3_master(net, fl4->flowi4_oif)) {
+               if (fl4->flowi4_oif) {
                        /* Apparently, routing tables are wrong. Assume,
                           that the destination is on link.
 
@@ -2306,7 +2301,9 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
                        else
                                fl4->saddr = fl4->daddr;
                }
-               dev_out = net->loopback_dev;
+
+               /* L3 master device is the loopback for that domain */
+               dev_out = l3mdev_master_dev_rcu(dev_out) ? : net->loopback_dev;
                fl4->flowi4_oif = dev_out->ifindex;
                flags |= RTCF_LOCAL;
                goto make_route;
@@ -2581,9 +2578,6 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
        fl4.flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0;
        fl4.flowi4_mark = mark;
 
-       if (netif_index_is_l3_master(net, fl4.flowi4_oif))
-               fl4.flowi4_flags = FLOWI_FLAG_L3MDEV_SRC | FLOWI_FLAG_SKIP_NH_OIF;
-
        if (iif) {
                struct net_device *dev;