diff --git a/src/wtp/kmod/capwap.c b/src/wtp/kmod/capwap.c index 22a5d8c..f1d714a 100644 --- a/src/wtp/kmod/capwap.c +++ b/src/wtp/kmod/capwap.c @@ -402,52 +402,52 @@ int sc_capwap_80211_to_8023(struct sk_buff* skb) { return 0; } -int sc_capwap_bind(struct sc_capwap_session *session, int protocol, struct sockaddr_storage *sockaddr) +int sc_capwap_create(struct sc_capwap_session *session) { - int ret; + int err; + struct udp_tunnel_sock_cfg cfg = { + .sk_user_data = session, + .encap_type = 1, + .encap_rcv = sc_capwap_recvpacket + }; TRACEKMOD("### sc_capwap_bind\n"); if (session->socket) return -EBUSY; - ret = sock_create_kern(session->net, sockaddr->ss_family, SOCK_DGRAM, protocol, &session->socket); - if (ret < 0) - return ret; + /* Open UDP socket */ + err = udp_sock_create(session->net, &session->udp_config, &session->socket); + if (err < 0) + goto error; - ret = kernel_bind(session->socket, (struct sockaddr *)sockaddr, sizeof(struct sockaddr_storage)); - if (ret < 0) - goto err_close; + setup_udp_tunnel_sock(session->net, session->socket, &cfg); - rcu_assign_sk_user_data(session->socket->sk, session); - - /* Set callback */ - udp_sk(session->socket->sk)->encap_type = 1; - udp_sk(session->socket->sk)->encap_rcv = sc_capwap_recvpacket; - - udp_encap_enable(); - if (sockaddr->ss_family == AF_INET6) + if (session->udp_config.family == AF_INET6) udpv6_encap_enable(); - return 0; + err = sc_capwap_sendkeepalive(session); + if (err < 0) + goto error; -err_close: - kernel_sock_shutdown(session->socket, SHUT_RDWR); - sock_release(session->socket); + return err; + +error: + if (session->socket) + udp_tunnel_sock_release(session->socket); session->socket = NULL; - return ret; + return err; } void sc_capwap_close(struct sc_capwap_session *session) { TRACEKMOD("### sc_capwap_close\n"); - if (session->socket) { - kernel_sock_shutdown(session->socket, SHUT_RDWR); - sock_release(session->socket); - } + if (session->socket) + udp_tunnel_sock_release(session->socket); session->socket = NULL; + sc_capwap_freesession(session); } diff --git a/src/wtp/kmod/capwap.h b/src/wtp/kmod/capwap.h index ee68acb..dbd600f 100644 --- a/src/wtp/kmod/capwap.h +++ b/src/wtp/kmod/capwap.h @@ -6,6 +6,11 @@ #include #include +#include +#include +#include +#include + #include "capwap_rfc.h" /* */ @@ -105,6 +110,7 @@ struct sc_capwap_session { struct net *net; struct socket *socket; + struct udp_port_cfg udp_config; uint16_t mtu; struct sc_capwap_sessionid_element sessionid; @@ -123,8 +129,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); /* Indipendent implementation function */ -int sc_capwap_bind(struct sc_capwap_session *session, int protocol, - struct sockaddr_storage *sockaddr); +int sc_capwap_create(struct sc_capwap_session *session); int sc_capwap_send(struct sc_capwap_session *session, uint8_t* buffer, int length); void sc_capwap_close(struct sc_capwap_session *session); diff --git a/src/wtp/kmod/capwap_private.c b/src/wtp/kmod/capwap_private.c index 2552c4c..dd7c9dc 100644 --- a/src/wtp/kmod/capwap_private.c +++ b/src/wtp/kmod/capwap_private.c @@ -38,26 +38,6 @@ int sc_capwap_init(struct sc_capwap_session *session, struct net *net) return 0; } -int sc_capwap_connect(struct sc_capwap_session *session, - struct sockaddr_storage *peeraddr, - struct sc_capwap_sessionid_element* sessionid, uint16_t mtu) -{ - int err; - - TRACEKMOD("### sc_capwap_connect(%p, %p, %p, %d)\n", session, peeraddr, sessionid, mtu); - - memcpy(&session->sessionid, sessionid, sizeof(struct sc_capwap_sessionid_element)); - session->mtu = mtu; - - err = kernel_connect(session->socket, - (struct sockaddr *)peeraddr, - sizeof(*peeraddr), 0); - if (err < 0) - return err; - - return sc_capwap_sendkeepalive(session); -} - /* */ void sc_capwap_resetsession(struct sc_capwap_session *session) { diff --git a/src/wtp/kmod/capwap_private.h b/src/wtp/kmod/capwap_private.h index 08ace4e..73a3774 100644 --- a/src/wtp/kmod/capwap_private.h +++ b/src/wtp/kmod/capwap_private.h @@ -16,9 +16,6 @@ struct sc_station *sc_find_station(struct hlist_head *sta_head, uint8_t radioid, int sc_capwap_init(struct sc_capwap_session *sc_acsession, struct net *net); /* */ -int sc_capwap_connect(struct sc_capwap_session *session, - struct sockaddr_storage *peeraddr, - struct sc_capwap_sessionid_element* sessionid, uint16_t mtu); void sc_capwap_resetsession(struct sc_capwap_session *sc_acsession); /* */ diff --git a/src/wtp/kmod/netlinkapp.c b/src/wtp/kmod/netlinkapp.c index 9a75ad3..879a46d 100644 --- a/src/wtp/kmod/netlinkapp.c +++ b/src/wtp/kmod/netlinkapp.c @@ -331,71 +331,65 @@ static int sc_netlink_notify(struct notifier_block* nb, return NOTIFY_DONE; } +static void cfg_assign_ip(void *ip, __be16 *port, struct sockaddr_storage *addr) +{ + if (addr->ss_family == AF_INET) { + memcpy(ip, &((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr)); + *port = ((struct sockaddr_in *)addr)->sin_port; + } +#if IS_ENABLED(CONFIG_IPV6) + if (addr->ss_family == AF_INET6) { + memcpy(ip, &((struct sockaddr_in6 *)addr)->sin6_addr, sizeof(struct in6_addr)); + *port = ((struct sockaddr_in6 *)addr)->sin6_port; + } +#endif + +} + /* */ -static int sc_netlink_bind(struct sk_buff* skb, struct genl_info* info) +static int sc_netlink_create(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); + struct sc_capwap_session *session = &sn->sc_acsession; + struct udp_port_cfg *cfg = &session->udp_config; + struct sockaddr_storage *local, *peer; + uint16_t mtu = DEFAULT_MTU; - TRACEKMOD("### sc_netlink_bind\n"); + TRACEKMOD("### sc_netlink_create\n"); /* Check Link */ if (!sn->sc_netlink_usermodeid) return -ENOLINK; /* 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_LOCAL_ADDRESS] || + !info->attrs[NLSMARTCAPWAP_ATTR_PEER_ADDRESS] || + !info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID]) return -EINVAL; - } - - /* Bind socket */ - return sc_capwap_bind(&sn->sc_acsession, IPPROTO_UDP, - (struct sockaddr_storage *)nla_data(info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS])); -} - -/* */ -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; - uint16_t mtu = DEFAULT_MTU; - - TRACEKMOD("### sc_netlink_connect\n"); - - /* Check Link */ - if (!sn->sc_netlink_usermodeid) - return -ENOLINK; - - /* Get AC address */ - if (!info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS] || - (nla_len(info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS]) != sizeof(struct sockaddr_storage))) { - return -EINVAL; - } /* Get MTU */ if (info->attrs[NLSMARTCAPWAP_ATTR_MTU]) { mtu = nla_get_u16(info->attrs[NLSMARTCAPWAP_ATTR_MTU]); - if ((mtu < MIN_MTU) || (mtu > MAX_MTU)) { + if ((mtu < MIN_MTU) || (mtu > MAX_MTU)) return -EINVAL; - } } - if (!info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID] || - nla_len(info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID]) != sizeof(struct sc_capwap_sessionid_element)) { - return -EINVAL; - } + memcpy(&session->sessionid, nla_data(info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID]), + sizeof(struct sc_capwap_sessionid_element)); + session->mtu = mtu; - /* Send packet */ - ret = sc_capwap_connect(&sn->sc_acsession, - (struct sockaddr_storage *)nla_data(info->attrs[NLSMARTCAPWAP_ATTR_ADDRESS]), - (struct sc_capwap_sessionid_element *)nla_data(info->attrs[NLSMARTCAPWAP_ATTR_SESSION_ID]), - mtu); - if (ret < 0) - return ret; + local = (struct sockaddr_storage *)nla_data(info->attrs[NLSMARTCAPWAP_ATTR_LOCAL_ADDRESS]); + peer = (struct sockaddr_storage *)nla_data(info->attrs[NLSMARTCAPWAP_ATTR_PEER_ADDRESS]); - return 0; + cfg->family = peer->ss_family; + cfg_assign_ip(&cfg->local_ip, &cfg->local_udp_port, local); + cfg_assign_ip(&cfg->peer_ip, &cfg->peer_udp_port, peer); + cfg->use_udp_checksums = 1; + cfg->use_udp6_tx_checksums = 1; + cfg->use_udp6_rx_checksums = 1; + + return sc_capwap_create(session); } /* */ @@ -728,9 +722,10 @@ static const struct nla_policy sc_netlink_policy[NLSMARTCAPWAP_ATTR_MAX + 1] = { [NLSMARTCAPWAP_ATTR_MGMT_SUBTYPE_MASK] = { .type = NLA_U16 }, [NLSMARTCAPWAP_ATTR_CTRL_SUBTYPE_MASK] = { .type = NLA_U16 }, [NLSMARTCAPWAP_ATTR_DATA_SUBTYPE_MASK] = { .type = NLA_U16 }, - [NLSMARTCAPWAP_ATTR_ADDRESS] = { .type = NLA_BINARY, .len = sizeof(struct sockaddr_storage) }, + [NLSMARTCAPWAP_ATTR_LOCAL_ADDRESS] = { .len = sizeof(struct sockaddr_storage) }, + [NLSMARTCAPWAP_ATTR_PEER_ADDRESS] = { .len = sizeof(struct sockaddr_storage) }, [NLSMARTCAPWAP_ATTR_MTU] = { .type = NLA_U16 }, - [NLSMARTCAPWAP_ATTR_SESSION_ID] = { .type = NLA_BINARY, .len = sizeof(struct sc_capwap_sessionid_element) }, + [NLSMARTCAPWAP_ATTR_SESSION_ID] = { .len = sizeof(struct sc_capwap_sessionid_element) }, [NLSMARTCAPWAP_ATTR_DTLS] = { .type = NLA_U16 }, [NLSMARTCAPWAP_ATTR_DATA_FRAME] = { .type = NLA_BINARY, .len = IEEE80211_MTU }, [NLSMARTCAPWAP_ATTR_RSSI] = { .type = NLA_U8 }, @@ -748,14 +743,8 @@ static const struct genl_ops sc_netlink_ops[] = { .flags = GENL_ADMIN_PERM, }, { - .cmd = NLSMARTCAPWAP_CMD_BIND, - .doit = sc_netlink_bind, - .policy = sc_netlink_policy, - .flags = GENL_ADMIN_PERM, - }, - { - .cmd = NLSMARTCAPWAP_CMD_CONNECT, - .doit = sc_netlink_connect, + .cmd = NLSMARTCAPWAP_CMD_CREATE, + .doit = sc_netlink_create, .policy = sc_netlink_policy, .flags = GENL_ADMIN_PERM, }, diff --git a/src/wtp/kmod/nlsmartcapwap.h b/src/wtp/kmod/nlsmartcapwap.h index 5b13e48..96f8969 100644 --- a/src/wtp/kmod/nlsmartcapwap.h +++ b/src/wtp/kmod/nlsmartcapwap.h @@ -22,7 +22,8 @@ enum nlsmartcapwap_attrs { NLSMARTCAPWAP_ATTR_CTRL_SUBTYPE_MASK, NLSMARTCAPWAP_ATTR_DATA_SUBTYPE_MASK, - NLSMARTCAPWAP_ATTR_ADDRESS, + NLSMARTCAPWAP_ATTR_LOCAL_ADDRESS, + NLSMARTCAPWAP_ATTR_PEER_ADDRESS, NLSMARTCAPWAP_ATTR_MTU, NLSMARTCAPWAP_ATTR_SESSION_ID, @@ -47,8 +48,7 @@ enum nlsmartcapwap_commands { NLSMARTCAPWAP_CMD_LINK, - NLSMARTCAPWAP_CMD_BIND, - NLSMARTCAPWAP_CMD_CONNECT, + NLSMARTCAPWAP_CMD_CREATE, NLSMARTCAPWAP_CMD_RESET, NLSMARTCAPWAP_CMD_SEND_KEEPALIVE, diff --git a/src/wtp/wtp_dfa_dtls.c b/src/wtp/wtp_dfa_dtls.c index 1dd5bde..08cd409 100644 --- a/src/wtp/wtp_dfa_dtls.c +++ b/src/wtp/wtp_dfa_dtls.c @@ -40,8 +40,8 @@ void wtp_start_datachannel(void) { #endif /* Bind data address and Connect to AC data channel */ - if (wtp_kmod_bind(g_wtp.net.localaddr.ss.ss_family) || - !wtp_kmod_connect(&dataaddr.ss, &g_wtp.sessionid, g_wtp.mtu)) { + if (wtp_kmod_create(g_wtp.net.localaddr.ss.ss_family, &dataaddr.ss, &g_wtp.sessionid, g_wtp.mtu) == 0) { + capwap_logging_error("Data channel connected"); /* Reset AC Prefered List Position */ g_wtp.acpreferedselected = 0; diff --git a/src/wtp/wtp_kmod.c b/src/wtp/wtp_kmod.c index e5f18fa..826707b 100644 --- a/src/wtp/wtp_kmod.c +++ b/src/wtp/wtp_kmod.c @@ -198,63 +198,33 @@ static void wtp_kmod_event_receive(int fd, void** params, int paramscount) { } /* */ -int wtp_kmod_bind(uint16_t family) { +int wtp_kmod_create(uint16_t family, struct sockaddr_storage* peeraddr, + struct capwap_sessionid_element* sessionid, uint16_t mtu) { int result; struct nl_msg* msg; struct sockaddr_storage sockaddr; ASSERT((family == AF_INET) || (family == AF_INET6)); + ASSERT(peeraddr != NULL); + ASSERT((peeraddr->ss_family == AF_INET) || (peeraddr->ss_family == AF_INET6)); + ASSERT(sessionid != NULL); /* */ - if (!wtp_kmod_isconnected()) { + if (!wtp_kmod_isconnected()) return -1; - } /* */ msg = nlmsg_alloc(); - if (!msg) { + if (!msg) return -1; - } - /* */ memset(&sockaddr, 0, sizeof(struct sockaddr_storage)); sockaddr.ss_family = family; /* */ - genlmsg_put(msg, 0, 0, g_wtp.kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_BIND, 0); - nla_put(msg, NLSMARTCAPWAP_ATTR_ADDRESS, sizeof(struct sockaddr_storage), &sockaddr); - - /* */ - result = wtp_kmod_send_and_recv_msg(msg, NULL, NULL); - - /* */ - nlmsg_free(msg); - return result; -} - -/* */ -int wtp_kmod_connect(struct sockaddr_storage* sockaddr, struct capwap_sessionid_element* sessionid, uint16_t mtu) { - int result; - struct nl_msg* msg; - - ASSERT(sockaddr != NULL); - ASSERT((sockaddr->ss_family == AF_INET) || (sockaddr->ss_family == AF_INET6)); - ASSERT(sessionid != NULL); - - /* */ - if (!wtp_kmod_isconnected()) { - return -1; - } - - /* */ - msg = nlmsg_alloc(); - if (!msg) { - return -1; - } - - /* */ - genlmsg_put(msg, 0, 0, g_wtp.kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_CONNECT, 0); - nla_put(msg, NLSMARTCAPWAP_ATTR_ADDRESS, sizeof(struct sockaddr_storage), sockaddr); + genlmsg_put(msg, 0, 0, g_wtp.kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_CREATE, 0); + nla_put(msg, NLSMARTCAPWAP_ATTR_LOCAL_ADDRESS, sizeof(struct sockaddr_storage), &sockaddr); + nla_put(msg, NLSMARTCAPWAP_ATTR_PEER_ADDRESS, sizeof(struct sockaddr_storage), peeraddr); nla_put(msg, NLSMARTCAPWAP_ATTR_SESSION_ID, sizeof(struct capwap_sessionid_element), sessionid); nla_put_u16(msg, NLSMARTCAPWAP_ATTR_MTU, mtu); diff --git a/src/wtp/wtp_kmod.h b/src/wtp/wtp_kmod.h index c279d65..2588277 100644 --- a/src/wtp/wtp_kmod.h +++ b/src/wtp/wtp_kmod.h @@ -50,8 +50,8 @@ int wtp_kmod_isconnected(void); int wtp_kmod_getfd(struct pollfd* fds, struct wtp_kmod_event* events, int count); /* */ -int wtp_kmod_bind(uint16_t family); -int wtp_kmod_connect(struct sockaddr_storage* sockaddr, struct capwap_sessionid_element* sessionid, uint16_t mtu); +int wtp_kmod_create(uint16_t family, struct sockaddr_storage* peeraddr, + struct capwap_sessionid_element* sessionid, uint16_t mtu); int wtp_kmod_resetsession(void); /* */