[NETLINK]: Correctly set NLM_F_MULTI without checking the pid
Jamal Hadi Salim [Sun, 19 Jun 2005 05:54:12 +0000 (22:54 -0700)]
This patch rectifies some rtnetlink message builders that derive the
flags from the pid. It is now explicit like the other cases
which get it right. Also fixes half a dozen dumpers which did not
set NLM_F_MULTI at all.

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

14 files changed:
net/core/neighbour.c
net/core/rtnetlink.c
net/decnet/dn_dev.c
net/decnet/dn_route.c
net/decnet/dn_rules.c
net/decnet/dn_table.c
net/ipv4/devinet.c
net/ipv4/fib_hash.c
net/ipv4/fib_lookup.h
net/ipv4/fib_rules.c
net/ipv4/fib_semantics.c
net/ipv4/route.c
net/ipv6/addrconf.c
net/ipv6/route.c

index 0fb742e..f6bdcad 100644 (file)
@@ -1859,18 +1859,17 @@ out:
 }
 
 static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n,
-                          u32 pid, u32 seq, int event)
+                          u32 pid, u32 seq, int event, unsigned int flags)
 {
        unsigned long now = jiffies;
        unsigned char *b = skb->tail;
        struct nda_cacheinfo ci;
        int locked = 0;
        u32 probes;
-       struct nlmsghdr *nlh = NLMSG_PUT(skb, pid, seq, event,
-                                        sizeof(struct ndmsg));
+       struct nlmsghdr *nlh = NLMSG_NEW(skb, pid, seq, event,
+                                        sizeof(struct ndmsg), flags);
        struct ndmsg *ndm = NLMSG_DATA(nlh);
 
-       nlh->nlmsg_flags = pid ? NLM_F_MULTI : 0;
        ndm->ndm_family  = n->ops->family;
        ndm->ndm_flags   = n->flags;
        ndm->ndm_type    = n->type;
@@ -1920,7 +1919,8 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                                continue;
                        if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
                                            cb->nlh->nlmsg_seq,
-                                           RTM_NEWNEIGH) <= 0) {
+                                           RTM_NEWNEIGH,
+                                           NLM_F_MULTI) <= 0) {
                                read_unlock_bh(&tbl->lock);
                                rc = -1;
                                goto out;
@@ -2329,7 +2329,7 @@ void neigh_app_ns(struct neighbour *n)
        if (!skb)
                return;
 
-       if (neigh_fill_info(skb, n, 0, 0, RTM_GETNEIGH) < 0) {
+       if (neigh_fill_info(skb, n, 0, 0, RTM_GETNEIGH, 0) < 0) {
                kfree_skb(skb);
                return;
        }
@@ -2348,7 +2348,7 @@ static void neigh_app_notify(struct neighbour *n)
        if (!skb)
                return;
 
-       if (neigh_fill_info(skb, n, 0, 0, RTM_NEWNEIGH) < 0) {
+       if (neigh_fill_info(skb, n, 0, 0, RTM_NEWNEIGH, 0) < 0) {
                kfree_skb(skb);
                return;
        }
index 56a20f0..63bd886 100644 (file)
@@ -178,14 +178,14 @@ rtattr_failure:
 
 
 static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
-                                int type, u32 pid, u32 seq, u32 change)
+                                int type, u32 pid, u32 seq, u32 change, 
+                                unsigned int flags)
 {
        struct ifinfomsg *r;
        struct nlmsghdr  *nlh;
        unsigned char    *b = skb->tail;
 
-       nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*r));
-       if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+       nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags);
        r = NLMSG_DATA(nlh);
        r->ifi_family = AF_UNSPEC;
        r->ifi_type = dev->type;
@@ -275,7 +275,10 @@ static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *c
        for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
                if (idx < s_idx)
                        continue;
-               if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0) <= 0)
+               if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK,
+                                         NETLINK_CB(cb->skb).pid,
+                                         cb->nlh->nlmsg_seq, 0,
+                                         NLM_F_MULTI) <= 0)
                        break;
        }
        read_unlock(&dev_base_lock);
@@ -449,7 +452,7 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
        if (!skb)
                return;
 
-       if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change) < 0) {
+       if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change, 0) < 0) {
                kfree_skb(skb);
                return;
        }
index ee7bf46..00233ec 100644 (file)
@@ -716,13 +716,13 @@ static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *a
 }
 
 static int dn_dev_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
