From patchwork Wed Sep 3 21:08:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Kirjanov X-Patchwork-Id: 385668 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9327D1401EC for ; Thu, 4 Sep 2014 07:35:12 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755633AbaICVfG (ORCPT ); Wed, 3 Sep 2014 17:35:06 -0400 Received: from mail-la0-f49.google.com ([209.85.215.49]:37598 "EHLO mail-la0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754851AbaICVfE (ORCPT ); Wed, 3 Sep 2014 17:35:04 -0400 Received: by mail-la0-f49.google.com with SMTP id b17so10438379lan.8 for ; Wed, 03 Sep 2014 14:35:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=+vlsUyQGpUYCSTymea+S2uARDpcjOq5vhwOd2M4YsCQ=; b=XsOyGLpXYYT7JAkHHnv4/hZi7OZ29L2l5Sk9XvlIOSTOZp1mmpgiAa6q4Ght3j9Sd1 nAHLU5V1efKOLDiVNRgZ6UgPR8HVRA0XzA+GSX6TL7OFKEQ/MOO2jbvYEKH8E17fCUAH zFZgH/LPBx9fsO06HCJjqUxhXm2SiB7AYiwpulg8oSemxQAXkh1S/iyd+rlYOrDu8kQj bV/+88ZJJJ08PQOKm873V2iBfemsIF/6LGUTsqqBbiu+S1qlh7+N6F7IEjGTdMPOjn3R Wh8VHfaP7iMvD19BHw1FT3QEu18TXZ6k3pAC/zfKUGv30H2r2bbHhJ+1Z5zzyqh0vnpN qEYw== X-Gm-Message-State: ALoCoQm45WhSqbOvYQkTvUwvPFxMJzGoT8Ie/TRJC2zQmohXGFXRkvzjIAn1d5kss3uQ468gWSZO X-Received: by 10.152.203.130 with SMTP id kq2mr286552lac.89.1409780102525; Wed, 03 Sep 2014 14:35:02 -0700 (PDT) Received: from hydra.kdaintranet ([5.35.52.78]) by mx.google.com with ESMTPSA id q3sm1516997laj.38.2014.09.03.14.35.00 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 03 Sep 2014 14:35:01 -0700 (PDT) From: Denis Kirjanov To: netdev@vger.kernel.org Cc: Denis Kirjanov , Markos Chandras , Martin Schwidefsky , Daniel Borkmann , Alexei Starovoitov Subject: [PATCH v2 net-next] net: filter: export pkt_type_offset() helper Date: Thu, 4 Sep 2014 01:08:31 +0400 Message-Id: <1409778511-21273-1-git-send-email-kda@linux-powerpc.org> X-Mailer: git-send-email 2.0.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currently we have 2 pkt_type_offset functions doing the same thing and spread across the architecture files. Let's use the generic helper routine. Signed-off-by: Denis Kirjanov Cc: Markos Chandras Cc: Martin Schwidefsky Cc: Daniel Borkmann Cc: Alexei Starovoitov V2: Initialize the pkt_type_offset through the pure_initcall() --- arch/mips/net/bpf_jit.c | 27 ++------------------------- arch/s390/net/bpf_jit_comp.c | 31 ------------------------------- include/linux/filter.h | 2 ++ net/core/filter.c | 16 +++++++++++++--- 4 files changed, 17 insertions(+), 59 deletions(-) diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c index 05a5661..bb9b53f 100644 --- a/arch/mips/net/bpf_jit.c +++ b/arch/mips/net/bpf_jit.c @@ -765,27 +765,6 @@ static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset) return (u64)err << 32 | ntohl(ret); } -#ifdef __BIG_ENDIAN_BITFIELD -#define PKT_TYPE_MAX (7 << 5) -#else -#define PKT_TYPE_MAX 7 -#endif -static int pkt_type_offset(void) -{ - struct sk_buff skb_probe = { - .pkt_type = ~0, - }; - u8 *ct = (u8 *)&skb_probe; - unsigned int off; - - for (off = 0; off < sizeof(struct sk_buff); off++) { - if (ct[off] == PKT_TYPE_MAX) - return off; - } - pr_err_once("Please fix pkt_type_offset(), as pkt_type couldn't be found\n"); - return -1; -} - static int build_body(struct jit_ctx *ctx) { void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w}; @@ -1332,11 +1311,9 @@ jmp_cmp: case BPF_ANC | SKF_AD_PKTTYPE: ctx->flags |= SEEN_SKB; - off = pkt_type_offset(); - - if (off < 0) + if (pkt_type_offset < 0) return -1; - emit_load_byte(r_tmp, r_skb, off, ctx); + emit_load_byte(r_tmp, r_skb, pkt_type_offset, ctx); /* Keep only the last 3 bits */ emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx); #ifdef __BIG_ENDIAN_BITFIELD diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 61e45b7..caa0cab 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -223,37 +223,6 @@ static void bpf_jit_epilogue(struct bpf_jit *jit) EMIT2(0x07fe); } -/* Helper to find the offset of pkt_type in sk_buff - * Make sure its still a 3bit field starting at the MSBs within a byte. - */ -#define PKT_TYPE_MAX 0xe0 -static int pkt_type_offset; - -static int __init bpf_pkt_type_offset_init(void) -{ - struct sk_buff skb_probe = { - .pkt_type = ~0, - }; - char *ct = (char *)&skb_probe; - int off; - - pkt_type_offset = -1; - for (off = 0; off < sizeof(struct sk_buff); off++) { - if (!ct[off]) - continue; - if (ct[off] == PKT_TYPE_MAX) - pkt_type_offset = off; - else { - /* Found non matching bit pattern, fix needed. */ - WARN_ON_ONCE(1); - pkt_type_offset = -1; - return -1; - } - } - return 0; -} -device_initcall(bpf_pkt_type_offset_init); - /* * make sure we dont leak kernel information to user */ diff --git a/include/linux/filter.h b/include/linux/filter.h index a5227ab..6814b54 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -424,6 +424,8 @@ static inline void *bpf_load_pointer(const struct sk_buff *skb, int k, return bpf_internal_load_pointer_neg_helper(skb, k, size); } +extern __read_mostly int pkt_type_offset; + #ifdef CONFIG_BPF_JIT #include #include diff --git a/net/core/filter.c b/net/core/filter.c index d814b8a..edd17f1 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -96,21 +96,29 @@ EXPORT_SYMBOL(sk_filter); #else #define PKT_TYPE_MAX 7 #endif -static unsigned int pkt_type_offset(void) + +__read_mostly int pkt_type_offset; + +static int __init init_pkt_type_offset(void) { struct sk_buff skb_probe = { .pkt_type = ~0, }; u8 *ct = (u8 *) &skb_probe; unsigned int off; + pkt_type_offset = -1; for (off = 0; off < sizeof(struct sk_buff); off++) { - if (ct[off] == PKT_TYPE_MAX) + if (ct[off] == PKT_TYPE_MAX) { + pkt_type_offset = off; return off; + } } pr_err_once("Please fix %s, as pkt_type couldn't be found!\n", __func__); return -1; } +pure_initcall(init_pkt_type_offset); + static u64 __skb_get_pay_offset(u64 ctx, u64 a, u64 x, u64 r4, u64 r5) { return __skb_get_poff((struct sk_buff *)(unsigned long) ctx); @@ -190,8 +198,10 @@ static bool convert_bpf_extensions(struct sock_filter *fp, break; case SKF_AD_OFF + SKF_AD_PKTTYPE: + if (pkt_type_offset < 0) + return false; *insn = BPF_LDX_MEM(BPF_B, BPF_REG_A, BPF_REG_CTX, - pkt_type_offset()); + pkt_type_offset); if (insn->off < 0) return false; insn++;