]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/rtadv.c
Merge branch 'fixes/command'
[mirror_frr.git] / zebra / rtadv.c
index 59542481ddc4bec6862c3b954e27db2f9af8afed..6a0d01a07242c9a88d6201bf462ec5ec08ef33db 100644 (file)
@@ -1,4 +1,5 @@
 /* Router advertisement
+ * Copyright (C) 2016 Cumulus Networks
  * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
  * Copyright (C) 1999 Kunihiro Ishiguro
  *
@@ -23,6 +24,7 @@
 #include <zebra.h>
 
 #include "memory.h"
+#include "zebra_memory.h"
 #include "sockopt.h"
 #include "thread.h"
 #include "if.h"
@@ -70,8 +72,25 @@ static int if_join_all_router (int, struct interface *);
 static int if_leave_all_router (int, struct interface *);
 
 static int
-rtadv_recv_packet (int sock, u_char *buf, int buflen,
-                  struct sockaddr_in6 *from, unsigned int *ifindex,
+rtadv_increment_received(struct zebra_ns *zns, ifindex_t *ifindex)
+{
+  int ret = -1;
+  struct interface *iface;
+  struct zebra_if *zif;
+
+  iface = if_lookup_by_index_per_ns (zns, *ifindex);
+  if (iface && iface->info)
+    {
+      zif = iface->info;
+      zif->ra_rcvd++;
+      ret = 0;
+    }
+  return ret;
+}
+
+static int
+rtadv_recv_packet (struct zebra_ns *zns, int sock, u_char *buf, int buflen,
+                  struct sockaddr_in6 *from, ifindex_t *ifindex,
                   int *hoplimit)
 {
   int ret;
@@ -119,6 +138,8 @@ rtadv_recv_packet (int sock, u_char *buf, int buflen,
          *hoplimit = *hoptr;
        }
     }
+
+  rtadv_increment_received(zns, ifindex);
   return ret;
 }
 
@@ -133,9 +154,6 @@ rtadv_send_packet (int sock, struct interface *ifp)
   struct cmsghdr  *cmsgptr;
   struct in6_pktinfo *pkt;
   struct sockaddr_in6 addr;
-#ifdef HAVE_STRUCT_SOCKADDR_DL
-  struct sockaddr_dl *sdl;
-#endif /* HAVE_STRUCT_SOCKADDR_DL */
   static void *adata = NULL;
   unsigned char buf[RTADV_MSG_SIZE];
   struct nd_router_advert *rtadv;
@@ -296,24 +314,6 @@ rtadv_send_packet (int sock, struct interface *ifp)
     }
 
   /* Hardware address. */
-#ifdef HAVE_STRUCT_SOCKADDR_DL
-  sdl = &ifp->sdl;
-  if (sdl != NULL && sdl->sdl_alen != 0)
-    {
-      buf[len++] = ND_OPT_SOURCE_LINKADDR;
-
-      /* Option length should be rounded up to next octet if
-         the link address does not end on an octet boundary. */
-      buf[len++] = (sdl->sdl_alen + 9) >> 3;
-
-      memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen);
-      len += sdl->sdl_alen;
-
-      /* Pad option to end on an octet boundary. */
-      memset (buf + len, 0, -(sdl->sdl_alen + 2) & 0x7);
-      len += -(sdl->sdl_alen + 2) & 0x7;
-    }
-#else
   if (ifp->hw_addr_len != 0)
     {
       buf[len++] = ND_OPT_SOURCE_LINKADDR;
@@ -329,7 +329,6 @@ rtadv_send_packet (int sock, struct interface *ifp)
       memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
       len += -(ifp->hw_addr_len + 2) & 0x7;
     }
-#endif /* HAVE_STRUCT_SOCKADDR_DL */
 
   /* MTU */
   if (zif->rtadv.AdvLinkMTU)
@@ -367,13 +366,15 @@ rtadv_send_packet (int sock, struct interface *ifp)
       zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)",
                 ifp->name, ifp->ifindex, sock, errno, safe_strerror(errno));
     }
