0001
0002
0003
0004 #include <stddef.h>
0005 #include <string.h>
0006 #include <linux/bpf.h>
0007 #include <linux/pkt_cls.h>
0008 #include <bpf/bpf_helpers.h>
0009
0010 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
0011 #define TEST_FIELD(TYPE, FIELD, MASK) \
0012 { \
0013 TYPE tmp = *(volatile TYPE *)&skb->FIELD; \
0014 if (tmp != ((*(volatile __u32 *)&skb->FIELD) & MASK)) \
0015 return TC_ACT_SHOT; \
0016 }
0017 #else
0018 #define TEST_FIELD_OFFSET(a, b) ((sizeof(a) - sizeof(b)) / sizeof(b))
0019 #define TEST_FIELD(TYPE, FIELD, MASK) \
0020 { \
0021 TYPE tmp = *((volatile TYPE *)&skb->FIELD + \
0022 TEST_FIELD_OFFSET(skb->FIELD, TYPE)); \
0023 if (tmp != ((*(volatile __u32 *)&skb->FIELD) & MASK)) \
0024 return TC_ACT_SHOT; \
0025 }
0026 #endif
0027
0028 SEC("tc")
0029 int test_pkt_md_access(struct __sk_buff *skb)
0030 {
0031 TEST_FIELD(__u8, len, 0xFF);
0032 TEST_FIELD(__u16, len, 0xFFFF);
0033 TEST_FIELD(__u32, len, 0xFFFFFFFF);
0034 TEST_FIELD(__u16, protocol, 0xFFFF);
0035 TEST_FIELD(__u32, protocol, 0xFFFFFFFF);
0036 TEST_FIELD(__u8, hash, 0xFF);
0037 TEST_FIELD(__u16, hash, 0xFFFF);
0038 TEST_FIELD(__u32, hash, 0xFFFFFFFF);
0039
0040 return TC_ACT_OK;
0041 }