Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=73417f617a93cf30342c3ea41abc38927bd467aa
Commit:     73417f617a93cf30342c3ea41abc38927bd467aa
Parent:     be776281aee54626a474ba06f91926b98bdd180d
Author:     Thomas Graf <[EMAIL PROTECTED]>
AuthorDate: Tue Mar 27 13:56:52 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Wed Apr 25 22:28:18 2007 -0700

    [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 <[EMAIL PROTECTED]> for catching a bug
    in the previous patch.
    
    Signed-off-by: Thomas Graf <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 include/net/fib_rules.h |    4 ++++
 net/core/fib_rules.c    |    8 ++++++++
 net/decnet/dn_rules.c   |    7 +++++++
 net/ipv4/fib_rules.c    |    6 ++++++
 4 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 08bab8b..ed3a887 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -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;
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 5824b26..cb2dae1 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)
                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;
@@ -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;
 
@@ -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;
        }
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index fd0cc2a..7f58b95 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -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;
 
@@ -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),
@@ -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,
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index b021b34..fe29b98 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)
               + 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),
@@ -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,
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to