+  else
+    zif->ra_sent++;
 }
 
 static int
 rtadv_timer (struct thread *thread)
 {
   struct zebra_ns *zns = THREAD_ARG (thread);
-  vrf_iter_t iter;
+  struct vrf *vrf;
   struct listnode *node, *nnode;
   struct interface *ifp;
   struct zebra_if *zif;
@@ -391,8 +392,8 @@ rtadv_timer (struct thread *thread)
       rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
     }
 
-  for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
-    for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp))
+  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
+    for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp))
       {
         if (if_is_loopback (ifp) ||
             CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) ||
@@ -513,7 +514,7 @@ rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp,
 
 
 static void
-rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int hoplimit,
+rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex, int hoplimit,
                       struct sockaddr_in6 *from, struct zebra_ns *zns)
 {
   struct icmp6_hdr *icmph;
@@ -588,7 +589,7 @@ rtadv_read (struct thread *thread)
   int len;
   u_char buf[RTADV_MSG_SIZE];
   struct sockaddr_in6 from;
-  unsigned int ifindex = 0;
+  ifindex_t ifindex = 0;
   int hoplimit = -1;
   struct zebra_ns *zns = THREAD_ARG (thread);
 
@@ -598,7 +599,7 @@ rtadv_read (struct thread *thread)
   /* Register myself. */
   rtadv_event (zns, RTADV_READ, sock);
 
-  len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit);
+  len = rtadv_recv_packet (zns, sock, buf, sizeof (buf), &from, &ifindex, &hoplimit);
 
   if (len < 0) 
     {
@@ -630,23 +631,41 @@ rtadv_make_socket (void)
                                 safe_strerror (errno) );
 
   if (sock < 0)
-    return -1;
+    {
+      close (sock);
+      return -1;
+    }
 
   ret = setsockopt_ipv6_pktinfo (sock, 1);
   if (ret < 0)
-    return ret;
+    {
+      close (sock);
+      return ret;
+    }
   ret = setsockopt_ipv6_multicast_loop (sock, 0);
   if (ret < 0)
-    return ret;
+    {
+      close (sock);
+      return ret;
+    }
   ret = setsockopt_ipv6_unicast_hops (sock, 255);
   if (ret < 0)
-    return ret;
+    {
+      close (sock);
+      return ret;
+    }
   ret = setsockopt_ipv6_multicast_hops (sock, 255);
   if (ret < 0)
-    return ret;
+    {
+      close (sock);
+      return ret;
+    }
   ret = setsockopt_ipv6_hoplimit (sock, 1);
   if (ret < 0)
-    return ret;
+    {
+      close (sock);
+      return ret;
+    }
 
   ICMP6_FILTER_SETBLOCKALL(&filter);
   ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
@@ -808,7 +827,7 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
 
   if (IS_ZEBRA_DEBUG_EVENT)
     zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
-               zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
+               zvrf_id (zvrf), ifindex, enable ? "enable" : "disable",
                zebra_route_string(client->proto), ra_interval);
 
   /* Locate interface and check VRF match. */
@@ -816,14 +835,14 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
   if (!ifp)
     {
       zlog_warn("%u: IF %u RA %s client %s - interface unknown",
-               zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
+               zvrf_id (zvrf), ifindex, enable ? "enable" : "disable",
                zebra_route_string(client->proto));
       return;
     }
-  if (ifp->vrf_id != zvrf->vrf_id)
+  if (ifp->vrf_id != zvrf_id (zvrf))
     {
       zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
-               zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
+               zvrf_id (zvrf), ifindex, enable ? "enable" : "disable",
                zebra_route_string(client->proto), ifp->vrf_id);
       return;
     }
