aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-02-25 02:18:28 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-25 02:18:28 -0500
commit1ce85fe402137824246bad03ff85f3913d565c17 (patch)
tree3a54c150e9616709a8f65270cd1f4aeecac4d48e /net/ipv6/addrconf.c
parent4fb0a54a55d34c28dc53c39567ce171166572699 (diff)
netlink: change nlmsg_notify() return value logic
This patch changes the return value of nlmsg_notify() as follows: If NETLINK_BROADCAST_ERROR is set by any of the listeners and an error in the delivery happened, return the broadcast error; else if there are no listeners apart from the socket that requested a change with the echo flag, return the result of the unicast notification. Thus, with this patch, the unicast notification is handled in the same way of a broadcast listener that has set the NETLINK_BROADCAST_ERROR socket flag. This patch is useful in case that the caller of nlmsg_notify() wants to know the result of the delivery of a netlink notification (including the broadcast delivery) and take any action in case that the delivery failed. For example, ctnetlink can drop packets if the event delivery failed to provide reliable logging and state-synchronization at the cost of dropping packets. This patch also modifies the rtnetlink code to ignore the return value of rtnl_notify() in all callers. The function rtnl_notify() (before this patch) returned the error of the unicast notification which makes rtnl_set_sk_err() reports errors to all listeners. This is not of any help since the origin of the change (the socket that requested the echoing) notices the ENOBUFS error if the notification fails and should resync itself. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Acked-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 03e2a1ad71e9..f8f76d6e21cb 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3638,7 +3638,8 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
3638 kfree_skb(skb); 3638 kfree_skb(skb);
3639 goto errout; 3639 goto errout;
3640 } 3640 }
3641 err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3641 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3642 return;
3642errout: 3643errout:
3643 if (err < 0) 3644 if (err < 0)
3644 rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); 3645 rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
@@ -3849,7 +3850,8 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
3849 kfree_skb(skb); 3850 kfree_skb(skb);
3850 goto errout; 3851 goto errout;
3851 } 3852 }
3852 err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3853 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3854 return;
3853errout: 3855errout:
3854 if (err < 0) 3856 if (err < 0)
3855 rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); 3857 rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
@@ -3919,7 +3921,8 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3919 kfree_skb(skb); 3921 kfree_skb(skb);
3920 goto errout; 3922 goto errout;
3921 } 3923 }
3922 err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); 3924 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
3925 return;
3923errout: 3926errout:
3924 if (err < 0) 3927 if (err < 0)
3925 rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err); 3928 rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err);