summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2005-05-23 23:03:08 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2005-05-23 23:03:08 +0000
commit6f7a36a599f19f7166afe18d1defb7b0b873ecba (patch)
treea9688359456bad806c2698020a65e7c0f63b112f
parentc3a576547178aad45c98a699c8bf2d35d59ae665 (diff)
First part of summary LSA origination. Not perfect but a start.
OK norby@
-rw-r--r--usr.sbin/ospfd/rde.c98
-rw-r--r--usr.sbin/ospfd/rde.h3
-rw-r--r--usr.sbin/ospfd/rde_spf.c8
3 files changed, 99 insertions, 10 deletions
diff --git a/usr.sbin/ospfd/rde.c b/usr.sbin/ospfd/rde.c
index 1dc6a5a9e49..410246266dd 100644
--- a/usr.sbin/ospfd/rde.c
+++ b/usr.sbin/ospfd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.19 2005/05/23 22:54:05 henning Exp $ */
+/* $OpenBSD: rde.c,v 1.20 2005/05/23 23:03:07 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
@@ -59,6 +59,9 @@ int rde_redistribute(struct kroute *);
struct lsa *rde_asext_get(struct kroute *);
struct lsa *rde_asext_put(struct kroute *);
+struct lsa *orig_asext_lsa(struct kroute *, u_int16_t);
+struct lsa *orig_sum_lsa(struct rt_node *, u_int8_t);
+
volatile sig_atomic_t rde_quit = 0;
struct ospfd_conf *rdeconf = NULL;
struct imsgbuf *ibuf_ospfe;
@@ -880,9 +883,6 @@ rde_req_list_free(struct rde_nbr *nbr)
*/
LIST_HEAD(, rde_asext) rde_asext_list;
-struct lsa *orig_asext_lsa(struct kroute *, u_int16_t);
-
-
int
rde_redistribute(struct kroute *kr)
{
@@ -978,6 +978,50 @@ rde_asext_put(struct kroute *kr)
return (NULL);
}
+/*
+ * summary LSA stuff
+ */
+void
+rde_summary_update(struct rt_node *rte, struct area *area)
+{
+ struct vertex *v;
+ struct lsa *lsa;
+ u_int8_t type;
+
+ /* first check if we acctually need to announce this route */
+ if (!(rte->d_type == DT_NET /* || as border rtr */))
+ return;
+ /* never create summaries for as-ext LSA */
+ if (rte->p_type == PT_TYPE1_EXT || rte->p_type == PT_TYPE2_EXT)
+ return;
+ /* no need for summary LSA in the originating area */
+ if (rte->area.s_addr == area->id.s_addr)
+ return;
+ /* TODO nexthop check, nexthop part of aera -> no summary */
+ if (rte->cost == LS_INFINITY)
+ return;
+ /* TODO AS border router specific checks */
+ /* TODO inter-area network route stuff */
+ /* TODO intra-area stuff -- condense LSA ??? */
+
+ /* update lsa but only if it was changed */
+ if (rte->d_type == DT_NET) {
+ type = LSA_TYPE_SUM_NETWORK;
+ v = lsa_find(area, type, rte->prefix.s_addr, rde_router_id());
+ } else if (rte->d_type == DT_RTR) {
+ type = LSA_TYPE_SUM_ROUTER;
+ v = lsa_find(area, type, rte->adv_rtr.s_addr, rde_router_id());
+ } else
+ fatalx("orig_sum_lsa: unknown route type");
+
+ lsa = orig_sum_lsa(rte, type);
+ lsa_merge(rde_nbr_self(area), lsa, v);
+}
+
+
+/*
+ * functions for self-originated LSA
+ */
struct lsa *
orig_asext_lsa(struct kroute *kr, u_int16_t age)
{
@@ -986,7 +1030,7 @@ orig_asext_lsa(struct kroute *kr, u_int16_t age)
len = sizeof(struct lsa_hdr) + sizeof(struct lsa_asext);
if ((lsa = calloc(1, len)) == NULL)
- fatal("rde_asext_new");
+ fatal("orig_asext_lsa");
log_debug("orig_asext_lsa: %s/%d age %d",
inet_ntoa(kr->prefix), kr->prefixlen, age);
@@ -1002,7 +1046,7 @@ orig_asext_lsa(struct kroute *kr, u_int16_t age)
/* prefix and mask */
/*
* TODO ls_id must be unique, for overlapping routes this may
- * not be true. In this case it a hack needs to be done to
+ * not be true. In this case a hack needs to be done to
* make the ls_id unique.
*/
lsa->hdr.ls_id = kr->prefix.s_addr;
@@ -1028,3 +1072,45 @@ orig_asext_lsa(struct kroute *kr, u_int16_t age)
return (lsa);
}
+struct lsa *
+orig_sum_lsa(struct rt_node *rte, u_int8_t type)
+{
+ struct lsa *lsa;
+ size_t len;
+
+ len = sizeof(struct lsa_hdr) + sizeof(struct lsa_sum);
+ if ((lsa = calloc(1, len)) == NULL)
+ fatal("orig_sum_lsa");
+
+ /* LSA header */
+ lsa->hdr.age = htons(rte->invalid ? MAX_AGE : DEFAULT_AGE);
+ lsa->hdr.opts = rdeconf->options; /* XXX not updated */
+ lsa->hdr.type = type;
+ lsa->hdr.adv_rtr = rdeconf->rtr_id.s_addr;
+ lsa->hdr.seq_num = htonl(INIT_SEQ_NUM);
+ lsa->hdr.len = htons(len);
+
+ /* prefix and mask */
+ /*
+ * TODO ls_id must be unique, for overlapping routes this may
+ * not be true. In this case a hack needs to be done to
+ * make the ls_id unique.
+ */
+ if (type == LSA_TYPE_SUM_NETWORK) {
+ lsa->hdr.ls_id = rte->prefix.s_addr;
+ lsa->data.sum.mask = prefixlen2mask(rte->prefixlen);
+ } else {
+ lsa->hdr.ls_id = rte->adv_rtr.s_addr;
+ lsa->data.sum.mask = 0; /* must be zero per RFC */
+ }
+
+ lsa->data.sum.metric = htonl(/* LSA_ASEXT_E_FLAG | */ 100);
+ /* XXX until now there is no metric */
+
+ lsa->hdr.ls_chksum = 0;
+ lsa->hdr.ls_chksum =
+ htons(iso_cksum(lsa, len, LS_CKSUM_OFFSET));
+
+ return (lsa);
+}
+
diff --git a/usr.sbin/ospfd/rde.h b/usr.sbin/ospfd/rde.h
index 31b8d04ad84..b3bb5c13bd0 100644
--- a/usr.sbin/ospfd/rde.h
+++ b/usr.sbin/ospfd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.14 2005/05/22 18:05:42 norby Exp $ */
+/* $OpenBSD: rde.h,v 1.15 2005/05/23 23:03:07 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -94,6 +94,7 @@ void rde_send_delete_kroute(struct rt_node *);
void rde_nbr_del(struct rde_nbr *);
int rde_nbr_loading(struct area *);
struct rde_nbr *rde_nbr_self(struct area *);
+void rde_summary_update(struct rt_node *, struct area *);
/* rde_lsdb.c */
void lsa_init(struct lsa_tree *);
diff --git a/usr.sbin/ospfd/rde_spf.c b/usr.sbin/ospfd/rde_spf.c
index c6d20705104..356c025234c 100644
--- a/usr.sbin/ospfd/rde_spf.c
+++ b/usr.sbin/ospfd/rde_spf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_spf.c,v 1.15 2005/05/23 22:26:45 norby Exp $ */
+/* $OpenBSD: rde_spf.c,v 1.16 2005/05/23 23:03:07 claudio Exp $ */
/*
* Copyright (c) 2005 Esben Norby <norby@openbsd.org>
@@ -530,11 +530,13 @@ spf_timer(int fd, short event, void *arg)
case SPF_DELAY:
rt_invalidate();
- LIST_FOREACH(area, &conf->area_list, entry) {
+ LIST_FOREACH(area, &conf->area_list, entry)
spf_calc(area);
- }
RB_FOREACH(r, rt_tree, &rt) {
+ LIST_FOREACH(area, &conf->area_list, entry)
+ rde_summary_update(r, area);
+
if (r->d_type != DT_NET)
continue;