@@ -853,10 +872,8 @@ DEFUN (ipv6_nd_suppress_ra,
        "Neighbor discovery\n"
        "Suppress Router Advertisement\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = vty->index;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   if (if_is_loopback (ifp) ||
       CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
@@ -866,7 +883,6 @@ DEFUN (ipv6_nd_suppress_ra,
     }
 
   ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
-  zif = ifp->info;
   zif->rtadv.configured = 0;
   return CMD_SUCCESS;
 }
@@ -879,10 +895,8 @@ DEFUN (no_ipv6_nd_suppress_ra,
        "Neighbor discovery\n"
        "Suppress Router Advertisement\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = vty->index;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   if (if_is_loopback (ifp) ||
       CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
@@ -892,27 +906,28 @@ DEFUN (no_ipv6_nd_suppress_ra,
     }
 
   ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
-  zif = ifp->info;
   zif->rtadv.configured = 1;
   return CMD_SUCCESS;
 }
 
 DEFUN (ipv6_nd_ra_interval_msec,
        ipv6_nd_ra_interval_msec_cmd,
-       "ipv6 nd ra-interval msec <70-1800000>",
+       "ipv6 nd ra-interval msec (70-1800000)",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Router Advertisement interval\n"
+       "Router Advertisement interval in milliseconds\n"
        "Router Advertisement interval in milliseconds\n")
 {
+  int idx_number = 4;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
   unsigned interval;
-  struct interface *ifp = (struct interface *) vty->index;
   struct zebra_if *zif = ifp->info;
   struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
   struct zebra_ns *zns;
 
   zns = zvrf->zns;
-  VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
+  VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[idx_number]->arg, 70, 1800000);
   if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
   {
     vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
@@ -934,20 +949,21 @@ DEFUN (ipv6_nd_ra_interval_msec,
 
 DEFUN (ipv6_nd_ra_interval,
        ipv6_nd_ra_interval_cmd,
-       "ipv6 nd ra-interval <1-1800>",
+       "ipv6 nd ra-interval (1-1800)",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Router Advertisement interval\n"
        "Router Advertisement interval in seconds\n")
 {
+  int idx_number = 3;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
   unsigned interval;
-  struct interface *ifp = (struct interface *) vty->index;
   struct zebra_if *zif = ifp->info;
   struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
   struct zebra_ns *zns;
 
   zns = zvrf->zns;
-  VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
+  VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[idx_number]->arg, 1, 1800);
   if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
   {
     vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
@@ -969,19 +985,20 @@ DEFUN (ipv6_nd_ra_interval,
 
 DEFUN (no_ipv6_nd_ra_interval,
        no_ipv6_nd_ra_interval_cmd,
-       "no ipv6 nd ra-interval",
+       "no ipv6 nd ra-interval [<(1-1800)|msec (1-1800000)>]",
        NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
-       "Router Advertisement interval\n")
+       "Router Advertisement interval\n"
+       "Router Advertisement interval in seconds\n"
+       "Specify millisecond router advertisement interval\n"
+       "Router Advertisement interval in milliseconds\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
   struct zebra_vrf *zvrf;
   struct zebra_ns *zns;
 
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
   zvrf = vrf_info_lookup (ifp->vrf_id);
   zns = zvrf->zns;
 
@@ -995,39 +1012,20 @@ DEFUN (no_ipv6_nd_ra_interval,
   return CMD_SUCCESS;
 }
 
-ALIAS (no_ipv6_nd_ra_interval,
-       no_ipv6_nd_ra_interval_val_cmd,
-       "no ipv6 nd ra-interval <1-1800>",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Router Advertisement interval\n")
-
-ALIAS (no_ipv6_nd_ra_interval,
-       no_ipv6_nd_ra_interval_msec_val_cmd,
-       "no ipv6 nd ra-interval msec <1-1800000>",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Router Advertisement interval\n"
-       "Router Advertisement interval in milliseconds\n")
-
 DEFUN (ipv6_nd_ra_lifetime,
        ipv6_nd_ra_lifetime_cmd,
-       "ipv6 nd ra-lifetime <0-9000>",
+       "ipv6 nd ra-lifetime (0-9000)",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Router lifetime\n"
        "Router lifetime in seconds (0 stands for a non-default gw)\n")
 {
+  int idx_number = 3;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
   int lifetime;
-  struct interface *ifp;
-  struct zebra_if *zif;
 
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
-
-  VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
+  VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[idx_number]->arg, 0, 9000);
 
   /* The value to be placed in the Router Lifetime field
    * of Router Advertisements sent from the interface,
@@ -1046,158 +1044,117 @@ DEFUN (ipv6_nd_ra_lifetime,
 
 DEFUN (no_ipv6_nd_ra_lifetime,
        no_ipv6_nd_ra_lifetime_cmd,
-       "no ipv6 nd ra-lifetime",
+       "no ipv6 nd ra-lifetime [(0-9000)]",
        NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
-       "Router lifetime\n")
+       "Router lifetime\n"
+       "Router lifetime in seconds (0 stands for a non-default gw)\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvDefaultLifetime = -1;
 
   return CMD_SUCCESS;
 }
 
-ALIAS (no_ipv6_nd_ra_lifetime,
-       no_ipv6_nd_ra_lifetime_val_cmd,
-       "no ipv6 nd ra-lifetime <0-9000>",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Router lifetime\n"
-       "Router lifetime in seconds (0 stands for a non-default gw)\n")
-
 DEFUN (ipv6_nd_reachable_time,
        ipv6_nd_reachable_time_cmd,
-       "ipv6 nd reachable-time <1-3600000>",
+       "ipv6 nd reachable-time (1-3600000)",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Reachable time\n"
        "Reachable time in milliseconds\n")
 {
-  struct interface *ifp = (struct interface *) vty->index;
+  int idx_number = 3;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
   struct zebra_if *zif = ifp->info;
-  VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
+  VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[idx_number]->arg, 1, RTADV_MAX_REACHABLE_TIME);
   return CMD_SUCCESS;
 }
 
 DEFUN (no_ipv6_nd_reachable_time,
        no_ipv6_nd_reachable_time_cmd,
-       "no ipv6 nd reachable-time",
+       "no ipv6 nd reachable-time [(1-3600000)]",
        NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
-       "Reachable time\n")
+       "Reachable time\n"
+       "Reachable time in milliseconds\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvReachableTime = 0;
 
   return CMD_SUCCESS;
 }
 
-ALIAS (no_ipv6_nd_reachable_time,
-       no_ipv6_nd_reachable_time_val_cmd,
-       "no ipv6 nd reachable-time <1-3600000>",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Reachable time\n"
-       "Reachable time in milliseconds\n")
-
 DEFUN (ipv6_nd_homeagent_preference,
        ipv6_nd_homeagent_preference_cmd,
-       "ipv6 nd home-agent-preference <0-65535>",
+       "ipv6 nd home-agent-preference (0-65535)",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Home Agent preference\n"
        "preference value (default is 0, least preferred)\n")
 {
-  struct interface *ifp = (struct interface *) vty->index;
+  int idx_number = 3;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
   struct zebra_if *zif = ifp->info;
-  VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
+  VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[idx_number]->arg, 0, 65535);
   return CMD_SUCCESS;
 }
 
 DEFUN (no_ipv6_nd_homeagent_preference,
        no_ipv6_nd_homeagent_preference_cmd,
-       "no ipv6 nd home-agent-preference",
+       "no ipv6 nd home-agent-preference [(0-65535)]",
        NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
-       "Home Agent preference\n")
+       "Home Agent preference\n"
+       "preference value (default is 0, least preferred)\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.HomeAgentPreference = 0;
 
   return CMD_SUCCESS;
 }
 
-ALIAS (no_ipv6_nd_homeagent_preference,
-       no_ipv6_nd_homeagent_preference_val_cmd,
-       "no ipv6 nd home-agent-preference <0-65535>",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Home Agent preference\n"
-       "preference value (default is 0, least preferred)\n")
-
 DEFUN (ipv6_nd_homeagent_lifetime,
        ipv6_nd_homeagent_lifetime_cmd,
-       "ipv6 nd home-agent-lifetime <0-65520>",
+       "ipv6 nd home-agent-lifetime (0-65520)",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Home Agent lifetime\n"
        "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
 {
-  struct interface *ifp = (struct interface *) vty->index;
+  int idx_number = 3;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
   struct zebra_if *zif = ifp->info;
-  VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
+  VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[idx_number]->arg, 0, RTADV_MAX_HALIFETIME);
   return CMD_SUCCESS;
 }
 
 DEFUN (no_ipv6_nd_homeagent_lifetime,
        no_ipv6_nd_homeagent_lifetime_cmd,
-       "no ipv6 nd home-agent-lifetime",
+       "no ipv6 nd home-agent-lifetime [(0-65520)]",
        NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
-       "Home Agent lifetime\n")
+       "Home Agent lifetime\n"
+       "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.HomeAgentLifetime = -1;
 
   return CMD_SUCCESS;
 }
 
-ALIAS (no_ipv6_nd_homeagent_lifetime,
-       no_ipv6_nd_homeagent_lifetime_val_cmd,
-       "no ipv6 nd home-agent-lifetime <0-65520>",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Home Agent lifetime\n"
-       "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
-
 DEFUN (ipv6_nd_managed_config_flag,
        ipv6_nd_managed_config_flag_cmd,
        "ipv6 nd managed-config-flag",
@@ -1205,11 +1162,8 @@ DEFUN (ipv6_nd_managed_config_flag,
        "Neighbor discovery\n"
        "Managed address configuration flag\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvManagedFlag = 1;
 
@@ -1224,11 +1178,8 @@ DEFUN (no_ipv6_nd_managed_config_flag,
        "Neighbor discovery\n"
        "Managed address configuration flag\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvManagedFlag = 0;
 
@@ -1242,11 +1193,8 @@ DEFUN (ipv6_nd_homeagent_config_flag,
        "Neighbor discovery\n"
        "Home Agent configuration flag\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvHomeAgentFlag = 1;
 
@@ -1261,11 +1209,8 @@ DEFUN (no_ipv6_nd_homeagent_config_flag,
        "Neighbor discovery\n"
        "Home Agent configuration flag\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvHomeAgentFlag = 0;
 
@@ -1279,11 +1224,8 @@ DEFUN (ipv6_nd_adv_interval_config_option,
        "Neighbor discovery\n"
        "Advertisement Interval Option\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvIntervalOption = 1;
 
@@ -1298,11 +1240,8 @@ DEFUN (no_ipv6_nd_adv_interval_config_option,
        "Neighbor discovery\n"
        "Advertisement Interval Option\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvIntervalOption = 0;
 
@@ -1316,11 +1255,8 @@ DEFUN (ipv6_nd_other_config_flag,
        "Neighbor discovery\n"
        "Other statefull configuration flag\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvOtherConfigFlag = 1;
 
@@ -1335,11 +1271,8 @@ DEFUN (no_ipv6_nd_other_config_flag,
        "Neighbor discovery\n"
        "Other statefull configuration flag\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.AdvOtherConfigFlag = 0;
 
@@ -1348,8 +1281,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|) (router-address|)",
+       "ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Prefix information\n"
@@ -1358,79 +1290,75 @@ DEFUN (ipv6_nd_prefix,
        "Infinite valid lifetime\n"
        "Preferred lifetime in seconds\n"
        "Infinite preferred lifetime\n"
+       "Set Router Address flag\n"
        "Do not use prefix for onlink determination\n"
        "Do not use prefix for autoconfiguration\n"
-       "Set Router Address flag\n")
+       "Do not use prefix for autoconfiguration\n"
+       "Do not use prefix for onlink determination\n")
 {
-  int i;
+  /* prelude */
+  char *prefix = argv[3]->arg;
+  int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN || strmatch (argv[4]->text, "infinite"));
+  int routeropts = lifetimes ? argc > 6 : argc > 4;
+
+  int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0;
+
+  char *lifetime = NULL, *preflifetime = NULL;
+  int routeraddr = 0, offlink = 0, noautoconf = 0;
+  if (lifetimes)
+  {
+    lifetime     = argv[4]->type == RANGE_TKN ? argv[4]->arg : argv[4]->text;
+    preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg : argv[5]->text;
+  }
+  if (routeropts)
+  {
+    routeraddr = strmatch (argv[idx_routeropts]->text, "router-address");
+    if (!routeraddr)
+    {
+      offlink    = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "off-link"));
+      noautoconf = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "no-autoconfig"));
+    }
+  }
+
+  /* business */
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zebra_if = ifp->info;
   int ret;
