summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin THIERRY <kevin.thierry@open.eurogiciel.org>2014-10-08 09:40:14 +0200
committerKévin THIERRY <kevin.thierry@open.eurogiciel.org>2014-10-16 10:47:44 +0200
commitecf56e75146238c071094b8a143db6740828c51f (patch)
treee09d8a18a0a9313f565a24f4c6cb22e313aa4034
parent7cc7a7e94a9ab3fd775fca58002bebac9f366f0f (diff)
downloadmeta-tizen-ecf56e75146238c071094b8a143db6740828c51f.tar.gz
meta-tizen-ecf56e75146238c071094b8a143db6740828c51f.tar.bz2
meta-tizen-ecf56e75146238c071094b8a143db6740828c51f.zip
linux-yocto: fix kernel build (TMP)
Fix error: "implicit declaration of function 'sk_run_filter'". Change-Id: I5e69461a51b9fe5aaecd053ad0ed1c2f2a831ff0 Signed-off-by: Kévin THIERRY <kevin.thierry@open.eurogiciel.org>
-rw-r--r--recipes-kernel/linux/linux-yocto/0001-net-ptp-do-not-reimplement-PTP-BPF-classifier.patch190
-rw-r--r--recipes-kernel/linux/linux-yocto/0001-net-ptp-move-PTP-classifier-in-its-own-file.patch471
-rw-r--r--recipes-kernel/linux/linux-yocto/0001-net-ptp-use-sk_unattached_filter_create-for-BPF.patch115
-rw-r--r--recipes-kernel/linux/linux-yocto_3.14.bbappend4
4 files changed, 780 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-yocto/0001-net-ptp-do-not-reimplement-PTP-BPF-classifier.patch b/recipes-kernel/linux/linux-yocto/0001-net-ptp-do-not-reimplement-PTP-BPF-classifier.patch
new file mode 100644
index 00000000..00e26a23
--- /dev/null
+++ b/recipes-kernel/linux/linux-yocto/0001-net-ptp-do-not-reimplement-PTP-BPF-classifier.patch
@@ -0,0 +1,190 @@
+From 164d8c6665213c931645578310256da7b1259331 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Fri, 28 Mar 2014 18:58:22 +0100
+Subject: [PATCH] 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>
+---
+ drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 11 +----------
+ drivers/net/ethernet/ti/cpts.c | 10 +---------
+ drivers/net/ethernet/xscale/ixp4xx_eth.c | 11 +----------
+ include/linux/ptp_classify.h | 10 ++--------
+ 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 464e910..73e6683 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,
+ 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;
+diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
+index 372cb19..a3bbf59 100644
+--- a/drivers/net/ethernet/ti/cpts.c
++++ b/drivers/net/ethernet/ti/cpts.c
+@@ -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)) {
+diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+index 25283f1..f7e0f0f 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;
+ 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;
+
+diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
+index 3decfa4..6d3b0a2 100644
+--- a/include/linux/ptp_classify.h
++++ b/include/linux/ptp_classify.h
+@@ -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
+diff --git a/net/core/timestamping.c b/net/core/timestamping.c
+index e43d56a..9ff26b3 100644
+--- a/net/core/timestamping.c
++++ b/net/core/timestamping.c
+@@ -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;
+ }
+--
+1.8.1.4
+
diff --git a/recipes-kernel/linux/linux-yocto/0001-net-ptp-move-PTP-classifier-in-its-own-file.patch b/recipes-kernel/linux/linux-yocto/0001-net-ptp-move-PTP-classifier-in-its-own-file.patch
new file mode 100644
index 00000000..0148b687
--- /dev/null
+++ b/recipes-kernel/linux/linux-yocto/0001-net-ptp-move-PTP-classifier-in-its-own-file.patch
@@ -0,0 +1,471 @@
+From 408eccce32044ee3285a7f6a812723ba3540c3e7 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Tue, 1 Apr 2014 16:20:23 +0200
+Subject: [PATCH] net: ptp: move PTP classifier in its own file
+
+This commit fixes a build error reported by Fengguang, that is
+triggered when CONFIG_NETWORK_PHY_TIMESTAMPING is not set:
+
+ ERROR: "ptp_classify_raw" [drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.ko] undefined!
+
+The fix is to introduce its own file for the PTP BPF classifier,
+so that PTP_1588_CLOCK and/or NETWORK_PHY_TIMESTAMPING can select
+it independently from each other. IXP4xx driver on ARM needs to
+select it as well since it does not seem to select PTP_1588_CLOCK
+or similar that would pull it in automatically.
+
+This also allows for hiding all of the internals of the BPF PTP
+program inside that file, and only exporting relevant API bits
+to drivers.
+
+This patch also adds a kdoc documentation of ptp_classify_raw()
+API to make it clear that it can return PTP_CLASS_* defines. Also,
+the BPF program has been translated into bpf_asm code, so that it
+can be more easily read and altered (extensively documented in [1]).
+
+In the kernel tree under tools/net/ we have bpf_asm and bpf_dbg
+tools, so the commented program can simply be translated via
+`./bpf_asm -c prog` where prog is a file that contains the
+commented code. This makes it easily readable/verifiable and when
+there's a need to change something, jump offsets etc do not need
+to be replaced manually which can be very error prone. Instead,
+a newly translated version via bpf_asm can simply replace the old
+code. I have checked opcode diffs before/after and it's the very
+same filter.
+
+ [1] Documentation/networking/filter.txt
+
+Fixes: 164d8c666521 ("net: ptp: do not reimplement PTP/BPF classifier")
+Reported-by: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
+Cc: Richard Cochran <richardcochran@gmail.com>
+Cc: Jiri Benc <jbenc@redhat.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/xscale/Kconfig | 1 +
+ drivers/net/phy/dp83640.c | 1 +
+ drivers/ptp/Kconfig | 1 +
+ include/linux/ptp_classify.h | 95 ++++++------------------
+ include/linux/skbuff.h | 2 -
+ net/Kconfig | 4 +
+ net/core/Makefile | 1 +
+ net/core/ptp_classifier.c | 141 ++++++++++++++++++++++++++++++++++++
+ net/core/timestamping.c | 18 -----
+ net/socket.c | 5 +-
+ 10 files changed, 173 insertions(+), 96 deletions(-)
+ create mode 100644 net/core/ptp_classifier.c
+
+diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig
+index 3f43101..b81bc9f 100644
+--- a/drivers/net/ethernet/xscale/Kconfig
++++ b/drivers/net/ethernet/xscale/Kconfig
+@@ -23,6 +23,7 @@ config IXP4XX_ETH
+ tristate "Intel IXP4xx Ethernet support"
+ depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
+ select PHYLIB
++ select NET_PTP_CLASSIFY
+ ---help---
+ Say Y here if you want to use built-in Ethernet ports
+ on IXP4xx processor.
+diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
+index 352c5e4..6a999e6 100644
+--- a/drivers/net/phy/dp83640.c
++++ b/drivers/net/phy/dp83640.c
+@@ -27,6 +27,7 @@
+ #include <linux/module.h>
+ #include <linux/net_tstamp.h>
+ #include <linux/netdevice.h>
++#include <linux/if_vlan.h>
+ #include <linux/phy.h>
+ #include <linux/ptp_classify.h>
+ #include <linux/ptp_clock_kernel.h>
+diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
+index 5a7910e..6963bdf 100644
+--- a/drivers/ptp/Kconfig
++++ b/drivers/ptp/Kconfig
+@@ -7,6 +7,7 @@ menu "PTP clock support"
+ config PTP_1588_CLOCK
+ tristate "PTP clock support"
+ select PPS
++ select NET_PTP_CLASSIFY
+ help
+ The IEEE 1588 standard defines a method to precisely
+ synchronize distributed clocks over Ethernet networks. The
+diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
+index 6d3b0a2..7dfed71 100644
+--- a/include/linux/ptp_classify.h
++++ b/include/linux/ptp_classify.h
+@@ -23,11 +23,8 @@
+ #ifndef _PTP_CLASSIFY_H_
+ #define _PTP_CLASSIFY_H_
+
+-#include <linux/if_ether.h>
+-#include <linux/if_vlan.h>
+ #include <linux/ip.h>
+-#include <linux/filter.h>
+-#include <linux/in.h>
++#include <linux/skbuff.h>
+
+ #define PTP_CLASS_NONE 0x00 /* not a PTP event message */
+ #define PTP_CLASS_V1 0x01 /* protocol version 1 */
+@@ -40,7 +37,7 @@
+ #define PTP_CLASS_PMASK 0xf0 /* mask for the packet type field */
+
+ #define PTP_CLASS_V1_IPV4 (PTP_CLASS_V1 | PTP_CLASS_IPV4)
+-#define PTP_CLASS_V1_IPV6 (PTP_CLASS_V1 | PTP_CLASS_IPV6) /*probably DNE*/
++#define PTP_CLASS_V1_IPV6 (PTP_CLASS_V1 | PTP_CLASS_IPV6) /* probably DNE */
+ #define PTP_CLASS_V2_IPV4 (PTP_CLASS_V2 | PTP_CLASS_IPV4)
+ #define PTP_CLASS_V2_IPV6 (PTP_CLASS_V2 | PTP_CLASS_IPV6)
+ #define PTP_CLASS_V2_L2 (PTP_CLASS_V2 | PTP_CLASS_L2)
+@@ -49,82 +46,34 @@
+ #define PTP_EV_PORT 319
+ #define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type */
+
+-#define OFF_ETYPE 12
+-#define OFF_IHL 14
+-#define OFF_FRAG 20
+-#define OFF_PROTO4 23
+-#define OFF_NEXT 6
+-#define OFF_UDP_DST 2
+-
+ #define OFF_PTP_SOURCE_UUID 22 /* PTPv1 only */
+ #define OFF_PTP_SEQUENCE_ID 30
+ #define OFF_PTP_CONTROL 32 /* PTPv1 only */
+
+-#define IPV4_HLEN(data) (((struct iphdr *)(data + OFF_IHL))->ihl << 2)
+-
++/* Below defines should actually be removed at some point in time. */
+ #define IP6_HLEN 40
+ #define UDP_HLEN 8
+-
+-#define RELOFF_DST4 (ETH_HLEN + OFF_UDP_DST)
+-#define OFF_DST6 (ETH_HLEN + IP6_HLEN + OFF_UDP_DST)
++#define OFF_IHL 14
+ #define OFF_PTP6 (ETH_HLEN + IP6_HLEN + UDP_HLEN)
++#define IPV4_HLEN(data) (((struct iphdr *)(data + OFF_IHL))->ihl << 2)
+
+-#define OP_AND (BPF_ALU | BPF_AND | BPF_K)
+-#define OP_JEQ (BPF_JMP | BPF_JEQ | BPF_K)
+-#define OP_JSET (BPF_JMP | BPF_JSET | BPF_K)
+-#define OP_LDB (BPF_LD | BPF_B | BPF_ABS)
+-#define OP_LDH (BPF_LD | BPF_H | BPF_ABS)
+-#define OP_LDHI (BPF_LD | BPF_H | BPF_IND)
+-#define OP_LDX (BPF_LDX | BPF_B | BPF_MSH)
+-#define OP_OR (BPF_ALU | BPF_OR | BPF_K)
+-#define OP_RETA (BPF_RET | BPF_A)
+-#define OP_RETK (BPF_RET | BPF_K)
+-
+-#define PTP_FILTER \
+- {OP_LDH, 0, 0, OFF_ETYPE }, /* */ \
+- {OP_JEQ, 0, 12, ETH_P_IP }, /* f goto L20 */ \
+- {OP_LDB, 0, 0, OFF_PROTO4 }, /* */ \
+- {OP_JEQ, 0, 9, IPPROTO_UDP }, /* f goto L10 */ \
+- {OP_LDH, 0, 0, OFF_FRAG }, /* */ \
+- {OP_JSET, 7, 0, 0x1fff }, /* t goto L11 */ \
+- {OP_LDX, 0, 0, OFF_IHL }, /* */ \
+- {OP_LDHI, 0, 0, RELOFF_DST4 }, /* */ \
+- {OP_JEQ, 0, 4, PTP_EV_PORT }, /* f goto L12 */ \
+- {OP_LDHI, 0, 0, ETH_HLEN + UDP_HLEN }, /* */ \
+- {OP_AND, 0, 0, PTP_CLASS_VMASK }, /* */ \
+- {OP_OR, 0, 0, PTP_CLASS_IPV4 }, /* */ \
+- {OP_RETA, 0, 0, 0 }, /* */ \
+-/*L1x*/ {OP_RETK, 0, 0, PTP_CLASS_NONE }, /* */ \
+-/*L20*/ {OP_JEQ, 0, 9, ETH_P_IPV6 }, /* f goto L40 */ \
+- {OP_LDB, 0, 0, ETH_HLEN + OFF_NEXT }, /* */ \
+- {OP_JEQ, 0, 6, IPPROTO_UDP }, /* f goto L30 */ \
+- {OP_LDH, 0, 0, OFF_DST6 }, /* */ \
+- {OP_JEQ, 0, 4, PTP_EV_PORT }, /* f goto L31 */ \
+- {OP_LDH, 0, 0, OFF_PTP6 }, /* */ \
+- {OP_AND, 0, 0, PTP_CLASS_VMASK }, /* */ \
+- {OP_OR, 0, 0, PTP_CLASS_IPV6 }, /* */ \
+- {OP_RETA, 0, 0, 0 }, /* */ \
+-/*L3x*/ {OP_RETK, 0, 0, PTP_CLASS_NONE }, /* */ \
+-/*L40*/ {OP_JEQ, 0, 9, ETH_P_8021Q }, /* f goto L50 */ \
+- {OP_LDH, 0, 0, OFF_ETYPE + 4 }, /* */ \
+- {OP_JEQ, 0, 15, ETH_P_1588 }, /* f goto L60 */ \
+- {OP_LDB, 0, 0, ETH_HLEN + VLAN_HLEN }, /* */ \
+- {OP_AND, 0, 0, PTP_GEN_BIT }, /* */ \
+- {OP_JEQ, 0, 12, 0 }, /* f goto L6x */ \
+- {OP_LDH, 0, 0, ETH_HLEN + VLAN_HLEN }, /* */ \
+- {OP_AND, 0, 0, PTP_CLASS_VMASK }, /* */ \
+- {OP_OR, 0, 0, PTP_CLASS_VLAN }, /* */ \
+- {OP_RETA, 0, 0, 0 }, /* */ \
+-/*L50*/ {OP_JEQ, 0, 7, ETH_P_1588 }, /* f goto L61 */ \
+- {OP_LDB, 0, 0, ETH_HLEN }, /* */ \
+- {OP_AND, 0, 0, PTP_GEN_BIT }, /* */ \
+- {OP_JEQ, 0, 4, 0 }, /* f goto L6x */ \
+- {OP_LDH, 0, 0, ETH_HLEN }, /* */ \
+- {OP_AND, 0, 0, PTP_CLASS_VMASK }, /* */ \
+- {OP_OR, 0, 0, PTP_CLASS_L2 }, /* */ \
+- {OP_RETA, 0, 0, 0 }, /* */ \
+-/*L6x*/ {OP_RETK, 0, 0, PTP_CLASS_NONE },
+-
++#if defined(CONFIG_NET_PTP_CLASSIFY)
++/**
++ * ptp_classify_raw - classify a PTP packet
++ * @skb: buffer
++ *
++ * Runs a minimal BPF dissector to classify a network packet to
++ * determine the PTP class. In case the skb does not contain any
++ * PTP protocol data, PTP_CLASS_NONE will be returned, otherwise
++ * PTP_CLASS_V1_IPV{4,6}, PTP_CLASS_V2_IPV{4,6} or
++ * PTP_CLASS_V2_{L2,VLAN}, depending on the packet content.
++ */
+ unsigned int ptp_classify_raw(const struct sk_buff *skb);
+
++void __init ptp_classifier_init(void);
++#else
++static inline void ptp_classifier_init(void)
++{
++}
+ #endif
++#endif /* _PTP_CLASSIFY_H_ */
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 18ef022..31edf63 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -2630,8 +2630,6 @@ static inline ktime_t net_invalid_timestamp(void)
+ return ktime_set(0, 0);
+ }
+
+-void skb_timestamping_init(void);
+-
+ #ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
+
+ void skb_clone_tx_timestamp(struct sk_buff *skb);
+diff --git a/net/Kconfig b/net/Kconfig
+index e411046..d1f6f96 100644
+--- a/net/Kconfig
++++ b/net/Kconfig
+@@ -89,8 +89,12 @@ config NETWORK_SECMARK
+ to nfmark, but designated for security purposes.
+ If you are unsure how to answer this question, answer N.
+
++config NET_PTP_CLASSIFY
++ def_bool n
++
+ config NETWORK_PHY_TIMESTAMPING
+ bool "Timestamping in PHY devices"
++ select NET_PTP_CLASSIFY
+ help
+ This allows timestamping of network packets by PHYs with
+ hardware timestamping capabilities. This option adds some
+diff --git a/net/core/Makefile b/net/core/Makefile
+index 9628c20..826b925 100644
+--- a/net/core/Makefile
++++ b/net/core/Makefile
+@@ -21,5 +21,6 @@ obj-$(CONFIG_FIB_RULES) += fib_rules.o
+ obj-$(CONFIG_TRACEPOINTS) += net-traces.o
+ obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o
+ obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o
++obj-$(CONFIG_NET_PTP_CLASSIFY) += ptp_classifier.o
+ obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o
+ obj-$(CONFIG_CGROUP_NET_CLASSID) += netclassid_cgroup.o
+diff --git a/net/core/ptp_classifier.c b/net/core/ptp_classifier.c
+new file mode 100644
+index 0000000..eaba0f6
+--- /dev/null
++++ b/net/core/ptp_classifier.c
+@@ -0,0 +1,141 @@
++/* PTP classifier
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of version 2 of the GNU General Public
++ * License as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ */
++
++/* The below program is the bpf_asm (tools/net/) representation of
++ * the opcode array in the ptp_filter structure.
++ *
++ * For convenience, this can easily be altered and reviewed with
++ * bpf_asm and bpf_dbg, e.g. `./bpf_asm -c prog` where prog is a
++ * simple file containing the below program:
++ *
++ * ldh [12] ; load ethertype
++ *
++ * ; PTP over UDP over IPv4 over Ethernet
++ * test_ipv4:
++ * jneq #0x800, test_ipv6 ; ETH_P_IP ?
++ * ldb [23] ; load proto
++ * jneq #17, drop_ipv4 ; IPPROTO_UDP ?
++ * ldh [20] ; load frag offset field
++ * jset #0x1fff, drop_ipv4 ; don't allow fragments
++ * ldxb 4*([14]&0xf) ; load IP header len
++ * ldh [x + 16] ; load UDP dst port
++ * jneq #319, drop_ipv4 ; is port PTP_EV_PORT ?
++ * ldh [x + 22] ; load payload
++ * and #0xf ; mask PTP_CLASS_VMASK
++ * or #0x10 ; PTP_CLASS_IPV4
++ * ret a ; return PTP class
++ * drop_ipv4: ret #0x0 ; PTP_CLASS_NONE
++ *
++ * ; PTP over UDP over IPv6 over Ethernet
++ * test_ipv6:
++ * jneq #0x86dd, test_8021q ; ETH_P_IPV6 ?
++ * ldb [20] ; load proto
++ * jneq #17, drop_ipv6 ; IPPROTO_UDP ?
++ * ldh [56] ; load UDP dst port
++ * jneq #319, drop_ipv6 ; is port PTP_EV_PORT ?
++ * ldh [62] ; load payload
++ * and #0xf ; mask PTP_CLASS_VMASK
++ * or #0x20 ; PTP_CLASS_IPV6
++ * ret a ; return PTP class
++ * drop_ipv6: ret #0x0 ; PTP_CLASS_NONE
++ *
++ * ; PTP over 802.1Q over Ethernet
++ * test_8021q:
++ * jneq #0x8100, test_ieee1588 ; ETH_P_8021Q ?
++ * ldh [16] ; load inner type
++ * jneq #0x88f7, drop_ieee1588 ; ETH_P_1588 ?
++ * ldb [18] ; load payload
++ * and #0x8 ; as we don't have ports here, test
++ * jneq #0x0, drop_ieee1588 ; for PTP_GEN_BIT and drop these
++ * ldh [18] ; reload payload
++ * and #0xf ; mask PTP_CLASS_VMASK
++ * or #0x40 ; PTP_CLASS_V2_VLAN
++ * ret a ; return PTP class
++ *
++ * ; PTP over Ethernet
++ * test_ieee1588:
++ * jneq #0x88f7, drop_ieee1588 ; ETH_P_1588 ?
++ * ldb [14] ; load payload
++ * and #0x8 ; as we don't have ports here, test
++ * jneq #0x0, drop_ieee1588 ; for PTP_GEN_BIT and drop these
++ * ldh [14] ; reload payload
++ * and #0xf ; mask PTP_CLASS_VMASK
++ * or #0x30 ; PTP_CLASS_L2
++ * ret a ; return PTP class
++ * drop_ieee1588: ret #0x0 ; PTP_CLASS_NONE
++ */
++
++#include <linux/skbuff.h>
++#include <linux/filter.h>
++#include <linux/ptp_classify.h>
++
++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);
++
++void __init ptp_classifier_init(void)
++{
++ static struct sock_filter ptp_filter[] = {
++ { 0x28, 0, 0, 0x0000000c },
++ { 0x15, 0, 12, 0x00000800 },
++ { 0x30, 0, 0, 0x00000017 },
++ { 0x15, 0, 9, 0x00000011 },
++ { 0x28, 0, 0, 0x00000014 },
++ { 0x45, 7, 0, 0x00001fff },
++ { 0xb1, 0, 0, 0x0000000e },
++ { 0x48, 0, 0, 0x00000010 },
++ { 0x15, 0, 4, 0x0000013f },
++ { 0x48, 0, 0, 0x00000016 },
++ { 0x54, 0, 0, 0x0000000f },
++ { 0x44, 0, 0, 0x00000010 },
++ { 0x16, 0, 0, 0x00000000 },
++ { 0x06, 0, 0, 0x00000000 },
++ { 0x15, 0, 9, 0x000086dd },
++ { 0x30, 0, 0, 0x00000014 },
++ { 0x15, 0, 6, 0x00000011 },
++ { 0x28, 0, 0, 0x00000038 },
++ { 0x15, 0, 4, 0x0000013f },
++ { 0x28, 0, 0, 0x0000003e },
++ { 0x54, 0, 0, 0x0000000f },
++ { 0x44, 0, 0, 0x00000020 },
++ { 0x16, 0, 0, 0x00000000 },
++ { 0x06, 0, 0, 0x00000000 },
++ { 0x15, 0, 9, 0x00008100 },
++ { 0x28, 0, 0, 0x00000010 },
++ { 0x15, 0, 15, 0x000088f7 },
++ { 0x30, 0, 0, 0x00000012 },
++ { 0x54, 0, 0, 0x00000008 },
++ { 0x15, 0, 12, 0x00000000 },
++ { 0x28, 0, 0, 0x00000012 },
++ { 0x54, 0, 0, 0x0000000f },
++ { 0x44, 0, 0, 0x00000040 },
++ { 0x16, 0, 0, 0x00000000 },
++ { 0x15, 0, 7, 0x000088f7 },
++ { 0x30, 0, 0, 0x0000000e },
++ { 0x54, 0, 0, 0x00000008 },
++ { 0x15, 0, 4, 0x00000000 },
++ { 0x28, 0, 0, 0x0000000e },
++ { 0x54, 0, 0, 0x0000000f },
++ { 0x44, 0, 0, 0x00000030 },
++ { 0x16, 0, 0, 0x00000000 },
++ { 0x06, 0, 0, 0x00000000 },
++ };
++ struct sock_fprog ptp_prog = {
++ .len = ARRAY_SIZE(ptp_filter), .filter = ptp_filter,
++ };
++
++ BUG_ON(sk_unattached_filter_create(&ptp_insns, &ptp_prog));
++}
+diff --git a/net/core/timestamping.c b/net/core/timestamping.c
+index 9ff26b3..6521dfd 100644
+--- a/net/core/timestamping.c
++++ b/net/core/timestamping.c
+@@ -23,14 +23,6 @@
+ #include <linux/skbuff.h>
+ #include <linux/export.h>
+
+-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 &&
+@@ -140,13 +132,3 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
+ return false;
+ }
+ EXPORT_SYMBOL_GPL(skb_defer_rx_timestamp);
+-
+-void __init skb_timestamping_init(void)
+-{
+- static struct sock_filter ptp_filter[] = { PTP_FILTER };
+- struct sock_fprog ptp_prog = {
+- .len = ARRAY_SIZE(ptp_filter), .filter = ptp_filter,
+- };
+-
+- BUG_ON(sk_unattached_filter_create(&ptp_insns, &ptp_prog));
+-}
+diff --git a/net/socket.c b/net/socket.c
+index f25eaa3..1b1e7e6 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -72,6 +72,7 @@
+ #include <linux/if_bridge.h>
+ #include <linux/if_frad.h>
+ #include <linux/if_vlan.h>
++#include <linux/ptp_classify.h>
+ #include <linux/init.h>
+ #include <linux/poll.h>
+ #include <linux/cache.h>
+@@ -2685,9 +2686,7 @@ static int __init sock_init(void)
+ goto out;
+ #endif
+
+-#ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
+- skb_timestamping_init();
+-#endif
++ ptp_classifier_init();
+
+ out:
+ return err;
+--
+1.8.1.4
+
diff --git a/recipes-kernel/linux/linux-yocto/0001-net-ptp-use-sk_unattached_filter_create-for-BPF.patch b/recipes-kernel/linux/linux-yocto/0001-net-ptp-use-sk_unattached_filter_create-for-BPF.patch
new file mode 100644
index 00000000..291d8d35
--- /dev/null
+++ b/recipes-kernel/linux/linux-yocto/0001-net-ptp-use-sk_unattached_filter_create-for-BPF.patch
@@ -0,0 +1,115 @@
+From e62d2df084e2849edffb206559725fa81bb569a8 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Fri, 28 Mar 2014 18:58:21 +0100
+Subject: [PATCH] net: ptp: use sk_unattached_filter_create() for BPF
+
+This patch migrates an open-coded sk_run_filter() implementation with
+proper use of the BPF API, that is, sk_unattached_filter_create(). This
+migration is needed, as we will be internally transforming the filter
+to a different representation, and therefore needs to be decoupled.
+
+It is okay to do so as skb_timestamping_init() is called during
+initialization of the network stack in core initcall via sock_init().
+This would effectively also allow for PTP filters to be jit compiled if
+bpf_jit_enable is set.
+
+For better readability, there are also some newlines introduced, also
+ptp_classify.h is only in kernel space.
+
+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>
+---
+ include/linux/ptp_classify.h | 4 ----
+ net/core/timestamping.c | 21 ++++++++++++++-------
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
+index 1dc420b..3decfa4 100644
+--- a/include/linux/ptp_classify.h
++++ b/include/linux/ptp_classify.h
+@@ -27,11 +27,7 @@
+ #include <linux/if_vlan.h>
+ #include <linux/ip.h>
+ #include <linux/filter.h>
+-#ifdef __KERNEL__
+ #include <linux/in.h>
+-#else
+-#include <netinet/in.h>
+-#endif
+
+ #define PTP_CLASS_NONE 0x00 /* not a PTP event message */
+ #define PTP_CLASS_V1 0x01 /* protocol version 1 */
+diff --git a/net/core/timestamping.c b/net/core/timestamping.c
+index 661b5a4..e43d56a 100644
+--- a/net/core/timestamping.c
++++ b/net/core/timestamping.c
+@@ -23,16 +23,13 @@
+ #include <linux/skbuff.h>
+ #include <linux/export.h>
+
+-static struct sock_filter ptp_filter[] = {
+- PTP_FILTER
+-};
++static struct sk_filter *ptp_insns __read_mostly;
+
+ static unsigned int classify(const struct sk_buff *skb)
+ {
+- if (likely(skb->dev &&
+- skb->dev->phydev &&
++ if (likely(skb->dev && skb->dev->phydev &&
+ skb->dev->phydev->drv))
+- return sk_run_filter(skb, ptp_filter);
++ return SK_RUN_FILTER(ptp_insns, skb);
+ else
+ return PTP_CLASS_NONE;
+ }
+@@ -60,11 +57,13 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
+ if (likely(phydev->drv->txtstamp)) {
+ if (!atomic_inc_not_zero(&sk->sk_refcnt))
+ return;
++
+ clone = skb_clone(skb, GFP_ATOMIC);
+ if (!clone) {
+ sock_put(sk);
+ return;
+ }
++
+ clone->sk = sk;
+ phydev->drv->txtstamp(phydev, clone, type);
+ }
+@@ -89,12 +88,15 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
+ }
+
+ *skb_hwtstamps(skb) = *hwtstamps;
++
+ serr = SKB_EXT_ERR(skb);
+ memset(serr, 0, sizeof(*serr));
+ serr->ee.ee_errno = ENOMSG;
+ serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
+ skb->sk = NULL;
++
+ err = sock_queue_err_skb(sk, skb);
++
+ sock_put(sk);
+ if (err)
+ kfree_skb(skb);
+@@ -135,5 +137,10 @@ EXPORT_SYMBOL_GPL(skb_defer_rx_timestamp);
+
+ void __init skb_timestamping_init(void)
+ {
+- BUG_ON(sk_chk_filter(ptp_filter, ARRAY_SIZE(ptp_filter)));
++ static struct sock_filter ptp_filter[] = { PTP_FILTER };
++ struct sock_fprog ptp_prog = {
++ .len = ARRAY_SIZE(ptp_filter), .filter = ptp_filter,
++ };
++
++ BUG_ON(sk_unattached_filter_create(&ptp_insns, &ptp_prog));
+ }
+--
+1.8.1.4
+
diff --git a/recipes-kernel/linux/linux-yocto_3.14.bbappend b/recipes-kernel/linux/linux-yocto_3.14.bbappend
index 051118e0..065c2c3d 100644
--- a/recipes-kernel/linux/linux-yocto_3.14.bbappend
+++ b/recipes-kernel/linux/linux-yocto_3.14.bbappend
@@ -3,6 +3,10 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://defconfig"
SRC_URI += "file://0001-Smack-Cgroup-filesystem-access.patch"
SRC_URI += "file://0002-SMACK-Fix-handling-value-NULL-in-post-setxattr.patch"
+# TMP fix for error: "implicit declaration of function 'sk_run_filter'"
+SRC_URI += "file://0001-net-ptp-use-sk_unattached_filter_create-for-BPF.patch"
+SRC_URI += "file://0001-net-ptp-do-not-reimplement-PTP-BPF-classifier.patch"
+SRC_URI += "file://0001-net-ptp-move-PTP-classifier-in-its-own-file.patch"
# Setting the KCONFIG_MODE variable prevents it to being set to
# "--allnoconfig" which disable all kernel options.