* [PATCH 3/3] gianfar: Enable eTSEC-20 erratum w/a for P2020 Rev1
From: Claudiu Manoil @ 2013-10-09 17:20 UTC (permalink / raw)
To: netdev, David S. Miller; +Cc: linuxppc-dev
In-Reply-To: <1381339242-32030-1-git-send-email-claudiu.manoil@freescale.com>
Enable workaround for P2020/P2010 erratum eTSEC 20,
"Excess delays when transmitting TOE=1 large frames".
The impact is that frames lager than 2500-bytes for which
TOE (i.e. TCP/IP hw accelerations like Tx csum) is enabled
may see excess delay before start of transmission.
This erratum was fixed in Rev 2.0.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 329a206..9fbe4dd 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -968,6 +968,9 @@ static void __gfar_detect_errata_85xx(struct gfar_private *priv)
if ((SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) == 0x20))
priv->errata |= GFAR_ERRATA_12;
+ if (((SVR_SOC_VER(svr) == SVR_P2020) && (SVR_REV(svr) < 0x20)) ||
+ ((SVR_SOC_VER(svr) == SVR_P2010) && (SVR_REV(svr) < 0x20)))
+ priv->errata |= GFAR_ERRATA_76; /* aka eTSEC 20 */
}
static void gfar_detect_errata(struct gfar_private *priv)
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH] veth: allow to setup multicast address for veth device
From: David Miller @ 2013-10-09 17:22 UTC (permalink / raw)
To: gaofeng; +Cc: netdev, pablo, edumazet, kaber, hannes
In-Reply-To: <52551ABD.40603@cn.fujitsu.com>
From: Gao feng <gaofeng@cn.fujitsu.com>
Date: Wed, 09 Oct 2013 16:58:37 +0800
> Hi David,
>
> On 10/04/2013 04:52 PM, Gao feng wrote:
>> We can only setup multicast address for network device when
>> net_device_ops->ndo_set_rx_mode is not null.
>>
>> Some configurations need to add multicast address for net
>> device, such as netfilter cluster match module.
>>
>> Add a fake ndo_set_rx_mode function to allow this operation.
>>
>> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
>
> I see this patch being marked as "Changes Requested" on patchwork.
> Is there something I missed?
It was a mistake, I put it back in Under Review.
^ permalink raw reply
* Re: [PATCH v2 net-next] net: fix build errors if ipv6 is disabled
From: David Miller @ 2013-10-09 17:23 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1381313148.4971.13.camel@edumazet-glaptop.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 09 Oct 2013 03:05:48 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> CONFIG_IPV6=n is still a valid choice ;)
>
> It appears we can remove dead code.
>
> Reported-by: Wu Fengguang <fengguang.wu@intel.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> v2: add the missing right parenthesis in ping_bind()
Applied, thanks.
^ permalink raw reply
* [PATCH 1/3] gianfar: Enable eTSEC-A002 erratum w/a for all parts
From: Claudiu Manoil @ 2013-10-09 17:20 UTC (permalink / raw)
To: netdev, David S. Miller; +Cc: linuxppc-dev
A002 is still in "no plans to fix" state, and applies to all
the current P1/P2 parts as well, so it's resonable to enable
its workaround by default, for all the soc's with etsec.
The impact of not enabling this workaround for affected parts
is that under certain conditons (runt frames or even frames
with RX error detected at PHY level) during controller reset,
the controller might fail to indicate Rx reset (GRS) completion.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index c4eaade..db5fc7b 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -947,6 +947,9 @@ static void gfar_detect_errata(struct gfar_private *priv)
unsigned int mod = (svr >> 16) & 0xfff6; /* w/o E suffix */
unsigned int rev = svr & 0xffff;
+ /* no plans to fix */
+ priv->errata |= GFAR_ERRATA_A002;
+
/* MPC8313 Rev 2.0 and higher; All MPC837x */
if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) ||
(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
@@ -957,11 +960,6 @@ static void gfar_detect_errata(struct gfar_private *priv)
(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
priv->errata |= GFAR_ERRATA_76;
- /* MPC8313 and MPC837x all rev */
- if ((pvr == 0x80850010 && mod == 0x80b0) ||
- (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
- priv->errata |= GFAR_ERRATA_A002;
-
/* MPC8313 Rev < 2.0, MPC8548 rev 2.0 */
if ((pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020) ||
(pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020))
@@ -1599,7 +1597,7 @@ static int __gfar_is_rx_idle(struct gfar_private *priv)
/* Normaly TSEC should not hang on GRS commands, so we should
* actually wait for IEVENT_GRSC flag.
*/
- if (likely(!gfar_has_errata(priv, GFAR_ERRATA_A002)))
+ if (!gfar_has_errata(priv, GFAR_ERRATA_A002))
return 0;
/* Read the eTSEC register at offset 0xD1C. If bits 7-14 are
--
1.7.11.7
^ permalink raw reply related
* [PATCH 2/3] gianfar: Use mpc85xx support for errata detection
From: Claudiu Manoil @ 2013-10-09 17:20 UTC (permalink / raw)
To: netdev, David S. Miller; +Cc: linuxppc-dev
In-Reply-To: <1381339242-32030-1-git-send-email-claudiu.manoil@freescale.com>
Use the macros and defines from mpc85xx.h to simplify
and prevent errors in identifying a mpc85xx based SoC
for errata detection.
This should help enabling (and identifying) workarounds
for various mpc85xx based chips and revisions.
For instance, express MPC8548 Rev.2 as:
(SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) == 0x20)
instead of:
(pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020)
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 33 ++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index db5fc7b..329a206 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -88,6 +88,7 @@
#include <asm/io.h>
#include <asm/reg.h>
+#include <asm/mpc85xx.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/module.h>
@@ -939,17 +940,13 @@ static void gfar_init_filer_table(struct gfar_private *priv)
}
}
-static void gfar_detect_errata(struct gfar_private *priv)
+static void __gfar_detect_errata_83xx(struct gfar_private *priv)
{
- struct device *dev = &priv->ofdev->dev;
unsigned int pvr = mfspr(SPRN_PVR);
unsigned int svr = mfspr(SPRN_SVR);
unsigned int mod = (svr >> 16) & 0xfff6; /* w/o E suffix */
unsigned int rev = svr & 0xffff;
- /* no plans to fix */
- priv->errata |= GFAR_ERRATA_A002;
-
/* MPC8313 Rev 2.0 and higher; All MPC837x */
if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) ||
(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
@@ -960,10 +957,30 @@ static void gfar_detect_errata(struct gfar_private *priv)
(pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
priv->errata |= GFAR_ERRATA_76;
- /* MPC8313 Rev < 2.0, MPC8548 rev 2.0 */
- if ((pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020) ||
- (pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020))
+ /* MPC8313 Rev < 2.0 */
+ if (pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020)
+ priv->errata |= GFAR_ERRATA_12;
+}
+
+static void __gfar_detect_errata_85xx(struct gfar_private *priv)
+{
+ unsigned int svr = mfspr(SPRN_SVR);
+
+ if ((SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) == 0x20))
priv->errata |= GFAR_ERRATA_12;
+}
+
+static void gfar_detect_errata(struct gfar_private *priv)
+{
+ struct device *dev = &priv->ofdev->dev;
+
+ /* no plans to fix */
+ priv->errata |= GFAR_ERRATA_A002;
+
+ if (pvr_version_is(PVR_VER_E500V1) || pvr_version_is(PVR_VER_E500V2))
+ __gfar_detect_errata_85xx(priv);
+ else /* non-mpc85xx parts, i.e. e300 core based */
+ __gfar_detect_errata_83xx(priv);
if (priv->errata)
dev_info(dev, "enabled errata workarounds, flags: 0x%x\n",
--
1.7.11.7
^ permalink raw reply related
* Re: IPv6 kernel warning
From: Yuchung Cheng @ 2013-10-09 17:33 UTC (permalink / raw)
To: dormando
Cc: Michele Baldessari, Russell King - ARM Linux, netdev,
Neal Cardwell, Nandita Dukkipati
In-Reply-To: <CAK6E8=d5VWMoOpDhZR4WaU6V6NJ9YSvJr=mm=rYNir0z644H=A@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 6631 bytes --]
On Tue, Oct 8, 2013 at 1:53 PM, Yuchung Cheng <ycheng@google.com> wrote:
>
> On Tue, Oct 8, 2013 at 11:24 AM, dormando <dormando@rydia.net> wrote:
> > On Mon, 7 Oct 2013, Yuchung Cheng wrote:
> >
> >> On Mon, Oct 7, 2013 at 12:56 PM, dormando <dormando@rydia.net> wrote:
> >> > On Mon, 7 Oct 2013, Yuchung Cheng wrote:
> >> >
> >> >> On Mon, Oct 7, 2013 at 11:13 AM, dormando <dormando@rydia.net> wrote:
> >> >> >
> >> >> > > >
> >> >> > > > there's been multiple reports about this one:
> >> >> > > > https://bugzilla.redhat.com/show_bug.cgi?id=989251
> >> >> > > > http://bugzilla.kernel.org/show_bug.cgi?id=60779
> >> >> > > >
> >> >> > > > Could you try Yuchung's debug patch?
> >> >> > > > http://www.spinics.net/lists/netdev/msg250193.html
> >> >> > > Yes it looks like the same bug. Please try that patch to help identify
> >> >> > > this elusive bug.
> >> >> > >
> >> >> >
> >> >> > Hi!
> >> >> >
> >> >> > We get this one a few times a day in production. Here's a warning with
> >> >> > your debug trace in the line immediately following:
> >> >> > (I censored a few things)
> >> >> >
> >> >> > [125311.721950] ------------[ cut here ]------------
> >> >> > [125311.721961] WARNING: at net/ipv4/tcp_input.c:2776 tcp_fastretrans_alert+0xb58/0xc80()
> >> >> > [125311.721962] Modules linked in: bridge ip_vs macvlan coretemp crc32_pclmul ghash_clmulni_intel gpio_ich ipmi_watchdog microcode ipmi_devintf sb_edac lpc_ich edac_core mfd_core ipmi_si ipmi_msghandler iptable_nat nf_nat_ipv4 nf_nat ixgbe igb mdio i2c_algo_bit ptp pps_core
> >> >> > [125311.721981] CPU: 11 PID: 0 Comm: swapper/11 Not tainted 3.10.13 #1
> >> >> > [125311.721982] Hardware name: Supermicro XXXXXXXXXXX, BIOS 1.1 10/03/2012
> >> >> > [125311.721984] ffffffff81a82007 ffff88407fc63958 ffffffff816bb9cc ffff88407fc63998
> >> >> > [125311.721986] ffffffff8104b940 00ff8840ad904f82 ffff883b8a165b00 0000000000004120
> >> >> > [125311.721989] 0000000000000001 0000000000000019 0000000000000000 ffff88407fc639a8
> >> >> > [125311.721991] Call Trace:
> >> >> > [125311.721992] <IRQ> [<ffffffff816bb9cc>] dump_stack+0x19/0x1d
> >> >> > [125311.722002] [<ffffffff8104b940>] warn_slowpath_common+0x70/0xa0
> >> >> > [125311.722005] [<ffffffff8104b98a>] warn_slowpath_null+0x1a/0x20
> >> >> > [125311.722007] [<ffffffff81616db8>] tcp_fastretrans_alert+0xb58/0xc80
> >> >> > [125311.722011] [<ffffffff8161891f>] tcp_ack+0x6df/0xe90
> >> >> > [125311.722016] [<ffffffff8164e0ca>] ? ipt_do_table+0x22a/0x680
> >> >> > [125311.722018] [<ffffffff816194b3>] ? tcp_validate_incoming+0x63/0x320
> >> >> > [125311.722021] [<ffffffff8161a55c>] tcp_rcv_established+0x2cc/0x810
> >> >> > [125311.722023] [<ffffffff81622c84>] tcp_v4_do_rcv+0x254/0x4f0
> >> >> > [125311.722025] [<ffffffff816245ac>] tcp_v4_rcv+0x5fc/0x750
> >> >> > [125311.722027] [<ffffffff815ffa00>] ? ip_rcv+0x350/0x350
> >> >> > [125311.722032] [<ffffffff815df3ad>] ? nf_hook_slow+0x7d/0x160
> >> >> > [125311.722034] [<ffffffff815ffa00>] ? ip_rcv+0x350/0x350
> >> >> > [125311.722036] [<ffffffff815fface>] ip_local_deliver_finish+0xce/0x250
> >> >> > [125311.722037] [<ffffffff815ffc9c>] ip_local_deliver+0x4c/0x80
> >> >> > [125311.722039] [<ffffffff815ff329>] ip_rcv_finish+0x119/0x360
> >> >> > [125311.722040] [<ffffffff815ff8e0>] ip_rcv+0x230/0x350
> >> >> > [125311.722046] [<ffffffff815b4067>] __netif_receive_skb_core+0x477/0x600
> >> >> > [125311.722049] [<ffffffff815b4217>] __netif_receive_skb+0x27/0x70
> >> >> > [125311.722051] [<ffffffff815b4354>] process_backlog+0xf4/0x1e0
> >> >> > [125311.722053] [<ffffffff815b4b45>] net_rx_action+0xf5/0x250
> >> >> > [125311.722056] [<ffffffff81053a5f>] __do_softirq+0xef/0x270
> >> >> > [125311.722058] [<ffffffff81053cb5>] irq_exit+0x95/0xa0
> >> >> > [125311.722062] [<ffffffff816c8f26>] do_IRQ+0x66/0xe0
> >> >> > [125311.722065] [<ffffffff816bf62a>] common_interrupt+0x6a/0x6a
> >> >> > [125311.722065] <EOI> [<ffffffff8100abf1>] ? default_idle+0x21/0xc0
> >> >> > [125311.722082] [<ffffffff8100a54f>] arch_cpu_idle+0xf/0x20
> >> >> > [125311.722086] [<ffffffff8108f353>] cpu_startup_entry+0xb3/0x230
> >> >> > [125311.722091] [<ffffffff816b439e>] start_secondary+0x1dc/0x1e3
> >> >> > [125311.722093] ---[ end trace e77cd5ba583fcbe9 ]---
> >> >> > [125311.722096] 355.355.1.355:22496 F0x4120 S1 s7 IF25+17-1-24f0 ur57 rr3 rt0 um0 hs23120 nxt23120
> >> >> >
> >> >> > It's been happening with all 3.10 kernels, and the one above is .13 as
> >> >> > stated in the trace.
> >> >>
> >> >> Thanks! could you post the output of `sysctl -a |grep tcp`?
> >> >>
> >> >> I suspect tcp_process_tlp_ack() should not revert state to Open
> >> >> directly, but calling tcp_try_keep_open() instead, similar to all the
> >> >> undo processing in the tcp_fastretrans_alert(): after
> >> >> tcp_end_cwnd_reduction(), the process (E) falls back to check other
> >> >> stats before moving to CA_Open.
> >> >>
> >> >>
> >> >> index 9c62257..9012b42 100644
> >> >> --- a/net/ipv4/tcp_input.c
> >> >> +++ b/net/ipv4/tcp_input.c
> >> >> @@ -3314,7 +3314,7 @@ static void tcp_process_tlp_ack(struct sock *sk, u32 ack,
> >> >> tcp_init_cwnd_reduction(sk, true);
> >> >> tcp_set_ca_state(sk, TCP_CA_CWR);
> >> >> tcp_end_cwnd_reduction(sk);
> >> >> - tcp_set_ca_state(sk, TCP_CA_Open);
> >> >> + tcp_try_keep_open(sk);
> >> >> NET_INC_STATS_BH(sock_net(sk),
> >> >> LINUX_MIB_TCPLOSSPROBERECOVERY);
> >> >> }
> >> >>
> >> >
> >> > Should I apply this and see if the warning stops?
Hi Dormando,
Could you try this patch to make sure it fixes the warning (with
sysctl net.ipv4.early_retrans=3)?
> >> I'd like to hear what the authors of TLP think. In the mean time could
> >> you help us collect more evidence by disabling TLP with
> >> sysctl net.ipv4.tcp_early_retrans=2
> >> and see if the problem still occurs? (it should not).
> >>
> >> thanks
> >
> > Box hasn't had a warning in the last 24ish hours. A neighboring machine
> > with the default tcp_early_retrans setting has had 5-6 in the same
> > timeframe.
> >
> > Is this a harmful situation to the socket in any way, or is it just
> > informational weirdness?
> It should be fairly harmless. The ack that triggers the warning should
> set the TCP back to the good (non-Open) state, but it's still good to
> get rid of.
[-- Attachment #2: 0001-tcp-fix-incorrect-ca_state-in-tail-loss-probe.patch --]
[-- Type: application/octet-stream, Size: 1356 bytes --]
From 6aacfe24692341ac93c1d153a801c34066b86262 Mon Sep 17 00:00:00 2001
From: Yuchung Cheng <ycheng@google.com>
Date: Wed, 9 Oct 2013 10:08:52 -0700
Subject: [PATCH] tcp: fix incorrect ca_state in tail loss probe
On receiving an ACK that covers the loss probe sequence, TLP
immediately sets the congestion state to Open, even though some packets
are not recovered and retransmisssion are on the way. The later ACks
may trigger a WARN_ON check of step D in tcp_fastretrans_alert().
The fix is to follow the similar procedure in recovery by calling
tcp_try_keep_open(). The sender switches to Open state if no packets
are retransmissted. Otherwise it goes to Disorder and let subsequent
ACKs move the state to Recovery or Open.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
---
net/ipv4/tcp_input.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 113dc5f..53974c7 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3291,7 +3291,7 @@ static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag)
tcp_init_cwnd_reduction(sk, true);
tcp_set_ca_state(sk, TCP_CA_CWR);
tcp_end_cwnd_reduction(sk);
- tcp_set_ca_state(sk, TCP_CA_Open);
+ tcp_try_keep_open(sk);
NET_INC_STATS_BH(sock_net(sk),
LINUX_MIB_TCPLOSSPROBERECOVERY);
}
--
1.8.4
^ permalink raw reply related
* Re: pull request (net): ipsec 2013-10-09
From: David Miller @ 2013-10-09 17:44 UTC (permalink / raw)
To: steffen.klassert; +Cc: herbert, netdev
In-Reply-To: <1381316351-14418-1-git-send-email-steffen.klassert@secunet.com>
From: Steffen Klassert <steffen.klassert@secunet.com>
Date: Wed, 9 Oct 2013 12:59:04 +0200
> 1) We used the wrong netlink attribute to verify the
> lenght of the replay window on async events. Fix this by
> using the right netlink attribute.
>
> 2) Policy lookups can not match the output interface on forwarding.
> Add the needed informations to the flow informations.
>
> 3) We update the pmtu when we receive a ICMPV6_DEST_UNREACH message
> on IPsec with ipv6. This is wrong and leads to strange fragmented
> packets, only ICMPV6_PKT_TOOBIG messages should update the pmtu.
> Fix this by removing the ICMPV6_DEST_UNREACH check from the IPsec
> protocol error handlers.
>
> 4) The legacy IPsec anti replay mechanism supports anti replay
> windows up to 32 packets. If a user requests for a bigger
> anti replay window, we use 32 packets but pretend that we use
> the requested window size. Fix from Fan Du.
>
> 5) If asynchronous events are enabled and replay_maxdiff is set to
> zero, we generate an async event for every received packet instead
> of checking whether a timeout occurred. Fix from Thomas Egerer.
>
> 6) Policies need a refcount when the state resolution timer is armed.
> Otherwise the timer can fire after the policy is deleted.
>
> 7) We might dreference a NULL pointer if the hold_queue is empty,
> add a check to avoid this.
>
> Please pull or let me know if there are problems.
Pulled, thanks a lot Steffen.
^ permalink raw reply
* Re: pull request: batman-adv 2013-10-09
From: David Miller @ 2013-10-09 17:56 UTC (permalink / raw)
To: antonio; +Cc: netdev, b.a.t.m.a.n
In-Reply-To: <1381322418-1349-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@meshcoding.com>
Date: Wed, 9 Oct 2013 14:40:02 +0200
> Hello David,
>
> this is a set of changes intended for net-next/linux-3.13.
>
> As introduced one year ago (http://article.gmane.org/gmane.org.freifunk.batman/8484)
> in the last period we have been busy working on giving our batman-adv
> protocol/packet-format all those means to get stable and avoid incompatibilities
> in the near future (this is also why we did not send many changes for
> linux-3.12..).
>
> With this patchset we are finally switching to a new compatibility version and
> within this development cycle I will send you all those changes aimed to
> introduce all the needed mechanism to avoid any further compatibility breakage.
>
> First of all, in this batch you have the new TVLV code (Type Version Value
> Length) which is the first very important milestone towards our goal[1].
> With this mechanism we will be able to improve/change the packet contents layout
> (used by the various features) without breaking compatibility with older
> protocol versions anymore.
> The development of this new component has been started by Spyros Gasteratos
> during his Google Summer of Code 2012 and then adjusted, finished and submitted
> by Marek Lindner.
>
> Together with it, you have a set of improvements that we are allowed to apply
> thanks to the switching to the new compat version.
> These changes are:
> - adapt the existing features to make them use the new TVLV mechanism
> - move from CRC16 to CRC32c for table correctness check in the TT component
> - reorder some of the flags sent over the wire
> - remove the __packed attribute from the OGM packet struct.
>
> Moreover, with this patchset we are totally removing our VISualisation component
> that is now implemented in userspace.
>
> Please pull let me know of any problem.
Pulled, thanks.
^ permalink raw reply
* Re: [PATCH 1/3] gianfar: Enable eTSEC-A002 erratum w/a for all parts
From: David Miller @ 2013-10-09 18:02 UTC (permalink / raw)
To: claudiu.manoil; +Cc: netdev, linuxppc-dev
In-Reply-To: <1381339242-32030-1-git-send-email-claudiu.manoil@freescale.com>
From: Claudiu Manoil <claudiu.manoil@freescale.com>
Date: Wed, 9 Oct 2013 20:20:40 +0300
> A002 is still in "no plans to fix" state, and applies to all
> the current P1/P2 parts as well, so it's resonable to enable
> its workaround by default, for all the soc's with etsec.
> The impact of not enabling this workaround for affected parts
> is that under certain conditons (runt frames or even frames
> with RX error detected at PHY level) during controller reset,
> the controller might fail to indicate Rx reset (GRS) completion.
>
> Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Applied.
^ permalink raw reply
* Re: [PATCH 2/3] gianfar: Use mpc85xx support for errata detection
From: David Miller @ 2013-10-09 18:02 UTC (permalink / raw)
To: claudiu.manoil; +Cc: netdev, linuxppc-dev
In-Reply-To: <1381339242-32030-2-git-send-email-claudiu.manoil@freescale.com>
From: Claudiu Manoil <claudiu.manoil@freescale.com>
Date: Wed, 9 Oct 2013 20:20:41 +0300
> Use the macros and defines from mpc85xx.h to simplify
> and prevent errors in identifying a mpc85xx based SoC
> for errata detection.
> This should help enabling (and identifying) workarounds
> for various mpc85xx based chips and revisions.
> For instance, express MPC8548 Rev.2 as:
> (SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) == 0x20)
> instead of:
> (pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020)
>
> Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Applied.
^ permalink raw reply
* Re: [PATCH 3/3] gianfar: Enable eTSEC-20 erratum w/a for P2020 Rev1
From: David Miller @ 2013-10-09 18:02 UTC (permalink / raw)
To: claudiu.manoil; +Cc: netdev, linuxppc-dev
In-Reply-To: <1381339242-32030-3-git-send-email-claudiu.manoil@freescale.com>
From: Claudiu Manoil <claudiu.manoil@freescale.com>
Date: Wed, 9 Oct 2013 20:20:42 +0300
> Enable workaround for P2020/P2010 erratum eTSEC 20,
> "Excess delays when transmitting TOE=1 large frames".
> The impact is that frames lager than 2500-bytes for which
> TOE (i.e. TCP/IP hw accelerations like Tx csum) is enabled
> may see excess delay before start of transmission.
> This erratum was fixed in Rev 2.0.
>
> Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Applied.
^ permalink raw reply
* Re: pull request: wireless 2013-10-09
From: David Miller @ 2013-10-09 18:04 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20131009152841.GD14381@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Wed, 9 Oct 2013 11:28:41 -0400
> Please pull this batch of fixes intended for 3.12...
>
> Most of the bits are for iwlwifi -- Johannes says:
>
> "I have a fix for WoWLAN/D3, a PCIe device fix, we're removing a
> warning, there's a fix for RF-kill while scanning (which goes together
> with a mac80211 fix) and last but not least we have many new PCI IDs."
>
> Also for iwlwifi is a patch from Johannes to correct some merge damage
> that crept into the tree before the last merge window.
>
> On top of that, Felix Fietkau sends an ath9k patch to avoid a Tx
> scheduling hang when changing channels to do a scan.
>
> Please let me know if there are problems!
Pulled, thanks a lot John.
^ permalink raw reply
* Re: IPv6 kernel warning
From: dormando @ 2013-10-09 18:48 UTC (permalink / raw)
To: Yuchung Cheng
Cc: Michele Baldessari, Russell King - ARM Linux, netdev,
Neal Cardwell, Nandita Dukkipati
In-Reply-To: <CAK6E8=fZnQXNjO_dh7sALOfsa=BL7qKzzZkzQrRtX3k9ehBZPA@mail.gmail.com>
On Wed, 9 Oct 2013, Yuchung Cheng wrote:
> On Tue, Oct 8, 2013 at 1:53 PM, Yuchung Cheng <ycheng@google.com> wrote:
> >
> > On Tue, Oct 8, 2013 at 11:24 AM, dormando <dormando@rydia.net> wrote:
> > > On Mon, 7 Oct 2013, Yuchung Cheng wrote:
> > >
> > >> On Mon, Oct 7, 2013 at 12:56 PM, dormando <dormando@rydia.net> wrote:
> > >> > On Mon, 7 Oct 2013, Yuchung Cheng wrote:
> > >> >
> > >> >> On Mon, Oct 7, 2013 at 11:13 AM, dormando <dormando@rydia.net> wrote:
> > >> >> >
> > >> >> > > >
> > >> >> > > > there's been multiple reports about this one:
> > >> >> > > > https://bugzilla.redhat.com/show_bug.cgi?id=989251
> > >> >> > > > http://bugzilla.kernel.org/show_bug.cgi?id=60779
> > >> >> > > >
> > >> >> > > > Could you try Yuchung's debug patch?
> > >> >> > > > http://www.spinics.net/lists/netdev/msg250193.html
> > >> >> > > Yes it looks like the same bug. Please try that patch to help identify
> > >> >> > > this elusive bug.
> > >> >> > >
> > >> >> >
> > >> >> > Hi!
> > >> >> >
> > >> >> > We get this one a few times a day in production. Here's a warning with
> > >> >> > your debug trace in the line immediately following:
> > >> >> > (I censored a few things)
> > >> >> >
> > >> >> > [125311.721950] ------------[ cut here ]------------
> > >> >> > [125311.721961] WARNING: at net/ipv4/tcp_input.c:2776 tcp_fastretrans_alert+0xb58/0xc80()
> > >> >> > [125311.721962] Modules linked in: bridge ip_vs macvlan coretemp crc32_pclmul ghash_clmulni_intel gpio_ich ipmi_watchdog microcode ipmi_devintf sb_edac lpc_ich edac_core mfd_core ipmi_si ipmi_msghandler iptable_nat nf_nat_ipv4 nf_nat ixgbe igb mdio i2c_algo_bit ptp pps_core
> > >> >> > [125311.721981] CPU: 11 PID: 0 Comm: swapper/11 Not tainted 3.10.13 #1
> > >> >> > [125311.721982] Hardware name: Supermicro XXXXXXXXXXX, BIOS 1.1 10/03/2012
> > >> >> > [125311.721984] ffffffff81a82007 ffff88407fc63958 ffffffff816bb9cc ffff88407fc63998
> > >> >> > [125311.721986] ffffffff8104b940 00ff8840ad904f82 ffff883b8a165b00 0000000000004120
> > >> >> > [125311.721989] 0000000000000001 0000000000000019 0000000000000000 ffff88407fc639a8
> > >> >> > [125311.721991] Call Trace:
> > >> >> > [125311.721992] <IRQ> [<ffffffff816bb9cc>] dump_stack+0x19/0x1d
> > >> >> > [125311.722002] [<ffffffff8104b940>] warn_slowpath_common+0x70/0xa0
> > >> >> > [125311.722005] [<ffffffff8104b98a>] warn_slowpath_null+0x1a/0x20
> > >> >> > [125311.722007] [<ffffffff81616db8>] tcp_fastretrans_alert+0xb58/0xc80
> > >> >> > [125311.722011] [<ffffffff8161891f>] tcp_ack+0x6df/0xe90
> > >> >> > [125311.722016] [<ffffffff8164e0ca>] ? ipt_do_table+0x22a/0x680
> > >> >> > [125311.722018] [<ffffffff816194b3>] ? tcp_validate_incoming+0x63/0x320
> > >> >> > [125311.722021] [<ffffffff8161a55c>] tcp_rcv_established+0x2cc/0x810
> > >> >> > [125311.722023] [<ffffffff81622c84>] tcp_v4_do_rcv+0x254/0x4f0
> > >> >> > [125311.722025] [<ffffffff816245ac>] tcp_v4_rcv+0x5fc/0x750
> > >> >> > [125311.722027] [<ffffffff815ffa00>] ? ip_rcv+0x350/0x350
> > >> >> > [125311.722032] [<ffffffff815df3ad>] ? nf_hook_slow+0x7d/0x160
> > >> >> > [125311.722034] [<ffffffff815ffa00>] ? ip_rcv+0x350/0x350
> > >> >> > [125311.722036] [<ffffffff815fface>] ip_local_deliver_finish+0xce/0x250
> > >> >> > [125311.722037] [<ffffffff815ffc9c>] ip_local_deliver+0x4c/0x80
> > >> >> > [125311.722039] [<ffffffff815ff329>] ip_rcv_finish+0x119/0x360
> > >> >> > [125311.722040] [<ffffffff815ff8e0>] ip_rcv+0x230/0x350
> > >> >> > [125311.722046] [<ffffffff815b4067>] __netif_receive_skb_core+0x477/0x600
> > >> >> > [125311.722049] [<ffffffff815b4217>] __netif_receive_skb+0x27/0x70
> > >> >> > [125311.722051] [<ffffffff815b4354>] process_backlog+0xf4/0x1e0
> > >> >> > [125311.722053] [<ffffffff815b4b45>] net_rx_action+0xf5/0x250
> > >> >> > [125311.722056] [<ffffffff81053a5f>] __do_softirq+0xef/0x270
> > >> >> > [125311.722058] [<ffffffff81053cb5>] irq_exit+0x95/0xa0
> > >> >> > [125311.722062] [<ffffffff816c8f26>] do_IRQ+0x66/0xe0
> > >> >> > [125311.722065] [<ffffffff816bf62a>] common_interrupt+0x6a/0x6a
> > >> >> > [125311.722065] <EOI> [<ffffffff8100abf1>] ? default_idle+0x21/0xc0
> > >> >> > [125311.722082] [<ffffffff8100a54f>] arch_cpu_idle+0xf/0x20
> > >> >> > [125311.722086] [<ffffffff8108f353>] cpu_startup_entry+0xb3/0x230
> > >> >> > [125311.722091] [<ffffffff816b439e>] start_secondary+0x1dc/0x1e3
> > >> >> > [125311.722093] ---[ end trace e77cd5ba583fcbe9 ]---
> > >> >> > [125311.722096] 355.355.1.355:22496 F0x4120 S1 s7 IF25+17-1-24f0 ur57 rr3 rt0 um0 hs23120 nxt23120
> > >> >> >
> > >> >> > It's been happening with all 3.10 kernels, and the one above is .13 as
> > >> >> > stated in the trace.
> > >> >>
> > >> >> Thanks! could you post the output of `sysctl -a |grep tcp`?
> > >> >>
> > >> >> I suspect tcp_process_tlp_ack() should not revert state to Open
> > >> >> directly, but calling tcp_try_keep_open() instead, similar to all the
> > >> >> undo processing in the tcp_fastretrans_alert(): after
> > >> >> tcp_end_cwnd_reduction(), the process (E) falls back to check other
> > >> >> stats before moving to CA_Open.
> > >> >>
> > >> >>
> > >> >> index 9c62257..9012b42 100644
> > >> >> --- a/net/ipv4/tcp_input.c
> > >> >> +++ b/net/ipv4/tcp_input.c
> > >> >> @@ -3314,7 +3314,7 @@ static void tcp_process_tlp_ack(struct sock *sk, u32 ack,
> > >> >> tcp_init_cwnd_reduction(sk, true);
> > >> >> tcp_set_ca_state(sk, TCP_CA_CWR);
> > >> >> tcp_end_cwnd_reduction(sk);
> > >> >> - tcp_set_ca_state(sk, TCP_CA_Open);
> > >> >> + tcp_try_keep_open(sk);
> > >> >> NET_INC_STATS_BH(sock_net(sk),
> > >> >> LINUX_MIB_TCPLOSSPROBERECOVERY);
> > >> >> }
> > >> >>
> > >> >
> > >> > Should I apply this and see if the warning stops?
> Hi Dormando,
>
> Could you try this patch to make sure it fixes the warning (with
> sysctl net.ipv4.early_retrans=3)?
It's now running on one machine, with early_retrans=3. Will have to give
it 24 hours to confirm.
> > >> I'd like to hear what the authors of TLP think. In the mean time could
> > >> you help us collect more evidence by disabling TLP with
> > >> sysctl net.ipv4.tcp_early_retrans=2
> > >> and see if the problem still occurs? (it should not).
> > >>
> > >> thanks
> > >
> > > Box hasn't had a warning in the last 24ish hours. A neighboring machine
> > > with the default tcp_early_retrans setting has had 5-6 in the same
> > > timeframe.
> > >
> > > Is this a harmful situation to the socket in any way, or is it just
> > > informational weirdness?
> > It should be fairly harmless. The ack that triggers the warning should
> > set the TCP back to the good (non-Open) state, but it's still good to
> > get rid of.
>
^ permalink raw reply
* Re: pull request: batman-adv 2013-10-09
From: David Miller @ 2013-10-09 18:53 UTC (permalink / raw)
To: antonio; +Cc: netdev, b.a.t.m.a.n
In-Reply-To: <20131009.135652.2086284751199593695.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Wed, 09 Oct 2013 13:56:52 -0400 (EDT)
> Pulled, thanks.
Please don't send me stuff that doesn't build:
net/batman-adv/translation-table.c: In function ‘batadv_send_roam_adv’:
net/batman-adv/translation-table.c:2210:49: warning: left-hand operand of comma expression has no effect [-Wunused-value]
net/batman-adv/translation-table.c:2211:21: warning: left-hand operand of comma expression has no effect [-Wunused-value]
net/batman-adv/translation-table.c:2210:6: warning: statement with no effect [-Wunused-value]
net/batman-adv/translation-table.c:2211:29: error: expected ‘;’ before ‘)’ token
net/batman-adv/translation-table.c:2211:29: error: expected statement before ‘)’ toke
That looks like:
/* before going on we have to check whether the client has
* already roamed to us too many times
*/
if (!batadv_tt_check_roam_count(bat_priv, client))
goto out;
"Sending ROAMING_ADV to %pM (client %pM)\n",
orig_node->orig, client);
Looks like a merge problem to me.
^ permalink raw reply
* Re: [PATCH net-next] bnx2x: Add ndo_get_phys_port_id support
From: David Miller @ 2013-10-09 18:55 UTC (permalink / raw)
To: yuvalmin; +Cc: netdev, ariele, eilong
In-Reply-To: <1381327588-11137-1-git-send-email-yuvalmin@broadcom.com>
From: "Yuval Mintz" <yuvalmin@broadcom.com>
Date: Wed, 9 Oct 2013 16:06:28 +0200
> Each network interface (either PF or VF) is identified by its port's MAC id.
>
> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
> Signed-off-by: Ariel Elior <ariele@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
> ---
> Hi Dave,
>
> Please consider applying this patch to 'net-next'.
Applied, thanks Yuval.
^ permalink raw reply
* Re: pull request: batman-adv 2013-10-09
From: Antonio Quartulli @ 2013-10-09 19:01 UTC (permalink / raw)
To: David Miller; +Cc: netdev, b.a.t.m.a.n
In-Reply-To: <20131009.145306.1949528592789606941.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 1395 bytes --]
On Wed, Oct 09, 2013 at 02:53:06PM -0400, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 09 Oct 2013 13:56:52 -0400 (EDT)
>
> > Pulled, thanks.
>
> Please don't send me stuff that doesn't build:
>
> net/batman-adv/translation-table.c: In function ‘batadv_send_roam_adv’:
> net/batman-adv/translation-table.c:2210:49: warning: left-hand operand of comma expression has no effect [-Wunused-value]
> net/batman-adv/translation-table.c:2211:21: warning: left-hand operand of comma expression has no effect [-Wunused-value]
> net/batman-adv/translation-table.c:2210:6: warning: statement with no effect [-Wunused-value]
> net/batman-adv/translation-table.c:2211:29: error: expected ‘;’ before ‘)’ token
> net/batman-adv/translation-table.c:2211:29: error: expected statement before ‘)’ toke
>
> That looks like:
>
> /* before going on we have to check whether the client has
> * already roamed to us too many times
> */
> if (!batadv_tt_check_roam_count(bat_priv, client))
> goto out;
>
> "Sending ROAMING_ADV to %pM (client %pM)\n",
> orig_node->orig, client);
>
> Looks like a merge problem to me.
Oh damn. Sorry David.
I have probably done something wrong during my last rebase on top net-next.
I'll fix, double check and resend the pull request.
Regards,
--
Antonio Quartulli
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH nf-next] netfilter: xtables: lightweight process control group matching
From: Daniel Borkmann @ 2013-10-09 19:12 UTC (permalink / raw)
To: Tejun Heo; +Cc: pablo, netfilter-devel, netdev, cgroups
In-Reply-To: <20131009170409.GH22495@htj.dyndns.org>
On 10/09/2013 07:04 PM, Tejun Heo wrote:
> Hello,
>
> On Tue, Oct 08, 2013 at 10:05:02AM +0200, Daniel Borkmann wrote:
>> Could you elaborate on "Wouldn't it be more logical to implement netfilter
>> rule to match the target cgroup paths?". I don't think (or hope) you mean
>> some string comparison on the dentry path here? :) With our proposal, we
>> have in the network stack's critical path only the following code that is
>> being executed here to match the cgroup ...
>
> Comparing path each time obviously doesn't make sense but you can
> determine the cgroup on config and hold onto the pointer while the
> rule exists.
>
>> ... where ``info->id == skb->sk->sk_cgrp_fwid'' is the actual work, so very
>> lightweight, which is good for high loads (1Gbit/s, 10Gbit/s and beyond), of
>> course. Also, it would be intuitive for admins familiar with other subsystems
>> to just set up and use these cgroup ids in iptabels. I'm not yet quite sure
>> how your suggestion would look like, so you would need to setup some "dummy"
>> subgroups first just to have a path that you can match on?
>
> Currently, it's tricky because we have multiple hierarchies to
> consider and there isn't an efficient way to map from task to cgroup
> on a specific hierarchy. I'm not sure whether we should add another
> mapping table in css_set or just allow using path matching on the
> unified hierarchy. The latter should be cleaner and easier but more
> restrictive.
>
> Anyways, it isn't manageable in the long term to keep adding
> controllers simply to tag tasks differently. If we want to do this,
> let's please work on a way to match a task's cgroup affiliation
> efficiently.
Agreed, let us solve that first, and then I go back to the netfilter module
to bring netfilter and cgroups together.
Thanks,
Daniel
^ permalink raw reply
* Re: [PATCH] net: sh_eth: Fix RX packets errors on R8A7740
From: Sergei Shtylyov @ 2013-10-09 20:27 UTC (permalink / raw)
To: Simon Horman; +Cc: David Miller, nh-ky, netdev, ryusuke.sakato.bx
In-Reply-To: <20131009042454.GA16885@verge.net.au>
Hello.
On 09-10-2013 6:24, Simon Horman wrote:
>>> This patch will fix RX packets errors when receiving big size of data.
>>> Moreover, I set suitable parameters for get more stable when receiving
>>> packets.
>>> It was created on the top of mainline kernel v3.11.
>>> I tested this patch on Armadillo800eva, it appears to be working well.
>>> Would you please review and apply it for me.
>> Applied, but at some point someone has to add definitions for the
>> RMCR register fields so that this driver is not full of magic constants.
> Sergei, would it be possible for you to address this?
Yes, perhaps, if I won't forget.
WBR, Sergei
^ permalink raw reply
* pull request: batman-adv 2013-10-09b
From: Antonio Quartulli @ 2013-10-09 19:32 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n
Hello David,
here you have my fixed pull request intended for net-next.
The previous build error was due to an accidental remotion of the beginning of a
batadv_dbg() statement during a merge conflict resolution.
Sorry for that.
Please pull or let me know of any problem.
Thanks a lot,
Antonio
The following changes since commit 3d7d562ca4a884089344eb13451b5903a18d3817:
bnx2x: Add ndo_get_phys_port_id support (2013-10-09 14:55:13 -0400)
are available in the git repository at:
git://git.open-mesh.org/linux-merge.git tags/batman-adv-for-davem
for you to fetch changes up to 18c68d5960c8dfeb2db113f4b871bab259cfd565:
batman-adv: reorder batadv_iv_flags (2013-10-09 21:22:35 +0200)
----------------------------------------------------------------
Included changes:
- update emails for A. Quartulli and M. Lindner in MAINTAINERS
- switch to the next on-the-wire protocol version
- introduce the T(ype) V(ersion) L(ength) V(alue) framework
- adjust the existing components to make them use the new TVLV code
- make the TT component use CRC32 instead of CRC16
- totally remove the VIS functionality (has been moved to userspace)
- reorder packet types and flags
- add static checks on packet format
- remove __packed from batadv_ogm_packet
----------------------------------------------------------------
Antonio Quartulli (4):
MAINTAINERS: batman-adv - update emails
batman-adv: switch to a new packet compatibility version
batman-adv: use CRC32C instead of CRC16 in TT code
batman-adv: move BATADV_TT_CLIENT_TEMP to higher bit
Marek Lindner (7):
batman-adv: tvlv - basic infrastructure
batman-adv: tvlv - gateway download/upload bandwidth container
batman-adv: tvlv - add distributed arp table container
batman-adv: tvlv - add network coding container
batman-adv: tvlv - convert tt data sent within OGMs
batman-adv: tvlv - convert tt query packet to use tvlv unicast packets
batman-adv: tvlv - convert roaming adv packet to use tvlv unicast packets
Simon Wunderlich (5):
batman-adv: remove vis functionality
batman-adv: add build check macros for packet member offset
batman-adv: reorder packet types
batman-adv: remove packed from batadv_ogm_packet
batman-adv: reorder batadv_iv_flags
Documentation/ABI/testing/sysfs-class-net-mesh | 11 -
Documentation/networking/batman-adv.txt | 50 +-
MAINTAINERS | 4 +-
net/batman-adv/Makefile | 1 -
net/batman-adv/bat_iv_ogm.c | 111 +--
net/batman-adv/debugfs.c | 9 -
net/batman-adv/distributed-arp-table.c | 64 ++
net/batman-adv/distributed-arp-table.h | 5 +
net/batman-adv/gateway_client.c | 187 +++--
net/batman-adv/gateway_client.h | 2 +-
net/batman-adv/gateway_common.c | 230 +++---
net/batman-adv/gateway_common.h | 14 +-
net/batman-adv/hard-interface.c | 9 -
net/batman-adv/main.c | 623 +++++++++++++++-
net/batman-adv/main.h | 37 +-
net/batman-adv/network-coding.c | 63 ++
net/batman-adv/network-coding.h | 5 +
net/batman-adv/originator.c | 4 +-
net/batman-adv/packet.h | 248 ++++---
net/batman-adv/routing.c | 247 ++-----
net/batman-adv/routing.h | 6 +-
net/batman-adv/send.c | 1 -
net/batman-adv/soft-interface.c | 4 +-
net/batman-adv/sysfs.c | 96 +--
net/batman-adv/translation-table.c | 905 ++++++++++++++----------
net/batman-adv/translation-table.h | 13 +-
net/batman-adv/types.h | 178 ++---
net/batman-adv/vis.c | 938 -------------------------
net/batman-adv/vis.h | 36 -
29 files changed, 1968 insertions(+), 2133 deletions(-)
delete mode 100644 net/batman-adv/vis.c
delete mode 100644 net/batman-adv/vis.h
^ permalink raw reply
* [PATCH 01/16] MAINTAINERS: batman-adv - update emails
From: Antonio Quartulli @ 2013-10-09 19:32 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <1381347174-3629-1-git-send-email-antonio@meshcoding.com>
Update my and Marek Lindner's email in the MAINTAINERS file
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
MAINTAINERS | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 43dfc82..7a86b44 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1652,9 +1652,9 @@ F: drivers/video/backlight/
F: include/linux/backlight.h
BATMAN ADVANCED
-M: Marek Lindner <lindner_marek@yahoo.de>
+M: Marek Lindner <mareklindner@neomailbox.ch>
M: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
-M: Antonio Quartulli <ordex@autistici.org>
+M: Antonio Quartulli <antonio@meshcoding.com>
L: b.a.t.m.a.n@lists.open-mesh.org
W: http://www.open-mesh.org/
S: Maintained
--
1.8.3.2
^ permalink raw reply related
* [PATCH 02/16] batman-adv: switch to a new packet compatibility version
From: Antonio Quartulli @ 2013-10-09 19:32 UTC (permalink / raw)
To: davem
Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Simon Wunderlich,
Marek Lindner, Martin Hundebøll
In-Reply-To: <1381347174-3629-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <ordex@autistici.org>
With this change batman-adv is breaking compatibility with
older versions and it is moving to compat-version 15.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Martin Hundebøll <martin@hundeboll.net>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/packet.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index a51ccfc..11a22c8 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -48,7 +48,7 @@ enum batadv_subtype {
};
/* this file is included by batctl which needs these defines */
-#define BATADV_COMPAT_VERSION 14
+#define BATADV_COMPAT_VERSION 15
enum batadv_iv_flags {
BATADV_NOT_BEST_NEXT_HOP = BIT(3),
--
1.8.3.2
^ permalink raw reply related
* [PATCH 05/16] batman-adv: tvlv - add distributed arp table container
From: Antonio Quartulli @ 2013-10-09 19:32 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Marek Lindner, Antonio Quartulli
In-Reply-To: <1381347174-3629-1-git-send-email-antonio@meshcoding.com>
From: Marek Lindner <lindner_marek@yahoo.de>
Create DAT container to announce DAT capabilities (if enabled).
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
net/batman-adv/distributed-arp-table.c | 64 ++++++++++++++++++++++++++++++++++
net/batman-adv/distributed-arp-table.h | 5 +++
net/batman-adv/packet.h | 2 ++
net/batman-adv/sysfs.c | 3 +-
net/batman-adv/types.h | 10 ++++++
5 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 06345d4..f07ec32 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -419,6 +419,10 @@ static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res,
bool ret = false;
int j;
+ /* check if orig node candidate is running DAT */
+ if (!(candidate->capabilities & BATADV_ORIG_CAPA_HAS_DAT))
+ goto out;
+
/* Check if this node has already been selected... */
for (j = 0; j < select; j++)
if (res[j].orig_node == candidate)
@@ -626,6 +630,59 @@ out:
}
/**
+ * batadv_dat_tvlv_container_update - update the dat tvlv container after dat
+ * setting change
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_dat_tvlv_container_update(struct batadv_priv *bat_priv)
+{
+ char dat_mode;
+
+ dat_mode = atomic_read(&bat_priv->distributed_arp_table);
+
+ switch (dat_mode) {
+ case 0:
+ batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1);
+ break;
+ case 1:
+ batadv_tvlv_container_register(bat_priv, BATADV_TVLV_DAT, 1,
+ NULL, 0);
+ break;
+ }
+}
+
+/**
+ * batadv_dat_status_update - update the dat tvlv container after dat
+ * setting change
+ * @net_dev: the soft interface net device
+ */
+void batadv_dat_status_update(struct net_device *net_dev)
+{
+ struct batadv_priv *bat_priv = netdev_priv(net_dev);
+ batadv_dat_tvlv_container_update(bat_priv);
+}
+
+/**
+ * batadv_gw_tvlv_ogm_handler_v1 - process incoming dat tvlv container
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: the orig_node of the ogm
+ * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
+ * @tvlv_value: tvlv buffer containing the gateway data
+ * @tvlv_value_len: tvlv buffer length
+ */
+static void batadv_dat_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig,
+ uint8_t flags,
+ void *tvlv_value,
+ uint16_t tvlv_value_len)
+{
+ if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
+ orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_DAT;
+ else
+ orig->capabilities |= BATADV_ORIG_CAPA_HAS_DAT;
+}
+
+/**
* batadv_dat_hash_free - free the local DAT hash table
* @bat_priv: the bat priv with all the soft interface information
*/
@@ -657,6 +714,10 @@ int batadv_dat_init(struct batadv_priv *bat_priv)
batadv_dat_start_timer(bat_priv);
+ batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1,
+ NULL, BATADV_TVLV_DAT, 1,
+ BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
+ batadv_dat_tvlv_container_update(bat_priv);
return 0;
}
@@ -666,6 +727,9 @@ int batadv_dat_init(struct batadv_priv *bat_priv)
*/
void batadv_dat_free(struct batadv_priv *bat_priv)
{
+ batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1);
+ batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_DAT, 1);
+
cancel_delayed_work_sync(&bat_priv->dat.work);
batadv_dat_hash_free(bat_priv);
diff --git a/net/batman-adv/distributed-arp-table.h b/net/batman-adv/distributed-arp-table.h
index 125c8c6..60d853b 100644
--- a/net/batman-adv/distributed-arp-table.h
+++ b/net/batman-adv/distributed-arp-table.h
@@ -29,6 +29,7 @@
#define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0)
+void batadv_dat_status_update(struct net_device *net_dev);
bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
struct sk_buff *skb);
bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
@@ -98,6 +99,10 @@ static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv,
#else
+static inline void batadv_dat_status_update(struct net_device *net_dev)
+{
+}
+
static inline bool
batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
struct sk_buff *skb)
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 6d0b3a7..8d470b2 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -121,9 +121,11 @@ enum batadv_bla_claimframe {
/**
* enum batadv_tvlv_type - tvlv type definitions
* @BATADV_TVLV_GW: gateway tvlv
+ * @BATADV_TVLV_DAT: distributed arp table tvlv
*/
enum batadv_tvlv_type {
BATADV_TVLV_GW = 0x01,
+ BATADV_TVLV_DAT = 0x02,
};
/* the destination hardware field in the ARP frame is used to
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 68793f5..e1a826e 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -425,7 +425,8 @@ BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
#endif
#ifdef CONFIG_BATMAN_ADV_DAT
-BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR, NULL);
+BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR,
+ batadv_dat_status_update);
#endif
BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index b22a043..35ce834 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -100,6 +100,7 @@ struct batadv_hard_iface {
* @bcast_seqno_reset: time when the broadcast seqno window was reset
* @batman_seqno_reset: time when the batman seqno window was reset
* @flags: for now only VIS_SERVER flag
+ * @capabilities: announced capabilities of this originator
* @last_ttvn: last seen translation table version number
* @tt_crc: CRC of the translation table
* @tt_buff: last tt changeset this node received from the orig node
@@ -147,6 +148,7 @@ struct batadv_orig_node {
unsigned long bcast_seqno_reset;
unsigned long batman_seqno_reset;
uint8_t flags;
+ uint8_t capabilities;
atomic_t last_ttvn;
uint16_t tt_crc;
unsigned char *tt_buff;
@@ -184,6 +186,14 @@ struct batadv_orig_node {
};
/**
+ * enum batadv_orig_capabilities - orig node capabilities
+ * @BATADV_ORIG_CAPA_HAS_DAT: orig node has distributed arp table enabled
+ */
+enum batadv_orig_capabilities {
+ BATADV_ORIG_CAPA_HAS_DAT = BIT(0),
+};
+
+/**
* struct batadv_gw_node - structure for orig nodes announcing gw capabilities
* @list: list node for batadv_priv_gw::list
* @orig_node: pointer to corresponding orig node
--
1.8.3.2
^ permalink raw reply related
* [PATCH 04/16] batman-adv: tvlv - gateway download/upload bandwidth container
From: Antonio Quartulli @ 2013-10-09 19:32 UTC (permalink / raw)
To: davem
Cc: netdev, b.a.t.m.a.n, Marek Lindner, Spyros Gasteratos,
Antonio Quartulli
In-Reply-To: <1381347174-3629-1-git-send-email-antonio@meshcoding.com>
From: Marek Lindner <lindner_marek@yahoo.de>
Prior to this patch batman-adv read the advertised uplink bandwidth
from userspace and compressed this information into a single byte
called "gateway class".
Now the download & upload bandwidth information is sent as-is. No
userspace change is necessary since the sysfs API always allowed
to specify a bandwidth.
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Spyros Gasteratos <morfeas3000@gmail.com>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
net/batman-adv/bat_iv_ogm.c | 23 +---
net/batman-adv/gateway_client.c | 197 +++++++++++++++++++++-------------
net/batman-adv/gateway_client.h | 2 +-
net/batman-adv/gateway_common.c | 230 +++++++++++++++++++++++++---------------
net/batman-adv/gateway_common.h | 14 ++-
net/batman-adv/main.c | 5 +
net/batman-adv/originator.c | 4 +-
net/batman-adv/packet.h | 21 +++-
net/batman-adv/soft-interface.c | 3 +-
net/batman-adv/sysfs.c | 15 ++-
net/batman-adv/types.h | 12 ++-
11 files changed, 331 insertions(+), 195 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index f7dd7e5..f0f02d1 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -135,6 +135,7 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
batadv_ogm_packet->header.ttl = 2;
batadv_ogm_packet->flags = BATADV_NO_FLAGS;
+ batadv_ogm_packet->reserved = 0;
batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
batadv_ogm_packet->tt_num_changes = 0;
batadv_ogm_packet->ttvn = 0;
@@ -690,7 +691,6 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
int vis_server, tt_num_changes = 0;
uint32_t seqno;
- uint8_t bandwidth;
uint16_t tvlv_len = 0;
vis_server = atomic_read(&bat_priv->vis_mode);
@@ -719,14 +719,6 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
else
batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
- if (hard_iface == primary_if &&
- atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) {
- bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
- batadv_ogm_packet->gw_flags = bandwidth;
- } else {
- batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
- }
-
batadv_iv_ogm_slide_own_bcast_window(hard_iface);
batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
@@ -861,19 +853,6 @@ update_tt:
batadv_ogm_packet->tt_num_changes,
batadv_ogm_packet->ttvn,
ntohs(batadv_ogm_packet->tt_crc));
-
- if (orig_node->gw_flags != batadv_ogm_packet->gw_flags)
- batadv_gw_node_update(bat_priv, orig_node,
- batadv_ogm_packet->gw_flags);
-
- orig_node->gw_flags = batadv_ogm_packet->gw_flags;
-
- /* restart gateway selection if fast or late switching was enabled */
- if ((orig_node->gw_flags) &&
- (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
- (atomic_read(&bat_priv->gw_sel_class) > 2))
- batadv_gw_check_election(bat_priv, orig_node);
-
goto out;
unlock:
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 1ce4b87..1bce63a 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -118,7 +118,6 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
uint32_t gw_divisor;
uint8_t max_tq = 0;
- int down, up;
uint8_t tq_avg;
struct batadv_orig_node *orig_node;
@@ -142,10 +141,9 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
switch (atomic_read(&bat_priv->gw_sel_class)) {
case 1: /* fast connection */
- batadv_gw_bandwidth_to_kbit(orig_node->gw_flags,
- &down, &up);
-
- tmp_gw_factor = tq_avg * tq_avg * down * 100 * 100;
+ tmp_gw_factor = tq_avg * tq_avg;
+ tmp_gw_factor *= gw_node->bandwidth_down;
+ tmp_gw_factor *= 100 * 100;
tmp_gw_factor /= gw_divisor;
if ((tmp_gw_factor > max_gw_factor) ||
@@ -258,16 +256,22 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
NULL);
} else if ((!curr_gw) && (next_gw)) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "Adding route to gateway %pM (gw_flags: %i, tq: %i)\n",
+ "Adding route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
next_gw->orig_node->orig,
- next_gw->orig_node->gw_flags, router->tq_avg);
+ next_gw->bandwidth_down / 10,
+ next_gw->bandwidth_down % 10,
+ next_gw->bandwidth_up / 10,
+ next_gw->bandwidth_up % 10, router->tq_avg);
batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
gw_addr);
} else {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "Changing route to gateway %pM (gw_flags: %i, tq: %i)\n",
+ "Changing route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
next_gw->orig_node->orig,
- next_gw->orig_node->gw_flags, router->tq_avg);
+ next_gw->bandwidth_down / 10,
+ next_gw->bandwidth_down % 10,
+ next_gw->bandwidth_up / 10,
+ next_gw->bandwidth_up % 10, router->tq_avg);
batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
gw_addr);
}
@@ -337,12 +341,20 @@ out:
return;
}
+/**
+ * batadv_gw_node_add - add gateway node to list of available gateways
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: originator announcing gateway capabilities
+ * @gateway: announced bandwidth information
+ */
static void batadv_gw_node_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- uint8_t new_gwflags)
+ struct batadv_tvlv_gateway_data *gateway)
{
struct batadv_gw_node *gw_node;
- int down, up;
+
+ if (gateway->bandwidth_down == 0)
+ return;
gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC);
if (!gw_node)
@@ -356,73 +368,116 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list);
spin_unlock_bh(&bat_priv->gw.list_lock);
- batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up);
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n",
- orig_node->orig, new_gwflags,
- (down > 2048 ? down / 1024 : down),
- (down > 2048 ? "MBit" : "KBit"),
- (up > 2048 ? up / 1024 : up),
- (up > 2048 ? "MBit" : "KBit"));
+ "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
+ orig_node->orig,
+ ntohl(gateway->bandwidth_down) / 10,
+ ntohl(gateway->bandwidth_down) % 10,
+ ntohl(gateway->bandwidth_up) / 10,
+ ntohl(gateway->bandwidth_up) % 10);
}
+/**
+ * batadv_gw_node_get - retrieve gateway node from list of available gateways
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: originator announcing gateway capabilities
+ *
+ * Returns gateway node if found or NULL otherwise.
+ */
+static struct batadv_gw_node *
+batadv_gw_node_get(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig_node)
+{
+ struct batadv_gw_node *gw_node_tmp, *gw_node = NULL;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(gw_node_tmp, &bat_priv->gw.list, list) {
+ if (gw_node_tmp->orig_node != orig_node)
+ continue;
+
+ if (gw_node_tmp->deleted)
+ continue;
+
+ if (!atomic_inc_not_zero(&gw_node_tmp->refcount))
+ continue;
+
+ gw_node = gw_node_tmp;
+ break;
+ }
+ rcu_read_unlock();
+
+ return gw_node;
+}
+
+/**
+ * batadv_gw_node_update - update list of available gateways with changed
+ * bandwidth information
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: originator announcing gateway capabilities
+ * @gateway: announced bandwidth information
+ */
void batadv_gw_node_update(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- uint8_t new_gwflags)
+ struct batadv_tvlv_gateway_data *gateway)
{
- struct batadv_gw_node *gw_node, *curr_gw;
+ struct batadv_gw_node *gw_node, *curr_gw = NULL;
- /* Note: We don't need a NULL check here, since curr_gw never gets
- * dereferenced. If curr_gw is NULL we also should not exit as we may
- * have this gateway in our list (duplication check!) even though we
- * have no currently selected gateway.
- */
- curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
+ gw_node = batadv_gw_node_get(bat_priv, orig_node);
+ if (!gw_node) {
+ batadv_gw_node_add(bat_priv, orig_node, gateway);
+ goto out;
+ }
- rcu_read_lock();
- hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
- if (gw_node->orig_node != orig_node)
- continue;
+ if ((gw_node->bandwidth_down == ntohl(gateway->bandwidth_down)) &&
+ (gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)))
+ goto out;
+ batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+ "Gateway bandwidth of originator %pM changed from %u.%u/%u.%u MBit to %u.%u/%u.%u MBit\n",
+ orig_node->orig,
+ gw_node->bandwidth_down / 10,
+ gw_node->bandwidth_down % 10,
+ gw_node->bandwidth_up / 10,
+ gw_node->bandwidth_up % 10,
+ ntohl(gateway->bandwidth_down) / 10,
+ ntohl(gateway->bandwidth_down) % 10,
+ ntohl(gateway->bandwidth_up) / 10,
+ ntohl(gateway->bandwidth_up) % 10);
+
+ gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
+ gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
+
+ gw_node->deleted = 0;
+ if (ntohl(gateway->bandwidth_down) == 0) {
+ gw_node->deleted = jiffies;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "Gateway class of originator %pM changed from %i to %i\n",
- orig_node->orig, gw_node->orig_node->gw_flags,
- new_gwflags);
-
- gw_node->deleted = 0;
-
- if (new_gwflags == BATADV_NO_FLAGS) {
- gw_node->deleted = jiffies;
- batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "Gateway %pM removed from gateway list\n",
- orig_node->orig);
-
- if (gw_node == curr_gw)
- goto deselect;
- }
-
- goto unlock;
+ "Gateway %pM removed from gateway list\n",
+ orig_node->orig);
+
+ /* Note: We don't need a NULL check here, since curr_gw never
+ * gets dereferenced.
+ */
+ curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
+ if (gw_node == curr_gw)
+ batadv_gw_deselect(bat_priv);
}
- if (new_gwflags == BATADV_NO_FLAGS)
- goto unlock;
-
- batadv_gw_node_add(bat_priv, orig_node, new_gwflags);
- goto unlock;
-
-deselect:
- batadv_gw_deselect(bat_priv);
-unlock:
- rcu_read_unlock();
-
+out:
if (curr_gw)
batadv_gw_node_free_ref(curr_gw);
+ if (gw_node)
+ batadv_gw_node_free_ref(gw_node);
}
void batadv_gw_node_delete(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node)
{
- batadv_gw_node_update(bat_priv, orig_node, 0);
+ struct batadv_tvlv_gateway_data gateway;
+
+ gateway.bandwidth_down = 0;
+ gateway.bandwidth_up = 0;
+
+ batadv_gw_node_update(bat_priv, orig_node, &gateway);
}
void batadv_gw_node_purge(struct batadv_priv *bat_priv)
@@ -467,9 +522,7 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
{
struct batadv_gw_node *curr_gw;
struct batadv_neigh_node *router;
- int down, up, ret = -1;
-
- batadv_gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
+ int ret = -1;
router = batadv_orig_node_get_router(gw_node->orig_node);
if (!router)
@@ -477,16 +530,15 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
- ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
+ ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
(curr_gw == gw_node ? "=>" : " "),
gw_node->orig_node->orig,
router->tq_avg, router->addr,
router->if_incoming->net_dev->name,
- gw_node->orig_node->gw_flags,
- (down > 2048 ? down / 1024 : down),
- (down > 2048 ? "MBit" : "KBit"),
- (up > 2048 ? up / 1024 : up),
- (up > 2048 ? "MBit" : "KBit"));
+ gw_node->bandwidth_down / 10,
+ gw_node->bandwidth_down % 10,
+ gw_node->bandwidth_up / 10,
+ gw_node->bandwidth_up % 10);
batadv_neigh_node_free_ref(router);
if (curr_gw)
@@ -508,7 +560,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
goto out;
seq_printf(seq,
- " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
+ " %-12s (%s/%i) %17s [%10s]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
"Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF",
BATADV_SOURCE_VERSION, primary_if->net_dev->name,
primary_if->net_dev->dev_addr, net_dev->name);
@@ -675,7 +727,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
{
struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL;
struct batadv_orig_node *orig_dst_node = NULL;
- struct batadv_gw_node *curr_gw = NULL;
+ struct batadv_gw_node *gw_node = NULL, *curr_gw = NULL;
struct ethhdr *ethhdr;
bool ret, out_of_range = false;
unsigned int header_len = 0;
@@ -691,7 +743,8 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
if (!orig_dst_node)
goto out;
- if (!orig_dst_node->gw_flags)
+ gw_node = batadv_gw_node_get(bat_priv, orig_dst_node);
+ if (!gw_node->bandwidth_down == 0)
goto out;
ret = batadv_is_type_dhcprequest(skb, header_len);
@@ -742,6 +795,8 @@ out:
batadv_orig_node_free_ref(orig_dst_node);
if (curr_gw)
batadv_gw_node_free_ref(curr_gw);
+ if (gw_node)
+ batadv_gw_node_free_ref(gw_node);
if (neigh_old)
batadv_neigh_node_free_ref(neigh_old);
if (neigh_curr)
diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h
index ceef4eb..d95c2d2 100644
--- a/net/batman-adv/gateway_client.h
+++ b/net/batman-adv/gateway_client.h
@@ -29,7 +29,7 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node);
void batadv_gw_node_update(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- uint8_t new_gwflags);
+ struct batadv_tvlv_gateway_data *gateway);
void batadv_gw_node_delete(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node);
void batadv_gw_node_purge(struct batadv_priv *bat_priv);
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index 84bb2b1..b211b0f 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -21,64 +21,23 @@
#include "gateway_common.h"
#include "gateway_client.h"
-/* calculates the gateway class from kbit */
-static void batadv_kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class)
-{
- int mdown = 0, tdown, tup, difference;
- uint8_t sbit, part;
-
- *gw_srv_class = 0;
- difference = 0x0FFFFFFF;
-
- /* test all downspeeds */
- for (sbit = 0; sbit < 2; sbit++) {
- for (part = 0; part < 16; part++) {
- tdown = 32 * (sbit + 2) * (1 << part);
-
- if (abs(tdown - down) < difference) {
- *gw_srv_class = (sbit << 7) + (part << 3);
- difference = abs(tdown - down);
- mdown = tdown;
- }
- }
- }
-
- /* test all upspeeds */
- difference = 0x0FFFFFFF;
-
- for (part = 0; part < 8; part++) {
- tup = ((part + 1) * (mdown)) / 8;
-
- if (abs(tup - up) < difference) {
- *gw_srv_class = (*gw_srv_class & 0xF8) | part;
- difference = abs(tup - up);
- }
- }
-}
-
-/* returns the up and downspeeds in kbit, calculated from the class */
-void batadv_gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up)
-{
- int sbit = (gw_srv_class & 0x80) >> 7;
- int dpart = (gw_srv_class & 0x78) >> 3;
- int upart = (gw_srv_class & 0x07);
-
- if (!gw_srv_class) {
- *down = 0;
- *up = 0;
- return;
- }
-
- *down = 32 * (sbit + 2) * (1 << dpart);
- *up = ((upart + 1) * (*down)) / 8;
-}
-
+/**
+ * batadv_parse_gw_bandwidth - parse supplied string buffer to extract download
+ * and upload bandwidth information
+ * @net_dev: the soft interface net device
+ * @buff: string buffer to parse
+ * @down: pointer holding the returned download bandwidth information
+ * @up: pointer holding the returned upload bandwidth information
+ *
+ * Returns false on parse error and true otherwise.
+ */
static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
- int *up, int *down)
+ uint32_t *down, uint32_t *up)
{
- int ret, multi = 1;
+ enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT;
char *slash_ptr, *tmp_ptr;
long ldown, lup;
+ int ret;
slash_ptr = strchr(buff, '/');
if (slash_ptr)
@@ -88,10 +47,10 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
tmp_ptr = buff + strlen(buff) - 4;
if (strnicmp(tmp_ptr, "mbit", 4) == 0)
- multi = 1024;
+ bw_unit_type = BATADV_BW_UNIT_MBIT;
if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
- (multi > 1))
+ (bw_unit_type == BATADV_BW_UNIT_MBIT))
*tmp_ptr = '\0';
}
@@ -103,20 +62,28 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
return false;
}
- *down = ldown * multi;
+ switch (bw_unit_type) {
+ case BATADV_BW_UNIT_MBIT:
+ *down = ldown * 10;
+ break;
+ case BATADV_BW_UNIT_KBIT:
+ default:
+ *down = ldown / 100;
+ break;
+ }
/* we also got some upload info */
if (slash_ptr) {
- multi = 1;
+ bw_unit_type = BATADV_BW_UNIT_KBIT;
if (strlen(slash_ptr + 1) > 4) {
tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1);
if (strnicmp(tmp_ptr, "mbit", 4) == 0)
- multi = 1024;
+ bw_unit_type = BATADV_BW_UNIT_MBIT;
if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
- (multi > 1))
+ (bw_unit_type == BATADV_BW_UNIT_MBIT))
*tmp_ptr = '\0';
}
@@ -128,52 +95,149 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
return false;
}
- *up = lup * multi;
+ switch (bw_unit_type) {
+ case BATADV_BW_UNIT_MBIT:
+ *up = lup * 10;
+ break;
+ case BATADV_BW_UNIT_KBIT:
+ default:
+ *up = lup / 100;
+ break;
+ }
}
return true;
}
+/**
+ * batadv_gw_tvlv_container_update - update the gw tvlv container after gateway
+ * setting change
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
+{
+ struct batadv_tvlv_gateway_data gw;
+ uint32_t down, up;
+ char gw_mode;
+
+ gw_mode = atomic_read(&bat_priv->gw_mode);
+
+ switch (gw_mode) {
+ case BATADV_GW_MODE_OFF:
+ case BATADV_GW_MODE_CLIENT:
+ batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
+ break;
+ case BATADV_GW_MODE_SERVER:
+ down = atomic_read(&bat_priv->gw.bandwidth_down);
+ up = atomic_read(&bat_priv->gw.bandwidth_up);
+ gw.bandwidth_down = htonl(down);
+ gw.bandwidth_up = htonl(up);
+ batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1,
+ &gw, sizeof(gw));
+ break;
+ }
+}
+
ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
size_t count)
{
struct batadv_priv *bat_priv = netdev_priv(net_dev);
- long gw_bandwidth_tmp = 0;
- int up = 0, down = 0;
+ uint32_t down_curr, up_curr, down_new = 0, up_new = 0;
bool ret;
- ret = batadv_parse_gw_bandwidth(net_dev, buff, &up, &down);
+ down_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_down);
+ up_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_up);
+
+ ret = batadv_parse_gw_bandwidth(net_dev, buff, &down_new, &up_new);
if (!ret)
goto end;
- if ((!down) || (down < 256))
- down = 2000;
+ if (!down_new)
+ down_new = 1;
- if (!up)
- up = down / 5;
+ if (!up_new)
+ up_new = down_new / 5;
- batadv_kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp);
+ if (!up_new)
+ up_new = 1;
- /* the gw bandwidth we guessed above might not match the given
- * speeds, hence we need to calculate it back to show the number
- * that is going to be propagated
- */
- batadv_gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up);
-
- if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp)
+ if ((down_curr == down_new) && (up_curr == up_new))
return count;
batadv_gw_deselect(bat_priv);
batadv_info(net_dev,
- "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n",
- atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp,
- (down > 2048 ? down / 1024 : down),
- (down > 2048 ? "MBit" : "KBit"),
- (up > 2048 ? up / 1024 : up),
- (up > 2048 ? "MBit" : "KBit"));
+ "Changing gateway bandwidth from: '%u.%u/%u.%u MBit' to: '%u.%u/%u.%u MBit'\n",
+ down_curr / 10, down_curr % 10, up_curr / 10, up_curr % 10,
+ down_new / 10, down_new % 10, up_new / 10, up_new % 10);
- atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp);
+ atomic_set(&bat_priv->gw.bandwidth_down, down_new);
+ atomic_set(&bat_priv->gw.bandwidth_up, up_new);
+ batadv_gw_tvlv_container_update(bat_priv);
end:
return count;
}
+
+/**
+ * batadv_gw_tvlv_ogm_handler_v1 - process incoming gateway tvlv container
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: the orig_node of the ogm
+ * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
+ * @tvlv_value: tvlv buffer containing the gateway data
+ * @tvlv_value_len: tvlv buffer length
+ */
+static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig,
+ uint8_t flags,
+ void *tvlv_value,
+ uint16_t tvlv_value_len)
+{
+ struct batadv_tvlv_gateway_data gateway, *gateway_ptr;
+
+ /* only fetch the tvlv value if the handler wasn't called via the
+ * CIFNOTFND flag and if there is data to fetch
+ */
+ if ((flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) ||
+ (tvlv_value_len < sizeof(gateway))) {
+ gateway.bandwidth_down = 0;
+ gateway.bandwidth_up = 0;
+ } else {
+ gateway_ptr = tvlv_value;
+ gateway.bandwidth_down = gateway_ptr->bandwidth_down;
+ gateway.bandwidth_up = gateway_ptr->bandwidth_up;
+ if ((gateway.bandwidth_down == 0) ||
+ (gateway.bandwidth_up == 0)) {
+ gateway.bandwidth_down = 0;
+ gateway.bandwidth_up = 0;
+ }
+ }
+
+ batadv_gw_node_update(bat_priv, orig, &gateway);
+
+ /* restart gateway selection if fast or late switching was enabled */
+ if ((gateway.bandwidth_down != 0) &&
+ (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
+ (atomic_read(&bat_priv->gw_sel_class) > 2))
+ batadv_gw_check_election(bat_priv, orig);
+}
+
+/**
+ * batadv_gw_init - initialise the gateway handling internals
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_gw_init(struct batadv_priv *bat_priv)
+{
+ batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
+ NULL, BATADV_TVLV_GW, 1,
+ BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
+}
+
+/**
+ * batadv_gw_free - free the gateway handling internals
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_gw_free(struct batadv_priv *bat_priv)
+{
+ batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
+ batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_GW, 1);
+}
diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h
index 509b2bf..56384a4 100644
--- a/net/batman-adv/gateway_common.h
+++ b/net/batman-adv/gateway_common.h
@@ -26,12 +26,24 @@ enum batadv_gw_modes {
BATADV_GW_MODE_SERVER,
};
+/**
+ * enum batadv_bandwidth_units - bandwidth unit types
+ * @BATADV_BW_UNIT_KBIT: unit type kbit
+ * @BATADV_BW_UNIT_MBIT: unit type mbit
+ */
+enum batadv_bandwidth_units {
+ BATADV_BW_UNIT_KBIT,
+ BATADV_BW_UNIT_MBIT,
+};
+
#define BATADV_GW_MODE_OFF_NAME "off"
#define BATADV_GW_MODE_CLIENT_NAME "client"
#define BATADV_GW_MODE_SERVER_NAME "server"
-void batadv_gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up);
ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
size_t count);
+void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv);
+void batadv_gw_init(struct batadv_priv *bat_priv);
+void batadv_gw_free(struct batadv_priv *bat_priv);
#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index e2de68a..cb9a446 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -37,6 +37,7 @@
#include "bridge_loop_avoidance.h"
#include "distributed-arp-table.h"
#include "unicast.h"
+#include "gateway_common.h"
#include "vis.h"
#include "hash.h"
#include "bat_algo.h"
@@ -152,6 +153,8 @@ int batadv_mesh_init(struct net_device *soft_iface)
if (ret < 0)
goto err;
+ batadv_gw_init(bat_priv);
+
atomic_set(&bat_priv->gw.reselect, 0);
atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
@@ -190,6 +193,8 @@ void batadv_mesh_free(struct net_device *soft_iface)
*/
batadv_originator_free(bat_priv);
+ batadv_gw_free(bat_priv);
+
free_percpu(bat_priv->bat_counters);
bat_priv->bat_counters = NULL;
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index f50553a..5d53d2f 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -388,9 +388,7 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
hlist_for_each_entry_safe(orig_node, node_tmp,
head, hash_entry) {
if (batadv_purge_orig_node(bat_priv, orig_node)) {
- if (orig_node->gw_flags)
- batadv_gw_node_delete(bat_priv,
- orig_node);
+ batadv_gw_node_delete(bat_priv, orig_node);
hlist_del_rcu(&orig_node->hash_entry);
batadv_orig_node_free_ref(orig_node);
continue;
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index b5c21c4..6d0b3a7 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -118,6 +118,14 @@ enum batadv_bla_claimframe {
BATADV_CLAIM_TYPE_REQUEST = 0x03,
};
+/**
+ * enum batadv_tvlv_type - tvlv type definitions
+ * @BATADV_TVLV_GW: gateway tvlv
+ */
+enum batadv_tvlv_type {
+ BATADV_TVLV_GW = 0x01,
+};
+
/* the destination hardware field in the ARP frame is used to
* transport the claim type and the group id
*/
@@ -147,7 +155,7 @@ struct batadv_ogm_packet {
__be32 seqno;
uint8_t orig[ETH_ALEN];
uint8_t prev_sender[ETH_ALEN];
- uint8_t gw_flags; /* flags related to gateway class */
+ uint8_t reserved;
uint8_t tq;
uint8_t tt_num_changes;
uint8_t ttvn; /* translation table version number */
@@ -352,4 +360,15 @@ struct batadv_tvlv_hdr {
__be16 len;
};
+/**
+ * struct batadv_tvlv_gateway_data - gateway data propagated through gw tvlv
+ * container
+ * @bandwidth_down: advertised uplink download bandwidth
+ * @bandwidth_up: advertised uplink upload bandwidth
+ */
+struct batadv_tvlv_gateway_data {
+ __be32 bandwidth_down;
+ __be32 bandwidth_up;
+};
+
#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 813db4e..84623a9 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -472,7 +472,8 @@ static int batadv_softif_init_late(struct net_device *dev)
atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
atomic_set(&bat_priv->gw_sel_class, 20);
- atomic_set(&bat_priv->gw_bandwidth, 41);
+ atomic_set(&bat_priv->gw.bandwidth_down, 100);
+ atomic_set(&bat_priv->gw.bandwidth_up, 20);
atomic_set(&bat_priv->orig_interval, 1000);
atomic_set(&bat_priv->hop_penalty, 30);
#ifdef CONFIG_BATMAN_ADV_DEBUG
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 4114b96..68793f5 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -390,6 +390,7 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
*/
batadv_gw_check_client_stop(bat_priv);
atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
+ batadv_gw_tvlv_container_update(bat_priv);
return count;
}
@@ -397,15 +398,13 @@ static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
struct attribute *attr, char *buff)
{
struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
- int down, up;
- int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth);
+ uint32_t down, up;
- batadv_gw_bandwidth_to_kbit(gw_bandwidth, &down, &up);
- return sprintf(buff, "%i%s/%i%s\n",
- (down > 2048 ? down / 1024 : down),
- (down > 2048 ? "MBit" : "KBit"),
- (up > 2048 ? up / 1024 : up),
- (up > 2048 ? "MBit" : "KBit"));
+ down = atomic_read(&bat_priv->gw.bandwidth_down);
+ up = atomic_read(&bat_priv->gw.bandwidth_up);
+
+ return sprintf(buff, "%u.%u/%u.%u MBit\n", down / 10,
+ down % 10, up / 10, up % 10);
}
static ssize_t batadv_store_gw_bwidth(struct kobject *kobj,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 4bdea16..b22a043 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -99,7 +99,6 @@ struct batadv_hard_iface {
* @last_seen: time when last packet from this node was received
* @bcast_seqno_reset: time when the broadcast seqno window was reset
* @batman_seqno_reset: time when the batman seqno window was reset
- * @gw_flags: flags related to gateway class
* @flags: for now only VIS_SERVER flag
* @last_ttvn: last seen translation table version number
* @tt_crc: CRC of the translation table
@@ -147,7 +146,6 @@ struct batadv_orig_node {
unsigned long last_seen;
unsigned long bcast_seqno_reset;
unsigned long batman_seqno_reset;
- uint8_t gw_flags;
uint8_t flags;
atomic_t last_ttvn;
uint16_t tt_crc;
@@ -189,6 +187,8 @@ struct batadv_orig_node {
* struct batadv_gw_node - structure for orig nodes announcing gw capabilities
* @list: list node for batadv_priv_gw::list
* @orig_node: pointer to corresponding orig node
+ * @bandwidth_down: advertised uplink download bandwidth
+ * @bandwidth_up: advertised uplink upload bandwidth
* @deleted: this struct is scheduled for deletion
* @refcount: number of contexts the object is used
* @rcu: struct used for freeing in an RCU-safe manner
@@ -196,6 +196,8 @@ struct batadv_orig_node {
struct batadv_gw_node {
struct hlist_node list;
struct batadv_orig_node *orig_node;
+ uint32_t bandwidth_down;
+ uint32_t bandwidth_up;
unsigned long deleted;
atomic_t refcount;
struct rcu_head rcu;
@@ -420,12 +422,16 @@ struct batadv_priv_debug_log {
* @list: list of available gateway nodes
* @list_lock: lock protecting gw_list & curr_gw
* @curr_gw: pointer to currently selected gateway node
+ * @bandwidth_down: advertised uplink download bandwidth (if gw_mode server)
+ * @bandwidth_up: advertised uplink upload bandwidth (if gw_mode server)
* @reselect: bool indicating a gateway re-selection is in progress
*/
struct batadv_priv_gw {
struct hlist_head list;
spinlock_t list_lock; /* protects gw_list & curr_gw */
struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
+ atomic_t bandwidth_down;
+ atomic_t bandwidth_up;
atomic_t reselect;
};
@@ -521,7 +527,6 @@ struct batadv_priv_nc {
* @vis_mode: vis operation: client or server (see batadv_vis_packettype)
* @gw_mode: gateway operation: off, client or server (see batadv_gw_modes)
* @gw_sel_class: gateway selection class (applies if gw_mode client)
- * @gw_bandwidth: gateway announced bandwidth (applies if gw_mode server)
* @orig_interval: OGM broadcast interval in milliseconds
* @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop
* @log_level: configured log level (see batadv_dbg_level)
@@ -569,7 +574,6 @@ struct batadv_priv {
atomic_t vis_mode;
atomic_t gw_mode;
atomic_t gw_sel_class;
- atomic_t gw_bandwidth;
atomic_t orig_interval;
atomic_t hop_penalty;
#ifdef CONFIG_BATMAN_ADV_DEBUG
--
1.8.3.2
^ permalink raw reply related
* [PATCH 06/16] batman-adv: tvlv - add network coding container
From: Antonio Quartulli @ 2013-10-09 19:32 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Marek Lindner, Antonio Quartulli
In-Reply-To: <1381347174-3629-1-git-send-email-antonio@meshcoding.com>
From: Marek Lindner <lindner_marek@yahoo.de>
Create network coding container to announce network coding
capabilities (if enabled).
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
net/batman-adv/network-coding.c | 63 +++++++++++++++++++++++++++++++++++++++++
net/batman-adv/network-coding.h | 5 ++++
net/batman-adv/packet.h | 2 ++
net/batman-adv/sysfs.c | 4 ++-
net/batman-adv/types.h | 2 ++
5 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index 4ecc0b6..23f611b 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -59,6 +59,59 @@ static void batadv_nc_start_timer(struct batadv_priv *bat_priv)
}
/**
+ * batadv_nc_tvlv_container_update - update the network coding tvlv container
+ * after network coding setting change
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_nc_tvlv_container_update(struct batadv_priv *bat_priv)
+{
+ char nc_mode;
+
+ nc_mode = atomic_read(&bat_priv->network_coding);
+
+ switch (nc_mode) {
+ case 0:
+ batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_NC, 1);
+ break;
+ case 1:
+ batadv_tvlv_container_register(bat_priv, BATADV_TVLV_NC, 1,
+ NULL, 0);
+ break;
+ }
+}
+
+/**
+ * batadv_nc_status_update - update the network coding tvlv container after
+ * network coding setting change
+ * @net_dev: the soft interface net device
+ */
+void batadv_nc_status_update(struct net_device *net_dev)
+{
+ struct batadv_priv *bat_priv = netdev_priv(net_dev);
+ batadv_nc_tvlv_container_update(bat_priv);
+}
+
+/**
+ * batadv_nc_tvlv_ogm_handler_v1 - process incoming nc tvlv container
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: the orig_node of the ogm
+ * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
+ * @tvlv_value: tvlv buffer containing the gateway data
+ * @tvlv_value_len: tvlv buffer length
+ */
+static void batadv_nc_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig,
+ uint8_t flags,
+ void *tvlv_value,
+ uint16_t tvlv_value_len)
+{
+ if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
+ orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_NC;
+ else
+ orig->capabilities |= BATADV_ORIG_CAPA_HAS_NC;
+}
+
+/**
* batadv_nc_mesh_init - initialise coding hash table and start house keeping
* @bat_priv: the bat priv with all the soft interface information
*/
@@ -87,6 +140,10 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv)
INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker);
batadv_nc_start_timer(bat_priv);
+ batadv_tvlv_handler_register(bat_priv, batadv_nc_tvlv_ogm_handler_v1,
+ NULL, BATADV_TVLV_NC, 1,
+ BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
+ batadv_nc_tvlv_container_update(bat_priv);
return 0;
err:
@@ -802,6 +859,10 @@ void batadv_nc_update_nc_node(struct batadv_priv *bat_priv,
if (!atomic_read(&bat_priv->network_coding))
goto out;
+ /* check if orig node is network coding enabled */
+ if (!(orig_node->capabilities & BATADV_ORIG_CAPA_HAS_NC))
+ goto out;
+
/* accept ogms from 'good' neighbors and single hop neighbors */
if (!batadv_can_nc_with_orig(bat_priv, orig_node, ogm_packet) &&
!is_single_hop_neigh)
@@ -1735,6 +1796,8 @@ free_nc_packet:
*/
void batadv_nc_mesh_free(struct batadv_priv *bat_priv)
{
+ batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_NC, 1);
+ batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_NC, 1);
cancel_delayed_work_sync(&bat_priv->nc.work);
batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash, NULL);
diff --git a/net/batman-adv/network-coding.h b/net/batman-adv/network-coding.h
index ddfa618..d4fd315 100644
--- a/net/batman-adv/network-coding.h
+++ b/net/batman-adv/network-coding.h
@@ -22,6 +22,7 @@
#ifdef CONFIG_BATMAN_ADV_NC
+void batadv_nc_status_update(struct net_device *net_dev);
int batadv_nc_init(void);
int batadv_nc_mesh_init(struct batadv_priv *bat_priv);
void batadv_nc_mesh_free(struct batadv_priv *bat_priv);
@@ -47,6 +48,10 @@ int batadv_nc_init_debugfs(struct batadv_priv *bat_priv);
#else /* ifdef CONFIG_BATMAN_ADV_NC */
+static inline void batadv_nc_status_update(struct net_device *net_dev)
+{
+}
+
static inline int batadv_nc_init(void)
{
return 0;
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 8d470b2..55deb4d 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -122,10 +122,12 @@ enum batadv_bla_claimframe {
* enum batadv_tvlv_type - tvlv type definitions
* @BATADV_TVLV_GW: gateway tvlv
* @BATADV_TVLV_DAT: distributed arp table tvlv
+ * @BATADV_TVLV_NC: network coding tvlv
*/
enum batadv_tvlv_type {
BATADV_TVLV_GW = 0x01,
BATADV_TVLV_DAT = 0x02,
+ BATADV_TVLV_NC = 0x03,
};
/* the destination hardware field in the ARP frame is used to
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index e1a826e..fbc1c25 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -21,6 +21,7 @@
#include "sysfs.h"
#include "translation-table.h"
#include "distributed-arp-table.h"
+#include "network-coding.h"
#include "originator.h"
#include "hard-interface.h"
#include "gateway_common.h"
@@ -447,7 +448,8 @@ static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
#endif
#ifdef CONFIG_BATMAN_ADV_NC
-BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR, NULL);
+BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR,
+ batadv_nc_status_update);
#endif
static struct batadv_attribute *batadv_mesh_attrs[] = {
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 35ce834..fa5cb0d 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -188,9 +188,11 @@ struct batadv_orig_node {
/**
* enum batadv_orig_capabilities - orig node capabilities
* @BATADV_ORIG_CAPA_HAS_DAT: orig node has distributed arp table enabled
+ * @BATADV_ORIG_CAPA_HAS_NC: orig node has network coding enabled
*/
enum batadv_orig_capabilities {
BATADV_ORIG_CAPA_HAS_DAT = BIT(0),
+ BATADV_ORIG_CAPA_HAS_NC = BIT(1),
};
/**
--
1.8.3.2
^ permalink raw reply related
* [PATCH 07/16] batman-adv: tvlv - convert tt data sent within OGMs
From: Antonio Quartulli @ 2013-10-09 19:32 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Marek Lindner, Antonio Quartulli
In-Reply-To: <1381347174-3629-1-git-send-email-antonio@meshcoding.com>
From: Marek Lindner <lindner_marek@yahoo.de>
The translation table meta data (version number, crc checksum, etc)
as well as the translation table diff propgated within OGMs now uses
the newly introduced tvlv infrastructure.
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
net/batman-adv/bat_iv_ogm.c | 44 +++----
net/batman-adv/packet.h | 51 ++++++--
net/batman-adv/translation-table.c | 240 ++++++++++++++++++++-----------------
net/batman-adv/translation-table.h | 8 +-
net/batman-adv/types.h | 2 +-
5 files changed, 187 insertions(+), 158 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index f0f02d1..871ba67 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -137,8 +137,6 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
batadv_ogm_packet->flags = BATADV_NO_FLAGS;
batadv_ogm_packet->reserved = 0;
batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
- batadv_ogm_packet->tt_num_changes = 0;
- batadv_ogm_packet->ttvn = 0;
res = 0;
@@ -257,14 +255,14 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
fwd_str = "Sending own";
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n",
+ "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s) on interface %s [%pM]\n",
fwd_str, (packet_num > 0 ? "aggregated " : ""),
batadv_ogm_packet->orig,
ntohl(batadv_ogm_packet->seqno),
batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl,
(batadv_ogm_packet->flags & BATADV_DIRECTLINK ?
"on" : "off"),
- batadv_ogm_packet->ttvn, hard_iface->net_dev->name,
+ hard_iface->net_dev->name,
hard_iface->net_dev->dev_addr);
buff_pos += BATADV_OGM_HLEN;
@@ -689,17 +687,22 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
struct batadv_ogm_packet *batadv_ogm_packet;
struct batadv_hard_iface *primary_if;
int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
- int vis_server, tt_num_changes = 0;
+ int vis_server;
uint32_t seqno;
uint16_t tvlv_len = 0;
vis_server = atomic_read(&bat_priv->vis_mode);
primary_if = batadv_primary_if_get_selected(bat_priv);
- if (hard_iface == primary_if)
+ if (hard_iface == primary_if) {
+ /* tt changes have to be committed before the tvlv data is
+ * appended as it may alter the tt tvlv container
+ */
+ batadv_tt_local_commit_changes(bat_priv);
tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
ogm_buff_len,
BATADV_OGM_HLEN);
+ }
batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
batadv_ogm_packet->tvlv_len = htons(tvlv_len);
@@ -709,11 +712,6 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
batadv_ogm_packet->seqno = htonl(seqno);
atomic_inc(&hard_iface->bat_iv.ogm_seqno);
- batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
- batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
- if (tt_num_changes >= 0)
- batadv_ogm_packet->tt_num_changes = tt_num_changes;
-
if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC)
batadv_ogm_packet->flags |= BATADV_VIS_SERVER;
else
@@ -814,11 +812,11 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
*/
router = batadv_orig_node_get_router(orig_node);
if (router == neigh_node)
- goto update_tt;
+ goto out;
/* if this neighbor does not offer a better TQ we won't consider it */
if (router && (router->tq_avg > neigh_node->tq_avg))
- goto update_tt;
+ goto out;
/* if the TQ is the same and the link not more symmetric we
* won't consider it either
@@ -837,22 +835,10 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
if (sum_orig >= sum_neigh)
- goto update_tt;
+ goto out;
}
batadv_update_route(bat_priv, orig_node, neigh_node);
-
-update_tt:
- /* I have to check for transtable changes only if the OGM has been
- * sent through a primary interface
- */
- if (((batadv_ogm_packet->orig != ethhdr->h_source) &&
- (batadv_ogm_packet->header.ttl > 2)) ||
- (batadv_ogm_packet->flags & BATADV_PRIMARIES_FIRST_HOP))
- batadv_tt_update_orig(bat_priv, orig_node, tt_buff,
- batadv_ogm_packet->tt_num_changes,
- batadv_ogm_packet->ttvn,
- ntohs(batadv_ogm_packet->tt_crc));
goto out;
unlock:
@@ -1103,13 +1089,11 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
is_single_hop_neigh = true;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %#.4x, changes %u, tq %d, TTL %d, V %d, IDF %d)\n",
+ "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, tq %d, TTL %d, V %d, IDF %d)\n",
ethhdr->h_source, if_incoming->net_dev->name,
if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig,
batadv_ogm_packet->prev_sender,
- ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->ttvn,
- ntohs(batadv_ogm_packet->tt_crc),
- batadv_ogm_packet->tt_num_changes, batadv_ogm_packet->tq,
+ ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->tq,
batadv_ogm_packet->header.ttl,
batadv_ogm_packet->header.version, has_directlink_flag);
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 55deb4d..cd59fcc 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -86,14 +86,21 @@ enum batadv_unicast_frag_flags {
/* TT_QUERY subtypes */
#define BATADV_TT_QUERY_TYPE_MASK 0x3
-enum batadv_tt_query_packettype {
- BATADV_TT_REQUEST = 0,
- BATADV_TT_RESPONSE = 1,
-};
+/* tt data subtypes */
+#define BATADV_TT_DATA_TYPE_MASK 0x0F
-/* TT_QUERY flags */
-enum batadv_tt_query_flags {
- BATADV_TT_FULL_TABLE = BIT(2),
+/**
+ * enum batadv_tt_data_flags - flags for tt data tvlv
+ * @BATADV_TT_OGM_DIFF: TT diff propagated through OGM
+ * @BATADV_TT_REQUEST: TT request message
+ * @BATADV_TT_RESPONSE: TT response message
+ * @BATADV_TT_FULL_TABLE: contains full table to replace existing table
+ */
+enum batadv_tt_data_flags {
+ BATADV_TT_OGM_DIFF = BIT(0),
+ BATADV_TT_REQUEST = BIT(1),
+ BATADV_TT_RESPONSE = BIT(2),
+ BATADV_TT_FULL_TABLE = BIT(4),
};
/* BATADV_TT_CLIENT flags.
@@ -123,11 +130,13 @@ enum batadv_bla_claimframe {
* @BATADV_TVLV_GW: gateway tvlv
* @BATADV_TVLV_DAT: distributed arp table tvlv
* @BATADV_TVLV_NC: network coding tvlv
+ * @BATADV_TVLV_TT: translation table tvlv
*/
enum batadv_tvlv_type {
BATADV_TVLV_GW = 0x01,
BATADV_TVLV_DAT = 0x02,
BATADV_TVLV_NC = 0x03,
+ BATADV_TVLV_TT = 0x04,
};
/* the destination hardware field in the ARP frame is used to
@@ -161,9 +170,6 @@ struct batadv_ogm_packet {
uint8_t prev_sender[ETH_ALEN];
uint8_t reserved;
uint8_t tq;
- uint8_t tt_num_changes;
- uint8_t ttvn; /* translation table version number */
- __be16 tt_crc;
__be16 tvlv_len;
} __packed;
@@ -375,4 +381,29 @@ struct batadv_tvlv_gateway_data {
__be32 bandwidth_up;
};
+/**
+ * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container
+ * @flags: translation table flags (see batadv_tt_data_flags)
+ * @ttvn: translation table version number
+ * @crc: crc16 checksum of the local translation table
+ */
+struct batadv_tvlv_tt_data {
+ uint8_t flags;
+ uint8_t ttvn;
+ __be16 crc;
+};
+
+/**
+ * struct batadv_tvlv_tt_change - translation table diff data
+ * @flags: status indicators concerning the non-mesh client (see
+ * batadv_tt_client_flags)
+ * @reserved: reserved field
+ * @addr: mac address of non-mesh client that triggered this tt change
+ */
+struct batadv_tvlv_tt_change {
+ uint8_t flags;
+ uint8_t reserved;
+ uint8_t addr[ETH_ALEN];
+};
+
#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 34510f3..3fac67f 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -180,11 +180,11 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
bool del_op_requested, del_op_entry;
tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
-
if (!tt_change_node)
return;
tt_change_node->change.flags = flags;
+ tt_change_node->change.reserved = 0;
memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
del_op_requested = flags & BATADV_TT_CLIENT_DEL;
@@ -376,71 +376,52 @@ out:
batadv_tt_global_entry_free_ref(tt_global);
}
-static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff,
- int *packet_buff_len,
- int min_packet_len,
- int new_packet_len)
+/**
+ * batadv_tt_tvlv_container_update - update the translation table tvlv container
+ * after local tt changes have been committed
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
{
- unsigned char *new_buff;
+ struct batadv_tt_change_node *entry, *safe;
+ struct batadv_tvlv_tt_data *tt_data;
+ struct batadv_tvlv_tt_change *tt_change;
+ int tt_diff_len = 0, tt_change_len = 0;
+ int tt_diff_entries_num = 0, tt_diff_entries_count = 0;
- new_buff = kmalloc(new_packet_len, GFP_ATOMIC);
-
- /* keep old buffer if kmalloc should fail */
- if (new_buff) {
- memcpy(new_buff, *packet_buff, min_packet_len);
- kfree(*packet_buff);
- *packet_buff = new_buff;
- *packet_buff_len = new_packet_len;
- }
-}
-
-static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv,
- unsigned char **packet_buff,
- int *packet_buff_len,
- int min_packet_len)
-{
- int req_len;
-
- req_len = min_packet_len;
- req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
+ tt_diff_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
/* if we have too many changes for one packet don't send any
* and wait for the tt table request which will be fragmented
*/
- if (req_len > bat_priv->soft_iface->mtu)
- req_len = min_packet_len;
+ if (tt_diff_len > bat_priv->soft_iface->mtu)
+ tt_diff_len = 0;
- batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
- min_packet_len, req_len);
-}
+ tt_data = kzalloc(sizeof(*tt_data) + tt_diff_len, GFP_ATOMIC);
+ if (!tt_data)
+ return;
-static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
- unsigned char **packet_buff,
- int *packet_buff_len,
- int min_packet_len)
-{
- struct batadv_tt_change_node *entry, *safe;
- int count = 0, tot_changes = 0, new_len;
- unsigned char *tt_buff;
+ tt_data->flags = BATADV_TT_OGM_DIFF;
+ tt_data->ttvn = atomic_read(&bat_priv->tt.vn);
+ tt_data->crc = htons(bat_priv->tt.local_crc);
- batadv_tt_prepare_packet_buff(bat_priv, packet_buff,
- packet_buff_len, min_packet_len);
+ if (tt_diff_len == 0)
+ goto container_register;
- new_len = *packet_buff_len - min_packet_len;
- tt_buff = *packet_buff + min_packet_len;
-
- if (new_len > 0)
- tot_changes = new_len / batadv_tt_len(1);
+ tt_diff_entries_num = tt_diff_len / batadv_tt_len(1);
spin_lock_bh(&bat_priv->tt.changes_list_lock);
atomic_set(&bat_priv->tt.local_changes, 0);
+ tt_change = (struct batadv_tvlv_tt_change *)(tt_data + 1);
+
list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
list) {
- if (count < tot_changes) {
- memcpy(tt_buff + batadv_tt_len(count),
- &entry->change, sizeof(struct batadv_tt_change));
- count++;
+ if (tt_diff_entries_count < tt_diff_entries_num) {
+ memcpy(tt_change + tt_diff_entries_count,
+ &entry->change,
+ sizeof(struct batadv_tvlv_tt_change));
+ tt_diff_entries_count++;
}
list_del(&entry->list);
kfree(entry);
@@ -452,20 +433,25 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
kfree(bat_priv->tt.last_changeset);
bat_priv->tt.last_changeset_len = 0;
bat_priv->tt.last_changeset = NULL;
+ tt_change_len = batadv_tt_len(tt_diff_entries_count);
/* check whether this new OGM has no changes due to size problems */
- if (new_len > 0) {
+ if (tt_diff_entries_count > 0) {
/* if kmalloc() fails we will reply with the full table
* instead of providing the diff
*/
- bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC);
+ bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC);
if (bat_priv->tt.last_changeset) {
- memcpy(bat_priv->tt.last_changeset, tt_buff, new_len);
- bat_priv->tt.last_changeset_len = new_len;
+ memcpy(bat_priv->tt.last_changeset,
+ tt_change, tt_change_len);
+ bat_priv->tt.last_changeset_len = tt_diff_len;
}
}
spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
- return count;
+container_register:
+ batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
+ sizeof(*tt_data) + tt_change_len);
+ kfree(tt_data);
}
int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
@@ -1504,7 +1490,7 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
const unsigned char *tt_buff,
- uint8_t tt_num_changes)
+ uint16_t tt_num_changes)
{
uint16_t tt_buff_len = batadv_tt_len(tt_num_changes);
@@ -2126,25 +2112,6 @@ out:
batadv_orig_node_free_ref(orig_node);
}
-int batadv_tt_init(struct batadv_priv *bat_priv)
-{
- int ret;
-
- ret = batadv_tt_local_init(bat_priv);
- if (ret < 0)
- return ret;
-
- ret = batadv_tt_global_init(bat_priv);
- if (ret < 0)
- return ret;
-
- INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
- queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
- msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
-
- return 1;
-}
-
static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
{
struct batadv_tt_roam_node *node, *safe;
@@ -2297,6 +2264,9 @@ static void batadv_tt_purge(struct work_struct *work)
void batadv_tt_free(struct batadv_priv *bat_priv)
{
+ batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1);
+ batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1);
+
cancel_delayed_work_sync(&bat_priv->tt.work);
batadv_tt_local_table_free(bat_priv);
@@ -2384,14 +2354,20 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
}
}
-static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
- unsigned char **packet_buff,
- int *packet_buff_len, int packet_min_len)
+/**
+ * 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)
{
uint16_t changed_num = 0;
- if (atomic_read(&bat_priv->tt.local_changes) < 1)
- return -ENOENT;
+ 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);
+ return;
+ }
changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash,
BATADV_TT_CLIENT_NEW, false);
@@ -2409,32 +2385,7 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
/* reset the sending counter */
atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
-
- return batadv_tt_changes_fill_buff(bat_priv, packet_buff,
- packet_buff_len, packet_min_len);
-}
-
-/* when calling this function (hard_iface == primary_if) has to be true */
-int batadv_tt_append_diff(struct batadv_priv *bat_priv,
- unsigned char **packet_buff, int *packet_buff_len,
- int packet_min_len)
-{
- int tt_num_changes;
-
- /* if at least one change happened */
- tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff,
- packet_buff_len,
- packet_min_len);
-
- /* if the changes have been sent often enough */
- if ((tt_num_changes < 0) &&
- (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) {
- batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
- packet_min_len, packet_min_len);
- tt_num_changes = 0;
- }
-
- return tt_num_changes;
+ batadv_tt_tvlv_container_update(bat_priv);
}
bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
@@ -2468,10 +2419,21 @@ out:
return ret;
}
-void batadv_tt_update_orig(struct batadv_priv *bat_priv,
- struct batadv_orig_node *orig_node,
- const unsigned char *tt_buff, uint8_t tt_num_changes,
- uint8_t ttvn, uint16_t tt_crc)
+/**
+ * batadv_tt_update_orig - update global translation table with new tt
+ * information received via ogms
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: the orig_node of the ogm
+ * @tt_buff: buffer holding the tt information
+ * @tt_num_changes: number of tt changes inside the tt buffer
+ * @ttvn: translation table version number of this changeset
+ * @tt_crc: crc16 checksum of orig node's translation table
+ */
+static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig_node,
+ const unsigned char *tt_buff,
+ uint16_t tt_num_changes, uint8_t ttvn,
+ uint16_t tt_crc)
{
uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
bool full_table = true;
@@ -2605,3 +2567,61 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
out:
return ret;
}
+
+/**
+ * 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
+ * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
+ * @tvlv_value: tvlv buffer containing the gateway data
+ * @tvlv_value_len: tvlv buffer length
+ */
+static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig,
+ uint8_t flags,
+ void *tvlv_value,
+ uint16_t tvlv_value_len)
+{
+ struct batadv_tvlv_tt_data *tt_data;
+ uint16_t num_entries;
+
+ if (tvlv_value_len < sizeof(*tt_data))
+ return;
+
+ tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
+ tvlv_value_len -= sizeof(*tt_data);
+
+ num_entries = tvlv_value_len / batadv_tt_len(1);
+
+ batadv_tt_update_orig(bat_priv, orig,
+ (unsigned char *)(tt_data + 1),
+ num_entries, tt_data->ttvn, ntohs(tt_data->crc));
+}
+
+/**
+ * batadv_tt_init - initialise the translation table internals
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Return 0 on success or negative error number in case of failure.
+ */
+int batadv_tt_init(struct batadv_priv *bat_priv)
+{
+ int ret;
+
+ ret = batadv_tt_local_init(bat_priv);
+ if (ret < 0)
+ return ret;
+
+ ret = batadv_tt_global_init(bat_priv);
+ if (ret < 0)
+ return ret;
+
+ batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
+ NULL, BATADV_TVLV_TT, 1, BATADV_NO_FLAGS);
+
+ INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
+ queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
+ msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
+
+ return 1;
+}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 659a3bb..a709249 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -50,13 +50,7 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv,
struct batadv_tt_query_packet *tt_response);
bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
uint8_t *dst);
-void batadv_tt_update_orig(struct batadv_priv *bat_priv,
- struct batadv_orig_node *orig_node,
- const unsigned char *tt_buff, uint8_t tt_num_changes,
- uint8_t ttvn, uint16_t tt_crc);
-int batadv_tt_append_diff(struct batadv_priv *bat_priv,
- unsigned char **packet_buff, int *packet_buff_len,
- int packet_min_len);
+void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv);
bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
uint8_t *addr);
bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index fa5cb0d..bdabbc2 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -772,7 +772,7 @@ struct batadv_tt_orig_list_entry {
*/
struct batadv_tt_change_node {
struct list_head list;
- struct batadv_tt_change change;
+ struct batadv_tvlv_tt_change change;
};
/**
--
1.8.3.2
^ 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