-  int cursor = 1;
-  struct interface *ifp;
-  struct zebra_if *zebra_if;
   struct rtadv_prefix rp;
 
-  ifp = (struct interface *) vty->index;
-  zebra_if = ifp->info;
-
-  ret = str2prefix_ipv6 (argv[0], &rp.prefix);
+  ret = str2prefix_ipv6 (prefix, &rp.prefix);
   if (!ret)
     {
       vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
   apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
-  rp.AdvOnLinkFlag = 1;
-  rp.AdvAutonomousFlag = 1;
-  rp.AdvRouterAddressFlag = 0;
+  rp.AdvOnLinkFlag = !offlink;
+  rp.AdvAutonomousFlag = !noautoconf;
+  rp.AdvRouterAddressFlag = routeraddr;
   rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
   rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
 
-  if (argc > 1)
-    {
-      if ((isdigit(argv[1][0])) || strncmp (argv[1], "i", 1) == 0)
-       {
-         if ( strncmp (argv[1], "i", 1) == 0)
-           rp.AdvValidLifetime = UINT32_MAX;
-         else
-           rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
-               (char **)NULL, 10);
-      
-         if ( strncmp (argv[2], "i", 1) == 0)
-           rp.AdvPreferredLifetime = UINT32_MAX;
-         else
-           rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
-               (char **)NULL, 10);
-
-         if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
-           {
-             vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
-             return CMD_WARNING;
-           }
-         cursor = cursor + 2;
-       }
-      if (argc > cursor)
-       {
-         for (i = cursor; i < argc; i++)
-           {
-             if (strncmp (argv[i], "of", 2) == 0)
-               rp.AdvOnLinkFlag = 0;
-             if (strncmp (argv[i], "no", 2) == 0)
-               rp.AdvAutonomousFlag = 0;
-             if (strncmp (argv[i], "ro", 2) == 0)
-               rp.AdvRouterAddressFlag = 1;
-           }
-       }
-    }
+  if (lifetimes)
+  {
+    rp.AdvValidLifetime     = strmatch (lifetime, "infinite") ? UINT32_MAX : strtoll (lifetime, NULL, 10);
+    rp.AdvPreferredLifetime = strmatch (preflifetime, "infinite") ? UINT32_MAX : strtoll (preflifetime, NULL, 10);
+    if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
+      {
+        vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
+        return CMD_WARNING;
+      }
+  }
 
   rtadv_prefix_set (zebra_if, &rp);
 
   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|)",
