Add skeleton code for CAPWAP Data Channel kernel module.

The IEEE802.11 data packets will embedded into CAPWAP Data Channel directly in
kernel mode. The CAPWAP Data Channel in usermode be used only for compatibility
reasons.
This commit is contained in:
vemax78 2014-06-01 16:32:30 +02:00
parent 289fbe01c7
commit 0ebf1a434f
16 changed files with 831 additions and 15 deletions

View File

@ -34,6 +34,7 @@ INCLUDES = \
-I$(top_srcdir)/build \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/wtp \
-I$(top_srcdir)/src/kmod \
-I$(top_srcdir)/src/common/binding/ieee80211 \
-I$(top_srcdir)/src/wtp/binding/ieee80211
@ -42,6 +43,7 @@ include $(top_srcdir)/build/Makefile_common.am
wtp_SOURCES = \
$(capwap_SOURCES) \
$(top_srcdir)/src/wtp/wtp.c \
$(top_srcdir)/src/wtp/wtp_kmod.c \
$(top_srcdir)/src/wtp/wtp_element_helper.c \
$(top_srcdir)/src/wtp/wtp_dfa.c \
$(top_srcdir)/src/wtp/wtp_dfa_idle.c \

103
openwrt/Makefile Normal file
View File

@ -0,0 +1,103 @@
#
# Copyright (C) 2006 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=smartcapwap
PKG_VERSION:=1.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
PKG_FIXUP:=autoreconf
include $(INCLUDE_DIR)/package.mk
define Package/smartcapwap
SECTION:=net
CATEGORY:=Network
TITLE:=SmartCAPWAP WTP
MAINTAINER:=Massimo Vellucci <vemax78@gmail.com>
DEPENDS:=+libnl-tiny +libconfig +libcyassl +kmod-smartcapwap
endef
define Package/smartcapwap/description
This package contains the SmartCAPWAP WTP daemon.
endef
define KernelPackage/smartcapwap
SUBMENU:=Network Support
TITLE:=SmartCAPWAP Data Channel Module
MAINTAINER:=Massimo Vellucci <vemax78@gmail.com>
DEPENDS:=+kmod-mac80211
FILES:=$(PKG_BUILD_DIR)/src/kmod/smartcapwap.ko
AUTOLOAD:=$(call AutoLoad,70,smartcapwap)
endef
define KernelPackage/smartcapwap/description
This package contains the SmartCAPWAP Data Transport kernel module.
endef
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/libnl-tiny
SRC_SMARTCAPWAP:=/mnt/hgfs/shared/smartcapwap
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) -r $(SRC_SMARTCAPWAP)/* $(PKG_BUILD_DIR)/
endef
define Build/Configure
$(call Build/Configure/Default, --disable-ac)
endef
define Build/Compile/wtp
$(MAKE) -C $(PKG_BUILD_DIR) \
$(TARGET_CONFIGURE_OPTS) \
all
endef
define Build/Compile/kmod
$(MAKE) -C "$(LINUX_DIR)" \
CROSS_COMPILE="$(KERNEL_CROSS)" \
ARCH="$(LINUX_KARCH)" \
SUBDIRS="$(PKG_BUILD_DIR)/src/kmod" \
KLIB_BUILD="$(LINUX_DIR)" \
KLIB="$(TARGET_MODULES_DIR)" \
KBUILD_EXTRA_SYMBOLS="$(LINUX_DIR)/../compat-wireless-2014-03-31/Module.symvers" \
LINUXINCLUDE="-I$(STAGING_DIR)/usr/include/mac80211-backport \
-I$(LINUX_DIR)/arch/x86/include \
-Iarch/x86/include/generated \
-Iinclude \
-I$(LINUX_DIR)/arch/x86/include/uapi \
-Iarch/x86/include/generated/uapi \
-I$(LINUX_DIR)/include/uapi \
-Iinclude/generated/uapi \
-include $(LINUX_DIR)/include/linux/kconfig.h \
-include $(STAGING_DIR)/usr/include/mac80211-backport/backport/backport.h \
" \
V="$(V)" \
modules
endef
define Build/Compile
$(Build/Compile/wtp)
$(Build/Compile/kmod)
endef
define Package/smartcapwap/install
$(INSTALL_DIR) $(1)/etc/capwap
$(INSTALL_CONF) ./files/wtp.conf $(1)/etc/capwap/wtp.conf
$(INSTALL_CONF) ./files/ca.crt $(1)/etc/capwap/ca.crt
$(INSTALL_CONF) ./files/wtp.crt $(1)/etc/capwap/wtp.crt
$(INSTALL_CONF) ./files/wtp.key $(1)/etc/capwap/wtp.key
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/wtp/wtp $(1)/usr/bin
endef
$(eval $(call BuildPackage,smartcapwap))
$(eval $(call KernelPackage,smartcapwap))

23
openwrt/files/ca.crt Normal file
View File

@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID3TCCA0agAwIBAgIJAJpqxrKqMyLFMA0GCSqGSIb3DQEBBQUAMIGmMQswCQYD
VQQGEwJJVDELMAkGA1UECBMCSVQxDTALBgNVBAcTBFJvbWUxFDASBgNVBAoTC1Nt
YXJ0Q0FQV0FQMRQwEgYDVQQLEwtTbWFydENBUFdBUDEXMBUGA1UEAxMOU21hcnRD
QVBXQVAgQ0ExFDASBgNVBCkTC1NtYXJ0Q0FQV0FQMSAwHgYJKoZIhvcNAQkBFhF2
ZW1heDc4QGdtYWlsLmNvbTAeFw0xNDA1MTUxODAxNDNaFw0yNDA1MTIxODAxNDNa
MIGmMQswCQYDVQQGEwJJVDELMAkGA1UECBMCSVQxDTALBgNVBAcTBFJvbWUxFDAS
BgNVBAoTC1NtYXJ0Q0FQV0FQMRQwEgYDVQQLEwtTbWFydENBUFdBUDEXMBUGA1UE
AxMOU21hcnRDQVBXQVAgQ0ExFDASBgNVBCkTC1NtYXJ0Q0FQV0FQMSAwHgYJKoZI
hvcNAQkBFhF2ZW1heDc4QGdtYWlsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEA72PBMR4HQ+rA+ifXJdMtUujlUQX1yrtXZ0HMdKbHbAbfoY3Rvyfdwo2i
TMaZYomyCASawZRzkZJvPchu/q9au/UdLuTmeaUCDpvIkibMK5tahTgP5x90IMGu
+uzdgZQaPbv+fjYkAmMGkZYYTha8GhH+vNloSb6n8oUh2eGf1kUCAwEAAaOCAQ8w
ggELMB0GA1UdDgQWBBS4vrLLxmi9CrvlvN6uVv4l5uSzHDCB2wYDVR0jBIHTMIHQ
gBS4vrLLxmi9CrvlvN6uVv4l5uSzHKGBrKSBqTCBpjELMAkGA1UEBhMCSVQxCzAJ
BgNVBAgTAklUMQ0wCwYDVQQHEwRSb21lMRQwEgYDVQQKEwtTbWFydENBUFdBUDEU
MBIGA1UECxMLU21hcnRDQVBXQVAxFzAVBgNVBAMTDlNtYXJ0Q0FQV0FQIENBMRQw
EgYDVQQpEwtTbWFydENBUFdBUDEgMB4GCSqGSIb3DQEJARYRdmVtYXg3OEBnbWFp
bC5jb22CCQCaasayqjMixTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
ANZuFab2/jLSakpGc0nZjCWAlXm29TCkL1i0yxmpjgbg/tqZrSAb1tuK5IANI7Tz
deOObRRxjjRGgSHnFLcKXmJeGjTmIdX7DLALWQALmc0GG+A1T1vHqVKc3YqjmUP3
4X/JgFqJnF1KkKmcDLiLBmA8W4+rLPe3kKhNloKQ9G1m
-----END CERTIFICATE-----

150
openwrt/files/wtp.conf Normal file
View File

@ -0,0 +1,150 @@
# WTP configuration file
version = "1.0";
application: {
standalone = true;
name = "wtp 1";
location = "Ufficio";
binding = "802.11";
tunnelmode: {
nativeframe = false;
ethframe = false;
localbridging = true;
};
mactype = "localmac";
boardinfo: {
idvendor = 123456;
element = (
{ name = "model"; value = "1.0"; },
{ name = "serial"; value = "2.0"; },
{ name = "id"; value = "3.0"; },
{ name = "revision"; value = "4.0"; },
{ name = "macaddress"; type = "interface"; value = "eth0"; }
);
};
descriptor: {
encryption = [
"802.11_AES",
"802.11_TKIP"
];
info = (
{ idvendor = 23456; type = "hardware"; value = "abcde"; },
{ idvendor = 33457; type = "software"; value = "fghil"; },
{ idvendor = 43458; type = "boot"; value = "mnopq"; },
{ idvendor = 53459; type = "other"; value = "qwert"; }
);
};
ecn = "limited";
timer: {
statistics = 120;
};
dtls: {
enable = true;
dtlspolicy: {
cleardatachannel = true;
dtlsdatachannel = true;
};
type = "x509";
presharedkey: {
identity = "prova";
pskkey = "123456";
};
x509: {
calist = "/etc/capwap/ca.crt";
certificate = "/etc/capwap/wtp.crt";
privatekey = "/etc/capwap/wtp.key";
};
};
wlan: {
prefix = "ap";
};
radio = (
{
device = "phy0";
enabled = true;
driver = "nl80211";
mode = "bg";
country = "IT";
outdoor = false;
rtsthreshold = 2347;
shortretry = 7;
longretry = 4;
shortpreamble = true;
fragmentationthreshold = 2346;
txmsdulifetime = 512;
rxmsdulifetime = 512;
maxbssid = 1;
bssprefixname = "ap";
dtimperiod = 2;
beaconperiod = 100;
antenna = {
diversity = false;
combiner = "omni";
selection = [ "internal" ];
};
multidomaincapability = {
firstchannel = 1;
numberchannels = 11;
maxtxpower = 100;
};
supportedrates = [
12, 18, 24, 36, 48, 72, 96, 108
];
txpower = {
current = 100;
supported = [ 100 ];
};
}
);
network: {
#binding = "eth1";
mtu = 1500;
transport = "udp";
ipv4 = true;
ipv6 = false;
ipdualstack = true;
};
acdiscovery: {
search = false;
host = [
"192.168.1.101"
];
};
acprefered: {
host = [
"192.168.1.101"
];
};
};
logging: {
enable = true;
level = "debug";
output = (
{ mode = "stdout"; }
);
};

73
openwrt/files/wtp.crt Normal file
View File

@ -0,0 +1,73 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=IT, ST=IT, L=Rome, O=SmartCAPWAP, OU=SmartCAPWAP, CN=SmartCAPWAP CA/name=SmartCAPWAP/emailAddress=vemax78@gmail.com
Validity
Not Before: May 15 18:02:22 2014 GMT
Not After : May 12 18:02:22 2024 GMT
Subject: C=IT, ST=IT, L=Rome, O=SmartCAPWAP, OU=SmartCAPWAP, CN=wtp1/name=SmartCAPWAP/emailAddress=vemax78@gmail.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:b2:b1:a5:56:a7:ef:4d:76:76:0c:09:0f:5e:c3:
4b:cd:9c:80:ae:1b:fa:8a:63:6b:3e:5d:df:18:e5:
30:25:4a:bf:02:90:a0:1a:db:d9:7b:d3:c0:f2:5b:
82:de:07:bd:4c:43:66:4d:39:6c:fe:88:d5:1a:ac:
47:d0:4c:2d:e0:05:4d:95:80:b5:61:df:84:03:cb:
26:f7:b3:77:8c:e5:28:9e:71:5e:4b:01:42:64:64:
d4:1f:8b:e2:c6:12:af:9f:64:de:63:f0:b2:ff:fb:
0e:82:d8:ba:cf:a9:21:7f:43:4f:c9:19:e0:50:e1:
90:ac:ce:d2:ab:dc:87:b9:9f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
Netscape Comment:
Easy-RSA Generated Certificate
X509v3 Subject Key Identifier:
5D:1C:43:55:79:96:EC:CD:9F:81:47:7F:23:F2:88:C4:80:EF:7A:C6
X509v3 Authority Key Identifier:
keyid:B8:BE:B2:CB:C6:68:BD:0A:BB:E5:BC:DE:AE:56:FE:25:E6:E4:B3:1C
DirName:/C=IT/ST=IT/L=Rome/O=SmartCAPWAP/OU=SmartCAPWAP/CN=SmartCAPWAP CA/name=SmartCAPWAP/emailAddress=vemax78@gmail.com
serial:9A:6A:C6:B2:AA:33:22:C5
X509v3 Extended Key Usage:
TLS Web Client Authentication
Signature Algorithm: sha1WithRSAEncryption
2e:1b:fb:12:36:08:97:f4:93:2d:5e:5a:94:e0:67:a9:69:9c:
d3:24:8b:51:87:b4:fd:02:cd:29:9c:54:5f:5c:27:4c:02:08:
6a:64:79:84:a9:dd:df:f4:9d:7d:b7:19:e9:26:a6:01:af:a7:
b4:00:50:51:9d:64:be:f6:38:6b:1d:04:e7:2d:34:16:26:75:
88:01:98:d8:4e:db:3f:a2:f1:9d:d7:9d:cd:8a:07:8a:82:b1:
9f:59:be:4c:e1:0f:8e:2f:ea:cc:98:0a:e1:54:6c:f4:00:a9:
21:fa:9d:ed:81:4d:c6:1f:cd:20:bb:4a:ed:4d:61:50:be:af:
02:f0
-----BEGIN CERTIFICATE-----
MIIEGTCCA4KgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBpjELMAkGA1UEBhMCSVQx
CzAJBgNVBAgTAklUMQ0wCwYDVQQHEwRSb21lMRQwEgYDVQQKEwtTbWFydENBUFdB
UDEUMBIGA1UECxMLU21hcnRDQVBXQVAxFzAVBgNVBAMTDlNtYXJ0Q0FQV0FQIENB
MRQwEgYDVQQpEwtTbWFydENBUFdBUDEgMB4GCSqGSIb3DQEJARYRdmVtYXg3OEBn
bWFpbC5jb20wHhcNMTQwNTE1MTgwMjIyWhcNMjQwNTEyMTgwMjIyWjCBnDELMAkG
A1UEBhMCSVQxCzAJBgNVBAgTAklUMQ0wCwYDVQQHEwRSb21lMRQwEgYDVQQKEwtT
bWFydENBUFdBUDEUMBIGA1UECxMLU21hcnRDQVBXQVAxDTALBgNVBAMTBHd0cDEx
FDASBgNVBCkTC1NtYXJ0Q0FQV0FQMSAwHgYJKoZIhvcNAQkBFhF2ZW1heDc4QGdt
YWlsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsrGlVqfvTXZ2DAkP
XsNLzZyArhv6imNrPl3fGOUwJUq/ApCgGtvZe9PA8luC3ge9TENmTTls/ojVGqxH
0Ewt4AVNlYC1Yd+EA8sm97N3jOUonnFeSwFCZGTUH4vixhKvn2TeY/Cy//sOgti6
z6khf0NPyRngUOGQrM7Sq9yHuZ8CAwEAAaOCAV0wggFZMAkGA1UdEwQCMAAwCwYD
VR0PBAQDAgTwMC0GCWCGSAGG+EIBDQQgFh5FYXN5LVJTQSBHZW5lcmF0ZWQgQ2Vy
dGlmaWNhdGUwHQYDVR0OBBYEFF0cQ1V5luzNn4FHfyPyiMSA73rGMIHbBgNVHSME
gdMwgdCAFLi+ssvGaL0Ku+W83q5W/iXm5LMcoYGspIGpMIGmMQswCQYDVQQGEwJJ
VDELMAkGA1UECBMCSVQxDTALBgNVBAcTBFJvbWUxFDASBgNVBAoTC1NtYXJ0Q0FQ
V0FQMRQwEgYDVQQLEwtTbWFydENBUFdBUDEXMBUGA1UEAxMOU21hcnRDQVBXQVAg
Q0ExFDASBgNVBCkTC1NtYXJ0Q0FQV0FQMSAwHgYJKoZIhvcNAQkBFhF2ZW1heDc4
QGdtYWlsLmNvbYIJAJpqxrKqMyLFMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqG
SIb3DQEBBQUAA4GBAC4b+xI2CJf0ky1eWpTgZ6lpnNMki1GHtP0CzSmcVF9cJ0wC
CGpkeYSp3d/0nX23GekmpgGvp7QAUFGdZL72OGsdBOctNBYmdYgBmNhO2z+i8Z3X
nc2KB4qCsZ9ZvkzhD44v6syYCuFUbPQAqSH6ne2BTcYfzSC7Su1NYVC+rwLw
-----END CERTIFICATE-----

16
openwrt/files/wtp.key Normal file
View File

@ -0,0 +1,16 @@
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALKxpVan7012dgwJ
D17DS82cgK4b+opjaz5d3xjlMCVKvwKQoBrb2XvTwPJbgt4HvUxDZk05bP6I1Rqs
R9BMLeAFTZWAtWHfhAPLJvezd4zlKJ5xXksBQmRk1B+L4sYSr59k3mPwsv/7DoLY
us+pIX9DT8kZ4FDhkKzO0qvch7mfAgMBAAECgYB3oUyChi1EG9GN3ybmFzMRdPwF
FAAYU9TBTREF1rHz1WWpLu+w64xfRPWAi1lCkcXeX6UGgDKC+VJJ6BqvzcBLgkjh
GBaWBCN/F782Ss4svt1dyRrixixUw+RfJLakKSdFPsrdIHctdSLIKsSl4wxj+9ek
NmGbOBm/2ZJazSzgEQJBAN5abmR53pRdGKgfFKeqUo+ygWSi1IDFqn0niw7DS4TU
3h/QuI9qWZQlTIK8ibguvpc7wHUK4IZ0pk7TwmN1H6cCQQDNu+4vw2Xe2CFjEkLI
X1stba8tsdqP04BGFectrxoeUhLMZtG2Y0ZCx+BjAACXTqfchsSjv+G9Fj/QHJLg
TxVJAkB8VQjBejvxrhTpfWepUV4VJ/WedkZpMx5gGUpymNWTkwwZsjZhS1CHvEuK
Fy7TJKBCJJE7YTenN3b/QP3Da2ylAkEAwVzMdR/Vcyj32EGleuYEsCHS78OlhGBo
w3Z6nTlh9vV0raBFooKT2tg5UVMDOzK2GlKgJreF104+E7+HXEN34QJAYF76xuMm
bKi3V1bI7/t8hXs87LLHjR90PHNzLdy61lWxMvb8oWe8KjDyaE253h24a6tEPzT1
a8lIpqpuuuvTbg==
-----END PRIVATE KEY-----

5
src/kmod/Makefile Normal file
View File

@ -0,0 +1,5 @@
obj-m += smartcapwap.o
smartcapwap-y := \
main.o \
netlinkapp.o

24
src/kmod/main.c Normal file
View File

@ -0,0 +1,24 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include "netlinkapp.h"
/* */
static int __init smartcapwap_init(void) {
int result = 0;
/* */
result = nlsmartcapwap_init();
return result;
}
module_init(smartcapwap_init);
/* */
static void __exit smartcapwap_exit(void) {
nlsmartcapwap_exit();
}
module_exit(smartcapwap_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Massimo Vellucci <vemax78@gmail.com>");
MODULE_DESCRIPTION("SmartCAPWAP Data Channel Module");

125
src/kmod/netlinkapp.c Normal file
View File

@ -0,0 +1,125 @@
#include <linux/module.h>
#include <linux/rtnetlink.h>
#include <linux/netlink.h>
#include <net/genetlink.h>
#include <linux/rcupdate.h>
#include "nlsmartcapwap.h"
#include "netlinkapp.h"
/* */
#define NLSMARTCAPWAP_FLAG_NEED_RTNL 0x01
/* */
static u32 g_nlusermodeid = 0;
/* */
static int nlsmartcapwap_pre_doit(__genl_const struct genl_ops* ops, struct sk_buff* skb, struct genl_info* info) {
int rtnl = ((ops->internal_flags & NLSMARTCAPWAP_FLAG_NEED_RTNL) ? 1 : 0);
/* */
if (rtnl) {
rtnl_lock();
}
return 0;
}
/* */
static void nlsmartcapwap_post_doit(__genl_const struct genl_ops* ops, struct sk_buff* skb, struct genl_info* info) {
if (ops->internal_flags & NLSMARTCAPWAP_FLAG_NEED_RTNL) {
rtnl_unlock();
}
}
/* */
static int nlsmartcapwap_connect(struct sk_buff *skb, struct genl_info *info) {
int result = 0;
u32 portid = genl_info_snd_portid(info);
if (!g_nlusermodeid) {
g_nlusermodeid = portid;
} else if (g_nlusermodeid == portid) {
result = -EALREADY;
} else {
result = -EBUSY;
}
return result;
}
/* */
static int nlsmartcapwap_netlink_notify(struct notifier_block* nb, unsigned long state, void* _notify) {
struct netlink_notify* notify = (struct netlink_notify*)_notify;
u32 portid = netlink_notify_portid(notify);
/* */
if (state = NETLINK_URELEASE) {
rtnl_lock();
if (g_nlusermodeid == portid) {
g_nlusermodeid = 0;
}
rtnl_unlock();
}
return NOTIFY_DONE;
}
/* Netlink Family */
static struct genl_family nlsmartcapwap_family = {
.id = GENL_ID_GENERATE,
.name = SMARTCAPWAP_GENL_NAME,
.hdrsize = 0,
.version = 1,
.maxattr = NLSMARTCAPWAP_ATTR_MAX,
.netnsok = true,
.pre_doit = nlsmartcapwap_pre_doit,
.post_doit = nlsmartcapwap_post_doit,
};
static const struct nla_policy nlsmartcapwap_policy[NLSMARTCAPWAP_ATTR_MAX + 1] = {
[NLSMARTCAPWAP_ATTR_IFINDEX] = { .type = NLA_U32 },
};
/* Netlink Ops */
static __genl_const struct genl_ops nlsmartcapwap_ops[] = {
{
.cmd = NLSMARTCAPWAP_CMD_CONNECT,
.doit = nlsmartcapwap_connect,
.policy = nlsmartcapwap_policy,
.flags = GENL_ADMIN_PERM,
.internal_flags = NLSMARTCAPWAP_FLAG_NEED_RTNL,
},
};
/* Netlink notify */
static struct notifier_block nlsmartcapwap_netlink_notifier = {
.notifier_call = nlsmartcapwap_netlink_notify,
};
/* */
int nlsmartcapwap_init(void) {
int result;
/* Register netlink family */
result = genl_register_family_with_ops(&nlsmartcapwap_family, nlsmartcapwap_ops);
if (result) {
return result;
}
/* Register netlink notifier */
result = netlink_register_notifier(&nlsmartcapwap_netlink_notifier);
if (result) {
genl_unregister_family(&nlsmartcapwap_family);
return result;
}
return result;
}
/* */
void nlsmartcapwap_exit(void) {
netlink_unregister_notifier(&nlsmartcapwap_netlink_notifier);
genl_unregister_family(&nlsmartcapwap_family);
}

8
src/kmod/netlinkapp.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __KMOD_CAPWAP_NETLINKAPP_HEADER__
#define __KMOD_CAPWAP_NETLINKAPP_HEADER__
/* */
int nlsmartcapwap_init(void);
void nlsmartcapwap_exit(void);
#endif /* __KMOD_CAPWAP_NETLINKAPP_HEADER__ */

29
src/kmod/nlsmartcapwap.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __CAPWAP_NLSMARTCAPWAP_HEADER__
#define __CAPWAP_NLSMARTCAPWAP_HEADER__
/* */
#define SMARTCAPWAP_GENL_NAME "smartcapwap"
/* */
enum nlsmartcapwap_attrs {
NLSMARTCAPWAP_ATTR_UNSPEC,
NLSMARTCAPWAP_ATTR_IFINDEX,
/* Last attribute */
__NLSMARTCAPWAP_ATTR_AFTER_LAST,
NLSMARTCAPWAP_ATTR_MAX = __NLSMARTCAPWAP_ATTR_AFTER_LAST - 1
};
/* */
enum nlsmartcapwap_commands {
NLSMARTCAPWAP_CMD_UNSPEC,
NLSMARTCAPWAP_CMD_CONNECT,
/* Last command */
__NLSMARTCAPWAP_CMD_AFTER_LAST,
NLSMARTCAPWAP_CMD_MAX = __NLSMARTCAPWAP_CMD_AFTER_LAST - 1
};
#endif /* __CAPWAP_NLSMARTCAPWAP_HEADER__ */

View File

@ -45,7 +45,7 @@ struct family_data {
/* Compatibility functions */
#ifdef HAVE_LIBNL_10
static uint32_t port_bitmap[32] = { 0 };
static uint32_t g_portbitmap[32] = { 0 };
static struct nl_sock* nl_socket_alloc_cb(void* cb) {
int i;
@ -54,11 +54,11 @@ static struct nl_sock* nl_socket_alloc_cb(void* cb) {
handle = nl_handle_alloc_cb(cb);
for (i = 0; i < 1024; i++) {
if (port_bitmap[i / 32] & (1 << (i % 32))) {
if (g_portbitmap[i / 32] & (1 << (i % 32))) {
continue;
}
port_bitmap[i / 32] |= 1 << (i % 32);
g_portbitmap[i / 32] |= 1 << (i % 32);
pid += i << 22;
break;
}
@ -71,7 +71,7 @@ static void nl_socket_free(struct nl_sock* handle) {
uint32_t port = nl_socket_get_local_port(handle);
port >>= 22;
port_bitmap[port / 32] &= ~(1 << (port % 32));
g_portbitmap[port / 32] &= ~(1 << (port % 32));
nl_handle_destroy(handle);
}

View File

@ -8,6 +8,7 @@
#include "capwap_dtls.h"
#include "wtp_dfa.h"
#include "wtp_radio.h"
#include "wtp_kmod.h"
#include <arpa/inet.h>
#include <libconfig.h>
@ -1390,21 +1391,38 @@ int main(int argc, char** argv) {
capwap_logging_info("Wait the initialization of radio interfaces");
wtp_wait_radio_ready();
/* */
capwap_logging_info("Startup WTP");
/* Connect WTP with kernel module */
value = wtp_kmod_init();
if (!value || !g_wtp.kmodrequest) {
if (!value) {
g_wtp.kmodconnect = 1;
capwap_logging_info("SmartCAPWAP kernel module connected");
}
/* Complete configuration WTP */
result = wtp_configure();
if (result == CAPWAP_SUCCESSFUL) {
/* Running WTP */
result = wtp_dfa_running();
/* */
capwap_logging_info("Startup WTP");
/* Close socket */
capwap_close_sockets(&g_wtp.net);
/* Complete configuration WTP */
result = wtp_configure();
if (result == CAPWAP_SUCCESSFUL) {
/* Running WTP */
result = wtp_dfa_running();
/* Close socket */
capwap_close_sockets(&g_wtp.net);
}
/* Disconnect kernel module */
if (g_wtp.kmodconnect) {
wtp_kmod_free();
}
/* */
capwap_logging_info("Terminate WTP");
} else {
capwap_logging_fatal("Unable to connect with kernel module");
}
capwap_logging_info("Terminate WTP");
/* Close radio */
wtp_radio_close();

View File

@ -56,6 +56,11 @@ struct wtp_t {
int standalone;
int running;
/* */
int kmodrequest;
int kmodconnect;
/* */
char wlanprefix[IFNAMSIZ];
/* */

227
src/wtp/wtp_kmod.c Normal file
View File

@ -0,0 +1,227 @@
#include "wtp.h"
#include "wtp_kmod.h"
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include "nlsmartcapwap.h"
/* Compatibility functions */
#ifdef HAVE_LIBNL_10
#define nl_sock nl_handle
static uint32_t g_portbitmap[32] = { 0 };
static struct nl_sock* nl_socket_alloc_cb(void* cb) {
int i;
struct nl_sock* handle;
uint32_t pid = getpid() & 0x3FFFFF;
handle = nl_handle_alloc_cb(cb);
for (i = 0; i < 1024; i++) {
if (g_portbitmap[i / 32] & (1 << (i % 32))) {
continue;
}
g_portbitmap[i / 32] |= 1 << (i % 32);
pid += i << 22;
break;
}
nl_socket_set_local_port(handle, pid);
return handle;
}
static void nl_socket_free(struct nl_sock* handle) {
uint32_t port = nl_socket_get_local_port(handle);
port >>= 22;
g_portbitmap[port / 32] &= ~(1 << (port % 32));
nl_handle_destroy(handle);
}
#endif
/* */
struct wtp_kmod_handle {
struct nl_sock* nl;
struct nl_cb* nl_cb;
int nlsmartcapwap_id;
};
/* */
typedef int (*wtp_kmod_valid_cb)(struct nl_msg* msg, void* data);
/* */
static struct wtp_kmod_handle g_kmodhandle;
/* */
static struct nl_sock* nl_create_handle(struct nl_cb* cb) {
struct nl_sock* handle;
handle = nl_socket_alloc_cb(cb);
if (!handle) {
return NULL;
}
if (genl_connect(handle)) {
nl_socket_free(handle);
return NULL;
}
return handle;
}
/* */
static int wtp_kmod_no_seq_check(struct nl_msg* msg, void* arg) {
return NL_OK;
}
/* */
static int wtp_kmod_error_handler(struct sockaddr_nl* nla, struct nlmsgerr* err, void* arg) {
*((int*)arg) = err->error;
return NL_STOP;
}
/* */
static int wtp_kmod_finish_handler(struct nl_msg* msg, void* arg) {
*((int*)arg) = 0;
return NL_SKIP;
}
/* */
static int wtp_kmod_ack_handler(struct nl_msg* msg, void* arg) {
*((int*)arg) = 0;
return NL_STOP;
}
/* */
static int wtp_kmod_valid_handler(struct nl_msg* msg, void* data) {
struct nlattr* tb_msg[NLSMARTCAPWAP_ATTR_MAX + 1];
struct genlmsghdr* gnlh = nlmsg_data(nlmsg_hdr(msg));
nla_parse(tb_msg, NLSMARTCAPWAP_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
return NL_SKIP;
}
/* */
static int wtp_kmod_send_and_recv(struct nl_sock* nl, struct nl_cb* nl_cb, struct nl_msg* msg, wtp_kmod_valid_cb valid_cb, void* data) {
int result;
struct nl_cb* cb;
/* Clone netlink callback */
cb = nl_cb_clone(nl_cb);
if (!cb) {
return -1;
}
/* Complete send message */
result = nl_send_auto_complete(nl, msg);
if (result < 0) {
nl_cb_put(cb);
return -1;
}
/* Customize message callback */
nl_cb_err(cb, NL_CB_CUSTOM, wtp_kmod_error_handler, &result);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wtp_kmod_finish_handler, &result);
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wtp_kmod_ack_handler, &result);
if (valid_cb) {
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_cb, data);
}
result = 1;
while (result > 0) {
nl_recvmsgs(nl, cb);
}
nl_cb_put(cb);
return result;
}
/* */
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_kmodhandle.nl, g_kmodhandle.nl_cb, msg, valid_cb, data);
}
/* */
static int wtp_kmod_connect(void) {
int result;
struct nl_msg* msg;
/* */
msg = nlmsg_alloc();
if (!msg) {
return -1;
}
/* */
genlmsg_put(msg, 0, 0, g_kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_CONNECT, 0);
/* */
result = wtp_kmod_send_and_recv_msg(msg, NULL, NULL);
if (result) {
if (result == -EALREADY) {
result = 0;
} else {
capwap_logging_warning("Unable to connect kernel module, error code: %d", result);
}
}
/* */
nlmsg_free(msg);
return result;
}
/* */
int wtp_kmod_init(void) {
int result;
/* */
memset(&g_kmodhandle, 0, sizeof(struct wtp_kmod_handle));
/* Configure netlink callback */
g_kmodhandle.nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
if (!g_kmodhandle.nl_cb) {
wtp_kmod_free();
return -1;
}
/* Create netlink socket */
g_kmodhandle.nl = nl_create_handle(g_kmodhandle.nl_cb);
if (!g_kmodhandle.nl) {
wtp_kmod_free();
return -1;
}
/* Get nlsmartcapwap netlink family */
g_kmodhandle.nlsmartcapwap_id = genl_ctrl_resolve(g_kmodhandle.nl, SMARTCAPWAP_GENL_NAME);
if (g_kmodhandle.nlsmartcapwap_id < 0) {
wtp_kmod_free();
return -1;
}
/* Configure callback function */
nl_cb_set(g_kmodhandle.nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, wtp_kmod_no_seq_check, NULL);
nl_cb_set(g_kmodhandle.nl_cb, NL_CB_VALID, NL_CB_CUSTOM, wtp_kmod_valid_handler, NULL);
/* Connect to kernel module */
result = wtp_kmod_connect();
if (result) {
wtp_kmod_free();
return result;
}
return 0;
}
/* */
void wtp_kmod_free(void) {
if (g_kmodhandle.nl) {
nl_socket_free(g_kmodhandle.nl);
}
if (g_kmodhandle.nl_cb) {
nl_cb_put(g_kmodhandle.nl_cb);
}
}

8
src/wtp/wtp_kmod.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __WTP_KMOD_HEADER__
#define __WTP_KMOD_HEADER__
/* */
int wtp_kmod_init(void);
void wtp_kmod_free(void);
#endif /* __WTP_KMOD_HEADER__ */