aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-03-28 13:58:22 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-31 00:45:09 -0400
commit164d8c6665213c931645578310256da7b1259331 (patch)
tree336d19cb5fd510a3aaf6b1eb908f256c0cb9ee09
parente62d2df084e2849edffb206559725fa81bb569a8 (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.c11
-rw-r--r--drivers/net/ethernet/ti/cpts.c10
-rw-r--r--drivers/net/ethernet/xscale/ixp4xx_eth.c11
-rw-r--r--include/linux/ptp_classify.h10
-rw-r--r--net/core/timestamping.c8
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);
121static void pch_gbe_set_multi(struct net_device *netdev); 121static void pch_gbe_set_multi(struct net_device *netdev);
122 122
123static struct sock_filter ptp_filter[] = {
124 PTP_FILTER
125};
126
127static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) 123static 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
34static 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;
256static struct port *npe_port_tab[MAX_NPES]; 256static struct port *npe_port_tab[MAX_NPES];
257static struct dma_pool *dma_pool; 257static struct dma_pool *dma_pool;
258 258
259static struct sock_filter ptp_filter[] = {
260 PTP_FILTER
261};
262
263static int ixp_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) 259static 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
83static 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
128unsigned 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
26static struct sk_filter *ptp_insns __read_mostly; 26static struct sk_filter *ptp_insns __read_mostly;
27 27
28unsigned int ptp_classify_raw(const struct sk_buff *skb)
29{
30 return SK_RUN_FILTER(ptp_insns, skb);
31}
32EXPORT_SYMBOL_GPL(ptp_classify_raw);
33
28static unsigned int classify(const struct sk_buff *skb) 34static 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}