summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
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;
};