aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-06-29 02:15:21 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-29 19:46:02 -0400
commita31f2d17b331db970259e875b7223d3aba7e3821 (patch)
tree0d10021be81446ab360f4240b0d16729f518387f
parentdd7f36ba3ce17d4fe85987d83efd5901b0935816 (diff)
netlink: add netlink_kernel_cfg parameter to netlink_kernel_create
This patch adds the following structure: struct netlink_kernel_cfg { unsigned int groups; void (*input)(struct sk_buff *skb); struct mutex *cb_mutex; }; That can be passed to netlink_kernel_create to set optional configurations for netlink kernel sockets. I've populated this structure by looking for NULL and zero parameters at the existing code. The remaining parameters that always need to be set are still left in the original interface. That includes optional parameters for the netlink socket creation. This allows easy extensibility of this interface in the future. This patch also adapts all callers to use this new interface. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--crypto/crypto_user.c7
-rw-r--r--drivers/connector/connector.c13
-rw-r--r--drivers/infiniband/core/netlink.c7
-rw-r--r--drivers/scsi/scsi_netlink.c7
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c9
-rw-r--r--drivers/staging/gdm72xx/netlink_k.c6
-rw-r--r--include/linux/netlink.h15
-rw-r--r--kernel/audit.c7
-rw-r--r--lib/kobject_uevent.c5
-rw-r--r--net/bridge/netfilter/ebt_ulog.c6
-rw-r--r--net/core/rtnetlink.c9
-rw-r--r--net/core/sock_diag.c8
-rw-r--r--net/decnet/netfilter/dn_rtmsg.c8
-rw-r--r--net/ipv4/fib_frontend.c7
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c8
-rw-r--r--net/netfilter/nfnetlink.c7
-rw-r--r--net/netlink/af_netlink.c16
-rw-r--r--net/netlink/genetlink.c10
-rw-r--r--net/xfrm/xfrm_user.c7
-rw-r--r--security/selinux/netlink.c6
20 files changed, 117 insertions, 51 deletions
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 5a37eadb4e56..ba2c611154af 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -496,9 +496,12 @@ static void crypto_netlink_rcv(struct sk_buff *skb)
496 496
497static int __init crypto_user_init(void) 497static int __init crypto_user_init(void)
498{ 498{
499 struct netlink_kernel_cfg cfg = {
500 .input = crypto_netlink_rcv,
501 };
502
499 crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, 503 crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO,
500 0, crypto_netlink_rcv, 504 THIS_MODULE, &cfg);
501 NULL, THIS_MODULE);
502 if (!crypto_nlsk) 505 if (!crypto_nlsk)
503 return -ENOMEM; 506 return -ENOMEM;
504 507
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 34e0e9e4d913..116cf8d02834 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -251,15 +251,20 @@ static const struct file_operations cn_file_ops = {
251 .release = single_release 251 .release = single_release
252}; 252};
253 253
254static struct cn_dev cdev = {
255 .input = cn_rx_skb,
256};
257
254static int __devinit cn_init(void) 258static int __devinit cn_init(void)
255{ 259{
256 struct cn_dev *dev = &cdev; 260 struct cn_dev *dev = &cdev;
257 261 struct netlink_kernel_cfg cfg = {
258 dev->input = cn_rx_skb; 262 .groups = CN_NETLINK_USERS + 0xf,
263 .input = dev->input,
264 };
259 265
260 dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR, 266 dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
261 CN_NETLINK_USERS + 0xf, 267 THIS_MODULE, &cfg);
262 dev->input, NULL, THIS_MODULE);
263 if (!dev->nls) 268 if (!dev->nls)
264 return -EIO; 269 return -EIO;
265 270
diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c
index 1e691dca1820..3ae2bfd31015 100644
--- a/drivers/infiniband/core/netlink.c
+++ b/drivers/infiniband/core/netlink.c
@@ -173,8 +173,11 @@ static void ibnl_rcv(struct sk_buff *skb)
173 173
174int __init ibnl_init(void) 174int __init ibnl_init(void)
175{ 175{
176 nls = netlink_kernel_create(&init_net, NETLINK_RDMA, 0, ibnl_rcv, 176 struct netlink_kernel_cfg cfg = {
177 NULL, THIS_MODULE); 177 .input = ibnl_rcv,
178 };
179
180 nls = netlink_kernel_create(&init_net, NETLINK_RDMA, THIS_MODULE, &cfg);
178 if (!nls) { 181 if (!nls) {
179 pr_warn("Failed to create netlink socket\n"); 182 pr_warn("Failed to create netlink socket\n");
180 return -ENOMEM; 183 return -ENOMEM;
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
index c77628afbf9f..8818dd681c19 100644
--- a/drivers/scsi/scsi_netlink.c
+++ b/drivers/scsi/scsi_netlink.c
@@ -486,6 +486,10 @@ void
486scsi_netlink_init(void) 486scsi_netlink_init(void)
487{ 487{
488 int error; 488 int error;
489 struct netlink_kernel_cfg cfg = {
490 .input = scsi_nl_rcv_msg,
491 .groups = SCSI_NL_GRP_CNT,
492 };
489 493
490 INIT_LIST_HEAD(&scsi_nl_drivers); 494 INIT_LIST_HEAD(&scsi_nl_drivers);
491 495
@@ -497,8 +501,7 @@ scsi_netlink_init(void)
497 } 501 }
498 502
499 scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT, 503 scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT,
500 SCSI_NL_GRP_CNT, scsi_nl_rcv_msg, NULL, 504 THIS_MODULE, &cfg);
501 THIS_MODULE);
502 if (!scsi_nl_sock) { 505 if (!scsi_nl_sock) {
503 printk(KERN_ERR "%s: register of receive handler failed\n", 506 printk(KERN_ERR "%s: register of receive handler failed\n",
504 __func__); 507 __func__);
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 1cf640e575da..6042954d8f3b 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2936,7 +2936,10 @@ EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
2936static __init int iscsi_transport_init(void) 2936static __init int iscsi_transport_init(void)
2937{ 2937{
2938 int err; 2938 int err;
2939 2939 struct netlink_kernel_cfg cfg = {
2940 .groups = 1,
2941 .input = iscsi_if_rx,
2942 };
2940 printk(KERN_INFO "Loading iSCSI transport class v%s.\n", 2943 printk(KERN_INFO "Loading iSCSI transport class v%s.\n",
2941 ISCSI_TRANSPORT_VERSION); 2944 ISCSI_TRANSPORT_VERSION);
2942 2945
@@ -2966,8 +2969,8 @@ static __init int iscsi_transport_init(void)
2966 if (err) 2969 if (err)
2967 goto unregister_conn_class; 2970 goto unregister_conn_class;
2968 2971
2969 nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, 2972 nls = netlink_kernel_create(&init_net, NETLINK_ISCSI,
2970 NULL, THIS_MODULE); 2973 THIS_MODULE, &cfg);
2971 if (!nls) { 2974 if (!nls) {
2972 err = -ENOBUFS; 2975 err = -ENOBUFS;
2973 goto unregister_session_class; 2976 goto unregister_session_class;
diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c
index 2489bb5597ca..87c3a07ed80e 100644
--- a/drivers/staging/gdm72xx/netlink_k.c
+++ b/drivers/staging/gdm72xx/netlink_k.c
@@ -88,13 +88,15 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type,
88 void *msg, int len)) 88 void *msg, int len))
89{ 89{
90 struct sock *sock; 90 struct sock *sock;
91 struct netlink_kernel_cfg cfg = {
92 .input = netlink_rcv,
93 };
91 94
92#if !defined(DEFINE_MUTEX) 95#if !defined(DEFINE_MUTEX)
93 init_MUTEX(&netlink_mutex); 96 init_MUTEX(&netlink_mutex);
94#endif 97#endif
95 98
96 sock = netlink_kernel_create(&init_net, unit, 0, netlink_rcv, NULL, 99 sock = netlink_kernel_create(&init_net, unit, THIS_MODULE, &cfg);
97 THIS_MODULE);
98 100
99 if (sock) 101 if (sock)
100 rcv_cb = cb; 102 rcv_cb = cb;
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index ed33f0901bc2..6085e4919cb3 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -174,11 +174,16 @@ struct netlink_skb_parms {
174extern void netlink_table_grab(void); 174extern void netlink_table_grab(void);
175extern void netlink_table_ungrab(void); 175extern void netlink_table_ungrab(void);
176 176
177extern struct sock *netlink_kernel_create(struct net *net, 177/* optional Netlink kernel configuration parameters */
178 int unit,unsigned int groups, 178struct netlink_kernel_cfg {
179 void (*input)(struct sk_buff *skb), 179 unsigned int groups;
180 struct mutex *cb_mutex, 180 void (*input)(struct sk_buff *skb);
181 struct module *module); 181 struct mutex *cb_mutex;
182};
183
184extern struct sock *netlink_kernel_create(struct net *net, int unit,
185 struct module *module,
186 struct netlink_kernel_cfg *cfg);
182extern void netlink_kernel_release(struct sock *sk); 187extern void netlink_kernel_release(struct sock *sk);
183extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups); 188extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
184extern int netlink_change_ngroups(struct sock *sk, unsigned int groups); 189extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
diff --git a/kernel/audit.c b/kernel/audit.c
index 30b252a1fb61..4a3f28d2ca65 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -962,14 +962,17 @@ static void audit_receive(struct sk_buff *skb)
962static int __init audit_init(void) 962static int __init audit_init(void)
963{ 963{
964 int i; 964 int i;
965 struct netlink_kernel_cfg cfg = {
966 .input = audit_receive,
967 };
965 968
966 if (audit_initialized == AUDIT_DISABLED) 969 if (audit_initialized == AUDIT_DISABLED)
967 return 0; 970 return 0;
968 971
969 printk(KERN_INFO "audit: initializing netlink socket (%s)\n", 972 printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
970 audit_default ? "enabled" : "disabled"); 973 audit_default ? "enabled" : "disabled");
971 audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, 974 audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT,
972 audit_receive, NULL, THIS_MODULE); 975 THIS_MODULE, &cfg);
973 if (!audit_sock) 976 if (!audit_sock)
974 audit_panic("cannot initialize netlink socket"); 977 audit_panic("cannot initialize netlink socket");
975 else 978 else
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 1a91efa6d121..0401d2916d9f 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -373,13 +373,16 @@ EXPORT_SYMBOL_GPL(add_uevent_var);
373static int uevent_net_init(struct net *net) 373static int uevent_net_init(struct net *net)
374{ 374{
375 struct uevent_sock *ue_sk; 375 struct uevent_sock *ue_sk;
376 struct netlink_kernel_cfg cfg = {
377 .groups = 1,
378 };
376 379
377 ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL); 380 ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL);
378 if (!ue_sk) 381 if (!ue_sk)
379 return -ENOMEM; 382 return -ENOMEM;
380 383
381 ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT, 384 ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT,
382 1, NULL, NULL, THIS_MODULE); 385 THIS_MODULE, &cfg);
383 if (!ue_sk->sk) { 386 if (!ue_sk->sk) {
384 printk(KERN_ERR 387 printk(KERN_ERR
385 "kobject_uevent: unable to create netlink socket!\n"); 388 "kobject_uevent: unable to create netlink socket!\n");
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 1bd173218f7b..374bdcd77039 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -282,6 +282,9 @@ static int __init ebt_ulog_init(void)
282{ 282{
283 int ret; 283 int ret;
284 int i; 284 int i;
285 struct netlink_kernel_cfg cfg = {
286 .groups = EBT_ULOG_MAXNLGROUPS,
287 };
285 288
286 if (nlbufsiz >= 128*1024) { 289 if (nlbufsiz >= 128*1024) {
287 pr_warning("Netlink buffer has to be <= 128kB," 290 pr_warning("Netlink buffer has to be <= 128kB,"
@@ -296,8 +299,7 @@ static int __init ebt_ulog_init(void)
296 } 299 }
297 300
298 ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, 301 ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
299 EBT_ULOG_MAXNLGROUPS, NULL, NULL, 302 THIS_MODULE, &cfg);
300 THIS_MODULE);
301 if (!ebtulognl) 303 if (!ebtulognl)
302 ret = -ENOMEM; 304 ret = -ENOMEM;
303 else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0) 305 else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index bc8a1cdaac98..2b325c340b44 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2353,8 +2353,13 @@ static struct notifier_block rtnetlink_dev_notifier = {
2353static int __net_init rtnetlink_net_init(struct net *net) 2353static int __net_init rtnetlink_net_init(struct net *net)
2354{ 2354{
2355 struct sock *sk; 2355 struct sock *sk;
2356 sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, 2356 struct netlink_kernel_cfg cfg = {
2357 rtnetlink_rcv, &rtnl_mutex, THIS_MODULE); 2357 .groups = RTNLGRP_MAX,
2358 .input = rtnetlink_rcv,
2359 .cb_mutex = &rtnl_mutex,
2360 };
2361
2362 sk = netlink_kernel_create(net, NETLINK_ROUTE, THIS_MODULE, &cfg);
2358 if (!sk) 2363 if (!sk)
2359 return -ENOMEM; 2364 return -ENOMEM;
2360 net->rtnl = sk; 2365 net->rtnl = sk;
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index ff2967acbfae..07a29eb34a41 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -171,8 +171,12 @@ EXPORT_SYMBOL_GPL(sock_diag_nlsk);
171 171
172static int __init sock_diag_init(void) 172static int __init sock_diag_init(void)
173{ 173{
174 sock_diag_nlsk = netlink_kernel_create(&init_net, NETLINK_SOCK_DIAG, 0, 174 struct netlink_kernel_cfg cfg = {
175 sock_diag_rcv, NULL, THIS_MODULE); 175 .input = sock_diag_rcv,
176 };
177
178 sock_diag_nlsk = netlink_kernel_create(&init_net, NETLINK_SOCK_DIAG,
179 THIS_MODULE, &cfg);
176 return sock_diag_nlsk == NULL ? -ENOMEM : 0; 180 return sock_diag_nlsk == NULL ? -ENOMEM : 0;
177} 181}
178 182
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index b8f7f5b8c350..11db0ecf342f 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -125,11 +125,13 @@ static struct nf_hook_ops dnrmg_ops __read_mostly = {
125static int __init dn_rtmsg_init(void) 125static int __init dn_rtmsg_init(void)
126{ 126{
127 int rv = 0; 127 int rv = 0;
128 struct netlink_kernel_cfg cfg = {
129 .groups = DNRNG_NLGRP_MAX,
130 .input = dnrmg_receive_user_skb,
131 };
128 132
129 dnrmg = netlink_kernel_create(&init_net, 133 dnrmg = netlink_kernel_create(&init_net,
130 NETLINK_DNRTMSG, DNRNG_NLGRP_MAX, 134 NETLINK_DNRTMSG, THIS_MODULE, &cfg);
131 dnrmg_receive_user_skb,
132 NULL, THIS_MODULE);
133 if (dnrmg == NULL) { 135 if (dnrmg == NULL) {
134 printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket"); 136 printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
135 return -ENOMEM; 137 return -ENOMEM;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index ae528d1b293a..3e11ea225dad 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -976,8 +976,11 @@ static void nl_fib_input(struct sk_buff *skb)
976static int __net_init nl_fib_lookup_init(struct net *net) 976static int __net_init nl_fib_lookup_init(struct net *net)
977{ 977{
978 struct sock *sk; 978 struct sock *sk;
979 sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, 0, 979 struct netlink_kernel_cfg cfg = {
980 nl_fib_input, NULL, THIS_MODULE); 980 .input = nl_fib_input,
981 };
982
983 sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, THIS_MODULE, &cfg);
981 if (sk == NULL) 984 if (sk == NULL)
982 return -EAFNOSUPPORT; 985 return -EAFNOSUPPORT;
983 net->ipv4.fibnl = sk; 986 net->ipv4.fibnl = sk;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 99b3f53f16a7..1109f7f6c254 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -381,6 +381,9 @@ static struct nf_logger ipt_ulog_logger __read_mostly = {
381static int __init ulog_tg_init(void) 381static int __init ulog_tg_init(void)
382{ 382{
383 int ret, i; 383 int ret, i;
384 struct netlink_kernel_cfg cfg = {
385 .groups = ULOG_MAXNLGROUPS,
386 };
384 387
385 pr_debug("init module\n"); 388 pr_debug("init module\n");
386 389
@@ -393,9 +396,8 @@ static int __init ulog_tg_init(void)
393 for (i = 0; i < ULOG_MAXNLGROUPS; i++) 396 for (i = 0; i < ULOG_MAXNLGROUPS; i++)
394 setup_timer(&ulog_buffers[i].timer, ulog_timer, i); 397 setup_timer(&ulog_buffers[i].timer, ulog_timer, i);
395 398
396 nflognl = netlink_kernel_create(&init_net, 399 nflognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
397 NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL, 400 THIS_MODULE, &cfg);
398 NULL, THIS_MODULE);
399 if (!nflognl) 401 if (!nflognl)
400 return -ENOMEM; 402 return -ENOMEM;
401 403
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 3e797d1fcb94..700e4616a098 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -203,9 +203,12 @@ static void nfnetlink_rcv(struct sk_buff *skb)
203static int __net_init nfnetlink_net_init(struct net *net) 203static int __net_init nfnetlink_net_init(struct net *net)
204{ 204{
205 struct sock *nfnl; 205 struct sock *nfnl;
206 struct netlink_kernel_cfg cfg = {
207 .groups = NFNLGRP_MAX,
208 .input = nfnetlink_rcv,
209 };
206 210
207 nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, NFNLGRP_MAX, 211 nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, THIS_MODULE, &cfg);
208 nfnetlink_rcv, NULL, THIS_MODULE);
209 if (!nfnl) 212 if (!nfnl)
210 return -ENOMEM; 213 return -ENOMEM;
211 net->nfnl_stash = nfnl; 214 net->nfnl_stash = nfnl;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index b3025a603d56..43a124feaad8 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1503,14 +1503,16 @@ static void netlink_data_ready(struct sock *sk, int len)
1503 */ 1503 */
1504 1504
1505struct sock * 1505struct sock *
1506netlink_kernel_create(struct net *net, int unit, unsigned int groups, 1506netlink_kernel_create(struct net *net, int unit,
1507 void (*input)(struct sk_buff *skb), 1507 struct module *module,
1508 struct mutex *cb_mutex, struct module *module) 1508 struct netlink_kernel_cfg *cfg)
1509{ 1509{
1510 struct socket *sock; 1510 struct socket *sock;
1511 struct sock *sk; 1511 struct sock *sk;
1512 struct netlink_sock *nlk; 1512 struct netlink_sock *nlk;
1513 struct listeners *listeners = NULL; 1513 struct listeners *listeners = NULL;
1514 struct mutex *cb_mutex = cfg ? cfg->cb_mutex : NULL;
1515 unsigned int groups;
1514 1516
1515 BUG_ON(!nl_table); 1517 BUG_ON(!nl_table);
1516 1518
@@ -1532,16 +1534,18 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
1532 sk = sock->sk; 1534 sk = sock->sk;
1533 sk_change_net(sk, net); 1535 sk_change_net(sk, net);
1534 1536
1535 if (groups < 32) 1537 if (!cfg || cfg->groups < 32)
1536 groups = 32; 1538 groups = 32;
1539 else
1540 groups = cfg->groups;
1537 1541
1538 listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL); 1542 listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL);
1539 if (!listeners) 1543 if (!listeners)
1540 goto out_sock_release; 1544 goto out_sock_release;
1541 1545
1542 sk->sk_data_ready = netlink_data_ready; 1546 sk->sk_data_ready = netlink_data_ready;
1543 if (input) 1547 if (cfg && cfg->input)
1544 nlk_sk(sk)->netlink_rcv = input; 1548 nlk_sk(sk)->netlink_rcv = cfg->input;
1545 1549
1546 if (netlink_insert(sk, net, 0)) 1550 if (netlink_insert(sk, net, 0))
1547 goto out_sock_release; 1551 goto out_sock_release;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 2cc7c1ee7690..32761b53015e 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -915,10 +915,14 @@ static struct genl_multicast_group notify_grp = {
915 915
916static int __net_init genl_pernet_init(struct net *net) 916static int __net_init genl_pernet_init(struct net *net)
917{ 917{
918 struct netlink_kernel_cfg cfg = {
919 .input = genl_rcv,
920 .cb_mutex = &genl_mutex,
921 };
922
918 /* we'll bump the group number right afterwards */ 923 /* we'll bump the group number right afterwards */
919 net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, 0, 924 net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC,
920 genl_rcv, &genl_mutex, 925 THIS_MODULE, &cfg);
921 THIS_MODULE);
922 926
923 if (!net->genl_sock && net_eq(net, &init_net)) 927 if (!net->genl_sock && net_eq(net, &init_net))
924 panic("GENL: Cannot initialize generic netlink\n"); 928 panic("GENL: Cannot initialize generic netlink\n");
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 540762726aaf..e75d8e47f35c 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2959,9 +2959,12 @@ static struct xfrm_mgr netlink_mgr = {
2959static int __net_init xfrm_user_net_init(struct net *net) 2959static int __net_init xfrm_user_net_init(struct net *net)
2960{ 2960{
2961 struct sock *nlsk; 2961 struct sock *nlsk;
2962 struct netlink_kernel_cfg cfg = {
2963 .groups = XFRMNLGRP_MAX,
2964 .input = xfrm_netlink_rcv,
2965 };
2962 2966
2963 nlsk = netlink_kernel_create(net, NETLINK_XFRM, XFRMNLGRP_MAX, 2967 nlsk = netlink_kernel_create(net, NETLINK_XFRM, THIS_MODULE, &cfg);
2964 xfrm_netlink_rcv, NULL, THIS_MODULE);
2965 if (nlsk == NULL) 2968 if (nlsk == NULL)
2966 return -ENOMEM; 2969 return -ENOMEM;
2967 net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */ 2970 net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 8a23a35b9c5b..8a77725423e0 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -111,8 +111,12 @@ void selnl_notify_policyload(u32 seqno)
111 111
112static int __init selnl_init(void) 112static int __init selnl_init(void)
113{ 113{
114 struct netlink_kernel_cfg cfg = {
115 .groups = SELNLGRP_MAX,
116 };
117
114 selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, 118 selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
115 SELNLGRP_MAX, NULL, NULL, THIS_MODULE); 119 THIS_MODULE, &cfg);
116 if (selnl == NULL) 120 if (selnl == NULL)
117 panic("SELinux: Cannot create netlink socket."); 121 panic("SELinux: Cannot create netlink socket.");
118 netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); 122 netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);