+DEFUN (no_ipv6_nd_prefix,
+       no_ipv6_nd_prefix_cmd,
+       "no ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]",
+        NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Prefix information\n"
@@ -1439,168 +1367,19 @@ ALIAS (ipv6_nd_prefix,
        "Infinite valid lifetime\n"
        "Preferred lifetime in seconds\n"
        "Infinite preferred lifetime\n"
+       "Set Router Address flag\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) "
-       "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
-       "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")
-
-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) "
-       "(<0-4294967295>|infinite) (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 autoconfiguration")
-
-ALIAS (ipv6_nd_prefix,
-       ipv6_nd_prefix_val_offlink_cmd,
-       "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
-       "(<0-4294967295>|infinite) (off-link|)",
-       "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")
-
-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) "
-       "(<0-4294967295>|infinite)",
-       "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")
-
-ALIAS (ipv6_nd_prefix,
-       ipv6_nd_prefix_noval_cmd,
-       "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
        "Do not use prefix for autoconfiguration\n"
        "Do not use prefix for onlink determination\n")
-
-ALIAS (ipv6_nd_prefix,
-       ipv6_nd_prefix_noval_rev_cmd,
-       "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
-       "Do not use prefix for onlink determination\n"
-       "Do not use prefix for autoconfiguration\n")
-
-ALIAS (ipv6_nd_prefix,
-       ipv6_nd_prefix_noval_noauto_cmd,
-       "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
-       "Do not use prefix for autoconfiguration\n")
-
-ALIAS (ipv6_nd_prefix,
-       ipv6_nd_prefix_noval_offlink_cmd,
-       "ipv6 nd prefix X:X::X:X/M (off-link|)",
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "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",
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n")
-
-DEFUN (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_cmd,
-       "no ipv6 nd prefix IPV6PREFIX",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n")
 {
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zebra_if = ifp->info;
   int ret;
-  struct interface *ifp;
-  struct zebra_if *zebra_if;
   struct rtadv_prefix rp;
+  char *prefix = argv[4]->arg;
 
-  ifp = (struct interface *) vty->index;
-  zebra_if = ifp->info;
-
-  ret = str2prefix_ipv6 (argv[0], &rp.prefix);
+  ret = str2prefix_ipv6 (prefix, &rp.prefix);
   if (!ret)
     {
       vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
@@ -1611,170 +1390,16 @@ DEFUN (no_ipv6_nd_prefix,
   ret = rtadv_prefix_reset (zebra_if, &rp);
   if (!ret)
     {
-      vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
+      vty_out (vty, "Non-existant IPv6 prefix%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
 
   return CMD_SUCCESS;
 }
 
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_val_nortaddr_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
-       NO_STR
-       "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"
-       "Set Router Address flag\n")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_val_rev_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
-       NO_STR
-       "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")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_val_rev_rtaddr_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
-       NO_STR
-       "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 (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_val_noauto_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
-       NO_STR
-       "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")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_val_offlink_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
-       NO_STR
-       "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")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_val_rtaddr_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
-       NO_STR
-       "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 (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_val_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
-       NO_STR
-       "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")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_noval_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
-       "Do not use prefix for autoconfiguration\n"
-       "Do not use prefix for onlink determination\n")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_noval_rev_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
-       "Do not use prefix for onlink determination\n"
-       "Do not use prefix for autoconfiguration\n")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_noval_noauto_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
-       "Do not use prefix for autoconfiguration\n")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_noval_offlink_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (off-link|)",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
-       "Do not use prefix for onlink determination\n")
-
-ALIAS (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_noval_rtaddr_cmd,
-       "no ipv6 nd prefix X:X::X:X/M (router-address|)",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
-       "Set Router Address flag\n")
-
 DEFUN (ipv6_nd_router_preference,
        ipv6_nd_router_preference_cmd,
-       "ipv6 nd router-preference (high|medium|low)",
+       "ipv6 nd router-preference <high|medium|low>",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Default router preference\n"
@@ -1782,16 +1407,14 @@ DEFUN (ipv6_nd_router_preference,
        "Low default router preference\n"
        "Medium default router preference (default)\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
+  int idx_high_medium_low = 3;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
   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)
+      if (strncmp (argv[idx_high_medium_low]->arg, rtadv_pref_strs[i], 1) == 0)
        {
          zif->rtadv.DefaultPreference = i;
          return CMD_SUCCESS;
@@ -1804,70 +1427,53 @@ DEFUN (ipv6_nd_router_preference,
 
 DEFUN (no_ipv6_nd_router_preference,
        no_ipv6_nd_router_preference_cmd,
-       "no ipv6 nd router-preference",
+       "no ipv6 nd router-preference [<high|medium|low>]",
        NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
-       "Default router preference\n")
+       "Default router preference\n"
+       "High default router preference\n"
+       "Medium default router preference (default)\n"
+       "Low default router preference\n")
 {
-  struct interface *ifp;
-  struct zebra_if *zif;
-
-  ifp = (struct interface *) vty->index;
-  zif = ifp->info;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
+  struct zebra_if *zif = ifp->info;
 
   zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
 
   return CMD_SUCCESS;
 }
 
-ALIAS (no_ipv6_nd_router_preference,
-       no_ipv6_nd_router_preference_val_cmd,
-       "no ipv6 nd router-preference (high|medium|low)",
-       NO_STR
-       "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")
-
 DEFUN (ipv6_nd_mtu,
        ipv6_nd_mtu_cmd,
-       "ipv6 nd mtu <1-65535>",
+       "ipv6 nd mtu (1-65535)",
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Advertised MTU\n"
        "MTU in bytes\n")
 {
-  struct interface *ifp = (struct interface *) vty->index;
+  int idx_number = 3;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
   struct zebra_if *zif = ifp->info;
-  VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
+  VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[idx_number]->arg, 1, 65535);
   return CMD_SUCCESS;
 }
 
 DEFUN (no_ipv6_nd_mtu,
        no_ipv6_nd_mtu_cmd,
-       "no ipv6 nd mtu",
+       "no ipv6 nd mtu [(1-65535)]",
        NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
-       "Advertised MTU\n")
+       "Advertised MTU\n"
+       "MTU in bytes\n")
 {
-  struct interface *ifp = (struct interface *) vty->index;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
   struct zebra_if *zif = ifp->info;
   zif->rtadv.AdvLinkMTU = 0;
   return CMD_SUCCESS;
 }
 
