3 May 2009 06:40
[quagga-dev 6541] Re: [PATCH] [zebra] RFC 4191 Default Router Preference support for router advertisements
Chris Caputo <ccaputo <at> alt.net>
2009-05-03 04:40:57 GMT
2009-05-03 04:40:57 GMT
On Sun, 3 May 2009, Chris Caputo wrote:
> For consideration... Feedback welcome.
2nd version. (fix to adhere to a "MUST" clause in the RFC)
Chris
---
[PATCH] [zebra] RFC 4191 Default Router Preference support for router advertisements
Adds "ipv6 nd router-preference (high|medium|low)" and
"no ipv6 nd router-preference" interface commands.
Files modified:
doc/ipv6.texi
zebra/interface.c
zebra/interface.h
zebra/rtadv.c
zebra/rtadv.h
Signed-off-by: Chris Caputo <ccaputo <at> alt.net>
---
doc/ipv6.texi | 10 +++++++-
zebra/interface.c | 9 +++++++
zebra/interface.h | 9 ++++++-
zebra/rtadv.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
zebra/rtadv.h | 2 +
5 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/doc/ipv6.texi b/doc/ipv6.texi
index 910253c..a78a92f 100644
--- a/doc/ipv6.texi
+++ b/doc/ipv6.texi
<at> <at> -150,6 +150,13 <at> <at> in milliseconds, between successive unsolicited Router Advertisements.
Default: not set
<at> end deffn
+ <at> deffn {Interface Command} {ipv6 nd router-preference (high|medium|low)} {}
+ <at> deffnx {Interface Command} {no ipv6 nd router-preference} {}
+Set default router preference in IPv6 router advertisements per RFC4191.
+
+Default: medium
+ <at> end deffn
+
<at> example
<at> group
interface eth0
<at> <at> -160,4 +167,5 <at> <at> interface eth0
For more information see <at> cite{RFC2462 (IPv6 Stateless Address Autoconfiguration)}
, <at> cite{RFC2461 (Neighbor Discovery for IP Version 6 (IPv6))}
-and <at> cite{RFC3775 (Mobility Support in IPv6 (Mobile IPv6))}.
+, <at> cite{RFC3775 (Mobility Support in IPv6 (Mobile IPv6))}
+and <at> cite{RFC4191 (Default Router Preferences and More-Specific Routes)}.
diff --git a/zebra/interface.c b/zebra/interface.c
index 184b42a..d455cd1 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
<at> <at> -41,6 +41,11 <at> <at>
#include "zebra/debug.h"
#include "zebra/irdp.h"
+#ifdef RTADV
+/* Order is intentional. Matches RFC4191. This array is also used for
+ command matching, so only modify with care. */
+const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
+#endif /* RTADV */
/* Called when new interface is added. */
static int
<at> <at> -76,6 +81,7 <at> <at> if_zebra_new_hook (struct interface *ifp)
rtadv->HomeAgentPreference = 0;
rtadv->HomeAgentLifetime = RTADV_ADV_DEFAULT_LIFETIME;
rtadv->AdvIntervalOption = 0;
+ rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
rtadv->AdvPrefixList = list_new ();
}
<at> <at> -623,6 +629,9 <at> <at> nd_dump_vty (struct vty *vty, struct interface *ifp)
VTY_NEWLINE);
vty_out (vty, " ND router advertisements live for %d seconds%s",
rtadv->AdvDefaultLifetime, VTY_NEWLINE);
+ vty_out (vty, " ND router advertisement default router preference is "
+ "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
+ VTY_NEWLINE);
if (rtadv->AdvManagedFlag)
vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
VTY_NEWLINE);
diff --git a/zebra/interface.h b/zebra/interface.h
index 0a6b036..ec047aa 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
<at> <at> -46,7 +46,7 <at> <at>
#endif
#ifdef RTADV
-/* Router advertisement parameter. From RFC2461 and RFC3775. */
+/* Router advertisement parameter. From RFC2461, RFC3775 and RFC4191. */
struct rtadvconf
{
/* A flag indicating whether or not the router sends periodic Router
<at> <at> -171,6 +171,13 <at> <at> struct rtadvconf
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. */
};
#endif /* RTADV */
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 4bdb83d..c247bbf 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
<at> <at> -209,7 +209,12 <at> <at> rtadv_send_packet (int sock, struct interface *ifp)
rtadv->nd_ra_cksum = 0;
rtadv->nd_ra_curhoplimit = 64;
- rtadv->nd_ra_flags_reserved = 0;
+
+ /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
+ rtadv->nd_ra_flags_reserved =
+ zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference;
+ rtadv->nd_ra_flags_reserved <<= 3;
+
if (zif->rtadv.AdvManagedFlag)
rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
if (zif->rtadv.AdvOtherConfigFlag)
<at> <at> -1372,6 +1377,56 <at> <at> DEFUN (no_ipv6_nd_prefix,
return CMD_SUCCESS;
}
+
+DEFUN (ipv6_nd_router_preference,
+ ipv6_nd_router_preference_cmd,
+ "ipv6 nd router-preference (high|medium|low)",
+ "Interface IPv6 config commands\n"
+ "Neighbor discovery\n"
+ "Default router preference\n"
+ "High default router preference\n"
+ "Low default router preference\n"
+ "Medium default router preference (default)\n")
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ int i = 0;
+
+ ifp = (struct interface *) vty->index;
+ zif = ifp->info;
+
+ while (0 != rtadv_pref_strs[i])
+ {
+ if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
+ {
+ zif->rtadv.DefaultPreference = i;
+ return CMD_SUCCESS;
+ }
+ i++;
+ }
+
+ return CMD_ERR_NO_MATCH;
+}
+
+DEFUN (no_ipv6_nd_router_preference,
+ no_ipv6_nd_router_preference_cmd,
+ "no ipv6 nd router-preference",
+ NO_STR
+ "Interface IPv6 config commands\n"
+ "Neighbor discovery\n"
+ "Default router preference\n")
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+
+ ifp = (struct interface *) vty->index;
+ zif = ifp->info;
+
+ zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
+
+ return CMD_SUCCESS;
+}
+
/* Write configuration about router advertisement. */
void
rtadv_config_write (struct vty *vty, struct interface *ifp)
<at> <at> -1419,6 +1474,11 <at> <at> rtadv_config_write (struct vty *vty, struct interface *ifp)
if (zif->rtadv.AdvOtherConfigFlag)
vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE);
+ if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
+ vty_out (vty, " ipv6 nd router-preference %s%s",
+ rtadv_pref_strs[zif->rtadv.DefaultPreference],
+ VTY_NEWLINE);
+
for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
{
vty_out (vty, " ipv6 nd prefix %s/%d",
<at> <at> -1540,6 +1600,8 <at> <at> rtadv_init (void)
install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
+ install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
+ install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
}
static int
diff --git a/zebra/rtadv.h b/zebra/rtadv.h
index abd1c6f..d8d263d 100644
--- a/zebra/rtadv.h
+++ b/zebra/rtadv.h
<at> <at> -94,4 +94,6 <at> <at> struct nd_opt_homeagent_info { /* Home Agent info */
} __attribute__((__packed__));
#endif
+extern const char *rtadv_pref_strs[];
+
#endif /* _ZEBRA_RTADV_H */
--
--
1.6.0.6
RSS Feed