Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
From: Jesper Dangaard Brouer @ 2012-08-17  8:06 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel, netdev
In-Reply-To: <1344542943-11588-6-git-send-email-kaber@trash.net>

On Thu, 2012-08-09 at 22:08 +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.

I'm working on IPv6 fragment handling for IPVS, and are taking advantage
of the "replay" by nf_ct_frag6_output() at hook prio -399
(NF_IP6_PRI_CONNTRACK_DEFRAG + 1).
By making a hook at NF_INET_PRE_ROUTING at prio -99 (NF_IP6_PRI_NAT_DST
+ 1).

I can see that the code path can be changed (with this patch), if a
helper is assigned.  Then the "replay" starts at prio -199
(NF_IP6_PRI_CONNTRACK + 1), I guess I'm safe as I run at -99.

I have tested that your patchset works, with my ipvs patches, but would
like the trigger the changed code path, to make sure.

Could you provide an iptables command/rule, that trigger this code path?


[cut]

> @@ -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)) {
> +			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);

Hook prio change to NF_IP6_PRI_CONNTRACK + 1


> +			return NF_DROP_ERR(-ECANCELED);
> +		}

[cut]

> @@ -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);

Old hook prio

> +		else
> +			kfree_skb(s);
> +
>  		s = s2;
>  	}
>  	nf_conntrack_put_reasm(skb);



^ permalink raw reply

* Re: [PATCH 001/001] smsc95xx: Fix hard_header_len
From: Steve Glendinning @ 2012-08-17  8:35 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: JamesBetts, netdev, David Miller
In-Reply-To: <1345139973.2832.3.camel@bwh-desktop.uk.solarflarecom.com>

> hard_header_len is set to ETH_HLEN by alloc_etherdev() (in the
> ether_setup() callback).  Any extra headroom you want before the
> Ethernet header should indeed be specified in needed_headroom.

Thanks Ben, looks like this patch is doing it the right way then.

Acked-By: Steve Glendinning <steve.glendinning@shawell.net>


-- 
Steve Glendinning

^ permalink raw reply

* Selected
From: MICROSOFT COMPANY @ 2012-08-16  7:43 UTC (permalink / raw)
  To: Recipients

Your Email Id has won (1,000,000.00 GBP) in the British MICROSOFT COMPANY 
Promo 2012. send your
1.Name.2.Address.3.Nationality.4.Age.5.Occupation.6.Phone/Fax.

To our claims deparment: claimunit012@live.co.uk
Tel: +44 7010040973

Sincerely,
Johnson smith

^ permalink raw reply

* Re: [PATCH v0 5/5] cgroup: Assign subsystem IDs during compile time
From: Daniel Wagner @ 2012-08-17  8:48 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, netdev, cgroups, Daniel Wagner, David S. Miller,
	Andrew Morton, Eric Dumazet, Gao feng, Glauber Costa,
	Jamal Hadi Salim, John Fastabend, Kamezawa Hiroyuki, Neil Horman
In-Reply-To: <502DF1DF.8040109@huawei.com>

On 17.08.2012 09:25, Li Zefan wrote:
> On 2012/8/17 7:20, Tejun Heo wrote:
>> On Thu, Aug 16, 2012 at 04:12:16PM +0200, Daniel Wagner wrote:
>>> From: Daniel Wagner <daniel.wagner@bmw-carit.de>
>>>
>>> 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 12 + 1 at max (at this point there are 12
>>> subsystem).
>>
>> So, IIUC, this is effectively removing the capability to implement
>> modularized controller which isn't known at kernel compile time.  Am I
>> right?
>>
>
> I think so.

I am preparing an updated version which does not need the extra 1 
pointer. Some more preprocessor magic involved :)

>> I don't think that's a bad idea but if we're doing that, can't we make
>> things even simpler?  Do we need to distinguish in-kernel and module
>> at all?
>>
>> Li, what do you think about this?
>>
>
> I'm definitely all for simplicity, but I'm not sure if we can do better in
> simplifying the code for modularized cgroup subsystem. (I guess you didn't
> mean to remove this feature?)

The new version should also be simpler to review because I don't have to 
touch the loops everywhere.

daniel

^ permalink raw reply

* Patrick
From: Patrick.chn @ 2012-08-17 11:13 UTC (permalink / raw)
  To: Recipients

