IPV6CP: suggest an interface identifier option
Some peers seem to be sending no such option. The rfc says in that case to try to send an option with a suggested value. Don't insist on it however if the peer still doesn't send any. That can fix IPv6 for some peers.
This commit is contained in:
parent
3add0afa38
commit
3ab80a9d66
2 changed files with 27 additions and 18 deletions
3
l2tpns.h
3
l2tpns.h
|
|
@ -441,6 +441,9 @@ typedef struct
|
|||
// last LCP Echo
|
||||
time_t last_echo;
|
||||
|
||||
// Whether we tried to suggest the IPV6CP identifier option.
|
||||
int tried_identifier;
|
||||
|
||||
// last unsolicited RA sent to user
|
||||
time_t last_ra;
|
||||
|
||||
|
|
|
|||
42
ppp.c
42
ppp.c
|
|
@ -1560,6 +1560,17 @@ void processipv6cp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
|||
int gotip = 0;
|
||||
uint32_t ident[2];
|
||||
|
||||
if (session[s].ipv6address.s6_addr[0])
|
||||
{
|
||||
// LSB 64bits of assigned IPv6 address to user (see radius attribut Framed-IPv6-Address)
|
||||
memcpy(&ident[0], &session[s].ipv6address.s6_addr[8], 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
ident[0] = htonl(session[s].ip);
|
||||
ident[1] = 0;
|
||||
}
|
||||
|
||||
while (length > 2)
|
||||
{
|
||||
if (!o[1] || o[1] > length) return;
|
||||
|
|
@ -1570,17 +1581,6 @@ void processipv6cp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
|||
gotip++; // seen address
|
||||
if (o[1] != 10) return;
|
||||
|
||||
if (session[s].ipv6address.s6_addr[0])
|
||||
{
|
||||
// LSB 64bits of assigned IPv6 address to user (see radius attribut Framed-IPv6-Address)
|
||||
memcpy(&ident[0], &session[s].ipv6address.s6_addr[8], 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
ident[0] = htonl(session[s].ip);
|
||||
ident[1] = 0;
|
||||
}
|
||||
|
||||
if (memcmp(o + 2, ident, sizeof(ident)))
|
||||
{
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPIPV6CP, &response, q, p, o, (uint8_t *)ident, sizeof(ident));
|
||||
|
|
@ -1599,24 +1599,30 @@ void processipv6cp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
|||
o += o[1];
|
||||
}
|
||||
|
||||
if (!response && !gotip && sess_local[s].tried_identifier++ < 2)
|
||||
{
|
||||
uint8_t identifier_option[6] = { 1, 6 };
|
||||
|
||||
// No interface identifier option, try to suggest one
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPIPV6CP, &response, q, p, identifier_option, (uint8_t *)ident, sizeof(ident));
|
||||
if (!q) return;
|
||||
}
|
||||
|
||||
if (response)
|
||||
{
|
||||
l = q - response; // IPV6CP packet length
|
||||
*((uint16_t *) (response + 2)) = htons(l); // update header
|
||||
}
|
||||
else if (gotip)
|
||||
else
|
||||
{
|
||||
if (!gotip)
|
||||
LOG(2, s, t, "No interface identifier in IPV6CP request, hoping for the best\n");
|
||||
|
||||
// Send packet back as ConfigAck
|
||||
response = makeppp(b, sizeof(b), p, l, s, t, PPPIPV6CP, 0, 0, 0);
|
||||
if (!response) return;
|
||||
*response = ConfigAck;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(3, s, t, "No interface identifier in IPV6CP request\n");
|
||||
STAT(tunnel_rx_errors);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (session[s].ppp.ipv6cp)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue