diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 13:48:32 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 13:48:32 -0400 |
| commit | d6fb1db02e02aea98f2d7e121fd30e24c84639d6 (patch) | |
| tree | 865546f0388c40d52cf98febe2c6d21039915ea2 /net/netlink/af_netlink.c | |
| parent | b4e6b09738fde057ce885703705f71cc953d0512 (diff) | |
| parent | a1b3f594dc5faab91d3a218c7019e9b5edd9fe1a (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (38 commits)
net: Expose all network devices in a namespaces in sysfs
hotplug: netns aware uevent_helper
kobj: Send hotplug events in the proper namespace.
netlink: Implment netlink_broadcast_filtered
net/sysfs: Fix the bitrot in network device kobject namespace support
netns: Teach network device kobjects which namespace they are in.
kobject: Send hotplug events in all network namespaces
driver-core: fix Typo in drivers/base/core.c for CONFIG_MODULE
pci: check caps from sysfs file open to read device dependent config space
sysfs: add struct file* to bin_attr callbacks
sysfs: Remove usage of S_BIAS to avoid merge conflict with the vfs tree
sysfs: Don't use enums in inline function declaration.
sysfs-namespaces: add a high-level Documentation file
sysfs: Comment sysfs directory tagging logic
driver core: Implement ns directory support for device classes.
sysfs: Implement sysfs_delete_link
sysfs: Add support for tagged directories with untagged members.
sysfs: Implement sysfs tagged directory support.
kobj: Add basic infrastructure for dealing with namespaces.
sysfs: Remove double free sysfs_get_sb
...
Diffstat (limited to 'net/netlink/af_netlink.c')
| -rw-r--r-- | net/netlink/af_netlink.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 6464a1972a69..a2eb965207d3 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -978,6 +978,8 @@ struct netlink_broadcast_data { | |||
| 978 | int delivered; | 978 | int delivered; |
| 979 | gfp_t allocation; | 979 | gfp_t allocation; |
| 980 | struct sk_buff *skb, *skb2; | 980 | struct sk_buff *skb, *skb2; |
| 981 | int (*tx_filter)(struct sock *dsk, struct sk_buff *skb, void *data); | ||
| 982 | void *tx_data; | ||
| 981 | }; | 983 | }; |
| 982 | 984 | ||
| 983 | static inline int do_one_broadcast(struct sock *sk, | 985 | static inline int do_one_broadcast(struct sock *sk, |
| @@ -1020,6 +1022,9 @@ static inline int do_one_broadcast(struct sock *sk, | |||
| 1020 | p->failure = 1; | 1022 | p->failure = 1; |
| 1021 | if (nlk->flags & NETLINK_BROADCAST_SEND_ERROR) | 1023 | if (nlk->flags & NETLINK_BROADCAST_SEND_ERROR) |
| 1022 | p->delivery_failure = 1; | 1024 | p->delivery_failure = 1; |
| 1025 | } else if (p->tx_filter && p->tx_filter(sk, p->skb2, p->tx_data)) { | ||
| 1026 | kfree_skb(p->skb2); | ||
| 1027 | p->skb2 = NULL; | ||
| 1023 | } else if (sk_filter(sk, p->skb2)) { | 1028 | } else if (sk_filter(sk, p->skb2)) { |
| 1024 | kfree_skb(p->skb2); | 1029 | kfree_skb(p->skb2); |
| 1025 | p->skb2 = NULL; | 1030 | p->skb2 = NULL; |
| @@ -1038,8 +1043,10 @@ out: | |||
| 1038 | return 0; | 1043 | return 0; |
| 1039 | } | 1044 | } |
| 1040 | 1045 | ||
| 1041 | int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | 1046 | int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, u32 pid, |
| 1042 | u32 group, gfp_t allocation) | 1047 | u32 group, gfp_t allocation, |
| 1048 | int (*filter)(struct sock *dsk, struct sk_buff *skb, void *data), | ||
| 1049 | void *filter_data) | ||
| 1043 | { | 1050 | { |
| 1044 | struct net *net = sock_net(ssk); | 1051 | struct net *net = sock_net(ssk); |
| 1045 | struct netlink_broadcast_data info; | 1052 | struct netlink_broadcast_data info; |
| @@ -1059,6 +1066,8 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | |||
| 1059 | info.allocation = allocation; | 1066 | info.allocation = allocation; |
| 1060 | info.skb = skb; | 1067 | info.skb = skb; |
| 1061 | info.skb2 = NULL; | 1068 | info.skb2 = NULL; |
| 1069 | info.tx_filter = filter; | ||
| 1070 | info.tx_data = filter_data; | ||
| 1062 | 1071 | ||
| 1063 | /* While we sleep in clone, do not allow to change socket list */ | 1072 | /* While we sleep in clone, do not allow to change socket list */ |
| 1064 | 1073 | ||
| @@ -1083,6 +1092,14 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | |||
| 1083 | } | 1092 | } |
| 1084 | return -ESRCH; | 1093 | return -ESRCH; |
| 1085 | } | 1094 | } |
| 1095 | EXPORT_SYMBOL(netlink_broadcast_filtered); | ||
| 1096 | |||
| 1097 | int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | ||
| 1098 | u32 group, gfp_t allocation) | ||
| 1099 | { | ||
| 1100 | return netlink_broadcast_filtered(ssk, skb, pid, group, allocation, | ||
| 1101 | NULL, NULL); | ||
| 1102 | } | ||
| 1086 | EXPORT_SYMBOL(netlink_broadcast); | 1103 | EXPORT_SYMBOL(netlink_broadcast); |
| 1087 | 1104 | ||
| 1088 | struct netlink_set_err_data { | 1105 | struct netlink_set_err_data { |
