mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 16:57:44 +00:00
ospf6d: read ospf6 socket until failure
To ensure we read all the datagrams availabe from a socket when the read task is scheduled, make the read helper return and error or continue enum and loop unitl an error is received. This requires the read from the socket to be non blocking Signed-off-by: Pat Ruddy <pat@voltanet.io>
This commit is contained in:
parent
ec44732ea3
commit
aa6a96ba78
@ -1572,9 +1572,14 @@ void ospf6_message_terminate(void)
|
||||
iobuflen = 0;
|
||||
}
|
||||
|
||||
enum ospf6_read_return_enum {
|
||||
OSPF6_READ_ERROR,
|
||||
OSPF6_READ_CONTINUE,
|
||||
};
|
||||
|
||||
static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6)
|
||||
{
|
||||
unsigned int len;
|
||||
int len;
|
||||
struct in6_addr src, dst;
|
||||
ifindex_t ifindex;
|
||||
struct iovec iovector[2];
|
||||
@ -1593,9 +1598,12 @@ static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6)
|
||||
|
||||
/* receive message */
|
||||
len = ospf6_recvmsg(&src, &dst, &ifindex, iovector, sockfd);
|
||||
if (len > iobuflen) {
|
||||
if (len < 0)
|
||||
return OSPF6_READ_ERROR;
|
||||
|
||||
if ((uint)len > iobuflen) {
|
||||
flog_err(EC_LIB_DEVELOPMENT, "Excess message read");
|
||||
return 0;
|
||||
return OSPF6_READ_ERROR;
|
||||
}
|
||||
|
||||
oi = ospf6_interface_lookup_by_ifindex(ifindex, ospf6->vrf_id);
|
||||
@ -1604,19 +1612,19 @@ static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6)
|
||||
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
|
||||
RECV_HDR))
|
||||
zlog_debug("Message received on disabled interface");
|
||||
return 0;
|
||||
return OSPF6_READ_CONTINUE;
|
||||
}
|
||||
if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)) {
|
||||
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
|
||||
RECV_HDR))
|
||||
zlog_debug("%s: Ignore message on passive interface %s",
|
||||
__func__, oi->interface->name);
|
||||
return 0;
|
||||
return OSPF6_READ_CONTINUE;
|
||||
}
|
||||
|
||||
oh = (struct ospf6_header *)recvbuf;
|
||||
if (ospf6_rxpacket_examin(oi, oh, len) != MSG_OK)
|
||||
return 0;
|
||||
return OSPF6_READ_CONTINUE;
|
||||
|
||||
/* Being here means, that no sizing/alignment issues were detected in
|
||||
the input packet. This renders the additional checks performed below
|
||||
@ -1677,13 +1685,14 @@ static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return OSPF6_READ_CONTINUE;
|
||||
}
|
||||
|
||||
int ospf6_receive(struct thread *thread)
|
||||
{
|
||||
int sockfd;
|
||||
struct ospf6 *ospf6;
|
||||
int count = 0;
|
||||
|
||||
/* add next read thread */
|
||||
ospf6 = THREAD_ARG(thread);
|
||||
@ -1692,7 +1701,17 @@ int ospf6_receive(struct thread *thread)
|
||||
thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
|
||||
&ospf6->t_ospf6_receive);
|
||||
|
||||
return ospf6_read_helper(sockfd, ospf6);
|
||||
while (count < 20) {
|
||||
count++;
|
||||
switch (ospf6_read_helper(sockfd, ospf6)) {
|
||||
case OSPF6_READ_ERROR:
|
||||
return 0;
|
||||
case OSPF6_READ_CONTINUE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ospf6_send(struct in6_addr *src, struct in6_addr *dst,
|
||||
|
@ -257,10 +257,13 @@ int ospf6_recvmsg(struct in6_addr *src, struct in6_addr *dst,
|
||||
rmsghdr.msg_control = (caddr_t)cmsgbuf;
|
||||
rmsghdr.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
retval = recvmsg(ospf6_sock, &rmsghdr, 0);
|
||||
if (retval < 0)
|
||||
zlog_warn("recvmsg failed: %s", safe_strerror(errno));
|
||||
else if (retval == iov_totallen(message))
|
||||
retval = recvmsg(ospf6_sock, &rmsghdr, MSG_DONTWAIT);
|
||||
if (retval < 0) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
zlog_warn("stream_recvmsg failed: %s",
|
||||
safe_strerror(errno));
|
||||
return retval;
|
||||
} else if (retval == iov_totallen(message))
|
||||
zlog_warn("recvmsg read full buffer size: %d", retval);
|
||||
|
||||
/* source address */
|
||||
|
Loading…
Reference in New Issue
Block a user