[radvd-devel-l] DeprecatePrefix option

Mark Smith radvd at 02a76c927861ca7413a122f2a73a0d37.nosense.org
Tue Mar 8 16:16:46 EST 2011


Hi,

I've recently developed the following patch to implement
per-prefix prefix deprecation. Here is the manual page text describing
what this option does -


       DeprecatePrefix on|off

              Upon shutdown, this option will cause radvd to deprecate
              the prefix by announcing it in the radvd  shutdown  RA
              with  a  zero preferred lifetime and a valid lifetime
              slightly greater than 2 hours. This will encourage
              end-nodes using this prefix to deprecate any associated
              addresses immediately. Note that  this option  should
              only be used when only one router is announcing the
              prefix onto the link, otherwise end- nodes will deprecate
              associated addresses despite the prefix still being valid
              for preferred use.

              See RFC4861, section 5.5.3., "Router Advertisement
              Processing", part (e).

              Default: off


Hopefully it is useful and could be added to a future radvd
release.

Currently prefix deprecation only occurs upon shutdown. Ideally it
should also occur when the configuration is reloaded via the HUP
signal. However, to do that well that requires doing things such as
identifying interfaces that are dead, are new and are changed in the
configuration, and then sending out interim deprecate prefix RAs for
the changed inferfaces. I've started working on doing this and am
around 40% though. However, it has turned out to be quite a bit of
work so I thought I'd send through a more fundamental version of
the DeprecatePrefix option first. If this version is ok, I'll whip up
deprecate flags for the other "deprecatable" options such as the Route
Information Option.

Regards,
Mark.


diff --git a/defaults.h b/defaults.h
index 6b6fb31..bc714fa 100644
--- a/defaults.h
+++ b/defaults.h
@@ -56,6 +56,7 @@
 #define DFLT_AdvOnLinkFlag		1
 #define DFLT_AdvPreferredLifetime	14400 /* seconds */
 #define DFLT_AdvAutonomousFlag		1
+#define DFLT_DeprecatePrefixFlag	0
 
 /* Each route has an associated: */
 #define DFLT_AdvRouteLifetime(iface)	(3 * (iface)->MaxRtrAdvInterval)
@@ -122,6 +123,9 @@
 
 #define MAX_PrefixLen			128
 
+/* SLAAC (RFC4862) Constants and Derived Values */
+#define MIN_AdvValidLifetime		7203	/* slight >2 hours in secs */
+
 /*
  * Mobile IPv6 extensions, off by default
  */
diff --git a/gram.y b/gram.y
index 17273f6..4b3d511 100644
--- a/gram.y
+++ b/gram.y
@@ -95,6 +95,7 @@ static struct in6_addr get_prefix6(struct in6_addr const *addr, struct in6_addr
 %token		T_AdvAutonomous
 %token		T_AdvValidLifetime
 %token		T_AdvPreferredLifetime
+%token		T_DeprecatePrefix
 
 %token		T_AdvRouterAddr
 %token		T_AdvHomeAgentFlag
@@ -561,6 +562,10 @@ prefixparms	: T_AdvOnLink SWITCH ';'
 					prefix->AdvPreferredLifetime = $2;
 			}
 		}
