From patchwork Thu Jan 31 01:51:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 217064 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 7F5022C008D for ; Thu, 31 Jan 2013 12:51:51 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753862Ab3AaBvt (ORCPT ); Wed, 30 Jan 2013 20:51:49 -0500 Received: from mail-pb0-f54.google.com ([209.85.160.54]:44802 "EHLO mail-pb0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753470Ab3AaBvr (ORCPT ); Wed, 30 Jan 2013 20:51:47 -0500 Received: by mail-pb0-f54.google.com with SMTP id rr4so1322227pbb.41 for ; Wed, 30 Jan 2013 17:51:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:message-id:subject:from:to:cc:date:content-type:x-mailer :content-transfer-encoding:mime-version; bh=eJv7cow55KOKD2pW0YieZmFV3hvJRy0YgkeD0Cn3ZKQ=; b=FwGrDqrRfHXXnpvtwe3HiMxoQl+BzJiiTqDDuZY2VEmOwjby+QuyBkLslE4uvQKDjc gtNtLOn5bF76wtfWMedC80/obiopjU56tCsa+QkyXkiUtZ3LfhOV7PN8/VXnGVPNaRUo 0/PS9i3h0ynfpMVQcDXUdoFbfM1jQqFfi3qUkz6lSIL5CwXJh54OONBWULX45VEKt/vQ o9CM+Lw8+2Ye5Dseqiaw+s4mnf4/WeZDfLGd0QelGJOPuFtq6rybF06P3k9ei4AI99sL jatzFRxR7LjjWXl/2u3a2xlTc6fHiHMu7yN5ANn0yP5jaq+60tAF4N9vshD5KGbffdqk iAPA== X-Received: by 10.66.87.8 with SMTP id t8mr16233199paz.28.1359597106842; Wed, 30 Jan 2013 17:51:46 -0800 (PST) Received: from ?IPv6:2620:0:1000:3304:6492:dc53:44c3:e50b? ([2620:0:1000:3304:6492:dc53:44c3:e50b]) by mx.google.com with ESMTPS id bj9sm3767933pab.22.2013.01.30.17.51.45 (version=SSLv3 cipher=RC4-SHA bits=128/128); Wed, 30 Jan 2013 17:51:46 -0800 (PST) Message-ID: <1359597104.30177.24.camel@edumazet-glaptop> Subject: [PATCH net-next] x86: bpf_jit_comp: add pkt_type support From: Eric Dumazet To: David Miller Cc: netdev , Maciej =?UTF-8?Q?=C5=BBenczykowski?= , Willem de Bruijn Date: Wed, 30 Jan 2013 17:51:44 -0800 X-Mailer: Evolution 3.2.3-0ubuntu6 Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Eric Dumazet Supporting access to skb->pkt_type is a bit tricky if we want to have a generic code, allowing pkt_type to be moved in struct sk_buff pkt_type is a bit field, so compiler cannot really help us to find its offset. Let's use a helper for this : It will throw a one time message if pkt_type no longer starts at a byte boundary or is no longer a 3bit field. Reported-by: Willem de Bruijn Signed-off-by: Eric Dumazet Cc: Maciej Żenczykowski --- arch/x86/net/bpf_jit_comp.c | 40 +++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index d11a470..3cbe4538 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -1,6 +1,6 @@ /* bpf_jit_comp.c : BPF JIT compiler * - * Copyright (C) 2011 Eric Dumazet (eric.dumazet@gmail.com) + * Copyright (C) 2011-2013 Eric Dumazet (eric.dumazet@gmail.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -124,6 +124,26 @@ static inline void bpf_flush_icache(void *start, void *end) #define CHOOSE_LOAD_FUNC(K, func) \ ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset) +/* Helper to find the offset of pkt_type in sk_buff + * We want to make sure its still a 3bit field starting at a byte boundary. + */ +#define PKT_TYPE_MAX 7 +static int pkt_type_offset(void) +{ + struct sk_buff skb_probe = { + .pkt_type = ~0, + }; + char *ct = (char *)&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; +} + void bpf_jit_compile(struct sk_filter *fp) { u8 temp[64]; @@ -216,6 +236,7 @@ void bpf_jit_compile(struct sk_filter *fp) case BPF_S_ANC_VLAN_TAG: case BPF_S_ANC_VLAN_TAG_PRESENT: case BPF_S_ANC_QUEUE: + case BPF_S_ANC_PKTTYPE: case BPF_S_LD_W_ABS: case BPF_S_LD_H_ABS: case BPF_S_LD_B_ABS: @@ -536,6 +557,23 @@ void bpf_jit_compile(struct sk_filter *fp) EMIT3(0x83, 0xe0, 0x01); /* and $0x1,%eax */ } break; + case BPF_S_ANC_PKTTYPE: + { + int off = pkt_type_offset(); + + if (off < 0) + goto out; + if (is_imm8(off)) { + /* movzbl off8(%rdi),%eax */ + EMIT4(0x0f, 0xb6, 0x47, off); + } else { + /* movbl off32(%rdi),%eax */ + EMIT3(0x0f, 0xb6, 0x87); + EMIT(off, 4); + } + EMIT3(0x83, 0xe0, PKT_TYPE_MAX); /* and $0x7,%eax */ + break; + } case BPF_S_LD_W_ABS: func = CHOOSE_LOAD_FUNC(K, sk_load_word); common_load: seen |= SEEN_DATAREF;