All of lore.kernel.org
 help / color / mirror / Atom feed
* [kbd] [PATCH] ignore all files ending in ~
From: Mike Frysinger @ 2011-10-30 23:36 UTC (permalink / raw)
  To: kbd

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 .gitignore |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/.gitignore b/.gitignore
index 4bdf45f..a3044e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+*~
 *.o
 *.1
 *.8
@@ -6,7 +7,6 @@ Makefile.in
 !po/Makefile.in
 aclocal.m4
 config.h
-config.h.in~
 config.guess
 config.status
 config.sub
-- 
1.7.6.1



^ permalink raw reply related

* [kbd] [PATCH] dvorak-ru.map: uncompress file
From: Mike Frysinger @ 2011-10-30 23:36 UTC (permalink / raw)
  To: kbd

This shouldn't be gzipped in git.

Reported-by: Ilia Pozhilov <ilyapoz@gmail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 data/keymaps/i386/dvorak/dvorak-ru.map |  Bin 2612 -> 10416 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/data/keymaps/i386/dvorak/dvorak-ru.map b/data/keymaps/i386/dvorak/dvorak-ru.map
index d85258739c8ee10c408baf991b7895170828d346..17cdf6a4e785d1c9e06d592444d24d248e95d9d6 100644
GIT binary patch
literal 10416
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

