diff options
author | Jamal Hadi Salim <hadi@cyberus.ca> | 2005-06-19 01:54:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-19 01:54:12 -0400 |
commit | b6544c0b4cf2bd96195f3cdb7cebfb35090fc557 (patch) | |
tree | 717f69a0c204b12eeedb8035fb66c8e9bb2d5a09 /net | |
parent | 1797754ea7ee5e0d859b0a32506ff999f8d5fb71 (diff) |
[NETLINK]: Correctly set NLM_F_MULTI without checking the pid
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/neighbour.c | 14 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 13 | ||||
-rw-r--r-- | net/decnet/dn_dev.c | 9 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 11 | ||||
-rw-r--r-- | net/decnet/dn_rules.c | 7 | ||||
-rw-r--r-- | net/decnet/dn_table.c | 8 | ||||
-rw-r--r-- | net/ipv4/devinet.c | 9 | ||||
-rw-r--r-- | net/ipv4/fib_hash.c | 3 | ||||
-rw-r--r-- | net/ipv4/fib_lookup.h | 3 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 7 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 6 | ||||
-rw-r--r-- | net/ipv4/route.c | 11 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 49 | ||||
-rw-r--r-- | net/ipv6/route.c | 11 |
14 files changed, 83 insertions, 78 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 0fb742e228cc..f6bdcad47da6 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1859,18 +1859,17 @@ out: | |||
1859 | } | 1859 | } |
1860 | 1860 | ||
1861 | static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, | 1861 | static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, |
1862 | u32 pid, u32 seq, int event) | 1862 | u32 pid, u32 seq, int event, unsigned int flags) |
1863 | { | 1863 | { |
1864 | unsigned long now = jiffies; | 1864 | unsigned long now = jiffies; |
1865 | unsigned char *b = skb->tail; | 1865 | unsigned char *b = skb->tail; |
1866 | struct nda_cacheinfo ci; | 1866 | struct nda_cacheinfo ci; |
1867 | int locked = 0; | 1867 | int locked = 0; |
1868 | u32 probes; | 1868 | u32 probes; |
1869 | struct nlmsghdr *nlh = NLMSG_PUT(skb, pid, seq, event, | 1869 | struct nlmsghdr *nlh = NLMSG_NEW(skb, pid, seq, event, |
1870 | sizeof(struct ndmsg)); | 1870 | sizeof(struct ndmsg), flags); |
1871 | struct ndmsg *ndm = NLMSG_DATA(nlh); | 1871 | struct ndmsg *ndm = NLMSG_DATA(nlh); |
1872 | 1872 | ||
1873 | nlh->nlmsg_flags = pid ? NLM_F_MULTI : 0; | ||
1874 | ndm->ndm_family = n->ops->family; | 1873 | ndm->ndm_family = n->ops->family; |
1875 | ndm->ndm_flags = n->flags; | 1874 | ndm->ndm_flags = n->flags; |
1876 | ndm->ndm_type = n->type; | 1875 | ndm->ndm_type = n->type; |
@@ -1920,7 +1919,8 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, | |||
1920 | continue; | 1919 | continue; |
1921 | if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid, | 1920 | if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid, |
1922 | cb->nlh->nlmsg_seq, | 1921 | cb->nlh->nlmsg_seq, |
1923 | RTM_NEWNEIGH) <= 0) { | 1922 | RTM_NEWNEIGH, |
1923 | NLM_F_MULTI) <= 0) { | ||
1924 | read_unlock_bh(&tbl->lock); | 1924 | read_unlock_bh(&tbl->lock); |
1925 | rc = -1; | 1925 | rc = -1; |
1926 | goto out; | 1926 | goto out; |
@@ -2329,7 +2329,7 @@ void neigh_app_ns(struct neighbour *n) | |||
2329 | if (!skb) | 2329 | if (!skb) |
2330 | return; | 2330 | return; |
2331 | 2331 | ||
2332 | if (neigh_fill_info(skb, n, 0, 0, RTM_GETNEIGH) < 0) { | 2332 | if (neigh_fill_info(skb, n, 0, 0, RTM_GETNEIGH, 0) < 0) { |
2333 | kfree_skb(skb); | 2333 | kfree_skb(skb); |
2334 | return; | 2334 | return; |
2335 | } | 2335 | } |
@@ -2348,7 +2348,7 @@ static void neigh_app_notify(struct neighbour *n) | |||
2348 | if (!skb) | 2348 | if (!skb) |
2349 | return; | 2349 | return; |
2350 | 2350 | ||
2351 | if (neigh_fill_info(skb, n, 0, 0, RTM_NEWNEIGH) < 0) { | 2351 | if (neigh_fill_info(skb, n, 0, 0, RTM_NEWNEIGH, 0) < 0) { |
2352 | kfree_skb(skb); | 2352 | kfree_skb(skb); |
2353 | return; | 2353 | return; |
2354 | } | 2354 | } |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 56a20f014b8a..63bd88665182 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -178,14 +178,14 @@ rtattr_failure: | |||
178 | 178 | ||
179 | 179 | ||
180 | static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | 180 | static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, |
181 | int type, u32 pid, u32 seq, u32 change) | 181 | int type, u32 pid, u32 seq, u32 change, |
182 | unsigned int flags) | ||
182 | { | 183 | { |
183 | struct ifinfomsg *r; | 184 | struct ifinfomsg *r; |
184 | struct nlmsghdr *nlh; | 185 | struct nlmsghdr *nlh; |
185 | unsigned char *b = skb->tail; | 186 | unsigned char *b = skb->tail; |
186 | 187 | ||
187 | nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*r)); | 188 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); |
188 | if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; | ||
189 | r = NLMSG_DATA(nlh); | 189 | r = NLMSG_DATA(nlh); |
190 | r->ifi_family = AF_UNSPEC; | 190 | r->ifi_family = AF_UNSPEC; |
191 | r->ifi_type = dev->type; | 191 | r->ifi_type = dev->type; |
@@ -275,7 +275,10 @@ static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *c | |||
275 | for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { | 275 | for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { |
276 | if (idx < s_idx) | 276 | if (idx < s_idx) |
277 | continue; | 277 | continue; |
278 | if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0) <= 0) | 278 | if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, |
279 | NETLINK_CB(cb->skb).pid, | ||
280 | cb->nlh->nlmsg_seq, 0, | ||
281 | NLM_F_MULTI) <= 0) | ||
279 | break; | 282 | break; |
280 | } | 283 | } |
281 | read_unlock(&dev_base_lock); | 284 | read_unlock(&dev_base_lock); |
@@ -449,7 +452,7 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) | |||
449 | if (!skb) | 452 | if (!skb) |
450 | return; | 453 | return; |
451 | 454 | ||
452 | if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change) < 0) { | 455 | if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change, 0) < 0) { |
453 | kfree_skb(skb); | 456 | kfree_skb(skb); |
454 | return; | 457 | return; |
455 | } | 458 | } |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index ee7bf46eb78a..00233ecbc9cb 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -716,13 +716,13 @@ static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *a | |||
716 | } | 716 | } |
717 | 717 | ||
718 | static int dn_dev_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, | 718 | static int dn_dev_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, |
719 | u32 pid, u32 seq, int event) | 719 | u32 pid, u32 seq, int event, unsigned int flags) |
720 | { | 720 | { |
721 | struct ifaddrmsg *ifm; | 721 | struct ifaddrmsg *ifm; |
722 | struct nlmsghdr *nlh; | 722 | struct nlmsghdr *nlh; |
723 | unsigned char *b = skb->tail; | 723 | unsigned char *b = skb->tail; |
724 | 724 | ||
725 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); | 725 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); |
726 | ifm = NLMSG_DATA(nlh); | 726 | ifm = NLMSG_DATA(nlh); |
727 | 727 | ||
728 | ifm->ifa_family = AF_DECnet; | 728 | ifm->ifa_family = AF_DECnet; |
@@ -755,7 +755,7 @@ static void rtmsg_ifa(int event, struct dn_ifaddr *ifa) | |||
755 | netlink_set_err(rtnl, 0, RTMGRP_DECnet_IFADDR, ENOBUFS); | 755 | netlink_set_err(rtnl, 0, RTMGRP_DECnet_IFADDR, ENOBUFS); |
756 | return; | 756 | return; |
757 | } | 757 | } |
758 | if (dn_dev_fill_ifaddr(skb, ifa, 0, 0, event) < 0) { | 758 | if (dn_dev_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) { |
759 | kfree_skb(skb); | 759 | kfree_skb(skb); |
760 | netlink_set_err(rtnl, 0, RTMGRP_DECnet_IFADDR, EINVAL); | 760 | netlink_set_err(rtnl, 0, RTMGRP_DECnet_IFADDR, EINVAL); |
761 | return; | 761 | return; |
@@ -790,7 +790,8 @@ static int dn_dev_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | |||
790 | if (dn_dev_fill_ifaddr(skb, ifa, | 790 | if (dn_dev_fill_ifaddr(skb, ifa, |
791 | NETLINK_CB(cb->skb).pid, | 791 | NETLINK_CB(cb->skb).pid, |
792 | cb->nlh->nlmsg_seq, | 792 | cb->nlh->nlmsg_seq, |
793 | RTM_NEWADDR) <= 0) | 793 | RTM_NEWADDR, |
794 | NLM_F_MULTI) <= 0) | ||
794 | goto done; | 795 | goto done; |
795 | } | 796 | } |
796 | } | 797 | } |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 1e7b5c3ea215..2399fa8a3f86 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -1465,7 +1465,8 @@ int dn_route_input(struct sk_buff *skb) | |||
1465 | return dn_route_input_slow(skb); | 1465 | return dn_route_input_slow(skb); |
1466 | } | 1466 | } |
1467 | 1467 | ||
1468 | static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int nowait) | 1468 | static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, |
1469 | int event, int nowait, unsigned int flags) | ||
1469 | { | 1470 | { |
1470 | struct dn_route *rt = (struct dn_route *)skb->dst; | 1471 | struct dn_route *rt = (struct dn_route *)skb->dst; |
1471 | struct rtmsg *r; | 1472 | struct rtmsg *r; |
@@ -1473,9 +1474,8 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int | |||
1473 | unsigned char *b = skb->tail; | 1474 | unsigned char *b = skb->tail; |
1474 | struct rta_cacheinfo ci; | 1475 | struct rta_cacheinfo ci; |
1475 | 1476 | ||
1476 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r)); | 1477 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); |
1477 | r = NLMSG_DATA(nlh); | 1478 | r = NLMSG_DATA(nlh); |
1478 | nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0; | ||
1479 | r->rtm_family = AF_DECnet; | 1479 | r->rtm_family = AF_DECnet; |
1480 | r->rtm_dst_len = 16; | 1480 | r->rtm_dst_len = 16; |
1481 | r->rtm_src_len = 0; | 1481 | r->rtm_src_len = 0; |
@@ -1596,7 +1596,7 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg) | |||
1596 | 1596 | ||
1597 | NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; | 1597 | NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; |
1598 | 1598 | ||
1599 | err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0); | 1599 | err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0); |
1600 | 1600 | ||
1601 | if (err == 0) | 1601 | if (err == 0) |
1602 | goto out_free; | 1602 | goto out_free; |
@@ -1644,7 +1644,8 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1644 | continue; | 1644 | continue; |
1645 | skb->dst = dst_clone(&rt->u.dst); | 1645 | skb->dst = dst_clone(&rt->u.dst); |
1646 | if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).pid, | 1646 | if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).pid, |
1647 | cb->nlh->nlmsg_seq, RTM_NEWROUTE, 1) <= 0) { | 1647 | cb->nlh->nlmsg_seq, RTM_NEWROUTE, |
1648 | 1, NLM_F_MULTI) <= 0) { | ||
1648 | dst_release(xchg(&skb->dst, NULL)); | 1649 | dst_release(xchg(&skb->dst, NULL)); |
1649 | rcu_read_unlock_bh(); | 1650 | rcu_read_unlock_bh(); |
1650 | goto done; | 1651 | goto done; |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 597587d170d8..1060de70bc0c 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -342,14 +342,15 @@ static struct notifier_block dn_fib_rules_notifier = { | |||
342 | .notifier_call = dn_fib_rules_event, | 342 | .notifier_call = dn_fib_rules_event, |
343 | }; | 343 | }; |
344 | 344 | ||
345 | static int dn_fib_fill_rule(struct sk_buff *skb, struct dn_fib_rule *r, struct netlink_callback *cb) | 345 | static int dn_fib_fill_rule(struct sk_buff *skb, struct dn_fib_rule *r, |
346 | struct netlink_callback *cb, unsigned int flags) | ||
346 | { | 347 | { |
347 | struct rtmsg *rtm; | 348 | struct rtmsg *rtm; |
348 | struct nlmsghdr *nlh; | 349 | struct nlmsghdr *nlh; |
349 | unsigned char *b = skb->tail; | 350 | unsigned char *b = skb->tail; |
350 | 351 | ||
351 | 352 | ||
352 | nlh = NLMSG_PUT(skb, NETLINK_CREDS(cb->skb)->pid, cb->nlh->nlmsg_seq, RTM_NEWRULE, sizeof(*rtm)); | 353 | nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags); |
353 | rtm = NLMSG_DATA(nlh); | 354 | rtm = NLMSG_DATA(nlh); |
354 | rtm->rtm_family = AF_DECnet; | 355 | rtm->rtm_family = AF_DECnet; |
355 | rtm->rtm_dst_len = r->r_dst_len; | 356 | 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) | |||
394 | for(r = dn_fib_rules, idx = 0; r; r = r->r_next, idx++) { | 395 | for(r = dn_fib_rules, idx = 0; r; r = r->r_next, idx++) { |
395 | if (idx < s_idx) | 396 | if (idx < s_idx) |
396 | continue; | 397 | continue; |
397 | if (dn_fib_fill_rule(skb, r, cb) < 0) | 398 | if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0) |
398 | break; | 399 | break; |
399 | } | 400 | } |
400 | read_unlock(&dn_fib_rules_lock); | 401 | read_unlock(&dn_fib_rules_lock); |
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index dad5603912be..28ba5777a25a 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c | |||
@@ -270,13 +270,13 @@ static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct dn_kern | |||
270 | 270 | ||
271 | static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | 271 | static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, |
272 | u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, | 272 | u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, |
273 | struct dn_fib_info *fi) | 273 | struct dn_fib_info *fi, unsigned int flags) |
274 | { | 274 | { |
275 | struct rtmsg *rtm; | 275 | struct rtmsg *rtm; |
276 | struct nlmsghdr *nlh; | 276 | struct nlmsghdr *nlh; |
277 | unsigned char *b = skb->tail; | 277 | unsigned char *b = skb->tail; |
278 | 278 | ||
279 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*rtm)); | 279 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags); |
280 | rtm = NLMSG_DATA(nlh); | 280 | rtm = NLMSG_DATA(nlh); |
281 | rtm->rtm_family = AF_DECnet; | 281 | rtm->rtm_family = AF_DECnet; |
282 | rtm->rtm_dst_len = dst_len; | 282 | 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, | |||
345 | 345 | ||
346 | if (dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, | 346 | if (dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, |
347 | f->fn_type, f->fn_scope, &f->fn_key, z, | 347 | f->fn_type, f->fn_scope, &f->fn_key, z, |
348 | DN_FIB_INFO(f)) < 0) { | 348 | DN_FIB_INFO(f), 0) < 0) { |
349 | kfree_skb(skb); | 349 | kfree_skb(skb); |
350 | return; | 350 | return; |
351 | } | 351 | } |
@@ -377,7 +377,7 @@ static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb, | |||
377 | tb->n, | 377 | tb->n, |
378 | (f->fn_state & DN_S_ZOMBIE) ? 0 : f->fn_type, | 378 | (f->fn_state & DN_S_ZOMBIE) ? 0 : f->fn_type, |
379 | f->fn_scope, &f->fn_key, dz->dz_order, | 379 | f->fn_scope, &f->fn_key, dz->dz_order, |
380 | f->fn_info) < 0) { | 380 | f->fn_info, NLM_F_MULTI) < 0) { |
381 | cb->args[3] = i; | 381 | cb->args[3] = i; |
382 | return -1; | 382 | return -1; |
383 | } | 383 | } |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 478a30179a52..fd47a1e890fa 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1030,14 +1030,13 @@ static struct notifier_block ip_netdev_notifier = { | |||
1030 | }; | 1030 | }; |
1031 | 1031 | ||
1032 | static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, | 1032 | static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, |
1033 | u32 pid, u32 seq, int event) | 1033 | u32 pid, u32 seq, int event, unsigned int flags) |
1034 | { | 1034 | { |
1035 | struct ifaddrmsg *ifm; | 1035 | struct ifaddrmsg *ifm; |
1036 | struct nlmsghdr *nlh; | 1036 | struct nlmsghdr *nlh; |
1037 | unsigned char *b = skb->tail; | 1037 | unsigned char *b = skb->tail; |
1038 | 1038 | ||
1039 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); | 1039 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); |
1040 | if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; | ||
1041 | ifm = NLMSG_DATA(nlh); | 1040 | ifm = NLMSG_DATA(nlh); |
1042 | ifm->ifa_family = AF_INET; | 1041 | ifm->ifa_family = AF_INET; |
1043 | ifm->ifa_prefixlen = ifa->ifa_prefixlen; | 1042 | ifm->ifa_prefixlen = ifa->ifa_prefixlen; |
@@ -1090,7 +1089,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | |||
1090 | continue; | 1089 | continue; |
1091 | if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, | 1090 | if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, |
1092 | cb->nlh->nlmsg_seq, | 1091 | cb->nlh->nlmsg_seq, |
1093 | RTM_NEWADDR) <= 0) { | 1092 | RTM_NEWADDR, NLM_F_MULTI) <= 0) { |
1094 | rcu_read_unlock(); | 1093 | rcu_read_unlock(); |
1095 | goto done; | 1094 | goto done; |
1096 | } | 1095 | } |
@@ -1113,7 +1112,7 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa) | |||
1113 | 1112 | ||
1114 | if (!skb) | 1113 | if (!skb) |
1115 | netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS); | 1114 | netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS); |
1116 | else if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) { | 1115 | else if (inet_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) { |
1117 | kfree_skb(skb); | 1116 | kfree_skb(skb); |
1118 | netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL); | 1117 | netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL); |
1119 | } else { | 1118 | } else { |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 6506dcc01b46..b10d6bb5ef3d 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
@@ -703,7 +703,8 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, | |||
703 | &f->fn_key, | 703 | &f->fn_key, |
704 | fz->fz_order, | 704 | fz->fz_order, |
705 | fa->fa_tos, | 705 | fa->fa_tos, |
706 | fa->fa_info) < 0) { | 706 | fa->fa_info, |
707 | NLM_F_MULTI) < 0) { | ||
707 | cb->args[3] = i; | 708 | cb->args[3] = i; |
708 | return -1; | 709 | return -1; |
709 | } | 710 | } |
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index ac4485f75e97..b729d97cfa93 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h | |||
@@ -30,7 +30,8 @@ extern int fib_nh_match(struct rtmsg *r, struct nlmsghdr *, | |||
30 | struct kern_rta *rta, struct fib_info *fi); | 30 | struct kern_rta *rta, struct fib_info *fi); |
31 | extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | 31 | extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, |
32 | u8 tb_id, u8 type, u8 scope, void *dst, | 32 | u8 tb_id, u8 type, u8 scope, void *dst, |
33 | int dst_len, u8 tos, struct fib_info *fi); | 33 | int dst_len, u8 tos, struct fib_info *fi, |
34 | unsigned int); | ||
34 | extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa, | 35 | extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa, |
35 | int z, int tb_id, | 36 | int z, int tb_id, |
36 | struct nlmsghdr *n, struct netlink_skb_parms *req); | 37 | struct nlmsghdr *n, struct netlink_skb_parms *req); |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 39d0aadb9a2a..0b298bbc1518 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -367,13 +367,14 @@ static struct notifier_block fib_rules_notifier = { | |||
367 | 367 | ||
368 | static __inline__ int inet_fill_rule(struct sk_buff *skb, | 368 | static __inline__ int inet_fill_rule(struct sk_buff *skb, |
369 | struct fib_rule *r, | 369 | struct fib_rule *r, |
370 | struct netlink_callback *cb) | 370 | struct netlink_callback *cb, |
371 | unsigned int flags) | ||
371 | { | 372 | { |
372 | struct rtmsg *rtm; | 373 | struct rtmsg *rtm; |
373 | struct nlmsghdr *nlh; | 374 | struct nlmsghdr *nlh; |
374 | unsigned char *b = skb->tail; | 375 | unsigned char *b = skb->tail; |
375 | 376 | ||
376 | nlh = NLMSG_PUT(skb, NETLINK_CREDS(cb->skb)->pid, cb->nlh->nlmsg_seq, RTM_NEWRULE, sizeof(*rtm)); | 377 | nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags); |
377 | rtm = NLMSG_DATA(nlh); | 378 | rtm = NLMSG_DATA(nlh); |
378 | rtm->rtm_family = AF_INET; | 379 | rtm->rtm_family = AF_INET; |
379 | rtm->rtm_dst_len = r->r_dst_len; | 380 | rtm->rtm_dst_len = r->r_dst_len; |
@@ -422,7 +423,7 @@ int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb) | |||
422 | for (r=fib_rules, idx=0; r; r = r->r_next, idx++) { | 423 | for (r=fib_rules, idx=0; r; r = r->r_next, idx++) { |
423 | if (idx < s_idx) | 424 | if (idx < s_idx) |
424 | continue; | 425 | continue; |
425 | if (inet_fill_rule(skb, r, cb) < 0) | 426 | if (inet_fill_rule(skb, r, cb, NLM_F_MULTI) < 0) |
426 | break; | 427 | break; |
427 | } | 428 | } |
428 | read_unlock(&fib_rules_lock); | 429 | read_unlock(&fib_rules_lock); |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 029362d66135..a9a44b4bef46 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -286,7 +286,7 @@ void rtmsg_fib(int event, u32 key, struct fib_alias *fa, | |||
286 | if (fib_dump_info(skb, pid, n->nlmsg_seq, event, tb_id, | 286 | if (fib_dump_info(skb, pid, n->nlmsg_seq, event, tb_id, |
287 | fa->fa_type, fa->fa_scope, &key, z, | 287 | fa->fa_type, fa->fa_scope, &key, z, |
288 | fa->fa_tos, | 288 | fa->fa_tos, |
289 | fa->fa_info) < 0) { | 289 | fa->fa_info, 0) < 0) { |
290 | kfree_skb(skb); | 290 | kfree_skb(skb); |
291 | return; | 291 | return; |
292 | } | 292 | } |
@@ -932,13 +932,13 @@ u32 __fib_res_prefsrc(struct fib_result *res) | |||
932 | int | 932 | int |
933 | fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | 933 | fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, |
934 | u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos, | 934 | u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos, |
935 | struct fib_info *fi) | 935 | struct fib_info *fi, unsigned int flags) |
936 | { | 936 | { |
937 | struct rtmsg *rtm; | 937 | struct rtmsg *rtm; |
938 | struct nlmsghdr *nlh; | 938 | struct nlmsghdr *nlh; |
939 | unsigned char *b = skb->tail; | 939 | unsigned char *b = skb->tail; |
940 | 940 | ||
941 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*rtm)); | 941 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags); |
942 | rtm = NLMSG_DATA(nlh); | 942 | rtm = NLMSG_DATA(nlh); |
943 | rtm->rtm_family = AF_INET; | 943 | rtm->rtm_family = AF_INET; |
944 | rtm->rtm_dst_len = dst_len; | 944 | rtm->rtm_dst_len = dst_len; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a682d28e247b..f4d53c919869 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2581,7 +2581,7 @@ int ip_route_output_key(struct rtable **rp, struct flowi *flp) | |||
2581 | } | 2581 | } |
2582 | 2582 | ||
2583 | static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | 2583 | static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, |
2584 | int nowait) | 2584 | int nowait, unsigned int flags) |
2585 | { | 2585 | { |
2586 | struct rtable *rt = (struct rtable*)skb->dst; | 2586 | struct rtable *rt = (struct rtable*)skb->dst; |
2587 | struct rtmsg *r; | 2587 | struct rtmsg *r; |
@@ -2591,9 +2591,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
2591 | #ifdef CONFIG_IP_MROUTE | 2591 | #ifdef CONFIG_IP_MROUTE |
2592 | struct rtattr *eptr; | 2592 | struct rtattr *eptr; |
2593 | #endif | 2593 | #endif |
2594 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r)); | 2594 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); |
2595 | r = NLMSG_DATA(nlh); | 2595 | r = NLMSG_DATA(nlh); |
2596 | nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0; | ||
2597 | r->rtm_family = AF_INET; | 2596 | r->rtm_family = AF_INET; |
2598 | r->rtm_dst_len = 32; | 2597 | r->rtm_dst_len = 32; |
2599 | r->rtm_src_len = 0; | 2598 | r->rtm_src_len = 0; |
@@ -2744,7 +2743,7 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) | |||
2744 | NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; | 2743 | NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; |
2745 | 2744 | ||
2746 | err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, | 2745 | err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, |
2747 | RTM_NEWROUTE, 0); | 2746 | RTM_NEWROUTE, 0, 0); |
2748 | if (!err) | 2747 | if (!err) |
2749 | goto out_free; | 2748 | goto out_free; |
2750 | if (err < 0) { | 2749 | if (err < 0) { |
@@ -2781,8 +2780,8 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
2781 | continue; | 2780 | continue; |
2782 | skb->dst = dst_clone(&rt->u.dst); | 2781 | skb->dst = dst_clone(&rt->u.dst); |
2783 | if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid, | 2782 | if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid, |
2784 | cb->nlh->nlmsg_seq, | 2783 | cb->nlh->nlmsg_seq, RTM_NEWROUTE, |
2785 | RTM_NEWROUTE, 1) <= 0) { | 2784 | 1, NLM_F_MULTI) <= 0) { |
2786 | dst_release(xchg(&skb->dst, NULL)); | 2785 | dst_release(xchg(&skb->dst, NULL)); |
2787 | rcu_read_unlock_bh(); | 2786 | rcu_read_unlock_bh(); |
2788 | goto done; | 2787 | goto done; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2720899d516c..cdd19c54c03f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2622,15 +2622,14 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2622 | } | 2622 | } |
2623 | 2623 | ||
2624 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | 2624 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, |
2625 | u32 pid, u32 seq, int event) | 2625 | u32 pid, u32 seq, int event, unsigned int flags) |
2626 | { | 2626 | { |
2627 | struct ifaddrmsg *ifm; | 2627 | struct ifaddrmsg *ifm; |
2628 | struct nlmsghdr *nlh; | 2628 | struct nlmsghdr *nlh; |
2629 | struct ifa_cacheinfo ci; | 2629 | struct ifa_cacheinfo ci; |
2630 | unsigned char *b = skb->tail; | 2630 | unsigned char *b = skb->tail; |
2631 | 2631 | ||
2632 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); | 2632 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); |
2633 | if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; | ||
2634 | ifm = NLMSG_DATA(nlh); | 2633 | ifm = NLMSG_DATA(nlh); |
2635 | ifm->ifa_family = AF_INET6; | 2634 | ifm->ifa_family = AF_INET6; |
2636 | ifm->ifa_prefixlen = ifa->prefix_len; | 2635 | ifm->ifa_prefixlen = ifa->prefix_len; |
@@ -2672,15 +2671,14 @@ rtattr_failure: | |||
2672 | } | 2671 | } |
2673 | 2672 | ||
2674 | static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, | 2673 | static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, |
2675 | u32 pid, u32 seq, int event) | 2674 | u32 pid, u32 seq, int event, unsigned flags) |
2676 | { | 2675 | { |
2677 | struct ifaddrmsg *ifm; | 2676 | struct ifaddrmsg *ifm; |
2678 | struct nlmsghdr *nlh; | 2677 | struct nlmsghdr *nlh; |
2679 | struct ifa_cacheinfo ci; | 2678 | struct ifa_cacheinfo ci; |
2680 | unsigned char *b = skb->tail; | 2679 | unsigned char *b = skb->tail; |
2681 | 2680 | ||
2682 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); | 2681 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); |
2683 | if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; | ||
2684 | ifm = NLMSG_DATA(nlh); | 2682 | ifm = NLMSG_DATA(nlh); |
2685 | ifm->ifa_family = AF_INET6; | 2683 | ifm->ifa_family = AF_INET6; |
2686 | ifm->ifa_prefixlen = 128; | 2684 | ifm->ifa_prefixlen = 128; |
@@ -2709,15 +2707,14 @@ rtattr_failure: | |||
2709 | } | 2707 | } |
2710 | 2708 | ||
2711 | static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, | 2709 | static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, |
2712 | u32 pid, u32 seq, int event) | 2710 | u32 pid, u32 seq, int event, unsigned int flags) |
2713 | { | 2711 | { |
2714 | struct ifaddrmsg *ifm; | 2712 | struct ifaddrmsg *ifm; |
2715 | struct nlmsghdr *nlh; | 2713 | struct nlmsghdr *nlh; |
2716 | struct ifa_cacheinfo ci; | 2714 | struct ifa_cacheinfo ci; |
2717 | unsigned char *b = skb->tail; | 2715 | unsigned char *b = skb->tail; |
2718 | 2716 | ||
2719 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); | 2717 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); |
2720 | if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; | ||
2721 | ifm = NLMSG_DATA(nlh); | 2718 | ifm = NLMSG_DATA(nlh); |
2722 | ifm->ifa_family = AF_INET6; | 2719 | ifm->ifa_family = AF_INET6; |
2723 | ifm->ifa_prefixlen = 128; | 2720 | ifm->ifa_prefixlen = 128; |
@@ -2786,7 +2783,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
2786 | continue; | 2783 | continue; |
2787 | if ((err = inet6_fill_ifaddr(skb, ifa, | 2784 | if ((err = inet6_fill_ifaddr(skb, ifa, |
2788 | NETLINK_CB(cb->skb).pid, | 2785 | NETLINK_CB(cb->skb).pid, |
2789 | cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) | 2786 | cb->nlh->nlmsg_seq, RTM_NEWADDR, |
2787 | NLM_F_MULTI)) <= 0) | ||
2790 | goto done; | 2788 | goto done; |
2791 | } | 2789 | } |
2792 | /* temp addr */ | 2790 | /* temp addr */ |
@@ -2797,7 +2795,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
2797 | continue; | 2795 | continue; |
2798 | if ((err = inet6_fill_ifaddr(skb, ifa, | 2796 | if ((err = inet6_fill_ifaddr(skb, ifa, |
2799 | NETLINK_CB(cb->skb).pid, | 2797 | NETLINK_CB(cb->skb).pid, |
2800 | cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) | 2798 | cb->nlh->nlmsg_seq, RTM_NEWADDR, |
2799 | NLM_F_MULTI)) <= 0) | ||
2801 | goto done; | 2800 | goto done; |
2802 | } | 2801 | } |
2803 | #endif | 2802 | #endif |
@@ -2810,7 +2809,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
2810 | continue; | 2809 | continue; |
2811 | if ((err = inet6_fill_ifmcaddr(skb, ifmca, | 2810 | if ((err = inet6_fill_ifmcaddr(skb, ifmca, |
2812 | NETLINK_CB(cb->skb).pid, | 2811 | NETLINK_CB(cb->skb).pid, |
2813 | cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0) | 2812 | cb->nlh->nlmsg_seq, RTM_GETMULTICAST, |
2813 | NLM_F_MULTI)) <= 0) | ||
2814 | goto done; | 2814 | goto done; |
2815 | } | 2815 | } |
2816 | break; | 2816 | break; |
@@ -2822,7 +2822,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
2822 | continue; | 2822 | continue; |
2823 | if ((err = inet6_fill_ifacaddr(skb, ifaca, | 2823 | if ((err = inet6_fill_ifacaddr(skb, ifaca, |
2824 | NETLINK_CB(cb->skb).pid, | 2824 | NETLINK_CB(cb->skb).pid, |
2825 | cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0) | 2825 | cb->nlh->nlmsg_seq, RTM_GETANYCAST, |
2826 | NLM_F_MULTI)) <= 0) | ||
2826 | goto done; | 2827 | goto done; |
2827 | } | 2828 | } |
2828 | break; | 2829 | break; |
@@ -2872,7 +2873,7 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | |||
2872 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, ENOBUFS); | 2873 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, ENOBUFS); |
2873 | return; | 2874 | return; |
2874 | } | 2875 | } |
2875 | if (inet6_fill_ifaddr(skb, ifa, 0, 0, event) < 0) { | 2876 | if (inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) { |
2876 | kfree_skb(skb); | 2877 | kfree_skb(skb); |
2877 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, EINVAL); | 2878 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, EINVAL); |
2878 | return; | 2879 | return; |
@@ -2907,7 +2908,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
2907 | } | 2908 | } |
2908 | 2909 | ||
2909 | static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, | 2910 | static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, |
2910 | u32 pid, u32 seq, int event) | 2911 | u32 pid, u32 seq, int event, unsigned int flags) |
2911 | { | 2912 | { |
2912 | struct net_device *dev = idev->dev; | 2913 | struct net_device *dev = idev->dev; |
2913 | __s32 *array = NULL; | 2914 | __s32 *array = NULL; |
@@ -2918,8 +2919,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, | |||
2918 | __u32 mtu = dev->mtu; | 2919 | __u32 mtu = dev->mtu; |
2919 | struct ifla_cacheinfo ci; | 2920 | struct ifla_cacheinfo ci; |
2920 | 2921 | ||
2921 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r)); | 2922 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); |
2922 | if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; | ||
2923 | r = NLMSG_DATA(nlh); | 2923 | r = NLMSG_DATA(nlh); |
2924 | r->ifi_family = AF_INET6; | 2924 | r->ifi_family = AF_INET6; |
2925 | r->ifi_type = dev->type; | 2925 | r->ifi_type = dev->type; |
@@ -2986,7 +2986,7 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
2986 | if ((idev = in6_dev_get(dev)) == NULL) | 2986 | if ((idev = in6_dev_get(dev)) == NULL) |
2987 | continue; | 2987 | continue; |
2988 | err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, | 2988 | err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, |
2989 | cb->nlh->nlmsg_seq, RTM_NEWLINK); | 2989 | cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI); |
2990 | in6_dev_put(idev); | 2990 | in6_dev_put(idev); |
2991 | if (err <= 0) | 2991 | if (err <= 0) |
2992 | break; | 2992 | break; |
@@ -3008,7 +3008,7 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | |||
3008 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, ENOBUFS); | 3008 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, ENOBUFS); |
3009 | return; | 3009 | return; |
3010 | } | 3010 | } |
3011 | if (inet6_fill_ifinfo(skb, idev, 0, 0, event) < 0) { | 3011 | if (inet6_fill_ifinfo(skb, idev, 0, 0, event, 0) < 0) { |
3012 | kfree_skb(skb); | 3012 | kfree_skb(skb); |
3013 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, EINVAL); | 3013 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, EINVAL); |
3014 | return; | 3014 | return; |
@@ -3018,18 +3018,15 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | |||
3018 | } | 3018 | } |
3019 | 3019 | ||
3020 | static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, | 3020 | static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, |
3021 | struct prefix_info *pinfo, u32 pid, u32 seq, int event) | 3021 | struct prefix_info *pinfo, u32 pid, u32 seq, |
3022 | int event, unsigned int flags) | ||
3022 | { | 3023 | { |
3023 | struct prefixmsg *pmsg; | 3024 | struct prefixmsg *pmsg; |
3024 | struct nlmsghdr *nlh; | 3025 | struct nlmsghdr *nlh; |
3025 | unsigned char *b = skb->tail; | 3026 | unsigned char *b = skb->tail; |
3026 | struct prefix_cacheinfo ci; | 3027 | struct prefix_cacheinfo ci; |
3027 | 3028 | ||
3028 | nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*pmsg)); | 3029 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); |
3029 | |||
3030 | if (pid) | ||
3031 | nlh->nlmsg_flags |= NLM_F_MULTI; | ||
3032 | |||
3033 | pmsg = NLMSG_DATA(nlh); | 3030 | pmsg = NLMSG_DATA(nlh); |
3034 | pmsg->prefix_family = AF_INET6; | 3031 | pmsg->prefix_family = AF_INET6; |
3035 | pmsg->prefix_ifindex = idev->dev->ifindex; | 3032 | pmsg->prefix_ifindex = idev->dev->ifindex; |
@@ -3068,7 +3065,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3068 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, ENOBUFS); | 3065 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, ENOBUFS); |
3069 | return; | 3066 | return; |
3070 | } | 3067 | } |
3071 | if (inet6_fill_prefix(skb, idev, pinfo, 0, 0, event) < 0) { | 3068 | if (inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0) < 0) { |
3072 | kfree_skb(skb); | 3069 | kfree_skb(skb); |
3073 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, EINVAL); | 3070 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, EINVAL); |
3074 | return; | 3071 | return; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 3bf8a0254f81..1f5b226c3573 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1570,7 +1570,8 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
1570 | struct in6_addr *src, | 1570 | struct in6_addr *src, |
1571 | int iif, | 1571 | int iif, |
1572 | int type, u32 pid, u32 seq, | 1572 | int type, u32 pid, u32 seq, |
1573 | struct nlmsghdr *in_nlh, int prefix) | 1573 | struct nlmsghdr *in_nlh, int prefix, |
1574 | unsigned int flags) | ||
1574 | { | 1575 | { |
1575 | struct rtmsg *rtm; | 1576 | struct rtmsg *rtm; |
1576 | struct nlmsghdr *nlh; | 1577 | struct nlmsghdr *nlh; |
@@ -1588,7 +1589,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
1588 | pid = in_nlh->nlmsg_pid; | 1589 | pid = in_nlh->nlmsg_pid; |
1589 | } | 1590 | } |
1590 | 1591 | ||
1591 | nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*rtm)); | 1592 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags); |
1592 | rtm = NLMSG_DATA(nlh); | 1593 | rtm = NLMSG_DATA(nlh); |
1593 | rtm->rtm_family = AF_INET6; | 1594 | rtm->rtm_family = AF_INET6; |
1594 | rtm->rtm_dst_len = rt->rt6i_dst.plen; | 1595 | rtm->rtm_dst_len = rt->rt6i_dst.plen; |
@@ -1674,7 +1675,7 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg) | |||
1674 | 1675 | ||
1675 | return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, | 1676 | return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, |
1676 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, | 1677 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, |
1677 | NULL, prefix); | 1678 | NULL, prefix, NLM_F_MULTI); |
1678 | } | 1679 | } |
1679 | 1680 | ||
1680 | static int fib6_dump_node(struct fib6_walker_t *w) | 1681 | 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) | |||
1822 | &fl.fl6_dst, &fl.fl6_src, | 1823 | &fl.fl6_dst, &fl.fl6_src, |
1823 | iif, | 1824 | iif, |
1824 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, | 1825 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, |
1825 | nlh->nlmsg_seq, nlh, 0); | 1826 | nlh->nlmsg_seq, nlh, 0, 0); |
1826 | if (err < 0) { | 1827 | if (err < 0) { |
1827 | err = -EMSGSIZE; | 1828 | err = -EMSGSIZE; |
1828 | goto out_free; | 1829 | goto out_free; |
@@ -1848,7 +1849,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh) | |||
1848 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS); | 1849 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS); |
1849 | return; | 1850 | return; |
1850 | } | 1851 | } |
1851 | if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0) < 0) { | 1852 | if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0, 0) < 0) { |
1852 | kfree_skb(skb); | 1853 | kfree_skb(skb); |
1853 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL); | 1854 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL); |
1854 | return; | 1855 | return; |