Patrick

My name is Patrick Chan I work with the Hang Seng Bank. There is the sum of 
$22,500,000.00 in my bank"Hang Seng Bank",Hong kong.

I wish to make a transfer of the $22,500,000.00 .I do solicit for you 
assistance in effecting this transaction.I intend to give  you 30% of the total 
funds as compensation for your assistance.

Should you be interested please send me an email on my private email 
(chanprivacy07@aol.com).
1. Full names
2. Private phone number
3. Current residential address

Regards,
chanprivacy07@aol.com
Patrick Chan.

^ permalink raw reply

* Re: [RFC net-next 0/4] gianfar: Use separate NAPI for Tx confirmation processing
From: Claudiu Manoil @ 2012-08-17 11:28 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: Tomas Hruby, Eric Dumazet, netdev, David S. Miller
In-Reply-To: <20120816153638.GA24993@windriver.com>

On 08/16/2012 06:36 PM, Paul Gortmaker wrote:
> [Re: [RFC net-next 0/4] gianfar: Use separate NAPI for Tx confirmation processing] On 14/08/2012 (Tue 19:08) Claudiu Manoil wrote:
>
>> On 08/14/2012 04:15 AM, Paul Gortmaker wrote:
>>> This is a lot lower variation than what you reported earlier (20
>>> versus 200, I think). It was the variation that raised a red flag
>>> for me...
>> Hi Paul,
>> The earlier variation, which is much bigger (indeed ~200), was
>> observed on a p1020 (slow, 2 cores, MQ_MG_MODE).
>> I did not collect however as detailed measurement results for that
>> board, as I did for p1010 (previous email).
>> The most important performance improvement I've noticed however was
>> on the p1020 platform.
>>
>>>> By changing the coalescing settings from default* (rx coalescing off,
>>>> tx-usecs: 10, tx-frames: 16) to:
>>>> ""
>>>> we get a throughput of ~710 Mbps.
>>>>
>>>> For *Image 2)*, using the default tcp_limit_output_bytes value
>>>> (131072) - I've noticed
>>>> that "tweaking" tcp_limit_output_bytes does not improve the
>>>> throughput -, we get the
>>>> following performance numbers:
>>>> * default coalescing settings: ~650 Mbps
>>>> * rx-frames tx-frames 22 rx-usecs 32 tx-usecs 32: ~860-880 Mbps
>>>>
>>>> For *Image 3)*, by disabling BQL (CONFIG_BQL = n), there's *no*
>>>> relevant performance
>>>> improvement compared to Image 1).
>>>> (note:
>>>> For all the measurements, rx and tx BD ring sizes have been set to
>>>> 64, for best performance.)
>>>>
>>>> So, I really tend to believe that the performance degradation comes
>>>> primarily from the driver,
>>>> and the napi poll processing turns out to be an important source for
>>>> that. The proposed patches
>>> This would make sense, if the CPU was slammed at 100% load in dealing
>>> with the tx processing, and the change made the driver considerably more
>>> efficient.  But is that really the case?  Is the p1010 really going flat
>>> out just to handle the Tx processing?  Have you done any sort of
>>> profiling to confirm/deny where the CPU is spending its time?
>> The current gfar_poll implementation processes first the tx
>> confirmation path exhaustively, without a budget/ work limit,
>> and only then proceeds with the rx processing within the allotted
>> budget. An this happens for both Rx and Tx confirmation
>> interrupts. I find this unfair and out of balance. Maybe by letting
>> rx processing to be triggered by rx interrupts only, and
>> the tx conf path processing to be triggered by tx confirmation
>> interrupts only, and, on top of that, by imposing a work limit
>> on the tx confirmation path too, we get a more responsive driver
>> that performs better. Indeed some profiling data to
>> confirm this would be great, but I don't have it.
>>
>> There's another issues that seems to be solved by this patchset, and
>> I've noticed it only on p1020rdb (this time).
>> And that is excessive Rx busy interrupts occurrence. Solving this
>> issue may be another factor for the performance
>> improvement on p1020. But maybe this is another discussion.
>>
>>>> show substantial improvement, especially for SMP systems where Tx
>>>> and Rx processing may be
>>>> done in parallel.
>>>> What do you think?
>>>> Is it ok to proceed by re-spinning the patches? Do you recommend
>>>> additional measurements?
>>> Unfortunately Eric is out this week, so we will be without his input for
>>> a while.  However, we are only at 3.6-rc1 -- meaning net-next will be
>>> open for quite some time, hence no need to rush to try and jam stuff in.
>>>
>>> Also, I have two targets I'm interested in testing your patches on.  The
>>> 1st is a 500MHz mpc8349 board -- which should replicate what you see on
>>> your p1010 (slow, single core).  The other is an 8641D, which is
>>> interesting since it will give us the SMP tx/rx as separate threads, but
>>> without the MQ_MG_MODE support (is that a correct assumption?)
>>>
>>> I don't have any fundamental problem with your patches (although 4/4
>>> might be better as two patches) -- the above targets/tests are only
>>> of interest, since I'm not convinced we yet understand _why_ your
>>> changes give a performance boost, and there might be something
>>> interesting hiding in there.
>>>
>>> So, while Eric is out, let me see if I can collect some more data on
>>> those two targets sometime this week.
>> Great, I don't mean to rush.  The more data we get on this the better.
>> It would be great if you could do some measurements on your platforms too.
>> 8641D is indeed a dual core with etsec 1.x (so without the MQ_MG_MODE),
>> but I did run some tests on a p2020, which has the same features. However
>> I'm eager to see your results.
> So, I've collected data on 8349 (520MHz single core) and 8641D (1GHz
> dual core) and the results are kind of surprising (to me).  The SMP
> target, which in theory should have benefited from the change, actually
> saw about an 8% reduction in throughput.  And the slower single core saw
> about a 5% increase.
>
> I also retested the 8641D with just your 1st 3 patches (i.e. drop the
> "Use separate NAPIs for Tx and Rx processing" patch) and it recovered
> about 1/2 the lost throughput, but not all.
>
> I've used your patches exactly as posted, and the same netperf cmdline.
> I briefly experimented with disabling BQL on the 8349 but didn't see any
> impact from doing that (consistent with what you'd reported).  I didn't
> see any real large variations either (target and server on same switch),
> but I'm thinking the scatter could be reduced further if I isolated
> the switch entirely to just the target and server.  I'll do that if I
> end up doing any more testing on this, since the averages seem to be
> reproduceable to about +/- 2% at the moment...
>
> Paul.
>
>   --------------
> Command: netperf -l 20 -cC -H 192.168.146.65 -t TCP_STREAM -- -m 1500
> next-next baseline: commit 1f07b62f3205f6ed41759df2892eaf433bc051a1
> fsl RFC:  http://patchwork.ozlabs.org/patch/175919/ applied to above.
> Default queue sizes (256), BQL defaults.
>
> 8349 (528 MHz, single core):
>     net-next 10 runs
>     avg=123
>     max=124
>     min=121
>     send utilization > 99%
>     
>     fsl RFC 13 runs:
>     avg=129 (+ ~5%)
>     max=131
>     min=127
>     send utilization > 99%
>     
> 8641D: (1GHz, dual core)
>     net-next 10 runs
>     avg=826
>     max=839
>     min=807
>     send utilization ~ 70%
>
>     fsl RFC 12 runs
>     avg=762 (- ~8%)
>     max=783
>     min=698
>     send utilization ~ 70%
>
>     fsl RFC, _only_ 1st 3 of 4 patches, 13 runs
>     avg=794 (- ~4%)
>     max=816
>     min=758
>     send utilization ~ 70%
>   --------------
Hello Paul,
Thanks again for the measurements. It will take me some time to "digest"
the results and even do more tests/ analysis on the platforms at my 
disposal.
Your results are indeed surprising, but there are some noticeable 
differences
b/w our setups too.
First of all, as noted before, I'm using BD rings of size 64 for best 
performance
(as this proved to be an optimal setting over the time). So, before 
starting any
tests, I was issuing: "ethtool -G <ethX> rx 64 tx 64".
Another point is that, to enhance the performance gain, I was using some
"decent" interrupt coalescing settings (at least to have rx coalescing 
enabled
too, which is by default off). So I've been using:
"ethtool -C eth1 rx-frames 22 rx-usecs 32 tx-frames 22 tx-usecs 32"
I think that the proposed code enhancement requires some balanced interrupt
coalescing settings too, for best results.

It's interesting that with these settings, I was able to reach ~940 Mbps 
on a p2020rdb
(which is also "single queue single group", but with two 1.2GHz e500v2 
cores), both with
and without the RFC patches.

Another point to consider when doing these measurements on SMP systems,
is that Rx/Tx interrupt handling should happen on distinct CPUs.
I think this happens by default for netperf on the "non-MQ_MG_MODE" systems
(like 8641D, or p2020), but this condition must be verified for the 
MQ_MG_MODE
systems (like p1020), by checking /proc/interrupts, and (if needed) 
forced by setting
interrupt affinities accordingly.
Btw., do you happen to have a p1020 board at your disposal too?

Best regards,
Claudiu

^ permalink raw reply

* Virus decteded
From: Webmail Helpdesk Support Centre @ 2012-08-17 11:07 UTC (permalink / raw)


Virus in your email account, you may lose your email account. Use the below web
link to
Delete the virus in your email account:
Click link below:
https://docs.google.com/spreadsheet/viewform?formkey=dGtEUFdyS3NhdU1YNk5TNEhqYmNKcFE6MQ

Thank you for using our email.
Copyright ©2012 Email Helpdesk Centre

^ permalink raw reply

* Re: [PATCH v3 0/7] mv643xx.c: Add basic device tree support.
From: Arnd Bergmann @ 2012-08-17 12:13 UTC (permalink / raw)
  To: Ian Molton
  Cc: linux-arm-kernel, thomas.petazzoni, andrew, netdev,
	devicetree-discuss, ben.dooks, dale, linuxppc-dev, David Miller
In-Reply-To: <5028D040.60604@codethink.co.uk>

On Monday 13 August 2012, Ian Molton wrote:
> On 10/08/12 11:49, Arnd Bergmann wrote:
> > On Thursday 09 August 2012, Ian Molton wrote:
> >>>  The driver
> >>> already knows all those offsets and they are always the same
> >>> for all variants of mv643xx, right?
> >> Yes, but its not clean. And no amount of refactoring is
> >> really going to make a nice driver that also fits the ancient
> >> (and badly thought out) OF bindings.
> > In what way is it badly though out, or not clean? The use of
> > underscores in the properties, and the way that the sram
> > is configured is problematic, I agree. But The way that
> > the three ports are addressed and how the PHY is found
> > seems quite clever.
> 
> It forces one to load the MDIO driver first, because it maps ALL the
> registers for both itself and all the ports, and the MDIO driver has no
> way of knowing how many ethernet blocks are present (I have a device
> here with two, and another with four). Thats anywhere from 1 to 12
> ports, split across 1 to 4 address ranges, and theres a big gap in the
> address range between controllers 0,1 and 2,3. *ALL* the devices on the
> board are sharing ethernet block 0's MDIO bus. By pure luck it happens
> to work, because the blocks 2,3 have an alias of the MDIO registers from
> blocks 0,1.
> 
> Having the MDIO driver map the ethernet drivers memory is a terrible
> solution, IMO. Ethernet drivers should map their own memory, and that
> introduces the n-ports-per-block problem, because their address ranges
> overlap.
> 
> I think the best solution is to make each ethernet block register 3 ports.
> 
> the PPC code can simply generate different fixups so that instead of
> creating 3 devices, it creates one, with three ports.

Ok.

> Can we get some consensus on the right approach here? I'm loathe to code
> this if its going to be rejected.
> 
> I'd prefer the driver to be properly split so we dont have the MDIO
> driver mapping the ethernet drivers address spaces, but if thats not
> going to be merged, I'm not feeling like doing the work for nothing.
> 
> If the driver is to use the overlapping-address mapped-by-the-mdio
> scheme, then so be it, but I could do with knowing.
> 
> Another point against the latter scheme is that the MDIO driver could
> sensibly be used (the block is identical) on the ArmadaXP, which has 4
> ethernet blocks rather than two, yet grouped in two pairs with a
> discontiguous address range.
> 
> I'd like to get this moved along as soon as possible though.

I don't object to any device driver changes, but I do want to make
sure that the bindings are sensible and can coexist with the
ones that have been used for the past 5 years.

Maybe you can move the binding for the ethernet parts out of the
marvell.txt file into the place you want to use for the new
bindings and then extend it to cover both the old and the new style.

	Arnd

^ permalink raw reply

* 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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox