Diff for /embedaddon/quagga/isisd/isis_pfpacket.c between versions 1.1 and 1.1.1.4

version 1.1, 2012/02/21 17:26:11 version 1.1.1.4, 2016/11/02 10:09:10
Line 26 Line 26
 #include <netpacket/packet.h>  #include <netpacket/packet.h>
   
 #include "log.h"  #include "log.h"
   #include "network.h"
 #include "stream.h"  #include "stream.h"
 #include "if.h"  #include "if.h"
   
Line 54  u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, Line 55  u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00,
 u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 };  u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 };
 u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 };  u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 };
   
static char discard_buff[8192];static uint8_t discard_buff[8192];
static char sock_buff[8192];static uint8_t sock_buff[8192];
   
 /*  /*
  * if level is 0 we are joining p2p multicast   * if level is 0 we are joining p2p multicast
Line 129  open_packet_socket (struct isis_circuit *circuit) Line 130  open_packet_socket (struct isis_circuit *circuit)
             sizeof (struct sockaddr_ll)) < 0)              sizeof (struct sockaddr_ll)) < 0)
     {      {
       zlog_warn ("open_packet_socket(): bind() failed: %s", safe_strerror (errno));        zlog_warn ("open_packet_socket(): bind() failed: %s", safe_strerror (errno));
         close (fd);
       return ISIS_WARNING;        return ISIS_WARNING;
     }      }
   
   circuit->fd = fd;    circuit->fd = fd;
   
  if (circuit->circ_type == CIRCUIT_T_BROADCAST)  if (if_is_broadcast (circuit->interface))
     {      {
       /*        /*
        * Join to multicast groups         * Join to multicast groups
Line 142  open_packet_socket (struct isis_circuit *circuit) Line 144  open_packet_socket (struct isis_circuit *circuit)
        * 8.4.2 - Broadcast subnetwork IIH PDUs         * 8.4.2 - Broadcast subnetwork IIH PDUs
        * FIXME: is there a case only one will fail??         * FIXME: is there a case only one will fail??
        */         */
      if (circuit->circuit_is_type & IS_LEVEL_1)      /* joining ALL_L1_ISS */
        {      retval |= isis_multicast_join (circuit->fd, 1,
          /* joining ALL_L1_ISS */                                      circuit->interface->ifindex);
          retval = isis_multicast_join (circuit->fd, 1,      /* joining ALL_L2_ISS */
                                        circuit->interface->ifindex);      retval |= isis_multicast_join (circuit->fd, 2,
          /* joining ALL_ISS */                                      circuit->interface->ifindex);
          retval = isis_multicast_join (circuit->fd, 3,      /* joining ALL_ISS (used in RFC 5309 p2p-over-lan as well) */
                                        circuit->interface->ifindex);      retval |= isis_multicast_join (circuit->fd, 3,
        }                                    circuit->interface->ifindex);
      if (circuit->circuit_is_type & IS_LEVEL_2) 
        /* joining ALL_L2_ISS */ 
        retval = isis_multicast_join (circuit->fd, 2, 
                                      circuit->interface->ifindex); 
     }      }
   else    else
     {      {
       retval =        retval =
        isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);        isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
     }      }
   
   return retval;    return retval;
