diff options
-rw-r--r-- | accel-pppd/accel-ppp.conf | 7 | ||||
-rw-r--r-- | accel-pppd/ctrl/pppoe/pppoe.c | 38 | ||||
-rw-r--r-- | accel-pppd/include/ap_net.h | 4 | ||||
-rw-r--r-- | accel-pppd/net.c | 42 | ||||
-rw-r--r-- | accel-pppd/net/CMakeLists.txt | 4 | ||||
-rw-r--r-- | accel-pppd/net/dp.c | 54 |
6 files changed, 122 insertions, 27 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index 2fcb85ad..d2212304 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -30,6 +30,8 @@ pppd_compat #ipv6_dhcp #ipv6pool +#net-accel-dp + [core] log-error=/var/log/accel-ppp/core.log thread-count=4 @@ -81,7 +83,7 @@ called-sid=mac #vlan-mon=eth0,10-200 #vlan-timeout=60 #vlan-name=%I.%N -#interface=eth1,padi-limit=1000 +#interface=eth1,padi-limit=1000,net=accel-dp interface=eth0 [l2tp] @@ -267,3 +269,6 @@ verbose=1 pref-lifetime=604800 valid-lifetime=2592000 route-via-gw=1 + +[accel-dp] +socket=/var/run/accel-dp.sock diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c index a4d1ca92..8a216baa 100644 --- a/accel-pppd/ctrl/pppoe/pppoe.c +++ b/accel-pppd/ctrl/pppoe/pppoe.c @@ -747,7 +747,7 @@ static void pppoe_send(struct pppoe_serv_t *serv, const uint8_t *pack) struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); int len = ETH_HLEN + sizeof(*hdr) + ntohs(hdr->length); - sendto(serv->disc_sock, pack, len, MSG_DONTWAIT, (struct sockaddr *)&addr, sizeof(addr)); + net->sendto(serv->disc_sock, pack, len, MSG_DONTWAIT, (struct sockaddr *)&addr, sizeof(addr)); } static void pppoe_send_PADO(struct pppoe_serv_t *serv, const uint8_t *addr, const struct pppoe_tag *host_uniq, const struct pppoe_tag *relay_sid, const struct pppoe_tag *service_name, uint16_t ppp_max_payload) @@ -1266,14 +1266,32 @@ static void pppoe_serv_timeout(struct triton_timer_t *t) pppoe_server_free(serv); } -static int parse_server(const char *opt, int *padi_limit) +static int parse_server(const char *opt, int *padi_limit, const struct ap_net **net) { char *ptr, *endptr; + char name[64]; - ptr = strstr(opt, ",padi-limit="); - if (ptr) { - *padi_limit = strtol(ptr + 12, &endptr, 10); - if (*endptr != 0 && *endptr != ',') + while (*opt == ',') { + opt++; + ptr = strchr(opt, '='); + if (!ptr) + goto out_err; + if (!strncmp(opt, "padi-limit=", sizeof("padi-limit=") - 1)) { + *padi_limit = strtol(ptr + 1, &endptr, 10); + if (*endptr != 0 && *endptr != ',') + goto out_err; + opt = endptr; + } else if (!strncmp(opt, "net=", sizeof("net=") - 1)) { + ptr++; + for (endptr = ptr + 1; *endptr && *endptr != ','; endptr++); + if (endptr - ptr >= sizeof(name)) + goto out_err; + memcpy(name, ptr, endptr - ptr); + name[endptr - ptr] = 0; + *net = ap_net_find(name); + if (!*net) + goto out_err; + } else goto out_err; } @@ -1358,16 +1376,18 @@ static void __pppoe_server_start(const char *ifname, const char *opt, void *cli, int padi_limit = conf_padi_limit; const struct ap_net *net = &def_net; - if (parse_server(opt, &padi_limit)) { + if (parse_server(opt, &padi_limit, &net)) { if (cli) cli_sendv(cli, "failed to parse '%s'\r\n", opt); else log_error("pppoe: failed to parse '%s'\r\n", opt); + + return; } pthread_rwlock_rdlock(&serv_lock); list_for_each_entry(serv, &serv_list, entry) { - if (!strcmp(serv->ifname, ifname)) { + if (serv->net == net && !strcmp(serv->ifname, ifname)) { if (cli) cli_send(cli, "error: already exists\r\n"); pthread_rwlock_unlock(&serv_lock); @@ -1442,7 +1462,7 @@ static void __pppoe_server_start(const char *ifname, const char *opt, void *cli, goto out_err; } - if (parent_ifindex == -1) + if (parent_ifindex == -1 && net == &def_net) vid = iplink_vlan_get_vid(ifr.ifr_ifindex, &parent_ifindex); serv->ctx.close = pppoe_serv_close; diff --git a/accel-pppd/include/ap_net.h b/accel-pppd/include/ap_net.h index 0872e228..40544d58 100644 --- a/accel-pppd/include/ap_net.h +++ b/accel-pppd/include/ap_net.h @@ -2,6 +2,7 @@ #define __AP_NET_H struct ap_net { + const char *name; int (*socket)(int domain, int type, int proto); int (*connect)(int sock, const struct sockaddr *, socklen_t len); int (*bind)(int sock, const struct sockaddr *, socklen_t len); @@ -17,4 +18,7 @@ struct ap_net { int (*ppp_ioctl)(int fd, unsigned long request, void *arg); }; +int ap_net_register(const struct ap_net *net); +const struct ap_net *ap_net_find(const char *name); + #endif diff --git a/accel-pppd/net.c b/accel-pppd/net.c index ddf2d2f8..d2bd4e03 100644 --- a/accel-pppd/net.c +++ b/accel-pppd/net.c @@ -1,5 +1,6 @@ #include <unistd.h> #include <fcntl.h> +#include <string.h> #include <sys/socket.h> #include <sys/ioctl.h> @@ -7,6 +8,11 @@ #include "ap_net.h" +#define MAX_NET 2 + +static const struct ap_net *nets[MAX_NET]; +static int net_cnt; + extern int sock_fd; __export __thread const struct ap_net *net; @@ -77,6 +83,7 @@ static int def_sock_ioctl(unsigned long request, void *arg) } __export const struct ap_net def_net = { + .name = "kernel", .socket = def_socket, .connect = def_connect, .bind = def_bind, @@ -91,3 +98,38 @@ __export const struct ap_net def_net = { .ppp_ioctl = def_ppp_ioctl, .sock_ioctl = def_sock_ioctl, }; + +static void __init init() +{ + nets[0] = &def_net; + net_cnt = 1; +} + +int __export ap_net_register(const struct ap_net *net) +{ + int i; + + if (net_cnt == MAX_NET) + return -1; + + for (i = 0; i < net_cnt; i++) { + if (!strcmp(net->name, nets[i]->name)) + return -1; + } + + nets[net_cnt++] = net; + + return 0; +} + +__export const struct ap_net *ap_net_find(const char *name) +{ + int i; + + for (i = 0; i < net_cnt; i++) { + if (!strcmp(name, nets[i]->name)) + return nets[i]; + } + + return NULL; +} diff --git a/accel-pppd/net/CMakeLists.txt b/accel-pppd/net/CMakeLists.txt index 422ca06a..f27c7c54 100644 --- a/accel-pppd/net/CMakeLists.txt +++ b/accel-pppd/net/CMakeLists.txt @@ -1,7 +1,7 @@ IF (DEFINED DPDK) - ADD_LIBRARY(net-dp SHARED dp.c) + ADD_LIBRARY(net-accel-dp SHARED dp.c) - INSTALL(TARGETS net-dp + INSTALL(TARGETS net-accel-dp LIBRARY DESTINATION lib${LIB_SUFFIX}/accel-ppp ) ENDIF() diff --git a/accel-pppd/net/dp.c b/accel-pppd/net/dp.c index e30d74b2..018c7c75 100644 --- a/accel-pppd/net/dp.c +++ b/accel-pppd/net/dp.c @@ -26,11 +26,14 @@ static int dp_socket(int domain, int type, int proto) }; struct msg_result res; - int sock = socket(AF_UNIX, SOCK_DGRAM, 0); - if (sock < 0) + int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (sock < 0) { + log_error("dp: socket: %s\n", strerror(errno)); return -1; + } if (connect(sock, (struct sockaddr *)&dp_addr, sizeof(dp_addr))) { + log_error("dp: connect: %s\n", strerror(errno)); close(sock); return -1; } @@ -149,12 +152,12 @@ static int dp_listen(int sock, int backlog) static ssize_t dp_read(int sock, void *buf, size_t len) { - struct msg_recv msg = { + /*struct msg_recv msg = { .id = MSG_RECV, .len = len, .flags = 0, .addrlen = 0, - }; + };*/ struct msg_result res; struct iovec iov[2] = { { @@ -166,12 +169,21 @@ static ssize_t dp_read(int sock, void *buf, size_t len) .iov_len = len, } }; + struct msghdr msg = { + .msg_iov = iov, + .msg_iovlen = 2, + }; + int n; - if (write(sock, &msg, sizeof(msg))) - return -1; + /*if (write(sock, &msg, sizeof(msg))) + return -1;*/ again: - if (readv(sock, iov, 2) < sizeof(res)) { + n = recvmsg(sock, &msg, MSG_DONTWAIT); + if (n < 0) + return -1; + + if (n < sizeof(res)) { errno = EBADE; return -1; } @@ -189,12 +201,12 @@ again: static ssize_t dp_recvfrom(int sock, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { - struct msg_recv msg = { + /*struct msg_recv msg = { .id = MSG_RECV, .len = len, .flags = flags, .addrlen = 0, - }; + };*/ struct msg_result res; struct iovec iov[2] = { { @@ -206,12 +218,21 @@ static ssize_t dp_recvfrom(int sock, void *buf, size_t len, int flags, struct so .iov_len = len, } }; + int n; + struct msghdr msg = { + .msg_iov = iov, + .msg_iovlen = 2, + }; - if (write(sock, &msg, sizeof(msg))) - return -1; + /*if (write(sock, &msg, sizeof(msg))) + return -1;*/ again: - if (readv(sock, iov, 2) < sizeof(res)) { + n = recvmsg(sock, &msg, MSG_DONTWAIT); + if (n < 0) + return -1; + + if (n < sizeof(res)) { errno = EBADE; return -1; } @@ -444,10 +465,11 @@ static int dp_sock_ioctl(unsigned long request, void *arg) return -1; } - return res.len; + return 0; } static const struct ap_net dp_net = { + .name = "accel-dp", .socket = dp_socket, .connect = dp_connect, .bind = dp_bind, @@ -465,7 +487,7 @@ static const struct ap_net dp_net = { static void init() { - const char *opt = conf_get_opt("net-dpdk", "socket"); + const char *opt = conf_get_opt("accel-dp", "socket"); if (!opt) return; @@ -479,7 +501,7 @@ static void init() dp_addr.sun_family = AF_UNIX; - dp_sock = socket(AF_UNIX, SOCK_DGRAM, 0); + dp_sock = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (dp_sock < 0) return; @@ -488,6 +510,8 @@ static void init() close(dp_sock); return; } + + ap_net_register(&dp_net); } DEFINE_INIT(1, init) |