Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 164d8c66 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller
Browse files

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: default avatarDaniel Borkmann <dborkman@redhat.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@plumgrid.com>
Cc: Richard Cochran <richard.cochran@omicron.at>
Cc: Jiri Benc <jbenc@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e62d2df0
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -120,10 +120,6 @@ static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg,
			       int data);
static void pch_gbe_set_multi(struct net_device *netdev);

static struct sock_filter ptp_filter[] = {
	PTP_FILTER
};

static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid)
{
	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)
	u16 *hi, *id;
	u32 lo;

	if (sk_run_filter(skb, ptp_filter) == PTP_CLASS_NONE)
	if (ptp_classify_raw(skb) == PTP_CLASS_NONE)
		return 0;

	offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
@@ -2635,11 +2631,6 @@ static int pch_gbe_probe(struct pci_dev *pdev,

	adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number,
					       PCI_DEVFN(12, 4));
	if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
		dev_err(&pdev->dev, "Bad ptp filter\n");
		ret = -EINVAL;
		goto err_free_netdev;
	}

	netdev->netdev_ops = &pch_gbe_netdev_ops;
	netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
+1 −9
Original line number Diff line number Diff line
@@ -31,10 +31,6 @@

#ifdef CONFIG_TI_CPTS

static struct sock_filter ptp_filter[] = {
	PTP_FILTER
};

#define cpts_read32(c, r)	__raw_readl(&c->reg->r)
#define cpts_write32(c, v, r)	__raw_writel(v, &c->reg->r)

@@ -301,7 +297,7 @@ static u64 cpts_find_ts(struct cpts *cpts, struct sk_buff *skb, int ev_type)
	u64 ns = 0;
	struct cpts_event *event;
	struct list_head *this, *next;
	unsigned int class = sk_run_filter(skb, ptp_filter);
	unsigned int class = ptp_classify_raw(skb);
	unsigned long flags;
	u16 seqid;
	u8 mtype;
@@ -372,10 +368,6 @@ int cpts_register(struct device *dev, struct cpts *cpts,
	int err, i;
	unsigned long flags;

	if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
		pr_err("cpts: bad ptp filter\n");
		return -EINVAL;
	}
	cpts->info = cpts_info;
	cpts->clock = ptp_clock_register(&cpts->info, dev);
	if (IS_ERR(cpts->clock)) {
+1 −10
Original line number Diff line number Diff line
@@ -256,10 +256,6 @@ static int ports_open;
static struct port *npe_port_tab[MAX_NPES];
static struct dma_pool *dma_pool;

static struct sock_filter ptp_filter[] = {
	PTP_FILTER
};

static int ixp_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid)
{
	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)
	u16 *hi, *id;
	u32 lo;

	if (sk_run_filter(skb, ptp_filter) != PTP_CLASS_V1_IPV4)
	if (ptp_classify_raw(skb) != PTP_CLASS_V1_IPV4)
		return 0;

	offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
@@ -1413,11 +1409,6 @@ static int eth_init_one(struct platform_device *pdev)
	char phy_id[MII_BUS_ID_SIZE + 3];
	int err;

	if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
		pr_err("ixp4xx_eth: bad ptp filter\n");
		return -EINVAL;
	}

	if (!(dev = alloc_etherdev(sizeof(struct port))))
		return -ENOMEM;

+2 −8
Original line number Diff line number Diff line
@@ -80,14 +80,6 @@
#define OP_RETA	(BPF_RET | BPF_A)
#define OP_RETK	(BPF_RET | BPF_K)

static inline int ptp_filter_init(struct sock_filter *f, int len)
{
	if (OP_LDH == f[0].code)
		return sk_chk_filter(f, len);
	else
		return 0;
}

#define PTP_FILTER \
	{OP_LDH,	0,   0, OFF_ETYPE		}, /*              */ \
	{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)
	{OP_RETA,	0,   0, 0			}, /*              */ \
/*L6x*/	{OP_RETK,	0,   0, PTP_CLASS_NONE		},

unsigned int ptp_classify_raw(const struct sk_buff *skb);

#endif
+7 −1
Original line number Diff line number Diff line
@@ -25,11 +25,17 @@

static struct sk_filter *ptp_insns __read_mostly;

unsigned int ptp_classify_raw(const struct sk_buff *skb)
{
	return SK_RUN_FILTER(ptp_insns, skb);
}
EXPORT_SYMBOL_GPL(ptp_classify_raw);

static unsigned int classify(const struct sk_buff *skb)
{
	if (likely(skb->dev && skb->dev->phydev &&
		   skb->dev->phydev->drv))
		return SK_RUN_FILTER(ptp_insns, skb);
		return ptp_classify_raw(skb);
	else
		return PTP_CLASS_NONE;
}