diff options
-rw-r--r-- | include/linux/fib_rules.h | 1 | ||||
-rw-r--r-- | net/core/fib_rules.c | 24 |
2 files changed, 18 insertions, 7 deletions
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h index adcdfbdd14d5..8270aac2aa5d 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 | ||
10 | struct fib_rule_hdr | 11 | struct fib_rule_hdr |
11 | { | 12 | { |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index da91bf2e6151..4148e274a204 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -107,6 +107,22 @@ out: | |||
107 | 107 | ||
108 | EXPORT_SYMBOL_GPL(fib_rules_unregister); | 108 | EXPORT_SYMBOL_GPL(fib_rules_unregister); |
109 | 109 | ||
110 | static 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); | ||
122 | out: | ||
123 | return (rule->flags & FIB_RULE_INVERT) ? !ret : ret; | ||
124 | } | ||
125 | |||
110 | int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, | 126 | int 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); |