Common router id.
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index 2bcce1c..d5ab328 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -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.
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 27a3c2e..6b3c498 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -41,6 +41,8 @@
#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 @@
return CMD_WARNING;
}
+ bgp->router_id_static = id;
bgp_router_id_set (bgp, &id);
return CMD_SUCCESS;
@@ -427,14 +430,15 @@
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;
}
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 42b8fc7..6226a93 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -39,61 +39,25 @@
/* 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;
+ struct bgp *bgp;
- for (cn = listhead (ifp->connected); cn; nextnode (cn))
+ zebra_router_id_update_read(zclient->ibuf,&router_id);
+ router_id_zebra = router_id.u.prefix4;
+
+ LIST_LOOP (bm->bgp, bgp, nn)
{
- 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;
- }
- }
- }
- }
+ if (!bgp->router_id_static.s_addr)
+ bgp_router_id_set (bgp, &router_id.u.prefix4);
}
- return 0;
-}
-int
-bgp_if_update_all ()
-{
- struct listnode *node;
- struct interface *ifp;
-
- for (node = listhead (iflist); node; node = nextnode (node))
- {
- ifp = getdata (node);
- bgp_if_update (ifp);
- }
return 0;
}
@@ -104,7 +68,6 @@
struct interface *ifp;
ifp = zebra_interface_add_read (zclient->ibuf);
- bgp_if_update (ifp);
return 0;
}
@@ -206,8 +169,6 @@
if (ifc == NULL)
return 0;
- bgp_if_update (ifc->ifp);
-
if (if_is_operative (ifc->ifp))
bgp_connected_add (ifc);
@@ -225,8 +186,6 @@
if (ifc == NULL)
return 0;
- bgp_if_update (ifc->ifp);
-
if (if_is_operative (ifc->ifp))
bgp_connected_delete (ifc);
@@ -987,6 +946,7 @@
/* 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;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 6afbe95..61ffe27 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -63,6 +63,8 @@
/* 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 @@
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;
-}
-
/* BGP's cluster-id control. */
int
bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
@@ -1910,7 +1876,7 @@
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;
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 61472d8..ed3f4d1 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -76,6 +76,7 @@
/* BGP router identifier. */
struct in_addr router_id;
+ struct in_addr router_id_static;
/* BGP route reflector cluster ID. */
struct in_addr cluster_id;
diff --git a/isisd/ChangeLog b/isisd/ChangeLog
index b95bdbf..c280bf2 100644
--- a/isisd/ChangeLog
+++ b/isisd/ChangeLog
@@ -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.
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 2f18543..567afa3 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -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 @@
struct tlvs tlv_data;
struct isis_lsp *lsp0 = lsp;
struct isis_passwd *passwd;
+ struct in_addr *routerid;
/*
* First add the tlvs related to area
@@ -1446,6 +1448,30 @@
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
*/
for (node = listhead (area->circuit_list); node; nextnode (node))
diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h
index 72f883d..b82be5b 100644
--- a/isisd/isis_tlv.h
+++ b/isisd/isis_tlv.h
@@ -260,6 +260,7 @@
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);
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 8e12208..f56c5d4 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -43,6 +43,22 @@
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 @@
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 @@
{
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;
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 05ad4db..e92147f 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -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
diff --git a/lib/zclient.c b/lib/zclient.c
index 3b68338..5df420f 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -260,6 +260,9 @@
/* 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 @@
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 @@
*
*/
+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 @@
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);
diff --git a/lib/zclient.h b/lib/zclient.h
index da8d016..03a6e0a 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -62,6 +62,7 @@
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 @@
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 *);
diff --git a/lib/zebra.h b/lib/zebra.h
index e53a40c..0b8b654 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -314,7 +314,10 @@
#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
diff --git a/ospf6d/ChangeLog b/ospf6d/ChangeLog
index a37c4ac..7778c58 100644
--- a/ospf6d/ChangeLog
+++ b/ospf6d/ChangeLog
@@ -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
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index dd89d8d..0baaaea 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -44,6 +44,25 @@
/* 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 @@
/* 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;
diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog
index 6e1a864..2043ad6 100644
--- a/ospfd/ChangeLog
+++ b/ospfd/ChangeLog
@@ -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
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 6a675a5..3172ebc 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -54,6 +54,28 @@
/* 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 @@
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 @@
/* 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;
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index bfde503..6c6dd8d 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -61,6 +61,7 @@
struct ospf_master *om;
extern struct zclient *zclient;
+extern struct in_addr router_id_zebra;
void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
@@ -68,33 +69,6 @@
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 @@
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;
diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index a62fb6c..19d5431 100644
--- a/zebra/ChangeLog
+++ b/zebra/ChangeLog
@@ -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,
diff --git a/zebra/Makefile.am b/zebra/Makefile.am
index 87a994f..f8a0f52 100644
--- a/zebra/Makefile.am
+++ b/zebra/Makefile.am
@@ -24,11 +24,11 @@
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
diff --git a/zebra/main.c b/zebra/main.c
index 0c1a7dd..e10755b 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -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 @@
rib_init ();
zebra_if_init ();
zebra_debug_init ();
+ router_id_init();
zebra_vty_init ();
access_list_init ();
rtadv_init ();
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 6dd3bd2..100a824 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -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 @@
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 @@
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
index 0000000..3052e56
--- /dev/null
+++ b/zebra/router-id.c
@@ -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
index 0000000..7f7a8c3
--- /dev/null
+++ b/zebra/router-id.h
@@ -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
diff --git a/zebra/zserv.c b/zebra/zserv.c
index f57fe5c..537b542 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -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 @@
"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"
};
struct zebra_message_queue
@@ -721,6 +725,38 @@
return 0;
}
+/* 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));
+}
+
/* Register zebra server interface information. Send current all
interface and address information. */
static void
@@ -1122,6 +1158,27 @@
}
#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 @@
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 @@
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
diff --git a/zebra/zserv.h b/zebra/zserv.h
index ac5da1b..620e24d 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -56,6 +56,9 @@
/* Interface information. */
u_char ifinfo;
+
+ /* Router-id information. */
+ u_char ridinfo;
};
/* Zebra instance */
@@ -92,6 +95,7 @@
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;