diff --git a/src/wtp/kmod/capwap_private.c b/src/wtp/kmod/capwap_private.c index 8b249ef..d9b16f9 100644 --- a/src/wtp/kmod/capwap_private.c +++ b/src/wtp/kmod/capwap_private.c @@ -13,7 +13,7 @@ static struct sc_capwap_session sc_acsession; /* */ -int sc_capwap_init(uint32_t threads) { +int sc_capwap_init(void) { TRACEKMOD("### sc_capwap_init\n"); /* Init session */ diff --git a/src/wtp/kmod/capwap_private.h b/src/wtp/kmod/capwap_private.h index da04a7d..ad4c70a 100644 --- a/src/wtp/kmod/capwap_private.h +++ b/src/wtp/kmod/capwap_private.h @@ -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); /* */ diff --git a/src/wtp/kmod/netlinkapp.c b/src/wtp/kmod/netlinkapp.c index a9342b4..4a5de0a 100644 --- a/src/wtp/kmod/netlinkapp.c +++ b/src/wtp/kmod/netlinkapp.c @@ -246,22 +246,23 @@ static int sc_netlink_link(struct sk_buff* skb, struct genl_info* info) { TRACEKMOD("### sc_netlink_link\n"); - if (!sc_netlink_usermodeid) { - /* Initialize library */ - ret = sc_capwap_init(1); - if (!ret) { - sc_netlink_usermodeid = portid; - - /* Deny unload module */ - try_module_get(THIS_MODULE); - } - } else if (sc_netlink_usermodeid == portid) { - ret = -EALREADY; - } else { - ret = -EBUSY; + /* */ + if (sc_netlink_usermodeid) { + TRACEKMOD("*** Busy kernel link\n"); + return -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"); /* Check Link */ - if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { + if (!sc_netlink_usermodeid) { 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) { 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(); - if (sc_netlink_usermodeid == netlink_notify_portid(notify)) { - sc_netlink_usermodeid = 0; + sc_netlink_usermodeid = 0; - /* Close all devices */ - sc_netlink_unregister_alldevice(); + /* Close all devices */ + sc_netlink_unregister_alldevice(); - /* Close capwap engine */ - sc_capwap_close(); + /* Close capwap engine */ + sc_capwap_close(); - /* Allow unload module */ - module_put(THIS_MODULE); - } + /* Allow unload module */ + module_put(THIS_MODULE); rtnl_unlock(); } @@ -315,7 +314,7 @@ static int sc_netlink_bind(struct sk_buff* skb, struct genl_info* info) { TRACEKMOD("### sc_netlink_bind\n"); /* Check Link */ - if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { + if (!sc_netlink_usermodeid) { return -ENOLINK; } @@ -343,7 +342,7 @@ static int sc_netlink_connect(struct sk_buff* skb, struct genl_info* info) { TRACEKMOD("### sc_netlink_connect\n"); /* Check Link */ - if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { + if (!sc_netlink_usermodeid) { 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"); /* Check Link */ - if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { + if (!sc_netlink_usermodeid) { 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"); /* Check Link */ - if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { + if (!sc_netlink_usermodeid) { return -ENOLINK; } else if (!info->attrs[NLSMARTCAPWAP_ATTR_RADIOID] || !info->attrs[NLSMARTCAPWAP_ATTR_DATA_FRAME]) { 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"); /* Check Link */ - if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { + if (!sc_netlink_usermodeid) { 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"); /* Check Link */ - if (sc_netlink_usermodeid != genl_info_snd_portid(info)) { + if (!sc_netlink_usermodeid) { return -ENOLINK; } diff --git a/src/wtp/wtp_kmod.c b/src/wtp/wtp_kmod.c index efd48af..a423c96 100644 --- a/src/wtp/wtp_kmod.c +++ b/src/wtp/wtp_kmod.c @@ -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) { - 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); /* */ - 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 == -EALREADY) { result = 0; @@ -536,6 +536,20 @@ int wtp_kmod_init(void) { 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(); return 0; @@ -556,6 +570,14 @@ void wtp_kmod_free(void) { 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) { nl_socket_free(g_wtp.kmodhandle.nl); } diff --git a/src/wtp/wtp_kmod.h b/src/wtp/wtp_kmod.h index 98e9b1b..46c49e1 100644 --- a/src/wtp/wtp_kmod.h +++ b/src/wtp/wtp_kmod.h @@ -25,6 +25,10 @@ struct wtp_kmod_handle { struct nl_cb* nl_cb; int nlsmartcapwap_id; + /* */ + struct nl_sock* nlmsg; + struct nl_cb* nlmsg_cb; + /* */ struct capwap_list* interfaces; };