Add PPPOE-SERVER functionality
This commit is contained in:
parent
ddffeb1ceb
commit
11996ba414
15 changed files with 1403 additions and 57 deletions
15
Makefile
15
Makefile
|
|
@ -26,7 +26,7 @@ INSTALL = install -c -D -o root -g root
|
||||||
l2tpns.LIBS = -lm -lcli -ldl
|
l2tpns.LIBS = -lm -lcli -ldl
|
||||||
|
|
||||||
OBJS = arp.o cli.o cluster.o constants.o control.o icmp.o l2tpns.o \
|
OBJS = arp.o cli.o cluster.o constants.o control.o icmp.o l2tpns.o \
|
||||||
ll.o md5.o ppp.o radius.o tbf.o util.o
|
ll.o md5.o ppp.o radius.o tbf.o util.o pppoe.o
|
||||||
|
|
||||||
PROGRAMS = l2tpns nsctl
|
PROGRAMS = l2tpns nsctl
|
||||||
PLUGINS = autosnoop.so autothrottle.so garden.so sessionctl.so \
|
PLUGINS = autosnoop.so autothrottle.so garden.so sessionctl.so \
|
||||||
|
|
@ -114,22 +114,23 @@ install: all
|
||||||
arp.o: arp.c l2tpns.h
|
arp.o: arp.c l2tpns.h
|
||||||
cli.o: cli.c l2tpns.h constants.h util.h cluster.h tbf.h ll.h bgp.h \
|
cli.o: cli.c l2tpns.h constants.h util.h cluster.h tbf.h ll.h bgp.h \
|
||||||
l2tplac.h
|
l2tplac.h
|
||||||
cluster.o: cluster.c l2tpns.h cluster.h util.h tbf.h bgp.h
|
cluster.o: cluster.c l2tpns.h cluster.h util.h tbf.h pppoe.h bgp.h
|
||||||
constants.o: constants.c constants.h
|
constants.o: constants.c constants.h
|
||||||
control.o: control.c l2tpns.h control.h
|
control.o: control.c l2tpns.h control.h
|
||||||
icmp.o: icmp.c l2tpns.h
|
icmp.o: icmp.c l2tpns.h pppoe.h
|
||||||
l2tpns.o: l2tpns.c md5.h l2tpns.h cluster.h plugin.h ll.h constants.h \
|
l2tpns.o: l2tpns.c md5.h l2tpns.h cluster.h plugin.h ll.h constants.h \
|
||||||
control.h util.h tbf.h bgp.h l2tplac.h
|
control.h util.h tbf.h bgp.h l2tplac.h pppoe.h
|
||||||
ll.o: ll.c ll.h
|
ll.o: ll.c ll.h
|
||||||
md5.o: md5.c md5.h
|
md5.o: md5.c md5.h
|
||||||
ppp.o: ppp.c l2tpns.h constants.h plugin.h util.h tbf.h cluster.h \
|
ppp.o: ppp.c l2tpns.h constants.h plugin.h util.h tbf.h cluster.h \
|
||||||
l2tplac.h
|
l2tplac.h pppoe.h
|
||||||
radius.o: radius.c md5.h constants.h l2tpns.h plugin.h util.h cluster.h \
|
radius.o: radius.c md5.h constants.h l2tpns.h plugin.h util.h cluster.h \
|
||||||
l2tplac.h
|
l2tplac.h pppoe.h
|
||||||
tbf.o: tbf.c l2tpns.h util.h tbf.h
|
tbf.o: tbf.c l2tpns.h util.h tbf.h
|
||||||
util.o: util.c l2tpns.h bgp.h
|
util.o: util.c l2tpns.h bgp.h
|
||||||
|
pppoe.o: pppoe.c l2tpns.h cluster.h constants.h md5.h util.h
|
||||||
bgp.o: bgp.c l2tpns.h bgp.h util.h
|
bgp.o: bgp.c l2tpns.h bgp.h util.h
|
||||||
l2tplac.o: l2tplac.c md5.h l2tpns.h util.h cluster.h l2tplac.h
|
l2tplac.o: l2tplac.c md5.h l2tpns.h util.h cluster.h l2tplac.h pppoe.h
|
||||||
autosnoop.so: autosnoop.c l2tpns.h plugin.h
|
autosnoop.so: autosnoop.c l2tpns.h plugin.h
|
||||||
autothrottle.so: autothrottle.c l2tpns.h plugin.h
|
autothrottle.so: autothrottle.c l2tpns.h plugin.h
|
||||||
garden.so: garden.c l2tpns.h plugin.h control.h
|
garden.so: garden.c l2tpns.h plugin.h control.h
|
||||||
|
|
|
||||||
22
cli.c
22
cli.c
|
|
@ -564,9 +564,9 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
"idle",
|
"idle",
|
||||||
"Rem.Time",
|
"Rem.Time",
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
"LAC(L)/R LNS(R)",
|
"LAC(L)/RLNS(R)/PPPOE(P)",
|
||||||
#else
|
#else
|
||||||
"LAC",
|
"LAC(L)/PPPOE(P)",
|
||||||
#endif
|
#endif
|
||||||
"CLI");
|
"CLI");
|
||||||
|
|
||||||
|
|
@ -579,9 +579,9 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
else
|
else
|
||||||
rem_time = session[i].timeout ? (session[i].timeout - (time_now-session[i].opened)) : 0;
|
rem_time = session[i].timeout ? (session[i].timeout - (time_now-session[i].opened)) : 0;
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
cli_print(cli, "%5d %7d %4d %-32s %-15s %s %s %s %s %10u %10lu %10lu %4u %10lu %3s%-15s %s",
|
cli_print(cli, "%5d %7d %4d %-32s %-15s %s %s %s %s %10u %10lu %10lu %4u %10lu %3s%-20s %s",
|
||||||
#else
|
#else
|
||||||
cli_print(cli, "%5d %4d %-32s %-15s %s %s %s %s %10u %10lu %10lu %4u %10lu %-15s %s",
|
cli_print(cli, "%5d %4d %-32s %-15s %s %s %s %s %10u %10lu %10lu %4u %10lu %3s%-20s %s",
|
||||||
#endif
|
#endif
|
||||||
i,
|
i,
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
|
|
@ -600,9 +600,11 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
|
abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
|
||||||
(unsigned long)(rem_time),
|
(unsigned long)(rem_time),
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
tunnel[session[i].tunnel].isremotelns?"(R)":"(L)",
|
(session[i].tunnel == TUNNEL_ID_PPPOE)?"(P)":(tunnel[session[i].tunnel].isremotelns?"(R)":"(L)"),
|
||||||
|
#else
|
||||||
|
(session[i].tunnel == TUNNEL_ID_PPPOE)?"(P)":"(L)",
|
||||||
#endif
|
#endif
|
||||||
fmtaddr(htonl(tunnel[ session[i].tunnel ].ip), 1),
|
(session[i].tunnel == TUNNEL_ID_PPPOE)?fmtMacAddr(session[i].src_hwaddr):fmtaddr(htonl(tunnel[session[i].tunnel].ip), 1),
|
||||||
session[i].calling[0] ? session[i].calling : "*");
|
session[i].calling[0] ? session[i].calling : "*");
|
||||||
}
|
}
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
|
|
@ -686,18 +688,16 @@ static int cmd_show_tunnels(struct cli_def *cli, char *command, char **argv, int
|
||||||
if (!show_all && (!tunnel[i].ip || tunnel[i].die)) continue;
|
if (!show_all && (!tunnel[i].ip || tunnel[i].die)) continue;
|
||||||
|
|
||||||
for (x = 0; x < MAXSESSION; x++) if (session[x].tunnel == i && session[x].opened && !session[x].die) sessions++;
|
for (x = 0; x < MAXSESSION; x++) if (session[x].tunnel == i && session[x].opened && !session[x].die) sessions++;
|
||||||
#ifdef LAC
|
|
||||||
cli_print(cli, "%4d %20s %20s %6s %6d %s",
|
cli_print(cli, "%4d %20s %20s %6s %6d %s",
|
||||||
#else
|
|
||||||
cli_print(cli, "%4d %20s %20s %6s %6d",
|
|
||||||
#endif
|
|
||||||
i,
|
i,
|
||||||
*tunnel[i].hostname ? tunnel[i].hostname : "(null)",
|
*tunnel[i].hostname ? tunnel[i].hostname : "(null)",
|
||||||
fmtaddr(htonl(tunnel[i].ip), 0),
|
fmtaddr(htonl(tunnel[i].ip), 0),
|
||||||
states[tunnel[i].state],
|
states[tunnel[i].state],
|
||||||
sessions
|
sessions
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
,(tunnel[i].isremotelns?"Tunnel To Remote LNS":"Tunnel To LAC")
|
,(i == TUNNEL_ID_PPPOE)?"Tunnel pppoe":(tunnel[i].isremotelns?"Tunnel To Remote LNS":"Tunnel To LAC")
|
||||||
|
#else
|
||||||
|
,(i == TUNNEL_ID_PPPOE)?"Tunnel pppoe":"Tunnel To LAC"
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
46
cluster.c
46
cluster.c
|
|
@ -21,6 +21,7 @@
|
||||||
#include "cluster.h"
|
#include "cluster.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "tbf.h"
|
#include "tbf.h"
|
||||||
|
#include "pppoe.h"
|
||||||
|
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
#include "bgp.h"
|
#include "bgp.h"
|
||||||
|
|
@ -303,10 +304,39 @@ static int _forward_packet(uint8_t *data, int size, in_addr_t addr, int port, in
|
||||||
//
|
//
|
||||||
// The master just processes the payload as if it had
|
// The master just processes the payload as if it had
|
||||||
// received it off the tun device.
|
// received it off the tun device.
|
||||||
//
|
//(note: THIS ROUTINE WRITES TO pack[-6]).
|
||||||
int master_forward_packet(uint8_t *data, int size, in_addr_t addr, int port)
|
int master_forward_packet(uint8_t *data, int size, in_addr_t addr, int port)
|
||||||
{
|
{
|
||||||
return _forward_packet(data, size, addr, port, C_FORWARD);
|
uint8_t *p = data - (3 * sizeof(uint32_t));
|
||||||
|
uint8_t *psave = p;
|
||||||
|
|
||||||
|
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
|
||||||
|
|
||||||
|
STAT(c_forwarded);
|
||||||
|
add_type(&p, C_FORWARD, addr, (uint8_t *) &port, sizeof(port)); // ick. should be uint16_t
|
||||||
|
|
||||||
|
return peer_send_data(config->cluster_master_address, psave, size + (3 * sizeof(uint32_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward PPPOE packet to the master.
|
||||||
|
//(note: THIS ROUTINE WRITES TO pack[-4]).
|
||||||
|
int master_forward_pppoe_packet(uint8_t *data, int size, uint8_t codepad)
|
||||||
|
{
|
||||||
|
uint8_t *p = data - (2 * sizeof(uint32_t));
|
||||||
|
uint8_t *psave = p;
|
||||||
|
|
||||||
|
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
LOG(4, 0, 0, "Forward PPPOE packet to master, code %s (size %d)\n", get_string_codepad(codepad), size);
|
||||||
|
|
||||||
|
STAT(c_forwarded);
|
||||||
|
add_type(&p, C_PPPOE_FORWARD, codepad, NULL, 0);
|
||||||
|
|
||||||
|
return peer_send_data(config->cluster_master_address, psave, size + (2 * sizeof(uint32_t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward a DAE RADIUS packet to the master.
|
// Forward a DAE RADIUS packet to the master.
|
||||||
|
|
@ -606,6 +636,7 @@ void cluster_check_master(void)
|
||||||
// to become a master!!!
|
// to become a master!!!
|
||||||
|
|
||||||
config->cluster_iam_master = 1;
|
config->cluster_iam_master = 1;
|
||||||
|
pppoe_send_garp(); // gratuitous arp of the pppoe interface
|
||||||
|
|
||||||
LOG(0, 0, 0, "I am declaring myself the master!\n");
|
LOG(0, 0, 0, "I am declaring myself the master!\n");
|
||||||
|
|
||||||
|
|
@ -1871,6 +1902,17 @@ int processcluster(uint8_t *data, int size, in_addr_t addr)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case C_PPPOE_FORWARD:
|
||||||
|
if (!config->cluster_iam_master)
|
||||||
|
{
|
||||||
|
LOG(0, 0, 0, "I'm not the master, but I got a C_PPPOE_FORWARD from %s?\n", fmtaddr(addr, 0));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pppoe_process_forward(p, s, addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
case C_MPPP_FORWARD:
|
case C_MPPP_FORWARD:
|
||||||
// Receive a MPPP packet from a slave.
|
// Receive a MPPP packet from a slave.
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#define C_BUNDLE 17 // Bundle structure.
|
#define C_BUNDLE 17 // Bundle structure.
|
||||||
#define C_CBUNDLE 18 // Compressed bundle structure.
|
#define C_CBUNDLE 18 // Compressed bundle structure.
|
||||||
#define C_MPPP_FORWARD 19 // MPPP Forwarded packet..
|
#define C_MPPP_FORWARD 19 // MPPP Forwarded packet..
|
||||||
|
#define C_PPPOE_FORWARD 20 // PPPOE Forwarded packet..
|
||||||
|
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
#define HB_VERSION 7 // Protocol version number..
|
#define HB_VERSION 7 // Protocol version number..
|
||||||
|
|
@ -97,5 +98,6 @@ void cluster_heartbeat(void);
|
||||||
void cluster_check_master(void);
|
void cluster_check_master(void);
|
||||||
void cluster_check_slaves(void);
|
void cluster_check_slaves(void);
|
||||||
int cmd_show_cluster(struct cli_def *cli, char *command, char **argv, int argc);
|
int cmd_show_cluster(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
|
int master_forward_pppoe_packet(uint8_t *data, int size, uint8_t codepad);
|
||||||
|
|
||||||
#endif /* __CLUSTER_H__ */
|
#endif /* __CLUSTER_H__ */
|
||||||
|
|
|
||||||
6
debian/changelog
vendored
6
debian/changelog
vendored
|
|
@ -1,3 +1,9 @@
|
||||||
|
l2tpns (2.2.1-2fdn3.2-pppoe) unstable; urgency=low
|
||||||
|
|
||||||
|
* pppoe server functionality
|
||||||
|
|
||||||
|
-- Fernando Alves <fernando.alves@sameswireless.fr> Thu, 27 Dec 2012 22:54:02 +0100
|
||||||
|
|
||||||
l2tpns (2.2.1-2fdn3.2) unstable; urgency=low
|
l2tpns (2.2.1-2fdn3.2) unstable; urgency=low
|
||||||
|
|
||||||
* Authorize to change the source IP of the tunnels l2tp.
|
* Authorize to change the source IP of the tunnels l2tp.
|
||||||
|
|
|
||||||
3
icmp.c
3
icmp.c
|
|
@ -15,6 +15,7 @@
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
#include "l2tpns.h"
|
#include "l2tpns.h"
|
||||||
|
#include "pppoe.h"
|
||||||
|
|
||||||
static uint16_t _checksum(uint8_t *addr, int count);
|
static uint16_t _checksum(uint8_t *addr, int count);
|
||||||
|
|
||||||
|
|
@ -130,7 +131,9 @@ void send_ipv6_ra(sessionidt s, tunnelidt t, struct in6_addr *ip)
|
||||||
*(o+9) = 0x80;
|
*(o+9) = 0x80;
|
||||||
*(o+23) = 1;
|
*(o+23) = 1;
|
||||||
if (ip != NULL)
|
if (ip != NULL)
|
||||||
|
{
|
||||||
memcpy(o+24, ip, 16); // dest = ip
|
memcpy(o+24, ip, 16); // dest = ip
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// FF02::1 - all hosts
|
// FF02::1 - all hosts
|
||||||
|
|
|
||||||
12
l2tplac.c
12
l2tplac.c
|
|
@ -1,7 +1,10 @@
|
||||||
/*
|
/*
|
||||||
|
* Fernando ALVES 2013
|
||||||
* Add functionality "LAC" to l2tpns.
|
* Add functionality "LAC" to l2tpns.
|
||||||
* Used to forward a ppp session to another "LNS".
|
* Used to forward a ppp session to another "LNS".
|
||||||
|
* GPL licenced
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
@ -11,6 +14,7 @@
|
||||||
#include "cluster.h"
|
#include "cluster.h"
|
||||||
|
|
||||||
#include "l2tplac.h"
|
#include "l2tplac.h"
|
||||||
|
#include "pppoe.h"
|
||||||
|
|
||||||
/* sequence diagram: Client <--> LAC <--> LNS1 <--> LNS2
|
/* sequence diagram: Client <--> LAC <--> LNS1 <--> LNS2
|
||||||
*
|
*
|
||||||
|
|
@ -466,7 +470,7 @@ int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto,
|
||||||
|
|
||||||
if ((!tunnel[t].isremotelns) && (!tunnel[session[sess].tunnel].isremotelns))
|
if ((!tunnel[t].isremotelns) && (!tunnel[session[sess].tunnel].isremotelns))
|
||||||
{
|
{
|
||||||
LOG(0, sess, session[sess].tunnel, "Link Tunnel Session (%u) broken\n", s);
|
LOG(0, sess, session[sess].tunnel, "Link Tunnel Session (%u/%u) broken\n", s, t);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -483,6 +487,12 @@ int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t == TUNNEL_ID_PPPOE)
|
||||||
|
{
|
||||||
|
pppoe_forwardto_session_pppoe(buf, len, sess, proto);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (*buf & 0x40)
|
if (*buf & 0x40)
|
||||||
{ // length
|
{ // length
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
|
||||||
108
l2tpns.c
108
l2tpns.c
|
|
@ -56,6 +56,7 @@
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
#include "l2tplac.h"
|
#include "l2tplac.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "pppoe.h"
|
||||||
|
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
char * Vendor_name = "Linux L2TPNS";
|
char * Vendor_name = "Linux L2TPNS";
|
||||||
|
|
@ -186,6 +187,9 @@ config_descriptt config_values[] = {
|
||||||
CONFIG("bind_address_remotelns", bind_address_remotelns, IPv4),
|
CONFIG("bind_address_remotelns", bind_address_remotelns, IPv4),
|
||||||
CONFIG("bind_portremotelns", bind_portremotelns, SHORT),
|
CONFIG("bind_portremotelns", bind_portremotelns, SHORT),
|
||||||
#endif
|
#endif
|
||||||
|
CONFIG("pppoe_if_name", pppoe_if_name, STRING),
|
||||||
|
CONFIG("pppoe_service_name", pppoe_service_name, STRING),
|
||||||
|
CONFIG("pppoe_ac_name", pppoe_ac_name, STRING),
|
||||||
{ NULL, 0, 0, 0 },
|
{ NULL, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1195,6 +1199,12 @@ void tunnelsend(uint8_t * buf, uint16_t l, tunnelidt t)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t == TUNNEL_ID_PPPOE)
|
||||||
|
{
|
||||||
|
pppoe_sess_send(buf, l, t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!tunnel[t].ip)
|
if (!tunnel[t].ip)
|
||||||
{
|
{
|
||||||
LOG(1, 0, t, "Error sending data out tunnel: no remote endpoint (tunnel not set up)\n");
|
LOG(1, 0, t, "Error sending data out tunnel: no remote endpoint (tunnel not set up)\n");
|
||||||
|
|
@ -2134,7 +2144,14 @@ void sessionshutdown(sessionidt s, char const *reason, int cdn_result, int cdn_e
|
||||||
throttle_session(s, 0, 0);
|
throttle_session(s, 0, 0);
|
||||||
|
|
||||||
if (cdn_result)
|
if (cdn_result)
|
||||||
{ // Send CDN
|
{
|
||||||
|
if (session[s].tunnel == TUNNEL_ID_PPPOE)
|
||||||
|
{
|
||||||
|
pppoe_shutdown_session(s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Send CDN
|
||||||
controlt *c = controlnew(14); // sending CDN
|
controlt *c = controlnew(14); // sending CDN
|
||||||
if (cdn_error)
|
if (cdn_error)
|
||||||
{
|
{
|
||||||
|
|
@ -2149,6 +2166,7 @@ void sessionshutdown(sessionidt s, char const *reason, int cdn_result, int cdn_e
|
||||||
control16(c, 14, s, 1); // assigned session (our end)
|
control16(c, 14, s, 1); // assigned session (our end)
|
||||||
controladd(c, session[s].far, session[s].tunnel); // send the message
|
controladd(c, session[s].far, session[s].tunnel); // send the message
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update filter refcounts
|
// update filter refcounts
|
||||||
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
|
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
|
||||||
|
|
@ -2414,6 +2432,12 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
STAT(tunnel_rx_errors);
|
STAT(tunnel_rx_errors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (t == TUNNEL_ID_PPPOE)
|
||||||
|
{
|
||||||
|
LOG(1, s, t, "Received UDP packet with tunnel ID reserved for pppoe\n");
|
||||||
|
STAT(tunnel_rx_errors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (*buf & 0x08)
|
if (*buf & 0x08)
|
||||||
{ // ns/nr
|
{ // ns/nr
|
||||||
ns = ntohs(*(uint16_t *) p);
|
ns = ntohs(*(uint16_t *) p);
|
||||||
|
|
@ -3441,6 +3465,9 @@ static void regular_cleanups(double period)
|
||||||
if (t > config->cluster_highest_tunnelid)
|
if (t > config->cluster_highest_tunnelid)
|
||||||
t = 1;
|
t = 1;
|
||||||
|
|
||||||
|
if (t == TUNNEL_ID_PPPOE)
|
||||||
|
continue;
|
||||||
|
|
||||||
// check for expired tunnels
|
// check for expired tunnels
|
||||||
if (tunnel[t].die && tunnel[t].die <= TIME)
|
if (tunnel[t].die && tunnel[t].die <= TIME)
|
||||||
{
|
{
|
||||||
|
|
@ -3664,7 +3691,8 @@ static void regular_cleanups(double period)
|
||||||
|
|
||||||
LOG(4, s, session[s].tunnel, "No data in %d seconds, sending LCP ECHO\n",
|
LOG(4, s, session[s].tunnel, "No data in %d seconds, sending LCP ECHO\n",
|
||||||
(int)(time_now - session[s].last_packet));
|
(int)(time_now - session[s].last_packet));
|
||||||
tunnelsend(b, 24, session[s].tunnel); // send it
|
|
||||||
|
tunnelsend(b, (q - b) + 8, session[s].tunnel); // send it
|
||||||
sess_local[s].last_echo = time_now;
|
sess_local[s].last_echo = time_now;
|
||||||
s_actions++;
|
s_actions++;
|
||||||
}
|
}
|
||||||
|
|
@ -3916,11 +3944,11 @@ static int still_busy(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
// the base set of fds polled: cli, cluster, tun, udp, control, dae, netlink, udplac
|
// the base set of fds polled: cli, cluster, tun, udp, control, dae, netlink, udplac, pppoedisc, pppoesess
|
||||||
#define BASE_FDS 8
|
#define BASE_FDS 10
|
||||||
#else
|
#else
|
||||||
// the base set of fds polled: cli, cluster, tun, udp, control, dae, netlink
|
// the base set of fds polled: cli, cluster, tun, udp, control, dae, netlink, pppoedisc, pppoesess
|
||||||
#define BASE_FDS 7
|
#define BASE_FDS 9
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// additional polled fds
|
// additional polled fds
|
||||||
|
|
@ -3935,8 +3963,9 @@ static void mainloop(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t buf[65536];
|
uint8_t buf[65536];
|
||||||
uint8_t *p = buf + 8; // for the hearder of the forwarded MPPP packet (see C_MPPP_FORWARD)
|
uint8_t *p = buf + 24; // for the hearder of the forwarded MPPP packet (see C_MPPP_FORWARD)
|
||||||
int size_bufp = sizeof(buf) - 8;
|
// and the forwarded pppoe session
|
||||||
|
int size_bufp = sizeof(buf) - 24;
|
||||||
clockt next_cluster_ping = 0; // send initial ping immediately
|
clockt next_cluster_ping = 0; // send initial ping immediately
|
||||||
struct epoll_event events[BASE_FDS + RADIUS_FDS + EXTRA_FDS];
|
struct epoll_event events[BASE_FDS + RADIUS_FDS + EXTRA_FDS];
|
||||||
int maxevent = sizeof(events)/sizeof(*events);
|
int maxevent = sizeof(events)/sizeof(*events);
|
||||||
|
|
@ -3948,11 +3977,11 @@ static void mainloop(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d , udplacfd=%d\n",
|
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d , udplacfd=%d, pppoefd=%d, pppoesessfd=%d\n",
|
||||||
clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd, nlfd, udplacfd);
|
clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd, nlfd, udplacfd, pppoediscfd, pppoesessfd);
|
||||||
#else
|
#else
|
||||||
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d\n",
|
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d, pppoefd=%d, pppoesessfd=%d\n",
|
||||||
clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd, nlfd);
|
clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd, nlfd, pppoediscfd, pppoesessfd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* setup our fds to poll for input */
|
/* setup our fds to poll for input */
|
||||||
|
|
@ -3999,6 +4028,14 @@ static void mainloop(void)
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, udplacfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, udplacfd, &e);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
d[i].type = FD_TYPE_PPPOEDISC;
|
||||||
|
e.data.ptr = &d[i++];
|
||||||
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, pppoediscfd, &e);
|
||||||
|
|
||||||
|
d[i].type = FD_TYPE_PPPOESESS;
|
||||||
|
e.data.ptr = &d[i++];
|
||||||
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, pppoesessfd, &e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
|
|
@ -4065,6 +4102,8 @@ static void mainloop(void)
|
||||||
int udplac_ready = 0;
|
int udplac_ready = 0;
|
||||||
int udplac_pkts = 0;
|
int udplac_pkts = 0;
|
||||||
#endif
|
#endif
|
||||||
|
int pppoesess_ready = 0;
|
||||||
|
int pppoesess_pkts = 0;
|
||||||
int tun_ready = 0;
|
int tun_ready = 0;
|
||||||
int cluster_ready = 0;
|
int cluster_ready = 0;
|
||||||
int udp_pkts = 0;
|
int udp_pkts = 0;
|
||||||
|
|
@ -4105,6 +4144,14 @@ static void mainloop(void)
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
case FD_TYPE_UDPLAC: udplac_ready++; break;
|
case FD_TYPE_UDPLAC: udplac_ready++; break;
|
||||||
#endif
|
#endif
|
||||||
|
case FD_TYPE_PPPOESESS: pppoesess_ready++; break;
|
||||||
|
|
||||||
|
case FD_TYPE_PPPOEDISC: // pppoe discovery
|
||||||
|
s = read(pppoediscfd, p, size_bufp);
|
||||||
|
if (s > 0) process_pppoe_disc(p, s);
|
||||||
|
n--;
|
||||||
|
break;
|
||||||
|
|
||||||
case FD_TYPE_CONTROL: // nsctl commands
|
case FD_TYPE_CONTROL: // nsctl commands
|
||||||
alen = sizeof(addr);
|
alen = sizeof(addr);
|
||||||
s = recvfromto(controlfd, buf, sizeof(buf), MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local);
|
s = recvfromto(controlfd, buf, sizeof(buf), MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local);
|
||||||
|
|
@ -4183,9 +4230,9 @@ static void mainloop(void)
|
||||||
if (udp_ready)
|
if (udp_ready)
|
||||||
{
|
{
|
||||||
alen = sizeof(addr);
|
alen = sizeof(addr);
|
||||||
if ((s = recvfrom(udpfd, buf, sizeof(buf), 0, (void *) &addr, &alen)) > 0)
|
if ((s = recvfrom(udpfd, p, size_bufp, 0, (void *) &addr, &alen)) > 0)
|
||||||
{
|
{
|
||||||
processudp(buf, s, &addr);
|
processudp(p, s, &addr);
|
||||||
udp_pkts++;
|
udp_pkts++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -4199,10 +4246,10 @@ static void mainloop(void)
|
||||||
if (udplac_ready)
|
if (udplac_ready)
|
||||||
{
|
{
|
||||||
alen = sizeof(addr);
|
alen = sizeof(addr);
|
||||||
if ((s = recvfrom(udplacfd, buf, sizeof(buf), 0, (void *) &addr, &alen)) > 0)
|
if ((s = recvfrom(udplacfd, p, size_bufp, 0, (void *) &addr, &alen)) > 0)
|
||||||
{
|
{
|
||||||
if (!config->disable_lac_func)
|
if (!config->disable_lac_func)
|
||||||
processudp(buf, s, &addr);
|
processudp(p, s, &addr);
|
||||||
|
|
||||||
udplac_pkts++;
|
udplac_pkts++;
|
||||||
}
|
}
|
||||||
|
|
@ -4228,13 +4275,28 @@ static void mainloop(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pppoe session
|
||||||
|
if (pppoesess_ready)
|
||||||
|
{
|
||||||
|
if ((s = read(pppoesessfd, p, size_bufp)) > 0)
|
||||||
|
{
|
||||||
|
process_pppoe_sess(p, s);
|
||||||
|
pppoesess_pkts++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pppoesess_ready = 0;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cluster
|
// cluster
|
||||||
if (cluster_ready)
|
if (cluster_ready)
|
||||||
{
|
{
|
||||||
alen = sizeof(addr);
|
alen = sizeof(addr);
|
||||||
if ((s = recvfrom(cluster_sockfd, buf, sizeof(buf), MSG_WAITALL, (void *) &addr, &alen)) > 0)
|
if ((s = recvfrom(cluster_sockfd, p, size_bufp, MSG_WAITALL, (void *) &addr, &alen)) > 0)
|
||||||
{
|
{
|
||||||
processcluster(buf, s, addr.sin_addr.s_addr);
|
processcluster(p, s, addr.sin_addr.s_addr);
|
||||||
cluster_pkts++;
|
cluster_pkts++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -5059,6 +5121,11 @@ int main(int argc, char *argv[])
|
||||||
inittun();
|
inittun();
|
||||||
LOG(1, 0, 0, "Set up on interface %s\n", config->tundevicename);
|
LOG(1, 0, 0, "Set up on interface %s\n", config->tundevicename);
|
||||||
|
|
||||||
|
if (*config->pppoe_if_name)
|
||||||
|
{
|
||||||
|
init_pppoe();
|
||||||
|
LOG(1, 0, 0, "Set up on pppoe interface %s\n", config->pppoe_if_name);
|
||||||
|
}
|
||||||
initudp();
|
initudp();
|
||||||
initrad();
|
initrad();
|
||||||
initippool();
|
initippool();
|
||||||
|
|
@ -5300,6 +5367,9 @@ static void update_config()
|
||||||
if(!config->iftun_address)
|
if(!config->iftun_address)
|
||||||
config->iftun_address = config->bind_address;
|
config->iftun_address = config->bind_address;
|
||||||
|
|
||||||
|
if (!*config->pppoe_ac_name)
|
||||||
|
strncpy(config->pppoe_ac_name, DEFAULT_PPPOE_AC_NAME, sizeof(config->pppoe_ac_name) - 1);
|
||||||
|
|
||||||
// re-initialise the random number source
|
// re-initialise the random number source
|
||||||
initrandom(config->random_device);
|
initrandom(config->random_device);
|
||||||
|
|
||||||
|
|
@ -6036,7 +6106,7 @@ static tunnelidt new_tunnel()
|
||||||
tunnelidt i;
|
tunnelidt i;
|
||||||
for (i = 1; i < MAXTUNNEL; i++)
|
for (i = 1; i < MAXTUNNEL; i++)
|
||||||
{
|
{
|
||||||
if (tunnel[i].state == TUNNELFREE)
|
if ((tunnel[i].state == TUNNELFREE) && (i != TUNNEL_ID_PPPOE))
|
||||||
{
|
{
|
||||||
LOG(4, 0, i, "Assigning tunnel ID %u\n", i);
|
LOG(4, 0, i, "Assigning tunnel ID %u\n", i);
|
||||||
if (i > config->cluster_highest_tunnelid)
|
if (i > config->cluster_highest_tunnelid)
|
||||||
|
|
|
||||||
16
l2tpns.h
16
l2tpns.h
|
|
@ -9,6 +9,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <net/ethernet.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
@ -24,6 +25,9 @@
|
||||||
#define MAXSESSION 60000 // could be up to 65535
|
#define MAXSESSION 60000 // could be up to 65535
|
||||||
#define MAXTBFS 6000 // Maximum token bucket filters. Might need up to 2 * session.
|
#define MAXTBFS 6000 // Maximum token bucket filters. Might need up to 2 * session.
|
||||||
|
|
||||||
|
// Tunnel Id reserved for pppoe
|
||||||
|
#define TUNNEL_ID_PPPOE 1
|
||||||
|
|
||||||
#define RADIUS_SHIFT 6
|
#define RADIUS_SHIFT 6
|
||||||
#define RADIUS_FDS (1 << RADIUS_SHIFT)
|
#define RADIUS_FDS (1 << RADIUS_SHIFT)
|
||||||
#define RADIUS_MASK ((1 << RADIUS_SHIFT) - 1)
|
#define RADIUS_MASK ((1 << RADIUS_SHIFT) - 1)
|
||||||
|
|
@ -323,9 +327,11 @@ typedef struct
|
||||||
struct in6_addr ipv6route; // Static IPv6 route
|
struct in6_addr ipv6route; // Static IPv6 route
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
sessionidt forwardtosession; // LNS id_session to forward
|
sessionidt forwardtosession; // LNS id_session to forward
|
||||||
char reserved[10]; // Space to expand structure without changing HB_VERSION
|
uint8_t src_hwaddr[ETH_ALEN]; // MAC addr source (for pppoe sessions 6 bytes)
|
||||||
|
char reserved[4]; // Space to expand structure without changing HB_VERSION
|
||||||
#else
|
#else
|
||||||
char reserved[12]; // Space to expand structure without changing HB_VERSION
|
uint8_t src_hwaddr[ETH_ALEN]; // MAC addr source (for pppoe sessions 6 bytes)
|
||||||
|
char reserved[6]; // Space to expand structure without changing HB_VERSION
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
sessiont;
|
sessiont;
|
||||||
|
|
@ -769,6 +775,10 @@ typedef struct
|
||||||
uint16_t bind_portremotelns;
|
uint16_t bind_portremotelns;
|
||||||
in_addr_t bind_address_remotelns;
|
in_addr_t bind_address_remotelns;
|
||||||
#endif
|
#endif
|
||||||
|
char pppoe_if_name[IFNAMSIZ]; // Name pppoe interface to bind
|
||||||
|
char pppoe_service_name[64]; // pppoe service name
|
||||||
|
char pppoe_ac_name[64];
|
||||||
|
uint8_t pppoe_hwaddr[ETH_ALEN]; // MAC addr of interface pppoe to bind
|
||||||
} configt;
|
} configt;
|
||||||
|
|
||||||
enum config_typet { INT, STRING, UNSIGNED_LONG, SHORT, BOOL, IPv4, IPv6 };
|
enum config_typet { INT, STRING, UNSIGNED_LONG, SHORT, BOOL, IPv4, IPv6 };
|
||||||
|
|
@ -1002,6 +1012,8 @@ struct event_data {
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
FD_TYPE_UDPLAC,
|
FD_TYPE_UDPLAC,
|
||||||
#endif
|
#endif
|
||||||
|
FD_TYPE_PPPOEDISC,
|
||||||
|
FD_TYPE_PPPOESESS
|
||||||
} type;
|
} type;
|
||||||
int index; // for RADIUS, BGP
|
int index; // for RADIUS, BGP
|
||||||
};
|
};
|
||||||
|
|
|
||||||
6
ppp.c
6
ppp.c
|
|
@ -15,6 +15,7 @@
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
#include "l2tplac.h"
|
#include "l2tplac.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "pppoe.h"
|
||||||
|
|
||||||
extern tunnelt *tunnel;
|
extern tunnelt *tunnel;
|
||||||
extern bundlet *bundle;
|
extern bundlet *bundle;
|
||||||
|
|
@ -2521,6 +2522,11 @@ uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelid
|
||||||
uint16_t type = mtype;
|
uint16_t type = mtype;
|
||||||
uint8_t *start = b;
|
uint8_t *start = b;
|
||||||
|
|
||||||
|
if (t == TUNNEL_ID_PPPOE)
|
||||||
|
{
|
||||||
|
return pppoe_makeppp(b, size, p, l, s, t, mtype, prio, bid, mp_bits);
|
||||||
|
}
|
||||||
|
|
||||||
if (size < 16) // Need more space than this!!
|
if (size < 16) // Need more space than this!!
|
||||||
{
|
{
|
||||||
LOG(0, s, t, "makeppp buffer too small for L2TP header (size=%d)\n", size);
|
LOG(0, s, t, "makeppp buffer too small for L2TP header (size=%d)\n", size);
|
||||||
|
|
|
||||||
23
pppoe.h
Normal file
23
pppoe.h
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
#ifndef __PPPOE_H__
|
||||||
|
#define __PPPOE_H__
|
||||||
|
|
||||||
|
#define DEFAULT_PPPOE_AC_NAME "l2tpns-pppoe"
|
||||||
|
|
||||||
|
// pppoe.c
|
||||||
|
void init_pppoe(void);
|
||||||
|
void process_pppoe_disc(uint8_t *pack, int size);
|
||||||
|
void process_pppoe_sess(uint8_t *pack, int size);
|
||||||
|
void pppoe_sess_send(const uint8_t *pack, uint16_t l, tunnelidt t);
|
||||||
|
uint8_t *pppoe_makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelidt t,
|
||||||
|
uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits);
|
||||||
|
void pppoe_shutdown_session(sessionidt s);
|
||||||
|
void pppoe_forwardto_session_pppoe(uint8_t *pack, int size, sessionidt sess, uint16_t proto);
|
||||||
|
void pppoe_process_forward(uint8_t *pack, int size, in_addr_t addr);
|
||||||
|
void pppoe_send_garp();
|
||||||
|
char * get_string_codepad(uint8_t codepad);
|
||||||
|
|
||||||
|
extern int pppoediscfd; // pppoe discovery socket
|
||||||
|
extern int pppoesessfd; // pppoe session socket
|
||||||
|
|
||||||
|
#endif /* __PPPOE_H__ */
|
||||||
1
radius.c
1
radius.c
|
|
@ -22,6 +22,7 @@
|
||||||
#ifdef LAC
|
#ifdef LAC
|
||||||
#include "l2tplac.h"
|
#include "l2tplac.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "pppoe.h"
|
||||||
|
|
||||||
extern radiust *radius;
|
extern radiust *radius;
|
||||||
extern sessiont *session;
|
extern sessiont *session;
|
||||||
|
|
|
||||||
11
util.c
11
util.c
|
|
@ -28,6 +28,17 @@ char *fmtaddr(in_addr_t addr, int n)
|
||||||
return strcpy(addrs[n], inet_ntoa(in));
|
return strcpy(addrs[n], inet_ntoa(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *fmtMacAddr(uint8_t *pMacAddr)
|
||||||
|
{
|
||||||
|
static char strMAC[2*ETH_ALEN];
|
||||||
|
|
||||||
|
sprintf(strMAC, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
|
pMacAddr[0], pMacAddr[1], pMacAddr[2],
|
||||||
|
pMacAddr[3], pMacAddr[4], pMacAddr[5]);
|
||||||
|
|
||||||
|
return strMAC;
|
||||||
|
}
|
||||||
|
|
||||||
void *shared_malloc(unsigned int size)
|
void *shared_malloc(unsigned int size)
|
||||||
{
|
{
|
||||||
void * p;
|
void * p;
|
||||||
|
|
|
||||||
1
util.h
1
util.h
|
|
@ -2,6 +2,7 @@
|
||||||
#define __UTIL_H__
|
#define __UTIL_H__
|
||||||
|
|
||||||
char *fmtaddr(in_addr_t addr, int n);
|
char *fmtaddr(in_addr_t addr, int n);
|
||||||
|
char *fmtMacAddr(uint8_t *pMacAddr);
|
||||||
void *shared_malloc(unsigned int size);
|
void *shared_malloc(unsigned int size);
|
||||||
pid_t fork_and_close(void);
|
pid_t fork_and_close(void);
|
||||||
ssize_t sendtofrom(int s, void const *buf, size_t len, int flags,
|
ssize_t sendtofrom(int s, void const *buf, size_t len, int flags,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue