diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-05-23 23:03:08 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-05-23 23:03:08 +0000 |
commit | 6f7a36a599f19f7166afe18d1defb7b0b873ecba (patch) | |
tree | a9688359456bad806c2698020a65e7c0f63b112f | |
parent | c3a576547178aad45c98a699c8bf2d35d59ae665 (diff) |
First part of summary LSA origination. Not perfect but a start.
OK norby@
-rw-r--r-- | usr.sbin/ospfd/rde.c | 98 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde.h | 3 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde_spf.c | 8 |
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; |