diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-03-25 08:52:22 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-03-25 08:52:22 +0000 |
commit | 6dbd8762909d18f1450d23bcbf5b9980824df4c6 (patch) | |
tree | 52ef0dfae8ff02b3898a0b85ec54898e12bdb6c0 | |
parent | 11590058261f6c91bbf847f54be36f51364f28c2 (diff) |
Rewrite the lsack generation. Make it more like the lsupdate code.
Removes some of the rather strange packet handling.
Tested by a few especially sthen@
-rw-r--r-- | usr.sbin/ospfd/lsack.c | 117 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospf.h | 4 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfe.c | 4 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfe.h | 4 |
4 files changed, 77 insertions, 52 deletions
diff --git a/usr.sbin/ospfd/lsack.c b/usr.sbin/ospfd/lsack.c index 2d0236c338b..446947dba4a 100644 --- a/usr.sbin/ospfd/lsack.c +++ b/usr.sbin/ospfd/lsack.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lsack.c,v 1.19 2010/05/26 13:56:08 nicm Exp $ */ +/* $OpenBSD: lsack.c,v 1.20 2011/03/25 08:52:21 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -31,44 +31,70 @@ #include "log.h" #include "ospfe.h" -void start_ls_ack_tx_timer_now(struct iface *); +int send_ls_ack(struct iface *, struct in_addr, struct ibuf *); +struct ibuf *prepare_ls_ack(struct iface *); +void start_ls_ack_tx_timer_now(struct iface *); /* link state acknowledgement packet handling */ +struct ibuf * +prepare_ls_ack(struct iface *iface) +{ + struct ibuf *buf; + + if ((buf = ibuf_open(iface->mtu - sizeof(struct ip))) == NULL) { + log_warn("prepare_ls_ack"); + return (NULL); + } + + /* OSPF header */ + if (gen_ospf_hdr(buf, iface, PACKET_TYPE_LS_ACK)) { + log_warn("prepare_ls_ack"); + ibuf_free(buf); + return (NULL); + } + + return (buf); +} + int -send_ls_ack(struct iface *iface, struct in_addr addr, void *data, size_t len) +send_ls_ack(struct iface *iface, struct in_addr addr, struct ibuf *buf) { - struct sockaddr_in dst; - struct ibuf *buf; - int ret; + struct sockaddr_in dst; + int ret; - /* XXX IBUF_READ_SIZE */ - if ((buf = ibuf_dynamic(PKG_DEF_SIZE, READ_BUF_SIZE)) == NULL) - fatal("send_ls_ack"); + /* update authentication and calculate checksum */ + if (auth_gen(buf, iface)) { + log_warn("send_ls_ack"); + return (-1); + } dst.sin_family = AF_INET; dst.sin_len = sizeof(struct sockaddr_in); dst.sin_addr.s_addr = addr.s_addr; - /* OSPF header */ - if (gen_ospf_hdr(buf, iface, PACKET_TYPE_LS_ACK)) - goto fail; + ret = send_packet(iface, buf, &dst); + return (ret); +} - /* LS ack(s) */ - if (ibuf_add(buf, data, len)) - goto fail; +int +send_direct_ack(struct iface *iface, struct in_addr addr, void *d, size_t len) +{ + struct ibuf *buf; + int ret; - /* update authentication and calculate checksum */ - if (auth_gen(buf, iface)) - goto fail; + if ((buf = prepare_ls_ack(iface)) == NULL) + return (-1); - ret = send_packet(iface, buf, &dst); + /* LS ack(s) */ + if (ibuf_add(buf, d, len)) { + log_warn("send_direct_ack"); + ibuf_free(buf); + return (-1); + } + ret = send_ls_ack(iface, addr, buf); ibuf_free(buf); return (ret); -fail: - log_warn("send_ls_ack"); - ibuf_free(buf); - return (-1); } void @@ -168,12 +194,9 @@ ls_ack_list_add(struct iface *iface, struct lsa_hdr *lsa) le->le_lsa = lsa; iface->ls_ack_cnt++; - /* reschedule now if we have enough for a full packet */ - if (iface->ls_ack_cnt > - ((iface->mtu - PACKET_HDR) / sizeof(struct lsa_hdr))) { + /* reschedule now if we have enough for a reasonably sized packet */ + if (iface->ls_ack_cnt > IP_MSS / sizeof(struct lsa_hdr)) start_ls_ack_tx_timer_now(iface); - } - } void @@ -212,40 +235,45 @@ ls_ack_tx_timer(int fd, short event, void *arg) { struct in_addr addr; struct iface *iface = arg; - struct lsa_hdr *lsa_hdr; struct lsa_entry *le, *nle; struct nbr *nbr; - char *buf; - char *ptr; - int cnt = 0; - - if ((buf = calloc(1, READ_BUF_SIZE)) == NULL) - fatal("ls_ack_tx_timer"); + struct ibuf *buf; + int cnt; while (!ls_ack_list_empty(iface)) { - ptr = buf; + if ((buf = prepare_ls_ack(iface)) == NULL) + fatal("ls_ack_tx_timer"); cnt = 0; - for (le = TAILQ_FIRST(&iface->ls_ack_list); le != NULL && - (ptr - buf < iface->mtu - PACKET_HDR); le = nle) { + + for (le = TAILQ_FIRST(&iface->ls_ack_list); le != NULL; + le = nle) { nle = TAILQ_NEXT(le, entry); - memcpy(ptr, le->le_lsa, sizeof(struct lsa_hdr)); - ptr += sizeof(*lsa_hdr); + if (ibuf_left(buf) < sizeof(struct lsa_hdr) + + MD5_DIGEST_LENGTH) + break; + if (ibuf_add(buf, le->le_lsa, sizeof(struct lsa_hdr))) + break; ls_ack_list_free(iface, le); cnt++; } + if (cnt == 0) { + log_warnx("ls_ack_tx_timer: lost in space"); + ibuf_free(buf); + return; + } /* send LS ack(s) but first set correct destination */ switch (iface->type) { case IF_TYPE_POINTOPOINT: inet_aton(AllSPFRouters, &addr); - send_ls_ack(iface, addr, buf, ptr - buf); + send_ls_ack(iface, addr, buf); break; case IF_TYPE_BROADCAST: if (iface->state & IF_STA_DRORBDR) inet_aton(AllSPFRouters, &addr); else inet_aton(AllDRouters, &addr); - send_ls_ack(iface, addr, buf, ptr - buf); + send_ls_ack(iface, addr, buf); break; case IF_TYPE_NBMA: case IF_TYPE_POINTOMULTIPOINT: @@ -255,15 +283,14 @@ ls_ack_tx_timer(int fd, short event, void *arg) continue; if (!(nbr->state & NBR_STA_FLOOD)) continue; - send_ls_ack(iface, nbr->addr, buf, ptr - buf); + send_ls_ack(iface, nbr->addr, buf); } break; default: fatalx("lsa_ack_tx_timer: unknown interface type"); } + ibuf_free(buf); } - - free(buf); } void diff --git a/usr.sbin/ospfd/ospf.h b/usr.sbin/ospfd/ospf.h index 740fb4e8ad8..7d2d6b1be61 100644 --- a/usr.sbin/ospfd/ospf.h +++ b/usr.sbin/ospfd/ospf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospf.h,v 1.19 2010/06/26 18:02:07 guenther Exp $ */ +/* $OpenBSD: ospf.h,v 1.20 2011/03/25 08:52:21 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -30,8 +30,6 @@ #define AllSPFRouters "224.0.0.5" #define AllDRouters "224.0.0.6" -#define PACKET_HDR 100 /* XXX used to calculate the IP payload */ - #define DEFAULT_METRIC 10 #define DEFAULT_REDIST_METRIC 100 #define MIN_METRIC 1 diff --git a/usr.sbin/ospfd/ospfe.c b/usr.sbin/ospfd/ospfe.c index f0fa84887bc..dafa545e9d4 100644 --- a/usr.sbin/ospfd/ospfe.c +++ b/usr.sbin/ospfd/ospfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.c,v 1.79 2011/03/24 08:35:59 claudio Exp $ */ +/* $OpenBSD: ospfe.c,v 1.80 2011/03/25 08:52:21 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -643,7 +643,7 @@ ospfe_dispatch_rde(int fd, short event, void *bula) break; /* send a direct acknowledgement */ - send_ls_ack(nbr->iface, nbr->addr, imsg.data, + send_direct_ack(nbr->iface, nbr->addr, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); break; diff --git a/usr.sbin/ospfd/ospfe.h b/usr.sbin/ospfd/ospfe.h index b6fe009b8ce..fadd896869c 100644 --- a/usr.sbin/ospfd/ospfe.h +++ b/usr.sbin/ospfd/ospfe.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.h,v 1.42 2010/05/26 13:56:08 nicm Exp $ */ +/* $OpenBSD: ospfe.h,v 1.43 2011/03/25 08:52:21 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -157,7 +157,7 @@ int if_set_ip_hdrincl(int); /* lsack.c */ int delay_lsa_ack(struct iface *, struct lsa_hdr *); -int send_ls_ack(struct iface *, struct in_addr, void *, size_t); +int send_direct_ack(struct iface *, struct in_addr, void *, size_t); void recv_ls_ack(struct nbr *, char *, u_int16_t); int lsa_hdr_check(struct nbr *, struct lsa_hdr *); void ls_ack_list_add(struct iface *, struct lsa_hdr *); |