Line 184  isis_sock_init (struct isis_circuit *circuit) Line 182  isis_sock_init (struct isis_circuit *circuit)
       goto end;        goto end;
     }      }
   
  if (circuit->circ_type == CIRCUIT_T_BROADCAST)  /* Assign Rx and Tx callbacks are based on real if type */
   if (if_is_broadcast (circuit->interface))
     {      {
       circuit->tx = isis_send_pdu_bcast;        circuit->tx = isis_send_pdu_bcast;
       circuit->rx = isis_recv_pdu_bcast;        circuit->rx = isis_recv_pdu_bcast;
     }      }
  else if (circuit->circ_type == CIRCUIT_T_P2P)  else if (if_is_pointopoint (circuit->interface))
     {      {
       circuit->tx = isis_send_pdu_p2p;        circuit->tx = isis_send_pdu_p2p;
       circuit->rx = isis_recv_pdu_p2p;        circuit->rx = isis_recv_pdu_p2p;
Line 232  isis_recv_pdu_bcast (struct isis_circuit *circuit, u_c Line 231  isis_recv_pdu_bcast (struct isis_circuit *circuit, u_c
                         LLC_LEN, MSG_PEEK,                          LLC_LEN, MSG_PEEK,
                         (struct sockaddr *) &s_addr, (socklen_t *) &addr_len);                          (struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
   
  if (!circuit->area) {  if ((bytesread < 0) || (s_addr.sll_ifindex != (int)circuit->interface->ifindex))
    return ISIS_OK; 
  } 
 
  if (bytesread < 0) 
     {      {
      zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",      if (bytesread < 0)
                 circuit->fd, safe_strerror (errno));        {
      zlog_warn ("circuit is %s", circuit->interface->name);          zlog_warn ("isis_recv_packet_bcast(): ifname %s, fd %d, "
      zlog_warn ("circuit fd %d", circuit->fd);                     "bytesread %d, recvfrom(): %s",
      zlog_warn ("bytesread %d", bytesread);                     circuit->interface->name, circuit->fd, bytesread,
                      safe_strerror (errno));
         }
       if (s_addr.sll_ifindex != (int)circuit->interface->ifindex)
         {
           zlog_warn("packet is received on multiple interfaces: "
                     "socket interface %d, circuit interface %d, "
                     "packet type %u",
                     s_addr.sll_ifindex, circuit->interface->ifindex,
                     s_addr.sll_pkttype);
         }
 
       /* get rid of the packet */        /* get rid of the packet */
      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));      bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff),
                             MSG_DONTWAIT, (struct sockaddr *) &s_addr,
                             (socklen_t *) &addr_len);
       return ISIS_WARNING;        return ISIS_WARNING;
     }      }
   /*    /*
Line 253  isis_recv_pdu_bcast (struct isis_circuit *circuit, u_c Line 261  isis_recv_pdu_bcast (struct isis_circuit *circuit, u_c
   if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING)    if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING)
     {      {
       /*  Read the packet into discard buff */        /*  Read the packet into discard buff */
      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));      bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff),
                             MSG_DONTWAIT, (struct sockaddr *) &s_addr,
                             (socklen_t *) &addr_len);
       if (bytesread < 0)        if (bytesread < 0)
        zlog_warn ("isis_recv_pdu_bcast(): read() failed");        zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed");
       return ISIS_WARNING;        return ISIS_WARNING;
     }      }
   
   /* on lan we have to read to the static buff first */    /* on lan we have to read to the static buff first */
  bytesread = recvfrom (circuit->fd, sock_buff, circuit->interface->mtu, 0,  bytesread = recvfrom (circuit->fd, sock_buff, sizeof (sock_buff), MSG_DONTWAIT,
                         (struct sockaddr *) &s_addr, (socklen_t *) &addr_len);                          (struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
     if (bytesread < 0)
       {
         zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed");
         return ISIS_WARNING;
       }
   
   /* then we lose the LLC */    /* then we lose the LLC */
   stream_write (circuit->rcv_stream, sock_buff + LLC_LEN, bytesread - LLC_LEN);    stream_write (circuit->rcv_stream, sock_buff + LLC_LEN, bytesread - LLC_LEN);
Line 289  isis_recv_pdu_p2p (struct isis_circuit *circuit, u_cha Line 304  isis_recv_pdu_p2p (struct isis_circuit *circuit, u_cha
   if (s_addr.sll_pkttype == PACKET_OUTGOING)    if (s_addr.sll_pkttype == PACKET_OUTGOING)
     {      {
       /*  Read the packet into discard buff */        /*  Read the packet into discard buff */
      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));      bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff),
                             MSG_DONTWAIT, (struct sockaddr *) &s_addr,
                             (socklen_t *) &addr_len);
       if (bytesread < 0)        if (bytesread < 0)
        zlog_warn ("isis_recv_pdu_p2p(): read() failed");        zlog_warn ("isis_recv_pdu_p2p(): recvfrom() failed");
       return ISIS_WARNING;        return ISIS_WARNING;
     }      }
   
