* Re: [PATCH net-next] sctp: fix compile issue with disabled CONFIG_NET_NS
From: Ulrich Weber @ 2012-08-17 12:07 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: netdev
In-Reply-To: <87fw7m64v9.fsf@xmission.com>
Hi Eric,
On 08/16/2012 08:58 PM, Eric W. Biederman wrote:
> Ulrich do you get any performance advantage by disabling the network
> namespace? I am wondering if there is any benefit to keeping it
> possible to disable the network namespace? The original reason for the
> option was so that distributions and other who wanted to avoid new
> code could protect their users, and that reasons seems to have long
> since passed.
we just disable most of the options we don't use. I have no idea,
if there are any performance advantages here...
Cheers
Ulrich
--
Ulrich Weber | ulrich.weber@sophos.com | Senior Software Engineer
Astaro - a Sophos company | Amalienbadstr 41 | 76227 Karlsruhe | Germany
Phone +49-721-25516-0 | Fax –200 | www.astaro.com
^ permalink raw reply
* using netif_rx while NAPI is used?
From: Daniel Nilsson @ 2012-08-17 12:24 UTC (permalink / raw)
To: netdev
I have a special case (VPN router) where I sometimes need to bounce up
a packet (after being marked) that is impossible to transmit using the
netif_rx() callback. The interface normally uses NAPI and therefore is
polled in the RX direction. Will it still work to pass a small amount
of packets directly up to the kernel using the netif_rx() callback?
/Daniel
^ permalink raw reply
* Re: [PATCH 13/19] netfilter: ip6tables: add MASQUERADE target
From: Pablo Neira Ayuso @ 2012-08-17 13:11 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel, netdev
In-Reply-To: <1344542943-11588-14-git-send-email-kaber@trash.net>
Hi Patrick,
On Thu, Aug 09, 2012 at 10:08:57PM +0200, kaber@trash.net wrote:
> From: Patrick McHardy <kaber@trash.net>
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
> ---
> include/net/addrconf.h | 2 +-
> net/ipv4/netfilter/ipt_MASQUERADE.c | 3 +-
> net/ipv6/addrconf.c | 2 +-
> net/ipv6/netfilter/Kconfig | 12 +++
> net/ipv6/netfilter/Makefile | 1 +
> net/ipv6/netfilter/ip6t_MASQUERADE.c | 135 ++++++++++++++++++++++++++++++++++
> 6 files changed, 152 insertions(+), 3 deletions(-)
> create mode 100644 net/ipv6/netfilter/ip6t_MASQUERADE.c
Please, add this chunk to this patch:
diff --git a/include/net/netfilter/nf_nat.h
b/include/net/netfilter/nf_nat.h
index 1752f133..bd8eea7 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -43,7 +43,9 @@ struct nf_conn_nat {
struct nf_conn *ct;
union nf_conntrack_nat_help help;
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
- defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
+ defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) || \
+ defined(CONFIG_IP6_NF_TARGET_MASQUERADE) || \
+ defined(CONFIG_IP6_NF_TARGET_MASQUERADE_MODULE)
int masq_index;
#endif
};
Otherwise, compilation breaks with:
* IPv4 NAT is disabled
* IPv6 NAT enabled.
And yes, that pile of ifdefs is really ugly, I wonder if they are
worth for saving 4 bytes. I think most vendors usually include
MASQUERADE support if NAT is enabled.
It seems we have the tradition of keeping several similar compile time
options in Netfilter to optimize memory in several situations (at the
cost of polluting the code with ifdefs). Probably we can think of
getting rid of them.
> diff --git a/include/net/addrconf.h b/include/net/addrconf.h
> index 089a09d..9e63e76 100644
> --- a/include/net/addrconf.h
> +++ b/include/net/addrconf.h
> @@ -78,7 +78,7 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
> int strict);
>
> extern int ipv6_dev_get_saddr(struct net *net,
> - struct net_device *dev,
> + const struct net_device *dev,
> const struct in6_addr *daddr,
> unsigned int srcprefs,
> struct in6_addr *saddr);
> diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
> index 1c3aa28..5d5d4d1 100644
> --- a/net/ipv4/netfilter/ipt_MASQUERADE.c
> +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
> @@ -99,7 +99,8 @@ device_cmp(struct nf_conn *i, void *ifindex)
>
> if (!nat)
> return 0;
> -
> + if (nf_ct_l3num(i) != NFPROTO_IPV4)
> + return 0;
> return nat->masq_index == (int)(long)ifindex;
> }
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 7918181..6536404 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -1095,7 +1095,7 @@ out:
> return ret;
> }
>
> -int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
> +int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
> const struct in6_addr *daddr, unsigned int prefs,
> struct in6_addr *saddr)
> {
> diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
> index b27e0ad..54a5032 100644
> --- a/net/ipv6/netfilter/Kconfig
> +++ b/net/ipv6/netfilter/Kconfig
> @@ -144,6 +144,18 @@ config IP6_NF_TARGET_HL
> (e.g. when running oldconfig). It selects
> CONFIG_NETFILTER_XT_TARGET_HL.
>
> +config IP6_NF_TARGET_MASQUERADE
> + tristate "MASQUERADE target support"
> + depends on NF_NAT_IPV6
> + help
> + Masquerading is a special case of NAT: all outgoing connections are
> + changed to seem to come from a particular interface's address, and
> + if the interface goes down, those connections are lost. This is
> + only useful for dialup accounts with dynamic IP address (ie. your IP
> + address will be different on next dialup).
> +
> + To compile it as a module, choose M here. If unsure, say N.
> +
> config IP6_NF_FILTER
> tristate "Packet filtering"
> default m if NETFILTER_ADVANCED=n
> diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
> index 7677937..068bad1 100644
> --- a/net/ipv6/netfilter/Makefile
> +++ b/net/ipv6/netfilter/Makefile
> @@ -34,4 +34,5 @@ obj-$(CONFIG_IP6_NF_MATCH_RPFILTER) += ip6t_rpfilter.o
> obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
>
> # targets
> +obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o
> obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
> diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c
> new file mode 100644
> index 0000000..60e9053
> --- /dev/null
> +++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c
> @@ -0,0 +1,135 @@
> +/*
> + * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Based on Rusty Russell's IPv6 MASQUERADE target. Development of IPv6
> + * NAT funded by Astaro.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/netdevice.h>
> +#include <linux/ipv6.h>
> +#include <linux/netfilter.h>
> +#include <linux/netfilter_ipv6.h>
> +#include <linux/netfilter/x_tables.h>
> +#include <net/netfilter/nf_nat.h>
> +#include <net/addrconf.h>
> +#include <net/ipv6.h>
> +
> +static unsigned int
> +masquerade_tg6(struct sk_buff *skb, const struct xt_action_param *par)
> +{
> + const struct nf_nat_range *range = par->targinfo;
> + enum ip_conntrack_info ctinfo;
> + struct in6_addr src;
> + struct nf_conn *ct;
> + struct nf_nat_range newrange;
> +
> + ct = nf_ct_get(skb, &ctinfo);
> + NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
> + ctinfo == IP_CT_RELATED_REPLY));
> +
> + if (ipv6_dev_get_saddr(dev_net(par->out), par->out,
> + &ipv6_hdr(skb)->daddr, 0, &src) < 0)
> + return NF_DROP;
> +
> + nfct_nat(ct)->masq_index = par->out->ifindex;
> +
> + newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
> + newrange.min_addr.in6 = src;
> + newrange.max_addr.in6 = src;
> + newrange.min_proto = range->min_proto;
> + newrange.max_proto = range->max_proto;
> +
> + return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
> +}
> +
> +static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par)
> +{
> + const struct nf_nat_range *range = par->targinfo;
> +
> + if (range->flags & NF_NAT_RANGE_MAP_IPS)
> + return -EINVAL;
> + return 0;
> +}
> +
> +static int device_cmp(struct nf_conn *ct, void *ifindex)
> +{
> + const struct nf_conn_nat *nat = nfct_nat(ct);
> +
> + if (!nat)
> + return 0;
> + if (nf_ct_l3num(ct) != NFPROTO_IPV6)
> + return 0;
> + return nat->masq_index == (int)(long)ifindex;
> +}
> +
> +static int masq_device_event(struct notifier_block *this,
> + unsigned long event, void *ptr)
> +{
> + const struct net_device *dev = ptr;
> + struct net *net = dev_net(dev);
> +
> + if (event == NETDEV_DOWN)
> + nf_ct_iterate_cleanup(net, device_cmp,
> + (void *)(long)dev->ifindex);
> +
> + return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block masq_dev_notifier = {
> + .notifier_call = masq_device_event,
> +};
> +
> +static int masq_inet_event(struct notifier_block *this,
> + unsigned long event, void *ptr)
> +{
> + struct inet6_ifaddr *ifa = ptr;
> +
> + return masq_device_event(this, event, ifa->idev->dev);
> +}
> +
> +static struct notifier_block masq_inet_notifier = {
> + .notifier_call = masq_inet_event,
> +};
> +
> +static struct xt_target masquerade_tg6_reg __read_mostly = {
> + .name = "MASQUERADE",
> + .family = NFPROTO_IPV6,
> + .checkentry = masquerade_tg6_checkentry,
> + .target = masquerade_tg6,
> + .targetsize = sizeof(struct nf_nat_range),
> + .table = "nat",
> + .hooks = 1 << NF_INET_POST_ROUTING,
> + .me = THIS_MODULE,
> +};
> +
> +static int __init masquerade_tg6_init(void)
> +{
> + int err;
> +
> + err = xt_register_target(&masquerade_tg6_reg);
> + if (err == 0) {
> + register_netdevice_notifier(&masq_dev_notifier);
> + register_inet6addr_notifier(&masq_inet_notifier);
> + }
> +
> + return err;
> +}
> +static void __exit masquerade_tg6_exit(void)
> +{
> + unregister_inet6addr_notifier(&masq_inet_notifier);
> + unregister_netdevice_notifier(&masq_dev_notifier);
> + xt_unregister_target(&masquerade_tg6_reg);
> +}
> +
> +module_init(masquerade_tg6_init);
> +module_exit(masquerade_tg6_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
> +MODULE_DESCRIPTION("Xtables: automatic address SNAT");
> --
> 1.7.1
>
> --
> 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
^ permalink raw reply related
* Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
From: Pablo Neira Ayuso @ 2012-08-17 13:36 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel, netdev
In-Reply-To: <1344542943-11588-6-git-send-email-kaber@trash.net>
On Thu, Aug 09, 2012 at 10:08:49PM +0200, kaber@trash.net wrote:
> From: Patrick McHardy <kaber@trash.net>
>
> The IPv6 conntrack fragmentation currently has a couple of shortcomings.
> Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the
> defragmented packet is then passed to conntrack, the resulting conntrack
> information is attached to each original fragment and the fragments then
> continue their way through the stack.
>
> Helper invocation occurs in the POSTROUTING hook, at which point only
> the original fragments are available. The result of this is that
> fragmented packets are never passed to helpers.
>
> This patch improves the situation in the following way:
>
> - If a reassembled packet belongs to a connection that has a helper
> assigned, the reassembled packet is passed through the stack instead
> of the original fragments.
>
> - During defragmentation, the largest received fragment size is stored.
> On output, the packet is refragmented if required. If the largest
> received fragment size exceeds the outgoing MTU, a "packet too big"
> message is generated, thus behaving as if the original fragments
> were passed through the stack from an outside point of view.
>
> - The ipv6_helper() hook function can't receive fragments anymore for
> connections using a helper, so it is switched to use ipv6_skip_exthdr()
> instead of the netfilter specific nf_ct_ipv6_skip_exthdr() and the
> reassembled packets are passed to connection tracking helpers.
>
> The result of this is that we can properly track fragmented packets, but
> still generate ICMPv6 Packet too big messages if we would have before.
>
> This patch is also required as a precondition for IPv6 NAT, where NAT
> helpers might enlarge packets up to a point that they require
> fragmentation. In that case we can't generate Packet too big messages
> since the proper MTU can't be calculated in all cases (f.i. when
> changing textual representation of a variable amount of addresses),
> so the packet is transparently fragmented iff the original packet or
> fragments would have fit the outgoing MTU.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
> ---
> include/linux/ipv6.h | 1 +
> net/ipv6/ip6_output.c | 7 +++-
> net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 37 ++++++++++++++++++------
> net/ipv6/netfilter/nf_conntrack_reasm.c | 19 ++++++++++--
> 4 files changed, 50 insertions(+), 14 deletions(-)
>
> diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
> index 879db26..0b94e91 100644
> --- a/include/linux/ipv6.h
> +++ b/include/linux/ipv6.h
> @@ -256,6 +256,7 @@ struct inet6_skb_parm {
> #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
> __u16 dsthao;
> #endif
> + __u16 frag_max_size;
>
> #define IP6SKB_XFRM_TRANSFORMED 1
> #define IP6SKB_FORWARDED 2
> diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
> index 5b2d63e..a4f6263 100644
> --- a/net/ipv6/ip6_output.c
> +++ b/net/ipv6/ip6_output.c
> @@ -493,7 +493,8 @@ int ip6_forward(struct sk_buff *skb)
> if (mtu < IPV6_MIN_MTU)
> mtu = IPV6_MIN_MTU;
>
> - if (skb->len > mtu && !skb_is_gso(skb)) {
> + if ((!skb->local_df && skb->len > mtu && !skb_is_gso(skb)) ||
> + (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) {
> /* Again, force OUTPUT device used as source address */
> skb->dev = dst->dev;
> icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
> @@ -636,7 +637,9 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
> /* We must not fragment if the socket is set to force MTU discovery
> * or if the skb it not generated by a local socket.
> */
> - if (unlikely(!skb->local_df && skb->len > mtu)) {
> + if (unlikely(!skb->local_df && skb->len > mtu) ||
> + (IP6CB(skb)->frag_max_size &&
> + IP6CB(skb)->frag_max_size > mtu)) {
> if (skb->sk && dst_allfrag(skb_dst(skb)))
> sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
>
> diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> index 4794f96..560d823 100644
> --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> @@ -153,10 +153,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,
> const struct nf_conn_help *help;
> const struct nf_conntrack_helper *helper;
> enum ip_conntrack_info ctinfo;
> - unsigned int ret, protoff;
> - unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
> - unsigned char pnum = ipv6_hdr(skb)->nexthdr;
> -
> + unsigned int ret;
> + __be16 frag_off;
> + int protoff;
> + u8 nexthdr;
>
> /* This is where we call the helper: as the packet goes out. */
> ct = nf_ct_get(skb, &ctinfo);
> @@ -171,9 +171,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,
> if (!helper)
> return NF_ACCEPT;
>
> - protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum,
> - skb->len - extoff);
> - if (protoff > skb->len || pnum == NEXTHDR_FRAGMENT) {
> + nexthdr = ipv6_hdr(skb)->nexthdr;
> + protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
> + &frag_off);
> + if (protoff < 0 || (frag_off & ntohs(~0x7)) != 0) {
> pr_debug("proto header not found\n");
> return NF_ACCEPT;
> }
> @@ -199,9 +200,13 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
> static unsigned int __ipv6_conntrack_in(struct net *net,
> unsigned int hooknum,
> struct sk_buff *skb,
> + const struct net_device *in,
> + const struct net_device *out,
> int (*okfn)(struct sk_buff *))
> {
> struct sk_buff *reasm = skb->nfct_reasm;
> + struct nf_conn *ct;
> + enum ip_conntrack_info ctinfo;
>
> /* This packet is fragmented and has reassembled packet. */
> if (reasm) {
> @@ -213,6 +218,20 @@ static unsigned int __ipv6_conntrack_in(struct net *net,
> if (ret != NF_ACCEPT)
> return ret;
> }
> +
> + /* Conntrack helpers need the entire reassembled packet in the
> + * POST_ROUTING hook.
> + */
> + ct = nf_ct_get(reasm, &ctinfo);
> + if (ct != NULL && test_bit(IPS_HELPER_BIT, &ct->status)) {
Two things regarding the line above:
- I think this also need to check for !nf_ct_is_untracked(ct)
- IPS_HELPER_BIT is only set if the CT target is used to attach
helpers. I know, this behaviour may seem confusing, but I didn't
find any better way to avoid that NAT removes the helper
explicitly attached via CT.
So basically now that status bit means: "this helper has been attached
via CT".
Setting it inconditionally in __nf_ct_try_assign_helper would break
the magic auto-assign helper code.
On the other hand, the automatic helper assignment is scheduled to
be removed (well, it would still take at least one 1.5/2 years
before we do so). At that time, we'll be able to say that all
conntrack with IPS_HELPER really has one helper. But now I think that
you'll have to use for nfct_help instead to check if that ct has a
helper.
> + nf_conntrack_get_reasm(skb);
> + NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
> + (struct net_device *)in,
> + (struct net_device *)out,
> + okfn, NF_IP6_PRI_CONNTRACK + 1);
> + return NF_DROP_ERR(-ECANCELED);
> + }
> +
> nf_conntrack_get(reasm->nfct);
> skb->nfct = reasm->nfct;
> skb->nfctinfo = reasm->nfctinfo;
> @@ -228,7 +247,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
> const struct net_device *out,
> int (*okfn)(struct sk_buff *))
> {
> - return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
> + return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn);
> }
>
> static unsigned int ipv6_conntrack_local(unsigned int hooknum,
> @@ -242,7 +261,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
> net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
> return NF_ACCEPT;
> }
> - return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
> + return __ipv6_conntrack_in(dev_net(out), hooknum, skb, in, out, okfn);
> }
>
> static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
> diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
> index c9c78c2..f94fb3a 100644
> --- a/net/ipv6/netfilter/nf_conntrack_reasm.c
> +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
> @@ -190,6 +190,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
> const struct frag_hdr *fhdr, int nhoff)
> {
> struct sk_buff *prev, *next;
> + unsigned int payload_len;
> int offset, end;
>
> if (fq->q.last_in & INET_FRAG_COMPLETE) {
> @@ -197,8 +198,10 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
> goto err;
> }
>
> + payload_len = ntohs(ipv6_hdr(skb)->payload_len);
> +
> offset = ntohs(fhdr->frag_off) & ~0x7;
> - end = offset + (ntohs(ipv6_hdr(skb)->payload_len) -
> + end = offset + (payload_len -
> ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
>
> if ((unsigned int)end > IPV6_MAXPLEN) {
> @@ -307,6 +310,8 @@ found:
> skb->dev = NULL;
> fq->q.stamp = skb->tstamp;
> fq->q.meat += skb->len;
> + if (payload_len > fq->q.max_size)
> + fq->q.max_size = payload_len;
> atomic_add(skb->truesize, &nf_init_frags.mem);
>
> /* The first fragment.
> @@ -412,10 +417,12 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
> }
> atomic_sub(head->truesize, &nf_init_frags.mem);
>
> + head->local_df = 1;
> head->next = NULL;
> head->dev = dev;
> head->tstamp = fq->q.stamp;
> ipv6_hdr(head)->payload_len = htons(payload_len);
> + IP6CB(head)->frag_max_size = sizeof(struct ipv6hdr) + fq->q.max_size;
>
> /* Yes, and fold redundant checksum back. 8) */
> if (head->ip_summed == CHECKSUM_COMPLETE)
> @@ -592,6 +599,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
> int (*okfn)(struct sk_buff *))
> {
> struct sk_buff *s, *s2;
> + unsigned int ret = 0;
>
> for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
> nf_conntrack_put_reasm(s->nfct_reasm);
> @@ -601,8 +609,13 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
> s2 = s->next;
> s->next = NULL;
>
> - NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s, in, out, okfn,
> - NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
> + if (ret != -ECANCELED)
> + ret = NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s,
> + in, out, okfn,
> + NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
> + else
> + kfree_skb(s);
> +
> s = s2;
> }
> nf_conntrack_put_reasm(skb);
> --
> 1.7.1
>
> --
> 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
^ permalink raw reply
* [PATCH] NET: xfrm, use correct rcu dereference helper
From: Jiri Slaby @ 2012-08-17 13:38 UTC (permalink / raw)
To: davem; +Cc: netdev, jirislaby, linux-kernel, Jiri Slaby, Priyanka Jain
Use rcu_dereference_bh while holding bh rcu lock. Otherwise we get:
===============================
[ INFO: suspicious RCU usage. ]
3.6.0-rc1-next-20120816+ #10 Not tainted
-------------------------------
net/xfrm/xfrm_policy.c:2504 suspicious rcu_dereference_check() usage!
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Priyanka Jain <Priyanka.Jain@freescale.com>
---
net/xfrm/xfrm_policy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 5ad4d2c..6405764 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2501,11 +2501,11 @@ static void __net_init xfrm_dst_ops_init(struct net *net)
struct xfrm_policy_afinfo *afinfo;
rcu_read_lock_bh();
- afinfo = rcu_dereference(xfrm_policy_afinfo[AF_INET]);
+ afinfo = rcu_dereference_bh(xfrm_policy_afinfo[AF_INET]);
if (afinfo)
net->xfrm.xfrm4_dst_ops = *afinfo->dst_ops;
#if IS_ENABLED(CONFIG_IPV6)
- afinfo = rcu_dereference(xfrm_policy_afinfo[AF_INET6]);
+ afinfo = rcu_dereference_bh(xfrm_policy_afinfo[AF_INET6]);
if (afinfo)
net->xfrm.xfrm6_dst_ops = *afinfo->dst_ops;
#endif
--
1.7.11.5
^ permalink raw reply related
* Re: [PATCH 00/19] netfilter: IPv6 NAT
From: Pablo Neira Ayuso @ 2012-08-17 13:42 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel, netdev
In-Reply-To: <1344542943-11588-1-git-send-email-kaber@trash.net>
On Thu, Aug 09, 2012 at 10:08:44PM +0200, kaber@trash.net wrote:
[...]
> - Patches 16-19 add some IPv6-capable ports of existing NAT helpers
There was one for IRC also, did it get lost?
I also made TFTP, it was more or less trivial, you can find it here:
http://1984.lsi.us.es/git/nf-next/commit/?h=nf-nat4&id=ac2a06ab790386c8c8333dbf84584fc3f80fcdc5
^ permalink raw reply
* [patch net-next] team: add support for non-ethernet devices
From: Jiri Pirko @ 2012-08-17 14:00 UTC (permalink / raw)
To: netdev; +Cc: davem
This is resolved by two things:
1) allow dev_addr of different length than ETH_ALEN
2) during port add, check for dev->type and change it if necessary
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/team/Kconfig | 4 +-
drivers/net/team/team.c | 89 +++++++++++++++++++++++--------
drivers/net/team/team_mode_broadcast.c | 8 +--
drivers/net/team/team_mode_roundrobin.c | 8 +--
include/linux/if_team.h | 4 +-
5 files changed, 79 insertions(+), 34 deletions(-)
diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig
index 6a7260b..6b08bd4 100644
--- a/drivers/net/team/Kconfig
+++ b/drivers/net/team/Kconfig
@@ -21,7 +21,7 @@ config NET_TEAM_MODE_BROADCAST
---help---
Basic mode where packets are transmitted always by all suitable ports.
- All added ports are setup to have team's mac address.
+ All added ports are setup to have team's device address.
To compile this team mode as a module, choose M here: the module
will be called team_mode_broadcast.
@@ -33,7 +33,7 @@ config NET_TEAM_MODE_ROUNDROBIN
Basic mode where port used for transmitting packets is selected in
round-robin fashion using packet counter.
- All added ports are setup to have team's mac address.
+ All added ports are setup to have team's device address.
To compile this team mode as a module, choose M here: the module
will be called team_mode_roundrobin.
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index dabddc5..659e510 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -54,29 +54,29 @@ static struct team_port *team_port_get_rtnl(const struct net_device *dev)
}
/*
- * Since the ability to change mac address for open port device is tested in
+ * Since the ability to change device address for open port device is tested in
* team_port_add, this function can be called without control of return value
*/
-static int __set_port_mac(struct net_device *port_dev,
- const unsigned char *dev_addr)
+static int __set_port_dev_addr(struct net_device *port_dev,
+ const unsigned char *dev_addr)
{
struct sockaddr addr;
- memcpy(addr.sa_data, dev_addr, ETH_ALEN);
- addr.sa_family = ARPHRD_ETHER;
+ memcpy(addr.sa_data, dev_addr, port_dev->addr_len);
+ addr.sa_family = port_dev->type;
return dev_set_mac_address(port_dev, &addr);
}
-static int team_port_set_orig_mac(struct team_port *port)
+static int team_port_set_orig_dev_addr(struct team_port *port)
{
- return __set_port_mac(port->dev, port->orig.dev_addr);
+ return __set_port_dev_addr(port->dev, port->orig.dev_addr);
}
-int team_port_set_team_mac(struct team_port *port)
+int team_port_set_team_dev_addr(struct team_port *port)
{
- return __set_port_mac(port->dev, port->team->dev->dev_addr);
+ return __set_port_dev_addr(port->dev, port->team->dev->dev_addr);
}
-EXPORT_SYMBOL(team_port_set_team_mac);
+EXPORT_SYMBOL(team_port_set_team_dev_addr);
static void team_refresh_port_linkup(struct team_port *port)
{
@@ -965,6 +965,8 @@ static struct netpoll_info *team_netpoll_info(struct team *team)
#endif
static void __team_port_change_check(struct team_port *port, bool linkup);
+static int team_dev_type_check_change(struct net_device *dev,
+ struct net_device *port_dev);
static int team_port_add(struct team *team, struct net_device *port_dev)
{
@@ -973,9 +975,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
char *portname = port_dev->name;
int err;
- if (port_dev->flags & IFF_LOOPBACK ||
- port_dev->type != ARPHRD_ETHER) {
- netdev_err(dev, "Device %s is of an unsupported type\n",
+ if (port_dev->flags & IFF_LOOPBACK) {
+ netdev_err(dev, "Device %s is loopback device. Loopback devices can't be added as a team port\n",
portname);
return -EINVAL;
}
@@ -986,6 +987,10 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
return -EBUSY;
}
+ err = team_dev_type_check_change(dev, port_dev);
+ if (err)
+ return err;
+
if (port_dev->flags & IFF_UP) {
netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n",
portname);
@@ -1008,7 +1013,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
goto err_set_mtu;
}
- memcpy(port->orig.dev_addr, port_dev->dev_addr, ETH_ALEN);
+ memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len);
err = team_port_enter(team, port);
if (err) {
@@ -1090,7 +1095,7 @@ err_vids_add:
err_dev_open:
team_port_leave(team, port);
- team_port_set_orig_mac(port);
+ team_port_set_orig_dev_addr(port);
err_port_enter:
dev_set_mtu(port_dev, port->orig.mtu);
@@ -1127,7 +1132,7 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
vlan_vids_del_by_dev(port_dev, dev);
dev_close(port_dev);
team_port_leave(team, port);
- team_port_set_orig_mac(port);
+ team_port_set_orig_dev_addr(port);
dev_set_mtu(port_dev, port->orig.mtu);
synchronize_rcu();
kfree(port);
@@ -1478,17 +1483,18 @@ static void team_set_rx_mode(struct net_device *dev)
static int team_set_mac_address(struct net_device *dev, void *p)
{
+ struct sockaddr *addr = p;
struct team *team = netdev_priv(dev);
struct team_port *port;
- int err;
- err = eth_mac_addr(dev, p);
- if (err)
- return err;
+ if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ dev->addr_assign_type &= ~NET_ADDR_RANDOM;
rcu_read_lock();
list_for_each_entry_rcu(port, &team->port_list, list)
- if (team->ops.port_change_mac)
- team->ops.port_change_mac(team, port);
+ if (team->ops.port_change_dev_addr)
+ team->ops.port_change_dev_addr(team, port);
rcu_read_unlock();
return 0;
}
@@ -1719,6 +1725,45 @@ static const struct net_device_ops team_netdev_ops = {
* rt netlink interface
***********************/
+static void team_setup_by_port(struct net_device *dev,
+ struct net_device *port_dev)
+{
+ dev->header_ops = port_dev->header_ops;
+ dev->type = port_dev->type;
+ dev->hard_header_len = port_dev->hard_header_len;
+ dev->addr_len = port_dev->addr_len;
+ dev->mtu = port_dev->mtu;
+ memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len);
+ memcpy(dev->dev_addr, port_dev->dev_addr, port_dev->addr_len);
+ dev->addr_assign_type &= ~NET_ADDR_RANDOM;
+}
+
+static int team_dev_type_check_change(struct net_device *dev,
+ struct net_device *port_dev)
+{
+ struct team *team = netdev_priv(dev);
+ char *portname = port_dev->name;
+ int err;
+
+ if (dev->type == port_dev->type)
+ return 0;
+ if (!list_empty(&team->port_list)) {
+ netdev_err(dev, "Device %s is of different type\n", portname);
+ return -EBUSY;
+ }
+ err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
+ err = notifier_to_errno(err);
+ if (err) {
+ netdev_err(dev, "Refused to change device type\n");
+ return err;
+ }
+ dev_uc_flush(dev);
+ dev_mc_flush(dev);
+ team_setup_by_port(dev, port_dev);
+ call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
+ return 0;
+}
+
static void team_setup(struct net_device *dev)
{
ether_setup(dev);
diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c
index c96e4d2..9db0171 100644
--- a/drivers/net/team/team_mode_broadcast.c
+++ b/drivers/net/team/team_mode_broadcast.c
@@ -48,18 +48,18 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
static int bc_port_enter(struct team *team, struct team_port *port)
{
- return team_port_set_team_mac(port);
+ return team_port_set_team_dev_addr(port);
}
-static void bc_port_change_mac(struct team *team, struct team_port *port)
+static void bc_port_change_dev_addr(struct team *team, struct team_port *port)
{
- team_port_set_team_mac(port);
+ team_port_set_team_dev_addr(port);
}
static const struct team_mode_ops bc_mode_ops = {
.transmit = bc_transmit,
.port_enter = bc_port_enter,
- .port_change_mac = bc_port_change_mac,
+ .port_change_dev_addr = bc_port_change_dev_addr,
};
static const struct team_mode bc_mode = {
diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c
index ad7ed0e..105135a 100644
--- a/drivers/net/team/team_mode_roundrobin.c
+++ b/drivers/net/team/team_mode_roundrobin.c
@@ -66,18 +66,18 @@ drop:
static int rr_port_enter(struct team *team, struct team_port *port)
{
- return team_port_set_team_mac(port);
+ return team_port_set_team_dev_addr(port);
}
-static void rr_port_change_mac(struct team *team, struct team_port *port)
+static void rr_port_change_dev_addr(struct team *team, struct team_port *port)
{
- team_port_set_team_mac(port);
+ team_port_set_team_dev_addr(port);
}
static const struct team_mode_ops rr_mode_ops = {
.transmit = rr_transmit,
.port_enter = rr_port_enter,
- .port_change_mac = rr_port_change_mac,
+ .port_change_dev_addr = rr_port_change_dev_addr,
};
static const struct team_mode rr_mode = {
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 33fcc20..8b000b2 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -123,7 +123,7 @@ struct team_mode_ops {
bool (*transmit)(struct team *team, struct sk_buff *skb);
int (*port_enter)(struct team *team, struct team_port *port);
void (*port_leave)(struct team *team, struct team_port *port);
- void (*port_change_mac)(struct team *team, struct team_port *port);
+ void (*port_change_dev_addr)(struct team *team, struct team_port *port);
void (*port_enabled)(struct team *team, struct team_port *port);
void (*port_disabled)(struct team *team, struct team_port *port);
};
@@ -238,7 +238,7 @@ static inline struct team_port *team_get_port_by_index_rcu(struct team *team,
return NULL;
}
-extern int team_port_set_team_mac(struct team_port *port);
+extern int team_port_set_team_dev_addr(struct team_port *port);
extern int team_options_register(struct team *team,
const struct team_option *option,
size_t option_count);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/5] netfilter: nf_ct_sip: fix helper name
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Patrick McHardy <kaber@trash.net>
Commit 3a8fc53a (netfilter: nf_ct_helper: allocate 16 bytes for the helper
and policy names) introduced a bug in the SIP helper, the helper name is
sprinted to the sip_names array instead of instead of into the helper
structure. This breaks the helper match and the /proc/net/nf_conntrack_expect
output.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_sip.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 758a1ba..2fb6669 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1515,7 +1515,6 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
}
static struct nf_conntrack_helper sip[MAX_PORTS][4] __read_mostly;
-static char sip_names[MAX_PORTS][4][sizeof("sip-65535")] __read_mostly;
static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = {
[SIP_EXPECT_SIGNALLING] = {
@@ -1585,9 +1584,9 @@ static int __init nf_conntrack_sip_init(void)
sip[i][j].me = THIS_MODULE;
if (ports[i] == SIP_PORT)
- sprintf(sip_names[i][j], "sip");
+ sprintf(sip[i][j].name, "sip");
else
- sprintf(sip_names[i][j], "sip-%u", i);
+ sprintf(sip[i][j].name, "sip-%u", i);
pr_debug("port #%u: %u\n", i, ports[i]);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/5] netfilter: nf_ct_sip: fix IPv6 address parsing
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Patrick McHardy <kaber@trash.net>
Within SIP messages IPv6 addresses are enclosed in square brackets in most
cases, with the exception of the "received=" header parameter. Currently
the helper fails to parse enclosed addresses.
This patch:
- changes the SIP address parsing function to enforce square brackets
when required, and accept them when not required but present, as
recommended by RFC 5118.
- adds a new SDP address parsing function that never accepts square
brackets since SDP doesn't use them.
With these changes, the SIP helper correctly parses all test messages
from RFC 5118 (Session Initiation Protocol (SIP) Torture Test Messages
for Internet Protocol Version 6 (IPv6)).
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter/nf_conntrack_sip.h | 2 +-
net/ipv4/netfilter/nf_nat_sip.c | 4 +-
net/netfilter/nf_conntrack_sip.c | 87 ++++++++++++++++++++++------
3 files changed, 73 insertions(+), 20 deletions(-)
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h
index 0dfc8b7..89f2a62 100644
--- a/include/linux/netfilter/nf_conntrack_sip.h
+++ b/include/linux/netfilter/nf_conntrack_sip.h
@@ -164,7 +164,7 @@ extern int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr
unsigned int dataoff, unsigned int datalen,
const char *name,
unsigned int *matchoff, unsigned int *matchlen,
- union nf_inet_addr *addr);
+ union nf_inet_addr *addr, bool delim);
extern int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
unsigned int off, unsigned int datalen,
const char *name,
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index ea4a238..eef8f29 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -173,7 +173,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
* the reply. */
if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
"maddr=", &poff, &plen,
- &addr) > 0 &&
+ &addr, true) > 0 &&
addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) {
buflen = sprintf(buffer, "%pI4",
@@ -187,7 +187,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
* from which the server received the request. */
if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
"received=", &poff, &plen,
- &addr) > 0 &&
+ &addr, false) > 0 &&
addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) {
buflen = sprintf(buffer, "%pI4",
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 2fb6669..5c0a112 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -183,12 +183,12 @@ static int media_len(const struct nf_conn *ct, const char *dptr,
return len + digits_len(ct, dptr, limit, shift);
}
-static int parse_addr(const struct nf_conn *ct, const char *cp,
- const char **endp, union nf_inet_addr *addr,
- const char *limit)
+static int sip_parse_addr(const struct nf_conn *ct, const char *cp,
+ const char **endp, union nf_inet_addr *addr,
+ const char *limit, bool delim)
{
const char *end;
- int ret = 0;
+ int ret;
if (!ct)
return 0;
@@ -197,16 +197,28 @@ static int parse_addr(const struct nf_conn *ct, const char *cp,
switch (nf_ct_l3num(ct)) {
case AF_INET:
ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
+ if (ret == 0)
+ return 0;
break;
case AF_INET6:
+ if (cp < limit && *cp == '[')
+ cp++;
+ else if (delim)
+ return 0;
+
ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end);
+ if (ret == 0)
+ return 0;
+
+ if (end < limit && *end == ']')
+ end++;
+ else if (delim)
+ return 0;
break;
default:
BUG();
}
- if (ret == 0 || end == cp)
- return 0;
if (endp)
*endp = end;
return 1;
@@ -219,7 +231,7 @@ static int epaddr_len(const struct nf_conn *ct, const char *dptr,
union nf_inet_addr addr;
const char *aux = dptr;
- if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
+ if (!sip_parse_addr(ct, dptr, &dptr, &addr, limit, true)) {
pr_debug("ip: %s parse failed.!\n", dptr);
return 0;
}
@@ -296,7 +308,7 @@ int ct_sip_parse_request(const struct nf_conn *ct,
return 0;
dptr += shift;
- if (!parse_addr(ct, dptr, &end, addr, limit))
+ if (!sip_parse_addr(ct, dptr, &end, addr, limit, true))
return -1;
if (end < limit && *end == ':') {
end++;
@@ -550,7 +562,7 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr,
if (ret == 0)
return ret;
- if (!parse_addr(ct, dptr + *matchoff, &c, addr, limit))
+ if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true))
return -1;
if (*c == ':') {
c++;
@@ -599,7 +611,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
unsigned int dataoff, unsigned int datalen,
const char *name,
unsigned int *matchoff, unsigned int *matchlen,
- union nf_inet_addr *addr)
+ union nf_inet_addr *addr, bool delim)
{
const char *limit = dptr + datalen;
const char *start, *end;
@@ -613,7 +625,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
return 0;
start += strlen(name);
- if (!parse_addr(ct, start, &end, addr, limit))
+ if (!sip_parse_addr(ct, start, &end, addr, limit, delim))
return 0;
*matchoff = start - dptr;
*matchlen = end - start;
@@ -675,6 +687,47 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr,
return 1;
}
+static int sdp_parse_addr(const struct nf_conn *ct, const char *cp,
+ const char **endp, union nf_inet_addr *addr,
+ const char *limit)
+{
+ const char *end;
+ int ret;
+
+ memset(addr, 0, sizeof(*addr));
+ switch (nf_ct_l3num(ct)) {
+ case AF_INET:
+ ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
+ break;
+ case AF_INET6:
+ ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end);
+ break;
+ default:
+ BUG();
+ }
+
+ if (ret == 0)
+ return 0;
+ if (endp)
+ *endp = end;
+ return 1;
+}
+
+/* skip ip address. returns its length. */
+static int sdp_addr_len(const struct nf_conn *ct, const char *dptr,
+ const char *limit, int *shift)
+{
+ union nf_inet_addr addr;
+ const char *aux = dptr;
+
+ if (!sdp_parse_addr(ct, dptr, &dptr, &addr, limit)) {
+ pr_debug("ip: %s parse failed.!\n", dptr);
+ return 0;
+ }
+
+ return dptr - aux;
+}
+
/* SDP header parsing: a SDP session description contains an ordered set of
* headers, starting with a section containing general session parameters,
* optionally followed by multiple media descriptions.
@@ -686,10 +739,10 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr,
*/
static const struct sip_header ct_sdp_hdrs[] = {
[SDP_HDR_VERSION] = SDP_HDR("v=", NULL, digits_len),
- [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", epaddr_len),
- [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", epaddr_len),
- [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", epaddr_len),
- [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", epaddr_len),
+ [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", sdp_addr_len),
+ [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", sdp_addr_len),
+ [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", sdp_addr_len),
+ [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", sdp_addr_len),
[SDP_HDR_MEDIA] = SDP_HDR("m=", NULL, media_len),
};
@@ -775,8 +828,8 @@ static int ct_sip_parse_sdp_addr(const struct nf_conn *ct, const char *dptr,
if (ret <= 0)
return ret;
- if (!parse_addr(ct, dptr + *matchoff, NULL, addr,
- dptr + *matchoff + *matchlen))
+ if (!sdp_parse_addr(ct, dptr + *matchoff, NULL, addr,
+ dptr + *matchoff + *matchlen))
return -1;
return 1;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/5] netfilter: nf_nat_sip: fix via header translation with multiple parameters
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Patrick McHardy <kaber@trash.net>
Via-headers are parsed beginning at the first character after the Via-address.
When the address is translated first and its length decreases, the offset to
start parsing at is incorrect and header parameters might be missed.
Update the offset after translating the Via-address to fix this.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/nf_nat_sip.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index eef8f29..4ad9cf1 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -148,7 +148,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
hdr, NULL, &matchoff, &matchlen,
&addr, &port) > 0) {
- unsigned int matchend, poff, plen, buflen, n;
+ unsigned int olen, matchend, poff, plen, buflen, n;
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
/* We're only interested in headers related to this
@@ -163,11 +163,12 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
goto next;
}
+ olen = *datalen;
if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
&addr, port))
return NF_DROP;
- matchend = matchoff + matchlen;
+ matchend = matchoff + matchlen + *datalen - olen;
/* The maddr= parameter (RFC 2361) specifies where to send
* the reply. */
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/5] netfilter: ctnetlink: fix missing locking while changing conntrack from nfqueue
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Since 9cb017665 netfilter: add glue code to integrate nfnetlink_queue and
ctnetlink, we can modify the conntrack entry via nfnl_queue. However, the
change of the conntrack entry via nfnetlink_queue requires appropriate
locking to avoid concurrent updates.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_netlink.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 14f67a2..da4fc37 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1896,10 +1896,15 @@ static int
ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct)
{
struct nlattr *cda[CTA_MAX+1];
+ int ret;
nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy);
- return ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
+ spin_lock_bh(&nf_conntrack_lock);
+ ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
+ spin_unlock_bh(&nf_conntrack_lock);
+
+ return ret;
}
static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
--
1.7.10.4
^ permalink raw reply related
* [PATCH 5/5] netfilter: nf_ct_expect: fix possible access to uninitialized timer
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
In __nf_ct_expect_check, the function refresh_timer returns 1
if a matching expectation is found and its timer is successfully
refreshed. This results in nf_ct_expect_related returning 0.
Note that at this point:
- the passed expectation is not inserted in the expectation table
and its timer was not initialized, since we have refreshed one
matching/existing expectation.
- nf_ct_expect_alloc uses kmem_cache_alloc, so the expectation
timer is in some undefined state just after the allocation,
until it is appropriately initialized.
This can be a problem for the SIP helper during the expectation
addition:
...
if (nf_ct_expect_related(rtp_exp) == 0) {
if (nf_ct_expect_related(rtcp_exp) != 0)
nf_ct_unexpect_related(rtp_exp);
...
Note that nf_ct_expect_related(rtp_exp) may return 0 for the timer refresh
case that is detailed above. Then, if nf_ct_unexpect_related(rtcp_exp)
returns != 0, nf_ct_unexpect_related(rtp_exp) is called, which does:
spin_lock_bh(&nf_conntrack_lock);
if (del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_ct_expect_put(exp);
}
spin_unlock_bh(&nf_conntrack_lock);
Note that del_timer always returns false if the timer has been
initialized. However, the timer was not initialized since setup_timer
was not called, therefore, the expectation timer remains in some
undefined state. If I'm not missing anything, this may lead to the
removal an unexistent expectation.
To fix this, the optimization that allows refreshing an expectation
is removed. Now nf_conntrack_expect_related looks more consistent
to me since it always add the expectation in case that it returns
success.
Thanks to Patrick McHardy for participating in the discussion of
this patch.
I think this may be the source of the problem described by:
http://marc.info/?l=netfilter-devel&m=134073514719421&w=2
Reported-by: Rafal Fitt <rafalf@aplusc.com.pl>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_expect.c | 29 ++++++-----------------------
1 file changed, 6 insertions(+), 23 deletions(-)
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 45cf602..527651a 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -361,23 +361,6 @@ static void evict_oldest_expect(struct nf_conn *master,
}
}
-static inline int refresh_timer(struct nf_conntrack_expect *i)
-{
- struct nf_conn_help *master_help = nfct_help(i->master);
- const struct nf_conntrack_expect_policy *p;
-
- if (!del_timer(&i->timeout))
- return 0;
-
- p = &rcu_dereference_protected(
- master_help->helper,
- lockdep_is_held(&nf_conntrack_lock)
- )->expect_policy[i->class];
- i->timeout.expires = jiffies + p->timeout * HZ;
- add_timer(&i->timeout);
- return 1;
-}
-
static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
{
const struct nf_conntrack_expect_policy *p;
@@ -386,7 +369,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
struct nf_conn_help *master_help = nfct_help(master);
struct nf_conntrack_helper *helper;
struct net *net = nf_ct_exp_net(expect);
- struct hlist_node *n;
+ struct hlist_node *n, *next;
unsigned int h;
int ret = 1;
@@ -395,12 +378,12 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
goto out;
}
h = nf_ct_expect_dst_hash(&expect->tuple);
- hlist_for_each_entry(i, n, &net->ct.expect_hash[h], hnode) {
+ hlist_for_each_entry_safe(i, n, next, &net->ct.expect_hash[h], hnode) {
if (expect_matches(i, expect)) {
- /* Refresh timer: if it's dying, ignore.. */
- if (refresh_timer(i)) {
- ret = 0;
- goto out;
+ if (del_timer(&i->timeout)) {
+ nf_ct_unlink_expect(i);
+ nf_ct_expect_put(i);
+ break;
}
} else if (expect_clash(i, expect)) {
ret = -EBUSY;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 0/5] netfilter fixes for 3.6-rc
From: pablo @ 2012-08-17 14:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Hi David,
The following five patches contain fixes for 3.6-rc, they are:
* Two fixes for message parsing in the SIP conntrack helper, from
Patrick McHardy.
* One fix for the SIP helper introduced in the user-space cthelper
infrastructure, from Patrick McHardy.
* fix missing appropriate locking while modifying one conntrack entry
from the nfqueue integration code, from myself.
* fix possible access to uninitiliazed timer in the nf_conntrack
expectation infrastructure, from myself.
You can pull these changes from:
git://1984.lsi.us.es/nf
Thanks!
Pablo Neira Ayuso (2):
netfilter: ctnetlink: fix missing locking while changing conntrack from nfqueue
netfilter: nf_ct_expect: fix possible access to uninitialized timer
Patrick McHardy (3):
netfilter: nf_ct_sip: fix helper name
netfilter: nf_ct_sip: fix IPv6 address parsing
netfilter: nf_nat_sip: fix via header translation with multiple parameters
include/linux/netfilter/nf_conntrack_sip.h | 2 +-
net/ipv4/netfilter/nf_nat_sip.c | 9 +--
net/netfilter/nf_conntrack_expect.c | 29 ++-------
net/netfilter/nf_conntrack_netlink.c | 7 ++-
net/netfilter/nf_conntrack_sip.c | 92 ++++++++++++++++++++++------
5 files changed, 90 insertions(+), 49 deletions(-)
--
1.7.10.4
^ permalink raw reply
* Linux -next build failure
From: Alan Cox @ 2012-08-17 15:03 UTC (permalink / raw)
To: netdev
Build with CONFIG_TIGON3=y and CONFIG_HWMON=m
drivers/built-in.o: In function `tg3_close':
tg3.c:(.text+0xe223a): undefined reference to `hwmon_device_unregister'
drivers/built-in.o: In function `tg3_hwmon_open':
tg3.c:(.text+0xe6109): undefined reference to `hwmon_device_register'
^ permalink raw reply
* [PATCH v1 0/5] cgroup: Assign subsystem IDs during compile time
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Hi,
I was able to 'fix' CGROUP_BUILTIN_SUBSYS_COUNT defition. With this
version there is no unused subsys_id.
The number of builtin subsystem are counted with gcc's predefined
__COUNTER__ macro. This is a bit fragile, because __COUNTER__
is only reset to 0 per compile unit. There is a workaround for this.
When starting to enumate we need to store the current value of
__COUNTER__ and then subtract that from all enums we define.
Not sure if that is okay or not.
cheers,
daniel
Original cover letter:
The patch #1 and #2 are there to be able to introduce (#3, #4) the
jump labels in task_cls_classid() and task_netprioidx(). The jump
labels are needed to know when it is safe to access the controller.
For example not safe means the module is not yet loaded.
All those patches are just preparation for the center piece (#5)
of these series. This one will remove the dynamic subsystem ID
generation and falls back to compile time generated IDs.
This is the first result from the discussion around on the
"cgroup cls & netprio 'cleanups'" patches.
This patches are against net-next
v1: - only use jump labels when built as module (#3, #4)
- get rid of the additional 'pointer' (#5)
v0: - initial version
Daniel Wagner (5):
cgroup: Use empty task_cls_classid() when !CONFIG_NET_CLS(_MODULE)
cgroup: Move sock_update_classid() decleration to cls_cgroup.h
cgroup: Protect access to task_cls_classid() when built as module
cgroup: Protect access to task_netprioidx() when built as module
cgroup: Assign subsystem IDs during compile time
include/linux/cgroup.h | 27 ++++++++++++++++++---------
include/linux/cgroup_subsys.h | 24 ++++++++++++------------
include/net/cls_cgroup.h | 39 ++++++++++++++++++++++++++-------------
include/net/netprio_cgroup.h | 25 +++++++++++--------------
include/net/sock.h | 8 --------
kernel/cgroup.c | 25 ++++++-------------------
net/core/netprio_cgroup.c | 21 ++++++++++-----------
net/core/sock.c | 12 ++++++------
net/sched/cls_cgroup.c | 22 +++++++++-------------
9 files changed, 98 insertions(+), 105 deletions(-)
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply
* [PATCH v1 1/5] cgroup: Use empty task_cls_classid() when !CONFIG_NET_CLS(_MODULE)
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Gao feng, Jamal Hadi Salim,
John Fastabend, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/cls_cgroup.h | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index a4dc5b0..e2fe2b9 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -24,7 +24,8 @@ struct cgroup_cls_state
u32 classid;
};
-#ifdef CONFIG_NET_CLS_CGROUP
+#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
+
static inline u32 task_cls_classid(struct task_struct *p)
{
int classid;
@@ -39,7 +40,9 @@ static inline u32 task_cls_classid(struct task_struct *p)
return classid;
}
-#else
+
+#elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
+
extern int net_cls_subsys_id;
static inline u32 task_cls_classid(struct task_struct *p)
@@ -60,11 +63,16 @@ static inline u32 task_cls_classid(struct task_struct *p)
return classid;
}
-#endif
+
#else
+
static inline u32 task_cls_classid(struct task_struct *p)
{
return 0;
}
-#endif
+
+#endif /* CONFIG_NET_CLS_CGROUP */
+
+#endif /* CONFIG_CGROURPS */
+
#endif /* _NET_CLS_CGROUP_H */
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v1 2/5] cgroup: Move sock_update_classid() decleration to cls_cgroup.h
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, Gao feng, Jamal Hadi Salim, John Fastabend,
Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
The only user of sock_update_classid() is net/socket.c which
happens to include cls_cgroup.h direclty.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/cls_cgroup.h | 8 ++++++++
include/net/sock.h | 8 --------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index e2fe2b9..401672c 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -24,6 +24,8 @@ struct cgroup_cls_state
u32 classid;
};
+extern void sock_update_classid(struct sock *sk);
+
#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
static inline u32 task_cls_classid(struct task_struct *p)
@@ -73,6 +75,12 @@ static inline u32 task_cls_classid(struct task_struct *p)
#endif /* CONFIG_NET_CLS_CGROUP */
+#else /* !CONFIG_CGROUPS */
+
+static inline void sock_update_classid(struct sock *sk)
+{
+}
+
#endif /* CONFIG_CGROURPS */
#endif /* _NET_CLS_CGROUP_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index 72132ae..160a680 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1486,14 +1486,6 @@ extern void *sock_kmalloc(struct sock *sk, int size,
extern void sock_kfree_s(struct sock *sk, void *mem, int size);
extern void sk_send_sigurg(struct sock *sk);
-#ifdef CONFIG_CGROUPS
-extern void sock_update_classid(struct sock *sk);
-#else
-static inline void sock_update_classid(struct sock *sk)
-{
-}
-#endif
-
/*
* Functions to fill in entries in struct proto_ops when a protocol
* does not implement a particular function.
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v1 3/5] cgroup: Protect access to task_cls_classid() when built as module
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Gao feng, Jamal Hadi Salim,
John Fastabend, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
The module version of task_cls_classid() checks if net_cls_sbusys_id
is valid to indentify when it is okay to access the controller.
Instead relying on the subusys_id to be set, make it explicit
with a jump label.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/cls_cgroup.h | 5 ++++-
net/core/sock.c | 5 +++++
net/sched/cls_cgroup.c | 9 +++++++++
3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index 401672c..bbbd957 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -16,6 +16,7 @@
#include <linux/cgroup.h>
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
+#include <linux/jump_label.h>
#ifdef CONFIG_CGROUPS
struct cgroup_cls_state
@@ -44,6 +45,8 @@ static inline u32 task_cls_classid(struct task_struct *p)
}
#elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
+extern struct static_key cgroup_cls_enabled;
+#define clscg_enabled static_key_false(&cgroup_cls_enabled)
extern int net_cls_subsys_id;
@@ -52,7 +55,7 @@ static inline u32 task_cls_classid(struct task_struct *p)
int id;
u32 classid = 0;
- if (in_interrupt())
+ if (!clscg_enabled || in_interrupt())
return 0;
rcu_read_lock();
diff --git a/net/core/sock.c b/net/core/sock.c
index 8f67ced..8106e77 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -327,6 +327,11 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
EXPORT_SYMBOL(__sk_backlog_rcv);
#if defined(CONFIG_CGROUPS)
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
+struct static_key cgroup_cls_enabled = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
+#endif
+
#if !defined(CONFIG_NET_CLS_CGROUP)
int net_cls_subsys_id = -1;
EXPORT_SYMBOL_GPL(net_cls_subsys_id);
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 7743ea8..0635894 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -44,12 +44,21 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
if (cgrp->parent)
cs->classid = cgrp_cls_state(cgrp->parent)->classid;
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
+ else if (!clscg_enabled)
+ static_key_slow_inc(&cgroup_cls_enabled);
+#endif
return &cs->css;
}
static void cgrp_destroy(struct cgroup *cgrp)
{
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
+ if (!cgrp->parent && clscg_enabled)
+ static_key_slow_dec(&cgroup_cls_enabled);
+#endif
+
kfree(cgrp_cls_state(cgrp));
}
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v1 4/5] cgroup: Protect access to task_netprioidx() when built as module
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Gao feng, Jamal Hadi Salim,
John Fastabend, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
The module version of task_netprioidex() checks if net_prio_subsys_id
is valid to indentify when it is okay to access the controller.
Instead relying on the net_prio_subsys_id to be set, make it explicit
with a jump label.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/netprio_cgroup.h | 8 +++++++-
net/core/netprio_cgroup.c | 10 ++++++++++
net/core/sock.c | 4 ++++
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index 2719dec..9ff58e4 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -16,7 +16,7 @@
#include <linux/cgroup.h>
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
-
+#include <linux/jump_label.h>
struct netprio_map {
struct rcu_head rcu;
@@ -54,12 +54,18 @@ static inline u32 task_netprioidx(struct task_struct *p)
#elif IS_MODULE(CONFIG_NETPRIO_CGROUP)
+extern struct static_key cgroup_netprio_enabled;
+#define netpriocg_enabled static_key_false(&cgroup_netprio_enabled)
+
static inline u32 task_netprioidx(struct task_struct *p)
{
struct cgroup_netprio_state *state;
int subsys_id;
u32 idx = 0;
+ if (!netpriocg_enabled)
+ return 0;
+
rcu_read_lock();
subsys_id = rcu_dereference_index_check(net_prio_subsys_id,
rcu_read_lock_held());
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index ed0c043..94e1270 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -155,6 +155,11 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
goto out;
}
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
+ if (!netpriocg_enabled && !cgrp->parent)
+ static_key_slow_inc(&cgroup_netprio_enabled);
+#endif
+
ret = update_netdev_tables();
if (ret < 0) {
put_prioidx(cs->prioidx);
@@ -173,6 +178,11 @@ static void cgrp_destroy(struct cgroup *cgrp)
struct net_device *dev;
struct netprio_map *map;
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
+ if (netpriocg_enabled && !cgrp->parent)
+ static_key_slow_dec(&cgroup_netprio_enabled);
+#endif
+
cs = cgrp_netprio_state(cgrp);
rtnl_lock();
for_each_netdev(&init_net, dev) {
diff --git a/net/core/sock.c b/net/core/sock.c
index 8106e77..1f119d2 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -331,6 +331,10 @@ EXPORT_SYMBOL(__sk_backlog_rcv);
struct static_key cgroup_cls_enabled = STATIC_KEY_INIT_FALSE;
EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
#endif
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
+struct static_key cgroup_netprio_enabled = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL_GPL(cgroup_netprio_enabled);
+#endif
#if !defined(CONFIG_NET_CLS_CGROUP)
int net_cls_subsys_id = -1;
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v1 5/5] cgroup: Assign subsystem IDs during compile time
From: Daniel Wagner @ 2012-08-17 14:58 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Andrew Morton, Eric Dumazet,
Gao feng, Glauber Costa, Jamal Hadi Salim, John Fastabend,
Kamezawa Hiroyuki, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1345215494-9181-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
We are able to safe some space when we assign the subsystem
IDs at compile time. Instead of allocating per cgroup
cgroup->subsys[CGROUP_SUBSYS_COUNT] where CGROUP_SUBSYS_COUNT is
always 64, we allocate at max 12 (at this point there are 12
subsystem).
The enum is created by passing in cgroup_subsys.h twice and
redefine the IS_SUBSYS_ENABLED. In the first pass, we just select
the builtin subsystem and in the second pass only the module
subsystems.
task_cls_classid() and task_netprioidx() (when built as
module) are protected by a jump label and therefore we can
simply replace the subsystem index lookup with the enum.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Eric Dumazet <edumazet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/linux/cgroup.h | 27 ++++++++++++++++++---------
include/linux/cgroup_subsys.h | 24 ++++++++++++------------
include/net/cls_cgroup.h | 12 +++---------
include/net/netprio_cgroup.h | 17 ++++-------------
kernel/cgroup.c | 25 ++++++-------------------
net/core/netprio_cgroup.c | 11 -----------
net/core/sock.c | 9 ---------
net/sched/cls_cgroup.c | 13 -------------
8 files changed, 43 insertions(+), 95 deletions(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index c90eaa8..1b9c8d9 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -44,18 +44,25 @@ extern void cgroup_unload_subsys(struct cgroup_subsys *ss);
extern const struct file_operations proc_cgroup_operations;
/* Define the enumeration of all builtin cgroup subsystems */
-#define SUBSYS(_x) _x ## _subsys_id,
+#define INCREASE_COUNTER() __COUNTER__
enum cgroup_subsys_id {
+
+#define SUBSYS(_x) _x ## _subsys_id = INCREASE_COUNTER(),
+#define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option)
#include <linux/cgroup_subsys.h>
- CGROUP_BUILTIN_SUBSYS_COUNT
-};
#undef SUBSYS
-/*
- * This define indicates the maximum number of subsystems that can be loaded
- * at once. We limit to this many since cgroupfs_root has subsys_bits to keep
- * track of all of them.
- */
-#define CGROUP_SUBSYS_COUNT (BITS_PER_BYTE*sizeof(unsigned long))
+#undef IS_SUBSYS_ENABLED
+
+#define SUBSYS(_x) _x ## _subsys_id,
+#define IS_SUBSYS_ENABLED(option) IS_MODULE(option)
+#include <linux/cgroup_subsys.h>
+#undef SUBSYS
+#undef IS_SUBSYS_ENABLED
+
+ CGROUP_SUBSYS_COUNT,
+ CGROUP_BUILTIN_SUBSYS_COUNT = INCREASE_COUNTER()
+};
+#undef INCREASE_COUNTER
/* Per-subsystem/per-cgroup state maintained by the system. */
struct cgroup_subsys_state {
@@ -521,7 +528,9 @@ struct cgroup_subsys {
};
#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
+#define IS_SUBSYS_ENABLED(option) IS_ENABLED(option)
#include <linux/cgroup_subsys.h>
+#undef IS_SUBSYS_ENABLED
#undef SUBSYS
static inline struct cgroup_subsys_state *cgroup_subsys_state(
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index dfae957..f204a7a 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -7,73 +7,73 @@
/* */
-#ifdef CONFIG_CPUSETS
+#if IS_SUBSYS_ENABLED(CONFIG_CPUSETS)
SUBSYS(cpuset)
#endif
/* */
-#ifdef CONFIG_CGROUP_DEBUG
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEBUG)
SUBSYS(debug)
#endif
/* */
-#ifdef CONFIG_CGROUP_SCHED
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_SCHED)
SUBSYS(cpu_cgroup)
#endif
/* */
-#ifdef CONFIG_CGROUP_CPUACCT
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_CPUACCT)
SUBSYS(cpuacct)
#endif
/* */
-#ifdef CONFIG_MEMCG
+#if IS_SUBSYS_ENABLED(CONFIG_MEMCG)
SUBSYS(mem_cgroup)
#endif
/* */
-#ifdef CONFIG_CGROUP_DEVICE
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEVICE)
SUBSYS(devices)
#endif
/* */
-#ifdef CONFIG_CGROUP_FREEZER
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_FREEZER)
SUBSYS(freezer)
#endif
/* */
-#ifdef CONFIG_NET_CLS_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_NET_CLS_CGROUP)
SUBSYS(net_cls)
#endif
/* */
-#ifdef CONFIG_BLK_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_BLK_CGROUP)
SUBSYS(blkio)
#endif
/* */
-#ifdef CONFIG_CGROUP_PERF
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_PERF)
SUBSYS(perf)
#endif
/* */
-#ifdef CONFIG_NETPRIO_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_NETPRIO_CGROUP)
SUBSYS(net_prio)
#endif
/* */
-#ifdef CONFIG_CGROUP_HUGETLB
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_HUGETLB)
SUBSYS(hugetlb)
#endif
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index bbbd957..037bfb1 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -48,22 +48,16 @@ static inline u32 task_cls_classid(struct task_struct *p)
extern struct static_key cgroup_cls_enabled;
#define clscg_enabled static_key_false(&cgroup_cls_enabled)
-extern int net_cls_subsys_id;
-
static inline u32 task_cls_classid(struct task_struct *p)
{
- int id;
- u32 classid = 0;
+ u32 classid;
if (!clscg_enabled || in_interrupt())
return 0;
rcu_read_lock();
- id = rcu_dereference_index_check(net_cls_subsys_id,
- rcu_read_lock_held());
- if (id >= 0)
- classid = container_of(task_subsys_state(p, id),
- struct cgroup_cls_state, css)->classid;
+ classid = container_of(task_subsys_state(p, net_cls_subsys_id),
+ struct cgroup_cls_state, css)->classid;
rcu_read_unlock();
return classid;
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index 9ff58e4..66241c6 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -31,10 +31,6 @@ struct cgroup_netprio_state {
u32 prioidx;
};
-#ifndef CONFIG_NETPRIO_CGROUP
-extern int net_prio_subsys_id;
-#endif
-
extern void sock_update_netprioidx(struct sock *sk, struct task_struct *task);
#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP)
@@ -60,20 +56,15 @@ extern struct static_key cgroup_netprio_enabled;
static inline u32 task_netprioidx(struct task_struct *p)
{
struct cgroup_netprio_state *state;
- int subsys_id;
- u32 idx = 0;
+ u32 idx;
if (!netpriocg_enabled)
return 0;
rcu_read_lock();
- subsys_id = rcu_dereference_index_check(net_prio_subsys_id,
- rcu_read_lock_held());
- if (subsys_id >= 0) {
- state = container_of(task_subsys_state(p, subsys_id),
- struct cgroup_netprio_state, css);
- idx = state->prioidx;
- }
+ state = container_of(task_subsys_state(p, net_prio_subsys_id),
+ struct cgroup_netprio_state, css);
+ idx = state->prioidx;
rcu_read_unlock();
return idx;
}
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 7981850..b00ae8a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -93,9 +93,12 @@ static DEFINE_MUTEX(cgroup_root_mutex);
* cgroup_mutex.
*/
#define SUBSYS(_x) &_x ## _subsys,
+#define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option)
static struct cgroup_subsys *subsys[CGROUP_SUBSYS_COUNT] = {
#include <linux/cgroup_subsys.h>
};
+#undef IS_SUBSYS_ENABLED
+#undef SUBSYS
#define MAX_CGROUP_ROOT_NAMELEN 64
@@ -4330,24 +4333,8 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
/* init base cftset */
cgroup_init_cftsets(ss);
- /*
- * need to register a subsys id before anything else - for example,
- * init_cgroup_css needs it.
- */
mutex_lock(&cgroup_mutex);
- /* find the first empty slot in the array */
- for (i = CGROUP_BUILTIN_SUBSYS_COUNT; i < CGROUP_SUBSYS_COUNT; i++) {
- if (subsys[i] == NULL)
- break;
- }
- if (i == CGROUP_SUBSYS_COUNT) {
- /* maximum number of subsystems already registered! */
- mutex_unlock(&cgroup_mutex);
- return -EBUSY;
- }
- /* assign ourselves the subsys_id */
- ss->subsys_id = i;
- subsys[i] = ss;
+ subsys[ss->subsys_id] = ss;
/*
* no ss->create seems to need anything important in the ss struct, so
@@ -4356,7 +4343,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
css = ss->create(dummytop);
if (IS_ERR(css)) {
/* failure case - need to deassign the subsys[] slot. */
- subsys[i] = NULL;
+ subsys[ss->subsys_id] = NULL;
mutex_unlock(&cgroup_mutex);
return PTR_ERR(css);
}
@@ -4372,7 +4359,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
if (ret) {
dummytop->subsys[ss->subsys_id] = NULL;
ss->destroy(dummytop);
- subsys[i] = NULL;
+ subsys[ss->subsys_id] = NULL;
mutex_unlock(&cgroup_mutex);
return ret;
}
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 94e1270..3a1d5cc 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -352,9 +352,7 @@ struct cgroup_subsys net_prio_subsys = {
.create = cgrp_create,
.destroy = cgrp_destroy,
.attach = net_prio_attach,
-#ifdef CONFIG_NETPRIO_CGROUP
.subsys_id = net_prio_subsys_id,
-#endif
.base_cftypes = ss_files,
.module = THIS_MODULE
};
@@ -392,10 +390,6 @@ static int __init init_cgroup_netprio(void)
ret = cgroup_load_subsys(&net_prio_subsys);
if (ret)
goto out;
-#ifndef CONFIG_NETPRIO_CGROUP
- smp_wmb();
- net_prio_subsys_id = net_prio_subsys.subsys_id;
-#endif
register_netdevice_notifier(&netprio_device_notifier);
@@ -412,11 +406,6 @@ static void __exit exit_cgroup_netprio(void)
cgroup_unload_subsys(&net_prio_subsys);
-#ifndef CONFIG_NETPRIO_CGROUP
- net_prio_subsys_id = -1;
- synchronize_rcu();
-#endif
-
rtnl_lock();
for_each_netdev(&init_net, dev) {
old = rtnl_dereference(dev->priomap);
diff --git a/net/core/sock.c b/net/core/sock.c
index 1f119d2..aa762d9 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -335,15 +335,6 @@ EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
struct static_key cgroup_netprio_enabled = STATIC_KEY_INIT_FALSE;
EXPORT_SYMBOL_GPL(cgroup_netprio_enabled);
#endif
-
-#if !defined(CONFIG_NET_CLS_CGROUP)
-int net_cls_subsys_id = -1;
-EXPORT_SYMBOL_GPL(net_cls_subsys_id);
-#endif
-#if !defined(CONFIG_NETPRIO_CGROUP)
-int net_prio_subsys_id = -1;
-EXPORT_SYMBOL_GPL(net_prio_subsys_id);
-#endif
#endif
static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 0635894..5dd6fe6 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -86,9 +86,7 @@ struct cgroup_subsys net_cls_subsys = {
.name = "net_cls",
.create = cgrp_create,
.destroy = cgrp_destroy,
-#ifdef CONFIG_NET_CLS_CGROUP
.subsys_id = net_cls_subsys_id,
-#endif
.base_cftypes = ss_files,
.module = THIS_MODULE,
};
@@ -292,12 +290,6 @@ static int __init init_cgroup_cls(void)
if (ret)
goto out;
-#ifndef CONFIG_NET_CLS_CGROUP
- /* We can't use rcu_assign_pointer because this is an int. */
- smp_wmb();
- net_cls_subsys_id = net_cls_subsys.subsys_id;
-#endif
-
ret = register_tcf_proto_ops(&cls_cgroup_ops);
if (ret)
cgroup_unload_subsys(&net_cls_subsys);
@@ -310,11 +302,6 @@ static void __exit exit_cgroup_cls(void)
{
unregister_tcf_proto_ops(&cls_cgroup_ops);
-#ifndef CONFIG_NET_CLS_CGROUP
- net_cls_subsys_id = -1;
- synchronize_rcu();
-#endif
-
cgroup_unload_subsys(&net_cls_subsys);
}
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* Re: [RFC PATCH 0/1] sched: Add a new API to find the prefer idlest cpu
From: Shirley Ma @ 2012-08-17 15:39 UTC (permalink / raw)
To: linux-kernel, mingo, peterz; +Cc: netdev, Michael S. Tsirkin, vivek, sri, sri
In-Reply-To: <1343026634.13461.15.camel@oc3660625478.ibm.com>
Hello Ingo, Peter,
Have you had chance to review below patch?
Thanks
Shirley
On Sun, 2012-07-22 at 23:57 -0700, Shirley Ma wrote:
> Introduce a new API to choose per-cpu thread from cgroup control cpuset
> (allowed) and preferred cpuset (local numa-node).
>
> The receiving cpus of a networking device are not under cgroup controls.
> When such a networking device uses per-cpu thread model, the cpu which
> is chose to process the packets might not be part of cgroup cpusets
> without this API. On numa system, the preferred cpusets would help to
> reduce expensive cross memory access to/from the other node.
>
> Signed-off-by: Shirley Ma <xma@us.ibm.com>
> ---
>
> include/linux/sched.h | 2 ++
> kernel/sched/fair.c | 30 ++++++++++++++++++++++++++++++
> 2 files changed, 32 insertions(+), 0 deletions(-)
>
> Thanks
> Shirley
>
>
>
> --
> 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
>
^ permalink raw reply
* Re: [PATCH 0/5] Call netif_carrier_off() after register_netdev()
From: Stephen Hemminger @ 2012-08-17 16:20 UTC (permalink / raw)
To: Ilya Shchepetkov
Cc: bjorn, David S. Miller, Ben Hutchings, netdev, linux-kernel,
ldv-project
In-Reply-To: <1345190143-12050-1-git-send-email-shchepetkov@ispras.ru>
On Fri, 17 Aug 2012 11:55:43 +0400
Ilya Shchepetkov <shchepetkov@ispras.ru> wrote:
> >> Ben Hutchings <bhutchings@solarflare.com> writes:
> >>> But if you do it beforehand then it doesn't have the intended effect.
> >>> (Supposed to be fixed by 22604c866889c4b2e12b73cbf1683bda1b72a313, which
> >>> had to be reverted: c276e098d3ee33059b4a1c747354226cec58487c.)
> >>>
> >>> So you have to do it after, but without dropping the RTNL lock in
> >>> between.
> >> So you may want to add something like
> >>
> >> int register_netdev_carrier_off(struct net_device *dev)
> >> {
> >> int err;
> >>
> >> rtnl_lock();
> >> err = register_netdevice(dev);
> >> if (!err)
> >> set_bit(__LINK_STATE_NOCARRIER, &dev->state)
> >> rtnl_unlock();
> >> return err;
> >> }
> >>
> >>
> >> for these drivers?
>
> t looks like this variant is equivalent to the existing code:
>
> netif_carrier_off(dev);
> err = register_netdev(dev);
> if (err)
> goto out;
>
> According to explanation in commit 22604c866889c4b2e12b73cbf1683bda1b72a313,
> in this case "this causes these drivers to incorrectly report their
> link status as IF_OPER_UNKNOWN which can falsely set the IFF_RUNNING
> flag when the interface is first brought up".
>
> As far as I understand, to fix the issue it is required to call
> netif_carrier_off() itself:
>
> int register_netdev_carrier_off(struct net_device *dev)
> {
> int err;
>
> rtnl_lock();
> err = register_netdevice(dev);
> if (!err)
> netif_carrier_off(dev);
> rtnl_unlock();
> return err;
> }
>
> What do you think?
Does this prevent multiple link events from being reported to user space?
If the root cause of the problem is the link status
(commit 22604c866889c4b2e12b73cbf1683bda1b72a313), then the kernel
should be fixed to do link status correctly.
>From an application point of view IFF_RUNNING is meaningless unless IFF_UP
is set.
^ permalink raw reply
* Re: [PATCH] smsc75xx: add missing entry to MAINTAINERS
From: Joe Perches @ 2012-08-17 16:21 UTC (permalink / raw)
To: Steve Glendinning; +Cc: linux-kernel, netdev, trivial
In-Reply-To: <1345103618-22753-1-git-send-email-steve.glendinning@shawell.net>
On Thu, 2012-08-16 at 08:53 +0100, Steve Glendinning wrote:
> Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
[]
> diff --git a/MAINTAINERS b/MAINTAINERS
[]
> +USB SMSC75XX ETHERNET DRIVER
> +M: Steve Glendinning <steve.glendinning@shawell.net>
> +L: netdev@vger.kernel.org
> +S: Maintained
> +F: drivers/net/usb/smsc75xx.*
> +
> USB SMSC95XX ETHERNET DRIVER
> M: Steve Glendinning <steve.glendinning@shawell.net>
> L: netdev@vger.kernel.org
Hi Steve.
Perhaps you could have a single updated [79]5xx entry with
F: drivers/net/usb/smsc[79]5xx.*
or
F: drivers/net/usb/smsc?5xx.*
Also, diff makes it seem the drivers aren't significantly
different. Might it be better to integrate the 2 drivers
into a single driver that supports both?
^ permalink raw reply
* Re: [RFC PATCH 0/1] sched: Add a new API to find the prefer idlest cpu
From: Peter Zijlstra @ 2012-08-17 16:48 UTC (permalink / raw)
To: Shirley Ma; +Cc: linux-kernel, mingo, netdev, Michael S. Tsirkin, vivek, sri
In-Reply-To: <1345217986.16533.1.camel@oc3660625478.ibm.com>
On Fri, 2012-08-17 at 08:39 -0700, Shirley Ma wrote:
> Hello Ingo, Peter,
> Have you had chance to review below patch?
Well no of course not, nobody CC'ed us..
Your patch submission sucks, you split the changelog and the actual
patch into two different emails.
It doesn't mention who would be calling this and how often. Nor does it
seem to explain where the cpumask arguments come from.
Please try again.
^ permalink raw reply
* Re: [RFC PATCH 0/1] sched: Add a new API to find the prefer idlest cpu
From: Shirley Ma @ 2012-08-17 16:58 UTC (permalink / raw)
To: Peter Zijlstra
Cc: linux-kernel, mingo, netdev, Michael S. Tsirkin, vivek, sri
In-Reply-To: <1345222134.29668.63.camel@twins>
On Fri, 2012-08-17 at 18:48 +0200, Peter Zijlstra wrote:
> On Fri, 2012-08-17 at 08:39 -0700, Shirley Ma wrote:
>
> > Hello Ingo, Peter,
> > Have you had chance to review below patch?
>
> Well no of course not, nobody CC'ed us..
>
> Your patch submission sucks, you split the changelog and the actual
> patch into two different emails.
>
> It doesn't mention who would be calling this and how often. Nor does
> it
> seem to explain where the cpumask arguments come from.
>
> Please try again.
Thanks for your comments. I must be spoiled by net-dev maintainers. I
used to submit the patch this way thought my linux email in the past
many years. So I need to reply on the changelog for the actual patch? I
hope I won't make any more suck submissions again.
I will try to explain more details why this API needs to be exported.
Thanks again.
Shirley
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox