summaryrefslogtreecommitdiff
path: root/isisd/isis_pfpacket.c
diff options
context:
space:
mode:
authorJosh Bailey <joshb@google.com>2012-03-24 08:35:20 -0700
committerAvneesh Sachdev <avneesh@opensourcerouting.org>2012-04-07 13:54:37 -0700
commit3f045a08812525505e165deea99a79447b44506b (patch)
treea5c944b0584e0e5a14908a2ac9476637e7c1d7e6 /isisd/isis_pfpacket.c
parent6902c69aa30a73ecd70ef8941518b541ca02b878 (diff)
isisd: add Google's changes to IS-IS
Diffstat (limited to 'isisd/isis_pfpacket.c')
-rw-r--r--isisd/isis_pfpacket.c91
1 files changed, 54 insertions, 37 deletions
diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c
index 9e4165e3..42947b22 100644
--- a/isisd/isis_pfpacket.c
+++ b/isisd/isis_pfpacket.c
@@ -134,7 +134,7 @@ open_packet_socket (struct isis_circuit *circuit)
circuit->fd = fd;
- if (circuit->circ_type == CIRCUIT_T_BROADCAST)
+ if (if_is_broadcast (circuit->interface))
{
/*
* Join to multicast groups
@@ -142,24 +142,22 @@ open_packet_socket (struct isis_circuit *circuit)
* 8.4.2 - Broadcast subnetwork IIH PDUs
* 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,
- circuit->interface->ifindex);
- /* joining ALL_ISS */
- 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);
+ if (circuit->is_type & IS_LEVEL_1)
+ /* joining ALL_L1_ISS */
+ retval = isis_multicast_join (circuit->fd, 1,
+ circuit->interface->ifindex);
+ if (circuit->is_type & IS_LEVEL_2)
+ /* joining ALL_L2_ISS */
+ retval = isis_multicast_join (circuit->fd, 2,
+ circuit->interface->ifindex);
+ /* joining ALL_ISS (used in RFC 5309 p2p-over-lan as well) */
+ retval = isis_multicast_join (circuit->fd, 3,
+ circuit->interface->ifindex);
}
else
{
retval =
- isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
+ isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
}
return retval;
@@ -184,12 +182,13 @@ isis_sock_init (struct isis_circuit *circuit)
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->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->rx = isis_recv_pdu_p2p;
@@ -234,13 +233,14 @@ isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
if (bytesread < 0)
{
- zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",
- circuit->fd, safe_strerror (errno));
- zlog_warn ("circuit is %s", circuit->interface->name);
- zlog_warn ("circuit fd %d", circuit->fd);
- zlog_warn ("bytesread %d", bytesread);
+ zlog_warn ("isis_recv_packet_bcast(): ifname %s, fd %d, bytesread %d, "
+ "recvfrom(): %s",
+ circuit->interface->name, circuit->fd, bytesread,
+ safe_strerror (errno));
/* 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;
}
/*
@@ -249,15 +249,22 @@ isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING)
{
/* 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)
- zlog_warn ("isis_recv_pdu_bcast(): read() failed");
+ zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed");
return ISIS_WARNING;
}
/* 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);
+ if (bytesread < 0)
+ {
+ zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed");
+ return ISIS_WARNING;
+ }
/* then we lose the LLC */
stream_write (circuit->rcv_stream, sock_buff + LLC_LEN, bytesread - LLC_LEN);
@@ -285,9 +292,11 @@ isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
if (s_addr.sll_pkttype == PACKET_OUTGOING)
{
/* 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)
- zlog_warn ("isis_recv_pdu_p2p(): read() failed");
+ zlog_warn ("isis_recv_pdu_p2p(): recvfrom() failed");
return ISIS_WARNING;
}
@@ -309,6 +318,9 @@ isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
int
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
* not need it
*/
@@ -321,7 +333,10 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
sa.sll_ifindex = circuit->interface->ifindex;
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);
else
memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);
@@ -332,14 +347,17 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
sock_buff[1] = 0xFE;
sock_buff[2] = 0x03;
- /* then we copy the data */
- memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data,
- stream_get_endp (circuit->snd_stream));
+ 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_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 */
- written = sendto (circuit->fd, sock_buff,
- stream_get_endp(circuit->snd_stream) + LLC_LEN, 0,
- (struct sockaddr *) &sa, sizeof (struct sockaddr_ll));
+ written = sendmsg (circuit->fd, &msg, 0);
return ISIS_OK;
}
@@ -347,7 +365,6 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
int
isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
{
-
int written = 1;
struct sockaddr_ll sa;