aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/fib_rules.h1
-rw-r--r--net/core/fib_rules.c24
2 files changed, 18 insertions, 7 deletions
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
index adcdfbdd14d..8270aac2aa5 100644
--- a/include/linux/fib_rules.h
+++ b/include/linux/fib_rules.h
@@ -6,6 +6,7 @@
6 6
7/* rule is permanent, and cannot be deleted */ 7/* rule is permanent, and cannot be deleted */
8#define FIB_RULE_PERMANENT 1 8#define FIB_RULE_PERMANENT 1
9#define FIB_RULE_INVERT 2
9 10
10struct fib_rule_hdr 11struct fib_rule_hdr
11{ 12{
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index da91bf2e615..4148e274a20 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -107,6 +107,22 @@ out:
107 107
108EXPORT_SYMBOL_GPL(fib_rules_unregister); 108EXPORT_SYMBOL_GPL(fib_rules_unregister);
109 109
110static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
111 struct flowi *fl, int flags)
112{
113 int ret = 0;
114
115 if (rule->ifindex && (rule->ifindex != fl->iif))
116 goto out;
117
118 if ((rule->mark ^ fl->mark) & rule->mark_mask)
119 goto out;
120
121 ret = ops->match(rule, fl, flags);
122out:
123 return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
124}
125
110int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, 126int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
111 int flags, struct fib_lookup_arg *arg) 127 int flags, struct fib_lookup_arg *arg)
112{ 128{
@@ -116,13 +132,7 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
116 rcu_read_lock(); 132 rcu_read_lock();
117 133
118 list_for_each_entry_rcu(rule, ops->rules_list, list) { 134 list_for_each_entry_rcu(rule, ops->rules_list, list) {
119 if (rule->ifindex && (rule->ifindex != fl->iif)) 135 if (!fib_rule_match(rule, ops, fl, flags))
120 continue;
121
122 if ((rule->mark ^ fl->mark) & rule->mark_mask)
123 continue;
124
125 if (!ops->match(rule, fl, flags))
126 continue; 136 continue;
127 137
128 err = ops->action(rule, fl, flags, arg); 138 err = ops->action(rule, fl, flags, arg);