diff options
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 10 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/kroute.c | 17 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 17 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 4 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 38 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 3 |
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; }; |