+		| T_DeprecatePrefix SWITCH ';'
+		{
+			prefix->DeprecatePrefixFlag = $2;
+		}
 		| T_Base6to4Interface name ';'
 		{
 			if (prefix) {
diff --git a/interface.c b/interface.c
index 83a6104..f285a0b 100644
--- a/interface.c
+++ b/interface.c
@@ -23,6 +23,8 @@ iface_init_defaults(struct Interface *iface)
 {
 	memset(iface, 0, sizeof(struct Interface));
 
+	iface->cease_adv	  = 0;
+
 	iface->HasFailed	  = 0;
 	iface->IgnoreIfMissing	  = DFLT_IgnoreIfMissing;
 	iface->AdvSendAdvert	  = DFLT_AdvSendAdv;
@@ -55,6 +57,7 @@ prefix_init_defaults(struct AdvPrefix *prefix)
 	prefix->AdvRouterAddr = DFLT_AdvRouterAddr;
 	prefix->AdvValidLifetime = DFLT_AdvValidLifetime;
 	prefix->AdvPreferredLifetime = DFLT_AdvPreferredLifetime;
+	prefix->DeprecatePrefixFlag = DFLT_DeprecatePrefixFlag;
 	prefix->if6to4[0] = 0;
 	prefix->enabled = 1;
 }
diff --git a/radvd.c b/radvd.c
index 4d762e9..7290f8a 100644
--- a/radvd.c
+++ b/radvd.c
@@ -472,7 +472,7 @@ stop_adverts(void)
 		if( ! iface->UnicastOnly ) {
 			if (iface->AdvSendAdvert) {
 				/* send a final advertisement with zero Router Lifetime */
-				iface->AdvDefaultLifetime = 0;
+				iface->cease_adv = 1;
 				send_ra_forall(iface, NULL);
 			}
 		}
diff --git a/radvd.conf.5.man b/radvd.conf.5.man
index e7e8282..12ee26e 100644
--- a/radvd.conf.5.man
+++ b/radvd.conf.5.man
@@ -423,6 +423,15 @@ Note: RFC4861's suggested default value is significantly longer: 7 days.
 Default: 14400 seconds (4 hours)
 
 .TP
+.BR DeprecatePrefix " " on | off
+
+Upon shutdown, this option will cause radvd to deprecate the prefix by announcing it in the radvd shutdown RA with a zero preferred lifetime and a valid lifetime slightly greater than 2 hours. This will encourage end-nodes using this prefix to deprecate any associated addresses immediately. Note that this option should only be used when only one router is announcing the prefix onto the link, otherwise end-nodes will deprecate associated addresses despite the prefix still being valid for preferred use.
+
+See RFC4861, section 5.5.3., "Router Advertisement Processing", part (e).
+
+Default: off
+
+.TP
 .BR "Base6to4Interface " name 
 
 If this option is specified, this prefix will be combined with the
diff --git a/radvd.h b/radvd.h
index b08a8c6..178d259 100644
--- a/radvd.h
+++ b/radvd.h
@@ -54,6 +54,8 @@ struct Interface {
 	int			if_hwaddr_len;
 	int			if_prefix_len;
 	int			if_maxmtu;
+	
+	int			cease_adv;
 
 	int			IgnoreIfMissing;
 	int			AdvSendAdvert;
@@ -109,6 +111,7 @@ struct AdvPrefix {
 	int			AdvAutonomousFlag;
 	uint32_t		AdvValidLifetime;
 	uint32_t		AdvPreferredLifetime;
+	int			DeprecatePrefixFlag;
 
 	/* Mobile IPv6 extensions */
 	int             	AdvRouterAddr;
diff --git a/scanner.l b/scanner.l
index 3796010..69bf8f6 100644
--- a/scanner.l
+++ b/scanner.l
@@ -69,6 +69,7 @@ AdvOnLink		{ return T_AdvOnLink; }
 AdvAutonomous		{ return T_AdvAutonomous; }
 AdvValidLifetime	{ return T_AdvValidLifetime; }
 AdvPreferredLifetime	{ return T_AdvPreferredLifetime; }
+DeprecatePrefix		{ return T_DeprecatePrefix; }
 
 AdvRouterAddr		{ return T_AdvRouterAddr; }
 AdvHomeAgentFlag	{ return T_AdvHomeAgentFlag; }
diff --git a/send.c b/send.c
index 6c2aa24..e97950d 100644
--- a/send.c
+++ b/send.c
@@ -160,8 +160,12 @@ send_ra(struct Interface *iface, struct in6_addr *dest)
 	radvert->nd_ra_flags_reserved   |=
 		(iface->AdvHomeAgentFlag)?ND_RA_FLAG_HOME_AGENT:0;
 
-	/* if forwarding is disabled, send zero router lifetime */
-	radvert->nd_ra_router_lifetime	 =  !check_ip6_forwarding() ? htons(iface->AdvDefaultLifetime) : 0;
+	if (iface->cease_adv) {
+		radvert->nd_ra_router_lifetime = 0;
+	} else {
+		/* if forwarding is disabled, send zero router lifetime */
+		radvert->nd_ra_router_lifetime	 =  !check_ip6_forwarding() ? htons(iface->AdvDefaultLifetime) : 0;
+	}
 	radvert->nd_ra_flags_reserved   |=
 		(iface->AdvDefaultPreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;
 
@@ -196,8 +200,15 @@ send_ra(struct Interface *iface, struct in6_addr *dest)
 			pinfo->nd_opt_pi_flags_reserved |=
 				(prefix->AdvRouterAddr)?ND_OPT_PI_FLAG_RADDR:0;
 
-			pinfo->nd_opt_pi_valid_time	= htonl(prefix->AdvValidLifetime);
-			pinfo->nd_opt_pi_preferred_time = htonl(prefix->AdvPreferredLifetime);
+			if (iface->cease_adv && prefix->DeprecatePrefixFlag) {
+				/* RFC4862, 5.5.3, step e) */
+				pinfo->nd_opt_pi_valid_time	= htonl(MIN_AdvValidLifetime);
+				pinfo->nd_opt_pi_preferred_time = 0;
+			} else {
+
+				pinfo->nd_opt_pi_valid_time	= htonl(prefix->AdvValidLifetime);
+				pinfo->nd_opt_pi_preferred_time = htonl(prefix->AdvPreferredLifetime);
+			}
 			pinfo->nd_opt_pi_reserved2	= 0;
 
 			memcpy(&pinfo->nd_opt_pi_prefix, &prefix->Prefix,




More information about the radvd-devel-l mailing list