ipv6: fib_rules: Check if rule is a default rule
authorIdo Schimmel <idosch@mellanox.com>
Thu, 3 Aug 2017 11:28:15 +0000 (13:28 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Aug 2017 22:35:59 +0000 (15:35 -0700)
As explained in commit 3c71006d15fd ("ipv4: fib_rules: Check if rule is
a default rule"), drivers supporting IPv6 FIB offload need to be able to
sanitize the rules they don't support and potentially flush their
tables.

Add an IPv6 helper to check if a FIB rule is a default rule.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip6_fib.h
net/ipv6/fib6_rules.c

index 1a88008cc6f5e14a788491f62ae3c15e47b62c16..6000b0dc51eedb0ff6cc96ed9c1f4c6c16a1225e 100644 (file)
@@ -295,6 +295,7 @@ int ipv6_route_open(struct inode *inode, struct file *file);
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 int fib6_rules_init(void);
 void fib6_rules_cleanup(void);
+bool fib6_rule_default(const struct fib_rule *rule);
 #else
 static inline int               fib6_rules_init(void)
 {
@@ -304,5 +305,9 @@ static inline void              fib6_rules_cleanup(void)
 {
        return ;
 }
+static inline bool fib6_rule_default(const struct fib_rule *rule)
+{
+       return true;
+}
 #endif
 #endif
index ec849d88a66205742b1a58c4959c08eeffc3f6d7..ef1fcee6bf168b5f67d89d432a9bb6b45337bac1 100644 (file)
@@ -29,6 +29,26 @@ struct fib6_rule {
        u8                      tclass;
 };
 
+static bool fib6_rule_matchall(const struct fib_rule *rule)
+{
+       struct fib6_rule *r = container_of(rule, struct fib6_rule, common);
+
+       if (r->dst.plen || r->src.plen || r->tclass)
+               return false;
+       return fib_rule_matchall(rule);
+}
+
+bool fib6_rule_default(const struct fib_rule *rule)
+{
+       if (!fib6_rule_matchall(rule) || rule->action != FR_ACT_TO_TBL ||
+           rule->l3mdev)
+               return false;
+       if (rule->table != RT6_TABLE_LOCAL && rule->table != RT6_TABLE_MAIN)
+               return false;
+       return true;
+}
+EXPORT_SYMBOL_GPL(fib6_rule_default);
+
 struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
                                   int flags, pol_lookup_t lookup)
 {