-                               u32 pid, u32 seq, int event)
+                               u32 pid, u32 seq, int event, unsigned int flags)
 {
        struct ifaddrmsg *ifm;
        struct nlmsghdr *nlh;
        unsigned char *b = skb->tail;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
        ifm = NLMSG_DATA(nlh);
 
        ifm->ifa_family = AF_DECnet;
@@ -755,7 +755,7 @@ static void rtmsg_ifa(int event, struct dn_ifaddr *ifa)
                netlink_set_err(rtnl, 0, RTMGRP_DECnet_IFADDR, ENOBUFS);
                return;
        }
-       if (dn_dev_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
+       if (dn_dev_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) {
                kfree_skb(skb);
                netlink_set_err(rtnl, 0, RTMGRP_DECnet_IFADDR, EINVAL);
                return;
@@ -790,7 +790,8 @@ static int dn_dev_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
                        if (dn_dev_fill_ifaddr(skb, ifa,
                                               NETLINK_CB(cb->skb).pid,
                                               cb->nlh->nlmsg_seq,
-                                              RTM_NEWADDR) <= 0)
+                                              RTM_NEWADDR,
+                                              NLM_F_MULTI) <= 0)
                                goto done;
                }
        }
index 1e7b5c3..2399fa8 100644 (file)
@@ -1465,7 +1465,8 @@ int dn_route_input(struct sk_buff *skb)
        return dn_route_input_slow(skb);
 }
 
-static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int nowait)
+static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+                          int event, int nowait, unsigned int flags)
 {
        struct dn_route *rt = (struct dn_route *)skb->dst;
        struct rtmsg *r;
@@ -1473,9 +1474,8 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int
        unsigned char *b = skb->tail;
        struct rta_cacheinfo ci;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
        r = NLMSG_DATA(nlh);
-       nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
        r->rtm_family = AF_DECnet;
        r->rtm_dst_len = 16;
        r->rtm_src_len = 0;
@@ -1596,7 +1596,7 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
 
        NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
 
-       err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0);
+       err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0);
 
        if (err == 0)
                goto out_free;
@@ -1644,7 +1644,8 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
                                continue;
                        skb->dst = dst_clone(&rt->u.dst);
                        if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
-                                       cb->nlh->nlmsg_seq, RTM_NEWROUTE, 1) <= 0) {
+                                       cb->nlh->nlmsg_seq, RTM_NEWROUTE, 
+                                       1, NLM_F_MULTI) <= 0) {
                                dst_release(xchg(&skb->dst, NULL));
                                rcu_read_unlock_bh();
                                goto done;
index 597587d..1060de7 100644 (file)
@@ -342,14 +342,15 @@ static struct notifier_block dn_fib_rules_notifier = {
        .notifier_call =        dn_fib_rules_event,
 };
 
-static int dn_fib_fill_rule(struct sk_buff *skb, struct dn_fib_rule *r, struct netlink_callback *cb)
+static int dn_fib_fill_rule(struct sk_buff *skb, struct dn_fib_rule *r,
+                           struct netlink_callback *cb, unsigned int flags)
 {
        struct rtmsg *rtm;
        struct nlmsghdr *nlh;
        unsigned char *b = skb->tail;
 
 
-       nlh = NLMSG_PUT(skb, NETLINK_CREDS(cb->skb)->pid, cb->nlh->nlmsg_seq, RTM_NEWRULE, sizeof(*rtm));
+       nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags);
        rtm = NLMSG_DATA(nlh);
        rtm->rtm_family = AF_DECnet;
        rtm->rtm_dst_len = r->r_dst_len;
@@ -394,7 +395,7 @@ int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
        for(r = dn_fib_rules, idx = 0; r; r = r->r_next, idx++) {
                if (idx < s_idx)
                        continue;
-               if (dn_fib_fill_rule(skb, r, cb) < 0)
+               if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
                        break;
        }
        read_unlock(&dn_fib_rules_lock);
index dad5603..28ba577 100644 (file)
@@ -270,13 +270,13 @@ static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct dn_kern
 
 static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                         u8 tb_id, u8 type, u8 scope, void *dst, int dst_len,
-                        struct dn_fib_info *fi)
+                        struct dn_fib_info *fi, unsigned int flags)
 {
         struct rtmsg *rtm;
         struct nlmsghdr *nlh;
         unsigned char *b = skb->tail;
 
-        nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*rtm));
+        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
         rtm = NLMSG_DATA(nlh);
         rtm->rtm_family = AF_DECnet;
         rtm->rtm_dst_len = dst_len;
