From patchwork Wed Mar 19 16:05:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arturo Borrero X-Patchwork-Id: 331778 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id B98242C00E7 for ; Thu, 20 Mar 2014 03:05:32 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965640AbaCSQF0 (ORCPT ); Wed, 19 Mar 2014 12:05:26 -0400 Received: from smtp3.cica.es ([150.214.5.190]:45722 "EHLO smtp.cica.es" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S965600AbaCSQFX (ORCPT ); Wed, 19 Mar 2014 12:05:23 -0400 Received: from localhost (unknown [127.0.0.1]) by smtp.cica.es (Postfix) with ESMTP id 43D2251ED32; Wed, 19 Mar 2014 16:05:20 +0000 (UTC) X-Virus-Scanned: amavisd-new at cica.es Received: from smtp.cica.es ([127.0.0.1]) by localhost (mail.cica.es [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id noWb1IMFFF1P; Wed, 19 Mar 2014 17:05:14 +0100 (CET) Received: from nfdev.cica.es (nfdev.cica.es [IPv6:2a00:9ac0:c1ca:31::220]) by smtp.cica.es (Postfix) with ESMTP id C16F851ED34; Wed, 19 Mar 2014 17:05:14 +0100 (CET) Subject: [nf_tables RFH PATCH] netfilter: nf_tables: add set_elem notifications To: netfilter-devel@vger.kernel.org From: Arturo Borrero Gonzalez Cc: pablo@netfilter.org Date: Wed, 19 Mar 2014 17:05:12 +0100 Message-ID: <20140319160352.2849.30373.stgit@nfdev.cica.es> User-Agent: StGit/0.15 MIME-Version: 1.0 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This patch adds set_elems notifications. When a set_elem is added/deleted, all listening peers in userspace will receive the corresponding notification. Signed-off-by: Arturo Borrero Gonzalez --- RFH: I'm requesting for a bit of help. Could anyone give me a few hints about what may be wrong? When adding a rule with an anonymous set with some elements, I keep having this: BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 IP: [] __skb_recv_datagram+0x126/0x3c1 PGD 3694a067 PUD 3714f067 PMD 0 Oops: 0002 [#1] SMP Modules linked in: nf_conntrack_netlink nf_conntrack loop snd_pcm snd_timer snd soundcore microcode psmouse parport_pc evdev parport pcspkr virtio_balloon serio_raw i2c_piix4 i2c_core processor button thermal_sys ext4 crc16 jbd2 mbcache sg sr_mod cdrom ata_generic floppy virtio_blk virtio_net ata_piix uhci_hcd ehci_hcd libata usbcore virtio_pci usb_common virtio_ring virtio scsi_mod CPU: 0 PID: 2782 Comm: lt-nft-events Not tainted 3.13.0+ #57 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 task: ffff8800373d8210 ti: ffff88003a4ac000 task.ti: ffff88003a4ac000 RIP: 0010:[] [] __skb_recv_datagram+0x126/0x3c1 RSP: 0018:ffff88003a4adb58 EFLAGS: 00010046 RAX: ffff88003a87f090 RBX: 7fffffffffffffff RCX: 0000000000000000 RDX: ffff88003a87f0a4 RSI: 0000000000000246 RDI: ffff88003a4adc20 RBP: ffff88003a87f090 R08: ffff88003a4adc48 R09: 00007f066a578700 R10: 0000000000000000 R11: 0000000000001000 R12: ffff88003a4adc48 R13: ffff88003a87f000 R14: ffff8800371b4940 R15: 0000000000000000 FS: 00007f066a578700(0000) GS:ffff88003ce00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 00000000369ae000 CR4: 00000000000006f0 Stack: ffff88003a87f0a4 0000000000000000 ffff88003d0fbb08 ffff88003a87f090 ffff88003a4adc24 ffff88003a4adfd8 ffff8800373d8210 ffff88003a4adc20 ffff88003a4adfd8 ffff8800373d8210 0000000000000044 0000000000000000 Call Trace: [] ? skb_recv_datagram+0x2c/0x31 [] ? netlink_recvmsg+0x47/0x2dd [] ? resched_task+0x15/0x4b [] ? check_preempt_wakeup+0x125/0x18b [] ? sock_recvmsg+0x54/0x71 [] ? __queue_work+0x1ef/0x23d [] ? ___sys_recvmsg+0x14a/0x1fc [] ? __wake_up+0x35/0x46 [] ? fsnotify+0x216/0x252 [] ? __dequeue_entity+0x19/0x2d [] ? __switch_to+0x1b1/0x3e0 [] ? finish_task_switch+0x44/0xbd [] ? __sys_recvmsg+0x39/0x57 [] ? system_call_fastpath+0x16/0x1b Code: 80 4e 7d 40 f0 41 ff 86 e4 00 00 00 eb 24 41 ff 8d a0 00 00 00 49 8b 0e 49 8b 46 08 49 c7 06 00 00 00 00 49 c7 46 08 00 00 00 00 <48> 89 41 08 48 89 08 48 89 d7 e8 30 af 0d 00 48 8b 4c 24 20 44 RIP [] __skb_recv_datagram+0x126/0x3c1 RSP CR2: 0000000000000008 ---[ end trace 4dbd24a21c60d72b ]--- net/netfilter/nf_tables_api.c | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index adce01e..33b1585 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2712,6 +2712,71 @@ static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb, return -EOPNOTSUPP; } +static int nf_tables_setelem_notify(const struct nft_ctx *ctx, + const struct nft_set *set, + const struct nft_set_elem *elem, + int event, u16 flags) +{ + const struct sk_buff *oskb = ctx->skb; + struct sk_buff *skb; + struct net *net; + struct nfgenmsg *nfmsg; + struct nlmsghdr *nlh; + struct nlattr *nest; + bool report; + u32 portid; + u32 seq = ctx->nlh->nlmsg_seq; + int err; + + portid = oskb ? NETLINK_CB(oskb).portid : 0; + net = oskb ? sock_net(oskb->sk) : &init_net; + + report = ctx->nlh ? nlmsg_report(ctx->nlh) : false; + if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) + return 0; + + err = -ENOBUFS; + skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (skb == NULL) + goto err; + + event |= NFNL_SUBSYS_NFTABLES << 8; + nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), + flags); + if (nlh == NULL) + goto err_free; + + nfmsg = nlmsg_data(nlh); + nfmsg->nfgen_family = ctx->afi->family; + nfmsg->version = NFNETLINK_V0; + nfmsg->res_id = 0; + + if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name)) + goto err_free; + if (nla_put_string(skb, NFTA_SET_NAME, set->name)) + goto err_free; + + nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS); + if (nest == NULL) + goto err_free; + + err = nf_tables_fill_setelem(skb, set, elem); + if (err < 0) + goto err_free; + + nla_nest_end(skb, nest); + nlmsg_end(skb, nlh); + + err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, + GFP_KERNEL); +err_free: + kfree_skb(skb); +err: + if (err < 0) + nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err); + return err; +} + static int nft_add_set_elem(const struct nft_ctx *ctx, struct nft_set *set, const struct nlattr *attr) { @@ -2788,6 +2853,7 @@ static int nft_add_set_elem(const struct nft_ctx *ctx, struct nft_set *set, if (err < 0) goto err3; + nf_tables_setelem_notify(ctx, set, &elem, NFT_MSG_NEWSETELEM, 0); return 0; err3: @@ -2857,6 +2923,8 @@ static int nft_del_setelem(const struct nft_ctx *ctx, struct nft_set *set, set->ops->remove(set, &elem); + nf_tables_setelem_notify(ctx, set, &elem, NFT_MSG_DELSETELEM, 0); + nft_data_uninit(&elem.key, NFT_DATA_VALUE); if (set->flags & NFT_SET_MAP) nft_data_uninit(&elem.data, set->dtype);