]> git.puffer.fish Git - mirror/frr.git/commitdiff
2005-03-25 Jean-Mickael Guerin <jean-mickael.guerin@6wind.com>
authorvincent <vincent>
Fri, 25 Mar 2005 13:08:53 +0000 (13:08 +0000)
committervincent <vincent>
Fri, 25 Mar 2005 13:08:53 +0000 (13:08 +0000)
* interface.c, interface.h, rtadv.c, rtadv.h: extensions to Neighbor
  discovery for Mobile IPv6.

zebra/ChangeLog
zebra/interface.c
zebra/interface.h
zebra/rtadv.c
zebra/rtadv.h

index ac99ff9711238b7ea4ede18517a8bec52afb18b4..bc3c738cfdfdb73ed0b724038b9ca1ab4e37f867 100644 (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
index 6c3e33aa06041ff063242795aa425f121034ed1d..55717545dcd86fec780e6395e50aa16378544a08 100644 (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 */
index 91578ffb39dbd92ec8fdc649d997ffb51b41c93f..0033f7d573962e10fdfb354d1698703db2c30dc6 100644 (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 */
index 1238396e28297eee180e1712496177f854eee462..725965630d1f74d939abf489e5b5db8646e78d7e 100644 (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,11 +365,14 @@ rtadv_timer (struct thread *thread)
       zif = ifp->info;
 
       if (zif->rtadv.AdvSendAdvertisements)
-       if (--zif->rtadv.AdvIntervalTimer <= 0)
-         {
-           zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
-           rtadv_send_packet (rtadv->sock, ifp);
-         }
+       { 
+         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);
 }
index 859b2d7e549577c9251dc1c8215b4b3a0a5be5ae..d52c2c0862d46aa907d43430e0d63cea2b5e73a1 100644 (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 */