|
5 | 5 | /*- |
6 | 6 | * SPDX-License-Identifier: BSD-3-Clause |
7 | 7 | * |
| 8 | + * Copyright (c) 2021 Franco Fichtner <franco@opnsense.org> |
8 | 9 | * Copyright (c) 1995, 1996, 1998, 1999 |
9 | 10 | * The Internet Software Consortium. All rights reserved. |
10 | 11 | * |
@@ -187,20 +188,58 @@ if_register_send(struct interface_info *info) |
187 | 188 | * Packet filter program... |
188 | 189 | */ |
189 | 190 | static const struct bpf_insn dhcp_bpf_filter[] = { |
| 191 | + /* Use relative index (0) for IP packet... */ |
| 192 | + BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, 0), |
| 193 | + |
| 194 | + /* |
| 195 | + * Test whether this is a VLAN packet... |
| 196 | + * |
| 197 | + * In case the server packet is using a VLAN ID |
| 198 | + * of 0, meaning an untagged priority was set, the |
| 199 | + * response shall be read and replied to. |
| 200 | + */ |
| 201 | + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 12), |
| 202 | + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_VLAN, 0, 4), |
| 203 | + |
| 204 | + /* Test whether it has a VID of 0 */ |
| 205 | + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 14), |
| 206 | + BPF_STMT(BPF_ALU + BPF_AND + BPF_K, EVL_VLID_MASK), |
| 207 | + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 17), |
| 208 | + |
| 209 | + /* Correct the relative index for VLAN packet (4)... */ |
| 210 | + BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, 4), |
| 211 | + |
190 | 212 | /* Make sure this is an IP packet... */ |
191 | | - BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12), |
192 | | - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8), |
| 213 | + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 12), |
| 214 | + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 14), |
193 | 215 |
|
194 | 216 | /* Make sure it's a UDP packet... */ |
195 | | - BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23), |
196 | | - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), |
| 217 | + BPF_STMT(BPF_LD + BPF_B + BPF_IND, 23), |
| 218 | + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 12), |
197 | 219 |
|
198 | 220 | /* Make sure this isn't a fragment... */ |
199 | | - BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20), |
200 | | - BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, IP_MF|IP_OFFMASK, 4, 0), |
| 221 | + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 20), |
| 222 | + BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, IP_MF|IP_OFFMASK, 10, 0), |
201 | 223 |
|
202 | | - /* Get the IP header length... */ |
| 224 | + /* |
| 225 | + * Get the IP header length... |
| 226 | + * |
| 227 | + * To find the correct position of the IP header |
| 228 | + * length field store the index (0 or 4) in the |
| 229 | + * accumulator and compare it with 0. |
| 230 | + */ |
| 231 | + BPF_STMT(BPF_MISC + BPF_TXA, 0), |
| 232 | + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 2), |
| 233 | + /* Store IP header length of IP packet in index. */ |
203 | 234 | BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14), |
| 235 | + /* Skip over following VLAN handling instruction. */ |
| 236 | + BPF_JUMP(BPF_JMP + BPF_JA, 1, 0, 0), |
| 237 | + /* Store IP header length of VLAN packet in index. */ |
| 238 | + BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 18), |
| 239 | + /* Add IP header length to previous relative index. */ |
| 240 | + BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0), |
| 241 | + /* Move result back to index to reach UDP header below. */ |
| 242 | + BPF_STMT(BPF_MISC + BPF_TAX, 0), |
204 | 243 |
|
205 | 244 | /* Make sure it's to the right port... */ |
206 | 245 | BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16), |
|
0 commit comments