Line 313  isis_recv_pdu_p2p (struct isis_circuit *circuit, u_cha Line 330  isis_recv_pdu_p2p (struct isis_circuit *circuit, u_cha
 int  int
 isis_send_pdu_bcast (struct isis_circuit *circuit, int level)  isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
 {  {
     struct msghdr msg;
     struct iovec iov[2];
   
   /* we need to do the LLC in here because of P2P circuits, which will    /* we need to do the LLC in here because of P2P circuits, which will
    * not need it     * not need it
    */     */
   int written = 1;  
   struct sockaddr_ll sa;    struct sockaddr_ll sa;
   
   stream_set_getp (circuit->snd_stream, 0);    stream_set_getp (circuit->snd_stream, 0);
Line 325  isis_send_pdu_bcast (struct isis_circuit *circuit, int Line 344  isis_send_pdu_bcast (struct isis_circuit *circuit, int
   sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);    sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
   sa.sll_ifindex = circuit->interface->ifindex;    sa.sll_ifindex = circuit->interface->ifindex;
   sa.sll_halen = ETH_ALEN;    sa.sll_halen = ETH_ALEN;
  if (level == 1)  /* RFC5309 section 4.1 recommends ALL_ISS */
   if (circuit->circ_type == CIRCUIT_T_P2P)
     memcpy (&sa.sll_addr, ALL_ISS, ETH_ALEN);
   else if (level == 1)
     memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);      memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
   else    else
     memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);      memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);
Line 336  isis_send_pdu_bcast (struct isis_circuit *circuit, int Line 358  isis_send_pdu_bcast (struct isis_circuit *circuit, int
   sock_buff[1] = 0xFE;    sock_buff[1] = 0xFE;
   sock_buff[2] = 0x03;    sock_buff[2] = 0x03;
   
  /* then we copy the data */  memset (&msg, 0, sizeof (msg));
  memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data,  msg.msg_name = &sa;
          stream_get_endp (circuit->snd_stream));  msg.msg_namelen = sizeof (struct sockaddr_ll);
   msg.msg_iov = iov;
   msg.msg_iovlen = 2;
   iov[0].iov_base = sock_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);
   
  /* now we can send this */  if (sendmsg(circuit->fd, &msg, 0) < 0)
  written = sendto (circuit->fd, sock_buff,    {
                    stream_get_endp(circuit->snd_stream) + LLC_LEN, 0,      zlog_warn("IS-IS pfpacket: could not transmit packet on %s: %s",
                    (struct sockaddr *) &sa, sizeof (struct sockaddr_ll));                circuit->interface->name, safe_strerror(errno));
      if (ERRNO_IO_RETRY(errno))
         return ISIS_WARNING;
       return ISIS_ERROR;
     }
   return ISIS_OK;    return ISIS_OK;
 }  }
   
 int  int
 isis_send_pdu_p2p (struct isis_circuit *circuit, int level)  isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
 {  {
   
   int written = 1;  
   struct sockaddr_ll sa;    struct sockaddr_ll sa;
     ssize_t rv;
   
   stream_set_getp (circuit->snd_stream, 0);    stream_set_getp (circuit->snd_stream, 0);
   memset (&sa, 0, sizeof (struct sockaddr_ll));    memset (&sa, 0, sizeof (struct sockaddr_ll));
Line 369  isis_send_pdu_p2p (struct isis_circuit *circuit, int l Line 399  isis_send_pdu_p2p (struct isis_circuit *circuit, int l
   
   /* lets try correcting the protocol */    /* lets try correcting the protocol */
   sa.sll_protocol = htons (0x00FE);    sa.sll_protocol = htons (0x00FE);
  written = sendto (circuit->fd, circuit->snd_stream->data,  rv = sendto(circuit->fd, circuit->snd_stream->data,
                    stream_get_endp (circuit->snd_stream), 0,               stream_get_endp (circuit->snd_stream), 0,
                    (struct sockaddr *) &sa,              (struct sockaddr *) &sa,
                    sizeof (struct sockaddr_ll));              sizeof (struct sockaddr_ll));
  if (rv < 0)
     {
       zlog_warn("IS-IS pfpacket: could not transmit packet on %s: %s",
                 circuit->interface->name, safe_strerror(errno));
       if (ERRNO_IO_RETRY(errno))
         return ISIS_WARNING;
       return ISIS_ERROR;
     }
   return ISIS_OK;    return ISIS_OK;
 }  }
   

Removed from v.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>