diff --git a/l2tpns.c b/l2tpns.c index fd10322..203fc40 100644 --- a/l2tpns.c +++ b/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; } - +static int create_kernel_ppp_chan(sessionidt s, int pppox_fd); // // Create the kernel session and PPPoX socket for this session static int create_kernel_pppox(sessionidt s) @@ -1024,7 +1024,14 @@ static int create_kernel_pppox(sessionidt s) tunnelidt t = session[s].tunnel; 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) @@ -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, "Setting up primary side channel\n"); int ppp_chan_fd = create_kernel_ppp_chan(s, pppox_fd); if (ppp_chan_fd < 0) 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); + 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); 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 // 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 -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)) /* Still cannot enable it */ @@ -1506,10 +1518,15 @@ static void apply_kernel_stats(sessionidt s) /* It is free */ return; + if (session[s].tunnel == TUNNEL_ID_PPPOE) + /* it is PPPoE */ + return; + if (sess_local[s].pppox_fd < 0) /* It does not have kernel acceleration */ return; + struct pppol2tp_ioc_stats stats, *last_stats = &sess_local[s].last_stats; int ret = ioctl(sess_local[s].pppox_fd, PPPIOCGL2TPSTATS, &stats); if (ret < 0) diff --git a/l2tpns.h b/l2tpns.h index efaf836..39cdb3c 100644 --- a/l2tpns.h +++ b/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_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_HEX #define LOG(D, s, t, f, ...) ({ if ((D) <= config->debug) _log((D), s, t, f, ## __VA_ARGS__); }) diff --git a/pppoe.c b/pppoe.c index ebfc240..d79a4aa 100644 --- a/pppoe.c +++ b/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)); exit(1); } + //pppoesessfd = 0; } // set up pppoe discovery/session socket @@ -248,10 +249,13 @@ void init_pppoe(void) // setup the PPPoE session socket int create_kernel_pppoe_socket(const sessionidt s) { 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); 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; } struct sockaddr_pppox sax; @@ -259,17 +263,18 @@ int create_kernel_pppoe_socket(const sessionidt s) { sax.sa_family = AF_PPPOX; 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.remote, session[s].src_hwaddr, ETH_ALEN); + int ret = connect(pppox_fd, (struct sockaddr *)&sax, sizeof(sax)); 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); return -1; } - return ret; + return pppox_fd; } 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); } + static void pppoe_recv_PADR(uint8_t *pack, int size) { 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; 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); 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); 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 *pl2tp = pppdata - 6; + uint8_t *pl2tp = pppdata - 8; uint8_t *p = pl2tp; uint16_t t = 0, s = 0; @@ -980,6 +987,9 @@ static void pppoe_forwardto_session_rmlns(uint8_t *pack, int size, sessionidt se p += 2; *(uint16_t *) p = htons(session[s].far); // session p += 2; + + *(uint16_t *) p = htons(0xFF03); // HDLC header + p += 2; if ((proto == PPPIP) || (proto == PPPMP) ||(proto == PPPIPV6 && config->ipv6_prefix.s6_addr[0])) { diff --git a/pppoe.h b/pppoe.h index a4dabc8..788092b 100644 --- a/pppoe.h +++ b/pppoe.h @@ -18,6 +18,8 @@ void pppoe_process_forward(uint8_t *pack, int size, in_addr_t addr); void pppoe_send_garp(); char * get_string_codepad(uint8_t codepad); +create_kernel_pppoe_socket(const sessionidt s); + extern int pppoediscfd; // pppoe discovery socket extern int pppoesessfd; // pppoe session socket