From 32fed393f45c4e09556252fc896e07137d68ba3a Mon Sep 17 00:00:00 2001 From: Emanuele Di Pascale Date: Mon, 20 May 2019 18:03:52 +0200 Subject: [PATCH] isisd: support circuits with mtu > 8192 the buffer to read from the socket when processing an incoming packet was hardcoded to be of size 8192. If the mtu of the interface is greater than that and hello padding is enabled on that circuit, the hello message will be truncated, and this will cause the adjacency establishment to fail. fix this by using a large enough stack buffer instead Signed-off-by: Emanuele Di Pascale --- isisd/isis_pfpacket.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c index 824acd0ff8..ea66e6950e 100644 --- a/isisd/isis_pfpacket.c +++ b/isisd/isis_pfpacket.c @@ -73,7 +73,6 @@ uint8_t ALL_ISS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x05}; uint8_t ALL_ESS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x04}; static uint8_t discard_buff[8192]; -static uint8_t sock_buff[8192]; /* * if level is 0 we are joining p2p multicast @@ -277,19 +276,22 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa) return ISIS_WARNING; } - /* on lan we have to read to the static buff first */ - bytesread = recvfrom(circuit->fd, sock_buff, sizeof(sock_buff), - MSG_DONTWAIT, (struct sockaddr *)&s_addr, - (socklen_t *)&addr_len); + /* Ensure that we have enough space for a pdu padded to fill the mtu */ + unsigned int max_size = + circuit->interface->mtu > circuit->interface->mtu6 + ? circuit->interface->mtu + : circuit->interface->mtu6; + uint8_t temp_buff[max_size]; + bytesread = + recvfrom(circuit->fd, temp_buff, max_size, MSG_DONTWAIT, + (struct sockaddr *)&s_addr, (socklen_t *)&addr_len); if (bytesread < 0) { - zlog_warn("isis_recv_pdu_bcast(): recvfrom() failed"); + zlog_warn("%s: recvfrom() failed", __func__); return ISIS_WARNING; } - /* then we lose the LLC */ - stream_write(circuit->rcv_stream, sock_buff + LLC_LEN, + stream_write(circuit->rcv_stream, temp_buff + LLC_LEN, bytesread - LLC_LEN); - memcpy(ssnpa, &s_addr.sll_addr, s_addr.sll_halen); return ISIS_OK; @@ -337,6 +339,7 @@ int isis_send_pdu_bcast(struct isis_circuit *circuit, int level) { struct msghdr msg; struct iovec iov[2]; + char temp_buff[LLC_LEN]; /* we need to do the LLC in here because of P2P circuits, which will * not need it @@ -361,16 +364,16 @@ int isis_send_pdu_bcast(struct isis_circuit *circuit, int level) /* on a broadcast circuit */ /* first we put the LLC in */ - sock_buff[0] = 0xFE; - sock_buff[1] = 0xFE; - sock_buff[2] = 0x03; + temp_buff[0] = 0xFE; + temp_buff[1] = 0xFE; + temp_buff[2] = 0x03; memset(&msg, 0, sizeof(msg)); msg.msg_name = &sa; msg.msg_namelen = sizeof(struct sockaddr_ll); msg.msg_iov = iov; msg.msg_iovlen = 2; - iov[0].iov_base = sock_buff; + iov[0].iov_base = temp_buff; iov[0].iov_len = LLC_LEN; iov[1].iov_base = circuit->snd_stream->data; iov[1].iov_len = stream_get_endp(circuit->snd_stream); -- 2.39.5