Merge pull request #11238 from opensourcerouting/rtadv-cleanup

zebra: clean up rtadv integration
This commit is contained in:
Donald Sharp 2022-05-22 15:02:27 -04:00 committed by GitHub
commit 6e3b94d9d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 397 additions and 371 deletions

View File

@ -155,48 +155,8 @@ static int if_zebra_new_hook(struct interface *ifp)
zebra_ptm_if_init(zebra_if);
ifp->ptm_enable = zebra_ptm_get_enable_state();
#if defined(HAVE_RTADV)
{
/* Set default router advertise values. */
struct rtadvconf *rtadv;
rtadv = &zebra_if->rtadv;
rtadv->AdvSendAdvertisements = 0;
rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
rtadv->AdvIntervalTimer = 0;
rtadv->AdvManagedFlag = 0;
rtadv->AdvOtherConfigFlag = 0;
rtadv->AdvHomeAgentFlag = 0;
rtadv->AdvLinkMTU = 0;
rtadv->AdvReachableTime = 0;
rtadv->AdvRetransTimer = 0;
rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT;
memset(&rtadv->lastadvcurhoplimit, 0,
sizeof(rtadv->lastadvcurhoplimit));
memset(&rtadv->lastadvmanagedflag, 0,
sizeof(rtadv->lastadvmanagedflag));
memset(&rtadv->lastadvotherconfigflag, 0,
sizeof(rtadv->lastadvotherconfigflag));
memset(&rtadv->lastadvreachabletime, 0,
sizeof(rtadv->lastadvreachabletime));
memset(&rtadv->lastadvretranstimer, 0,
sizeof(rtadv->lastadvretranstimer));
rtadv->AdvDefaultLifetime =
-1; /* derive from MaxRtrAdvInterval */
rtadv->HomeAgentPreference = 0;
rtadv->HomeAgentLifetime =
-1; /* derive from AdvDefaultLifetime */
rtadv->AdvIntervalOption = 0;
rtadv->UseFastRexmit = true;
rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
rtadv->AdvPrefixList = list_new();
rtadv->AdvRDNSSList = list_new();
rtadv->AdvDNSSLList = list_new();
}
#endif /* HAVE_RTADV */
rtadv_if_init(zebra_if);
memset(&zebra_if->neigh_mac[0], 0, 6);
@ -271,15 +231,8 @@ static int if_zebra_delete_hook(struct interface *ifp)
/* Free installed address chains tree. */
if (zebra_if->ipv4_subnets)
route_table_finish(zebra_if->ipv4_subnets);
#if defined(HAVE_RTADV)
struct rtadvconf *rtadv;
rtadv = &zebra_if->rtadv;
list_delete(&rtadv->AdvPrefixList);
list_delete(&rtadv->AdvRDNSSList);
list_delete(&rtadv->AdvDNSSLList);
#endif /* HAVE_RTADV */
rtadv_if_fini(zebra_if);
zebra_evpn_if_cleanup(zebra_if);
zebra_evpn_mac_ifp_del(ifp);
@ -1078,15 +1031,7 @@ void if_up(struct interface *ifp, bool install_connected)
if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp);
#if defined(HAVE_RTADV)
/* Enable fast tx of RA if enabled && RA interval is not in msecs */
if (zif->rtadv.AdvSendAdvertisements
&& (zif->rtadv.MaxRtrAdvInterval >= 1000)
&& zif->rtadv.UseFastRexmit) {
zif->rtadv.inFastRexmit = 1;
zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
}
#endif
rtadv_if_up(zif);
/* Install connected routes to the kernel. */
if (install_connected)

View File

