summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMichele Marchetto <michele@cvs.openbsd.org>2008-11-21 10:39:33 +0000
committerMichele Marchetto <michele@cvs.openbsd.org>2008-11-21 10:39:33 +0000
commitb0c613da10f0c496e63de57d577671f797ccdaf8 (patch)
tree4885885b3054d49d5ac2adef65a52bf1f60bb717 /usr.sbin
parent8221cbf7ddb4bc1dfc97533a54db6e061d0168ce (diff)
Introduce support for flash updates.
They spread routing changes immediately as they happen avoiding wait until the next report interval. OK norby@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/dvmrpd/dvmrpd.h6
-rw-r--r--usr.sbin/dvmrpd/dvmrpe.c38
-rw-r--r--usr.sbin/dvmrpd/rde_srt.c35
3 files changed, 74 insertions, 5 deletions
diff --git a/usr.sbin/dvmrpd/dvmrpd.h b/usr.sbin/dvmrpd/dvmrpd.h
index 2a8e6d21d03..b271d198112 100644
--- a/usr.sbin/dvmrpd/dvmrpd.h
+++ b/usr.sbin/dvmrpd/dvmrpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dvmrpd.h,v 1.8 2007/09/11 18:23:05 claudio Exp $ */
+/* $OpenBSD: dvmrpd.h,v 1.9 2008/11/21 10:39:32 michele Exp $ */
/*
* Copyright (c) 2004, 2005, 2006 Esben Norby <norby@openbsd.org>
@@ -108,7 +108,9 @@ enum imsg_type {
IMSG_FULL_ROUTE_REPORT,
IMSG_FULL_ROUTE_REPORT_END,
IMSG_MFC_ADD,
- IMSG_MFC_DEL
+ IMSG_MFC_DEL,
+ IMSG_FLASH_UPDATE,
+ IMSG_FLASH_UPDATE_DS
};
struct imsg_hdr {
diff --git a/usr.sbin/dvmrpd/dvmrpe.c b/usr.sbin/dvmrpd/dvmrpe.c
index 2963e913188..468ed1a69c3 100644
--- a/usr.sbin/dvmrpd/dvmrpe.c
+++ b/usr.sbin/dvmrpd/dvmrpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dvmrpe.c,v 1.2 2006/06/01 21:47:27 claudio Exp $ */
+/* $OpenBSD: dvmrpe.c,v 1.3 2008/11/21 10:39:32 michele Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -349,6 +349,42 @@ dvmrpe_dispatch_rde(int fd, short event, void *bula)
nbr = nbr_find_peerid(imsg.hdr.peerid);
rr_list_send(&nbr->rr_list, NULL, nbr);
break;
+ case IMSG_FLASH_UPDATE:
+ if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(*rr))
+ fatalx("invalid size of RDE request");
+
+ if ((rr = calloc(1, sizeof(*rr))) == NULL)
+ fatal("dvmrpe_dispatch_rde");
+
+ memcpy(rr, imsg.data, sizeof(*rr));
+
+ LIST_FOREACH(iface, &deconf->iface_list, entry) {
+ if (!if_nbr_list_empty(iface)) {
+ rr_list_add(&iface->rr_list, rr);
+ rr_list_send(&iface->rr_list, iface,
+ NULL);
+ }
+ }
+ break;
+ case IMSG_FLASH_UPDATE_DS:
+ if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(*rr))
+ fatalx("invalid size of RDE request");
+
+ if ((rr = calloc(1, sizeof(*rr))) == NULL)
+ fatal("dvmrpe_dispatch_rde");
+
+ memcpy(rr, imsg.data, sizeof(*rr));
+
+ LIST_FOREACH(iface, &deconf->iface_list, entry) {
+ if (iface->ifindex == rr->ifindex)
+ continue;
+ if (!if_nbr_list_empty(iface)) {
+ rr_list_add(&iface->rr_list, rr);
+ rr_list_send(&iface->rr_list, iface,
+ NULL);
+ }
+ }
+ break;
default:
log_debug("dvmrpe_dispatch_rde: error handling imsg %d",
imsg.hdr.type);
diff --git a/usr.sbin/dvmrpd/rde_srt.c b/usr.sbin/dvmrpd/rde_srt.c
index a1f30e6ff4e..47dae6b0e32 100644
--- a/usr.sbin/dvmrpd/rde_srt.c
+++ b/usr.sbin/dvmrpd/rde_srt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_srt.c,v 1.8 2008/10/21 20:20:00 michele Exp $ */
+/* $OpenBSD: rde_srt.c,v 1.9 2008/11/21 10:39:32 michele Exp $ */
/*
* Copyright (c) 2005, 2006 Esben Norby <norby@openbsd.org>
@@ -48,6 +48,7 @@ void srt_update_ds_forwarders(struct src_node *, struct rt_node *,
void srt_current_forwarder(struct src_node *, struct rt_node *,
struct iface *, u_int32_t, u_int32_t);
+/* Downstrean neighbor */
void srt_add_ds(struct src_node *, struct rt_node *, u_int32_t,
u_int32_t);
struct ds *srt_find_ds(struct src_node *, u_int32_t);
@@ -57,6 +58,10 @@ struct src_node *srt_find_src(struct in_addr, struct in_addr);
struct src_node *srt_add_src(struct in_addr, struct in_addr, u_int32_t);
void srt_delete_src(struct src_node *);
+/* Flash updates */
+void flash_update(struct rt_node *);
+void flash_update_ds(struct rt_node *);
+
RB_HEAD(rt_tree, rt_node) rt;
RB_PROTOTYPE(rt_tree, rt_node, entry, rt_compare)
RB_GENERATE(rt_tree, rt_node, entry, rt_compare)
@@ -337,13 +342,16 @@ srt_check_route(struct route_report *rr, int connected)
srt_delete_ds(src, rn, ds_nbr, iface);
if (adj_metric > rn->cost) {
- if (nbr_ip == nbr_report)
+ if (nbr_ip == nbr_report) {
rn->cost = adj_metric;
+ flash_update_ds(rn);
+ }
} else if (adj_metric < rn->cost) {
rn->cost = adj_metric;
if (nbr_ip != nbr_report) {
rn->nexthop.s_addr = nbr_report;
srt_set_upstream(rn, ifindex);
+ flash_update(rn);
}
/* We have a new best route to source, update the
* designated forwarders on downstream interfaces to
@@ -353,6 +361,7 @@ srt_check_route(struct route_report *rr, int connected)
if (nbr_report < nbr_ip) {
rn->nexthop.s_addr = nbr_report;
srt_set_upstream(rn, ifindex);
+ flash_update(rn);
}
}
/* Update forwarder of current interface if necessary and
@@ -551,3 +560,25 @@ srt_delete_src(struct src_node *src_node)
RB_REMOVE(src_head, &rdeconf->src_list, src_node);
free(src_node);
}
+
+void
+flash_update(struct rt_node *rn) {
+ struct route_report rr;
+
+ rr.net = rn->prefix;
+ rr.mask.s_addr = ntohl(prefixlen2mask(rn->prefixlen));
+ rr.metric = rn->cost;
+ rr.ifindex = rn->ifindex;
+ rde_imsg_compose_dvmrpe(IMSG_FLASH_UPDATE, 0, 0, &rr, sizeof(rr));
+}
+
+void
+flash_update_ds(struct rt_node *rn) {
+ struct route_report rr;
+
+ rr.net = rn->prefix;
+ rr.mask.s_addr = ntohl(prefixlen2mask(rn->prefixlen));
+ rr.metric = rn->cost;
+ rr.ifindex = rn->ifindex;
+ rde_imsg_compose_dvmrpe(IMSG_FLASH_UPDATE_DS, 0, 0, &rr, sizeof(rr));
+}