summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-10-19 12:02:51 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-10-19 12:02:51 +0000
commitdad2ed0ea2d46300983f4e9cde6008dba2926d1e (patch)
tree1d33e1002e97ab67386bd63daa50de6a21566c2d /usr.sbin/bgpd
parent7624dce6c878f38e238494751c696fb265e11e2b (diff)
allow neighbor definitions to depend on interface state.
with this, if a neighbor is configured as dependent on carp0 for example, the neighbor will remain in state IDLE as long as carp0 is not master. once carp0 becomes master the session(s) depending on it immediately go to CONNECT (or ACTIVE, if they're configured passive), reducing failover time. claudio ok, with some input from ryan as well
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.c10
-rw-r--r--usr.sbin/bgpd/bgpd.h8
-rw-r--r--usr.sbin/bgpd/kroute.c17
-rw-r--r--usr.sbin/bgpd/parse.y17
-rw-r--r--usr.sbin/bgpd/printconf.c4
-rw-r--r--usr.sbin/bgpd/session.c38
-rw-r--r--usr.sbin/bgpd/session.h3
7 files changed, 85 insertions, 12 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index 381ce2ed37e..05d4bcf5898 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.109 2004/09/23 01:55:05 henning Exp $ */
+/* $OpenBSD: bgpd.c,v 1.110 2004/10/19 12:02:49 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -545,6 +545,14 @@ dispatch_imsg(struct imsgbuf *ibuf, int idx)
else
kr_show_route(&imsg);
break;
+ case IMSG_IFINFO:
+ if (idx != PFD_PIPE_SESSION)
+ log_warnx("IFINFO request not from SE");
+ else if (imsg.hdr.len != IMSG_HEADER_SIZE + IFNAMSIZ)
+ log_warnx("IFINFO request with wrong len");
+ else
+ kr_ifinfo(imsg.data);
+ break;
default:
break;
}
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 8d600a76931..33083d296f7 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.144 2004/09/28 12:09:31 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.145 2004/10/19 12:02:50 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -222,6 +222,7 @@ struct peer_config {
struct peer_auth auth;
u_int8_t capabilities;
u_int8_t reflector_client;
+ char if_depend[IFNAMSIZ];
enum reconf_action reconf_action;
};
@@ -297,7 +298,8 @@ enum imsg_type {
IMSG_CTL_SHOW_RIB_AS,
IMSG_CTL_SHOW_RIB_PREFIX,
IMSG_CTL_SHOW_NETWORK,
- IMSG_REFRESH
+ IMSG_REFRESH,
+ IMSG_IFINFO
};
struct imsg_hdr {
@@ -618,12 +620,12 @@ int kr_dispatch_msg(void);
int kr_nexthop_add(struct bgpd_addr *);
void kr_nexthop_delete(struct bgpd_addr *);
void kr_show_route(struct imsg *);
+void kr_ifinfo(char *);
in_addr_t prefixlen2mask(u_int8_t);
struct in6_addr *prefixlen2mask6(u_int8_t prefixlen);
void inet6applymask(struct in6_addr *, const struct in6_addr *,
int);
-
/* control.c */
int control_init(void);
void control_cleanup(void);
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c
index 367b1af2d73..914859fe2ef 100644
--- a/usr.sbin/bgpd/kroute.c
+++ b/usr.sbin/bgpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.109 2004/10/16 12:24:23 henning Exp $ */
+/* $OpenBSD: kroute.c,v 1.110 2004/10/19 12:02:50 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -400,6 +400,19 @@ kr_show_route(struct imsg *imsg)
send_imsg_session(IMSG_CTL_END, imsg->hdr.pid, NULL, 0);
}
+void
+kr_ifinfo(char *ifname)
+{
+ struct kif_node *kif;
+
+ RB_FOREACH(kif, kif_tree, &kit)
+ if (!strcmp(ifname, kif->k.ifname)) {
+ send_imsg_session(IMSG_IFINFO, 0,
+ &kif->k, sizeof(kif->k));
+ return;
+ }
+}
+
/*
* RB-tree compare functions
*/
@@ -952,6 +965,8 @@ if_change(u_short ifindex, int flags, struct if_data *ifd)
kif->k.media_type = ifd->ifi_type;
kif->k.baudrate = ifd->ifi_baudrate;
+ send_imsg_session(IMSG_IFINFO, 0, &kif->k, sizeof(kif->k));
+
if ((reachable = (flags & IFF_UP) &&
(ifd->ifi_link_state != LINK_STATE_DOWN)) == kif->k.nh_reachable)
return; /* nothing changed wrt nexthop validity */
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 2c257a2de7c..6634244a094 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.140 2004/09/28 12:09:31 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.141 2004/10/19 12:02:50 henning Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -139,7 +139,7 @@ typedef struct {
%token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE
%token GROUP NEIGHBOR NETWORK
%token REMOTEAS DESCR LOCALADDR MULTIHOP PASSIVE MAXPREFIX ANNOUNCE
-%token ENFORCE NEIGHBORAS CAPABILITIES REFLECTOR
+%token ENFORCE NEIGHBORAS CAPABILITIES REFLECTOR DEPEND
%token DUMP IN OUT
%token LOG ROUTECOLL
%token TCP MD5SIG PASSWORD KEY
@@ -740,6 +740,18 @@ peeropts : REMOTEAS asnumber {
curpeer->conf.reflector_client = 1;
conf->clusterid = $2.v4.s_addr;
}
+ | DEPEND ON STRING {
+ if (strlcpy(curpeer->conf.if_depend, $3,
+ sizeof(curpeer->conf.if_depend)) >=
+ sizeof(curpeer->conf.if_depend)) {
+ yyerror("interface name \"%s\" too long: "
+ "max %u", $3,
+ sizeof(curpeer->conf.if_depend) - 1);
+ free($3);
+ YYERROR;
+ }
+ free($3);
+ }
;
espah : ESP { $$ = 1; }
@@ -1213,6 +1225,7 @@ lookup(char *s)
{ "capabilities", CAPABILITIES},
{ "community", COMMUNITY},
{ "deny", DENY},
+ { "depend", DEPEND},
{ "descr", DESCR},
{ "dump", DUMP},
{ "enforce", ENFORCE},
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index e147eb23011..678b56d5361 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.30 2004/09/28 12:09:31 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.31 2004/10/19 12:02:50 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -193,6 +193,8 @@ print_peer(struct peer_config *p, struct bgpd_config *conf)
inet_ntoa(ina));
}
}
+ if (p->if_depend[0])
+ printf("%s\tdepend on \"%s\"\n", c, p->if_depend);
if (p->auth.method == AUTH_MD5SIG)
printf("%s\ttcp md5sig\n", c);
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index 37ff59a7764..1b0f138a990 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.195 2004/10/07 13:39:14 henning Exp $ */
+/* $OpenBSD: session.c,v 1.196 2004/10/19 12:02:50 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -533,6 +533,12 @@ init_peer(struct peer *p)
p->capa.announce = p->conf.capabilities;
p->capa.ann_mp = 1;
p->capa.ann_refresh = 1;
+ if (p->conf.if_depend[0])
+ imsg_compose(ibuf_main, IMSG_IFINFO, 0, 0, -1,
+ p->conf.if_depend, sizeof(p->conf.if_depend));
+ else
+ p->depend_ok = 1;
+
peer_cnt++;
change_state(p, STATE_IDLE, EVNT_NONE);
@@ -570,7 +576,9 @@ bgp_fsm(struct peer *peer, enum session_events event)
return;
}
- if (peer->conf.passive || peer->conf.template) {
+ if (!peer->depend_ok)
+ peer->ConnectRetryTimer = 0;
+ else if (peer->conf.passive || peer->conf.template) {
change_state(peer, STATE_ACTIVE, event);
peer->ConnectRetryTimer = 0;
} else {
@@ -2019,9 +2027,10 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
struct peer_config *pconf;
struct peer *p, *next;
struct listen_addr *la, *nla;
+ struct kif *kif;
u_char *data;
enum reconf_action reconf;
- int n;
+ int n, depend_ok;
u_int8_t errcode, subcode;
if ((n = imsg_read(ibuf)) == -1)
@@ -2161,6 +2170,29 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
pending_reconf = 0;
log_info("SE reconfigured");
break;
+ case IMSG_IFINFO:
+ if (idx != PFD_PIPE_MAIN)
+ fatalx("IFINFO message not from parent");
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct kif))
+ fatalx("IFINFO imsg with wrong len");
+ kif = imsg.data;
+ depend_ok = (kif->flags & IFF_UP) &&
+ (kif->link_state == LINK_STATE_UP ||
+ (kif->link_state == LINK_STATE_UNKNOWN &&
+ strncmp(kif->ifname, "carp", 4)));
+
+ for (p = peers; p != NULL; p = p->next)
+ if (!strcmp(p->conf.if_depend, kif->ifname)) {
+ if (depend_ok && !p->depend_ok) {
+ p->depend_ok = depend_ok;
+ bgp_fsm(p, EVNT_START);
+ } else if (!depend_ok && p->depend_ok) {
+ p->depend_ok = depend_ok;
+ bgp_fsm(p, EVNT_STOP);
+ }
+ }
+ break;
case IMSG_MRT_OPEN:
case IMSG_MRT_REOPEN:
if (imsg.hdr.len > IMSG_HEADER_SIZE +
diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h
index fbfcdd2af60..f12507644b3 100644
--- a/usr.sbin/bgpd/session.h
+++ b/usr.sbin/bgpd/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.63 2004/09/22 08:46:28 henning Exp $ */
+/* $OpenBSD: session.h,v 1.64 2004/10/19 12:02:50 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -180,6 +180,7 @@ struct peer {
struct msgbuf wbuf;
struct buf_read *rbuf;
u_int8_t auth_established;
+ u_int8_t depend_ok;
struct peer *next;
};