Skip to content

Commit 1d07dba

Browse files
committed
zebra: add ipv6 nd disable-ra command
Introduce a command to completely disable sending IPv6 router advertisement messages on an interface. Before, there were cases where it could be enabled by other daemons, namely bgpd and vrrpd. Particularly, it happens when BGP extended-nexthop capability is used: bgpd tells zebra to enable RA in this case, though it wasn't intended. Signed-off-by: Mikhail Sokolovskiy <[email protected]>
1 parent d7d4915 commit 1d07dba

File tree

8 files changed

+108
-5
lines changed

8 files changed

+108
-5
lines changed

doc/user/ipv6.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@ Router Advertisement
2525
.. clicmd:: ipv6 nd suppress-ra
2626

2727
Don't send router advertisement messages. The ``no`` form of this command
28-
enables sending RA messages.
28+
enables sending RA messages. Note that while being suppressed, RA messages
29+
might still be enabled by other daemons, such as bgpd.
30+
31+
.. clicmd:: ipv6 nd disable-ra
32+
33+
Don't send router advertisement messages at all, even if other daemons
34+
request to enable them. The ``no`` form of this command allows sending RA
35+
messages. Note that this command cannot enable sending RA by itself.
36+
2937

3038
.. clicmd:: ipv6 nd prefix ipv6prefix [valid-lifetime] [preferred-lifetime] [off-link] [no-autoconfig] [router-address]
3139

yang/frr-zebra.yang

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2284,7 +2284,18 @@ module frr-zebra {
22842284
description
22852285
"A flag indicating whether or not the router sends
22862286
periodic Router Advertisements and responds to
2287-
Router Solicitations.";
2287+
Router Solicitations. Note that if this option is
2288+
disabled, RA can still be enabled by other daemons.";
2289+
reference
2290+
"RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
2291+
- AdvSendAdvertisements";
2292+
}
2293+
leaf disable-advertisements {
2294+
type boolean;
2295+
default "false";
2296+
description
2297+
"A flag indicating whether sending Router Advertisements
2298+
messages is allowed on the interface.";
22882299
reference
22892300
"RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
22902301
- AdvSendAdvertisements";

zebra/rtadv.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,8 @@ void ipv6_nd_interval_set(struct interface *ifp, uint32_t interval)
13471347
}
13481348

13491349
/*
1350-
* Handle client (BGP) message to enable or disable IPv6 RA on an interface.
1350+
* Handle client (BGP/VRRP) message to enable or disable IPv6 RA on an
1351+
* interface.
13511352
* Note that while the client could request RA on an interface on which the
13521353
* operator has not enabled RA, RA won't be disabled upon client request
13531354
* if the operator has explicitly enabled RA. The enable request can also
@@ -1403,7 +1404,10 @@ static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
14031404
interfaces_configured_for_ra_from_bgp++;
14041405

14051406
SET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
1406-
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
1407+
1408+
if (!CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_DISABLED))
1409+
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
1410+
14071411
if (ra_interval
14081412
&& (ra_interval * 1000) < (unsigned int) zif->rtadv.MaxRtrAdvInterval
14091413
&& !CHECK_FLAG(zif->rtadv.ra_configured,

zebra/rtadv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ struct rtadvconf {
204204
#define VTY_RA_CONFIGURED (1 << 1) /* Operator configured RA? */
205205
#define VTY_RA_INTERVAL_CONFIGURED \
206206
(1 << 2) /* Operator configured RA interval */
207+
#define VTY_RA_DISABLED (1 << 3) /* Operator completely disabled RA? */
208+
207209
int NumFastReXmitsRemain; /* Loaded first with number of fast
208210
rexmits to do */
209211

zebra/zebra_cli.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,25 @@ DEFPY_YANG (ipv6_nd_suppress_ra,
12431243
return nb_cli_apply_changes(vty, NULL);
12441244
}
12451245

1246+
DEFPY_YANG (ipv6_nd_disable_ra,
1247+
ipv6_nd_disable_ra_cmd,
1248+
"[no] ipv6 nd disable-ra",
1249+
NO_STR
1250+
"Interface IPv6 config commands\n"
1251+
"Neighbor discovery\n"
1252+
"Disable Router Advertisement completely\n")
1253+
{
1254+
if (!no)
1255+
nb_cli_enqueue_change(vty,
1256+
"./frr-zebra:zebra/ipv6-router-advertisements/disable-advertisements",
1257+
NB_OP_MODIFY, "true");
1258+
else
1259+
nb_cli_enqueue_change(vty,
1260+
"./frr-zebra:zebra/ipv6-router-advertisements/disable-advertisements",
1261+
NB_OP_DESTROY, NULL);
1262+
return nb_cli_apply_changes(vty, NULL);
1263+
}
1264+
12461265
static void
12471266
lib_interface_zebra_ipv6_router_advertisements_send_advertisements_cli_write(
12481267
struct vty *vty, const struct lyd_node *dnode, bool show_defaults)
@@ -1255,6 +1274,18 @@ lib_interface_zebra_ipv6_router_advertisements_send_advertisements_cli_write(
12551274
vty_out(vty, " ipv6 nd suppress-ra\n");
12561275
}
12571276

