* [less-CONFIG_NET v2 1/8] net: reorder filter code
[not found] ` <1530189936-25780-1-git-send-email-nmanthey@amazon.de>
@ 2018-06-28 12:45 ` Norbert Manthey
2018-06-28 12:45 ` [less-CONFIG_NET v2 2/8] net: reorder flow_dissector Norbert Manthey
` (3 subsequent siblings)
4 siblings, 0 replies; 5+ messages in thread
From: Norbert Manthey @ 2018-06-28 12:45 UTC (permalink / raw)
To: Norbert Manthey, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, David S. Miller, netdev
This commit reorders the definition of functions and struct in the
file filter.c, such that in the next step we can easily cut the file
into a commonly used part, as well as a part that is only required in
case CONFIG_NET is actually set.
This is part of the effort to split CONFIG_SECCOMP_FILTER and
CONFIG_NET.
Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
---
net/core/filter.c | 330 +++++++++++++++++++++++++++---------------------------
1 file changed, 165 insertions(+), 165 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index e7f12e9..61c24c9 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -69,58 +69,6 @@
#include <net/seg6.h>
#include <net/seg6_local.h>
-/**
- * sk_filter_trim_cap - run a packet through a socket filter
- * @sk: sock associated with &sk_buff
- * @skb: buffer to filter
- * @cap: limit on how short the eBPF program may trim the packet
- *
- * Run the eBPF program and then cut skb->data to correct size returned by
- * the program. If pkt_len is 0 we toss packet. If skb->len is smaller
- * than pkt_len we keep whole skb->data. This is the socket level
- * wrapper to BPF_PROG_RUN. It returns 0 if the packet should
- * be accepted or -EPERM if the packet should be tossed.
- *
- */
-int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap)
-{
- int err;
- struct sk_filter *filter;
-
- /*
- * If the skb was allocated from pfmemalloc reserves, only
- * allow SOCK_MEMALLOC sockets to use it as this socket is
- * helping free memory
- */
- if (skb_pfmemalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC)) {
- NET_INC_STATS(sock_net(sk), LINUX_MIB_PFMEMALLOCDROP);
- return -ENOMEM;
- }
- err = BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb);
- if (err)
- return err;
-
- err = security_sock_rcv_skb(sk, skb);
- if (err)
- return err;
-
- rcu_read_lock();
- filter = rcu_dereference(sk->sk_filter);
- if (filter) {
- struct sock *save_sk = skb->sk;
- unsigned int pkt_len;
-
- skb->sk = sk;
- pkt_len = bpf_prog_run_save_cb(filter->prog, skb);
- skb->sk = save_sk;
- err = pkt_len ? pskb_trim(skb, max(cap, pkt_len)) : -EPERM;
- }
- rcu_read_unlock();
-
- return err;
-}
-EXPORT_SYMBOL(sk_filter_trim_cap);
-
BPF_CALL_1(bpf_skb_get_pay_offset, struct sk_buff *, skb)
{
return skb_get_poff(skb);
@@ -256,12 +204,6 @@ BPF_CALL_0(bpf_get_raw_cpu_id)
return raw_smp_processor_id();
}
-static const struct bpf_func_proto bpf_get_raw_smp_processor_id_proto = {
- .func = bpf_get_raw_cpu_id,
- .gpl_only = false,
- .ret_type = RET_INTEGER,
-};
-
static u32 convert_skb_access(int skb_field, int dst_reg, int src_reg,
struct bpf_insn *insn_buf)
{
@@ -1138,71 +1080,6 @@ static void __bpf_prog_release(struct bpf_prog *prog)
}
}
-static void __sk_filter_release(struct sk_filter *fp)
-{
- __bpf_prog_release(fp->prog);
- kfree(fp);
-}
-
-/**
- * sk_filter_release_rcu - Release a socket filter by rcu_head
- * @rcu: rcu_head that contains the sk_filter to free
- */
-static void sk_filter_release_rcu(struct rcu_head *rcu)
-{
- struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
-
- __sk_filter_release(fp);
-}
-
-/**
- * sk_filter_release - release a socket filter
- * @fp: filter to remove
- *
- * Remove a filter from a socket and release its resources.
- */
-static void sk_filter_release(struct sk_filter *fp)
-{
- if (refcount_dec_and_test(&fp->refcnt))
- call_rcu(&fp->rcu, sk_filter_release_rcu);
-}
-
-void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
-{
- u32 filter_size = bpf_prog_size(fp->prog->len);
-
- atomic_sub(filter_size, &sk->sk_omem_alloc);
- sk_filter_release(fp);
-}
-
-/* try to charge the socket memory if there is space available
- * return true on success
- */
-static bool __sk_filter_charge(struct sock *sk, struct sk_filter *fp)
-{
- u32 filter_size = bpf_prog_size(fp->prog->len);
-
- /* same check as in sock_kmalloc() */
- if (filter_size <= sysctl_optmem_max &&
- atomic_read(&sk->sk_omem_alloc) + filter_size < sysctl_optmem_max) {
- atomic_add(filter_size, &sk->sk_omem_alloc);
- return true;
- }
- return false;
-}
-
-bool sk_filter_charge(struct sock *sk, struct sk_filter *fp)
-{
- if (!refcount_inc_not_zero(&fp->refcnt))
- return false;
-
- if (!__sk_filter_charge(sk, fp)) {
- sk_filter_release(fp);
- return false;
- }
- return true;
-}
-
static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp)
{
struct sock_filter *old_prog;
@@ -1314,19 +1191,22 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
}
/**
- * bpf_prog_create - create an unattached filter
+ * bpf_prog_create_from_user - create an unattached filter from user buffer
* @pfp: the unattached filter that is created
* @fprog: the filter program
+ * @trans: post-classic verifier transformation handler
+ * @save_orig: save classic BPF program
*
- * Create a filter independent of any socket. We first run some
- * sanity checks on it to make sure it does not explode on us later.
- * If an error occurs or there is insufficient memory for the filter
- * a negative errno code is returned. On success the return is zero.
+ * This function effectively does the same as bpf_prog_create(), only
+ * that it builds up its insns buffer from user space provided buffer.
+ * It also allows for passing a bpf_aux_classic_check_t handler.
*/
-int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
+int bpf_prog_create_from_user(struct bpf_prog **pfp, struct sock_fprog *fprog,
+ bpf_aux_classic_check_t trans, bool save_orig)
{
unsigned int fsize = bpf_classic_proglen(fprog);
struct bpf_prog *fp;
+ int err;
/* Make sure new filter is there and in the right amounts. */
if (!bpf_check_basics_ok(fprog->filter, fprog->len))
@@ -1336,44 +1216,177 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
if (!fp)
return -ENOMEM;
- memcpy(fp->insns, fprog->filter, fsize);
+ if (copy_from_user(fp->insns, fprog->filter, fsize)) {
+ __bpf_prog_free(fp);
+ return -EFAULT;
+ }
fp->len = fprog->len;
- /* Since unattached filters are not copied back to user
- * space through sk_get_filter(), we do not need to hold
- * a copy here, and can spare us the work.
- */
fp->orig_prog = NULL;
+ if (save_orig) {
+ err = bpf_prog_store_orig_filter(fp, fprog);
+ if (err) {
+ __bpf_prog_free(fp);
+ return -ENOMEM;
+ }
+ }
+
/* bpf_prepare_filter() already takes care of freeing
* memory in case something goes wrong.
*/
- fp = bpf_prepare_filter(fp, NULL);
+ fp = bpf_prepare_filter(fp, trans);
if (IS_ERR(fp))
return PTR_ERR(fp);
*pfp = fp;
return 0;
}
-EXPORT_SYMBOL_GPL(bpf_prog_create);
+EXPORT_SYMBOL_GPL(bpf_prog_create_from_user);
+
+void bpf_prog_destroy(struct bpf_prog *fp)
+{
+ __bpf_prog_release(fp);
+}
+EXPORT_SYMBOL_GPL(bpf_prog_destroy);
/**
- * bpf_prog_create_from_user - create an unattached filter from user buffer
+ * sk_filter_trim_cap - run a packet through a socket filter
+ * @sk: sock associated with &sk_buff
+ * @skb: buffer to filter
+ * @cap: limit on how short the eBPF program may trim the packet
+ *
+ * Run the eBPF program and then cut skb->data to correct size returned by
+ * the program. If pkt_len is 0 we toss packet. If skb->len is smaller
+ * than pkt_len we keep whole skb->data. This is the socket level
+ * wrapper to BPF_PROG_RUN. It returns 0 if the packet should
+ * be accepted or -EPERM if the packet should be tossed.
+ *
+ */
+int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap)
+{
+ int err;
+ struct sk_filter *filter;
+
+ /*
+ * If the skb was allocated from pfmemalloc reserves, only
+ * allow SOCK_MEMALLOC sockets to use it as this socket is
+ * helping free memory
+ */
+ if (skb_pfmemalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC)) {
+ NET_INC_STATS(sock_net(sk), LINUX_MIB_PFMEMALLOCDROP);
+ return -ENOMEM;
+ }
+ err = BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb);
+ if (err)
+ return err;
+
+ err = security_sock_rcv_skb(sk, skb);
+ if (err)
+ return err;
+
+ rcu_read_lock();
+ filter = rcu_dereference(sk->sk_filter);
+ if (filter) {
+ struct sock *save_sk = skb->sk;
+ unsigned int pkt_len;
+
+ skb->sk = sk;
+ pkt_len = bpf_prog_run_save_cb(filter->prog, skb);
+ skb->sk = save_sk;
+ err = pkt_len ? pskb_trim(skb, max(cap, pkt_len)) : -EPERM;
+ }
+ rcu_read_unlock();
+
+ return err;
+}
+EXPORT_SYMBOL(sk_filter_trim_cap);
+
+static const struct bpf_func_proto bpf_get_raw_smp_processor_id_proto = {
+ .func = bpf_get_raw_cpu_id,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+};
+
+static void __sk_filter_release(struct sk_filter *fp)
+{
+ __bpf_prog_release(fp->prog);
+ kfree(fp);
+}
+
+/**
+ * sk_filter_release_rcu - Release a socket filter by rcu_head
+ * @rcu: rcu_head that contains the sk_filter to free
+ */
+static void sk_filter_release_rcu(struct rcu_head *rcu)
+{
+ struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
+
+ __sk_filter_release(fp);
+}
+
+/**
+ * sk_filter_release - release a socket filter
+ * @fp: filter to remove
+ *
+ * Remove a filter from a socket and release its resources.
+ */
+static void sk_filter_release(struct sk_filter *fp)
+{
+ if (refcount_dec_and_test(&fp->refcnt))
+ call_rcu(&fp->rcu, sk_filter_release_rcu);
+}
+
+void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
+{
+ u32 filter_size = bpf_prog_size(fp->prog->len);
+
+ atomic_sub(filter_size, &sk->sk_omem_alloc);
+ sk_filter_release(fp);
+}
+
+/* try to charge the socket memory if there is space available
+ * return true on success
+ */
+static bool __sk_filter_charge(struct sock *sk, struct sk_filter *fp)
+{
+ u32 filter_size = bpf_prog_size(fp->prog->len);
+
+ /* same check as in sock_kmalloc() */
+ if (filter_size <= sysctl_optmem_max &&
+ atomic_read(&sk->sk_omem_alloc) + filter_size < sysctl_optmem_max) {
+ atomic_add(filter_size, &sk->sk_omem_alloc);
+ return true;
+ }
+ return false;
+}
+
+bool sk_filter_charge(struct sock *sk, struct sk_filter *fp)
+{
+ if (!refcount_inc_not_zero(&fp->refcnt))
+ return false;
+
+ if (!__sk_filter_charge(sk, fp)) {
+ sk_filter_release(fp);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * bpf_prog_create - create an unattached filter
* @pfp: the unattached filter that is created
* @fprog: the filter program
- * @trans: post-classic verifier transformation handler
- * @save_orig: save classic BPF program
*
- * This function effectively does the same as bpf_prog_create(), only
- * that it builds up its insns buffer from user space provided buffer.
- * It also allows for passing a bpf_aux_classic_check_t handler.
+ * Create a filter independent of any socket. We first run some
+ * sanity checks on it to make sure it does not explode on us later.
+ * If an error occurs or there is insufficient memory for the filter
+ * a negative errno code is returned. On success the return is zero.
*/
-int bpf_prog_create_from_user(struct bpf_prog **pfp, struct sock_fprog *fprog,
- bpf_aux_classic_check_t trans, bool save_orig)
+int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
{
unsigned int fsize = bpf_classic_proglen(fprog);
struct bpf_prog *fp;
- int err;
/* Make sure new filter is there and in the right amounts. */
if (!bpf_check_basics_ok(fprog->filter, fprog->len))
@@ -1383,39 +1396,26 @@ int bpf_prog_create_from_user(struct bpf_prog **pfp, struct sock_fprog *fprog,
if (!fp)
return -ENOMEM;
- if (copy_from_user(fp->insns, fprog->filter, fsize)) {
- __bpf_prog_free(fp);
- return -EFAULT;
- }
+ memcpy(fp->insns, fprog->filter, fsize);
fp->len = fprog->len;
+ /* Since unattached filters are not copied back to user
+ * space through sk_get_filter(), we do not need to hold
+ * a copy here, and can spare us the work.
+ */
fp->orig_prog = NULL;
- if (save_orig) {
- err = bpf_prog_store_orig_filter(fp, fprog);
- if (err) {
- __bpf_prog_free(fp);
- return -ENOMEM;
- }
- }
-
/* bpf_prepare_filter() already takes care of freeing
* memory in case something goes wrong.
*/
- fp = bpf_prepare_filter(fp, trans);
+ fp = bpf_prepare_filter(fp, NULL);
if (IS_ERR(fp))
return PTR_ERR(fp);
*pfp = fp;
return 0;
}
-EXPORT_SYMBOL_GPL(bpf_prog_create_from_user);
-
-void bpf_prog_destroy(struct bpf_prog *fp)
-{
- __bpf_prog_release(fp);
-}
-EXPORT_SYMBOL_GPL(bpf_prog_destroy);
+EXPORT_SYMBOL_GPL(bpf_prog_create);
static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk)
{
--
2.7.4
Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B
^ permalink raw reply related [flat|nested] 5+ messages in thread* [less-CONFIG_NET v2 2/8] net: reorder flow_dissector
[not found] ` <1530189936-25780-1-git-send-email-nmanthey@amazon.de>
2018-06-28 12:45 ` [less-CONFIG_NET v2 1/8] net: reorder filter code Norbert Manthey
@ 2018-06-28 12:45 ` Norbert Manthey
2018-06-28 12:45 ` [less-CONFIG_NET v2 3/8] seccomp: include net Norbert Manthey
` (2 subsequent siblings)
4 siblings, 0 replies; 5+ messages in thread
From: Norbert Manthey @ 2018-06-28 12:45 UTC (permalink / raw)
To: Norbert Manthey, linux-kernel
Cc: David S. Miller, David Ahern, Jiri Pirko, Jon Maloy, Simon Horman,
Paolo Abeni, Tom Herbert, Michal Kubecek, Sven Eckelmann,
WANG Cong, netdev
This commit reorders the definitions, such that in the next step we
can easily cut the file into a commonly used part, as well as a part
that is only required in case CONFIG_NET is used.
This is part of the effort to split CONFIG_SECCOMP_FILTER and
CONFIG_NET.
Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
---
net/core/flow_dissector.c | 206 +++++++++++++++++++++++-----------------------
1 file changed, 103 insertions(+), 103 deletions(-)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 53f96e4..76d0b23 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1085,36 +1085,6 @@ static inline size_t flow_keys_hash_length(const struct flow_keys *flow)
return (sizeof(*flow) - diff) / sizeof(u32);
}
-__be32 flow_get_u32_src(const struct flow_keys *flow)
-{
- switch (flow->control.addr_type) {
- case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
- return flow->addrs.v4addrs.src;
- case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
- return (__force __be32)ipv6_addr_hash(
- &flow->addrs.v6addrs.src);
- case FLOW_DISSECTOR_KEY_TIPC:
- return flow->addrs.tipckey.key;
- default:
- return 0;
- }
-}
-EXPORT_SYMBOL(flow_get_u32_src);
-
-__be32 flow_get_u32_dst(const struct flow_keys *flow)
-{
- switch (flow->control.addr_type) {
- case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
- return flow->addrs.v4addrs.dst;
- case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
- return (__force __be32)ipv6_addr_hash(
- &flow->addrs.v6addrs.dst);
- default:
- return 0;
- }
-}
-EXPORT_SYMBOL(flow_get_u32_dst);
-
static inline void __flow_hash_consistentify(struct flow_keys *keys)
{
int addr_diff, i;
@@ -1162,49 +1132,6 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
return hash;
}
-u32 flow_hash_from_keys(struct flow_keys *keys)
-{
- __flow_hash_secret_init();
- return __flow_hash_from_keys(keys, hashrnd);
-}
-EXPORT_SYMBOL(flow_hash_from_keys);
-
-static inline u32 ___skb_get_hash(const struct sk_buff *skb,
- struct flow_keys *keys, u32 keyval)
-{
- skb_flow_dissect_flow_keys(skb, keys,
- FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
-
- return __flow_hash_from_keys(keys, keyval);
-}
-
-struct _flow_keys_digest_data {
- __be16 n_proto;
- u8 ip_proto;
- u8 padding;
- __be32 ports;
- __be32 src;
- __be32 dst;
-};
-
-void make_flow_keys_digest(struct flow_keys_digest *digest,
- const struct flow_keys *flow)
-{
- struct _flow_keys_digest_data *data =
- (struct _flow_keys_digest_data *)digest;
-
- BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
-
- memset(digest, 0, sizeof(*digest));
-
- data->n_proto = flow->basic.n_proto;
- data->ip_proto = flow->basic.ip_proto;
- data->ports = flow->ports.ports;
- data->src = flow->addrs.v4addrs.src;
- data->dst = flow->addrs.v4addrs.dst;
-}
-EXPORT_SYMBOL(make_flow_keys_digest);
-
static struct flow_dissector flow_keys_dissector_symmetric __read_mostly;
u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
@@ -1222,36 +1149,6 @@ u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
-/**
- * __skb_get_hash: calculate a flow hash
- * @skb: sk_buff to calculate flow hash from
- *
- * This function calculates a flow hash based on src/dst addresses
- * and src/dst port numbers. Sets hash in skb to non-zero hash value
- * on success, zero indicates no valid hash. Also, sets l4_hash in skb
- * if hash is a canonical 4-tuple hash over transport ports.
- */
-void __skb_get_hash(struct sk_buff *skb)
-{
- struct flow_keys keys;
- u32 hash;
-
- __flow_hash_secret_init();
-
- hash = ___skb_get_hash(skb, &keys, hashrnd);
-
- __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
-}
-EXPORT_SYMBOL(__skb_get_hash);
-
-__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
-{
- struct flow_keys keys;
-
- return ___skb_get_hash(skb, &keys, perturb);
-}
-EXPORT_SYMBOL(skb_get_hash_perturb);
-
u32 __skb_get_poff(const struct sk_buff *skb, void *data,
const struct flow_keys_basic *keys, int hlen)
{
@@ -1322,6 +1219,109 @@ u32 skb_get_poff(const struct sk_buff *skb)
return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
}
+__be32 flow_get_u32_src(const struct flow_keys *flow)
+{
+ switch (flow->control.addr_type) {
+ case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
+ return flow->addrs.v4addrs.src;
+ case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
+ return (__force __be32)ipv6_addr_hash(
+ &flow->addrs.v6addrs.src);
+ case FLOW_DISSECTOR_KEY_TIPC:
+ return flow->addrs.tipckey.key;
+ default:
+ return 0;
+ }
+}
+EXPORT_SYMBOL(flow_get_u32_src);
+
+__be32 flow_get_u32_dst(const struct flow_keys *flow)
+{
+ switch (flow->control.addr_type) {
+ case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
+ return flow->addrs.v4addrs.dst;
+ case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
+ return (__force __be32)ipv6_addr_hash(
+ &flow->addrs.v6addrs.dst);
+ default:
+ return 0;
+ }
+}
+EXPORT_SYMBOL(flow_get_u32_dst);
+
+u32 flow_hash_from_keys(struct flow_keys *keys)
+{
+ __flow_hash_secret_init();
+ return __flow_hash_from_keys(keys, hashrnd);
+}
+EXPORT_SYMBOL(flow_hash_from_keys);
+
+static inline u32 ___skb_get_hash(const struct sk_buff *skb,
+ struct flow_keys *keys, u32 keyval)
+{
+ skb_flow_dissect_flow_keys(skb, keys,
+ FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
+
+ return __flow_hash_from_keys(keys, keyval);
+}
+
+struct _flow_keys_digest_data {
+ __be16 n_proto;
+ u8 ip_proto;
+ u8 padding;
+ __be32 ports;
+ __be32 src;
+ __be32 dst;
+};
+
+void make_flow_keys_digest(struct flow_keys_digest *digest,
+ const struct flow_keys *flow)
+{
+ struct _flow_keys_digest_data *data =
+ (struct _flow_keys_digest_data *)digest;
+
+ BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
+
+ memset(digest, 0, sizeof(*digest));
+
+ data->n_proto = flow->basic.n_proto;
+ data->ip_proto = flow->basic.ip_proto;
+ data->ports = flow->ports.ports;
+ data->src = flow->addrs.v4addrs.src;
+ data->dst = flow->addrs.v4addrs.dst;
+}
+EXPORT_SYMBOL(make_flow_keys_digest);
+
+/**
+ * __skb_get_hash: calculate a flow hash
+ * @skb: sk_buff to calculate flow hash from
+ *
+ * This function calculates a flow hash based on src/dst addresses
+ * and src/dst port numbers. Sets hash in skb to non-zero hash value
+ * on success, zero indicates no valid hash. Also, sets l4_hash in skb
+ * if hash is a canonical 4-tuple hash over transport ports.
+ */
+void __skb_get_hash(struct sk_buff *skb)
+{
+ struct flow_keys keys;
+ u32 hash;
+
+ __flow_hash_secret_init();
+
+ hash = ___skb_get_hash(skb, &keys, hashrnd);
+
+ __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
+}
+EXPORT_SYMBOL(__skb_get_hash);
+
+__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
+{
+ struct flow_keys keys;
+
+ return ___skb_get_hash(skb, &keys, perturb);
+}
+EXPORT_SYMBOL(skb_get_hash_perturb);
+
__u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys)
{
memset(keys, 0, sizeof(*keys));
--
2.7.4
Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B
^ permalink raw reply related [flat|nested] 5+ messages in thread* [less-CONFIG_NET v2 3/8] seccomp: include net
[not found] ` <1530189936-25780-1-git-send-email-nmanthey@amazon.de>
2018-06-28 12:45 ` [less-CONFIG_NET v2 1/8] net: reorder filter code Norbert Manthey
2018-06-28 12:45 ` [less-CONFIG_NET v2 2/8] net: reorder flow_dissector Norbert Manthey
@ 2018-06-28 12:45 ` Norbert Manthey
2018-06-28 12:45 ` [less-CONFIG_NET v2 5/8] seccomp: cut off functions not required Norbert Manthey
2018-06-28 12:45 ` [less-CONFIG_NET v2 6/8] bpf: avoid duplicate definitions Norbert Manthey
4 siblings, 0 replies; 5+ messages in thread
From: Norbert Manthey @ 2018-06-28 12:45 UTC (permalink / raw)
To: Norbert Manthey, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, David S. Miller, netdev
When we want to use CONFIG_SECCOMP_FILTER without CONFIG_NET, we have
to ensure that the required files that would be pulled in via
CONFIG_NET are compiled when dropping CONFIG_NET.
Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
---
kernel/bpf/Makefile | 1 +
net/Makefile | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
index f27f549..16936c0 100644
--- a/kernel/bpf/Makefile
+++ b/kernel/bpf/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o
obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o
obj-$(CONFIG_BPF_SYSCALL) += disasm.o
obj-$(CONFIG_BPF_SYSCALL) += btf.o
+
ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_BPF_SYSCALL) += devmap.o
obj-$(CONFIG_BPF_SYSCALL) += cpumap.o
diff --git a/net/Makefile b/net/Makefile
index 13ec0d5..f3fb03a 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -11,6 +11,11 @@ obj-$(CONFIG_NET) := socket.o core/
tmp-$(CONFIG_COMPAT) := compat.o
obj-$(CONFIG_NET) += $(tmp-y)
+ifneq ($(CONFIG_NET),y)
+obj-$(CONFIG_SECCOMP_FILTER) += core/filter.o
+obj-$(CONFIG_SECCOMP_FILTER) += core/flow_dissector.o
+endif
+
# LLC has to be linked before the files in net/802/
obj-$(CONFIG_LLC) += llc/
obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/ bpf/
--
2.7.4
Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B
^ permalink raw reply related [flat|nested] 5+ messages in thread* [less-CONFIG_NET v2 5/8] seccomp: cut off functions not required
[not found] ` <1530189936-25780-1-git-send-email-nmanthey@amazon.de>
` (2 preceding siblings ...)
2018-06-28 12:45 ` [less-CONFIG_NET v2 3/8] seccomp: include net Norbert Manthey
@ 2018-06-28 12:45 ` Norbert Manthey
2018-06-28 12:45 ` [less-CONFIG_NET v2 6/8] bpf: avoid duplicate definitions Norbert Manthey
4 siblings, 0 replies; 5+ messages in thread
From: Norbert Manthey @ 2018-06-28 12:45 UTC (permalink / raw)
To: Norbert Manthey, linux-kernel
Cc: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
Ido Schimmel, Paolo Abeni, Andrew Lunn, Tom Herbert, Simon Horman,
Michal Kubecek, John Crispin, Sven Eckelmann, WANG Cong,
David Ahern, Jon Maloy, netdev
When using CONFIG_SECCOMP_FILTER, not all functions of filter.c and
flow_dissector.c are required. To not pull in more dependencies,
guard the functions that are not required with CONFIG_NET defines.
This way, these functions are enabled in case the file is compiled
because of CONFIG_NET, but they are not present when the file is
compiled because of other configurations.
Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
---
net/core/filter.c | 2 ++
net/core/flow_dissector.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/net/core/filter.c b/net/core/filter.c
index 61c24c9..410189c 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1250,6 +1250,7 @@ void bpf_prog_destroy(struct bpf_prog *fp)
}
EXPORT_SYMBOL_GPL(bpf_prog_destroy);
+#if defined(CONFIG_NET)
/**
* sk_filter_trim_cap - run a packet through a socket filter
* @sk: sock associated with &sk_buff
@@ -6823,3 +6824,4 @@ int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf,
release_sock(sk);
return ret;
}
+#endif // CONFIG_NET
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 76d0b23..f5ba8e9 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1219,6 +1219,7 @@ u32 skb_get_poff(const struct sk_buff *skb)
return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
}
+#if defined(CONFIG_NET)
__be32 flow_get_u32_src(const struct flow_keys *flow)
{
switch (flow->control.addr_type) {
@@ -1340,6 +1341,7 @@ __u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys)
return flow_hash_from_keys(keys);
}
EXPORT_SYMBOL(__get_hash_from_flowi6);
+#endif // CONFIG_NET
static const struct flow_dissector_key flow_keys_dissector_keys[] = {
{
--
2.7.4
Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B
^ permalink raw reply related [flat|nested] 5+ messages in thread* [less-CONFIG_NET v2 6/8] bpf: avoid duplicate definitions
[not found] ` <1530189936-25780-1-git-send-email-nmanthey@amazon.de>
` (3 preceding siblings ...)
2018-06-28 12:45 ` [less-CONFIG_NET v2 5/8] seccomp: cut off functions not required Norbert Manthey
@ 2018-06-28 12:45 ` Norbert Manthey
4 siblings, 0 replies; 5+ messages in thread
From: Norbert Manthey @ 2018-06-28 12:45 UTC (permalink / raw)
To: Norbert Manthey, linux-kernel; +Cc: Alexei Starovoitov, Daniel Borkmann, netdev
With the aim of making CONFIG_SECCOMP_FILTER independent of CONFIG_NET,
some bpf functions are not required to provide net functionality, as
already implemented in the header include/linux/bpf.h. However, the source
files assumed to be only included if CONFIG_NET is activated.
To be able to include the source files while CONFIG_NET is disabled, make
sure the functions defined in the header include/linux/bpf.h are not
included in the source file.
To reduce the amount of #ifdef CONFIG_NET guards, the position of the
functions __bpf_map_offload_destroy and bpf_map_offload_map_alloc has been
swapped.
Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
---
kernel/bpf/offload.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
index ac747d5..7042dbe 100644
--- a/kernel/bpf/offload.c
+++ b/kernel/bpf/offload.c
@@ -32,6 +32,7 @@ static DECLARE_RWSEM(bpf_devs_lock);
static LIST_HEAD(bpf_prog_offload_devs);
static LIST_HEAD(bpf_map_offload_devs);
+#ifdef CONFIG_NET
static int bpf_dev_offload_check(struct net_device *netdev)
{
if (!netdev)
@@ -84,6 +85,7 @@ int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr)
kfree(offload);
return err;
}
+#endif // CONFIG_NET
static int __bpf_offload_ndo(struct bpf_prog *prog, enum bpf_netdev_command cmd,
struct netdev_bpf *data)
@@ -291,6 +293,16 @@ static int bpf_map_offload_ndo(struct bpf_offloaded_map *offmap,
return netdev->netdev_ops->ndo_bpf(netdev, &data);
}
+static void __bpf_map_offload_destroy(struct bpf_offloaded_map *offmap)
+{
+ WARN_ON(bpf_map_offload_ndo(offmap, BPF_OFFLOAD_MAP_FREE));
+ /* Make sure BPF_MAP_GET_NEXT_ID can't find this dead map */
+ bpf_map_free_id(&offmap->map, true);
+ list_del_init(&offmap->offloads);
+ offmap->netdev = NULL;
+}
+
+#ifdef CONFIG_NET
struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr)
{
struct net *net = current->nsproxy->net_ns;
@@ -333,15 +345,6 @@ struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr)
return ERR_PTR(err);
}
-static void __bpf_map_offload_destroy(struct bpf_offloaded_map *offmap)
-{
- WARN_ON(bpf_map_offload_ndo(offmap, BPF_OFFLOAD_MAP_FREE));
- /* Make sure BPF_MAP_GET_NEXT_ID can't find this dead map */
- bpf_map_free_id(&offmap->map, true);
- list_del_init(&offmap->offloads);
- offmap->netdev = NULL;
-}
-
void bpf_map_offload_map_free(struct bpf_map *map)
{
struct bpf_offloaded_map *offmap = map_to_offmap(map);
@@ -355,6 +358,7 @@ void bpf_map_offload_map_free(struct bpf_map *map)
kfree(offmap);
}
+#endif // CONFIG_NET
int bpf_map_offload_lookup_elem(struct bpf_map *map, void *key, void *value)
{
--
2.7.4
Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B
^ permalink raw reply related [flat|nested] 5+ messages in thread