]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospf6d/ospf6_message.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / ospf6d / ospf6_message.c
index ae7f16a9f61ebdc951a6e1db51da65beced7a8be..b7f261fcf9954de0ee8897a7a417665aea120117 100644 (file)
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (C) 2003 Yasuhiro Ohara
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -28,6 +13,7 @@
 #include "linklist.h"
 #include "lib_errors.h"
 #include "checksum.h"
+#include "network.h"
 
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
@@ -1733,19 +1719,22 @@ static unsigned int iobuflen = 0;
 
 int ospf6_iobuf_size(unsigned int size)
 {
-       uint8_t *recvnew, *sendnew;
+       /* NB: there was previously code here that tried to dynamically size
+        * the buffer for whatever we see in MTU on interfaces.  Which is
+        * _unconditionally wrong_ - we can always receive fragmented IPv6
+        * up to the regular 64k length limit.  (No jumbograms, thankfully.)
+        */
 
-       if (size <= iobuflen)
-               return iobuflen;
+       if (!iobuflen) {
+               /* the + 128 is to have some runway at the end */
+               size_t alloc_size = 65536 + 128;
 
-       recvnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size);
-       sendnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size);
+               assert(!recvbuf && !sendbuf);
 
-       XFREE(MTYPE_OSPF6_MESSAGE, recvbuf);
-       XFREE(MTYPE_OSPF6_MESSAGE, sendbuf);
-       recvbuf = recvnew;
-       sendbuf = sendnew;
-       iobuflen = size;
+               recvbuf = XMALLOC(MTYPE_OSPF6_MESSAGE, alloc_size);
+               sendbuf = XMALLOC(MTYPE_OSPF6_MESSAGE, alloc_size);
+               iobuflen = alloc_size;
+       }
 
        return iobuflen;
 }
@@ -1779,7 +1768,6 @@ static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6)
        memset(&src, 0, sizeof(src));
        memset(&dst, 0, sizeof(dst));
        ifindex = 0;
-       memset(recvbuf, 0, iobuflen);
        iovector[0].iov_base = recvbuf;
        iovector[0].iov_len = iobuflen;
        iovector[1].iov_base = NULL;
@@ -1795,6 +1783,9 @@ static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6)
                return OSPF6_READ_ERROR;
        }
 
+       /* ensure some zeroes past the end, just as a security precaution */
+       memset(recvbuf + len, 0, MIN(128, iobuflen - len));
+
        oi = ospf6_interface_lookup_by_ifindex(ifindex, ospf6->vrf_id);
        if (oi == NULL || oi->area == NULL
            || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
@@ -2010,6 +2001,9 @@ static void ospf6_auth_trailer_copy_keychain_key(struct ospf6_interface *oi)
                         * these values
                         */
                        oi->at_data.hash_algo = key->hash_algo;
+                       if (oi->at_data.auth_key)
+                               XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY,
+                                     oi->at_data.auth_key);
                        oi->at_data.auth_key = XSTRDUP(
                                MTYPE_OSPF6_AUTH_MANUAL_KEY, key->string);
                        oi->at_data.key_id = key->index;
@@ -2081,7 +2075,6 @@ static void ospf6_write(struct thread *thread)
 {
        struct ospf6 *ospf6 = THREAD_ARG(thread);
        struct ospf6_interface *oi;
-       struct ospf6_interface *last_serviced_oi = NULL;
        struct ospf6_header *oh;
        struct ospf6_packet *op;
        struct listnode *node;
@@ -2101,9 +2094,7 @@ static void ospf6_write(struct thread *thread)
        assert(node);
        oi = listgetdata(node);
 
-       while ((pkt_count < ospf6->write_oi_count) && oi
-              && (last_serviced_oi != oi)) {
-
+       while ((pkt_count < ospf6->write_oi_count) && oi) {
                op = ospf6_fifo_head(oi->obuf);
                assert(op);
                assert(op->length >= OSPF6_HEADER_SIZE);
@@ -2216,7 +2207,6 @@ static void ospf6_write(struct thread *thread)
                list_delete_node(ospf6->oi_write_q, node);
                if (ospf6_fifo_head(oi->obuf) == NULL) {
                        oi->on_write_q = 0;
-                       last_serviced_oi = NULL;
                        oi = NULL;
                } else {
                        listnode_add(ospf6->oi_write_q, oi);
@@ -2296,7 +2286,7 @@ static uint16_t ospf6_make_dbdesc(struct ospf6_neighbor *on, struct stream *s)
        /* if this is initial one, initialize sequence number for DbDesc */
        if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
            && (on->dbdesc_seqnum == 0)) {
-               on->dbdesc_seqnum = monotime(NULL);
+               on->dbdesc_seqnum = frr_sequence32_next();
        }
 
        /* reserved */