2005-03-25 Jean-Mickael Guerin <jean-mickael.guerin@6wind.com>

* interface.c, interface.h, rtadv.c, rtadv.h: extensions to Neighbor
	  discovery for Mobile IPv6.
This commit is contained in:
vincent 2005-03-25 13:08:53 +00:00
parent 29c4c9bd11
commit 7cee1bb150
5 changed files with 468 additions and 23 deletions

View File

@ -1,3 +1,13 @@
2005-03-25 Jean-Mickael Guerin <jean-mickael.guerin@6wind.com>
* interface.c, interface.h, rtadv.c, rtadv.h: modifications to
IPv6 Neighbor Discovery according to RFC3775, section 7:
o 1-bit Home Agent flag management in Router Advertisement (7.1).
o 1-bit Router Address flag management in Prefix Information
Option (7.2).
o Advertisement Interval Option (7.3)
o Home Agent Information Option (7.4)
o Changes to Sending Router Advertisements more frequently (7.5)
2005-03-13 Hasso Tepper <hasso at quagga.net>
* zebra/interaface.c: "show interface description" command

View File

@ -87,11 +87,15 @@ if_zebra_new_hook (struct interface *ifp)
rtadv->AdvIntervalTimer = 0;
rtadv->AdvManagedFlag = 0;
rtadv->AdvOtherConfigFlag = 0;
rtadv->AdvHomeAgentFlag = 0;
rtadv->AdvLinkMTU = 0;
rtadv->AdvReachableTime = 0;
rtadv->AdvRetransTimer = 0;
rtadv->AdvCurHopLimit = 0;
rtadv->AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME;
rtadv->HomeAgentPreference = 0;
rtadv->HomeAgentLifetime = RTADV_ADV_DEFAULT_LIFETIME;
rtadv->AdvIntervalOption = 0;
rtadv->AdvPrefixList = list_new ();
}
@ -604,6 +608,7 @@ nd_dump_vty (struct vty *vty, struct interface *ifp)
{
struct zebra_if *zif;
struct rtadvconf *rtadv;
int interval;
zif = (struct zebra_if *) ifp->info;
rtadv = &zif->rtadv;
@ -614,8 +619,15 @@ nd_dump_vty (struct vty *vty, struct interface *ifp)
rtadv->AdvReachableTime, VTY_NEWLINE);
vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
rtadv->AdvRetransTimer, VTY_NEWLINE);
vty_out (vty, " ND router advertisements are sent every %d seconds%s",
rtadv->MaxRtrAdvInterval, VTY_NEWLINE);
interval = rtadv->MaxRtrAdvInterval;
if (interval % 1000)
vty_out (vty, " ND router advertisements are sent every "
"%d milliseconds%s", interval,
VTY_NEWLINE);
else
vty_out (vty, " ND router advertisements are sent every "
"%d seconds%s", interval / 1000,
VTY_NEWLINE);
vty_out (vty, " ND router advertisements live for %d seconds%s",
rtadv->AdvDefaultLifetime, VTY_NEWLINE);
if (rtadv->AdvManagedFlag)
@ -624,6 +636,13 @@ nd_dump_vty (struct vty *vty, struct interface *ifp)
else
vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
VTY_NEWLINE);
if (rtadv->AdvHomeAgentFlag)
vty_out (vty, " ND router advertisements with "
"Home Agent flag bit set.%s",
VTY_NEWLINE);
if (rtadv->AdvIntervalOption)
vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
VTY_NEWLINE);
}
}
#endif /* RTADV */

View File

