Attempt to hack in acceleration for PPPoE
This commit is contained in:
parent
0c9338b03a
commit
57004c5744
4 changed files with 40 additions and 9 deletions
23
l2tpns.c
23
l2tpns.c
|
|
@ -1016,7 +1016,7 @@ static int create_ppp_socket(int udp_fd, uint32_t tid, uint32_t peer_tid, uint32
|
||||||
|
|
||||||
return pppox_fd;
|
return pppox_fd;
|
||||||
}
|
}
|
||||||
|
static int create_kernel_ppp_chan(sessionidt s, int pppox_fd);
|
||||||
//
|
//
|
||||||
// Create the kernel session and PPPoX socket for this session
|
// Create the kernel session and PPPoX socket for this session
|
||||||
static int create_kernel_pppox(sessionidt s)
|
static int create_kernel_pppox(sessionidt s)
|
||||||
|
|
@ -1024,7 +1024,14 @@ static int create_kernel_pppox(sessionidt s)
|
||||||
tunnelidt t = session[s].tunnel;
|
tunnelidt t = session[s].tunnel;
|
||||||
|
|
||||||
if (t == TUNNEL_ID_PPPOE) {
|
if (t == TUNNEL_ID_PPPOE) {
|
||||||
return create_kernel_pppoe_socket(s);
|
int ret = create_kernel_pppoe_socket(s);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
create_kernel_ppp_chan(s, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tunn_local[t].l2tp_fd < 0)
|
if (tunn_local[t].l2tp_fd < 0)
|
||||||
|
|
@ -1301,11 +1308,16 @@ int create_kernel_bridge(sessionidt s, sessionidt fwds)
|
||||||
|
|
||||||
LOG(3, s, t, "Starting kernel-accelerated bridge between %u and %u\n", s, fwds);
|
LOG(3, s, t, "Starting kernel-accelerated bridge between %u and %u\n", s, fwds);
|
||||||
|
|
||||||
|
LOG(3, s, t, "Setting up primary side channel\n");
|
||||||
int ppp_chan_fd = create_kernel_ppp_chan(s, pppox_fd);
|
int ppp_chan_fd = create_kernel_ppp_chan(s, pppox_fd);
|
||||||
if (ppp_chan_fd < 0)
|
if (ppp_chan_fd < 0)
|
||||||
goto err_fwd_pppox_fd;
|
goto err_fwd_pppox_fd;
|
||||||
|
|
||||||
|
LOG(3, s, t, "Fetching secondary side channel (already existing) fwd_fd=%d fwd_pppox_fd=%d\n", fwds, fwd_pppox_fd);
|
||||||
int fwd_idx = get_kernel_ppp_chan(fwds, fwd_pppox_fd);
|
int fwd_idx = get_kernel_ppp_chan(fwds, fwd_pppox_fd);
|
||||||
|
LOG(3, s, t, "Got channel ID = %d\n", fwd_idx);
|
||||||
|
|
||||||
|
LOG(3, s, t, "Performing bridging\n");
|
||||||
|
|
||||||
int ret = ioctl(ppp_chan_fd, PPPIOCBRIDGECHAN, &fwd_idx);
|
int ret = ioctl(ppp_chan_fd, PPPIOCBRIDGECHAN, &fwd_idx);
|
||||||
close(ppp_chan_fd);
|
close(ppp_chan_fd);
|
||||||
|
|
@ -1392,7 +1404,7 @@ static int delete_kernel_accel(sessionidt s)
|
||||||
// Enable (set=1) or disable (set=0) kernel PPP acceleration
|
// Enable (set=1) or disable (set=0) kernel PPP acceleration
|
||||||
// This basically calls create/delete_kernel_accel, but also updates routes
|
// This basically calls create/delete_kernel_accel, but also updates routes
|
||||||
// If now is 0, we may delay this if we have already made a lot of switches since last cleanup
|
// If now is 0, we may delay this if we have already made a lot of switches since last cleanup
|
||||||
static void set_kernel_accel(sessionidt s, int set, int nodelay)
|
void set_kernel_accel(sessionidt s, int set, int nodelay)
|
||||||
{
|
{
|
||||||
if (set && !can_kernel_accel(s))
|
if (set && !can_kernel_accel(s))
|
||||||
/* Still cannot enable it */
|
/* Still cannot enable it */
|
||||||
|
|
@ -1506,10 +1518,15 @@ static void apply_kernel_stats(sessionidt s)
|
||||||
/* It is free */
|
/* It is free */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (session[s].tunnel == TUNNEL_ID_PPPOE)
|
||||||
|
/* it is PPPoE */
|
||||||
|
return;
|
||||||
|
|
||||||
if (sess_local[s].pppox_fd < 0)
|
if (sess_local[s].pppox_fd < 0)
|
||||||
/* It does not have kernel acceleration */
|
/* It does not have kernel acceleration */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
struct pppol2tp_ioc_stats stats, *last_stats = &sess_local[s].last_stats;
|
struct pppol2tp_ioc_stats stats, *last_stats = &sess_local[s].last_stats;
|
||||||
int ret = ioctl(sess_local[s].pppox_fd, PPPIOCGL2TPSTATS, &stats);
|
int ret = ioctl(sess_local[s].pppox_fd, PPPIOCGL2TPSTATS, &stats);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
|
||||||
2
l2tpns.h
2
l2tpns.h
|
|
@ -1057,6 +1057,8 @@ void lac_send_SCCRQ(tunnelidt t, uint8_t * auth, unsigned int auth_len);
|
||||||
void lac_send_ICRQ(tunnelidt t, sessionidt s);
|
void lac_send_ICRQ(tunnelidt t, sessionidt s);
|
||||||
void lac_tunnelshutdown(tunnelidt t, char *reason, int result, int error, char *msg);
|
void lac_tunnelshutdown(tunnelidt t, char *reason, int result, int error, char *msg);
|
||||||
|
|
||||||
|
void set_kernel_accel(sessionidt s, int set, int nodelay);
|
||||||
|
|
||||||
#undef LOG
|
#undef LOG
|
||||||
#undef LOG_HEX
|
#undef LOG_HEX
|
||||||
#define LOG(D, s, t, f, ...) ({ if ((D) <= config->debug) _log((D), s, t, f, ## __VA_ARGS__); })
|
#define LOG(D, s, t, f, ...) ({ if ((D) <= config->debug) _log((D), s, t, f, ## __VA_ARGS__); })
|
||||||
|
|
|
||||||
22
pppoe.c
22
pppoe.c
|
|
@ -225,6 +225,7 @@ static void init_pppoe_sess(void)
|
||||||
LOG(0, 0, 0, "Error pppoe: failed to set nonblocking mode: %s\n", strerror(errno));
|
LOG(0, 0, 0, "Error pppoe: failed to set nonblocking mode: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
//pppoesessfd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up pppoe discovery/session socket
|
// set up pppoe discovery/session socket
|
||||||
|
|
@ -249,9 +250,12 @@ void init_pppoe(void)
|
||||||
int create_kernel_pppoe_socket(const sessionidt s) {
|
int create_kernel_pppoe_socket(const sessionidt s) {
|
||||||
tunnelidt t = TUNNEL_ID_PPPOE;
|
tunnelidt t = TUNNEL_ID_PPPOE;
|
||||||
|
|
||||||
|
LOG(3, s, t, "Creating kernel-accelerated pppoe socket on %s\n", config->pppoe_if_to_bind);
|
||||||
|
LOG_HEX(3, "Mac: ", session[s].src_hwaddr, ETH_ALEN);
|
||||||
|
|
||||||
int pppox_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
|
int pppox_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
|
||||||
if (pppox_fd < 0) {
|
if (pppox_fd < 0) {
|
||||||
LOG(2, s, t, "Can't create PPPoE socket: %s\n", strerror(errno));
|
LOG(3, s, t, "Can't create PPPoE socket: %s\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct sockaddr_pppox sax;
|
struct sockaddr_pppox sax;
|
||||||
|
|
@ -259,17 +263,18 @@ int create_kernel_pppoe_socket(const sessionidt s) {
|
||||||
|
|
||||||
sax.sa_family = AF_PPPOX;
|
sax.sa_family = AF_PPPOX;
|
||||||
sax.sa_protocol = PX_PROTO_OE;
|
sax.sa_protocol = PX_PROTO_OE;
|
||||||
sax.sa_addr.pppoe.sid = s;
|
sax.sa_addr.pppoe.sid = htons(s);
|
||||||
memcpy(sax.sa_addr.pppoe.dev, config->pppoe_if_to_bind, IFNAMSIZ);
|
memcpy(sax.sa_addr.pppoe.dev, config->pppoe_if_to_bind, IFNAMSIZ);
|
||||||
memcpy(sax.sa_addr.pppoe.remote, session[s].src_hwaddr, ETH_ALEN);
|
memcpy(sax.sa_addr.pppoe.remote, session[s].src_hwaddr, ETH_ALEN);
|
||||||
|
|
||||||
|
|
||||||
int ret = connect(pppox_fd, (struct sockaddr *)&sax, sizeof(sax));
|
int ret = connect(pppox_fd, (struct sockaddr *)&sax, sizeof(sax));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG(2, s, t, "Can't connect PPPoE: %s\n", strerror(errno));
|
LOG(3, s, t, "Can't connect PPPoE: %s\n", strerror(errno));
|
||||||
close(pppox_fd);
|
close(pppox_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return ret;
|
return pppox_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * get_string_codepad(uint8_t codepad)
|
char * get_string_codepad(uint8_t codepad)
|
||||||
|
|
@ -579,6 +584,7 @@ static void pppoe_recv_PADI(uint8_t *pack, int size)
|
||||||
pppoe_send_PADO(ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag);
|
pppoe_send_PADO(ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void pppoe_recv_PADR(uint8_t *pack, int size)
|
static void pppoe_recv_PADR(uint8_t *pack, int size)
|
||||||
{
|
{
|
||||||
struct ethhdr *ethhdr = (struct ethhdr *)pack;
|
struct ethhdr *ethhdr = (struct ethhdr *)pack;
|
||||||
|
|
@ -696,6 +702,7 @@ static void pppoe_recv_PADR(uint8_t *pack, int size)
|
||||||
sess_local[sid].mp_epdis = 0;
|
sess_local[sid].mp_epdis = 0;
|
||||||
|
|
||||||
memcpy(session[sid].src_hwaddr, ethhdr->h_source, ETH_ALEN);
|
memcpy(session[sid].src_hwaddr, ethhdr->h_source, ETH_ALEN);
|
||||||
|
//set_kernel_accel(sid, 1, 1);
|
||||||
pppoe_send_PADS(sid, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag);
|
pppoe_send_PADS(sid, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag);
|
||||||
|
|
||||||
sendlcp(sid, session[sid].tunnel);
|
sendlcp(sid, session[sid].tunnel);
|
||||||
|
|
@ -947,9 +954,9 @@ static void pppoe_forwardto_session_rmlns(uint8_t *pack, int size, sessionidt se
|
||||||
{
|
{
|
||||||
struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN);
|
struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN);
|
||||||
uint16_t lppp = ntohs(hdr->length);
|
uint16_t lppp = ntohs(hdr->length);
|
||||||
uint16_t ll2tp = lppp + 6;
|
uint16_t ll2tp = lppp + 8;
|
||||||
uint8_t *pppdata = (uint8_t *) hdr->tag;
|
uint8_t *pppdata = (uint8_t *) hdr->tag;
|
||||||
uint8_t *pl2tp = pppdata - 6;
|
uint8_t *pl2tp = pppdata - 8;
|
||||||
uint8_t *p = pl2tp;
|
uint8_t *p = pl2tp;
|
||||||
uint16_t t = 0, s = 0;
|
uint16_t t = 0, s = 0;
|
||||||
|
|
||||||
|
|
@ -981,6 +988,9 @@ static void pppoe_forwardto_session_rmlns(uint8_t *pack, int size, sessionidt se
|
||||||
*(uint16_t *) p = htons(session[s].far); // session
|
*(uint16_t *) p = htons(session[s].far); // session
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
|
*(uint16_t *) p = htons(0xFF03); // HDLC header
|
||||||
|
p += 2;
|
||||||
|
|
||||||
if ((proto == PPPIP) || (proto == PPPMP) ||(proto == PPPIPV6 && config->ipv6_prefix.s6_addr[0]))
|
if ((proto == PPPIP) || (proto == PPPMP) ||(proto == PPPIPV6 && config->ipv6_prefix.s6_addr[0]))
|
||||||
{
|
{
|
||||||
session[sess].last_packet = time_now;
|
session[sess].last_packet = time_now;
|
||||||
|
|
|
||||||
2
pppoe.h
2
pppoe.h
|
|
@ -18,6 +18,8 @@ void pppoe_process_forward(uint8_t *pack, int size, in_addr_t addr);
|
||||||
void pppoe_send_garp();
|
void pppoe_send_garp();
|
||||||
char * get_string_codepad(uint8_t codepad);
|
char * get_string_codepad(uint8_t codepad);
|
||||||
|
|
||||||
|
create_kernel_pppoe_socket(const sessionidt s);
|
||||||
|
|
||||||
extern int pppoediscfd; // pppoe discovery socket
|
extern int pppoediscfd; // pppoe discovery socket
|
||||||
extern int pppoesessfd; // pppoe session socket
|
extern int pppoesessfd; // pppoe session socket
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue