]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Common router id.
authorhasso <hasso>
Sun, 3 Oct 2004 18:18:34 +0000 (18:18 +0000)
committerhasso <hasso>
Sun, 3 Oct 2004 18:18:34 +0000 (18:18 +0000)
26 files changed:
bgpd/ChangeLog
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h
isisd/ChangeLog
isisd/isis_lsp.c
isisd/isis_tlv.h
isisd/isis_zebra.c
lib/ChangeLog
lib/zclient.c
lib/zclient.h
lib/zebra.h
ospf6d/ChangeLog
ospf6d/ospf6_zebra.c
ospfd/ChangeLog
ospfd/ospf_zebra.c
ospfd/ospfd.c
zebra/ChangeLog
zebra/Makefile.am
zebra/main.c
zebra/redistribute.c
zebra/router-id.c [new file with mode: 0644]
zebra/router-id.h [new file with mode: 0644]
zebra/zserv.c
zebra/zserv.h

index 2bcce1c7b0623ca55a0aa63002752175b31ec842..d5ab328262aa4ed518cbf52fc221449833321eed 100644 (file)
@@ -1,3 +1,11 @@
+2004-10-03 James R. Leu <jleu at mindspring.com>
+
+       * bgp_vty.c: Router id from zebra can be manually overriden.
+       * bgp_zebra.c: Read router id related messages from zebra daemon.
+         Remove own code related with router id selection.
+       * bgpd.c, bgpd.h: Remove own router id selection code. Use the one
+         from zebra daemon if it isn't manually overriden.
+
 2004-09-26 Hasso Tepper <hasso at quagga.net>
 
        * bgp_aspath.c, bgp_packet.c, bgp_vty.c: Fix compiler warnings.
index 27a3c2eb53b124ce4da01c762922663b405944c3..6b3c4988d5d51fa12b2a70cc1a1ce26017b7ba51 100644 (file)
@@ -41,6 +41,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "bgpd/bgp_zebra.h"
 #include "bgpd/bgp_table.h"
 
+extern struct in_addr router_id_zebra;
+
 /* Utility function to get address family from current node.  */
 afi_t
 bgp_node_afi (struct vty *vty)
@@ -400,6 +402,7 @@ DEFUN (bgp_router_id,
       return CMD_WARNING;
     }
 
+  bgp->router_id_static = id;
   bgp_router_id_set (bgp, &id);
 
   return CMD_SUCCESS;
@@ -427,14 +430,15 @@ DEFUN (no_bgp_router_id,
          return CMD_WARNING;
        }
 
-      if (! IPV4_ADDR_SAME (&bgp->router_id, &id))
+      if (! IPV4_ADDR_SAME (&bgp->router_id_static, &id))
        {
          vty_out (vty, "%% BGP router-id doesn't match%s", VTY_NEWLINE);
          return CMD_WARNING;
        }
     }
 
-  bgp_router_id_unset (bgp);
+  bgp->router_id_static.s_addr = 0;
+  bgp_router_id_set (bgp, &router_id_zebra);
 
   return CMD_SUCCESS;
 }
index 42b8fc746e4296c34c6d823cc442b73cdd734481..6226a9383fe547fa0f93b56a800be2b77bfe5a45 100644 (file)
@@ -39,61 +39,25 @@ Boston, MA 02111-1307, USA.  */
 \f
 /* All information about zebra. */
 static struct zclient *zclient = NULL;
+struct in_addr router_id_zebra;
 
-/* Update default router id. */
+/* Router-id update message from zebra. */
 int
-bgp_if_update (struct interface *ifp)
+bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
 {
-  struct bgp *bgp;
-  struct listnode *cn;
+  struct prefix router_id;
   struct listnode *nn;
-  struct listnode *nm;
-  struct peer *peer;
-
-  for (cn = listhead (ifp->connected); cn; nextnode (cn))
-    {
-      struct connected *co;
-      struct in_addr addr;
-
-      co = getdata (cn);
-
-      if (co->address->family == AF_INET)
-       {
-         addr = co->address->u.prefix4;
-
-         /* Ignore NET127. */
-         if (IPV4_NET127 (ntohl (addr.s_addr)))
-           continue;
-
-         LIST_LOOP (bm->bgp, bgp, nn)
-           {
-             /* Respect configured router id */
-             if (! (bgp->config & BGP_CONFIG_ROUTER_ID))
-               if (ntohl (bgp->router_id.s_addr) < ntohl (addr.s_addr))
-                 {
-                   bgp->router_id = addr;
-                   LIST_LOOP (bgp->peer, peer, nm)
-                     {
-                       peer->local_id = addr;
-                     }
-                 }
-           }
-       }
-    }
-  return 0;
-}
+  struct bgp *bgp;
 
-int
-bgp_if_update_all ()
-{
-  struct listnode *node;
-  struct interface *ifp;
+  zebra_router_id_update_read(zclient->ibuf,&router_id);
+  router_id_zebra = router_id.u.prefix4;
 
-  for (node = listhead (iflist); node; node = nextnode (node))
+  LIST_LOOP (bm->bgp, bgp, nn)
     {
-      ifp = getdata (node);
-      bgp_if_update (ifp);
+      if (!bgp->router_id_static.s_addr)
+      bgp_router_id_set (bgp, &router_id.u.prefix4);
     }
+
   return 0;
 }
 
@@ -104,7 +68,6 @@ bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
   struct interface *ifp;
 
   ifp = zebra_interface_add_read (zclient->ibuf);
-  bgp_if_update (ifp);
 
   return 0;
 }
@@ -206,8 +169,6 @@ bgp_interface_address_add (int command, struct zclient *zclient,
   if (ifc == NULL)
     return 0;
 
-  bgp_if_update (ifc->ifp);
-
   if (if_is_operative (ifc->ifp))
     bgp_connected_add (ifc);
 
@@ -225,8 +186,6 @@ bgp_interface_address_delete (int command, struct zclient *zclient,
   if (ifc == NULL)
     return 0;
 
-  bgp_if_update (ifc->ifp);
-
   if (if_is_operative (ifc->ifp))
     bgp_connected_delete (ifc);
 
@@ -987,6 +946,7 @@ bgp_zebra_init (int enable)
   /* Set default values. */
   zclient = zclient_new ();
   zclient_init (zclient, ZEBRA_ROUTE_BGP);
+  zclient->router_id_update = bgp_router_id_update;
   zclient->interface_add = bgp_interface_add;
   zclient->interface_delete = bgp_interface_delete;
   zclient->interface_address_add = bgp_interface_address_add;
index 6afbe9593e4fd965aba6a38cfcf4df294778506e..61ffe2799db44886560f686fa99e6d33141527ca 100644 (file)
@@ -63,6 +63,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 /* BGP process wide configuration.  */
 static struct bgp_master bgp_master;
 
+extern struct in_addr router_id_zebra;
+
 /* BGP process wide configuration pointer to export.  */
 struct bgp_master *bm;
 
@@ -182,42 +184,6 @@ bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
   return 0;
 }
 
-/* Unset BGP router identifier. */
-int
-bgp_router_id_unset (struct bgp *bgp)
-{
-  struct peer *peer;
-  struct listnode *nn;
-
-  if (! bgp_config_check (bgp, BGP_CONFIG_ROUTER_ID))
-    return 0;
-
-  bgp->router_id.s_addr = 0;
-  bgp_config_unset (bgp, BGP_CONFIG_ROUTER_ID);
-
-  /* Clear peer router id configuration.  */
-  LIST_LOOP (bgp->peer, peer, nn)
-    {
-      peer->local_id.s_addr = 0;
-    }
-
-  /* Set router-id from interface's address. */
-  bgp_if_update_all ();
-
-  /* Reset all BGP sessions to use new router-id.  */
-  LIST_LOOP (bgp->peer, peer, nn)
-    {
-      if (peer->status == Established)
-       {
-         peer->last_reset = PEER_DOWN_RID_CHANGE;
-         bgp_notify_send (peer, BGP_NOTIFY_CEASE,
-                          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
-       }
-    }
-
-  return 0;
-}
-\f
 /* BGP's cluster-id control. */
 int
 bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
@@ -1910,7 +1876,7 @@ bgp_get (struct bgp **bgp_val, as_t *as, char *name)
 
   bgp = bgp_create (as, name);
   listnode_add (bm->bgp, bgp);
-  bgp_if_update_all ();
+  bgp_router_id_set(bgp, &router_id_zebra);
   *bgp_val = bgp;
 
   return 0;
index 61472d850cde8d2861d369fc235e6f32392d556d..ed3f4d18394e2c794c7154fa3bc9cbdc40c3c729 100644 (file)
@@ -76,6 +76,7 @@ struct bgp
 
   /* BGP router identifier.  */
   struct in_addr router_id;
+  struct in_addr router_id_static;
 
   /* BGP route reflector cluster ID.  */
   struct in_addr cluster_id;
index b95bdbf99dbfd743da9da78c0cba31455d4d4a2d..c280bf26be22743a35b832c7c29798b7c0857676 100644 (file)
@@ -1,3 +1,10 @@
+2004-10-03 Hasso Tepper <hasso at quagga.net>
+
+       * isis_zebra.c: Read router id related messages from zebra daemon.
+       * isis_lsp.c: Use router id in IP address TLV in LSP's. It's how Junos
+         routers behave as well.
+       * isis_tlv.h: Export add_tlv() function.
+
 2004-09-27 Hasso Tepper <hasso at quagga.net>
 
        * isis_pdu.c: Fix accessing NULL found by valgrind.
index 2f1854374cee36c6132c8a7bc09ff2230b42e601..567afa3b514a490a836983bd8fbfee3f201262d3 100644 (file)
@@ -59,6 +59,7 @@
 
 extern struct isis *isis;
 extern struct thread_master *master;
+extern struct in_addr router_id_zebra;
 
 /* staticly assigned vars for printing purposes */
 char lsp_bits_string[200];     /* FIXME: enough ? */
@@ -1380,6 +1381,7 @@ lsp_build_nonpseudo (struct isis_lsp *lsp, struct isis_area *area)
   struct tlvs tlv_data;
   struct isis_lsp *lsp0 = lsp;
   struct isis_passwd *passwd;
+  struct in_addr *routerid;
 
   /*
    * First add the tlvs related to area
@@ -1445,6 +1447,30 @@ lsp_build_nonpseudo (struct isis_lsp *lsp, struct isis_area *area)
     tlv_add_area_addrs (lsp->tlv_data.area_addrs, lsp->pdu);
 
   memset (&tlv_data, 0, sizeof (struct tlvs));
+  /*
+   * IPv4 address TLV. We don't follow "C" vendor, but "J" vendor behavior -
+   * one IPv4 address is put into LSP and this address is same as router id.
+   */
+  if (router_id_zebra.s_addr != 0)
+    {
+      u_char value[4];
+
+      if (lsp->tlv_data.ipv4_addrs == NULL)
+       lsp->tlv_data.ipv4_addrs = list_new ();
+
+      routerid = XMALLOC (MTYPE_ISIS_TLV, sizeof (struct in_addr));
+      routerid->s_addr = router_id_zebra.s_addr;
+
+      listnode_add (lsp->tlv_data.ipv4_addrs, routerid);
+
+      /* 
+       * FIXME: Using add_tlv() directly is hack, but tlv_add_ip_addrs()
+       * expects list of prefix_ipv4 structures, but we have list of
+       * in_addr structures.
+       */
+      add_tlv (IPV4_ADDR, IPV4_MAX_BYTELEN, (u_char *) &routerid->s_addr,
+              lsp->pdu);
+    }
   /*
    * Then build lists of tlvs related to circuits
    */
index 72f883dbbeb5f7b8e830996a0180c1507ff907be..b82be5b12ef4e8b9042612a4a410128ccbf5c04c 100644 (file)
@@ -260,6 +260,7 @@ int parse_tlvs (char *areatag, u_char * stream, int size,
                u_int32_t * expected, u_int32_t * found, struct tlvs *tlvs);
 void free_tlv (void *val);
 
+int add_tlv (u_char, u_char, u_char *, struct stream *);
 int tlv_add_area_addrs (struct list *area_addrs, struct stream *stream);
 int tlv_add_is_neighs (struct list *is_neighs, struct stream *stream);
 int tlv_add_lan_neighs (struct list *lan_neighs, struct stream *stream);
index 8e122082a5351c8c70277eedc9399205589e3d8c..f56c5d49c923002ef07fd49431516d29b983fe2a 100644 (file)
 struct zclient *zclient = NULL;
 
 extern struct thread_master *master;
+struct in_addr router_id_zebra;
+
+/* Router-id update message from zebra. */
+int
+isis_router_id_update_zebra (int command, struct zclient *zclient,
+                            zebra_size_t length)
+{
+  struct prefix router_id;
+  char buf[BUFSIZ];
+
+  zebra_router_id_update_read (zclient->ibuf,&router_id);
+  router_id_zebra = router_id.u.prefix4;
+
+  /* FIXME: Do we react somehow? */
+  return 0;
+}
 
 int
 isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
@@ -106,19 +122,6 @@ zebra_interface_if_lookup (struct stream *s)
   return ifp;
 }
 
-void
-zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
-{
-  /* Read interface's index. */
-  ifp->ifindex = stream_getl (s);
-
-  /* Read interface's value. */
-  ifp->flags = stream_getl (s);
-  ifp->metric = stream_getl (s);
-  ifp->mtu = stream_getl (s);
-  ifp->bandwidth = stream_getl (s);
-}
-
 int
 isis_zebra_if_state_up (int command, struct zclient *zclient,
                        zebra_size_t length)
@@ -591,6 +594,7 @@ isis_zebra_init ()
 {
   zclient = zclient_new ();
   zclient_init (zclient, ZEBRA_ROUTE_ISIS);
+  zclient->router_id_update = isis_router_id_update_zebra;
   zclient->interface_add = isis_zebra_if_add;
   zclient->interface_delete = isis_zebra_if_del;
   zclient->interface_up = isis_zebra_if_state_up;
index 05ad4db57fab8c6ac04112852f62875571e12b53..e92147f30d133cab77e897b31e33b86e94c1ddbb 100644 (file)
@@ -1,3 +1,8 @@
+2004-10-03 James R. Leu <jleu at mindspring.com>
+
+       * zclient.c, zclient.h: zclient functions for router id handling.
+       * zebra.h: New message types for router id handling.
+
 2004-09-27 Paul Jakma <paul@dishone.st>
 
        * zebra.h: Add WANT_OSPF_WRITE_FRAGMENT for ospfd
index 3b68338753e61ac68c658a4699f61654271473f4..5df420f21ff508df0670b99e936a67280987d6fc 100644 (file)
@@ -260,6 +260,9 @@ zclient_start (struct zclient *zclient)
   /* We need interface information. */
   zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
 
+  /* We need router-id information. */
+  zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
+
   /* Flush all redistribute request. */
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
     if (i != zclient->redist_default && zclient->redist[i])
@@ -477,6 +480,20 @@ zebra_redistribute_send (int command, int sock, int type)
   return ret;
 }
 
+/* Router-id update from zebra daemon. */
+void
+zebra_router_id_update_read (struct stream *s, struct prefix *rid)
+{
+  int plen;
+
+  /* Fetch interface address. */
+  rid->family = stream_getc (s);
+
+  plen = prefix_blen (rid);
+  stream_get (&rid->u.prefix, s, plen);
+  rid->prefixlen = stream_getc (s);
+}
+
 /* Interface addition from zebra daemon. */
 /*  
  * The format of the message sent with type ZEBRA_INTERFACE_ADD or
@@ -614,6 +631,19 @@ zebra_interface_state_read (struct stream *s)
  *
  */
 
+void
+zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
+{
+  /* Read interface's index. */
+  ifp->ifindex = stream_getl (s);
+
+  /* Read interface's value. */
+  ifp->flags = stream_getl (s);
+  ifp->metric = stream_getl (s);
+  ifp->mtu = stream_getl (s);
+  ifp->bandwidth = stream_getl (s);
+}
+
 struct connected *
 zebra_interface_address_read (int type, struct stream *s)
 {
@@ -745,6 +775,10 @@ zclient_read (struct thread *thread)
 
   switch (command)
     {
+    case ZEBRA_ROUTER_ID_UPDATE:
+      if (zclient->router_id_update)
+       ret = (*zclient->router_id_update) (command, zclient, length);
+      break;
     case ZEBRA_INTERFACE_ADD:
       if (zclient->interface_add)
        ret = (*zclient->interface_add) (command, zclient, length);
index da8d016db6f0c09865a9b0d01578ba694c306d6e..03a6e0a75f62175478f28879acc5965b3fbb4cec 100644 (file)
@@ -62,6 +62,7 @@ struct zclient
   u_char default_information;
 
   /* Pointer to the callback functions. */
+  int (*router_id_update) (int, struct zclient *, zebra_size_t);
   int (*interface_add) (int, struct zclient *, zebra_size_t);
   int (*interface_delete) (int, struct zclient *, zebra_size_t);
   int (*interface_up) (int, struct zclient *, zebra_size_t);
@@ -119,6 +120,8 @@ int zebra_redistribute_send (int, int, int);
 struct interface *zebra_interface_add_read (struct stream *);
 struct interface *zebra_interface_state_read (struct stream *s);
 struct connected *zebra_interface_address_read (int, struct stream *);
+void zebra_interface_if_set_value (struct stream *, struct interface *);
+void zebra_router_id_update_read (struct stream *s, struct prefix *rid);
 int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *, 
                      struct zapi_ipv4 *);
 
index e53a40c52d2cff41976281863610cd060848b6a7..0b8b654cc13d0cbbb2acffa809eddc6a1e62584d 100644 (file)
@@ -314,7 +314,10 @@ struct in_pktinfo
 #define ZEBRA_IPV4_IMPORT_LOOKUP          17
 #define ZEBRA_IPV6_IMPORT_LOOKUP          18
 #define ZEBRA_INTERFACE_RENAME            19
-#define ZEBRA_MESSAGE_MAX                 20
+#define ZEBRA_ROUTER_ID_ADD               20
+#define ZEBRA_ROUTER_ID_DELETE            21
+#define ZEBRA_ROUTER_ID_UPDATE            22
+#define ZEBRA_MESSAGE_MAX                 23
 
 /* Zebra route's types. */
 #define ZEBRA_ROUTE_SYSTEM               0
index a37c4ac127764c3b06a5d06393067598d3be2870..7778c58aad287f46f7bf40ca088b2c73a887069b 100644 (file)
@@ -1,3 +1,8 @@
+2004-10-03 Hasso Tepper <hasso at quagga.net>
+
+       * ospf6_zebra.c: Use router id from zebra daemon if it wasn't set in
+       configuration.
+
 2004-09-25  Hasso Tepper  <hasso at estpak.ee>
 
        * ospf6_asbr.c, ospf6_lsa.c, ospf6_proto.c, ospf6_proto.h: Fix
index dd89d8db2a30ddd619d84b70450a627e592fda85..0baaaea9d670ac51ad55105b547be2b6b6de2330 100644 (file)
@@ -44,6 +44,25 @@ unsigned char conf_debug_ospf6_zebra = 0;
 /* information about zebra. */
 struct zclient *zclient = NULL;
 
+struct in_addr router_id_zebra;
+
+/* Router-id update message from zebra. */
+int
+ospf6_router_id_update_zebra (int command, struct zclient *zclient,
+                             zebra_size_t length)
+{
+  struct prefix router_id;
+  struct ospf6 *o = ospf6;
+
+  zebra_router_id_update_read(zclient->ibuf,&router_id);
+  router_id_zebra = router_id.u.prefix4;
+
+  if (o->router_id  == 0)
+    o->router_id = (u_int32_t) router_id_zebra.s_addr;
+
+  return 0;
+}
+
 /* redistribute function */
 void
 ospf6_zebra_redistribute (int type)
@@ -535,6 +554,7 @@ ospf6_zebra_init ()
   /* Allocate zebra structure. */
   zclient = zclient_new ();
   zclient_init (zclient, ZEBRA_ROUTE_OSPF6);
+  zclient->router_id_update = ospf6_router_id_update_zebra;
   zclient->interface_add = ospf6_zebra_if_add;
   zclient->interface_delete = ospf6_zebra_if_del;
   zclient->interface_up = ospf6_zebra_if_state_update;
index 6e1a86464de0aa1560040aa4e2e7c4cc803ec3b5..2043ad6148f8a9783a2588095d09e310348a4d2b 100644 (file)
@@ -1,3 +1,10 @@
+2004-10-03 James R. Leu <jleu at mindspring.com>
+
+       * ospf_zebra.c: Read router id related messages from zebra daemon.
+         Schedule router-id update thread if it's changed.
+       * ospfd.c: Remove own router-id selection function. Use router id from
+         zebra daemon if it isn't manually overriden in configuration.
+
 2004-09-27 Paul Jakma <paul@dishone.st>
 
        * ospf_dump.c: (ospf_ip_header_dump) Use HAVE_IP_HDRINCL_BSD_ORDER
index 6a675a599f49fe2ee9384bac862b6d07a807557c..3172ebc5e5bfc81b9e601be7eaa2366c8786577d 100644 (file)
@@ -54,6 +54,28 @@ struct zclient *zclient = NULL;
 
 /* For registering threads. */
 extern struct thread_master *master;
+struct in_addr router_id_zebra;
+
+/* Router-id update message from zebra. */
+int
+ospf_router_id_update_zebra (int command, struct zclient *zclient,
+                            zebra_size_t length)
+{
+  struct ospf *ospf;
+  struct prefix router_id;
+  zebra_router_id_update_read(zclient->ibuf,&router_id);
+
+  router_id_zebra = router_id.u.prefix4;
+
+  ospf = ospf_lookup ();
+  if (ospf != NULL)
+    {
+      if (ospf->t_router_id_update == NULL)
+       OSPF_TIMER_ON (ospf->t_router_id_update, ospf_router_id_update_timer,
+                       OSPF_ROUTER_ID_UPDATE_DELAY);
+    }
+  return 0;
+}
 
 /* Inteface addition message from zebra. */
 int
@@ -148,20 +170,6 @@ zebra_interface_if_lookup (struct stream *s)
   return ifp;
 }
 
-void
-zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
-{
-  /* Read interface's index. */
-  ifp->ifindex = stream_getl (s);
-
-  /* Read interface's value. */
-  ifp->status = stream_getc (s);
-  ifp->flags = stream_getl (s);
-  ifp->metric = stream_getl (s);
-  ifp->mtu = stream_getl (s);
-  ifp->bandwidth = stream_getl (s);
-}
-
 int
 ospf_interface_state_up (int command, struct zclient *zclient,
                          zebra_size_t length)
@@ -1248,6 +1256,7 @@ ospf_zebra_init ()
   /* Allocate zebra structure. */
   zclient = zclient_new ();
   zclient_init (zclient, ZEBRA_ROUTE_OSPF);
+  zclient->router_id_update = ospf_router_id_update_zebra;
   zclient->interface_add = ospf_interface_add;
   zclient->interface_delete = ospf_interface_delete;
   zclient->interface_up = ospf_interface_state_up;
index bfde503d593e7b7dabe4a50c9bc89fa3e7648d5d..6c6dd8ded865a03729581e7dfa40a96e752e2b0a 100644 (file)
@@ -61,6 +61,7 @@ static struct ospf_master ospf_master;
 struct ospf_master *om;
 
 extern struct zclient *zclient;
+extern struct in_addr router_id_zebra;
 
 \f
 void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
@@ -68,33 +69,6 @@ void ospf_network_free (struct ospf *, struct ospf_network *);
 void ospf_area_free (struct ospf_area *);
 void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
 
-/* Get Router ID from ospf interface list. */
-struct in_addr
-ospf_router_id_get (struct list *if_list)
-{
-  struct listnode *node;
-  struct in_addr router_id;
-
-  memset (&router_id, 0, sizeof (struct in_addr));
-
-  for (node = listhead (if_list); node; nextnode (node))
-    {
-      struct ospf_interface *oi = getdata (node);
-
-      if (!if_is_up (oi->ifp) ||
-         OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
-       continue;
-      
-      /* Ignore virtual link interface. */
-      if (oi->type != OSPF_IFTYPE_VIRTUALLINK &&
-         oi->type != OSPF_IFTYPE_LOOPBACK) 
-       if (IPV4_ADDR_CMP (&router_id, &oi->address->u.prefix4) < 0)
-         router_id = oi->address->u.prefix4;
-    }
-
-  return router_id;
-}
-
 #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
 
 void
@@ -111,7 +85,7 @@ ospf_router_id_update (struct ospf *ospf)
   if (ospf->router_id_static.s_addr != 0)
     router_id = ospf->router_id_static;
   else
-    router_id = ospf_router_id_get (ospf->oiflist);
+    router_id = router_id_zebra;
 
   ospf->router_id = router_id;
   
index a62fb6cc6af73dedd9fe749475f6cc0c10caab12..19d54312bf544ca97dad9e364daf78184970a7aa 100644 (file)
@@ -1,3 +1,15 @@
+2004-10-03 James R. Leu <jleu at mindspring.com>
+
+       * router-id.c, router-id.h: New files. Router id selection process. If
+         there is non 127.x.x.x address in loopack interface, lowest of them
+         is chosen. If there isn't, lowest from other interfaces addresses
+         are chosen. "router-id x.x.x.x" vty command to manual override.
+       * Makefile.am: Compile new files.
+       * main.c: Initialize router id.
+       * redistribute.c: Add interface addresses into router id selection
+         lists as they (dis)appear.
+       * zserv.c, zserv.h: Sending router id related messages to daemons.
+
 2004-09-26 Hasso Tepper <hasso at quagga.net>
 
        * irdp_interface.c, irdp_main.c, irdp_packet.c, rt_netlink.c,
index 87a994f13affed1e7a8b134fa9dd264b97b2e4cc..f8a0f523d17065a371276fce24cb7a34b505ab80 100644 (file)
@@ -24,11 +24,11 @@ sbin_PROGRAMS = zebra
 zebra_SOURCES = \
        zserv.c main.c interface.c connected.c zebra_rib.c \
        redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \
-       irdp_main.c irdp_interface.c irdp_packet.c
+       irdp_main.c irdp_interface.c irdp_packet.c router-id.c
 
 noinst_HEADERS = \
        connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \
-       interface.h ipforward.h irdp.h
+       interface.h ipforward.h irdp.h router-id.h
 
 zebra_LDADD = $(otherobj) $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la
 
index 0c1a7ddb4c378a336f5b6ec2e0dd7c1c6c476c27..e10755b93d98c4a66d9a662a12d495988bbbe1c9 100644 (file)
@@ -35,7 +35,7 @@
 #include "zebra/rib.h"
 #include "zebra/zserv.h"
 #include "zebra/debug.h"
-#include "zebra/rib.h"
+#include "zebra/router-id.h"
 #include "zebra/irdp.h"
 
 /* Zebra instance */
@@ -314,6 +314,7 @@ main (int argc, char **argv)
   rib_init ();
   zebra_if_init ();
   zebra_debug_init ();
+  router_id_init();
   zebra_vty_init ();
   access_list_init ();
   rtadv_init ();
index 6dd3bd2ab7620d3fef413bae654b151016c2348a..100a824ee9b3a86c3be18e7662b68e33306f37bb 100644 (file)
@@ -35,6 +35,7 @@
 #include "zebra/zserv.h"
 #include "zebra/redistribute.h"
 #include "zebra/debug.h"
+#include "zebra/router-id.h"
 
 /* master zebra server structure */
 extern struct zebra_t zebrad;
@@ -387,6 +388,8 @@ zebra_interface_address_add_update (struct interface *ifp,
                 p->prefixlen, ifc->ifp->name);
     }
 
+  router_id_add_address(ifc);
+
   for (node = listhead (zebrad.client_list); node; nextnode (node))
     if ((client = getdata (node)) != NULL)
       if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
@@ -411,6 +414,8 @@ zebra_interface_address_delete_update (struct interface *ifp,
                 p->prefixlen, ifc->ifp->name);
     }
 
+  router_id_del_address(ifc);
+
   for (node = listhead (zebrad.client_list); node; nextnode (node))
     if ((client = getdata (node)) != NULL)
       if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
diff --git a/zebra/router-id.c b/zebra/router-id.c
new file mode 100644 (file)
index 0000000..3052e56
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Router ID for zebra daemon.
+ *
+ * Copyright (C) 2004 James R. Leu 
+ *
+ * This file is part of Quagga routing suite.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "if.h"
+#include "vty.h"
+#include "sockunion.h"
+#include "prefix.h"
+#include "stream.h"
+#include "command.h"
+#include "memory.h"
+#include "ioctl.h"
+#include "connected.h"
+#include "network.h"
+#include "log.h"
+#include "table.h"
+#include "rib.h"
+
+#include "zebra/zserv.h"
+
+static struct list rid_all_sorted_list;
+static struct list rid_lo_sorted_list;
+static struct prefix rid_user_assigned;
+
+/* master zebra server structure */
+extern struct zebra_t zebrad;
+
+static struct connected *
+router_id_find_node (struct list *l, struct connected *ifc)
+{
+  struct listnode *node;
+  struct connected *c;
+
+  for (node = l->head; node; node = node->next)
+    {
+      c = (struct connected *) getdata (node);
+      if (prefix_same (ifc->address, c->address))
+       return c;
+    }
+  return NULL;
+}
+
+static int
+router_id_bad_address (struct connected *ifc)
+{
+  struct prefix n;
+
+  if (ifc->address->family != AF_INET)
+    return 1;
+
+  n.u.prefix4.s_addr = htonl (INADDR_LOOPBACK);
+  n.prefixlen = 8;
+  n.family = AF_INET;
+
+  if (prefix_match (&n, ifc->address))
+    return 1;
+
+  return 0;
+}
+
+void
+router_id_get (struct prefix *p)
+{
+  struct listnode *node;
+  struct connected *c;
+
+  p->u.prefix4.s_addr = 0;
+  p->family = AF_INET;
+  p->prefixlen = 32;
+
+  if (rid_user_assigned.u.prefix4.s_addr)
+    p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr;
+  else if (!list_isempty (&rid_lo_sorted_list))
+    {
+      node = listtail (&rid_lo_sorted_list);
+      c = getdata (node);
+      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
+    }
+  else if (!list_isempty (&rid_all_sorted_list))
+    {
+      node = listtail (&rid_all_sorted_list);
+      c = getdata (node);
+      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
+    }
+}
+
+static void
+router_id_set (struct prefix *p)
+{
+  struct prefix p2;
+  struct listnode *node;
+  struct zserv *client;
+
+  rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
+
+  router_id_get (&p2);
+  for (node = listhead (zebrad.client_list); node; nextnode (node))
+    if ((client = getdata (node)) != NULL)
+      zsend_router_id_update (client, &p2);
+}
+
+void
+router_id_add_address (struct connected *ifc)
+{
+  struct list *l = NULL;
+  struct listnode *node;
+  struct prefix before;
+  struct prefix after;
+  struct zserv *client;
+
+  if (router_id_bad_address (ifc))
+    return;
+
+  router_id_get (&before);
+
+  if (!strncmp (ifc->ifp->name, "lo", 2)
+      || !strncmp (ifc->ifp->name, "dummy", 5))
+    l = &rid_lo_sorted_list;
+  else
+    l = &rid_all_sorted_list;
+  
+  if (!router_id_find_node (l, ifc))
+    listnode_add (l, ifc);
+
+  router_id_get (&after);
+
+  if (prefix_same (&before, &after))
+    return;
+
+  for (node = listhead (zebrad.client_list); node; nextnode (node))
+    if ((client = getdata (node)) != NULL)
+      zsend_router_id_update (client, &after);
+}
+
+void
+router_id_del_address (struct connected *ifc)
+{
+  struct connected *c;
+  struct list *l;
+  struct prefix after;
+  struct prefix before;
+  struct listnode *node;
+  struct zserv *client;
+
+  if (router_id_bad_address (ifc))
+    return;
+
+  router_id_get (&before);
+
+  if (!strncmp (ifc->ifp->name, "lo", 2)
+      || !strncmp (ifc->ifp->name, "dummy", 5))
+    l = &rid_lo_sorted_list;
+  else
+    l = &rid_all_sorted_list;
+
+  if ((c = router_id_find_node (l, ifc)))
+    listnode_delete (l, c);
+
+  router_id_get (&after);
+
+  if (prefix_same (&before, &after))
+    return;
+
+  for (node = listhead (zebrad.client_list); node; nextnode (node))
+    if ((client = getdata (node)) != NULL)
+      zsend_router_id_update (client, &after);
+}
+
+void
+router_id_write (struct vty *vty)
+{
+  if (rid_user_assigned.u.prefix4.s_addr)
+    vty_out (vty, "router-id %s%s", inet_ntoa (rid_user_assigned.u.prefix4),
+            VTY_NEWLINE);
+}
+
+DEFUN (router_id,
+       router_id_cmd,
+       "router-id A.B.C.D",
+       "Manually set the router-id\n"
+       "IP address to use for router-id\n")
+{
+  struct prefix rid;
+
+  rid.u.prefix4.s_addr = inet_addr (argv[0]);
+  if (!rid.u.prefix4.s_addr)
+    return CMD_WARNING;
+
+  rid.prefixlen = 32;
+  rid.family = AF_INET;
+
+  router_id_set (&rid);
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_router_id,
+       no_router_id_cmd,
+       "no router-id",
+       NO_STR
+       "Remove the manually configured router-id\n")
+{
+  struct prefix rid;
+
+  rid.u.prefix4.s_addr = 0;
+  rid.prefixlen = 0;
+  rid.family = AF_INET;
+
+  router_id_set (&rid);
+
+  return CMD_SUCCESS;
+}
+
+int
+router_id_cmp (void *a, void *b)
+{
+  unsigned int A, B;
+
+  A = ((struct connected *) a)->address->u.prefix4.s_addr;
+  B = ((struct connected *) b)->address->u.prefix4.s_addr;
+
+  if (A > B)
+    return 1;
+  else if (A < B)
+    return -1;
+  return 0;
+}
+
+void
+router_id_init (void)
+{
+  install_element (CONFIG_NODE, &router_id_cmd);
+  install_element (CONFIG_NODE, &no_router_id_cmd);
+
+  memset (&rid_all_sorted_list, 0, sizeof (rid_all_sorted_list));
+  memset (&rid_lo_sorted_list, 0, sizeof (rid_lo_sorted_list));
+  memset (&rid_user_assigned, 0, sizeof (rid_user_assigned));
+
+  rid_all_sorted_list.cmp = router_id_cmp;
+  rid_lo_sorted_list.cmp = router_id_cmp;
+
+  rid_user_assigned.family = AF_INET;
+  rid_user_assigned.prefixlen = 32;
+}
diff --git a/zebra/router-id.h b/zebra/router-id.h
new file mode 100644 (file)
index 0000000..7f7a8c3
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Router ID for zebra daemon.
+ *
+ * Copyright (C) 2004 James R. Leu
+ *
+ * This file is part of Quagga routing suite.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _ROUTER_ID_H_
+#define _ROUTER_ID_H_
+
+#include <zebra.h>
+
+#include "memory.h"
+#include "prefix.h"
+#include "zclient.h"
+#include "if.h"
+
+extern void router_id_add_address(struct connected *);
+extern void router_id_del_address(struct connected *);
+extern void router_id_init(void);
+extern void router_id_write(struct vty *);
+extern void router_id_get(struct prefix *);
+
+extern void zread_router_id_add(struct zserv *, u_short);
+extern void zread_router_id_delete(struct zserv *, u_short);
+
+#endif
index f57fe5c43240fba9adce18e708651ea9e786c96d..537b5429a263435e5721f3c13e8d0997d3e0b45d 100644 (file)
@@ -36,6 +36,7 @@
 #include "privs.h"
 
 #include "zebra/zserv.h"
+#include "zebra/router-id.h"
 #include "zebra/redistribute.h"
 #include "zebra/debug.h"
 #include "zebra/ipforward.h"
@@ -70,7 +71,10 @@ static char *zebra_command_str [] =
   "ZEBRA_IPV4_NEXTHOP_LOOKUP",
   "ZEBRA_IPV6_NEXTHOP_LOOKUP",
   "ZEBRA_IPV4_IMPORT_LOOKUP",
-  "ZEBRA_IPV6_IMPORT_LOOKUP"
+  "ZEBRA_IPV6_IMPORT_LOOKUP",
+  "ZEBRA_ROUTER_ID_ADD",
+  "ZEBRA_ROUTER_ID_DELETE",
+  "ZEBRA_ROUTER_ID_UPDATE"
 };
 \f
 struct zebra_message_queue
@@ -721,6 +725,38 @@ zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
   return 0;
 }
 \f
+/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
+int
+zsend_router_id_update (struct zserv *client, struct prefix *p)
+{
+  struct stream *s;
+  int blen;
+
+  /* Check this client need interface information. */
+  if (!client->ridinfo)
+    return -1;
+
+  s = client->obuf;
+  stream_reset (s);
+
+  /* Place holder for size. */
+  stream_putw (s, 0);
+
+  /* Message type. */
+  stream_putc (s, ZEBRA_ROUTER_ID_UPDATE);
+
+  /* Prefix information. */
+  stream_putc (s, p->family);
+  blen = prefix_blen (p);
+  stream_put (s, &p->u.prefix, blen);
+  stream_putc (s, p->prefixlen);
+
+  /* Write packet size. */
+  stream_putw_at (s, 0, stream_get_endp (s));
+
+  return writen (client->sock, s->data, stream_get_endp (s));
+}
+\f
 /* Register zebra server interface information.  Send current all
    interface and address information. */
 static void
@@ -1122,6 +1158,27 @@ zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
 }
 #endif /* HAVE_IPV6 */
 
+/* Register zebra server router-id information.  Send current router-id */
+void
+zread_router_id_add (struct zserv *client, u_short length)
+{
+  struct prefix p;
+
+  /* Router-id information is needed. */
+  client->ridinfo = 1;
+
+  router_id_get (&p);
+
+  zsend_router_id_update (client,&p);
+}
+
+/* Unregister zebra server router-id information. */
+void
+zread_router_id_delete (struct zserv *client, u_short length)
+{
+  client->ridinfo = 0;
+}
+
 /* Close zebra client. */
 static void
 zebra_client_close (struct zserv *client)
@@ -1233,6 +1290,12 @@ zebra_client_read (struct thread *thread)
 
   switch (command) 
     {
+    case ZEBRA_ROUTER_ID_ADD:
+      zread_router_id_add (client, length);
+      break;
+    case ZEBRA_ROUTER_ID_DELETE:
+      zread_router_id_delete (client, length);
+      break;
     case ZEBRA_INTERFACE_ADD:
       zread_interface_add (client, length);
       break;
@@ -1676,6 +1739,9 @@ DEFUN (no_ipv6_forwarding,
 int
 config_write_forwarding (struct vty *vty)
 {
+  /* FIXME: Find better place for that. */
+  router_id_write (vty);
+
   if (ipforward ())
     vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
 #ifdef HAVE_IPV6
index ac5da1b22a093a97e0c4e9361424e45d91a6de4b..620e24dda7cec364a02e88d39c7f22db5dac6012 100644 (file)
@@ -56,6 +56,9 @@ struct zserv
 
   /* Interface information. */
   u_char ifinfo;
+
+  /* Router-id information. */
+  u_char ridinfo;
 };
 
 /* Zebra instance */
@@ -92,6 +95,7 @@ int zsend_interface_address (int, struct zserv *, struct interface *,
                              struct connected *);
 int zsend_interface_update (int, struct zserv *, struct interface *);
 int zsend_route_multipath (int, struct zserv *, struct prefix *, struct rib *);
+int zsend_router_id_update(struct zserv *, struct prefix *);
 
 extern pid_t pid;
 extern pid_t old_pid;