+// 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>
#include "linklist.h"
#include "lib_errors.h"
#include "checksum.h"
+#include "network.h"
#include "ospf6_proto.h"
#include "ospf6_lsa.h"
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;
}
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;
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)) {
* 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;
{
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;
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);
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);
/* 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 */
struct ospf6_packet *op;
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
- on->thread_send_dbdesc = (struct thread *)NULL;
if (on->state < OSPF6_NEIGHBOR_EXSTART) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_DBDESC, SEND))
uint16_t length = OSPF6_HEADER_SIZE;
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
- on->thread_send_lsreq = (struct thread *)NULL;
/* LSReq will be sent only in ExStart or Loading */
if (on->state != OSPF6_NEIGHBOR_EXCHANGE
int lsa_cnt = 0;
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
- on->thread_send_lsupdate = (struct thread *)NULL;
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND_HDR))
zlog_debug("LSUpdate to neighbor %s", on->name);
int lsa_cnt = 0;
oi = (struct ospf6_interface *)THREAD_ARG(thread);
- oi->thread_send_lsupdate = (struct thread *)NULL;
if (oi->state <= OSPF6_INTERFACE_WAITING) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE,
uint16_t length = OSPF6_HEADER_SIZE;
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
- on->thread_send_lsack = (struct thread *)NULL;
if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND_HDR))
uint16_t length = OSPF6_HEADER_SIZE;
oi = (struct ospf6_interface *)THREAD_ARG(thread);
- oi->thread_send_lsack = (struct thread *)NULL;
if (oi->state <= OSPF6_INTERFACE_WAITING) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND_HDR))