]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/core/fib_rules.c
[PKTGEN]: Remove write-only variable.
[linux-2.6-omap-h63xx.git] / net / core / fib_rules.c
index 0d8bb2efb0c1ba8fac29b54668e6105c95bce5e6..8c5474e16683aa22971b1bed0390354b728a0f64 100644 (file)
@@ -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;
@@ -146,7 +152,9 @@ jumped:
                                rule = target;
                                goto jumped;
                        }
-               } else
+               } else if (rule->action == FR_ACT_NOP)
+                       continue;
+               else
                        err = ops->action(rule, fl, flags, arg);
 
                if (err != -EAGAIN) {
@@ -312,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;
 
@@ -402,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;
        }
@@ -450,9 +460,13 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
        if (rule->action == FR_ACT_GOTO && rule->ctarget == NULL)
                frh->flags |= FIB_RULE_UNRESOLVED;
 
-       if (rule->ifname[0])
+       if (rule->ifname[0]) {
                NLA_PUT_STRING(skb, FRA_IFNAME, rule->ifname);
 
+               if (rule->ifindex == -1)
+                       frh->flags |= FIB_RULE_DEV_DETACHED;
+       }
+
        if (rule->pref)
                NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref);
 
@@ -481,8 +495,7 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
        int idx = 0;
        struct fib_rule *rule;
 
-       rcu_read_lock();
-       list_for_each_entry_rcu(rule, ops->rules_list, list) {
+       list_for_each_entry(rule, ops->rules_list, list) {
                if (idx < cb->args[1])
                        goto skip;
 
@@ -493,7 +506,6 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
 skip:
                idx++;
        }
-       rcu_read_unlock();
        cb->args[1] = idx;
        rules_ops_put(ops);