aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Sørensen <stefan.sorensen@spectralink.com>2014-06-27 05:59:10 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-07 19:57:18 -0400
commitae5c6c6d7bcadfbedefb5fc8ff0ebe2bfa83a0a1 (patch)
treed1071ae8d47415a2575f689e54e35119f541befd
parentb9c701edc7ff6ddd522497b0194b0bc3ec1b51a9 (diff)
ptp: Classify ptp over ip over vlan packets
This extends the ptp bpf to also match ptp over ip over vlan packets. The ptp classes are changed to orthogonal bitfields representing version, transport and vlan values to simplify matching. Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ti/cpts.c24
-rw-r--r--drivers/net/phy/dp83640.c46
-rw-r--r--include/linux/ptp_classify.h5
-rw-r--r--net/core/ptp_classifier.c64
4 files changed, 92 insertions, 47 deletions
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 6b56f85951e5..ab92f67da035 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -256,23 +256,21 @@ static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
256 u16 ts_seqid, u8 ts_msgtype) 256 u16 ts_seqid, u8 ts_msgtype)
257{ 257{
258 u16 *seqid; 258 u16 *seqid;
259 unsigned int offset; 259 unsigned int offset = 0;
260 u8 *msgtype, *data = skb->data; 260 u8 *msgtype, *data = skb->data;
261 261
262 switch (ptp_class) { 262 if (ptp_class & PTP_CLASS_VLAN)
263 case PTP_CLASS_V1_IPV4: 263 offset += VLAN_HLEN;
264 case PTP_CLASS_V2_IPV4: 264
265 offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; 265 switch (ptp_class & PTP_CLASS_PMASK) {
266 break; 266 case PTP_CLASS_IPV4:
267 case PTP_CLASS_V1_IPV6: 267 offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
268 case PTP_CLASS_V2_IPV6:
269 offset = OFF_PTP6;
270 break; 268 break;
271 case PTP_CLASS_V2_L2: 269 case PTP_CLASS_IPV6:
272 offset = ETH_HLEN; 270 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
273 break; 271 break;
274 case PTP_CLASS_V2_VLAN: 272 case PTP_CLASS_L2:
275 offset = ETH_HLEN + VLAN_HLEN; 273 offset += ETH_HLEN;
276 break; 274 break;
277 default: 275 default:
278 return 0; 276 return 0;
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 293ad064905d..53bd1af68422 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -856,20 +856,18 @@ static int is_sync(struct sk_buff *skb, int type)
856 u8 *data = skb->data, *msgtype; 856 u8 *data = skb->data, *msgtype;
857 unsigned int offset = 0; 857 unsigned int offset = 0;
858 858
859 switch (type) { 859 if (type & PTP_CLASS_VLAN)
860 case PTP_CLASS_V1_IPV4: 860 offset += VLAN_HLEN;
861 case PTP_CLASS_V2_IPV4: 861
862 offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; 862 switch (type & PTP_CLASS_PMASK) {
863 break; 863 case PTP_CLASS_IPV4:
864 case PTP_CLASS_V1_IPV6: 864 offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
865 case PTP_CLASS_V2_IPV6:
866 offset = OFF_PTP6;
867 break; 865 break;
868 case PTP_CLASS_V2_L2: 866 case PTP_CLASS_IPV6:
869 offset = ETH_HLEN; 867 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
870 break; 868 break;
871 case PTP_CLASS_V2_VLAN: 869 case PTP_CLASS_L2:
872 offset = ETH_HLEN + VLAN_HLEN; 870 offset += ETH_HLEN;
873 break; 871 break;
874 default: 872 default:
875 return 0; 873 return 0;
@@ -889,25 +887,23 @@ static int is_sync(struct sk_buff *skb, int type)
889static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts) 887static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
890{ 888{
891 u16 *seqid; 889 u16 *seqid;
892 unsigned int offset; 890 unsigned int offset = 0;
893 u8 *msgtype, *data = skb_mac_header(skb); 891 u8 *msgtype, *data = skb_mac_header(skb);
894 892
895 /* check sequenceID, messageType, 12 bit hash of offset 20-29 */ 893 /* check sequenceID, messageType, 12 bit hash of offset 20-29 */
896 894
897 switch (type) { 895 if (type & PTP_CLASS_VLAN)
898 case PTP_CLASS_V1_IPV4: 896 offset += VLAN_HLEN;
899 case PTP_CLASS_V2_IPV4: 897
900 offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; 898 switch (type & PTP_CLASS_PMASK) {
901 break; 899 case PTP_CLASS_IPV4:
902 case PTP_CLASS_V1_IPV6: 900 offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
903 case PTP_CLASS_V2_IPV6:
904 offset = OFF_PTP6;
905 break; 901 break;
906 case PTP_CLASS_V2_L2: 902 case PTP_CLASS_IPV6:
907 offset = ETH_HLEN; 903 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
908 break; 904 break;
909 case PTP_CLASS_V2_VLAN: 905 case PTP_CLASS_L2:
910 offset = ETH_HLEN + VLAN_HLEN; 906 offset += ETH_HLEN;
911 break; 907 break;
912 default: 908 default:
913 return 0; 909 return 0;
diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
index 7dfed71d76a6..159c987b1853 100644
--- a/include/linux/ptp_classify.h
+++ b/include/linux/ptp_classify.h
@@ -33,8 +33,8 @@
33#define PTP_CLASS_IPV4 0x10 /* event in an IPV4 UDP packet */ 33#define PTP_CLASS_IPV4 0x10 /* event in an IPV4 UDP packet */
34#define PTP_CLASS_IPV6 0x20 /* event in an IPV6 UDP packet */ 34#define PTP_CLASS_IPV6 0x20 /* event in an IPV6 UDP packet */
35#define PTP_CLASS_L2 0x30 /* event in a L2 packet */ 35#define PTP_CLASS_L2 0x30 /* event in a L2 packet */
36#define PTP_CLASS_VLAN 0x40 /* event in a VLAN tagged L2 packet */ 36#define PTP_CLASS_PMASK 0x30 /* mask for the packet type field */
37#define PTP_CLASS_PMASK 0xf0 /* mask for the packet type field */ 37#define PTP_CLASS_VLAN 0x40 /* event in a VLAN tagged packet */
38 38
39#define PTP_CLASS_V1_IPV4 (PTP_CLASS_V1 | PTP_CLASS_IPV4) 39#define PTP_CLASS_V1_IPV4 (PTP_CLASS_V1 | PTP_CLASS_IPV4)
40#define PTP_CLASS_V1_IPV6 (PTP_CLASS_V1 | PTP_CLASS_IPV6) /* probably DNE */ 40#define PTP_CLASS_V1_IPV6 (PTP_CLASS_V1 | PTP_CLASS_IPV6) /* probably DNE */
@@ -54,7 +54,6 @@
54#define IP6_HLEN 40 54#define IP6_HLEN 40
55#define UDP_HLEN 8 55#define UDP_HLEN 8
56#define OFF_IHL 14 56#define OFF_IHL 14
57#define OFF_PTP6 (ETH_HLEN + IP6_HLEN + UDP_HLEN)
58#define IPV4_HLEN(data) (((struct iphdr *)(data + OFF_IHL))->ihl << 2) 57#define IPV4_HLEN(data) (((struct iphdr *)(data + OFF_IHL))->ihl << 2)
59 58
60#if defined(CONFIG_NET_PTP_CLASSIFY) 59#if defined(CONFIG_NET_PTP_CLASSIFY)
diff --git a/net/core/ptp_classifier.c b/net/core/ptp_classifier.c
index d3027a73fd4b..12ab7b4be609 100644
--- a/net/core/ptp_classifier.c
+++ b/net/core/ptp_classifier.c
@@ -52,14 +52,43 @@
52 * test_8021q: 52 * test_8021q:
53 * jneq #0x8100, test_ieee1588 ; ETH_P_8021Q ? 53 * jneq #0x8100, test_ieee1588 ; ETH_P_8021Q ?
54 * ldh [16] ; load inner type 54 * ldh [16] ; load inner type
55 * jneq #0x88f7, drop_ieee1588 ; ETH_P_1588 ? 55 * jneq #0x88f7, test_8021q_ipv4 ; ETH_P_1588 ?
56 * ldb [18] ; load payload 56 * ldb [18] ; load payload
57 * and #0x8 ; as we don't have ports here, test 57 * and #0x8 ; as we don't have ports here, test
58 * jneq #0x0, drop_ieee1588 ; for PTP_GEN_BIT and drop these 58 * jneq #0x0, drop_ieee1588 ; for PTP_GEN_BIT and drop these
59 * ldh [18] ; reload payload 59 * ldh [18] ; reload payload
60 * and #0xf ; mask PTP_CLASS_VMASK 60 * and #0xf ; mask PTP_CLASS_VMASK
61 * or #0x40 ; PTP_CLASS_V2_VLAN 61 * or #0x70 ; PTP_CLASS_VLAN|PTP_CLASS_L2
62 * ret a ; return PTP class
63 *
64 * ; PTP over UDP over IPv4 over 802.1Q over Ethernet
65 * test_8021q_ipv4:
66 * jneq #0x800, test_8021q_ipv6 ; ETH_P_IP ?
67 * ldb [27] ; load proto
68 * jneq #17, drop_8021q_ipv4 ; IPPROTO_UDP ?
69 * ldh [24] ; load frag offset field
70 * jset #0x1fff, drop_8021q_ipv4; don't allow fragments
71 * ldxb 4*([18]&0xf) ; load IP header len
72 * ldh [x + 20] ; load UDP dst port
73 * jneq #319, drop_8021q_ipv4 ; is port PTP_EV_PORT ?
74 * ldh [x + 26] ; load payload
75 * and #0xf ; mask PTP_CLASS_VMASK
76 * or #0x50 ; PTP_CLASS_VLAN|PTP_CLASS_IPV4
77 * ret a ; return PTP class
78 * drop_8021q_ipv4: ret #0x0 ; PTP_CLASS_NONE
79 *
80 * ; PTP over UDP over IPv6 over 802.1Q over Ethernet
81 * test_8021q_ipv6:
82 * jneq #0x86dd, drop_8021q_ipv6 ; ETH_P_IPV6 ?
83 * ldb [24] ; load proto
84 * jneq #17, drop_8021q_ipv6 ; IPPROTO_UDP ?
85 * ldh [60] ; load UDP dst port
86 * jneq #319, drop_8021q_ipv6 ; is port PTP_EV_PORT ?
87 * ldh [66] ; load payload
88 * and #0xf ; mask PTP_CLASS_VMASK
89 * or #0x60 ; PTP_CLASS_VLAN|PTP_CLASS_IPV6
62 * ret a ; return PTP class 90 * ret a ; return PTP class
91 * drop_8021q_ipv6: ret #0x0 ; PTP_CLASS_NONE
63 * 92 *
64 * ; PTP over Ethernet 93 * ; PTP over Ethernet
65 * test_ieee1588: 94 * test_ieee1588:
@@ -113,16 +142,39 @@ void __init ptp_classifier_init(void)
113 { 0x44, 0, 0, 0x00000020 }, 142 { 0x44, 0, 0, 0x00000020 },
114 { 0x16, 0, 0, 0x00000000 }, 143 { 0x16, 0, 0, 0x00000000 },
115 { 0x06, 0, 0, 0x00000000 }, 144 { 0x06, 0, 0, 0x00000000 },
116 { 0x15, 0, 9, 0x00008100 }, 145 { 0x15, 0, 32, 0x00008100 },
117 { 0x28, 0, 0, 0x00000010 }, 146 { 0x28, 0, 0, 0x00000010 },
118 { 0x15, 0, 15, 0x000088f7 }, 147 { 0x15, 0, 7, 0x000088f7 },
119 { 0x30, 0, 0, 0x00000012 }, 148 { 0x30, 0, 0, 0x00000012 },
120 { 0x54, 0, 0, 0x00000008 }, 149 { 0x54, 0, 0, 0x00000008 },
121 { 0x15, 0, 12, 0x00000000 }, 150 { 0x15, 0, 35, 0x00000000 },
122 { 0x28, 0, 0, 0x00000012 }, 151 { 0x28, 0, 0, 0x00000012 },
123 { 0x54, 0, 0, 0x0000000f }, 152 { 0x54, 0, 0, 0x0000000f },
124 { 0x44, 0, 0, 0x00000040 }, 153 { 0x44, 0, 0, 0x00000070 },
154 { 0x16, 0, 0, 0x00000000 },
155 { 0x15, 0, 12, 0x00000800 },
156 { 0x30, 0, 0, 0x0000001b },
157 { 0x15, 0, 9, 0x00000011 },
158 { 0x28, 0, 0, 0x00000018 },
159 { 0x45, 7, 0, 0x00001fff },
160 { 0xb1, 0, 0, 0x00000012 },
161 { 0x48, 0, 0, 0x00000014 },
162 { 0x15, 0, 4, 0x0000013f },
163 { 0x48, 0, 0, 0x0000001a },
164 { 0x54, 0, 0, 0x0000000f },
165 { 0x44, 0, 0, 0x00000050 },
166 { 0x16, 0, 0, 0x00000000 },
167 { 0x06, 0, 0, 0x00000000 },
168 { 0x15, 0, 8, 0x000086dd },
169 { 0x30, 0, 0, 0x00000018 },
170 { 0x15, 0, 6, 0x00000011 },
171 { 0x28, 0, 0, 0x0000003c },
172 { 0x15, 0, 4, 0x0000013f },
173 { 0x28, 0, 0, 0x00000042 },
174 { 0x54, 0, 0, 0x0000000f },
175 { 0x44, 0, 0, 0x00000060 },
125 { 0x16, 0, 0, 0x00000000 }, 176 { 0x16, 0, 0, 0x00000000 },
177 { 0x06, 0, 0, 0x00000000 },
126 { 0x15, 0, 7, 0x000088f7 }, 178 { 0x15, 0, 7, 0x000088f7 },
127 { 0x30, 0, 0, 0x0000000e }, 179 { 0x30, 0, 0, 0x0000000e },
128 { 0x54, 0, 0, 0x00000008 }, 180 { 0x54, 0, 0, 0x00000008 },