]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Multi-Instance OSPF Summary
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:03:42 +0000 (18:03 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:03:42 +0000 (18:03 -0700)
——————————————-------------

- etc/init.d/quagga is modified to support creating separate ospf daemon
  process for each instance. Each individual instance is monitored by
  watchquagga just like any protocol daemons.(requires initd-mi.patch).

- Vtysh is modified to able to connect to multiple daemons of the same
  protocol (supported for OSPF only for now).

- ospfd is modified to remember the Instance-ID that its invoked with. For
  the entire life of the process it caters to any command request that
  matches that instance-ID (unless its a non instance specific command).
  Routes/messages to zebra are tagged with instance-ID.

- zebra route/redistribute mechanisms are modified to work with
  [protocol type + instance-id]

- bgpd now has ability to have multiple instance specific redistribution
  for a protocol (OSPF only supported/tested for now).

- zlog ability to display instance-id besides the protocol/daemon name.

- Changes in other daemons are to because of the needed integration with
  some of the modified APIs/routines. (Didn’t prefer replicating too many
  separate instance specific APIs.)

- config/show/debug commands are modified to take instance-id argument
  as appropriate.

Guidelines to start using multi-instance ospf
---------------------------------------------

The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.

To enable multiple instances, do the following:

     1. service quagga stop
     2. Modify /etc/quagga/daemons to add instance-ids of each desired
        instance in the following format:
        ospfd=“yes"
        ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
     3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
        and ospfd-3.conf.
     4. service quagga start/restart
     5. Verify that the deamons are started as expected. You should see
        ospfd started with -n <instance-id> option.
      ps –ef | grep quagga
      With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
     6. vtysh to work with instances as you would with any other deamons.
     7. Overall most quagga semantics are the same working with the instance
      deamon, like it is for any other daemon.

NOTE:
     To safeguard against errors leading to too many processes getting invoked,
     a hard limit on number of instance-ids is in place, currently its 5.
     Allowed instance-id range is <1-65535>
     Once daemons are up, show running from vtysh should show the instance-id
     of  each daemon as 'router ospf <instance-id>’  (without needing explicit
     configuration)
     Instance-id can not be changed via vtysh, other router ospf configuration
     is allowed as before.

Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
60 files changed:
babeld/babel_main.c
babeld/babel_zebra.c
babeld/babeld.c
bgpd/bgp_main.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgp_zebra.h
bgpd/bgpd.c
bgpd/bgpd.h
isisd/isis_main.c
isisd/isis_zebra.c
lib/log.c
lib/log.h
lib/routemap.c
lib/zclient.c
lib/zclient.h
ospf6d/ospf6_main.c
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospfd/ospf_asbr.c
ospfd/ospf_asbr.h
ospfd/ospf_dump.c
ospfd/ospf_flood.c
ospfd/ospf_lsa.c
ospfd/ospf_lsa.h
ospfd/ospf_main.c
ospfd/ospf_nsm.c
ospfd/ospf_opaque.c
ospfd/ospf_packet.c
ospfd/ospf_routemap.c
ospfd/ospf_te.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospf_zebra.h
ospfd/ospfd.c
ospfd/ospfd.h
ripd/rip_main.c
ripd/rip_zebra.c
ripngd/ripng_main.c
ripngd/ripng_zebra.c
tests/test-sig.c
vtysh/extract.pl.in
vtysh/vtysh.c
watchquagga/watchquagga.c
zebra/connected.c
zebra/kernel_socket.c
zebra/main.c
zebra/redistribute.c
zebra/rib.h
zebra/rt_netlink.c
zebra/rtread_getmsg.c
zebra/rtread_proc.c
zebra/test_main.c
zebra/zebra_rib.c
zebra/zebra_vty.c
zebra/zserv.c
zebra/zserv.h

index 529c3f2959a6b734c957352793b051d1c72a29af..0b3e549f3858ce44fb4dc5d2a5712a4ea135a56e 100644 (file)
@@ -187,7 +187,7 @@ babel_init(int argc, char **argv)
     progname = babel_get_progname(argv[0]);
 
     /* set default log (lib/log.h) */
-    zlog_default = openzlog(progname, ZLOG_BABEL,
+    zlog_default = openzlog(progname, ZLOG_BABEL, 0,
                             LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
     /* set log destination as stdout until the config file is read */
     zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);
index 75a1e6a849b252a2f083cda9ca1298723d615d4d..f584e0396e7f4beed6ca57ab5dd8b213b6e1e74e 100644 (file)
@@ -99,6 +99,7 @@ babel_zebra_read_ipv6 (int command, struct zclient *zclient,
 
     /* Type, flags, message. */
     api.type = stream_getc (s);
+    api.instance = stream_getw (s);
     api.flags = stream_getc (s);
     api.message = stream_getc (s);
 
@@ -151,6 +152,7 @@ babel_zebra_read_ipv4 (int command, struct zclient *zclient,
 
     /* Type, flags, message. */
     api.type = stream_getc (s);
+    api.instance = stream_getw (s);
     api.flags = stream_getc (s);
     api.message = stream_getc (s);
 
@@ -205,7 +207,7 @@ DEFUN (babel_redistribute_type,
         return CMD_WARNING;
     }
 
-    zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+    zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
     return CMD_SUCCESS;
 }
 
@@ -229,7 +231,7 @@ DEFUN (no_babel_redistribute_type,
         return CMD_WARNING;
     }
 
-    zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
+    zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, 0);
     /* perhaps should we remove xroutes having the same type... */
     return CMD_SUCCESS;
 }
@@ -332,7 +334,7 @@ debug_babel_config_write (struct vty * vty)
 void babelz_zebra_init(void)
 {
     zclient = zclient_new();
-    zclient_init(zclient, ZEBRA_ROUTE_BABEL);
+    zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
 
     zclient->interface_add = babel_interface_add;
     zclient->interface_delete = babel_interface_delete;
@@ -362,7 +364,7 @@ zebra_config_write (struct vty *vty)
         vty_out (vty, "no router zebra%s", VTY_NEWLINE);
         return 1;
     }
-    else if (! zclient->redist[ZEBRA_ROUTE_BABEL])
+    else if (! zclient->redist[ZEBRA_ROUTE_BABEL].enabled)
     {
         vty_out (vty, "router zebra%s", VTY_NEWLINE);
         vty_out (vty, " no redistribute babel%s", VTY_NEWLINE);
index 1ae3f042c8e39e718b9e2fa9fcf5c4b0bd58913f..334f64c311207cd1b3883a7249fab0206832be16 100644 (file)
@@ -111,7 +111,8 @@ babel_config_write (struct vty *vty)
     lines = 1 + babel_enable_if_config_write (vty);
     /* list redistributed protocols */
     for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-        if (i != zclient->redist_default && zclient->redist[i])
+        if (i != zclient->redist_default &&
+            zclient->redist[i].enabled)
         {
             vty_out (vty, " redistribute %s%s", zebra_route_string (i), VTY_NEWLINE);
             lines++;
index 62fcb64d6aba23e916c2e04cc53bead2fb2b500b..234f17d1f90ab2e9ddd8b0853c1b11c370b0ddd1 100644 (file)
@@ -324,7 +324,7 @@ main (int argc, char **argv)
   /* Preserve name of myself. */
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
-  zlog_default = openzlog (progname, ZLOG_BGP,
+  zlog_default = openzlog (progname, ZLOG_BGP, 0,
                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
 
   /* BGP master init. */
index 24a46c04d6f552cdaa2e42cd07a6fbeea8b7bb1d..cb10cf2e6437972734147e36fc0e1c6b1893808f 100644 (file)
@@ -2044,7 +2044,7 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
 }
 
 static struct bgp_info *
-info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
+info_make (int type, int sub_type, u_short instance, struct peer *peer, struct attr *attr,
           struct bgp_node *rn)
 {
   struct bgp_info *new;
@@ -2052,6 +2052,7 @@ info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
   /* Make new BGP info. */
   new = XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
   new->type = type;
+  new->instance = instance;
   new->sub_type = sub_type;
   new->peer = peer;
   new->attr = attr;
@@ -2205,7 +2206,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
                   p->prefixlen, rsclient->host);
     }
 
-  new = info_make(type, sub_type, peer, attr_new, rn);
+  new = info_make(type, sub_type, 0, peer, attr_new, rn);
 
   /* Update MPLS tag. */
   if (safi == SAFI_MPLS_VPN)
@@ -2546,7 +2547,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
     }
 
   /* Make new BGP info. */
-  new = info_make(type, sub_type, peer, attr_new, rn);
+  new = info_make(type, sub_type, 0, peer, attr_new, rn);
 
   /* Update MPLS tag. */
   if (safi == SAFI_MPLS_VPN)
@@ -3671,7 +3672,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
     }
 
   /* Make new BGP info. */
-  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self,
+  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
                  attr_new, rn);
   /* Nexthop reachability check. */
   if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
@@ -3821,7 +3822,7 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
     }
 
   /* Make new BGP info. */
-  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self, attr_new,
+  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
                  rn);
   /* Nexthop reachability check. */
   if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
@@ -3886,7 +3887,7 @@ bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
 
   /* Make new BGP info. */
-  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self,
+  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
                  bgp_attr_default_intern(BGP_ORIGIN_IGP), rn);
 
   SET_FLAG (new->flags, BGP_INFO_VALID);
@@ -5041,7 +5042,7 @@ bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
   if (aggregate->count > 0)
     {
       rn = bgp_node_get (table, p);
-      new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, bgp->peer_self,
+      new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
                      bgp_attr_aggregate_intern(bgp, origin, aspath, community,
                                                aggregate->as_set,
                                                 atomic_aggregate), rn);
@@ -5236,7 +5237,7 @@ bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
   if (aggregate->count)
     {
       rn = bgp_node_get (table, p);
-      new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, bgp->peer_self,
+      new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
                      bgp_attr_aggregate_intern(bgp, origin, aspath, community,
                                                aggregate->as_set,
                                                 atomic_aggregate), rn);
@@ -5766,7 +5767,7 @@ ALIAS (no_ipv6_aggregate_address_summary_only,
 void
 bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
                      const struct in6_addr *nexthop6, unsigned int ifindex,
-                     u_int32_t metric, u_char type, u_short tag)
+                     u_int32_t metric, u_char type, u_short instance, u_short tag)
 {
   struct bgp *bgp;
   struct listnode *node, *nnode;
@@ -5778,6 +5779,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
   struct attr *new_attr;
   afi_t afi;
   int ret;
+  struct bgp_redist *red;
 
   /* Make default attribute. */
   bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
@@ -5802,7 +5804,8 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
     {
       afi = family2afi (p->family);
 
-      if (bgp->redist[afi][type])
+      red = bgp_redist_lookup(bgp, afi, type, instance);
+      if (red)
        {
          struct attr attr_new;
          struct attr_extra extra_new;
@@ -5811,19 +5814,18 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
          attr_new.extra = &extra_new;
          bgp_attr_dup (&attr_new, &attr);
 
-         if (bgp->redist_metric_flag[afi][type])
-           attr_new.med = bgp->redist_metric[afi][type];
+         if (red->redist_metric_flag)
+           attr_new.med = red->redist_metric;
 
          /* Apply route-map. */
-         if (bgp->rmap[afi][type].map)
+         if (red->rmap.map)
            {
              info.peer = bgp->peer_self;
              info.attr = &attr_new;
 
               SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
 
-             ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
-                                    &info);
+             ret = route_map_apply (red->rmap.map, p, RMAP_BGP, &info);
 
               bgp->peer_self->rmap_type = 0;
 
@@ -5835,7 +5837,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
                  /* Unintern original. */
                  aspath_unintern (&attr.aspath);
                  bgp_attr_extra_free (&attr);
-                 bgp_redistribute_delete (p, type);
+                 bgp_redistribute_delete (p, type, instance);
                  return;
                }
            }
@@ -5885,7 +5887,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
                }
            }
 
-         new = info_make(type, BGP_ROUTE_REDISTRIBUTE, bgp->peer_self,
+         new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance, bgp->peer_self,
                          new_attr, bn);
          SET_FLAG (new->flags, BGP_INFO_VALID);
 
@@ -5902,19 +5904,21 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
 }
 
 void
-bgp_redistribute_delete (struct prefix *p, u_char type)
+bgp_redistribute_delete (struct prefix *p, u_char type, u_short instance)
 {
   struct bgp *bgp;
   struct listnode *node, *nnode;
   afi_t afi;
   struct bgp_node *rn;
   struct bgp_info *ri;
+  struct bgp_redist *red;
 
   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
     {
       afi = family2afi (p->family);
 
-      if (bgp->redist[afi][type])
+      red = bgp_redist_lookup(bgp, afi, type, instance);
+      if (red)
        {
          rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
 
@@ -5936,7 +5940,7 @@ bgp_redistribute_delete (struct prefix *p, u_char type)
 
 /* Withdraw specified route type's route. */
 void
-bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
+bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type, u_short instance)
 {
   struct bgp_node *rn;
   struct bgp_info *ri;
@@ -5948,7 +5952,8 @@ bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
     {
       for (ri = rn->info; ri; ri = ri->next)
        if (ri->peer == bgp->peer_self
-           && ri->type == type)
+           && ri->type == type
+            && ri->instance == instance)
          break;
 
       if (ri)
index 56d72c4e7abae740c169fb0bb8be9b7a65160a13..f452ea25430aa752a1e4b32a84b049b42922d338 100644 (file)
@@ -105,6 +105,9 @@ struct bgp_info
 #define BGP_ROUTE_STATIC       1
 #define BGP_ROUTE_AGGREGATE    2
 #define BGP_ROUTE_REDISTRIBUTE 3 
+
+  u_short instance;
+
 };
 
 /* BGP static route configuration. */
@@ -224,9 +227,9 @@ extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
 
 extern void bgp_redistribute_add (struct prefix *, const struct in_addr *,
                                  const struct in6_addr *, unsigned int ifindex,
-                                 u_int32_t, u_char, u_short);
-extern void bgp_redistribute_delete (struct prefix *, u_char);
-extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int);
+                                 u_int32_t, u_char, u_short, u_short);
+extern void bgp_redistribute_delete (struct prefix *, u_char, u_short);
+extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int, u_short);
 
 extern void bgp_static_delete (struct bgp *);
 extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,
index 2a88f0f082cfaeb1b593f9bd265b13b755daf074..2e68f31abc0032f6c701221085c4743f1813b0b9 100644 (file)
@@ -2791,7 +2791,7 @@ bgp_route_map_process_update (void *arg, char *rmap_name, int route_update)
   char buf[INET6_ADDRSTRLEN];
 
   if (!bgp)
-    return;
+    return (-1);
 
   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
     {
@@ -2875,20 +2875,31 @@ bgp_route_map_process_update (void *arg, char *rmap_name, int route_update)
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
     for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
       {
-       if (bgp->rmap[afi][i].name &&
-           (strcmp(rmap_name, bgp->rmap[afi][i].name) == 0))
-         {
-           bgp->rmap[afi][i].map =
-             route_map_lookup_by_name (bgp->rmap[afi][i].name);
-
-           if (bgp->redist[afi][i] && route_update)
-             {
-                if (BGP_DEBUG (zebra, ZEBRA))
-                 zlog_debug("Processing route_map %s update on "
-                            "redistributed routes", rmap_name);
-
-               bgp_redistribute_resend (bgp, afi, i);
-             }
+        struct list *red_list;
+        struct listnode *node;
+        struct bgp_redist *red;
+
+        red_list = bgp->redist[afi][i];
+        if (!red_list)
+            continue;
+
+        for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+          {
+            if (red->rmap.name &&
+                (strcmp(rmap_name, red->rmap.name) == 0))
+              {
+                red->rmap.map =
+                  route_map_lookup_by_name (red->rmap.name);
+
+                if (route_update)
+                  {
+                    if (bgp_debug_update(peer, NULL, 0))
+                      zlog_debug("Processing route_map %s update on "
+                                 "redistributed routes", rmap_name);
+
+                    bgp_redistribute_resend (bgp, afi, i, red->instance);
+                  }
+              }
          }
       }
 
index 92c402db547bbc5052aec413937a52be3162cd28..3c625755cd1a71e0c1bb4c27b114add3796c59f7 100644 (file)
@@ -9639,7 +9639,8 @@ DEFUN (bgp_redistribute_ipv4,
       vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
-  return bgp_redistribute_set (vty->index, AFI_IP, type);
+  bgp_redist_add(vty->index, AFI_IP, type, 0);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (bgp_redistribute_ipv4_rmap,
@@ -9651,6 +9652,7 @@ DEFUN (bgp_redistribute_ipv4_rmap,
        "Pointer to route-map entries\n")
 {
   int type;
+  struct bgp_redist *red;
 
   type = proto_redistnum (AFI_IP, argv[0]);
   if (type < 0 || type == ZEBRA_ROUTE_BGP)
@@ -9659,8 +9661,9 @@ DEFUN (bgp_redistribute_ipv4_rmap,
       return CMD_WARNING;
     }
 
-  bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[1]);
-  return bgp_redistribute_set (vty->index, AFI_IP, type);
+  red = bgp_redist_add(vty->index, AFI_IP, type, 0);
+  bgp_redistribute_rmap_set (red, argv[1]);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (bgp_redistribute_ipv4_metric,
@@ -9673,6 +9676,7 @@ DEFUN (bgp_redistribute_ipv4_metric,
 {
   int type;
   u_int32_t metric;
+  struct bgp_redist *red;
 
   type = proto_redistnum (AFI_IP, argv[0]);
   if (type < 0 || type == ZEBRA_ROUTE_BGP)
@@ -9682,8 +9686,9 @@ DEFUN (bgp_redistribute_ipv4_metric,
     }
   VTY_GET_INTEGER ("metric", metric, argv[1]);
 
-  bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
-  return bgp_redistribute_set (vty->index, AFI_IP, type);
+  red = bgp_redist_add(vty->index, AFI_IP, type, 0);
+  bgp_redistribute_metric_set (red, metric);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (bgp_redistribute_ipv4_rmap_metric,
@@ -9698,6 +9703,7 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
 {
   int type;
   u_int32_t metric;
+  struct bgp_redist *red;
 
   type = proto_redistnum (AFI_IP, argv[0]);
   if (type < 0 || type == ZEBRA_ROUTE_BGP)
@@ -9707,9 +9713,10 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
     }
   VTY_GET_INTEGER ("metric", metric, argv[2]);
 
-  bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[1]);
-  bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
-  return bgp_redistribute_set (vty->index, AFI_IP, type);
+  red = bgp_redist_add(vty->index, AFI_IP, type, 0);
+  bgp_redistribute_rmap_set (red, argv[1]);
+  bgp_redistribute_metric_set (red, metric);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (bgp_redistribute_ipv4_metric_rmap,
@@ -9724,6 +9731,7 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
 {
   int type;
   u_int32_t metric;
+  struct bgp_redist *red;
 
   type = proto_redistnum (AFI_IP, argv[0]);
   if (type < 0 || type == ZEBRA_ROUTE_BGP)
@@ -9733,11 +9741,171 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
     }
   VTY_GET_INTEGER ("metric", metric, argv[1]);
 
-  bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
-  bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[2]);
-  return bgp_redistribute_set (vty->index, AFI_IP, type);
+  red = bgp_redist_add(vty->index, AFI_IP, type, 0);
+  bgp_redistribute_metric_set (red, metric);
+  bgp_redistribute_rmap_set (red, argv[2]);
+  return bgp_redistribute_set (type, 0);
 }
 
+DEFUN (bgp_redistribute_ipv4_ospf,
+       bgp_redistribute_ipv4_ospf_cmd,
+       "redistribute ospf <1-65535>",
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n")
+{
+  u_short instance;
+
+  VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
+  bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
+  return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
+}
+
+DEFUN (bgp_redistribute_ipv4_ospf_rmap,
+       bgp_redistribute_ipv4_ospf_rmap_cmd,
+       "redistribute ospf <1-65535> route-map WORD",
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+{
+  struct bgp_redist *red;
+  u_short instance;
+
+  VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
+  red = bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
+  bgp_redistribute_rmap_set (red, argv[1]);
+  return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
+}
+
+DEFUN (bgp_redistribute_ipv4_ospf_metric,
+       bgp_redistribute_ipv4_ospf_metric_cmd,
+       "redistribute ospf <1-65535> metric <0-4294967295>",
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n")
+{
+  u_int32_t metric;
+  struct bgp_redist *red;
+  u_short instance;
+
+  VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
+  VTY_GET_INTEGER ("metric", metric, argv[1]);
+
+  red = bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
+  bgp_redistribute_metric_set (red, metric);
+  return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
+}
+
+DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
+       bgp_redistribute_ipv4_ospf_rmap_metric_cmd,
+       "redistribute ospf <1-65535> route-map WORD metric <0-4294967295>",
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n")
+{
+  u_int32_t metric;
+  struct bgp_redist *red;
+  u_short instance;
+
+  VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
+  VTY_GET_INTEGER ("metric", metric, argv[2]);
+
+  red = bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
+  bgp_redistribute_rmap_set (red, argv[1]);
+  bgp_redistribute_metric_set (red, metric);
+  return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
+}
+
+DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
+       bgp_redistribute_ipv4_ospf_metric_rmap_cmd,
+       "redistribute ospf <1-65535> metric <0-4294967295> route-map WORD",
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+{
+  u_int32_t metric;
+  struct bgp_redist *red;
+  u_short instance;
+
+  VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
+  VTY_GET_INTEGER ("metric", metric, argv[1]);
+
+  red = bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
+  bgp_redistribute_metric_set (red, metric);
+  bgp_redistribute_rmap_set (red, argv[2]);
+  return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
+}
+
+DEFUN (no_bgp_redistribute_ipv4_ospf,
+       no_bgp_redistribute_ipv4_ospf_cmd,
+       "no redistribute ospf <1-65535>",
+       NO_STR
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n")
+{
+  u_short instance;
+
+  VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
+  return bgp_redistribute_unset (vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
+}
+
+ALIAS (no_bgp_redistribute_ipv4_ospf,
+       no_bgp_redistribute_ipv4_ospf_rmap_cmd,
+       "no redistribute ospf <1-65535> route-map WORD",
+       NO_STR
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+
+ALIAS (no_bgp_redistribute_ipv4_ospf,
+       no_bgp_redistribute_ipv4_ospf_metric_cmd,
+       "no redistribute ospf <1-65535> metric <0-4294967295>",
+       NO_STR
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n")
+
+ALIAS (no_bgp_redistribute_ipv4_ospf,
+       no_bgp_redistribute_ipv4_ospf_rmap_metric_cmd,
+       "no redistribute ospf <1-65535> route-map WORD metric <0-4294967295>",
+       NO_STR
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n")
+
+ALIAS (no_bgp_redistribute_ipv4_ospf,
+       no_bgp_redistribute_ipv4_ospf_metric_rmap_cmd,
+       "no redistribute ospf <1-65535> metric <0-4294967295> route-map WORD",
+       NO_STR
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+
 DEFUN (no_bgp_redistribute_ipv4,
        no_bgp_redistribute_ipv4_cmd,
        "no redistribute " QUAGGA_IP_REDIST_STR_BGPD,
@@ -9753,8 +9921,7 @@ DEFUN (no_bgp_redistribute_ipv4,
       vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
-
-  return bgp_redistribute_unset (vty->index, AFI_IP, type);
+  return bgp_redistribute_unset (vty->index, AFI_IP, type, 0);
 }
 
 ALIAS (no_bgp_redistribute_ipv4,
@@ -9813,7 +9980,8 @@ DEFUN (bgp_redistribute_ipv6,
       return CMD_WARNING;
     }
 
-  return bgp_redistribute_set (vty->index, AFI_IP6, type);
+  bgp_redist_add(vty->index, AFI_IP6, type, 0);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (bgp_redistribute_ipv6_rmap,
@@ -9825,6 +9993,7 @@ DEFUN (bgp_redistribute_ipv6_rmap,
        "Pointer to route-map entries\n")
 {
   int type;
+  struct bgp_redist *red;
 
   type = proto_redistnum (AFI_IP6, argv[0]);
   if (type < 0 || type == ZEBRA_ROUTE_BGP)
@@ -9833,8 +10002,9 @@ DEFUN (bgp_redistribute_ipv6_rmap,
       return CMD_WARNING;
     }
 
-  bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[1]);
-  return bgp_redistribute_set (vty->index, AFI_IP6, type);
+  red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
+  bgp_redistribute_rmap_set (red, argv[1]);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (bgp_redistribute_ipv6_metric,
@@ -9847,6 +10017,7 @@ DEFUN (bgp_redistribute_ipv6_metric,
 {
   int type;
   u_int32_t metric;
+  struct bgp_redist *red;
 
   type = proto_redistnum (AFI_IP6, argv[0]);
   if (type < 0 || type == ZEBRA_ROUTE_BGP)
@@ -9856,8 +10027,9 @@ DEFUN (bgp_redistribute_ipv6_metric,
     }
   VTY_GET_INTEGER ("metric", metric, argv[1]);
 
-  bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
-  return bgp_redistribute_set (vty->index, AFI_IP6, type);
+  red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
+  bgp_redistribute_metric_set (red, metric);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (bgp_redistribute_ipv6_rmap_metric,
@@ -9872,6 +10044,7 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
 {
   int type;
   u_int32_t metric;
+  struct bgp_redist *red;
 
   type = proto_redistnum (AFI_IP6, argv[0]);
   if (type < 0 || type == ZEBRA_ROUTE_BGP)
@@ -9881,9 +10054,10 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
     }
   VTY_GET_INTEGER ("metric", metric, argv[2]);
 
-  bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[1]);
-  bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
-  return bgp_redistribute_set (vty->index, AFI_IP6, type);
+  red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
+  bgp_redistribute_rmap_set (red, argv[1]);
+  bgp_redistribute_metric_set (red, metric);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (bgp_redistribute_ipv6_metric_rmap,
@@ -9898,6 +10072,7 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
 {
   int type;
   u_int32_t metric;
+  struct bgp_redist *red;
 
   type = proto_redistnum (AFI_IP6, argv[0]);
   if (type < 0 || type == ZEBRA_ROUTE_BGP)
@@ -9907,9 +10082,10 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
     }
   VTY_GET_INTEGER ("metric", metric, argv[1]);
 
-  bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
-  bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[2]);
-  return bgp_redistribute_set (vty->index, AFI_IP6, type);
+  red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
+  bgp_redistribute_metric_set (red, metric);
+  bgp_redistribute_rmap_set (red, argv[2]);
+  return bgp_redistribute_set (type, 0);
 }
 
 DEFUN (no_bgp_redistribute_ipv6,
@@ -9928,7 +10104,7 @@ DEFUN (no_bgp_redistribute_ipv6,
       return CMD_WARNING;
     }
 
-  return bgp_redistribute_unset (vty->index, AFI_IP6, type);
+  return bgp_redistribute_unset (vty->index, AFI_IP6, type, 0);
 }
 
 ALIAS (no_bgp_redistribute_ipv6,
@@ -9985,21 +10161,31 @@ bgp_config_write_redistribute (struct vty *vty, struct bgp *bgp, afi_t afi,
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
     {
       /* Redistribute BGP does not make sense.  */
-      if (bgp->redist[afi][i] && i != ZEBRA_ROUTE_BGP)
+      if (i != ZEBRA_ROUTE_BGP)
        {
-         /* Display "address-family" when it is not yet diplayed.  */
-         bgp_config_write_family_header (vty, afi, safi, write);
-
-         /* "redistribute" configuration.  */
-         vty_out (vty, " redistribute %s", zebra_route_string(i));
-
-         if (bgp->redist_metric_flag[afi][i])
-           vty_out (vty, " metric %u", bgp->redist_metric[afi][i]);
+          struct list *red_list;
+          struct listnode *node;
+          struct bgp_redist *red;
 
-         if (bgp->rmap[afi][i].name)
-           vty_out (vty, " route-map %s", bgp->rmap[afi][i].name);
+          red_list = bgp->redist[afi][i];
+          if (!red_list)
+            continue;
 
-         vty_out (vty, "%s", VTY_NEWLINE);
+          for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+            {
+              /* Display "address-family" when it is not yet diplayed.  */
+              bgp_config_write_family_header (vty, afi, safi, write);
+
+              /* "redistribute" configuration.  */
+              vty_out (vty, " redistribute %s", zebra_route_string(i));
+              if (red->instance)
+                vty_out (vty, " %d", red->instance);
+              if (red->redist_metric_flag)
+                vty_out (vty, " metric %u", red->redist_metric);
+              if (red->rmap.name)
+                vty_out (vty, " route-map %s", red->rmap.name);
+              vty_out (vty, "%s", VTY_NEWLINE);
+            }
        }
     }
   return *write;
@@ -11264,6 +11450,16 @@ bgp_vty_init (void)
   install_element (BGP_NODE, &bgp_redistribute_ipv4_metric_rmap_cmd);
   install_element (BGP_NODE, &no_bgp_redistribute_ipv4_rmap_metric_cmd);
   install_element (BGP_NODE, &no_bgp_redistribute_ipv4_metric_rmap_cmd);
+  install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_cmd);
+  install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_cmd);
+  install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_cmd);
+  install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_rmap_cmd);
+  install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_cmd);
+  install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_metric_cmd);
+  install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
+  install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
+  install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
+  install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
 #ifdef HAVE_IPV6
   install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_cmd);
   install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_cmd);
index d2787ec820d4f3e893155d32e9efed2c53e06a50..386de45ede438e97068c2bc0006aa7cc7c6f734d 100644 (file)
@@ -428,6 +428,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
 
   /* Type, flags, message. */
   api.type = stream_getc (s);
+  api.instance = stream_getw (s);
   api.flags = stream_getc (s);
   api.message = stream_getc (s);
 
@@ -468,8 +469,8 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
       if (bgp_debug_zebra(&p))
        {
          char buf[2][INET_ADDRSTRLEN];
-         zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u tag %d",
-                    zebra_route_string(api.type),
+         zlog_debug("Zebra rcvd: IPv4 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
+                    zebra_route_string(api.type), api.instance,
                     inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
                     p.prefixlen,
                     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
@@ -477,23 +478,23 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
                     api.tag);
        }
       bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
-                          api.metric, api.type, api.tag);
+                          api.metric, api.type, api.instance, api.tag);
     }
   else
     {
       if (bgp_debug_zebra(&p))
        {
          char buf[2][INET_ADDRSTRLEN];
-         zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
+         zlog_debug("Zebra rcvd: IPv4 route delete %s[%d] %s/%d "
                     "nexthop %s metric %u tag %d",
-                    zebra_route_string(api.type),
+                    zebra_route_string(api.type), api.instance,
                     inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
                     p.prefixlen,
                     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
                     api.metric,
                     api.tag);
        }
-      bgp_redistribute_delete((struct prefix *)&p, api.type);
+      bgp_redistribute_delete((struct prefix *)&p, api.type, api.instance);
     }
 
   return 0;
@@ -515,6 +516,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
 
   /* Type, flags, message. */
   api.type = stream_getc (s);
+  api.instance = stream_getw (s);
   api.flags = stream_getc (s);
   api.message = stream_getc (s);
 
@@ -561,8 +563,8 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
       if (bgp_debug_zebra(&p))
        {
          char buf[2][INET6_ADDRSTRLEN];
-         zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u tag %d",
-                    zebra_route_string(api.type),
+         zlog_debug("Zebra rcvd: IPv6 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
+                    zebra_route_string(api.type), api.instance,
                     inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
                     p.prefixlen,
                     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
@@ -570,23 +572,23 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
                     api.tag);
        }
       bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
-                           api.metric, api.type, api.tag);
+                           api.metric, api.type, api.instance, api.tag);
     }
   else
     {
       if (bgp_debug_zebra(&p))
        {
          char buf[2][INET6_ADDRSTRLEN];
-         zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
+         zlog_debug("Zebra rcvd: IPv6 route delete %s[%d] %s/%d "
                     "nexthop %s metric %u tag %d",
-                    zebra_route_string(api.type),
+                    zebra_route_string(api.type), api.instance,
                     inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
                     p.prefixlen,
                     inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
                     api.metric,
                      api.tag);
        }
-      bgp_redistribute_delete ((struct prefix *) &p, api.type);
+      bgp_redistribute_delete ((struct prefix *) &p, api.type, api.instance);
     }
   
   return 0;
@@ -942,7 +944,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
   if (zclient->sock < 0)
     return;
 
-  if (! zclient->redist[ZEBRA_ROUTE_BGP])
+  if (!zclient->redist[ZEBRA_ROUTE_BGP].enabled)
     return;
 
   if (bgp->main_zebra_update_hold)
@@ -1049,6 +1051,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
 
       api.flags = flags;
       api.type = ZEBRA_ROUTE_BGP;
+      api.instance = 0;
       api.message = 0;
       api.safi = safi;
       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
@@ -1217,6 +1220,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
       /* Make Zebra API structure. */
       api.flags = flags;
       api.type = ZEBRA_ROUTE_BGP;
+      api.instance = 0;
       api.message = 0;
       api.safi = safi;
       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
@@ -1280,7 +1284,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
   if (zclient->sock < 0)
     return;
 
-  if (! zclient->redist[ZEBRA_ROUTE_BGP])
+  if (!zclient->redist[ZEBRA_ROUTE_BGP].enabled)
     return;
 
   peer = info->peer;
@@ -1309,6 +1313,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
       nexthop = &info->attr->nexthop;
 
       api.type = ZEBRA_ROUTE_BGP;
+      api.instance = 0;
       api.message = 0;
       api.safi = safi;
       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
@@ -1372,6 +1377,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
 
       api.flags = flags;
       api.type = ZEBRA_ROUTE_BGP;
+      api.instance = 0;
       api.message = 0;
       api.safi = safi;
       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
@@ -1405,117 +1411,177 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
     }
 #endif /* HAVE_IPV6 */
 }
+struct bgp_redist *
+bgp_redist_lookup (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
+{
+  struct list *red_list;
+  struct listnode *node;
+  struct bgp_redist *red;
+
+  red_list = bgp->redist[afi][type];
+  if (!red_list)
+    return(NULL);
+
+  for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+    if (red->instance == instance)
+      return red;
+
+  return NULL;
+}
+
+struct bgp_redist *
+bgp_redist_add (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
+{
+  struct list *red_list;
+  struct bgp_redist *red;
+
+  red = bgp_redist_lookup(bgp, afi, type, instance);
+  if (red)
+    return red;
+
+  if (!bgp->redist[afi][type])
+    bgp->redist[afi][type] = list_new();
+
+  red_list = bgp->redist[afi][type];
+  red = (struct bgp_redist *)calloc (1, sizeof(struct bgp_redist));
+  red->instance = instance;
+
+  listnode_add(red_list, red);
+
+  return red;
+}
+
+static void
+bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
+{
+  struct bgp_redist *red;
+
+  red = bgp_redist_lookup(bgp, afi, type, instance);
+
+  if (red)
+    {
+      listnode_delete(bgp->redist[afi][type], red);
+      if (!bgp->redist[afi][type]->count)
+        {
+          list_free(bgp->redist[afi][type]);
+          bgp->redist[afi][type] = NULL;
+        }
+    }
+}
 
 /* Other routes redistribution into BGP. */
 int
-bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
+bgp_redistribute_set (int type, u_short instance)
 {
-  /* Set flag to BGP instance. */
-  bgp->redist[afi][type] = 1;
 
   /* Return if already redistribute flag is set. */
-  if (zclient->redist[type])
+  if (redist_check_instance(&zclient->redist[type], instance))
     return CMD_WARNING;
 
-  zclient->redist[type] = 1;
+  redist_add_instance(&zclient->redist[type], instance);
 
   /* Return if zebra connection is not established. */
   if (zclient->sock < 0)
     return CMD_WARNING;
 
   if (BGP_DEBUG (zebra, ZEBRA))
-    zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
+    zlog_debug("Zebra send: redistribute add %s %d", zebra_route_string(type),
+               instance);
 
   /* Send distribute add message to zebra. */
-  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, instance);
 
   return CMD_SUCCESS;
 }
 
 int
-bgp_redistribute_resend (struct bgp *bgp, afi_t afi, int type)
+bgp_redistribute_resend (struct bgp *bgp, afi_t afi, int type, u_short instance)
 {
   /* Return if zebra connection is not established. */
   if (zclient->sock < 0)
     return -1;
 
   if (BGP_DEBUG (zebra, ZEBRA))
-    zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
+    zlog_debug("Zebra send: redistribute add %s %d", zebra_route_string(type),
+               instance);
 
   /* Send distribute add message to zebra. */
-  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
-  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, instance);
+  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, instance);
 
   return 0;
 }
 
 /* Redistribute with route-map specification.  */
 int
-bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type, 
-                           const char *name)
+bgp_redistribute_rmap_set (struct bgp_redist *red, const char *name)
 {
-  if (bgp->rmap[afi][type].name
-      && (strcmp (bgp->rmap[afi][type].name, name) == 0))
+  if (red->rmap.name
+      && (strcmp (red->rmap.name, name) == 0))
     return 0;
 
-  if (bgp->rmap[afi][type].name)
-    free (bgp->rmap[afi][type].name);
-  bgp->rmap[afi][type].name = strdup (name);
-  bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
+  if (red->rmap.name)
+    free (red->rmap.name);
+  red->rmap.name = strdup (name);
+  red->rmap.map = route_map_lookup_by_name (name);
 
   return 1;
 }
 
 /* Redistribute with metric specification.  */
 int
-bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
-                            u_int32_t metric)
+bgp_redistribute_metric_set (struct bgp_redist *red, u_int32_t metric)
 {
-  if (bgp->redist_metric_flag[afi][type]
-      && bgp->redist_metric[afi][type] == metric)
+  if (red->redist_metric_flag
+      && red->redist_metric == metric)
     return 0;
 
-  bgp->redist_metric_flag[afi][type] = 1;
-  bgp->redist_metric[afi][type] = metric;
+  red->redist_metric_flag = 1;
+  red->redist_metric = metric;
 
   return 1;
 }
 
 /* Unset redistribution.  */
 int
-bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
+bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance)
 {
-  /* Unset flag from BGP instance. */
-  bgp->redist[afi][type] = 0;
+  struct bgp_redist *red;
+
+  red = bgp_redist_lookup(bgp, afi, type, instance);
+  if (!red)
+    return CMD_SUCCESS;
 
   /* Unset route-map. */
-  if (bgp->rmap[afi][type].name)
-    free (bgp->rmap[afi][type].name);
-  bgp->rmap[afi][type].name = NULL;
-  bgp->rmap[afi][type].map = NULL;
+  if (red->rmap.name)
+    free (red->rmap.name);
+  red->rmap.name = NULL;
+  red->rmap.map = NULL;
 
   /* Unset metric. */
-  bgp->redist_metric_flag[afi][type] = 0;
-  bgp->redist_metric[afi][type] = 0;
+  red->redist_metric_flag = 0;
+  red->redist_metric = 0;
+
+  bgp_redist_del(bgp, afi, type, instance);
 
   /* Return if zebra connection is disabled. */
-  if (! zclient->redist[type])
+  if (!redist_check_instance(&zclient->redist[type], instance))
     return CMD_WARNING;
-  zclient->redist[type] = 0;
+  redist_del_instance(&zclient->redist[type], instance);
 
-  if (bgp->redist[AFI_IP][type] == 0 
-      && bgp->redist[AFI_IP6][type] == 0 
+  if (!bgp_redist_lookup(bgp, AFI_IP, type, instance)
+      && !bgp_redist_lookup(bgp, AFI_IP6, type, instance)
       && zclient->sock >= 0)
     {
       /* Send distribute delete message to zebra. */
       if (BGP_DEBUG (zebra, ZEBRA))
-       zlog_debug("Zebra send: redistribute delete %s",
-                  zebra_route_string(type));
-      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
+       zlog_debug("Zebra send: redistribute delete %s %d",
+                  zebra_route_string(type), instance);
+      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, instance);
     }
   
   /* Withdraw redistributed routes from current BGP's routing table. */
-  bgp_redistribute_withdraw (bgp, afi, type);
+  bgp_redistribute_withdraw (bgp, afi, type, instance);
 
   return CMD_SUCCESS;
 }
@@ -1531,7 +1597,7 @@ bgp_zebra_init (void)
 {
   /* Set default values. */
   zclient = zclient_new ();
-  zclient_init (zclient, ZEBRA_ROUTE_BGP);
+  zclient_init (zclient, ZEBRA_ROUTE_BGP, 0);
   zclient->router_id_update = bgp_router_id_update;
   zclient->interface_add = bgp_interface_add;
   zclient->interface_delete = bgp_interface_delete;
index 334e3af1ddf8202dc0fe3749d3e638037b7c8966..be94c5a01607c89a12f83c0b318908f992873787 100644 (file)
@@ -38,11 +38,13 @@ extern void bgp_zebra_announce (struct prefix *, struct bgp_info *, struct bgp *
 extern void bgp_zebra_announce_table (struct bgp *, afi_t, safi_t);
 extern void bgp_zebra_withdraw (struct prefix *, struct bgp_info *, safi_t);
 
-extern int bgp_redistribute_set (struct bgp *, afi_t, int);
-extern int bgp_redistribute_resend (struct bgp *, afi_t, int);
-extern int bgp_redistribute_rmap_set (struct bgp *, afi_t, int, const char *);
-extern int bgp_redistribute_metric_set (struct bgp *, afi_t, int, u_int32_t);
-extern int bgp_redistribute_unset (struct bgp *, afi_t, int);
+extern struct bgp_redist *bgp_redist_lookup (struct bgp *, afi_t, u_char, u_short);
+extern struct bgp_redist *bgp_redist_add (struct bgp *, afi_t, u_char, u_short);
+extern int bgp_redistribute_set (int, u_short);
+extern int bgp_redistribute_resend (struct bgp *, afi_t, int, u_short);
+extern int bgp_redistribute_rmap_set (struct bgp_redist *, const char *);
+extern int bgp_redistribute_metric_set (struct bgp_redist *, u_int32_t);
+extern int bgp_redistribute_unset (struct bgp *, afi_t, int, u_short);
 
 extern struct interface *if_lookup_by_ipv4 (struct in_addr *);
 extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *);
index 7df12326a81fbd71116ef86e96ea1a8550dc8045..8ec27e338dd3c1f43d78586588101921200028d3 100644 (file)
@@ -2397,7 +2397,7 @@ bgp_delete (struct bgp *bgp)
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
     for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
       if (i != ZEBRA_ROUTE_BGP)
-       bgp_redistribute_unset (bgp, afi, i);
+       bgp_redistribute_unset (bgp, afi, i, 0);
 
   for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
     {
index 14852293dd9169c6e5f31d842c2fe6c9c417c4e8..94540749b9c2ce189fa2596ecf430adb24907f47 100644 (file)
@@ -70,6 +70,18 @@ struct bgp_rmap
   struct route_map *map;
 };
 
+struct bgp_redist
+{
+  u_short instance;
+
+  /* BGP redistribute metric configuration. */
+  u_char redist_metric_flag;
+  u_int32_t redist_metric;
+
+  /* BGP redistribute route-map.  */
+  struct bgp_rmap rmap;
+};
+
 /* BGP instance structure.  */
 struct bgp 
 {
@@ -185,14 +197,7 @@ struct bgp
   struct bgp_rmap table_map[AFI_MAX][SAFI_MAX];
 
   /* BGP redistribute configuration. */
-  u_char redist[AFI_MAX][ZEBRA_ROUTE_MAX];
-
-  /* BGP redistribute metric configuration. */
-  u_char redist_metric_flag[AFI_MAX][ZEBRA_ROUTE_MAX];
-  u_int32_t redist_metric[AFI_MAX][ZEBRA_ROUTE_MAX];
-
-  /* BGP redistribute route-map.  */
-  struct bgp_rmap rmap[AFI_MAX][ZEBRA_ROUTE_MAX];
+  struct list *redist[AFI_MAX][ZEBRA_ROUTE_MAX];
 
   /* timer to dampen route map changes */
   struct thread *t_rmap_update;   /* Handle route map updates */
index 283b7eaae030400754af0b4c439427155cfd65ef..f87314859d39b1cc0ab011fbf56a0130989a9dda 100644 (file)
@@ -239,7 +239,7 @@ main (int argc, char **argv, char **envp)
   /* Get the programname without the preceding path. */
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
-  zlog_default = openzlog (progname, ZLOG_ISIS,
+  zlog_default = openzlog (progname, ZLOG_ISIS, 0,
                           LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
 
   /* for reload */
index 2df746291397f226fa87129886dc7647827deb87..dfedc624c928e181baeedcd6acc894182aa28286 100644 (file)
@@ -236,7 +236,7 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
   if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
     return;
 
-  if (zclient->redist[ZEBRA_ROUTE_ISIS])
+  if (zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
     {
       message = 0;
       flags = 0;
@@ -252,6 +252,8 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
       zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD);
       /* type */
       stream_putc (stream, ZEBRA_ROUTE_ISIS);
+      /* instance */
+      stream_putw (stream, 0);
       /* flags */
       stream_putc (stream, flags);
       /* message */
@@ -301,9 +303,10 @@ isis_zebra_route_del_ipv4 (struct prefix *prefix,
   struct zapi_ipv4 api;
   struct prefix_ipv4 prefix4;
 
-  if (zclient->redist[ZEBRA_ROUTE_ISIS])
+  if (zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
     {
       api.type = ZEBRA_ROUTE_ISIS;
+      api.instance = 0;
       api.flags = 0;
       api.message = 0;
       api.safi = SAFI_UNICAST;
@@ -334,6 +337,7 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
     return;
 
   api.type = ZEBRA_ROUTE_ISIS;
+  api.instance = 0;
   api.flags = 0;
   api.message = 0;
   api.safi = SAFI_UNICAST;
@@ -419,6 +423,7 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
     return;
 
   api.type = ZEBRA_ROUTE_ISIS;
+  api.instance = 0;
   api.flags = 0;
   api.message = 0;
   api.safi = SAFI_UNICAST;
@@ -488,7 +493,7 @@ isis_zebra_route_update (struct prefix *prefix,
   if (zclient->sock < 0)
     return;
 
-  if (!zclient->redist[ZEBRA_ROUTE_ISIS])
+  if (!zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
     return;
 
   if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
@@ -527,6 +532,7 @@ isis_zebra_read_ipv4 (int command, struct zclient *zclient,
   ifindex = 0;
 
   api.type = stream_getc (stream);
+  api.instance = stream_getw (stream);
   api.flags = stream_getc (stream);
   api.message = stream_getc (stream);
 
@@ -570,7 +576,8 @@ isis_zebra_read_ipv6 (int command, struct zclient *zclient,
 #endif
 
 #define ISIS_TYPE_IS_REDISTRIBUTED(T) \
-T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type]
+T == ZEBRA_ROUTE_MAX ? zclient->default_information : \
+zclient->redist[type].enabled
 
 int
 isis_distribute_list_update (int routetype)
@@ -591,7 +598,7 @@ void
 isis_zebra_init ()
 {
   zclient = zclient_new ();
-  zclient_init (zclient, ZEBRA_ROUTE_ISIS);
+  zclient_init (zclient, ZEBRA_ROUTE_ISIS, 0);
   zclient->router_id_update = isis_router_id_update_zebra;
   zclient->interface_add = isis_zebra_if_add;
   zclient->interface_delete = isis_zebra_if_del;
index 06f1171aeeb591e023ba39de216cb2cf7d19bbb7..cdca478acdf7a262739b1b0da5f54bc6fad7a8d7 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -150,6 +150,7 @@ time_print(FILE *fp, struct timestamp_control *ctl)
 static void
 vzlog (struct zlog *zl, int priority, const char *format, va_list args)
 {
+  char proto_str[32];
   struct timestamp_control tsctl;
   tsctl.already_rendered = 0;
 
@@ -181,6 +182,11 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
       va_end(ac);
     }
 
+  if (zl->instance)
+   sprintf (proto_str, "%s[%d]: ", zlog_proto_names[zl->protocol], zl->instance);
+  else
+   sprintf (proto_str, "%s: ", zlog_proto_names[zl->protocol]);
+
   /* File output. */
   if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp)
     {
@@ -188,7 +194,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
       time_print (zl->fp, &tsctl);
       if (zl->record_priority)
        fprintf (zl->fp, "%s: ", zlog_priority[priority]);
-      fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]);
+      fprintf (zl->fp, "%s", proto_str);
       va_copy(ac, args);
       vfprintf (zl->fp, format, ac);
       va_end(ac);
@@ -203,7 +209,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
       time_print (stdout, &tsctl);
       if (zl->record_priority)
        fprintf (stdout, "%s: ", zlog_priority[priority]);
-      fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]);
+      fprintf (stdout, "%s", proto_str);
       va_copy(ac, args);
       vfprintf (stdout, format, ac);
       va_end(ac);
@@ -214,7 +220,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
   /* Terminal monitor. */
   if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR])
     vty_log ((zl->record_priority ? zlog_priority[priority] : NULL),
-            zlog_proto_names[zl->protocol], format, &tsctl, args);
+            proto_str, format, &tsctl, args);
 }
 
 static char *
@@ -600,7 +606,7 @@ _zlog_assert_failed (const char *assertion, const char *file,
 
 /* Open log stream */
 struct zlog *
-openzlog (const char *progname, zlog_proto_t protocol,
+openzlog (const char *progname, zlog_proto_t protocol, u_short instance,
          int syslog_flags, int syslog_facility)
 {
   struct zlog *zl;
@@ -610,6 +616,7 @@ openzlog (const char *progname, zlog_proto_t protocol,
 
   zl->ident = progname;
   zl->protocol = protocol;
+  zl->instance = instance;
   zl->facility = syslog_facility;
   zl->syslog_options = syslog_flags;
 
index b27ba2530d323726c5601c2c400bbaf1526cee25..28fc3736fb2582c415f3272bfb423550b52d35d4 100644 (file)
--- a/lib/log.h
+++ b/lib/log.h
@@ -73,6 +73,7 @@ struct zlog
 {
   const char *ident;   /* daemon name (first arg to openlog) */
   zlog_proto_t protocol;
+  u_short      instance;
   int maxlvl[ZLOG_NUM_DESTS];  /* maximum priority to send to associated
                                   logging destination */
   int default_lvl;     /* maxlvl to use if none is specified */
@@ -97,7 +98,7 @@ extern struct zlog *zlog_default;
 
 /* Open zlog function */
 extern struct zlog *openzlog (const char *progname, zlog_proto_t protocol,
-                             int syslog_options, int syslog_facility);
+                             u_short instance, int syslog_options, int syslog_facility);
 
 /* Close zlog function. */
 extern void closezlog (struct zlog *zl);
index b884fed2a9930e988dad5dbc5fda360d8b6ff2fd..40ba87da4571e197fffa474251574b5e9a9b9b64 100644 (file)
@@ -327,8 +327,10 @@ vty_show_route_map_entry (struct vty *vty, struct route_map *map)
 
   /* Print the name of the protocol */
   if (zlog_default)
-    vty_out (vty, "%s:%s", zlog_proto_names[zlog_default->protocol],
-             VTY_NEWLINE);
+    vty_out (vty, "%s", zlog_proto_names[zlog_default->protocol]);
+  if (zlog_default->instance)
+    vty_out (vty, " %d", zlog_default->instance);
+  vty_out (vty, ":%s", VTY_NEWLINE);
 
   for (index = map->head; index; index = index->next)
     {
index 24962bac3469eb60e5d8a803846c2ea604261979..f2f910f6b6191a8938a3556f674ed40e8d96328e 100644 (file)
@@ -78,10 +78,66 @@ zclient_free (struct zclient *zclient)
   XFREE (MTYPE_ZCLIENT, zclient);
 }
 
+int
+redist_check_instance (struct redist_proto *red, u_short instance)
+{
+  struct listnode *node;
+  u_short *id;
+
+  if (!red->instances)
+    return 0;
+
+  for (ALL_LIST_ELEMENTS_RO (red->instances, node, id))
+    if (*id == instance)
+      return 1;
+
+  return 0;
+}
+
+void
+redist_add_instance (struct redist_proto *red, u_short instance)
+{
+  u_short *in;
+
+  red->enabled = 1;
+
+  if (!red->instances)
+    red->instances = list_new();
+
+  in = (u_short *)calloc(1, sizeof(u_short));
+  *in = instance;
+  listnode_add (red->instances, in);
+}
+
+void
+redist_del_instance (struct redist_proto *red, u_short instance)
+{
+  struct listnode *node;
+  u_short *id = NULL;
+
+  if (!red->instances)
+    return 0;
+
+  for (ALL_LIST_ELEMENTS_RO (red->instances, node, id))
+    if (*id == instance)
+        break;
+
+  if (id)
+    {
+      listnode_delete(red->instances, id);
+      if (!red->instances->count)
+        {
+          red->enabled = 0;
+          list_free(red->instances);
+          red->instances = NULL;
+        }
+    }
+}
+
 /* Initialize zebra client.  Argument redist_default is unwanted
    redistribute route type. */
 void
-zclient_init (struct zclient *zclient, int redist_default)
+zclient_init (struct zclient *zclient, int redist_default, u_short instance)
 {
   int i;
   
@@ -93,12 +149,13 @@ zclient_init (struct zclient *zclient, int redist_default)
 
   /* Clear redistribution flags. */
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-    zclient->redist[i] = 0;
+    memset(&zclient->redist[i], 0, sizeof(struct redist_proto));
 
   /* Set unwanted redistribute route.  bgpd does not need BGP route
      redistribution. */
   zclient->redist_default = redist_default;
-  zclient->redist[redist_default] = 1;
+  zclient->instance = instance;
+  redist_add_instance (&zclient->redist[redist_default], instance);
 
   /* Set default-information redistribute to zero. */
   zclient->default_information = 0;
@@ -142,7 +199,7 @@ void
 zclient_reset (struct zclient *zclient)
 {
   zclient_stop (zclient);
-  zclient_init (zclient, zclient->redist_default);
+  zclient_init (zclient, zclient->redist_default, zclient->instance);
 }
 
 #ifdef HAVE_TCP_ZEBRA
@@ -330,6 +387,7 @@ zebra_hello_send (struct zclient *zclient)
 
       zclient_create_header (s, ZEBRA_HELLO);
       stream_putc (s, zclient->redist_default);
+      stream_putw (s, zclient->instance);
       stream_putw_at (s, 0, stream_get_endp (s));
       return zclient_send_message(zclient);
     }
@@ -388,8 +446,15 @@ zclient_start (struct zclient *zclient)
 
   /* Flush all redistribute request. */
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-    if (i != zclient->redist_default && zclient->redist[i])
-      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i);
+    if (zclient->redist[i].enabled)
+      {
+        struct listnode *node;
+        u_short *id;
+
+        for (ALL_LIST_ELEMENTS_RO(zclient->redist[i].instances, node, id))
+          if (!(i == zclient->redist_default && *id == zclient->instance))
+            zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i, *id);
+      }
 
   /* If default information is needed. */
   if (zclient->default_information)
@@ -491,6 +556,7 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
   
   /* Put type and nexthop. */
   stream_putc (s, api->type);
+  stream_putw (s, api->instance);
   stream_putc (s, api->flags);
   stream_putc (s, api->message);
   stream_putw (s, api->safi);
@@ -572,6 +638,7 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
 
   /* Put type and nexthop. */
   stream_putc (s, api->type);
+  stream_putw (s, api->instance);
   stream_putc (s, api->flags);
   stream_putc (s, api->message);
   stream_putw (s, api->safi);
@@ -627,7 +694,8 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
  * sending client
  */
 int
-zebra_redistribute_send (int command, struct zclient *zclient, int type)
+zebra_redistribute_send (int command, struct zclient *zclient, int type,
+                         u_short instance)
 {
   struct stream *s;
 
@@ -636,6 +704,7 @@ zebra_redistribute_send (int command, struct zclient *zclient, int type)
   
   zclient_create_header (s, command);
   stream_putc (s, type);
+  stream_putw (s, instance);
   
   stream_putw_at (s, 0, stream_get_endp (s));
   
@@ -1153,24 +1222,25 @@ zclient_read (struct thread *thread)
 }
 
 void
-zclient_redistribute (int command, struct zclient *zclient, int type)
+zclient_redistribute (int command, struct zclient *zclient, int type,
+                      u_short instance)
 {
 
   if (command == ZEBRA_REDISTRIBUTE_ADD) 
     {
-      if (zclient->redist[type])
+      if (redist_check_instance(&zclient->redist[type], instance))
          return;
-      zclient->redist[type] = 1;
+      redist_add_instance(&zclient->redist[type], instance);
     }
   else
     {
-      if (!zclient->redist[type])
+      if (!redist_check_instance(&zclient->redist[type], instance))
          return;
-      zclient->redist[type] = 0;
+      redist_del_instance(&zclient->redist[type], instance);
     }
 
   if (zclient->sock > 0)
-    zebra_redistribute_send (command, zclient, type);
+    zebra_redistribute_send (command, zclient, type, instance);
 }
 
 
index e1bb2000caa4a9d80ea6f01718b04334dc7bc3d3..3c214d27852e05ad604d0994a815f5ec42589aea 100644 (file)
 /* Zebra header size. */
 #define ZEBRA_HEADER_SIZE             6
 
+struct redist_proto
+{
+  u_char enabled;
+  struct list *instances;
+};
+
 /* Structure for the zebra client. */
 struct zclient
 {
@@ -64,8 +70,9 @@ struct zclient
   struct thread *t_write;
 
   /* Redistribute information. */
-  u_char redist_default;
-  u_char redist[ZEBRA_ROUTE_MAX];
+  u_char redist_default; /* clients protocol */
+  u_short instance;
+  struct redist_proto redist[ZEBRA_ROUTE_MAX];
 
   /* Redistribute defauilt. */
   u_char default_information;
@@ -112,6 +119,7 @@ struct zserv_header
 struct zapi_ipv4
 {
   u_char type;
+  u_short instance;
 
   u_char flags;
 
@@ -134,7 +142,7 @@ struct zapi_ipv4
 
 /* Prototypes of zebra client service functions. */
 extern struct zclient *zclient_new (void);
-extern void zclient_init (struct zclient *, int);
+extern void zclient_init (struct zclient *, int, u_short);
 extern int zclient_start (struct zclient *);
 extern void zclient_stop (struct zclient *);
 extern void zclient_reset (struct zclient *);
@@ -143,11 +151,16 @@ extern void zclient_free (struct zclient *);
 extern int  zclient_socket_connect (struct zclient *);
 extern void zclient_serv_path_set  (char *path);
 
+extern int redist_check_instance (struct redist_proto *, u_short);
+extern void redist_add_instance (struct redist_proto *, u_short);
+extern void redist_del_instance (struct redist_proto *, u_short);
+
 /* Send redistribute command to zebra daemon. Do not update zclient state. */
-extern int zebra_redistribute_send (int command, struct zclient *, int type);
+extern int zebra_redistribute_send (int command, struct zclient *, int type, u_short instance);
 
 /* If state has changed, update state and call zebra_redistribute_send. */
-extern void zclient_redistribute (int command, struct zclient *, int type);
+extern void zclient_redistribute (int command, struct zclient *, int type,
+                                  u_short instance);
 
 /* If state has changed, update state and send the command to zebra. */
 extern void zclient_redistribute_default (int command, struct zclient *);
@@ -175,6 +188,7 @@ extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
 struct zapi_ipv6
 {
   u_char type;
+  u_short instance;
 
   u_char flags;
 
index 8272d4733de8eb4b520633f409fc48d1c7a1adea..75e409357c6a4c89bb1937295339e988615a6245 100644 (file)
@@ -313,7 +313,7 @@ main (int argc, char *argv[], char *envp[])
   master = thread_master_create ();
 
   /* Initializations. */
-  zlog_default = openzlog (progname, ZLOG_OSPF6,
+  zlog_default = openzlog (progname, ZLOG_OSPF6, 0,
                            LOG_CONS|LOG_NDELAY|LOG_PID,
                            LOG_DAEMON);
   zprivs_init (&ospf6d_privs);
index 04a1fd64881c4d81f88c1f9540588f707f315e01..78dd0f6d2ba53669cfd6e1e81da85f8db3e04fef 100644 (file)
@@ -70,21 +70,21 @@ ospf6_router_id_update_zebra (int command, struct zclient *zclient,
 void
 ospf6_zebra_redistribute (int type)
 {
-  if (zclient->redist[type])
+  if (zclient->redist[type].enabled)
     return;
-  zclient->redist[type] = 1;
+  redist_add_instance(&zclient->redist[type], 0);
   if (zclient->sock > 0)
-    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
 }
 
 void
 ospf6_zebra_no_redistribute (int type)
 {
-  if (! zclient->redist[type])
+  if (! zclient->redist[type].enabled)
     return;
-  zclient->redist[type] = 0;
+  redist_del_instance(&zclient->redist[type], 0);
   if (zclient->sock > 0)
-    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
+    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, 0);
 }
 
 /* Inteface addition message from zebra. */
@@ -215,6 +215,7 @@ ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
 
   /* Type, flags, message. */
   api.type = stream_getc (s);
+  api.instance = stream_getw (s);
   api.flags = stream_getc (s);
   api.message = stream_getc (s);
 
@@ -296,7 +297,7 @@ DEFUN (show_zebra,
   vty_out (vty, "  redistribute:");
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
     {
-      if (zclient->redist[i])
+      if (zclient->redist[i].enabled)
         vty_out (vty, " %s", zebra_route_string(i));
     }
   vty_out (vty, "%s", VNL);
@@ -336,7 +337,7 @@ config_write_ospf6_zebra (struct vty *vty)
       vty_out (vty, "no router zebra%s", VNL);
       vty_out (vty, "!%s", VNL);
     }
-  else if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
+  else if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
     {
       vty_out (vty, "router zebra%s", VNL);
       vty_out (vty, " no redistribute ospf6%s", VNL);
@@ -438,6 +439,7 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request)
   ospf6_route_zebra_copy_nexthops (request, ifindexes, nexthops, nhcount);
 
   api.type = ZEBRA_ROUTE_OSPF6;
+  api.instance = 0;
   api.flags = 0;
   api.message = 0;
   api.safi = SAFI_UNICAST;
@@ -470,7 +472,7 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request)
 void
 ospf6_zebra_route_update_add (struct ospf6_route *request)
 {
-  if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
+  if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
     {
       ospf6->route_table->hook_add = NULL;
       ospf6->route_table->hook_remove = NULL;
@@ -482,7 +484,7 @@ ospf6_zebra_route_update_add (struct ospf6_route *request)
 void
 ospf6_zebra_route_update_remove (struct ospf6_route *request)
 {
-  if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
+  if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
     {
       ospf6->route_table->hook_add = NULL;
       ospf6->route_table->hook_remove = NULL;
@@ -498,12 +500,13 @@ ospf6_zebra_add_discard (struct ospf6_route *request)
   char buf[INET6_ADDRSTRLEN];
   struct prefix_ipv6 *dest;
 
-  if (zclient->redist[ZEBRA_ROUTE_OSPF6])
+  if (zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
     {
       if (!CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
        {
          api.type = ZEBRA_ROUTE_OSPF6;
          api.flags = ZEBRA_FLAG_BLACKHOLE;
+         api.instance = 0;
          api.message = 0;
          api.safi = SAFI_UNICAST;
          SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
@@ -541,13 +544,14 @@ ospf6_zebra_delete_discard (struct ospf6_route *request)
   char buf[INET6_ADDRSTRLEN];
   struct prefix_ipv6 *dest;
 
-  if (zclient->redist[ZEBRA_ROUTE_OSPF6])
+  if (zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
     {
       if (CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
        {
 
          api.type = ZEBRA_ROUTE_OSPF6;
          api.flags = ZEBRA_FLAG_BLACKHOLE;
+         api.instance = 0;
          api.message = 0;
          api.safi = SAFI_UNICAST;
          SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
@@ -583,10 +587,10 @@ DEFUN (redistribute_ospf6,
 {
   struct ospf6_route *route;
 
-  if (zclient->redist[ZEBRA_ROUTE_OSPF6])
+  if (zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
     return CMD_SUCCESS;
 
-  zclient->redist[ZEBRA_ROUTE_OSPF6] = 1;
+  redist_add_instance(&zclient->redist[ZEBRA_ROUTE_OSPF6], 0);
 
   if (ospf6 == NULL)
     return CMD_SUCCESS;
@@ -611,10 +615,10 @@ DEFUN (no_redistribute_ospf6,
 {
   struct ospf6_route *route;
 
-  if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
+  if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
     return CMD_SUCCESS;
 
-  zclient->redist[ZEBRA_ROUTE_OSPF6] = 0;
+  redist_del_instance(&zclient->redist[ZEBRA_ROUTE_OSPF6], 0);
 
   if (ospf6 == NULL)
     return CMD_SUCCESS;
@@ -635,7 +639,7 @@ ospf6_zebra_init (void)
 {
   /* Allocate zebra structure. */
   zclient = zclient_new ();
-  zclient_init (zclient, ZEBRA_ROUTE_OSPF6);
+  zclient_init (zclient, ZEBRA_ROUTE_OSPF6, 0);
   zclient->router_id_update = ospf6_router_id_update_zebra;
   zclient->interface_add = ospf6_zebra_if_add;
   zclient->interface_delete = ospf6_zebra_if_del;
index 753b8edc94b6377c1be82fb84815df6b73bfe81b..b7a609d3ab6e8a51d95de1027cf141a25a50ba51 100644 (file)
@@ -42,7 +42,7 @@ extern void ospf6_zebra_route_update_remove (struct ospf6_route *request);
 
 extern void ospf6_zebra_redistribute (int);
 extern void ospf6_zebra_no_redistribute (int);
-#define ospf6_zebra_is_redistribute(type) (zclient->redist[type])
+#define ospf6_zebra_is_redistribute(type) (zclient->redist[type].enabled)
 extern void ospf6_zebra_init (void);
 extern void ospf6_zebra_add_discard (struct ospf6_route *request);
 extern void ospf6_zebra_delete_discard (struct ospf6_route *request);
index f4140b858c55f860d216ba1ef499a03f3f57ce66..5eb97d8f6648ea14d22cd6e85ba03d9d76e3eebd 100644 (file)
@@ -99,13 +99,14 @@ ospf_external_route_lookup (struct ospf *ospf,
 
 /* Add an External info for AS-external-LSA. */
 struct external_info *
-ospf_external_info_new (u_char type)
+ospf_external_info_new (u_char type, u_short instance)
 {
   struct external_info *new;
 
   new = (struct external_info *)
     XCALLOC (MTYPE_OSPF_EXTERNAL_INFO, sizeof (struct external_info));
   new->type = type;
+  new->instance = instance;
 
   ospf_reset_route_map_set_values (&new->route_map_set);
   return new;
@@ -134,32 +135,33 @@ ospf_route_map_set_compare (struct route_map_set_values *values1,
 
 /* Add an External info for AS-external-LSA. */
 struct external_info *
-ospf_external_info_add (u_char type, struct prefix_ipv4 p,
+ospf_external_info_add (u_char type, u_short instance, struct prefix_ipv4 p,
                        unsigned int ifindex, struct in_addr nexthop,
                         u_short tag)
 {
   struct external_info *new;
   struct route_node *rn;
+  struct ospf_external *ext;
 
-  /* Initialize route table. */
-  if (EXTERNAL_INFO (type) == NULL)
-    EXTERNAL_INFO (type) = route_table_init ();
+  ext = ospf_external_lookup(type, instance);
+  if (!ext)
+    ext = ospf_external_add(type, instance);
 
-  rn = route_node_get (EXTERNAL_INFO (type), (struct prefix *) &p);
+  rn = route_node_get (EXTERNAL_INFO (ext), (struct prefix *) &p);
   /* If old info exists, -- discard new one or overwrite with new one? */
   if (rn)
     if (rn->info)
       {
        route_unlock_node (rn);
-       zlog_warn ("Redistribute[%s]: %s/%d already exists, discard.",
-                  ospf_redist_string(type),
+       zlog_warn ("Redistribute[%s][%d]: %s/%d already exists, discard.",
+                  ospf_redist_string(type), instance,
                   inet_ntoa (p.prefix), p.prefixlen);
        /* XFREE (MTYPE_OSPF_TMP, rn->info); */
        return rn->info;
       }
 
   /* Create new External info instance. */
-  new = ospf_external_info_new (type);
+  new = ospf_external_info_new (type, instance);
   new->p = p;
   new->ifindex = ifindex;
   new->nexthop = nexthop;
@@ -176,11 +178,16 @@ ospf_external_info_add (u_char type, struct prefix_ipv4 p,
 }
 
 void
-ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
+ospf_external_info_delete (u_char type, u_short instance, struct prefix_ipv4 p)
 {
   struct route_node *rn;
+  struct ospf_external *ext;
 
-  rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
+  ext = ospf_external_lookup(type, instance);
+  if (!ext)
+    return;
+
+  rn = route_node_lookup (EXTERNAL_INFO (ext), (struct prefix *) &p);
   if (rn)
     {
       ospf_external_info_free (rn->info);
@@ -191,10 +198,16 @@ ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
 }
 
 struct external_info *
-ospf_external_info_lookup (u_char type, struct prefix_ipv4 *p)
+ospf_external_info_lookup (u_char type, u_short instance, struct prefix_ipv4 *p)
 {
   struct route_node *rn;
-  rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) p);
+  struct ospf_external *ext;
+
+  ext = ospf_external_lookup(type, instance);
+  if (!ext)
+    return NULL;
+
+  rn = route_node_lookup (EXTERNAL_INFO (ext), (struct prefix *) p);
   if (rn)
     {
       route_unlock_node (rn);
@@ -271,14 +284,19 @@ ospf_asbr_status_update (struct ospf *ospf, u_char status)
 }
 
 void
-ospf_redistribute_withdraw (struct ospf *ospf, u_char type)
+ospf_redistribute_withdraw (struct ospf *ospf, u_char type, u_short instance)
 {
   struct route_node *rn;
   struct external_info *ei;
+  struct ospf_external *ext;
+
+  ext = ospf_external_lookup(type, instance);
+  if (!ext)
+    return;
 
   /* Delete external info for specified type. */
-  if (EXTERNAL_INFO (type))
-    for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
+  if (EXTERNAL_INFO (ext))
+    for (rn = route_top (EXTERNAL_INFO (ext)); rn; rn = route_next (rn))
       if ((ei = rn->info))
        if (ospf_external_info_find_lsa (ospf, &ei->p))
          {
index bb773c979042f802c1e2867f2dc872f0dc3e6241..ade671013ac21588a5ee41c6e07a79b8e24a530b 100644 (file)
@@ -35,6 +35,8 @@ struct external_info
   /* Type of source protocol. */
   u_char type;
 
+  u_short instance;
+
   /* Prefix. */
   struct prefix_ipv4 p;
 
@@ -55,23 +57,23 @@ struct external_info
 #define OSPF_ASBR_CHECK_DELAY 30
 
 extern void ospf_external_route_remove (struct ospf *, struct prefix_ipv4 *);
-extern struct external_info *ospf_external_info_new (u_char);
+extern struct external_info *ospf_external_info_new (u_char, u_short);
 extern void ospf_reset_route_map_set_values (struct route_map_set_values *);
 extern int ospf_route_map_set_compare (struct route_map_set_values *,
                                struct route_map_set_values *);
-extern struct external_info *ospf_external_info_add (u_char, 
+extern struct external_info *ospf_external_info_add (u_char, u_short,
                                               struct prefix_ipv4,
                                              unsigned int, 
                                              struct in_addr,
                                              u_short);
-extern void ospf_external_info_delete (u_char, struct prefix_ipv4);
-extern struct external_info *ospf_external_info_lookup (u_char, 
+extern void ospf_external_info_delete (u_char, u_short, struct prefix_ipv4);
+extern struct external_info *ospf_external_info_lookup (u_char, u_short,
                                                  struct prefix_ipv4 *);
 extern struct ospf_route *ospf_external_route_lookup (struct ospf *, 
                                                struct prefix_ipv4 *);
 extern void ospf_asbr_status_update (struct ospf *, u_char);
 
-extern void ospf_redistribute_withdraw (struct ospf *, u_char);
+extern void ospf_redistribute_withdraw (struct ospf *, u_char, u_short);
 extern void ospf_asbr_check (void);
 extern void ospf_schedule_asbr_check (void);
 extern void ospf_asbr_route_install_lsa (struct ospf_lsa *);
index de62e0b7fad732644da8f72f57eac454fc7b713a..af5cbf534ef1171673de7d994529f474e3e53d18 100644 (file)
@@ -755,60 +755,51 @@ ospf_packet_dump (struct stream *s)
 
 
 /*
-   [no] debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)
+   [no] debug ospf [<1-65535>] packet (hello|dd|ls-request|ls-update|ls-ack|all)
                           [send|recv [detail]]
 */
-DEFUN (debug_ospf_packet,
-       debug_ospf_packet_all_cmd,
-       "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)",
-       DEBUG_STR
-       OSPF_STR
-       "OSPF packets\n"
-       "OSPF Hello\n"
-       "OSPF Database Description\n"
-       "OSPF Link State Request\n"
-       "OSPF Link State Update\n"
-       "OSPF Link State Acknowledgment\n"
-       "OSPF all packets\n")
+static int
+debug_ospf_packet_common (struct vty *vty, int arg_base, int argc,
+                          const char **argv)
 {
   int type = 0;
   int flag = 0;
   int i;
 
-  assert (argc > 0);
+  assert (argc > arg_base + 0);
 
   /* Check packet type. */
-  if (strncmp (argv[0], "h", 1) == 0)
+  if (strncmp (argv[arg_base + 0], "h", 1) == 0)
     type = OSPF_DEBUG_HELLO;
-  else if (strncmp (argv[0], "d", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "d", 1) == 0)
     type = OSPF_DEBUG_DB_DESC;
-  else if (strncmp (argv[0], "ls-r", 4) == 0)
+  else if (strncmp (argv[arg_base + 0], "ls-r", 4) == 0)
     type = OSPF_DEBUG_LS_REQ;
-  else if (strncmp (argv[0], "ls-u", 4) == 0)
+  else if (strncmp (argv[arg_base + 0], "ls-u", 4) == 0)
     type = OSPF_DEBUG_LS_UPD;
-  else if (strncmp (argv[0], "ls-a", 4) == 0)
+  else if (strncmp (argv[arg_base + 0], "ls-a", 4) == 0)
     type = OSPF_DEBUG_LS_ACK;
-  else if (strncmp (argv[0], "a", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "a", 1) == 0)
     type = OSPF_DEBUG_ALL;
 
   /* Default, both send and recv. */
-  if (argc == 1)
+  if (argc == arg_base + 1)
     flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV;
 
   /* send or recv. */
-  if (argc >= 2)
+  if (argc >= arg_base + 2)
     {
-      if (strncmp (argv[1], "s", 1) == 0)
+      if (strncmp (argv[arg_base + 1], "s", 1) == 0)
        flag = OSPF_DEBUG_SEND;
-      else if (strncmp (argv[1], "r", 1) == 0)
+      else if (strncmp (argv[arg_base + 1], "r", 1) == 0)
        flag = OSPF_DEBUG_RECV;
-      else if (strncmp (argv[1], "d", 1) == 0)
+      else if (strncmp (argv[arg_base + 1], "d", 1) == 0)
        flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL;
     }
 
   /* detail. */
-  if (argc == 3)
-    if (strncmp (argv[2], "d", 1) == 0)
+  if (argc == arg_base + 3)
+    if (strncmp (argv[arg_base + 2], "d", 1) == 0)
       flag |= OSPF_DEBUG_DETAIL;
 
   for (i = 0; i < 5; i++)
@@ -823,6 +814,22 @@ DEFUN (debug_ospf_packet,
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf_packet,
+       debug_ospf_packet_all_cmd,
+       "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)",
+       DEBUG_STR
+       OSPF_STR
+       "OSPF packets\n"
+       "OSPF Hello\n"
+       "OSPF Database Description\n"
+       "OSPF Link State Request\n"
+       "OSPF Link State Update\n"
+       "OSPF Link State Acknowledgment\n"
+       "OSPF all packets\n")
+{
+  return (debug_ospf_packet_common(vty, 0, argc, argv));
+}
+
 ALIAS (debug_ospf_packet,
        debug_ospf_packet_send_recv_cmd,
        "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)",
@@ -855,13 +862,12 @@ ALIAS (debug_ospf_packet,
        "Packet received\n"
        "Detail Information\n")
        
-
-DEFUN (no_debug_ospf_packet,
-       no_debug_ospf_packet_all_cmd,
-       "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)",
-       NO_STR
+DEFUN (debug_ospf_instance_packet,
+       debug_ospf_instance_packet_all_cmd,
+       "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all)",
        DEBUG_STR
        OSPF_STR
+       "Instance ID\n"
        "OSPF packets\n"
        "OSPF Hello\n"
        "OSPF Database Description\n"
@@ -869,45 +875,92 @@ DEFUN (no_debug_ospf_packet,
        "OSPF Link State Update\n"
        "OSPF Link State Acknowledgment\n"
        "OSPF all packets\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return (debug_ospf_packet_common(vty, 1, argc, argv));
+}
+
+ALIAS (debug_ospf_instance_packet,
+       debug_ospf_instance_packet_send_recv_cmd,
+       "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)",
+       "Debugging functions\n"
+       "OSPF information\n"
+       "Instance ID\n"
+       "OSPF packets\n"
+       "OSPF Hello\n"
+       "OSPF Database Description\n"
+       "OSPF Link State Request\n"
+       "OSPF Link State Update\n"
+       "OSPF Link State Acknowledgment\n"
+       "OSPF all packets\n"
+       "Packet sent\n"
+       "Packet received\n"
+       "Detail information\n")
+
+ALIAS (debug_ospf_instance_packet,
+       debug_ospf_instance_packet_send_recv_detail_cmd,
+       "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) (detail|)",
+       "Debugging functions\n"
+       "OSPF information\n"
+       "Instance ID\n"
+       "OSPF packets\n"
+       "OSPF Hello\n"
+       "OSPF Database Description\n"
+       "OSPF Link State Request\n"
+       "OSPF Link State Update\n"
+       "OSPF Link State Acknowledgment\n"
+       "OSPF all packets\n"
+       "Packet sent\n"
+       "Packet received\n"
+       "Detail Information\n")
+
+static int
+no_debug_ospf_packet_common (struct vty *vty, int arg_base, int argc,
+                             const char **argv)
 {
   int type = 0;
   int flag = 0;
   int i;
 
-  assert (argc > 0);
+  assert (argc > arg_base + 0);
 
   /* Check packet type. */
-  if (strncmp (argv[0], "h", 1) == 0)
+  if (strncmp (argv[arg_base + 0], "h", 1) == 0)
     type = OSPF_DEBUG_HELLO;
-  else if (strncmp (argv[0], "d", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "d", 1) == 0)
     type = OSPF_DEBUG_DB_DESC;
-  else if (strncmp (argv[0], "ls-r", 4) == 0)
+  else if (strncmp (argv[arg_base + 0], "ls-r", 4) == 0)
     type = OSPF_DEBUG_LS_REQ;
-  else if (strncmp (argv[0], "ls-u", 4) == 0)
+  else if (strncmp (argv[arg_base + 0], "ls-u", 4) == 0)
     type = OSPF_DEBUG_LS_UPD;
-  else if (strncmp (argv[0], "ls-a", 4) == 0)
+  else if (strncmp (argv[arg_base + 0], "ls-a", 4) == 0)
     type = OSPF_DEBUG_LS_ACK;
-  else if (strncmp (argv[0], "a", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "a", 1) == 0)
     type = OSPF_DEBUG_ALL;
 
   /* Default, both send and recv. */
-  if (argc == 1)
+  if (argc == arg_base + 1)
     flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL ;
 
   /* send or recv. */
-  if (argc == 2)
+  if (argc == arg_base + 2)
     {
-      if (strncmp (argv[1], "s", 1) == 0)
+      if (strncmp (argv[arg_base + 1], "s", 1) == 0)
        flag = OSPF_DEBUG_SEND | OSPF_DEBUG_DETAIL;
-      else if (strncmp (argv[1], "r", 1) == 0)
+      else if (strncmp (argv[arg_base + 1], "r", 1) == 0)
        flag = OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL;
-      else if (strncmp (argv[1], "d", 1) == 0)
+      else if (strncmp (argv[arg_base + 1], "d", 1) == 0)
        flag = OSPF_DEBUG_DETAIL;
     }
 
   /* detail. */
-  if (argc == 3)
-    if (strncmp (argv[2], "d", 1) == 0)
+  if (argc == arg_base + 3)
+    if (strncmp (argv[arg_base + 2], "d", 1) == 0)
       flag = OSPF_DEBUG_DETAIL;
 
   for (i = 0; i < 5; i++)
@@ -929,6 +982,23 @@ DEFUN (no_debug_ospf_packet,
   return CMD_SUCCESS;
 }
 
+DEFUN (no_debug_ospf_packet,
+       no_debug_ospf_packet_all_cmd,
+       "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "OSPF packets\n"
+       "OSPF Hello\n"
+       "OSPF Database Description\n"
+       "OSPF Link State Request\n"
+       "OSPF Link State Update\n"
+       "OSPF Link State Acknowledgment\n"
+       "OSPF all packets\n")
+{
+  return no_debug_ospf_packet_common(vty, 0, argc, argv);
+}
+
 ALIAS (no_debug_ospf_packet,
        no_debug_ospf_packet_send_recv_cmd,
        "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)",
@@ -963,25 +1033,81 @@ ALIAS (no_debug_ospf_packet,
        "Packet received\n"
        "Detail Information\n")
 
-
-DEFUN (debug_ospf_ism,
-       debug_ospf_ism_cmd,
-       "debug ospf ism",
+DEFUN (no_debug_ospf_instance_packet,
+       no_debug_ospf_instance_packet_all_cmd,
+       "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all)",
+       NO_STR
        DEBUG_STR
        OSPF_STR
-       "OSPF Interface State Machine\n")
+       "Instance ID\n"
+       "OSPF packets\n"
+       "OSPF Hello\n"
+       "OSPF Database Description\n"
+       "OSPF Link State Request\n"
+       "OSPF Link State Update\n"
+       "OSPF Link State Acknowledgment\n"
+       "OSPF all packets\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return (no_debug_ospf_packet_common(vty, 1, argc, argv));
+}
+
+ALIAS (no_debug_ospf_instance_packet,
+       no_debug_ospf_instance_packet_send_recv_cmd,
+       "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)",
+       NO_STR
+       "Debugging functions\n"
+       "OSPF information\n"
+       "Instance ID\n"
+       "OSPF packets\n"
+       "OSPF Hello\n"
+       "OSPF Database Description\n"
+       "OSPF Link State Request\n"
+       "OSPF Link State Update\n"
+       "OSPF Link State Acknowledgment\n"
+       "OSPF all packets\n"
+       "Packet sent\n"
+       "Packet received\n"
+       "Detail Information\n")
+
+ALIAS (no_debug_ospf_instance_packet,
+       no_debug_ospf_instance_packet_send_recv_detail_cmd,
+       "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) (detail|)",
+       NO_STR
+       "Debugging functions\n"
+       "OSPF information\n"
+       "Instance ID\n"
+       "OSPF packets\n"
+       "OSPF Hello\n"
+       "OSPF Database Description\n"
+       "OSPF Link State Request\n"
+       "OSPF Link State Update\n"
+       "OSPF Link State Acknowledgment\n"
+       "OSPF all packets\n"
+       "Packet sent\n"
+       "Packet received\n"
+       "Detail Information\n")
+
+
+static int
+debug_ospf_ism_common (struct vty *vty, int arg_base, int argc, const char **argv)
 {
   if (vty->node == CONFIG_NODE)
     {
-      if (argc == 0)
+      if (argc == arg_base + 0)
        DEBUG_ON (ism, ISM);
-      else if (argc == 1)
+      else if (argc == arg_base + 1)
        {
-         if (strncmp (argv[0], "s", 1) == 0)
+         if (strncmp (argv[arg_base + 0], "s", 1) == 0)
            DEBUG_ON (ism, ISM_STATUS);
-         else if (strncmp (argv[0], "e", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
            DEBUG_ON (ism, ISM_EVENTS);
-         else if (strncmp (argv[0], "t", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
            DEBUG_ON (ism, ISM_TIMERS);
        }
 
@@ -989,21 +1115,31 @@ DEFUN (debug_ospf_ism,
     }
 
   /* ENABLE_NODE. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     TERM_DEBUG_ON (ism, ISM);
-  else if (argc == 1)
+  else if (argc == arg_base + 1)
     {
-      if (strncmp (argv[0], "s", 1) == 0)
+      if (strncmp (argv[arg_base + 0], "s", 1) == 0)
        TERM_DEBUG_ON (ism, ISM_STATUS);
-      else if (strncmp (argv[0], "e", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
        TERM_DEBUG_ON (ism, ISM_EVENTS);
-      else if (strncmp (argv[0], "t", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
        TERM_DEBUG_ON (ism, ISM_TIMERS);
     }
 
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf_ism,
+       debug_ospf_ism_cmd,
+       "debug ospf ism",
+       DEBUG_STR
+       OSPF_STR
+       "OSPF Interface State Machine\n")
+{
+  return debug_ospf_ism_common(vty, 0, argc, argv);
+}
+
 ALIAS (debug_ospf_ism,
        debug_ospf_ism_sub_cmd,
        "debug ospf ism (status|events|timers)",
@@ -1014,46 +1150,81 @@ ALIAS (debug_ospf_ism,
        "ISM Event Information\n"
        "ISM TImer Information\n")
 
-DEFUN (no_debug_ospf_ism,
-       no_debug_ospf_ism_cmd,
-       "no debug ospf ism",
-       NO_STR
+DEFUN (debug_ospf_instance_ism,
+       debug_ospf_instance_ism_cmd,
+       "debug ospf <1-65535> ism",
        DEBUG_STR
        OSPF_STR
-       "OSPF Interface State Machine")
+       "Instance ID\n"
+       "OSPF Interface State Machine\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return debug_ospf_ism_common(vty, 1, argc, argv);
+}
+
+ALIAS (debug_ospf_instance_ism,
+       debug_ospf_instance_ism_sub_cmd,
+       "debug ospf <1-65535> ism (status|events|timers)",
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF Interface State Machine\n"
+       "ISM Status Information\n"
+       "ISM Event Information\n"
+       "ISM TImer Information\n")
+
+static int
+no_debug_ospf_ism_common(struct vty *vty, int arg_base, int argc,
+                         const char **argv)
 {
   if (vty->node == CONFIG_NODE)
     {
-      if (argc == 0)
+      if (argc == arg_base + 0)
        DEBUG_OFF (ism, ISM);
-      else if (argc == 1)
+      else if (argc == arg_base + 1)
        {
-         if (strncmp (argv[0], "s", 1) == 0)
+         if (strncmp (argv[arg_base + 0], "s", 1) == 0)
            DEBUG_OFF (ism, ISM_STATUS);
-         else if (strncmp (argv[0], "e", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
            DEBUG_OFF (ism, ISM_EVENTS);
-         else if (strncmp (argv[0], "t", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
            DEBUG_OFF (ism, ISM_TIMERS);
        }
       return CMD_SUCCESS;
     }
 
   /* ENABLE_NODE. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     TERM_DEBUG_OFF (ism, ISM);
-  else if (argc == 1)
+  else if (argc == arg_base + 1)
     {
-      if (strncmp (argv[0], "s", 1) == 0)
+      if (strncmp (argv[arg_base + 0], "s", 1) == 0)
        TERM_DEBUG_OFF (ism, ISM_STATUS);
-      else if (strncmp (argv[0], "e", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
        TERM_DEBUG_OFF (ism, ISM_EVENTS);
-      else if (strncmp (argv[0], "t", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
        TERM_DEBUG_OFF (ism, ISM_TIMERS);
     }
 
   return CMD_SUCCESS;
 }
 
+DEFUN (no_debug_ospf_ism,
+       no_debug_ospf_ism_cmd,
+       "no debug ospf ism",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "OSPF Interface State Machine")
+{
+  return no_debug_ospf_ism_common(vty, 0, argc, argv);
+}
+
 ALIAS (no_debug_ospf_ism,
        no_debug_ospf_ism_sub_cmd,
        "no debug ospf ism (status|events|timers)",
@@ -1065,25 +1236,50 @@ ALIAS (no_debug_ospf_ism,
        "ISM Event Information\n"
        "ISM Timer Information\n")
 
-
-DEFUN (debug_ospf_nsm,
-       debug_ospf_nsm_cmd,
-       "debug ospf nsm",
+DEFUN (no_debug_ospf_instance_ism,
+       no_debug_ospf_instance_ism_cmd,
+       "no debug ospf <1-65535> ism",
+       NO_STR
        DEBUG_STR
        OSPF_STR
-       "OSPF Neighbor State Machine\n")
+       "Instance ID\n"
+       "OSPF Interface State Machine")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return no_debug_ospf_ism_common(vty, 1, argc, argv);
+}
+
+ALIAS (no_debug_ospf_instance_ism,
+       no_debug_ospf_instance_ism_sub_cmd,
+       "no debug ospf <1-65535> ism (status|events|timers)",
+       NO_STR
+       "Debugging functions\n"
+       "OSPF information\n"
+       "Instance ID\n"
+       "OSPF Interface State Machine\n"
+       "ISM Status Information\n"
+       "ISM Event Information\n"
+       "ISM Timer Information\n")
+
+static int
+debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **argv)
 {
   if (vty->node == CONFIG_NODE)
     {
-      if (argc == 0)
+      if (argc == arg_base + 0)
        DEBUG_ON (nsm, NSM);
-      else if (argc == 1)
+      else if (argc == arg_base + 1)
        {
-         if (strncmp (argv[0], "s", 1) == 0)
+         if (strncmp (argv[arg_base + 0], "s", 1) == 0)
            DEBUG_ON (nsm, NSM_STATUS);
-         else if (strncmp (argv[0], "e", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
            DEBUG_ON (nsm, NSM_EVENTS);
-         else if (strncmp (argv[0], "t", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
            DEBUG_ON (nsm, NSM_TIMERS);
        }
 
@@ -1091,21 +1287,31 @@ DEFUN (debug_ospf_nsm,
     }
 
   /* ENABLE_NODE. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     TERM_DEBUG_ON (nsm, NSM);
-  else if (argc == 1)
+  else if (argc == arg_base + 1)
     {
-      if (strncmp (argv[0], "s", 1) == 0)
+      if (strncmp (argv[arg_base + 0], "s", 1) == 0)
        TERM_DEBUG_ON (nsm, NSM_STATUS);
-      else if (strncmp (argv[0], "e", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
        TERM_DEBUG_ON (nsm, NSM_EVENTS);
-      else if (strncmp (argv[0], "t", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
        TERM_DEBUG_ON (nsm, NSM_TIMERS);
     }
 
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf_nsm,
+       debug_ospf_nsm_cmd,
+       "debug ospf nsm",
+       DEBUG_STR
+       OSPF_STR
+       "OSPF Neighbor State Machine\n")
+{
+  return debug_ospf_nsm_common (vty, 0, argc, argv);
+}
+
 ALIAS (debug_ospf_nsm,
        debug_ospf_nsm_sub_cmd,
        "debug ospf nsm (status|events|timers)",
@@ -1116,25 +1322,48 @@ ALIAS (debug_ospf_nsm,
        "NSM Event Information\n"
        "NSM Timer Information\n")
 
-DEFUN (no_debug_ospf_nsm,
-       no_debug_ospf_nsm_cmd,
-       "no debug ospf nsm",
-       NO_STR
+DEFUN (debug_ospf_instance_nsm,
+       debug_ospf_instance_nsm_cmd,
+       "debug ospf <1-65535> nsm",
        DEBUG_STR
        OSPF_STR
-       "OSPF Neighbor State Machine")
+       "Instance ID\n"
+       "OSPF Neighbor State Machine\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return debug_ospf_nsm_common (vty, 1, argc, argv);
+}
+
+ALIAS (debug_ospf_instance_nsm,
+       debug_ospf_instance_nsm_sub_cmd,
+       "debug ospf <1-65535> nsm (status|events|timers)",
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF Neighbor State Machine\n"
+       "NSM Status Information\n"
+       "NSM Event Information\n"
+       "NSM Timer Information\n")
+
+static int
+no_debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **argv)
 {
   if (vty->node == CONFIG_NODE)
     {
-      if (argc == 0)
+      if (argc == arg_base + 0)
        DEBUG_OFF (nsm, NSM);
-      else if (argc == 1)
+      else if (argc == arg_base + 1)
        {
-         if (strncmp (argv[0], "s", 1) == 0)
+         if (strncmp (argv[arg_base + 0], "s", 1) == 0)
            DEBUG_OFF (nsm, NSM_STATUS);
-         else if (strncmp (argv[0], "e", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
            DEBUG_OFF (nsm, NSM_EVENTS);
-         else if (strncmp (argv[0], "t", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
            DEBUG_OFF (nsm, NSM_TIMERS);
        }
 
@@ -1142,21 +1371,32 @@ DEFUN (no_debug_ospf_nsm,
     }
 
   /* ENABLE_NODE. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     TERM_DEBUG_OFF (nsm, NSM);
-  else if (argc == 1)
+  else if (argc == arg_base + 1)
     {
-      if (strncmp (argv[0], "s", 1) == 0)
+      if (strncmp (argv[arg_base + 0], "s", 1) == 0)
        TERM_DEBUG_OFF (nsm, NSM_STATUS);
-      else if (strncmp (argv[0], "e", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
        TERM_DEBUG_OFF (nsm, NSM_EVENTS);
-      else if (strncmp (argv[0], "t", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
        TERM_DEBUG_OFF (nsm, NSM_TIMERS);
     }
 
   return CMD_SUCCESS;
 }
 
+DEFUN (no_debug_ospf_nsm,
+       no_debug_ospf_nsm_cmd,
+       "no debug ospf nsm",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "OSPF Neighbor State Machine")
+{
+  return no_debug_ospf_nsm_common(vty, 0, argc, argv);
+}
+
 ALIAS (no_debug_ospf_nsm,
        no_debug_ospf_nsm_sub_cmd,
        "no debug ospf nsm (status|events|timers)",
@@ -1168,27 +1408,53 @@ ALIAS (no_debug_ospf_nsm,
        "NSM Event Information\n"
        "NSM Timer Information\n")
 
-
-DEFUN (debug_ospf_lsa,
-       debug_ospf_lsa_cmd,
-       "debug ospf lsa",
+DEFUN (no_debug_ospf_instance_nsm,
+       no_debug_ospf_instance_nsm_cmd,
+       "no debug ospf <1-65535> nsm",
+       NO_STR
        DEBUG_STR
        OSPF_STR
-       "OSPF Link State Advertisement\n")
+       "Instance ID\n"
+       "OSPF Neighbor State Machine")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return no_debug_ospf_nsm_common(vty, 1, argc, argv);
+}
+
+ALIAS (no_debug_ospf_instance_nsm,
+       no_debug_ospf_instance_nsm_sub_cmd,
+       "no debug ospf <1-65535> nsm (status|events|timers)",
+       NO_STR
+       "Debugging functions\n"
+       "OSPF information\n"
+       "Instance ID\n"
+       "OSPF Interface State Machine\n"
+       "NSM Status Information\n"
+       "NSM Event Information\n"
+       "NSM Timer Information\n")
+
+
+static int
+debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **argv)
 {
   if (vty->node == CONFIG_NODE)
     {
-      if (argc == 0)
+      if (argc == arg_base + 0)
        DEBUG_ON (lsa, LSA);
-      else if (argc == 1)
+      else if (argc == arg_base + 1)
        {
-         if (strncmp (argv[0], "g", 1) == 0)
+         if (strncmp (argv[arg_base + 0], "g", 1) == 0)
            DEBUG_ON (lsa, LSA_GENERATE);
-         else if (strncmp (argv[0], "f", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "f", 1) == 0)
            DEBUG_ON (lsa, LSA_FLOODING);
-         else if (strncmp (argv[0], "i", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "i", 1) == 0)
            DEBUG_ON (lsa, LSA_INSTALL);
-         else if (strncmp (argv[0], "r", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
            DEBUG_ON (lsa, LSA_REFRESH);
        }
 
@@ -1196,23 +1462,33 @@ DEFUN (debug_ospf_lsa,
     }
 
   /* ENABLE_NODE. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     TERM_DEBUG_ON (lsa, LSA);
-  else if (argc == 1)
+  else if (argc == arg_base + 1)
     {
-      if (strncmp (argv[0], "g", 1) == 0)
+      if (strncmp (argv[arg_base + 0], "g", 1) == 0)
        TERM_DEBUG_ON (lsa, LSA_GENERATE);
-      else if (strncmp (argv[0], "f", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "f", 1) == 0)
        TERM_DEBUG_ON (lsa, LSA_FLOODING);
-      else if (strncmp (argv[0], "i", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "i", 1) == 0)
        TERM_DEBUG_ON (lsa, LSA_INSTALL);
-      else if (strncmp (argv[0], "r", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
        TERM_DEBUG_ON (lsa, LSA_REFRESH);
     }
 
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf_lsa,
+       debug_ospf_lsa_cmd,
+       "debug ospf lsa",
+       DEBUG_STR
+       OSPF_STR
+       "OSPF Link State Advertisement\n")
+{
+  return debug_ospf_lsa_common(vty, 0, argc, argv);
+}
+
 ALIAS (debug_ospf_lsa,
        debug_ospf_lsa_sub_cmd,
        "debug ospf lsa (generate|flooding|install|refresh)",
@@ -1224,27 +1500,51 @@ ALIAS (debug_ospf_lsa,
        "LSA Install/Delete\n"
        "LSA Refresh\n")
 
-DEFUN (no_debug_ospf_lsa,
-       no_debug_ospf_lsa_cmd,
-       "no debug ospf lsa",
-       NO_STR
+DEFUN (debug_ospf_instance_lsa,
+       debug_ospf_instance_lsa_cmd,
+       "debug ospf <1-65535> lsa",
        DEBUG_STR
        OSPF_STR
+       "Instance ID\n"
        "OSPF Link State Advertisement\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return debug_ospf_lsa_common(vty, 1, argc, argv);
+}
+
+ALIAS (debug_ospf_instance_lsa,
+       debug_ospf_instance_lsa_sub_cmd,
+       "debug ospf <1-65535> lsa (generate|flooding|install|refresh)",
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF Link State Advertisement\n"
+       "LSA Generation\n"
+       "LSA Flooding\n"
+       "LSA Install/Delete\n"
+       "LSA Refresh\n")
+
+static int
+no_debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **argv)
 {
   if (vty->node == CONFIG_NODE)
     {
-      if (argc == 0)
+      if (argc == arg_base + 0)
        DEBUG_OFF (lsa, LSA);
-      else if (argc == 1)
+      else if (argc == arg_base + 1)
        {
-         if (strncmp (argv[0], "g", 1) == 0)
+         if (strncmp (argv[arg_base + 0], "g", 1) == 0)
            DEBUG_OFF (lsa, LSA_GENERATE);
-         else if (strncmp (argv[0], "f", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "f", 1) == 0)
            DEBUG_OFF (lsa, LSA_FLOODING);
-         else if (strncmp (argv[0], "i", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "i", 1) == 0)
            DEBUG_OFF (lsa, LSA_INSTALL);
-         else if (strncmp (argv[0], "r", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
            DEBUG_OFF (lsa, LSA_REFRESH);
        }
 
@@ -1252,23 +1552,34 @@ DEFUN (no_debug_ospf_lsa,
     }
 
   /* ENABLE_NODE. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     TERM_DEBUG_OFF (lsa, LSA);
-  else if (argc == 1)
+  else if (argc == arg_base + 1)
     {
-      if (strncmp (argv[0], "g", 1) == 0)
+      if (strncmp (argv[arg_base + 0], "g", 1) == 0)
        TERM_DEBUG_OFF (lsa, LSA_GENERATE);
-      else if (strncmp (argv[0], "f", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "f", 1) == 0)
        TERM_DEBUG_OFF (lsa, LSA_FLOODING);
-      else if (strncmp (argv[0], "i", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "i", 1) == 0)
        TERM_DEBUG_OFF (lsa, LSA_INSTALL);
-      else if (strncmp (argv[0], "r", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
        TERM_DEBUG_OFF (lsa, LSA_REFRESH);
     }
 
   return CMD_SUCCESS;
 }
 
+DEFUN (no_debug_ospf_lsa,
+       no_debug_ospf_lsa_cmd,
+       "no debug ospf lsa",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "OSPF Link State Advertisement\n")
+{
+  return no_debug_ospf_lsa_common (vty, 0, argc, argv);
+}
+
 ALIAS (no_debug_ospf_lsa,
        no_debug_ospf_lsa_sub_cmd,
        "no debug ospf lsa (generate|flooding|install|refresh)",
@@ -1281,23 +1592,50 @@ ALIAS (no_debug_ospf_lsa,
        "LSA Install/Delete\n"
        "LSA Refres\n")
 
+DEFUN (no_debug_ospf_instance_lsa,
+       no_debug_ospf_instance_lsa_cmd,
+       "no debug ospf <1-65535> lsa",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF Link State Advertisement\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
 
-DEFUN (debug_ospf_zebra,
-       debug_ospf_zebra_cmd,
-       "debug ospf zebra",
+  return no_debug_ospf_lsa_common (vty, 1, argc, argv);
+}
+
+ALIAS (no_debug_ospf_instance_lsa,
+       no_debug_ospf_instance_lsa_sub_cmd,
+       "no debug ospf <1-65535> lsa (generate|flooding|install|refresh)",
+       NO_STR
        DEBUG_STR
        OSPF_STR
-       "OSPF Zebra information\n")
+       "Instance ID\n"
+       "OSPF Link State Advertisement\n"
+       "LSA Generation\n"
+       "LSA Flooding\n"
+       "LSA Install/Delete\n"
+       "LSA Refres\n")
+
+
+static int
+debug_ospf_zebra_common (struct vty *vty, int arg_base, int argc, const char **argv)
 {
   if (vty->node == CONFIG_NODE)
     {
-      if (argc == 0)
+      if (argc == arg_base + 0)
        DEBUG_ON (zebra, ZEBRA);
-      else if (argc == 1)
+      else if (argc == arg_base + 1)
        {
-         if (strncmp (argv[0], "i", 1) == 0)
+         if (strncmp (argv[arg_base + 0], "i", 1) == 0)
            DEBUG_ON (zebra, ZEBRA_INTERFACE);
-         else if (strncmp (argv[0], "r", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
            DEBUG_ON (zebra, ZEBRA_REDISTRIBUTE);
        }
 
@@ -1305,19 +1643,29 @@ DEFUN (debug_ospf_zebra,
     }
 
   /* ENABLE_NODE. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     TERM_DEBUG_ON (zebra, ZEBRA);
-  else if (argc == 1)
+  else if (argc == arg_base + 1)
     {
-      if (strncmp (argv[0], "i", 1) == 0)
+      if (strncmp (argv[arg_base + 0], "i", 1) == 0)
        TERM_DEBUG_ON (zebra, ZEBRA_INTERFACE);
-      else if (strncmp (argv[0], "r", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
        TERM_DEBUG_ON (zebra, ZEBRA_REDISTRIBUTE);
     }
 
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf_zebra,
+       debug_ospf_zebra_cmd,
+       "debug ospf zebra",
+       DEBUG_STR
+       OSPF_STR
+       "OSPF Zebra information\n")
+{
+  return debug_ospf_zebra_common(vty, 0, argc, argv);
+}
+
 ALIAS (debug_ospf_zebra,
        debug_ospf_zebra_sub_cmd,
        "debug ospf zebra (interface|redistribute)",
@@ -1327,23 +1675,46 @@ ALIAS (debug_ospf_zebra,
        "Zebra interface\n"
        "Zebra redistribute\n")
 
-DEFUN (no_debug_ospf_zebra,
-       no_debug_ospf_zebra_cmd,
-       "no debug ospf zebra",
-       NO_STR
+DEFUN (debug_ospf_instance_zebra,
+       debug_ospf_instance_zebra_cmd,
+       "debug ospf <1-65535> zebra",
        DEBUG_STR
        OSPF_STR
+       "Instance ID\n"
        "OSPF Zebra information\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return debug_ospf_zebra_common(vty, 1, argc, argv);
+}
+
+ALIAS (debug_ospf_instance_zebra,
+       debug_ospf_instance_zebra_sub_cmd,
+       "debug ospf <1-65535> zebra (interface|redistribute)",
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF Zebra information\n"
+       "Zebra interface\n"
+       "Zebra redistribute\n")
+
+static int
+no_debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc,
+                           const char **argv)
 {
   if (vty->node == CONFIG_NODE)
     {
-      if (argc == 0)
+      if (argc == arg_base + 0)
        DEBUG_OFF (zebra, ZEBRA);
-      else if (argc == 1)
+      else if (argc == arg_base + 1)
        {
-         if (strncmp (argv[0], "i", 1) == 0)
+         if (strncmp (argv[arg_base + 0], "i", 1) == 0)
            DEBUG_OFF (zebra, ZEBRA_INTERFACE);
-         else if (strncmp (argv[0], "r", 1) == 0)
+         else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
            DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE);
        }
 
@@ -1351,19 +1722,30 @@ DEFUN (no_debug_ospf_zebra,
     }
 
   /* ENABLE_NODE. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     TERM_DEBUG_OFF (zebra, ZEBRA);
-  else if (argc == 1)
+  else if (argc == arg_base + 1)
     {
-      if (strncmp (argv[0], "i", 1) == 0)
+      if (strncmp (argv[arg_base + 0], "i", 1) == 0)
        TERM_DEBUG_OFF (zebra, ZEBRA_INTERFACE);
-      else if (strncmp (argv[0], "r", 1) == 0)
+      else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
        TERM_DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE);
     }
 
   return CMD_SUCCESS;
 }
 
+DEFUN (no_debug_ospf_zebra,
+       no_debug_ospf_zebra_cmd,
+       "no debug ospf zebra",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "OSPF Zebra information\n")
+{
+  return no_debug_ospf_zebra_common(vty, 0, argc, argv);
+}
+
 ALIAS (no_debug_ospf_zebra,
        no_debug_ospf_zebra_sub_cmd,
        "no debug ospf zebra (interface|redistribute)",
@@ -1374,6 +1756,36 @@ ALIAS (no_debug_ospf_zebra,
        "Zebra interface\n"
        "Zebra redistribute\n")
 
+DEFUN (no_debug_ospf_instance_zebra,
+       no_debug_ospf_instance_zebra_cmd,
+       "no debug ospf <1-65535> zebra",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF Zebra information\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  return no_debug_ospf_zebra_common(vty, 1, argc, argv);
+}
+
+ALIAS (no_debug_ospf_instance_zebra,
+       no_debug_ospf_instance_zebra_sub_cmd,
+       "no debug ospf <1-65535> zebra (interface|redistribute)",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF Zebra information\n"
+       "Zebra interface\n"
+       "Zebra redistribute\n")
+
+
 DEFUN (debug_ospf_event,
        debug_ospf_event_cmd,
        "debug ospf event",
@@ -1401,6 +1813,47 @@ DEFUN (no_debug_ospf_event,
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf_instance_event,
+       debug_ospf_instance_event_cmd,
+       "debug ospf <1-65535> event",
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF event information\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  if (vty->node == CONFIG_NODE)
+    CONF_DEBUG_ON (event, EVENT);
+  TERM_DEBUG_ON (event, EVENT);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_ospf_instance_event,
+       no_debug_ospf_instance_event_cmd,
+       "no debug ospf <1-65535> event",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF event information\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  if (vty->node == CONFIG_NODE)
+    CONF_DEBUG_OFF (event, EVENT);
+  TERM_DEBUG_OFF (event, EVENT);
+  return CMD_SUCCESS;
+}
+
 DEFUN (debug_ospf_nssa,
        debug_ospf_nssa_cmd,
        "debug ospf nssa",
@@ -1428,16 +1881,57 @@ DEFUN (no_debug_ospf_nssa,
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf_instance_nssa,
+       debug_ospf_instance_nssa_cmd,
+       "debug ospf <1-65535> nssa",
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF nssa information\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
 
-DEFUN (show_debugging_ospf,
-       show_debugging_ospf_cmd,
-       "show debugging ospf",
-       SHOW_STR
+  if (vty->node == CONFIG_NODE)
+    CONF_DEBUG_ON (nssa, NSSA);
+  TERM_DEBUG_ON (nssa, NSSA);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_ospf_instance_nssa,
+       no_debug_ospf_instance_nssa_cmd,
+       "no debug ospf <1-65535> nssa",
+       NO_STR
        DEBUG_STR
-       OSPF_STR)
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF nssa information\n")
+{
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if (!ospf_lookup_instance (instance))
+    return CMD_SUCCESS;
+
+  if (vty->node == CONFIG_NODE)
+    CONF_DEBUG_OFF (nssa, NSSA);
+  TERM_DEBUG_OFF (nssa, NSSA);
+  return CMD_SUCCESS;
+}
+
+
+static int
+show_debugging_ospf_common (struct vty *vty, struct ospf *ospf)
 {
   int i;
 
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
+
   vty_out (vty, "OSPF debugging status:%s", VTY_NEWLINE);
 
   /* Show debug status for events. */
@@ -1523,9 +2017,44 @@ DEFUN (show_debugging_ospf,
   if (IS_DEBUG_OSPF (nssa, NSSA) == OSPF_DEBUG_NSSA)
     vty_out (vty, "  OSPF NSSA debugging is on%s", VTY_NEWLINE);
 
+  vty_out (vty, "%s", VTY_NEWLINE);
+
   return CMD_SUCCESS;
 }
 
+DEFUN (show_debugging_ospf,
+       show_debugging_ospf_cmd,
+       "show debugging ospf",
+       SHOW_STR
+       DEBUG_STR
+       OSPF_STR)
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_debugging_ospf_common(vty, ospf);
+}
+
+DEFUN (show_debugging_ospf_instance,
+       show_debugging_ospf_instance_cmd,
+       "show debugging ospf <1-65535>",
+       SHOW_STR
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance (instance)) == NULL )
+    return CMD_SUCCESS;
+
+  return show_debugging_ospf_common(vty, ospf);
+}
+
 /* Debug node. */
 static struct cmd_node debug_node =
 {
@@ -1544,58 +2073,69 @@ config_write_debug (struct vty *vty)
   const char *detail_str[] = {"", " send", " recv", "", " detail",
                        " send detail", " recv detail", " detail"};
 
+  struct ospf *ospf;
+  char str[16];
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  if (ospf->instance)
+    sprintf(str, " %d", ospf->instance);
+  else
+    sprintf(str, "");
+
   /* debug ospf ism (status|events|timers). */
   if (IS_CONF_DEBUG_OSPF (ism, ISM) == OSPF_DEBUG_ISM)
-    vty_out (vty, "debug ospf ism%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf%s ism%s", str, VTY_NEWLINE);
   else
     {
       if (IS_CONF_DEBUG_OSPF (ism, ISM_STATUS))
-       vty_out (vty, "debug ospf ism status%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s ism status%s", str, VTY_NEWLINE);
       if (IS_CONF_DEBUG_OSPF (ism, ISM_EVENTS))
-       vty_out (vty, "debug ospf ism event%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s ism event%s", str, VTY_NEWLINE);
       if (IS_CONF_DEBUG_OSPF (ism, ISM_TIMERS))
-       vty_out (vty, "debug ospf ism timer%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s ism timer%s", str, VTY_NEWLINE);
     }
 
   /* debug ospf nsm (status|events|timers). */
   if (IS_CONF_DEBUG_OSPF (nsm, NSM) == OSPF_DEBUG_NSM)
-    vty_out (vty, "debug ospf nsm%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf%s nsm%s", str, VTY_NEWLINE);
   else
     {
       if (IS_CONF_DEBUG_OSPF (nsm, NSM_STATUS))
-       vty_out (vty, "debug ospf nsm status%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s nsm status%s", str, VTY_NEWLINE);
       if (IS_CONF_DEBUG_OSPF (nsm, NSM_EVENTS))
-       vty_out (vty, "debug ospf nsm event%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s nsm event%s", str, VTY_NEWLINE);
       if (IS_CONF_DEBUG_OSPF (nsm, NSM_TIMERS))
-       vty_out (vty, "debug ospf nsm timer%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s nsm timer%s", str, VTY_NEWLINE);
     }
 
   /* debug ospf lsa (generate|flooding|install|refresh). */
   if (IS_CONF_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
-    vty_out (vty, "debug ospf lsa%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf%s lsa%s", str, VTY_NEWLINE);
   else
     {
       if (IS_CONF_DEBUG_OSPF (lsa, LSA_GENERATE))
-       vty_out (vty, "debug ospf lsa generate%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s lsa generate%s", str, VTY_NEWLINE);
       if (IS_CONF_DEBUG_OSPF (lsa, LSA_FLOODING))
-       vty_out (vty, "debug ospf lsa flooding%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s lsa flooding%s", str, VTY_NEWLINE);
       if (IS_CONF_DEBUG_OSPF (lsa, LSA_INSTALL))
-       vty_out (vty, "debug ospf lsa install%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s lsa install%s", str, VTY_NEWLINE);
       if (IS_CONF_DEBUG_OSPF (lsa, LSA_REFRESH))
-       vty_out (vty, "debug ospf lsa refresh%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s lsa refresh%s", str, VTY_NEWLINE);
 
       write = 1;
     }
 
   /* debug ospf zebra (interface|redistribute). */
   if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA) == OSPF_DEBUG_ZEBRA)
-    vty_out (vty, "debug ospf zebra%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf%s zebra%s", str, VTY_NEWLINE);
   else
     {
       if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
-       vty_out (vty, "debug ospf zebra interface%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s zebra interface%s", str, VTY_NEWLINE);
       if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
-       vty_out (vty, "debug ospf zebra redistribute%s", VTY_NEWLINE);
+       vty_out (vty, "debug ospf%s zebra redistribute%s", str, VTY_NEWLINE);
 
       write = 1;
     }
@@ -1603,14 +2143,14 @@ config_write_debug (struct vty *vty)
   /* debug ospf event. */
   if (IS_CONF_DEBUG_OSPF (event, EVENT) == OSPF_DEBUG_EVENT)
     {
-      vty_out (vty, "debug ospf event%s", VTY_NEWLINE);
+      vty_out (vty, "debug ospf%s event%s", str, VTY_NEWLINE);
       write = 1;
     }
 
   /* debug ospf nssa. */
   if (IS_CONF_DEBUG_OSPF (nssa, NSSA) == OSPF_DEBUG_NSSA)
     {
-      vty_out (vty, "debug ospf nssa%s", VTY_NEWLINE);
+      vty_out (vty, "debug ospf%s nssa%s", str, VTY_NEWLINE);
       write = 1;
     }
   
@@ -1620,7 +2160,7 @@ config_write_debug (struct vty *vty)
     r &= conf_debug_ospf_packet[i] & (OSPF_DEBUG_SEND_RECV|OSPF_DEBUG_DETAIL);
   if (r == (OSPF_DEBUG_SEND_RECV|OSPF_DEBUG_DETAIL))
     {
-      vty_out (vty, "debug ospf packet all detail%s", VTY_NEWLINE);
+      vty_out (vty, "debug ospf%s packet all detail%s", str, VTY_NEWLINE);
       return 1;
     }
 
@@ -1630,10 +2170,10 @@ config_write_debug (struct vty *vty)
     r &= conf_debug_ospf_packet[i] & OSPF_DEBUG_SEND_RECV;
   if (r == OSPF_DEBUG_SEND_RECV)
     {
-      vty_out (vty, "debug ospf packet all%s", VTY_NEWLINE);
+      vty_out (vty, "debug ospf%s packet all%s", str, VTY_NEWLINE);
       for (i = 0; i < 5; i++)
        if (conf_debug_ospf_packet[i] & OSPF_DEBUG_DETAIL)
-         vty_out (vty, "debug ospf packet %s detail%s",
+         vty_out (vty, "debug ospf%s packet %s detail%s", str,
                   type_str[i],
                   VTY_NEWLINE);
       return 1;
@@ -1646,7 +2186,7 @@ config_write_debug (struct vty *vty)
       if (conf_debug_ospf_packet[i] == 0)
        continue;
       
-      vty_out (vty, "debug ospf packet %s%s%s",
+      vty_out (vty, "debug ospf%s packet %s%s%s", str,
               type_str[i], detail_str[conf_debug_ospf_packet[i]],
               VTY_NEWLINE);
       write = 1;
@@ -1689,6 +2229,34 @@ debug_init ()
   install_element (ENABLE_NODE, &no_debug_ospf_event_cmd);
   install_element (ENABLE_NODE, &no_debug_ospf_nssa_cmd);
 
+  install_element (ENABLE_NODE, &show_debugging_ospf_instance_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_packet_send_recv_detail_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_packet_send_recv_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_packet_all_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_ism_sub_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_ism_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_nsm_sub_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_nsm_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_lsa_sub_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_lsa_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_zebra_sub_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_zebra_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_event_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_instance_nssa_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_send_recv_detail_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_send_recv_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_all_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_ism_sub_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_ism_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_nsm_sub_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_nsm_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_lsa_sub_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_lsa_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_zebra_sub_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_zebra_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_event_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_instance_nssa_cmd);
+
   install_element (CONFIG_NODE, &debug_ospf_packet_send_recv_detail_cmd);
   install_element (CONFIG_NODE, &debug_ospf_packet_send_recv_cmd);
   install_element (CONFIG_NODE, &debug_ospf_packet_all_cmd);
@@ -1715,4 +2283,31 @@ debug_init ()
   install_element (CONFIG_NODE, &no_debug_ospf_zebra_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf_event_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf_nssa_cmd);
+
+  install_element (CONFIG_NODE, &debug_ospf_instance_packet_send_recv_detail_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_packet_send_recv_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_packet_all_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_ism_sub_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_ism_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_nsm_sub_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_nsm_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_lsa_sub_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_lsa_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_zebra_sub_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_zebra_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_event_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_instance_nssa_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_send_recv_detail_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_send_recv_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_all_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_ism_sub_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_ism_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_nsm_sub_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_nsm_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_lsa_sub_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_lsa_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_zebra_sub_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_zebra_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_event_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_instance_nssa_cmd);
 }
index d18314a9d9253a24e444593ece62a84adaf3e9c8..1d107ca0d061b6e03d1627814ea08fdaa148fc0d 100644 (file)
@@ -92,19 +92,33 @@ ospf_external_info_check (struct ospf_lsa *lsa)
 
   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
     {
-      int redist_type = is_prefix_default (&p) ? DEFAULT_ROUTE : type;
-      if (ospf_is_type_redistributed (redist_type))
-       if (EXTERNAL_INFO (type))
-         {
-           rn = route_node_lookup (EXTERNAL_INFO (type),
-                                   (struct prefix *) &p);
-           if (rn)
-             {
-               route_unlock_node (rn);
-               if (rn->info != NULL)
-                 return (struct external_info *) rn->info;
-             }
-         }
+      int redist_on = 0;
+
+      redist_on = is_prefix_default (&p) ? zclient->default_information :
+                  zclient->redist[type].enabled;
+      if (redist_on)
+        {
+          struct list *ext_list;
+          struct listnode *node;
+          struct ospf_external *ext;
+
+          ext_list = om->external[type];
+          if (!ext_list)
+            continue;
+
+          for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
+            {
+              if (ext->external_info)
+                rn = route_node_lookup (ext->external_info,
+                                        (struct prefix *) &p);
+              if (rn)
+                {
+                  route_unlock_node (rn);
+                  if (rn->info != NULL)
+                    return (struct external_info *) rn->info;
+                }
+            }
+        }
     }
 
   return NULL;
index 1de03440ce70c65c3c74ac4495e67b70bba59775..f988468e3a76d1d012c8c3d3e352d1a8926757fc 100644 (file)
@@ -1590,16 +1590,23 @@ ospf_get_nssa_ip (struct ospf_area *area)
 #define DEFAULT_METRIC_TYPE                 EXTERNAL_METRIC_TYPE_2
 
 int
-metric_type (struct ospf *ospf, u_char src)
+metric_type (struct ospf *ospf, u_char src, u_short instance)
 {
-  return (ospf->dmetric[src].type < 0 ?
-         DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
+  struct ospf_redist *red;
+
+  red = ospf_redist_lookup(ospf, src, instance);
+
+  return ((!red || red->dmetric.type < 0) ?
+         DEFAULT_METRIC_TYPE : red->dmetric.type);
 }
 
 int
-metric_value (struct ospf *ospf, u_char src)
+metric_value (struct ospf *ospf, u_char src, u_short instance)
 {
-  if (ospf->dmetric[src].value < 0)
+  struct ospf_redist *red;
+
+  red = ospf_redist_lookup(ospf, src, instance);
+  if (!red || red->dmetric.value < 0)
     {
       if (src == DEFAULT_ROUTE)
        {
@@ -1614,7 +1621,7 @@ metric_value (struct ospf *ospf, u_char src)
        return ospf->default_metric;
     }
 
-  return ospf->dmetric[src].value;
+  return red->dmetric.value;
 }
 
 /* Set AS-external-LSA body. */
@@ -1627,6 +1634,7 @@ ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
   u_int32_t mvalue;
   int mtype;
   int type;
+  u_short instance;
 
   /* Put Network Mask. */
   masklen2ip (p->prefixlen, &mask);
@@ -1634,12 +1642,13 @@ ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
 
   /* If prefix is default, specify DEFAULT_ROUTE. */
   type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
+  instance = is_prefix_default (&ei->p) ? 0 : ei->instance;
   
   mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
-    ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
+    ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type, instance);
 
   mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
-    ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
+    ROUTEMAP_METRIC (ei) : metric_value (ospf, type, instance);
 
   /* Put type of external metric. */
   stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
@@ -2106,17 +2115,25 @@ ospf_external_lsa_originate_timer (struct thread *thread)
   struct external_info *ei;
   struct route_table *rt;
   int type = THREAD_VAL (thread);
+  struct list *ext_list;
+  struct listnode *node;
+  struct ospf_external *ext;
 
   ospf->t_external_lsa = NULL;
 
-  /* Originate As-external-LSA from all type of distribute source. */
-  if ((rt = EXTERNAL_INFO (type)))
-    for (rn = route_top (rt); rn; rn = route_next (rn))
-      if ((ei = rn->info) != NULL)
-       if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
-         if (!ospf_external_lsa_originate (ospf, ei))
-           zlog_warn ("LSA: AS-external-LSA was not originated.");
-  
+  ext_list = om->external[type];
+  if (!ext_list)
+    return 0;
+
+  for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
+    /* Originate As-external-LSA from all type of distribute source. */
+    if ((rt = ext->external_info))
+      for (rn = route_top (rt); rn; rn = route_next (rn))
+        if ((ei = rn->info) != NULL)
+          if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
+            if (!ospf_external_lsa_originate (ospf, ei))
+              zlog_warn ("LSA: AS-external-LSA was not originated.");
+
   return 0;
 }
 
@@ -2133,17 +2150,30 @@ ospf_default_external_info (struct ospf *ospf)
 
   /* First, lookup redistributed default route. */
   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
-    if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
-      {
-       rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
-       if (rn != NULL)
-         {
-           route_unlock_node (rn);
-           assert (rn->info);
-           if (ospf_redistribute_check (ospf, rn->info, NULL))
-             return rn->info;
-         }
-      }
+    {
+      struct list *ext_list;
+      struct listnode *node;
+      struct ospf_external *ext;
+
+      if (type == ZEBRA_ROUTE_OSPF)
+        continue;
+
+      ext_list = om->external[type];
+      if (!ext_list)
+        continue;
+
+      for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
+        {
+          rn = route_node_lookup (ext->external_info, (struct prefix *) &p);
+          if (rn != NULL)
+            {
+              route_unlock_node (rn);
+              assert (rn->info);
+              if (ospf_redistribute_check (ospf, rn->info, NULL))
+                return rn->info;
+            }
+        }
+    }
 
   return NULL;
 }
@@ -2167,7 +2197,7 @@ ospf_default_originate_timer (struct thread *thread)
       /* If there is no default route via redistribute,
         then originate AS-external-LSA with nexthop 0 (self). */
       nexthop.s_addr = 0;
-      ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop, 0);
+      ospf_external_info_add (DEFAULT_ROUTE, 0, p, 0, nexthop, 0);
     }
 
   if ((ei = ospf_default_external_info (ospf)))
@@ -2298,15 +2328,18 @@ ospf_external_lsa_refresh_default (struct ospf *ospf)
 }
 
 void
-ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
+ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, u_short instance,
+                                int force)
 {
   struct route_node *rn;
   struct external_info *ei;
+  struct ospf_external *ext;
 
   if (type != DEFAULT_ROUTE)
-    if (EXTERNAL_INFO(type))
+    if ((ext = ospf_external_lookup(type, instance)) &&
+        EXTERNAL_INFO (ext))
       /* Refresh each redistributed AS-external-LSAs. */
-      for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
+      for (rn = route_top (EXTERNAL_INFO (ext)); rn; rn = route_next (rn))
        if ((ei = rn->info))
          if (!is_prefix_default (&ei->p))
            {
index c71877da4d31ad07f048835d399b1547c1520a6d..624efc4c157002d40433e50191affc7f14c543fb 100644 (file)
@@ -314,7 +314,7 @@ extern struct ospf_lsa *ospf_lsa_refresh (struct ospf *, struct ospf_lsa *);
  
 extern void ospf_external_lsa_refresh_default (struct ospf *);
 
-extern void ospf_external_lsa_refresh_type (struct ospf *, u_char, int);
+extern void ospf_external_lsa_refresh_type (struct ospf *, u_char, u_short, int);
 extern struct ospf_lsa *ospf_external_lsa_refresh (struct ospf *,
                                                    struct ospf_lsa *,
                                                    struct external_info *,
@@ -333,8 +333,8 @@ extern void ospf_lsa_maxage_delete (struct ospf *, struct ospf_lsa *);
 extern void ospf_discard_from_db (struct ospf *, struct ospf_lsdb *, struct ospf_lsa*);
 extern int is_prefix_default (struct prefix_ipv4 *);
 
-extern int metric_type (struct ospf *, u_char);
-extern int metric_value (struct ospf *, u_char);
+extern int metric_type (struct ospf *, u_char, u_short);
+extern int metric_value (struct ospf *, u_char, u_short);
 
 extern struct in_addr ospf_get_nssa_ip (struct ospf_area *);
 extern int ospf_translated_nssa_compare (struct ospf_lsa *, struct ospf_lsa *);
index 19b9121cc6ed24f7c3ede52c0627d418cb651bfc..d34e65dc4227377245ea49540c37ae853d972367 100644 (file)
@@ -73,12 +73,13 @@ struct zebra_privs_t ospfd_privs =
 };
 
 /* Configuration filename and directory. */
-char config_default[] = SYSCONFDIR OSPF_DEFAULT_CONFIG;
+char config_default[100];
 
 /* OSPFd options. */
 struct option longopts[] = 
 {
   { "daemon",      no_argument,       NULL, 'd'},
+  { "instance",    required_argument, NULL, 'n'},
   { "config_file", required_argument, NULL, 'f'},
   { "pid_file",    required_argument, NULL, 'i'},
   { "socket",      required_argument, NULL, 'z'},
@@ -99,7 +100,7 @@ struct option longopts[] =
 struct thread_master *master;
 
 /* Process ID saved for use by init system */
-const char *pid_file = PATH_OSPFD_PID;
+char pid_file[100];
 
 #ifdef SUPPORT_OSPF_API
 extern int ospf_apiserver_enable;
@@ -116,6 +117,7 @@ usage (char *progname, int status)
       printf ("Usage : %s [OPTION...]\n\
 Daemon which manages OSPF.\n\n\
 -d, --daemon       Runs in daemon mode\n\
+-n, --instance     Set the instance id\n\
 -f, --config_file  Set configuration file name\n\
 -i, --pid_file     Set process identifier file name\n\
 -z, --socket       Set path of zebra socket\n\
@@ -182,9 +184,11 @@ main (int argc, char **argv)
   char *p;
   char *vty_addr = NULL;
   int vty_port = OSPF_VTY_PORT;
+  char vty_path[100];
   int daemon_mode = 0;
   char *config_file = NULL;
   char *progname;
+  u_short instance = 0;
   struct thread thread;
   int dryrun = 0;
 
@@ -203,13 +207,18 @@ main (int argc, char **argv)
     {
       int opt;
 
-      opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:avC", longopts, 0);
+      opt = getopt_long (argc, argv, "df:i:n:z:hA:P:u:g:avC", longopts, 0);
     
       if (opt == EOF)
        break;
 
       switch (opt) 
        {
+       case 'n':
+          instance = atoi(optarg);
+          if (instance < 1  ||  instance > 65535)
+            exit(0);
+         break;
        case 0:
          break;
        case 'd':
@@ -222,7 +231,7 @@ main (int argc, char **argv)
          vty_addr = optarg;
          break;
         case 'i':
-          pid_file = optarg;
+          strcpy(pid_file,optarg);
           break;
        case 'z':
          zclient_serv_path_set (optarg);
@@ -274,7 +283,7 @@ main (int argc, char **argv)
       exit (1);
     }
 
-  zlog_default = openzlog (progname, ZLOG_OSPF,
+  zlog_default = openzlog (progname, ZLOG_OSPF, instance,
                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
 
   /* OSPF master init. */
@@ -296,7 +305,7 @@ main (int argc, char **argv)
 
   /* OSPFd inits. */
   ospf_if_init ();
-  ospf_zebra_init ();
+  ospf_zebra_init (instance);
 
   /* OSPF vty inits. */
   ospf_vty_init ();
@@ -314,13 +323,17 @@ main (int argc, char **argv)
   /* Need to initialize the default ospf structure, so the interface mode
      commands can be duly processed if they are received before 'router ospf',
      when quagga(ospfd) is restarted */
-  if (!ospf_get())
+  if (!ospf_get_instance(instance))
     {
       zlog_err("OSPF instance init failed: %s", strerror(errno));
       exit (1);
     }
 
   /* Get configuration file. */
+  if (instance)
+    sprintf(config_default, "%sospfd-%d.conf", SYSCONFDIR, instance);
+  else
+    sprintf(config_default, "%s%s", SYSCONFDIR, OSPF_DEFAULT_CONFIG);
   vty_read_config (config_file, config_default);
 
   /* Start execution only if not in dry-run mode */
@@ -334,14 +347,23 @@ main (int argc, char **argv)
       exit (1);
     }
 
+  /* Create VTY socket */
+  if (instance)
+    {
+      sprintf(pid_file, "/var/run/quagga/ospfd-%d.pid", instance);
+      sprintf(vty_path, "/var/run/quagga/ospfd-%d.vty", instance);
+    }
+  else
+    {
+      strcpy(pid_file, PATH_OSPFD_PID);
+      strcpy(vty_path, OSPF_VTYSH_PATH);
+    }
   /* Process id file create. */
   pid_output (pid_file);
-
-  /* Create VTY socket */
-  vty_serv_sock (vty_addr, vty_port, OSPF_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_path);
 
   /* Print banner. */
-  zlog_notice ("OSPFd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
+  zlog_notice ("OSPFd %s starting: vty@%d, %s", QUAGGA_VERSION, vty_port, vty_path);
 
   /* Fetch next active thread. */
   while (thread_fetch (master, &thread))
index d3266e83557f429e6850bc80c271ebfc99118c2e..2cbd04bbee2ddab41ecc356c0d9de6519b3a553e 100644 (file)
@@ -719,9 +719,19 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
          /* kevinm: refresh any redistributions */
          for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++)
            {
-             if (x == ZEBRA_ROUTE_OSPF || x == ZEBRA_ROUTE_OSPF6)
-               continue;
-             ospf_external_lsa_refresh_type (oi->ospf, x, force);
+              struct list *red_list;
+              struct listnode *node;
+              struct ospf_redist *red;
+
+              if (x == ZEBRA_ROUTE_OSPF6)
+                continue;
+
+              red_list = oi->ospf->redist[x];
+              if (!red_list)
+                continue;
+
+              for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+               ospf_external_lsa_refresh_type (oi->ospf, x, red->instance, force);
            }
           /* XXX: Clearly some thing is wrong with refresh of external LSAs
            * this added to hack around defaults not refreshing after a timer
index 744952c96eef2cc9c5fee0c41f82b990da1d8b14..999893ff1f2d3b49ba60258707b493487bc16b07 100644 (file)
@@ -767,6 +767,9 @@ DEFUN (capability_opaque,
 {
   struct ospf *ospf = (struct ospf *) vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   /* Turn on the "master switch" of opaque-lsa capability. */
   if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
     {
@@ -794,6 +797,9 @@ DEFUN (no_capability_opaque,
 {
   struct ospf *ospf = (struct ospf *) vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   /* Turn off the "master switch" of opaque-lsa capability. */
   if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
     {
index ff1bdae59fa7068a4291f2dc0e4a8228db6a3522..491b9c54b40add2d3a9e2d4e1189f0c6fb7248f2 100644 (file)
@@ -2889,7 +2889,7 @@ ospf_read (struct thread *thread)
     {
       if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
         {
-          if (IS_DEBUG_OSPF_EVENT)
+          if (!ospf->instance && IS_DEBUG_OSPF_EVENT)
             zlog_debug ("Packet from [%s] received on link %s"
                         " but no ospf_interface",
                         inet_ntoa (iph->ip_src), ifp->name);
index 425524d48441492e1b21e657a20e099de93091f7..6e02de3a16becbe38a0f707db3d986943275c771 100644 (file)
@@ -45,6 +45,7 @@ ospf_route_map_update (const char *name)
 {
   struct ospf *ospf;
   int type;
+  u_short instance; // PENDING
 
   /* If OSPF instatnce does not exist, return right now. */
   ospf = ospf_lookup ();
@@ -54,22 +55,33 @@ ospf_route_map_update (const char *name)
   /* Update route-map */
   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
     {
-      if (ROUTEMAP_NAME (ospf, type)
-         && strcmp (ROUTEMAP_NAME (ospf, type), name) == 0)
-       {
-         /* Keep old route-map. */
-         struct route_map *old = ROUTEMAP (ospf, type);
-
-         /* Update route-map. */
-         ROUTEMAP (ospf, type) =
-           route_map_lookup_by_name (ROUTEMAP_NAME (ospf, type));
-
-         /* No update for this distribute type. */
-         if (old == NULL && ROUTEMAP (ospf, type) == NULL)
-           continue;
-
-         ospf_distribute_list_update (ospf, type);
-       }
+      struct list *red_list;
+      struct listnode *node;
+      struct ospf_redist *red;
+
+      red_list = ospf->redist[type];
+      if (!red_list)
+        continue;
+
+      for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+        {
+          if (ROUTEMAP_NAME (red)
+              && strcmp (ROUTEMAP_NAME (red), name) == 0)
+            {
+              /* Keep old route-map. */
+              struct route_map *old = ROUTEMAP (red);
+
+              /* Update route-map. */
+              ROUTEMAP (red) =
+                route_map_lookup_by_name (ROUTEMAP_NAME (red));
+
+              /* No update for this distribute type. */
+              if (old == NULL && ROUTEMAP (red) == NULL)
+                continue;
+
+              ospf_distribute_list_update (ospf, type, red->instance);
+            }
+        }
     }
 }
 
@@ -84,13 +96,23 @@ ospf_route_map_event (route_map_event_t event, const char *name)
   if (ospf == NULL)
     return;
 
-  /* Update route-map. */
   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
     {
-      if (ROUTEMAP_NAME (ospf, type) &&  ROUTEMAP (ospf, type)
-         && !strcmp (ROUTEMAP_NAME (ospf, type), name))
+      struct list *red_list;
+      struct listnode *node;
+      struct ospf_redist *red;
+
+      red_list = ospf->redist[type];
+      if (!red_list)
+        continue;
+
+      for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
         {
-          ospf_distribute_list_update (ospf, type);
+          if (ROUTEMAP_NAME (red) &&  ROUTEMAP (red)
+              && !strcmp (ROUTEMAP_NAME (red), name))
+            {
+              ospf_distribute_list_update (ospf, type, red->instance);
+            }
         }
     }
 }
index c605ce68d3a077f244fd6720efd98a9be73bcc4f..e7e1a4362f292324db33296ec4b57d879dbbe586 100644 (file)
@@ -1473,6 +1473,10 @@ DEFUN (mpls_te,
 {
   struct listnode *node, *nnode;
   struct mpls_te_link *lp;
+  struct ospf *ospf = vty->index;
+
+  if (!ospf)
+    return CMD_SUCCESS;
 
   if (OspfMplsTE.status == enabled)
     return CMD_SUCCESS;
@@ -1511,6 +1515,10 @@ DEFUN (no_mpls_te,
 {
   struct listnode *node, *nnode;
   struct mpls_te_link *lp;
+  struct ospf *ospf = vty->index;
+
+  if (!ospf)
+    return CMD_SUCCESS;
 
   if (OspfMplsTE.status == disabled)
     return CMD_SUCCESS;
@@ -1537,6 +1545,10 @@ DEFUN (mpls_te_router_addr,
 {
   struct te_tlv_router_addr *ra = &OspfMplsTE.router_addr;
   struct in_addr value;
+  struct ospf *ospf = vty->index;
+
+  if (!ospf)
+    return CMD_SUCCESS;
 
   if (! inet_aton (argv[0], &value))
     {
index 2854a41b4f4c7fad7201dd49d56c7fc07609559d..4f0727b583f1dd1113c7d214fd18ff46737871eb 100644 (file)
@@ -149,12 +149,38 @@ DEFUN (router_ospf,
        "Enable a routing process\n"
        "Start OSPF configuration\n")
 {
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  ospf = ospf_lookup();
+  if (!ospf)
+    {
+      vty_out (vty, "There isn't active ospf instance %s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
   vty->node = OSPF_NODE;
-  vty->index = ospf_get ();
+
+  if (argc)
+    VTY_GET_INTEGER ("Instance", instance, argv[0]);
+
+  /* The following logic to set the vty->index is in place to be able
+     to ignore the commands which dont belong to this instance. */
+  if (ospf->instance != instance)
+    vty->index = NULL;
+  else
+    vty->index = ospf;
  
   return CMD_SUCCESS;
 }
 
+ALIAS (router_ospf,
+       router_ospf_instance_cmd,
+       "router ospf <1-65535>",
+       "Enable a routing process\n"
+       "Start OSPF configuration\n"
+       "Instance ID\n")
+
 DEFUN (no_router_ospf,
        no_router_ospf_cmd,
        "no router ospf",
@@ -163,19 +189,27 @@ DEFUN (no_router_ospf,
        "Start OSPF configuration\n")
 {
   struct ospf *ospf;
+  u_short instance = 0;
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, "There isn't active ospf instance%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
+  if (argc)
+    VTY_GET_INTEGER ("Instance", instance, argv[0]);
+
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
 
   ospf_finish (ospf);
 
   return CMD_SUCCESS;
 }
 
+ALIAS (no_router_ospf,
+       no_router_ospf_instance_cmd,
+       "no router ospf <1-65535>",
+       NO_STR
+       "Enable a routing process\n"
+       "Start OSPF configuration\n"
+       "Instance ID\n")
+
 DEFUN (ospf_router_id,
        ospf_router_id_cmd,
        "ospf router-id A.B.C.D",
@@ -187,6 +221,9 @@ DEFUN (ospf_router_id,
   struct in_addr router_id;
   int ret;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ret = inet_aton (argv[0], &router_id);
   if (!ret)
     {
@@ -216,6 +253,9 @@ DEFUN (no_ospf_router_id,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf->router_id_static.s_addr = 0;
 
   ospf_router_id_update (ospf);
@@ -298,6 +338,9 @@ DEFUN (ospf_passive_interface,
   struct route_node *rn;
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (argc == 0)
     {
       ospf_passive_interface_default (ospf, OSPF_IF_PASSIVE);
@@ -374,6 +417,9 @@ DEFUN (no_ospf_passive_interface,
   struct route_node *rn;
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (argc == 0)
     {
       ospf_passive_interface_default (ospf, OSPF_IF_ACTIVE);
@@ -446,6 +492,16 @@ DEFUN (ospf_network_area,
   struct in_addr area_id;
   int ret, format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
+  if (ospf->instance)
+    {
+      vty_out (vty, "The network command is not supported in multi-instance ospf%s",
+              VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
   if (ospf->if_ospf_cli_count > 0)
     {
       vty_out (vty, "Please remove all ip ospf area x.x.x.x commands first.%s",
@@ -482,6 +538,16 @@ DEFUN (no_ospf_network_area,
   struct in_addr area_id;
   int ret, format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
+  if (ospf->instance)
+    {
+      vty_out (vty, "The network command is not supported in multi-instance ospf%s",
+              VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
   /* Get network prefix and Area ID. */
   VTY_GET_IPV4_PREFIX ("network prefix", p, argv[0]);
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[1]);
@@ -513,6 +579,9 @@ DEFUN (ospf_area_range,
   int format;
   u_int32_t cost;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
   VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
 
@@ -574,6 +643,9 @@ DEFUN (ospf_area_range_not_advertise,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
   VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
 
@@ -597,6 +669,9 @@ DEFUN (no_ospf_area_range,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
   VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
 
@@ -658,6 +733,9 @@ DEFUN (ospf_area_range_substitute,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
   VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
   VTY_GET_IPV4_PREFIX ("substituted network prefix", s, argv[2]);
@@ -684,6 +762,9 @@ DEFUN (no_ospf_area_range_substitute,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
   VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
   VTY_GET_IPV4_PREFIX ("substituted network prefix", s, argv[2]);
@@ -959,6 +1040,9 @@ DEFUN (ospf_area_vlink,
   int i;
   int ret;
   
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf_vl_config_data_init(&vl_config, vty);
 
   /* Read off first 2 parameters and check them */
@@ -1095,6 +1179,9 @@ DEFUN (no_ospf_area_vlink,
   int i;
   int ret, format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf_vl_config_data_init(&vl_config, vty);
 
   ret = ospf_str2area_id (argv[0], &vl_config.area_id, &format);
@@ -1407,6 +1494,9 @@ DEFUN (ospf_area_shortcut,
   int mode;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[0]);
 
   area = ospf_area_get (ospf, area_id, format);
@@ -1446,6 +1536,9 @@ DEFUN (no_ospf_area_shortcut,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[0]);
 
   area = ospf_area_lookup_by_area_id (ospf, area_id);
@@ -1470,6 +1563,9 @@ DEFUN (ospf_area_stub,
   struct in_addr area_id;
   int ret, format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]);
 
   ret = ospf_area_stub_set (ospf, area_id);
@@ -1498,6 +1594,9 @@ DEFUN (ospf_area_stub_no_summary,
   struct in_addr area_id;
   int ret, format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]);
 
   ret = ospf_area_stub_set (ospf, area_id);
@@ -1526,6 +1625,9 @@ DEFUN (no_ospf_area_stub,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]);
 
   ospf_area_stub_unset (ospf, area_id);
@@ -1548,6 +1650,9 @@ DEFUN (no_ospf_area_stub_no_summary,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]);
   ospf_area_no_summary_unset (ospf, area_id);
 
@@ -1562,6 +1667,9 @@ ospf_area_nssa_cmd_handler (struct vty *vty, int argc, const char *argv[],
   struct in_addr area_id;
   int ret, format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[0]);
 
   ret = ospf_area_nssa_set (ospf, area_id);
@@ -1665,6 +1773,9 @@ DEFUN (no_ospf_area_nssa,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[0]);
 
   ospf_area_nssa_unset (ospf, area_id);
@@ -1689,6 +1800,9 @@ DEFUN (no_ospf_area_nssa_no_summary,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[0]);
   ospf_area_no_summary_unset (ospf, area_id);
 
@@ -1711,6 +1825,9 @@ DEFUN (ospf_area_default_cost,
   int format;
   struct prefix_ipv4 p;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[0]);
   VTY_GET_INTEGER_RANGE ("stub default cost", cost, argv[1], 0, 16777215);
 
@@ -1752,6 +1869,9 @@ DEFUN (no_ospf_area_default_cost,
   int format;
   struct prefix_ipv4 p;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[0]);
   VTY_CHECK_INTEGER_RANGE ("stub default cost", argv[1], 0, OSPF_LS_INFINITY);
 
@@ -1796,6 +1916,9 @@ DEFUN (ospf_area_export_list,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   area = ospf_area_get (ospf, area_id, format);
@@ -1819,6 +1942,9 @@ DEFUN (no_ospf_area_export_list,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   area = ospf_area_lookup_by_area_id (ospf, area_id);
@@ -1845,6 +1971,9 @@ DEFUN (ospf_area_import_list,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   area = ospf_area_get (ospf, area_id, format);
@@ -1868,6 +1997,9 @@ DEFUN (no_ospf_area_import_list,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   area = ospf_area_lookup_by_area_id (ospf, area_id);
@@ -1897,6 +2029,9 @@ DEFUN (ospf_area_filter_list,
   struct prefix_list *plist;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   area = ospf_area_get (ospf, area_id, format);
@@ -1941,6 +2076,9 @@ DEFUN (no_ospf_area_filter_list,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   if ((area = ospf_area_lookup_by_area_id (ospf, area_id)) == NULL)
@@ -1993,6 +2131,9 @@ DEFUN (ospf_area_authentication_message_digest,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   area = ospf_area_get (ospf, area_id, format);
@@ -2014,6 +2155,9 @@ DEFUN (ospf_area_authentication,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   area = ospf_area_get (ospf, area_id, format);
@@ -2036,6 +2180,9 @@ DEFUN (no_ospf_area_authentication,
   struct in_addr area_id;
   int format;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
   area = ospf_area_lookup_by_area_id (ospf, area_id);
@@ -2063,6 +2210,9 @@ DEFUN (ospf_abr_type,
   struct ospf *ospf = vty->index;
   u_char abr_type = OSPF_ABR_UNKNOWN;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (strncmp (argv[0], "c", 1) == 0)
     abr_type = OSPF_ABR_CISCO;
   else if (strncmp (argv[0], "i", 1) == 0)
@@ -2097,6 +2247,9 @@ DEFUN (no_ospf_abr_type,
   struct ospf *ospf = vty->index;
   u_char abr_type = OSPF_ABR_UNKNOWN;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (strncmp (argv[0], "c", 1) == 0)
     abr_type = OSPF_ABR_CISCO;
   else if (strncmp (argv[0], "i", 1) == 0)
@@ -2125,6 +2278,9 @@ DEFUN (ospf_log_adjacency_changes,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
   return CMD_SUCCESS;
 }
@@ -2137,6 +2293,9 @@ DEFUN (ospf_log_adjacency_changes_detail,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
   SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
   return CMD_SUCCESS;
@@ -2150,6 +2309,9 @@ DEFUN (no_ospf_log_adjacency_changes,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
   UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
   return CMD_SUCCESS;
@@ -2164,6 +2326,9 @@ DEFUN (no_ospf_log_adjacency_changes_detail,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
   return CMD_SUCCESS;
 }
@@ -2176,6 +2341,9 @@ DEFUN (ospf_compatible_rfc1583,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
     {
       SET_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE);
@@ -2193,6 +2361,9 @@ DEFUN (no_ospf_compatible_rfc1583,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
     {
       UNSET_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE);
@@ -2221,6 +2392,9 @@ ospf_timers_spf_set (struct vty *vty, unsigned int delay,
 {
   struct ospf *ospf = vty->index;
   
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf->spf_delay = delay;
   ospf->spf_holdtime = hold;
   ospf->spf_max_holdtime = max;
@@ -2316,6 +2490,9 @@ DEFUN (ospf_neighbor,
   unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
   unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]);
 
   if (argc > 1)
@@ -2364,6 +2541,9 @@ DEFUN (ospf_neighbor_poll_interval,
   unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
   unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]);
 
   if (argc > 1)
@@ -2401,6 +2581,9 @@ DEFUN (no_ospf_neighbor,
   struct ospf *ospf = vty->index;
   struct in_addr nbr_addr;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]);
 
   (void)ospf_nbr_nbma_unset (ospf, nbr_addr);
@@ -2447,6 +2630,9 @@ DEFUN (ospf_refresh_timer, ospf_refresh_timer_cmd,
   struct ospf *ospf = vty->index;
   unsigned int interval;
   
+  if (!ospf)
+    return CMD_SUCCESS;
+
   VTY_GET_INTEGER_RANGE ("refresh timer", interval, argv[0], 10, 1800);
   interval = (interval / 10) * 10;
 
@@ -2464,6 +2650,9 @@ DEFUN (no_ospf_refresh_timer, no_ospf_refresh_timer_val_cmd,
   struct ospf *ospf = vty->index;
   unsigned int interval;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (argc == 1)
     {
       VTY_GET_INTEGER_RANGE ("refresh timer", interval, argv[0], 10, 1800);
@@ -2496,6 +2685,9 @@ DEFUN (ospf_auto_cost_reference_bandwidth,
   struct listnode *node;
   struct interface *ifp;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   refbw = strtol (argv[0], NULL, 10);
   if (refbw < 1 || refbw > 4294967)
     {
@@ -2525,6 +2717,9 @@ DEFUN (no_ospf_auto_cost_reference_bandwidth,
   struct listnode *node, *nnode;
   struct interface *ifp;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH)
     return CMD_SUCCESS;
   
@@ -2548,6 +2743,9 @@ DEFUN (ospf_write_multiplier,
   struct ospf *ospf = vty->index;
   u_int32_t write_oi_count;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   write_oi_count = strtol (argv[0], NULL, 10);
   if (write_oi_count < 1 || write_oi_count > 100)
     {
@@ -2574,6 +2772,9 @@ DEFUN (no_ospf_write_multiplier,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
   return CMD_SUCCESS;
 }
@@ -2726,32 +2927,23 @@ show_ip_ospf_area (struct vty *vty, struct ospf_area *area)
   vty_out (vty, "%s", VTY_NEWLINE);
 }
 
-DEFUN (show_ip_ospf,
-       show_ip_ospf_cmd,
-       "show ip ospf",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n")
+static int
+show_ip_ospf_common (struct vty *vty, struct ospf *ospf)
 {
   struct listnode *node, *nnode;
   struct ospf_area * area;
-  struct ospf *ospf;
   struct timeval result;
   char timebuf[OSPF_TIME_DUMP_SIZE];
 
-  /* Check OSPF is enable. */
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
 
   /* Show Router ID. */
   vty_out (vty, " OSPF Routing Process, Router ID: %s%s",
            inet_ntoa (ospf->router_id),
            VTY_NEWLINE);
-  
+
   /* Graceful shutdown */
   if (ospf->t_deferred_shutdown)
     vty_out (vty, " Deferred shutdown in progress, %s remaining%s",
@@ -2860,6 +3052,40 @@ DEFUN (show_ip_ospf,
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_ospf,
+       show_ip_ospf_cmd,
+       "show ip ospf",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n")
+
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return (show_ip_ospf_common(vty, ospf));
+}
+
+DEFUN (show_ip_ospf_instance,
+       show_ip_ospf_instance_cmd,
+       "show ip ospf <1-65535>",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return (show_ip_ospf_common(vty, ospf));
+}
+
 
 static void
 show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf,
@@ -3026,42 +3252,75 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf,
     }
 }
 
-DEFUN (show_ip_ospf_interface,
-       show_ip_ospf_interface_cmd,
-       "show ip ospf interface [INTERFACE]",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       "Interface information\n"
-       "Interface name\n")
+static int
+show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int arg_base,
+                               int argc, const char **argv)
 {
   struct interface *ifp;
-  struct ospf *ospf;
   struct listnode *node;
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
+
+  if (argc == arg_base + 0)
     {
-      vty_out (vty, "OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
+      /* Show All Interfaces. */
+      for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
+        if (ospf_oi_count(ifp))
+          show_ip_ospf_interface_sub (vty, ospf, ifp);
     }
-
-  /* Show All Interfaces. */
-  if (argc == 0)
-    for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
-      show_ip_ospf_interface_sub (vty, ospf, ifp);
-  /* Interface name is specified. */
   else
     {
-      if ((ifp = if_lookup_by_name (argv[0])) == NULL)
+      /* Interface name is specified. */
+      if ((ifp = if_lookup_by_name (argv[arg_base + 0])) == NULL)
         vty_out (vty, "No such interface name%s", VTY_NEWLINE);
       else
         show_ip_ospf_interface_sub (vty, ospf, ifp);
     }
 
+  vty_out (vty, "%s", VTY_NEWLINE);
+
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_ospf_interface,
+       show_ip_ospf_interface_cmd,
+       "show ip ospf interface [INTERFACE]",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Interface information\n"
+       "Interface name\n")
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_interface_common(vty, ospf, 0, argc, argv);
+}
+
+DEFUN (show_ip_ospf_instance_interface,
+       show_ip_ospf_instance_interface_cmd,
+       "show ip ospf <1-65535> interface [INTERFACE]",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Interface information\n"
+       "Interface name\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_interface_common(vty, ospf, 1, argc, argv);
+}
+
 static void
 show_ip_ospf_neighbour_header (struct vty *vty)
 {
@@ -3110,56 +3369,74 @@ show_ip_ospf_neighbor_sub (struct vty *vty, struct ospf_interface *oi)
          }
 }
 
-DEFUN (show_ip_ospf_neighbor,
-       show_ip_ospf_neighbor_cmd,
-       "show ip ospf neighbor",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       "Neighbor list\n")
+static int
+show_ip_ospf_neighbor_common (struct vty *vty, struct ospf *ospf)
 {
-  struct ospf *ospf;
   struct ospf_interface *oi;
   struct listnode *node;
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance, VTY_NEWLINE);
 
   show_ip_ospf_neighbour_header (vty);
 
   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
     show_ip_ospf_neighbor_sub (vty, oi);
 
+  vty_out (vty, "%s", VTY_NEWLINE);
+
   return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_all,
-       show_ip_ospf_neighbor_all_cmd,
-       "show ip ospf neighbor all",
+DEFUN (show_ip_ospf_neighbor,
+       show_ip_ospf_neighbor_cmd,
+       "show ip ospf neighbor",
        SHOW_STR
        IP_STR
        "OSPF information\n"
-       "Neighbor list\n"
-       "include down status neighbor\n")
+       "Neighbor list\n")
 {
-  struct ospf *ospf = ospf_lookup ();
-  struct listnode *node;
-  struct ospf_interface *oi;
+  struct ospf *ospf;
 
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
-  
-  show_ip_ospf_neighbour_header (vty);
-  
-  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
-    {
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_common(vty, ospf);
+}
+
+
+DEFUN (show_ip_ospf_instance_neighbor,
+       show_ip_ospf_instance_neighbor_cmd,
+       "show ip ospf <1-65535> neighbor",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Neighbor list\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance(instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_common(vty, ospf);
+}
+
+static int
+show_ip_ospf_neighbor_all_common (struct vty *vty, struct ospf *ospf)
+{
+  struct listnode *node;
+  struct ospf_interface *oi;
+
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance, VTY_NEWLINE);
+
+  show_ip_ospf_neighbour_header (vty);
+
+  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
+    {
       struct listnode *nbr_node;
       struct ospf_nbr_nbma *nbr_nbma;
 
@@ -3180,35 +3457,64 @@ DEFUN (show_ip_ospf_neighbor_all,
       }
     }
 
+  vty_out (vty, "%s", VTY_NEWLINE);
+
   return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_int,
-       show_ip_ospf_neighbor_int_cmd,
-       "show ip ospf neighbor IFNAME",
+DEFUN (show_ip_ospf_neighbor_all,
+       show_ip_ospf_neighbor_all_cmd,
+       "show ip ospf neighbor all",
        SHOW_STR
        IP_STR
        "OSPF information\n"
        "Neighbor list\n"
-       "Interface name\n")
+       "include down status neighbor\n")
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_all_common(vty, ospf);
+}
+
+DEFUN (show_ip_ospf_instance_neighbor_all,
+       show_ip_ospf_instance_neighbor_all_cmd,
+       "show ip ospf <1-65535> neighbor all",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Neighbor list\n"
+       "include down status neighbor\n")
 {
   struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance(instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_all_common(vty, ospf);
+}
+
+static int
+show_ip_ospf_neighbor_int_common (struct vty *vty, struct ospf *ospf, int arg_base,
+                                  const char **argv)
+{
   struct interface *ifp;
   struct route_node *rn;
-  ifp = if_lookup_by_name (argv[0]);
+
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance, VTY_NEWLINE);
+
+  ifp = if_lookup_by_name (argv[arg_base + 0]);
   if (!ifp)
     {
       vty_out (vty, "No such interface.%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
-
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
   
   show_ip_ospf_neighbour_header (vty);
   
@@ -3225,6 +3531,43 @@ DEFUN (show_ip_ospf_neighbor_int,
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_ospf_neighbor_int,
+       show_ip_ospf_neighbor_int_cmd,
+       "show ip ospf neighbor IFNAME",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Neighbor list\n"
+       "Interface name\n")
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_int_common(vty, ospf, 0, argv);
+}
+
+DEFUN (show_ip_ospf_instance_neighbor_int,
+       show_ip_ospf_instance_neighbor_int_cmd,
+       "show ip ospf <1-65535> neighbor IFNAME",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Neighbor list\n"
+       "Interface name\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance(instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_int_common(vty, ospf, 1, argv);
+}
+
 static void
 show_ip_ospf_nbr_nbma_detail_sub (struct vty *vty, struct ospf_interface *oi,
                                  struct ospf_nbr_nbma *nbr_nbma)
@@ -3335,36 +3678,27 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi,
           nbr->t_ls_upd != NULL ? "on" : "off", VTY_NEWLINE, VTY_NEWLINE);
 }
 
-DEFUN (show_ip_ospf_neighbor_id,
-       show_ip_ospf_neighbor_id_cmd,
-       "show ip ospf neighbor A.B.C.D",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       "Neighbor list\n"
-       "Neighbor ID\n")
+static int
+show_ip_ospf_neighbor_id_common (struct vty *vty, struct ospf *ospf,
+                                 int arg_base, const char **argv)
 {
-  struct ospf *ospf;
   struct listnode *node;
   struct ospf_neighbor *nbr;
   struct ospf_interface *oi;
   struct in_addr router_id;
   int ret;
 
-  ret = inet_aton (argv[0], &router_id);
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
+
+  ret = inet_aton (argv[arg_base + 0], &router_id);
   if (!ret)
     {
       vty_out (vty, "Please specify Neighbor ID by A.B.C.D%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
-
   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
     if ((nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &router_id)))
       show_ip_ospf_neighbor_detail_sub (vty, oi, nbr);
@@ -3372,25 +3706,52 @@ DEFUN (show_ip_ospf_neighbor_id,
   return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_detail,
-       show_ip_ospf_neighbor_detail_cmd,
-       "show ip ospf neighbor detail",
+DEFUN (show_ip_ospf_neighbor_id,
+       show_ip_ospf_neighbor_id_cmd,
+       "show ip ospf neighbor A.B.C.D",
        SHOW_STR
        IP_STR
        "OSPF information\n"
        "Neighbor list\n"
-       "detail of all neighbors\n")
+       "Neighbor ID\n")
 {
   struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv);
+}
+
+DEFUN (show_ip_ospf_instance_neighbor_id,
+       show_ip_ospf_instance_neighbor_id_cmd,
+       "show ip ospf <1-65535> neighbor A.B.C.D",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Neighbor list\n"
+       "Neighbor ID\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance(instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_id_common(vty, ospf, 1, argv);
+}
+
+static int
+show_ip_ospf_neighbor_detail_common (struct vty *vty, struct ospf *ospf)
+{
   struct ospf_interface *oi;
   struct listnode *node;
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
 
   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
     {
@@ -3407,26 +3768,52 @@ DEFUN (show_ip_ospf_neighbor_detail,
   return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_detail_all,
-       show_ip_ospf_neighbor_detail_all_cmd,
-       "show ip ospf neighbor detail all",
+DEFUN (show_ip_ospf_neighbor_detail,
+       show_ip_ospf_neighbor_detail_cmd,
+       "show ip ospf neighbor detail",
        SHOW_STR
        IP_STR
        "OSPF information\n"
        "Neighbor list\n"
-       "detail of all neighbors\n"
-       "include down status neighbor\n")
+       "detail of all neighbors\n")
 {
   struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_detail_common(vty, ospf);
+}
+
+DEFUN (show_ip_ospf_instance_neighbor_detail,
+       show_ip_ospf_instance_neighbor_detail_cmd,
+       "show ip ospf <1-65535> neighbor detail",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Neighbor list\n"
+       "detail of all neighbors\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_detail_common(vty, ospf);
+}
+
+static int
+show_ip_ospf_neighbor_detail_all_common (struct vty *vty, struct ospf *ospf)
+{
   struct listnode *node;
   struct ospf_interface *oi;
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
 
   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
     {
@@ -3454,37 +3841,65 @@ DEFUN (show_ip_ospf_neighbor_detail_all,
   return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_int_detail,
-       show_ip_ospf_neighbor_int_detail_cmd,
-       "show ip ospf neighbor IFNAME detail",
+DEFUN (show_ip_ospf_neighbor_detail_all,
+       show_ip_ospf_neighbor_detail_all_cmd,
+       "show ip ospf neighbor detail all",
        SHOW_STR
        IP_STR
        "OSPF information\n"
        "Neighbor list\n"
-       "Interface name\n"
-       "detail of all neighbors")
+       "detail of all neighbors\n"
+       "include down status neighbor\n")
 {
   struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_detail_all_common(vty, ospf);
+}
+
+DEFUN (show_ip_ospf_instance_neighbor_detail_all,
+       show_ip_ospf_instance_neighbor_detail_all_cmd,
+       "show ip ospf <1-65535> neighbor detail all",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Neighbor list\n"
+       "detail of all neighbors\n"
+       "include down status neighbor\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance(instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_detail_all_common(vty, ospf);
+}
+
+static int
+show_ip_ospf_neighbor_int_detail_common (struct vty *vty, struct ospf *ospf,
+                                         int arg_base, const char **argv)
+{
   struct ospf_interface *oi;
   struct interface *ifp;
   struct route_node *rn, *nrn;
   struct ospf_neighbor *nbr;
 
-  ifp = if_lookup_by_name (argv[0]);
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
+
+  ifp = if_lookup_by_name (argv[arg_base + 0]);
   if (!ifp)
     {
       vty_out (vty, "No such interface.%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
-
-
   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
     if ((oi = rn->info))
       for (nrn = route_top (oi->nbrs); nrn; nrn = route_next (nrn))
@@ -3496,6 +3911,44 @@ DEFUN (show_ip_ospf_neighbor_int_detail,
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_ospf_neighbor_int_detail,
+       show_ip_ospf_neighbor_int_detail_cmd,
+       "show ip ospf neighbor IFNAME detail",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Neighbor list\n"
+       "Interface name\n"
+       "detail of all neighbors")
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0, argv);
+}
+
+DEFUN (show_ip_ospf_instance_neighbor_int_detail,
+       show_ip_ospf_instance_neighbor_int_detail_cmd,
+       "show ip ospf <1-65535> neighbor IFNAME detail",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Neighbor list\n"
+       "Interface name\n"
+       "detail of all neighbors")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance(instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_neighbor_int_detail_common(vty, ospf, 1, argv);
+}
 
 /* Show functions */
 static int
@@ -4154,89 +4607,81 @@ show_ip_ospf_database_maxage (struct vty *vty, struct ospf *ospf)
    OSPF_LSA_TYPE_OPAQUE_AREA_DESC                                             \
    OSPF_LSA_TYPE_OPAQUE_AS_DESC     
 
-DEFUN (show_ip_ospf_database,
-       show_ip_ospf_database_cmd,
-       "show ip ospf database",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       "Database summary\n")
+static int
+show_ip_ospf_database_common (struct vty *vty, struct ospf *ospf,
+                              int arg_base, int argc, const char **argv)
 {
-  struct ospf *ospf;
   int type, ret;
   struct in_addr id, adv_router;
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE);
 
   vty_out (vty, "%s       OSPF Router with ID (%s)%s%s", VTY_NEWLINE,
            inet_ntoa (ospf->router_id), VTY_NEWLINE, VTY_NEWLINE);
 
   /* Show all LSA. */
-  if (argc == 0)
+  if (argc == arg_base + 0)
     {
       show_ip_ospf_database_summary (vty, ospf, 0);
       return CMD_SUCCESS;
     }
 
   /* Set database type to show. */
-  if (strncmp (argv[0], "r", 1) == 0)
+  if (strncmp (argv[arg_base + 0], "r", 1) == 0)
     type = OSPF_ROUTER_LSA;
-  else if (strncmp (argv[0], "ne", 2) == 0)
+  else if (strncmp (argv[arg_base + 0], "ne", 2) == 0)
     type = OSPF_NETWORK_LSA;
-  else if (strncmp (argv[0], "ns", 2) == 0)
+  else if (strncmp (argv[arg_base + 0], "ns", 2) == 0)
     type = OSPF_AS_NSSA_LSA;
-  else if (strncmp (argv[0], "su", 2) == 0)
+  else if (strncmp (argv[arg_base + 0], "su", 2) == 0)
     type = OSPF_SUMMARY_LSA;
-  else if (strncmp (argv[0], "a", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "a", 1) == 0)
     type = OSPF_ASBR_SUMMARY_LSA;
-  else if (strncmp (argv[0], "e", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
     type = OSPF_AS_EXTERNAL_LSA;
-  else if (strncmp (argv[0], "se", 2) == 0)
+  else if (strncmp (argv[arg_base + 0], "se", 2) == 0)
     {
       show_ip_ospf_database_summary (vty, ospf, 1);
       return CMD_SUCCESS;
     }
-  else if (strncmp (argv[0], "m", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "m", 1) == 0)
     {
       show_ip_ospf_database_maxage (vty, ospf);
       return CMD_SUCCESS;
     }
 #ifdef HAVE_OPAQUE_LSA
-  else if (strncmp (argv[0], "opaque-l", 8) == 0)
+  else if (strncmp (argv[arg_base + 0], "opaque-l", 8) == 0)
     type = OSPF_OPAQUE_LINK_LSA;
-  else if (strncmp (argv[0], "opaque-ar", 9) == 0)
+  else if (strncmp (argv[arg_base + 0], "opaque-ar", 9) == 0)
     type = OSPF_OPAQUE_AREA_LSA;
-  else if (strncmp (argv[0], "opaque-as", 9) == 0)
+  else if (strncmp (argv[arg_base + 0], "opaque-as", 9) == 0)
     type = OSPF_OPAQUE_AS_LSA;
 #endif /* HAVE_OPAQUE_LSA */
   else
     return CMD_WARNING;
 
   /* `show ip ospf database LSA'. */
-  if (argc == 1)
+  if (argc == arg_base + 1)
     show_lsa_detail (vty, ospf, type, NULL, NULL);
-  else if (argc >= 2)
+  else if (argc >= arg_base + 2)
     {
-      ret = inet_aton (argv[1], &id);
+      ret = inet_aton (argv[arg_base + 1], &id);
       if (!ret)
        return CMD_WARNING;
       
       /* `show ip ospf database LSA ID'. */
-      if (argc == 2)
+      if (argc == arg_base + 2)
        show_lsa_detail (vty, ospf, type, &id, NULL);
       /* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */
-      else if (argc == 3)
+      else if (argc == arg_base + 3)
        {
-         if (strncmp (argv[2], "s", 1) == 0)
+         if (strncmp (argv[arg_base + 2], "s", 1) == 0)
            adv_router = ospf->router_id;
          else
            {
-             ret = inet_aton (argv[2], &adv_router);
+             ret = inet_aton (argv[arg_base + 2], &adv_router);
              if (!ret)
                return CMD_WARNING;
            }
@@ -4247,6 +4692,22 @@ DEFUN (show_ip_ospf_database,
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_ospf_database,
+       show_ip_ospf_database_cmd,
+       "show ip ospf database",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Database summary\n")
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv));
+}
+
 ALIAS (show_ip_ospf_database,
        show_ip_ospf_database_type_cmd,
        "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR "|max-age|self-originate)",
@@ -4292,84 +4753,195 @@ ALIAS (show_ip_ospf_database,
        "Self-originated link states\n"
        "\n")
 
-DEFUN (show_ip_ospf_database_type_adv_router,
-       show_ip_ospf_database_type_adv_router_cmd,
-       "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") adv-router A.B.C.D",
+DEFUN (show_ip_ospf_instance_database,
+       show_ip_ospf_instance_database_cmd,
+       "show ip ospf <1-65535> database",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       "Instance ID\n"
+       "Database summary\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return (show_ip_ospf_database_common(vty, ospf, 1, argc, argv));
+}
+
+ALIAS (show_ip_ospf_instance_database,
+       show_ip_ospf_instance_database_type_cmd,
+       "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR "|max-age|self-originate)",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Database summary\n"
+       OSPF_LSA_TYPES_DESC
+       "LSAs in MaxAge list\n"
+       "Self-originated link states\n")
+
+ALIAS (show_ip_ospf_instance_database,
+       show_ip_ospf_instance_database_type_id_cmd,
+       "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Database summary\n"
+       OSPF_LSA_TYPES_DESC
+       "Link State ID (as an IP address)\n")
+
+ALIAS (show_ip_ospf_instance_database,
+       show_ip_ospf_instance_database_type_id_adv_router_cmd,
+       "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D adv-router A.B.C.D",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
        "Database summary\n"
        OSPF_LSA_TYPES_DESC
+       "Link State ID (as an IP address)\n"
        "Advertising Router link states\n"
        "Advertising Router (as an IP address)\n")
+
+ALIAS (show_ip_ospf_instance_database,
+       show_ip_ospf_instance_database_type_id_self_cmd,
+       "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D (self-originate|)",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Database summary\n"
+       OSPF_LSA_TYPES_DESC
+       "Link State ID (as an IP address)\n"
+       "Self-originated link states\n"
+       "\n")
+
+
+static int
+show_ip_ospf_database_type_adv_router_common (struct vty *vty, struct ospf *ospf,
+                                              int arg_base, int argc, const char **argv)
 {
-  struct ospf *ospf;
   int type, ret;
   struct in_addr adv_router;
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE);
 
   vty_out (vty, "%s       OSPF Router with ID (%s)%s%s", VTY_NEWLINE,
            inet_ntoa (ospf->router_id), VTY_NEWLINE, VTY_NEWLINE);
 
-  if (argc != 2)
+  if (argc != arg_base + 2)
     return CMD_WARNING;
 
   /* Set database type to show. */
-  if (strncmp (argv[0], "r", 1) == 0)
+  if (strncmp (argv[arg_base + 0], "r", 1) == 0)
     type = OSPF_ROUTER_LSA;
-  else if (strncmp (argv[0], "ne", 2) == 0)
+  else if (strncmp (argv[arg_base + 0], "ne", 2) == 0)
     type = OSPF_NETWORK_LSA;
-  else if (strncmp (argv[0], "ns", 2) == 0)
+  else if (strncmp (argv[arg_base + 0], "ns", 2) == 0)
     type = OSPF_AS_NSSA_LSA;
-  else if (strncmp (argv[0], "s", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "s", 1) == 0)
     type = OSPF_SUMMARY_LSA;
-  else if (strncmp (argv[0], "a", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "a", 1) == 0)
     type = OSPF_ASBR_SUMMARY_LSA;
-  else if (strncmp (argv[0], "e", 1) == 0)
+  else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
     type = OSPF_AS_EXTERNAL_LSA;
 #ifdef HAVE_OPAQUE_LSA
-  else if (strncmp (argv[0], "opaque-l", 8) == 0)
+  else if (strncmp (argv[arg_base + 0], "opaque-l", 8) == 0)
     type = OSPF_OPAQUE_LINK_LSA;
-  else if (strncmp (argv[0], "opaque-ar", 9) == 0)
+  else if (strncmp (argv[arg_base + 0], "opaque-ar", 9) == 0)
     type = OSPF_OPAQUE_AREA_LSA;
-  else if (strncmp (argv[0], "opaque-as", 9) == 0)
+  else if (strncmp (argv[arg_base + 0], "opaque-as", 9) == 0)
     type = OSPF_OPAQUE_AS_LSA;
 #endif /* HAVE_OPAQUE_LSA */
   else
     return CMD_WARNING;
 
-  /* `show ip ospf database LSA adv-router ADV_ROUTER'. */
-  if (strncmp (argv[1], "s", 1) == 0)
-    adv_router = ospf->router_id;
-  else
-    {
-      ret = inet_aton (argv[1], &adv_router);
-      if (!ret)
-       return CMD_WARNING;
-    }
+  /* `show ip ospf database LSA adv-router ADV_ROUTER'. */
+  if (strncmp (argv[arg_base + 1], "s", 1) == 0)
+    adv_router = ospf->router_id;
+  else
+    {
+      ret = inet_aton (argv[arg_base + 1], &adv_router);
+      if (!ret)
+       return CMD_WARNING;
+    }
+
+  show_lsa_detail_adv_router (vty, ospf, type, &adv_router);
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_ospf_database_type_adv_router,
+       show_ip_ospf_database_type_adv_router_cmd,
+       "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") adv-router A.B.C.D",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Database summary\n"
+       OSPF_LSA_TYPES_DESC
+       "Advertising Router link states\n"
+       "Advertising Router (as an IP address)\n")
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup()) == NULL)
+    return CMD_SUCCESS;
+
+  return (show_ip_ospf_database_type_adv_router_common(vty, ospf, 0, argc, argv));
+}
+
+ALIAS (show_ip_ospf_database_type_adv_router,
+       show_ip_ospf_database_type_self_cmd,
+       "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") (self-originate|)",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Database summary\n"
+       OSPF_LSA_TYPES_DESC
+       "Self-originated link states\n")
+
+DEFUN (show_ip_ospf_instance_database_type_adv_router,
+       show_ip_ospf_instance_database_type_adv_router_cmd,
+       "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") adv-router A.B.C.D",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Database summary\n"
+       OSPF_LSA_TYPES_DESC
+       "Advertising Router link states\n"
+       "Advertising Router (as an IP address)\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
 
-  show_lsa_detail_adv_router (vty, ospf, type, &adv_router);
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
 
-  return CMD_SUCCESS;
+  return (show_ip_ospf_database_type_adv_router_common(vty, ospf, 1, argc, argv));
 }
 
-ALIAS (show_ip_ospf_database_type_adv_router,
-       show_ip_ospf_database_type_self_cmd,
-       "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") (self-originate|)",
+ALIAS (show_ip_ospf_instance_database_type_adv_router,
+       show_ip_ospf_instance_database_type_self_cmd,
+       "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") (self-originate|)",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       "Instance ID\n"
        "Database summary\n"
        OSPF_LSA_TYPES_DESC
        "Self-originated link states\n")
 
-
 DEFUN (ip_ospf_authentication_args,
        ip_ospf_authentication_args_addr_cmd,
        "ip ospf authentication (null|message-digest) A.B.C.D",
@@ -5909,15 +6481,25 @@ DEFUN (ip_ospf_area,
   struct ospf *ospf;
   struct ospf_if_params *params;
   struct route_node *rn;
+  u_short instance = 0;
 
-  ospf = ospf_lookup ();
+  if (argc == 2)
+    VTY_GET_INTEGER ("Instance", instance, argv[0]);
+
+  ospf = ospf_lookup_instance (instance);
   if (ospf == NULL)
     {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
+      params = IF_DEF_PARAMS (ifp);
+      if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+        {
+          ospf_interface_unset (ifp);
+          ospf = ospf_lookup();
+          ospf->if_ospf_cli_count--;
+        }
       return CMD_SUCCESS;
     }
 
-  ret = ospf_str2area_id (argv[0], &area_id, &format);
+  ret = ospf_str2area_id (argv[instance ? 1 : 0], &area_id, &format);
   if (ret < 0)
     {
       vty_out (vty, "Please specify area by A.B.C.D|<0-4294967295>%s",
@@ -5952,6 +6534,16 @@ DEFUN (ip_ospf_area,
   return CMD_SUCCESS;
 }
 
+ALIAS (ip_ospf_area,
+       ip_ospf_instance_area_cmd,
+       "ip ospf <1-65535> area (A.B.C.D|<0-4294967295>)",
+       "IP Information\n"
+       "OSPF interface commands\n"
+       "Instance ID\n"
+       "Enable OSPF on this interface\n"
+       "OSPF area ID in IP address format\n"
+       "OSPF area ID as a decimal value\n")
+
 DEFUN (no_ip_ospf_area,
        no_ip_ospf_area_cmd,
        "no ip ospf area",
@@ -5963,13 +6555,13 @@ DEFUN (no_ip_ospf_area,
   struct interface *ifp = vty->index;
   struct ospf *ospf;
   struct ospf_if_params *params;
+  u_short instance = 0;
 
-  ospf = ospf_lookup ();
-  if (ospf == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+  if (argc)
+    VTY_GET_INTEGER ("Instance", instance, argv[0]);
+
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
 
   params = IF_DEF_PARAMS (ifp);
   if (!OSPF_IF_PARAM_CONFIGURED(params, if_area))
@@ -5983,6 +6575,15 @@ DEFUN (no_ip_ospf_area,
   return CMD_SUCCESS;
 }
 
+ALIAS (no_ip_ospf_area,
+       no_ip_ospf_instance_area_cmd,
+       "no ip ospf <1-65535> area",
+       NO_STR
+       "IP Information\n"
+       "OSPF interface commands\n"
+       "Instance ID\n"
+       "Disable OSPF on this interface\n")
+
 DEFUN (ospf_redistribute_source,
        ospf_redistribute_source_cmd,
        "redistribute " QUAGGA_REDIST_STR_OSPFD
@@ -6001,10 +6602,14 @@ DEFUN (ospf_redistribute_source,
   int source;
   int type = -1;
   int metric = -1;
+  struct ospf_redist *red;
 
   if (argc < 4)
     return CMD_WARNING; /* should not happen */
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   /* Get distribute source. */
   source = proto_redistnum(AFI_IP, argv[0]);
   if (source < 0 || source == ZEBRA_ROUTE_OSPF)
@@ -6020,12 +6625,14 @@ DEFUN (ospf_redistribute_source,
     if (!str2metric_type (argv[2], &type))
       return CMD_WARNING;
 
+  red = ospf_redist_add(ospf, source, 0);
+
   if (argv[3] != NULL)
-    ospf_routemap_set (ospf, source, argv[3]);
+    ospf_routemap_set (red, argv[3]);
   else
-    ospf_routemap_unset (ospf, source);
+    ospf_routemap_unset (red);
 
-  return ospf_redistribute_set (ospf, source, type, metric);
+  return ospf_redistribute_set (ospf, source, 0, type, metric);
 }
 
 DEFUN (no_ospf_redistribute_source,
@@ -6037,13 +6644,131 @@ DEFUN (no_ospf_redistribute_source,
 {
   struct ospf *ospf = vty->index;
   int source;
+  struct ospf_redist *red;
+  if (!ospf)
+    return CMD_SUCCESS;
 
   source = proto_redistnum(AFI_IP, argv[0]);
   if (source < 0 || source == ZEBRA_ROUTE_OSPF)
     return CMD_WARNING;
 
-  ospf_routemap_unset (ospf, source);
-  return ospf_redistribute_unset (ospf, source);
+  red = ospf_redist_lookup(ospf, source, 0);
+  if (!red)
+    return CMD_SUCCESS;
+
+  ospf_routemap_unset (red);
+  return ospf_redistribute_unset (ospf, source, 0);
+}
+
+DEFUN (ospf_redistribute_instance_source,
+       ospf_redistribute_instance_source_cmd,
+       "redistribute ospf <1-65535>"
+         " {metric <0-16777214>|metric-type (1|2)|route-map WORD}",
+       REDIST_STR
+       "Open Shortest Path First\n"
+       "Instance ID\n"
+       "Metric for redistributed routes\n"
+       "OSPF default metric\n"
+       "OSPF exterior metric type for redistributed routes\n"
+       "Set OSPF External Type 1 metrics\n"
+       "Set OSPF External Type 2 metrics\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+{
+  struct ospf *ospf = vty->index;
+  int source;
+  int type = -1;
+  int metric = -1;
+  u_short instance;
+  struct ospf_redist *red;
+
+  VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
+
+  if (!ospf)
+    return CMD_SUCCESS;
+
+  if (!ospf->instance)
+    {
+      vty_out (vty, "Instance redistribution in non-instanced OSPF not allowed%s",
+               VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if (ospf->instance == instance)
+    {
+      vty_out (vty, "Same instance OSPF redistribution not allowed%s",
+               VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  source = ZEBRA_ROUTE_OSPF;
+
+  /* Get metric value. */
+  if (argv[1] != NULL)
+    if (!str2metric (argv[1], &metric))
+      return CMD_WARNING;
+
+  /* Get metric type. */
+  if (argv[2] != NULL)
+    if (!str2metric_type (argv[2], &type))
+      return CMD_WARNING;
+
+  red = ospf_redist_add(ospf, source, instance);
+  if (argv[3] != NULL)
+    ospf_routemap_set (red, argv[3]);
+  else
+    ospf_routemap_unset (red);
+
+  return ospf_redistribute_set (ospf, source, instance, type, metric);
+}
+
+DEFUN (no_ospf_redistribute_instance_source,
+       no_ospf_redistribute_instance_source_cmd,
+       "no redistribute ospf <1-65535>"
+       " {metric <0-16777214>|metric-type (1|2)|route-map WORD}",
+       NO_STR
+       REDIST_STR
+       "Open Shortest Path First\n"
+       "Instance ID\n"
+       "Metric for redistributed routes\n"
+       "OSPF default metric\n"
+       "OSPF exterior metric type for redistributed routes\n"
+       "Set OSPF External Type 1 metrics\n"
+       "Set OSPF External Type 2 metrics\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+{
+  struct ospf *ospf = vty->index;
+  u_int instance;
+  struct ospf_redist *red;
+  int source;
+
+  if (!ospf)
+    return CMD_SUCCESS;
+
+  VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
+
+  if (!ospf->instance)
+    {
+      vty_out (vty, "Instance redistribution in non-instanced OSPF not allowed%s",
+               VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if (ospf->instance == instance)
+    {
+      vty_out (vty, "Same instance OSPF redistribution not allowed%s",
+               VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  source = ZEBRA_ROUTE_OSPF;
+  red = ospf_redist_lookup(ospf, source, instance);
+  if (!red)
+    return CMD_SUCCESS;
+
+  ospf_routemap_unset (red);
+  return ospf_redistribute_unset (ospf, source, instance);
 }
 
 DEFUN (ospf_distribute_list_out,
@@ -6057,6 +6782,9 @@ DEFUN (ospf_distribute_list_out,
   struct ospf *ospf = vty->index;
   int source;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   /* Get distribute source. */
   source = proto_redistnum(AFI_IP, argv[1]);
   if (source < 0 || source == ZEBRA_ROUTE_OSPF)
@@ -6077,6 +6805,9 @@ DEFUN (no_ospf_distribute_list_out,
   struct ospf *ospf = vty->index;
   int source;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   source = proto_redistnum(AFI_IP, argv[1]);
   if (source < 0 || source == ZEBRA_ROUTE_OSPF)
     return CMD_WARNING;
@@ -6104,6 +6835,10 @@ DEFUN (ospf_default_information_originate,
   int default_originate = DEFAULT_ORIGINATE_ZEBRA;
   int type = -1;
   int metric = -1;
+  struct ospf_redist *red;
+
+  if (!ospf)
+    return CMD_SUCCESS;
 
   if (argc < 4)
     return CMD_WARNING; /* this should not happen */
@@ -6112,6 +6847,8 @@ DEFUN (ospf_default_information_originate,
   if (argv[0] != NULL)
     default_originate = DEFAULT_ORIGINATE_ALWAYS;
 
+  red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
+
   /* Get metric value. */
   if (argv[1] != NULL)
     if (!str2metric (argv[1], &metric))
@@ -6123,9 +6860,9 @@ DEFUN (ospf_default_information_originate,
       return CMD_WARNING;
 
   if (argv[3] != NULL)
-    ospf_routemap_set (ospf, DEFAULT_ROUTE, argv[3]);
+    ospf_routemap_set (red, argv[3]);
   else
-    ospf_routemap_unset (ospf, DEFAULT_ROUTE);
+    ospf_routemap_unset (red);
 
   return ospf_redistribute_default_set (ospf, default_originate,
                                        type, metric);
@@ -6140,20 +6877,29 @@ DEFUN (no_ospf_default_information_originate,
 {
   struct ospf *ospf = vty->index;
   struct prefix_ipv4 p;
+  struct ospf_external *ext;
+  struct ospf_redist *red;
     
+  if (!ospf)
+    return CMD_SUCCESS;
+
   p.family = AF_INET;
   p.prefix.s_addr = 0;
   p.prefixlen = 0;
 
   ospf_external_lsa_flush (ospf, DEFAULT_ROUTE, &p, 0);
 
-  if (EXTERNAL_INFO (DEFAULT_ROUTE)) {
-    ospf_external_info_delete (DEFAULT_ROUTE, p);
-    route_table_finish (EXTERNAL_INFO (DEFAULT_ROUTE));
-    EXTERNAL_INFO (DEFAULT_ROUTE) = NULL;
+  if ((ext = ospf_external_lookup(DEFAULT_ROUTE, 0)) &&
+      EXTERNAL_INFO (ext)) {
+    ospf_external_info_delete (DEFAULT_ROUTE, 0, p);
+    ospf_external_del (DEFAULT_ROUTE, 0);
   }
 
-  ospf_routemap_unset (ospf, DEFAULT_ROUTE);
+  red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
+  if (!red)
+    return CMD_SUCCESS;
+
+  ospf_routemap_unset (red);
   return ospf_redistribute_default_unset (ospf);
 }
 
@@ -6166,6 +6912,9 @@ DEFUN (ospf_default_metric,
   struct ospf *ospf = vty->index;
   int metric = -1;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (!str2metric (argv[0], &metric))
     return CMD_WARNING;
 
@@ -6182,6 +6931,9 @@ DEFUN (no_ospf_default_metric,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf->default_metric = -1;
 
   return CMD_SUCCESS;
@@ -6202,6 +6954,9 @@ DEFUN (ospf_distance,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf->distance_all = atoi (argv[0]);
 
   return CMD_SUCCESS;
@@ -6216,6 +6971,9 @@ DEFUN (no_ospf_distance,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf->distance_all = 0;
 
   return CMD_SUCCESS;
@@ -6237,6 +6995,9 @@ DEFUN (no_ospf_distance_ospf,
   if (argc < 3)
     return CMD_WARNING;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (argv[0] != NULL)
     ospf->distance_intra = 0;
 
@@ -6303,6 +7064,9 @@ DEFUN (ospf_distance_source,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf_distance_set (vty, ospf, argv[0], argv[1], NULL);
 
   return CMD_SUCCESS;
@@ -6318,6 +7082,9 @@ DEFUN (no_ospf_distance_source,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf_distance_unset (vty, ospf, argv[0], argv[1], NULL);
 
   return CMD_SUCCESS;
@@ -6333,6 +7100,9 @@ DEFUN (ospf_distance_source_access_list,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf_distance_set (vty, ospf, argv[0], argv[1], argv[2]);
 
   return CMD_SUCCESS;
@@ -6349,6 +7119,9 @@ DEFUN (no_ospf_distance_source_access_list,
 {
   struct ospf *ospf = vty->index;
 
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf_distance_unset (vty, ospf, argv[0], argv[1], argv[2]);
 
   return CMD_SUCCESS;
@@ -6464,6 +7237,9 @@ DEFUN (ospf_max_metric_router_lsa_admin,
   struct ospf_area *area;
   struct ospf *ospf = vty->index;
     
+  if (!ospf)
+    return CMD_SUCCESS;
+
   for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
     {
       SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
@@ -6490,6 +7266,9 @@ DEFUN (no_ospf_max_metric_router_lsa_admin,
   struct ospf_area *area;
   struct ospf *ospf = vty->index;
     
+  if (!ospf)
+    return CMD_SUCCESS;
+
   for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
     {
       UNSET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
@@ -6517,6 +7296,9 @@ DEFUN (ospf_max_metric_router_lsa_startup,
   unsigned int seconds;
   struct ospf *ospf = vty->index;
     
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (argc != 1)
     {
       vty_out (vty, "%% Must supply stub-router period");
@@ -6542,6 +7324,9 @@ DEFUN (no_ospf_max_metric_router_lsa_startup,
   struct ospf_area *area;
   struct ospf *ospf = vty->index;
   
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
   
   for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
@@ -6570,6 +7355,9 @@ DEFUN (ospf_max_metric_router_lsa_shutdown,
   unsigned int seconds;
   struct ospf *ospf = vty->index;
     
+  if (!ospf)
+    return CMD_SUCCESS;
+
   if (argc != 1)
     {
       vty_out (vty, "%% Must supply stub-router shutdown period");
@@ -6593,6 +7381,9 @@ DEFUN (no_ospf_max_metric_router_lsa_shutdown,
 {
   struct ospf *ospf = vty->index;
     
+  if (!ospf)
+    return CMD_SUCCESS;
+
   ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
   
   return CMD_SUCCESS;
@@ -6775,21 +7566,12 @@ show_ip_ospf_route_external (struct vty *vty, struct route_table *rt)
   vty_out (vty, "%s", VTY_NEWLINE);
 }
 
-DEFUN (show_ip_ospf_border_routers,
-       show_ip_ospf_border_routers_cmd,
-       "show ip ospf border-routers",
-       SHOW_STR
-       IP_STR
-       "show all the ABR's and ASBR's\n"
-       "for this area\n")
+static int
+show_ip_ospf_border_routers_common (struct vty *vty, struct ospf *ospf)
 {
-  struct ospf *ospf;
-
-  if ((ospf = ospf_lookup ()) == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
 
   if (ospf->new_table == NULL)
     {
@@ -6803,24 +7585,52 @@ DEFUN (show_ip_ospf_border_routers,
   /* Show Router routes. */
   show_ip_ospf_route_router (vty, ospf->new_rtrs);
 
+  vty_out (vty, "%s", VTY_NEWLINE);
+
   return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_route,
-       show_ip_ospf_route_cmd,
-       "show ip ospf route",
+DEFUN (show_ip_ospf_border_routers,
+       show_ip_ospf_border_routers_cmd,
+       "show ip ospf border-routers",
        SHOW_STR
        IP_STR
        "OSPF information\n"
-       "OSPF routing table\n")
+       "Show all the ABR's and ASBR's\n")
 {
   struct ospf *ospf;
 
   if ((ospf = ospf_lookup ()) == NULL)
-    {
-      vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
-      return CMD_SUCCESS;
-    }
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_border_routers_common(vty, ospf);
+}
+
+DEFUN (show_ip_ospf_instance_border_routers,
+       show_ip_ospf_instance_border_routers_cmd,
+       "show ip ospf <1-65535> border-routers",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "Show all the ABR's and ASBR's\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_border_routers_common(vty, ospf);
+}
+
+static int
+show_ip_ospf_route_common (struct vty *vty, struct ospf *ospf)
+{
+  if (ospf->instance)
+    vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance,
+             VTY_NEWLINE, VTY_NEWLINE);
 
   if (ospf->new_table == NULL)
     {
@@ -6837,9 +7647,45 @@ DEFUN (show_ip_ospf_route,
   /* Show AS External routes. */
   show_ip_ospf_route_external (vty, ospf->old_external_route);
 
+  vty_out (vty, "%s", VTY_NEWLINE);
+
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_ospf_route,
+       show_ip_ospf_route_cmd,
+       "show ip ospf route",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "OSPF routing table\n")
+{
+  struct ospf *ospf;
+
+  if ((ospf = ospf_lookup ()) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_route_common(vty, ospf);
+}
+
+DEFUN (show_ip_ospf_instance_route,
+       show_ip_ospf_instance_route_cmd,
+       "show ip ospf <1-65535> route",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       "Instance ID\n"
+       "OSPF routing table\n")
+{
+  struct ospf *ospf;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+  if ((ospf = ospf_lookup_instance (instance)) == NULL)
+    return CMD_SUCCESS;
+
+  return show_ip_ospf_route_common(vty, ospf);
+}
 
 const char *ospf_abr_type_str[] = 
 {
@@ -6891,6 +7737,7 @@ config_write_interface (struct vty *vty)
   int write = 0;
   struct route_node *rn = NULL;
   struct ospf_if_params *params;
+  struct ospf *ospf = ospf_lookup();
 
   for (ALL_LIST_ELEMENTS_RO (iflist, n1, ifp))
     {
@@ -6972,7 +7819,7 @@ config_write_interface (struct vty *vty)
        for (ALL_LIST_ELEMENTS_RO (params->auth_crypt, n2, ck))
          {
            vty_out (vty, " ip ospf message-digest-key %d md5 %s",
-                    ck->key_id, ck->auth_key);
+                     ck->key_id, ck->auth_key);
            if (params != IF_DEF_PARAMS (ifp))
              vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4));
            vty_out (vty, "%s", VTY_NEWLINE);
@@ -7050,8 +7897,12 @@ config_write_interface (struct vty *vty)
        /* Area  print. */
        if (OSPF_IF_PARAM_CONFIGURED (params, if_area))
          {
-           vty_out (vty, " ip ospf area %s%s",
-                    inet_ntoa (params->if_area), VTY_NEWLINE);
+           if (ospf->instance)
+             vty_out (vty, " ip ospf %d area %s%s", ospf->instance,
+                      inet_ntoa (params->if_area), VTY_NEWLINE);
+           else
+             vty_out (vty, " ip ospf area %s%s",
+                      inet_ntoa (params->if_area), VTY_NEWLINE);
 
          }
 
@@ -7323,20 +8174,33 @@ config_write_ospf_redistribute (struct vty *vty, struct ospf *ospf)
 
   /* redistribute print. */
   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
-    if (type != zclient->redist_default && zclient->redist[type])
-      {
-        vty_out (vty, " redistribute %s", zebra_route_string(type));
-       if (ospf->dmetric[type].value >= 0)
-         vty_out (vty, " metric %d", ospf->dmetric[type].value);
-       
-        if (ospf->dmetric[type].type == EXTERNAL_METRIC_TYPE_1)
-         vty_out (vty, " metric-type 1");
+    {
+      struct list *red_list;
+      struct listnode *node;
+      struct ospf_redist *red;
 
-       if (ROUTEMAP_NAME (ospf, type))
-         vty_out (vty, " route-map %s", ROUTEMAP_NAME (ospf, type));
-       
-        vty_out (vty, "%s", VTY_NEWLINE);
-      }
+      red_list = ospf->redist[type];
+      if (!red_list)
+        continue;
+
+      for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+        {
+          vty_out (vty, " redistribute %s", zebra_route_string(type));
+          if (red->instance)
+            vty_out (vty, " %d", red->instance);
+
+          if (red->dmetric.value >= 0)
+            vty_out (vty, " metric %d", red->dmetric.value);
+
+          if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1)
+            vty_out (vty, " metric-type 1");
+
+          if (ROUTEMAP_NAME (red))
+            vty_out (vty, " route-map %s", ROUTEMAP_NAME (red));
+
+          vty_out (vty, "%s", VTY_NEWLINE);
+        }
+    }
 
   return 0;
 }
@@ -7354,6 +8218,7 @@ static int
 config_write_ospf_distribute (struct vty *vty, struct ospf *ospf)
 {
   int type;
+  struct ospf_redist *red;
 
   if (ospf)
     {
@@ -7371,15 +8236,19 @@ config_write_ospf_distribute (struct vty *vty, struct ospf *ospf)
          if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
            vty_out (vty, " always");
 
-         if (ospf->dmetric[DEFAULT_ROUTE].value >= 0)
-           vty_out (vty, " metric %d",
-                    ospf->dmetric[DEFAULT_ROUTE].value);
-         if (ospf->dmetric[DEFAULT_ROUTE].type == EXTERNAL_METRIC_TYPE_1)
-           vty_out (vty, " metric-type 1");
-
-         if (ROUTEMAP_NAME (ospf, DEFAULT_ROUTE))
-           vty_out (vty, " route-map %s",
-                    ROUTEMAP_NAME (ospf, DEFAULT_ROUTE));
+          red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
+          if (red)
+            {
+              if (red->dmetric.value >= 0)
+                vty_out (vty, " metric %d",
+                         red->dmetric.value);
+              if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1)
+                vty_out (vty, " metric-type 1");
+
+              if (ROUTEMAP_NAME (red))
+                vty_out (vty, " route-map %s",
+                         ROUTEMAP_NAME (red));
+            }
          
          vty_out (vty, "%s", VTY_NEWLINE);
        }
@@ -7439,7 +8308,10 @@ ospf_config_write (struct vty *vty)
   if (ospf != NULL)
     {
       /* `router ospf' print. */
-      vty_out (vty, "router ospf%s", VTY_NEWLINE);
+      if (ospf->instance)
+        vty_out (vty, "router ospf %d%s", ospf->instance, VTY_NEWLINE);
+      else
+        vty_out (vty, "router ospf%s", VTY_NEWLINE);
 
       write++;
 
@@ -7570,6 +8442,9 @@ ospf_vty_show_init (void)
   install_element (VIEW_NODE, &show_ip_ospf_cmd);
   install_element (ENABLE_NODE, &show_ip_ospf_cmd);
 
+  install_element (VIEW_NODE, &show_ip_ospf_instance_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_cmd);
+
   /* "show ip ospf database" commands. */
   install_element (VIEW_NODE, &show_ip_ospf_database_type_cmd);
   install_element (VIEW_NODE, &show_ip_ospf_database_type_id_cmd);
@@ -7586,10 +8461,28 @@ ospf_vty_show_init (void)
   install_element (ENABLE_NODE, &show_ip_ospf_database_type_self_cmd);
   install_element (ENABLE_NODE, &show_ip_ospf_database_cmd);
 
+  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_adv_router_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_self_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_self_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_database_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_id_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_id_adv_router_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_id_self_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_self_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_database_cmd);
+
   /* "show ip ospf interface" commands. */
   install_element (VIEW_NODE, &show_ip_ospf_interface_cmd);
   install_element (ENABLE_NODE, &show_ip_ospf_interface_cmd);
 
+  install_element (VIEW_NODE, &show_ip_ospf_instance_interface_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_interface_cmd);
+
   /* "show ip ospf neighbor" commands. */
   install_element (VIEW_NODE, &show_ip_ospf_neighbor_int_detail_cmd);
   install_element (VIEW_NODE, &show_ip_ospf_neighbor_int_cmd);
@@ -7606,11 +8499,31 @@ ospf_vty_show_init (void)
   install_element (ENABLE_NODE, &show_ip_ospf_neighbor_cmd);
   install_element (ENABLE_NODE, &show_ip_ospf_neighbor_all_cmd);
 
+  install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_int_detail_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_int_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_id_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_all_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_all_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_int_detail_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_int_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_id_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_detail_all_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_detail_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_all_cmd);
+
   /* "show ip ospf route" commands. */
   install_element (VIEW_NODE, &show_ip_ospf_route_cmd);
   install_element (ENABLE_NODE, &show_ip_ospf_route_cmd);
   install_element (VIEW_NODE, &show_ip_ospf_border_routers_cmd);
   install_element (ENABLE_NODE, &show_ip_ospf_border_routers_cmd);
+
+  install_element (VIEW_NODE, &show_ip_ospf_instance_route_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_route_cmd);
+  install_element (VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd);
+  install_element (ENABLE_NODE, &show_ip_ospf_instance_border_routers_cmd);
 }
 
 
@@ -7708,6 +8621,8 @@ ospf_vty_if_init (void)
   /* "ip ospf area" commands. */
   install_element (INTERFACE_NODE, &ip_ospf_area_cmd);
   install_element (INTERFACE_NODE, &no_ip_ospf_area_cmd);
+  install_element (INTERFACE_NODE, &ip_ospf_instance_area_cmd);
+  install_element (INTERFACE_NODE, &no_ip_ospf_instance_area_cmd);
 
   /* These commands are compatibitliy for previous version. */
   install_element (INTERFACE_NODE, &ospf_authentication_key_cmd);
@@ -7741,6 +8656,8 @@ ospf_vty_zebra_init (void)
 {
   install_element (OSPF_NODE, &ospf_redistribute_source_cmd);
   install_element (OSPF_NODE, &no_ospf_redistribute_source_cmd);
+  install_element (OSPF_NODE, &ospf_redistribute_instance_source_cmd);
+  install_element (OSPF_NODE, &no_ospf_redistribute_instance_source_cmd);
 
   install_element (OSPF_NODE, &ospf_distribute_list_out_cmd);
   install_element (OSPF_NODE, &no_ospf_distribute_list_out_cmd);
@@ -7828,6 +8745,9 @@ ospf_vty_init (void)
   install_element (CONFIG_NODE, &router_ospf_cmd);
   install_element (CONFIG_NODE, &no_router_ospf_cmd);
 
+  install_element (CONFIG_NODE, &router_ospf_instance_cmd);
+  install_element (CONFIG_NODE, &no_router_ospf_instance_cmd);
+
   install_default (OSPF_NODE);
 
   /* "ospf router-id" commands. */
index 9a35253795a5f87cae6a4e2bbf04f98b1c4a9c36..ad7e98f0991242a83a6f6d887b289cb02167265f 100644 (file)
@@ -386,8 +386,9 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
 #ifdef HAVE_NETLINK
   int ol_cnt = 0, not_ol_cnt = 0;
 #endif /* HAVE_NETLINK */
+  struct ospf *ospf = ospf_lookup ();
 
-  if (zclient->redist[ZEBRA_ROUTE_OSPF])
+  if (redist_check_instance(&zclient->redist[ZEBRA_ROUTE_OSPF], ospf->instance))
     {
       message = 0;
       flags = 0;
@@ -414,6 +415,7 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
       /* Put command, type, flags, message. */
       zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
       stream_putc (s, ZEBRA_ROUTE_OSPF);
+      stream_putw (s, ospf->instance);
       stream_putc (s, flags);
       stream_putc (s, message);
       stream_putw (s, SAFI_UNICAST);
@@ -529,8 +531,9 @@ ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
   struct stream *s;
   struct ospf_path *path;
   struct listnode *node;
+  struct ospf *ospf = ospf_lookup ();
 
-  if (zclient->redist[ZEBRA_ROUTE_OSPF])
+  if (redist_check_instance(&zclient->redist[ZEBRA_ROUTE_OSPF], ospf->instance))
     {
       message = 0;
       flags = 0;
@@ -543,6 +546,7 @@ ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
       /* Put command, type, flags, message. */
       zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE);
       stream_putc (s, ZEBRA_ROUTE_OSPF);
+      stream_putw (s, ospf->instance);
       stream_putc (s, flags);
       stream_putc (s, message);
       stream_putw (s, SAFI_UNICAST);
@@ -610,10 +614,12 @@ void
 ospf_zebra_add_discard (struct prefix_ipv4 *p)
 {
   struct zapi_ipv4 api;
+  struct ospf *ospf = ospf_lookup ();
 
-  if (zclient->redist[ZEBRA_ROUTE_OSPF])
+  if (redist_check_instance(&zclient->redist[ZEBRA_ROUTE_OSPF], ospf->instance))
     {
       api.type = ZEBRA_ROUTE_OSPF;
+      api.instance = ospf->instance;
       api.flags = ZEBRA_FLAG_BLACKHOLE;
       api.message = 0;
       api.safi = SAFI_UNICAST;
@@ -634,10 +640,12 @@ void
 ospf_zebra_delete_discard (struct prefix_ipv4 *p)
 {
   struct zapi_ipv4 api;
+  struct ospf *ospf = ospf_lookup ();
 
-  if (zclient->redist[ZEBRA_ROUTE_OSPF])
+  if (redist_check_instance(&zclient->redist[ZEBRA_ROUTE_OSPF], ospf->instance))
     {
       api.type = ZEBRA_ROUTE_OSPF;
+      api.instance = ospf->instance;
       api.flags = ZEBRA_FLAG_BLACKHOLE;
       api.message = 0;
       api.safi = SAFI_UNICAST;
@@ -655,50 +663,180 @@ ospf_zebra_delete_discard (struct prefix_ipv4 *p)
     }
 }
 
+struct ospf_external *
+ospf_external_lookup (u_char type, u_short instance)
+{
+  struct list *ext_list;
+  struct listnode *node;
+  struct ospf_external *ext;
+
+  ext_list = om->external[type];
+  if (!ext_list)
+    return(NULL);
+
+  for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
+    if (ext->instance == instance)
+      return ext;
+
+  return NULL;
+}
+
+struct ospf_external *
+ospf_external_add (u_char type, u_short instance)
+{
+  struct list *ext_list;
+  struct ospf_external *ext;
+
+  ext = ospf_external_lookup(type, instance);
+  if (ext)
+    return ext;
+
+  if (!om->external[type])
+    om->external[type] = list_new();
+
+  ext_list = om->external[type];
+  ext = (struct ospf_external *)calloc (1, sizeof(struct ospf_external));
+  ext->instance = instance;
+  EXTERNAL_INFO (ext) = route_table_init ();
+
+  listnode_add(ext_list, ext);
+
+  return ext;
+}
+
+void
+ospf_external_del (u_char type, u_short instance)
+{
+  struct ospf_external *ext;
+
+  ext = ospf_external_lookup(type, instance);
+
+  if (ext)
+    {
+      if (EXTERNAL_INFO (ext))
+        route_table_finish(EXTERNAL_INFO (ext));
+
+      listnode_delete(om->external[type], ext);
+      if (!om->external[type]->count)
+        {
+          list_free(om->external[type]);
+          om->external[type] = NULL;
+        }
+    }
+}
+
+struct ospf_redist *
+ospf_redist_lookup (struct ospf *ospf, u_char type, u_short instance)
+{
+  struct list *red_list;
+  struct listnode *node;
+  struct ospf_redist *red;
+
+  red_list = ospf->redist[type];
+  if (!red_list)
+    return(NULL);
+
+  for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+    if (red->instance == instance)
+      return red;
+
+  return NULL;
+}
+
+struct ospf_redist *
+ospf_redist_add (struct ospf *ospf, u_char type, u_short instance)
+{
+  struct list *red_list;
+  struct ospf_redist *red;
+
+  red = ospf_redist_lookup(ospf, type, instance);
+  if (red)
+    return red;
+
+  if (!ospf->redist[type])
+    ospf->redist[type] = list_new();
+
+  red_list = ospf->redist[type];
+  red = (struct ospf_redist *)calloc (1, sizeof(struct ospf_redist));
+  red->instance = instance;
+  red->dmetric.type = -1;
+  red->dmetric.value = -1;
+
+  listnode_add(red_list, red);
+
+  return red;
+}
+
+void
+ospf_redist_del (struct ospf *ospf, u_char type, u_short instance)
+{
+  struct ospf_redist *red;
+
+  red = ospf_redist_lookup(ospf, type, instance);
+
+  if (red)
+    {
+      listnode_delete(ospf->redist[type], red);
+      if (!ospf->redist[type]->count)
+        {
+          list_free(ospf->redist[type]);
+          ospf->redist[type] = NULL;
+        }
+    }
+}
+
+
 int
-ospf_is_type_redistributed (int type)
+ospf_is_type_redistributed (int type, u_short instance)
 {
-  return (DEFAULT_ROUTE_TYPE (type)) ?
-    zclient->default_information : zclient->redist[type];
+  return (DEFAULT_ROUTE_TYPE (type) ?
+    zclient->default_information :
+    redist_check_instance(&zclient->redist[type], instance));
 }
 
 int
-ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
+ospf_redistribute_set (struct ospf *ospf, int type, u_short instance, int mtype,
+                       int mvalue)
 {
   int force = 0;
+  struct ospf_redist *red;
 
-  if (ospf_is_type_redistributed (type))
+  red = ospf_redist_lookup(ospf, type, instance);
+  if (ospf_is_type_redistributed (type, instance))
     {
-      if (mtype != ospf->dmetric[type].type)
+      if (mtype != red->dmetric.type)
         {
-          ospf->dmetric[type].type = mtype;
+          red->dmetric.type = mtype;
           force = LSA_REFRESH_FORCE;
         }
-      if (mvalue != ospf->dmetric[type].value)
+      if (mvalue != red->dmetric.value)
         {
-          ospf->dmetric[type].value = mvalue;
+          red->dmetric.value = mvalue;
           force = LSA_REFRESH_FORCE;
         }
 
-      ospf_external_lsa_refresh_type (ospf, type, force);
+      ospf_external_lsa_refresh_type (ospf, type, instance, force);
 
       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
-        zlog_debug ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
-                   ospf_redist_string(type),
-                   metric_type (ospf, type), metric_value (ospf, type));
+        zlog_debug ("Redistribute[%s][%d]: Refresh  Type[%d], Metric[%d]",
+                   ospf_redist_string(type), instance,
+                   metric_type (ospf, type, instance),
+                   metric_value (ospf, type, instance));
 
       return CMD_SUCCESS;
     }
 
-  ospf->dmetric[type].type = mtype;
-  ospf->dmetric[type].value = mvalue;
+  red->dmetric.type = mtype;
+  red->dmetric.value = mvalue;
 
-  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+  ospf_external_add(type, instance);
+
+  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, instance);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
-    zlog_debug ("Redistribute[%s]: Start  Type[%d], Metric[%d]",
-               ospf_redist_string(type),
-               metric_type (ospf, type), metric_value (ospf, type));
+    zlog_debug ("Redistribute[%s][%d]: Start  Type[%d], Metric[%d]",
+               ospf_redist_string(type), instance,
+               metric_type (ospf, type, instance), metric_value (ospf, type, instance));
 
   ospf_asbr_status_update (ospf, ++ospf->redistribute);
 
@@ -706,25 +844,26 @@ ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
 }
 
 int
-ospf_redistribute_unset (struct ospf *ospf, int type)
+ospf_redistribute_unset (struct ospf *ospf, int type, u_short instance)
 {
-  if (type == zclient->redist_default)
+  if (type == zclient->redist_default && instance == zclient->instance)
     return CMD_SUCCESS;
 
-  if (!ospf_is_type_redistributed (type))
+  if (!ospf_is_type_redistributed (type, instance))
     return CMD_SUCCESS;
 
-  zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
+  zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, instance);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
-    zlog_debug ("Redistribute[%s]: Stop",
-               ospf_redist_string(type));
+    zlog_debug ("Redistribute[%s][%d]: Stop",
+               ospf_redist_string(type), instance);
 
-  ospf->dmetric[type].type = -1;
-  ospf->dmetric[type].value = -1;
+  ospf_redist_del (ospf, type, instance);
 
   /* Remove the routes from OSPF table. */
-  ospf_redistribute_withdraw (ospf, type);
+  ospf_redistribute_withdraw (ospf, type, instance);
+
+  ospf_external_del(type, instance);
 
   ospf_asbr_status_update (ospf, --ospf->redistribute);
 
@@ -735,11 +874,17 @@ int
 ospf_redistribute_default_set (struct ospf *ospf, int originate,
                                int mtype, int mvalue)
 {
+  struct ospf_redist *red;
+
   ospf->default_originate = originate;
-  ospf->dmetric[DEFAULT_ROUTE].type = mtype;
-  ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
 
-  if (ospf_is_type_redistributed (DEFAULT_ROUTE))
+  red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
+  red->dmetric.type = mtype;
+  red->dmetric.value = mvalue;
+
+  ospf_external_add(DEFAULT_ROUTE, 0);
+
+  if (ospf_is_type_redistributed (DEFAULT_ROUTE, 0))
     {
       /* if ospf->default_originate changes value, is calling
         ospf_external_lsa_refresh_default sufficient to implement
@@ -749,8 +894,8 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
         zlog_debug ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
                    ospf_redist_string(DEFAULT_ROUTE),
-                   metric_type (ospf, DEFAULT_ROUTE),
-                   metric_value (ospf, DEFAULT_ROUTE));
+                   metric_type (ospf, DEFAULT_ROUTE, 0),
+                   metric_value (ospf, DEFAULT_ROUTE, 0));
       return CMD_SUCCESS;
     }
 
@@ -758,8 +903,8 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_debug ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
-               metric_type (ospf, DEFAULT_ROUTE),
-               metric_value (ospf, DEFAULT_ROUTE));
+               metric_type (ospf, DEFAULT_ROUTE, 0),
+               metric_value (ospf, DEFAULT_ROUTE, 0));
 
   if (ospf->router_id.s_addr == 0)
     ospf->external_origin |= (1 << DEFAULT_ROUTE);
@@ -774,18 +919,19 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
 int
 ospf_redistribute_default_unset (struct ospf *ospf)
 {
-  if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
+  if (!ospf_is_type_redistributed (DEFAULT_ROUTE, 0))
     return CMD_SUCCESS;
 
   ospf->default_originate = DEFAULT_ORIGINATE_NONE;
-  ospf->dmetric[DEFAULT_ROUTE].type = -1;
-  ospf->dmetric[DEFAULT_ROUTE].value = -1;
+  ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
 
   zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_debug ("Redistribute[DEFAULT]: Stop");
 
+  //Pending: how does the external_info cleanup work in this case?
+
   ospf_asbr_status_update (ospf, --ospf->redistribute);
 
   return CMD_SUCCESS;
@@ -836,7 +982,9 @@ ospf_redistribute_check (struct ospf *ospf,
 {
   struct route_map_set_values save_values;
   struct prefix_ipv4 *p = &ei->p;
+  struct ospf_redist *red;
   u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
+  u_short instance = is_prefix_default (&ei->p) ? 0 : ei->instance;
 
   if (changed)
     *changed = 0;
@@ -865,11 +1013,12 @@ ospf_redistribute_check (struct ospf *ospf,
   ospf_reset_route_map_set_values (&ei->route_map_set);
 
   /* apply route-map if needed */
-  if (ROUTEMAP_NAME (ospf, type))
+  red = ospf_redist_lookup (ospf, type, instance);
+  if (red && ROUTEMAP_NAME(red))
     {
       int ret;
 
-      ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
+      ret = route_map_apply (ROUTEMAP (red), (struct prefix *) p,
                              RMAP_OSPF, ei);
 
       if (ret == RMAP_DENYMATCH)
@@ -893,23 +1042,23 @@ ospf_redistribute_check (struct ospf *ospf,
 
 /* OSPF route-map set for redistribution */
 void
-ospf_routemap_set (struct ospf *ospf, int type, const char *name)
+ospf_routemap_set (struct ospf_redist *red, const char *name)
 {
-  if (ROUTEMAP_NAME (ospf, type))
-    free (ROUTEMAP_NAME (ospf, type));
+  if (ROUTEMAP_NAME (red))
+    free (ROUTEMAP_NAME (red));
 
-  ROUTEMAP_NAME (ospf, type) = strdup (name);
-  ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
+  ROUTEMAP_NAME (red) = strdup (name);
+  ROUTEMAP (red) = route_map_lookup_by_name (name);
 }
 
 void
-ospf_routemap_unset (struct ospf *ospf, int type)
+ospf_routemap_unset (struct ospf_redist *red)
 {
-  if (ROUTEMAP_NAME (ospf, type))
-    free (ROUTEMAP_NAME (ospf, type));
+  if (ROUTEMAP_NAME (red))
+    free (ROUTEMAP_NAME (red));
 
-  ROUTEMAP_NAME (ospf, type) = NULL;
-  ROUTEMAP (ospf, type) = NULL;
+  ROUTEMAP_NAME (red) = NULL;
+  ROUTEMAP (red) = NULL;
 }
 
 /* Zebra route add and delete treatment. */
@@ -931,6 +1080,7 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
 
   /* Type, flags, message. */
   api.type = stream_getc (s);
+  api.instance = stream_getw (s);
   api.flags = stream_getc (s);
   api.message = stream_getc (s);
 
@@ -985,7 +1135,8 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
       if (ospf->dtag[api.type] > 0)
        api.tag = ospf->dtag[api.type];
 
-      ei = ospf_external_info_add (api.type, p, ifindex, nexthop, api.tag);
+      ei = ospf_external_info_add (api.type, api.instance, p, ifindex,
+                                   nexthop, api.tag);
 
       if (ospf->router_id.s_addr == 0)
         /* Set flags to generate AS-external-LSA originate event
@@ -1016,7 +1167,7 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
     }
   else                          /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
     {
-      ospf_external_info_delete (api.type, p);
+      ospf_external_info_delete (api.type, api.instance, p);
       if (is_prefix_default (&p))
         ospf_external_lsa_refresh_default (ospf);
       else
@@ -1042,7 +1193,7 @@ ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
 
   /* If access-list have been set, schedule update timer. */
   if (DISTRIBUTE_LIST (ospf, type))
-    ospf_distribute_list_update (ospf, type);
+    ospf_distribute_list_update (ospf, type, 0);
 
   return CMD_SUCCESS;
 }
@@ -1052,7 +1203,7 @@ ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
 {
   /* Schedule update timer. */
   if (DISTRIBUTE_LIST (ospf, type))
-    ospf_distribute_list_update (ospf, type);
+    ospf_distribute_list_update (ospf, type, 0);
 
   /* Unset distribute-list. */
   DISTRIBUTE_LIST (ospf, type) = NULL;
@@ -1088,19 +1239,30 @@ ospf_distribute_list_update_timer (struct thread *thread)
   /* foreach all external info. */
   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
     {
-      rt = EXTERNAL_INFO (type);
-      if (!rt)
-       continue;
-      for (rn = route_top (rt); rn; rn = route_next (rn))
-       if ((ei = rn->info) != NULL)
-         {
-           if (is_prefix_default (&ei->p))
-             default_refresh = 1;
-           else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
-             ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
-           else
-             ospf_external_lsa_originate (ospf, ei);
-         }
+      struct list *ext_list;
+      struct listnode *node;
+      struct ospf_external *ext;
+
+      ext_list = om->external[type];
+      if (!ext_list)
+        continue;
+
+      for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
+        {
+          rt = ext->external_info;
+          if (!rt)
+            continue;
+          for (rn = route_top (rt); rn; rn = route_next (rn))
+            if ((ei = rn->info) != NULL)
+              {
+                if (is_prefix_default (&ei->p))
+                  default_refresh = 1;
+                else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
+                  ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
+                else
+                  ospf_external_lsa_originate (ospf, ei);
+              }
+        }
     }
   if (default_refresh)
     ospf_external_lsa_refresh_default (ospf);
@@ -1111,12 +1273,15 @@ ospf_distribute_list_update_timer (struct thread *thread)
 
 /* Update distribute-list and set timer to apply access-list. */
 void
-ospf_distribute_list_update (struct ospf *ospf, uintptr_t type)
+ospf_distribute_list_update (struct ospf *ospf, uintptr_t type,
+                             u_short instance)
 {
   struct route_table *rt;
+  struct ospf_external *ext;
 
   /* External info does not exist. */
-  if (!(rt = EXTERNAL_INFO (type)))
+  ext = ospf_external_lookup(type, instance);
+  if (!ext || !(rt = EXTERNAL_INFO (ext)))
     return;
 
   /* If exists previously invoked thread, then let it continue. */
@@ -1139,7 +1304,7 @@ ospf_filter_update (struct access_list *access)
   struct ospf_area *area;
   struct listnode *node;
 
-  /* If OSPF instatnce does not exist, return right now. */
+  /* If OSPF instance does not exist, return right now. */
   ospf = ospf_lookup ();
   if (ospf == NULL)
     return;
@@ -1147,12 +1312,20 @@ ospf_filter_update (struct access_list *access)
   /* Update distribute-list, and apply filter. */
   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
     {
-      if (ROUTEMAP (ospf, type) != NULL)
-        {
-          /* if route-map is not NULL it may be using this access list */
-          ospf_distribute_list_update (ospf, type);
-          continue;
-        }
+      struct list *red_list;
+      struct listnode *node;
+      struct ospf_redist *red;
+
+      red_list = ospf->redist[type];
+      if (red_list)
+        for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+          {
+            if (ROUTEMAP (red))
+              {
+                /* if route-map is not NULL it may be using this access list */
+                ospf_distribute_list_update (ospf, type, red->instance);
+              }
+          }
 
       /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
        * but no distribute list. */
@@ -1175,7 +1348,7 @@ ospf_filter_update (struct access_list *access)
           /* Schedule distribute-list update timer. */
           if (DISTRIBUTE_LIST (ospf, type) == NULL ||
               strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
-            ospf_distribute_list_update (ospf, type);
+            ospf_distribute_list_update (ospf, type, 0);
         }
     }
 
@@ -1220,12 +1393,20 @@ ospf_prefix_list_update (struct prefix_list *plist)
    */
   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
     {
-      if (ROUTEMAP (ospf, type) != NULL)
-        {
-          /* If route-map is not NULL it may be using this prefix list */
-          ospf_distribute_list_update (ospf, type);
-          continue;
-        }
+      struct list *red_list;
+      struct listnode *node;
+      struct ospf_redist *red;
+
+      red_list = ospf->redist[type];
+      if (red_list)
+        for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+          {
+            if (ROUTEMAP (red))
+              {
+                /* if route-map is not NULL it may be using this prefix list */
+                ospf_distribute_list_update (ospf, type, red->instance);
+              }
+          }
     }
 
   /* Update area filter-lists. */
@@ -1400,11 +1581,11 @@ ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
 }
 
 void
-ospf_zebra_init ()
+ospf_zebra_init (u_short instance)
 {
   /* Allocate zebra structure. */
   zclient = zclient_new ();
-  zclient_init (zclient, ZEBRA_ROUTE_OSPF);
+  zclient_init (zclient, ZEBRA_ROUTE_OSPF, instance);
   zclient->router_id_update = ospf_router_id_update_zebra;
   zclient->interface_add = ospf_interface_add;
   zclient->interface_delete = ospf_interface_delete;
index 148f6520ff62ff51f9f1e190d2ad0a4ddffb3421..1cebb3d6d295f181b6452a70882e3f2b9d65251d 100644 (file)
@@ -54,25 +54,32 @@ extern int ospf_redistribute_check (struct ospf *, struct external_info *,
                                    int *);
 extern int ospf_distribute_check_connected (struct ospf *,
                                            struct external_info *);
-extern void ospf_distribute_list_update (struct ospf *, uintptr_t);
+extern void ospf_distribute_list_update (struct ospf *, uintptr_t, u_short);
 
-extern int ospf_is_type_redistributed (int);
+extern int ospf_is_type_redistributed (int, u_short);
 extern void ospf_distance_reset (struct ospf *);
 extern u_char ospf_distance_apply (struct prefix_ipv4 *, struct ospf_route *);
+extern struct ospf_external *ospf_external_lookup (u_char, u_short);
+extern struct ospf_external *ospf_external_add (u_char, u_short);
+extern void ospf_external_del (u_char, u_short);
+extern struct ospf_redist *ospf_redist_lookup (struct ospf *, u_char, u_short);
+extern struct ospf_redist *ospf_redist_add (struct ospf *, u_char, u_short);
+extern void ospf_redist_del (struct ospf *, u_char, u_short);
 
-extern int ospf_redistribute_set (struct ospf *, int, int, int);
-extern int ospf_redistribute_unset (struct ospf *, int);
+
+extern int ospf_redistribute_set (struct ospf *, int, u_short, int, int);
+extern int ospf_redistribute_unset (struct ospf *, int, u_short);
 extern int ospf_redistribute_default_set (struct ospf *, int, int, int);
 extern int ospf_redistribute_default_unset (struct ospf *);
 extern int ospf_distribute_list_out_set (struct ospf *, int, const char *);
 extern int ospf_distribute_list_out_unset (struct ospf *, int, const char *);
-extern void ospf_routemap_set (struct ospf *, int, const char *);
-extern void ospf_routemap_unset (struct ospf *, int);
+extern void ospf_routemap_set (struct ospf_redist *, const char *);
+extern void ospf_routemap_unset (struct ospf_redist *);
 extern int ospf_distance_set (struct vty *, struct ospf *, const char *,
                              const char *, const char *);
 extern int ospf_distance_unset (struct vty *, struct ospf *, const char *,
                                const char *, const char *);
-extern void ospf_zebra_init (void);
+extern void ospf_zebra_init (u_short);
 
 #endif /* _ZEBRA_OSPF_ZEBRA_H */
 
index a69b5595d76185ff7b6fa99881762fc43c08f031..e815c521cac54669966032f20407e75a7302a57a 100644 (file)
@@ -153,12 +153,13 @@ ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
 
 /* Allocate new ospf structure. */
 static struct ospf *
-ospf_new (void)
+ospf_new (u_short instance)
 {
   int i;
 
   struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
 
+  new->instance = instance;
   new->router_id.s_addr = htonl (0);
   new->router_id_static.s_addr = htonl (0);
 
@@ -187,8 +188,6 @@ ospf_new (void)
   /* Distribute parameter init. */
   for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
     {
-      new->dmetric[i].type = -1;
-      new->dmetric[i].value = -1;
       new->dtag[i] = 0;
     }
   new->default_metric = -1;
@@ -248,6 +247,23 @@ ospf_lookup ()
   return listgetdata (listhead (om->ospf));
 }
 
+struct ospf *
+ospf_lookup_instance (u_short instance)
+{
+  struct ospf *ospf;
+  struct listnode *node, *nnode;
+
+  if (listcount (om->ospf) == 0)
+    return NULL;
+
+  for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
+    if ((ospf->instance == 0 && instance == 0)
+        || (ospf->instance && instance && ospf->instance == instance))
+      return ospf;
+
+  return NULL;
+}
+
 static void
 ospf_add (struct ospf *ospf)
 {
@@ -268,7 +284,29 @@ ospf_get ()
   ospf = ospf_lookup ();
   if (ospf == NULL)
     {
-      ospf = ospf_new ();
+      ospf = ospf_new (0);
+      ospf_add (ospf);
+
+      if (ospf->router_id_static.s_addr == 0)
+       ospf_router_id_update (ospf);
+
+#ifdef HAVE_OPAQUE_LSA
+      ospf_opaque_type11_lsa_init (ospf);
+#endif /* HAVE_OPAQUE_LSA */
+    }
+
+  return ospf;
+}
+
+struct ospf *
+ospf_get_instance (u_short instance)
+{
+  struct ospf *ospf;
+
+  ospf = ospf_lookup_instance (instance);
+  if (ospf == NULL)
+    {
+      ospf = ospf_new (instance);
       ospf_add (ospf);
 
       if (ospf->router_id_static.s_addr == 0)
@@ -409,6 +447,7 @@ ospf_finish_final (struct ospf *ospf)
   struct ospf_vl_data *vl_data;
   struct listnode *node, *nnode;
   int i;
+  u_short instance;
 
 #ifdef HAVE_OPAQUE_LSA
   ospf_opaque_type11_lsa_term (ospf);
@@ -419,7 +458,17 @@ ospf_finish_final (struct ospf *ospf)
   
   /* Unregister redistribution */
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-    ospf_redistribute_unset (ospf, i);
+    {
+      struct list *red_list;
+      struct ospf_redist *red;
+
+      red_list = ospf->redist[i];
+      if (!red_list)
+        continue;
+
+      for (ALL_LIST_ELEMENTS(red_list, node, nnode, red))
+        ospf_redistribute_unset (ospf, i, red->instance);
+    }
   ospf_redistribute_default_unset (ospf);
 
   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
@@ -557,23 +606,43 @@ ospf_finish_final (struct ospf *ospf)
   list_delete (ospf->areas);
   
   for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
-    if (EXTERNAL_INFO (i) != NULL)
-      for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
-       {
-         if (rn->info == NULL)
-           continue;
-         
-         XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
-         rn->info = NULL;
-         route_unlock_node (rn);
-       }
+    {
+      struct list *ext_list;
+      struct listnode *node;
+      struct ospf_external *ext;
+
+      ext_list = om->external[i];
+      if (!ext_list)
+        continue;
+
+      for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
+        {
+          if (ext->external_info)
+            for (rn = route_top (ext->external_info); rn; rn = route_next (rn))
+              {
+                if (rn->info == NULL)
+                  continue;
+
+                XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
+                rn->info = NULL;
+                route_unlock_node (rn);
+              }
+        }
+    }
 
   ospf_distance_reset (ospf);
   route_table_finish (ospf->distance_table);
 
+  if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
+    instance = ospf->instance;
+
   ospf_delete (ospf);
 
   XFREE (MTYPE_OSPF_TOP, ospf);
+
+  if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
+    ospf_get_instance(instance);
+
 }
 
 
@@ -775,11 +844,13 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf)
 {
   struct route_node *rn;
   struct external_info *ei;
+  struct ospf_external *ext;
 
-  if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
-    if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
+  if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT, 0))
+    if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0)) &&
+         EXTERNAL_INFO (ext))
       {
-        for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
+        for (rn = route_top (EXTERNAL_INFO (ext));
              rn; rn = route_next (rn))
           {
             if ((ei = rn->info) != NULL)
index 53c4099f2b3b30b595beaaa1580f26aa2374e917..7cbd8578679b2288d1403ab5d4a2ac2bcb19af8a 100644 (file)
 #define OSPF_LS_REFRESH_SHIFT       (60 * 15)
 #define OSPF_LS_REFRESH_JITTER      60
 
+struct ospf_external
+{
+  u_short instance;
+  struct route_table *external_info;
+};
+
 /* OSPF master for system wide configuration and variables. */
 struct ospf_master
 {
@@ -89,8 +95,8 @@ struct ospf_master
   struct list *iflist;
 
   /* Redistributed external information. */
-  struct route_table *external_info[ZEBRA_ROUTE_MAX + 1];
-#define EXTERNAL_INFO(T)      om->external_info[T]
+  struct list *external[ZEBRA_ROUTE_MAX + 1];
+#define EXTERNAL_INFO(E)      (E->external_info)
 
   /* OSPF start time. */
   time_t start_time;
@@ -100,9 +106,34 @@ struct ospf_master
 #define OSPF_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */  
 };
 
+struct ospf_redist
+{
+  u_short instance;
+
+  /* Redistribute metric info. */
+  struct
+  {
+    int type;                   /* External metric type (E1 or E2).  */
+    int value;                 /* Value for static metric (24-bit).
+                                  -1 means metric value is not set. */
+  } dmetric;
+
+  /* For redistribute route map. */
+  struct
+  {
+    char *name;
+    struct route_map *map;
+  } route_map; /* +1 is for default-information */
+#define ROUTEMAP_NAME(R)   (R->route_map.name)
+#define ROUTEMAP(R)        (R->route_map.map)
+};
+
 /* OSPF instance structure. */
 struct ospf
 {
+  /* OSPF instance ID  */
+  u_short instance;
+
   /* OSPF Router ID. */
   struct in_addr router_id;            /* Configured automatically. */
   struct in_addr router_id_static;     /* Configured manually. */
@@ -236,26 +267,12 @@ struct ospf
 #define DISTRIBUTE_NAME(O,T)    (O)->dlist[T].name
 #define DISTRIBUTE_LIST(O,T)    (O)->dlist[T].list
 
-  /* Redistribute metric info. */
-  struct 
-  {
-    int type;                   /* External metric type (E1 or E2).  */
-    int value;                 /* Value for static metric (24-bit).
-                                  -1 means metric value is not set. */
-  } dmetric [ZEBRA_ROUTE_MAX + 1];
+  /* OSPF redistribute configuration */
+  struct list *redist[ZEBRA_ROUTE_MAX + 1];
 
   /* Redistribute tag info. */
-  u_short dtag [ZEBRA_ROUTE_MAX + 1];
+  u_short dtag[ZEBRA_ROUTE_MAX + 1]; //Pending: cant configure as of now
 
-  /* For redistribute route map. */
-  struct
-  {
-    char *name;
-    struct route_map *map;
-  } route_map [ZEBRA_ROUTE_MAX + 1]; /* +1 is for default-information */
-#define ROUTEMAP_NAME(O,T)   (O)->route_map[T].name
-#define ROUTEMAP(O,T)        (O)->route_map[T].map
-  
   int default_metric;          /* Default metric for redistribute. */
 
 #define OSPF_LSA_REFRESHER_GRANULARITY 10
@@ -514,7 +531,9 @@ extern int ospf_zlog;
 /* Prototypes. */
 extern const char *ospf_redist_string(u_int route_type);
 extern struct ospf *ospf_lookup (void);
+extern struct ospf *ospf_lookup_instance (u_short);
 extern struct ospf *ospf_get (void);
+extern struct ospf *ospf_get_instance (u_short);
 extern void ospf_finish (struct ospf *);
 extern void ospf_router_id_update (struct ospf *ospf);
 extern int ospf_network_set (struct ospf *, struct prefix_ipv4 *,
index e81e61b80351846f4dd5d3322fa049cdf93c85c8..dbb9b46fe1ede9a964f9648ca9edda7a0764913b 100644 (file)
@@ -201,7 +201,7 @@ main (int argc, char **argv)
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
   /* First of all we need logging init. */
-  zlog_default = openzlog (progname, ZLOG_RIP,
+  zlog_default = openzlog (progname, ZLOG_RIP, 0,
                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
 
   /* Command line option parse. */
index 1f6ef612065bae08bf7db23c6b1b6cc54e8a3385..d0ab21d2bf5b65fd649f1b6229607556afcc376d 100644 (file)
@@ -41,9 +41,10 @@ rip_zebra_ipv4_add (struct prefix_ipv4 *p, struct in_addr *nexthop,
 {
   struct zapi_ipv4 api;
 
-  if (zclient->redist[ZEBRA_ROUTE_RIP])
+  if (zclient->redist[ZEBRA_ROUTE_RIP].enabled)
     {
       api.type = ZEBRA_ROUTE_RIP;
+      api.instance = 0;
       api.flags = 0;
       api.message = 0;
       api.safi = SAFI_UNICAST;
@@ -72,9 +73,10 @@ rip_zebra_ipv4_delete (struct prefix_ipv4 *p, struct in_addr *nexthop,
 {
   struct zapi_ipv4 api;
 
-  if (zclient->redist[ZEBRA_ROUTE_RIP])
+  if (zclient->redist[ZEBRA_ROUTE_RIP].enabled)
     {
       api.type = ZEBRA_ROUTE_RIP;
+      api.instance = 0;
       api.flags = 0;
       api.message = 0;
       api.safi = SAFI_UNICAST;
@@ -107,6 +109,7 @@ rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
 
   /* Type, flags, message. */
   api.type = stream_getc (s);
+  api.instance = stream_getw (s);
   api.flags = stream_getc (s);
   api.message = stream_getc (s);
 
@@ -255,13 +258,13 @@ rip_redistribute_set (int type)
 static int
 rip_redistribute_unset (int type)
 {
-  if (! zclient->redist[type])
+  if (! zclient->redist[type].enabled)
     return CMD_SUCCESS;
 
-  zclient->redist[type] = 0;
+  redist_del_instance(&zclient->redist[type], 0);
 
   if (zclient->sock > 0)
-    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
+    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, 0);
 
   /* Remove the routes from RIP table. */
   rip_redistribute_withdraw (type);
@@ -272,7 +275,7 @@ rip_redistribute_unset (int type)
 int
 rip_redistribute_check (int type)
 {
-  return (zclient->redist[type]);
+  return (zclient->redist[type].enabled);
 }
 
 void
@@ -282,13 +285,13 @@ rip_redistribute_clean (void)
 
   for (i = 0; redist_type[i].str; i++)
     {
-      if (zclient->redist[redist_type[i].type])
+      if (zclient->redist[redist_type[i].type].enabled)
        {
          if (zclient->sock > 0)
            zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
-                                    zclient, redist_type[i].type);
+                                    zclient, redist_type[i].type, 0);
 
-         zclient->redist[redist_type[i].type] = 0;
+          redist_del_instance(&zclient->redist[redist_type[i].type], 0);
 
          /* Remove the routes from RIP table. */
          rip_redistribute_withdraw (redist_type[i].type);
@@ -302,7 +305,7 @@ DEFUN (rip_redistribute_rip,
        "Redistribute information from another routing protocol\n"
        "Routing Information Protocol (RIP)\n")
 {
-  zclient->redist[ZEBRA_ROUTE_RIP] = 1;
+  redist_add_instance(&zclient->redist[ZEBRA_ROUTE_RIP], 0);
   return CMD_SUCCESS;
 }
 
@@ -313,7 +316,7 @@ DEFUN (no_rip_redistribute_rip,
        "Redistribute information from another routing protocol\n"
        "Routing Information Protocol (RIP)\n")
 {
-  zclient->redist[ZEBRA_ROUTE_RIP] = 0;
+  redist_del_instance(&zclient->redist[ZEBRA_ROUTE_RIP], 0);
   return CMD_SUCCESS;
 }
 
@@ -331,7 +334,7 @@ DEFUN (rip_redistribute_type,
                   redist_type[i].str_min_len) == 0) 
        {
          zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, 
-                               redist_type[i].type);
+                               redist_type[i].type, 0);
          return CMD_SUCCESS;
        }
     }
@@ -384,7 +387,7 @@ DEFUN (rip_redistribute_type_routemap,
                redist_type[i].str_min_len) == 0) 
       {
        rip_routemap_set (redist_type[i].type, argv[1]);
-       zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
+       zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type, 0);
        return CMD_SUCCESS;
       }
   }
@@ -442,7 +445,7 @@ DEFUN (rip_redistribute_type_metric,
                redist_type[i].str_min_len) == 0) 
       {
        rip_redistribute_metric_set (redist_type[i].type, metric);
-       zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
+       zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type, 0);
        return CMD_SUCCESS;
       }
   }
@@ -503,7 +506,7 @@ DEFUN (rip_redistribute_type_metric_routemap,
       {
        rip_redistribute_metric_set (redist_type[i].type, metric);
        rip_routemap_set (redist_type[i].type, argv[2]);
-       zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
+       zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type, 0);
        return CMD_SUCCESS;
       }
   }
@@ -607,7 +610,7 @@ config_write_zebra (struct vty *vty)
       vty_out (vty, "no router zebra%s", VTY_NEWLINE);
       return 1;
     }
-  else if (! zclient->redist[ZEBRA_ROUTE_RIP])
+  else if (! zclient->redist[ZEBRA_ROUTE_RIP].enabled)
     {
       vty_out (vty, "router zebra%s", VTY_NEWLINE);
       vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
@@ -622,7 +625,8 @@ config_write_rip_redistribute (struct vty *vty, int config_mode)
   int i;
 
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-    if (i != zclient->redist_default && zclient->redist[i])
+    if (i != zclient->redist_default &&
+        zclient->redist[i].enabled)
       {
        if (config_mode)
          {
@@ -667,7 +671,7 @@ rip_zclient_init ()
 {
   /* Set default value to the zebra client structure. */
   zclient = zclient_new ();
-  zclient_init (zclient, ZEBRA_ROUTE_RIP);
+  zclient_init (zclient, ZEBRA_ROUTE_RIP, 0);
   zclient->interface_add = rip_interface_add;
   zclient->interface_delete = rip_interface_delete;
   zclient->interface_address_add = rip_interface_address_add;
index acc980ded9f6c96c22d939343724203f147e6ddf..522c48272724504a3f039589e9c98212703d2720 100644 (file)
@@ -200,7 +200,7 @@ main (int argc, char **argv)
   /* get program name */
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
-  zlog_default = openzlog(progname, ZLOG_RIPNG,
+  zlog_default = openzlog(progname, ZLOG_RIPNG, 0,
                          LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
 
   while (1) 
index 68f37be324c4d224bdb484169a1985beb3fdd994..92c845418365124c99e87cb758b697bf395713ba 100644 (file)
@@ -48,9 +48,10 @@ ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
 {
   struct zapi_ipv6 api;
 
-  if (zclient->redist[ZEBRA_ROUTE_RIPNG])
+  if (zclient->redist[ZEBRA_ROUTE_RIPNG].enabled)
     {
       api.type = ZEBRA_ROUTE_RIPNG;
+      api.instance = 0;
       api.flags = 0;
       api.message = 0;
       api.safi = SAFI_UNICAST;
@@ -73,9 +74,10 @@ ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
 {
   struct zapi_ipv6 api;
 
-  if (zclient->redist[ZEBRA_ROUTE_RIPNG])
+  if (zclient->redist[ZEBRA_ROUTE_RIPNG].enabled)
     {
       api.type = ZEBRA_ROUTE_RIPNG;
+      api.instance = 0;
       api.flags = 0;
       api.message = 0;
       api.safi = SAFI_UNICAST;
@@ -107,6 +109,7 @@ ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
 
   /* Type, flags, message. */
   api.type = stream_getc (s);
+  api.instance = stream_getw (s);
   api.flags = stream_getc (s);
   api.message = stream_getc (s);
 
@@ -153,13 +156,13 @@ ripng_zclient_reset (void)
 static int
 ripng_redistribute_unset (int type)
 {
-  if (! zclient->redist[type])
+  if (! zclient->redist[type].enabled)
     return CMD_SUCCESS;
 
-  zclient->redist[type] = 0;
+  redist_del_instance(&zclient->redist[type], 0);
 
   if (zclient->sock > 0)
-    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
+    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, 0);
 
   ripng_redistribute_withdraw (type);
   
@@ -169,7 +172,7 @@ ripng_redistribute_unset (int type)
 int
 ripng_redistribute_check (int type)
 {
-  return (zclient->redist[type]);
+  return (zclient->redist[type].enabled);
 }
 
 static void
@@ -229,13 +232,13 @@ ripng_redistribute_clean ()
 
   for (i = 0; redist_type[i].str; i++)
     {
-      if (zclient->redist[redist_type[i].type])
+      if (zclient->redist[redist_type[i].type].enabled)
         {
           if (zclient->sock > 0)
             zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
-                                     zclient, redist_type[i].type);
+                                     zclient, redist_type[i].type, 0);
 
-          zclient->redist[redist_type[i].type] = 0;
+          redist_del_instance(&zclient->redist[redist_type[i].type], 0);
 
           /* Remove the routes from RIPng table. */
           ripng_redistribute_withdraw (redist_type[i].type);
@@ -273,7 +276,7 @@ DEFUN (ripng_redistribute_ripng,
        "Redistribute information from another routing protocol\n"
        "RIPng route\n")
 {
-  zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
+  redist_add_instance(&zclient->redist[ZEBRA_ROUTE_RIPNG], 0);
   return CMD_SUCCESS;
 }
 
@@ -284,7 +287,7 @@ DEFUN (no_ripng_redistribute_ripng,
        "Redistribute information from another routing protocol\n"
        "RIPng route\n")
 {
-  zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
+  redist_del_instance(&zclient->redist[ZEBRA_ROUTE_RIPNG], 0);
   return CMD_SUCCESS;
 }
 
@@ -304,7 +307,7 @@ DEFUN (ripng_redistribute_type,
       return CMD_WARNING;
     }
 
-  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
   return CMD_SUCCESS;
 }
 
@@ -352,7 +355,7 @@ DEFUN (ripng_redistribute_type_metric,
     }
 
   ripng_redistribute_metric_set (type, metric);
-  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
   return CMD_SUCCESS;
 }
 
@@ -384,7 +387,7 @@ DEFUN (ripng_redistribute_type_routemap,
     }
 
   ripng_redistribute_routemap_set (type, argv[1]);
-  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
  return CMD_SUCCESS;
 }
 
@@ -421,7 +424,7 @@ DEFUN (ripng_redistribute_type_metric_routemap,
 
   ripng_redistribute_metric_set (type, metric);
   ripng_redistribute_routemap_set (type, argv[2]);
-  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
+  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
   return CMD_SUCCESS;
 }
 
@@ -440,7 +443,8 @@ ripng_redistribute_write (struct vty *vty, int config_mode)
   int i;
 
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-    if (i != zclient->redist_default && zclient->redist[i])
+    if (i != zclient->redist_default &&
+        zclient->redist[i].enabled)
       {
       if (config_mode)
        {
@@ -480,7 +484,7 @@ zebra_config_write (struct vty *vty)
       vty_out (vty, "no router zebra%s", VTY_NEWLINE);
       return 1;
     }
-  else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
+  else if (! zclient->redist[ZEBRA_ROUTE_RIPNG].enabled)
     {
       vty_out (vty, "router zebra%s", VTY_NEWLINE);
       vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
@@ -502,7 +506,7 @@ zebra_init ()
 {
   /* Allocate zebra structure. */
   zclient = zclient_new ();
-  zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
+  zclient_init (zclient, ZEBRA_ROUTE_RIPNG, 0);
 
   zclient->interface_up = ripng_interface_up;
   zclient->interface_down = ripng_interface_down;
index df023fac60a151c35468705e36bdcd2d4b3599ed..75e2afceba7c1a2397e8593361d00df40698cb3d 100644 (file)
@@ -46,7 +46,7 @@ main (void)
   master = thread_master_create ();
   signal_init (master, array_size(sigs), sigs);
   
-  zlog_default = openzlog("testsig", ZLOG_NONE,
+  zlog_default = openzlog("testsig", ZLOG_NONE, 0,
                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
   zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
   zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
index 49788363ea6a3edd5df57f918e72e526d4fe9d5e..2249b4092a59535724f76c567ce97e7b5c481453 100755 (executable)
@@ -35,7 +35,7 @@ $ignore{'"ip vrf NAME"'} = "ignore";
 $ignore{'"router rip"'} = "ignore";
 $ignore{'"router ripng"'} = "ignore";
 $ignore{'"router ospf"'} = "ignore";
-$ignore{'"router ospf <0-65535>"'} = "ignore";
+$ignore{'"router ospf <1-65535>"'} = "ignore";
 $ignore{'"router ospf6"'} = "ignore";
 $ignore{'"router babel"'} = "ignore";
 $ignore{'"router bgp " "<1-4294967295>"'} = "ignore";
index f6d82972d9f3f5e6b2cded74d2d0126bd4fe2737..2534e8ae13ba4dad8a37dd155ba36e9cdd0280a5 100644 (file)
 #include <readline/readline.h>
 #include <readline/history.h>
 
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+
 #include "command.h"
 #include "memory.h"
 #include "vtysh/vtysh.h"
@@ -46,19 +50,22 @@ char *vtysh_pager_name = NULL;
 struct vtysh_client
 {
   int fd;
-  const char *name;
+  char *name;
   int flag;
-  const char *path;
-} vtysh_client[] =
-{
-  { .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path = ZEBRA_VTYSH_PATH},
-  { .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH},
-  { .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH},
-  { .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH},
-  { .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},
-  { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},
-  { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},
-  { .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH},
+  char *path;
+  struct vtysh_client *next;
+};
+
+struct vtysh_client vtysh_client[] =
+{
+  { .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path = ZEBRA_VTYSH_PATH, .next = NULL},
+  { .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH, .next = NULL},
+  { .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH, .next = NULL},
+  { .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH, .next = NULL},
+  { .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH, .next = NULL},
+  { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH, .next = NULL},
+  { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH, .next = NULL},
+  { .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH, .next = NULL},
 };
 
 
@@ -88,7 +95,7 @@ vclient_close (struct vtysh_client *vclient)
  * under load - it SHOULD handle it. */
 #define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
 static int
-vtysh_client_config (struct vtysh_client *vclient, char *line)
+vtysh_client_config_one (struct vtysh_client *vclient, char *line)
 {
   int ret;
   char *buf;
@@ -186,7 +193,28 @@ vtysh_client_config (struct vtysh_client *vclient, char *line)
 }
 
 static int
-vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)
+vtysh_client_config (struct vtysh_client *head_client, char *line)
+{
+  struct vtysh_client *client;
+  int rc;
+
+  rc = vtysh_client_config_one(head_client, line);
+  if (rc != CMD_SUCCESS)
+    return rc;
+
+  client = head_client->next;
+  while (client)
+    {
+      rc = vtysh_client_config_one(client, line);
+      if (rc != CMD_SUCCESS)
+        return rc;
+      client = client->next;
+    }
+  return CMD_SUCCESS;
+}
+
+static int
+vtysh_client_execute_one (struct vtysh_client *vclient, const char *line, FILE *fp)
 {
   int ret;
   char buf[1001];
@@ -250,6 +278,27 @@ vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)
     }
 }
 
+static int
+vtysh_client_execute (struct vtysh_client *head_client, const char *line, FILE *fp)
+{
+  struct vtysh_client *client;
+  int rc;
+
+  rc = vtysh_client_execute_one(head_client, line, fp);
+  if (rc != CMD_SUCCESS)
+    return rc;
+
+  client = head_client->next;
+  while (client)
+    {
+      rc = vtysh_client_execute_one(client, line, fp);
+      if (rc != CMD_SUCCESS)
+        return rc;
+      client = client->next;
+    }
+  return CMD_SUCCESS;
+}
+
 void
 vtysh_exit_ripd_only (void)
 {
@@ -1005,6 +1054,14 @@ DEFUNSH (VTYSH_OSPFD,
   return CMD_SUCCESS;
 }
 
+ALIAS_SH (VTYSH_OSPFD,
+        router_ospf,
+        router_ospf_instance_cmd,
+        "router ospf <1-65535>",
+        "Enable a routing process\n"
+        "Start OSPF configuration\n"
+         "Instance ID\n")
+
 DEFUNSH (VTYSH_OSPF6D,
         router_ospf6,
         router_ospf6_cmd,
@@ -2177,6 +2234,114 @@ vtysh_connect (struct vtysh_client *vclient)
   return 0;
 }
 
+/* Return true if str begins with prefix, else return false */
+static int
+begins_with(const char *str, const char *prefix)
+{
+  if (!str || !prefix)
+    return 0;
+  size_t lenstr = strlen(str);
+  size_t lenprefix = strlen(prefix);
+  if (lenprefix >  lenstr)
+    return 0;
+  return strncmp(str, prefix, lenprefix) == 0;
+}
+
+/* Return true if str ends with suffix, else return false */
+static int
+ends_with(const char *str, const char *suffix)
+{
+  if (!str || !suffix)
+    return 0;
+  size_t lenstr = strlen(str);
+  size_t lensuffix = strlen(suffix);
+  if (lensuffix >  lenstr)
+    return 0;
+  return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
+}
+
+static void
+vtysh_client_sorted_insert (struct vtysh_client *head_client,
+                            struct vtysh_client *client)
+{
+  struct vtysh_client *prev_node, *current_node;
+
+  prev_node = head_client;
+  current_node = head_client->next;
+  while (current_node)
+    {
+      if (strcmp(current_node->path, client->path) > 0)
+        break;
+
+      prev_node = current_node;
+      current_node = current_node->next;
+    }
+  client->next = current_node;
+  prev_node->next = client;
+}
+
+#define MAXIMUM_INSTANCES 10
+
+static void
+vtysh_update_all_insances(struct vtysh_client * head_client)
+{
+  struct vtysh_client *client;
+  char *path;
+  DIR *dir;
+  struct dirent *file;
+  int n = 0;
+
+  if (head_client->flag != VTYSH_OSPFD) return;
+
+  /* ls /var/run/quagga/ and look for all files ending in .vty */
+  dir = opendir("/var/run/quagga/");
+  if (dir)
+    {
+      while ((file = readdir(dir)) != NULL)
+        {
+          if (begins_with(file->d_name, "ospfd-") && ends_with(file->d_name, ".vty"))
+            {
+              if (n == MAXIMUM_INSTANCES)
+                {
+                  fprintf(stderr,
+                          "Parsing /var/run/quagga/, client limit(%d) reached!\n", n);
+                  break;
+                }
+              client = (struct vtysh_client *) malloc(sizeof(struct vtysh_client));
+              client->fd = -1;
+              client->name = (char *) malloc(10);
+              strcpy(client->name, "ospfd");
+              client->flag = VTYSH_OSPFD;
+              client->path = (char *) malloc(100);
+              sprintf(client->path, "/var/run/quagga/%s", file->d_name);
+              client->next = NULL;
+              vtysh_client_sorted_insert(head_client, client);
+              n++;
+            }
+        }
+      closedir(dir);
+    }
+}
+
+int
+vtysh_connect_all_instances (struct vtysh_client *head_client)
+{
+  struct vtysh_client *client;
+  int rc = 0;
+
+  vtysh_update_all_insances(head_client);
+
+  client = head_client->next;
+  while (client)
+    {
+      if (vtysh_connect(client) == 0)
+        rc++;
+      client = client->next;
+    }
+
+  return rc;
+}
+
 int
 vtysh_connect_all(const char *daemon_name)
 {
@@ -2194,7 +2359,9 @@ vtysh_connect_all(const char *daemon_name)
          /* We need direct access to ripd in vtysh_exit_ripd_only. */
          if (vtysh_client[i].flag == VTYSH_RIPD)
            ripd_client = &vtysh_client[i];
-       }
+
+          rc += vtysh_connect_all_instances(&vtysh_client[i]);
+       }
     }
   if (!matches)
     fprintf(stderr, "Error: no daemons match name %s!\n", daemon_name);
@@ -2368,6 +2535,7 @@ vtysh_init_vty (void)
   install_element (CONFIG_NODE, &router_ripng_cmd);
 #endif
   install_element (CONFIG_NODE, &router_ospf_cmd);
+  install_element (CONFIG_NODE, &router_ospf_instance_cmd);
 #ifdef HAVE_IPV6
   install_element (CONFIG_NODE, &router_ospf6_cmd);
 #endif
index c1c88921098720c2199cd9f2cd012d5ba3133ece..ca05361c1ce0e389a7040f20b1fc9d5ccb63fe7e 100644 (file)
@@ -1336,7 +1336,7 @@ main(int argc, char **argv)
       return usage(progname,1);
     }
 
-  zlog_default = openzlog(progname, ZLOG_NONE,
+  zlog_default = openzlog(progname, ZLOG_NONE, 0,
                          LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
   zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
   if (daemon_mode)
index ef1792c2f5f5a849fb50a470f440163835b7a381..0c9221da43663abbcd03f98461d90ba012dbd89f 100644 (file)
@@ -207,10 +207,10 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
   if (prefix_ipv4_any (&p))
     return;
 
-  rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
+  rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, NULL, ifp->ifindex,
        RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
 
-  rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
+  rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, NULL, ifp->ifindex,
        RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);
 
   rib_update ();
@@ -323,9 +323,9 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
     return;
 
   /* Same logic as for connected_up_ipv4(): push the changes into the head. */
-  rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
+  rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
 
-  rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_MULTICAST);
+  rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_MULTICAST);
 
   rib_update ();
 }
@@ -410,7 +410,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
     return;
 #endif
 
-  rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN,
+  rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN,
                 ifp->metric, 0, SAFI_UNICAST);
 
   rib_update ();
@@ -496,7 +496,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
   if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
     return;
 
-  rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
+  rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
 
   rib_update ();
 }
index 3dbeb98bce1b3c57d4f27086d8f9b527bc2cbcb9..03f3eaeb6a5d930d281108b79f459bd71669dfeb 100644 (file)
@@ -934,16 +934,16 @@ rtm_read (struct rt_msghdr *rtm)
        * to specify the route really
        */
       if (rtm->rtm_type == RTM_CHANGE)
-        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
+        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
                          NULL, 0, 0, SAFI_UNICAST);
       
       if (rtm->rtm_type == RTM_GET 
           || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)
-       rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 
+       rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
                      &p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0, SAFI_UNICAST);
       else
-       rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 
+       rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0 zebra_flags,
                      &p, &gate.sin.sin_addr, 0, 0, SAFI_UNICAST);
     }
 #ifdef HAVE_IPV6
@@ -976,16 +976,16 @@ rtm_read (struct rt_msghdr *rtm)
        * to specify the route really
        */
       if (rtm->rtm_type == RTM_CHANGE)
-        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
+        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
                          NULL, 0, 0, SAFI_UNICAST);
       
       if (rtm->rtm_type == RTM_GET 
           || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)
-       rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
+       rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
                      &p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0, SAFI_UNICAST);
       else
-       rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
+       rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
                         &p, &gate.sin6.sin6_addr, ifindex, 0, SAFI_UNICAST);
     }
 #endif /* HAVE_IPV6 */
index 13ad08eff59e4660b032aba2e296418bcb5f181d..6cff6d45d80b4d20bfcdd2c54d9e1f973f06e2ba 100644 (file)
@@ -228,7 +228,7 @@ main (int argc, char **argv)
   /* preserve my name */
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
-  zlog_default = openzlog (progname, ZLOG_ZEBRA,
+  zlog_default = openzlog (progname, ZLOG_ZEBRA, 0,
                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
 
   while (1) 
index 5c9412c13bbe7bcfe3b8c1c0d35a623aad6e7762..b67430d1aeaf8d81b56e1f36572cf1d3a6c9b5ba 100644 (file)
@@ -142,7 +142,7 @@ zebra_redistribute_default (struct zserv *client)
 
 /* Redistribute routes. */
 static void
-zebra_redistribute (struct zserv *client, int type)
+zebra_redistribute (struct zserv *client, int type, u_short instance)
 {
   struct rib *newrib;
   struct route_table *table;
@@ -153,7 +153,8 @@ zebra_redistribute (struct zserv *client, int type)
     for (rn = route_top (table); rn; rn = route_next (rn))
       RNODE_FOREACH_RIB (rn, newrib)
        if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED) 
-           && newrib->type == type 
+           && newrib->type == type
+            && newrib->instance == instance
            && newrib->distance != DISTANCE_INFINITY
            && zebra_check_addr (&rn->p))
          {
@@ -167,7 +168,8 @@ zebra_redistribute (struct zserv *client, int type)
     for (rn = route_top (table); rn; rn = route_next (rn))
       RNODE_FOREACH_RIB (rn, newrib)
        if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
-           && newrib->type == type 
+           && newrib->type == type
+            && newrib->instance == instance
            && newrib->distance != DISTANCE_INFINITY
            && zebra_check_addr (&rn->p))
          {
@@ -187,7 +189,8 @@ redistribute_add (struct prefix *p, struct rib *rib)
     {
       if (is_default (p))
         {
-          if (client->redist_default || client->redist[rib->type])
+          if (client->redist_default ||
+              redist_check_instance(&client->redist[rib->type], rib->instance))
             {
               if (p->family == AF_INET)
                {
@@ -203,7 +206,7 @@ redistribute_add (struct prefix *p, struct rib *rib)
 #endif /* HAVE_IPV6 */   
            }
         }
-      else if (client->redist[rib->type])
+      else if (redist_check_instance(&client->redist[rib->type], rib->instance))
         {
           if (p->family == AF_INET)
            {
@@ -235,7 +238,8 @@ redistribute_delete (struct prefix *p, struct rib *rib)
     {
       if (is_default (p))
        {
-         if (client->redist_default || client->redist[rib->type])
+         if (client->redist_default ||
+              redist_check_instance(&client->redist[rib->type], rib->instance))
            {
              if (p->family == AF_INET)
                zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
@@ -247,8 +251,8 @@ redistribute_delete (struct prefix *p, struct rib *rib)
 #endif /* HAVE_IPV6 */
            }
        }
-      else if (client->redist[rib->type])
-       {
+      else if (redist_check_instance(&client->redist[rib->type], rib->instance))
+      {
          if (p->family == AF_INET)
            zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
 #ifdef HAVE_IPV6
@@ -263,16 +267,18 @@ void
 zebra_redistribute_add (int command, struct zserv *client, int length)
 {
   int type;
+  u_short instance;
 
   type = stream_getc (client->ibuf);
+  instance = stream_getw (client->ibuf);
 
   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
     return;
 
-  if (! client->redist[type])
+  if (!redist_check_instance(&client->redist[type], instance))
     {
-      client->redist[type] = 1;
-      zebra_redistribute (client, type);
+      redist_add_instance(&client->redist[type], instance);
+      zebra_redistribute (client, type, instance);
     }
 }
 
@@ -280,13 +286,19 @@ void
 zebra_redistribute_delete (int command, struct zserv *client, int length)
 {
   int type;
+  u_short instance;
 
   type = stream_getc (client->ibuf);
+  instance = stream_getw (client->ibuf);
 
   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
     return;
 
-  client->redist[type] = 0;
+  if (redist_check_instance(&client->redist[type], instance))
+    {
+      redist_del_instance(&client->redist[type], instance);
+      //Pending: why no reaction here?
+    }
 }
 
 void
index 472bcf1d601ff6a75b99cf506bc3bd274c3a3343..e3c606f42c50057057b577a20912a93516c68d65 100644 (file)
@@ -48,6 +48,9 @@ struct rib
   /* Type fo this route. */
   int type;
 
+  /* Source protocol instance */
+  u_short instance;
+
   /* Which routing table */
   int table;                   
 
@@ -383,14 +386,14 @@ extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t i
 /* NOTE:
  * All rib_add_ipv[46]* functions will not just add prefix into RIB, but
  * also implicitly withdraw equal prefix of same type. */
-extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, 
+extern int rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
                         struct in_addr *gate, struct in_addr *src,
                         unsigned int ifindex, u_int32_t vrf_id,
                         u_int32_t, u_char, safi_t);
 
 extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *, safi_t);
 
-extern int rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
+extern int rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
                            struct in_addr *gate, unsigned int ifindex, 
                            u_int32_t, safi_t safi);
 
@@ -403,7 +406,7 @@ extern void rib_weed_tables (void);
 extern void rib_sweep_route (void);
 extern void rib_close (void);
 extern void rib_init (void);
-extern unsigned long rib_score_proto (u_char proto);
+extern unsigned long rib_score_proto (u_char proto, u_short instance);
 struct zebra_t;
 extern void rib_queue_add (struct zebra_t *zebra, struct route_node *rn);
 
@@ -418,12 +421,12 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
 
 #ifdef HAVE_IPV6
 extern int
-rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
+rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
              struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
              u_int32_t metric, u_char distance, safi_t safi);
 
 extern int
-rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
+rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
                 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi);
 
 extern struct rib *rib_lookup_ipv6 (struct in6_addr *);
index 5e8eb7b9f159be37eb857e2276d1e312cc440df0..1fa4593f4b891c54b32adf008d0a83842065e8b8 100644 (file)
@@ -743,7 +743,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
       p.prefixlen = rtm->rtm_dst_len;
 
       if (!tb[RTA_MULTIPATH])
-          rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index,
+          rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, src, index,
                         table, metric, 0, SAFI_UNICAST);
       else
         {
@@ -809,7 +809,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
       memcpy (&p.prefix, dest, 16);
       p.prefixlen = rtm->rtm_dst_len;
 
-      rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table,
+      rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, index, table,
                    metric, 0, SAFI_UNICAST);
     }
 #endif /* HAVE_IPV6 */
@@ -948,7 +948,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
       if (h->nlmsg_type == RTM_NEWROUTE)
         {
           if (!tb[RTA_MULTIPATH])
-            rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table,
+            rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, src, index, table,
                           metric, 0, SAFI_UNICAST);
           else
             {
@@ -1007,7 +1007,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
             }
         }
       else
-        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, index,
+        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
                          table, SAFI_UNICAST);
     }
 
@@ -1034,9 +1034,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
         }
 
       if (h->nlmsg_type == RTM_NEWROUTE)
-        rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, metric, 0, SAFI_UNICAST);
+        rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, index, table, metric, 0, SAFI_UNICAST);
       else
-        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, index,
+        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
                          table, SAFI_UNICAST);
     }
 #endif /* HAVE_IPV6 */
index 81bf0de6478a7caaa01a341acd5975cb5ac74f34..17d75b283a6e77117b13aa1f703aa014cf59330a 100644 (file)
@@ -89,7 +89,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
 
        gateway.s_addr = routeEntry->ipRouteNextHop;
 
-       rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &prefix,
+       rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix,
                      &gateway, NULL, 0, 0, 0, 0, SAFI_UNICAST);
 }
 
index 07e8491adf640d165cc26e6f47ad1c4940bd6cb5..b365d958f974ae015d54469e89b94019fae08b25 100644 (file)
@@ -96,7 +96,7 @@ proc_route_read (void)
       p.prefixlen = ip_masklen (tmpmask);
       sscanf (gate, "%lX", (unsigned long *)&gateway);
 
-      rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, NULL, 0, 0, 0, 0, SAFI_UNICAST);
+      rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, &gateway, NULL, 0, 0, 0, 0, SAFI_UNICAST);
     }
 
   fclose (fp);
index f98bb41995624549b842ef5f486595e8282b7e39..2d4874b7ddc175cab4eac4174e9b84cc2cec2871 100644 (file)
@@ -215,7 +215,7 @@ main (int argc, char **argv)
   /* preserve my name */
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
-  zlog_default = openzlog (progname, ZLOG_ZEBRA,
+  zlog_default = openzlog (progname, ZLOG_ZEBRA, 0,
                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
 
   while (1) 
index 08f65be1047e6b1b62486a8dda1a93808f05874d..f55302e135d2592ae8508154ab66b2979ed821f8 100644 (file)
@@ -2029,7 +2029,7 @@ rib_delnode (struct route_node *rn, struct rib *rib)
 }
 
 int
-rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, 
+rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
              struct in_addr *gate, struct in_addr *src,
              unsigned int ifindex, u_int32_t vrf_id,
              u_int32_t metric, u_char distance, safi_t safi)
@@ -2073,6 +2073,8 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
       
       if (rib->type != type)
        continue;
+      if (rib->instance != instance)
+       continue;
       if (rib->type != ZEBRA_ROUTE_CONNECT)
         {
           same = rib;
@@ -2092,6 +2094,7 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
   /* Allocate new rib structure. */
   rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
   rib->type = type;
+  rib->instance = instance;
   rib->distance = distance;
   rib->flags = flags;
   rib->metric = metric;
@@ -2149,11 +2152,12 @@ void _rib_dump (const char * func,
   zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
   zlog_debug
   (
-    "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
+    "%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
     func,
     rib->refcnt,
     (unsigned long) rib->uptime,
     rib->type,
+    rib->instance,
     rib->table
   );
   zlog_debug
@@ -2330,7 +2334,8 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
       if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
         continue;
       
-      if (same->type == rib->type && same->table == rib->table
+      if (same->type == rib->type && same->instance == rib->instance
+          && same->table == rib->table
          && same->type != ZEBRA_ROUTE_CONNECT)
         break;
     }
@@ -2369,7 +2374,7 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
 
 /* XXX factor with rib_delete_ipv6 */
 int
-rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
+rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
                 struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
 {
   struct route_table *table;
@@ -2437,6 +2442,8 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
 
       if (rib->type != type)
        continue;
+      if (rib->instance != instance)
+       continue;
       if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
          nexthop->type == NEXTHOP_TYPE_IFINDEX)
        {
@@ -2575,6 +2582,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
       rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
       
       rib->type = ZEBRA_ROUTE_STATIC;
+      rib->instance = 0;
       rib->distance = si->distance;
       rib->metric = 0;
       rib->table = zebrad.rtm_table_default;
@@ -2876,7 +2884,7 @@ rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
 }
 
 int
-rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
+rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
              struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
              u_int32_t metric, u_char distance, safi_t safi)
 {
@@ -2917,6 +2925,8 @@ rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
 
       if (rib->type != type)
        continue;
+      if (rib->instance != instance)
+       continue;
       if (rib->type != ZEBRA_ROUTE_CONNECT)
        {
          same = rib;
@@ -2935,6 +2945,7 @@ rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
   rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
   
   rib->type = type;
+  rib->instance = instance;
   rib->distance = distance;
   rib->flags = flags;
   rib->metric = metric;
@@ -3029,6 +3040,10 @@ rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi,
        continue;
      }
 
+     if (same->instance != rib->instance) {
+       continue;
+     }
+
      if (same->table != rib->table) {
        continue;
      }
@@ -3072,7 +3087,7 @@ rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi,
 
 /* XXX factor with rib_delete_ipv6 */
 int
-rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
+rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
                 struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
 {
   struct route_table *table;
@@ -3125,6 +3140,8 @@ rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
 
       if (rib->type != type)
         continue;
+      if (rib->instance != instance)
+        continue;
       if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
          nexthop->type == NEXTHOP_TYPE_IFINDEX)
        {
@@ -3265,6 +3282,7 @@ static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
       rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
       
       rib->type = ZEBRA_ROUTE_STATIC;
+      rib->instance = 0;
       rib->distance = si->distance;
       rib->metric = 0;
       rib->table = zebrad.rtm_table_default;
@@ -3616,7 +3634,7 @@ rib_sweep_route (void)
 
 /* Remove specific by protocol routes from 'table'. */
 static unsigned long
-rib_score_proto_table (u_char proto, struct route_table *table)
+rib_score_proto_table (u_char proto, u_short instance, struct route_table *table)
 {
   struct route_node *rn;
   struct rib *rib;
@@ -3629,7 +3647,7 @@ rib_score_proto_table (u_char proto, struct route_table *table)
         {
           if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
             continue;
-          if (rib->type == proto)
+          if (rib->type == proto && rib->instance == instance)
             {
               rib_delnode (rn, rib);
               n++;
@@ -3641,10 +3659,10 @@ rib_score_proto_table (u_char proto, struct route_table *table)
 
 /* Remove specific by protocol routes. */
 unsigned long
-rib_score_proto (u_char proto)
+rib_score_proto (u_char proto, u_short instance)
 {
-  return  rib_score_proto_table (proto, vrf_table (AFI_IP,  SAFI_UNICAST, 0))
-         +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
+  return  rib_score_proto_table (proto, instance, vrf_table (AFI_IP,  SAFI_UNICAST, 0))
+         +rib_score_proto_table (proto, instance, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
 }
 
 /* Close RIB and clean up kernel routes. */
index 6031da87662970ca7e49d2dfd029c3aff380c81d..a44d1961851a7662b354015d74100aa3fd981d67 100644 (file)
@@ -893,7 +893,10 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
       vty_out (vty, "Routing entry for %s/%d%s", 
               inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
               VTY_NEWLINE);
-      vty_out (vty, "  Known via \"%s\"", zebra_route_string (rib->type));
+      vty_out (vty, "  Known via \"%s", zebra_route_string (rib->type));
+      if (rib->instance)
+        vty_out (vty, "[%d]", rib->instance);
+      vty_out (vty, "\"");
       vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
       if (rib->tag)
        vty_out (vty, ", tag %d", rib->tag);
@@ -1022,15 +1025,17 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
       if (nexthop == rib->nexthop)
        {
          /* Prefix information. */
-         len = vty_out (vty, "%c%c%c %s/%d",
-                        zebra_route_char (rib->type),
+         len = vty_out (vty, "%c", zebra_route_char (rib->type));
+          if (rib->instance)
+           len += vty_out (vty, "[%d]", rib->instance);
+          len += vty_out (vty, "%c%c %s/%d",
                         CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
                         ? '>' : ' ',
                         CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
                         ? '*' : ' ',
                         inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
                         rn->p.prefixlen);
-               
+
          /* Distance and metric display. */
          if (rib->type != ZEBRA_ROUTE_CONNECT 
              && rib->type != ZEBRA_ROUTE_KERNEL)
@@ -1348,6 +1353,42 @@ DEFUN (show_ip_route_protocol,
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_route_ospf_instance,
+       show_ip_route_ospf_instance_cmd,
+       "show ip route ospf <1-65535>",
+       SHOW_STR
+       IP_STR
+       "IP routing table\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Instance ID\n")
+{
+  struct route_table *table;
+  struct route_node *rn;
+  struct rib *rib;
+  int first = 1;
+  u_short instance = 0;
+
+  VTY_GET_INTEGER ("Instance", instance, argv[0]);
+
+  table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+  if (! table)
+    return CMD_SUCCESS;
+
+  /* Show matched type IPv4 routes. */
+  for (rn = route_top (table); rn; rn = route_next (rn))
+    RNODE_FOREACH_RIB (rn, rib)
+      if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance)
+       {
+         if (first)
+           {
+             vty_out (vty, SHOW_ROUTE_V4_HEADER);
+             first = 0;
+           }
+         vty_show_ip_route (vty, rn, rib);
+       }
+  return CMD_SUCCESS;
+}
+
 DEFUN (show_ip_route_addr,
        show_ip_route_addr_cmd,
        "show ip route A.B.C.D",
@@ -2899,6 +2940,7 @@ zebra_vty_init (void)
   install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_cmd);
 
   install_element (VIEW_NODE, &show_ip_route_cmd);
+  install_element (VIEW_NODE, &show_ip_route_ospf_instance_cmd);
   install_element (VIEW_NODE, &show_ip_route_tag_cmd);
   install_element (VIEW_NODE, &show_ip_nht_cmd);
   install_element (VIEW_NODE, &show_ipv6_nht_cmd);
@@ -2910,6 +2952,7 @@ zebra_vty_init (void)
   install_element (VIEW_NODE, &show_ip_route_summary_cmd);
   install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
   install_element (ENABLE_NODE, &show_ip_route_cmd);
+  install_element (ENABLE_NODE, &show_ip_route_ospf_instance_cmd);
   install_element (ENABLE_NODE, &show_ip_route_tag_cmd);
   install_element (ENABLE_NODE, &show_ip_nht_cmd);
   install_element (ENABLE_NODE, &show_ipv6_nht_cmd);
index d745a43d5ffacba1d83b6f21c81fc9c4a5c1da93..960514319ffdab70c76e8ea12c09344086111416 100644 (file)
@@ -66,15 +66,6 @@ zserv_delayed_close(struct thread *thread)
   return 0;
 }
 
-/* When client connects, it sends hello message
- * with promise to send zebra routes of specific type.
- * Zebra stores a socket fd of the client into
- * this array. And use it to clean up routes that
- * client didn't remove for some reasons after closing
- * connection.
- */
-static int route_type_oaths[ZEBRA_ROUTE_MAX];
-
 static int
 zserv_flush_data(struct thread *thread)
 {
@@ -552,6 +543,7 @@ zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
   
   /* Put type and nexthop. */
   stream_putc (s, rib->type);
+  stream_putw (s, rib->instance);
   stream_putc (s, rib->flags);
   
   /* marker for message flags field */
@@ -1032,6 +1024,7 @@ zread_ipv4_add (struct zserv *client, u_short length)
   
   /* Type, flags, message. */
   rib->type = stream_getc (s);
+  rib->instance = stream_getw (s);
   rib->flags = stream_getc (s);
   message = stream_getc (s); 
   safi = stream_getw (s);
@@ -1133,6 +1126,7 @@ zread_ipv4_delete (struct zserv *client, u_short length)
 
   /* Type, flags, message. */
   api.type = stream_getc (s);
+  api.instance = stream_getw (s);
   api.flags = stream_getc (s);
   api.message = stream_getc (s);
   api.safi = stream_getw (s);
@@ -1195,7 +1189,7 @@ zread_ipv4_delete (struct zserv *client, u_short length)
   else
     api.tag = 0;
 
-  rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
+  rib_delete_ipv4 (api.type, api.instance, api.flags, &p, nexthop_p, ifindex,
                   client->rtm_table, api.safi);
   client->v4_route_del_cnt++;
   return 0;
@@ -1259,6 +1253,7 @@ zread_ipv6_add (struct zserv *client, u_short length)
 
   /* Type, flags, message. */
   rib->type = stream_getc (s);
+  rib->instance = stream_getw (s);
   rib->flags = stream_getc (s);
   message = stream_getc (s);
   safi = stream_getw (s);
@@ -1375,6 +1370,7 @@ zread_ipv6_delete (struct zserv *client, u_short length)
 
   /* Type, flags, message. */
   api.type = stream_getc (s);
+  api.instance = stream_getw (s);
   api.flags = stream_getc (s);
   api.message = stream_getc (s);
   api.safi = stream_getw (s);
@@ -1426,9 +1422,9 @@ zread_ipv6_delete (struct zserv *client, u_short length)
     api.tag = 0;
 
   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
-    rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
+    rib_delete_ipv6 (api.type, api.instance, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
   else
-    rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
+    rib_delete_ipv6 (api.type, api.instance, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
 
   client->v6_route_del_cnt++;
   return 0;
@@ -1477,7 +1473,10 @@ zread_hello (struct zserv *client)
 {
   /* type of protocol (lib/zebra.h) */
   u_char proto;
+  u_short instance;
+
   proto = stream_getc (client->ibuf);
+  instance = stream_getw (client->ibuf);
 
   /* accept only dynamic routing protocols */
   if ((proto < ZEBRA_ROUTE_MAX)
@@ -1485,36 +1484,14 @@ zread_hello (struct zserv *client)
     {
       zlog_notice ("client %d says hello and bids fair to announce only %s routes",
                     client->sock, zebra_route_string(proto));
+      if (instance)
+        zlog_notice ("client protocol instance %d", instance);
 
-      /* if route-type was binded by other client */
-      if (route_type_oaths[proto])
-        zlog_warn ("sender of %s routes changed %c->%c",
-                    zebra_route_string(proto), route_type_oaths[proto],
-                    client->sock);
-
-      route_type_oaths[proto] = client->sock;
       client->proto = proto;
+      client->instance = instance;
     }
 }
 
-/* If client sent routes of specific type, zebra removes it
- * and returns number of deleted routes.
- */
-static void
-zebra_score_rib (int client_sock)
-{
-  int i;
-
-  for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
-    if (client_sock == route_type_oaths[i])
-      {
-        zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
-                      client_sock, rib_score_proto (i), zebra_route_string (i));
-        route_type_oaths[i] = 0;
-        break;
-      }
-}
-
 /* Close zebra client. */
 static void
 zebra_client_close (struct zserv *client)
@@ -1525,8 +1502,12 @@ zebra_client_close (struct zserv *client)
   /* Close file descriptor. */
   if (client->sock)
     {
+      unsigned long nroutes;
+
       close (client->sock);
-      zebra_score_rib (client->sock);
+      nroutes = rib_score_proto (client->proto, client->instance);
+      zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
+                   client->sock, nroutes, zebra_route_string (client->proto));
       client->sock = -1;
     }
 
@@ -1814,7 +1795,6 @@ zebra_serv ()
       return;
     }
 
-  memset (&route_type_oaths, 0, sizeof (route_type_oaths));
   memset (&addr, 0, sizeof (struct sockaddr_in));
   addr.sin_family = AF_INET;
   addr.sin_port = htons (ZEBRA_PORT);
@@ -1885,8 +1865,6 @@ zebra_serv_un (const char *path)
       return;
     }
 
-  memset (&route_type_oaths, 0, sizeof (route_type_oaths));
-
   /* Make server socket. */
   memset (&serv, 0, sizeof (struct sockaddr_un));
   serv.sun_family = AF_UNIX;
@@ -1984,8 +1962,11 @@ zebra_show_client_detail (struct vty *vty, struct zserv *client)
   char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
   char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF];
 
-  vty_out (vty, "Client: %s %s",
-          zebra_route_string(client->proto), VTY_NEWLINE);
+  vty_out (vty, "Client: %s", zebra_route_string(client->proto));
+  if (client->instance)
+    vty_out (vty, " Instance: %d", client->instance);
+  vty_out (vty, "%s", VTY_NEWLINE);
+
   vty_out (vty, "------------------------ %s", VTY_NEWLINE);
   vty_out (vty, "FD: %d %s", client->sock, VTY_NEWLINE);
   vty_out (vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE);
index 4e42b85864931a256b895a983677d0e5b45144cb..cb181eebe067913846ab6d71ac491e18ed20c0ed 100644 (file)
@@ -26,6 +26,7 @@
 #include "if.h"
 #include "workqueue.h"
 #include "routemap.h"
+#include "zclient.h"
 
 /* Default port information. */
 #define ZEBRA_VTY_PORT                2601
@@ -59,7 +60,7 @@ struct zserv
   int rtm_table;
 
   /* This client's redistribute flag. */
-  u_char redist[ZEBRA_ROUTE_MAX];
+  struct redist_proto redist[ZEBRA_ROUTE_MAX];
 
   /* Redistribute default route flag. */
   u_char redist_default;
@@ -72,6 +73,7 @@ struct zserv
 
   /* client's protocol */
   u_char proto;
+  u_short instance;
 
   /* Statistics */
   u_int32_t redist_v4_add_cnt;