From 18a6dce6f83dd20caf1f36c8e840868ff0bf6dbd Mon Sep 17 00:00:00 2001 From: hasso Date: Sun, 3 Oct 2004 18:18:34 +0000 Subject: Common router id. --- bgpd/ChangeLog | 8 ++ bgpd/bgp_vty.c | 8 +- bgpd/bgp_zebra.c | 64 +++---------- bgpd/bgpd.c | 40 +------- bgpd/bgpd.h | 1 + isisd/ChangeLog | 7 ++ isisd/isis_lsp.c | 26 +++++ isisd/isis_tlv.h | 1 + isisd/isis_zebra.c | 30 +++--- lib/ChangeLog | 5 + lib/zclient.c | 34 +++++++ lib/zclient.h | 3 + lib/zebra.h | 5 +- ospf6d/ChangeLog | 5 + ospf6d/ospf6_zebra.c | 20 ++++ ospfd/ChangeLog | 7 ++ ospfd/ospf_zebra.c | 37 ++++--- ospfd/ospfd.c | 30 +----- zebra/ChangeLog | 12 +++ zebra/Makefile.am | 4 +- zebra/main.c | 3 +- zebra/redistribute.c | 5 + zebra/router-id.c | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++ zebra/router-id.h | 43 +++++++++ zebra/zserv.c | 68 ++++++++++++- zebra/zserv.h | 4 + 26 files changed, 584 insertions(+), 151 deletions(-) create mode 100644 zebra/router-id.c create mode 100644 zebra/router-id.h diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 2bcce1c7..d5ab3282 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,11 @@ +2004-10-03 James R. Leu + + * 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 * 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 27a3c2eb..6b3c4988 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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; } diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 42b8fc74..6226a938 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -39,61 +39,25 @@ Boston, MA 02111-1307, USA. */ /* 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; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 6afbe959..61ffe279 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -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; -} - /* 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; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 61472d85..ed3f4d18 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -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; diff --git a/isisd/ChangeLog b/isisd/ChangeLog index b95bdbf9..c280bf26 100644 --- a/isisd/ChangeLog +++ b/isisd/ChangeLog @@ -1,3 +1,10 @@ +2004-10-03 Hasso Tepper + + * 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 * isis_pdu.c: Fix accessing NULL found by valgrind. diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 2f185437..567afa3b 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 @@ 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 */ diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h index 72f883db..b82be5b1 100644 --- a/isisd/isis_tlv.h +++ b/isisd/isis_tlv.h @@ -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); diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 8e122082..f56c5d49 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 @@ 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; diff --git a/lib/ChangeLog b/lib/ChangeLog index 05ad4db5..e92147f3 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,8 @@ +2004-10-03 James R. Leu + + * zclient.c, zclient.h: zclient functions for router id handling. + * zebra.h: New message types for router id handling. + 2004-09-27 Paul Jakma * zebra.h: Add WANT_OSPF_WRITE_FRAGMENT for ospfd diff --git a/lib/zclient.c b/lib/zclient.c index 3b683387..5df420f2 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -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); diff --git a/lib/zclient.h b/lib/zclient.h index da8d016d..03a6e0a7 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -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 *); diff --git a/lib/zebra.h b/lib/zebra.h index e53a40c5..0b8b654c 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -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 diff --git a/ospf6d/ChangeLog b/ospf6d/ChangeLog index a37c4ac1..7778c58a 100644 --- a/ospf6d/ChangeLog +++ b/ospf6d/ChangeLog @@ -1,3 +1,8 @@ +2004-10-03 Hasso Tepper + + * ospf6_zebra.c: Use router id from zebra daemon if it wasn't set in + configuration. + 2004-09-25 Hasso Tepper * 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 dd89d8db..0baaaea9 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -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; diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index 6e1a8646..2043ad61 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,10 @@ +2004-10-03 James R. Leu + + * 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 * 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 6a675a59..3172ebc5 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -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; diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index bfde503d..6c6dd8de 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -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; 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; diff --git a/zebra/ChangeLog b/zebra/ChangeLog index a62fb6cc..19d54312 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -1,3 +1,15 @@ +2004-10-03 James R. Leu + + * 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 * irdp_interface.c, irdp_main.c, irdp_packet.c, rt_netlink.c, diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 87a994f1..f8a0f523 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -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 diff --git a/zebra/main.c b/zebra/main.c index 0c1a7ddb..e10755b9 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 @@ main (int argc, char **argv) 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 6dd3bd2a..100a824e 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 @@ 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 index 00000000..3052e56a --- /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 + +#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 00000000..7f7a8c3b --- /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 + +#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 f57fe5c4..537b5429 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 @@ 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" }; struct zebra_message_queue @@ -721,6 +725,38 @@ zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p) 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 @@ 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 diff --git a/zebra/zserv.h b/zebra/zserv.h index ac5da1b2..620e24dd 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -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; -- cgit v1.2.1