@@ -345,7 +345,7 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, int tb_id,
 
         if (dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, 
                                 f->fn_type, f->fn_scope, &f->fn_key, z, 
-                                DN_FIB_INFO(f)) < 0) {
+                                DN_FIB_INFO(f), 0) < 0) {
                 kfree_skb(skb);
                 return;
         }
@@ -377,7 +377,7 @@ static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
                                tb->n, 
                                (f->fn_state & DN_S_ZOMBIE) ? 0 : f->fn_type,
                                f->fn_scope, &f->fn_key, dz->dz_order, 
-                               f->fn_info) < 0) {
+                               f->fn_info, NLM_F_MULTI) < 0) {
                        cb->args[3] = i;
                        return -1;
                }
index 478a301..fd47a1e 100644 (file)
@@ -1030,14 +1030,13 @@ static struct notifier_block ip_netdev_notifier = {
 };
 
 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
-                           u32 pid, u32 seq, int event)
+                           u32 pid, u32 seq, int event, unsigned int flags)
 {
        struct ifaddrmsg *ifm;
        struct nlmsghdr  *nlh;
        unsigned char    *b = skb->tail;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
-       if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
        ifm = NLMSG_DATA(nlh);
        ifm->ifa_family = AF_INET;
        ifm->ifa_prefixlen = ifa->ifa_prefixlen;
@@ -1090,7 +1089,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
                                continue;
                        if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
                                             cb->nlh->nlmsg_seq,
-                                            RTM_NEWADDR) <= 0) {
+                                            RTM_NEWADDR, NLM_F_MULTI) <= 0) {
                                rcu_read_unlock();
                                goto done;
                        }
@@ -1113,7 +1112,7 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
 
        if (!skb)
                netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
-       else if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
+       else if (inet_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) {
                kfree_skb(skb);
                netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
        } else {
index 6506dcc..b10d6bb 100644 (file)
@@ -703,7 +703,8 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
                                          &f->fn_key,
                                          fz->fz_order,
                                          fa->fa_tos,
-                                         fa->fa_info) < 0) {
+                                         fa->fa_info,
+                                         NLM_F_MULTI) < 0) {
                                cb->args[3] = i;
                                return -1;
                        }
index ac4485f..b729d97 100644 (file)
@@ -30,7 +30,8 @@ extern int fib_nh_match(struct rtmsg *r, struct nlmsghdr *,
                        struct kern_rta *rta, struct fib_info *fi);
 extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                         u8 tb_id, u8 type, u8 scope, void *dst,
-                        int dst_len, u8 tos, struct fib_info *fi);
+                        int dst_len, u8 tos, struct fib_info *fi,
+                        unsigned int);
 extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
                      int z, int tb_id,
                      struct nlmsghdr *n, struct netlink_skb_parms *req);
index 39d0aad..0b298bb 100644 (file)
@@ -367,13 +367,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)
+                                    struct netlink_callback *cb,
+                                    unsigned int flags)
 {
        struct rtmsg *rtm;
        struct nlmsghdr  *nlh;
        unsigned char    *b = skb->tail;
 
-       nlh = NLMSG_PUT(skb, NETLINK_CREDS(cb->skb)->pid, cb->nlh->nlmsg_seq, RTM_NEWRULE, sizeof(*rtm));
+       nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags);
        rtm = NLMSG_DATA(nlh);
        rtm->rtm_family = AF_INET;
        rtm->rtm_dst_len = r->r_dst_len;
@@ -422,7 +423,7 @@ int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
        for (r=fib_rules, idx=0; r; r = r->r_next, idx++) {
                if (idx < s_idx)
                        continue;
-               if (inet_fill_rule(skb, r, cb) < 0)
+               if (inet_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
                        break;
        }
        read_unlock(&fib_rules_lock);
index 029362d..a9a44b4 100644 (file)
@@ -286,7 +286,7 @@ void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
        if (fib_dump_info(skb, pid, n->nlmsg_seq, event, tb_id,
                          fa->fa_type, fa->fa_scope, &key, z,
                          fa->fa_tos,
-                         fa->fa_info) < 0) {
+                         fa->fa_info, 0) < 0) {
                kfree_skb(skb);
                return;
        }
@@ -932,13 +932,13 @@ u32 __fib_res_prefsrc(struct fib_result *res)
 int
 fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
              u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos,
