|
10 | 10 | #include <linux/if_vlan.h>
|
11 | 11 | #include <linux/filter.h>
|
12 | 12 | #include <linux/random.h>
|
| 13 | +#include <linux/init.h> |
13 | 14 | #include <asm/cacheflush.h>
|
14 | 15 | #include <asm/processor.h>
|
15 | 16 | #include <asm/facility.h>
|
@@ -222,6 +223,37 @@ static void bpf_jit_epilogue(struct bpf_jit *jit)
|
222 | 223 | EMIT2(0x07fe);
|
223 | 224 | }
|
224 | 225 |
|
| 226 | +/* Helper to find the offset of pkt_type in sk_buff |
| 227 | + * Make sure its still a 3bit field starting at the MSBs within a byte. |
| 228 | + */ |
| 229 | +#define PKT_TYPE_MAX 0xe0 |
| 230 | +static int pkt_type_offset; |
| 231 | + |
| 232 | +static int __init bpf_pkt_type_offset_init(void) |
| 233 | +{ |
| 234 | + struct sk_buff skb_probe = { |
| 235 | + .pkt_type = ~0, |
| 236 | + }; |
| 237 | + char *ct = (char *)&skb_probe; |
| 238 | + int off; |
| 239 | + |
| 240 | + pkt_type_offset = -1; |
| 241 | + for (off = 0; off < sizeof(struct sk_buff); off++) { |
| 242 | + if (!ct[off]) |
| 243 | + continue; |
| 244 | + if (ct[off] == PKT_TYPE_MAX) |
| 245 | + pkt_type_offset = off; |
| 246 | + else { |
| 247 | + /* Found non matching bit pattern, fix needed. */ |
| 248 | + WARN_ON_ONCE(1); |
| 249 | + pkt_type_offset = -1; |
| 250 | + return -1; |
| 251 | + } |
| 252 | + } |
| 253 | + return 0; |
| 254 | +} |
| 255 | +device_initcall(bpf_pkt_type_offset_init); |
| 256 | + |
225 | 257 | /*
|
226 | 258 | * make sure we dont leak kernel information to user
|
227 | 259 | */
|
@@ -721,6 +753,16 @@ load_abs: if ((int) K < 0)
|
721 | 753 | EMIT4_DISP(0x88500000, 12);
|
722 | 754 | }
|
723 | 755 | break;
|
| 756 | + case BPF_S_ANC_PKTTYPE: |
| 757 | + if (pkt_type_offset < 0) |
| 758 | + goto out; |
| 759 | + /* lhi %r5,0 */ |
| 760 | + EMIT4(0xa7580000); |
| 761 | + /* ic %r5,<d(pkt_type_offset)>(%r2) */ |
| 762 | + EMIT4_DISP(0x43502000, pkt_type_offset); |
| 763 | + /* srl %r5,5 */ |
| 764 | + EMIT4_DISP(0x88500000, 5); |
| 765 | + break; |
724 | 766 | case BPF_S_ANC_CPU: /* A = smp_processor_id() */
|
725 | 767 | #ifdef CONFIG_SMP
|
726 | 768 | /* l %r5,<d(cpu_nr)> */
|
|
0 commit comments