From ecf56e75146238c071094b8a143db6740828c51f Mon Sep 17 00:00:00 2001 From: =?utf8?q?K=C3=A9vin=20THIERRY?= Date: Wed, 8 Oct 2014 09:40:14 +0200 Subject: [PATCH] linux-yocto: fix kernel build (TMP) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fix error: "implicit declaration of function 'sk_run_filter'". Change-Id: I5e69461a51b9fe5aaecd053ad0ed1c2f2a831ff0 Signed-off-by: Kévin THIERRY --- ...ptp-do-not-reimplement-PTP-BPF-classifier.patch | 190 +++++++++ ...t-ptp-move-PTP-classifier-in-its-own-file.patch | 471 +++++++++++++++++++++ ...p-use-sk_unattached_filter_create-for-BPF.patch | 115 +++++ recipes-kernel/linux/linux-yocto_3.14.bbappend | 4 + 4 files changed, 780 insertions(+) create mode 100644 recipes-kernel/linux/linux-yocto/0001-net-ptp-do-not-reimplement-PTP-BPF-classifier.patch create mode 100644 recipes-kernel/linux/linux-yocto/0001-net-ptp-move-PTP-classifier-in-its-own-file.patch create mode 100644 recipes-kernel/linux/linux-yocto/0001-net-ptp-use-sk_unattached_filter_create-for-BPF.patch 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 0000000..00e26a2 --- /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 +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 +Signed-off-by: Alexei Starovoitov +Cc: Richard Cochran +Cc: Jiri Benc +Signed-off-by: David S. Miller +--- + 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 0000000..0148b68 --- /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 +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 +Signed-off-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +Cc: Richard Cochran +Cc: Jiri Benc +Acked-by: Richard Cochran +Signed-off-by: David S. Miller +--- + 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 + #include + #include ++#include + #include + #include + #include +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 +-#include + #include +-#include +-#include ++#include + + #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 ++#include ++#include ++ ++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 + #include + +-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 + #include + #include ++#include + #include + #include + #include +@@ -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 0000000..291d8d3 --- /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 +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 +Signed-off-by: Alexei Starovoitov +Cc: Richard Cochran +Cc: Jiri Benc +Signed-off-by: David S. Miller +--- + 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 + #include + #include +-#ifdef __KERNEL__ + #include +-#else +-#include +-#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 + #include + +-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 051118e..065c2c3 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. -- 2.7.4