Separate netlink socket for receive message and send event

This commit is contained in:
vemax78 2014-12-28 16:14:19 +01:00
parent b05d6631f4
commit 0c27172ca6
5 changed files with 60 additions and 35 deletions

View File

@ -13,7 +13,7 @@
static struct sc_capwap_session sc_acsession; static struct sc_capwap_session sc_acsession;
/* */ /* */
int sc_capwap_init(uint32_t threads) { int sc_capwap_init(void) {
TRACEKMOD("### sc_capwap_init\n"); TRACEKMOD("### sc_capwap_init\n");
/* Init session */ /* Init session */

View File

@ -10,7 +10,7 @@ struct sc_capwap_workthread {
}; };
/* */ /* */
int sc_capwap_init(uint32_t threads); int sc_capwap_init(void);
void sc_capwap_close(void); void sc_capwap_close(void);
/* */ /* */

View File

@ -246,22 +246,23 @@ static int sc_netlink_link(struct sk_buff* skb, struct genl_info* info) {
TRACEKMOD("### sc_netlink_link\n"); TRACEKMOD("### sc_netlink_link\n");
if (!sc_netlink_usermodeid) { /* */
/* Initialize library */ if (sc_netlink_usermodeid) {
ret = sc_capwap_init(1); TRACEKMOD("*** Busy kernel link\n");
if (!ret) { return -EBUSY;
sc_netlink_usermodeid = portid;
/* Deny unload module */
try_module_get(THIS_MODULE);
}
} else if (sc_netlink_usermodeid == portid) {
ret = -EALREADY;
} else {
ret = -EBUSY;
} }
return ret; /* Initialize library */
ret = sc_capwap_init();
if (ret) {
return ret;
}
/* Deny unload module */
sc_netlink_usermodeid = portid;
try_module_get(THIS_MODULE);
return 0;
} }
/* */ /* */
@ -269,7 +270,7 @@ static int sc_netlink_reset(struct sk_buff* skb, struct genl_info* info) {
TRACEKMOD("### sc_netlink_reset\n"); TRACEKMOD("### sc_netlink_reset\n");
/* Check Link */ /* Check Link */
if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { if (!sc_netlink_usermodeid) {
return -ENOLINK; return -ENOLINK;
} }
@ -286,21 +287,19 @@ static int sc_netlink_reset(struct sk_buff* skb, struct genl_info* info) {
static int sc_netlink_notify(struct notifier_block* nb, unsigned long state, void* _notify) { static int sc_netlink_notify(struct notifier_block* nb, unsigned long state, void* _notify) {
struct netlink_notify* notify = (struct netlink_notify*)_notify; struct netlink_notify* notify = (struct netlink_notify*)_notify;
if (state == NETLINK_URELEASE) { if ((state == NETLINK_URELEASE) && (sc_netlink_usermodeid == netlink_notify_portid(notify))) {
rtnl_lock(); rtnl_lock();
if (sc_netlink_usermodeid == netlink_notify_portid(notify)) { sc_netlink_usermodeid = 0;
sc_netlink_usermodeid = 0;
/* Close all devices */ /* Close all devices */
sc_netlink_unregister_alldevice(); sc_netlink_unregister_alldevice();
/* Close capwap engine */ /* Close capwap engine */
sc_capwap_close(); sc_capwap_close();
/* Allow unload module */ /* Allow unload module */
module_put(THIS_MODULE); module_put(THIS_MODULE);
}
rtnl_unlock(); rtnl_unlock();
} }
@ -315,7 +314,7 @@ static int sc_netlink_bind(struct sk_buff* skb, struct genl_info* info) {
TRACEKMOD("### sc_netlink_bind\n"); TRACEKMOD("### sc_netlink_bind\n");
/* Check Link */ /* Check Link */
if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { if (!sc_netlink_usermodeid) {
return -ENOLINK; return -ENOLINK;
} }
@ -343,7 +342,7 @@ static int sc_netlink_connect(struct sk_buff* skb, struct genl_info* info) {
TRACEKMOD("### sc_netlink_connect\n"); TRACEKMOD("### sc_netlink_connect\n");
/* Check Link */ /* Check Link */
if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { if (!sc_netlink_usermodeid) {
return -ENOLINK; return -ENOLINK;
} }
@ -388,7 +387,7 @@ static int sc_netlink_send_keepalive(struct sk_buff* skb, struct genl_info* info
TRACEKMOD("### sc_netlink_send_keepalive\n"); TRACEKMOD("### sc_netlink_send_keepalive\n");
/* Check Link */ /* Check Link */
if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { if (!sc_netlink_usermodeid) {
return -ENOLINK; return -ENOLINK;
} }
@ -418,7 +417,7 @@ static int sc_netlink_send_data(struct sk_buff* skb, struct genl_info* info) {
TRACEKMOD("### sc_netlink_send_data\n"); TRACEKMOD("### sc_netlink_send_data\n");
/* Check Link */ /* Check Link */
if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { if (!sc_netlink_usermodeid) {
return -ENOLINK; return -ENOLINK;
} else if (!info->attrs[NLSMARTCAPWAP_ATTR_RADIOID] || !info->attrs[NLSMARTCAPWAP_ATTR_DATA_FRAME]) { } else if (!info->attrs[NLSMARTCAPWAP_ATTR_RADIOID] || !info->attrs[NLSMARTCAPWAP_ATTR_DATA_FRAME]) {
return -EINVAL; return -EINVAL;
@ -494,7 +493,7 @@ static int sc_netlink_join_mac80211_device(struct sk_buff* skb, struct genl_info
TRACEKMOD("### sc_netlink_join_mac80211_device\n"); TRACEKMOD("### sc_netlink_join_mac80211_device\n");
/* Check Link */ /* Check Link */
if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { if (!sc_netlink_usermodeid) {
return -ENOLINK; return -ENOLINK;
} }
@ -551,7 +550,7 @@ static int sc_netlink_leave_mac80211_device(struct sk_buff* skb, struct genl_inf
TRACEKMOD("### sc_netlink_leave_mac80211_device\n"); TRACEKMOD("### sc_netlink_leave_mac80211_device\n");
/* Check Link */ /* Check Link */
if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { if (!sc_netlink_usermodeid) {
return -ENOLINK; return -ENOLINK;
} }

View File

@ -150,7 +150,7 @@ static int wtp_kmod_send_and_recv(struct nl_sock* nl, struct nl_cb* nl_cb, struc
/* */ /* */
static int wtp_kmod_send_and_recv_msg(struct nl_msg* msg, wtp_kmod_valid_cb valid_cb, void* data) { static int wtp_kmod_send_and_recv_msg(struct nl_msg* msg, wtp_kmod_valid_cb valid_cb, void* data) {
return wtp_kmod_send_and_recv(g_wtp.kmodhandle.nl, g_wtp.kmodhandle.nl_cb, msg, valid_cb, data); return wtp_kmod_send_and_recv(g_wtp.kmodhandle.nlmsg, g_wtp.kmodhandle.nlmsg_cb, msg, valid_cb, data);
} }
/* */ /* */
@ -168,7 +168,7 @@ static int wtp_kmod_link(void) {
genlmsg_put(msg, 0, 0, g_wtp.kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_LINK, 0); genlmsg_put(msg, 0, 0, g_wtp.kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_LINK, 0);
/* */ /* */
result = wtp_kmod_send_and_recv_msg(msg, NULL, NULL); result = wtp_kmod_send_and_recv(g_wtp.kmodhandle.nl, g_wtp.kmodhandle.nl_cb, msg, NULL, NULL);
if (result) { if (result) {
if (result == -EALREADY) { if (result == -EALREADY) {
result = 0; result = 0;
@ -536,6 +536,20 @@ int wtp_kmod_init(void) {
return result; return result;
} }
/* Configure netlink message socket */
g_wtp.kmodhandle.nlmsg_cb = nl_cb_alloc(NL_CB_DEFAULT);
if (!g_wtp.kmodhandle.nlmsg_cb) {
wtp_kmod_free();
return -1;
}
/* */
g_wtp.kmodhandle.nlmsg = nl_create_handle(g_wtp.kmodhandle.nlmsg_cb);
if (!g_wtp.kmodhandle.nlmsg) {
wtp_kmod_free();
return -1;
}
/* */ /* */
g_wtp.kmodhandle.interfaces = capwap_list_create(); g_wtp.kmodhandle.interfaces = capwap_list_create();
return 0; return 0;
@ -556,6 +570,14 @@ void wtp_kmod_free(void) {
capwap_list_free(g_wtp.kmodhandle.interfaces); capwap_list_free(g_wtp.kmodhandle.interfaces);
} }
if (g_wtp.kmodhandle.nlmsg) {
nl_socket_free(g_wtp.kmodhandle.nlmsg);
}
if (g_wtp.kmodhandle.nlmsg_cb) {
nl_cb_put(g_wtp.kmodhandle.nlmsg_cb);
}
if (g_wtp.kmodhandle.nl) { if (g_wtp.kmodhandle.nl) {
nl_socket_free(g_wtp.kmodhandle.nl); nl_socket_free(g_wtp.kmodhandle.nl);
} }

View File

@ -25,6 +25,10 @@ struct wtp_kmod_handle {
struct nl_cb* nl_cb; struct nl_cb* nl_cb;
int nlsmartcapwap_id; int nlsmartcapwap_id;
/* */
struct nl_sock* nlmsg;
struct nl_cb* nlmsg_cb;
/* */ /* */
struct capwap_list* interfaces; struct capwap_list* interfaces;
}; };