From 05772e2295fbd1dafc589db4b7c14e723504bcd5 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 3 Dec 2023 22:32:07 +0100 Subject: [PATCH] Add periodic RA sends The RFC indeed say that we should send them periodically. We were previously only sending them along LCP echo replies, but echo requests are typically sent only when there is no trafic, which RA need to be sent even when there is trafic. --- icmp.c | 2 +- l2tpns.c | 8 ++++++++ l2tpns.h | 5 +++++ ppp.c | 6 ++---- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/icmp.c b/icmp.c index be5d8ea..b804f2a 100644 --- a/icmp.c +++ b/icmp.c @@ -141,7 +141,7 @@ void send_ipv6_ra(sessionidt s, tunnelidt t, struct in6_addr *ip) p_nra->nd_ra_cksum = 0; // Checksum p_nra->nd_ra_curhoplimit = 64; // Hop count p_nra->nd_ra_flags_reserved = (ND_RA_FLAG_MANAGED|ND_RA_FLAG_OTHER); // Flags - p_nra->nd_ra_router_lifetime = 0xFFFF; // Lifetime + p_nra->nd_ra_router_lifetime = AdvDefaultLifetime; // Lifetime p_nra->nd_ra_reachable = 0; // Reachable time p_nra->nd_ra_retransmit = 0; // Retrans timer // Option PI after RA message (rfc4861) diff --git a/l2tpns.c b/l2tpns.c index 03da55f..591fef9 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -3833,6 +3833,14 @@ static void regular_cleanups(double period) s_actions++; } + // Send periodic RA + if (session[s].ppp.phase == Network && session[s].ppp.ipv6cp == Opened && + (time_now - sess_local[s].last_ra >= RtrAdvInterval)) + { + send_ipv6_ra(s, t, NULL); + sess_local[s].last_ra = time_now; + } + // Drop sessions who have reached session_timeout seconds if (session[s].session_timeout) { diff --git a/l2tpns.h b/l2tpns.h index 8c9fc0b..53ace04 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -56,6 +56,8 @@ #define ECHO_TIMEOUT 10 // Time between last packet sent and LCP ECHO generation #define IDLE_ECHO_TIMEOUT 240 // Time between last packet seen and session shutdown #define BUSY_WAIT_TIME 3000 // 5 minutes in 1/10th seconds to wait for radius to cleanup on shutdown +#define AdvDefaultLifetime 9000 +#define RtrAdvInterval 1800 #define MP_BEGIN 0x80 // This value is used when (b)egin bit is set in MP header #define MP_END 0x40 // This value is used when (e)nd bit is set in MP header @@ -434,6 +436,9 @@ typedef struct // last LCP Echo time_t last_echo; + // last unsolicited RA sent to user + time_t last_ra; + // Last Multilink frame sequence number received uint32_t last_seq; diff --git a/ppp.c b/ppp.c index aae7f86..08c2ef0 100644 --- a/ppp.c +++ b/ppp.c @@ -1103,9 +1103,6 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) if (config->debug > 3) dumplcp(q, l); tunnelsend(b, l + (q - b), t); // send it - - if (session[s].ppp.phase == Network && session[s].ppp.ipv6cp == Opened) - send_ipv6_ra(s, t, NULL); // send a RA } else if (*p == EchoReply) { @@ -1498,8 +1495,9 @@ static void ipv6cp_open(sessionidt s, tunnelidt t) route6set(s, session[s].ipv6address, 128, 1); } - // Send an initial RA (TODO: Should we send these regularly?) + // Send an initial RA send_ipv6_ra(s, t, NULL); + sess_local[s].last_ra = time_now; } // Process IPV6CP messages