Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

isis:interface vlan #16487

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions include/linux/if_packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,76 @@ struct sockaddr_ll {
unsigned char sll_addr[8];
};

/* Packet types */

#define PACKET_HOST 0 /* To us */
#define PACKET_BROADCAST 1 /* To all */
#define PACKET_MULTICAST 2 /* To group */
#define PACKET_OTHERHOST 3 /* To someone else */
#define PACKET_OUTGOING 4 /* Outgoing of any type */
#define PACKET_LOOPBACK 5 /* MC/BRD frame looped back */
#define PACKET_USER 6 /* To user space */
#define PACKET_KERNEL 7 /* To kernel space */
/* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
#define PACKET_FASTROUTE 6 /* Fastrouted frame */

/* Packet socket options */

#define PACKET_ADD_MEMBERSHIP 1
#define PACKET_DROP_MEMBERSHIP 2
#define PACKET_RECV_OUTPUT 3
/* Value 4 is still used by obsolete turbo-packet. */
#define PACKET_RX_RING 5
#define PACKET_STATISTICS 6
#define PACKET_COPY_THRESH 7
#define PACKET_AUXDATA 8
#define PACKET_ORIGDEV 9
#define PACKET_VERSION 10
#define PACKET_HDRLEN 11
#define PACKET_RESERVE 12
#define PACKET_TX_RING 13
#define PACKET_LOSS 14
#define PACKET_VNET_HDR 15
#define PACKET_TX_TIMESTAMP 16
#define PACKET_TIMESTAMP 17
#define PACKET_FANOUT 18
#define PACKET_TX_HAS_OFF 19
#define PACKET_QDISC_BYPASS 20
#define PACKET_ROLLOVER_STATS 21
#define PACKET_FANOUT_DATA 22
#define PACKET_IGNORE_OUTGOING 23

struct tpacket_auxdata {
__u32 tp_status;
__u32 tp_len;
__u32 tp_snaplen;
__u16 tp_mac;
__u16 tp_net;
__u16 tp_vlan_tci;
__u16 tp_vlan_tpid;
};

/* Rx ring - header status */
#define TP_STATUS_KERNEL 0
#define TP_STATUS_USER (1 << 0)
#define TP_STATUS_COPY (1 << 1)
#define TP_STATUS_LOSING (1 << 2)
#define TP_STATUS_CSUMNOTREADY (1 << 3)
#define TP_STATUS_VLAN_VALID (1 << 4) /* auxdata has valid tp_vlan_tci */
#define TP_STATUS_BLK_TMO (1 << 5)
#define TP_STATUS_VLAN_TPID_VALID (1 << 6) /* auxdata has valid tp_vlan_tpid */
#define TP_STATUS_CSUM_VALID (1 << 7)

struct packet_mreq {
int mr_ifindex;
unsigned short mr_type;
unsigned short mr_alen;
unsigned char mr_address[8];
};

#define PACKET_MR_MULTICAST 0
#define PACKET_MR_PROMISC 1
#define PACKET_MR_ALLMULTI 2
#define PACKET_MR_UNICAST 3

#endif
53 changes: 49 additions & 4 deletions isisd/isis_pfpacket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -134,6 +134,12 @@ 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));
Expand Down Expand Up @@ -284,13 +290,52 @@ 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);
Expand Down
Loading