]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: support circuits with mtu > 8192
authorEmanuele Di Pascale <emanuele@voltanet.io>
Mon, 20 May 2019 16:03:52 +0000 (18:03 +0200)
committerEmanuele Di Pascale <emanuele@voltanet.io>
Thu, 23 May 2019 13:50:31 +0000 (15:50 +0200)
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 <emanuele@voltanet.io>
isisd/isis_pfpacket.c

index 824acd0ff80f493ada4f48f60198515f5a550a21..ea66e6950e68d8c0516297f1bdc1aa8ea6d89164 100644 (file)
@@ -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);