1277+
static void
1278+
lib_interface_zebra_ipv6_router_advertisements_disable_advertisements_cli_write(
1279+
struct vty *vty, const struct lyd_node *dnode, bool show_defaults)
1280+
{
1281+
bool disable_advertisements = yang_dnode_get_bool(dnode, NULL);
1282+
1283+
if (disable_advertisements)
1284+
vty_out(vty, " ipv6 nd disable-ra\n");
1285+
else if (show_defaults)
1286+
vty_out(vty, " no ipv6 nd disable-ra\n");
1287+
}
1288+
12581289
DEFPY_YANG (ipv6_nd_ra_interval,
12591290
ipv6_nd_ra_interval_cmd,
12601291
"[no] ipv6 nd ra-interval ![<(1-1800)$sec|msec (70-1800000)$msec>]",
@@ -2748,6 +2779,10 @@ const struct frr_yang_module_info frr_zebra_cli_info = {
27482779
.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/send-advertisements",
27492780
.cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_send_advertisements_cli_write,
27502781
},
2782+
{
2783+
.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/disable-advertisements",
2784+
.cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_disable_advertisements_cli_write,
2785+
},
27512786
{
27522787
.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval",
27532788
.cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_cli_write,
@@ -2913,6 +2948,7 @@ void zebra_cli_init(void)
29132948
install_element(INTERFACE_NODE, &ipv6_nd_ra_retrans_interval_cmd);
29142949
install_element(INTERFACE_NODE, &ipv6_nd_ra_hop_limit_cmd);
29152950
install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
2951+
install_element(INTERFACE_NODE, &ipv6_nd_disable_ra_cmd);
29162952
install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
29172953
install_element(INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
29182954
install_element(INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);

zebra/zebra_nb.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,12 @@ const struct frr_yang_module_info frr_zebra_info = {
592592
.modify = lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify,
593593
}
594594
},
595+
{
596+
.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/disable-advertisements",
597+
.cbs = {
598+
.modify = lib_interface_zebra_ipv6_router_advertisements_disable_advertisements_modify,
599+
}
600+
},
595601
{
596602
.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval",
597603
.cbs = {

zebra/zebra_nb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ int lib_interface_zebra_evpn_mh_uplink_modify(struct nb_cb_modify_args *args);
199199
#if defined(HAVE_RTADV)
200200
int lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify(
201201
struct nb_cb_modify_args *args);
202+
int lib_interface_zebra_ipv6_router_advertisements_disable_advertisements_modify(
203+
struct nb_cb_modify_args *args);
202204
int lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_modify(
203205
struct nb_cb_modify_args *args);
204206
int lib_interface_zebra_ipv6_router_advertisements_managed_flag_modify(

zebra/zebra_nb_config.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2562,7 +2562,8 @@ int lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify(
25622562
send_adv = yang_dnode_get_bool(args->dnode, NULL);
25632563

25642564
if (send_adv) {
2565-
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
2565+
if (!CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_DISABLED))
2566+
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
25662567
SET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
25672568
} else {
25682569
if (!CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
@@ -2573,6 +2574,39 @@ int lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify(
25732574
return NB_OK;
25742575
}
25752576

2577+
/*
2578+
* XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/disable-advertisements
2579+
*/
2580+
int lib_interface_zebra_ipv6_router_advertisements_disable_advertisements_modify(
2581+
struct nb_cb_modify_args *args)
2582+
{
2583+
struct interface *ifp;
2584+
struct zebra_if *zif;
2585+
bool disable_adv;
2586+
2587+
if (args->event != NB_EV_APPLY)
2588+
return NB_OK;
2589+
2590+
ifp = nb_running_get_entry(args->dnode, NULL, true);
2591+
zif = ifp->info;
2592+
2593+
disable_adv = yang_dnode_get_bool(args->dnode, NULL);
2594+
2595+
if (disable_adv) {
2596+
/* Do it regardless of current status */
2597+
ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
2598+
SET_FLAG(zif->rtadv.ra_configured, VTY_RA_DISABLED);
2599+
} else {
2600+
/* Enable if it has been activated by someone before disabling */
2601+
if (CHECK_FLAG(zif->rtadv.ra_configured,
2602+
(VTY_RA_CONFIGURED | BGP_RA_CONFIGURED)))
2603+
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
2604+
UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_DISABLED);
2605+
}
2606+
2607+
return NB_OK;
2608+
}
2609+
25762610
/*
25772611
* XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval
25782612
*/

0 commit comments

Comments
 (0)