]> git.proxmox.com Git - mirror_frr.git/blobdiff - isisd/isis_pfpacket.c
Merge pull request #5280 from qlyoung/doc-clean-topotest-json
[mirror_frr.git] / isisd / isis_pfpacket.c
index 6e56870ebd8c432b1236f86f85bd222445a70e01..69ac3fc555b93e4401956a4362cb3ccad046a1cf 100644 (file)
@@ -31,8 +31,8 @@
 #include "network.h"
 #include "stream.h"
 #include "if.h"
+#include "lib_errors.h"
 
-#include "isisd/dict.h"
 #include "isisd/isis_constants.h"
 #include "isisd/isis_common.h"
 #include "isisd/isis_circuit.h"
@@ -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
@@ -184,35 +183,30 @@ int isis_sock_init(struct isis_circuit *circuit)
 {
        int retval = ISIS_OK;
 
-       if (isisd_privs.change(ZPRIVS_RAISE))
-               zlog_err("%s: could not raise privs, %s", __func__,
-                        safe_strerror(errno));
+       frr_with_privs(&isisd_privs) {
 
-       retval = open_packet_socket(circuit);
+               retval = open_packet_socket(circuit);
 
-       if (retval != ISIS_OK) {
-               zlog_warn("%s: could not initialize the socket", __func__);
-               goto end;
-       }
+               if (retval != ISIS_OK) {
+                       zlog_warn("%s: could not initialize the socket",
+                                 __func__);
+                       break;
+               }
 
        /* Assign Rx and Tx callbacks are based on real if type */
-       if (if_is_broadcast(circuit->interface)) {
-               circuit->tx = isis_send_pdu_bcast;
-               circuit->rx = isis_recv_pdu_bcast;
-       } else if (if_is_pointopoint(circuit->interface)) {
-               circuit->tx = isis_send_pdu_p2p;
-               circuit->rx = isis_recv_pdu_p2p;
-       } else {
-               zlog_warn("isis_sock_init(): unknown circuit type");
-               retval = ISIS_WARNING;
-               goto end;
+               if (if_is_broadcast(circuit->interface)) {
+                       circuit->tx = isis_send_pdu_bcast;
+                       circuit->rx = isis_recv_pdu_bcast;
+               } else if (if_is_pointopoint(circuit->interface)) {
+                       circuit->tx = isis_send_pdu_p2p;
+                       circuit->rx = isis_recv_pdu_p2p;
+               } else {
+                       zlog_warn("isis_sock_init(): unknown circuit type");
+                       retval = ISIS_WARNING;
+                       break;
+               }
        }
 
-end:
-       if (isisd_privs.change(ZPRIVS_LOWER))
-               zlog_err("%s: could not lower privs, %s", __func__,
-                        safe_strerror(errno));
-
        return retval;
 }
 
@@ -282,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;
@@ -309,9 +306,9 @@ int isis_recv_pdu_p2p(struct isis_circuit *circuit, uint8_t *ssnpa)
        addr_len = sizeof(s_addr);
 
        /* we can read directly to the stream */
-       stream_recvfrom(circuit->rcv_stream, circuit->fd,
-                       circuit->interface->mtu, 0, (struct sockaddr *)&s_addr,
-                       (socklen_t *)&addr_len);
+       (void)stream_recvfrom(
+               circuit->rcv_stream, circuit->fd, circuit->interface->mtu, 0,
+               (struct sockaddr *)&s_addr, (socklen_t *)&addr_len);
 
        if (s_addr.sll_pkttype == PACKET_OUTGOING) {
                /*  Read the packet into discard buff */
@@ -342,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
@@ -366,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);