Merge svn revision 855 from Zebra repository.
diff --git a/ospf6d/ChangeLog b/ospf6d/ChangeLog
index 96490b0..a29b274 100644
--- a/ospf6d/ChangeLog
+++ b/ospf6d/ChangeLog
@@ -1,3 +1,9 @@
+2004-07-06  Yasuhiro Ohara  <yasu@sfc.wide.ad.jp>
+
+	* ospf6_message.c, ospf6_interface.c: add a command to configure
+	ospf6 ifmtu on a interface.
+	* ospf6d.h: version 0.9.7d
+
 2004-05-18  Hasso Tepper <hasso@estpak.ee>
 
 	* *.*: Merge rewritten ospf6d from Zebra repository.
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 9a02920..aea5f42 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -141,16 +141,15 @@
   oi->state = OSPF6_INTERFACE_DOWN;
   oi->flag = 0;
 
-  /* Try to adust I/O buffer size with IfMtu */
+  /* Try to adjust I/O buffer size with IfMtu */
+  oi->ifmtu = ifp->mtu;
   iobuflen = ospf6_iobuf_size (ifp->mtu);
-  if (iobuflen < ifp->mtu)
+  if (oi->ifmtu > iobuflen)
     {
       zlog_info ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
                  ifp->name, iobuflen);
       oi->ifmtu = iobuflen;
     }
-  else
-    oi->ifmtu = ifp->mtu;
 
   oi->lsupdate_list = ospf6_lsdb_create ();
   oi->lsack_list = ospf6_lsdb_create ();
@@ -270,16 +269,16 @@
   if (oi == NULL)
     return;
 
-  /* Try to adust I/O buffer size with IfMtu */
+  /* Try to adjust I/O buffer size with IfMtu */
+  if (oi->ifmtu == 0)
+    oi->ifmtu = ifp->mtu;
   iobuflen = ospf6_iobuf_size (ifp->mtu);
-  if (iobuflen < ifp->mtu)
+  if (oi->ifmtu > iobuflen)
     {
       zlog_info ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
                  ifp->name, iobuflen);
       oi->ifmtu = iobuflen;
     }
-  else
-    oi->ifmtu = ifp->mtu;
 
   /* interface start */
   if (oi->area)
@@ -1041,6 +1040,67 @@
 
 
 /* interface variable set command */
+DEFUN (ipv6_ospf6_ifmtu,
+       ipv6_ospf6_ifmtu_cmd,
+       "ipv6 ospf6 ifmtu <1-65535>",
+       IP6_STR
+       OSPF6_STR
+       "Interface MTU\n"
+       "OSPFv3 Interface MTU\n"
+       )
+{
+  struct ospf6_interface *oi;
+  struct interface *ifp;
+  int ifmtu, iobuflen;
+  listnode node;
+  struct ospf6_neighbor *on;
+
+  ifp = (struct interface *) vty->index;
+  assert (ifp);
+
+  oi = (struct ospf6_interface *) ifp->info;
+  if (oi == NULL)
+    oi = ospf6_interface_create (ifp);
+  assert (oi);
+
+  ifmtu = strtol (argv[0], NULL, 10);
+
+  if (oi->ifmtu == ifmtu)
+    return CMD_SUCCESS;
+
+  if (ifp->mtu != 0 && ifp->mtu < ifmtu)
+    {
+      vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s",
+               ifp->name, ifp->mtu, VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if (oi->ifmtu < ifmtu)
+    {
+      iobuflen = ospf6_iobuf_size (ifmtu);
+      if (iobuflen < ifmtu)
+        {
+          vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
+                   ifp->name, iobuflen, VTY_NEWLINE);
+          oi->ifmtu = iobuflen;
+        }
+      else
+        oi->ifmtu = ifmtu;
+    }
+  else
+    oi->ifmtu = ifmtu;
+
+  /* re-establish adjacencies */
+  for (node = listhead (oi->neighbor_list); node; nextnode (node))
+    {
+      on = (struct ospf6_neighbor *) getdata (node);
+      THREAD_OFF (on->inactivity_timer);
+      thread_execute (master, inactivity_timer, on, 0);
+    }
+
+  return CMD_SUCCESS;
+}
+
 DEFUN (ipv6_ospf6_cost,
        ipv6_ospf6_cost_cmd,
        "ipv6 ospf6 cost <1-65535>",
@@ -1392,6 +1452,8 @@
       if (ifp->desc)
         vty_out (vty, " description %s%s", ifp->desc, VTY_NEWLINE);
 
+      if (ifp->mtu != oi->ifmtu)
+        vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VTY_NEWLINE);
       vty_out (vty, " ipv6 ospf6 cost %d%s",
                oi->cost, VTY_NEWLINE);
       vty_out (vty, " ipv6 ospf6 hello-interval %d%s",
@@ -1453,6 +1515,7 @@
   install_element (INTERFACE_NODE, &interface_desc_cmd);
   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
+  install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 19ea2c7..71ff362 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -1119,6 +1119,10 @@
   sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
   if (recvnew == NULL || sendnew == NULL)
     {
+      if (recvnew)
+        XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
+      if (sendnew)
+        XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
       zlog_info ("Could not allocate I/O buffer of size %d.", size);
       return iobuflen;
     }
diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h
index 9e261bc..69d62d9 100644
--- a/ospf6d/ospf6d.h
+++ b/ospf6d/ospf6d.h
@@ -22,7 +22,7 @@
 #ifndef OSPF6D_H
 #define OSPF6D_H
 
-#define OSPF6_DAEMON_VERSION    "0.9.7c"
+#define OSPF6_DAEMON_VERSION    "0.9.7d"
 
 /* global variables */
 extern int errno;