Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
[cascardo/linux.git] / net / ipv4 / fib_frontend.c
index 690bcbc..cc8f3e5 100644 (file)
@@ -45,7 +45,7 @@
 #include <net/ip_fib.h>
 #include <net/rtnetlink.h>
 #include <net/xfrm.h>
-#include <net/vrf.h>
+#include <net/l3mdev.h>
 #include <trace/events/fib.h>
 
 #ifndef CONFIG_IP_MULTIPLE_TABLES
@@ -255,7 +255,7 @@ EXPORT_SYMBOL(inet_addr_type);
 unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
                                __be32 addr)
 {
-       u32 rt_table = vrf_dev_table(dev) ? : RT_TABLE_LOCAL;
+       u32 rt_table = l3mdev_fib_table(dev) ? : RT_TABLE_LOCAL;
 
        return __inet_dev_addr_type(net, dev, addr, rt_table);
 }
@@ -268,7 +268,7 @@ unsigned int inet_addr_type_dev_table(struct net *net,
                                      const struct net_device *dev,
                                      __be32 addr)
 {
-       u32 rt_table = vrf_dev_table(dev) ? : RT_TABLE_LOCAL;
+       u32 rt_table = l3mdev_fib_table(dev) ? : RT_TABLE_LOCAL;
 
        return __inet_dev_addr_type(net, NULL, addr, rt_table);
 }
@@ -332,7 +332,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
        bool dev_match;
 
        fl4.flowi4_oif = 0;
-       fl4.flowi4_iif = vrf_master_ifindex_rcu(dev);
+       fl4.flowi4_iif = l3mdev_master_ifindex_rcu(dev);
        if (!fl4.flowi4_iif)
                fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX;
        fl4.daddr = src;
@@ -367,7 +367,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
                if (nh->nh_dev == dev) {
                        dev_match = true;
                        break;
-               } else if (vrf_master_ifindex_rcu(nh->nh_dev) == dev->ifindex) {
+               } else if (l3mdev_master_ifindex_rcu(nh->nh_dev) == dev->ifindex) {
                        dev_match = true;
                        break;
                }
@@ -804,7 +804,7 @@ out:
 static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa)
 {
        struct net *net = dev_net(ifa->ifa_dev->dev);
-       u32 tb_id = vrf_dev_table_rtnl(ifa->ifa_dev->dev);
+       u32 tb_id = l3mdev_fib_table(ifa->ifa_dev->dev);
        struct fib_table *tb;
        struct fib_config cfg = {
                .fc_protocol = RTPROT_KERNEL,
@@ -867,9 +867,10 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
 
        if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) &&
            (prefix != addr || ifa->ifa_prefixlen < 32)) {
-               fib_magic(RTM_NEWROUTE,
-                         dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST,
-                         prefix, ifa->ifa_prefixlen, prim);
+               if (!(ifa->ifa_flags & IFA_F_NOPREFIXROUTE))
+                       fib_magic(RTM_NEWROUTE,
+                                 dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST,
+                                 prefix, ifa->ifa_prefixlen, prim);
 
                /* Add network specific broadcasts, when it takes a sense */
                if (ifa->ifa_prefixlen < 31) {
@@ -914,9 +915,10 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
                }
        } else if (!ipv4_is_zeronet(any) &&
                   (any != ifa->ifa_local || ifa->ifa_prefixlen < 32)) {
-               fib_magic(RTM_DELROUTE,
-                         dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST,
-                         any, ifa->ifa_prefixlen, prim);
+               if (!(ifa->ifa_flags & IFA_F_NOPREFIXROUTE))
+                       fib_magic(RTM_DELROUTE,
+                                 dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST,
+                                 any, ifa->ifa_prefixlen, prim);
                subnet = 1;
        }
 
@@ -1110,9 +1112,10 @@ static void nl_fib_lookup_exit(struct net *net)
        net->ipv4.fibnl = NULL;
 }
 
-static void fib_disable_ip(struct net_device *dev, unsigned long event)
+static void fib_disable_ip(struct net_device *dev, unsigned long event,
+                          bool force)
 {
-       if (fib_sync_down_dev(dev, event))
+       if (fib_sync_down_dev(dev, event, force))
                fib_flush(dev_net(dev));
        rt_cache_flush(dev_net(dev));
        arp_ifdown(dev);
@@ -1140,7 +1143,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
                        /* Last address was deleted from this interface.
                         * Disable IP.
                         */
-                       fib_disable_ip(dev, event);
+                       fib_disable_ip(dev, event, true);
                } else {
                        rt_cache_flush(dev_net(dev));
                }
@@ -1157,7 +1160,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
        unsigned int flags;
 
        if (event == NETDEV_UNREGISTER) {
-               fib_disable_ip(dev, event);
+               fib_disable_ip(dev, event, true);
                rt_flush_dev(dev);
                return NOTIFY_DONE;
        }
@@ -1178,14 +1181,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
                rt_cache_flush(net);
                break;
        case NETDEV_DOWN:
-               fib_disable_ip(dev, event);
+               fib_disable_ip(dev, event, false);
                break;
        case NETDEV_CHANGE:
                flags = dev_get_flags(dev);
                if (flags & (IFF_RUNNING | IFF_LOWER_UP))
                        fib_sync_up(dev, RTNH_F_LINKDOWN);
                else
-                       fib_sync_down_dev(dev, event);
+                       fib_sync_down_dev(dev, event, false);
                /* fall through */
        case NETDEV_CHANGEMTU:
                rt_cache_flush(net);