aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2007-03-27 16:56:52 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:28:18 -0400
commit73417f617a93cf30342c3ea41abc38927bd467aa (patch)
tree6093005afdca1825197758d851ca5f275d62356f
parentbe776281aee54626a474ba06f91926b98bdd180d (diff)
[NET] fib_rules: Flush route cache after rule modifications
The results of FIB rules lookups are cached in the routing cache except for IPv6 as no such cache exists. So far, it was the responsibility of the user to flush the cache after modifying any rules. This lead to many false bug reports due to misunderstanding of this concept. This patch automatically flushes the route cache after inserting or deleting a rule. Thanks to Muli Ben-Yehuda <muli@il.ibm.com> for catching a bug in the previous patch. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/fib_rules.h4
-rw-r--r--net/core/fib_rules.c8
-rw-r--r--net/decnet/dn_rules.c7
-rw-r--r--net/ipv4/fib_rules.c6
4 files changed, 25 insertions, 0 deletions
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 08bab8b6e575..ed3a8872c6ca 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -59,6 +59,10 @@ struct fib_rules_ops
59 u32 (*default_pref)(void); 59 u32 (*default_pref)(void);
60 size_t (*nlmsg_payload)(struct fib_rule *); 60 size_t (*nlmsg_payload)(struct fib_rule *);
61 61
62 /* Called after modifications to the rules set, must flush
63 * the route cache if one exists. */
64 void (*flush_cache)(void);
65
62 int nlgroup; 66 int nlgroup;
63 struct nla_policy *policy; 67 struct nla_policy *policy;
64 struct list_head *rules_list; 68 struct list_head *rules_list;
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 5824b2644f26..cb2dae19531b 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -44,6 +44,12 @@ static void rules_ops_put(struct fib_rules_ops *ops)
44 module_put(ops->owner); 44 module_put(ops->owner);
45} 45}
46 46
47static void flush_route_cache(struct fib_rules_ops *ops)
48{
49 if (ops->flush_cache)
50 ops->flush_cache();
51}
52
47int fib_rules_register(struct fib_rules_ops *ops) 53int fib_rules_register(struct fib_rules_ops *ops)
48{ 54{
49 int err = -EEXIST; 55 int err = -EEXIST;
@@ -314,6 +320,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
314 list_add_rcu(&rule->list, ops->rules_list); 320 list_add_rcu(&rule->list, ops->rules_list);
315 321
316 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid); 322 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
323 flush_route_cache(ops);
317 rules_ops_put(ops); 324 rules_ops_put(ops);
318 return 0; 325 return 0;
319 326
@@ -404,6 +411,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
404 notify_rule_change(RTM_DELRULE, rule, ops, nlh, 411 notify_rule_change(RTM_DELRULE, rule, ops, nlh,
405 NETLINK_CB(skb).pid); 412 NETLINK_CB(skb).pid);
406 fib_rule_put(rule); 413 fib_rule_put(rule);
414 flush_route_cache(ops);
407 rules_ops_put(ops); 415 rules_ops_put(ops);
408 return 0; 416 return 0;
409 } 417 }
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index fd0cc2aa316c..7f58b95b27d1 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -31,6 +31,7 @@
31#include <net/dn_fib.h> 31#include <net/dn_fib.h>
32#include <net/dn_neigh.h> 32#include <net/dn_neigh.h>
33#include <net/dn_dev.h> 33#include <net/dn_dev.h>
34#include <net/dn_route.h>
34 35
35static struct fib_rules_ops dn_fib_rules_ops; 36static struct fib_rules_ops dn_fib_rules_ops;
36 37
@@ -239,6 +240,11 @@ static u32 dn_fib_rule_default_pref(void)
239 return 0; 240 return 0;
240} 241}
241 242
243static void dn_fib_rule_flush_cache(void)
244{
245 dn_rt_cache_flush(0);
246}
247
242static struct fib_rules_ops dn_fib_rules_ops = { 248static struct fib_rules_ops dn_fib_rules_ops = {
243 .family = AF_DECnet, 249 .family = AF_DECnet,
244 .rule_size = sizeof(struct dn_fib_rule), 250 .rule_size = sizeof(struct dn_fib_rule),
@@ -249,6 +255,7 @@ static struct fib_rules_ops dn_fib_rules_ops = {
249 .compare = dn_fib_rule_compare, 255 .compare = dn_fib_rule_compare,
250 .fill = dn_fib_rule_fill, 256 .fill = dn_fib_rule_fill,
251 .default_pref = dn_fib_rule_default_pref, 257 .default_pref = dn_fib_rule_default_pref,
258 .flush_cache = dn_fib_rule_flush_cache,
252 .nlgroup = RTNLGRP_DECnet_RULE, 259 .nlgroup = RTNLGRP_DECnet_RULE,
253 .policy = dn_fib_rule_policy, 260 .policy = dn_fib_rule_policy,
254 .rules_list = &dn_fib_rules, 261 .rules_list = &dn_fib_rules,
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index b021b3440ca3..fe29b98d6c8f 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -298,6 +298,11 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
298 + nla_total_size(4); /* flow */ 298 + nla_total_size(4); /* flow */
299} 299}
300 300
301static void fib4_rule_flush_cache(void)
302{
303 rt_cache_flush(0);
304}
305
301static struct fib_rules_ops fib4_rules_ops = { 306static struct fib_rules_ops fib4_rules_ops = {
302 .family = AF_INET, 307 .family = AF_INET,
303 .rule_size = sizeof(struct fib4_rule), 308 .rule_size = sizeof(struct fib4_rule),
@@ -309,6 +314,7 @@ static struct fib_rules_ops fib4_rules_ops = {
309 .fill = fib4_rule_fill, 314 .fill = fib4_rule_fill,
310 .default_pref = fib4_rule_default_pref, 315 .default_pref = fib4_rule_default_pref,
311 .nlmsg_payload = fib4_rule_nlmsg_payload, 316 .nlmsg_payload = fib4_rule_nlmsg_payload,
317 .flush_cache = fib4_rule_flush_cache,
312 .nlgroup = RTNLGRP_IPV4_RULE, 318 .nlgroup = RTNLGRP_IPV4_RULE,
313 .policy = fib4_rule_policy, 319 .policy = fib4_rule_policy,
314 .rules_list = &fib4_rules, 320 .rules_list = &fib4_rules,