PR/40690: Jordan Gordeev: pppoe(4) doesn't work when PPPoE relays are present
Add support for sending the session id tag back.
This commit is contained in:
parent
f654d345dd
commit
c6c3da7776
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $ */
|
||||
/* $NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $");
|
||||
|
||||
#include "pppoe.h"
|
||||
#include "bpfilter.h"
|
||||
@ -138,6 +138,8 @@ struct pppoe_softc {
|
||||
char *sc_concentrator_name; /* if != NULL: requested concentrator id */
|
||||
uint8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
|
||||
size_t sc_ac_cookie_len; /* length of cookie data */
|
||||
uint8_t *sc_relay_sid; /* content of relay SID we must echo back */
|
||||
size_t sc_relay_sid_len; /* length of relay SID data */
|
||||
#ifdef PPPOE_SERVER
|
||||
uint8_t *sc_hunique; /* content of host unique we must echo back */
|
||||
size_t sc_hunique_len; /* length of host unique */
|
||||
@ -283,6 +285,8 @@ pppoe_clone_destroy(struct ifnet *ifp)
|
||||
free(sc->sc_service_name, M_DEVBUF);
|
||||
if (sc->sc_ac_cookie)
|
||||
free(sc->sc_ac_cookie, M_DEVBUF);
|
||||
if (sc->sc_relay_sid)
|
||||
free(sc->sc_relay_sid, M_DEVBUF);
|
||||
callout_destroy(&sc->sc_timeout);
|
||||
free(sc, M_DEVBUF);
|
||||
|
||||
@ -400,6 +404,8 @@ pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
|
||||
char *error;
|
||||
uint8_t *ac_cookie;
|
||||
size_t ac_cookie_len;
|
||||
uint8_t *relay_sid;
|
||||
size_t relay_sid_len;
|
||||
#ifdef PPPOE_SERVER
|
||||
uint8_t *hunique;
|
||||
size_t hunique_len;
|
||||
@ -423,6 +429,8 @@ pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
|
||||
|
||||
ac_cookie = NULL;
|
||||
ac_cookie_len = 0;
|
||||
relay_sid = NULL;
|
||||
relay_sid_len = 0;
|
||||
#ifdef PPPOE_SERVER
|
||||
hunique = NULL;
|
||||
hunique_len = 0;
|
||||
@ -528,6 +536,19 @@ pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
|
||||
ac_cookie_len = len;
|
||||
}
|
||||
break;
|
||||
case PPPOE_TAG_RELAYSID:
|
||||
if (relay_sid == NULL) {
|
||||
n = m_pulldown(m, off + sizeof(*pt), len,
|
||||
&noff);
|
||||
if (!n) {
|
||||
err_msg = "TAG RELAYSID ERROR";
|
||||
m = NULL;
|
||||
break;
|
||||
}
|
||||
relay_sid = mtod(n, char *) + noff;
|
||||
relay_sid_len = len;
|
||||
}
|
||||
break;
|
||||
case PPPOE_TAG_SNAME_ERR:
|
||||
err_msg = "SERVICE NAME ERROR";
|
||||
errortag = 1;
|
||||
@ -669,6 +690,20 @@ breakbreak:;
|
||||
sc->sc_ac_cookie_len = ac_cookie_len;
|
||||
memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
|
||||
}
|
||||
if (relay_sid) {
|
||||
if (sc->sc_relay_sid)
|
||||
free(sc->sc_relay_sid, M_DEVBUF);
|
||||
sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF,
|
||||
M_DONTWAIT);
|
||||
if (sc->sc_relay_sid == NULL) {
|
||||
printf("%s: FATAL: could not allocate memory "
|
||||
"for relay SID\n",
|
||||
sc->sc_sppp.pp_if.if_xname);
|
||||
goto done;
|
||||
}
|
||||
sc->sc_relay_sid_len = relay_sid_len;
|
||||
memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len);
|
||||
}
|
||||
memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
|
||||
callout_stop(&sc->sc_timeout);
|
||||
sc->sc_padr_retried = 0;
|
||||
@ -1200,6 +1235,11 @@ pppoe_disconnect(struct pppoe_softc *sc)
|
||||
sc->sc_ac_cookie = NULL;
|
||||
}
|
||||
sc->sc_ac_cookie_len = 0;
|
||||
if (sc->sc_relay_sid) {
|
||||
free(sc->sc_relay_sid, M_DEVBUF);
|
||||
sc->sc_relay_sid = NULL;
|
||||
}
|
||||
sc->sc_relay_sid_len = 0;
|
||||
#ifdef PPPOE_SERVER
|
||||
if (sc->sc_hunique) {
|
||||
free(sc->sc_hunique, M_DEVBUF);
|
||||
@ -1251,6 +1291,8 @@ pppoe_send_padr(struct pppoe_softc *sc)
|
||||
}
|
||||
if (sc->sc_ac_cookie_len > 0)
|
||||
len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */
|
||||
if (sc->sc_relay_sid_len > 0)
|
||||
len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */
|
||||
m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
|
||||
if (!m0)
|
||||
return ENOBUFS;
|
||||
@ -1270,6 +1312,12 @@ pppoe_send_padr(struct pppoe_softc *sc)
|
||||
memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
|
||||
p += sc->sc_ac_cookie_len;
|
||||
}
|
||||
if (sc->sc_relay_sid_len > 0) {
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID);
|
||||
PPPOE_ADD_16(p, sc->sc_relay_sid_len);
|
||||
memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len);
|
||||
p += sc->sc_relay_sid_len;
|
||||
}
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
|
||||
PPPOE_ADD_16(p, sizeof(sc));
|
||||
memcpy(p, &sc, sizeof sc);
|
||||
@ -1508,6 +1556,10 @@ pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
|
||||
free(sc->sc_ac_cookie, M_DEVBUF);
|
||||
sc->sc_ac_cookie = NULL;
|
||||
}
|
||||
if (sc->sc_relay_sid) {
|
||||
free(sc->sc_relay_sid, M_DEVBUF);
|
||||
sc->sc_relay_sid = NULL;
|
||||
}
|
||||
sc->sc_ac_cookie_len = 0;
|
||||
sc->sc_session = 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user