summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2011-03-25 08:52:22 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2011-03-25 08:52:22 +0000
commit6dbd8762909d18f1450d23bcbf5b9980824df4c6 (patch)
tree52ef0dfae8ff02b3898a0b85ec54898e12bdb6c0
parent11590058261f6c91bbf847f54be36f51364f28c2 (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.c117
-rw-r--r--usr.sbin/ospfd/ospf.h4
-rw-r--r--usr.sbin/ospfd/ospfe.c4
-rw-r--r--usr.sbin/ospfd/ospfe.h4
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 *);