* [PATCH] Fix: Dereference pointer-value of sk_prot->memory_pressure
From: Eric W. Biederman @ 2013-10-23 19:58 UTC (permalink / raw)
To: David Miller
Cc: Christoph Paasch, fengguang.wu, netdev, linux-kernel,
Eric Dumazet
In-Reply-To: <1382533364.7572.15.camel@edumazet-glaptop.roam.corp.google.com>
From: Christoph Paasch <christoph.paasch@uclouvain.be>
Date: Wed, 23 Oct 2013 12:49:21 -0700
2e685cad57 (tcp_memcontrol: Kill struct tcp_memcontrol) falsly modified
the access to memory_pressure of sk->sk_prot->memory_pressure. The patch
did modify the memory_pressure-field of struct cg_proto, but not the one
of struct proto.
So, the access to sk_prot->memory_pressure should not be changed.
Acked-by: Eric Dumazet <edumazet@google.com>
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
Resent because I fat fingered and deleted Dave by accident.
include/net/sock.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index c93542f92420..e3a18ff0c38b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1137,7 +1137,7 @@ static inline bool sk_under_memory_pressure(const struct sock *sk)
if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
return !!sk->sk_cgrp->memory_pressure;
- return !!sk->sk_prot->memory_pressure;
+ return !!*sk->sk_prot->memory_pressure;
}
static inline void sk_leave_memory_pressure(struct sock *sk)
--
1.7.5.4
^ permalink raw reply related
* [PATCH] Fix: Dereference pointer-value of sk_prot->memory_pressure
From: Eric W. Biederman @ 2013-10-23 19:55 UTC (permalink / raw)
To: Eric Dumazet
Cc: Christoph Paasch, fengguang.wu, netdev, linux-kernel,
Eric Dumazet
In-Reply-To: <1382533364.7572.15.camel@edumazet-glaptop.roam.corp.google.com>
From: Christoph Paasch <christoph.paasch@uclouvain.be>
Date: Wed, 23 Oct 2013 12:49:21 -0700
2e685cad57 (tcp_memcontrol: Kill struct tcp_memcontrol) falsly modified
the access to memory_pressure of sk->sk_prot->memory_pressure. The patch
did modify the memory_pressure-field of struct cg_proto, but not the one
of struct proto.
So, the access to sk_prot->memory_pressure should not be changed.
Acked-by: Eric Dumazet <edumazet@google.com>
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
include/net/sock.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index c93542f92420..e3a18ff0c38b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1137,7 +1137,7 @@ static inline bool sk_under_memory_pressure(const struct sock *sk)
if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
return !!sk->sk_cgrp->memory_pressure;
- return !!sk->sk_prot->memory_pressure;
+ return !!*sk->sk_prot->memory_pressure;
}
static inline void sk_leave_memory_pressure(struct sock *sk)
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH net-next 0/2] Removal of struct esp_data
From: David Miller @ 2013-10-23 19:40 UTC (permalink / raw)
To: steffen.klassert; +Cc: mathias.krause, netdev, herbert
In-Reply-To: <20131023080716.GA10148@secunet.com>
From: Steffen Klassert <steffen.klassert@secunet.com>
Date: Wed, 23 Oct 2013 10:07:16 +0200
> Well, I thought to either take this as a reminder to implement the
> missing stuff or to take the removing patches if this is really obsolete.
> I'll do one of both once I'm back from conference week in Edinburgh.
Sounds like a good plan, thanks.
^ permalink raw reply
* Re: [PATCH 1/4] [RFC] net: Explicitly initialize u64_stats_sync structures for lockdep
From: Julian Anastasov @ 2013-10-23 19:37 UTC (permalink / raw)
To: John Stultz
Cc: LKML, Eric Dumazet, Thomas Petazzoni, Mirko Lindner,
Stephen Hemminger, Roger Luethi, Patrick McHardy, Rusty Russell,
Michael S. Tsirkin, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, Wensong Zhang, Simon Horman, Jesse Gross,
Mathieu Desnoyers, Steven Rostedt, Peter Zijlstra, Ingo Molnar,
Thomas Gleixner, David S. Miller, netdev, netfilter-devel
In-Reply-To: <52681407.8060804@linaro.org>
Hello,
On Wed, 23 Oct 2013, John Stultz wrote:
> Just wanted to ping folks on this patch, as I haven't gotten any feedback.
>
> As its a prereq for the seqcount lockdep support, I'd like to get it
> queued/merged, but I'm not sure what the right maintainer path or
> approach should be.
>
> 1) Do folks prefer to see this patch split up into 30-some separate
> trivial clenaup patches, or have it go in all as one logical change?
>
> 2) Would folks want this patch (in whichever form) to be merged
> separately via the networking maintainers, or can it be merged via -tip
> as part of the seqcount lockdep series?
The IPVS part in net/netfilter/ipvs/ looks ok to me.
We do not have any pending changes for this area, so you can
skip the ipvs trees for this change. If you need ack for the
IPVS part, here it is:
Acked-by: Julian Anastasov <ja@ssi.bg>
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* URGENT REPLY NEEDED
From: Suleman Abubaker @ 2013-10-23 18:57 UTC (permalink / raw)
Greetings Dear Friend.
I am Mr Suleman Abubaker, Staff of Bank Of Africa in Burkina Faso. I would like you to indicate your interest to
receive the transfer of ($20.5 Million Dollars) I will like you to stand as the next of kin to my late client whose account is presently dormant for claims. if you are interested,indicate and i will intimate you with the method of application and how you can apply to the bank .
But before i send to you the text of application form,I will like you to send me the following informations
1.NAME IN FULL:................................
2.ADDRESS:.......................................
3.NATIONALITY:.................................. .
4.AGE:.............................................
5.SEX..............................................
6.OCCUPATION:......................................
7.MARITAL STATUS:..................................
8.PRIAVTE PHONE NO............................................
9.PRIVATE FAX NO:.............................................
10.ATTACH COPY OF YOUR IDENTIFICATION...........................
Now my questions are:
1) Can you handle this project?
2) Can I give you this trust?
so i will like you to send to me those informations for easy and effective communication.Upon receipt of your reply, I will send to you by fax or
email the text of the application form.I will not fail to bring to your notice that this transaction is hitch-free and that you should not entertain any atom of fear as all required arrangements have been made for the transfer. You should contact me immediately as soon as you receive this letter,if only you are intrested and ready to help. Trusting to hear from you immediately.
Do keep this a top secret for security reasons.
Best Regards
Mr Suleman Abubaker.
^ permalink raw reply
* [PATCH net-next] fix rtnl notification in atomic context
From: Alexei Starovoitov @ 2013-10-23 18:32 UTC (permalink / raw)
To: David S. Miller; +Cc: Nicolas Dichtel, Cong Wang, netdev
commit 991fb3f74c "dev: always advertise rx_flags changes via netlink"
introduced rtnl notification from __dev_set_promiscuity(),
which can be called in atomic context.
Steps to reproduce:
ip tuntap add dev tap1 mode tap
ifconfig tap1 up
tcpdump -nei tap1 &
ip tuntap del dev tap1 mode tap
[ 271.627994] device tap1 left promiscuous mode
[ 271.639897] BUG: sleeping function called from invalid context at mm/slub.c:940
[ 271.664491] in_atomic(): 1, irqs_disabled(): 0, pid: 3394, name: ip
[ 271.677525] INFO: lockdep is turned off.
[ 271.690503] CPU: 0 PID: 3394 Comm: ip Tainted: G W 3.12.0-rc3+ #73
[ 271.703996] Hardware name: System manufacturer System Product Name/P8Z77 WS, BIOS 3007 07/26/2012
[ 271.731254] ffffffff81a58506 ffff8807f0d57a58 ffffffff817544e5 ffff88082fa0f428
[ 271.760261] ffff8808071f5f40 ffff8807f0d57a88 ffffffff8108bad1 ffffffff81110ff8
[ 271.790683] 0000000000000010 00000000000000d0 00000000000000d0 ffff8807f0d57af8
[ 271.822332] Call Trace:
[ 271.838234] [<ffffffff817544e5>] dump_stack+0x55/0x76
[ 271.854446] [<ffffffff8108bad1>] __might_sleep+0x181/0x240
[ 271.870836] [<ffffffff81110ff8>] ? rcu_irq_exit+0x68/0xb0
[ 271.887076] [<ffffffff811a80be>] kmem_cache_alloc_node+0x4e/0x2a0
[ 271.903368] [<ffffffff810b4ddc>] ? vprintk_emit+0x1dc/0x5a0
[ 271.919716] [<ffffffff81614d67>] ? __alloc_skb+0x57/0x2a0
[ 271.936088] [<ffffffff810b4de0>] ? vprintk_emit+0x1e0/0x5a0
[ 271.952504] [<ffffffff81614d67>] __alloc_skb+0x57/0x2a0
[ 271.968902] [<ffffffff8163a0b2>] rtmsg_ifinfo+0x52/0x100
[ 271.985302] [<ffffffff8162ac6d>] __dev_notify_flags+0xad/0xc0
[ 272.001642] [<ffffffff8162ad0c>] __dev_set_promiscuity+0x8c/0x1c0
[ 272.017917] [<ffffffff81731ea5>] ? packet_notifier+0x5/0x380
[ 272.033961] [<ffffffff8162b109>] dev_set_promiscuity+0x29/0x50
[ 272.049855] [<ffffffff8172e937>] packet_dev_mc+0x87/0xc0
[ 272.065494] [<ffffffff81732052>] packet_notifier+0x1b2/0x380
[ 272.080915] [<ffffffff81731ea5>] ? packet_notifier+0x5/0x380
[ 272.096009] [<ffffffff81761c66>] notifier_call_chain+0x66/0x150
[ 272.110803] [<ffffffff8108503e>] __raw_notifier_call_chain+0xe/0x10
[ 272.125468] [<ffffffff81085056>] raw_notifier_call_chain+0x16/0x20
[ 272.139984] [<ffffffff81620190>] call_netdevice_notifiers_info+0x40/0x70
[ 272.154523] [<ffffffff816201d6>] call_netdevice_notifiers+0x16/0x20
[ 272.168552] [<ffffffff816224c5>] rollback_registered_many+0x145/0x240
[ 272.182263] [<ffffffff81622641>] rollback_registered+0x31/0x40
[ 272.195369] [<ffffffff816229c8>] unregister_netdevice_queue+0x58/0x90
[ 272.208230] [<ffffffff81547ca0>] __tun_detach+0x140/0x340
[ 272.220686] [<ffffffff81547ed6>] tun_chr_close+0x36/0x60
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
---
include/linux/rtnetlink.h | 4 +++-
net/core/dev.c | 2 +-
net/core/rtnetlink.c | 12 +++++++++---
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index f28544b..26f5edc 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -15,7 +15,9 @@ extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
u32 id, long expires, u32 error);
-extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
+void __rtmsg_ifinfo(int type, struct net_device *dev, unsigned change,
+ gfp_t flags);
+void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
/* RTNL is used as a global lock for all changes to network configuration */
extern void rtnl_lock(void);
diff --git a/net/core/dev.c b/net/core/dev.c
index 0918aad..59b90fe 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5257,7 +5257,7 @@ void __dev_notify_flags(struct net_device *dev, unsigned int old_flags,
unsigned int changes = dev->flags ^ old_flags;
if (gchanges)
- rtmsg_ifinfo(RTM_NEWLINK, dev, gchanges);
+ __rtmsg_ifinfo(RTM_NEWLINK, dev, gchanges, GFP_ATOMIC);
if (changes & IFF_UP) {
if (dev->flags & IFF_UP)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4aedf03..5931af9 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1984,14 +1984,15 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
-void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change)
+void __rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
+ gfp_t flags)
{
struct net *net = dev_net(dev);
struct sk_buff *skb;
int err = -ENOBUFS;
size_t if_info_size;
- skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL);
+ skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags);
if (skb == NULL)
goto errout;
@@ -2002,12 +2003,17 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change)
kfree_skb(skb);
goto errout;
}
- rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags);
return;
errout:
if (err < 0)
rtnl_set_sk_err(net, RTNLGRP_LINK, err);
}
+
+void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change)
+{
+ __rtmsg_ifinfo(type, dev, change, GFP_KERNEL);
+}
EXPORT_SYMBOL(rtmsg_ifinfo);
static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 1/4] [RFC] net: Explicitly initialize u64_stats_sync structures for lockdep
From: John Stultz @ 2013-10-23 18:23 UTC (permalink / raw)
To: John Stultz, LKML
Cc: Eric Dumazet, Thomas Petazzoni, Mirko Lindner, Stephen Hemminger,
Roger Luethi, Patrick McHardy, Rusty Russell, Michael S. Tsirkin,
Alexey Kuznetsov, James Morris, Hideaki YOSHIFUJI, Wensong Zhang,
Simon Horman, Julian Anastasov, Jesse Gross, Mathieu Desnoyers,
Steven Rostedt, Peter Zijlstra, Ingo Molnar, Thomas Gleixner,
David S. Miller, netdev, netfilter-devel
In-Reply-To: <1381186321-4906-2-git-send-email-john.stultz@linaro.org>
On 10/07/2013 03:51 PM, John Stultz wrote:
> In order to enable lockdep on seqcount/seqlock structures, we
> must explicitly initialize any locks.
>
> The u64_stats_sync structure, uses a seqcount, and thus we need
> to introduce a u64_stats_init() function and use it to initialize
> the structure.
>
> This unfortunately adds a lot of fairly trivial initialization code
> to a number of drivers. But the benefit of ensuring correctness makes
> this worth while.
>
> Because these changes are required for lockdep to be enabled, and the
> changes are quite trivial, I've not yet split this patch out into 30-some
> separate patches, as I figured it would be better to get the various
> maintainers thoughts on how to best merge this change along with
> the seqcount lockdep enablement.
Just wanted to ping folks on this patch, as I haven't gotten any feedback.
As its a prereq for the seqcount lockdep support, I'd like to get it
queued/merged, but I'm not sure what the right maintainer path or
approach should be.
1) Do folks prefer to see this patch split up into 30-some separate
trivial clenaup patches, or have it go in all as one logical change?
2) Would folks want this patch (in whichever form) to be merged
separately via the networking maintainers, or can it be merged via -tip
as part of the seqcount lockdep series?
thanks
-john
^ permalink raw reply
* Re: Neterion and UFO handling [was: Re: [PATCH] ipv6: udp packets following an UFO enqueued packet need also be handled by UFO]
From: Hannes Frederic Sowa @ 2013-10-23 18:15 UTC (permalink / raw)
To: Jon Mason
Cc: Jiri Pirko, netdev, yoshfuji, David Miller, Alexey Kuznetsov,
jmorris, Patrick McHardy, Herbert Xu, Eric Dumazet
In-Reply-To: <CAPoiz9xnvmQ18D0iGdFVKL8bD-1nC=8zQVD9o1oxfT4Qc942xw@mail.gmail.com>
On Wed, Oct 23, 2013 at 09:35:43AM -0700, Jon Mason wrote:
> On Wed, Oct 16, 2013 at 9:45 PM, Hannes Frederic Sowa
> <hannes@stressinduktion.org> wrote:
> > Hi Jon and Jiri!
> >
> > Just wanted to remind you if you could have a look at this?
> >
> > If you don't have time to test this may I know your assessment of the
> > situation? I could send a compile-time tested patch to disable UFO or if you
> > say so we could leave this as is.
>
> So, bad news. My Xframe 2 adapter (the only variety that does UFO
> offload) won't fit in a standard PCI(32) slot. Since my PCI-X system
> at home is faulty (I'm trying to fix it , but it won't be in the time
> frame you want), there is no way for me to test it on the hardware.
> Terribly sorry.
>
> I am fine with this patch going out, since UFO is off by default.
> I'll handle any issues once they are discovered. Alternatively, we
> could just kill UFO and make everyone's lives easier.
Oh, I missed that UFO is off by default.
If it turns out that UFO is causing broken frames it should be either
killed or (if you have the time for that) fixed. Because there shouldn't
be regressions in stable kernels I am fine with this resolution. Maybe
you can have a look at this problem once your hardware is fixed.
Thank you,
Hannes
^ permalink raw reply
* [PATCH net-next v2 2/2] net: initialize hashrnd in flow_dissector with net_get_random_once
From: Hannes Frederic Sowa @ 2013-10-23 18:06 UTC (permalink / raw)
To: netdev, davem, edumazet
In-Reply-To: <20131023111219.GA31531@order.stressinduktion.org>
We also can defer the initialization of hashrnd in flow_dissector
to its first use. Since net_get_random_once is irq safe now we don't
have to audit the call paths if one of this functions get called by an
interrupt handler.
Cc: David S. Miller <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
v2: Reword the commit message only. It looked horribly.
net/core/flow_dissector.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index f8e25ac..5cac36e 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -184,6 +184,22 @@ ipv6:
EXPORT_SYMBOL(skb_flow_dissect);
static u32 hashrnd __read_mostly;
+static __always_inline void __flow_hash_secret_init(void)
+{
+ net_get_random_once(&hashrnd, sizeof(hashrnd));
+}
+
+static __always_inline u32 __flow_hash_3words(u32 a, u32 b, u32 c)
+{
+ __flow_hash_secret_init();
+ return jhash_3words(a, b, c, hashrnd);
+}
+
+static __always_inline u32 __flow_hash_1word(u32 a)
+{
+ __flow_hash_secret_init();
+ return jhash_1word(a, hashrnd);
+}
/*
* __skb_get_rxhash: calculate a flow hash based on src/dst addresses
@@ -210,9 +226,9 @@ void __skb_get_rxhash(struct sk_buff *skb)
swap(keys.port16[0], keys.port16[1]);
}
- hash = jhash_3words((__force u32)keys.dst,
- (__force u32)keys.src,
- (__force u32)keys.ports, hashrnd);
+ hash = __flow_hash_3words((__force u32)keys.dst,
+ (__force u32)keys.src,
+ (__force u32)keys.ports);
if (!hash)
hash = 1;
@@ -248,7 +264,7 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb,
hash = skb->sk->sk_hash;
else
hash = (__force u16) skb->protocol;
- hash = jhash_1word(hash, hashrnd);
+ hash = __flow_hash_1word(hash);
return (u16) (((u64) hash * qcount) >> 32) + qoffset;
}
@@ -340,7 +356,7 @@ static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
else
hash = (__force u16) skb->protocol ^
skb->rxhash;
- hash = jhash_1word(hash, hashrnd);
+ hash = __flow_hash_1word(hash);
queue_index = map->queues[
((u64)hash * map->len) >> 32];
}
@@ -395,11 +411,3 @@ struct netdev_queue *netdev_pick_tx(struct net_device *dev,
skb_set_queue_mapping(skb, queue_index);
return netdev_get_tx_queue(dev, queue_index);
}
-
-static int __init initialize_hashrnd(void)
-{
- get_random_bytes(&hashrnd, sizeof(hashrnd));
- return 0;
-}
-
-late_initcall_sync(initialize_hashrnd);
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v2 1/2] net: make net_get_random_once irq safe
From: Hannes Frederic Sowa @ 2013-10-23 18:05 UTC (permalink / raw)
To: netdev, davem, edumazet
In-Reply-To: <20131023111200.GB26236@order.stressinduktion.org>
I initial build non irq safe version of net_get_random_once because I
would liked to have the freedom to defer even the extraction process of
get_random_bytes until the nonblocking pool is fully seeded.
I don't think this is a good idea anymore and thus this patch makes
net_get_random_once irq safe. Now someone using net_get_random_once does
not need to care from where it is called.
Cc: David S. Miller <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
v2: Reword the commit message only. It looked horribly.
include/linux/net.h | 1 -
net/core/utils.c | 7 ++++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/linux/net.h b/include/linux/net.h
index aca446b..b292a04 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -250,7 +250,6 @@ bool __net_get_random_once(void *buf, int nbytes, bool *done,
#define ___NET_RANDOM_STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
#endif /* HAVE_JUMP_LABEL */
-/* BE CAREFUL: this function is not interrupt safe */
#define net_get_random_once(buf, nbytes) \
({ \
bool ___ret = false; \
diff --git a/net/core/utils.c b/net/core/utils.c
index bf09371..2f737bf 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -370,16 +370,17 @@ bool __net_get_random_once(void *buf, int nbytes, bool *done,
struct static_key *done_key)
{
static DEFINE_SPINLOCK(lock);
+ unsigned long flags;
- spin_lock_bh(&lock);
+ spin_lock_irqsave(&lock, flags);
if (*done) {
- spin_unlock_bh(&lock);
+ spin_unlock_irqrestore(&lock, flags);
return false;
}
get_random_bytes(buf, nbytes);
*done = true;
- spin_unlock_bh(&lock);
+ spin_unlock_irqrestore(&lock, flags);
__net_random_once_disable_jump(done_key);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH 03/16] batman-adv: add bat_orig_print API function
From: Antonio Quartulli @ 2013-10-23 17:37 UTC (permalink / raw)
To: Joe Perches; +Cc: davem, netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382549233.22433.33.camel@joe-AO722>
[-- Attachment #1: Type: text/plain, Size: 2466 bytes --]
On Wed, Oct 23, 2013 at 10:27:13AM -0700, Joe Perches wrote:
> On Wed, 2013-10-23 at 19:18 +0200, Antonio Quartulli wrote:
> > On Wed, Oct 23, 2013 at 10:00:30AM -0700, Joe Perches wrote:
> > > On Wed, 2013-10-23 at 18:04 +0200, Antonio Quartulli wrote:
> > > > Each routing protocol has its own metric and private
> > > > variables, therefore it is useful to introduce a new API
> > > > for originator information printing.
> > > >
> > > > This API needs to be implemented by each protocol in order
> > > > to provide its specific originator table output.
> > > []
> > > > +static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
> > > > + struct seq_file *seq)
> > > []
> > > > + seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
> > > > + "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE,
> > > > + "Nexthop", "outgoingIF", "Potential nexthops");
> > >
> > > This header printf really doesn't add much with the formatting sizes.
> > > It's pretty obscure why some of these are sized and others not sized.
> > > For instance: %-15s doesn't refer to a mac address size.
> > > Perhaps it'd be better to just emit the fixed string just using
> > > BATADV_TO_MAX_VALUE. It'd also be easier to find via grep.
> >
> > This string is printed out of a debugfs file and follows a format that we have
> > been using for long time (this patch is just moving this code from one point to
> > another).
>
> I saw.
>
> > I didn't get what you mean with BATADV_TO_MAX_VALUE (maybe you meant
> > BATADV_TQ_MAX_VALUE? but even in this case I don't get it).
>
> Yeah, TQ not TO. Both look similar with squiggles
> underneath them when using spell checking.
>
> It's a #define, all the others are fixed strings.
>
> Anyway, using
> seq_printf(seq, " Originator last-seen (#/%d) Nexthop [outgoingIF]: Potential nexthops ...\n",
> BATADV_TQ_MAX_VALUE);
> is probably trivially smaller overall code size too.
>
> Your code, you decide...
Now I fully understand your point.
Honestly I agree with you, but this string is there since a while and I'd
like to get a feedback from the other guys before changing it.
If for David it is not a problem I'd like keep it like that and I'll discuss and
possibly add this change (this is not the only header in the code printed this
way) later.
Thanks a lot for your feedback!
Cheers,
--
Antonio Quartulli
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 03/16] batman-adv: add bat_orig_print API function
From: Joe Perches @ 2013-10-23 17:27 UTC (permalink / raw)
To: Antonio Quartulli
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner,
davem-fT/PcQaiUtIeIZ0/mPfg9Q, Antonio Quartulli
In-Reply-To: <20131023171810.GB2651-rVWd3aGhH2zPj3vggD0kEA@public.gmane.org>
On Wed, 2013-10-23 at 19:18 +0200, Antonio Quartulli wrote:
> On Wed, Oct 23, 2013 at 10:00:30AM -0700, Joe Perches wrote:
> > On Wed, 2013-10-23 at 18:04 +0200, Antonio Quartulli wrote:
> > > Each routing protocol has its own metric and private
> > > variables, therefore it is useful to introduce a new API
> > > for originator information printing.
> > >
> > > This API needs to be implemented by each protocol in order
> > > to provide its specific originator table output.
> > []
> > > +static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
> > > + struct seq_file *seq)
> > []
> > > + seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
> > > + "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE,
> > > + "Nexthop", "outgoingIF", "Potential nexthops");
> >
> > This header printf really doesn't add much with the formatting sizes.
> > It's pretty obscure why some of these are sized and others not sized.
> > For instance: %-15s doesn't refer to a mac address size.
> > Perhaps it'd be better to just emit the fixed string just using
> > BATADV_TO_MAX_VALUE. It'd also be easier to find via grep.
>
> This string is printed out of a debugfs file and follows a format that we have
> been using for long time (this patch is just moving this code from one point to
> another).
I saw.
> I didn't get what you mean with BATADV_TO_MAX_VALUE (maybe you meant
> BATADV_TQ_MAX_VALUE? but even in this case I don't get it).
Yeah, TQ not TO. Both look similar with squiggles
underneath them when using spell checking.
It's a #define, all the others are fixed strings.
Anyway, using
seq_printf(seq, " Originator last-seen (#/%d) Nexthop [outgoingIF]: Potential nexthops ...\n",
BATADV_TQ_MAX_VALUE);
is probably trivially smaller overall code size too.
Your code, you decide...
cheers, Joe
^ permalink raw reply
* Re: [PATCH 03/16] batman-adv: add bat_orig_print API function
From: Antonio Quartulli @ 2013-10-23 17:18 UTC (permalink / raw)
To: Joe Perches; +Cc: davem, netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382547630.22433.23.camel@joe-AO722>
[-- Attachment #1: Type: text/plain, Size: 2648 bytes --]
On Wed, Oct 23, 2013 at 10:00:30AM -0700, Joe Perches wrote:
> On Wed, 2013-10-23 at 18:04 +0200, Antonio Quartulli wrote:
> > Each routing protocol has its own metric and private
> > variables, therefore it is useful to introduce a new API
> > for originator information printing.
> >
> > This API needs to be implemented by each protocol in order
> > to provide its specific originator table output.
> []
> > +static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
> > + struct seq_file *seq)
> []
> > + seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
> > + "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE,
> > + "Nexthop", "outgoingIF", "Potential nexthops");
>
> This header printf really doesn't add much with the formatting sizes.
> It's pretty obscure why some of these are sized and others not sized.
> For instance: %-15s doesn't refer to a mac address size.
> Perhaps it'd be better to just emit the fixed string just using
> BATADV_TO_MAX_VALUE. It'd also be easier to find via grep.
This string is printed out of a debugfs file and follows a format that we have
been using for long time (this patch is just moving this code from one point to
another).
I didn't get what you mean with BATADV_TO_MAX_VALUE (maybe you meant
BATADV_TQ_MAX_VALUE? but even in this case I don't get it).
The sized parameters in the format string are such that this header is correctly
aligned with the entries of the table that follow.
Moreover we tried to keep this table human readable as much as possible.
Here you have an example of what we get (this output is not printed with exactly
that format string because it belongs to an older batman-adv version)
[B.A.T.M.A.N. adv 2013.3.0, MainIF/MAC: mesh0/xx:xx:xx:xx:xx:xx (bat0)]
Originator last-seen (#/255) Nexthop [outgoingIF]: Potential nexthops ...
yyyy 4.720s (247) yyyy [ mesh0]: aaaaa (221) bbbbbb (200)
aaaaa 4.270s (237) ddddd [ mesh0]: aaaa (195) vvvvvv (215)
bbbbbb 4.480s (248) cccccc [ mesh0]: bbbb (213) cccccc (200)
ccccc 0.480s (255) bbbbb [ mesh0]: cccc (217) dddddd (190)
dddddd 1.050s (223) dddddd [ mesh0]: dddddd (191) eeee (203)
If the width of your terminal is adequate you get a nice table which is rather
helpful for debugging purposes.
Regards,
--
Antonio Quartulli
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 3/3] netfilter: x_tables: fix ordering of jumpstack allocation and table update
From: Eric Dumazet @ 2013-10-23 17:04 UTC (permalink / raw)
To: Will Deacon
Cc: David Laight, Pablo Neira Ayuso, netfilter-devel@vger.kernel.org,
davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <20131023163706.GA5117@mudshark.cambridge.arm.com>
On Wed, 2013-10-23 at 17:37 +0100, Will Deacon wrote:
> What I'm *not* 100% sure about is the table freeing path. There is a mutex
> there for removing the table from a list, but I'm not sure how we ensure
> that there are no parallel readers at that point.
Sequence is :
xt_replace_table();
get_counters();
xt_free_table_info();
get_counters() is the way we ensure no cpu is using old copy of the
table before freeing.
^ permalink raw reply
* Fwd: Re: Big performance loss from 3.4.63 to 3.10.13 when routing ipv4
From: Wolfgang Walter @ 2013-10-23 17:01 UTC (permalink / raw)
To: netdev; +Cc: David Miller, hannes, klassert
Am Mittwoch, 23. Oktober 2013, 09:17:30 schrieben Sie:
> On Wed, 2013-10-23 at 17:57 +0200, Wolfgang Walter wrote:
> > Am Mittwoch, 23. Oktober 2013, 05:00:01 schrieb Eric Dumazet:
> > > On Wed, 2013-10-23 at 13:33 +0200, Wolfgang Walter wrote:
> > > > I don't know what this value actually means. But on 3.4.x it is much
> > > > higher. On a machine with 512MB ram it is 32768, on a machine with 1GB
> > > > ram it is 262144 and with 16GB ram it is 4194304.
> > >
> > > Such huge values should not be needed. We should have at most one dst
> > > per packet in flight.
> > >
> > > On a loaded router, a NIC not using BQL could queue around 16,000
> > > packets.
> > >
> > > Of course, Qdisc layers could also store a lot of packets, but using the
> > > default pfifo_fast is only adding 1000 packets per interface.
> > >
> > > I guess using 65536 as the default value should be safe and reasonable
> > >
> > > Have you tried using 32768 or 65536 ?
> >
> > I use 32768 on routers with 512MB. They usually have around 50
> > ipsec-tunnels and only about 10 interfaces including vlan-interfaces.
> >
> > On larger ones I set the bigger values from 3.4.x. That one with 16GB has
> > about 2000 ipsec-tunnels. It has about 80 interfaces (inlcuding vlan-
> > interfaces). Physically it has 8 interfaces with together about 30
> > hardware- queues.
>
> offlist
>
> OK, but you do not have the idea of actual number of entries ?
>
> If you use SLAB, you probably can try "grep dst /proc/slabinfo"
Ah, ok. I use SLUB, but SLABINFO=y.
Without much traffic it is:
# grep dst /proc/slabinfo
xfrm_dst_cache 4435 4608 448 36 4 : tunables 0 0 0 :
slabdata 128 128 0
on the big one.
I can recompile the kernels with SLAB instead of SLUB if SLAB gives more
usefull infos.
Regards,
--
Wolfgang Walter
Studentenwerk München
Anstalt des öffentlichen Rechts
^ permalink raw reply
* Re: [PATCH 03/16] batman-adv: add bat_orig_print API function
From: Joe Perches @ 2013-10-23 17:00 UTC (permalink / raw)
To: Antonio Quartulli
Cc: davem, netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382544303-2694-4-git-send-email-antonio@meshcoding.com>
On Wed, 2013-10-23 at 18:04 +0200, Antonio Quartulli wrote:
> Each routing protocol has its own metric and private
> variables, therefore it is useful to introduce a new API
> for originator information printing.
>
> This API needs to be implemented by each protocol in order
> to provide its specific originator table output.
[]
> +static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
> + struct seq_file *seq)
[]
> + seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
> + "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE,
> + "Nexthop", "outgoingIF", "Potential nexthops");
This header printf really doesn't add much with the formatting sizes.
It's pretty obscure why some of these are sized and others not sized.
For instance: %-15s doesn't refer to a mac address size.
Perhaps it'd be better to just emit the fixed string just using
BATADV_TO_MAX_VALUE. It'd also be easier to find via grep.
^ permalink raw reply
* Re: [PATCH v5] net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)
From: Joe Perches @ 2013-10-23 16:52 UTC (permalink / raw)
To: Arvid Brodin
Cc: netdev@vger.kernel.org, David Miller, Stephen Hemminger,
Javier Boticario, balferreira@googlemail.com,
Elías Molina Muñoz
In-Reply-To: <5267F4BD.70409@xdin.com>
On Wed, 2013-10-23 at 18:09 +0200, Arvid Brodin wrote:
> High-availability Seamless Redundancy ("HSR") provides instant failover
> redundancy for Ethernet networks. It requires a special network topology where
> all nodes are connected in a ring (each node having two physical network
> interfaces). It is suited for applications that demand high availability and
> very short reaction time.
trivia: (can be ignored/fixed later)
> +static void restore_slaves(struct net_device *hsr_dev)
> +{
> + struct hsr_priv *hsr_priv;
> + int i;
> + int res;
> +
> + hsr_priv = netdev_priv(hsr_dev);
> +
> + rtnl_lock();
> +
> + /* Restore promiscuity */
> + for (i = 0; i < 2; i++) {
I presume all of these for slave loops that use
for (i = 0; i < 2; i++) should be i < HSR_MAX_SLAVE
Maybe it'd be useful to add a foreach_slave() helper.
> +static struct node_entry *find_node_by_AddrA(struct list_head *node_db,
> + const unsigned char addr[ETH_ALEN])
> +{
> + struct node_entry *node;
> +
> + list_for_each_entry_rcu(node, node_db, mac_list) {
> + if (!compare_ether_addr(node->MacAddressA, addr))
Please use ether_addr_equal instead for all these uses.
compare_ether_addr should be removed one day.
> +static struct node_entry *find_node_by_AddrB(struct list_head *node_db,
> + const unsigned char addr[ETH_ALEN])
[]
> + if (!compare_ether_addr(node->MacAddressB, addr))
[]
> +struct node_entry *hsr_find_node(struct list_head *node_db, struct sk_buff *skb)
[]
> + if (!compare_ether_addr(node->MacAddressA, ethhdr->h_source))
> + return node;
> + if (!compare_ether_addr(node->MacAddressB, ethhdr->h_source))
> + return node;
> +struct node_entry *hsr_merge_node(struct hsr_priv *hsr_priv,
> + struct node_entry *node,
> + struct sk_buff *skb,
> + enum hsr_dev_idx dev_idx)
[]
> + if (node && compare_ether_addr(node->MacAddressA, hsr_sp->MacAddressA)) {
[]
> + if (node && (dev_idx == node->AddrB_if) &&
> + compare_ether_addr(node->MacAddressB, hsr_ethsup->ethhdr.h_source)) {
[]
> + if (node && (dev_idx != node->AddrB_if) &&
> + (node->AddrB_if != HSR_DEV_NONE) &&
> + compare_ether_addr(node->MacAddressA, hsr_ethsup->ethhdr.h_source)) {
[]
> + if (compare_ether_addr(hsr_sp->MacAddressA, hsr_ethsup->ethhdr.h_source))
[]
> +/* above(a, b) - return 1 if a > b, 0 otherwise.
> + */
> +static bool above(u16 a, u16 b)
> +{
> + /* Remove inconsistency where above(a, b) == below(a, b) */
> + if ((int) b - a == 32768)
> + return 0;
> +
> + return (((s16) (b - a)) < 0);
> +}
> +#define below(a, b) above((b), (a))
> +#define above_or_eq(a, b) (!below((a), (b)))
> +#define below_or_eq(a, b) (!above((a), (b)))
This looks odd. Perhaps
static bool above(u16 a, u16 b)
{
return a > b;
}
#define below(a, b) above(b, a)
static bool above_or_eq(u16 a, u16 b)
{
return a >= b;
}
#define below_or_eq(a, b) above_or_eq(b, a)
^ permalink raw reply
* Re: [PATCH 3/3] netfilter: x_tables: fix ordering of jumpstack allocation and table update
From: Will Deacon @ 2013-10-23 16:37 UTC (permalink / raw)
To: David Laight
Cc: Pablo Neira Ayuso, netfilter-devel@vger.kernel.org,
davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B73A2@saturn3.aculab.com>
Hi David,
On Wed, Oct 23, 2013 at 10:45:04AM +0100, David Laight wrote:
> > Subject: [PATCH 3/3] netfilter: x_tables: fix ordering of jumpstack allocation and table update
> ...
> > Meanwhile, CPU0 is handling the network receive path and ends up in
> > ipt_do_table, resulting in:
> >
> > private = table->private;
> >
> > [...]
> >
> > jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
> >
> > On weakly ordered memory architectures, the writes to table->private
> > and newinfo->jumpstack from CPU1 can be observed out of order by CPU0.
> > Furthermore, on architectures which don't respect ordering of address
> > dependencies (i.e. Alpha), the reads from CPU0 can also be re-ordered.
>
> Which reads might be out of order?
> AFAICT they are strongly sequenced because they second depends on the
> value read by the first.
> So I don't see why the read barrier is needed.
That is why this is a dependent read barrier. Some architectures (e.g.
Alpha) *do* allow dependent reads to be observed out of order, so you can
effectively load the data pointed to by a pointer before you load the
pointer itself!
Take a look at Paul's paper about memory ordering if you're curious:
http://www.rdrop.com/users/paulmck/scalability/paper/whymb.2009.04.05a.pdf
> > - table->private = newinfo;
> > newinfo->initial_entries = private->initial_entries;
> > + /*
> > + * Ensure contents of newinfo are visible before assigning to
> > + * private.
> > + */
> > + smp_wmb();
> > + table->private = newinfo;
>
> Those writes were in the wrong order on all systems.
> Also gcc needs to be told not to reorder the writes even on non-smp
> systems (if the code might be pre-empted).
> So an asm volatile (:::"memory") is needed there even if no specific
> synchronisation instruction is needed.
The smp_* barriers expand to barrier() when !CONFIG_SMP, which gives you the
memory clobber you want.
What I'm *not* 100% sure about is the table freeing path. There is a mutex
there for removing the table from a list, but I'm not sure how we ensure
that there are no parallel readers at that point.
Will
^ permalink raw reply
* Re: Neterion and UFO handling [was: Re: [PATCH] ipv6: udp packets following an UFO enqueued packet need also be handled by UFO]
From: Jon Mason @ 2013-10-23 16:35 UTC (permalink / raw)
To: Jon Mason, Jiri Pirko, netdev, yoshfuji, David Miller,
Alexey Kuznetsov, jmorris, Patrick McHardy, Herbert Xu,
Eric Dumazet
In-Reply-To: <20131017044551.GE18135@order.stressinduktion.org>
On Wed, Oct 16, 2013 at 9:45 PM, Hannes Frederic Sowa
<hannes@stressinduktion.org> wrote:
> Hi Jon and Jiri!
>
> Just wanted to remind you if you could have a look at this?
>
> If you don't have time to test this may I know your assessment of the
> situation? I could send a compile-time tested patch to disable UFO or if you
> say so we could leave this as is.
So, bad news. My Xframe 2 adapter (the only variety that does UFO
offload) won't fit in a standard PCI(32) slot. Since my PCI-X system
at home is faulty (I'm trying to fix it , but it won't be in the time
frame you want), there is no way for me to test it on the hardware.
Terribly sorry.
I am fine with this patch going out, since UFO is off by default.
I'll handle any issues once they are discovered. Alternatively, we
could just kill UFO and make everyone's lives easier.
Thanks,
Jon
> Jiri, I would suggest you resend your patches then.
>
> Thanks,
>
> Hannes
>
> [top-posted by intention]
>
> On Tue, Oct 08, 2013 at 04:53:31PM +0200, Hannes Frederic Sowa wrote:
>> On Tue, Oct 08, 2013 at 01:07:29AM -0700, Jon Mason wrote:
>> > On Wed, Oct 2, 2013 at 9:27 AM, Hannes Frederic Sowa
>> > <hannes@stressinduktion.org> wrote:
>> > > Hi!
>> > >
>> > > I have a question regarding UFO and the neterion driver, which as the only one
>> > > advertises hardware UFO support:
>> > >
>> > > The patch discusses in this thread
>> > > http://thread.gmane.org/gmane.linux.network/284348/focus=285405 could change
>> > > some semantics how packets are constructed before submitted to the driver.
>> > >
>> > > We currently guarantee that we have the MAC/IP/UDP header in skb->data and the
>> > > payload is attached in the skb's frags. With the changes discussed in this
>> > > thread it is possible that we also append to skb->data some amount of data
>> > > which is not targeted for the header. From reading the driver sources it seems
>> > > the hardware interprets the skb->data to skb_headlen as the header, so we
>> > > could include some data in the fragments more than once.
>> >
>> > From my reading of the HW Spec and a quick look at the driver, it
>> > appears that the driver is using one entry in the TX ring for the
>> > header and another for the body of the packet to be fragmented (which
>> > is what the hardware wants). I don't understand what you are saying,
>> > but if you are asking if simply appending a new header & data to the
>> > end of skb->data will get it out on the wire correct, I don't believe
>> > it will.
>>
>> No this is not what I tried to say. I'll try to be more clear this
>> time. ;)
>>
>> We start with an UDP socket which is corked. As soon as we write the
>> first few bytes (smaller than the mtu) onto this socket we put the
>> header in place and the rest of the data is just appended behind the
>> header directly in skb->data via plain ip_append_data.
>>
>> Now a second write with a length > mtu happens: The ip(6)_append_data
>> will branch to ufo_append. This will fetch the first skb and append
>> to skb->frags. gso_type and gso_size will be updated on this skb (this
>> currently does not happen but will with the patches discussed in this
>> thread).
>>
>> If this packet is transmitted down to the device driver we have the udp
>> header in skb->data *and* also the payload from the first write. The
>> payload from the second write is appended as a frag and gso_type and
>> gso_size are set. This header+payload seem to be mapped just after the
>> ufo_in_band_v descriptor as the header in the first tx descriptor:
>>
>> 4174 txdp->Buffer_Pointer = pci_map_single(sp->pdev, skb->data,
>> 4175 frg_len, PCI_DMA_TODEVICE);
>>
>> frg_len is set to skb_headlen(skb). This happens right after setting up
>> the descriptor for the in-band ufo data.
>>
>> My guess is that this data isn't split currently by the neterion driver
>> (at least I could not find it in the driver as Eric showed it for bnx2x)
>> so it might reappear in the packets when the hardware fragments the
>> packet and places the first tx ring in front of every packet.
>>
>> Before these changes we never updated the gso_type and gso_size even when
>> we did append via UFO. So we never had payload in an UFO marked skb->data,
>> only the headers. Now we could also end up with a some payload in the
>> first TX ring, which you said is only for the header.
>>
>> > I do have hardware that I can try the patch on, if you can walk me
>> > through the use case (unless it is as easy as setup an IPv6 connection
>> > and ping).
>>
>> Ok, testing this should not be that complicated:
>>
>> We can test this with plain IPv4/UDP sockets. I would suggest a net-next kernel
>> with this patch from Jiri applied: http://patchwork.ozlabs.org/patch/279691/
>>
>> --- >8 ---
>> #include <sys/types.h>
>> #include <sys/socket.h>
>> #include <netinet/in.h>
>> #include <arpa/inet.h>
>> #include <linux/udp.h>
>> #include <stdio.h>
>>
>> int test(int mtu)
>> {
>> int fd;
>> const int one = 1;
>> const int off = 0;
>> struct sockaddr_in addr = {.sin_family = AF_INET, .sin_port = htons(53) };
>> unsigned char buffer[3701];
>>
>> inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
>>
>> fd = socket(AF_INET, SOCK_DGRAM, 0);
>> connect(fd, (struct sockaddr *) &addr, sizeof(addr));
>>
>> setsockopt(fd, IPPROTO_UDP, UDP_CORK, &one, sizeof(one));
>>
>> write(fd, " ", 4);
>> write(fd, buffer, sizeof(buffer));
>> write(fd, " ", 1);
>>
>> setsockopt(fd, IPPROTO_UDP, UDP_CORK, &off, sizeof(off));
>>
>> close(fd);
>> }
>>
>> int main() {
>> test(1280);
>> }
>> --- >8 ---
>>
>> I left out error handling so it is better observed with strace if
>> something went wrong.
>>
>> You should change the port number and ip address to something reasonable
>> for your network. My guess would be that the spaces (0x20) of the first
>> write is now placed between UDP header and payload of every packet
>> fragmented by the hardware. Would be nice to hear that I am wrong. ;)
>>
>> Be aware that the above program can cause memory corruption in the kernel
>> if you did not apply Jiri's patch.
>>
>> Thanks for helping!
>>
>> Hannes
>>
>> --
>> 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
>>
>
> --
> gruss,
>
> Hannes
>
^ permalink raw reply
* [PATCH 16/16] batman-adv: generalize batman-adv icmp packet handling
From: Antonio Quartulli @ 2013-10-23 16:05 UTC (permalink / raw)
To: davem
Cc: netdev, b.a.t.m.a.n, Simon Wunderlich, Marek Lindner,
Antonio Quartulli
In-Reply-To: <1382544303-2694-1-git-send-email-antonio@meshcoding.com>
From: Simon Wunderlich <sw@simonwunderlich.de>
Instead of handling icmp packets only up to length of icmp_packet_rr,
the code should handle any icmp length size. Therefore the length
truncating is moved to when the packet is actually sent to userspace
(this does not support lengths longer than icmp_packet_rr yet). Longer
packets are forwarded without truncating.
This patch also cleans up some parts where the icmp header struct could
be used instead of other icmp_packet(_rr) structs to make the code more
readable.
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
net/batman-adv/icmp_socket.c | 128 +++++++++++++++++++++++++++----------------
net/batman-adv/icmp_socket.h | 2 +-
net/batman-adv/packet.h | 2 +
net/batman-adv/routing.c | 120 ++++++++++++++++++++++++----------------
net/batman-adv/types.h | 2 +-
5 files changed, 157 insertions(+), 97 deletions(-)
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 82ac647..29ae4ef 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -29,7 +29,7 @@
static struct batadv_socket_client *batadv_socket_client_hash[256];
static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
- struct batadv_icmp_packet_rr *icmp_packet,
+ struct batadv_icmp_header *icmph,
size_t icmp_len);
void batadv_socket_init(void)
@@ -155,13 +155,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
struct batadv_priv *bat_priv = socket_client->bat_priv;
struct batadv_hard_iface *primary_if = NULL;
struct sk_buff *skb;
- struct batadv_icmp_packet_rr *icmp_packet;
-
+ struct batadv_icmp_packet_rr *icmp_packet_rr;
+ struct batadv_icmp_header *icmp_header;
struct batadv_orig_node *orig_node = NULL;
struct batadv_neigh_node *neigh_node = NULL;
size_t packet_len = sizeof(struct batadv_icmp_packet);
- if (len < sizeof(struct batadv_icmp_packet)) {
+ if (len < sizeof(struct batadv_icmp_header)) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Error - can't send packet from char device: invalid packet size\n");
return -EINVAL;
@@ -174,8 +174,10 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
goto out;
}
- if (len >= sizeof(struct batadv_icmp_packet_rr))
- packet_len = sizeof(struct batadv_icmp_packet_rr);
+ if (len >= BATADV_ICMP_MAX_PACKET_SIZE)
+ packet_len = BATADV_ICMP_MAX_PACKET_SIZE;
+ else
+ packet_len = len;
skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN);
if (!skb) {
@@ -185,67 +187,78 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, ETH_HLEN);
- icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
+ icmp_header = (struct batadv_icmp_header *)skb_put(skb, packet_len);
- if (copy_from_user(icmp_packet, buff, packet_len)) {
+ if (copy_from_user(icmp_header, buff, packet_len)) {
len = -EFAULT;
goto free_skb;
}
- if (icmp_packet->icmph.header.packet_type != BATADV_ICMP) {
+ if (icmp_header->header.packet_type != BATADV_ICMP) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
len = -EINVAL;
goto free_skb;
}
- if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
+ switch (icmp_header->msg_type) {
+ case BATADV_ECHO_REQUEST:
+ if (len < sizeof(struct batadv_icmp_packet)) {
+ batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+ "Error - can't send packet from char device: invalid packet size\n");
+ len = -EINVAL;
+ goto free_skb;
+ }
+
+ if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
+ goto dst_unreach;
+
+ orig_node = batadv_orig_hash_find(bat_priv, icmp_header->dst);
+ if (!orig_node)
+ goto dst_unreach;
+
+ neigh_node = batadv_orig_node_get_router(orig_node);
+ if (!neigh_node)
+ goto dst_unreach;
+
+ if (!neigh_node->if_incoming)
+ goto dst_unreach;
+
+ if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
+ goto dst_unreach;
+
+ icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmp_header;
+ if (packet_len == sizeof(*icmp_packet_rr))
+ memcpy(icmp_packet_rr->rr,
+ neigh_node->if_incoming->net_dev->dev_addr,
+ ETH_ALEN);
+
+ break;
+ default:
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
+ "Error - can't send packet from char device: got unknown message type\n");
len = -EINVAL;
goto free_skb;
}
- icmp_packet->icmph.uid = socket_client->index;
+ icmp_header->uid = socket_client->index;
- if (icmp_packet->icmph.header.version != BATADV_COMPAT_VERSION) {
- icmp_packet->icmph.msg_type = BATADV_PARAMETER_PROBLEM;
- icmp_packet->icmph.header.version = BATADV_COMPAT_VERSION;
- batadv_socket_add_packet(socket_client, icmp_packet,
+ if (icmp_header->header.version != BATADV_COMPAT_VERSION) {
+ icmp_header->msg_type = BATADV_PARAMETER_PROBLEM;
+ icmp_header->header.version = BATADV_COMPAT_VERSION;
+ batadv_socket_add_packet(socket_client, icmp_header,
packet_len);
goto free_skb;
}
- if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
- goto dst_unreach;
-
- orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
- if (!orig_node)
- goto dst_unreach;
-
- neigh_node = batadv_orig_node_get_router(orig_node);
- if (!neigh_node)
- goto dst_unreach;
-
- if (!neigh_node->if_incoming)
- goto dst_unreach;
-
- if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
- goto dst_unreach;
-
- memcpy(icmp_packet->icmph.orig,
- primary_if->net_dev->dev_addr, ETH_ALEN);
-
- if (packet_len == sizeof(struct batadv_icmp_packet_rr))
- memcpy(icmp_packet->rr,
- neigh_node->if_incoming->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_header->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
goto out;
dst_unreach:
- icmp_packet->icmph.msg_type = BATADV_DESTINATION_UNREACHABLE;
- batadv_socket_add_packet(socket_client, icmp_packet, packet_len);
+ icmp_header->msg_type = BATADV_DESTINATION_UNREACHABLE;
+ batadv_socket_add_packet(socket_client, icmp_header, packet_len);
free_skb:
kfree_skb(skb);
out:
@@ -298,27 +311,40 @@ err:
return -ENOMEM;
}
+/**
+ * batadv_socket_receive_packet - schedule an icmp packet to be sent to userspace
+ * on an icmp socket.
+ * @socket_client: the socket this packet belongs to
+ * @icmph: pointer to the header of the icmp packet
+ * @icmp_len: total length of the icmp packet
+ */
static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
- struct batadv_icmp_packet_rr *icmp_packet,
+ struct batadv_icmp_header *icmph,
size_t icmp_len)
{
struct batadv_socket_packet *socket_packet;
+ size_t len;
socket_packet = kmalloc(sizeof(*socket_packet), GFP_ATOMIC);
if (!socket_packet)
return;
+ len = icmp_len;
+ /* check the maximum length before filling the buffer */
+ if (len > sizeof(socket_packet->icmp_packet))
+ len = sizeof(socket_packet->icmp_packet);
+
INIT_LIST_HEAD(&socket_packet->list);
- memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len);
- socket_packet->icmp_len = icmp_len;
+ memcpy(&socket_packet->icmp_packet, icmph, len);
+ socket_packet->icmp_len = len;
spin_lock_bh(&socket_client->lock);
/* while waiting for the lock the socket_client could have been
* deleted
*/
- if (!batadv_socket_client_hash[icmp_packet->icmph.uid]) {
+ if (!batadv_socket_client_hash[icmph->uid]) {
spin_unlock_bh(&socket_client->lock);
kfree(socket_packet);
return;
@@ -342,12 +368,18 @@ static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
wake_up(&socket_client->queue_wait);
}
-void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet,
+/**
+ * batadv_socket_receive_packet - schedule an icmp packet to be received
+ * locally and sent to userspace.
+ * @icmph: pointer to the header of the icmp packet
+ * @icmp_len: total length of the icmp packet
+ */
+void batadv_socket_receive_packet(struct batadv_icmp_header *icmph,
size_t icmp_len)
{
struct batadv_socket_client *hash;
- hash = batadv_socket_client_hash[icmp_packet->icmph.uid];
+ hash = batadv_socket_client_hash[icmph->uid];
if (hash)
- batadv_socket_add_packet(hash, icmp_packet, icmp_len);
+ batadv_socket_add_packet(hash, icmph, icmp_len);
}
diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h
index 1fcca37..6665080 100644
--- a/net/batman-adv/icmp_socket.h
+++ b/net/batman-adv/icmp_socket.h
@@ -24,7 +24,7 @@
void batadv_socket_init(void);
int batadv_socket_setup(struct batadv_priv *bat_priv);
-void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet,
+void batadv_socket_receive_packet(struct batadv_icmp_header *icmph,
size_t icmp_len);
#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 843b96a..207459b 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -239,6 +239,8 @@ struct batadv_icmp_packet_rr {
uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
};
+#define BATADV_ICMP_MAX_PACKET_SIZE sizeof(struct batadv_icmp_packet_rr)
+
/* All packet headers in front of an ethernet header have to be completely
* divisible by 2 but not by 4 to make the payload after the ethernet
* header again 4 bytes boundary aligned.
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 71fba14..d4114d7 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -260,47 +260,65 @@ bool batadv_check_management_packet(struct sk_buff *skb,
return true;
}
+/**
+ * batadv_recv_my_icmp_packet - receive an icmp packet locally
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: icmp packet to process
+ *
+ * Returns NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP
+ * otherwise.
+ */
static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
- struct sk_buff *skb, size_t icmp_len)
+ struct sk_buff *skb)
{
struct batadv_hard_iface *primary_if = NULL;
struct batadv_orig_node *orig_node = NULL;
- struct batadv_icmp_packet_rr *icmp_packet;
- int ret = NET_RX_DROP;
+ struct batadv_icmp_header *icmph;
+ int res, ret = NET_RX_DROP;
- icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
+ icmph = (struct batadv_icmp_header *)skb->data;
- /* add data to device queue */
- if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
- batadv_socket_receive_packet(icmp_packet, icmp_len);
- goto out;
- }
+ switch (icmph->msg_type) {
+ case BATADV_ECHO_REPLY:
+ case BATADV_DESTINATION_UNREACHABLE:
+ case BATADV_TTL_EXCEEDED:
+ /* receive the packet */
+ if (skb_linearize(skb) < 0)
+ break;
- primary_if = batadv_primary_if_get_selected(bat_priv);
- if (!primary_if)
- goto out;
+ batadv_socket_receive_packet(icmph, skb->len);
+ break;
+ case BATADV_ECHO_REQUEST:
+ /* answer echo request (ping) */
+ primary_if = batadv_primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
- /* answer echo request (ping) */
- /* get routing information */
- orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig);
- if (!orig_node)
- goto out;
+ /* get routing information */
+ orig_node = batadv_orig_hash_find(bat_priv, icmph->orig);
+ if (!orig_node)
+ goto out;
- /* create a copy of the skb, if needed, to modify it. */
- if (skb_cow(skb, ETH_HLEN) < 0)
- goto out;
+ /* create a copy of the skb, if needed, to modify it. */
+ if (skb_cow(skb, ETH_HLEN) < 0)
+ goto out;
- icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
+ icmph = (struct batadv_icmp_header *)skb->data;
- memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN);
- memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr,
- ETH_ALEN);
- icmp_packet->icmph.msg_type = BATADV_ECHO_REPLY;
- icmp_packet->icmph.header.ttl = BATADV_TTL;
+ memcpy(icmph->dst, icmph->orig, ETH_ALEN);
+ memcpy(icmph->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
+ icmph->msg_type = BATADV_ECHO_REPLY;
+ icmph->header.ttl = BATADV_TTL;
- if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
- ret = NET_RX_SUCCESS;
+ res = batadv_send_skb_to_orig(skb, orig_node, NULL);
+ if (res != NET_XMIT_DROP)
+ ret = NET_RX_SUCCESS;
+ break;
+ default:
+ /* drop unknown type */
+ goto out;
+ }
out:
if (primary_if)
batadv_hardif_free_ref(primary_if);
@@ -363,16 +381,13 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if)
{
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
- struct batadv_icmp_packet_rr *icmp_packet;
+ struct batadv_icmp_header *icmph;
+ struct batadv_icmp_packet_rr *icmp_packet_rr;
struct ethhdr *ethhdr;
struct batadv_orig_node *orig_node = NULL;
- int hdr_size = sizeof(struct batadv_icmp_packet);
+ int hdr_size = sizeof(struct batadv_icmp_header);
int ret = NET_RX_DROP;
- /* we truncate all incoming icmp packets if they don't match our size */
- if (skb->len >= sizeof(struct batadv_icmp_packet_rr))
- hdr_size = sizeof(struct batadv_icmp_packet_rr);
-
/* drop packet if it has not necessary minimum size */
if (unlikely(!pskb_may_pull(skb, hdr_size)))
goto out;
@@ -391,28 +406,39 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
goto out;
- icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
+ icmph = (struct batadv_icmp_header *)skb->data;
/* add record route information if not full */
- if ((icmp_packet->icmph.msg_type == BATADV_ECHO_REPLY ||
- icmp_packet->icmph.msg_type == BATADV_ECHO_REQUEST) &&
- (hdr_size == sizeof(struct batadv_icmp_packet_rr)) &&
- (icmp_packet->rr_cur < BATADV_RR_LEN)) {
- memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
+ if ((icmph->msg_type == BATADV_ECHO_REPLY ||
+ icmph->msg_type == BATADV_ECHO_REQUEST) &&
+ (skb->len >= sizeof(struct batadv_icmp_packet_rr))) {
+ if (skb_linearize(skb) < 0)
+ goto out;
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (skb_cow(skb, ETH_HLEN) < 0)
+ goto out;
+
+ icmph = (struct batadv_icmp_header *)skb->data;
+ icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph;
+ if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN)
+ goto out;
+
+ memcpy(&(icmp_packet_rr->rr[icmp_packet_rr->rr_cur]),
ethhdr->h_dest, ETH_ALEN);
- icmp_packet->rr_cur++;
+ icmp_packet_rr->rr_cur++;
}
/* packet for me */
- if (batadv_is_my_mac(bat_priv, icmp_packet->icmph.dst))
- return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size);
+ if (batadv_is_my_mac(bat_priv, icmph->dst))
+ return batadv_recv_my_icmp_packet(bat_priv, skb);
/* TTL exceeded */
- if (icmp_packet->icmph.header.ttl < 2)
+ if (icmph->header.ttl < 2)
return batadv_recv_icmp_ttl_exceeded(bat_priv, skb);
/* get routing information */
- orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
+ orig_node = batadv_orig_hash_find(bat_priv, icmph->dst);
if (!orig_node)
goto out;
@@ -420,10 +446,10 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
if (skb_cow(skb, ETH_HLEN) < 0)
goto out;
- icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
+ icmph = (struct batadv_icmp_header *)skb->data;
/* decrement ttl */
- icmp_packet->icmph.header.ttl--;
+ icmph->header.ttl--;
/* route it */
if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 3c21162..91dd369 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -749,7 +749,7 @@ struct batadv_socket_client {
struct batadv_socket_packet {
struct list_head list;
size_t icmp_len;
- struct batadv_icmp_packet_rr icmp_packet;
+ uint8_t icmp_packet[BATADV_ICMP_MAX_PACKET_SIZE];
};
/**
--
1.8.4
^ permalink raw reply related
* [PATCH 15/16] batman-adv: Start new development cycle
From: Antonio Quartulli @ 2013-10-23 16:05 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Simon Wunderlich, Antonio Quartulli
In-Reply-To: <1382544303-2694-1-git-send-email-antonio@meshcoding.com>
From: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
net/batman-adv/main.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 773301a..f94f287b 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -26,7 +26,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION
-#define BATADV_SOURCE_VERSION "2013.4.0"
+#define BATADV_SOURCE_VERSION "2013.5.0"
#endif
/* B.A.T.M.A.N. parameters */
--
1.8.4
^ permalink raw reply related
* [PATCH 10/16] batman-adv: limit local translation table max size
From: Antonio Quartulli @ 2013-10-23 16:04 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Marek Lindner
In-Reply-To: <1382544303-2694-1-git-send-email-antonio@meshcoding.com>
From: Marek Lindner <lindner_marek@yahoo.de>
The local translation table size is limited by what can be
transferred from one node to another via a full table request.
The number of entries fitting into a full table request depend
on whether the fragmentation is enabled or not. Therefore this
patch introduces a max table size check and refuses to add
more local clients when that size is reached. Moreover, if the
max full table packet size changes (MTU change or fragmentation
is disabled) the local table is downsized instantaneously.
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Acked-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/hard-interface.c | 41 ++++++----
net/batman-adv/soft-interface.c | 12 ++-
net/batman-adv/translation-table.c | 150 +++++++++++++++++++++++++++++++++----
net/batman-adv/translation-table.h | 3 +-
net/batman-adv/types.h | 3 +
5 files changed, 173 insertions(+), 36 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index c5f871f..c60d3ed 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -266,16 +266,9 @@ static void batadv_check_known_mac_addr(const struct net_device *net_dev)
int batadv_hardif_min_mtu(struct net_device *soft_iface)
{
- const struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(soft_iface);
const struct batadv_hard_iface *hard_iface;
- /* allow big frames if all devices are capable to do so
- * (have MTU > 1500 + batadv_max_header_len())
- */
int min_mtu = ETH_DATA_LEN;
- int max_header_len = batadv_max_header_len();
-
- if (atomic_read(&bat_priv->fragmentation))
- goto out;
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
@@ -286,22 +279,40 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface)
if (hard_iface->soft_iface != soft_iface)
continue;
- min_mtu = min_t(int, hard_iface->net_dev->mtu - max_header_len,
- min_mtu);
+ min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
}
rcu_read_unlock();
+
+ atomic_set(&bat_priv->packet_size_max, min_mtu);
+
+ if (atomic_read(&bat_priv->fragmentation) == 0)
+ goto out;
+
+ /* with fragmentation enabled the maximum size of internally generated
+ * packets such as translation table exchanges or tvlv containers, etc
+ * has to be calculated
+ */
+ min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE);
+ min_mtu -= sizeof(struct batadv_frag_packet);
+ min_mtu *= BATADV_FRAG_MAX_FRAGMENTS;
+ atomic_set(&bat_priv->packet_size_max, min_mtu);
+
+ /* with fragmentation enabled we can fragment external packets easily */
+ min_mtu = min_t(int, min_mtu, ETH_DATA_LEN);
+
out:
- return min_mtu;
+ return min_mtu - batadv_max_header_len();
}
/* adjusts the MTU if a new interface with a smaller MTU appeared. */
void batadv_update_min_mtu(struct net_device *soft_iface)
{
- int min_mtu;
+ soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
- min_mtu = batadv_hardif_min_mtu(soft_iface);
- if (soft_iface->mtu != min_mtu)
- soft_iface->mtu = min_mtu;
+ /* Check if the local translate table should be cleaned up to match a
+ * new (and smaller) MTU.
+ */
+ batadv_tt_local_resize_to_mtu(soft_iface);
}
static void
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index e70f530..36f0508 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -166,7 +166,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
unsigned int header_len = 0;
int data_len = skb->len, ret;
unsigned long brd_delay = 1;
- bool do_bcast = false;
+ bool do_bcast = false, client_added;
unsigned short vid;
uint32_t seqno;
@@ -196,9 +196,12 @@ static int batadv_interface_tx(struct sk_buff *skb,
ethhdr = (struct ethhdr *)skb->data;
/* Register the client MAC in the transtable */
- if (!is_multicast_ether_addr(ethhdr->h_source))
- batadv_tt_local_add(soft_iface, ethhdr->h_source, vid,
- skb->skb_iif);
+ if (!is_multicast_ether_addr(ethhdr->h_source)) {
+ client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source,
+ vid, skb->skb_iif);
+ if (!client_added)
+ goto dropped;
+ }
/* don't accept stp packets. STP does not help in meshes.
* better use the bridge loop avoidance ...
@@ -674,6 +677,7 @@ static int batadv_softif_init_late(struct net_device *dev)
atomic_set(&bat_priv->log_level, 0);
#endif
atomic_set(&bat_priv->fragmentation, 1);
+ atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN);
atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 4c28251..a3c965d 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -401,6 +401,35 @@ static uint16_t batadv_tt_entries(uint16_t tt_len)
return tt_len / batadv_tt_len(1);
}
+/**
+ * batadv_tt_local_table_transmit_size - calculates the local translation table
+ * size when transmitted over the air
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Returns local translation table size in bytes.
+ */
+static int batadv_tt_local_table_transmit_size(struct batadv_priv *bat_priv)
+{
+ uint16_t num_vlan = 0, tt_local_entries = 0;
+ struct batadv_softif_vlan *vlan;
+ int hdr_size;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+ num_vlan++;
+ tt_local_entries += atomic_read(&vlan->tt.num_entries);
+ }
+ rcu_read_unlock();
+
+ /* header size of tvlv encapsulated tt response payload */
+ hdr_size = sizeof(struct batadv_unicast_tvlv_packet);
+ hdr_size += sizeof(struct batadv_tvlv_hdr);
+ hdr_size += sizeof(struct batadv_tvlv_tt_data);
+ hdr_size += num_vlan * sizeof(struct batadv_tvlv_tt_vlan_data);
+
+ return hdr_size + batadv_tt_len(tt_local_entries);
+}
+
static int batadv_tt_local_init(struct batadv_priv *bat_priv)
{
if (bat_priv->tt.local_hash)
@@ -439,8 +468,10 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv,
* @vid: VLAN identifier
* @ifindex: index of the interface where the client is connected to (useful to
* identify wireless clients)
+ *
+ * Returns true if the client was successfully added, false otherwise.
*/
-void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
+bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
unsigned short vid, int ifindex)
{
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
@@ -448,8 +479,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
struct batadv_tt_global_entry *tt_global;
struct hlist_head *head;
struct batadv_tt_orig_list_entry *orig_entry;
- int hash_added;
- bool roamed_back = false;
+ int hash_added, table_size, packet_size_max;
+ bool ret = false, roamed_back = false;
tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
@@ -484,6 +515,17 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
goto check_roaming;
}
+ /* Ignore the client if we cannot send it in a full table response. */
+ table_size = batadv_tt_local_table_transmit_size(bat_priv);
+ table_size += batadv_tt_len(1);
+ packet_size_max = atomic_read(&bat_priv->packet_size_max);
+ if (table_size > packet_size_max) {
+ net_ratelimited_function(batadv_info, soft_iface,
+ "Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n",
+ table_size, packet_size_max, addr);
+ goto out;
+ }
+
tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
if (!tt_local)
goto out;
@@ -550,11 +592,14 @@ check_roaming:
}
}
+ ret = true;
+
out:
if (tt_local)
batadv_tt_local_entry_free_ref(tt_local);
if (tt_global)
batadv_tt_global_entry_free_ref(tt_global);
+ return ret;
}
/**
@@ -926,8 +971,16 @@ out:
return curr_flags;
}
+/**
+ * batadv_tt_local_purge_list - purge inactive tt local entries
+ * @bat_priv: the bat priv with all the soft interface information
+ * @head: pointer to the list containing the local tt entries
+ * @timeout: parameter deciding whether a given tt local entry is considered
+ * inactive or not
+ */
static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
- struct hlist_head *head)
+ struct hlist_head *head,
+ int timeout)
{
struct batadv_tt_local_entry *tt_local_entry;
struct batadv_tt_common_entry *tt_common_entry;
@@ -945,8 +998,7 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
continue;
- if (!batadv_has_timed_out(tt_local_entry->last_seen,
- BATADV_TT_LOCAL_TIMEOUT))
+ if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout))
continue;
batadv_tt_local_set_pending(bat_priv, tt_local_entry,
@@ -954,7 +1006,14 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
}
}
-static void batadv_tt_local_purge(struct batadv_priv *bat_priv)
+/**
+ * batadv_tt_local_purge - purge inactive tt local entries
+ * @bat_priv: the bat priv with all the soft interface information
+ * @timeout: parameter deciding whether a given tt local entry is considered
+ * inactive or not
+ */
+static void batadv_tt_local_purge(struct batadv_priv *bat_priv,
+ int timeout)
{
struct batadv_hashtable *hash = bat_priv->tt.local_hash;
struct hlist_head *head;
@@ -966,7 +1025,7 @@ static void batadv_tt_local_purge(struct batadv_priv *bat_priv)
list_lock = &hash->list_locks[i];
spin_lock_bh(list_lock);
- batadv_tt_local_purge_list(bat_priv, head);
+ batadv_tt_local_purge_list(bat_priv, head, timeout);
spin_unlock_bh(list_lock);
}
}
@@ -2383,6 +2442,15 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
req_dst_orig_node);
}
+ /* Don't send the response, if larger than fragmented packet. */
+ tt_len = sizeof(struct batadv_unicast_tvlv_packet) + tvlv_len;
+ if (tt_len > atomic_read(&bat_priv->packet_size_max)) {
+ net_ratelimited_function(batadv_info, bat_priv->soft_iface,
+ "Ignoring TT_REQUEST from %pM; Response size exceeds max packet size.\n",
+ res_dst_orig_node->orig);
+ goto out;
+ }
+
tvlv_tt_data->flags = BATADV_TT_RESPONSE;
tvlv_tt_data->ttvn = req_ttvn;
@@ -2859,7 +2927,7 @@ static void batadv_tt_purge(struct work_struct *work)
priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
bat_priv = container_of(priv_tt, struct batadv_priv, tt);
- batadv_tt_local_purge(bat_priv);
+ batadv_tt_local_purge(bat_priv, BATADV_TT_LOCAL_TIMEOUT);
batadv_tt_global_purge(bat_priv);
batadv_tt_req_purge(bat_priv);
batadv_tt_roam_purge(bat_priv);
@@ -2972,18 +3040,18 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
}
/**
- * batadv_tt_local_commit_changes - commit all pending local tt changes which
- * have been queued in the time since the last commit
+ * batadv_tt_local_commit_changes_nolock - commit all pending local tt changes
+ * which have been queued in the time since the last commit
* @bat_priv: the bat priv with all the soft interface information
+ *
+ * Caller must hold tt->commit_lock.
*/
-void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
+static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
{
- spin_lock_bh(&bat_priv->tt.commit_lock);
-
if (atomic_read(&bat_priv->tt.local_changes) < 1) {
if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
batadv_tt_tvlv_container_update(bat_priv);
- goto out;
+ return;
}
batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true);
@@ -3000,8 +3068,17 @@ void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
/* reset the sending counter */
atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
batadv_tt_tvlv_container_update(bat_priv);
+}
-out:
+/**
+ * batadv_tt_local_commit_changes - commit all pending local tt changes which
+ * have been queued in the time since the last commit
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
+{
+ spin_lock_bh(&bat_priv->tt.commit_lock);
+ batadv_tt_local_commit_changes_nolock(bat_priv);
spin_unlock_bh(&bat_priv->tt.commit_lock);
}
@@ -3197,6 +3274,47 @@ out:
}
/**
+ * batadv_tt_local_resize_to_mtu - resize the local translation table fit the
+ * maximum packet size that can be transported through the mesh
+ * @soft_iface: netdev struct of the mesh interface
+ *
+ * Remove entries older than 'timeout' and half timeout if more entries need
+ * to be removed.
+ */
+void batadv_tt_local_resize_to_mtu(struct net_device *soft_iface)
+{
+ struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+ int packet_size_max = atomic_read(&bat_priv->packet_size_max);
+ int table_size, timeout = BATADV_TT_LOCAL_TIMEOUT / 2;
+ bool reduced = false;
+
+ spin_lock_bh(&bat_priv->tt.commit_lock);
+
+ while (true) {
+ table_size = batadv_tt_local_table_transmit_size(bat_priv);
+ if (packet_size_max >= table_size)
+ break;
+
+ batadv_tt_local_purge(bat_priv, timeout);
+ batadv_tt_local_purge_pending_clients(bat_priv);
+
+ timeout /= 2;
+ reduced = true;
+ net_ratelimited_function(batadv_info, soft_iface,
+ "Forced to purge local tt entries to fit new maximum fragment MTU (%i)\n",
+ packet_size_max);
+ }
+
+ /* commit these changes immediately, to avoid synchronization problem
+ * with the TTVN
+ */
+ if (reduced)
+ batadv_tt_local_commit_changes_nolock(bat_priv);
+
+ spin_unlock_bh(&bat_priv->tt.commit_lock);
+}
+
+/**
* batadv_tt_tvlv_ogm_handler_v1 - process incoming tt tvlv container
* @bat_priv: the bat priv with all the soft interface information
* @orig: the orig_node of the ogm
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index dc6db4e..026b1ff 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -21,7 +21,7 @@
#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
int batadv_tt_init(struct batadv_priv *bat_priv);
-void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
+bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
unsigned short vid, int ifindex);
uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
const uint8_t *addr, unsigned short vid,
@@ -45,6 +45,7 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
uint8_t *addr, unsigned short vid);
bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
uint8_t *addr, unsigned short vid);
+void batadv_tt_local_resize_to_mtu(struct net_device *soft_iface);
bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
const unsigned char *addr,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 672a813..04b6b0b 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -612,6 +612,8 @@ struct batadv_softif_vlan {
* @aggregated_ogms: bool indicating whether OGM aggregation is enabled
* @bonding: bool indicating whether traffic bonding is enabled
* @fragmentation: bool indicating whether traffic fragmentation is enabled
+ * @packet_size_max: max packet size that can be transmitted via
+ * multiple fragmented skbs or a single frame if fragmentation is disabled
* @frag_seqno: incremental counter to identify chains of egress fragments
* @bridge_loop_avoidance: bool indicating whether bridge loop avoidance is
* enabled
@@ -658,6 +660,7 @@ struct batadv_priv {
atomic_t aggregated_ogms;
atomic_t bonding;
atomic_t fragmentation;
+ atomic_t packet_size_max;
atomic_t frag_seqno;
#ifdef CONFIG_BATMAN_ADV_BLA
atomic_t bridge_loop_avoidance;
--
1.8.4
^ permalink raw reply related
* [PATCH 12/16] batman-adv: invoke dev_get_by_index() outside of is_wifi_iface()
From: Antonio Quartulli @ 2013-10-23 16:04 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382544303-2694-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
Upcoming changes need to perform other checks on the
incoming net_device struct.
To avoid performing dev_get_by_index() for each and every
check, it is better to move it outside of is_wifi_iface()
and search the netdev object once only.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
net/batman-adv/hard-interface.c | 33 ++++-----------------------------
net/batman-adv/hard-interface.h | 2 +-
net/batman-adv/translation-table.c | 8 +++++++-
3 files changed, 12 insertions(+), 31 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 1ba8a55..57c2a19 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -125,8 +125,11 @@ static int batadv_is_valid_iface(const struct net_device *net_dev)
*
* Returns true if the net device is a 802.11 wireless device, false otherwise.
*/
-static bool batadv_is_wifi_netdev(struct net_device *net_device)
+bool batadv_is_wifi_netdev(struct net_device *net_device)
{
+ if (!net_device)
+ return false;
+
#ifdef CONFIG_WIRELESS_EXT
/* pre-cfg80211 drivers have to implement WEXT, so it is possible to
* check for wireless_handlers != NULL
@@ -142,34 +145,6 @@ static bool batadv_is_wifi_netdev(struct net_device *net_device)
return false;
}
-/**
- * batadv_is_wifi_iface - check if the given interface represented by ifindex
- * is a wifi interface
- * @ifindex: interface index to check
- *
- * Returns true if the interface represented by ifindex is a 802.11 wireless
- * device, false otherwise.
- */
-bool batadv_is_wifi_iface(int ifindex)
-{
- struct net_device *net_device = NULL;
- bool ret = false;
-
- if (ifindex == BATADV_NULL_IFINDEX)
- goto out;
-
- net_device = dev_get_by_index(&init_net, ifindex);
- if (!net_device)
- goto out;
-
- ret = batadv_is_wifi_netdev(net_device);
-
-out:
- if (net_device)
- dev_put(net_device);
- return ret;
-}
-
static struct batadv_hard_iface *
batadv_hardif_get_active(const struct net_device *soft_iface)
{
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index 4989288..df4c8bd 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -41,6 +41,7 @@ enum batadv_hard_if_cleanup {
extern struct notifier_block batadv_hard_if_notifier;
+bool batadv_is_wifi_netdev(struct net_device *net_device);
struct batadv_hard_iface*
batadv_hardif_get_by_netdev(const struct net_device *net_dev);
int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
@@ -51,7 +52,6 @@ void batadv_hardif_remove_interfaces(void);
int batadv_hardif_min_mtu(struct net_device *soft_iface);
void batadv_update_min_mtu(struct net_device *soft_iface);
void batadv_hardif_free_rcu(struct rcu_head *rcu);
-bool batadv_is_wifi_iface(int ifindex);
static inline void
batadv_hardif_free_ref(struct batadv_hard_iface *hard_iface)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index a3c965d..b0fe177 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -477,11 +477,15 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
struct batadv_tt_local_entry *tt_local;
struct batadv_tt_global_entry *tt_global;
+ struct net_device *in_dev = NULL;
struct hlist_head *head;
struct batadv_tt_orig_list_entry *orig_entry;
int hash_added, table_size, packet_size_max;
bool ret = false, roamed_back = false;
+ if (ifindex != BATADV_NULL_IFINDEX)
+ in_dev = dev_get_by_index(&init_net, ifindex);
+
tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
@@ -542,7 +546,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
*/
tt_local->common.flags = BATADV_TT_CLIENT_NEW;
tt_local->common.vid = vid;
- if (batadv_is_wifi_iface(ifindex))
+ if (batadv_is_wifi_netdev(in_dev))
tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
atomic_set(&tt_local->common.refcount, 2);
tt_local->last_seen = jiffies;
@@ -595,6 +599,8 @@ check_roaming:
ret = true;
out:
+ if (in_dev)
+ dev_put(in_dev);
if (tt_local)
batadv_tt_local_entry_free_ref(tt_local);
if (tt_global)
--
1.8.4
^ permalink raw reply related
* [PATCH 11/16] batman-adv: send GW_DEL event in case of soft-iface destruction
From: Antonio Quartulli @ 2013-10-23 16:04 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382544303-2694-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
In case of soft_iface destruction send a GW DEL event to
userspace so that applications which are listening for GW
events are informed about the lost of connectivity and can
react accordingly.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
net/batman-adv/hard-interface.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index c60d3ed..1ba8a55 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -28,6 +28,7 @@
#include "originator.h"
#include "hash.h"
#include "bridge_loop_avoidance.h"
+#include "gateway_client.h"
#include <linux/if_arp.h>
#include <linux/if_ether.h>
@@ -535,8 +536,12 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
dev_put(hard_iface->soft_iface);
/* nobody uses this interface anymore */
- if (!bat_priv->num_ifaces && autodel == BATADV_IF_CLEANUP_AUTO)
- batadv_softif_destroy_sysfs(hard_iface->soft_iface);
+ if (!bat_priv->num_ifaces) {
+ batadv_gw_check_client_stop(bat_priv);
+
+ if (autodel == BATADV_IF_CLEANUP_AUTO)
+ batadv_softif_destroy_sysfs(hard_iface->soft_iface);
+ }
netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
hard_iface->soft_iface = NULL;
--
1.8.4
^ permalink raw reply related
* [PATCH 14/16] batman-adv: include the sync-flags when compute the global/local table CRC
From: Antonio Quartulli @ 2013-10-23 16:05 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382544303-2694-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
Flags covered by TT_SYNC_MASK are kept in sync among the
nodes in the network and therefore they have to be
considered while computing the global/local table CRC.
In this way a generic originator is able to understand if
its table contains the correct flags or not.
Bits from 4 to 7 in the TT flags fields are now reserved for
"synchronized" flags only.
This allows future developers to add more flags of this type
without breaking compatibility.
It's important to note that not all the remote TT flags are
synchronised. This comes from the fact that some flags are
used to inject an information once only.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
net/batman-adv/packet.h | 5 +++--
net/batman-adv/translation-table.c | 19 +++++++++++++++++++
net/batman-adv/types.h | 6 ++++++
3 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 9fbcaac..843b96a 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -110,12 +110,13 @@ enum batadv_tt_data_flags {
/* BATADV_TT_CLIENT flags.
* Flags from BIT(0) to BIT(7) are sent on the wire, while flags from BIT(8) to
- * BIT(15) are used for local computation only
+ * BIT(15) are used for local computation only.
+ * Flags from BIT(4) to BIT(7) are kept in sync with the rest of the network.
*/
enum batadv_tt_client_flags {
BATADV_TT_CLIENT_DEL = BIT(0),
BATADV_TT_CLIENT_ROAM = BIT(1),
- BATADV_TT_CLIENT_WIFI = BIT(2),
+ BATADV_TT_CLIENT_WIFI = BIT(4),
BATADV_TT_CLIENT_NOPURGE = BIT(8),
BATADV_TT_CLIENT_NEW = BIT(9),
BATADV_TT_CLIENT_PENDING = BIT(10),
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 267780f..4add57d 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1959,6 +1959,7 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
struct batadv_tt_global_entry *tt_global;
struct hlist_head *head;
uint32_t i, crc_tmp, crc = 0;
+ uint8_t flags;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -1997,6 +1998,13 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
crc_tmp = crc32c(0, &tt_common->vid,
sizeof(tt_common->vid));
+
+ /* compute the CRC on flags that have to be kept in sync
+ * among nodes
+ */
+ flags = tt_common->flags & BATADV_TT_SYNC_MASK;
+ crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
+
crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
}
rcu_read_unlock();
@@ -2022,6 +2030,7 @@ static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv,
struct batadv_tt_common_entry *tt_common;
struct hlist_head *head;
uint32_t i, crc_tmp, crc = 0;
+ uint8_t flags;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -2042,6 +2051,13 @@ static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv,
crc_tmp = crc32c(0, &tt_common->vid,
sizeof(tt_common->vid));
+
+ /* compute the CRC on flags that have to be kept in sync
+ * among nodes
+ */
+ flags = tt_common->flags & BATADV_TT_SYNC_MASK;
+ crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
+
crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
}
rcu_read_unlock();
@@ -3524,6 +3540,9 @@ int batadv_tt_init(struct batadv_priv *bat_priv)
{
int ret;
+ /* synchronized flags must be remote */
+ BUILD_BUG_ON(!(BATADV_TT_SYNC_MASK & BATADV_TT_REMOTE_MASK));
+
ret = batadv_tt_local_init(bat_priv);
if (ret < 0)
return ret;
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 61297b6..3c21162 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -42,6 +42,12 @@
#define BATADV_TT_REMOTE_MASK 0x00FF
/**
+ * BATADV_TT_SYNC_MASK - bitmask of the flags that need to be kept in sync
+ * among the nodes. These flags are used to compute the global/local CRC
+ */
+#define BATADV_TT_SYNC_MASK 0x00F0
+
+/**
* struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data
* @ogm_buff: buffer holding the OGM packet
* @ogm_buff_len: length of the OGM packet buffer
--
1.8.4
^ permalink raw reply related
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