diff options
author | Thomas Graf <tgraf@suug.ch> | 2006-08-15 03:32:48 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 17:54:51 -0400 |
commit | c17084d21c18497b506bd28b82d964bc9e6c424b (patch) | |
tree | 2c8c32dfc2b1535b2f9edf6cb70ec1a86c48c0f0 | |
parent | 97676b6b5538b3e059d33b8338e7d5cc41c5f1f1 (diff) |
[NET] fib_rules: Convert fib rule notification to use rtnl_notify()
Adds support for NLM_F_ECHO to simplify the process of identifying
inserted rules with an auto generated priority.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/fib_rules.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 873b04d5df81..7b2e9bb1a605 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -18,7 +18,8 @@ static LIST_HEAD(rules_ops); | |||
18 | static DEFINE_SPINLOCK(rules_mod_lock); | 18 | static DEFINE_SPINLOCK(rules_mod_lock); |
19 | 19 | ||
20 | static void notify_rule_change(int event, struct fib_rule *rule, | 20 | static void notify_rule_change(int event, struct fib_rule *rule, |
21 | struct fib_rules_ops *ops); | 21 | struct fib_rules_ops *ops, struct nlmsghdr *nlh, |
22 | u32 pid); | ||
22 | 23 | ||
23 | static struct fib_rules_ops *lookup_rules_ops(int family) | 24 | static struct fib_rules_ops *lookup_rules_ops(int family) |
24 | { | 25 | { |
@@ -209,7 +210,7 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
209 | else | 210 | else |
210 | list_add_rcu(&rule->list, ops->rules_list); | 211 | list_add_rcu(&rule->list, ops->rules_list); |
211 | 212 | ||
212 | notify_rule_change(RTM_NEWRULE, rule, ops); | 213 | notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid); |
213 | rules_ops_put(ops); | 214 | rules_ops_put(ops); |
214 | return 0; | 215 | return 0; |
215 | 216 | ||
@@ -266,7 +267,8 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
266 | 267 | ||
267 | list_del_rcu(&rule->list); | 268 | list_del_rcu(&rule->list); |
268 | synchronize_rcu(); | 269 | synchronize_rcu(); |
269 | notify_rule_change(RTM_DELRULE, rule, ops); | 270 | notify_rule_change(RTM_DELRULE, rule, ops, nlh, |
271 | NETLINK_CB(skb).pid); | ||
270 | fib_rule_put(rule); | 272 | fib_rule_put(rule); |
271 | rules_ops_put(ops); | 273 | rules_ops_put(ops); |
272 | return 0; | 274 | return 0; |
@@ -344,18 +346,26 @@ skip: | |||
344 | EXPORT_SYMBOL_GPL(fib_rules_dump); | 346 | EXPORT_SYMBOL_GPL(fib_rules_dump); |
345 | 347 | ||
346 | static void notify_rule_change(int event, struct fib_rule *rule, | 348 | static void notify_rule_change(int event, struct fib_rule *rule, |
347 | struct fib_rules_ops *ops) | 349 | struct fib_rules_ops *ops, struct nlmsghdr *nlh, |
350 | u32 pid) | ||
348 | { | 351 | { |
349 | int size = nlmsg_total_size(sizeof(struct fib_rule_hdr) + 128); | 352 | struct sk_buff *skb; |
350 | struct sk_buff *skb = alloc_skb(size, GFP_KERNEL); | 353 | int err = -ENOBUFS; |
351 | 354 | ||
355 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
352 | if (skb == NULL) | 356 | if (skb == NULL) |
353 | netlink_set_err(rtnl, 0, ops->nlgroup, ENOBUFS); | 357 | goto errout; |
354 | else if (fib_nl_fill_rule(skb, rule, 0, 0, event, 0, ops) < 0) { | 358 | |
359 | err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); | ||
360 | if (err < 0) { | ||
355 | kfree_skb(skb); | 361 | kfree_skb(skb); |
356 | netlink_set_err(rtnl, 0, ops->nlgroup, EINVAL); | 362 | goto errout; |
357 | } else | 363 | } |
358 | netlink_broadcast(rtnl, skb, 0, ops->nlgroup, GFP_KERNEL); | 364 | |
365 | err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); | ||
366 | errout: | ||
367 | if (err < 0) | ||
368 | rtnl_set_sk_err(ops->nlgroup, err); | ||
359 | } | 369 | } |
360 | 370 | ||
361 | static void attach_rules(struct list_head *rules, struct net_device *dev) | 371 | static void attach_rules(struct list_head *rules, struct net_device *dev) |