ip6-nd: set router flag on NA if appropriate

Type: fix

The router flag on a neighbor advertisement can be used by neighbors to
detect that a router has changed to a host (RFC 4861 section 4.4).

If a neighbor adds routes after receiving a router advertisement sent
by VPP and subsequently receives a neighbor advertisement sent by VPP,
it may remove any routes it added based on the RA if the NA does not
have the router flag set. It appears that this is how windows behaves.

When sending a neighbor advertisement, set the router flag if sending
RAs is enabled on the interface.

Signed-off-by: Matthew Smith <mgsmith@netgate.com>
Change-Id: I1f3e42bbd8ea1a4c116b1ce5a8273652d4cd763d
This commit is contained in:
Matthew Smith
2022-11-05 18:33:08 +00:00
committed by Dave Barach
parent f094ce7653
commit ce1ff6a9b1
3 changed files with 19 additions and 1 deletions

View File

@ -23,6 +23,7 @@
#include <vnet/ip/icmp46_packet.h>
#include <vnet/ip/ip6.h>
#include <vnet/ip-neighbor/ip_neighbor_types.h>
#include <vnet/ip6-nd/ip6_ra.h>
typedef enum
{
@ -71,6 +72,13 @@ icmp6_send_neighbor_advertisement (
clib_host_to_net_u32 (ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED |
ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE);
/* if sending RAs is enabled, the "router" flag should be set,
* otherwise, neighbors may believe we have changed from a router
* to a host - RFC 4861 section 4.4 */
if (ip6_ra_adv_enabled (sw_if_index0))
icmp6_nsa->advertisement_flags |=
clib_host_to_net_u32 (ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER);
icmp6_nsa->icmp.checksum = 0;
icmp6_nsa->icmp.checksum =
ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6_h, &bogus_length);

View File

@ -204,6 +204,16 @@ ip6_ra_get_itf (u32 sw_if_index)
return (NULL);
}
u8
ip6_ra_adv_enabled (u32 sw_if_index)
{
ip6_ra_t *ra;
ra = ip6_ra_get_itf (sw_if_index);
return ((ra != NULL) && (ra->send_radv != 0));
}
/* for "syslogging" - use elog for now */
#define foreach_log_level \
_ (DEBUG, "DEBUG") \

View File

@ -82,7 +82,7 @@ extern void ip6_ra_update_secondary_radv_info (ip6_address_t * address,
u32 primary_sw_if_index,
u32 valid_time,
u32 preferred_time);
extern u8 ip6_ra_adv_enabled (u32 sw_if_index);
#endif /* included_ip6_neighbor_h */
/*