mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-29 21:21:54 +00:00
Implements interface masks for choosing router id.
Router ID could be automatically determined based of subset of ifaces/addresses specified by 'router id from' option. The patch also does some minor changes related to router ID reconfiguration. Thanks to Alexander V. Chernikov for most of the work.
This commit is contained in:
parent
a92cf57dd6
commit
79b4e12e60
16
conf/conf.c
16
conf/conf.c
@ -200,9 +200,19 @@ global_commit(struct config *new, struct config *old)
|
||||
log(L_WARN "Reconfiguration of BGP listening socket not implemented, please restart BIRD.");
|
||||
|
||||
if (!new->router_id)
|
||||
new->router_id = old->router_id;
|
||||
if (new->router_id != old->router_id)
|
||||
return 1;
|
||||
{
|
||||
new->router_id = old->router_id;
|
||||
|
||||
if (new->router_id_from)
|
||||
{
|
||||
u32 id = if_choose_router_id(new->router_id_from, old->router_id);
|
||||
if (!id)
|
||||
log(L_WARN "Cannot determine router ID, using old one");
|
||||
else
|
||||
new->router_id = id;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ struct config {
|
||||
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
|
||||
char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
|
||||
struct rtable_config *master_rtc; /* Configuration of master routing table */
|
||||
struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */
|
||||
|
||||
u32 router_id; /* Our Router ID */
|
||||
ip_addr listen_bgp_addr; /* Listening BGP socket should use this address */
|
||||
|
@ -337,7 +337,18 @@ protocol rip {
|
||||
Besides, there are some predefined numeric constants based on /etc/iproute2/rt_* files.
|
||||
A list of defined constants can be seen (together with other symbols) using 'show symbols' command.
|
||||
|
||||
<tag>router id <m/IPv4 address/</tag> Set BIRD's router ID. It's a world-wide unique identification of your router, usually one of router's IPv4 addresses. Default: in IPv4 version, the lowest IP address of a non-loopback interface. In IPv6 version, this option is mandatory.
|
||||
<tag>router id <m/IPv4 address/</tag>
|
||||
Set BIRD's router ID. It's a world-wide unique identification
|
||||
of your router, usually one of router's IPv4 addresses.
|
||||
Default: in IPv4 version, the lowest IP address of a
|
||||
non-loopback interface. In IPv6 version, this option is
|
||||
mandatory.
|
||||
|
||||
<tag>router id from [-] [ "<m/mask/" ] [ <m/prefix/ ] [, ...]</tag>
|
||||
Set BIRD's router ID based on an IP address of an interface
|
||||
specified by an interface pattern. The option is applicable
|
||||
for IPv4 version only. See <ref id="dsc-iface" name="interface">
|
||||
section for detailed description of interface patterns.
|
||||
|
||||
<tag>listen bgp [address <m/address/] [port <m/port/] [dual]</tag>
|
||||
This option allows to specify address and port where BGP
|
||||
|
@ -75,9 +75,9 @@ CF_GRAMMAR
|
||||
|
||||
CF_ADDTO(conf, rtrid)
|
||||
|
||||
rtrid: ROUTER ID idval ';' {
|
||||
new_config->router_id = $3;
|
||||
}
|
||||
rtrid:
|
||||
ROUTER ID idval ';' { new_config->router_id = $3; }
|
||||
| ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; }
|
||||
;
|
||||
|
||||
idval:
|
||||
@ -264,6 +264,17 @@ iface_patt_list:
|
||||
| iface_patt_list ',' iface_patt_node
|
||||
;
|
||||
|
||||
iface_patt_init: {
|
||||
/* Generic this_ipatt init */
|
||||
this_ipatt = cfg_allocz(sizeof(struct iface_patt));
|
||||
init_list(&this_ipatt->ipn_list);
|
||||
}
|
||||
;
|
||||
|
||||
iface_patt:
|
||||
iface_patt_init iface_patt_list
|
||||
;
|
||||
|
||||
|
||||
/* Direct device route protocol */
|
||||
|
||||
|
66
nest/iface.c
66
nest/iface.c
@ -35,8 +35,6 @@
|
||||
|
||||
static pool *if_pool;
|
||||
|
||||
static void auto_router_id(void);
|
||||
|
||||
list iface_list;
|
||||
|
||||
/**
|
||||
@ -354,9 +352,6 @@ if_end_update(void)
|
||||
struct iface *i;
|
||||
struct ifa *a, *b;
|
||||
|
||||
if (!config->router_id)
|
||||
auto_router_id();
|
||||
|
||||
WALK_LIST(i, iface_list)
|
||||
{
|
||||
if (!(i->flags & IF_UPDATED))
|
||||
@ -583,24 +578,57 @@ ifa_delete(struct ifa *a)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
auto_router_id(void)
|
||||
u32
|
||||
if_choose_router_id(struct iface_patt *mask, u32 old_id)
|
||||
{
|
||||
#ifndef IPV6
|
||||
struct iface *i, *j;
|
||||
struct iface *i;
|
||||
struct ifa *a, *b;
|
||||
|
||||
j = NULL;
|
||||
b = NULL;
|
||||
WALK_LIST(i, iface_list)
|
||||
if ((i->flags & IF_ADMIN_UP) &&
|
||||
!(i->flags & (IF_IGNORE | IF_SHUTDOWN)) &&
|
||||
i->addr &&
|
||||
!(i->addr->flags & IA_PEER) &&
|
||||
(!j || ipa_to_u32(i->addr->ip) < ipa_to_u32(j->addr->ip)))
|
||||
j = i;
|
||||
if (!j)
|
||||
die("Cannot determine router ID (no suitable network interface found), please configure it manually");
|
||||
log(L_INFO "Guessed router ID %I according to interface %s", j->addr->ip, j->name);
|
||||
config->router_id = ipa_to_u32(j->addr->ip);
|
||||
{
|
||||
if (!(i->flags & IF_ADMIN_UP) ||
|
||||
(i->flags & (IF_IGNORE | IF_SHUTDOWN)))
|
||||
continue;
|
||||
|
||||
WALK_LIST(a, i->addrs)
|
||||
{
|
||||
if (a->flags & IA_SECONDARY)
|
||||
continue;
|
||||
|
||||
if (a->scope <= SCOPE_LINK)
|
||||
continue;
|
||||
|
||||
/* FIXME: This should go away */
|
||||
if (a->flags & IA_PEER)
|
||||
continue;
|
||||
|
||||
/* FIXME: This should go away too */
|
||||
if (!mask && (a != i->addr))
|
||||
continue;
|
||||
|
||||
/* Check pattern if specified */
|
||||
if (mask && !iface_patt_match(mask, i, a))
|
||||
continue;
|
||||
|
||||
/* No pattern or pattern matched */
|
||||
if (!b || ipa_to_u32(a->ip) < ipa_to_u32(b->ip))
|
||||
b = a;
|
||||
}
|
||||
}
|
||||
|
||||
if (!b)
|
||||
return 0;
|
||||
|
||||
u32 id = ipa_to_u32(b->ip);
|
||||
if (id != old_id)
|
||||
log(L_INFO "Chosen router ID %R according to interface %s", id, b->iface->name);
|
||||
|
||||
return id;
|
||||
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,7 @@ struct iface *if_find_by_name(char *);
|
||||
struct iface *if_get_by_name(char *);
|
||||
void ifa_recalc_all_primary_addresses(void);
|
||||
|
||||
|
||||
/* The Neighbor Cache */
|
||||
|
||||
typedef struct neighbor {
|
||||
@ -161,4 +162,7 @@ int iface_patt_match(struct iface_patt *ifp, struct iface *i, struct ifa *a);
|
||||
struct iface_patt *iface_patt_find(list *l, struct iface *i, struct ifa *a);
|
||||
int iface_patts_equal(list *, list *, int (*)(struct iface_patt *, struct iface_patt *));
|
||||
|
||||
|
||||
u32 if_choose_router_id(struct iface_patt *mask, u32 old_id);
|
||||
|
||||
#endif
|
||||
|
14
nest/proto.c
14
nest/proto.c
@ -382,11 +382,9 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config
|
||||
/* If there is a too big change in core attributes, ... */
|
||||
if ((nc->protocol != oc->protocol) ||
|
||||
(nc->disabled != p->disabled) ||
|
||||
(nc->table->table != oc->table->table) ||
|
||||
(proto_get_router_id(nc) != proto_get_router_id(oc)))
|
||||
(nc->table->table != oc->table->table))
|
||||
return 0;
|
||||
|
||||
|
||||
p->debug = nc->debug;
|
||||
p->mrtdump = nc->mrtdump;
|
||||
proto_reconfig_type = type;
|
||||
@ -552,6 +550,16 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
|
||||
initial_device_proto = NULL;
|
||||
}
|
||||
|
||||
/* Determine router ID for the first time - it has to be here and not in
|
||||
global_commit() because it is postponed after start of device protocol */
|
||||
if (!config->router_id)
|
||||
{
|
||||
config->router_id = if_choose_router_id(config->router_id_from, 0);
|
||||
if (!config->router_id)
|
||||
die("Cannot determine router ID, please configure it manually");
|
||||
}
|
||||
|
||||
/* Start all other protocols */
|
||||
WALK_LIST_DELSAFE(p, n, initial_proto_list)
|
||||
proto_rethink_goal(p);
|
||||
}
|
||||
|
@ -1009,6 +1009,9 @@ bgp_reconfigure(struct proto *P, struct proto_config *C)
|
||||
struct bgp_proto *p = (struct bgp_proto *) P;
|
||||
struct bgp_config *old = p->cf;
|
||||
|
||||
if (proto_get_router_id(C) != p->local_id)
|
||||
return 0;
|
||||
|
||||
int same = !memcmp(((byte *) old) + sizeof(struct proto_config),
|
||||
((byte *) new) + sizeof(struct proto_config),
|
||||
// password item is last and must be checked separately
|
||||
|
@ -729,6 +729,9 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
|
||||
struct ospf_iface *ifa, *ifx;
|
||||
struct ospf_iface_patt *ip;
|
||||
|
||||
if (proto_get_router_id(c) != po->router_id)
|
||||
return 0;
|
||||
|
||||
if (po->rfc1583 != new->rfc1583)
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user