|
@@ -80,6 +80,7 @@ struct netlink_sock {
|
|
|
struct mutex *cb_mutex;
|
|
|
struct mutex cb_def_mutex;
|
|
|
void (*netlink_rcv)(struct sk_buff *skb);
|
|
|
+ void (*netlink_bind)(int group);
|
|
|
struct module *module;
|
|
|
};
|
|
|
|
|
@@ -124,6 +125,7 @@ struct netlink_table {
|
|
|
unsigned int groups;
|
|
|
struct mutex *cb_mutex;
|
|
|
struct module *module;
|
|
|
+ void (*bind)(int group);
|
|
|
int registered;
|
|
|
};
|
|
|
|
|
@@ -444,6 +446,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
|
|
|
struct module *module = NULL;
|
|
|
struct mutex *cb_mutex;
|
|
|
struct netlink_sock *nlk;
|
|
|
+ void (*bind)(int group);
|
|
|
int err = 0;
|
|
|
|
|
|
sock->state = SS_UNCONNECTED;
|
|
@@ -468,6 +471,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
|
|
|
else
|
|
|
err = -EPROTONOSUPPORT;
|
|
|
cb_mutex = nl_table[protocol].cb_mutex;
|
|
|
+ bind = nl_table[protocol].bind;
|
|
|
netlink_unlock_table();
|
|
|
|
|
|
if (err < 0)
|
|
@@ -483,6 +487,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
|
|
|
|
|
|
nlk = nlk_sk(sock->sk);
|
|
|
nlk->module = module;
|
|
|
+ nlk->netlink_bind = bind;
|
|
|
out:
|
|
|
return err;
|
|
|
|
|
@@ -683,6 +688,15 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
|
|
netlink_update_listeners(sk);
|
|
|
netlink_table_ungrab();
|
|
|
|
|
|
+ if (nlk->netlink_bind && nlk->groups[0]) {
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i=0; i<nlk->ngroups; i++) {
|
|
|
+ if (test_bit(i, nlk->groups))
|
|
|
+ nlk->netlink_bind(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1239,6 +1253,10 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
|
|
|
netlink_update_socket_mc(nlk, val,
|
|
|
optname == NETLINK_ADD_MEMBERSHIP);
|
|
|
netlink_table_ungrab();
|
|
|
+
|
|
|
+ if (nlk->netlink_bind)
|
|
|
+ nlk->netlink_bind(val);
|
|
|
+
|
|
|
err = 0;
|
|
|
break;
|
|
|
}
|
|
@@ -1559,6 +1577,7 @@ netlink_kernel_create(struct net *net, int unit,
|
|
|
rcu_assign_pointer(nl_table[unit].listeners, listeners);
|
|
|
nl_table[unit].cb_mutex = cb_mutex;
|
|
|
nl_table[unit].module = module;
|
|
|
+ nl_table[unit].bind = cfg ? cfg->bind : NULL;
|
|
|
nl_table[unit].registered = 1;
|
|
|
} else {
|
|
|
kfree(listeners);
|