summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2005-05-24 21:36:41 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2005-05-24 21:36:41 +0000
commitbaa4d0bf261602db9b2d6cac8ce0ba53fc79301b (patch)
tree12f9e52ba9f81a0062a58574252edc9a6bf6f235
parent07cb07bab92828e544cce0201f960f9b9e4591b1 (diff)
Only redistribute networks if the interface they depend on is actually
up and running. This makes redistribution of carp(4)-ed networks magically work. OK norby@
-rw-r--r--usr.sbin/ospfd/kroute.c31
-rw-r--r--usr.sbin/ospfd/ospfd.h4
-rw-r--r--usr.sbin/ospfd/rde.c49
3 files changed, 78 insertions, 6 deletions
diff --git a/usr.sbin/ospfd/kroute.c b/usr.sbin/ospfd/kroute.c
index c67b049f8be..67bd9850751 100644
--- a/usr.sbin/ospfd/kroute.c
+++ b/usr.sbin/ospfd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.17 2005/05/24 21:31:07 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.18 2005/05/24 21:36:40 claudio Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -477,6 +477,34 @@ kif_clear(void)
kif_remove(kif);
}
+void
+kif_update(struct kif *k)
+{
+ struct kif_node *kif;
+
+ if ((kif = kif_find(k->ifindex)) == NULL) {
+ log_warnx("interface with index %u not found",
+ k->ifindex);
+ return;
+ }
+
+ memcpy(&kif->k, k, sizeof(struct kif));
+}
+
+int
+kif_validate(int ifindex)
+{
+ struct kif_node *kif;
+
+ if ((kif = kif_find(ifindex)) == NULL) {
+ log_warnx("interface with index %u not found",
+ ifindex);
+ return (1);
+ }
+
+ return (kif->k.nh_reachable);
+}
+
struct kroute_node *
kroute_match(in_addr_t key)
{
@@ -592,6 +620,7 @@ if_change(u_short ifindex, int flags, struct if_data *ifd)
kif->k.nh_reachable = reachable;
main_imsg_compose_ospfe(IMSG_IFINFO, 0, &kif->k, sizeof(kif->k));
+ main_imsg_compose_rde(IMSG_IFINFO, 0, &kif->k, sizeof(kif->k));
}
void
diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h
index bc798d0f6b5..15366e51f1b 100644
--- a/usr.sbin/ospfd/ospfd.h
+++ b/usr.sbin/ospfd/ospfd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfd.h,v 1.30 2005/05/22 18:05:42 norby Exp $ */
+/* $OpenBSD: ospfd.h,v 1.31 2005/05/24 21:36:40 claudio Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -518,6 +518,8 @@ void kr_nexthop_delete(struct in_addr);
void kr_show_route(struct imsg *);
void kr_ifinfo(char *, pid_t);
struct kif *kif_findname(char *);
+void kif_update(struct kif *);
+int kif_validate(int);
u_int8_t mask2prefixlen(in_addr_t);
in_addr_t prefixlen2mask(u_int8_t);
diff --git a/usr.sbin/ospfd/rde.c b/usr.sbin/ospfd/rde.c
index 5dface6ed98..6cef0537989 100644
--- a/usr.sbin/ospfd/rde.c
+++ b/usr.sbin/ospfd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.22 2005/05/24 20:40:57 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.23 2005/05/24 21:36:40 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
@@ -56,6 +56,7 @@ void rde_req_list_del(struct rde_nbr *, struct lsa_hdr *);
void rde_req_list_free(struct rde_nbr *);
int rde_redistribute(struct kroute *);
+void rde_update_redistribute(int);
struct lsa *rde_asext_get(struct kroute *);
struct lsa *rde_asext_put(struct kroute *);
@@ -544,6 +545,7 @@ rde_dispatch_parent(int fd, short event, void *bula)
struct lsa *lsa;
struct vertex *v;
struct kroute kr;
+ struct kif kif;
int n;
switch (event) {
@@ -601,6 +603,18 @@ rde_dispatch_parent(int fd, short event, void *bula)
lsa_merge(nbrself, lsa, v);
}
break;
+ case IMSG_IFINFO:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kif)) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
+ memcpy(&kif, imsg.data, sizeof(kif));
+
+ log_debug("IMSG_IFINFO: ifindex %i reachable %d",
+ kif.ifindex, kif.nh_reachable);
+ kif_update(&kif);
+ rde_update_redistribute(kif.ifindex);
+ break;
default:
log_debug("rde_dispatch_parent: unexpected imsg %d",
imsg.hdr.type);
@@ -913,11 +927,12 @@ rde_redistribute(struct kroute *kr)
(kr->flags & F_CONNECTED))
rv = 1;
+ /* interface is not up and running so don't announce */
+ if (kif_validate(kr->ifindex) == 0)
+ return (0);
+
LIST_FOREACH(area, &rdeconf->area_list, entry)
LIST_FOREACH(iface, &area->iface_list, entry) {
- log_debug("rde_redistribute: iface %s/%d",
- inet_ntoa(iface->addr),
- mask2prefixlen(iface->mask.s_addr));
if ((iface->addr.s_addr & iface->mask.s_addr) ==
kr->prefix.s_addr && iface->mask.s_addr ==
prefixlen2mask(kr->prefixlen))
@@ -928,6 +943,32 @@ rde_redistribute(struct kroute *kr)
return (rv);
}
+void
+rde_update_redistribute(int ifindex)
+{
+ struct rde_asext *ae;
+ struct lsa *lsa;
+ struct vertex *v;
+ int wasused;
+
+ LIST_FOREACH(ae, &rde_asext_list, entry)
+ if (ae->kr.ifindex == ifindex) {
+ wasused = ae->used;
+ ae->used = rde_redistribute(&ae->kr);
+ if (ae->used)
+ lsa = orig_asext_lsa(&ae->kr, DEFAULT_AGE);
+ else if (wasused)
+ lsa = orig_asext_lsa(&ae->kr, MAX_AGE);
+ else
+ continue;
+
+ v = lsa_find(NULL, lsa->hdr.type,
+ lsa->hdr.ls_id, lsa->hdr.adv_rtr);
+
+ lsa_merge(nbrself, lsa, v);
+ }
+}
+
struct lsa *
rde_asext_get(struct kroute *kr)
{