]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/fib_rules.c
[IPV4] inetpeer: Get rid of volatile from peer_total
[linux-2.6-omap-h63xx.git] / net / ipv4 / fib_rules.c
index 768e8f5d7daa37e95863195d0418d0d77e6e0684..773b12ba4e3cf965634df3ad4bf9fb34a8e74433 100644 (file)
@@ -19,7 +19,6 @@
  *             Marc Boucher    :       routing by fwmark
  */
 
-#include <linux/config.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <linux/bitops.h>
@@ -104,6 +103,8 @@ static struct hlist_head fib_rules;
 
 /* writer func called from netlink -- rtnl_sem hold*/
 
+static void rtmsg_rule(int, struct fib_rule *);
+
 int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
        struct rtattr **rta = arg;
@@ -131,6 +132,7 @@ int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 
                        hlist_del_rcu(&r->hlist);
                        r->r_dead = 1;
+                       rtmsg_rule(RTM_DELRULE, r);
                        fib_rule_put(r);
                        err = 0;
                        break;
@@ -253,6 +255,7 @@ int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        else
                hlist_add_before_rcu(&new_r->hlist, &r->hlist);
 
+       rtmsg_rule(RTM_NEWRULE, new_r);
        return 0;
 }
 
@@ -382,14 +385,14 @@ static struct notifier_block fib_rules_notifier = {
 
 static __inline__ int inet_fill_rule(struct sk_buff *skb,
                                     struct fib_rule *r,
-                                    struct netlink_callback *cb,
+                                    u32 pid, u32 seq, int event,
                                     unsigned int flags)
 {
        struct rtmsg *rtm;
        struct nlmsghdr  *nlh;
        unsigned char    *b = skb->tail;
 
-       nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags);
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
        rtm = NLMSG_DATA(nlh);
        rtm->rtm_family = AF_INET;
        rtm->rtm_dst_len = r->r_dst_len;
@@ -430,6 +433,21 @@ rtattr_failure:
 
 /* callers should hold rtnl semaphore */
 
+static void rtmsg_rule(int event, struct fib_rule *r)
+{
+       int size = NLMSG_SPACE(sizeof(struct rtmsg) + 128);
+       struct sk_buff *skb = alloc_skb(size, GFP_KERNEL);
+
+       if (!skb)
+               netlink_set_err(rtnl, 0, RTNLGRP_IPV4_RULE, ENOBUFS);
+       else if (inet_fill_rule(skb, r, 0, 0, event, 0) < 0) {
+               kfree_skb(skb);
+               netlink_set_err(rtnl, 0, RTNLGRP_IPV4_RULE, EINVAL);
+       } else {
+               netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV4_RULE, GFP_KERNEL);
+       }
+}
+
 int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
 {
        int idx = 0;
@@ -439,11 +457,13 @@ int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
 
        rcu_read_lock();
        hlist_for_each_entry(r, node, &fib_rules, hlist) {
-
                if (idx < s_idx)
-                       continue;
-               if (inet_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
+                       goto next;
+               if (inet_fill_rule(skb, r, NETLINK_CB(cb->skb).pid,
+                                  cb->nlh->nlmsg_seq,
+                                  RTM_NEWRULE, NLM_F_MULTI) < 0)
                        break;
+next:
                idx++;
        }
        rcu_read_unlock();