Skip to content

Commit

Permalink
[NET] fib_rules: Flush route cache after rule modifications
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Thomas Graf authored and David S. Miller committed Apr 26, 2007
1 parent be77628 commit 73417f6
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/net/fib_rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ struct fib_rules_ops
u32 (*default_pref)(void);
size_t (*nlmsg_payload)(struct fib_rule *);

/* Called after modifications to the rules set, must flush
* the route cache if one exists. */
void (*flush_cache)(void);

int nlgroup;
struct nla_policy *policy;
struct list_head *rules_list;
Expand Down
8 changes: 8 additions & 0 deletions net/core/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ static void rules_ops_put(struct fib_rules_ops *ops)
module_put(ops->owner);
}

static void flush_route_cache(struct fib_rules_ops *ops)
{
if (ops->flush_cache)
ops->flush_cache();
}

int fib_rules_register(struct fib_rules_ops *ops)
{
int err = -EEXIST;
Expand Down Expand Up @@ -314,6 +320,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
list_add_rcu(&rule->list, ops->rules_list);

notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
flush_route_cache(ops);
rules_ops_put(ops);
return 0;

Expand Down Expand Up @@ -404,6 +411,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
notify_rule_change(RTM_DELRULE, rule, ops, nlh,
NETLINK_CB(skb).pid);
fib_rule_put(rule);
flush_route_cache(ops);
rules_ops_put(ops);
return 0;
}
Expand Down
7 changes: 7 additions & 0 deletions net/decnet/dn_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <net/dn_fib.h>
#include <net/dn_neigh.h>
#include <net/dn_dev.h>
#include <net/dn_route.h>

static struct fib_rules_ops dn_fib_rules_ops;

Expand Down Expand Up @@ -239,6 +240,11 @@ static u32 dn_fib_rule_default_pref(void)
return 0;
}

static void dn_fib_rule_flush_cache(void)
{
dn_rt_cache_flush(0);
}

static struct fib_rules_ops dn_fib_rules_ops = {
.family = AF_DECnet,
.rule_size = sizeof(struct dn_fib_rule),
Expand All @@ -249,6 +255,7 @@ static struct fib_rules_ops dn_fib_rules_ops = {
.compare = dn_fib_rule_compare,
.fill = dn_fib_rule_fill,
.default_pref = dn_fib_rule_default_pref,
.flush_cache = dn_fib_rule_flush_cache,
.nlgroup = RTNLGRP_DECnet_RULE,
.policy = dn_fib_rule_policy,
.rules_list = &dn_fib_rules,
Expand Down
6 changes: 6 additions & 0 deletions net/ipv4/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
+ nla_total_size(4); /* flow */
}

static void fib4_rule_flush_cache(void)
{
rt_cache_flush(0);
}

static struct fib_rules_ops fib4_rules_ops = {
.family = AF_INET,
.rule_size = sizeof(struct fib4_rule),
Expand All @@ -309,6 +314,7 @@ static struct fib_rules_ops fib4_rules_ops = {
.fill = fib4_rule_fill,
.default_pref = fib4_rule_default_pref,
.nlmsg_payload = fib4_rule_nlmsg_payload,
.flush_cache = fib4_rule_flush_cache,
.nlgroup = RTNLGRP_IPV4_RULE,
.policy = fib4_rule_policy,
.rules_list = &fib4_rules,
Expand Down

0 comments on commit 73417f6

Please sign in to comment.