diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2005-03-14 08:44:34 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2005-03-14 08:44:34 +0000 |
commit | c6ae3437c11492b8cd492307af0dfda67ea01aac (patch) | |
tree | abe24d22ade618aee226f1257cfe2ee9bf4b5f59 /usr.sbin/bgpd/kroute.c | |
parent | aacb098271f996a33e681a7777e47c1aa3afe52d (diff) |
"we notice when you plug the cable" - yeah, but we didn't notice when it
was unplugged from the beginning on...
correctly take interfaces' link state into account for nexthop verification
in all cases.
add a new function kroute_validate() that looks up the interface for a given
kroute via the ifindex and check its link state. use it in all cases instead
of hand-rolling the test. claudio ok
Diffstat (limited to 'usr.sbin/bgpd/kroute.c')
-rw-r--r-- | usr.sbin/bgpd/kroute.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c index 0cde25b783a..11d5addb0ba 100644 --- a/usr.sbin/bgpd/kroute.c +++ b/usr.sbin/bgpd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.114 2005/03/13 15:52:34 henning Exp $ */ +/* $OpenBSD: kroute.c,v 1.115 2005/03/14 08:44:33 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -95,6 +95,7 @@ void kif_clear(void); int kif_kr_insert(struct kroute_node *); int kif_kr_remove(struct kroute_node *); +int kroute_validate(struct kroute *kr); void knexthop_validate(struct knexthop_node *); struct kroute_node *kroute_match(in_addr_t); void kroute_attach_nexthop(struct knexthop_node *, @@ -382,8 +383,7 @@ kr_show_route(struct imsg *imsg) bzero(&snh, sizeof(snh)); memcpy(&snh.addr, &h->nexthop, sizeof(snh.addr)); if (h->kroute != NULL) - if (!(h->kroute->r.flags & F_DOWN)) - snh.valid = 1; + snh.valid = kroute_validate(&h->kroute->r); send_imsg_session(IMSG_CTL_SHOW_NEXTHOP, imsg->hdr.pid, &snh, sizeof(snh)); } @@ -729,6 +729,24 @@ kif_kr_remove(struct kroute_node *kr) * nexthop validation */ +int +kroute_validate(struct kroute *kr) +{ + struct kif_node *kif; + + if (kr->flags & F_DOWN) + return (0); + + if ((kif = kif_find(kr->ifindex)) == NULL) { + log_warnx("interface with index %d not found, " + "referenced from route for %s/%u", + kr->ifindex, inet_ntoa(kr->prefix), + kr->prefixlen); + return (1); + } else + return (kif->k.link_state != LINK_STATE_DOWN); +} + void knexthop_validate(struct knexthop_node *kn) { @@ -736,8 +754,8 @@ knexthop_validate(struct knexthop_node *kn) struct kroute_nexthop n; int was_valid = 0; - if (kn->kroute != NULL && (!(kn->kroute->r.flags & F_DOWN))) - was_valid = 1; + if (kn->kroute != NULL) + was_valid = kroute_validate(&kn->kroute->r); bzero(&n, sizeof(n)); memcpy(&n.nexthop, &kn->nexthop, sizeof(n.nexthop)); @@ -749,10 +767,7 @@ knexthop_validate(struct knexthop_node *kn) if (was_valid) send_nexthop_update(&n); } else { /* match */ - if (kr->r.flags & F_DOWN) { /* is down */ - if (was_valid) - send_nexthop_update(&n); - } else { /* valid */ + if (kroute_validate(&kr->r)) { /* valid */ n.valid = 1; n.connected = kr->r.flags & F_CONNECTED; if ((n.gateway.v4.s_addr = @@ -760,7 +775,10 @@ knexthop_validate(struct knexthop_node *kn) n.gateway.af = AF_INET; memcpy(&n.kr, &kr->r, sizeof(n.kr)); send_nexthop_update(&n); - } + } else /* down */ + if (was_valid) + send_nexthop_update(&n); + kroute_attach_nexthop(kn, kr); } break; @@ -989,7 +1007,7 @@ if_change(u_short ifindex, int flags, struct if_data *ifd) bzero(&nh, sizeof(nh)); memcpy(&nh.nexthop, &n->nexthop, sizeof(nh.nexthop)); - if (!(kkr->kr->r.flags & F_DOWN)) { + if (kroute_validate(&n->kroute->r)) { nh.valid = 1; nh.connected = 1; if ((nh.gateway.v4.s_addr = |