Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / net / ipv4 / fib_frontend.c
index 4734475..4e60dae 100644 (file)
@@ -85,7 +85,7 @@ struct fib_table *fib_new_table(struct net *net, u32 id)
        if (tb)
                return tb;
 
-       if (id == RT_TABLE_LOCAL)
+       if (id == RT_TABLE_LOCAL && !net->ipv4.fib_has_custom_rules)
                alias = fib_new_table(net, RT_TABLE_MAIN);
 
        tb = fib_trie_table(id, alias);
@@ -280,7 +280,6 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
        struct in_device *in_dev;
        struct fib_result res;
        struct rtable *rt;
-       struct flowi4 fl4;
        struct net *net;
        int scope;
 
@@ -296,14 +295,13 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
 
        scope = RT_SCOPE_UNIVERSE;
        if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) {
-               fl4.flowi4_oif = 0;
-               fl4.flowi4_iif = LOOPBACK_IFINDEX;
-               fl4.daddr = ip_hdr(skb)->saddr;
-               fl4.saddr = 0;
-               fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
-               fl4.flowi4_scope = scope;
-               fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
-               fl4.flowi4_tun_key.tun_id = 0;
+               struct flowi4 fl4 = {
+                       .flowi4_iif = LOOPBACK_IFINDEX,
+                       .daddr = ip_hdr(skb)->saddr,
+                       .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
+                       .flowi4_scope = scope,
+                       .flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0,
+               };
                if (!fib_lookup(net, &fl4, &res, 0))
                        return FIB_RES_PREFSRC(net, res);
        } else {
@@ -906,7 +904,11 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
        if (ifa->ifa_flags & IFA_F_SECONDARY) {
                prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);
                if (!prim) {
-                       pr_warn("%s: bug: prim == NULL\n", __func__);
+                       /* if the device has been deleted, we don't perform
+                        * address promotion
+                        */
+                       if (!in_dev->dead)
+                               pr_warn("%s: bug: prim == NULL\n", __func__);
                        return;
                }
                if (iprim && iprim != prim) {
@@ -922,6 +924,9 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
                subnet = 1;
        }
 
+       if (in_dev->dead)
+               goto no_promotions;
+
        /* Deletion is more complicated than add.
         * We should take care of not to delete too much :-)
         *
@@ -997,6 +1002,7 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
                }
        }
 
+no_promotions:
        if (!(ok & BRD_OK))
                fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
        if (subnet && ifa->ifa_prefixlen < 31) {