Add L2 PPP and PPPoE

This commit is contained in:
Sergio R. Caprile
2026-04-01 14:50:00 -03:00
parent b491b7c624
commit ba47e29c28
4 changed files with 71 additions and 0 deletions
+57
View File
@@ -3740,6 +3740,7 @@ struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet
#define MG_PPPoE_PADS 0x65
#define MG_PPPoE_PADT 0xa7
<<<<<<< HEAD
#define MG_PPPoE_ST_DISC 0 // Discovery phase, see what servers are out there
#define MG_PPPoE_ST_REQ 1 // Chose a server, request a session and wait
#define MG_PPPoE_ST_SESS 2 // Session established, PPP traffic is exchanged
@@ -3748,6 +3749,12 @@ struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet
static bool s_link = false; // *******************************************
static uint8_t s_state = MG_PPPoE_ST_DISC;
=======
#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
static bool s_link = false; // *******************************************
static uint8_t s_state = 0;
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
static uint16_t s_id;
void mg_l2_ppp_init(struct mg_tcpip_if *ifp) {
@@ -3764,7 +3771,12 @@ void mg_l2_pppoe_init(struct mg_tcpip_if *ifp) {
}
bool mg_l2_ppp_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) {
<<<<<<< HEAD
if (expired_1000ms && ifp->state == MG_TCPIP_STATE_DOWN) s_link = false;
=======
(void) ifp;
(void) expired_1000ms;
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
return s_link;
}
@@ -4106,17 +4118,26 @@ static size_t pppoe_tx_frame(struct mg_tcpip_if *ifp, uint8_t code, uint16_t id,
extern struct mg_l2addr *mg_l2_eth_mapip(enum mg_l2addrtype, struct mg_addr *);
bool mg_l2_pppoe_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) {
<<<<<<< HEAD
if (expired_1000ms && s_state == MG_PPPoE_ST_DISC &&
ifp->state == MG_TCPIP_STATE_LINK_UP) {
=======
if (expired_1000ms && s_state == 0 && ifp->driver_up) {
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
uint16_t tags[2];
tags[0] = mg_htons(0x0101); // Service Request
tags[1] = mg_htons(0x0000); // Any
pppoe_tx_frame(ifp, MG_PPPoE_PADI, 0, (uint8_t *) tags, sizeof(tags),
mg_l2_eth_mapip(MG_TCPIP_L2ADDR_BCAST, NULL));
MG_DEBUG(("Sent PADI"));
<<<<<<< HEAD
} else if (expired_1000ms && (s_state != MG_PPPoE_ST_SESS ||
ifp->state == MG_TCPIP_STATE_DOWN)) {
s_state = MG_PPPoE_ST_DISC;
=======
} else if (expired_1000ms && (s_state != 2 || !ifp->driver_up)) {
s_state = 0;
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
}
return mg_l2_ppp_poll(ifp, expired_1000ms);
}
@@ -4134,8 +4155,12 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
if (pay->len < sizeof(*pppoe)) return false; // Truncated
if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_DISC) {
MG_VERBOSE(("PPPoE_DISC"));
<<<<<<< HEAD
if (s_state == MG_PPPoE_ST_DISC && pppoe->code == MG_PPPoE_PADO &&
pppoe->id == 0) {
=======
if (s_state == 0 && pppoe->code == MG_PPPoE_PADO && pppoe->id == 0) {
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
uint16_t tags[2];
bool has_cookie = false;
size_t len = pay->len - sizeof(*pppoe);
@@ -4164,6 +4189,7 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
pppoe_tx_frame(ifp, MG_PPPoE_PADR, 0, p, taglen,
mg_l2_eth_getaddr((uint8_t *) raw->buf));
MG_DEBUG(("Sent PADR"));
<<<<<<< HEAD
s_state = MG_PPPoE_ST_REQ;
} else if (s_state == MG_PPPoE_ST_REQ && pppoe->code == MG_PPPoE_PADS) {
s_id = pppoe->id;
@@ -4171,14 +4197,29 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
MG_DEBUG(("PPPoE session 0x%04x started", mg_ntohs(s_id)));
s_state = MG_PPPoE_ST_SESS;
} else if (s_state == MG_PPPoE_ST_SESS && pppoe->code == MG_PPPoE_PADT &&
=======
s_state = 1;
} else if (s_state == 1 && pppoe->code == MG_PPPoE_PADS) {
s_id = pppoe->id;
memcpy(&ifp->gwmac, mg_l2_eth_getaddr((uint8_t *) raw->buf)->addr.mac, 6);
MG_DEBUG(("PPPoE session 0x%04x started", mg_ntohs(s_id)));
s_state = 2;
} else if (s_state == 2 && pppoe->code == MG_PPPoE_PADT &&
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
pppoe->id == s_id) {
MG_ERROR(("Got PADT"));
s_id = 0;
s_link = false;
<<<<<<< HEAD
s_state = MG_PPPoE_ST_DISC;
}
} else if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_SESS &&
s_state == MG_PPPoE_ST_SESS) {
=======
s_state = 0;
}
} else if (eth_proto == MG_TCPIP_L2PROTO_PPPoE_SESS && s_state == 2) {
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
pay->buf = (char *) (pppoe + 1);
pay->len = pay->len - sizeof(*pppoe);
return ppp_rx(ifp, proto, pay, raw);
@@ -7193,7 +7234,11 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
pkt.raw.len = len;
pkt.l2 = (uint8_t *) pkt.raw.buf;
if (!mg_l2_rx(ifp, &proto, &pkt.pay, &pkt.raw)) return;
<<<<<<< HEAD
if (ifp->state < MG_TCPIP_STATE_UP) return; // discard while L2 is not up
=======
if (ifp->state == MG_TCPIP_STATE_DOWN) return; // discard while L2 is not up
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
if (proto == MG_TCPIP_L2PROTO_ARP) {
pkt.arp = (struct arp *) (pkt.pay.buf);
if (pkt.pay.len < sizeof(*pkt.arp)) return; // Truncated
@@ -7319,9 +7364,17 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
drv_up = ifp->driver->poll ? ifp->driver->poll(ifp, expired_1000ms) : true;
l2_up = mg_l2_poll(ifp, expired_1000ms); // Handle L2 up/down link status;
if (expired_1000ms) { // ifp->state rules over state6
<<<<<<< HEAD
mg_ip_link(ifp, drv_up, l2_up); // Handle IPv4
mg_ip6_link(ifp, drv_up, l2_up); // Handle IPv6
if (ifp->state < MG_TCPIP_STATE_UP) MG_ERROR(("Network is down"));
=======
bool up = drv_up & l2_up;
ifp->driver_up = drv_up; // update physical link state
mg_ip_link(ifp, up); // Handle IPv4
mg_ip6_link(ifp, up); // Handle IPv6
if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
mg_tcpip_call(ifp, MG_TCPIP_EV_TIMER_1S, NULL);
}
}
@@ -7345,7 +7398,11 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
mg_queue_del(&ifp->recv_queue, len);
}
}
<<<<<<< HEAD
if (ifp->state < MG_TCPIP_STATE_UP) return; // need to let L2 do its job
=======
if (ifp->state == MG_TCPIP_STATE_DOWN) return; // need to let L2 do its job
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
// Process timeouts
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
+1
View File
@@ -3346,6 +3346,7 @@ struct mg_tcpip_if {
#define MG_TCPIP_STATE_IP 4 // Interface is up and has an IP assigned
#define MG_TCPIP_STATE_READY 5 // Interface has fully come up, ready to work
bool gw_ready; // We've got a hw address for the router
bool driver_up; // Driver reports link state is up
#if MG_ENABLE_IPV6
uint8_t gw6mac[sizeof(struct mg_l2addr)]; // IPV6 Router's hw address
uint8_t state6; // Current IPv6 state
+12
View File
@@ -82,6 +82,7 @@ struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet
#define MG_PPPoE_PADS 0x65
#define MG_PPPoE_PADT 0xa7
<<<<<<< HEAD
#define MG_PPPoE_ST_DISC 0 // Discovery phase, see what servers are out there
#define MG_PPPoE_ST_REQ 1 // Chose a server, request a session and wait
#define MG_PPPoE_ST_SESS 2 // Session established, PPP traffic is exchanged
@@ -90,6 +91,12 @@ struct pppoe { // RFC-2516, "A Method for Transmitting PPP Over Ethernet
static bool s_link = false; // *******************************************
static uint8_t s_state = MG_PPPoE_ST_DISC;
=======
#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
static bool s_link = false; // *******************************************
static uint8_t s_state = 0;
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
static uint16_t s_id;
void mg_l2_ppp_init(struct mg_tcpip_if *ifp) {
@@ -106,7 +113,12 @@ void mg_l2_pppoe_init(struct mg_tcpip_if *ifp) {
}
bool mg_l2_ppp_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) {
<<<<<<< HEAD
if (expired_1000ms && ifp->state == MG_TCPIP_STATE_DOWN) s_link = false;
=======
(void) ifp;
(void) expired_1000ms;
>>>>>>> 668f10fc (Add L2 PPP and PPPoE)
return s_link;
}
+1
View File
@@ -88,6 +88,7 @@ struct mg_tcpip_if {
#define MG_TCPIP_STATE_IP 4 // Interface is up and has an IP assigned
#define MG_TCPIP_STATE_READY 5 // Interface has fully come up, ready to work
bool gw_ready; // We've got a hw address for the router
bool driver_up; // Driver reports link state is up
#if MG_ENABLE_IPV6
uint8_t gw6mac[sizeof(struct mg_l2addr)]; // IPV6 Router's hw address
uint8_t state6; // Current IPv6 state