-             struct fib_info *fi)
+             struct fib_info *fi, unsigned int flags)
 {
        struct rtmsg *rtm;
        struct nlmsghdr  *nlh;
        unsigned char    *b = skb->tail;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*rtm));
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
        rtm = NLMSG_DATA(nlh);
        rtm->rtm_family = AF_INET;
        rtm->rtm_dst_len = dst_len;
index a682d28..f4d53c9 100644 (file)
@@ -2581,7 +2581,7 @@ int ip_route_output_key(struct rtable **rp, struct flowi *flp)
 }
 
 static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
-                       int nowait)
+                       int nowait, unsigned int flags)
 {
        struct rtable *rt = (struct rtable*)skb->dst;
        struct rtmsg *r;
@@ -2591,9 +2591,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 #ifdef CONFIG_IP_MROUTE
        struct rtattr *eptr;
 #endif
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
        r = NLMSG_DATA(nlh);
-       nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
        r->rtm_family    = AF_INET;
        r->rtm_dst_len  = 32;
        r->rtm_src_len  = 0;
@@ -2744,7 +2743,7 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
        NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
 
        err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
-                               RTM_NEWROUTE, 0);
+                               RTM_NEWROUTE, 0, 0);
        if (!err)
                goto out_free;
        if (err < 0) {
@@ -2781,8 +2780,8 @@ int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
                                continue;
                        skb->dst = dst_clone(&rt->u.dst);
                        if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
-                                        cb->nlh->nlmsg_seq,
-                                        RTM_NEWROUTE, 1) <= 0) {
+                                        cb->nlh->nlmsg_seq, RTM_NEWROUTE, 
+                                        1, NLM_F_MULTI) <= 0) {
                                dst_release(xchg(&skb->dst, NULL));
                                rcu_read_unlock_bh();
                                goto done;
index 2720899..cdd19c5 100644 (file)
@@ -2622,15 +2622,14 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 }
 
 static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
-                            u32 pid, u32 seq, int event)
+                            u32 pid, u32 seq, int event, unsigned int flags)
 {
        struct ifaddrmsg *ifm;
        struct nlmsghdr  *nlh;
        struct ifa_cacheinfo ci;
        unsigned char    *b = skb->tail;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
-       if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
        ifm = NLMSG_DATA(nlh);
        ifm->ifa_family = AF_INET6;
        ifm->ifa_prefixlen = ifa->prefix_len;
@@ -2672,15 +2671,14 @@ rtattr_failure:
 }
 
 static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
-                               u32 pid, u32 seq, int event)
+                               u32 pid, u32 seq, int event, unsigned flags)
 {
        struct ifaddrmsg *ifm;
        struct nlmsghdr  *nlh;
        struct ifa_cacheinfo ci;
        unsigned char    *b = skb->tail;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
-       if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
        ifm = NLMSG_DATA(nlh);
        ifm->ifa_family = AF_INET6;     
        ifm->ifa_prefixlen = 128;
@@ -2709,15 +2707,14 @@ rtattr_failure:
 }
 
 static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
-                               u32 pid, u32 seq, int event)
+                               u32 pid, u32 seq, int event, unsigned int flags)
 {
        struct ifaddrmsg *ifm;
        struct nlmsghdr  *nlh;
        struct ifa_cacheinfo ci;
        unsigned char    *b = skb->tail;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
-       if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
        ifm = NLMSG_DATA(nlh);
        ifm->ifa_family = AF_INET6;     
        ifm->ifa_prefixlen = 128;
@@ -2786,7 +2783,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                                        continue;
                                if ((err = inet6_fill_ifaddr(skb, ifa, 
                                    NETLINK_CB(cb->skb).pid, 
-                                   cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
+                                   cb->nlh->nlmsg_seq, RTM_NEWADDR,
+                                   NLM_F_MULTI)) <= 0)
                                        goto done;
                        }
                        /* temp addr */
@@ -2797,7 +2795,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                                        continue;
                                if ((err = inet6_fill_ifaddr(skb, ifa, 
                                    NETLINK_CB(cb->skb).pid, 
-                                   cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
+                                   cb->nlh->nlmsg_seq, RTM_NEWADDR,
+                                   NLM_F_MULTI)) <= 0) 
                                        goto done;
                        }
 #endif
@@ -2810,7 +2809,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                                        continue;
                                if ((err = inet6_fill_ifmcaddr(skb, ifmca, 
                                    NETLINK_CB(cb->skb).pid, 
-                                   cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0)
+                                   cb->nlh->nlmsg_seq, RTM_GETMULTICAST,
+                                   NLM_F_MULTI)) <= 0)
                                        goto done;
                        }
                        break;
@@ -2822,7 +2822,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                                        continue;
                                if ((err = inet6_fill_ifacaddr(skb, ifaca, 
                                    NETLINK_CB(cb->skb).pid, 
-                                   cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0) 
+                                   cb->nlh->nlmsg_seq, RTM_GETANYCAST,
+                                   NLM_F_MULTI)) <= 0) 
                                        goto done;
                        }
                        break;
@@ -2872,7 +2873,7 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, ENOBUFS);
                return;
        }
-       if (inet6_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
+       if (inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) {
                kfree_skb(skb);
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, EINVAL);
                return;
@@ -2907,7 +2908,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
 }
 
 static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 
-                            u32 pid, u32 seq, int event)
+                            u32 pid, u32 seq, int event, unsigned int flags)
 {
        struct net_device       *dev = idev->dev;
        __s32                   *array = NULL;
@@ -2918,8 +2919,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
        __u32                   mtu = dev->mtu;
        struct ifla_cacheinfo   ci;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
-       if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
        r = NLMSG_DATA(nlh);
        r->ifi_family = AF_INET6;
        r->ifi_type = dev->type;
@@ -2986,7 +2986,7 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
                if ((idev = in6_dev_get(dev)) == NULL)
                        continue;
                err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, 
-                               cb->nlh->nlmsg_seq, RTM_NEWLINK);
+                               cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI);
                in6_dev_put(idev);
                if (err <= 0)
                        break;
@@ -3008,7 +3008,7 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, ENOBUFS);
                return;
        }
-       if (inet6_fill_ifinfo(skb, idev, 0, 0, event) < 0) {
+       if (inet6_fill_ifinfo(skb, idev, 0, 0, event, 0) < 0) {
                kfree_skb(skb);
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, EINVAL);
                return;
@@ -3018,18 +3018,15 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
 }
 
 static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
-                       struct prefix_info *pinfo, u32 pid, u32 seq, int event)
+                       struct prefix_info *pinfo, u32 pid, u32 seq, 
+                       int event, unsigned int flags)
 {
        struct prefixmsg        *pmsg;
        struct nlmsghdr         *nlh;
        unsigned char           *b = skb->tail;
        struct prefix_cacheinfo ci;
 
-       nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*pmsg));
-       
-       if (pid) 
-               nlh->nlmsg_flags |= NLM_F_MULTI;
-       
+       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags);
        pmsg = NLMSG_DATA(nlh);
        pmsg->prefix_family = AF_INET6;
        pmsg->prefix_ifindex = idev->dev->ifindex;
@@ -3068,7 +3065,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, ENOBUFS);
                return;
        }
-       if (inet6_fill_prefix(skb, idev, pinfo, 0, 0, event) < 0) {
+       if (inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0) < 0) {
                kfree_skb(skb);
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, EINVAL);
                return;
index 3bf8a02..1f5b226 100644 (file)
@@ -1570,7 +1570,8 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
                         struct in6_addr *src,
                         int iif,
                         int type, u32 pid, u32 seq,
-                        struct nlmsghdr *in_nlh, int prefix)
+                        struct nlmsghdr *in_nlh, int prefix,
+                        unsigned int flags)
 {
        struct rtmsg *rtm;
        struct nlmsghdr  *nlh;
@@ -1588,7 +1589,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
                pid = in_nlh->nlmsg_pid;
        }
 
-       nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*rtm));
+       nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags);
        rtm = NLMSG_DATA(nlh);
        rtm->rtm_family = AF_INET6;
        rtm->rtm_dst_len = rt->rt6i_dst.plen;
@@ -1674,7 +1675,7 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg)
 
        return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
                     NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
-                    NULL, prefix);
+                    NULL, prefix, NLM_F_MULTI);
 }
 
 static int fib6_dump_node(struct fib6_walker_t *w)
@@ -1822,7 +1823,7 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
                            &fl.fl6_dst, &fl.fl6_src,
                            iif,
                            RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
-                           nlh->nlmsg_seq, nlh, 0);
+                           nlh->nlmsg_seq, nlh, 0, 0);
        if (err < 0) {
                err = -EMSGSIZE;
                goto out_free;
@@ -1848,7 +1849,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh)
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS);
                return;
        }
-       if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0) < 0) {
+       if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0, 0) < 0) {
                kfree_skb(skb);
                netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL);
                return;