diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2014-03-28 13:58:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-31 00:45:09 -0400 |
commit | 164d8c6665213c931645578310256da7b1259331 (patch) | |
tree | 336d19cb5fd510a3aaf6b1eb908f256c0cb9ee09 | |
parent | e62d2df084e2849edffb206559725fa81bb569a8 (diff) |
net: ptp: do not reimplement PTP/BPF classifier
There are currently pch_gbe, cpts, and ixp4xx_eth drivers that open-code
and reimplement a BPF classifier for the PTP protocol. Since all of them
effectively do the very same thing and load the very same PTP/BPF filter,
we can just consolidate that code by introducing ptp_classify_raw() in
the time-stamping core framework which can be used in drivers.
As drivers get initialized after bootstrapping the core networking
subsystem, they can make use of ptp_insns wrapped through
ptp_classify_raw(), which allows to simplify and remove PTP classifier
setup code in drivers.
Joint work with Alexei Starovoitov.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Cc: Richard Cochran <richard.cochran@omicron.at>
Cc: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpts.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/xscale/ixp4xx_eth.c | 11 | ||||
-rw-r--r-- | include/linux/ptp_classify.h | 10 | ||||
-rw-r--r-- | net/core/timestamping.c | 8 |
5 files changed, 12 insertions, 38 deletions
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 464e91058c81..73e66838cfef 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | |||
@@ -120,10 +120,6 @@ static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, | |||
120 | int data); | 120 | int data); |
121 | static void pch_gbe_set_multi(struct net_device *netdev); | 121 | static void pch_gbe_set_multi(struct net_device *netdev); |
122 | 122 | ||
123 | static struct sock_filter ptp_filter[] = { | ||
124 | PTP_FILTER | ||
125 | }; | ||
126 | |||
127 | static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) | 123 | static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) |
128 | { | 124 | { |
129 | u8 *data = skb->data; | 125 | u8 *data = skb->data; |
@@ -131,7 +127,7 @@ static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) | |||
131 | u16 *hi, *id; | 127 | u16 *hi, *id; |
132 | u32 lo; | 128 | u32 lo; |
133 | 129 | ||
134 | if (sk_run_filter(skb, ptp_filter) == PTP_CLASS_NONE) | 130 | if (ptp_classify_raw(skb) == PTP_CLASS_NONE) |
135 | return 0; | 131 | return 0; |
136 | 132 | ||
137 | offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; | 133 | offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; |
@@ -2635,11 +2631,6 @@ static int pch_gbe_probe(struct pci_dev *pdev, | |||
2635 | 2631 | ||
2636 | adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number, | 2632 | adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number, |
2637 | PCI_DEVFN(12, 4)); | 2633 | PCI_DEVFN(12, 4)); |
2638 | if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) { | ||
2639 | dev_err(&pdev->dev, "Bad ptp filter\n"); | ||
2640 | ret = -EINVAL; | ||
2641 | goto err_free_netdev; | ||
2642 | } | ||
2643 | 2634 | ||
2644 | netdev->netdev_ops = &pch_gbe_netdev_ops; | 2635 | netdev->netdev_ops = &pch_gbe_netdev_ops; |
2645 | netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; | 2636 | netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; |
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index 372cb192c5aa..a3bbf59eaafd 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c | |||
@@ -31,10 +31,6 @@ | |||
31 | 31 | ||
32 | #ifdef CONFIG_TI_CPTS | 32 | #ifdef CONFIG_TI_CPTS |
33 | 33 | ||
34 | static struct sock_filter ptp_filter[] = { | ||
35 | PTP_FILTER | ||
36 | }; | ||
37 | |||
38 | #define cpts_read32(c, r) __raw_readl(&c->reg->r) | 34 | #define cpts_read32(c, r) __raw_readl(&c->reg->r) |
39 | #define cpts_write32(c, v, r) __raw_writel(v, &c->reg->r) | 35 | #define cpts_write32(c, v, r) __raw_writel(v, &c->reg->r) |
40 | 36 | ||
@@ -301,7 +297,7 @@ static u64 cpts_find_ts(struct cpts *cpts, struct sk_buff *skb, int ev_type) | |||
301 | u64 ns = 0; | 297 | u64 ns = 0; |
302 | struct cpts_event *event; | 298 | struct cpts_event *event; |
303 | struct list_head *this, *next; | 299 | struct list_head *this, *next; |
304 | unsigned int class = sk_run_filter(skb, ptp_filter); | 300 | unsigned int class = ptp_classify_raw(skb); |
305 | unsigned long flags; | 301 | unsigned long flags; |
306 | u16 seqid; | 302 | u16 seqid; |
307 | u8 mtype; | 303 | u8 mtype; |
@@ -372,10 +368,6 @@ int cpts_register(struct device *dev, struct cpts *cpts, | |||
372 | int err, i; | 368 | int err, i; |
373 | unsigned long flags; | 369 | unsigned long flags; |
374 | 370 | ||
375 | if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) { | ||
376 | pr_err("cpts: bad ptp filter\n"); | ||
377 | return -EINVAL; | ||
378 | } | ||
379 | cpts->info = cpts_info; | 371 | cpts->info = cpts_info; |
380 | cpts->clock = ptp_clock_register(&cpts->info, dev); | 372 | cpts->clock = ptp_clock_register(&cpts->info, dev); |
381 | if (IS_ERR(cpts->clock)) { | 373 | if (IS_ERR(cpts->clock)) { |
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 25283f17d82f..f7e0f0f7c2e2 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c | |||
@@ -256,10 +256,6 @@ static int ports_open; | |||
256 | static struct port *npe_port_tab[MAX_NPES]; | 256 | static struct port *npe_port_tab[MAX_NPES]; |
257 | static struct dma_pool *dma_pool; | 257 | static struct dma_pool *dma_pool; |
258 | 258 | ||
259 | static struct sock_filter ptp_filter[] = { | ||
260 | PTP_FILTER | ||
261 | }; | ||
262 | |||
263 | static int ixp_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) | 259 | static int ixp_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) |
264 | { | 260 | { |
265 | u8 *data = skb->data; | 261 | u8 *data = skb->data; |
@@ -267,7 +263,7 @@ static int ixp_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) | |||
267 | u16 *hi, *id; | 263 | u16 *hi, *id; |
268 | u32 lo; | 264 | u32 lo; |
269 | 265 | ||
270 | if (sk_run_filter(skb, ptp_filter) != PTP_CLASS_V1_IPV4) | 266 | if (ptp_classify_raw(skb) != PTP_CLASS_V1_IPV4) |
271 | return 0; | 267 | return 0; |
272 | 268 | ||
273 | offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; | 269 | offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; |
@@ -1413,11 +1409,6 @@ static int eth_init_one(struct platform_device *pdev) | |||
1413 | char phy_id[MII_BUS_ID_SIZE + 3]; | 1409 | char phy_id[MII_BUS_ID_SIZE + 3]; |
1414 | int err; | 1410 | int err; |
1415 | 1411 | ||
1416 | if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) { | ||
1417 | pr_err("ixp4xx_eth: bad ptp filter\n"); | ||
1418 | return -EINVAL; | ||
1419 | } | ||
1420 | |||
1421 | if (!(dev = alloc_etherdev(sizeof(struct port)))) | 1412 | if (!(dev = alloc_etherdev(sizeof(struct port)))) |
1422 | return -ENOMEM; | 1413 | return -ENOMEM; |
1423 | 1414 | ||
diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h index 3decfa4d3732..6d3b0a2ef9ce 100644 --- a/include/linux/ptp_classify.h +++ b/include/linux/ptp_classify.h | |||
@@ -80,14 +80,6 @@ | |||
80 | #define OP_RETA (BPF_RET | BPF_A) | 80 | #define OP_RETA (BPF_RET | BPF_A) |
81 | #define OP_RETK (BPF_RET | BPF_K) | 81 | #define OP_RETK (BPF_RET | BPF_K) |
82 | 82 | ||
83 | static inline int ptp_filter_init(struct sock_filter *f, int len) | ||
84 | { | ||
85 | if (OP_LDH == f[0].code) | ||
86 | return sk_chk_filter(f, len); | ||
87 | else | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | #define PTP_FILTER \ | 83 | #define PTP_FILTER \ |
92 | {OP_LDH, 0, 0, OFF_ETYPE }, /* */ \ | 84 | {OP_LDH, 0, 0, OFF_ETYPE }, /* */ \ |
93 | {OP_JEQ, 0, 12, ETH_P_IP }, /* f goto L20 */ \ | 85 | {OP_JEQ, 0, 12, ETH_P_IP }, /* f goto L20 */ \ |
@@ -133,4 +125,6 @@ static inline int ptp_filter_init(struct sock_filter *f, int len) | |||
133 | {OP_RETA, 0, 0, 0 }, /* */ \ | 125 | {OP_RETA, 0, 0, 0 }, /* */ \ |
134 | /*L6x*/ {OP_RETK, 0, 0, PTP_CLASS_NONE }, | 126 | /*L6x*/ {OP_RETK, 0, 0, PTP_CLASS_NONE }, |
135 | 127 | ||
128 | unsigned int ptp_classify_raw(const struct sk_buff *skb); | ||
129 | |||
136 | #endif | 130 | #endif |
diff --git a/net/core/timestamping.c b/net/core/timestamping.c index e43d56acf803..9ff26b3cc021 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c | |||
@@ -25,11 +25,17 @@ | |||
25 | 25 | ||
26 | static struct sk_filter *ptp_insns __read_mostly; | 26 | static struct sk_filter *ptp_insns __read_mostly; |
27 | 27 | ||
28 | unsigned int ptp_classify_raw(const struct sk_buff *skb) | ||
29 | { | ||
30 | return SK_RUN_FILTER(ptp_insns, skb); | ||
31 | } | ||
32 | EXPORT_SYMBOL_GPL(ptp_classify_raw); | ||
33 | |||
28 | static unsigned int classify(const struct sk_buff *skb) | 34 | static unsigned int classify(const struct sk_buff *skb) |
29 | { | 35 | { |
30 | if (likely(skb->dev && skb->dev->phydev && | 36 | if (likely(skb->dev && skb->dev->phydev && |
31 | skb->dev->phydev->drv)) | 37 | skb->dev->phydev->drv)) |
32 | return SK_RUN_FILTER(ptp_insns, skb); | 38 | return ptp_classify_raw(skb); |
33 | else | 39 | else |
34 | return PTP_CLASS_NONE; | 40 | return PTP_CLASS_NONE; |
35 | } | 41 | } |