summaryrefslogtreecommitdiff
path: root/usr.sbin/ospfd/kroute.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2006-01-12 15:10:03 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2006-01-12 15:10:03 +0000
commit5e4a3b237324beb330b3eaa92a6f66ca4b2136d9 (patch)
treed36dcbefb99f9ede57b5760ce8723cef6a4e62ec /usr.sbin/ospfd/kroute.c
parent89ea3802de539e5fbf173ab41da10f5f3239e559 (diff)
Rewrite the redistribute code. The previous implementation was stupid and
resulted in a major bottleneck if bgpd was used on the same box -- not clever to do linear searches over 175k entries :(. This now moves the redistribute code back into kroute duty and kills the linear list. Also default routes are now redistributed without the need for a kernel default route. OK norby@
Diffstat (limited to 'usr.sbin/ospfd/kroute.c')
-rw-r--r--usr.sbin/ospfd/kroute.c86
1 files changed, 64 insertions, 22 deletions
diff --git a/usr.sbin/ospfd/kroute.c b/usr.sbin/ospfd/kroute.c
index ee85583ae32..406cc96c903 100644
--- a/usr.sbin/ospfd/kroute.c
+++ b/usr.sbin/ospfd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.23 2006/01/12 15:00:48 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.24 2006/01/12 15:10:02 claudio Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -75,6 +75,7 @@ struct kif_node *kif_find(int);
int kif_insert(struct kif_node *);
int kif_remove(struct kif_node *);
void kif_clear(void);
+int kif_validate(int);
struct kroute_node *kroute_match(in_addr_t);
@@ -331,10 +332,30 @@ kr_redistribute(int type, struct kroute *kr)
{
u_int32_t a;
+
+ if (type == IMSG_NETWORK_DEL) {
+ /* was the route redistributed? */
+ if (kr->flags & F_REDISTRIBUTED) {
+ /* remove redistributed flag */
+ kr->flags &= ~F_REDISTRIBUTED;
+ main_imsg_compose_rde(type, 0, kr,
+ sizeof(struct kroute));
+ }
+ return;
+ }
+
+ /* Only non-ospfd routes are considered for redistribution. */
+ if (kr->flags & F_OSPFD_INSERTED)
+ return;
+
/* Dynamic routes are not redistributable. */
if (kr->flags & F_DYNAMIC)
return;
+ /* interface is not up and running so don't announce */
+ if (kr->flags & F_DOWN)
+ return;
+
/*
* We consider the loopback net, multicast and experimental addresses
* as not redistributable.
@@ -349,6 +370,12 @@ kr_redistribute(int type, struct kroute *kr)
if (kr->nexthop.s_addr == htonl(INADDR_LOOPBACK))
return;
+ /* Should we redistrubute this route? */
+ if (!ospf_redistribute(kr))
+ return;
+
+ /* Does not matter if we resend the kr, the RDE will cope. */
+ kr->flags |= F_REDISTRIBUTED;
main_imsg_compose_rde(type, 0, kr, sizeof(struct kroute));
}
@@ -395,8 +422,18 @@ kroute_insert(struct kroute_node *kr)
return (-1);
}
- if (kr->r.flags & F_KERNEL)
- kr_redistribute(IMSG_NETWORK_ADD, &kr->r);
+ if (kr->r.flags & F_OSPFD_INSERTED) {
+ /* don't validate or redistribute ospf route */
+ kr->r.flags &= ~F_DOWN;
+ return (0);
+ }
+
+ if (kif_validate(kr->r.ifindex))
+ kr->r.flags &= ~F_DOWN;
+ else
+ kr->r.flags |= F_DOWN;
+
+ kr_redistribute(IMSG_NETWORK_ADD, &kr->r);
return (0);
}
@@ -410,8 +447,7 @@ kroute_remove(struct kroute_node *kr)
return (-1);
}
- if (kr->r.flags & F_KERNEL)
- kr_redistribute(IMSG_NETWORK_DEL, &kr->r);
+ kr_redistribute(IMSG_NETWORK_DEL, &kr->r);
free(kr);
return (0);
@@ -482,20 +518,6 @@ 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)
{
@@ -606,6 +628,8 @@ void
if_change(u_short ifindex, int flags, struct if_data *ifd)
{
struct kif_node *kif;
+ struct kroute_node *kr;
+ int type;
u_int8_t reachable;
if ((kif = kif_find(ifindex)) == NULL) {
@@ -626,8 +650,21 @@ if_change(u_short ifindex, int flags, struct if_data *ifd)
return; /* nothing changed wrt nexthop validity */
kif->k.nh_reachable = reachable;
+ type = reachable ? IMSG_NETWORK_ADD : IMSG_NETWORK_DEL;
+
+ /* notify ospfe about interface link state */
main_imsg_compose_ospfe(IMSG_IFINFO, 0, &kif->k, sizeof(kif->k));
- main_imsg_compose_rde(IMSG_IFINFO, 0, &kif->k, sizeof(kif->k));
+
+ /* update redistribute list */
+ RB_FOREACH(kr, kroute_tree, &krt)
+ if (kr->r.ifindex == ifindex) {
+ if (reachable)
+ kr->r.flags &= ~F_DOWN;
+ else
+ kr->r.flags |= F_DOWN;
+
+ kr_redistribute(type, &kr->r);
+ }
}
void
@@ -777,8 +814,7 @@ fetchtable(void)
return (-1);
}
- if (!(rtm->rtm_flags & RTF_PROTO1))
- kr->r.flags = F_KERNEL;
+ kr->r.flags = F_KERNEL;
switch (sa->sa_family) {
case AF_INET:
@@ -1002,6 +1038,12 @@ dispatch_rtmsg(void)
if (kr->r.flags & F_KERNEL) {
kr->r.nexthop.s_addr = nexthop.s_addr;
kr->r.flags = flags;
+
+ if (kif_validate(kr->r.ifindex))
+ kr->r.flags &= ~F_DOWN;
+ else
+ kr->r.flags |= F_DOWN;
+
/* just readd, the RDE will care */
kr_redistribute(IMSG_NETWORK_ADD,
&kr->r);