1 // SPDX-License-Identifier: GPL-2.0-only 2 /* PTP classifier 3 */ 4 5 /* The below program is the bpf_asm (tools/net/) representation of 6 * the opcode array in the ptp_filter structure. 7 * 8 * For convenience, this can easily be altered and reviewed with 9 * bpf_asm and bpf_dbg, e.g. `./bpf_asm -c prog` where prog is a 10 * simple file containing the below program: 11 * 12 * ldh [12] ; load ethertype 13 * 14 * ; PTP over UDP over IPv4 over Ethernet 15 * test_ipv4: 16 * jneq #0x800, test_ipv6 ; ETH_P_IP ? 17 * ldb [23] ; load proto 18 * jneq #17, drop_ipv4 ; IPPROTO_UDP ? 19 * ldh [20] ; load frag offset field 20 * jset #0x1fff, drop_ipv4 ; don't allow fragments 21 * ldxb 4*([14]&0xf) ; load IP header len 22 * ldh [x + 16] ; load UDP dst port 23 * jneq #319, drop_ipv4 ; is port PTP_EV_PORT ? 24 * ldh [x + 22] ; load payload 25 * and #0xf ; mask PTP_CLASS_VMASK 26 * or #0x10 ; PTP_CLASS_IPV4 27 * ret a ; return PTP class 28 * drop_ipv4: ret #0x0 ; PTP_CLASS_NONE 29 * 30 * ; PTP over UDP over IPv6 over Ethernet 31 * test_ipv6: 32 * jneq #0x86dd, test_8021q ; ETH_P_IPV6 ? 33 * ldb [20] ; load proto 34 * jneq #17, drop_ipv6 ; IPPROTO_UDP ? 35 * ldh [56] ; load UDP dst port 36 * jneq #319, drop_ipv6 ; is port PTP_EV_PORT ? 37 * ldh [62] ; load payload 38 * and #0xf ; mask PTP_CLASS_VMASK 39 * or #0x20 ; PTP_CLASS_IPV6 40 * ret a ; return PTP class 41 * drop_ipv6: ret #0x0 ; PTP_CLASS_NONE 42 * 43 * ; PTP over 802.1Q over Ethernet 44 * test_8021q: 45 * jneq #0x8100, test_ieee1588 ; ETH_P_8021Q ? 46 * ldh [16] ; load inner type 47 * jneq #0x88f7, test_8021q_ipv4 ; ETH_P_1588 ? 48 * ldb [18] ; load payload 49 * and #0x8 ; as we don't have ports here, test 50 * jneq #0x0, drop_ieee1588 ; for PTP_GEN_BIT and drop these 51 * ldh [18] ; reload payload 52 * and #0xf ; mask PTP_CLASS_VMASK 53 * or #0xc0 ; PTP_CLASS_VLAN|PTP_CLASS_L2 54 * ret a ; return PTP class 55 * 56 * ; PTP over UDP over IPv4 over 802.1Q over Ethernet 57 * test_8021q_ipv4: 58 * jneq #0x800, test_8021q_ipv6 ; ETH_P_IP ? 59 * ldb [27] ; load proto 60 * jneq #17, drop_8021q_ipv4 ; IPPROTO_UDP ? 61 * ldh [24] ; load frag offset field 62 * jset #0x1fff, drop_8021q_ipv4; don't allow fragments 63 * ldxb 4*([18]&0xf) ; load IP header len 64 * ldh [x + 20] ; load UDP dst port 65 * jneq #319, drop_8021q_ipv4 ; is port PTP_EV_PORT ? 66 * ldh [x + 26] ; load payload 67 * and #0xf ; mask PTP_CLASS_VMASK 68 * or #0x90 ; PTP_CLASS_VLAN|PTP_CLASS_IPV4 69 * ret a ; return PTP class 70 * drop_8021q_ipv4: ret #0x0 ; PTP_CLASS_NONE 71 * 72 * ; PTP over UDP over IPv6 over 802.1Q over Ethernet 73 * test_8021q_ipv6: 74 * jneq #0x86dd, drop_8021q_ipv6 ; ETH_P_IPV6 ? 75 * ldb [24] ; load proto 76 * jneq #17, drop_8021q_ipv6 ; IPPROTO_UDP ? 77 * ldh [60] ; load UDP dst port 78 * jneq #319, drop_8021q_ipv6 ; is port PTP_EV_PORT ? 79 * ldh [66] ; load payload 80 * and #0xf ; mask PTP_CLASS_VMASK 81 * or #0xa0 ; PTP_CLASS_VLAN|PTP_CLASS_IPV6 82 * ret a ; return PTP class 83 * drop_8021q_ipv6: ret #0x0 ; PTP_CLASS_NONE 84 * 85 * ; PTP over Ethernet 86 * test_ieee1588: 87 * jneq #0x88f7, drop_ieee1588 ; ETH_P_1588 ? 88 * ldb [14] ; load payload 89 * and #0x8 ; as we don't have ports here, test 90 * jneq #0x0, drop_ieee1588 ; for PTP_GEN_BIT and drop these 91 * ldh [14] ; reload payload 92 * and #0xf ; mask PTP_CLASS_VMASK 93 * or #0x40 ; PTP_CLASS_L2 94 * ret a ; return PTP class 95 * drop_ieee1588: ret #0x0 ; PTP_CLASS_NONE 96 */ 97 98 #include <linux/skbuff.h> 99 #include <linux/filter.h> 100 #include <linux/ptp_classify.h> 101 102 static struct bpf_prog *ptp_insns __read_mostly; 103 104 unsigned int ptp_classify_raw(const struct sk_buff *skb) 105 { 106 return BPF_PROG_RUN(ptp_insns, skb); 107 } 108 EXPORT_SYMBOL_GPL(ptp_classify_raw); 109 110 void __init ptp_classifier_init(void) 111 { 112 static struct sock_filter ptp_filter[] __initdata = { 113 { 0x28, 0, 0, 0x0000000c }, 114 { 0x15, 0, 12, 0x00000800 }, 115 { 0x30, 0, 0, 0x00000017 }, 116 { 0x15, 0, 9, 0x00000011 }, 117 { 0x28, 0, 0, 0x00000014 }, 118 { 0x45, 7, 0, 0x00001fff }, 119 { 0xb1, 0, 0, 0x0000000e }, 120 { 0x48, 0, 0, 0x00000010 }, 121 { 0x15, 0, 4, 0x0000013f }, 122 { 0x48, 0, 0, 0x00000016 }, 123 { 0x54, 0, 0, 0x0000000f }, 124 { 0x44, 0, 0, 0x00000010 }, 125 { 0x16, 0, 0, 0x00000000 }, 126 { 0x06, 0, 0, 0x00000000 }, 127 { 0x15, 0, 9, 0x000086dd }, 128 { 0x30, 0, 0, 0x00000014 }, 129 { 0x15, 0, 6, 0x00000011 }, 130 { 0x28, 0, 0, 0x00000038 }, 131 { 0x15, 0, 4, 0x0000013f }, 132 { 0x28, 0, 0, 0x0000003e }, 133 { 0x54, 0, 0, 0x0000000f }, 134 { 0x44, 0, 0, 0x00000020 }, 135 { 0x16, 0, 0, 0x00000000 }, 136 { 0x06, 0, 0, 0x00000000 }, 137 { 0x15, 0, 32, 0x00008100 }, 138 { 0x28, 0, 0, 0x00000010 }, 139 { 0x15, 0, 7, 0x000088f7 }, 140 { 0x30, 0, 0, 0x00000012 }, 141 { 0x54, 0, 0, 0x00000008 }, 142 { 0x15, 0, 35, 0x00000000 }, 143 { 0x28, 0, 0, 0x00000012 }, 144 { 0x54, 0, 0, 0x0000000f }, 145 { 0x44, 0, 0, 0x000000c0 }, 146 { 0x16, 0, 0, 0x00000000 }, 147 { 0x15, 0, 12, 0x00000800 }, 148 { 0x30, 0, 0, 0x0000001b }, 149 { 0x15, 0, 9, 0x00000011 }, 150 { 0x28, 0, 0, 0x00000018 }, 151 { 0x45, 7, 0, 0x00001fff }, 152 { 0xb1, 0, 0, 0x00000012 }, 153 { 0x48, 0, 0, 0x00000014 }, 154 { 0x15, 0, 4, 0x0000013f }, 155 { 0x48, 0, 0, 0x0000001a }, 156 { 0x54, 0, 0, 0x0000000f }, 157 { 0x44, 0, 0, 0x00000090 }, 158 { 0x16, 0, 0, 0x00000000 }, 159 { 0x06, 0, 0, 0x00000000 }, 160 { 0x15, 0, 8, 0x000086dd }, 161 { 0x30, 0, 0, 0x00000018 }, 162 { 0x15, 0, 6, 0x00000011 }, 163 { 0x28, 0, 0, 0x0000003c }, 164 { 0x15, 0, 4, 0x0000013f }, 165 { 0x28, 0, 0, 0x00000042 }, 166 { 0x54, 0, 0, 0x0000000f }, 167 { 0x44, 0, 0, 0x000000a0 }, 168 { 0x16, 0, 0, 0x00000000 }, 169 { 0x06, 0, 0, 0x00000000 }, 170 { 0x15, 0, 7, 0x000088f7 }, 171 { 0x30, 0, 0, 0x0000000e }, 172 { 0x54, 0, 0, 0x00000008 }, 173 { 0x15, 0, 4, 0x00000000 }, 174 { 0x28, 0, 0, 0x0000000e }, 175 { 0x54, 0, 0, 0x0000000f }, 176 { 0x44, 0, 0, 0x00000040 }, 177 { 0x16, 0, 0, 0x00000000 }, 178 { 0x06, 0, 0, 0x00000000 }, 179 }; 180 struct sock_fprog_kern ptp_prog; 181 182 ptp_prog.len = ARRAY_SIZE(ptp_filter); 183 ptp_prog.filter = ptp_filter; 184 185 BUG_ON(bpf_prog_create(&ptp_insns, &ptp_prog)); 186 } 187