Common router id.

This commit is contained in:
hasso 2004-10-03 18:18:34 +00:00
parent a49c0ff677
commit 18a6dce6f8
26 changed files with 584 additions and 151 deletions

View 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.

View 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;
}

View File

@ -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;
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 @@ 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;

View 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;
}
/* 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;

View 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;

View 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.

View 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
*/

View 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);

View File

@ -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;

View 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

View 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);

View 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 *);

View 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

View 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

View 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;

View 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

View 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;

View 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;
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;

View 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,

View 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

View 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 ();

View 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))

265
zebra/router-id.c Normal file
View File

@ -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;
}

43
zebra/router-id.h Normal file
View File

@ -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

View 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"
};
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

View 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;