diff options
author | JosiahMg <josiahmg@163.com> | 2024-08-01 03:09:35 +0200 |
---|---|---|
committer | JosiahMg <josiahmg@163.com> | 2024-08-01 03:09:35 +0200 |
commit | 6e823d288c023f2cf463a29347b1fe1b7855bd71 (patch) | |
tree | 4f1148b1b18c5bb57fe0e109eaa77799a8d54e20 /isisd | |
parent | nhrpd: fixes duplicate auth extension (diff) | |
download | frr-6e823d288c023f2cf463a29347b1fe1b7855bd71.tar.xz frr-6e823d288c023f2cf463a29347b1fe1b7855bd71.zip |
isisd: vlan-subif isis neighbor
Fixed the problem that physical interfaces can establish isis neighbor
relationships with vlan subinterfaces
Signed-off-by: JosiahMg <JosiahMg@163.com>
Diffstat (limited to 'isisd')
-rw-r--r-- | isisd/isis_pfpacket.c | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c index af69fac1c..634bdca7c 100644 --- a/isisd/isis_pfpacket.c +++ b/isisd/isis_pfpacket.c @@ -10,7 +10,7 @@ #include <zebra.h> #if ISIS_METHOD == ISIS_METHOD_PFPACKET #include <net/ethernet.h> /* the L2 protocols */ -#include <netpacket/packet.h> +#include "linux/if_packet.h" #include <linux/filter.h> @@ -134,6 +134,13 @@ static int open_packet_socket(struct isis_circuit *circuit) return ISIS_WARNING; } + int val = 1; + if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, &val, sizeof(val)) == -1 && + errno != ENOPROTOOPT) { + zlog_warn("%s: PACKET_AUXDATA failed: %s", __func__, + safe_strerror(errno)); + } + if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))) { zlog_warn("%s: SO_ATTACH_FILTER failed: %s", __func__, safe_strerror(errno)); @@ -284,13 +291,54 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa) ? 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); + + union { + struct cmsghdr cmsg; + char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))]; + } cmsg_buf; + struct iovec iov; + struct msghdr msg; + memset(&cmsg_buf, 0x00, sizeof(cmsg_buf)); + memset(&iov, 0x00, sizeof(iov)); + memset(&msg, 0x00, sizeof(msg)); + + iov.iov_base = temp_buff; + iov.iov_len = max_size; + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + msg.msg_name = &s_addr; + msg.msg_namelen = addr_len; + + msg.msg_control = &cmsg_buf; + msg.msg_controllen = sizeof(cmsg_buf); + + bytesread = recvmsg(circuit->fd, &msg, MSG_DONTWAIT); if (bytesread < 0) { zlog_warn("%s: recvfrom() failed", __func__); return ISIS_WARNING; } + + bool vlan_packet = false; + + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); cmsg; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_len >= CMSG_LEN(sizeof(struct tpacket_auxdata)) && + cmsg->cmsg_level == SOL_PACKET && + cmsg->cmsg_type == PACKET_AUXDATA) { + struct tpacket_auxdata *aux = + (struct tpacket_auxdata *)CMSG_DATA(cmsg); + + if (aux && (aux->tp_status & TP_STATUS_VLAN_VALID)) + vlan_packet = true; + break; + } + } + + if (vlan_packet) + return ISIS_WARNING; + /* then we lose the LLC */ stream_write(circuit->rcv_stream, temp_buff + LLC_LEN, bytesread - LLC_LEN); |