diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2009-01-29 19:07:54 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2009-01-29 19:07:54 +0000 |
commit | 198fcd7564a916694acd172de1b010aeaeba366a (patch) | |
tree | 1091ffd7baa40a08c6ef85e6009406f7383b28eb /usr.sbin/ospf6d | |
parent | 558c6686a2ca3074fb73e5a9511b75cd6ac00ca4 (diff) |
Originate Intra-Area-Prefix LSAs which reference a router LSA.
Routers can now advertise prefixes with global scope throughout
an area. This paves the way towards doing SPF calculations to
generate routing tables for a single area.
ok claudio@
Diffstat (limited to 'usr.sbin/ospf6d')
-rw-r--r-- | usr.sbin/ospf6d/interface.c | 3 | ||||
-rw-r--r-- | usr.sbin/ospf6d/ospfe.c | 106 | ||||
-rw-r--r-- | usr.sbin/ospf6d/ospfe.h | 3 |
3 files changed, 108 insertions, 4 deletions
diff --git a/usr.sbin/ospf6d/interface.c b/usr.sbin/ospf6d/interface.c index a6a3d09abd8..9d58b26fd2c 100644 --- a/usr.sbin/ospf6d/interface.c +++ b/usr.sbin/ospf6d/interface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: interface.c,v 1.10 2009/01/27 21:58:28 stsp Exp $ */ +/* $OpenBSD: interface.c,v 1.11 2009/01/29 19:07:53 stsp Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -142,6 +142,7 @@ if_fsm(struct iface *iface, enum iface_event event) if (iface->state != old_state) { orig_rtr_lsa(iface); orig_link_lsa(iface); + orig_intra_lsa_rtr(iface); } if (old_state & (IF_STA_MULTI | IF_STA_POINTTOPOINT) && diff --git a/usr.sbin/ospf6d/ospfe.c b/usr.sbin/ospf6d/ospfe.c index 9936ad499ec..93f949f4828 100644 --- a/usr.sbin/ospf6d/ospfe.c +++ b/usr.sbin/ospf6d/ospfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.c,v 1.18 2009/01/28 22:47:36 stsp Exp $ */ +/* $OpenBSD: ospfe.c,v 1.19 2009/01/29 19:07:53 stsp Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -296,6 +296,7 @@ ospfe_dispatch_main(int fd, short event, void *bula) if_fsm(iface, IF_EVT_DOWN); log_warnx("interface %s down", iface->name); } + orig_intra_lsa_rtr(iface); break; case IMSG_IFADD: if ((niface = malloc(sizeof(struct iface))) == NULL) @@ -308,6 +309,7 @@ ospfe_dispatch_main(int fd, short event, void *bula) narea = area_find(oeconf, niface->area_id); LIST_INSERT_HEAD(&narea->iface_list, niface, entry); + orig_intra_lsa_rtr(niface); break; case IMSG_IFDELETE: if (imsg.hdr.len != IMSG_HEADER_SIZE + @@ -320,6 +322,7 @@ ospfe_dispatch_main(int fd, short event, void *bula) fatalx("interface lost in ospfe"); LIST_REMOVE(iface, entry); + orig_intra_lsa_rtr(iface); if_del(iface); break; case IMSG_RECONF_CONF: @@ -1022,7 +1025,8 @@ orig_link_lsa(struct iface *iface) log_debug("orig_link_lsa: prefix %s", log_in6addr(&prefix)); if (buf_add(buf, &lsa_prefix, sizeof(lsa_prefix))) fatal("orig_link_lsa: buf_add failed"); - if (buf_add(buf, &prefix, LSA_PREFIXSIZE(ia->prefixlen))) + if (buf_add(buf, &prefix.s6_addr[0], + LSA_PREFIXSIZE(ia->prefixlen))) fatal("orig_link_lsa: buf_add failed"); num_prefix++; } @@ -1057,6 +1061,104 @@ orig_link_lsa(struct iface *iface) buf_free(buf); } +void +orig_intra_lsa_rtr(struct iface *iface_arg) +{ + struct lsa_hdr lsa_hdr; + struct lsa_intra_prefix lsa_intra; + struct lsa_prefix lsa_prefix; + struct in6_addr prefix; + struct buf *buf; + struct area *area; + struct iface *iface; + struct iface_addr *ia; + struct nbr *self; + u_int16_t numprefix; + u_int16_t chksum; + + /* XXX READ_BUF_SIZE */ + if ((buf = buf_dynamic(sizeof(lsa_hdr) + sizeof(lsa_intra), + READ_BUF_SIZE)) == NULL) + fatal("orig_intra_lsa_rtr"); + + /* reserve space for LSA header and Intra-Area-Prefix LSA header */ + if (buf_reserve(buf, sizeof(lsa_hdr) + sizeof(lsa_intra)) == NULL) + fatal("orig_intra_lsa_rtr: buf_reserve failed"); + + lsa_intra.ref_type = htons(LSA_TYPE_ROUTER); + lsa_intra.ref_lsid = 0; + lsa_intra.ref_adv_rtr = oeconf->rtr_id.s_addr; + + numprefix = 0; + self = NULL; + + if ((area = area_find(oeconf, iface_arg->area_id)) == NULL) + fatalx("interface lost area"); + + log_debug("orig_intra_lsa_rtr: area %s", inet_ntoa(area->id)); + + LIST_FOREACH(iface, &area->iface_list, entry) { + if (self == NULL && iface->self != NULL) + self = iface->self; + + if (iface->state & IF_STA_DOWN) + continue; + + TAILQ_FOREACH(ia, &iface->ifa_list, entry) { + if (IN6_IS_ADDR_LINKLOCAL(&ia->addr)) + continue; + + bzero(&lsa_prefix, sizeof(lsa_prefix)); + + if (iface->type == IF_TYPE_POINTOMULTIPOINT + || iface->state == IF_STA_LOOPBACK) { + lsa_prefix.prefixlen = 128; + lsa_prefix.options = OSPF_PREFIX_LA; + } else { + lsa_prefix.prefixlen = ia->prefixlen; + lsa_prefix.metric = htons(iface->metric); + } + + inet6applymask(&prefix, &ia->addr, lsa_prefix.prefixlen); + log_debug("orig_intra_lsa_rtr: prefix %s, interface %s", + log_in6addr(&prefix), iface->name); + if (buf_add(buf, &lsa_prefix, sizeof(lsa_prefix))) + fatal("orig_intra_lsa_rtr: buf_add failed"); + if (buf_add(buf, &prefix.s6_addr[0], + LSA_PREFIXSIZE(lsa_prefix.prefixlen))) + fatal("orig_intra_lsa_rtr: buf_add failed"); + numprefix++; + } + + /* TOD: Add prefixes of directly attached hosts, too */ + /* TOD: Add prefixes for virtual links */ + } + + lsa_intra.numprefix = htons(numprefix); + memcpy(buf_seek(buf, sizeof(lsa_hdr), sizeof(lsa_intra)), + &lsa_intra, sizeof(lsa_intra)); + + /* LSA header */ + lsa_hdr.age = htons(DEFAULT_AGE); + lsa_hdr.type = htons(LSA_TYPE_INTRA_A_PREFIX); + lsa_hdr.ls_id = 1; /* TODO: fragmentation */ + lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr; + lsa_hdr.seq_num = htonl(INIT_SEQ_NUM); + lsa_hdr.len = htons(buf->wpos); + lsa_hdr.ls_chksum = 0; /* updated later */ + memcpy(buf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr)); + + chksum = htons(iso_cksum(buf->buf, buf->wpos, LS_CKSUM_OFFSET)); + memcpy(buf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)), + &chksum, sizeof(chksum)); + + if (self) + imsg_compose(ibuf_rde, IMSG_LS_UPD, self->peerid, 0, + buf->buf, buf->wpos); + + buf_free(buf); +} + u_int32_t ospfe_router_id(void) { diff --git a/usr.sbin/ospf6d/ospfe.h b/usr.sbin/ospf6d/ospfe.h index 74fa0dd3edb..de492bc41c3 100644 --- a/usr.sbin/ospf6d/ospfe.h +++ b/usr.sbin/ospf6d/ospfe.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.h,v 1.12 2009/01/27 21:58:28 stsp Exp $ */ +/* $OpenBSD: ospfe.h,v 1.13 2009/01/29 19:07:53 stsp Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -123,6 +123,7 @@ void ospfe_nbr_ctl(struct ctl_conn *); void orig_rtr_lsa(struct iface *); void orig_net_lsa(struct iface *); void orig_link_lsa(struct iface *); +void orig_intra_lsa_rtr(struct iface *); void ospfe_demote_area(struct area *, int); void ospfe_demote_iface(struct iface *, int); |