@ -46,7 +46,7 @@
#endif
#ifdef RTADV
/* Router advertisement parameter. From RFC2461. */
/* Router advertisement parameter. From RFC2461 and RFC3775. */
struct rtadvconf
{
/* A flag indicating whether or not the router sends periodic Router
@ -55,16 +55,18 @@ struct rtadvconf
int AdvSendAdvertisements;
/* The maximum time allowed between sending unsolicited multicast
Router Advertisements from the interface, in seconds. MUST be no
less than 4 seconds and no greater than 1800 seconds.
Router Advertisements from the interface, in milliseconds.
MUST be no less than 70 ms (RFC3775, section 7.4) and no greater
than 1800000 ms (See RFC2461).
Default: 600 seconds */
Default: 600000 milliseconds */
int MaxRtrAdvInterval;
#define RTADV_MAX_RTR_ADV_INTERVAL 600
#define RTADV_MAX_RTR_ADV_INTERVAL 600000
/* The minimum time allowed between sending unsolicited multicast
Router Advertisements from the interface, in seconds. MUST be no
less than 3 seconds and no greater than .75 * MaxRtrAdvInterval.
Router Advertisements from the interface, in milliseconds.
MUST be no less than 30 ms (See RFC3775, section 7.4).
MUST be no greater than .75 * MaxRtrAdvInterval.
Default: 0.33 * MaxRtrAdvInterval */
int MinRtrAdvInterval;
@ -140,6 +142,35 @@ struct rtadvconf
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 [RFC3775 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 3775 7.3]
Default: FALSE */
int AdvIntervalOption;
};
#endif /* RTADV */

View File

@ -1,4 +1,5 @@
/* Router advertisement
* Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
* Copyright (C) 1999 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
@ -58,7 +59,8 @@ extern struct zebra_privs_t zserv_privs;
extern struct zebra_t zebrad;
enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER, RTADV_READ};
enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
RTADV_TIMER_MSEC, RTADV_READ};
void rtadv_event (enum rtadv_event, int);
@ -71,6 +73,7 @@ struct rtadv
int sock;
int adv_if_count;
int adv_msec_if_count;
struct thread *ra_read;
struct thread *ra_timer;
@ -210,12 +213,37 @@ rtadv_send_packet (int sock, struct interface *ifp)
rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
if (zif->rtadv.AdvOtherConfigFlag)
rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
if (zif->rtadv.AdvHomeAgentFlag)
rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
rtadv->nd_ra_router_lifetime = htons (zif->rtadv.AdvDefaultLifetime);
rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime);
rtadv->nd_ra_retransmit = htonl (0);
len = sizeof (struct nd_router_advert);
if (zif->rtadv.AdvHomeAgentFlag)
{
struct nd_opt_homeagent_info *ndopt_hai =
(struct nd_opt_homeagent_info *)(buf + len);
ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
ndopt_hai->nd_opt_hai_len = 1;
ndopt_hai->nd_opt_hai_reserved = 0;
ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference);
ndopt_hai->nd_opt_hai_lifetime = htons(zif->rtadv.HomeAgentLifetime);
len += sizeof(struct nd_opt_homeagent_info);
}
if (zif->rtadv.AdvIntervalOption)
{
struct nd_opt_adv_interval *ndopt_adv =
(struct nd_opt_adv_interval *)(buf + len);
ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
ndopt_adv->nd_opt_ai_len = 1;
ndopt_adv->nd_opt_ai_reserved = 0;
ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval);
len += sizeof(struct nd_opt_adv_interval);
}
/* Fill in prefix. */
for (node = listhead (zif->rtadv.AdvPrefixList); node; node = nextnode (node))
{
@ -235,6 +263,8 @@ rtadv_send_packet (int sock, struct interface *ifp)
pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
if (rprefix->AdvAutonomousFlag)
pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
if (rprefix->AdvRouterAddressFlag)
pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime);
pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime);
@ -311,9 +341,19 @@ rtadv_timer (struct thread *thread)
struct listnode *node;
struct interface *ifp;
struct zebra_if *zif;
int period;
rtadv->ra_timer = NULL;
rtadv_event (RTADV_TIMER, 1);
if (rtadv->adv_msec_if_count == 0)
{
period = 1000; /* 1 s */
rtadv_event (RTADV_TIMER, 1 /* 1 s */);
}
else
{
period = 10; /* 10 ms */
rtadv_event (RTADV_TIMER_MSEC, 10 /* 10 ms */);
}
for (node = listhead (iflist); node; nextnode (node))
{
@ -325,12 +365,15 @@ rtadv_timer (struct thread *thread)
zif = ifp->info;
if (zif->rtadv.AdvSendAdvertisements)
if (--zif->rtadv.AdvIntervalTimer <= 0)
{
zif->rtadv.AdvIntervalTimer -= period;
if (zif->rtadv.AdvIntervalTimer <= 0)
{
zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
rtadv_send_packet (rtadv->sock, ifp);
}
}
}
return 0;
}
@ -547,6 +590,7 @@ rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
}
int
@ -634,6 +678,42 @@ DEFUN (no_ipv6_nd_suppress_ra,
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_ra_interval_msec,
ipv6_nd_ra_interval_msec_cmd,
"ipv6 nd ra-interval msec MILLISECONDS",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Router Advertisement interval\n"
"Router Advertisement interval in milliseconds\n")
{
int interval;
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
interval = atoi (argv[0]);
if (interval <= 0)
{
vty_out (vty, "Invalid Router Advertisement Interval%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (zif->rtadv.MaxRtrAdvInterval % 1000)
rtadv->adv_msec_if_count--;
if (interval % 1000)
rtadv->adv_msec_if_count++;
zif->rtadv.MaxRtrAdvInterval = interval;
zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
zif->rtadv.AdvIntervalTimer = 0;
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_ra_interval,
ipv6_nd_ra_interval_cmd,
"ipv6 nd ra-interval SECONDS",
@ -651,12 +731,18 @@ DEFUN (ipv6_nd_ra_interval,
interval = atoi (argv[0]);
if (interval < 0)
if (interval <= 0)
{
vty_out (vty, "Invalid Router Advertisement Interval%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (zif->rtadv.MaxRtrAdvInterval % 1000)
rtadv->adv_msec_if_count--;
/* convert to milliseconds */
interval = interval * 1000;
zif->rtadv.MaxRtrAdvInterval = interval;
zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
zif->rtadv.AdvIntervalTimer = 0;
@ -678,6 +764,9 @@ DEFUN (no_ipv6_nd_ra_interval,
ifp = (struct interface *) vty->index;
zif = ifp->info;
if (zif->rtadv.MaxRtrAdvInterval % 1000)
rtadv->adv_msec_if_count--;
zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
@ -779,6 +868,100 @@ DEFUN (no_ipv6_nd_reachable_time,
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_homeagent_preference,
ipv6_nd_homeagent_preference_cmd,
"ipv6 nd home-agent-preference PREFERENCE",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Home Agent preference\n"
"Home Agent preference value 0..65535\n")
{
u_int32_t hapref;
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
hapref = (u_int32_t) atol (argv[0]);
if (hapref > 65535)
{
vty_out (vty, "Invalid Home Agent preference%s", VTY_NEWLINE);
return CMD_WARNING;
}
zif->rtadv.HomeAgentPreference = hapref;
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_homeagent_preference,
no_ipv6_nd_homeagent_preference_cmd,
"no ipv6 nd home-agent-preference",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Home Agent preference\n")
{
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
zif->rtadv.HomeAgentPreference = 0;
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_homeagent_lifetime,
ipv6_nd_homeagent_lifetime_cmd,
"ipv6 nd home-agent-lifetime SECONDS",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Home Agent lifetime\n"
"Home Agent lifetime in seconds\n")
{
u_int32_t ha_ltime;
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
ha_ltime = (u_int32_t) atol (argv[0]);
if (ha_ltime > RTADV_MAX_HALIFETIME)
{
vty_out (vty, "Invalid Home Agent Lifetime time%s", VTY_NEWLINE);
return CMD_WARNING;
}
zif->rtadv.HomeAgentLifetime = ha_ltime;
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_homeagent_lifetime,
no_ipv6_nd_homeagent_lifetime_cmd,
"no ipv6 nd home-agent-lifetime",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Home Agent lifetime\n")
{
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
zif->rtadv.HomeAgentLifetime = 0;
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_managed_config_flag,
ipv6_nd_managed_config_flag_cmd,
"ipv6 nd managed-config-flag",
@ -816,6 +999,80 @@ DEFUN (no_ipv6_nd_managed_config_flag,
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_homeagent_config_flag,
ipv6_nd_homeagent_config_flag_cmd,
"ipv6 nd home-agent-config-flag",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Home Agent configuration flag\n")
{
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
zif->rtadv.AdvHomeAgentFlag = 1;
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_homeagent_config_flag,
no_ipv6_nd_homeagent_config_flag_cmd,
"no ipv6 nd home-agent-config-flag",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Home Agent configuration flag\n")
{
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
zif->rtadv.AdvHomeAgentFlag = 0;
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_adv_interval_config_option,
ipv6_nd_adv_interval_config_option_cmd,
"ipv6 nd adv-interval-option",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Advertisement Interval Option\n")
{
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
zif->rtadv.AdvIntervalOption = 1;
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_adv_interval_config_option,
no_ipv6_nd_adv_interval_config_option_cmd,
"no ipv6 nd adv-interval-option",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Advertisement Interval Option\n")
{
struct interface *ifp;
struct zebra_if *zif;
ifp = (struct interface *) vty->index;
zif = ifp->info;
zif->rtadv.AdvIntervalOption = 0;
return CMD_SUCCESS;
}
DEFUN (ipv6_nd_other_config_flag,
ipv6_nd_other_config_flag_cmd,
"ipv6 nd other-config-flag",
@ -856,7 +1113,7 @@ DEFUN (no_ipv6_nd_other_config_flag,
DEFUN (ipv6_nd_prefix,
ipv6_nd_prefix_cmd,
"ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
"(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
"(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Prefix information\n"
@ -866,7 +1123,8 @@ DEFUN (ipv6_nd_prefix,
"Preferred lifetime in seconds\n"
"Infinite preferred lifetime\n"
"Do not use prefix for onlink determination\n"
"Do not use prefix for autoconfiguration\n")
"Do not use prefix for autoconfiguration\n"
"Set Router Address flag\n")
{
int i;
int ret;
@ -886,6 +1144,7 @@ DEFUN (ipv6_nd_prefix,
}
rp.AdvOnLinkFlag = 1;
rp.AdvAutonomousFlag = 1;
rp.AdvRouterAddressFlag = 0;
rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
@ -920,6 +1179,8 @@ DEFUN (ipv6_nd_prefix,
rp.AdvOnLinkFlag = 0;
if (strncmp (argv[i], "no", 2) == 0)
rp.AdvAutonomousFlag = 0;
if (strncmp (argv[i], "ro", 2) == 0)
rp.AdvRouterAddressFlag = 1;
}
}
}
@ -929,6 +1190,21 @@ DEFUN (ipv6_nd_prefix,
return CMD_SUCCESS;
}
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_val_nortaddr_cmd,
"ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
"(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Prefix information\n"
"IPv6 prefix\n"
"Valid lifetime in seconds\n"
"Infinite valid lifetime\n"
"Preferred lifetime in seconds\n"
"Infinite preferred lifetime\n"
"Do not use prefix for onlink determination\n"
"Do not use prefix for autoconfiguration\n")
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_val_rev_cmd,
"ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
@ -944,6 +1220,22 @@ ALIAS (ipv6_nd_prefix,
"Do not use prefix for autoconfiguration\n"
"Do not use prefix for onlink determination\n")
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_val_rev_rtaddr_cmd,
"ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
"(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Prefix information\n"
"IPv6 prefix\n"
"Valid lifetime in seconds\n"
"Infinite valid lifetime\n"
"Preferred lifetime in seconds\n"
"Infinite preferred lifetime\n"
"Do not use prefix for autoconfiguration\n"
"Do not use prefix for onlink determination\n"
"Set Router Address flag\n")
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_val_noauto_cmd,
"ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
@ -956,7 +1248,7 @@ ALIAS (ipv6_nd_prefix,
"Infinite valid lifetime\n"
"Preferred lifetime in seconds\n"
"Infinite preferred lifetime\n"
"Do not use prefix for autoconfigurationn")
"Do not use prefix for autoconfiguration")
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_val_offlink_cmd,
@ -972,6 +1264,20 @@ ALIAS (ipv6_nd_prefix,
"Infinite preferred lifetime\n"
"Do not use prefix for onlink determination\n")
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_val_rtaddr_cmd,
"ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
"(<0-4294967295>|infinite) (router-address|)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Prefix information\n"
"IPv6 prefix\n"
"Valid lifetime in seconds\n"
"Infinite valid lifetime\n"
"Preferred lifetime in seconds\n"
"Infinite preferred lifetime\n"
"Set Router Address flag\n")
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_val_cmd,
"ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
@ -1023,6 +1329,15 @@ ALIAS (ipv6_nd_prefix,
"IPv6 prefix\n"
"Do not use prefix for onlink determination\n")
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_noval_rtaddr_cmd,
"ipv6 nd prefix X:X::X:X/M (router-address|)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Prefix information\n"
"IPv6 prefix\n"
"Set Router Address flag\n")
ALIAS (ipv6_nd_prefix,
ipv6_nd_prefix_prefix_cmd,
"ipv6 nd prefix X:X::X:X/M",
@ -1064,7 +1379,6 @@ DEFUN (no_ipv6_nd_prefix,
return CMD_SUCCESS;
}
/* Write configuration about router advertisement. */
void
rtadv_config_write (struct vty *vty, struct interface *ifp)
@ -1073,6 +1387,7 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
struct listnode *node;
struct rtadv_prefix *rprefix;
u_char buf[INET6_ADDRSTRLEN];
int interval;
if (! rtadv)
return;
@ -1087,8 +1402,14 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
vty_out (vty, " ipv6 nd suppress-ra%s", VTY_NEWLINE);
}
if (zif->rtadv.MaxRtrAdvInterval != RTADV_MAX_RTR_ADV_INTERVAL)
vty_out (vty, " ipv6 nd ra-interval %d%s", zif->rtadv.MaxRtrAdvInterval,
interval = zif->rtadv.MaxRtrAdvInterval;
if (interval % 1000)
vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval,
VTY_NEWLINE);
else
if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000,
VTY_NEWLINE);
if (zif->rtadv.AdvDefaultLifetime != RTADV_ADV_DEFAULT_LIFETIME)
@ -1128,6 +1449,8 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
vty_out (vty, " off-link");
if (!rprefix->AdvAutonomousFlag)
vty_out (vty, " no-autoconfig");
if (rprefix->AdvRouterAddressFlag)
vty_out (vty, " router-address");
vty_out (vty, "%s", VTY_NEWLINE);
}
}
@ -1162,6 +1485,11 @@ rtadv_event (enum rtadv_event event, int val)
rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, NULL,
val);
break;
case RTADV_TIMER_MSEC:
if (! rtadv->ra_timer)
rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
NULL, val);
break;
case RTADV_READ:
if (! rtadv->ra_read)
rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, NULL, val);
@ -1187,6 +1515,7 @@ rtadv_init ()
install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
@ -1196,15 +1525,27 @@ rtadv_init ()
install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_noauto_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_offlink_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rev_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_noauto_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_offlink_cmd);
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);
}

View File

@ -1,4 +1,5 @@
/* Router advertisement
* Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
* Copyright (C) 1999 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
@ -42,8 +43,51 @@ struct rtadv_prefix
/* The value to be placed in the Autonomous Flag. */
int AdvAutonomousFlag;
/* The value to be placed in the Router Address Flag (RFC3775 7.2). */
int AdvRouterAddressFlag;
#ifndef ND_OPT_PI_FLAG_RADDR
#define ND_OPT_PI_FLAG_RADDR 0x20
#endif
};
void rtadv_config_write (struct vty *, struct interface *);
/* draft-ietf-mip6-mipext-advapi-03 */
#ifndef ND_OPT_ADV_INTERVAL
#define ND_OPT_ADV_INTERVAL 7 /* Adv Interval Option */
#endif
#ifndef ND_OPT_HA_INFORMATION
#define ND_OPT_HA_INFORMATION 8 /* HA Information Option */
#endif
#ifndef HAVE_ND_OPT_ADV_INTERVAL
struct nd_opt_adv_interval { /* Advertisement interval option */
uint8_t nd_opt_ai_type;
uint8_t nd_opt_ai_len;
uint16_t nd_opt_ai_reserved;
uint32_t nd_opt_ai_interval;
} __attribute__((__packed__));
#else
#ifndef HAVE_ND_OPT_ADV_INTERVAL_AI_FIELDS
/* fields may have to be renamed */
#define nd_opt_ai_type nd_opt_adv_interval_type
#define nd_opt_ai_len nd_opt_adv_interval_len
#define nd_opt_ai_reserved nd_opt_adv_interval_reserved
#define nd_opt_ai_interval nd_opt_adv_interval_ival
#endif
#endif
#ifndef HAVE_ND_OPT_HOMEAGENT_INFO
struct nd_opt_homeagent_info { /* Home Agent info */
u_int8_t nd_opt_hai_type;
u_int8_t nd_opt_hai_len;
u_int16_t nd_opt_hai_reserved;
u_int16_t nd_opt_hai_preference;
u_int16_t nd_opt_hai_lifetime;
} __attribute__((__packed__));
#endif
#endif /* _ZEBRA_RTADV_H */