literal 2612
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
WOr8ev!y_~W=l=r>(ZfoxC;$K!SO6;k

-- 
1.7.6.1



^ permalink raw reply

* [U-Boot] [PATCH] mvsata_ide: add delay after EDMA port reset
From: Albert ARIBAUD @ 2011-10-30 23:32 UTC (permalink / raw)
  To: u-boot

Although fast SoCs like kirkwood can cope without it,
this delay is required by slower chips like orion5x.

Signed-off-by: Albert ARIBAUD <albert.u.boot@aribaud.net>
---
Commit 70c55f5ab324d43093f1c8745462d92042b7306d had introduced resetting
the EDMA port on IDE reset. This obviously worked for kirkwoods, but not
for orion5x Ed Mini V2, where it made ide_reset() fail. Adding a slight
delay after returning port from reset to normal mode made ide_reset()
work again correctly.

Please check and confirm it does not break kirkwoods!

 drivers/block/mvsata_ide.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/block/mvsata_ide.c b/drivers/block/mvsata_ide.c
index 1be395f..75defe7 100644
--- a/drivers/block/mvsata_ide.c
+++ b/drivers/block/mvsata_ide.c
@@ -122,6 +122,7 @@ static int mvsata_ide_initialize_port(struct mvsata_port_registers *port)
 	writel(MVSATA_EDMA_CMD_ATA_RST, &port->edma_cmd);
 	udelay(25); /* taken from original marvell port */
 	writel(0, &port->edma_cmd);
+	udelay(1); /* wait after reset was acked -- required for orion5x */
 
 	/* Set control IPM to 3 (no low power) and DET to 1 (initialize) */
 	control = readl(&port->scontrol);
-- 
1.7.5.4

^ permalink raw reply related

* (unknown), 
From: Mrs Mellisa Lewis. @ 2011-10-30 23:21 UTC (permalink / raw)




Contact My Lawyer For More Details,!! Barr jay mchenry for  
$14,258,000.00 tell him that i have will this money to  
you.Ref:(JJ/MMS/953/5015/GwrI/316us/uk For charity organization in  
your country.Email:(bjmfirm@fengv.com) Tel: +44703 183 9543,God Bless  
You Mrs Mellisa Lewis.

^ permalink raw reply

* Re: [B.A.T.M.A.N.] [RFC 02/11] batman-adv: add basic bridge loop avoidance code
From: Marek Lindner @ 2011-10-30 23:20 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking
In-Reply-To: <1320015072-10313-3-git-send-email-siwu@hrz.tu-chemnitz.de>


Hi,

>  * always become a backbone gw for a VLAN when there is traffic,
>    even if there are no claims, to let at least let other backbone gw
>    nodes that we are able to receive on that VLAN and avoid broadcast
>    loops.

could you give some more details on this change ? Why is it not necessary 
without VLANs ?

Regards,
Marek

^ permalink raw reply

* RE: [GIT PULL] mm: frontswap (for 3.2 window)
From: Dan Magenheimer @ 2011-10-30 23:19 UTC (permalink / raw)
  To: Johannes Weiner
  Cc: Pekka Enberg, Cyclonus J, Sasha Levin, Christoph Hellwig,
	David Rientjes, Linus Torvalds, linux-mm, LKML, Andrew Morton,
	Konrad Wilk, Jeremy Fitzhardinge, Seth Jennings, ngupta,
	Chris Mason, JBeulich, Dave Hansen, Jonathan Corbet
In-Reply-To: <20111030214748.GB3650@redhat.com>

> From: Johannes Weiner [mailto:jweiner@redhat.com]
> Subject: Re: [GIT PULL] mm: frontswap (for 3.2 window)

Hi Johannes --

Thanks for taking the time for some real technical discussion (below).

> On Fri, Oct 28, 2011 at 10:07:12AM -0700, Dan Magenheimer wrote:
> >
> > > From: Johannes Weiner [mailto:jweiner@redhat.com]
> > > Subject: Re: [GIT PULL] mm: frontswap (for 3.2 window)
> > >
> > > On Fri, Oct 28, 2011 at 06:36:03PM +0300, Pekka Enberg wrote:
> > > > On Fri, Oct 28, 2011 at 6:21 PM, Dan Magenheimer
> > > > <dan.magenheimer@oracle.com> wrote:
> > > > Looking at your patches, there's no trace that anyone outside your own
> > > > development team even looked at the patches. Why do you feel that it's
> > > > OK to ask Linus to pull them?
> > >
> > > People did look at it.
> > >
> > > In my case, the handwavy benefits did not convince me.  The handwavy
> > > 'this is useful' from just more people of the same company does not
> > > help, either.
> > >
> > > I want to see a usecase that tangibly gains from this, not just more
> > > marketing material.  Then we can talk about boring infrastructure and
> > > adding hooks to the VM.
> > >
> > > Convincing the development community of the problem you are trying to
> > > solve is the undocumented part of the process you fail to follow.
> >
> > Hi Johannes --
> >
> > First, there are several companies and several unaffiliated kernel
> > developers contributing here, building on top of frontswap.  I happen
> > to be spearheading it, and my company is backing me up.  (It
> > might be more appropriate to note that much of the resistance comes
> > from people of your company... but please let's keep our open-source
> > developer hats on and have a technical discussion rather than one
> > which pleases our respective corporate overlords.)
> 
> I didn't mean to start a mud fight about this, I only mentioned the
> part about your company because I already assume it sees value in tmem
> - it probably wouldn't fund its development otherwise.  I just tend to
> not care too much about Acks from the same company as the patch itself
> and I believe other people do the same.

Oops, sorry for mudslinging if none was intended.

Although I understand your position about Acks from the same company,
isn't that challenging the integrity of the individual's ack/review,
implying that they are not really reviewing the code with the same
intensity as if it came from another company?  Especially with
something like tmem, maybe the review is just as valid, and people
from the same company have just had more incentive to truly
understand the intent and potential of the functionality, as well as
the syntax in the code?  And maybe, on some patches, reviewers ARE
from different companies are "good buddies" and watch each others'
back and those reviews are not really complete?

So perhaps this default assumption about code review is flawed?

> > Second, have you read http://lwn.net/Articles/454795/ ?
> > If not, please do.  If yes, please explain what you don't
> > see as convincing or tangible or documented.  All of this
> > exists today as working publicly available code... it's
> > not marketing material.
> 
> I remember answering this to you in private already some time ago when
> discussing frontswap.

Yes, reading ahead, all the questions sound familiar and I thought
they were all answered (albeit some offlist).  I think the conversation
ended at that point, so I assumed any issues were resolved.

> You keep proposing a bridge and I keep asking for proof that this is
> not a bridge to nowhere.  Unless that question is answered, I am not
> interested in discussing the bridge's design.
>
> According to the LWN article, there are the following backends:
> 
> 1. Zcache: allow swapping into compressed memory
> 
> This sets aside a portion of memory which the kernel will swap
> compressed pages into upon pressure.  Now, obviously, reserving memory
> from the system for this increases the pressure in the first place,
> eating away on what space we have for anonymous memory and page cache.
> 
> Do you auto-size that region depending on workload?

Yes.  A key value of the whole transcendent memory design
is that everything is done dynamically.  That's one
reason that Nitin Gupta (author of zram) supports zcache.

> If so, how?  If not, is it documented how to size it manually?

See above.  There are some zcache policy parameters that can be
adjusted manually (currently through sysfs) so we can adjust
the defaults as necessary over time.

> Where are the performance numbers for various workloads, including
> both those that benefit from every bit of page cache and those that
> would fit into memory without zcache occupying space?

I have agreed already that more zcache measurement is warranted
(though I maintain it will get a lot more measurement merged than
it will unmerged).  So I can only answer theoretically, though
I would appreciate your comment if you disagree.

Space used for page cache is almost always opportunistic; it is
a "guess" that the page will be needed again in the future.
Frontswap only stores pages that MUST otherwise be swapped.
Swapping occurs only if the clean list is empty (or if the
MM system is too slow to respond to changes in workload).
In fact some of the pages-to-be-swapped that end up in
frontswap can be dirty page cache pages.

All of this is handled dynamically.  The kernel is still deciding
which pages to keep and which to reclaim and which to swap.
The hooks simply grab pages as they are going by.  That's
why the frontswap patch can be so simple and can have many "users"
built on top of it.

> However, looking at the zcache code, it seems it wants to allocate
> storage pages only when already trying to swap out.  Are you sure this
> works in reality?

Yes.  I'd encourage you to try it.  I'd be a fool if I tried
to guarantee that there are no bugs of course.

> 2. RAMster: allow swapping between machines in a cluster
> 
> Are there people using it?  It, too, sounds like a good idea but I
> don't see any proof it actually works as intended.

No.  I've posted the code publicly but it's still a godawful mess
and I'd be embarrassed if anyone looked at it.  But the code
does work and I've got some ideas on how to make it more
upstreamable.  If anybody seriously wants to work on it right
now, I could do that, but I'd prefer some more time alone with
it first.

Conceptually, it's just a matter of moving pages to a different
machine instead of across a hypercall interface.  All the "magic"
is in the frontswap and cleancache hooks.  They run on both
machines, both dynamically managing space (and compressing it
too).  The code uses ocfs2 for "cluster" discovery and is built
on top of a modified zcache.

> 3. Xen: allow guests to swap into the host.
> 
> The article mentions that there is code to put the guests under
> pressure and let them swap to host memory when the pressure is too
> high.  This sounds useful.
>
> Where is the code that controls the amount of pressure put on the
> guests?

See drivers/xen/xen-selfballoon.c, which was just merged at 3.1,
though there have been versions of it floating around for 2+ years.
Note there's a bug fix pending that makes the pressure a little less
aggressive.  I think it is/was submitted for the open 3.2 window.
(Note the same file manipulates the number of pages in frontswap.)
 
> Where are the performance numbers?  Surely you can construct a case
> where the initial machine sizes are not quite right and then collect
> data that demonstrates the machines are rebalancing as expected?

Yes I can.  It just works and with the right tools running, it's
even fun to watch.  Some interesting performance numbers were
published at Xen Summit 2010.  See the last few pages of:

http://oss.oracle.com/projects/tmem/dist/documentation/presentations/TranscendentMemoryXenSummit2010.pdf 

The speakers notes (so you can follow the presentation without video)
are in the same dir.

> 4. kvm: same as Xen
> 
> Apart from the questions that already apply to Xen, I remember KVM
> people in particular complaining about the synchroneous single-page
> interface that results in a hypercall per swapped page.  What happened
> to this concern?

I think we (me and the KVM people) agreed that the best way to determine
if this is a concern is to just measure it.  Sasha and Neo are working on
a KVM implementation which should make this possible (but neither wants
to invest a lot of time if frontswap isn't merged or has a clear path
to merging).

So, again, theoretically, and please argue if you disagree...
(and yes I know real measurements are better, but I think we all
know how easy it is to manipulate benchmarks so IMHO a
theoretical understanding is useful too).

What is the cost of a KVM hypercall (vmexit/vmenter) vs the cost of
swapping a page?  Clearly, reading/writing a disk is a very slow
operation, but has very little CPU overhead (though preparing a
page to be swapped via blkio is NOT very inexpensive).  But if
you are swapping, it is almost never the case that the CPU is busy,
especially on a multicore CPU.

I expect on old slow (e.g. first gen 1 core VT-x processors) this might
sometimes be measureable, but rarely an issue.  On modern processors,
I don't expect it to be significant.

BTW, it occurs to me that this is now measureable on Xen too, since
Xen tmem works now for fully-virtualized guests.  I don't have
the machines to reproduce the same experiment, but if you look at
the graphs in the Xen presentation, you can see that CPU utilization
goes up substantially, but throughput still improves.  I am almost
positive that the CPU cost of compression/decompression plus the
cost of deduplication insert/fetch exceeds the cost of a vmexit/vmenter,
so the additional cost of vmexit/vmenter will at most increase
the CPU utilization.  The real performance gain comes from avoiding
(waiting for) disk accesses.

> I would really appreciate if you could pick one of those backends and
> present them as a real and practical solution to real and practical
> problems.  With documentation on configuration and performance data of
> real workloads.  We can discuss implementation details like how memory
> is exchanged between source and destination when we come to it.
> 
> I am not asking for just more code that uses your interface, I want to
> know the real value for real people of the combination of all that
> stuff.  With proof, not just explanations of how it's supposed to
> work.

Well, the Xen implementation is by far the most mature and the
Xen presentation above is reasonably conclusive though, as always,
more measurements of more workloads would be good.

Not to get back into the mudslinging, but certain people from certain
companies try to ignore or minimize the value of Xen, so I've been
trying to emphasize the other (non-Xen, non-virtualization) code.
Personally, I think the Xen use case is sufficient by itself as it
solves a problem nobody else has ever solved (or, more precisely,
that VMware attempted to solve but, as real VMware customers will
attest, did so very poorly).

To be a good Linux kernel citizen, I've encouraged my company to hold
off on widespread support for Xen tmem until all the parts are upstream
in Linux, so there isn't a wide existing body of "proof" data.  And
releasing customer data from my employer requires an act of God.  But
private emails to Linus for cleancache seemed to convince him that
there was enough justification for cleancache.  I thought frontswap
was simpler and would be the easy part, but was clearly mistaken :-(
We are now proceeding fully with Xen tmem with both frontswap
and cleancache in the kernel.

> Until you can accept that, please include
> 
> 	Nacked-by: Johannes Weiner <hannes@cmpxchg.org>
> 
> on all further stand-alone submissions of tmem core code and/or hooks
> in the VM.  Thanks.

If you are willing to accept that Xen is a valid use case, I
think I have provided that (although I agree that more data would
be good and would be happy to take suggestions for what data to
provide).  If not, I would call that a form of mudslinging
but will add your Nack.  Please let me know.

Dan

^ permalink raw reply

* RE: [GIT PULL] mm: frontswap (for 3.2 window)
From: Dan Magenheimer @ 2011-10-30 23:19 UTC (permalink / raw)
  To: Johannes Weiner
  Cc: Pekka Enberg, Cyclonus J, Sasha Levin, Christoph Hellwig,
	David Rientjes, Linus Torvalds, linux-mm, LKML, Andrew Morton,
	Konrad Wilk, Jeremy Fitzhardinge, Seth Jennings, ngupta,
	Chris Mason, JBeulich, Dave Hansen, Jonathan Corbet
In-Reply-To: <20111030214748.GB3650@redhat.com>

> From: Johannes Weiner [mailto:jweiner@redhat.com]
> Subject: Re: [GIT PULL] mm: frontswap (for 3.2 window)

Hi Johannes --

Thanks for taking the time for some real technical discussion (below).

> On Fri, Oct 28, 2011 at 10:07:12AM -0700, Dan Magenheimer wrote:
> >
> > > From: Johannes Weiner [mailto:jweiner@redhat.com]
> > > Subject: Re: [GIT PULL] mm: frontswap (for 3.2 window)
> > >
> > > On Fri, Oct 28, 2011 at 06:36:03PM +0300, Pekka Enberg wrote:
> > > > On Fri, Oct 28, 2011 at 6:21 PM, Dan Magenheimer
> > > > <dan.magenheimer@oracle.com> wrote:
> > > > Looking at your patches, there's no trace that anyone outside your own
> > > > development team even looked at the patches. Why do you feel that it's
> > > > OK to ask Linus to pull them?
> > >
> > > People did look at it.
> > >
> > > In my case, the handwavy benefits did not convince me.  The handwavy
> > > 'this is useful' from just more people of the same company does not
> > > help, either.
> > >
> > > I want to see a usecase that tangibly gains from this, not just more
> > > marketing material.  Then we can talk about boring infrastructure and
> > > adding hooks to the VM.
> > >
> > > Convincing the development community of the problem you are trying to
> > > solve is the undocumented part of the process you fail to follow.
> >
> > Hi Johannes --
> >
> > First, there are several companies and several unaffiliated kernel
> > developers contributing here, building on top of frontswap.  I happen
> > to be spearheading it, and my company is backing me up.  (It
> > might be more appropriate to note that much of the resistance comes
> > from people of your company... but please let's keep our open-source
> > developer hats on and have a technical discussion rather than one
> > which pleases our respective corporate overlords.)
> 
> I didn't mean to start a mud fight about this, I only mentioned the
> part about your company because I already assume it sees value in tmem
> - it probably wouldn't fund its development otherwise.  I just tend to
> not care too much about Acks from the same company as the patch itself
> and I believe other people do the same.

Oops, sorry for mudslinging if none was intended.

Although I understand your position about Acks from the same company,
isn't that challenging the integrity of the individual's ack/review,
implying that they are not really reviewing the code with the same
intensity as if it came from another company?  Especially with
something like tmem, maybe the review is just as valid, and people
from the same company have just had more incentive to truly
understand the intent and potential of the functionality, as well as
the syntax in the code?  And maybe, on some patches, reviewers ARE
from different companies are "good buddies" and watch each others'
back and those reviews are not really complete?

So perhaps this default assumption about code review is flawed?

> > Second, have you read http://lwn.net/Articles/454795/ ?
> > If not, please do.  If yes, please explain what you don't
> > see as convincing or tangible or documented.  All of this
> > exists today as working publicly available code... it's
> > not marketing material.
> 
> I remember answering this to you in private already some time ago when
> discussing frontswap.

Yes, reading ahead, all the questions sound familiar and I thought
they were all answered (albeit some offlist).  I think the conversation
ended at that point, so I assumed any issues were resolved.

> You keep proposing a bridge and I keep asking for proof that this is
> not a bridge to nowhere.  Unless that question is answered, I am not
> interested in discussing the bridge's design.
>
> According to the LWN article, there are the following backends:
> 
> 1. Zcache: allow swapping into compressed memory
> 
> This sets aside a portion of memory which the kernel will swap
> compressed pages into upon pressure.  Now, obviously, reserving memory
> from the system for this increases the pressure in the first place,
> eating away on what space we have for anonymous memory and page cache.
> 
> Do you auto-size that region depending on workload?

Yes.  A key value of the whole transcendent memory design
is that everything is done dynamically.  That's one
reason that Nitin Gupta (author of zram) supports zcache.

> If so, how?  If not, is it documented how to size it manually?

See above.  There are some zcache policy parameters that can be
adjusted manually (currently through sysfs) so we can adjust
the defaults as necessary over time.

> Where are the performance numbers for various workloads, including
> both those that benefit from every bit of page cache and those that
> would fit into memory without zcache occupying space?

I have agreed already that more zcache measurement is warranted
(though I maintain it will get a lot more measurement merged than
it will unmerged).  So I can only answer theoretically, though
I would appreciate your comment if you disagree.

Space used for page cache is almost always opportunistic; it is
a "guess" that the page will be needed again in the future.
Frontswap only stores pages that MUST otherwise be swapped.
Swapping occurs only if the clean list is empty (or if the
MM system is too slow to respond to changes in workload).
In fact some of the pages-to-be-swapped that end up in
frontswap can be dirty page cache pages.

All of this is handled dynamically.  The kernel is still deciding
which pages to keep and which to reclaim and which to swap.
The hooks simply grab pages as they are going by.  That's
why the frontswap patch can be so simple and can have many "users"
built on top of it.

> However, looking at the zcache code, it seems it wants to allocate
> storage pages only when already trying to swap out.  Are you sure this
> works in reality?

Yes.  I'd encourage you to try it.  I'd be a fool if I tried
to guarantee that there are no bugs of course.

> 2. RAMster: allow swapping between machines in a cluster
> 
> Are there people using it?  It, too, sounds like a good idea but I
> don't see any proof it actually works as intended.

No.  I've posted the code publicly but it's still a godawful mess
and I'd be embarrassed if anyone looked at it.  But the code
does work and I've got some ideas on how to make it more
upstreamable.  If anybody seriously wants to work on it right
now, I could do that, but I'd prefer some more time alone with
it first.

Conceptually, it's just a matter of moving pages to a different
machine instead of across a hypercall interface.  All the "magic"
is in the frontswap and cleancache hooks.  They run on both
machines, both dynamically managing space (and compressing it
too).  The code uses ocfs2 for "cluster" discovery and is built
on top of a modified zcache.

> 3. Xen: allow guests to swap into the host.
> 
> The article mentions that there is code to put the guests under
> pressure and let them swap to host memory when the pressure is too
> high.  This sounds useful.
>
> Where is the code that controls the amount of pressure put on the
> guests?

See drivers/xen/xen-selfballoon.c, which was just merged at 3.1,
though there have been versions of it floating around for 2+ years.
Note there's a bug fix pending that makes the pressure a little less
aggressive.  I think it is/was submitted for the open 3.2 window.
(Note the same file manipulates the number of pages in frontswap.)
 
> Where are the performance numbers?  Surely you can construct a case
> where the initial machine sizes are not quite right and then collect
> data that demonstrates the machines are rebalancing as expected?

Yes I can.  It just works and with the right tools running, it's
even fun to watch.  Some interesting performance numbers were
published at Xen Summit 2010.  See the last few pages of:

http://oss.oracle.com/projects/tmem/dist/documentation/presentations/TranscendentMemoryXenSummit2010.pdf 

The speakers notes (so you can follow the presentation without video)
are in the same dir.

> 4. kvm: same as Xen
> 
> Apart from the questions that already apply to Xen, I remember KVM
> people in particular complaining about the synchroneous single-page
> interface that results in a hypercall per swapped page.  What happened
> to this concern?

I think we (me and the KVM people) agreed that the best way to determine
if this is a concern is to just measure it.  Sasha and Neo are working on
a KVM implementation which should make this possible (but neither wants
to invest a lot of time if frontswap isn't merged or has a clear path
to merging).

So, again, theoretically, and please argue if you disagree...
(and yes I know real measurements are better, but I think we all
know how easy it is to manipulate benchmarks so IMHO a
theoretical understanding is useful too).

What is the cost of a KVM hypercall (vmexit/vmenter) vs the cost of
swapping a page?  Clearly, reading/writing a disk is a very slow
operation, but has very little CPU overhead (though preparing a
page to be swapped via blkio is NOT very inexpensive).  But if
you are swapping, it is almost never the case that the CPU is busy,
especially on a multicore CPU.

I expect on old slow (e.g. first gen 1 core VT-x processors) this might
sometimes be measureable, but rarely an issue.  On modern processors,
I don't expect it to be significant.

BTW, it occurs to me that this is now measureable on Xen too, since
Xen tmem works now for fully-virtualized guests.  I don't have
the machines to reproduce the same experiment, but if you look at
the graphs in the Xen presentation, you can see that CPU utilization
goes up substantially, but throughput still improves.  I am almost
positive that the CPU cost of compression/decompression plus the
cost of deduplication insert/fetch exceeds the cost of a vmexit/vmenter,
so the additional cost of vmexit/vmenter will at most increase
the CPU utilization.  The real performance gain comes from avoiding
(waiting for) disk accesses.

> I would really appreciate if you could pick one of those backends and
> present them as a real and practical solution to real and practical
> problems.  With documentation on configuration and performance data of
> real workloads.  We can discuss implementation details like how memory
> is exchanged between source and destination when we come to it.
> 
> I am not asking for just more code that uses your interface, I want to
> know the real value for real people of the combination of all that
> stuff.  With proof, not just explanations of how it's supposed to
> work.

Well, the Xen implementation is by far the most mature and the
Xen presentation above is reasonably conclusive though, as always,
more measurements of more workloads would be good.

Not to get back into the mudslinging, but certain people from certain
companies try to ignore or minimize the value of Xen, so I've been
trying to emphasize the other (non-Xen, non-virtualization) code.
Personally, I think the Xen use case is sufficient by itself as it
solves a problem nobody else has ever solved (or, more precisely,
that VMware attempted to solve but, as real VMware customers will
attest, did so very poorly).

To be a good Linux kernel citizen, I've encouraged my company to hold
off on widespread support for Xen tmem until all the parts are upstream
in Linux, so there isn't a wide existing body of "proof" data.  And
releasing customer data from my employer requires an act of God.  But
private emails to Linus for cleancache seemed to convince him that
there was enough justification for cleancache.  I thought frontswap
was simpler and would be the easy part, but was clearly mistaken :-(
We are now proceeding fully with Xen tmem with both frontswap
and cleancache in the kernel.

> Until you can accept that, please include
> 
> 	Nacked-by: Johannes Weiner <hannes@cmpxchg.org>
> 
> on all further stand-alone submissions of tmem core code and/or hooks
> in the VM.  Thanks.

If you are willing to accept that Xen is a valid use case, I
think I have provided that (although I agree that more data would
be good and would be happy to take suggestions for what data to
provide).  If not, I would call that a form of mudslinging
but will add your Nack.  Please let me know.

Dan

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: where does that "50G" disk space figure come from in QS guide?
From: Wolfgang Denk @ 2011-10-30 23:17 UTC (permalink / raw)
  To: Robert P. J. Day; +Cc: Yocto discussion list
In-Reply-To: <alpine.DEB.2.02.1110301735310.4586@localhost6.localdomain6>

Dear Robert,

In message <alpine.DEB.2.02.1110301735310.4586@localhost6.localdomain6> you wrote:
> 
>   QS guide suggests build process using sato will use about 50G of
> disk space.  where does that figure come from?  i just did a configure
> and build of core-image-sato for beagleboard on my 64-bit ubuntu 11.10
> system and it cost me about 3.5G for the tarball download directory,
> and just under 28G for the entire build directory.  so where does 50G
> come from?  and that was *without* economizing using "INHERIT +=
> rm_work".

After building core-image-sato-sdk, core-image-qte-sdk,
meta-toolchain-sdk, and meta-toolchain-qte I see 70G used...

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
 The software required `Windows 95 or better', so I installed Linux.


^ permalink raw reply

* Re: Question about mdadm commit d6508f0cfb60edf07b36f1532eae4d9cddf7178b "be more careful about add attempts"
From: NeilBrown @ 2011-10-30 23:16 UTC (permalink / raw)
  To: Alexander Lyakas; +Cc: linux-raid
In-Reply-To: <CAGRgLy7biNy4Tj9wXhBosjC4QNy7dXC2aoimu7ezGqdL82Axxg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5774 bytes --]

On Thu, 27 Oct 2011 11:10:54 +0200 Alexander Lyakas <alex.bolshoy@gmail.com>
wrote:

> Hello Neil,
> it makes perfect sense not to turn a device into a spare inadvertently.
> 
> However, with mdadm 3.1.4 under gdb, I tried the following:
> - I had a raid6 with 4 drives (sda/b/c/d), their "desc_nr" in the
> kernel were respectively (according to GET_DISK_INFO): 0,1,2,3.
> - I failed the two last drives (c & d) via mdadm and removed them from the array
> - I wiped the superblock on drive d.
> - I added the drive d back to the array
> So now the array had the following setup:
> sda: disc_nr=0, raid_disk=0
> sdb: disc_nr=1, raid_disk=1
> sdd: disc_nr=4, raid_disk=2
> So sdd was added to the array into slot 2, and received disc_nr=4
> 
> - Now I asked to re-add drive sdc back to array. In gdb I followed the
> re-add flow, to the place where it fills the mdu_disk_info_t structure
> from the superblock read from sdc. It put there the following content:
> disc.major = ...
> disc.minor = ...
> disc.number = 2
> disc.raid_disk = 2 (because previously this drive was in slot 2)
> disc.state = ...
> 
> Now in gdb I changed disc.number to 4 (to match the desc_nr of sdd).
> And then issued ADD_NEW_DISK. It succeeded, and the sdc drive received
> disc_nr=2 (while it was asking for 4). Of course, it could not have
> received the same raid_disk, because this raid_disk was already
> occupied by sdd. So it was added as a spare.
> 
> But you are saying:
> > If a device already exists with the same disk.number, a re-add cannot
> > succeed, so mdadm doesn't even try.
> while in my case it succeeded (while it actually did "add" and not "re-add").

We seem to be using word differently.
If I ask mdadm to do a "re-add" and it does an "add", then I consider that to
be "failure", however you seem to consider it to be a "success".

That seems to be the source of confusion.


> 
> That's why I was thinking it makes more sense to check disc.raid_disk
> and not disc.number in this check. Since disc.number is not the
> drive's role within the array (right?), it is simply a position of the
> drive in the list of all drives.
> So if you check raid_disk, and see that this raid slot is already
> occupied, then, naturally, the drive will be converted to spare, which
> we want to avoid.

It may well be appropriate to check raid_disk as well, yes.  It isn't so easy
though which is maybe why I didn't.

With 0.90 metadata, the disc.number is the same as disc.raid_disk for active
devices.  That might be another reason for the code being the way that it is.

Thanks,
NeilBrown



> 
> And the enough_fd() check protects us from adding a spare to a failed
> array (like you mentioned to me previously).
> 
> What am I missing?
> 
> Thanks,
>   Alex.
> 
> 
> 
> 
> 
> 
> 
> On Wed, Oct 26, 2011 at 11:51 PM, NeilBrown <neilb@suse.de> wrote:
> > On Wed, 26 Oct 2011 19:02:37 +0200 Alexander Lyakas <alex.bolshoy@gmail.com>
> > wrote:
> >
> >> Greetings everybody,
> >> I have a question about the following code in Manage.c:Manage_subdevs()
> >>
> >> disc.number = mdi.disk.number;
> >> if (ioctl(fd, GET_DISK_INFO, &disc) != 0
> >>     || disc.major != 0 || disc.minor != 0
> >>     || !enough_fd(fd))
> >>     goto skip_re_add;
> >>
> >> I do not underatand why the checks: disc.major != 0 || disc.minor != 0
> >> are required. This basically means that the kernel already has an
> >> rdev->desc_nr equal to disc.number. But why fail the re-add procedure?
> >>
> >> Let's say that enough_fd() returns true, and we go ahead an issue
> >> ioctl(ADD_NEW_DISK). In this case, according to the kernel code in
> >> add_new_disk(), it will not even look at info->number. It will
> >> initialize rdev->desc_nr to -1, and will allocate a free desc_nr for
> >> the rdev later.
> >>
> >> Doing this with mdadm 3.1.4, where this check is not present, actually
> >> succeeds. I understand that this code was added for cases when
> >> enough_fd() returns false, which sounds perfectly fine to protect
> >> from.
> >>
> >> I was thinking that this code should actually check something like:
> >> if (ioctl(fd, GET_DISK_INFO, &disc) != 0
> >>     || disk.raid_disk != mdi.disk.raid_disk
> >>     || !enough_fd(fd))
> >>     goto skip_re_add;
> >>
> >> That is to check that the slot that was being occupied by the drive we
> >> are trying to add, is already occupied by a different drive (need also
> >> to cover cases of raid_disk <0, raid_disk >= raid_disks etc...) and
> >> not the desc_nr, which does not have any persistent meaning.
> >>
> >> Perhaps there are some compatibility issues with old kernels? Or
> >> special considerations for ... containers? non-persistent arrays?
> >
> > The point of this code is to make --re-add fail unless mdadm is certain that
> > the kernel will accept the re-add, rather than turn the device into a spare.
> >
> > If a device already exists with the same disk.number, a re-add cannot
> > succeed, so mdadm doesn't even try.
> >
> > When you say in 3.1.4 it "actually succeeds" - what succeeds?  Does it re-add
> > the device to the array, or does it turn the device into a spare?
> > I particularly do not want --re-add to turn a device into a spare because
> > people sometimes use it in cases where it cannot work, their device gets
> > turned into a spare, and they lose information that could have been used to
> > reconstruct the array.
> >
> > That that make sense?
> >
> > NeilBrown
> >
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* [PATCH] init: /dev/.initramfs symlink fixup
From: Michal Soltys @ 2011-10-30 23:02 UTC (permalink / raw)
  To: initramfs-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1318962806-24000-1-git-send-email-soltys-R61QfzASbfY@public.gmane.org>

It's not related to $PREFIX being set or not (anymore).

Signed-off-by: Michal Soltys <soltys-R61QfzASbfY@public.gmane.org>
---
 modules.d/99base/init |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/modules.d/99base/init b/modules.d/99base/init
index c109ae4..0ce8ed8 100755
--- a/modules.d/99base/init
+++ b/modules.d/99base/init
@@ -380,7 +380,7 @@ if [ -d "$NEWROOT/run" ]; then
 else
     NEWRUN=/dev/.run
     mkdir -p -m 0755 "$NEWRUN"
-    [ -n "$PREFIX" ] && ln -sfn .run/initramfs /dev/.initramfs
+    ln -sfn .run/initramfs /dev/.initramfs
     # if initramfs's udev uses /run by default, but the host is
     # still /run-less, we should copy udev's data to legacy
     # /dev/.udev, so the necessary info is available for the host
-- 
1.7.7.1

^ permalink raw reply related

* Re: linux-next: Tree for Oct 25 (mfd/ab8500)
From: Samuel Ortiz @ 2011-10-30 23:04 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Stephen Rothwell, linux-next, LKML, Linus, Srinidhi Kasagar,
	Linus Walleij
In-Reply-To: <4EA850C1.4060405@xenotime.net>

Hi Randy,

On Wed, Oct 26, 2011 at 11:26:09AM -0700, Randy Dunlap wrote:
> On 10/25/11 02:36, Stephen Rothwell wrote:
> > Hi all,
> 
> 
> drivers/mfd/ab8500-core.c:881:7: error: 'AB8500_CUT3P3' undeclared
Thanks for the report. This is now fixed.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply

* [U-Boot] [PATCH 12/18] GCC4.6: Squash warnings in smsc95xx.c
From: Mike Frysinger @ 2011-10-30 22:59 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <201110302148.50367.marek.vasut@gmail.com>

On Sunday 30 October 2011 16:48:50 Marek Vasut wrote:
> > On Tuesday 25 October 2011 05:39:58 Marek Vasut wrote:
> > > --- a/drivers/usb/eth/smsc95xx.c
> > > +++ b/drivers/usb/eth/smsc95xx.c
> > > 
> > > -	addr_lo = cpu_to_le32(*((u32 *)eth->enetaddr));
> > > +	addr_lo = cpu_to_le32(*eth->enetaddr);
> > 
> > pretty sure this is wrong.  enetaddr is a uchar[], so your code now reads
> > only 1 byte instead of 4.
> > 
> > that said, this code also seems to not be endian safe ...
> 
> It's good anyone actually cares to properly review. Anyway, why does noone
> actually care to fix all the damn warnings in their drivers before
> submitting them in the first place ?!

the strict alias warnings you are hitting show up only in newer compilers.  so 
i'm sure at the time of their development/submission, they didn't exist.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20111030/c4ccfb1b/attachment.pgp 

^ permalink raw reply

* Re: [PATCH] mfd/abx500: fix missing abx500 header file updates
From: Samuel Ortiz @ 2011-10-30 23:02 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-kernel, Randy Dunlap, Linus Walleij
In-Reply-To: <1319804135-2740-1-git-send-email-linus.walleij@stericsson.com>

Hi Linus,

On Fri, Oct 28, 2011 at 02:15:35PM +0200, Linus Walleij wrote:
> From: Linus Walleij <linus.walleij@linaro.org>
> 
> I missed to include a patch adding the new silicon revision define
> CUT3P3 and remove the retired CUT0 versions of AB8500. Also delete
> the reference to the retired AB3550 from the header.
Thanks. I had to apply it manually as the first chunk would not apply against
my for-next branch, but I pushed the actual fix now.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply

* [GIT PULL] i.MX6Q support
From: Arnd Bergmann @ 2011-10-30 22:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20111022005800.GC337@S2100-06.ap.freescale.net>

On Saturday 22 October 2011, Shawn Guo wrote:
> On Fri, Oct 21, 2011 at 08:01:58PM +0200, Sascha Hauer wrote:
> > 
> > Adding the following at least gives a compilable result. Works on i.MX3,
> > I couldn't test on i.MX6 though.
> 
> It works for imx6q.

I had to rebase the branch after pulling the updated gic series.
Sorry to bother you again, but can you check the new branch one more time?

	Arnd

^ permalink raw reply

* [meta-xfce] xfce4-weather-plugin: initial add 0.7.4
From: Andreas Müller @ 2011-10-30 22:51 UTC (permalink / raw)
  To: openembedded-devel

port-to-libxfce4ui.patch was taken from [1]

[1] https://bugzilla.xfce.org/show_bug.cgi?id=7956

Signed-off-by: Andreas Müller <schnitzeltony@gmx.de>
---
 .../weather/files/port-to-libxfce4ui.patch         |  104 ++++++++++++++++++++
 .../weather/xfce4-weather-plugin_0.7.4.bb          |   12 +++
 2 files changed, 116 insertions(+), 0 deletions(-)
 create mode 100644 meta-xfce/recipes-panel-plugins/weather/files/port-to-libxfce4ui.patch
 create mode 100644 meta-xfce/recipes-panel-plugins/weather/xfce4-weather-plugin_0.7.4.bb

diff --git a/meta-xfce/recipes-panel-plugins/weather/files/port-to-libxfce4ui.patch b/meta-xfce/recipes-panel-plugins/weather/files/port-to-libxfce4ui.patch
new file mode 100644
index 0000000..968d84f
--- /dev/null
+++ b/meta-xfce/recipes-panel-plugins/weather/files/port-to-libxfce4ui.patch
@@ -0,0 +1,104 @@
+From 24da1964f72429b0b4d20e0805cbd8346179527f Mon Sep 17 00:00:00 2001
+From: Matias De lellis <mati86dl@gmail.com>
+Date: Mon, 5 Sep 2011 14:17:29 -0300
+Subject: [PATCH] Port xfce4-weather-plugin to libxfce4ui
+
+---
+ configure.ac                   |    2 +-
+ panel-plugin/Makefile.am       |    4 ++--
+ panel-plugin/weather-config.c  |    2 +-
+ panel-plugin/weather-search.c  |    2 +-
+ panel-plugin/weather-summary.c |    2 +-
+ panel-plugin/weather.c         |    2 +-
+ 6 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 04f466a..d1bb58e 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -59,7 +59,7 @@ dnl ***********************************
+ XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.6.0])
+ XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.6.0])
+ XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.3.90.2])
+-XDT_CHECK_PACKAGE([LIBXFCEGUI4], [libxfcegui4-1.0], [4.3.90.2])
++XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce4ui-1], [4.7.0])
+ XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-1.0], [4.3.99.1])
+ XDT_CHECK_PACKAGE([LIBXML], [libxml-2.0], [2.4.0])
+ 
+diff --git a/panel-plugin/Makefile.am b/panel-plugin/Makefile.am
+index 50fc962..ed06da1 100644
+--- a/panel-plugin/Makefile.am
++++ b/panel-plugin/Makefile.am
+@@ -33,7 +33,7 @@ xfce4_weather_plugin_SOURCES =						\
+ 
+ xfce4_weather_plugin_CFLAGS =						\
+ 	$(LIBXFCE4PANEL_CFLAGS)						\
+-	$(LIBXFCEGUI4_CFLAGS)						\
++	$(LIBXFCE4UI_CFLAGS)						\
+ 	$(LIBXFCE4UTIL_CFLAGS)						\
+ 	$(GTK_CFLAGS)							\
+ 	$(LIBXML_CFLAGS)
+@@ -41,7 +41,7 @@ xfce4_weather_plugin_CFLAGS =						\
+ xfce4_weather_plugin_LDADD =						\
+ 	$(LIBXFCE4PANEL_LIBS)						\
+ 	$(LIBXFCE4UTIL_LIBS)						\
+-	$(LIBXFCEGUI4_LIBS)						\
++	$(LIBXFCE4UI_LIBS)						\
+ 	$(GTK_LIBS)							\
+ 	$(LIBXML_LIBS)							\
+ 	$(LIBRESOLV)
+diff --git a/panel-plugin/weather-config.c b/panel-plugin/weather-config.c
+index 3023e11..d183e75 100644
+--- a/panel-plugin/weather-config.c
++++ b/panel-plugin/weather-config.c
+@@ -20,7 +20,7 @@
+ #endif
+ 
+ #include <string.h>
+-#include <libxfcegui4/libxfcegui4.h>
++#include <libxfce4ui/libxfce4ui.h>
+ 
+ #include "weather-parsers.h"
+ #include "weather-data.h"
+diff --git a/panel-plugin/weather-search.c b/panel-plugin/weather-search.c
+index c43ad15..dba395f 100644
+--- a/panel-plugin/weather-search.c
++++ b/panel-plugin/weather-search.c
+@@ -21,7 +21,7 @@
+ 
+ #include <string.h>
+ 
+-#include <libxfcegui4/libxfcegui4.h>
++#include <libxfce4ui/libxfce4ui.h>
+ 
+ #include "weather-parsers.h"
+ #include "weather-data.h"
+diff --git a/panel-plugin/weather-summary.c b/panel-plugin/weather-summary.c
+index 36eeb14..b584c7d 100644
+--- a/panel-plugin/weather-summary.c
++++ b/panel-plugin/weather-summary.c
+@@ -19,7 +19,7 @@
+ #include <config.h>
+ #endif
+ 
+-#include <libxfcegui4/libxfcegui4.h>
++#include <libxfce4ui/libxfce4ui.h>
+ 
+ #include "weather-parsers.h"
+ #include "weather-data.h"
+diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c
+index cd341aa..c6c918d 100644
+--- a/panel-plugin/weather.c
++++ b/panel-plugin/weather.c
+@@ -23,7 +23,7 @@
+ #include <sys/stat.h>
+ 
+ #include <libxfce4util/libxfce4util.h>
+-#include <libxfcegui4/libxfcegui4.h>
++#include <libxfce4ui/libxfce4ui.h>
+ 
+ #include "weather-parsers.h"
+ #include "weather-data.h"
+-- 
+1.7.6
+
diff --git a/meta-xfce/recipes-panel-plugins/weather/xfce4-weather-plugin_0.7.4.bb b/meta-xfce/recipes-panel-plugins/weather/xfce4-weather-plugin_0.7.4.bb
new file mode 100644
index 0000000..d75d51e
--- /dev/null
+++ b/meta-xfce/recipes-panel-plugins/weather/xfce4-weather-plugin_0.7.4.bb
@@ -0,0 +1,12 @@
+DESCRIPTION = "Panel plugin to display current temperature and weather condition"
+HOMEPAGE = "http://goodies.xfce.org/projects/panel-plugins/xfce4-weather-plugin"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f"
+
+inherit xfce-panel-plugin
+
+SRC_URI += "file://port-to-libxfce4ui.patch"
+SRC_URI[md5sum] = "03c972d13eba5cd226432ff66e3ff282"
+SRC_URI[sha256sum] = "3f76207b8a845d15bfec6825bd5300aedd086c455259c4dd8670a89a3c8ab382"
+
+FILES_${PN} += "${datadir}/xfce4/weather"
-- 
1.7.4.4




^ permalink raw reply related

* LVM2 lib/metadata/thin_manip.c libdm/libdm-dep ...
From: zkabelac @ 2011-10-30 22:52 UTC (permalink / raw)
  To: lvm-devel

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	zkabelac at sourceware.org	2011-10-30 22:52:08

Modified files:
	lib/metadata   : thin_manip.c 
	libdm          : libdm-deptree.c 

Log message:
	Thin fix compile warns
	
	Test for dm_snprintf < 0.
	Add header for moved backup.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/thin_manip.c.diff?cvsroot=lvm2&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-deptree.c.diff?cvsroot=lvm2&r1=1.141&r2=1.142

--- LVM2/lib/metadata/thin_manip.c	2011/10/30 22:01:39	1.16
+++ LVM2/lib/metadata/thin_manip.c	2011/10/30 22:52:08	1.17
@@ -18,6 +18,7 @@
 #include "metadata.h"
 #include "segtype.h"
 #include "lv_alloc.h"
+#include "archiver.h"
 
 int attach_pool_metadata_lv(struct lv_segment *seg, struct logical_volume *pool_metadata_lv)
 {
--- LVM2/libdm/libdm-deptree.c	2011/10/30 22:04:57	1.141
+++ LVM2/libdm/libdm-deptree.c	2011/10/30 22:52:08	1.142
@@ -1294,9 +1294,11 @@
 				m->u.m_set_transaction_id.current_id,
 				m->u.m_set_transaction_id.new_id);
 		break;
+	default:
+		r = -1;
 	}
 
-	if (!r) {
+	if (r < 0) {
 		log_error("Failed to prepare message.");
 		return 0;
 	}



^ permalink raw reply

* [B.A.T.M.A.N.] [RFC 11/11] [RFC] batman-adv: get primaries address through bat_priv->own_orig
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

Instead of acquiring the first interfaces originator through
hard interface (including referencing/dereferencing), we can use the
cached value in bat_priv->own_orig.

There might be some cases where this function was implicitly used to
check whether there is a hard interface configured at all (i.e. if
batman is active), therfore this is patch is an RFC.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 icmp_socket.c       |   12 +-----------
 routing.c           |   25 +++----------------------
 translation-table.c |   16 ++--------------
 unicast.c           |    9 +--------
 vis.c               |   20 ++------------------
 5 files changed, 9 insertions(+), 73 deletions(-)

diff --git a/icmp_socket.c b/icmp_socket.c
index ac3520e..86dcffd 100644
--- a/icmp_socket.c
+++ b/icmp_socket.c
@@ -153,7 +153,6 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
 {
 	struct socket_client *socket_client = file->private_data;
 	struct bat_priv *bat_priv = socket_client->bat_priv;
-	struct hard_iface *primary_if = NULL;
 	struct sk_buff *skb;
 	struct icmp_packet_rr *icmp_packet;
 
@@ -168,13 +167,6 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
 		return -EINVAL;
 	}
 
-	primary_if = primary_if_get_selected(bat_priv);
-
-	if (!primary_if) {
-		len = -EFAULT;
-		goto out;
-	}
-
 	if (len >= sizeof(struct icmp_packet_rr))
 		packet_len = sizeof(struct icmp_packet_rr);
 
@@ -240,7 +232,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
 		goto dst_unreach;
 
 	memcpy(icmp_packet->orig,
-	       primary_if->net_dev->dev_addr, ETH_ALEN);
+	       bat_priv->own_orig, ETH_ALEN);
 
 	if (packet_len == sizeof(struct icmp_packet_rr))
 		memcpy(icmp_packet->rr,
@@ -255,8 +247,6 @@ dst_unreach:
 free_skb:
 	kfree_skb(skb);
 out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
 	if (neigh_node)
 		neigh_node_free_ref(neigh_node);
 	if (orig_node)
diff --git a/routing.c b/routing.c
index 00e5339..5ef6f75 100644
--- a/routing.c
+++ b/routing.c
@@ -284,7 +284,6 @@ int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
 static int recv_my_icmp_packet(struct bat_priv *bat_priv,
 			       struct sk_buff *skb, size_t icmp_len)
 {
-	struct hard_iface *primary_if = NULL;
 	struct orig_node *orig_node = NULL;
 	struct neigh_node *router = NULL;
 	struct icmp_packet_rr *icmp_packet;
@@ -298,10 +297,6 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
 		goto out;
 	}
 
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-
 	/* answer echo request (ping) */
 	/* get routing information */
 	orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
@@ -319,7 +314,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
 	icmp_packet = (struct icmp_packet_rr *)skb->data;
 
 	memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
-	memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
+	memcpy(icmp_packet->orig, bat_priv->own_orig, ETH_ALEN);
 	icmp_packet->msg_type = ECHO_REPLY;
 	icmp_packet->ttl = TTL;
 
@@ -327,8 +322,6 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
 	ret = NET_RX_SUCCESS;
 
 out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
 	if (router)
 		neigh_node_free_ref(router);
 	if (orig_node)
@@ -339,7 +332,6 @@ out:
 static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
 				  struct sk_buff *skb)
 {
-	struct hard_iface *primary_if = NULL;
 	struct orig_node *orig_node = NULL;
 	struct neigh_node *router = NULL;
 	struct icmp_packet *icmp_packet;
@@ -355,10 +347,6 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
 		goto out;
 	}
 
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-
 	/* get routing information */
 	orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
 	if (!orig_node)
@@ -375,7 +363,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
 	icmp_packet = (struct icmp_packet *)skb->data;
 
 	memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
-	memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
+	memcpy(icmp_packet->orig, bat_priv->own_orig, ETH_ALEN);
 	icmp_packet->msg_type = TTL_EXCEEDED;
 	icmp_packet->ttl = TTL;
 
@@ -383,8 +371,6 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
 	ret = NET_RX_SUCCESS;
 
 out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
 	if (router)
 		neigh_node_free_ref(router);
 	if (orig_node)
@@ -894,7 +880,6 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv,
 	uint8_t curr_ttvn;
 	struct orig_node *orig_node;
 	struct ethhdr *ethhdr;
-	struct hard_iface *primary_if;
 	struct unicast_packet *unicast_packet;
 	bool tt_poss_change;
 
@@ -931,12 +916,8 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv,
 		if (!orig_node) {
 			if (!is_my_client(bat_priv, ethhdr->h_dest))
 				return 0;
-			primary_if = primary_if_get_selected(bat_priv);
-			if (!primary_if)
-				return 0;
 			memcpy(unicast_packet->dest,
-			       primary_if->net_dev->dev_addr, ETH_ALEN);
-			hardif_free_ref(primary_if);
+			       bat_priv->own_orig, ETH_ALEN);
 		} else {
 			memcpy(unicast_packet->dest, orig_node->orig,
 			       ETH_ALEN);
diff --git a/translation-table.c b/translation-table.c
index 06a51e5..486f464 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -1195,14 +1195,9 @@ static int send_tt_request(struct bat_priv *bat_priv,
 	struct sk_buff *skb = NULL;
 	struct tt_query_packet *tt_request;
 	struct neigh_node *neigh_node = NULL;
-	struct hard_iface *primary_if;
 	struct tt_req_node *tt_req_node = NULL;
 	int ret = 1;
 
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-
 	/* The new tt_req will be issued only if I'm not waiting for a
 	 * reply from the same orig_node yet */
 	tt_req_node = new_tt_req_node(bat_priv, dst_orig_node);
@@ -1220,7 +1215,7 @@ static int send_tt_request(struct bat_priv *bat_priv,
 
 	tt_request->packet_type = BAT_TT_QUERY;
 	tt_request->version = COMPAT_VERSION;
-	memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
+	memcpy(tt_request->src, bat_priv->own_orig, ETH_ALEN);
 	memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
 	tt_request->ttl = TTL;
 	tt_request->ttvn = ttvn;
@@ -1244,8 +1239,6 @@ static int send_tt_request(struct bat_priv *bat_priv,
 out:
 	if (neigh_node)
 		neigh_node_free_ref(neigh_node);
-	if (primary_if)
-		hardif_free_ref(primary_if);
 	if (ret)
 		kfree_skb(skb);
 	if (ret && tt_req_node) {
@@ -1745,7 +1738,6 @@ void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
 	struct sk_buff *skb = NULL;
 	struct roam_adv_packet *roam_adv_packet;
 	int ret = 1;
-	struct hard_iface *primary_if;
 
 	/* before going on we have to check whether the client has
 	 * already roamed to us too many times */
@@ -1764,11 +1756,7 @@ void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
 	roam_adv_packet->packet_type = BAT_ROAM_ADV;
 	roam_adv_packet->version = COMPAT_VERSION;
 	roam_adv_packet->ttl = TTL;
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-	memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
-	hardif_free_ref(primary_if);
+	memcpy(roam_adv_packet->src, bat_priv->own_orig, ETH_ALEN);
 	memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
 	memcpy(roam_adv_packet->client, client, ETH_ALEN);
 
diff --git a/unicast.c b/unicast.c
index 07d1c1d..733da47 100644
--- a/unicast.c
+++ b/unicast.c
@@ -220,7 +220,6 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
 		  struct hard_iface *hard_iface, const uint8_t dstaddr[])
 {
 	struct unicast_packet tmp_uc, *unicast_packet;
-	struct hard_iface *primary_if;
 	struct sk_buff *frag_skb;
 	struct unicast_frag_packet *frag1, *frag2;
 	int uc_hdr_len = sizeof(*unicast_packet);
@@ -229,10 +228,6 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
 	int large_tail = 0, ret = NET_RX_DROP;
 	uint16_t seqno;
 
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto dropped;
-
 	frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
 	if (!frag_skb)
 		goto dropped;
@@ -255,7 +250,7 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
 	frag1->version = COMPAT_VERSION;
 	frag1->packet_type = BAT_UNICAST_FRAG;
 
-	memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
+	memcpy(frag1->orig, bat_priv->own_orig, ETH_ALEN);
 	memcpy(frag2, frag1, sizeof(*frag2));
 
 	if (data_len & 1)
@@ -278,8 +273,6 @@ drop_frag:
 dropped:
 	kfree_skb(skb);
 out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
 	return ret;
 }
 
diff --git a/vis.c b/vis.c
index 7445413..e08ecd7 100644
--- a/vis.c
+++ b/vis.c
@@ -190,7 +190,6 @@ static ssize_t vis_data_read_entry(char *buff,
 
 int vis_seq_print_text(struct seq_file *seq, void *offset)
 {
-	struct hard_iface *primary_if;
 	struct hlist_node *node;
 	struct hlist_head *head;
 	struct vis_info *info;
@@ -209,10 +208,6 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
 	char *buff;
 	int compare;
 
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-
 	if (vis_server == VIS_TYPE_CLIENT_UPDATE)
 		goto out;
 
@@ -321,8 +316,6 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
 	kfree(buff);
 
 out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
 	return ret;
 }
 
@@ -810,20 +803,15 @@ out:
 /* only send one vis packet. called from send_vis_packets() */
 static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
 {
-	struct hard_iface *primary_if;
 	struct vis_packet *packet;
 
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-
 	packet = (struct vis_packet *)info->skb_packet->data;
 	if (packet->ttl < 2) {
 		pr_debug("Error - can't send vis packet: ttl exceeded\n");
-		goto out;
+		return;
 	}
 
-	memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
+	memcpy(packet->sender_orig, bat_priv->own_orig, ETH_ALEN);
 	packet->ttl--;
 
 	if (is_broadcast_ether_addr(packet->target_orig))
@@ -831,10 +819,6 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
 	else
 		unicast_vis_packet(bat_priv, info);
 	packet->ttl++; /* restore TTL */
-
-out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
 }
 
 /* called from timer; send (and maybe generate) vis packet. */
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 10/11] batman-adv: Update README and sysfs description
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 README               |   28 +++++++++++++++-------------
 sysfs-class-net-mesh |    9 +++++++++
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/README b/README
index 5ba56b5..44061af 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-[state: 30-09-2011]
+[state: 27-10-2011]
 
 BATMAN-ADV
 ----------
@@ -82,17 +82,17 @@ To deactivate an interface you have  to  write  "none"  into  its
 All  mesh  wide  settings  can be found in batman's own interface
 folder:
 
-#  ls  /sys/class/net/bat0/mesh/
-# aggregated_ogms   fragmentation gw_sel_class   vis_mode
-# ap_isolation      gw_bandwidth  hop_penalty
-# bonding           gw_mode       orig_interval
+# ls /sys/class/net/bat0/mesh/
+# aggregated_ogms        fragmentation          hop_penalty
+# ap_isolation           gw_bandwidth           log_level
+# bonding                gw_mode                orig_interval
+# bridge_loop_avoidance  gw_sel_class           vis_mode
 
 There is a special folder for debugging information:
 
 #  ls /sys/kernel/debug/batman_adv/bat0/
-#  gateways     socket        transtable_global  vis_data
-#  originators  softif_neigh  transtable_local
-
+# bla_claim_table    log                socket             transtable_local
+# gateways           originators        transtable_global  vis_data
 
 Some of the files contain all sort of status information  regard-
 ing  the  mesh  network.  For  example, you can view the table of
@@ -216,15 +216,17 @@ file in debugfs
 The additional debug output is by default disabled. It can be en-
 abled  during run time. Following log_levels are defined:
 
-0 - All  debug  output  disabled
-1 - Enable messages related to routing / flooding / broadcasting
-2 - Enable route or tt entry added / changed / deleted
-3 - Enable all messages
+0 - all debug output disabled
+1 - messages related to routing / flooding / broadcasting
+2 - messages related to route added / changed / deleted
+4 - messages related to translation table operations
+8 - messages related to bridge loop avoidance
+15 - enable all messages
 
 The debug output can be changed at runtime  using  the  file
 /sys/class/net/bat0/mesh/log_level. e.g.
 
-# echo 2 > /sys/class/net/bat0/mesh/log_level
+# echo 6 > /sys/class/net/bat0/mesh/log_level
 
 will enable debug messages for when routes or TTs change.
 
diff --git a/sysfs-class-net-mesh b/sysfs-class-net-mesh
index b020014..1d39bc7 100644
--- a/sysfs-class-net-mesh
+++ b/sysfs-class-net-mesh
@@ -14,6 +14,15 @@ Description:
                 mesh will be sent using multiple interfaces at the
                 same time (if available).
 
+What:           /sys/class/net/<mesh_iface>/mesh/bridge_loop_avoidance
+Date:           November 2011
+Contact:        Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Description:
+                Indicates whether the bridge loop avoidance feature
+                is enabled. This feature detects and avoids loops
+                between the mesh and devices bridged with the soft
+                interface <mesh_iface>.
+
 What:           /sys/class/net/<mesh_iface>/mesh/fragmentation
 Date:           October 2010
 Contact:        Andreas Langer <an.langer@gmx.de>
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 09/11] batman-adv: form groups in the bridge loop avoidance
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

backbone gateways may be part of the same LAN, but participate
in different meshes. With this patch, backbone gateways form groups by
applying the groupid of another backbone gateway if it is higher. After
forming the group, they only accept messages from backbone gateways of
the same group.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
[2011-10-27] fix a nasty bug which has overwritten the claim type

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

[2011-10-30] Changes suggested by Marek Lindner:
 * give hw_src and hw_dst as parameter in check_claim_group() to
   avoid code duplicates
 * update group id when primary if address is changed

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 bridge_loop_avoidance.c |  111 +++++++++++++++++++++++++++++++++++++++++++---
 types.h                 |    1 +
 2 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index b1f2abc..52575f2 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -33,7 +33,6 @@
 #include <net/arp.h>
 #include <linux/if_vlan.h>
 
-static const uint8_t claim_dest[6] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
 static const uint8_t announce_mac[6] = {0x43, 0x05, 0x43, 0x05, 0x00, 0x00};
 
 static void bla_periodic_work(struct work_struct *work);
@@ -255,7 +254,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
 	if (!primary_if)
 		return;
 
-	memcpy(&local_claim_dest, claim_dest,
+	memcpy(&local_claim_dest, &bat_priv->claim_dest,
 			sizeof(local_claim_dest));
 	local_claim_dest.type = claimtype;
 
@@ -268,8 +267,9 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
 		NULL,				/* Ethernet DST: Broadcast */
 		primary_if->net_dev->dev_addr,	/* Ethernet SRC/HW SRC:
 						 * originator mac */
-		(uint8_t *)&local_claim_dest	/* HW DST: FF:43:05:XX:00:00
-						 * with XX   = claim type */
+		(uint8_t *)&local_claim_dest	/* HW DST: FF:43:05:XX:YY:YY
+						 * with XX   = claim type
+						 * and YY:YY = group id */
 		);
 
 	if (!skb)
@@ -701,6 +701,82 @@ static int handle_claim(struct bat_priv *bat_priv,
 	return 1;
 }
 
+/**
+ *
+ * @bat_priv: the bat priv with all the soft interface information
+ * @hw_src: the Hardware source in the ARP Header
+ * @hw_dst: the Hardware destination in the ARP Header
+ * @ethhdr: pointer to the Ethernet header of the claim frame
+ *
+ * checks if it is a claim packet and if its on the same group.
+ * This function also applies the group ID of the sender
+ * if it is in the same mesh.
+ *
+ * returns:
+ *	2  - if it is a claim packet and on the same group
+ *	1  - if is a claim packet from another group
+ *	0  - if it is not a claim packet
+ */
+static int check_claim_group(struct bat_priv *bat_priv,
+		uint8_t *hw_src, uint8_t *hw_dst, struct ethhdr *ethhdr)
+{
+	uint8_t *backbone_addr;
+	struct orig_node *orig_node;
+	struct bla_claim_dst *bla_dst, *bla_dst_own;
+
+	bla_dst = (struct bla_claim_dst *) hw_dst;
+	bla_dst_own = &bat_priv->claim_dest;
+
+	/* check if it is a claim packet in general */
+	if (memcmp(bla_dst->magic, bla_dst_own->magic,
+			sizeof(bla_dst->magic)) != 0)
+		return 0;
+
+	/* if announcement packet, use the source,
+	 * otherwise assume it is in the hw_src */
+	switch (bla_dst->type) {
+	case CLAIM_TYPE_ADD:
+		backbone_addr = hw_src;
+		break;
+	case CLAIM_TYPE_REQUEST:
+	case CLAIM_TYPE_ANNOUNCE:
+	case CLAIM_TYPE_DEL:
+		backbone_addr = ethhdr->h_source;
+		break;
+	default:
+		return 0;
+	}
+
+	/* don't accept claim frames from ourselves */
+	if (compare_eth(backbone_addr, bat_priv->own_orig))
+		return 0;
+
+	/* if its already the same group, it is fine. */
+	if (bla_dst->group == bla_dst_own->group)
+		return 2;
+
+	/* lets see if this originator is in our mesh */
+	orig_node = orig_hash_find(bat_priv, backbone_addr);
+
+	/* dont accept claims from gateways which are not in
+	 * the same mesh or group. */
+	if (!orig_node)
+		return 1;
+
+	/* if our mesh friends mac is bigger, use it for ourselves. */
+	if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) {
+		bat_dbg(DBG_BLA, bat_priv,
+			"taking other backbones claim group: %04x\n",
+			ntohs(bla_dst->group));
+		bla_dst_own->group = bla_dst->group;
+	}
+
+	orig_node_free_ref(orig_node);
+
+	return 2;
+}
+
+
 /*
  * @bat_priv: the bat priv with all the soft interface information
  * @skb: the frame to be checked
@@ -721,6 +797,7 @@ static int bla_process_claim(struct bat_priv *bat_priv, struct sk_buff *skb)
 	uint16_t proto;
 	int headlen;
 	short vid = -1;
+	int ret;
 
 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
@@ -761,8 +838,15 @@ static int bla_process_claim(struct bat_priv *bat_priv, struct sk_buff *skb)
 	bla_dst = (struct bla_claim_dst *) hw_dst;
 
 	/* check if it is a claim frame. */
-	if (memcmp(hw_dst, claim_dest, 3) != 0)
-		return 0;
+	ret = check_claim_group(bat_priv, hw_src, hw_dst, ethhdr);
+	if (ret == 1)
+		bat_dbg(DBG_BLA, bat_priv, "bla_process_claim(): received "
+			"a claim frame from another group. From: "
+			"%pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
+			ethhdr->h_source, vid, hw_src, hw_dst);
+
+	if (ret < 2)
+		return ret;
 
 	/* become a backbone gw ourselves on this vlan if not happened yet */
 	bla_update_own_backbone_gw(bat_priv, vid);
@@ -806,6 +890,9 @@ void bla_update_orig_address(struct bat_priv *bat_priv, uint8_t *newaddr)
 	struct hashtable_t *hash;
 	int i;
 
+	/* reset bridge loop avoidance group id */
+	bat_priv->claim_dest.group = htons(crc16(0, newaddr, ETH_ALEN));
+
 	hash = bat_priv->backbone_hash;
 	if (!hash)
 		return;
@@ -971,9 +1058,16 @@ timer:
 int bla_init(struct bat_priv *bat_priv)
 {
 	int i;
+	uint8_t claim_dest[6] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
 
 	bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n");
 
+	/* setting claim destination address */
+	memcpy(&bat_priv->claim_dest.magic, claim_dest, 3);
+	bat_priv->claim_dest.type = 0;
+	bat_priv->claim_dest.group =
+		htons(crc16(0, bat_priv->own_orig, ETH_ALEN));
+
 	/* initialize the duplicate list */
 	for (i = 0; i < DUPLIST_SIZE; i++)
 		bat_priv->bcast_duplist[i].entrytime =
@@ -1390,8 +1484,9 @@ int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
 	}
 
 	seq_printf(seq, "Claims announced for the mesh %s "
-			"(orig %pM)\n",
-			net_dev->name, bat_priv->own_orig);
+			"(orig %pM, group id %04x)\n",
+			net_dev->name, bat_priv->own_orig,
+			ntohs(bat_priv->claim_dest.group));
 	seq_printf(seq, "   %-17s    %-5s    %-17s [o] (%-4s)\n",
 		   "Client", "VID", "Originator", "CRC");
 	for (i = 0; i < hash->size; i++) {
diff --git a/types.h b/types.h
index 5f02447..21c4f3e 100644
--- a/types.h
+++ b/types.h
@@ -192,6 +192,7 @@ struct bat_priv {
 	struct hashtable_t *vis_hash;
 	struct bcast_duplist_entry bcast_duplist[DUPLIST_SIZE];
 	int bcast_duplist_curr;
+	struct bla_claim_dst claim_dest;
 	spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
 	spinlock_t forw_bcast_list_lock; /* protects  */
 	spinlock_t tt_changes_list_lock; /* protects tt_changes */
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 08/11] batman-adv: drop STP over batman
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 soft-interface.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/soft-interface.c b/soft-interface.c
index 46dd328..7f7efb9 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -129,6 +129,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
 	struct hard_iface *primary_if = NULL;
 	struct bcast_packet *bcast_packet;
 	struct vlan_ethhdr *vhdr;
+	uint8_t stp_addr[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x00};
 	unsigned int header_len = 0;
 	int data_len = skb->len, ret;
 	short vid = -1;
@@ -158,6 +159,11 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
 	/* Register the client MAC in the transtable */
 	tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
 
+	/* don't accept stp packets. STP does not help in meshes.
+	 * better use the bridge loop avoidance ... */
+	if (compare_eth(ethhdr->h_dest, stp_addr))
+		goto dropped;
+
 	if (is_multicast_ether_addr(ethhdr->h_dest)) {
 		do_bcast = true;
 
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 07/11] batman-adv: add broadcast duplicate check
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

When multiple backbone gateways relay the same broadcast from the
backbone into the mesh, other nodes in the mesh may receive this
broadcast multiple times. To avoid this, the crc checksums of
received broadcasts are recorded and new broadcast packets with
the same content may be dropped if received by another gateway.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 bridge_loop_avoidance.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++
 bridge_loop_avoidance.h |    2 +
 main.h                  |    3 ++
 routing.c               |    4 ++
 types.h                 |    7 ++++
 5 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index a787c96..b1f2abc 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -970,8 +970,16 @@ timer:
 /* initialize all bla structures */
 int bla_init(struct bat_priv *bat_priv)
 {
+	int i;
+
 	bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n");
 
+	/* initialize the duplicate list */
+	for (i = 0; i < DUPLIST_SIZE; i++)
+		bat_priv->bcast_duplist[i].entrytime =
+			jiffies - msecs_to_jiffies(DUPLIST_TIMEOUT);
+	bat_priv->bcast_duplist_curr = 0;
+
 	if (bat_priv->claim_hash)
 		return 1;
 
@@ -989,6 +997,71 @@ int bla_init(struct bat_priv *bat_priv)
 
 /**
  * @bat_priv: the bat priv with all the soft interface information
+ * @bcast_packet: originator mac address
+ * @hdr_size: maximum length of the frame
+ *
+ * check if it is on our broadcast list. Another gateway might
+ * have sent the same packet because it is connected to the same backbone,
+ * so we have to remove this duplicate.
+ *
+ * This is performed by checking the CRC, which will tell us
+ * with a good chance that it is the same packet. If it is furthermore
+ * sent by another host, drop it. We allow equal packets from
+ * the same host however as this might be intended.
+ *
+ **/
+
+int bla_check_bcast_duplist(struct bat_priv *bat_priv,
+		struct bcast_packet *bcast_packet, int hdr_size)
+{
+	int i, length, curr;
+	uint8_t *content;
+	uint16_t crc;
+	struct bcast_duplist_entry *entry;
+
+	length = hdr_size - sizeof(*bcast_packet);
+	content = (uint8_t *) bcast_packet;
+	content += sizeof(*bcast_packet);
+
+	/* calculate the crc ... */
+	crc = crc16(0, content, length);
+
+	for (i = 0 ; i < DUPLIST_SIZE; i++) {
+		curr = (bat_priv->bcast_duplist_curr + i) % DUPLIST_SIZE;
+		entry = &bat_priv->bcast_duplist[curr];
+
+		/* we can stop searching if the entry is too old ;
+		 * later entries will be even older */
+		if (time_after(jiffies, entry->entrytime
+				+ msecs_to_jiffies(DUPLIST_TIMEOUT)))
+			break;
+
+		if (entry->crc != crc)
+			continue;
+
+		if (compare_eth(entry->orig, bcast_packet->orig))
+			continue;
+
+		/* this entry seems to match: same crc, not too old,
+		 * and from another gw. therefore return 1 to forbid it. */
+		return 1;
+	}
+	/* not found, add a new entry (overwrite the oldest entry) */
+	curr = (bat_priv->bcast_duplist_curr + DUPLIST_SIZE - 1) % DUPLIST_SIZE;
+	entry = &bat_priv->bcast_duplist[curr];
+	entry->crc = crc;
+	entry->entrytime = jiffies;
+	memcpy(entry->orig, bcast_packet->orig, ETH_ALEN);
+	bat_priv->bcast_duplist_curr = curr;
+
+	/* allow it, its the first occurence. */
+	return 0;
+}
+
+
+
+/**
+ * @bat_priv: the bat priv with all the soft interface information
  * @orig: originator mac address
  *
  * check if the originator is a gateway for any VLAN ID.
diff --git a/bridge_loop_avoidance.h b/bridge_loop_avoidance.h
index bafcfac..60dcb1b 100644
--- a/bridge_loop_avoidance.h
+++ b/bridge_loop_avoidance.h
@@ -25,6 +25,8 @@ int bla_is_backbone_gw(struct sk_buff *skb,
 		struct orig_node *orig_node, int hdr_size);
 int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
 int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig);
+int bla_check_bcast_duplist(struct bat_priv *bat_priv,
+		struct bcast_packet *bcast_packet, int hdr_size);
 void bla_update_orig_address(struct bat_priv *bat_priv, uint8_t *newaddr);
 int bla_init(struct bat_priv *bat_priv);
 void bla_free(struct bat_priv *bat_priv);
diff --git a/main.h b/main.h
index 1bd41f1..f96d817 100644
--- a/main.h
+++ b/main.h
@@ -82,6 +82,9 @@
 #define BLA_PERIOD_LENGTH	10000	/* 10 seconds */
 #define BLA_BACKBONE_TIMEOUT	(BLA_PERIOD_LENGTH * 3)
 #define BLA_CLAIM_TIMEOUT	(BLA_PERIOD_LENGTH * 10)
+
+#define DUPLIST_SIZE		16
+#define DUPLIST_TIMEOUT		500	/* 500 ms */
 /* don't reset again within 30 seconds */
 #define RESET_PROTECTION_MS 30000
 #define EXPECTED_SEQNO_RANGE	65536
diff --git a/routing.c b/routing.c
index 1554f60..00e5339 100644
--- a/routing.c
+++ b/routing.c
@@ -1078,6 +1078,10 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 
 	spin_unlock_bh(&orig_node->bcast_seqno_lock);
 
+	/* check whether this has been sent by another originator before */
+	if (bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size))
+		goto out;
+
 	/* rebroadcast packet */
 	add_bcast_packet_to_list(bat_priv, skb, 1);
 
diff --git a/types.h b/types.h
index 0ca2d4c..5f02447 100644
--- a/types.h
+++ b/types.h
@@ -139,6 +139,11 @@ struct neigh_node {
 	spinlock_t tq_lock;	/* protects: tq_recv, tq_index */
 };
 
+struct bcast_duplist_entry {
+	uint8_t orig[ETH_ALEN];
+	uint16_t crc;
+	unsigned long entrytime;
+};
 
 struct bat_priv {
 	atomic_t mesh_state;
@@ -185,6 +190,8 @@ struct bat_priv {
 	struct list_head tt_req_list; /* list of pending tt_requests */
 	struct list_head tt_roam_list;
 	struct hashtable_t *vis_hash;
+	struct bcast_duplist_entry bcast_duplist[DUPLIST_SIZE];
+	int bcast_duplist_curr;
 	spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
 	spinlock_t forw_bcast_list_lock; /* protects  */
 	spinlock_t tt_changes_list_lock; /* protects tt_changes */
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 06/11] batman-adv: don't let backbone gateways exchange tt entries
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

As the backbone gateways are connected to the same backbone, they
should announce the same clients on the backbone non-exclusively.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
[2011-10-27] Changes suggested by Marek Lindner:
 * move rcu_read_lock() more into the loops

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 bridge_loop_avoidance.c |   50 +++++++++++++++++++++++++++++++++++++++++++++++
 bridge_loop_avoidance.h |    1 +
 routing.c               |    6 +++++
 translation-table.c     |   17 ++++++++++++++-
 4 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index bc4e57f..a787c96 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -24,6 +24,7 @@
 #include "hard-interface.h"
 #include "originator.h"
 #include "bridge_loop_avoidance.h"
+#include "translation-table.h"
 #include "send.h"
 
 #include <linux/etherdevice.h>
@@ -350,6 +351,7 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv,
 		uint8_t *orig, short vid)
 {
 	struct backbone_gw *entry;
+	struct orig_node *orig_node;
 
 	entry = backbone_hash_find(bat_priv, orig, vid);
 
@@ -377,6 +379,13 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv,
 	hash_add(bat_priv->backbone_hash, compare_backbone_gw, choose_claim,
 			entry, &entry->hash_entry);
 
+	/* this is a gateway now, remove any tt entries */
+	orig_node = orig_hash_find(bat_priv, orig);
+	if (orig_node) {
+		tt_global_del_orig(bat_priv, orig_node,
+			    "became a backbone gateway");
+		orig_node_free_ref(orig_node);
+	}
 	return entry;
 }
 
@@ -979,6 +988,47 @@ int bla_init(struct bat_priv *bat_priv)
 }
 
 /**
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: originator mac address
+ *
+ * check if the originator is a gateway for any VLAN ID.
+ *
+ * returns 1 if it is found, 0 otherwise
+ *
+ **/
+
+int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig)
+{
+	struct hashtable_t *hash = bat_priv->backbone_hash;
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct backbone_gw *backbone_gw;
+	int i;
+
+	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
+		return 0;
+
+	if (!hash)
+		return 0;
+
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+
+		rcu_read_lock();
+		hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
+			if (compare_eth(backbone_gw->orig, orig)) {
+				rcu_read_unlock();
+				return 1;
+			}
+		}
+		rcu_read_unlock();
+	}
+
+	return 0;
+}
+
+
+/**
  * @skb: the frame to be checked
  * @orig_node: the orig_node of the frame
  * @hdr_size: maximum length of the frame
diff --git a/bridge_loop_avoidance.h b/bridge_loop_avoidance.h
index 91aa515..bafcfac 100644
--- a/bridge_loop_avoidance.h
+++ b/bridge_loop_avoidance.h
@@ -24,6 +24,7 @@ int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid);
 int bla_is_backbone_gw(struct sk_buff *skb,
 		struct orig_node *orig_node, int hdr_size);
 int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
+int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig);
 void bla_update_orig_address(struct bat_priv *bat_priv, uint8_t *newaddr);
 int bla_init(struct bat_priv *bat_priv);
 void bla_free(struct bat_priv *bat_priv);
diff --git a/routing.c b/routing.c
index 8050fb2..1554f60 100644
--- a/routing.c
+++ b/routing.c
@@ -675,6 +675,12 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
 	if (!is_my_mac(roam_adv_packet->dst))
 		return route_unicast_packet(skb, recv_if);
 
+	/* check if it is a backbone gateway. we don't accept
+	 * roaming advertisement from it, as it has the same
+	 * entries as we have. */
+	if (bla_is_backbone_gw_orig(bat_priv, roam_adv_packet->src))
+		goto out;
+
 	orig_node = orig_hash_find(bat_priv, roam_adv_packet->src);
 	if (!orig_node)
 		goto out;
diff --git a/translation-table.c b/translation-table.c
index 946a872..06a51e5 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -27,6 +27,7 @@
 #include "hash.h"
 #include "originator.h"
 #include "routing.h"
+#include "bridge_loop_avoidance.h"
 
 #include <linux/crc16.h>
 
@@ -1501,9 +1502,13 @@ out:
 bool send_tt_response(struct bat_priv *bat_priv,
 		      struct tt_query_packet *tt_request)
 {
-	if (is_my_mac(tt_request->dst))
+	if (is_my_mac(tt_request->dst)) {
+		/* don't answer backbone gws! */
+		if (bla_is_backbone_gw_orig(bat_priv, tt_request->src))
+			return true;
+
 		return send_my_tt_response(bat_priv, tt_request);
-	else
+	} else
 		return send_other_tt_response(bat_priv, tt_request);
 }
 
@@ -1608,6 +1613,10 @@ void handle_tt_response(struct bat_priv *bat_priv,
 		tt_response->tt_data,
 		(tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
 
+	/* we should have never asked a backbone gw */
+	if (bla_is_backbone_gw_orig(bat_priv, tt_response->src))
+		goto out;
+
 	orig_node = orig_hash_find(bat_priv, tt_response->src);
 	if (!orig_node)
 		goto out;
@@ -1922,6 +1931,10 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
 	uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
 	bool full_table = true;
 
+	/* don't care about a backbone gateways updates. */
+	if (bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
+		return;
+
 	/* the ttvn increased by one -> we can apply the attached changes */
 	if (ttvn - orig_ttvn == 1) {
 		/* the OGM could not contain the changes due to their size or
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 05/11] batman-adv: allow multiple entries in tt_global_entries
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

as backbone gateways will all independently announce the same clients,
also the tt global table must be able to hold multiple originators per
client entry.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

---
[2011-10-30] recalculate global crc in any case:

 this should not be required, but the crc diverges for some reason.
 Need to dig into this further ...
---
 translation-table.c |  333 ++++++++++++++++++++++++++++++++++++---------------
 types.h             |   13 ++-
 2 files changed, 246 insertions(+), 100 deletions(-)

diff --git a/translation-table.c b/translation-table.c
index 78b9528..946a872 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -30,10 +30,8 @@
 
 #include <linux/crc16.h>
 
-static void _tt_global_del(struct bat_priv *bat_priv,
-			   struct tt_global_entry *tt_global_entry,
-			   const char *message);
 static void tt_purge(struct work_struct *work);
+static void tt_global_del_orig_list(struct tt_global_entry *tt_global_entry);
 
 /* returns 1 if they are the same mac addr */
 static int compare_ltt(const struct hlist_node *node, const void *data2)
@@ -142,17 +140,30 @@ static void tt_global_entry_free_rcu(struct rcu_head *rcu)
 	struct tt_global_entry *tt_global_entry;
 
 	tt_global_entry = container_of(rcu, struct tt_global_entry, rcu);
-
-	if (tt_global_entry->orig_node)
-		orig_node_free_ref(tt_global_entry->orig_node);
-
 	kfree(tt_global_entry);
 }
 
 static void tt_global_entry_free_ref(struct tt_global_entry *tt_global_entry)
 {
-	if (atomic_dec_and_test(&tt_global_entry->refcount))
+	if (atomic_dec_and_test(&tt_global_entry->refcount)) {
+		tt_global_del_orig_list(tt_global_entry);
 		call_rcu(&tt_global_entry->rcu, tt_global_entry_free_rcu);
+	}
+}
+
+static void tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
+{
+	struct tt_orig_list_entry *orig_entry;
+
+	orig_entry = container_of(rcu, struct tt_orig_list_entry, rcu);
+	atomic_dec(&orig_entry->orig_node->tt_size);
+	orig_node_free_ref(orig_entry->orig_node);
+	kfree(orig_entry);
+}
+
+static void tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry)
+{
+	call_rcu(&orig_entry->rcu, tt_orig_list_entry_free_rcu);
 }
 
 static void tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr,
@@ -201,6 +212,9 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 	struct bat_priv *bat_priv = netdev_priv(soft_iface);
 	struct tt_local_entry *tt_local_entry = NULL;
 	struct tt_global_entry *tt_global_entry = NULL;
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct tt_orig_list_entry *orig_entry;
 
 	tt_local_entry = tt_local_hash_find(bat_priv, addr);
 
@@ -243,13 +257,20 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 
 	/* Check whether it is a roaming! */
 	if (tt_global_entry) {
-		/* This node is probably going to update its tt table */
-		tt_global_entry->orig_node->tt_poss_change = true;
-		/* The global entry has to be marked as PENDING and has to be
-		 * kept for consistency purpose */
+		/* These node are probably going to update their tt table */
+		head = &tt_global_entry->orig_list;
+		rcu_read_lock();
+		hlist_for_each_entry_rcu(orig_entry,
+				node, head, list) {
+			orig_entry->orig_node->tt_poss_change = true;
+
+			/* The global entry has to be marked as PENDING and
+			 * has to be kept for consistency purpose */
+			send_roam_adv(bat_priv, tt_global_entry->addr,
+				orig_entry->orig_node);
+		}
+		rcu_read_unlock();
 		tt_global_entry->flags |= TT_CLIENT_PENDING;
-		send_roam_adv(bat_priv, tt_global_entry->addr,
-			      tt_global_entry->orig_node);
 	}
 out:
 	if (tt_local_entry)
@@ -494,49 +515,90 @@ static void tt_changes_list_free(struct bat_priv *bat_priv)
 	spin_unlock_bh(&bat_priv->tt_changes_list_lock);
 }
 
+/* find out if an orig_node is already in the list of a tt_global_entry.
+ * we expect to have an rcu_readlock outside. */
+static struct tt_orig_list_entry *tt_global_entry_find_orig(
+		struct tt_global_entry *tt_global_entry,
+		struct orig_node *orig_node)
+{
+	struct tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
+	struct hlist_head *head;
+	struct hlist_node *node;
+
+	head = &tt_global_entry->orig_list;
+	hlist_for_each_entry_rcu(tmp_orig_entry,
+			node, head, list) {
+		if (tmp_orig_entry->orig_node == orig_node) {
+			orig_entry = tmp_orig_entry;
+			break;
+		}
+	}
+	return orig_entry;
+}
+
 /* caller must hold orig_node refcount */
 int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node,
 		  const unsigned char *tt_addr, uint8_t ttvn, bool roaming,
 		  bool wifi)
 {
-	struct tt_global_entry *tt_global_entry;
-	struct orig_node *orig_node_tmp;
+	struct tt_global_entry *tt_global_entry = NULL;
+	struct tt_orig_list_entry *orig_entry = NULL;
 	int ret = 0;
 
 	tt_global_entry = tt_global_hash_find(bat_priv, tt_addr);
 
 	if (!tt_global_entry) {
-		tt_global_entry =
-			kmalloc(sizeof(*tt_global_entry),
-				GFP_ATOMIC);
+		tt_global_entry = kzalloc(sizeof(*tt_global_entry),
+			GFP_ATOMIC);
 		if (!tt_global_entry)
 			goto out;
+		orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
+		if (!orig_entry) {
+			kfree(tt_global_entry);
+			tt_global_entry = NULL;
+			goto out;
+		}
 
 		memcpy(tt_global_entry->addr, tt_addr, ETH_ALEN);
-		/* Assign the new orig_node */
-		atomic_inc(&orig_node->refcount);
-		tt_global_entry->orig_node = orig_node;
-		tt_global_entry->ttvn = ttvn;
+
 		tt_global_entry->flags = NO_FLAGS;
 		tt_global_entry->roam_at = 0;
 		atomic_set(&tt_global_entry->refcount, 2);
 
+		INIT_HLIST_HEAD(&tt_global_entry->orig_list);
+		spin_lock_init(&tt_global_entry->list_lock);
+
 		hash_add(bat_priv->tt_global_hash, compare_gtt,
 			 choose_orig, tt_global_entry,
 			 &tt_global_entry->hash_entry);
+	} else {
+		rcu_read_lock();
+		orig_entry = tt_global_entry_find_orig(tt_global_entry,
+				orig_node);
+		rcu_read_unlock();
+
+		if (orig_entry)
+			/* already in the list, no need to add it again */
+			orig_entry = NULL;
+		else
+			orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
+
+		tt_global_entry->flags = NO_FLAGS;
+		tt_global_entry->roam_at = 0;
+	}
+
+	/* new orig_entry needs to be added */
+	if (orig_entry) {
+		INIT_HLIST_NODE(&orig_entry->list);
+		atomic_inc(&orig_node->refcount);
 		atomic_inc(&orig_node->tt_size);
-	} else {
-		if (tt_global_entry->orig_node != orig_node) {
-			atomic_dec(&tt_global_entry->orig_node->tt_size);
-			orig_node_tmp = tt_global_entry->orig_node;
-			atomic_inc(&orig_node->refcount);
-			tt_global_entry->orig_node = orig_node;
-			orig_node_free_ref(orig_node_tmp);
-			atomic_inc(&orig_node->tt_size);
-		}
-		tt_global_entry->ttvn = ttvn;
-		tt_global_entry->flags = NO_FLAGS;
-		tt_global_entry->roam_at = 0;
+		orig_entry->orig_node = orig_node;
+		orig_entry->ttvn = ttvn;
+
+		spin_lock_bh(&tt_global_entry->list_lock);
+		hlist_add_head_rcu(&orig_entry->list,
+				&tt_global_entry->orig_list);
+		spin_unlock_bh(&tt_global_entry->list_lock);
 	}
 
 	if (wifi)
@@ -556,6 +618,33 @@ out:
 	return ret;
 }
 
+/*
+ * print all orig nodes who announce the address for this global entry.
+ * it is assumed that the caller holds rcu_read_lock();
+ */
+static void tt_global_print_entry(struct tt_global_entry *tt_global_entry,
+		struct seq_file *seq)
+{
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct tt_orig_list_entry *orig_entry;
+
+	head = &tt_global_entry->orig_list;
+
+	hlist_for_each_entry_rcu(orig_entry, node, head, list) {
+		seq_printf(seq,	" * %pM  (%3u) via %pM     (%3u)   "
+			"[%c%c%c]\n", tt_global_entry->addr,
+			orig_entry->ttvn,
+			orig_entry->orig_node->orig,
+			(uint8_t) atomic_read(&orig_entry->orig_node->
+				last_ttvn),
+			(tt_global_entry->flags & TT_CLIENT_ROAM ? 'R' : '.'),
+			(tt_global_entry->flags &
+				TT_CLIENT_PENDING ? 'X' : '.'),
+			(tt_global_entry->flags & TT_CLIENT_WIFI ? 'W' : '.'));
+	}
+}
+
 int tt_global_seq_print_text(struct seq_file *seq, void *offset)
 {
 	struct net_device *net_dev = (struct net_device *)seq->private;
@@ -594,21 +683,8 @@ int tt_global_seq_print_text(struct seq_file *seq, void *offset)
 
 		rcu_read_lock();
 		hlist_for_each_entry_rcu(tt_global_entry, node,
-					 head, hash_entry) {
-			seq_printf(seq, " * %pM  (%3u) via %pM     (%3u)   "
-					"[%c%c%c]\n", tt_global_entry->addr,
-					tt_global_entry->ttvn,
-					tt_global_entry->orig_node->orig,
-					(uint8_t) atomic_read(
-						&tt_global_entry->orig_node->
-						last_ttvn),
-					(tt_global_entry->flags &
-					 TT_CLIENT_ROAM ? 'R' : '.'),
-					(tt_global_entry->flags &
-					 TT_CLIENT_PENDING ? 'X' : '.'),
-					(tt_global_entry->flags &
-					 TT_CLIENT_WIFI ? 'W' : '.'));
-		}
+					 head, hash_entry)
+			tt_global_print_entry(tt_global_entry, seq);
 		rcu_read_unlock();
 	}
 out:
@@ -617,27 +693,47 @@ out:
 	return ret;
 }
 
-static void _tt_global_del(struct bat_priv *bat_priv,
-			   struct tt_global_entry *tt_global_entry,
-			   const char *message)
+/* deletes the orig list of a tt_global_entry */
+static void tt_global_del_orig_list(struct tt_global_entry *tt_global_entry)
 {
-	if (!tt_global_entry)
-		goto out;
+	struct hlist_head *head;
+	struct hlist_node *node, *safe;
+	struct tt_orig_list_entry *orig_entry;
 
-	bat_dbg(DBG_TT, bat_priv,
-		"Deleting global tt entry %pM (via %pM): %s\n",
-		tt_global_entry->addr, tt_global_entry->orig_node->orig,
-		message);
+	spin_lock_bh(&tt_global_entry->list_lock);
+	head = &tt_global_entry->orig_list;
+	hlist_for_each_entry_safe(orig_entry, node, safe, head, list) {
+		hlist_del_rcu(node);
+		tt_orig_list_entry_free_ref(orig_entry);
+	}
+	spin_unlock_bh(&tt_global_entry->list_lock);
 
-	atomic_dec(&tt_global_entry->orig_node->tt_size);
+}
+
+static void tt_global_del_orig_entry(struct bat_priv *bat_priv,
+		struct tt_global_entry *tt_global_entry,
+		struct orig_node *orig_node, const char *message)
+{
+	struct hlist_head *head;
+	struct hlist_node *node, *safe;
+	struct tt_orig_list_entry *orig_entry;
 
-	hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
-		    tt_global_entry->addr);
-out:
-	if (tt_global_entry)
-		tt_global_entry_free_ref(tt_global_entry);
+	spin_lock_bh(&tt_global_entry->list_lock);
+	head = &tt_global_entry->orig_list;
+	hlist_for_each_entry_safe(orig_entry, node, safe, head, list) {
+		if (orig_entry->orig_node == orig_node) {
+			bat_dbg(DBG_TT, bat_priv,
+				"Deleting %pM from global tt entry %pM: %s\n",
+				orig_node->orig, tt_global_entry->addr,
+				message);
+			hlist_del_rcu(node);
+			tt_orig_list_entry_free_ref(orig_entry);
+		}
+	}
+	spin_unlock_bh(&tt_global_entry->list_lock);
 }
 
+
 void tt_global_del(struct bat_priv *bat_priv,
 		   struct orig_node *orig_node, const unsigned char *addr,
 		   const char *message, bool roaming)
@@ -648,13 +744,23 @@ void tt_global_del(struct bat_priv *bat_priv,
 	if (!tt_global_entry)
 		goto out;
 
-	if (tt_global_entry->orig_node == orig_node) {
-		if (roaming) {
-			tt_global_entry->flags |= TT_CLIENT_ROAM;
-			tt_global_entry->roam_at = jiffies;
-			goto out;
-		}
-		_tt_global_del(bat_priv, tt_global_entry, message);
+	if (roaming) {
+		tt_global_entry->flags |= TT_CLIENT_ROAM;
+		tt_global_entry->roam_at = jiffies;
+		goto out;
+	}
+	tt_global_del_orig_entry(bat_priv, tt_global_entry,
+			orig_node, message);
+
+	if (hlist_empty(&tt_global_entry->orig_list)) {
+		bat_dbg(DBG_TT, bat_priv,
+			"Deleting global tt entry %pM (via %pM): %s\n",
+			tt_global_entry->addr, orig_node->orig,
+			message);
+
+		hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
+			    tt_global_entry->addr);
+		tt_global_entry_free_ref(tt_global_entry);
 	}
 out:
 	if (tt_global_entry)
@@ -681,12 +787,13 @@ void tt_global_del_orig(struct bat_priv *bat_priv,
 		spin_lock_bh(list_lock);
 		hlist_for_each_entry_safe(tt_global_entry, node, safe,
 					 head, hash_entry) {
-			if (tt_global_entry->orig_node == orig_node) {
+			tt_global_del_orig_entry(bat_priv, tt_global_entry,
+					orig_node, message);
+
+			if (hlist_empty(&tt_global_entry->orig_list)) {
 				bat_dbg(DBG_TT, bat_priv,
-					"Deleting global tt entry %pM "
-					"(via %pM): %s\n",
+					"Deleting global tt entry %pM: %s\n",
 					tt_global_entry->addr,
-					tt_global_entry->orig_node->orig,
 					message);
 				hlist_del_rcu(node);
 				tt_global_entry_free_ref(tt_global_entry);
@@ -718,11 +825,10 @@ static void tt_global_roam_purge(struct bat_priv *bat_priv)
 			if (!is_out_of_time(tt_global_entry->roam_at,
 					    TT_CLIENT_ROAM_TIMEOUT * 1000))
 				continue;
-
 			bat_dbg(DBG_TT, bat_priv, "Deleting global "
 				"tt entry (%pM): Roaming timeout\n",
 				tt_global_entry->addr);
-			atomic_dec(&tt_global_entry->orig_node->tt_size);
+
 			hlist_del_rcu(node);
 			tt_global_entry_free_ref(tt_global_entry);
 		}
@@ -781,6 +887,11 @@ struct orig_node *transtable_search(struct bat_priv *bat_priv,
 	struct tt_local_entry *tt_local_entry = NULL;
 	struct tt_global_entry *tt_global_entry = NULL;
 	struct orig_node *orig_node = NULL;
+	struct neigh_node *router = NULL;
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct tt_orig_list_entry *orig_entry;
+	int best_tq;
 
 	if (src && atomic_read(&bat_priv->ap_isolation)) {
 		tt_local_entry = tt_local_hash_find(bat_priv, src);
@@ -797,16 +908,30 @@ struct orig_node *transtable_search(struct bat_priv *bat_priv,
 	if (tt_local_entry && _is_ap_isolated(tt_local_entry, tt_global_entry))
 		goto out;
 
-	if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
-		goto out;
-
 	/* A global client marked as PENDING has already moved from that
 	 * originator */
 	if (tt_global_entry->flags & TT_CLIENT_PENDING)
 		goto out;
 
-	orig_node = tt_global_entry->orig_node;
+	best_tq = 0;
 
+	rcu_read_lock();
+	head = &tt_global_entry->orig_list;
+	hlist_for_each_entry_rcu(orig_entry, node, head, list) {
+		router = orig_node_get_router(orig_entry->orig_node);
+		if (!router)
+			continue;
+
+		if (router->tq_avg > best_tq) {
+			orig_node = orig_entry->orig_node;
+			best_tq = router->tq_avg;
+		}
+		neigh_node_free_ref(router);
+	}
+	/* found anything? */
+	if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
+			orig_node = NULL;
+	rcu_read_unlock();
 out:
 	if (tt_global_entry)
 		tt_global_entry_free_ref(tt_global_entry);
@@ -822,6 +947,7 @@ uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node)
 	uint16_t total = 0, total_one;
 	struct hashtable_t *hash = bat_priv->tt_global_hash;
 	struct tt_global_entry *tt_global_entry;
+	struct tt_orig_list_entry *orig_entry;
 	struct hlist_node *node;
 	struct hlist_head *head;
 	uint32_t i;
@@ -833,20 +959,25 @@ uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node)
 		rcu_read_lock();
 		hlist_for_each_entry_rcu(tt_global_entry, node,
 					 head, hash_entry) {
-			if (compare_eth(tt_global_entry->orig_node,
-					orig_node)) {
-				/* Roaming clients are in the global table for
-				 * consistency only. They don't have to be
-				 * taken into account while computing the
-				 * global crc */
-				if (tt_global_entry->flags & TT_CLIENT_ROAM)
-					continue;
-				total_one = 0;
-				for (j = 0; j < ETH_ALEN; j++)
-					total_one = crc16_byte(total_one,
-						tt_global_entry->addr[j]);
-				total ^= total_one;
-			}
+			/* Roaming clients are in the global table for
+			 * consistency only. They don't have to be
+			 * taken into account while computing the
+			 * global crc */
+			if (tt_global_entry->flags & TT_CLIENT_ROAM)
+				continue;
+
+			/* find out if this global entry is announced by this
+			 * originator */
+			orig_entry = tt_global_entry_find_orig(tt_global_entry,
+					orig_node);
+			if (!orig_entry)
+				continue;
+
+			total_one = 0;
+			for (j = 0; j < ETH_ALEN; j++)
+				total_one = crc16_byte(total_one,
+					tt_global_entry->addr[j]);
+			total ^= total_one;
 		}
 		rcu_read_unlock();
 	}
@@ -978,11 +1109,18 @@ static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr)
 {
 	const struct tt_global_entry *tt_global_entry = entry_ptr;
 	const struct orig_node *orig_node = data_ptr;
+	struct tt_orig_list_entry *orig_entry;
 
 	if (tt_global_entry->flags & TT_CLIENT_ROAM)
 		return 0;
 
-	return (tt_global_entry->orig_node == orig_node);
+	rcu_read_lock();
+	orig_entry = tt_global_entry_find_orig(
+			(struct tt_global_entry *) tt_global_entry,
+			(struct orig_node *) orig_node);
+	rcu_read_unlock();
+
+	return (orig_entry != NULL);
 }
 
 static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
@@ -1819,6 +1957,7 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
 	} else {
 		/* if we missed more than one change or our tables are not
 		 * in sync anymore -> request fresh tt data */
+		orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
 		if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
 request_table:
 			bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
diff --git a/types.h b/types.h
index 3cffe8d..0ca2d4c 100644
--- a/types.h
+++ b/types.h
@@ -237,12 +237,19 @@ struct tt_local_entry {
 struct tt_global_entry {
 	uint8_t addr[ETH_ALEN];
 	struct hlist_node hash_entry; /* entry in the global table */
-	struct orig_node *orig_node;
-	uint8_t ttvn;
-	uint16_t flags; /* only TT_GLOBAL_ROAM is used */
 	unsigned long roam_at; /* time at which TT_GLOBAL_ROAM was set */
+	uint16_t flags; /* only TT_GLOBAL_ROAM is used */
 	atomic_t refcount;
 	struct rcu_head rcu;
+	struct hlist_head orig_list;
+	spinlock_t list_lock;	/* protects the list */
+};
+
+struct tt_orig_list_entry {
+	struct orig_node *orig_node;
+	uint8_t ttvn;
+	struct rcu_head rcu;
+	struct hlist_node list;
 };
 
 struct backbone_gw {
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 04/11] batman-adv: export claim tables through debugfs
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
[2011-10-27] Changes suggested by Marek Lindner:
 * move rcu_read_lock() more into the loops

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

[2011-10-30] Changes suggested by Marek Lindner:
 * pimp up claim table debugfs output

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 bat_debugfs.c           |   10 +++++++++
 bridge_loop_avoidance.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++
 bridge_loop_avoidance.h |    1 +
 3 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/bat_debugfs.c b/bat_debugfs.c
index 492eec7..20d3fc9 100644
--- a/bat_debugfs.c
+++ b/bat_debugfs.c
@@ -32,6 +32,7 @@
 #include "soft-interface.h"
 #include "vis.h"
 #include "icmp_socket.h"
+#include "bridge_loop_avoidance.h"
 
 static struct dentry *bat_debugfs;
 
@@ -239,6 +240,13 @@ static int transtable_global_open(struct inode *inode, struct file *file)
 	return single_open(file, tt_global_seq_print_text, net_dev);
 }
 
+static int bla_claim_table_open(struct inode *inode, struct file *file)
+{
+	struct net_device *net_dev = (struct net_device *)inode->i_private;
+	return single_open(file, bla_claim_table_seq_print_text, net_dev);
+}
+
+
 static int transtable_local_open(struct inode *inode, struct file *file)
 {
 	struct net_device *net_dev = (struct net_device *)inode->i_private;
@@ -271,6 +279,7 @@ struct bat_debuginfo bat_debuginfo_##_name = {	\
 static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
 static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open);
 static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open);
+static BAT_DEBUGINFO(bla_claim_table, S_IRUGO, bla_claim_table_open);
 static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open);
 static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
 
@@ -278,6 +287,7 @@ static struct bat_debuginfo *mesh_debuginfos[] = {
 	&bat_debuginfo_originators,
 	&bat_debuginfo_gateways,
 	&bat_debuginfo_transtable_global,
+	&bat_debuginfo_bla_claim_table,
 	&bat_debuginfo_transtable_local,
 	&bat_debuginfo_vis_data,
 	NULL,
diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index 641dbcc..bc4e57f 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -1238,3 +1238,54 @@ handled:
 		claim_free_ref(claim);
 	return 1;
 }
+
+int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
+{
+	struct net_device *net_dev = (struct net_device *)seq->private;
+	struct bat_priv *bat_priv = netdev_priv(net_dev);
+	struct hashtable_t *hash = bat_priv->claim_hash;
+	struct claim *claim;
+	struct hard_iface *primary_if;
+	struct hlist_node *node;
+	struct hlist_head *head;
+	uint32_t i;
+	int ret = 0;
+
+	primary_if = primary_if_get_selected(bat_priv);
+	if (!primary_if) {
+		ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
+				 "specify interfaces to enable it\n",
+				 net_dev->name);
+		goto out;
+	}
+
+	if (primary_if->if_status != IF_ACTIVE) {
+		ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+				 "primary interface not active\n",
+				 net_dev->name);
+		goto out;
+	}
+
+	seq_printf(seq, "Claims announced for the mesh %s "
+			"(orig %pM)\n",
+			net_dev->name, bat_priv->own_orig);
+	seq_printf(seq, "   %-17s    %-5s    %-17s [o] (%-4s)\n",
+		   "Client", "VID", "Originator", "CRC");
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+
+		rcu_read_lock();
+		hlist_for_each_entry_rcu(claim, node, head, hash_entry)
+			seq_printf(seq,	" * %pM on % 5d by %pM [%c] (%04x)\n",
+				claim->addr, claim->vid,
+				claim->backbone_gw->orig,
+				(compare_eth(claim->backbone_gw->orig,
+					     bat_priv->own_orig) ? 'x' : ' '),
+				claim->backbone_gw->crc);
+		rcu_read_unlock();
+	}
+out:
+	if (primary_if)
+		hardif_free_ref(primary_if);
+	return ret;
+}
diff --git a/bridge_loop_avoidance.h b/bridge_loop_avoidance.h
index 8df5036..91aa515 100644
--- a/bridge_loop_avoidance.h
+++ b/bridge_loop_avoidance.h
@@ -23,6 +23,7 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid);
 int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid);
 int bla_is_backbone_gw(struct sk_buff *skb,
 		struct orig_node *orig_node, int hdr_size);
+int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
 void bla_update_orig_address(struct bat_priv *bat_priv, uint8_t *newaddr);
 int bla_init(struct bat_priv *bat_priv);
 void bla_free(struct bat_priv *bat_priv);
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 03/11] batman-adv: make bridge loop avoidance switchable
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 bat_sysfs.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/bat_sysfs.c b/bat_sysfs.c
index ec2e437..cb7a524 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -379,6 +379,7 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr,
 
 BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
 BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
+BAT_ATTR_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
 BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu);
 BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
 static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
@@ -396,6 +397,7 @@ BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL);
 static struct bat_attribute *mesh_attrs[] = {
 	&bat_attr_aggregated_ogms,
 	&bat_attr_bonding,
+	&bat_attr_bridge_loop_avoidance,
 	&bat_attr_fragmentation,
 	&bat_attr_ap_isolation,
 	&bat_attr_vis_mode,
-- 
1.7.7.1


^ permalink raw reply related


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.