ipv4: implement support for NOPREFIXROUTE ifa flag for ipv4 address
[cascardo/linux.git] / net / ipv4 / fib_frontend.c
index 690bcbc..e786873 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;
        }