Skip to content

Packet Filter Linux ignore VLAN tagged packets #119

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

svenauhagen
Copy link

If you define kea dhcp on an untagged interface that also has a tagged
vlan interface on top, it will see both dhcp packets (eth0 and eth0.10).

Linux has a feature for auxiliary data on raw sockets which contains
data about the vlan of the packet received.

Kea should only answer packets without a vlan in the aux data,
since those are the data send to the attached interface.
vlan data are missing on the intended interface eth0.10 but set on eth0
for the same packet.

There was a discussion about this here:

http://kea-users.7364.n8.nabble.com/Kea-users-KEA-DHCP-and-VLANS-td1618.html

Signed-off-by: Sven Auhagen [email protected]

If you define kea dhcp on an untagged interface that also has a tagged
vlan interface on top, it will see both dhcp packets (eth0 and eth0.10).

Linux has a feature for auxiliary data on raw sockets which contains
data about the vlan of the packet received.

Kea should only answer packets without a vlan in the aux data,
since those are the data send to the attached interface.
vlan data are missing on the intended interface eth0.10 but set on eth0
for the same packet.

There was a discussion about this here:

http://kea-users.7364.n8.nabble.com/Kea-users-KEA-DHCP-and-VLANS-td1618.html

Signed-off-by: Sven Auhagen <[email protected]>
@fabiodepin
Copy link

Very thanks.
I thought about doing the same thing, so you push this code.
Its work!

There was a discussion about this here:
https://gitlab.isc.org/isc-projects/kea/-/issues/1117

@svenauhagen
Copy link
Author

Hi,

ah I did not see that ticket, thanks.
I updated the PR an hour ago to memset the data to zero.
Have you tested that last patch?

@fabiodepin
Copy link

Yes.
Here that's log:
Getting IP: https://pastebin.com/j3UQirSC
Release: https://pastebin.com/mYu9krcj

@svenauhagen
Copy link
Author

Great, thank you for testing!

@fabiodepin
Copy link

Hello,

Any reason why the merge of this task is still pending?

@NetForces
Copy link

Any ETA on getting a release with this fixed merged in ?

@g-v-egidy
Copy link

I think the underlying problem is an important issue for anyone dealing with a more complex VLAN infrastructure and it should be fixed.

But I don't think the proposed solution in this pull request is overly elegant:
It asks the kernel to add additional PACKET_AUXDATA messages to each packet. The full packets and these additional messages are then received and parsed for each packet and then the vlan-tagged packets are discarded.

But kea already has a perfectly capable BPF/LPF filtering program in place that is currently used to discard packets of the wrong type, to the wrong port and so on, directly in the kernel. This BPF/LPF filtering program can easily be extended to also check for any vlan-tagged packets and discard them right in the kernel, before ever sending them to kea.

The old dhcpd suffered from the same problem and it used a very similar BPF/LPF filtering solution. Here is how I fixed the problem for dhcpd:

--- dhcp-4.1-ESV-R6.orig/common/bpf.c	2012-07-13 08:11:52.000000000 +0200
+++ dhcp-4.1-ESV-R6/common/bpf.c	2025-06-25 12:54:53.000000000 +0200
@@ -172,6 +172,11 @@
    offsets used in if_register_send to patch the BPF program! XXX */
 
 struct bpf_insn dhcp_bpf_filter [] = {
+	/* Make sure there is no VLAN tag set... */
+	/* packets from dedicated vlan interfaces have their vlan tag stripped by the kernel */
+	BPF_STMT (BPF_LD + BPF_B + BPF_ABS, SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT),
+	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 10),
+	
 	/* Make sure this is an IP packet... */
 	BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
 	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
diff -r -u dhcp-4.1-ESV-R6.orig/common/lpf.c dhcp-4.1-ESV-R6/common/lpf.c
--- dhcp-4.1-ESV-R6.orig/common/lpf.c	2012-07-13 08:11:52.000000000 +0200
+++ dhcp-4.1-ESV-R6/common/lpf.c	2025-06-25 12:55:44.000000000 +0200
@@ -225,7 +225,7 @@
         /* Patch the server port into the LPF  program...
 	   XXX changes to filter program may require changes
 	   to the insn number(s) used below! XXX */
-	dhcp_bpf_filter [8].k = ntohs ((short)local_port);
+	dhcp_bpf_filter [10].k = ntohs ((short)local_port);
 
 	if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
 			sizeof p) < 0) {

I think it shouldn't be hard to adapt this to the kea BPF/LPF filter. Just the two offsets would have to be adjusted (jump offset 10 jumps to return 0, the patch offset points to the instruction with the port number). I don't have the necessary infrastructure for testing kea with this at hand right now or I would send a full pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants