start with network namespace support
This is incomplete. There are several places left where a global variable is used (e.g. there can only be one AC session).
This commit is contained in:
parent
69ca3d3256
commit
385832a010
@ -380,13 +380,13 @@ int sc_capwap_80211_to_8023(struct sk_buff* skb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_capwap_bind(union capwap_addr* sockaddr) {
|
int sc_capwap_bind(struct net *net, union capwap_addr* sockaddr) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
TRACEKMOD("### sc_capwap_bind\n");
|
TRACEKMOD("### sc_capwap_bind\n");
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
ret = sc_socket_bind(sockaddr);
|
ret = sc_socket_bind(net, sockaddr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -482,7 +482,9 @@ int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_capwap_parsingpacket(struct sc_capwap_session* session, const union capwap_addr* sockaddr, struct sk_buff* skb) {
|
int sc_capwap_parsingpacket(struct sc_capwap_session* session,
|
||||||
|
const union capwap_addr* sockaddr,
|
||||||
|
struct sk_buff* skb) {
|
||||||
int length;
|
int length;
|
||||||
uint16_t headersize;
|
uint16_t headersize;
|
||||||
struct sc_capwap_data_message* dataheader;
|
struct sc_capwap_data_message* dataheader;
|
||||||
@ -560,7 +562,7 @@ int sc_capwap_parsingpacket(struct sc_capwap_session* session, const union capwa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Session found */
|
/* Session found */
|
||||||
sc_netlink_notify_recv_keepalive(sockaddr, sessionid);
|
sc_netlink_notify_recv_keepalive(session->net, sockaddr, sessionid);
|
||||||
|
|
||||||
/* Parsing complete */
|
/* Parsing complete */
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
@ -77,6 +77,8 @@ struct sc_capwap_fragment_queue {
|
|||||||
|
|
||||||
/* */
|
/* */
|
||||||
struct sc_capwap_session {
|
struct sc_capwap_session {
|
||||||
|
struct net *net;
|
||||||
|
|
||||||
uint16_t mtu;
|
uint16_t mtu;
|
||||||
union capwap_addr peeraddr;
|
union capwap_addr peeraddr;
|
||||||
struct sc_capwap_sessionid_element sessionid;
|
struct sc_capwap_sessionid_element sessionid;
|
||||||
@ -98,7 +100,7 @@ void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_bu
|
|||||||
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb);
|
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb);
|
||||||
|
|
||||||
/* Indipendent implementation function */
|
/* Indipendent implementation function */
|
||||||
int sc_capwap_bind(union capwap_addr* sockaddr);
|
int sc_capwap_bind(struct net *net, union capwap_addr* sockaddr);
|
||||||
|
|
||||||
void sc_capwap_initsession(struct sc_capwap_session* session);
|
void sc_capwap_initsession(struct sc_capwap_session* session);
|
||||||
void sc_capwap_freesession(struct sc_capwap_session* session);
|
void sc_capwap_freesession(struct sc_capwap_session* session);
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/ieee80211.h>
|
#include <linux/ieee80211.h>
|
||||||
|
|
||||||
|
#include <net/net_namespace.h>
|
||||||
#include <net/mac80211.h>
|
#include <net/mac80211.h>
|
||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
|
|
||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
#include "nlsmartcapwap.h"
|
#include "nlsmartcapwap.h"
|
||||||
#include "netlinkapp.h"
|
#include "netlinkapp.h"
|
||||||
@ -13,13 +17,15 @@
|
|||||||
static struct sc_capwap_session sc_acsession;
|
static struct sc_capwap_session sc_acsession;
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_capwap_init(void) {
|
int sc_capwap_init(struct net *net) {
|
||||||
TRACEKMOD("### sc_capwap_init\n");
|
TRACEKMOD("### sc_capwap_init\n");
|
||||||
|
|
||||||
/* Init session */
|
/* Init session */
|
||||||
memset(&sc_acsession, 0, sizeof(struct sc_capwap_session));
|
memset(&sc_acsession, 0, sizeof(struct sc_capwap_session));
|
||||||
sc_capwap_initsession(&sc_acsession);
|
sc_capwap_initsession(&sc_acsession);
|
||||||
|
|
||||||
|
sc_acsession.net = net;
|
||||||
|
|
||||||
/* Init sockect */
|
/* Init sockect */
|
||||||
memset(&sc_localaddr, 0, sizeof(union capwap_addr));
|
memset(&sc_localaddr, 0, sizeof(union capwap_addr));
|
||||||
return sc_socket_init();
|
return sc_socket_init();
|
||||||
@ -36,7 +42,8 @@ void sc_capwap_close(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_capwap_connect(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid, uint16_t mtu) {
|
int sc_capwap_connect(struct net *net, const union capwap_addr* sockaddr,
|
||||||
|
struct sc_capwap_sessionid_element* sessionid, uint16_t mtu) {
|
||||||
TRACEKMOD("### sc_capwap_connect\n");
|
TRACEKMOD("### sc_capwap_connect\n");
|
||||||
|
|
||||||
if ((sc_localaddr.ss.ss_family != AF_INET) && (sc_localaddr.ss.ss_family != AF_INET6)) {
|
if ((sc_localaddr.ss.ss_family != AF_INET) && (sc_localaddr.ss.ss_family != AF_INET6)) {
|
||||||
@ -197,7 +204,7 @@ void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_bu
|
|||||||
uint16_t bitmask = be16_to_cpu(destwlan->wlanidbitmap);
|
uint16_t bitmask = be16_to_cpu(destwlan->wlanidbitmap);
|
||||||
while (bitmask) {
|
while (bitmask) {
|
||||||
if (bitmask & 0x01) {
|
if (bitmask & 0x01) {
|
||||||
dev = sc_netlink_getdev_from_wlanid(GET_RID_HEADER(header), wlanid);
|
dev = sc_netlink_getdev_from_wlanid(session->net, GET_RID_HEADER(header), wlanid);
|
||||||
if (dev) {
|
if (dev) {
|
||||||
struct sk_buff* clone = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb), GFP_KERNEL);
|
struct sk_buff* clone = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb), GFP_KERNEL);
|
||||||
if (!clone) {
|
if (!clone) {
|
||||||
@ -243,7 +250,7 @@ void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_bu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
dev = sc_netlink_getdev_from_bssid(GET_RID_HEADER(header), ((struct ieee80211_hdr*)skb->data)->addr2);
|
dev = sc_netlink_getdev_from_bssid(session->net, GET_RID_HEADER(header), ((struct ieee80211_hdr*)skb->data)->addr2);
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -271,5 +278,5 @@ void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_bu
|
|||||||
TRACEKMOD("### sc_capwap_parsingmgmtpacket\n");
|
TRACEKMOD("### sc_capwap_parsingmgmtpacket\n");
|
||||||
|
|
||||||
/* Send packet with capwap header into userspace */
|
/* Send packet with capwap header into userspace */
|
||||||
sc_netlink_notify_recv_data(skb->data, skb->len);
|
sc_netlink_notify_recv_data(session->net, skb->data, skb->len);
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,12 @@ struct sc_capwap_workthread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_capwap_init(void);
|
int sc_capwap_init(struct net *net);
|
||||||
void sc_capwap_close(void);
|
void sc_capwap_close(void);
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_capwap_connect(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid, uint16_t mtu);
|
int sc_capwap_connect(struct net *net, const union capwap_addr* sockaddr,
|
||||||
|
struct sc_capwap_sessionid_element* sessionid, uint16_t mtu);
|
||||||
void sc_capwap_resetsession(void);
|
void sc_capwap_resetsession(void);
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <net/genetlink.h>
|
|
||||||
#include <linux/rcupdate.h>
|
#include <linux/rcupdate.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <net/mac80211.h>
|
|
||||||
#include <linux/ieee80211.h>
|
#include <linux/ieee80211.h>
|
||||||
|
|
||||||
|
#include <net/net_namespace.h>
|
||||||
|
#include <net/genetlink.h>
|
||||||
|
#include <net/mac80211.h>
|
||||||
|
#include <net/netns/generic.h>
|
||||||
|
|
||||||
#include "nlsmartcapwap.h"
|
#include "nlsmartcapwap.h"
|
||||||
#include "netlinkapp.h"
|
#include "netlinkapp.h"
|
||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
@ -26,8 +31,12 @@ struct sc_netlink_device {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static uint32_t sc_netlink_usermodeid;
|
static int sc_net_id __read_mostly;
|
||||||
static LIST_HEAD(sc_netlink_dev_list);
|
|
||||||
|
struct sc_net {
|
||||||
|
uint32_t sc_netlink_usermodeid;
|
||||||
|
struct list_head sc_netlink_dev_list;
|
||||||
|
};
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_pre_doit(const struct genl_ops* ops, struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_pre_doit(const struct genl_ops* ops, struct sk_buff* skb, struct genl_info* info) {
|
||||||
@ -109,14 +118,16 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static struct sc_netlink_device* sc_netlink_new_device(uint32_t ifindex, uint8_t radioid, u8 wlanid, uint8_t binding) {
|
static struct sc_netlink_device* sc_netlink_new_device(struct net *net, uint32_t ifindex,
|
||||||
|
uint8_t radioid, u8 wlanid, uint8_t binding)
|
||||||
|
{
|
||||||
struct net_device* dev;
|
struct net_device* dev;
|
||||||
struct sc_netlink_device* nldev;
|
struct sc_netlink_device* nldev;
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_new_device\n");
|
TRACEKMOD("### sc_netlink_new_device\n");
|
||||||
|
|
||||||
/* Retrieve device from ifindex */
|
/* Retrieve device from ifindex */
|
||||||
dev = dev_get_by_index(&init_net, ifindex);
|
dev = dev_get_by_index(net, ifindex);
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -147,7 +158,8 @@ static struct sc_netlink_device* sc_netlink_new_device(uint32_t ifindex, uint8_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static void sc_netlink_free_device(struct sc_netlink_device* nldev) {
|
static void sc_netlink_free_device(struct sc_netlink_device* nldev)
|
||||||
|
{
|
||||||
TRACEKMOD("### sc_netlink_free_device\n");
|
TRACEKMOD("### sc_netlink_free_device\n");
|
||||||
|
|
||||||
/* Disconnect device from mac80211 */
|
/* Disconnect device from mac80211 */
|
||||||
@ -161,7 +173,11 @@ static void sc_netlink_free_device(struct sc_netlink_device* nldev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static struct sc_netlink_device* sc_netlink_register_device(uint32_t ifindex, uint8_t radioid, uint16_t wlanid, uint8_t binding) {
|
static struct sc_netlink_device *
|
||||||
|
sc_netlink_register_device(struct net *net, uint32_t ifindex, uint8_t radioid,
|
||||||
|
uint16_t wlanid, uint8_t binding)
|
||||||
|
{
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
struct sc_netlink_device* nldev;
|
struct sc_netlink_device* nldev;
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_register_device\n");
|
TRACEKMOD("### sc_netlink_register_device\n");
|
||||||
@ -174,23 +190,24 @@ static struct sc_netlink_device* sc_netlink_register_device(uint32_t ifindex, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Search device */
|
/* Search device */
|
||||||
list_for_each_entry(nldev, &sc_netlink_dev_list, list) {
|
list_for_each_entry(nldev, &sn->sc_netlink_dev_list, list) {
|
||||||
if (nldev->ifindex == ifindex) {
|
if (nldev->ifindex == ifindex) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create device */
|
/* Create device */
|
||||||
nldev = sc_netlink_new_device(ifindex, radioid, wlanid, binding);
|
nldev = sc_netlink_new_device(net, ifindex, radioid, wlanid, binding);
|
||||||
if (nldev) {
|
if (nldev) {
|
||||||
list_add_rcu(&nldev->list, &sc_netlink_dev_list);
|
list_add_rcu(&nldev->list, &sn->sc_netlink_dev_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nldev;
|
return nldev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_unregister_device(uint32_t ifindex) {
|
static int sc_netlink_unregister_device(struct sc_net *sn, uint32_t ifindex)
|
||||||
|
{
|
||||||
int ret = -ENODEV;
|
int ret = -ENODEV;
|
||||||
struct sc_netlink_device* nldev;
|
struct sc_netlink_device* nldev;
|
||||||
|
|
||||||
@ -199,7 +216,7 @@ static int sc_netlink_unregister_device(uint32_t ifindex) {
|
|||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
/* Search device */
|
/* Search device */
|
||||||
list_for_each_entry(nldev, &sc_netlink_dev_list, list) {
|
list_for_each_entry(nldev, &sn->sc_netlink_dev_list, list) {
|
||||||
if (nldev->ifindex == ifindex) {
|
if (nldev->ifindex == ifindex) {
|
||||||
/* Remove from list */
|
/* Remove from list */
|
||||||
list_del_rcu(&nldev->list);
|
list_del_rcu(&nldev->list);
|
||||||
@ -216,7 +233,7 @@ static int sc_netlink_unregister_device(uint32_t ifindex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static void sc_netlink_unregister_alldevice(void) {
|
static void sc_netlink_unregister_alldevice(struct sc_net *sn) {
|
||||||
struct sc_netlink_device* tmp;
|
struct sc_netlink_device* tmp;
|
||||||
struct sc_netlink_device* nldev;
|
struct sc_netlink_device* nldev;
|
||||||
|
|
||||||
@ -225,7 +242,7 @@ static void sc_netlink_unregister_alldevice(void) {
|
|||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
/* Close all devices */
|
/* Close all devices */
|
||||||
list_for_each_entry_safe(nldev, tmp, &sc_netlink_dev_list, list) {
|
list_for_each_entry_safe(nldev, tmp, &sn->sc_netlink_dev_list, list) {
|
||||||
/* Remove from list */
|
/* Remove from list */
|
||||||
list_del_rcu(&nldev->list);
|
list_del_rcu(&nldev->list);
|
||||||
synchronize_net();
|
synchronize_net();
|
||||||
@ -236,42 +253,48 @@ static void sc_netlink_unregister_alldevice(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_link(struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_link(struct sk_buff* skb, struct genl_info* info)
|
||||||
|
{
|
||||||
|
struct net *net = genl_info_net(info);
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t portid = genl_info_snd_portid(info);
|
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_link\n");
|
TRACEKMOD("### sc_netlink_link\n");
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
if (sc_netlink_usermodeid) {
|
if (sn->sc_netlink_usermodeid) {
|
||||||
TRACEKMOD("*** Busy kernel link\n");
|
TRACEKMOD("*** Busy kernel link\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize library */
|
/* Initialize library */
|
||||||
ret = sc_capwap_init();
|
ret = sc_capwap_init(net);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deny unload module */
|
/* Deny unload module */
|
||||||
sc_netlink_usermodeid = portid;
|
sn->sc_netlink_usermodeid = info->snd_portid;
|
||||||
try_module_get(THIS_MODULE);
|
try_module_get(THIS_MODULE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_reset(struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_reset(struct sk_buff* skb, struct genl_info* info)
|
||||||
|
{
|
||||||
|
struct net *net = genl_info_net(info);
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_reset\n");
|
TRACEKMOD("### sc_netlink_reset\n");
|
||||||
|
|
||||||
/* Check Link */
|
/* Check Link */
|
||||||
if (!sc_netlink_usermodeid) {
|
if (!sn->sc_netlink_usermodeid) {
|
||||||
return -ENOLINK;
|
return -ENOLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close all devices */
|
/* Close all devices */
|
||||||
sc_netlink_unregister_alldevice();
|
sc_netlink_unregister_alldevice(sn);
|
||||||
|
|
||||||
/* Reset session */
|
/* Reset session */
|
||||||
sc_capwap_resetsession();
|
sc_capwap_resetsession();
|
||||||
@ -280,16 +303,20 @@ 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;
|
||||||
|
struct sc_net *sn = net_generic(notify->net, sc_net_id);
|
||||||
|
|
||||||
if ((state == NETLINK_URELEASE) && (sc_netlink_usermodeid == netlink_notify_portid(notify))) {
|
if ((state == NETLINK_URELEASE) && (sn->sc_netlink_usermodeid == notify->portid)) {
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
|
|
||||||
sc_netlink_usermodeid = 0;
|
sn->sc_netlink_usermodeid = 0;
|
||||||
|
|
||||||
/* Close all devices */
|
/* Close all devices */
|
||||||
sc_netlink_unregister_alldevice();
|
sc_netlink_unregister_alldevice(sn);
|
||||||
|
|
||||||
/* Close capwap engine */
|
/* Close capwap engine */
|
||||||
sc_capwap_close();
|
sc_capwap_close();
|
||||||
@ -304,18 +331,22 @@ static int sc_netlink_notify(struct notifier_block* nb, unsigned long state, voi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_bind(struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_bind(struct sk_buff* skb, struct genl_info* info)
|
||||||
|
{
|
||||||
|
struct net *net = genl_info_net(info);
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
union capwap_addr sockaddr;
|
union capwap_addr sockaddr;
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_bind\n");
|
TRACEKMOD("### sc_netlink_bind\n");
|
||||||
|
|
||||||
/* Check Link */
|
/* Check Link */
|
||||||
if (!sc_netlink_usermodeid) {
|
if (!sn->sc_netlink_usermodeid) {
|
||||||
return -ENOLINK;
|
return -ENOLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get bind address */
|
/* Get bind address */
|
||||||
if (!info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS] || (nla_len(info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS]) != sizeof(struct sockaddr_storage))) {
|
if (!info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS] ||
|
||||||
|
(nla_len(info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS]) != sizeof(struct sockaddr_storage))) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,11 +356,14 @@ static int sc_netlink_bind(struct sk_buff* skb, struct genl_info* info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Bind socket */
|
/* Bind socket */
|
||||||
return sc_capwap_bind(&sockaddr);
|
return sc_capwap_bind(net, &sockaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_connect(struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_connect(struct sk_buff* skb, struct genl_info* info)
|
||||||
|
{
|
||||||
|
struct net *net = genl_info_net(info);
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
int ret;
|
int ret;
|
||||||
union capwap_addr sockaddr;
|
union capwap_addr sockaddr;
|
||||||
struct sc_capwap_sessionid_element sessionid;
|
struct sc_capwap_sessionid_element sessionid;
|
||||||
@ -338,12 +372,13 @@ 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) {
|
if (!sn->sc_netlink_usermodeid) {
|
||||||
return -ENOLINK;
|
return -ENOLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get AC address */
|
/* Get AC address */
|
||||||
if (!info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS] || (nla_len(info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS]) != sizeof(struct sockaddr_storage))) {
|
if (!info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS] ||
|
||||||
|
(nla_len(info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS]) != sizeof(struct sockaddr_storage))) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,14 +396,15 @@ static int sc_netlink_connect(struct sk_buff* skb, struct genl_info* info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get Session ID */
|
/* Get Session ID */
|
||||||
if (info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID] && (nla_len(info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID]) == sizeof(struct sc_capwap_sessionid_element))) {
|
if (info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID] &&
|
||||||
|
(nla_len(info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID]) == sizeof(struct sc_capwap_sessionid_element))) {
|
||||||
memcpy(sessionid.id, nla_data(info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID]), sizeof(struct sc_capwap_sessionid_element));
|
memcpy(sessionid.id, nla_data(info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID]), sizeof(struct sc_capwap_sessionid_element));
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send packet */
|
/* Send packet */
|
||||||
ret = sc_capwap_connect(&sockaddr, &sessionid, mtu);
|
ret = sc_capwap_connect(net, &sockaddr, &sessionid, mtu);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -377,13 +413,16 @@ static int sc_netlink_connect(struct sk_buff* skb, struct genl_info* info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_send_keepalive(struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_send_keepalive(struct sk_buff* skb, struct genl_info* info)
|
||||||
|
{
|
||||||
|
struct net *net = genl_info_net(info);
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_send_keepalive\n");
|
TRACEKMOD("### sc_netlink_send_keepalive\n");
|
||||||
|
|
||||||
/* Check Link */
|
/* Check Link */
|
||||||
if (!sc_netlink_usermodeid) {
|
if (!sn->sc_netlink_usermodeid) {
|
||||||
return -ENOLINK;
|
return -ENOLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +436,10 @@ static int sc_netlink_send_keepalive(struct sk_buff* skb, struct genl_info* info
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_send_data(struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_send_data(struct sk_buff* skb, struct genl_info* info)
|
||||||
|
{
|
||||||
|
struct net *net = genl_info_net(info);
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t radioid;
|
uint8_t radioid;
|
||||||
uint8_t binding;
|
uint8_t binding;
|
||||||
@ -413,9 +455,10 @@ 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) {
|
if (!sn->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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,7 +524,10 @@ static int sc_netlink_send_data(struct sk_buff* skb, struct genl_info* info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_join_mac80211_device(struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_join_mac80211_device(struct sk_buff* skb, struct genl_info* info)
|
||||||
|
{
|
||||||
|
struct net *net = genl_info_net(info);
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t ifindex;
|
uint32_t ifindex;
|
||||||
struct sc_netlink_device* nldev;
|
struct sc_netlink_device* nldev;
|
||||||
@ -489,7 +535,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) {
|
if (!sn->sc_netlink_usermodeid) {
|
||||||
return -ENOLINK;
|
return -ENOLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,12 +550,17 @@ static int sc_netlink_join_mac80211_device(struct sk_buff* skb, struct genl_info
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check */
|
/* Check */
|
||||||
if (!info->attrs[NLSMARTCAPWAP_ATTR_RADIOID] || !info->attrs[NLSMARTCAPWAP_ATTR_WLANID] || !info->attrs[NLSMARTCAPWAP_ATTR_BINDING]) {
|
if (!info->attrs[NLSMARTCAPWAP_ATTR_RADIOID] ||
|
||||||
|
!info->attrs[NLSMARTCAPWAP_ATTR_WLANID] ||
|
||||||
|
!info->attrs[NLSMARTCAPWAP_ATTR_BINDING]) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register device */
|
/* Register device */
|
||||||
nldev = sc_netlink_register_device(ifindex, nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_RADIOID]), nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_WLANID]), nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_BINDING]));
|
nldev = sc_netlink_register_device(net, ifindex,
|
||||||
|
nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_RADIOID]),
|
||||||
|
nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_WLANID]),
|
||||||
|
nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_BINDING]));
|
||||||
if (!nldev) {
|
if (!nldev) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -521,32 +572,39 @@ static int sc_netlink_join_mac80211_device(struct sk_buff* skb, struct genl_info
|
|||||||
|
|
||||||
/* Set subtype masking */
|
/* Set subtype masking */
|
||||||
if (info->attrs[NLSMARTCAPWAP_ATTR_MGMT_SUBTYPE_MASK]) {
|
if (info->attrs[NLSMARTCAPWAP_ATTR_MGMT_SUBTYPE_MASK]) {
|
||||||
nldev->pcktunnel_handler.subtype_mask[0] = nla_get_u16(info->attrs[NLSMARTCAPWAP_ATTR_MGMT_SUBTYPE_MASK]);
|
nldev->pcktunnel_handler.subtype_mask[0] =
|
||||||
|
nla_get_u16(info->attrs[NLSMARTCAPWAP_ATTR_MGMT_SUBTYPE_MASK]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->attrs[NLSMARTCAPWAP_ATTR_CTRL_SUBTYPE_MASK]) {
|
if (info->attrs[NLSMARTCAPWAP_ATTR_CTRL_SUBTYPE_MASK]) {
|
||||||
nldev->pcktunnel_handler.subtype_mask[1] = nla_get_u16(info->attrs[NLSMARTCAPWAP_ATTR_CTRL_SUBTYPE_MASK]);
|
nldev->pcktunnel_handler.subtype_mask[1] =
|
||||||
|
nla_get_u16(info->attrs[NLSMARTCAPWAP_ATTR_CTRL_SUBTYPE_MASK]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->attrs[NLSMARTCAPWAP_ATTR_DATA_SUBTYPE_MASK]) {
|
if (info->attrs[NLSMARTCAPWAP_ATTR_DATA_SUBTYPE_MASK]) {
|
||||||
nldev->pcktunnel_handler.subtype_mask[2] = nla_get_u16(info->attrs[NLSMARTCAPWAP_ATTR_DATA_SUBTYPE_MASK]);
|
nldev->pcktunnel_handler.subtype_mask[2] =
|
||||||
|
nla_get_u16(info->attrs[NLSMARTCAPWAP_ATTR_DATA_SUBTYPE_MASK]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect device to mac80211 */
|
/* Connect device to mac80211 */
|
||||||
ret = ieee80211_pcktunnel_register(nldev->dev, &nldev->pcktunnel_handler);
|
ret = ieee80211_pcktunnel_register(nldev->dev, &nldev->pcktunnel_handler);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
sc_netlink_unregister_device(ifindex);
|
sc_netlink_unregister_device(sn, ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_netlink_leave_mac80211_device(struct sk_buff* skb, struct genl_info* info) {
|
static int sc_netlink_leave_mac80211_device(struct sk_buff* skb, struct genl_info* info)
|
||||||
|
{
|
||||||
|
struct net *net = genl_info_net(info);
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_leave_mac80211_device\n");
|
TRACEKMOD("### sc_netlink_leave_mac80211_device\n");
|
||||||
|
|
||||||
/* Check Link */
|
/* Check Link */
|
||||||
if (!sc_netlink_usermodeid) {
|
if (!sn->sc_netlink_usermodeid) {
|
||||||
return -ENOLINK;
|
return -ENOLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,15 +614,19 @@ static int sc_netlink_leave_mac80211_device(struct sk_buff* skb, struct genl_inf
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unregister device */
|
/* Unregister device */
|
||||||
return sc_netlink_unregister_device(nla_get_u32(info->attrs[NLSMARTCAPWAP_ATTR_IFINDEX]));
|
return sc_netlink_unregister_device(sn, nla_get_u32(info->attrs[NLSMARTCAPWAP_ATTR_IFINDEX]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_device_event(struct notifier_block* unused, unsigned long event, void* ptr) {
|
static int sc_device_event(struct notifier_block* unused,
|
||||||
|
unsigned long event,
|
||||||
|
void* ptr)
|
||||||
|
{
|
||||||
struct net_device* dev = netdev_notifier_info_to_dev(ptr);
|
struct net_device* dev = netdev_notifier_info_to_dev(ptr);
|
||||||
|
struct sc_net *sn = net_generic(dev_net(dev), sc_net_id);
|
||||||
|
|
||||||
/* Check event only if connect with WTP userspace */
|
/* Check event only if connect with WTP userspace */
|
||||||
if (!sc_netlink_usermodeid) {
|
if (!sn->sc_netlink_usermodeid) {
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,7 +634,7 @@ static int sc_device_event(struct notifier_block* unused, unsigned long event, v
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
case NETDEV_UNREGISTER: {
|
case NETDEV_UNREGISTER: {
|
||||||
/* Try to unregister device */
|
/* Try to unregister device */
|
||||||
sc_netlink_unregister_device(dev->ifindex);
|
sc_netlink_unregister_device(sn, dev->ifindex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -664,7 +726,11 @@ struct notifier_block sc_device_notifier = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid) {
|
int sc_netlink_notify_recv_keepalive(struct net *net,
|
||||||
|
const union capwap_addr* sockaddr,
|
||||||
|
struct sc_capwap_sessionid_element* sessionid)
|
||||||
|
{
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
void* msg;
|
void* msg;
|
||||||
struct sk_buff* sk_msg;
|
struct sk_buff* sk_msg;
|
||||||
|
|
||||||
@ -685,11 +751,13 @@ int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct s
|
|||||||
|
|
||||||
/* Send message */
|
/* Send message */
|
||||||
genlmsg_end(sk_msg, msg);
|
genlmsg_end(sk_msg, msg);
|
||||||
return genlmsg_unicast(&init_net, sk_msg, sc_netlink_usermodeid);
|
return genlmsg_unicast(net, sk_msg, sn->sc_netlink_usermodeid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_netlink_notify_recv_data(uint8_t* packet, int length) {
|
int sc_netlink_notify_recv_data(struct net *net, uint8_t* packet, int length)
|
||||||
|
{
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
void* msg;
|
void* msg;
|
||||||
struct sk_buff* sk_msg;
|
struct sk_buff* sk_msg;
|
||||||
|
|
||||||
@ -714,7 +782,7 @@ int sc_netlink_notify_recv_data(uint8_t* packet, int length) {
|
|||||||
|
|
||||||
/* Send message */
|
/* Send message */
|
||||||
genlmsg_end(sk_msg, msg);
|
genlmsg_end(sk_msg, msg);
|
||||||
return genlmsg_unicast(&init_net, sk_msg, sc_netlink_usermodeid);
|
return genlmsg_unicast(net, sk_msg, sn->sc_netlink_usermodeid);
|
||||||
|
|
||||||
error2:
|
error2:
|
||||||
genlmsg_cancel(sk_msg, msg);
|
genlmsg_cancel(sk_msg, msg);
|
||||||
@ -725,13 +793,17 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
struct net_device* sc_netlink_getdev_from_wlanid(uint8_t radioid, uint8_t wlanid) {
|
struct net_device* sc_netlink_getdev_from_wlanid(struct net *net,
|
||||||
|
uint8_t radioid,
|
||||||
|
uint8_t wlanid)
|
||||||
|
{
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
struct sc_netlink_device* nldev;
|
struct sc_netlink_device* nldev;
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_getdev_from_wlanid\n");
|
TRACEKMOD("### sc_netlink_getdev_from_wlanid\n");
|
||||||
|
|
||||||
/* Search */
|
/* Search */
|
||||||
list_for_each_entry(nldev, &sc_netlink_dev_list, list) {
|
list_for_each_entry(nldev, &sn->sc_netlink_dev_list, list) {
|
||||||
if ((nldev->radioid == radioid) && (nldev->wlanid == wlanid)) {
|
if ((nldev->radioid == radioid) && (nldev->wlanid == wlanid)) {
|
||||||
return nldev->dev;
|
return nldev->dev;
|
||||||
}
|
}
|
||||||
@ -741,13 +813,17 @@ struct net_device* sc_netlink_getdev_from_wlanid(uint8_t radioid, uint8_t wlanid
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
struct net_device* sc_netlink_getdev_from_bssid(uint8_t radioid, const uint8_t* addr) {
|
struct net_device* sc_netlink_getdev_from_bssid(struct net *net,
|
||||||
|
uint8_t radioid,
|
||||||
|
const uint8_t* addr)
|
||||||
|
{
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
struct sc_netlink_device* nldev;
|
struct sc_netlink_device* nldev;
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_getdev_from_bssid\n");
|
TRACEKMOD("### sc_netlink_getdev_from_bssid\n");
|
||||||
|
|
||||||
/* Search */
|
/* Search */
|
||||||
list_for_each_entry(nldev, &sc_netlink_dev_list, list) {
|
list_for_each_entry(nldev, &sn->sc_netlink_dev_list, list) {
|
||||||
if ((nldev->radioid == radioid) && !memcmp(nldev->dev->dev_addr, addr, MACADDRESS_EUI48_LENGTH)) {
|
if ((nldev->radioid == radioid) && !memcmp(nldev->dev->dev_addr, addr, MACADDRESS_EUI48_LENGTH)) {
|
||||||
return nldev->dev;
|
return nldev->dev;
|
||||||
}
|
}
|
||||||
@ -756,48 +832,79 @@ struct net_device* sc_netlink_getdev_from_bssid(uint8_t radioid, const uint8_t*
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __net_init sc_net_init(struct net *net)
|
||||||
|
{
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
|
|
||||||
|
sn->sc_netlink_usermodeid = 0;
|
||||||
|
INIT_LIST_HEAD(&sn->sc_netlink_dev_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __net_exit sc_net_exit(struct net *net)
|
||||||
|
{
|
||||||
|
struct sc_net *sn = net_generic(net, sc_net_id);
|
||||||
|
|
||||||
|
rtnl_lock();
|
||||||
|
sc_netlink_unregister_alldevice(sn);
|
||||||
|
rtnl_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pernet_operations sc_net_ops = {
|
||||||
|
.init = sc_net_init,
|
||||||
|
.exit = sc_net_exit,
|
||||||
|
.id = &sc_net_id,
|
||||||
|
.size = sizeof(struct sc_net),
|
||||||
|
};
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_netlink_init(void) {
|
int __init sc_netlink_init(void) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
TRACEKMOD("### sc_netlink_init\n");
|
TRACEKMOD("### sc_netlink_init\n");
|
||||||
|
|
||||||
/* */
|
|
||||||
sc_netlink_usermodeid = 0;
|
|
||||||
|
|
||||||
/* Register interface event */
|
/* Register interface event */
|
||||||
ret = register_netdevice_notifier(&sc_device_notifier);
|
ret = register_netdevice_notifier(&sc_device_notifier);
|
||||||
if (ret) {
|
if (ret < 0)
|
||||||
goto error;
|
goto error_out;
|
||||||
}
|
|
||||||
|
|
||||||
/* Register netlink family */
|
/* Register netlink family */
|
||||||
ret = genl_register_family_with_ops(&sc_netlink_family, sc_netlink_ops);
|
ret = genl_register_family_with_ops(&sc_netlink_family, sc_netlink_ops);
|
||||||
if (ret) {
|
if (ret < 0)
|
||||||
goto error2;
|
goto unreg_netdev_notifier;
|
||||||
}
|
|
||||||
|
|
||||||
/* Register netlink notifier */
|
/* Register netlink notifier */
|
||||||
ret = netlink_register_notifier(&sc_netlink_notifier);
|
ret = netlink_register_notifier(&sc_netlink_notifier);
|
||||||
if (ret) {
|
if (ret)
|
||||||
goto error3;
|
goto unreg_genl_family;
|
||||||
}
|
|
||||||
|
|
||||||
|
ret = register_pernet_subsys(&sc_net_ops);
|
||||||
|
if (ret < 0)
|
||||||
|
goto unreg_nl_notifier;
|
||||||
|
|
||||||
|
pr_info("smartCAPWAP module loaded");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error3:
|
unreg_nl_notifier:
|
||||||
|
netlink_unregister_notifier(&sc_netlink_notifier);
|
||||||
|
unreg_genl_family:
|
||||||
genl_unregister_family(&sc_netlink_family);
|
genl_unregister_family(&sc_netlink_family);
|
||||||
error2:
|
unreg_netdev_notifier:
|
||||||
unregister_netdevice_notifier(&sc_device_notifier);
|
unregister_netdevice_notifier(&sc_device_notifier);
|
||||||
error:
|
error_out:
|
||||||
|
pr_err("error loading smartCAPWAP module\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
void sc_netlink_exit(void) {
|
void __exit sc_netlink_exit(void) {
|
||||||
TRACEKMOD("### sc_netlink_exit\n");
|
TRACEKMOD("### sc_netlink_exit\n");
|
||||||
|
|
||||||
|
unregister_pernet_subsys(&sc_net_ops);
|
||||||
netlink_unregister_notifier(&sc_netlink_notifier);
|
netlink_unregister_notifier(&sc_netlink_notifier);
|
||||||
genl_unregister_family(&sc_netlink_family);
|
genl_unregister_family(&sc_netlink_family);
|
||||||
unregister_netdevice_notifier(&sc_device_notifier);
|
unregister_netdevice_notifier(&sc_device_notifier);
|
||||||
|
|
||||||
|
pr_info("smartCAWAP module unloaded\n");
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,13 @@ int sc_netlink_init(void);
|
|||||||
void sc_netlink_exit(void);
|
void sc_netlink_exit(void);
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
struct net_device* sc_netlink_getdev_from_wlanid(uint8_t radioid, uint8_t wlanid);
|
struct net_device* sc_netlink_getdev_from_wlanid(struct net *net, uint8_t radioid, uint8_t wlanid);
|
||||||
struct net_device* sc_netlink_getdev_from_bssid(uint8_t radioid, const uint8_t* addr);
|
struct net_device* sc_netlink_getdev_from_bssid(struct net *net, uint8_t radioid, const uint8_t* addr);
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid);
|
int sc_netlink_notify_recv_keepalive(struct net *net,
|
||||||
int sc_netlink_notify_recv_data(uint8_t* packet, int length);
|
const union capwap_addr* sockaddr,
|
||||||
|
struct sc_capwap_sessionid_element* sessionid);
|
||||||
|
int sc_netlink_notify_recv_data(struct net *net, uint8_t* packet, int length);
|
||||||
|
|
||||||
#endif /* __KMOD_WTP_NETLINKAPP_HEADER__ */
|
#endif /* __KMOD_WTP_NETLINKAPP_HEADER__ */
|
||||||
|
@ -29,13 +29,13 @@ int sc_socket_recvpacket(struct sock* sk, struct sk_buff* skb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int sc_socket_create(int type, union capwap_addr* sockaddr, uint16_t protocol) {
|
static int sc_socket_create(struct net *net, int type, union capwap_addr* sockaddr, uint16_t protocol) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
TRACEKMOD("### sc_socket_create\n");
|
TRACEKMOD("### sc_socket_create\n");
|
||||||
|
|
||||||
/* Create socket */
|
/* Create socket */
|
||||||
ret = sock_create_kern(sockaddr->ss.ss_family, SOCK_DGRAM, protocol, &sc_sockets[type]);
|
ret = sock_create_kern(net, sockaddr->ss.ss_family, SOCK_DGRAM, protocol, &sc_sockets[type]);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -158,7 +158,7 @@ int sc_socket_init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_socket_bind(union capwap_addr* sockaddr) {
|
int sc_socket_bind(struct net *net, union capwap_addr* sockaddr) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
TRACEKMOD("### sc_socket_bind\n");
|
TRACEKMOD("### sc_socket_bind\n");
|
||||||
@ -169,13 +169,13 @@ int sc_socket_bind(union capwap_addr* sockaddr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* UDP socket */
|
/* UDP socket */
|
||||||
ret = sc_socket_create(SOCKET_UDP, sockaddr, IPPROTO_UDP);
|
ret = sc_socket_create(net, SOCKET_UDP, sockaddr, IPPROTO_UDP);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UDPLite socket */
|
/* UDPLite socket */
|
||||||
ret = sc_socket_create(SOCKET_UDPLITE, sockaddr, IPPROTO_UDPLITE);
|
ret = sc_socket_create(net, SOCKET_UDPLITE, sockaddr, IPPROTO_UDPLITE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ int sc_socket_init(void);
|
|||||||
void sc_socket_close(void);
|
void sc_socket_close(void);
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int sc_socket_bind(union capwap_addr* sockaddr);
|
int sc_socket_bind(struct net *net, union capwap_addr* sockaddr);
|
||||||
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr);
|
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr);
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
Loading…
Reference in New Issue
Block a user