l2_packet_freebsd: Enable receiving priority tagged (VID=0) frames
Certain internet service providers transmit VLAN 0 priority tagged EAPOL frames from the ONT towards the residential gateway. VID 0 should be ignored, and the frame processed according to the priority set in the 802.1P bits and the encapsulated EtherType (i.e., EAPOL). The pcap filter utilized by l2_packet_* is inadquate for this use case. Here we modify the pcap filter on FreeBSD to accept both unencapsulated and encapsulated (with VLAN 0) EAPOL EtherTypes. This preserves the original filter behavior while also matching on encapsulated EAPOL. Additional work is required to support this handling on other platforms. We also modify the rx_receive handler to offset the packet buffer and length when handling dot1q encapsulated frames so the existing packet parsing code works as-is. Signed-off-by: R. Christian McDonald <rcm@rcm.sh> Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
parent
0aa44ccf82
commit
5b21f4861c
1 changed files with 10 additions and 2 deletions
|
@ -20,6 +20,7 @@
|
|||
#include <sys/sysctl.h>
|
||||
#endif /* __sun__ */
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
|
@ -94,6 +95,13 @@ static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
|
|||
} else {
|
||||
buf = (unsigned char *) (ethhdr + 1);
|
||||
len = hdr.caplen - sizeof(*ethhdr);
|
||||
|
||||
/* Handle IEEE 802.1Q encapsulated frames */
|
||||
if (len >= ETHER_VLAN_ENCAP_LEN &&
|
||||
ethhdr->h_proto == htons(ETH_P_8021Q)) {
|
||||
buf += ETHER_VLAN_ENCAP_LEN;
|
||||
len -= ETHER_VLAN_ENCAP_LEN;
|
||||
}
|
||||
}
|
||||
l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, buf, len);
|
||||
}
|
||||
|
@ -122,10 +130,10 @@ static int l2_packet_init_libpcap(struct l2_packet_data *l2,
|
|||
os_snprintf(pcap_filter, sizeof(pcap_filter),
|
||||
"not ether src " MACSTR " and "
|
||||
"( ether dst " MACSTR " or ether dst " MACSTR " ) and "
|
||||
"ether proto 0x%x",
|
||||
"( ether proto 0x%x or ( vlan 0 and ether proto 0x%x ) )",
|
||||
MAC2STR(l2->own_addr), /* do not receive own packets */
|
||||
MAC2STR(l2->own_addr), MAC2STR(pae_group_addr),
|
||||
protocol);
|
||||
protocol, protocol);
|
||||
if (pcap_compile(l2->pcap, &pcap_fp, pcap_filter, 1, pcap_netp) < 0) {
|
||||
fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(l2->pcap));
|
||||
return -1;
|
||||
|
|
Loading…
Reference in a new issue