The way lsacks were generated always bugged me. I was not happy how the
packets were filled.  This new version is more like the lsupdate code.
This removes another READ_BUF_SIZE and kills the stupid PKG_DEF_SIZE
define.  In the end nothing should change.

OK?
-- 
:wq Claudio

Index: lsack.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/lsack.c,v
retrieving revision 1.19
diff -u -p -r1.19 lsack.c
--- lsack.c     26 May 2010 13:56:08 -0000      1.19
+++ lsack.c     4 Mar 2011 13:57:24 -0000
@@ -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, str
        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, voi
 {
        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, voi
                                        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
Index: ospf.h
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospf.h,v
retrieving revision 1.19
diff -u -p -r1.19 ospf.h
--- ospf.h      26 Jun 2010 18:02:07 -0000      1.19
+++ ospf.h      17 Feb 2011 19:19:19 -0000
@@ -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
Index: ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v
retrieving revision 1.78
diff -u -p -r1.78 ospfe.c
--- ospfe.c     8 Mar 2011 10:56:02 -0000       1.78
+++ ospfe.c     9 Mar 2011 18:20:00 -0000
@@ -641,7 +641,7 @@ ospfe_dispatch_rde(int fd, short event, 
                                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;
Index: ospfe.h
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfe.h,v
retrieving revision 1.42
diff -u -p -r1.42 ospfe.h
--- ospfe.h     26 May 2010 13:56:08 -0000      1.42
+++ ospfe.h     17 Feb 2011 19:19:19 -0000
@@ -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 *);

Reply via email to