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:
Samuel Thibault 2024-02-06 20:06:58 +01:00
parent 3add0afa38
commit 3ab80a9d66
2 changed files with 27 additions and 18 deletions

42
ppp.c
View file

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