Attempt to hack in acceleration for PPPoE

This commit is contained in:
Tassilo Schweyer 2025-04-29 00:43:40 +02:00
parent 0c9338b03a
commit 57004c5744
4 changed files with 40 additions and 9 deletions

View file

@ -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)

View file

@ -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__); })

22
pppoe.c
View file

@ -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
@ -249,9 +250,12 @@ void init_pppoe(void)
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;
@ -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
p += 2;
*(uint16_t *) p = htons(0xFF03); // HDLC header
p += 2;
if ((proto == PPPIP) || (proto == PPPMP) ||(proto == PPPIPV6 && config->ipv6_prefix.s6_addr[0]))
{
session[sess].last_packet = time_now;

View file

@ -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