@ -30,6 +30,7 @@
#include "zebra/zebra_l2.h"
#include "zebra/zebra_nhg_private.h"
#include "zebra/zebra_router.h"
#include "zebra/rtadv.h"
#ifdef __cplusplus
extern "C" {
@ -46,218 +47,6 @@ extern "C" {
#define IF_VLAN_BITMAP_MAX 4096
#if defined(HAVE_RTADV)
/* Router advertisement parameter. From RFC4861, RFC6275 and RFC4191. */
struct rtadvconf {
/* A flag indicating whether or not the router sends periodic Router
Advertisements and responds to Router Solicitations.
Default: false */
int AdvSendAdvertisements;
/* The maximum time allowed between sending unsolicited multicast
Router Advertisements from the interface, in milliseconds.
MUST be no less than 70 ms [RFC6275 7.5] and no greater
than 1800000 ms [RFC4861 6.2.1].
Default: 600000 milliseconds */
int MaxRtrAdvInterval;
#define RTADV_MAX_RTR_ADV_INTERVAL 600000
/* The minimum time allowed between sending unsolicited multicast
Router Advertisements from the interface, in milliseconds.
MUST be no less than 30 ms [RFC6275 7.5].
MUST be no greater than .75 * MaxRtrAdvInterval.
Default: 0.33 * MaxRtrAdvInterval */
int MinRtrAdvInterval; /* This field is currently unused. */
#define RTADV_MIN_RTR_ADV_INTERVAL (0.33 * RTADV_MAX_RTR_ADV_INTERVAL)
/* Unsolicited Router Advertisements' interval timer. */
int AdvIntervalTimer;
/* The true/false value to be placed in the "Managed address
configuration" flag field in the Router Advertisement. See
[ADDRCONF].
Default: false */
int AdvManagedFlag;
struct timeval lastadvmanagedflag;
/* The true/false value to be placed in the "Other stateful
configuration" flag field in the Router Advertisement. See
[ADDRCONF].
Default: false */
int AdvOtherConfigFlag;
struct timeval lastadvotherconfigflag;
/* The value to be placed in MTU options sent by the router. A
value of zero indicates that no MTU options are sent.
Default: 0 */
int AdvLinkMTU;
/* The value to be placed in the Reachable Time field in the Router
Advertisement messages sent by the router. The value zero means
unspecified (by this router). MUST be no greater than 3,600,000
milliseconds (1 hour).
Default: 0 */
uint32_t AdvReachableTime;
#define RTADV_MAX_REACHABLE_TIME 3600000
struct timeval lastadvreachabletime;
/* The value to be placed in the Retrans Timer field in the Router
Advertisement messages sent by the router. The value zero means
unspecified (by this router).
Default: 0 */
int AdvRetransTimer;
struct timeval lastadvretranstimer;
/* The default value to be placed in the Cur Hop Limit field in the
Router Advertisement messages sent by the router. The value
should be set to that current diameter of the Internet. The
value zero means unspecified (by this router).
Default: The value specified in the "Assigned Numbers" RFC
[ASSIGNED] that was in effect at the time of implementation. */
int AdvCurHopLimit;
struct timeval lastadvcurhoplimit;
#define RTADV_DEFAULT_HOPLIMIT 64 /* 64 hops */
/* The value to be placed in the Router Lifetime field of Router
Advertisements sent from the interface, in seconds. MUST be
either zero or between MaxRtrAdvInterval and 9000 seconds. A
value of zero indicates that the router is not to be used as a
default router.
Default: 3 * MaxRtrAdvInterval */
int AdvDefaultLifetime;
#define RTADV_MAX_RTRLIFETIME 9000 /* 2.5 hours */
/* A list of prefixes to be placed in Prefix Information options in
Router Advertisement messages sent from the interface.
Default: all prefixes that the router advertises via routing
protocols as being on-link for the interface from which the
advertisement is sent. The link-local prefix SHOULD NOT be
included in the list of advertised prefixes. */
struct list *AdvPrefixList;
/* The true/false value to be placed in the "Home agent"
flag field in the Router Advertisement. See [RFC6275 7.1].
Default: false */
int AdvHomeAgentFlag;
#ifndef ND_RA_FLAG_HOME_AGENT
#define ND_RA_FLAG_HOME_AGENT 0x20
#endif
/* The value to be placed in Home Agent Information option if Home
Flag is set.
Default: 0 */
int HomeAgentPreference;
/* The value to be placed in Home Agent Information option if Home
Flag is set. Lifetime (seconds) MUST not be greater than 18.2
hours.
The value 0 has special meaning: use of AdvDefaultLifetime value.
Default: 0 */
int HomeAgentLifetime;
#define RTADV_MAX_HALIFETIME 65520 /* 18.2 hours */
/* The true/false value to insert or not an Advertisement Interval
option. See [RFC 6275 7.3]
Default: false */
int AdvIntervalOption;
/* The value to be placed in the Default Router Preference field of
a router advertisement. See [RFC 4191 2.1 & 2.2]
Default: 0 (medium) */
int DefaultPreference;
#define RTADV_PREF_MEDIUM 0x0 /* Per RFC4191. */
/*
* List of recursive DNS servers to include in the RDNSS option.
* See [RFC8106 5.1]
*
* Default: empty list; do not emit RDNSS option
*/
struct list *AdvRDNSSList;
/*
* List of DNS search domains to include in the DNSSL option.
* See [RFC8106 5.2]
*
* Default: empty list; do not emit DNSSL option
*/
struct list *AdvDNSSLList;
/*
* rfc4861 states RAs must be sent at least 3 seconds apart.
* We allow faster retransmits to speed up convergence but can
* turn that capability off to meet the rfc if needed.
*/
bool UseFastRexmit; /* True if fast rexmits are enabled */
uint8_t inFastRexmit; /* True if we're rexmits faster than usual */
/* Track if RA was configured by BGP or by the Operator or both */
uint8_t ra_configured; /* Was RA configured? */
#define BGP_RA_CONFIGURED (1<<0) /* BGP configured RA? */
#define VTY_RA_CONFIGURED (1<<1) /* Operator configured RA? */
#define VTY_RA_INTERVAL_CONFIGURED (1<<2) /* Operator configured RA interval */
int NumFastReXmitsRemain; /* Loaded first with number of fast
rexmits to do */
#define RTADV_FAST_REXMIT_PERIOD 1 /* 1 sec */
#define RTADV_NUM_FAST_REXMITS 4 /* Fast Rexmit RA 4 times on certain events */
};
struct rtadv_rdnss {
/* Address of recursive DNS server to advertise */
struct in6_addr addr;
/*
* Lifetime in seconds; all-ones means infinity, zero
* stop using it.
*/
uint32_t lifetime;
/* If lifetime not set, use a default of 3*MaxRtrAdvInterval */
int lifetime_set;
};
/*
* [RFC1035 2.3.4] sets the maximum length of a domain name (a sequence of
* labels, each prefixed by a length octet) at 255 octets.
*/
#define RTADV_MAX_ENCODED_DOMAIN_NAME 255
struct rtadv_dnssl {
/* Domain name without trailing root zone dot (NUL-terminated) */
char name[RTADV_MAX_ENCODED_DOMAIN_NAME - 1];
/* Name encoded as in [RFC1035 3.1] */
uint8_t encoded_name[RTADV_MAX_ENCODED_DOMAIN_NAME];
/* Actual length of encoded_name */
size_t encoded_len;
/* Lifetime as for RDNSS */
uint32_t lifetime;
int lifetime_set;
};
#endif /* HAVE_RTADV */
/* Zebra interface type - ones of interest. */
enum zebra_iftype {
ZEBRA_IF_OTHER = 0, /* Anything else */
@ -361,10 +150,8 @@ struct zebra_if {
unsigned int down_count;
char down_last[FRR_TIMESTAMP_LEN];
#if defined(HAVE_RTADV)
struct rtadvconf rtadv;
unsigned int ra_sent, ra_rcvd;
#endif /* HAVE_RTADV */
struct irdp_interface *irdp;

View File

@ -408,9 +408,7 @@ int main(int argc, char **argv)
zebra_vty_init();
access_list_init();
prefix_list_init();
#if defined(HAVE_RTADV)
rtadv_cmd_init();
#endif
/* PTM socket */
#ifdef ZEBRA_PTM_SUPPORT
zebra_ptm_init();

View File

@ -288,33 +288,6 @@ DECLARE_LIST(re_list, struct route_entry, next);
#define RNODE_NEXT_RE(rn, re) RE_DEST_NEXT_ROUTE(rib_dest_from_rnode(rn), re)
#if defined(HAVE_RTADV)
PREDECL_SORTLIST_UNIQ(adv_if_list);
/* Structure which hold status of router advertisement. */
struct rtadv {
int sock;
struct adv_if_list_head adv_if;
struct adv_if_list_head adv_msec_if;
struct thread *ra_read;
struct thread *ra_timer;
};
/* adv list node */
struct adv_if {
char name[INTERFACE_NAMSIZ];
struct adv_if_list_item list_item;
};
static int adv_if_cmp(const struct adv_if *a, const struct adv_if *b)
{
return if_cmp_name_func(a->name, b->name);
}
DECLARE_SORTLIST_UNIQ(adv_if_list, struct adv_if, list_item, adv_if_cmp);
#endif /* HAVE_RTADV */
/*
* rib_table_info_t
*

View File

@ -73,6 +73,28 @@ DEFINE_MTYPE_STATIC(ZEBRA, ADV_IF, "Advertised Interface");
#define ALLNODE "ff02::1"
#define ALLROUTER "ff02::2"
/* adv list node */
struct adv_if {
char name[INTERFACE_NAMSIZ];
struct adv_if_list_item list_item;
};
static int adv_if_cmp(const struct adv_if *a, const struct adv_if *b)
{
return if_cmp_name_func(a->name, b->name);
}
DECLARE_SORTLIST_UNIQ(adv_if_list, struct adv_if, list_item, adv_if_cmp);
static int rtadv_prefix_cmp(const struct rtadv_prefix *a,
const struct rtadv_prefix *b)
{
return prefix_cmp(&a->prefix, &b->prefix);
}
DECLARE_RBTREE_UNIQ(rtadv_prefixes, struct rtadv_prefix, item,
rtadv_prefix_cmp);
DEFINE_MTYPE_STATIC(ZEBRA, RTADV_RDNSS, "Router Advertisement RDNSS");
DEFINE_MTYPE_STATIC(ZEBRA, RTADV_DNSSL, "Router Advertisement DNSSL");
@ -315,7 +337,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp,
}
/* Fill in prefix. */
for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) {
frr_each (rtadv_prefixes, zif->rtadv.prefixes, rprefix) {
struct nd_opt_prefix_info *pinfo;
pinfo = (struct nd_opt_prefix_info *)(buf + len);
@ -1065,31 +1087,20 @@ static void rtadv_prefix_free(struct rtadv_prefix *rtadv_prefix)
XFREE(MTYPE_RTADV_PREFIX, rtadv_prefix);
}
static struct rtadv_prefix *rtadv_prefix_lookup(struct list *rplist,
static struct rtadv_prefix *rtadv_prefix_get(struct rtadv_prefixes_head *list,
struct prefix_ipv6 *p)
{
struct listnode *node;
struct rtadv_prefix *rprefix;
struct rtadv_prefix *rprefix, ref;
for (ALL_LIST_ELEMENTS_RO(rplist, node, rprefix))
if (prefix_same((struct prefix *)&rprefix->prefix,
(struct prefix *)p))
return rprefix;
return NULL;
}
ref.prefix = *p;
static struct rtadv_prefix *rtadv_prefix_get(struct list *rplist,
struct prefix_ipv6 *p)
{
struct rtadv_prefix *rprefix;
rprefix = rtadv_prefix_lookup(rplist, p);
rprefix = rtadv_prefixes_find(list, &ref);
if (rprefix)
return rprefix;
rprefix = rtadv_prefix_new();
memcpy(&rprefix->prefix, p, sizeof(struct prefix_ipv6));
listnode_add(rplist, rprefix);
rtadv_prefixes_add(list, rprefix);
return rprefix;
}
@ -1107,7 +1118,7 @@ static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp)
{
struct rtadv_prefix *rprefix;
rprefix = rtadv_prefix_get(zif->rtadv.AdvPrefixList, &rp->prefix);
rprefix = rtadv_prefix_get(zif->rtadv.prefixes, &rp->prefix);
/*
* Set parameters based on where the prefix is created.
@ -1142,7 +1153,7 @@ static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp)
{
struct rtadv_prefix *rprefix;
rprefix = rtadv_prefix_lookup(zif->rtadv.AdvPrefixList, &rp->prefix);
rprefix = rtadv_prefixes_find(zif->rtadv.prefixes, rp);
if (rprefix != NULL) {
/*
@ -1165,7 +1176,7 @@ static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp)
}
}
listnode_delete(zif->rtadv.AdvPrefixList, (void *)rprefix);
rtadv_prefixes_del(zif->rtadv.prefixes, rprefix);
rtadv_prefix_free(rprefix);
return 1;
} else
@ -1358,7 +1369,6 @@ void rtadv_stop_ra_all(void)
{
struct vrf *vrf;
struct interface *ifp;
struct listnode *node, *nnode;
struct zebra_if *zif;
struct rtadv_prefix *rprefix;
@ -1366,8 +1376,8 @@ void rtadv_stop_ra_all(void)
FOR_ALL_INTERFACES (vrf, ifp) {
zif = ifp->info;
for (ALL_LIST_ELEMENTS(zif->rtadv.AdvPrefixList,
node, nnode, rprefix))
frr_each_safe (rtadv_prefixes, zif->rtadv.prefixes,
rprefix)
rtadv_prefix_reset(zif, rprefix);
rtadv_stop_ra(ifp);
@ -2671,7 +2681,7 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp)
if (zif->rtadv.AdvLinkMTU)
vty_out(vty, " ipv6 nd mtu %d\n", zif->rtadv.AdvLinkMTU);
for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) {
frr_each (rtadv_prefixes, zif->rtadv.prefixes, rprefix) {
if ((rprefix->AdvPrefixCreate == PREFIX_SRC_MANUAL)
|| (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH)) {
vty_out(vty, " ipv6 nd prefix %pFX", &rprefix->prefix);
@ -2768,6 +2778,72 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
return;
}
void rtadv_if_up(struct zebra_if *zif)
{
/* Enable fast tx of RA if enabled && RA interval is not in msecs */
if (zif->rtadv.AdvSendAdvertisements &&
(zif->rtadv.MaxRtrAdvInterval >= 1000) &&
zif->rtadv.UseFastRexmit) {
zif->rtadv.inFastRexmit = 1;
zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
}
}
void rtadv_if_init(struct zebra_if *zif)
{
/* Set default router advertise values. */
struct rtadvconf *rtadv;
rtadv = &zif->rtadv;
rtadv->AdvSendAdvertisements = 0;
rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
rtadv->AdvIntervalTimer = 0;
rtadv->AdvManagedFlag = 0;
rtadv->AdvOtherConfigFlag = 0;
rtadv->AdvHomeAgentFlag = 0;
rtadv->AdvLinkMTU = 0;
rtadv->AdvReachableTime = 0;
rtadv->AdvRetransTimer = 0;
rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT;
memset(&rtadv->lastadvcurhoplimit, 0,
sizeof(rtadv->lastadvcurhoplimit));
memset(&rtadv->lastadvmanagedflag, 0,
sizeof(rtadv->lastadvmanagedflag));
memset(&rtadv->lastadvotherconfigflag, 0,
sizeof(rtadv->lastadvotherconfigflag));
memset(&rtadv->lastadvreachabletime, 0,
sizeof(rtadv->lastadvreachabletime));
memset(&rtadv->lastadvretranstimer, 0,
sizeof(rtadv->lastadvretranstimer));
rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
rtadv->HomeAgentPreference = 0;
rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
rtadv->AdvIntervalOption = 0;
rtadv->UseFastRexmit = true;
rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
rtadv_prefixes_init(rtadv->prefixes);
rtadv->AdvRDNSSList = list_new();
rtadv->AdvDNSSLList = list_new();
}
void rtadv_if_fini(struct zebra_if *zif)
{
struct rtadvconf *rtadv;
struct rtadv_prefix *rp;
rtadv = &zif->rtadv;
while ((rp = rtadv_prefixes_pop(rtadv->prefixes)))
rtadv_prefix_free(rp);
list_delete(&rtadv->AdvRDNSSList);
list_delete(&rtadv->AdvDNSSLList);
}
void rtadv_vrf_init(struct zebra_vrf *zvrf)
{
if (!vrf_is_backend_netns() && (zvrf_id(zvrf) != VRF_DEFAULT))
@ -2899,37 +2975,7 @@ bool rtadv_compiled_in(void)
return true;
}
#else
void rtadv_vrf_init(struct zebra_vrf *zvrf)
{
/* Empty.*/;
}
void rtadv_cmd_init(void)
{
/* Empty.*/;
}
void rtadv_add_prefix(struct zebra_if *zif, const struct prefix_ipv6 *p)
{
/* Empty.*/;
}
void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p)
{
/* Empty.*/;
}
void rtadv_stop_ra(struct interface *ifp)
{
/* Empty.*/;
}
void rtadv_stop_ra_all(void)
{
/* Empty.*/;
}
#else /* !HAVE_RTADV */
/*
* If the end user does not have RADV enabled we should
* handle this better

View File

@ -24,17 +24,248 @@
#include "zebra.h"
#include "vty.h"
#include "zebra/interface.h"
#include "typesafe.h"
#include "zebra/zserv.h"
#ifdef __cplusplus
extern "C" {
#endif
/* NB: RTADV is defined in zebra/interface.h above */
struct interface;
struct zebra_if;
#if defined(HAVE_RTADV)
PREDECL_SORTLIST_UNIQ(adv_if_list);
/* Structure which hold status of router advertisement. */
struct rtadv {
int sock;
struct adv_if_list_head adv_if;
struct adv_if_list_head adv_msec_if;
struct thread *ra_read;
struct thread *ra_timer;
};
PREDECL_RBTREE_UNIQ(rtadv_prefixes);
/* Router advertisement parameter. From RFC4861, RFC6275 and RFC4191. */
struct rtadvconf {
/* A flag indicating whether or not the router sends periodic Router
Advertisements and responds to Router Solicitations.
Default: false */
int AdvSendAdvertisements;
/* The maximum time allowed between sending unsolicited multicast
Router Advertisements from the interface, in milliseconds.
MUST be no less than 70 ms [RFC6275 7.5] and no greater
than 1800000 ms [RFC4861 6.2.1].
Default: 600000 milliseconds */
int MaxRtrAdvInterval;
#define RTADV_MAX_RTR_ADV_INTERVAL 600000
/* The minimum time allowed between sending unsolicited multicast
Router Advertisements from the interface, in milliseconds.
MUST be no less than 30 ms [RFC6275 7.5].
MUST be no greater than .75 * MaxRtrAdvInterval.
Default: 0.33 * MaxRtrAdvInterval */
int MinRtrAdvInterval; /* This field is currently unused. */
#define RTADV_MIN_RTR_ADV_INTERVAL (0.33 * RTADV_MAX_RTR_ADV_INTERVAL)
/* Unsolicited Router Advertisements' interval timer. */
int AdvIntervalTimer;
/* The true/false value to be placed in the "Managed address
configuration" flag field in the Router Advertisement. See
[ADDRCONF].
Default: false */
int AdvManagedFlag;
struct timeval lastadvmanagedflag;
/* The true/false value to be placed in the "Other stateful
configuration" flag field in the Router Advertisement. See
[ADDRCONF].
Default: false */
int AdvOtherConfigFlag;
struct timeval lastadvotherconfigflag;
/* The value to be placed in MTU options sent by the router. A
value of zero indicates that no MTU options are sent.
Default: 0 */
int AdvLinkMTU;
/* The value to be placed in the Reachable Time field in the Router
Advertisement messages sent by the router. The value zero means
unspecified (by this router). MUST be no greater than 3,600,000
milliseconds (1 hour).
Default: 0 */
uint32_t AdvReachableTime;
#define RTADV_MAX_REACHABLE_TIME 3600000
struct timeval lastadvreachabletime;
/* The value to be placed in the Retrans Timer field in the Router
Advertisement messages sent by the router. The value zero means
unspecified (by this router).
Default: 0 */
int AdvRetransTimer;
struct timeval lastadvretranstimer;
/* The default value to be placed in the Cur Hop Limit field in the
Router Advertisement messages sent by the router. The value
should be set to that current diameter of the Internet. The
value zero means unspecified (by this router).
Default: The value specified in the "Assigned Numbers" RFC
[ASSIGNED] that was in effect at the time of implementation. */
int AdvCurHopLimit;
struct timeval lastadvcurhoplimit;
#define RTADV_DEFAULT_HOPLIMIT 64 /* 64 hops */
/* The value to be placed in the Router Lifetime field of Router
Advertisements sent from the interface, in seconds. MUST be
either zero or between MaxRtrAdvInterval and 9000 seconds. A
value of zero indicates that the router is not to be used as a
default router.
Default: 3 * MaxRtrAdvInterval */
int AdvDefaultLifetime;
#define RTADV_MAX_RTRLIFETIME 9000 /* 2.5 hours */
/* A list of prefixes to be placed in Prefix Information options in
Router Advertisement messages sent from the interface.
Default: all prefixes that the router advertises via routing
protocols as being on-link for the interface from which the
advertisement is sent. The link-local prefix SHOULD NOT be
included in the list of advertised prefixes. */
struct rtadv_prefixes_head prefixes[1];
/* The true/false value to be placed in the "Home agent"
flag field in the Router Advertisement. See [RFC6275 7.1].
Default: false */
int AdvHomeAgentFlag;
#ifndef ND_RA_FLAG_HOME_AGENT
#define ND_RA_FLAG_HOME_AGENT 0x20
#endif
/* The value to be placed in Home Agent Information option if Home
Flag is set.
Default: 0 */
int HomeAgentPreference;
/* The value to be placed in Home Agent Information option if Home
Flag is set. Lifetime (seconds) MUST not be greater than 18.2
hours.
The value 0 has special meaning: use of AdvDefaultLifetime value.
Default: 0 */
int HomeAgentLifetime;
#define RTADV_MAX_HALIFETIME 65520 /* 18.2 hours */
/* The true/false value to insert or not an Advertisement Interval
option. See [RFC 6275 7.3]
Default: false */
int AdvIntervalOption;
/* The value to be placed in the Default Router Preference field of
a router advertisement. See [RFC 4191 2.1 & 2.2]
Default: 0 (medium) */
int DefaultPreference;
#define RTADV_PREF_MEDIUM 0x0 /* Per RFC4191. */
/*
* List of recursive DNS servers to include in the RDNSS option.
* See [RFC8106 5.1]
*
* Default: empty list; do not emit RDNSS option
*/
struct list *AdvRDNSSList;
/*
* List of DNS search domains to include in the DNSSL option.
* See [RFC8106 5.2]
*
* Default: empty list; do not emit DNSSL option
*/
struct list *AdvDNSSLList;
/*
* rfc4861 states RAs must be sent at least 3 seconds apart.
* We allow faster retransmits to speed up convergence but can
* turn that capability off to meet the rfc if needed.
*/
bool UseFastRexmit; /* True if fast rexmits are enabled */
uint8_t inFastRexmit; /* True if we're rexmits faster than usual */
/* Track if RA was configured by BGP or by the Operator or both */
uint8_t ra_configured; /* Was RA configured? */
#define BGP_RA_CONFIGURED (1 << 0) /* BGP configured RA? */
#define VTY_RA_CONFIGURED (1 << 1) /* Operator configured RA? */
#define VTY_RA_INTERVAL_CONFIGURED \
(1 << 2) /* Operator configured RA interval */
int NumFastReXmitsRemain; /* Loaded first with number of fast
rexmits to do */
#define RTADV_FAST_REXMIT_PERIOD 1 /* 1 sec */
#define RTADV_NUM_FAST_REXMITS 4 /* Fast Rexmit RA 4 times on certain events \
*/
};
struct rtadv_rdnss {
/* Address of recursive DNS server to advertise */
struct in6_addr addr;
/*
* Lifetime in seconds; all-ones means infinity, zero
* stop using it.
*/
uint32_t lifetime;
/* If lifetime not set, use a default of 3*MaxRtrAdvInterval */
int lifetime_set;
};
/*
* [RFC1035 2.3.4] sets the maximum length of a domain name (a sequence of
* labels, each prefixed by a length octet) at 255 octets.
*/
#define RTADV_MAX_ENCODED_DOMAIN_NAME 255
struct rtadv_dnssl {
/* Domain name without trailing root zone dot (NUL-terminated) */
char name[RTADV_MAX_ENCODED_DOMAIN_NAME - 1];
/* Name encoded as in [RFC1035 3.1] */
uint8_t encoded_name[RTADV_MAX_ENCODED_DOMAIN_NAME];
/* Actual length of encoded_name */
size_t encoded_len;
/* Lifetime as for RDNSS */
uint32_t lifetime;
int lifetime_set;
};
/* Router advertisement prefix. */
struct rtadv_prefix {
struct rtadv_prefixes_item item;
/* Prefix to be advertised. */
struct prefix_ipv6 prefix;
@ -135,8 +366,6 @@ struct nd_opt_dnssl { /* DNS search list option [RFC8106 5.2] */
} __attribute__((__packed__));
#endif
#endif /* HAVE_RTADV */
/*
* ipv6 nd prefixes can be manually defined, derived from the kernel interface
* configs or both. If both, manual flag/timer settings are used.
@ -158,10 +387,60 @@ extern void rtadv_vrf_terminate(struct zebra_vrf *zvrf);
extern void rtadv_stop_ra(struct interface *ifp);
extern void rtadv_stop_ra_all(void);
extern void rtadv_cmd_init(void);
extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS);
extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
extern void rtadv_if_init(struct zebra_if *zif);
extern void rtadv_if_up(struct zebra_if *zif);
extern void rtadv_if_fini(struct zebra_if *zif);
extern void rtadv_add_prefix(struct zebra_if *zif, const struct prefix_ipv6 *p);
extern void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p);
#else /* !HAVE_RTADV */
struct rtadv {
/* empty structs aren't valid ISO C */
char dummy;
};
struct rtadvconf {
/* same again, empty structs aren't valid ISO C */
char dummy;
};
static inline void rtadv_vrf_init(struct zebra_vrf *zvrf)
{
}
static inline void rtadv_vrf_terminate(struct zebra_vrf *zvrf)
{
}
static inline void rtadv_cmd_init(void)
{
}
static inline void rtadv_if_init(struct zebra_if *zif)
{
}
static inline void rtadv_if_up(struct zebra_if *zif)
{
}
static inline void rtadv_if_fini(struct zebra_if *zif)
{
}
static inline void rtadv_add_prefix(struct zebra_if *zif,
const struct prefix_ipv6 *p)
{
}
static inline void rtadv_delete_prefix(struct zebra_if *zif,
const struct prefix *p)
{
}
static inline void rtadv_stop_ra(struct interface *ifp)
{
}
static inline void rtadv_stop_ra_all(void)
{
}
#endif
extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS);
extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
extern uint32_t rtadv_get_interfaces_configured_from_bgp(void);
extern bool rtadv_compiled_in(void);

View File

@ -28,6 +28,7 @@
#include "if.h"
#include "vlan.h"
#include "vxlan.h"
#include "zebra/zebra_vrf.h"
#ifdef __cplusplus
extern "C" {

View File

@ -25,6 +25,7 @@
#include "zebra/debug.h"
#include "zebra/zserv.h"
#include "zebra/zebra_opaque.h"
#include "zebra/rib.h"
/* Mem type */
DEFINE_MTYPE_STATIC(ZEBRA, OPQ, "ZAPI Opaque Information");

View File

@ -141,9 +141,8 @@ static int zebra_vrf_enable(struct vrf *vrf)
zvrf->zns = zebra_ns_lookup((ns_id_t)vrf->vrf_id);
else
zvrf->zns = zebra_ns_lookup(NS_DEFAULT);
#if defined(HAVE_RTADV)
rtadv_vrf_init(zvrf);
#endif
/* Inform clients that the VRF is now active. This is an
* add for the clients.
@ -186,9 +185,7 @@ static int zebra_vrf_disable(struct vrf *vrf)
/* Stop any VxLAN-EVPN processing. */
zebra_vxlan_vrf_disable(zvrf);
#if defined(HAVE_RTADV)
rtadv_vrf_terminate(zvrf);
#endif
/* Inform clients that the VRF is now inactive. This is a
* delete for the clients.

View File

@ -26,6 +26,7 @@
#include <zebra/zebra_ns.h>
#include <zebra/zebra_pw.h>
#include <zebra/rtadv.h>
#include <lib/vxlan.h>
#ifdef __cplusplus
@ -177,9 +178,7 @@ struct zebra_vrf {
struct table_manager *tbl_mgr;
#if defined(HAVE_RTADV)
struct rtadv rtadv;
#endif /* HAVE_RTADV */
bool zebra_rnh_ip_default_route;
bool zebra_rnh_ipv6_default_route;

View File

@ -36,14 +36,14 @@
#include "lib/linklist.h" /* for list */
#include "lib/workqueue.h" /* for work_queue */
#include "lib/hook.h" /* for DECLARE_HOOK, DECLARE_KOOH */
#include "zebra/zebra_vrf.h" /* for zebra_vrf */
/* clang-format on */
#ifdef __cplusplus
extern "C" {
#endif
struct zebra_vrf;
/* Default port information. */
#define ZEBRA_VTY_PORT 2601