-ALIAS (no_ipv6_nd_mtu,
-       no_ipv6_nd_mtu_val_cmd,
-       "no ipv6 nd mtu <1-65535>",
-       NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Advertised MTU\n"
-       "MTU in bytes\n")
 
 /* Write configuration about router advertisement. */
 void
@@ -1876,7 +1482,7 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
   struct zebra_if *zif;
   struct listnode *node;
   struct rtadv_prefix *rprefix;
-  u_char buf[INET6_ADDRSTRLEN];
+  char buf[PREFIX_STRLEN];
   int interval;
 
   zif = ifp->info;
@@ -1884,16 +1490,8 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
   if (!(if_is_loopback (ifp) ||
         CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)))
     {
-      if (ipv6_address_configured(ifp))
-        {
-          if (! zif->rtadv.AdvSendAdvertisements)
-            vty_out (vty, " ipv6 nd suppress-ra%s", VTY_NEWLINE);
-        }
-      else
-        {
-          if (zif->rtadv.AdvSendAdvertisements)
-            vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
-        }
+      if (zif->rtadv.AdvSendAdvertisements)
+        vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
     }
   
   interval = zif->rtadv.MaxRtrAdvInterval;
@@ -1943,10 +1541,8 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
 
   for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
     {
-      vty_out (vty, " ipv6 nd prefix %s/%d",
-              inet_ntop (AF_INET6, &rprefix->prefix.prefix,
-                         (char *) buf, INET6_ADDRSTRLEN),
-              rprefix->prefix.prefixlen);
+      vty_out (vty, " ipv6 nd prefix %s",
+               prefix2str (&rprefix->prefix, buf, sizeof(buf)));
       if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) || 
          (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME))
        {
@@ -2044,14 +1640,10 @@ rtadv_cmd_init (void)
   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, &no_ipv6_nd_ra_interval_val_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd);
   install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
   install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
   install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
   install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
@@ -2060,45 +1652,16 @@ rtadv_cmd_init (void)
   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, &no_ipv6_nd_homeagent_preference_val_cmd);
   install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_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);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_nortaddr_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_noauto_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_offlink_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rtaddr_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rev_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_noauto_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_offlink_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rtaddr_cmd);
   install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
   install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
-  install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
 }
 
 static int