Netdev List
 help / color / mirror / Atom feed
* Re: [net-next-2.6 PATCH 0/3 RFC] macvlan: MAC Address filtering support for passthru mode
From: Michael S. Tsirkin @ 2011-09-08 11:08 UTC (permalink / raw)
  To: Roopa Prabhu
  Cc: netdev, dragos.tatulea, arnd, dwang2, benve, kaber, sri, davem,
	eric.dumazet, mchan, kvm
In-Reply-To: <CA8D9EAC.33A98%roprabhu@cisco.com>

On Wed, Sep 07, 2011 at 10:20:28PM -0700, Roopa Prabhu wrote:
> On 9/7/11 5:34 AM, "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Tue, Sep 06, 2011 at 03:35:40PM -0700, Roopa Prabhu wrote:
> >> This patch is an attempt at providing address filtering support for macvtap
> >> devices in PASSTHRU mode. Its still a work in progress.
> >> Briefly tested for basic functionality. Wanted to get some feedback on the
> >> direction before proceeding.
> >> 
> > 
> > Good work, thanks.
> > 
> 
> Thanks.
> 
> >> I have hopefully CC'ed all concerned people.
> > 
> > kvm crowd might also be interested.
> > Try using ./scripts/get_maintainer.pl as well.
> > 
> Thanks for the tip. Expanded CC list a bit more.
> 
> >> PASSTHRU mode today sets the lowerdev in promiscous mode. In PASSTHRU mode
> >> there is a 1-1 mapping between macvtap device and physical nic or VF. And all
> >> filtering is done in lowerdev hw. The lowerdev does not need to be in
> >> promiscous mode as long as the guest filters are passed down to the lowerdev.
> >> This patch tries to remove the need for putting the lowerdev in promiscous
> >> mode. 
> >> I have also referred to the thread below where TUNSETTXFILTER was mentioned
> >> in 
> >> this context: 
> >>  http://patchwork.ozlabs.org/patch/69297/
> >> 
> >> This patch basically passes the addresses got by TUNSETTXFILTER to macvlan
> >> lowerdev.
> >> 
> >> I have looked at previous work and discussions on this for qemu-kvm
> >> by Michael Tsirkin, Alex Williamson and Dragos Tatulea
> >> http://patchwork.ozlabs.org/patch/78595/
> >> http://patchwork.ozlabs.org/patch/47160/
> >> https://patchwork.kernel.org/patch/474481/
> >> 
> >> Redhat bugzilla by Michael Tsirkin:
> >> https://bugzilla.redhat.com/show_bug.cgi?id=655013
> >> 
> >> I used Michael's qemu-kvm patch for testing the changes with KVM
> >> 
> >> I would like to cover both MAC and vlan filtering in this work.
> >> 
> >> Open Questions/Issues:
> >> - There is a need for vlan filtering to complete the patch. It will require
> >>   a new tap ioctl cmd for vlans.
> >>   Some ideas on this are:
> >> 
> >>   a) TUNSETVLANFILTER: This will entail we send the whole vlan bitmap filter
> >> (similar to tun_filter for addresses). Passing the vlan id's to lower
> >> device will mean going thru the whole list of vlans every time.
> >> 
> >>   OR
> >> 
> >>   b) TUNSETVLAN with vlan id and flag to set/unset
> >> 
> >>   Does option 'b' sound ok ?
> >> 
> >> - In this implementation we make the macvlan address list same as the address
> >>   list that came in the filter with TUNSETTXFILTER. This will not cover cases
> >>   where the macvlan device needs to have other addresses that are not
> >>   necessarily in the filter. Is this a problem ?
> > 
> > What cases do you have in mind?
> > 
> This patch targets only macvlan PASSTHRU mode and for PASSTHRU mode I don't
> see a problem with uc/mc address list being the same in all the stacked
> netdevs in the path. I called that out above to make sure I was not missing
> any case in PASSTHRU mode where this might be invalid. Otherwise I don't see
> a problem in the simple PASSTHRU use case this patch supports.
> 
> >> - The patch currently only supports passing of IFF_PROMISC and IFF_MULTICAST
> >> filter flags to lowerdev
> >> 
> >> This patch series implements the following
> >> 01/3 - macvlan: Add support for unicast filtering in macvlan
> >> 02/3 - macvlan: Add function to set addr filter on lower device in passthru
> >> mode
> >> 03/3 - macvtap: Add support for TUNSETTXFILTER
> >> 
> >> Please comment. Thanks.
> >> 
> >> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
> >> Signed-off-by: Christian Benvenuti <benve@cisco.com>
> >> Signed-off-by: David Wang <dwang2@cisco.com>
> > 
> > The security isn't lower than with promisc, so I don't see
> > a problem with this as such.
> > 
> > There are more features we'll want down the road though,
> > so let's see whether the interface will be able to
> > satisfy them in a backwards compatible way before we
> > set it in stone. Here's what I came up with:
> > 
> > How will the filtering table be partitioned within guests?
> 
> Since this patch supports macvlan PASSTHRU mode only, in which the lower
> device has 1-1 mapping to the guest nic, it does not require any
> partitioning of filtering table within guests. Unless I missed understanding
> something. 
> If the lower device were being shared by multiple guest network interfaces
> (non PASSTHRU mode), only then we will need to maintain separate filter
> tables for each guest network interface in macvlan and forward the pkt to
> respective guest interface after a filter lookup. This could affect
> performance too I think.

Not with hardware filtering support. Which is where we'd need to
partition the host nic mac table between guests.

> I chose to support PASSTHRU Mode only at first because its simpler and all
> code additions are in control path only.

I agree. It would be a bit silly to have a dedicated interface
for passthough and a completely separate one for
non passthrough.

> > 
> > A way to limit what the guest can do would also be useful.
> > How can this be done? selinux?
> 
> I vaguely remember a thread on the same context.. had a suggestion to
> maintain pre-approved address lists and allow guest filter registration of
> only those addresses for security. This seemed reasonable. Plus the ability
> to support additional address registration from guest could be made
> configurable (One of your ideas again from prior work).
> 
> I am not an selinux expert, but I am thinking we can use it to only allow or
> disallow access or operations to the macvtap device. (?). I will check more
> on this.

We'd have to have a way to revoke that as well.

> > 
> > Any thoughts on spoofing filtering?
> 
> I can only think of checking addresses against an allowed address list.
> Don't know of any other ways. Any hints ?

Hardware (esp SRIOV) often has ways to do this check, too.

> 
> In any case I am assuming all the protection/security measures should be
> taken at the layer calling the TUNSETTXFILTER ie..In macvtap virtualization
> use case its libvirt or qemu-kvm. No ?

Ideally we'd have a way to separate these capabilities, so that libvirt
can override qemu.

> > 
> > Would it be possible to make the filtering programmable
> > using netlink, e.g. ethtool, ip, or some such?
> 
> Should be possible via ethtool or ip calling ioctl TUNSETTXFILTER. Are you
> thinking of macvlan having a netlink interface to set filter and not ioctl
> ?. Sure.

Yes.

> But I was thinking the point of implementing TUNSETTXFILTER was to
> maintain compatibility with the generic tap interface that does the same
> thing. 

Yes. OTOH I don't think anyone uses that ATM so it might not
be important if it's not a good fit.
E.g. we could notify libvirt and have it use netlink for us
if we like that better.

> And having both the netlink op and ioctl interface might not be clean ?.

No idea.

> Sorry if I misunderstood your question.
> 
> > That would make this useful for bridged setups besides
> > macvtap/virtualization.
> > 
> 
> Thanks for the comments. 

^ permalink raw reply

* (unknown), 
From: DEACONNESS CLARA BENZ @ 2011-09-08 23:34 UTC (permalink / raw)


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

KINDLY DOWNLOAD ATTACHMENT

[-- Attachment #2: CLARA BENZ.txt --]
[-- Type: application/octet-stream, Size: 1159 bytes --]

I am happy to finally contact you on your new email id as i have been trying to reach you 
regarding your 800,000USD Draft which i have with me.But due to the fact that i couldnt 
reach you i then decided to deposite the draft with Fedex courier service United Kingdom(England).
for them to deliver it to you.I travelled out of the country for some official duties and
i will be staying for 3months.

Kindly contact them immediately  by clicking reply to so that they can let you know when delivery will be
made to you.here is there contact number Tel- +447010039919(Mr Anthny moore).The tracking number will
be provided to you by Fedex.You are to send your mobile details.

You are requried to pay $85 USD as secuity deposite as they(Fedex) have refused to 
accept the amount because they dont know when you will contact them and so decided to avoid any
sort of demurages.Make sure  you confirm your postal address and telephone numbers to them when contacting them.
All other chrages including delivey and premiun charges have been paid already by me.Thanks once more and do contact
them as soon as you receive this email.fedex212unit@qatar.io

^ permalink raw reply

* Re: [PATCH] net: phy: Add config option to specify external switch port to be used if switch is used as PHY
From: Lambrecht Jürgen @ 2011-09-08 11:59 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev@vger.kernel.org, linux-embedded@vger.kernel.org
In-Reply-To: <20110908101315.GA27909@electric-eye.fr.zoreil.com>

On 09/08/2011 12:13 PM, Francois Romieu wrote:
>
> Lambrecht Jürgen <J.Lambrecht@TELEVIC.com> :
> [...]
> > diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
> > index 6c58da2..016437a 100644
> > --- a/drivers/net/phy/mdio_bus.c
> > +++ b/drivers/net/phy/mdio_bus.c
> > @@ -112,7 +112,14 @@ int mdiobus_register(struct mii_bus *bus)
> >          if (bus->reset)
> >                  bus->reset(bus);
> >
> > +       /* The config below is always availble with CONFIG_PHYLIB. 
> If 0, the
> > +          behavior is as before without this patch (or P0 of the 
> switch is
> > +          taken because it is the first one found). */
> > +#if CONFIG_SWITCH_PHY
> > +       i = CONFIG_SWITCH_PHY;
> > +#else
> >          for (i = 0; i < PHY_MAX_ADDR; i++) {
> > +#endif
> >                  if ((bus->phy_mask & (1 << i)) == 0) {
> >                          struct phy_device *phydev;
>
> This config option may help your platform but it is nowhere reusable on a
> slightly different one (each mii_bus behavior is changed).
>
> Which driver(s) do you use that you can not set phy_mask directly ?
>
The HW driver is 'FEC' for iMX Ethernet. For the PHY, just MII and PHYLIB.
I am rather new to linux, didn't knew phy_mask. Checked it now, and is 
not set in fec.c.
You mean then to patch drivers/net/fec.c in the same way (as my current 
patch) to set the phy_mask instead (via menuconfig, or in the platform 
init)?

Thanks for your reply,
Jürgen
>
>
> --
> Ueimor
>


-- 
Jürgen Lambrecht
R&D Associate
Tel: +32 (0)51 303045    Fax: +32 (0)51 310670
http://www.televic-rail.com
Televic Rail NV - Leo Bekaertlaan 1 - 8870 Izegem - Belgium
Company number 0825.539.581 - RPR Kortrijk

^ permalink raw reply

* Re: [PATCH v2 3/9] socket: initial cgroup code.
From: Glauber Costa @ 2011-09-08 12:41 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: linux-kernel, xemul, netdev, linux-mm, Eric W. Biederman,
	containers, David S. Miller
In-Reply-To: <20110908053558.GA9464@shutemov.name>

On 09/08/2011 02:35 AM, Kirill A. Shutemov wrote:
> On Thu, Sep 08, 2011 at 01:54:03AM -0300, Glauber Costa wrote:
>> On 09/07/2011 07:17 PM, Kirill A. Shutemov wrote:
>>> On Wed, Sep 07, 2011 at 01:23:13AM -0300, Glauber Costa wrote:
>>>> We aim to control the amount of kernel memory pinned at any
>>>> time by tcp sockets. To lay the foundations for this work,
>>>> this patch adds a pointer to the kmem_cgroup to the socket
>>>> structure.
>>>>
>>>> Signed-off-by: Glauber Costa<glommer@parallels.com>
>>>> CC: David S. Miller<davem@davemloft.net>
>>>> CC: Hiroyouki Kamezawa<kamezawa.hiroyu@jp.fujitsu.com>
>>>> CC: Eric W. Biederman<ebiederm@xmission.com>
>>>> ---
>>>>    include/linux/kmem_cgroup.h |   29 +++++++++++++++++++++++++++++
>>>>    include/net/sock.h          |    2 ++
>>>>    net/core/sock.c             |    5 ++---
>>>>    3 files changed, 33 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/include/linux/kmem_cgroup.h b/include/linux/kmem_cgroup.h
>>>> index 0e4a74b..77076d8 100644
>>>> --- a/include/linux/kmem_cgroup.h
>>>> +++ b/include/linux/kmem_cgroup.h
>>>> @@ -49,5 +49,34 @@ static inline struct kmem_cgroup *kcg_from_task(struct task_struct *tsk)
>>>>    	return NULL;
>>>>    }
>>>>    #endif /* CONFIG_CGROUP_KMEM */
>>>> +
>>>> +#ifdef CONFIG_INET
>>>
>>> Will it break something if you define the helpers even if CONFIG_INET
>>> is not defined?
>>> It will be much cleaner. You can reuse ifdef CONFIG_CGROUP_KMEM in this
>>> case.
>>
>> The helpers inside CONFIG_INET are needed for the network code,
>> regardless of kmem cgroup is defined or not, not the other way around.
>>
>> So I could remove CONFIG_INET, but I can't possibly move it inside
>> CONFIG_CGROUP_KMEM. So this buy us nothing.
>
> You can define empty under CONFIG_CGROUP_KMEM's #else, can't you?
> Like with kcg_from_cgroup()/kcg_from_task().
>
Do you really think it is cleaner?

Why would I define empty something that is not empty at all?
Look again. Most of those helpers would be the exact same with or 
without CONFIG_CGROUP_KMEM . The others, very few differences. If 
CONFIG_INET bothers you, I can remove it altogether, making it 
unconditional. But moving it inside CONFIG_CGROUP_KMEM makes no sense.

--
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

* [PATCH net-next v3] af_unix: Fix use-after-free crashes
From: Eric Dumazet @ 2011-09-08 13:21 UTC (permalink / raw)
  To: sedat.dilek
  Cc: Yan, Zheng, Tim Chen, Yan, Zheng, netdev@vger.kernel.org,
	davem@davemloft.net, sfr@canb.auug.org.au, jirislaby@gmail.com,
	Shi, Alex, Valdis Kletnieks
In-Reply-To: <CA+icZUWH8953m4qs74JLhNwrzJM0eMfE8aizJ1XtuVFFTtLKqg@mail.gmail.com>

Le jeudi 08 septembre 2011 à 11:59 +0200, Sedat Dilek a écrit :

> I have tested this fixup patch on i386.
> Can we have a separate patch with corrected descriptive text?
> 
> Thanks to all involved people.

Here it is :

[PATCH net-next v3] af_unix: Fix use-after-free crashes

Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced an use-after-free
bug.

We are allowed to steal the references to pid/cred only in the last skb
sent from unix_stream_sendmsg(), because first skbs might be consumed by
the receiver before we finish our sendmsg() call.

Remove scm_release() helper, since its cleaner to clear pid/cred fields
in unix_scm_to_skb() when we steal them.

Based on prior patches from Yan Zheng and Tim Chen

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Reported-by: Jiri Slaby <jirislaby@gmail.com>
Tested-by: Sedat Dilek <sedat.dilek@googlemail.com>
Tested-by: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
---
 include/net/scm.h  |    9 ---------
 net/unix/af_unix.c |   32 +++++++++++++++++---------------
 2 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/include/net/scm.h b/include/net/scm.h
index 68e1e48..2a5b42f 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -78,15 +78,6 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 		__scm_destroy(scm);
 }
 
-static __inline__ void scm_release(struct scm_cookie *scm)
-{
-	/* keep ref on pid and cred */
-	scm->pid = NULL;
-	scm->cred = NULL;
-	if (scm->fp)
-		__scm_destroy(scm);
-}
-
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm)
 {
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e6d9d10..c8a08ba 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1379,15 +1379,18 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
 }
 
 static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb,
-			   bool send_fds, bool ref)
+			   bool send_fds, bool steal_refs)
 {
 	int err = 0;
-	if (ref) {
+
+	if (!steal_refs) {
 		UNIXCB(skb).pid  = get_pid(scm->pid);
 		UNIXCB(skb).cred = get_cred(scm->cred);
 	} else {
 		UNIXCB(skb).pid  = scm->pid;
 		UNIXCB(skb).cred = scm->cred;
+		scm->pid = NULL;
+		scm->cred = NULL;
 	}
 	UNIXCB(skb).fp = NULL;
 	if (scm->fp && send_fds)
@@ -1454,7 +1457,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
 	if (skb == NULL)
 		goto out;
 
-	err = unix_scm_to_skb(siocb->scm, skb, true, false);
+	err = unix_scm_to_skb(siocb->scm, skb, true, true);
 	if (err < 0)
 		goto out_free;
 	max_level = err + 1;
@@ -1550,7 +1553,7 @@ restart:
 	unix_state_unlock(other);
 	other->sk_data_ready(other, len);
 	sock_put(other);
-	scm_release(siocb->scm);
+	scm_destroy(siocb->scm);
 	return len;
 
 out_unlock:
@@ -1577,6 +1580,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 	int sent = 0;
 	struct scm_cookie tmp_scm;
 	bool fds_sent = false;
+	bool steal_refs = false;
 	int max_level;
 
 	if (NULL == siocb->scm)
@@ -1638,11 +1642,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 		size = min_t(int, size, skb_tailroom(skb));
 
 
-		/* Only send the fds and no ref to pid in the first buffer */
-		err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, fds_sent);
+		/* Only send the fds in first buffer
+		 * Last buffer can steal our references to pid/cred
+		 */
+		steal_refs = (sent + size >= len);
+		err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, steal_refs);
 		if (err < 0) {
 			kfree_skb(skb);
-			goto out;
+			goto out_err;
 		}
 		max_level = err + 1;
 		fds_sent = true;
@@ -1650,7 +1657,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 		err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
 		if (err) {
 			kfree_skb(skb);
-			goto out;
+			goto out_err;
 		}
 
 		unix_state_lock(other);
@@ -1667,10 +1674,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 		sent += size;
 	}
 
-	if (skb)
-		scm_release(siocb->scm);
-	else
-		scm_destroy(siocb->scm);
+	scm_destroy(siocb->scm);
 	siocb->scm = NULL;
 
 	return sent;
@@ -1683,9 +1687,7 @@ pipe_err:
 		send_sig(SIGPIPE, current, 0);
 	err = -EPIPE;
 out_err:
-	if (skb == NULL)
-		scm_destroy(siocb->scm);
-out:
+	scm_destroy(siocb->scm);
 	siocb->scm = NULL;
 	return sent ? : err;
 }

^ permalink raw reply related

* Re: [PATCH -next v2] unix stream: Fix use-after-free crashes
From: Eric Dumazet @ 2011-09-08 13:28 UTC (permalink / raw)
  To: Tim Chen
  Cc: Yan, Zheng, Yan, Zheng, netdev@vger.kernel.org,
	davem@davemloft.net, sfr@canb.auug.org.au, jirislaby@gmail.com,
	sedat.dilek@gmail.com, Shi, Alex, Valdis Kletnieks
In-Reply-To: <1315430766.2532.1.camel@edumazet-laptop>

Le mercredi 07 septembre 2011 à 23:26 +0200, Eric Dumazet a écrit :
> Le mercredi 07 septembre 2011 à 05:01 -0700, Tim Chen a écrit :

> > Eric, are you planning to do a fast path patch that doesn't do pid ref
> > for the case where CONFIG_PID_NS is not set?
> > 
> 
> Yes, I'll try to cook a patch.

Thinking a bit more on this issue, I really believe we should not stick
pid/cred in skbs sent from a write() system call.

That would break following use case :

An application uses a write(fd) and expects a receiver using recvmsg()
to get process credentials (SCM_CREDENTIALS)

This is currently working, but not documented (man unix says ancillary
data are sent with sendmsg())

If everybody agrees, I can send a patch for this : This would speedup
write()/read() af_unix by an order of magnitude.

^ permalink raw reply

* Re: [PATCH 45/62] net: irq: Remove IRQF_DISABLED
From: Yong Zhang @ 2011-09-08 13:41 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: perex, dhowells, prakity, netdev, chunkeey, sonic.zhang,
	klaus.kudielka, t.sailer, khilman, eric.dumazet, jhovold, cyril,
	rmk+kernel, mingo, jpr, adobriyan, jreuter, cbe-oss-dev,
	martinez.javier, samuel, vapier, grundler, tklauser,
	lucas.demarchi, u.kleine-koenig, olof, uclinux-dist-devel,
	linux-hams, leitao, blogic, shawn.guo, nico, geoff, jkosina,
	linux-wireless, linux-kernel, ralf, ralph.hempel, jdmas
In-Reply-To: <alpine.LFD.2.02.1109072000290.2723@ionos>

On Wed, Sep 07, 2011 at 08:03:14PM +0200, Thomas Gleixner wrote:
> On Wed, 7 Sep 2011, David Miller wrote:
> 
> > From: Thomas Gleixner <tglx@linutronix.de>
> > Date: Wed, 7 Sep 2011 19:32:39 +0200 (CEST)
> > 
> > > On Wed, 7 Sep 2011, David Miller wrote:
> > > 
> > >> From: Yong Zhang <yong.zhang0@gmail.com>
> > >> Date: Wed,  7 Sep 2011 16:10:42 +0800
> > >> 
> > >> > This flag is a NOOP and can be removed now.
> > >> > 
> > >> > Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
> > >> 
> > >> I have the same concerns here as I had for the sparc case.
> > >> 
> > >> Some of these drivers might be using IRQF_DISABLED to make sure the
> > >> IRQ cannot be delivered until it is explicitly enabled via an
> > >> enable_irq() call.
> > >> 
> > >> How is that being accomodated now?
> > > 
> > > Again IRQF_DISABLED never ever had that functionality. 
> > 
> > My bad.
> > 
> > But what if these interrupts want interrupts disabled during their
> > interrupt handler, for other reasons?
> 
> We run ALL interrupt handlers with irqs disabled always.
>  
> > This has the potential to break tons of stuff, especially on the
> > really old chips which almost no developers have any more but some
> > user might try to use.
> 
> It won't. We removed IRQF_DISABLED from kernel/irq/* long ago

Yeah, and this is why we say it's a NOOP now :)

Thanks,
Yong

^ permalink raw reply

* Uk Winner
From: Sir Ivan Smith @ 2011-09-08 13:53 UTC (permalink / raw)


Your E-Address was selected online in this week's Monday online Promo.Your draw has a total value of 891,934,00GBP.Please acknowledge the receipt of this mail with your full details such as,name,age,occupation,tel no sex,country etc to: Mr.Peter Mansen..Email:(mnlclaims@hotmail.com) CALL NOW: Tel: +447024055916.

^ permalink raw reply

* Re: possible routing table cache bug for mtu/advmss attributes in Linux 3.0.4
From: Yan, Zheng  @ 2011-09-08 14:42 UTC (permalink / raw)
  To: David Madore; +Cc: Linux Netdev Mailing-List
In-Reply-To: <20110901214643.GA16989@aldebaran.gro-tsen.net>

On Fri, Sep 2, 2011 at 5:46 AM, David Madore <david+ml@madore.org> wrote:
> Hi,
>
> I believe I've found a bug in the routing cache (perhaps only for
> IPv6) in Linux 3.0.4.  Since I'm uncertain about the diagnosis, I'm
> posting here for guidance as to how to proceed.
>
> In a nutshell, the problem is this: my (manually entered) routing
> tables specify an explicit MTU/MSS for certain IPv6 routes, and after
> upgrading from 2.6.38.7 to 3.0.4, I found that this MTU/MSS setting is
> sometimes ignored.  More precisely, it seems that connecting to a host
> through the route in question causes a routing cache entry to be
> created, and it is when this cache entry expires that the route
> forgets the MTU/MSS setting.  (It may also be relevant that in my case
> the route belongs to a routing table other than "main".)
>
> In more details: my routing tables contains the following:
>
> vega david ~ $ sudo ip -6 rule show
> 0:      from all lookup local
> 32766:  from all lookup main
> 40000:  from 2002::/16 lookup 2002
> 40100:  from all lookup 2001
> vega david ~ $ sudo ip -6 route show table 2001
> 2002::/16 via ::192.88.99.1 dev tun6to4  metric 512  mtu 1466 advmss 1406
> 2000::/3 dev ppp0  metric 64  mtu 1466 advmss 1406
>
> Initially, trying to get the route to 2001:41d0:1:a431::1 correctly
> returns route with the mtu and advmss values I entered:
>
> vega david ~ $ sudo ip route get 2001:41d0:1:a431::1
> 2001:41d0:1:a431::1 from :: via 2001:41d0:1:a431::1 dev ppp0  src 2001:7a8:78ae::1  metric 0
>    cache  mtu 1466 advmss 1406
>
> Now I start an ssh connection to 2001:41d0:1:a431::1, close it
> immediately, and fetch the route again:
>
> vega david ~ $ sudo ip route get 2001:41d0:1:a431::1
> 2001:41d0:1:a431::1 from :: via 2001:41d0:1:a431::1 dev ppp0  src 2001:7a8:78ae::1  metric 0
>    cache  mtu 1466 rtt 37ms rttvar 37ms cwnd 10 advmss 1406
>
> This is still correct.  But if I wait a few seconds (doing nothing)
> for these data to expire, they seems to take the mtu and advmss values
> away with them:
>
> vega david ~ $ sudo ip route get 2001:41d0:1:a431::1
> 2001:41d0:1:a431::1 from :: via 2001:41d0:1:a431::1 dev ppp0  src 2001:7a8:78ae::1  metric 0
>    cache
>
> (note the empty "cache" line and the absence of mtu/advmss settings).
>
> This is not just wrongly reported: the route really is wrong, and
> opening a TCP connection at this stage will use a wrong MSS (and
> freeze on large packets, because my Internet provider is worthless,
> but that's another story).  At some point the route seems to return to
> normal, but I couldn't figure out what causes this exactly.
>
> In case it's uesful, my kernel config is on <URL:
> http://www.madore.org/~david/.tmp/config-3.0.4-vega
>  >.
>

Would you please try patch http://marc.info/?l=linux-netdev&m=131529445904858

Thanks

> Any thoughts?
>
> --
>     David A. Madore
>   ( http://www.madore.org/~david/ )
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.

^ permalink raw reply

* Re: [PATCH v3] net/smsc911x: add device tree probe support
From: Dave Martin @ 2011-09-08 14:59 UTC (permalink / raw)
  To: Shawn Guo
  Cc: netdev, patches, devicetree-discuss, Grant Likely,
	Steve Glendinning, David S. Miller, linux-arm-kernel
In-Reply-To: <1312050360-15767-1-git-send-email-shawn.guo@linaro.org>

Hi Shawn,

On Sun, Jul 31, 2011 at 02:26:00AM +0800, Shawn Guo wrote:
> It adds device tree probe support for smsc911x driver.
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Steve Glendinning <steve.glendinning@smsc.com>
> Cc: David S. Miller <davem@davemloft.net>
> Reviewed-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> Changes since v2:
>  * Fix a typo in smsc911x.txt
> 
> Changes since v1:
>  * Instead of getting irq line from gpio number, it use irq domain
>    to keep platform_get_resource(IORESOURCE_IRQ) works for dt too.
>  * Use 'lan9115' the first model that smsc911x supports in the match
>    table
>  * Use reg-shift and reg-io-width which already used in of_serial for
>    shift and access size binding

When using this patch with vexpress, I found that 16-bit register access
mode doesn't seem to be getting set correctly.

Can you take a look at this additional patch and let me know if it looks
correct?

Cheers
---Dave

From: Dave Martin <dave.martin@linaro.org>
Date: Wed, 7 Sep 2011 17:26:31 +0100
Subject: [PATCH] net/smsc911x: Correctly configure 16-bit register access from DT

The SMSC911X_USE_16BIT needs to be set when using 16-bit register
access.  However, currently no flag is set if the DT doesn't specify
32-bit access.

This patch should set the SMSC911X_USE_16BIT flag in a manner consistent
with the documented DT bindings.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
 drivers/net/smsc911x.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 75c08a5..1a35c25 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -2121,6 +2121,8 @@ static int __devinit smsc911x_probe_config_dt(
 	of_property_read_u32(np, "reg-io-width", &width);
 	if (width == 4)
 		config->flags |= SMSC911X_USE_32BIT;
+	else
+		config->flags |= SMSC911X_USE_16BIT;
 
 	if (of_get_property(np, "smsc,irq-active-high", NULL))
 		config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
-- 
1.7.4.1

^ permalink raw reply related

* Re: [PATCH net-next v3] af_unix: Fix use-after-free crashes
From: Tim Chen @ 2011-09-08  8:37 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: sedat.dilek, Yan, Zheng, Yan, Zheng, netdev@vger.kernel.org,
	davem@davemloft.net, sfr@canb.auug.org.au, jirislaby@gmail.com,
	Shi, Alex, Valdis Kletnieks
In-Reply-To: <1315488103.2456.16.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>

On Thu, 2011-09-08 at 15:21 +0200, Eric Dumazet wrote:
> Le jeudi 08 septembre 2011 à 11:59 +0200, Sedat Dilek a écrit :
> 
> > I have tested this fixup patch on i386.
> > Can we have a separate patch with corrected descriptive text?
> > 
> > Thanks to all involved people.
> 
> Here it is :
> 
> [PATCH net-next v3] af_unix: Fix use-after-free crashes
> 
> Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
> in Unix socket's send and receive path) introduced an use-after-free
> bug.
> 
> We are allowed to steal the references to pid/cred only in the last skb
> sent from unix_stream_sendmsg(), because first skbs might be consumed by
> the receiver before we finish our sendmsg() call.
> 
> Remove scm_release() helper, since its cleaner to clear pid/cred fields
> in unix_scm_to_skb() when we steal them.
> 
> Based on prior patches from Yan Zheng and Tim Chen
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Reported-by: Jiri Slaby <jirislaby@gmail.com>
> Tested-by: Sedat Dilek <sedat.dilek@googlemail.com>
> Tested-by: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
> ---

Thanks.

Acked-by: Tim Chen <tim.c.chen@linux.intel.com>

^ permalink raw reply

* [RFC PATCH 12/11] netlink: improve flow control and speed up dumps with memory mapped I/O
From: Patrick McHardy @ 2011-09-08 16:36 UTC (permalink / raw)
  To: netfilter-devel@vger.kernel.org; +Cc: NetDev

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

This patch on top of the memory mapped netlink I/O series is
meant to speed up dumps by dumping messages more aggressively.

Messages are dumped until half the ring is used, this is similar
to flow-control used with regular I/O with the difference that
all messages are constructed during a single poll call instead
of multiple recvmsg() calls.

The result is not as good as I expected, dumping 196611
routes using rtnl-route-dump from libmnl show the following
results (averaged over 10 runs):

user-time: -7.9%
system-time: -10.4%
real-time: +0.09%
CPU: -7.45%

Strangely the real time stays almost the same and CPU usage
decreases by a few percent - I would have expected a reduction
of real-time with identical CPU usage (99%). Not sure what
the reason is, will try to investigate further.


[-- Attachment #2: nldump.diff --]
[-- Type: text/plain, Size: 1951 bytes --]

commit 1eadec60573240c2b6ee3ce942471b3e0656e4dc
Author: Patrick McHardy <kaber@trash.net>
Date:   Thu Sep 8 16:26:27 2011 +0200

    netlink: improve flow control and speed up dumps with memory mapped I/O
    
    Improve dump flow control with memory mapped I/O: dumps are only continued
    if at least half the ring is free, similar to regular I/O. This minimizes
    the risk of receiving socket errors when the socket is also used for receiving
    regular unicast messages.
    
    Additionally speed up dumps by dumping multiple messages at once until
    the dump is either complete or less than half the ring is free.
    
    Signed-off-by: Patrick McHardy <kaber@trash.net>

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 2f4745d..fadf216 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -530,6 +530,24 @@ static void netlink_forward_ring(struct netlink_ring *ring)
 	} while (ring->head != head);
 }
 
+static bool netlink_dump_space(struct netlink_sock *nlk)
+{
+	struct netlink_ring *ring = &nlk->rx_ring;
+	struct nl_mmap_hdr *hdr;
+	unsigned int n;
+
+	hdr = netlink_current_frame(ring, NL_MMAP_STATUS_UNUSED);
+	if (hdr == NULL)
+		return false;
+
+	n = ring->head + ring->frame_max / 2;
+	if (n > ring->frame_max)
+		n -= ring->frame_max;
+	hdr = __netlink_lookup_frame(ring, n);
+
+	return hdr->nm_status == NL_MMAP_STATUS_UNUSED;
+}
+
 static unsigned int netlink_poll(struct file *file, struct socket *sock,
 				 poll_table *wait)
 {
@@ -543,11 +561,12 @@ static unsigned int netlink_poll(struct file *file, struct socket *sock,
 		 * is performed here under the assumption that the entire ring
 		 * has been processed before invoking poll().
 		 */
-		if (nlk->cb != NULL) {
+		while (nlk->cb != NULL && netlink_dump_space(nlk)) {
 			err = netlink_dump(sk);
 			if (err < 0) {
 				sk->sk_err = err;
 				sk->sk_error_report(sk);
+				break;
 			}
 		}
 		netlink_rcv_wake(sk);

^ permalink raw reply related

* pull request: batman-adv 2011-09-08
From: Marek Lindner @ 2011-09-08 16:40 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r

Hi,

here comes the next batch batch I'd like to get the pulled into 
net-next-2.6/3.2. These patches mainly focus restructering the 
routing code in order to allow the kernel module the handling
of the current routing algorithm and the upcoming one. 

To ensure a smooth transition and efficient testing later, we 
decided to offer a choice of routing algorithm but have not     
come to a final decision on how to design this choice yet. It
either will be a compile time option, a module parameter or a
runtime switch. Any suggestions / best practice tips ?

Note: The new algorithm has been designed with backward 
compatibility in mind (using TLVs). We are trying to address
the incompatibility issue you and others have pointed out.

Thanks,
Marek

The following changes since commit a943cac144e035c21d4f1b31b95f15b33c33a480:

  batman-adv: merge update_transtable() into tt related code (2011-08-22 15:16:22 +0200)

are available in the git repository at:
  git://git.open-mesh.org/linux-merge.git batman-adv/next

Joe Perches (1):
      batman-adv: Remove unnecessary OOM logging messages

Marek Lindner (4):
      batman-adv: rename all instances of batman_packet to batman_ogm_packet
      batman-adv: agglomerate all batman iv ogm processing functions in a single file
      batman-adv: move routing packet initialization into corresponding file
      batman-adv: agglomerate all batman iv ogm sending functions in the batman iv file

Simon Wunderlich (1):
      batman-adv: update README (date & ap isolation sysfs file)

Sven Eckelmann (1):
      batman-adv: update internal version number

 Documentation/networking/batman-adv.txt     |    8 +-
 net/batman-adv/Makefile                     |    2 +-
 net/batman-adv/aggregation.c                |  293 -------
 net/batman-adv/bat_iv_ogm.c                 | 1170 +++++++++++++++++++++++++++
 net/batman-adv/{aggregation.h => bat_ogm.h} |   30 +-
 net/batman-adv/hard-interface.c             |   54 +-
 net/batman-adv/main.c                       |    2 -
 net/batman-adv/main.h                       |    2 +-
 net/batman-adv/originator.c                 |   19 +-
 net/batman-adv/packet.h                     |   18 +-
 net/batman-adv/routing.c                    |  602 +-------------
 net/batman-adv/routing.h                    |   17 +-
 net/batman-adv/send.c                       |  305 +-------
 net/batman-adv/send.h                       |    9 +-
 net/batman-adv/soft-interface.c             |   21 +-
 net/batman-adv/vis.c                        |    4 +-
 16 files changed, 1281 insertions(+), 1275 deletions(-)
 delete mode 100644 net/batman-adv/aggregation.c
 create mode 100644 net/batman-adv/bat_iv_ogm.c
 rename net/batman-adv/{aggregation.h => bat_ogm.h} (50%)

^ permalink raw reply

* [PATCH 1/7] batman-adv: rename all instances of batman_packet to batman_ogm_packet
From: Marek Lindner @ 2011-09-08 16:40 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
In-Reply-To: <1315500051-1122-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

The follow-up routing code changes are going to introduce additional
routing packet types which make this distinction necessary.

Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
---
 net/batman-adv/aggregation.c    |   48 ++++++++-------
 net/batman-adv/aggregation.h    |    2 +-
 net/batman-adv/hard-interface.c |   49 ++++++++-------
 net/batman-adv/packet.h         |   18 +++---
 net/batman-adv/routing.c        |  118 +++++++++++++++++++----------------
 net/batman-adv/routing.h        |    2 +-
 net/batman-adv/send.c           |  130 ++++++++++++++++++++-------------------
 net/batman-adv/send.h           |    2 +-
 net/batman-adv/soft-interface.c |   17 +++---
 9 files changed, 204 insertions(+), 182 deletions(-)

diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index 69467fe..f20423f 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -27,7 +27,8 @@
 #include "hard-interface.h"
 
 /* return true if new_packet can be aggregated with forw_packet */
-static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
+static bool can_aggregate_with(const struct batman_ogm_packet
+							*new_batman_ogm_packet,
 			       struct bat_priv *bat_priv,
 			       int packet_len,
 			       unsigned long send_time,
@@ -35,8 +36,8 @@ static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
 			       const struct hard_iface *if_incoming,
 			       const struct forw_packet *forw_packet)
 {
-	struct batman_packet *batman_packet =
-		(struct batman_packet *)forw_packet->skb->data;
+	struct batman_ogm_packet *batman_ogm_packet =
+			(struct batman_ogm_packet *)forw_packet->skb->data;
 	int aggregated_bytes = forw_packet->packet_len + packet_len;
 	struct hard_iface *primary_if = NULL;
 	bool res = false;
@@ -71,8 +72,8 @@ static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
 		/* packets without direct link flag and high TTL
 		 * are flooded through the net  */
 		if ((!directlink) &&
-		    (!(batman_packet->flags & DIRECTLINK)) &&
-		    (batman_packet->ttl != 1) &&
+		    (!(batman_ogm_packet->flags & DIRECTLINK)) &&
+		    (batman_ogm_packet->ttl != 1) &&
 
 		    /* own packets originating non-primary
 		     * interfaces leave only that interface */
@@ -85,13 +86,13 @@ static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
 		/* if the incoming packet is sent via this one
 		 * interface only - we still can aggregate */
 		if ((directlink) &&
-		    (new_batman_packet->ttl == 1) &&
+		    (new_batman_ogm_packet->ttl == 1) &&
 		    (forw_packet->if_incoming == if_incoming) &&
 
 		    /* packets from direct neighbors or
 		     * own secondary interface packets
 		     * (= secondary interface packets in general) */
-		    (batman_packet->flags & DIRECTLINK ||
+		    (batman_ogm_packet->flags & DIRECTLINK ||
 		     (forw_packet->own &&
 		      forw_packet->if_incoming != primary_if))) {
 			res = true;
@@ -213,9 +214,11 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
 	 */
 	struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
 	struct hlist_node *tmp_node;
-	struct batman_packet *batman_packet =
-		(struct batman_packet *)packet_buff;
-	bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
+	struct batman_ogm_packet *batman_ogm_packet;
+	bool direct_link;
+
+	batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
+	direct_link = batman_ogm_packet->flags & DIRECTLINK ? 1 : 0;
 
 	/* find position for the packet in the forward queue */
 	spin_lock_bh(&bat_priv->forw_bat_list_lock);
@@ -223,7 +226,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
 	if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
 		hlist_for_each_entry(forw_packet_pos, tmp_node,
 				     &bat_priv->forw_bat_list, list) {
-			if (can_aggregate_with(batman_packet,
+			if (can_aggregate_with(batman_ogm_packet,
 					       bat_priv,
 					       packet_len,
 					       send_time,
@@ -267,27 +270,28 @@ void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
 			     unsigned char *packet_buff, int packet_len,
 			     struct hard_iface *if_incoming)
 {
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 	int buff_pos = 0;
 	unsigned char *tt_buff;
 
-	batman_packet = (struct batman_packet *)packet_buff;
+	batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
 
 	do {
 		/* network to host order for our 32bit seqno and the
 		   orig_interval */
-		batman_packet->seqno = ntohl(batman_packet->seqno);
-		batman_packet->tt_crc = ntohs(batman_packet->tt_crc);
+		batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno);
+		batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc);
 
-		tt_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
+		tt_buff = packet_buff + buff_pos + BATMAN_OGM_LEN;
 
-		receive_bat_packet(ethhdr, batman_packet, tt_buff, if_incoming);
+		receive_bat_packet(ethhdr, batman_ogm_packet,
+				   tt_buff, if_incoming);
 
-		buff_pos += BAT_PACKET_LEN +
-			tt_len(batman_packet->tt_num_changes);
+		buff_pos += BATMAN_OGM_LEN +
+				tt_len(batman_ogm_packet->tt_num_changes);
 
-		batman_packet = (struct batman_packet *)
-			(packet_buff + buff_pos);
+		batman_ogm_packet = (struct batman_ogm_packet *)
+						(packet_buff + buff_pos);
 	} while (aggregated_packet(buff_pos, packet_len,
-				   batman_packet->tt_num_changes));
+				   batman_ogm_packet->tt_num_changes));
 }
diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h
index df4a5a9..7fc23b0 100644
--- a/net/batman-adv/aggregation.h
+++ b/net/batman-adv/aggregation.h
@@ -28,7 +28,7 @@
 static inline int aggregated_packet(int buff_pos, int packet_len,
 				    int tt_num_changes)
 {
-	int next_buff_pos = buff_pos + BAT_PACKET_LEN + tt_len(tt_num_changes);
+	int next_buff_pos = buff_pos + BATMAN_OGM_LEN + tt_len(tt_num_changes);
 
 	return (next_buff_pos <= packet_len) &&
 		(next_buff_pos <= MAX_AGGREGATION_BYTES);
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index bf91e4d..cf9f4af 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -131,7 +131,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
 			      struct hard_iface *new_hard_iface)
 {
 	struct hard_iface *curr_hard_iface;
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 
 	ASSERT_RTNL();
 
@@ -147,9 +147,10 @@ static void primary_if_select(struct bat_priv *bat_priv,
 	if (!new_hard_iface)
 		return;
 
-	batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff);
-	batman_packet->flags = PRIMARIES_FIRST_HOP;
-	batman_packet->ttl = TTL;
+	batman_ogm_packet = (struct batman_ogm_packet *)
+						(new_hard_iface->packet_buff);
+	batman_ogm_packet->flags = PRIMARIES_FIRST_HOP;
+	batman_ogm_packet->ttl = TTL;
 
 	primary_if_update_addr(bat_priv);
 }
@@ -164,9 +165,12 @@ static bool hardif_is_iface_up(const struct hard_iface *hard_iface)
 
 static void update_mac_addresses(struct hard_iface *hard_iface)
 {
-	memcpy(((struct batman_packet *)(hard_iface->packet_buff))->orig,
+	struct batman_ogm_packet *batman_ogm_packet;
+
+	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
+	memcpy(batman_ogm_packet->orig,
 	       hard_iface->net_dev->dev_addr, ETH_ALEN);
-	memcpy(((struct batman_packet *)(hard_iface->packet_buff))->prev_sender,
+	memcpy(batman_ogm_packet->prev_sender,
 	       hard_iface->net_dev->dev_addr, ETH_ALEN);
 }
 
@@ -283,7 +287,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 			    const char *iface_name)
 {
 	struct bat_priv *bat_priv;
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 	struct net_device *soft_iface;
 	int ret;
 
@@ -318,7 +322,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 
 	hard_iface->soft_iface = soft_iface;
 	bat_priv = netdev_priv(hard_iface->soft_iface);
-	hard_iface->packet_len = BAT_PACKET_LEN;
+	hard_iface->packet_len = BATMAN_OGM_LEN;
 	hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
 
 	if (!hard_iface->packet_buff) {
@@ -328,14 +332,15 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 		goto err;
 	}
 
-	batman_packet = (struct batman_packet *)(hard_iface->packet_buff);
-	batman_packet->packet_type = BAT_PACKET;
-	batman_packet->version = COMPAT_VERSION;
-	batman_packet->flags = NO_FLAGS;
-	batman_packet->ttl = 2;
-	batman_packet->tq = TQ_MAX_VALUE;
-	batman_packet->tt_num_changes = 0;
-	batman_packet->ttvn = 0;
+	batman_ogm_packet = (struct batman_ogm_packet *)
+						(hard_iface->packet_buff);
+	batman_ogm_packet->packet_type = BAT_OGM;
+	batman_ogm_packet->version = COMPAT_VERSION;
+	batman_ogm_packet->flags = NO_FLAGS;
+	batman_ogm_packet->ttl = 2;
+	batman_ogm_packet->tq = TQ_MAX_VALUE;
+	batman_ogm_packet->tt_num_changes = 0;
+	batman_ogm_packet->ttvn = 0;
 
 	hard_iface->if_num = bat_priv->num_ifaces;
 	bat_priv->num_ifaces++;
@@ -580,7 +585,7 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 			   struct net_device *orig_dev)
 {
 	struct bat_priv *bat_priv;
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 	struct hard_iface *hard_iface;
 	int ret;
 
@@ -612,21 +617,21 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	if (hard_iface->if_status != IF_ACTIVE)
 		goto err_free;
 
-	batman_packet = (struct batman_packet *)skb->data;
+	batman_ogm_packet = (struct batman_ogm_packet *)skb->data;
 
-	if (batman_packet->version != COMPAT_VERSION) {
+	if (batman_ogm_packet->version != COMPAT_VERSION) {
 		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: incompatible batman version (%i)\n",
-			batman_packet->version);
+			batman_ogm_packet->version);
 		goto err_free;
 	}
 
 	/* all receive handlers return whether they received or reused
 	 * the supplied skb. if not, we have to free the skb. */
 
-	switch (batman_packet->packet_type) {
+	switch (batman_ogm_packet->packet_type) {
 		/* batman originator packet */
-	case BAT_PACKET:
+	case BAT_OGM:
 		ret = recv_bat_packet(skb, hard_iface);
 		break;
 
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 8802eab..4d9e54c 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -25,14 +25,14 @@
 #define ETH_P_BATMAN  0x4305	/* unofficial/not registered Ethertype */
 
 enum bat_packettype {
-	BAT_PACKET       = 0x01,
-	BAT_ICMP         = 0x02,
-	BAT_UNICAST      = 0x03,
-	BAT_BCAST        = 0x04,
-	BAT_VIS          = 0x05,
+	BAT_OGM		 = 0x01,
+	BAT_ICMP	 = 0x02,
+	BAT_UNICAST	 = 0x03,
+	BAT_BCAST	 = 0x04,
+	BAT_VIS		 = 0x05,
 	BAT_UNICAST_FRAG = 0x06,
-	BAT_TT_QUERY     = 0x07,
-	BAT_ROAM_ADV     = 0x08
+	BAT_TT_QUERY	 = 0x07,
+	BAT_ROAM_ADV	 = 0x08
 };
 
 /* this file is included by batctl which needs these defines */
@@ -90,7 +90,7 @@ enum tt_client_flags {
 	TT_CLIENT_PENDING = 1 << 10
 };
 
-struct batman_packet {
+struct batman_ogm_packet {
 	uint8_t  packet_type;
 	uint8_t  version;  /* batman version field */
 	uint8_t  ttl;
@@ -105,7 +105,7 @@ struct batman_packet {
 	uint16_t tt_crc;
 } __packed;
 
-#define BAT_PACKET_LEN sizeof(struct batman_packet)
+#define BATMAN_OGM_LEN sizeof(struct batman_ogm_packet)
 
 struct icmp_packet {
 	uint8_t  packet_type;
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 1949928..6efd1d0 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -130,7 +130,7 @@ out:
 
 static int is_bidirectional_neigh(struct orig_node *orig_node,
 				struct orig_node *orig_neigh_node,
-				struct batman_packet *batman_packet,
+				struct batman_ogm_packet *batman_ogm_packet,
 				struct hard_iface *if_incoming)
 {
 	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -209,7 +209,8 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
 					 TQ_LOCAL_WINDOW_SIZE *
 					 TQ_LOCAL_WINDOW_SIZE);
 
-	batman_packet->tq = ((batman_packet->tq * tq_own * tq_asym_penalty) /
+	batman_ogm_packet->tq = ((batman_ogm_packet->tq * tq_own
+							* tq_asym_penalty) /
 						(TQ_MAX_VALUE * TQ_MAX_VALUE));
 
 	bat_dbg(DBG_BATMAN, bat_priv,
@@ -218,11 +219,11 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
 		"real recv = %2i, local tq: %3i, asym_penalty: %3i, "
 		"total tq: %3i\n",
 		orig_node->orig, orig_neigh_node->orig, total_count,
-		neigh_rq_count, tq_own,	tq_asym_penalty, batman_packet->tq);
+		neigh_rq_count, tq_own,	tq_asym_penalty, batman_ogm_packet->tq);
 
 	/* if link has the minimum required transmission quality
 	 * consider it bidirectional */
-	if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
+	if (batman_ogm_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
 		ret = 1;
 
 out:
@@ -321,9 +322,10 @@ out:
 /* copy primary address for bonding */
 static void bonding_save_primary(const struct orig_node *orig_node,
 				 struct orig_node *orig_neigh_node,
-				 const struct batman_packet *batman_packet)
+				 const struct batman_ogm_packet
+							*batman_ogm_packet)
 {
-	if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
+	if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
 		return;
 
 	memcpy(orig_neigh_node->primary_addr, orig_node->orig, ETH_ALEN);
@@ -331,7 +333,7 @@ static void bonding_save_primary(const struct orig_node *orig_node,
 
 static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
 			const struct ethhdr *ethhdr,
-			const struct batman_packet *batman_packet,
+			const struct batman_ogm_packet *batman_ogm_packet,
 			struct hard_iface *if_incoming,
 			const unsigned char *tt_buff, int is_duplicate)
 {
@@ -386,19 +388,19 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
 
 	rcu_read_unlock();
 
-	orig_node->flags = batman_packet->flags;
+	orig_node->flags = batman_ogm_packet->flags;
 	neigh_node->last_valid = jiffies;
 
 	spin_lock_bh(&neigh_node->tq_lock);
 	ring_buffer_set(neigh_node->tq_recv,
 			&neigh_node->tq_index,
-			batman_packet->tq);
+			batman_ogm_packet->tq);
 	neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
 	spin_unlock_bh(&neigh_node->tq_lock);
 
 	if (!is_duplicate) {
-		orig_node->last_ttl = batman_packet->ttl;
-		neigh_node->last_ttl = batman_packet->ttl;
+		orig_node->last_ttl = batman_ogm_packet->ttl;
+		neigh_node->last_ttl = batman_ogm_packet->ttl;
 	}
 
 	bonding_candidate_add(orig_node, neigh_node);
@@ -437,17 +439,19 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
 update_tt:
 	/* I have to check for transtable changes only if the OGM has been
 	 * sent through a primary interface */
-	if (((batman_packet->orig != ethhdr->h_source) &&
-				(batman_packet->ttl > 2)) ||
-				(batman_packet->flags & PRIMARIES_FIRST_HOP))
+	if (((batman_ogm_packet->orig != ethhdr->h_source) &&
+	     (batman_ogm_packet->ttl > 2)) ||
+	    (batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
 		tt_update_orig(bat_priv, orig_node, tt_buff,
-			       batman_packet->tt_num_changes,
-			       batman_packet->ttvn, batman_packet->tt_crc);
+			       batman_ogm_packet->tt_num_changes,
+			       batman_ogm_packet->ttvn,
+			       batman_ogm_packet->tt_crc);
 
-	if (orig_node->gw_flags != batman_packet->gw_flags)
-		gw_node_update(bat_priv, orig_node, batman_packet->gw_flags);
+	if (orig_node->gw_flags != batman_ogm_packet->gw_flags)
+		gw_node_update(bat_priv, orig_node,
+			       batman_ogm_packet->gw_flags);
 
-	orig_node->gw_flags = batman_packet->gw_flags;
+	orig_node->gw_flags = batman_ogm_packet->gw_flags;
 
 	/* restart gateway selection if fast or late switching was enabled */
 	if ((orig_node->gw_flags) &&
@@ -500,8 +504,8 @@ static int window_protected(struct bat_priv *bat_priv,
  *     was protected. Caller should drop it.
  */
 static int count_real_packets(const struct ethhdr *ethhdr,
-			       const struct batman_packet *batman_packet,
-			       const struct hard_iface *if_incoming)
+			      const struct batman_ogm_packet *batman_ogm_packet,
+			      const struct hard_iface *if_incoming)
 {
 	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct orig_node *orig_node;
@@ -512,12 +516,12 @@ static int count_real_packets(const struct ethhdr *ethhdr,
 	int need_update = 0;
 	int set_mark, ret = -1;
 
-	orig_node = get_orig_node(bat_priv, batman_packet->orig);
+	orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
 	if (!orig_node)
 		return 0;
 
 	spin_lock_bh(&orig_node->ogm_cnt_lock);
-	seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
+	seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno;
 
 	/* signalize caller that the packet is to be dropped. */
 	if (window_protected(bat_priv, seq_diff,
@@ -530,7 +534,7 @@ static int count_real_packets(const struct ethhdr *ethhdr,
 
 		is_duplicate |= get_bit_status(tmp_neigh_node->real_bits,
 					       orig_node->last_real_seqno,
-					       batman_packet->seqno);
+					       batman_ogm_packet->seqno);
 
 		if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
 		    (tmp_neigh_node->if_incoming == if_incoming))
@@ -551,8 +555,8 @@ static int count_real_packets(const struct ethhdr *ethhdr,
 	if (need_update) {
 		bat_dbg(DBG_BATMAN, bat_priv,
 			"updating last_seqno: old %d, new %d\n",
-			orig_node->last_real_seqno, batman_packet->seqno);
-		orig_node->last_real_seqno = batman_packet->seqno;
+			orig_node->last_real_seqno, batman_ogm_packet->seqno);
+		orig_node->last_real_seqno = batman_ogm_packet->seqno;
 	}
 
 	ret = is_duplicate;
@@ -564,7 +568,7 @@ out:
 }
 
 void receive_bat_packet(const struct ethhdr *ethhdr,
-			struct batman_packet *batman_packet,
+			struct batman_ogm_packet *batman_ogm_packet,
 			const unsigned char *tt_buff,
 			struct hard_iface *if_incoming)
 {
@@ -587,31 +591,31 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 	 * it as an additional length.
 	 *
 	 * TODO: A more sane solution would be to have a bit in the
-	 * batman_packet to detect whether the packet is the last
+	 * batman_ogm_packet to detect whether the packet is the last
 	 * packet in an aggregation.  Here we expect that the padding
 	 * is always zero (or not 0x01)
 	 */
-	if (batman_packet->packet_type != BAT_PACKET)
+	if (batman_ogm_packet->packet_type != BAT_OGM)
 		return;
 
 	/* could be changed by schedule_own_packet() */
 	if_incoming_seqno = atomic_read(&if_incoming->seqno);
 
-	has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
+	has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
 
 	is_single_hop_neigh = (compare_eth(ethhdr->h_source,
-					   batman_packet->orig) ? 1 : 0);
+					   batman_ogm_packet->orig) ? 1 : 0);
 
 	bat_dbg(DBG_BATMAN, bat_priv,
 		"Received BATMAN packet via NB: %pM, IF: %s [%pM] "
 		"(from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, "
 		"crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
 		ethhdr->h_source, if_incoming->net_dev->name,
-		if_incoming->net_dev->dev_addr, batman_packet->orig,
-		batman_packet->prev_sender, batman_packet->seqno,
-		batman_packet->ttvn, batman_packet->tt_crc,
-		batman_packet->tt_num_changes, batman_packet->tq,
-		batman_packet->ttl, batman_packet->version,
+		if_incoming->net_dev->dev_addr, batman_ogm_packet->orig,
+		batman_ogm_packet->prev_sender, batman_ogm_packet->seqno,
+		batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc,
+		batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq,
+		batman_ogm_packet->ttl, batman_ogm_packet->version,
 		has_directlink_flag);
 
 	rcu_read_lock();
@@ -626,11 +630,11 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 				hard_iface->net_dev->dev_addr))
 			is_my_addr = 1;
 
-		if (compare_eth(batman_packet->orig,
+		if (compare_eth(batman_ogm_packet->orig,
 				hard_iface->net_dev->dev_addr))
 			is_my_orig = 1;
 
-		if (compare_eth(batman_packet->prev_sender,
+		if (compare_eth(batman_ogm_packet->prev_sender,
 				hard_iface->net_dev->dev_addr))
 			is_my_oldorig = 1;
 
@@ -639,10 +643,10 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 	}
 	rcu_read_unlock();
 
-	if (batman_packet->version != COMPAT_VERSION) {
+	if (batman_ogm_packet->version != COMPAT_VERSION) {
 		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: incompatible batman version (%i)\n",
-			batman_packet->version);
+			batman_ogm_packet->version);
 		return;
 	}
 
@@ -674,13 +678,14 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 		/* save packet seqno for bidirectional check */
 		if (has_directlink_flag &&
 		    compare_eth(if_incoming->net_dev->dev_addr,
-				batman_packet->orig)) {
+				batman_ogm_packet->orig)) {
 			offset = if_incoming->if_num * NUM_WORDS;
 
 			spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
 			word = &(orig_neigh_node->bcast_own[offset]);
 			bit_mark(word,
-				 if_incoming_seqno - batman_packet->seqno - 2);
+				 if_incoming_seqno -
+						batman_ogm_packet->seqno - 2);
 			orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
 				bit_packet_count(word);
 			spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
@@ -699,11 +704,12 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 		return;
 	}
 
-	orig_node = get_orig_node(bat_priv, batman_packet->orig);
+	orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
 	if (!orig_node)
 		return;
 
-	is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
+	is_duplicate = count_real_packets(ethhdr, batman_ogm_packet,
+					  if_incoming);
 
 	if (is_duplicate == -1) {
 		bat_dbg(DBG_BATMAN, bat_priv,
@@ -712,7 +718,7 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 		goto out;
 	}
 
-	if (batman_packet->tq == 0) {
+	if (batman_ogm_packet->tq == 0) {
 		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: originator packet with tq equal 0\n");
 		goto out;
@@ -724,8 +730,9 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 
 	/* avoid temporary routing loops */
 	if (router && router_router &&
-	    (compare_eth(router->addr, batman_packet->prev_sender)) &&
-	    !(compare_eth(batman_packet->orig, batman_packet->prev_sender)) &&
+	    (compare_eth(router->addr, batman_ogm_packet->prev_sender)) &&
+	    !(compare_eth(batman_ogm_packet->orig,
+			  batman_ogm_packet->prev_sender)) &&
 	    (compare_eth(router->addr, router_router->addr))) {
 		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: ignoring all rebroadcast packets that "
@@ -752,24 +759,25 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 	}
 
 	is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node,
-						batman_packet, if_incoming);
+						  batman_ogm_packet,
+						  if_incoming);
 
-	bonding_save_primary(orig_node, orig_neigh_node, batman_packet);
+	bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet);
 
 	/* update ranking if it is not a duplicate or has the same
 	 * seqno and similar ttl as the non-duplicate */
 	if (is_bidirectional &&
 	    (!is_duplicate ||
-	     ((orig_node->last_real_seqno == batman_packet->seqno) &&
-	      (orig_node->last_ttl - 3 <= batman_packet->ttl))))
-		update_orig(bat_priv, orig_node, ethhdr, batman_packet,
+	     ((orig_node->last_real_seqno == batman_ogm_packet->seqno) &&
+	      (orig_node->last_ttl - 3 <= batman_ogm_packet->ttl))))
+		update_orig(bat_priv, orig_node, ethhdr, batman_ogm_packet,
 			    if_incoming, tt_buff, is_duplicate);
 
 	/* is single hop (direct) neighbor */
 	if (is_single_hop_neigh) {
 
 		/* mark direct link on incoming interface */
-		schedule_forward_packet(orig_node, ethhdr, batman_packet,
+		schedule_forward_packet(orig_node, ethhdr, batman_ogm_packet,
 					1, if_incoming);
 
 		bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
@@ -792,7 +800,7 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
 
 	bat_dbg(DBG_BATMAN, bat_priv,
 		"Forwarding packet: rebroadcast originator packet\n");
-	schedule_forward_packet(orig_node, ethhdr, batman_packet,
+	schedule_forward_packet(orig_node, ethhdr, batman_ogm_packet,
 				0, if_incoming);
 
 out_neigh:
@@ -814,7 +822,7 @@ int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
 	struct ethhdr *ethhdr;
 
 	/* drop packet if it has not necessary minimum size */
-	if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet))))
+	if (unlikely(!pskb_may_pull(skb, BATMAN_OGM_LEN)))
 		return NET_RX_DROP;
 
 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index fb14e95..893db7f 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -24,7 +24,7 @@
 
 void slide_own_bcast_window(struct hard_iface *hard_iface);
 void receive_bat_packet(const struct ethhdr *ethhdr,
-			struct batman_packet *batman_packet,
+			struct batman_ogm_packet *batman_ogm_packet,
 			const unsigned char *tt_buff,
 			struct hard_iface *if_incoming);
 void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 57ae809..40a5fcd 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -107,7 +107,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
 	char *fwd_str;
 	uint8_t packet_num;
 	int16_t buff_pos;
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 	struct sk_buff *skb;
 
 	if (hard_iface->if_status != IF_ACTIVE)
@@ -115,20 +115,20 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
 
 	packet_num = 0;
 	buff_pos = 0;
-	batman_packet = (struct batman_packet *)forw_packet->skb->data;
+	batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
 
 	/* adjust all flags and log packets */
 	while (aggregated_packet(buff_pos,
 				 forw_packet->packet_len,
-				 batman_packet->tt_num_changes)) {
+				 batman_ogm_packet->tt_num_changes)) {
 
 		/* we might have aggregated direct link packets with an
 		 * ordinary base packet */
 		if ((forw_packet->direct_link_flags & (1 << packet_num)) &&
 		    (forw_packet->if_incoming == hard_iface))
-			batman_packet->flags |= DIRECTLINK;
+			batman_ogm_packet->flags |= DIRECTLINK;
 		else
-			batman_packet->flags &= ~DIRECTLINK;
+			batman_ogm_packet->flags &= ~DIRECTLINK;
 
 		fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
 							    "Sending own" :
@@ -137,18 +137,19 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
 			"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
 			" IDF %s, ttvn %d) on interface %s [%pM]\n",
 			fwd_str, (packet_num > 0 ? "aggregated " : ""),
-			batman_packet->orig, ntohl(batman_packet->seqno),
-			batman_packet->tq, batman_packet->ttl,
-			(batman_packet->flags & DIRECTLINK ?
+			batman_ogm_packet->orig,
+			ntohl(batman_ogm_packet->seqno),
+			batman_ogm_packet->tq, batman_ogm_packet->ttl,
+			(batman_ogm_packet->flags & DIRECTLINK ?
 			 "on" : "off"),
-			batman_packet->ttvn, hard_iface->net_dev->name,
+			batman_ogm_packet->ttvn, hard_iface->net_dev->name,
 			hard_iface->net_dev->dev_addr);
 
-		buff_pos += sizeof(*batman_packet) +
-			tt_len(batman_packet->tt_num_changes);
+		buff_pos += BATMAN_OGM_LEN +
+				tt_len(batman_ogm_packet->tt_num_changes);
 		packet_num++;
-		batman_packet = (struct batman_packet *)
-			(forw_packet->skb->data + buff_pos);
+		batman_ogm_packet = (struct batman_ogm_packet *)
+					(forw_packet->skb->data + buff_pos);
 	}
 
 	/* create clone because function is called more than once */
@@ -164,9 +165,11 @@ static void send_packet(struct forw_packet *forw_packet)
 	struct net_device *soft_iface;
 	struct bat_priv *bat_priv;
 	struct hard_iface *primary_if = NULL;
-	struct batman_packet *batman_packet =
-		(struct batman_packet *)(forw_packet->skb->data);
-	int directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
+	struct batman_ogm_packet *batman_ogm_packet =
+			(struct batman_ogm_packet *)(forw_packet->skb->data);
+	unsigned char directlink;
+
+	directlink = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
 
 	if (!forw_packet->if_incoming) {
 		pr_err("Error - can't forward packet: incoming iface not "
@@ -186,7 +189,7 @@ static void send_packet(struct forw_packet *forw_packet)
 
 	/* multihomed peer assumed */
 	/* non-primary OGMs are only broadcasted on their interface */
-	if ((directlink && (batman_packet->ttl == 1)) ||
+	if ((directlink && (batman_ogm_packet->ttl == 1)) ||
 	    (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
 
 		/* FIXME: what about aggregated packets ? */
@@ -194,8 +197,9 @@ static void send_packet(struct forw_packet *forw_packet)
 			"%s packet (originator %pM, seqno %d, TTL %d) "
 			"on interface %s [%pM]\n",
 			(forw_packet->own ? "Sending own" : "Forwarding"),
-			batman_packet->orig, ntohl(batman_packet->seqno),
-			batman_packet->ttl,
+			batman_ogm_packet->orig,
+			ntohl(batman_ogm_packet->seqno),
+			batman_ogm_packet->ttl,
 			forw_packet->if_incoming->net_dev->name,
 			forw_packet->if_incoming->net_dev->dev_addr);
 
@@ -223,17 +227,16 @@ out:
 }
 
 static void realloc_packet_buffer(struct hard_iface *hard_iface,
-				int new_len)
+				  int new_len)
 {
 	unsigned char *new_buff;
-	struct batman_packet *batman_packet;
 
 	new_buff = kmalloc(new_len, GFP_ATOMIC);
 
 	/* keep old buffer if kmalloc should fail */
 	if (new_buff) {
 		memcpy(new_buff, hard_iface->packet_buff,
-		       sizeof(*batman_packet));
+		       BATMAN_OGM_LEN);
 
 		kfree(hard_iface->packet_buff);
 		hard_iface->packet_buff = new_buff;
@@ -246,39 +249,39 @@ static void prepare_packet_buffer(struct bat_priv *bat_priv,
 				  struct hard_iface *hard_iface)
 {
 	int new_len;
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 
-	new_len = BAT_PACKET_LEN +
+	new_len = BATMAN_OGM_LEN +
 		  tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes));
 
 	/* if we have too many changes for one packet don't send any
 	 * and wait for the tt table request which will be fragmented */
 	if (new_len > hard_iface->soft_iface->mtu)
-		new_len = BAT_PACKET_LEN;
+		new_len = BATMAN_OGM_LEN;
 
 	realloc_packet_buffer(hard_iface, new_len);
-	batman_packet = (struct batman_packet *)hard_iface->packet_buff;
+	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
 
 	atomic_set(&bat_priv->tt_crc, tt_local_crc(bat_priv));
 
 	/* reset the sending counter */
 	atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX);
 
-	batman_packet->tt_num_changes = tt_changes_fill_buffer(bat_priv,
-				hard_iface->packet_buff + BAT_PACKET_LEN,
-				hard_iface->packet_len - BAT_PACKET_LEN);
+	batman_ogm_packet->tt_num_changes = tt_changes_fill_buffer(bat_priv,
+				hard_iface->packet_buff + BATMAN_OGM_LEN,
+				hard_iface->packet_len - BATMAN_OGM_LEN);
 
 }
 
 static void reset_packet_buffer(struct bat_priv *bat_priv,
-	struct hard_iface *hard_iface)
+				struct hard_iface *hard_iface)
 {
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 
-	realloc_packet_buffer(hard_iface, BAT_PACKET_LEN);
+	realloc_packet_buffer(hard_iface, BATMAN_OGM_LEN);
 
-	batman_packet = (struct batman_packet *)hard_iface->packet_buff;
-	batman_packet->tt_num_changes = 0;
+	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
+	batman_ogm_packet->tt_num_changes = 0;
 }
 
 void schedule_own_packet(struct hard_iface *hard_iface)
@@ -286,7 +289,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
 	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 	struct hard_iface *primary_if;
 	unsigned long send_time;
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 	int vis_server;
 
 	if ((hard_iface->if_status == IF_NOT_IN_USE) ||
@@ -322,26 +325,27 @@ void schedule_own_packet(struct hard_iface *hard_iface)
 	 * NOTE: packet_buff might just have been re-allocated in
 	 * prepare_packet_buffer() or in reset_packet_buffer()
 	 */
-	batman_packet = (struct batman_packet *)hard_iface->packet_buff;
+	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
 
 	/* change sequence number to network order */
-	batman_packet->seqno =
-		htonl((uint32_t)atomic_read(&hard_iface->seqno));
+	batman_ogm_packet->seqno =
+			htonl((uint32_t)atomic_read(&hard_iface->seqno));
 
-	batman_packet->ttvn = atomic_read(&bat_priv->ttvn);
-	batman_packet->tt_crc = htons((uint16_t)atomic_read(&bat_priv->tt_crc));
+	batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn);
+	batman_ogm_packet->tt_crc = htons((uint16_t)
+						atomic_read(&bat_priv->tt_crc));
 
 	if (vis_server == VIS_TYPE_SERVER_SYNC)
-		batman_packet->flags |= VIS_SERVER;
+		batman_ogm_packet->flags |= VIS_SERVER;
 	else
-		batman_packet->flags &= ~VIS_SERVER;
+		batman_ogm_packet->flags &= ~VIS_SERVER;
 
 	if ((hard_iface == primary_if) &&
 	    (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
-		batman_packet->gw_flags =
+		batman_ogm_packet->gw_flags =
 				(uint8_t)atomic_read(&bat_priv->gw_bandwidth);
 	else
-		batman_packet->gw_flags = NO_FLAGS;
+		batman_ogm_packet->gw_flags = NO_FLAGS;
 
 	atomic_inc(&hard_iface->seqno);
 
@@ -358,7 +362,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
 
 void schedule_forward_packet(struct orig_node *orig_node,
 			     const struct ethhdr *ethhdr,
-			     struct batman_packet *batman_packet,
+			     struct batman_ogm_packet *batman_ogm_packet,
 			     int directlink,
 			     struct hard_iface *if_incoming)
 {
@@ -368,19 +372,19 @@ void schedule_forward_packet(struct orig_node *orig_node,
 	unsigned long send_time;
 	uint8_t tt_num_changes;
 
-	if (batman_packet->ttl <= 1) {
+	if (batman_ogm_packet->ttl <= 1) {
 		bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
 		return;
 	}
 
 	router = orig_node_get_router(orig_node);
 
-	in_tq = batman_packet->tq;
-	in_ttl = batman_packet->ttl;
-	tt_num_changes = batman_packet->tt_num_changes;
+	in_tq = batman_ogm_packet->tq;
+	in_ttl = batman_ogm_packet->ttl;
+	tt_num_changes = batman_ogm_packet->tt_num_changes;
 
-	batman_packet->ttl--;
-	memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
+	batman_ogm_packet->ttl--;
+	memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
 
 	/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
 	 * of our best tq value */
@@ -388,10 +392,10 @@ void schedule_forward_packet(struct orig_node *orig_node,
 
 		/* rebroadcast ogm of best ranking neighbor as is */
 		if (!compare_eth(router->addr, ethhdr->h_source)) {
-			batman_packet->tq = router->tq_avg;
+			batman_ogm_packet->tq = router->tq_avg;
 
 			if (router->last_ttl)
-				batman_packet->ttl = router->last_ttl - 1;
+				batman_ogm_packet->ttl = router->last_ttl - 1;
 		}
 
 		tq_avg = router->tq_avg;
@@ -401,28 +405,28 @@ void schedule_forward_packet(struct orig_node *orig_node,
 		neigh_node_free_ref(router);
 
 	/* apply hop penalty */
-	batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv);
+	batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv);
 
 	bat_dbg(DBG_BATMAN, bat_priv,
 		"Forwarding packet: tq_orig: %i, tq_avg: %i, "
 		"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
-		in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
-		batman_packet->ttl);
+		in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1,
+		batman_ogm_packet->ttl);
 
-	batman_packet->seqno = htonl(batman_packet->seqno);
-	batman_packet->tt_crc = htons(batman_packet->tt_crc);
+	batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno);
+	batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc);
 
 	/* switch of primaries first hop flag when forwarding */
-	batman_packet->flags &= ~PRIMARIES_FIRST_HOP;
+	batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP;
 	if (directlink)
-		batman_packet->flags |= DIRECTLINK;
+		batman_ogm_packet->flags |= DIRECTLINK;
 	else
-		batman_packet->flags &= ~DIRECTLINK;
+		batman_ogm_packet->flags &= ~DIRECTLINK;
 
 	send_time = forward_send_time();
 	add_bat_packet_to_list(bat_priv,
-			       (unsigned char *)batman_packet,
-			       sizeof(*batman_packet) + tt_len(tt_num_changes),
+			       (unsigned char *)batman_ogm_packet,
+			       BATMAN_OGM_LEN + tt_len(tt_num_changes),
 			       if_incoming, 0, send_time);
 }
 
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 1f2d1e8..8a22d84 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -27,7 +27,7 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
 void schedule_own_packet(struct hard_iface *hard_iface);
 void schedule_forward_packet(struct orig_node *orig_node,
 			     const struct ethhdr *ethhdr,
-			     struct batman_packet *batman_packet,
+			     struct batman_ogm_packet *batman_ogm_packet,
 			     int directlink,
 			     struct hard_iface *if_outgoing);
 int add_bcast_packet_to_list(struct bat_priv *bat_priv,
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 402fd96..7d8332e 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -445,30 +445,31 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
 {
 	struct bat_priv *bat_priv = netdev_priv(dev);
 	struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
-	struct batman_packet *batman_packet;
+	struct batman_ogm_packet *batman_ogm_packet;
 	struct softif_neigh *softif_neigh = NULL;
 	struct hard_iface *primary_if = NULL;
 	struct softif_neigh *curr_softif_neigh = NULL;
 
 	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
-		batman_packet = (struct batman_packet *)
+		batman_ogm_packet = (struct batman_ogm_packet *)
 					(skb->data + ETH_HLEN + VLAN_HLEN);
 	else
-		batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN);
+		batman_ogm_packet = (struct batman_ogm_packet *)
+							(skb->data + ETH_HLEN);
 
-	if (batman_packet->version != COMPAT_VERSION)
+	if (batman_ogm_packet->version != COMPAT_VERSION)
 		goto out;
 
-	if (batman_packet->packet_type != BAT_PACKET)
+	if (batman_ogm_packet->packet_type != BAT_OGM)
 		goto out;
 
-	if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
+	if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
 		goto out;
 
-	if (is_my_mac(batman_packet->orig))
+	if (is_my_mac(batman_ogm_packet->orig))
 		goto out;
 
-	softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid);
+	softif_neigh = softif_neigh_get(bat_priv, batman_ogm_packet->orig, vid);
 	if (!softif_neigh)
 		goto out;
 
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 2/7] batman-adv: agglomerate all batman iv ogm processing functions in a single file
From: Marek Lindner @ 2011-09-08 16:40 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
In-Reply-To: <1315500051-1122-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

In preparation of the upcoming improved routing algorithm the code based has
to be re-organized to allow choosing the routing algorithm at compile time.

Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
---
 net/batman-adv/Makefile         |    1 +
 net/batman-adv/aggregation.c    |   31 --
 net/batman-adv/aggregation.h    |    3 -
 net/batman-adv/bat_iv_ogm.c     |  639 +++++++++++++++++++++++++++++++++++++++
 net/batman-adv/bat_ogm.h        |   30 ++
 net/batman-adv/hard-interface.c |    2 +-
 net/batman-adv/originator.c     |    3 +-
 net/batman-adv/routing.c        |  606 +------------------------------------
 net/batman-adv/routing.h        |   17 +-
 9 files changed, 698 insertions(+), 634 deletions(-)
 create mode 100644 net/batman-adv/bat_iv_ogm.c
 create mode 100644 net/batman-adv/bat_ogm.h

diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index 2de93d0..3293598 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -21,6 +21,7 @@
 obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
 batman-adv-y += aggregation.o
 batman-adv-y += bat_debugfs.o
+batman-adv-y += bat_iv_ogm.o
 batman-adv-y += bat_sysfs.o
 batman-adv-y += bitarray.o
 batman-adv-y += gateway_client.o
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index f20423f..4716c93 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -264,34 +264,3 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
 		spin_unlock_bh(&bat_priv->forw_bat_list_lock);
 	}
 }
-
-/* unpack the aggregated packets and process them one by one */
-void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
-			     unsigned char *packet_buff, int packet_len,
-			     struct hard_iface *if_incoming)
-{
-	struct batman_ogm_packet *batman_ogm_packet;
-	int buff_pos = 0;
-	unsigned char *tt_buff;
-
-	batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
-
-	do {
-		/* network to host order for our 32bit seqno and the
-		   orig_interval */
-		batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno);
-		batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc);
-
-		tt_buff = packet_buff + buff_pos + BATMAN_OGM_LEN;
-
-		receive_bat_packet(ethhdr, batman_ogm_packet,
-				   tt_buff, if_incoming);
-
-		buff_pos += BATMAN_OGM_LEN +
-				tt_len(batman_ogm_packet->tt_num_changes);
-
-		batman_ogm_packet = (struct batman_ogm_packet *)
-						(packet_buff + buff_pos);
-	} while (aggregated_packet(buff_pos, packet_len,
-				   batman_ogm_packet->tt_num_changes));
-}
diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h
index 7fc23b0..7a92e4c 100644
--- a/net/batman-adv/aggregation.h
+++ b/net/batman-adv/aggregation.h
@@ -38,8 +38,5 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
 			    unsigned char *packet_buff, int packet_len,
 			    struct hard_iface *if_incoming, int own_packet,
 			    unsigned long send_time);
-void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
-			     unsigned char *packet_buff, int packet_len,
-			     struct hard_iface *if_incoming);
 
 #endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
new file mode 100644
index 0000000..6fa2d46
--- /dev/null
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "bat_ogm.h"
+#include "translation-table.h"
+#include "ring_buffer.h"
+#include "originator.h"
+#include "routing.h"
+#include "gateway_common.h"
+#include "gateway_client.h"
+#include "hard-interface.h"
+#include "send.h"
+
+/* is there another aggregated packet here? */
+static int bat_ogm_aggr_packet(int buff_pos, int packet_len,
+			       int tt_num_changes)
+{
+	int next_buff_pos = buff_pos + BATMAN_OGM_LEN + tt_len(tt_num_changes);
+
+	return (next_buff_pos <= packet_len) &&
+		(next_buff_pos <= MAX_AGGREGATION_BYTES);
+}
+
+static void bat_ogm_orig_update(struct bat_priv *bat_priv,
+				struct orig_node *orig_node,
+				const struct ethhdr *ethhdr,
+				const struct batman_ogm_packet
+							*batman_ogm_packet,
+				struct hard_iface *if_incoming,
+				const unsigned char *tt_buff, int is_duplicate)
+{
+	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
+	struct neigh_node *router = NULL;
+	struct orig_node *orig_node_tmp;
+	struct hlist_node *node;
+	uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
+
+	bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
+		"Searching and updating originator entry of received packet\n");
+
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(tmp_neigh_node, node,
+				 &orig_node->neigh_list, list) {
+		if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
+		    (tmp_neigh_node->if_incoming == if_incoming) &&
+		     atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
+			if (neigh_node)
+				neigh_node_free_ref(neigh_node);
+			neigh_node = tmp_neigh_node;
+			continue;
+		}
+
+		if (is_duplicate)
+			continue;
+
+		spin_lock_bh(&tmp_neigh_node->tq_lock);
+		ring_buffer_set(tmp_neigh_node->tq_recv,
+				&tmp_neigh_node->tq_index, 0);
+		tmp_neigh_node->tq_avg =
+			ring_buffer_avg(tmp_neigh_node->tq_recv);
+		spin_unlock_bh(&tmp_neigh_node->tq_lock);
+	}
+
+	if (!neigh_node) {
+		struct orig_node *orig_tmp;
+
+		orig_tmp = get_orig_node(bat_priv, ethhdr->h_source);
+		if (!orig_tmp)
+			goto unlock;
+
+		neigh_node = create_neighbor(orig_node, orig_tmp,
+					     ethhdr->h_source, if_incoming);
+
+		orig_node_free_ref(orig_tmp);
+		if (!neigh_node)
+			goto unlock;
+	} else
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Updating existing last-hop neighbor of originator\n");
+
+	rcu_read_unlock();
+
+	orig_node->flags = batman_ogm_packet->flags;
+	neigh_node->last_valid = jiffies;
+
+	spin_lock_bh(&neigh_node->tq_lock);
+	ring_buffer_set(neigh_node->tq_recv,
+			&neigh_node->tq_index,
+			batman_ogm_packet->tq);
+	neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
+	spin_unlock_bh(&neigh_node->tq_lock);
+
+	if (!is_duplicate) {
+		orig_node->last_ttl = batman_ogm_packet->ttl;
+		neigh_node->last_ttl = batman_ogm_packet->ttl;
+	}
+
+	bonding_candidate_add(orig_node, neigh_node);
+
+	/* if this neighbor already is our next hop there is nothing
+	 * to change */
+	router = orig_node_get_router(orig_node);
+	if (router == neigh_node)
+		goto update_tt;
+
+	/* if this neighbor does not offer a better TQ we won't consider it */
+	if (router && (router->tq_avg > neigh_node->tq_avg))
+		goto update_tt;
+
+	/* if the TQ is the same and the link not more symmetric we
+	 * won't consider it either */
+	if (router && (neigh_node->tq_avg == router->tq_avg)) {
+		orig_node_tmp = router->orig_node;
+		spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
+		bcast_own_sum_orig =
+			orig_node_tmp->bcast_own_sum[if_incoming->if_num];
+		spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
+
+		orig_node_tmp = neigh_node->orig_node;
+		spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
+		bcast_own_sum_neigh =
+			orig_node_tmp->bcast_own_sum[if_incoming->if_num];
+		spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
+
+		if (bcast_own_sum_orig >= bcast_own_sum_neigh)
+			goto update_tt;
+	}
+
+	update_route(bat_priv, orig_node, neigh_node);
+
+update_tt:
+	/* I have to check for transtable changes only if the OGM has been
+	 * sent through a primary interface */
+	if (((batman_ogm_packet->orig != ethhdr->h_source) &&
+	     (batman_ogm_packet->ttl > 2)) ||
+	    (batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
+		tt_update_orig(bat_priv, orig_node, tt_buff,
+			       batman_ogm_packet->tt_num_changes,
+			       batman_ogm_packet->ttvn,
+			       batman_ogm_packet->tt_crc);
+
+	if (orig_node->gw_flags != batman_ogm_packet->gw_flags)
+		gw_node_update(bat_priv, orig_node,
+			       batman_ogm_packet->gw_flags);
+
+	orig_node->gw_flags = batman_ogm_packet->gw_flags;
+
+	/* restart gateway selection if fast or late switching was enabled */
+	if ((orig_node->gw_flags) &&
+	    (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) &&
+	    (atomic_read(&bat_priv->gw_sel_class) > 2))
+		gw_check_election(bat_priv, orig_node);
+
+	goto out;
+
+unlock:
+	rcu_read_unlock();
+out:
+	if (neigh_node)
+		neigh_node_free_ref(neigh_node);
+	if (router)
+		neigh_node_free_ref(router);
+}
+
+static int bat_ogm_calc_tq(struct orig_node *orig_node,
+			   struct orig_node *orig_neigh_node,
+			   struct batman_ogm_packet *batman_ogm_packet,
+			   struct hard_iface *if_incoming)
+{
+	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+	struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
+	struct hlist_node *node;
+	uint8_t total_count;
+	uint8_t orig_eq_count, neigh_rq_count, tq_own;
+	int tq_asym_penalty, ret = 0;
+
+	/* find corresponding one hop neighbor */
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(tmp_neigh_node, node,
+				 &orig_neigh_node->neigh_list, list) {
+
+		if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig))
+			continue;
+
+		if (tmp_neigh_node->if_incoming != if_incoming)
+			continue;
+
+		if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+			continue;
+
+		neigh_node = tmp_neigh_node;
+		break;
+	}
+	rcu_read_unlock();
+
+	if (!neigh_node)
+		neigh_node = create_neighbor(orig_neigh_node,
+					     orig_neigh_node,
+					     orig_neigh_node->orig,
+					     if_incoming);
+
+	if (!neigh_node)
+		goto out;
+
+	/* if orig_node is direct neighbor update neigh_node last_valid */
+	if (orig_node == orig_neigh_node)
+		neigh_node->last_valid = jiffies;
+
+	orig_node->last_valid = jiffies;
+
+	/* find packet count of corresponding one hop neighbor */
+	spin_lock_bh(&orig_node->ogm_cnt_lock);
+	orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
+	neigh_rq_count = neigh_node->real_packet_count;
+	spin_unlock_bh(&orig_node->ogm_cnt_lock);
+
+	/* pay attention to not get a value bigger than 100 % */
+	total_count = (orig_eq_count > neigh_rq_count ?
+		       neigh_rq_count : orig_eq_count);
+
+	/* if we have too few packets (too less data) we set tq_own to zero */
+	/* if we receive too few packets it is not considered bidirectional */
+	if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
+	    (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
+		tq_own = 0;
+	else
+		/* neigh_node->real_packet_count is never zero as we
+		 * only purge old information when getting new
+		 * information */
+		tq_own = (TQ_MAX_VALUE * total_count) /	neigh_rq_count;
+
+	/*
+	 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
+	 * affect the nearly-symmetric links only a little, but
+	 * punishes asymmetric links more.  This will give a value
+	 * between 0 and TQ_MAX_VALUE
+	 */
+	tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE *
+				(TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
+				(TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
+				(TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) /
+					(TQ_LOCAL_WINDOW_SIZE *
+					 TQ_LOCAL_WINDOW_SIZE *
+					 TQ_LOCAL_WINDOW_SIZE);
+
+	batman_ogm_packet->tq = ((batman_ogm_packet->tq * tq_own
+							* tq_asym_penalty) /
+						(TQ_MAX_VALUE * TQ_MAX_VALUE));
+
+	bat_dbg(DBG_BATMAN, bat_priv,
+		"bidirectional: "
+		"orig = %-15pM neigh = %-15pM => own_bcast = %2i, "
+		"real recv = %2i, local tq: %3i, asym_penalty: %3i, "
+		"total tq: %3i\n",
+		orig_node->orig, orig_neigh_node->orig, total_count,
+		neigh_rq_count, tq_own,	tq_asym_penalty, batman_ogm_packet->tq);
+
+	/* if link has the minimum required transmission quality
+	 * consider it bidirectional */
+	if (batman_ogm_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
+		ret = 1;
+
+out:
+	if (neigh_node)
+		neigh_node_free_ref(neigh_node);
+	return ret;
+}
+
+/* processes a batman packet for all interfaces, adjusts the sequence number and
+ * finds out whether it is a duplicate.
+ * returns:
+ *   1 the packet is a duplicate
+ *   0 the packet has not yet been received
+ *  -1 the packet is old and has been received while the seqno window
+ *     was protected. Caller should drop it.
+ */
+static int bat_ogm_update_seqnos(const struct ethhdr *ethhdr,
+				 const struct batman_ogm_packet
+							*batman_ogm_packet,
+				 const struct hard_iface *if_incoming)
+{
+	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+	struct orig_node *orig_node;
+	struct neigh_node *tmp_neigh_node;
+	struct hlist_node *node;
+	int is_duplicate = 0;
+	int32_t seq_diff;
+	int need_update = 0;
+	int set_mark, ret = -1;
+
+	orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
+	if (!orig_node)
+		return 0;
+
+	spin_lock_bh(&orig_node->ogm_cnt_lock);
+	seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno;
+
+	/* signalize caller that the packet is to be dropped. */
+	if (window_protected(bat_priv, seq_diff,
+			     &orig_node->batman_seqno_reset))
+		goto out;
+
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(tmp_neigh_node, node,
+				 &orig_node->neigh_list, list) {
+
+		is_duplicate |= get_bit_status(tmp_neigh_node->real_bits,
+					       orig_node->last_real_seqno,
+					       batman_ogm_packet->seqno);
+
+		if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
+		    (tmp_neigh_node->if_incoming == if_incoming))
+			set_mark = 1;
+		else
+			set_mark = 0;
+
+		/* if the window moved, set the update flag. */
+		need_update |= bit_get_packet(bat_priv,
+					      tmp_neigh_node->real_bits,
+					      seq_diff, set_mark);
+
+		tmp_neigh_node->real_packet_count =
+			bit_packet_count(tmp_neigh_node->real_bits);
+	}
+	rcu_read_unlock();
+
+	if (need_update) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"updating last_seqno: old %d, new %d\n",
+			orig_node->last_real_seqno, batman_ogm_packet->seqno);
+		orig_node->last_real_seqno = batman_ogm_packet->seqno;
+	}
+
+	ret = is_duplicate;
+
+out:
+	spin_unlock_bh(&orig_node->ogm_cnt_lock);
+	orig_node_free_ref(orig_node);
+	return ret;
+}
+
+static void bat_ogm_process(const struct ethhdr *ethhdr,
+			    struct batman_ogm_packet *batman_ogm_packet,
+			    const unsigned char *tt_buff,
+			    struct hard_iface *if_incoming)
+{
+	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+	struct hard_iface *hard_iface;
+	struct orig_node *orig_neigh_node, *orig_node;
+	struct neigh_node *router = NULL, *router_router = NULL;
+	struct neigh_node *orig_neigh_router = NULL;
+	int has_directlink_flag;
+	int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
+	int is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
+	int is_duplicate;
+	uint32_t if_incoming_seqno;
+
+	/* Silently drop when the batman packet is actually not a
+	 * correct packet.
+	 *
+	 * This might happen if a packet is padded (e.g. Ethernet has a
+	 * minimum frame length of 64 byte) and the aggregation interprets
+	 * it as an additional length.
+	 *
+	 * TODO: A more sane solution would be to have a bit in the
+	 * batman_ogm_packet to detect whether the packet is the last
+	 * packet in an aggregation.  Here we expect that the padding
+	 * is always zero (or not 0x01)
+	 */
+	if (batman_ogm_packet->packet_type != BAT_OGM)
+		return;
+
+	/* could be changed by schedule_own_packet() */
+	if_incoming_seqno = atomic_read(&if_incoming->seqno);
+
+	has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
+
+	is_single_hop_neigh = (compare_eth(ethhdr->h_source,
+					   batman_ogm_packet->orig) ? 1 : 0);
+
+	bat_dbg(DBG_BATMAN, bat_priv,
+		"Received BATMAN packet via NB: %pM, IF: %s [%pM] "
+		"(from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, "
+		"crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
+		ethhdr->h_source, if_incoming->net_dev->name,
+		if_incoming->net_dev->dev_addr, batman_ogm_packet->orig,
+		batman_ogm_packet->prev_sender, batman_ogm_packet->seqno,
+		batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc,
+		batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq,
+		batman_ogm_packet->ttl, batman_ogm_packet->version,
+		has_directlink_flag);
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
+		if (hard_iface->if_status != IF_ACTIVE)
+			continue;
+
+		if (hard_iface->soft_iface != if_incoming->soft_iface)
+			continue;
+
+		if (compare_eth(ethhdr->h_source,
+				hard_iface->net_dev->dev_addr))
+			is_my_addr = 1;
+
+		if (compare_eth(batman_ogm_packet->orig,
+				hard_iface->net_dev->dev_addr))
+			is_my_orig = 1;
+
+		if (compare_eth(batman_ogm_packet->prev_sender,
+				hard_iface->net_dev->dev_addr))
+			is_my_oldorig = 1;
+
+		if (is_broadcast_ether_addr(ethhdr->h_source))
+			is_broadcast = 1;
+	}
+	rcu_read_unlock();
+
+	if (batman_ogm_packet->version != COMPAT_VERSION) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: incompatible batman version (%i)\n",
+			batman_ogm_packet->version);
+		return;
+	}
+
+	if (is_my_addr) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: received my own broadcast (sender: %pM"
+			")\n",
+			ethhdr->h_source);
+		return;
+	}
+
+	if (is_broadcast) {
+		bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
+		"ignoring all packets with broadcast source addr (sender: %pM"
+		")\n", ethhdr->h_source);
+		return;
+	}
+
+	if (is_my_orig) {
+		unsigned long *word;
+		int offset;
+
+		orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source);
+		if (!orig_neigh_node)
+			return;
+
+		/* neighbor has to indicate direct link and it has to
+		 * come via the corresponding interface */
+		/* save packet seqno for bidirectional check */
+		if (has_directlink_flag &&
+		    compare_eth(if_incoming->net_dev->dev_addr,
+				batman_ogm_packet->orig)) {
+			offset = if_incoming->if_num * NUM_WORDS;
+
+			spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
+			word = &(orig_neigh_node->bcast_own[offset]);
+			bit_mark(word,
+				 if_incoming_seqno -
+						batman_ogm_packet->seqno - 2);
+			orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
+				bit_packet_count(word);
+			spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
+		}
+
+		bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
+			"originator packet from myself (via neighbor)\n");
+		orig_node_free_ref(orig_neigh_node);
+		return;
+	}
+
+	if (is_my_oldorig) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: ignoring all rebroadcast echos (sender: "
+			"%pM)\n", ethhdr->h_source);
+		return;
+	}
+
+	orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
+	if (!orig_node)
+		return;
+
+	is_duplicate = bat_ogm_update_seqnos(ethhdr, batman_ogm_packet,
+					     if_incoming);
+
+	if (is_duplicate == -1) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: packet within seqno protection time "
+			"(sender: %pM)\n", ethhdr->h_source);
+		goto out;
+	}
+
+	if (batman_ogm_packet->tq == 0) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: originator packet with tq equal 0\n");
+		goto out;
+	}
+
+	router = orig_node_get_router(orig_node);
+	if (router)
+		router_router = orig_node_get_router(router->orig_node);
+
+	/* avoid temporary routing loops */
+	if (router && router_router &&
+	    (compare_eth(router->addr, batman_ogm_packet->prev_sender)) &&
+	    !(compare_eth(batman_ogm_packet->orig,
+			  batman_ogm_packet->prev_sender)) &&
+	    (compare_eth(router->addr, router_router->addr))) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: ignoring all rebroadcast packets that "
+			"may make me loop (sender: %pM)\n", ethhdr->h_source);
+		goto out;
+	}
+
+	/* if sender is a direct neighbor the sender mac equals
+	 * originator mac */
+	orig_neigh_node = (is_single_hop_neigh ?
+			   orig_node :
+			   get_orig_node(bat_priv, ethhdr->h_source));
+	if (!orig_neigh_node)
+		goto out;
+
+	orig_neigh_router = orig_node_get_router(orig_neigh_node);
+
+	/* drop packet if sender is not a direct neighbor and if we
+	 * don't route towards it */
+	if (!is_single_hop_neigh && (!orig_neigh_router)) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: OGM via unknown neighbor!\n");
+		goto out_neigh;
+	}
+
+	is_bidirectional = bat_ogm_calc_tq(orig_node, orig_neigh_node,
+					   batman_ogm_packet, if_incoming);
+
+	bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet);
+
+	/* update ranking if it is not a duplicate or has the same
+	 * seqno and similar ttl as the non-duplicate */
+	if (is_bidirectional &&
+	    (!is_duplicate ||
+	     ((orig_node->last_real_seqno == batman_ogm_packet->seqno) &&
+	      (orig_node->last_ttl - 3 <= batman_ogm_packet->ttl))))
+		bat_ogm_orig_update(bat_priv, orig_node, ethhdr,
+				    batman_ogm_packet, if_incoming,
+				    tt_buff, is_duplicate);
+
+	/* is single hop (direct) neighbor */
+	if (is_single_hop_neigh) {
+
+		/* mark direct link on incoming interface */
+		schedule_forward_packet(orig_node, ethhdr, batman_ogm_packet,
+					1, if_incoming);
+
+		bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
+			"rebroadcast neighbor packet with direct link flag\n");
+		goto out_neigh;
+	}
+
+	/* multihop originator */
+	if (!is_bidirectional) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: not received via bidirectional link\n");
+		goto out_neigh;
+	}
+
+	if (is_duplicate) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: duplicate packet received\n");
+		goto out_neigh;
+	}
+
+	bat_dbg(DBG_BATMAN, bat_priv,
+		"Forwarding packet: rebroadcast originator packet\n");
+	schedule_forward_packet(orig_node, ethhdr, batman_ogm_packet,
+				0, if_incoming);
+
+out_neigh:
+	if ((orig_neigh_node) && (!is_single_hop_neigh))
+		orig_node_free_ref(orig_neigh_node);
+out:
+	if (router)
+		neigh_node_free_ref(router);
+	if (router_router)
+		neigh_node_free_ref(router_router);
+	if (orig_neigh_router)
+		neigh_node_free_ref(orig_neigh_router);
+
+	orig_node_free_ref(orig_node);
+}
+
+void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
+		     int packet_len, struct hard_iface *if_incoming)
+{
+	struct batman_ogm_packet *batman_ogm_packet;
+	int buff_pos = 0;
+	unsigned char *tt_buff;
+
+	batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
+
+	/* unpack the aggregated packets and process them one by one */
+	do {
+		/* network to host order for our 32bit seqno and the
+		   orig_interval */
+		batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno);
+		batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc);
+
+		tt_buff = packet_buff + buff_pos + BATMAN_OGM_LEN;
+
+		bat_ogm_process(ethhdr, batman_ogm_packet,
+				tt_buff, if_incoming);
+
+		buff_pos += BATMAN_OGM_LEN +
+				tt_len(batman_ogm_packet->tt_num_changes);
+
+		batman_ogm_packet = (struct batman_ogm_packet *)
+						(packet_buff + buff_pos);
+	} while (bat_ogm_aggr_packet(buff_pos, packet_len,
+				     batman_ogm_packet->tt_num_changes));
+}
diff --git a/net/batman-adv/bat_ogm.h b/net/batman-adv/bat_ogm.h
new file mode 100644
index 0000000..bdd3d1e
--- /dev/null
+++ b/net/batman-adv/bat_ogm.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_OGM_H_
+#define _NET_BATMAN_ADV_OGM_H_
+
+#include "main.h"
+
+void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
+		     int packet_len, struct hard_iface *if_incoming);
+
+#endif /* _NET_BATMAN_ADV_OGM_H_ */
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index cf9f4af..cfee017 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -632,7 +632,7 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	switch (batman_ogm_packet->packet_type) {
 		/* batman originator packet */
 	case BAT_OGM:
-		ret = recv_bat_packet(skb, hard_iface);
+		ret = recv_bat_ogm_packet(skb, hard_iface);
 		break;
 
 		/* batman icmp packet */
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index d448018..cd7d256 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -336,8 +336,7 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
 	} else {
 		if (purge_orig_neighbors(bat_priv, orig_node,
 							&best_neigh_node)) {
-			update_routes(bat_priv, orig_node,
-				      best_neigh_node);
+			update_route(bat_priv, orig_node, best_neigh_node);
 		}
 	}
 
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 6efd1d0..f961cc5 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -22,18 +22,14 @@
 #include "main.h"
 #include "routing.h"
 #include "send.h"
-#include "hash.h"
 #include "soft-interface.h"
 #include "hard-interface.h"
 #include "icmp_socket.h"
 #include "translation-table.h"
 #include "originator.h"
-#include "ring_buffer.h"
 #include "vis.h"
-#include "aggregation.h"
-#include "gateway_common.h"
-#include "gateway_client.h"
 #include "unicast.h"
+#include "bat_ogm.h"
 
 void slide_own_bcast_window(struct hard_iface *hard_iface)
 {
@@ -64,9 +60,9 @@ void slide_own_bcast_window(struct hard_iface *hard_iface)
 	}
 }
 
-static void update_route(struct bat_priv *bat_priv,
-			 struct orig_node *orig_node,
-			 struct neigh_node *neigh_node)
+static void _update_route(struct bat_priv *bat_priv,
+			  struct orig_node *orig_node,
+			  struct neigh_node *neigh_node)
 {
 	struct neigh_node *curr_router;
 
@@ -110,8 +106,8 @@ static void update_route(struct bat_priv *bat_priv,
 		neigh_node_free_ref(curr_router);
 }
 
-void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
-		   struct neigh_node *neigh_node)
+void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node,
+		  struct neigh_node *neigh_node)
 {
 	struct neigh_node *router = NULL;
 
@@ -121,117 +117,13 @@ void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
 	router = orig_node_get_router(orig_node);
 
 	if (router != neigh_node)
-		update_route(bat_priv, orig_node, neigh_node);
+		_update_route(bat_priv, orig_node, neigh_node);
 
 out:
 	if (router)
 		neigh_node_free_ref(router);
 }
 
-static int is_bidirectional_neigh(struct orig_node *orig_node,
-				struct orig_node *orig_neigh_node,
-				struct batman_ogm_packet *batman_ogm_packet,
-				struct hard_iface *if_incoming)
-{
-	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
-	struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
-	struct hlist_node *node;
-	uint8_t total_count;
-	uint8_t orig_eq_count, neigh_rq_count, tq_own;
-	int tq_asym_penalty, ret = 0;
-
-	/* find corresponding one hop neighbor */
-	rcu_read_lock();
-	hlist_for_each_entry_rcu(tmp_neigh_node, node,
-				 &orig_neigh_node->neigh_list, list) {
-
-		if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig))
-			continue;
-
-		if (tmp_neigh_node->if_incoming != if_incoming)
-			continue;
-
-		if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
-			continue;
-
-		neigh_node = tmp_neigh_node;
-		break;
-	}
-	rcu_read_unlock();
-
-	if (!neigh_node)
-		neigh_node = create_neighbor(orig_neigh_node,
-					     orig_neigh_node,
-					     orig_neigh_node->orig,
-					     if_incoming);
-
-	if (!neigh_node)
-		goto out;
-
-	/* if orig_node is direct neighbor update neigh_node last_valid */
-	if (orig_node == orig_neigh_node)
-		neigh_node->last_valid = jiffies;
-
-	orig_node->last_valid = jiffies;
-
-	/* find packet count of corresponding one hop neighbor */
-	spin_lock_bh(&orig_node->ogm_cnt_lock);
-	orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
-	neigh_rq_count = neigh_node->real_packet_count;
-	spin_unlock_bh(&orig_node->ogm_cnt_lock);
-
-	/* pay attention to not get a value bigger than 100 % */
-	total_count = (orig_eq_count > neigh_rq_count ?
-		       neigh_rq_count : orig_eq_count);
-
-	/* if we have too few packets (too less data) we set tq_own to zero */
-	/* if we receive too few packets it is not considered bidirectional */
-	if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
-	    (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
-		tq_own = 0;
-	else
-		/* neigh_node->real_packet_count is never zero as we
-		 * only purge old information when getting new
-		 * information */
-		tq_own = (TQ_MAX_VALUE * total_count) /	neigh_rq_count;
-
-	/*
-	 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
-	 * affect the nearly-symmetric links only a little, but
-	 * punishes asymmetric links more.  This will give a value
-	 * between 0 and TQ_MAX_VALUE
-	 */
-	tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE *
-				(TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
-				(TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
-				(TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) /
-					(TQ_LOCAL_WINDOW_SIZE *
-					 TQ_LOCAL_WINDOW_SIZE *
-					 TQ_LOCAL_WINDOW_SIZE);
-
-	batman_ogm_packet->tq = ((batman_ogm_packet->tq * tq_own
-							* tq_asym_penalty) /
-						(TQ_MAX_VALUE * TQ_MAX_VALUE));
-
-	bat_dbg(DBG_BATMAN, bat_priv,
-		"bidirectional: "
-		"orig = %-15pM neigh = %-15pM => own_bcast = %2i, "
-		"real recv = %2i, local tq: %3i, asym_penalty: %3i, "
-		"total tq: %3i\n",
-		orig_node->orig, orig_neigh_node->orig, total_count,
-		neigh_rq_count, tq_own,	tq_asym_penalty, batman_ogm_packet->tq);
-
-	/* if link has the minimum required transmission quality
-	 * consider it bidirectional */
-	if (batman_ogm_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
-		ret = 1;
-
-out:
-	if (neigh_node)
-		neigh_node_free_ref(neigh_node);
-	return ret;
-}
-
 /* caller must hold the neigh_list_lock */
 void bonding_candidate_del(struct orig_node *orig_node,
 			   struct neigh_node *neigh_node)
@@ -249,8 +141,8 @@ out:
 	return;
 }
 
-static void bonding_candidate_add(struct orig_node *orig_node,
-				  struct neigh_node *neigh_node)
+void bonding_candidate_add(struct orig_node *orig_node,
+			   struct neigh_node *neigh_node)
 {
 	struct hlist_node *node;
 	struct neigh_node *tmp_neigh_node, *router = NULL;
@@ -320,10 +212,9 @@ out:
 }
 
 /* copy primary address for bonding */
-static void bonding_save_primary(const struct orig_node *orig_node,
-				 struct orig_node *orig_neigh_node,
-				 const struct batman_ogm_packet
-							*batman_ogm_packet)
+void bonding_save_primary(const struct orig_node *orig_node,
+			  struct orig_node *orig_neigh_node,
+			  const struct batman_ogm_packet *batman_ogm_packet)
 {
 	if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
 		return;
@@ -331,153 +222,13 @@ static void bonding_save_primary(const struct orig_node *orig_node,
 	memcpy(orig_neigh_node->primary_addr, orig_node->orig, ETH_ALEN);
 }
 
-static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
-			const struct ethhdr *ethhdr,
-			const struct batman_ogm_packet *batman_ogm_packet,
-			struct hard_iface *if_incoming,
-			const unsigned char *tt_buff, int is_duplicate)
-{
-	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
-	struct neigh_node *router = NULL;
-	struct orig_node *orig_node_tmp;
-	struct hlist_node *node;
-	uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
-
-	bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
-		"Searching and updating originator entry of received packet\n");
-
-	rcu_read_lock();
-	hlist_for_each_entry_rcu(tmp_neigh_node, node,
-				 &orig_node->neigh_list, list) {
-		if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
-		    (tmp_neigh_node->if_incoming == if_incoming) &&
-		     atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
-			if (neigh_node)
-				neigh_node_free_ref(neigh_node);
-			neigh_node = tmp_neigh_node;
-			continue;
-		}
-
-		if (is_duplicate)
-			continue;
-
-		spin_lock_bh(&tmp_neigh_node->tq_lock);
-		ring_buffer_set(tmp_neigh_node->tq_recv,
-				&tmp_neigh_node->tq_index, 0);
-		tmp_neigh_node->tq_avg =
-			ring_buffer_avg(tmp_neigh_node->tq_recv);
-		spin_unlock_bh(&tmp_neigh_node->tq_lock);
-	}
-
-	if (!neigh_node) {
-		struct orig_node *orig_tmp;
-
-		orig_tmp = get_orig_node(bat_priv, ethhdr->h_source);
-		if (!orig_tmp)
-			goto unlock;
-
-		neigh_node = create_neighbor(orig_node, orig_tmp,
-					     ethhdr->h_source, if_incoming);
-
-		orig_node_free_ref(orig_tmp);
-		if (!neigh_node)
-			goto unlock;
-	} else
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Updating existing last-hop neighbor of originator\n");
-
-	rcu_read_unlock();
-
-	orig_node->flags = batman_ogm_packet->flags;
-	neigh_node->last_valid = jiffies;
-
-	spin_lock_bh(&neigh_node->tq_lock);
-	ring_buffer_set(neigh_node->tq_recv,
-			&neigh_node->tq_index,
-			batman_ogm_packet->tq);
-	neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
-	spin_unlock_bh(&neigh_node->tq_lock);
-
-	if (!is_duplicate) {
-		orig_node->last_ttl = batman_ogm_packet->ttl;
-		neigh_node->last_ttl = batman_ogm_packet->ttl;
-	}
-
-	bonding_candidate_add(orig_node, neigh_node);
-
-	/* if this neighbor already is our next hop there is nothing
-	 * to change */
-	router = orig_node_get_router(orig_node);
-	if (router == neigh_node)
-		goto update_tt;
-
-	/* if this neighbor does not offer a better TQ we won't consider it */
-	if (router && (router->tq_avg > neigh_node->tq_avg))
-		goto update_tt;
-
-	/* if the TQ is the same and the link not more symmetric we
-	 * won't consider it either */
-	if (router && (neigh_node->tq_avg == router->tq_avg)) {
-		orig_node_tmp = router->orig_node;
-		spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
-		bcast_own_sum_orig =
-			orig_node_tmp->bcast_own_sum[if_incoming->if_num];
-		spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
-
-		orig_node_tmp = neigh_node->orig_node;
-		spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
-		bcast_own_sum_neigh =
-			orig_node_tmp->bcast_own_sum[if_incoming->if_num];
-		spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
-
-		if (bcast_own_sum_orig >= bcast_own_sum_neigh)
-			goto update_tt;
-	}
-
-	update_routes(bat_priv, orig_node, neigh_node);
-
-update_tt:
-	/* I have to check for transtable changes only if the OGM has been
-	 * sent through a primary interface */
-	if (((batman_ogm_packet->orig != ethhdr->h_source) &&
-	     (batman_ogm_packet->ttl > 2)) ||
-	    (batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
-		tt_update_orig(bat_priv, orig_node, tt_buff,
-			       batman_ogm_packet->tt_num_changes,
-			       batman_ogm_packet->ttvn,
-			       batman_ogm_packet->tt_crc);
-
-	if (orig_node->gw_flags != batman_ogm_packet->gw_flags)
-		gw_node_update(bat_priv, orig_node,
-			       batman_ogm_packet->gw_flags);
-
-	orig_node->gw_flags = batman_ogm_packet->gw_flags;
-
-	/* restart gateway selection if fast or late switching was enabled */
-	if ((orig_node->gw_flags) &&
-	    (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) &&
-	    (atomic_read(&bat_priv->gw_sel_class) > 2))
-		gw_check_election(bat_priv, orig_node);
-
-	goto out;
-
-unlock:
-	rcu_read_unlock();
-out:
-	if (neigh_node)
-		neigh_node_free_ref(neigh_node);
-	if (router)
-		neigh_node_free_ref(router);
-}
-
 /* checks whether the host restarted and is in the protection time.
  * returns:
  *  0 if the packet is to be accepted
  *  1 if the packet is to be ignored.
  */
-static int window_protected(struct bat_priv *bat_priv,
-			    int32_t seq_num_diff,
-			    unsigned long *last_reset)
+int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff,
+		     unsigned long *last_reset)
 {
 	if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
 		|| (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
@@ -495,329 +246,7 @@ static int window_protected(struct bat_priv *bat_priv,
 	return 0;
 }
 
-/* processes a batman packet for all interfaces, adjusts the sequence number and
- * finds out whether it is a duplicate.
- * returns:
- *   1 the packet is a duplicate
- *   0 the packet has not yet been received
- *  -1 the packet is old and has been received while the seqno window
- *     was protected. Caller should drop it.
- */
-static int count_real_packets(const struct ethhdr *ethhdr,
-			      const struct batman_ogm_packet *batman_ogm_packet,
-			      const struct hard_iface *if_incoming)
-{
-	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
-	struct orig_node *orig_node;
-	struct neigh_node *tmp_neigh_node;
-	struct hlist_node *node;
-	int is_duplicate = 0;
-	int32_t seq_diff;
-	int need_update = 0;
-	int set_mark, ret = -1;
-
-	orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
-	if (!orig_node)
-		return 0;
-
-	spin_lock_bh(&orig_node->ogm_cnt_lock);
-	seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno;
-
-	/* signalize caller that the packet is to be dropped. */
-	if (window_protected(bat_priv, seq_diff,
-			     &orig_node->batman_seqno_reset))
-		goto out;
-
-	rcu_read_lock();
-	hlist_for_each_entry_rcu(tmp_neigh_node, node,
-				 &orig_node->neigh_list, list) {
-
-		is_duplicate |= get_bit_status(tmp_neigh_node->real_bits,
-					       orig_node->last_real_seqno,
-					       batman_ogm_packet->seqno);
-
-		if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
-		    (tmp_neigh_node->if_incoming == if_incoming))
-			set_mark = 1;
-		else
-			set_mark = 0;
-
-		/* if the window moved, set the update flag. */
-		need_update |= bit_get_packet(bat_priv,
-					      tmp_neigh_node->real_bits,
-					      seq_diff, set_mark);
-
-		tmp_neigh_node->real_packet_count =
-			bit_packet_count(tmp_neigh_node->real_bits);
-	}
-	rcu_read_unlock();
-
-	if (need_update) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"updating last_seqno: old %d, new %d\n",
-			orig_node->last_real_seqno, batman_ogm_packet->seqno);
-		orig_node->last_real_seqno = batman_ogm_packet->seqno;
-	}
-
-	ret = is_duplicate;
-
-out:
-	spin_unlock_bh(&orig_node->ogm_cnt_lock);
-	orig_node_free_ref(orig_node);
-	return ret;
-}
-
-void receive_bat_packet(const struct ethhdr *ethhdr,
-			struct batman_ogm_packet *batman_ogm_packet,
-			const unsigned char *tt_buff,
-			struct hard_iface *if_incoming)
-{
-	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
-	struct hard_iface *hard_iface;
-	struct orig_node *orig_neigh_node, *orig_node;
-	struct neigh_node *router = NULL, *router_router = NULL;
-	struct neigh_node *orig_neigh_router = NULL;
-	int has_directlink_flag;
-	int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
-	int is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
-	int is_duplicate;
-	uint32_t if_incoming_seqno;
-
-	/* Silently drop when the batman packet is actually not a
-	 * correct packet.
-	 *
-	 * This might happen if a packet is padded (e.g. Ethernet has a
-	 * minimum frame length of 64 byte) and the aggregation interprets
-	 * it as an additional length.
-	 *
-	 * TODO: A more sane solution would be to have a bit in the
-	 * batman_ogm_packet to detect whether the packet is the last
-	 * packet in an aggregation.  Here we expect that the padding
-	 * is always zero (or not 0x01)
-	 */
-	if (batman_ogm_packet->packet_type != BAT_OGM)
-		return;
-
-	/* could be changed by schedule_own_packet() */
-	if_incoming_seqno = atomic_read(&if_incoming->seqno);
-
-	has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
-
-	is_single_hop_neigh = (compare_eth(ethhdr->h_source,
-					   batman_ogm_packet->orig) ? 1 : 0);
-
-	bat_dbg(DBG_BATMAN, bat_priv,
-		"Received BATMAN packet via NB: %pM, IF: %s [%pM] "
-		"(from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, "
-		"crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
-		ethhdr->h_source, if_incoming->net_dev->name,
-		if_incoming->net_dev->dev_addr, batman_ogm_packet->orig,
-		batman_ogm_packet->prev_sender, batman_ogm_packet->seqno,
-		batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc,
-		batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq,
-		batman_ogm_packet->ttl, batman_ogm_packet->version,
-		has_directlink_flag);
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
-		if (hard_iface->if_status != IF_ACTIVE)
-			continue;
-
-		if (hard_iface->soft_iface != if_incoming->soft_iface)
-			continue;
-
-		if (compare_eth(ethhdr->h_source,
-				hard_iface->net_dev->dev_addr))
-			is_my_addr = 1;
-
-		if (compare_eth(batman_ogm_packet->orig,
-				hard_iface->net_dev->dev_addr))
-			is_my_orig = 1;
-
-		if (compare_eth(batman_ogm_packet->prev_sender,
-				hard_iface->net_dev->dev_addr))
-			is_my_oldorig = 1;
-
-		if (is_broadcast_ether_addr(ethhdr->h_source))
-			is_broadcast = 1;
-	}
-	rcu_read_unlock();
-
-	if (batman_ogm_packet->version != COMPAT_VERSION) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: incompatible batman version (%i)\n",
-			batman_ogm_packet->version);
-		return;
-	}
-
-	if (is_my_addr) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: received my own broadcast (sender: %pM"
-			")\n",
-			ethhdr->h_source);
-		return;
-	}
-
-	if (is_broadcast) {
-		bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
-		"ignoring all packets with broadcast source addr (sender: %pM"
-		")\n", ethhdr->h_source);
-		return;
-	}
-
-	if (is_my_orig) {
-		unsigned long *word;
-		int offset;
-
-		orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source);
-		if (!orig_neigh_node)
-			return;
-
-		/* neighbor has to indicate direct link and it has to
-		 * come via the corresponding interface */
-		/* save packet seqno for bidirectional check */
-		if (has_directlink_flag &&
-		    compare_eth(if_incoming->net_dev->dev_addr,
-				batman_ogm_packet->orig)) {
-			offset = if_incoming->if_num * NUM_WORDS;
-
-			spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
-			word = &(orig_neigh_node->bcast_own[offset]);
-			bit_mark(word,
-				 if_incoming_seqno -
-						batman_ogm_packet->seqno - 2);
-			orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
-				bit_packet_count(word);
-			spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
-		}
-
-		bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
-			"originator packet from myself (via neighbor)\n");
-		orig_node_free_ref(orig_neigh_node);
-		return;
-	}
-
-	if (is_my_oldorig) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: ignoring all rebroadcast echos (sender: "
-			"%pM)\n", ethhdr->h_source);
-		return;
-	}
-
-	orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
-	if (!orig_node)
-		return;
-
-	is_duplicate = count_real_packets(ethhdr, batman_ogm_packet,
-					  if_incoming);
-
-	if (is_duplicate == -1) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: packet within seqno protection time "
-			"(sender: %pM)\n", ethhdr->h_source);
-		goto out;
-	}
-
-	if (batman_ogm_packet->tq == 0) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: originator packet with tq equal 0\n");
-		goto out;
-	}
-
-	router = orig_node_get_router(orig_node);
-	if (router)
-		router_router = orig_node_get_router(router->orig_node);
-
-	/* avoid temporary routing loops */
-	if (router && router_router &&
-	    (compare_eth(router->addr, batman_ogm_packet->prev_sender)) &&
-	    !(compare_eth(batman_ogm_packet->orig,
-			  batman_ogm_packet->prev_sender)) &&
-	    (compare_eth(router->addr, router_router->addr))) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: ignoring all rebroadcast packets that "
-			"may make me loop (sender: %pM)\n", ethhdr->h_source);
-		goto out;
-	}
-
-	/* if sender is a direct neighbor the sender mac equals
-	 * originator mac */
-	orig_neigh_node = (is_single_hop_neigh ?
-			   orig_node :
-			   get_orig_node(bat_priv, ethhdr->h_source));
-	if (!orig_neigh_node)
-		goto out;
-
-	orig_neigh_router = orig_node_get_router(orig_neigh_node);
-
-	/* drop packet if sender is not a direct neighbor and if we
-	 * don't route towards it */
-	if (!is_single_hop_neigh && (!orig_neigh_router)) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: OGM via unknown neighbor!\n");
-		goto out_neigh;
-	}
-
-	is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node,
-						  batman_ogm_packet,
-						  if_incoming);
-
-	bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet);
-
-	/* update ranking if it is not a duplicate or has the same
-	 * seqno and similar ttl as the non-duplicate */
-	if (is_bidirectional &&
-	    (!is_duplicate ||
-	     ((orig_node->last_real_seqno == batman_ogm_packet->seqno) &&
-	      (orig_node->last_ttl - 3 <= batman_ogm_packet->ttl))))
-		update_orig(bat_priv, orig_node, ethhdr, batman_ogm_packet,
-			    if_incoming, tt_buff, is_duplicate);
-
-	/* is single hop (direct) neighbor */
-	if (is_single_hop_neigh) {
-
-		/* mark direct link on incoming interface */
-		schedule_forward_packet(orig_node, ethhdr, batman_ogm_packet,
-					1, if_incoming);
-
-		bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
-			"rebroadcast neighbor packet with direct link flag\n");
-		goto out_neigh;
-	}
-
-	/* multihop originator */
-	if (!is_bidirectional) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: not received via bidirectional link\n");
-		goto out_neigh;
-	}
-
-	if (is_duplicate) {
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"Drop packet: duplicate packet received\n");
-		goto out_neigh;
-	}
-
-	bat_dbg(DBG_BATMAN, bat_priv,
-		"Forwarding packet: rebroadcast originator packet\n");
-	schedule_forward_packet(orig_node, ethhdr, batman_ogm_packet,
-				0, if_incoming);
-
-out_neigh:
-	if ((orig_neigh_node) && (!is_single_hop_neigh))
-		orig_node_free_ref(orig_neigh_node);
-out:
-	if (router)
-		neigh_node_free_ref(router);
-	if (router_router)
-		neigh_node_free_ref(router_router);
-	if (orig_neigh_router)
-		neigh_node_free_ref(orig_neigh_router);
-
-	orig_node_free_ref(orig_node);
-}
-
-int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
+int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
 {
 	struct ethhdr *ethhdr;
 
@@ -845,10 +274,7 @@ int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
 
 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
-	receive_aggr_bat_packet(ethhdr,
-				skb->data,
-				skb_headlen(skb),
-				hard_iface);
+	bat_ogm_receive(ethhdr, skb->data, skb_headlen(skb), hard_iface);
 
 	kfree_skb(skb);
 	return NET_RX_SUCCESS;
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index 893db7f..7aaee0f 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -23,19 +23,15 @@
 #define _NET_BATMAN_ADV_ROUTING_H_
 
 void slide_own_bcast_window(struct hard_iface *hard_iface);
-void receive_bat_packet(const struct ethhdr *ethhdr,
-			struct batman_ogm_packet *batman_ogm_packet,
-			const unsigned char *tt_buff,
-			struct hard_iface *if_incoming);
-void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
-		   struct neigh_node *neigh_node);
+void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node,
+		  struct neigh_node *neigh_node);
 int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
 int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if);
 int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
 int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if);
 int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
 int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if);
-int recv_bat_packet(struct sk_buff *skb, struct hard_iface *recv_if);
+int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *recv_if);
 int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if);
 int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if);
 struct neigh_node *find_router(struct bat_priv *bat_priv,
@@ -43,5 +39,12 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
 			       const struct hard_iface *recv_if);
 void bonding_candidate_del(struct orig_node *orig_node,
 			   struct neigh_node *neigh_node);
+void bonding_candidate_add(struct orig_node *orig_node,
+			   struct neigh_node *neigh_node);
+void bonding_save_primary(const struct orig_node *orig_node,
+			  struct orig_node *orig_neigh_node,
+			  const struct batman_ogm_packet *batman_ogm_packet);
+int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff,
+		     unsigned long *last_reset);
 
 #endif /* _NET_BATMAN_ADV_ROUTING_H_ */
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 3/7] batman-adv: move routing packet initialization into corresponding file
From: Marek Lindner @ 2011-09-08 16:40 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
In-Reply-To: <1315500051-1122-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
---
 net/batman-adv/bat_iv_ogm.c     |   37 +++++++++++++++++++++++++++++++++++++
 net/batman-adv/bat_ogm.h        |    3 +++
 net/batman-adv/hard-interface.c |   38 ++++++--------------------------------
 3 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 6fa2d46..468bd5e 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -30,6 +30,43 @@
 #include "hard-interface.h"
 #include "send.h"
 
+void bat_ogm_init(struct hard_iface *hard_iface)
+{
+	struct batman_ogm_packet *batman_ogm_packet;
+
+	hard_iface->packet_len = BATMAN_OGM_LEN;
+	hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
+
+	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
+	batman_ogm_packet->packet_type = BAT_OGM;
+	batman_ogm_packet->version = COMPAT_VERSION;
+	batman_ogm_packet->flags = NO_FLAGS;
+	batman_ogm_packet->ttl = 2;
+	batman_ogm_packet->tq = TQ_MAX_VALUE;
+	batman_ogm_packet->tt_num_changes = 0;
+	batman_ogm_packet->ttvn = 0;
+}
+
+void bat_ogm_init_primary(struct hard_iface *hard_iface)
+{
+	struct batman_ogm_packet *batman_ogm_packet;
+
+	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
+	batman_ogm_packet->flags = PRIMARIES_FIRST_HOP;
+	batman_ogm_packet->ttl = TTL;
+}
+
+void bat_ogm_update_mac(struct hard_iface *hard_iface)
+{
+	struct batman_ogm_packet *batman_ogm_packet;
+
+	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
+	memcpy(batman_ogm_packet->orig,
+	       hard_iface->net_dev->dev_addr, ETH_ALEN);
+	memcpy(batman_ogm_packet->prev_sender,
+	       hard_iface->net_dev->dev_addr, ETH_ALEN);
+}
+
 /* is there another aggregated packet here? */
 static int bat_ogm_aggr_packet(int buff_pos, int packet_len,
 			       int tt_num_changes)
diff --git a/net/batman-adv/bat_ogm.h b/net/batman-adv/bat_ogm.h
index bdd3d1e..7809b92 100644
--- a/net/batman-adv/bat_ogm.h
+++ b/net/batman-adv/bat_ogm.h
@@ -24,6 +24,9 @@
 
 #include "main.h"
 
+void bat_ogm_init(struct hard_iface *hard_iface);
+void bat_ogm_init_primary(struct hard_iface *hard_iface);
+void bat_ogm_update_mac(struct hard_iface *hard_iface);
 void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
 		     int packet_len, struct hard_iface *if_incoming);
 
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index cfee017..2a15582 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -28,6 +28,7 @@
 #include "bat_sysfs.h"
 #include "originator.h"
 #include "hash.h"
+#include "bat_ogm.h"
 
 #include <linux/if_arp.h>
 
@@ -131,7 +132,6 @@ static void primary_if_select(struct bat_priv *bat_priv,
 			      struct hard_iface *new_hard_iface)
 {
 	struct hard_iface *curr_hard_iface;
-	struct batman_ogm_packet *batman_ogm_packet;
 
 	ASSERT_RTNL();
 
@@ -147,11 +147,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
 	if (!new_hard_iface)
 		return;
 
-	batman_ogm_packet = (struct batman_ogm_packet *)
-						(new_hard_iface->packet_buff);
-	batman_ogm_packet->flags = PRIMARIES_FIRST_HOP;
-	batman_ogm_packet->ttl = TTL;
-
+	bat_ogm_init_primary(new_hard_iface);
 	primary_if_update_addr(bat_priv);
 }
 
@@ -163,17 +159,6 @@ static bool hardif_is_iface_up(const struct hard_iface *hard_iface)
 	return false;
 }
 
-static void update_mac_addresses(struct hard_iface *hard_iface)
-{
-	struct batman_ogm_packet *batman_ogm_packet;
-
-	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
-	memcpy(batman_ogm_packet->orig,
-	       hard_iface->net_dev->dev_addr, ETH_ALEN);
-	memcpy(batman_ogm_packet->prev_sender,
-	       hard_iface->net_dev->dev_addr, ETH_ALEN);
-}
-
 static void check_known_mac_addr(const struct net_device *net_dev)
 {
 	const struct hard_iface *hard_iface;
@@ -248,7 +233,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
 
 	bat_priv = netdev_priv(hard_iface->soft_iface);
 
-	update_mac_addresses(hard_iface);
+	bat_ogm_update_mac(hard_iface);
 	hard_iface->if_status = IF_TO_BE_ACTIVATED;
 
 	/**
@@ -287,7 +272,6 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 			    const char *iface_name)
 {
 	struct bat_priv *bat_priv;
-	struct batman_ogm_packet *batman_ogm_packet;
 	struct net_device *soft_iface;
 	int ret;
 
@@ -322,8 +306,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 
 	hard_iface->soft_iface = soft_iface;
 	bat_priv = netdev_priv(hard_iface->soft_iface);
-	hard_iface->packet_len = BATMAN_OGM_LEN;
-	hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
+
+	bat_ogm_init(hard_iface);
 
 	if (!hard_iface->packet_buff) {
 		bat_err(hard_iface->soft_iface, "Can't add interface packet "
@@ -332,16 +316,6 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 		goto err;
 	}
 
-	batman_ogm_packet = (struct batman_ogm_packet *)
-						(hard_iface->packet_buff);
-	batman_ogm_packet->packet_type = BAT_OGM;
-	batman_ogm_packet->version = COMPAT_VERSION;
-	batman_ogm_packet->flags = NO_FLAGS;
-	batman_ogm_packet->ttl = 2;
-	batman_ogm_packet->tq = TQ_MAX_VALUE;
-	batman_ogm_packet->tt_num_changes = 0;
-	batman_ogm_packet->ttvn = 0;
-
 	hard_iface->if_num = bat_priv->num_ifaces;
 	bat_priv->num_ifaces++;
 	hard_iface->if_status = IF_INACTIVE;
@@ -556,7 +530,7 @@ static int hard_if_event(struct notifier_block *this,
 			goto hardif_put;
 
 		check_known_mac_addr(hard_iface->net_dev);
-		update_mac_addresses(hard_iface);
+		bat_ogm_update_mac(hard_iface);
 
 		bat_priv = netdev_priv(hard_iface->soft_iface);
 		primary_if = primary_if_get_selected(bat_priv);
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 4/7] batman-adv: agglomerate all batman iv ogm sending functions in the batman iv file
From: Marek Lindner @ 2011-09-08 16:40 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
In-Reply-To: <1315500051-1122-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

In the process the batman iv OGM aggregation code could be merged
into the batman iv code base which makes the separate aggregation
files superfluous.

Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
---
 net/batman-adv/Makefile         |    1 -
 net/batman-adv/aggregation.c    |  266 ---------------------
 net/batman-adv/aggregation.h    |   42 ----
 net/batman-adv/bat_iv_ogm.c     |  502 ++++++++++++++++++++++++++++++++++++++-
 net/batman-adv/bat_ogm.h        |    2 +
 net/batman-adv/hard-interface.c |    2 +-
 net/batman-adv/send.c           |  297 ++----------------------
 net/batman-adv/send.h           |    9 +-
 8 files changed, 522 insertions(+), 599 deletions(-)
 delete mode 100644 net/batman-adv/aggregation.c
 delete mode 100644 net/batman-adv/aggregation.h

diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index 3293598..ce68611 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -19,7 +19,6 @@
 #
 
 obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
-batman-adv-y += aggregation.o
 batman-adv-y += bat_debugfs.o
 batman-adv-y += bat_iv_ogm.o
 batman-adv-y += bat_sysfs.o
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
deleted file mode 100644
index 4716c93..0000000
--- a/net/batman-adv/aggregation.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-#include "main.h"
-#include "translation-table.h"
-#include "aggregation.h"
-#include "send.h"
-#include "routing.h"
-#include "hard-interface.h"
-
-/* return true if new_packet can be aggregated with forw_packet */
-static bool can_aggregate_with(const struct batman_ogm_packet
-							*new_batman_ogm_packet,
-			       struct bat_priv *bat_priv,
-			       int packet_len,
-			       unsigned long send_time,
-			       bool directlink,
-			       const struct hard_iface *if_incoming,
-			       const struct forw_packet *forw_packet)
-{
-	struct batman_ogm_packet *batman_ogm_packet =
-			(struct batman_ogm_packet *)forw_packet->skb->data;
-	int aggregated_bytes = forw_packet->packet_len + packet_len;
-	struct hard_iface *primary_if = NULL;
-	bool res = false;
-
-	/**
-	 * we can aggregate the current packet to this aggregated packet
-	 * if:
-	 *
-	 * - the send time is within our MAX_AGGREGATION_MS time
-	 * - the resulting packet wont be bigger than
-	 *   MAX_AGGREGATION_BYTES
-	 */
-
-	if (time_before(send_time, forw_packet->send_time) &&
-	    time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS),
-					forw_packet->send_time) &&
-	    (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
-
-		/**
-		 * check aggregation compatibility
-		 * -> direct link packets are broadcasted on
-		 *    their interface only
-		 * -> aggregate packet if the current packet is
-		 *    a "global" packet as well as the base
-		 *    packet
-		 */
-
-		primary_if = primary_if_get_selected(bat_priv);
-		if (!primary_if)
-			goto out;
-
-		/* packets without direct link flag and high TTL
-		 * are flooded through the net  */
-		if ((!directlink) &&
-		    (!(batman_ogm_packet->flags & DIRECTLINK)) &&
-		    (batman_ogm_packet->ttl != 1) &&
-
-		    /* own packets originating non-primary
-		     * interfaces leave only that interface */
-		    ((!forw_packet->own) ||
-		     (forw_packet->if_incoming == primary_if))) {
-			res = true;
-			goto out;
-		}
-
-		/* if the incoming packet is sent via this one
-		 * interface only - we still can aggregate */
-		if ((directlink) &&
-		    (new_batman_ogm_packet->ttl == 1) &&
-		    (forw_packet->if_incoming == if_incoming) &&
-
-		    /* packets from direct neighbors or
-		     * own secondary interface packets
-		     * (= secondary interface packets in general) */
-		    (batman_ogm_packet->flags & DIRECTLINK ||
-		     (forw_packet->own &&
-		      forw_packet->if_incoming != primary_if))) {
-			res = true;
-			goto out;
-		}
-	}
-
-out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
-	return res;
-}
-
-/* create a new aggregated packet and add this packet to it */
-static void new_aggregated_packet(const unsigned char *packet_buff,
-				  int packet_len, unsigned long send_time,
-				  bool direct_link,
-				  struct hard_iface *if_incoming,
-				  int own_packet)
-{
-	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
-	struct forw_packet *forw_packet_aggr;
-	unsigned char *skb_buff;
-
-	if (!atomic_inc_not_zero(&if_incoming->refcount))
-		return;
-
-	/* own packet should always be scheduled */
-	if (!own_packet) {
-		if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
-			bat_dbg(DBG_BATMAN, bat_priv,
-				"batman packet queue full\n");
-			goto out;
-		}
-	}
-
-	forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC);
-	if (!forw_packet_aggr) {
-		if (!own_packet)
-			atomic_inc(&bat_priv->batman_queue_left);
-		goto out;
-	}
-
-	if ((atomic_read(&bat_priv->aggregated_ogms)) &&
-	    (packet_len < MAX_AGGREGATION_BYTES))
-		forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
-						      sizeof(struct ethhdr));
-	else
-		forw_packet_aggr->skb = dev_alloc_skb(packet_len +
-						      sizeof(struct ethhdr));
-
-	if (!forw_packet_aggr->skb) {
-		if (!own_packet)
-			atomic_inc(&bat_priv->batman_queue_left);
-		kfree(forw_packet_aggr);
-		goto out;
-	}
-	skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
-
-	INIT_HLIST_NODE(&forw_packet_aggr->list);
-
-	skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
-	forw_packet_aggr->packet_len = packet_len;
-	memcpy(skb_buff, packet_buff, packet_len);
-
-	forw_packet_aggr->own = own_packet;
-	forw_packet_aggr->if_incoming = if_incoming;
-	forw_packet_aggr->num_packets = 0;
-	forw_packet_aggr->direct_link_flags = NO_FLAGS;
-	forw_packet_aggr->send_time = send_time;
-
-	/* save packet direct link flag status */
-	if (direct_link)
-		forw_packet_aggr->direct_link_flags |= 1;
-
-	/* add new packet to packet list */
-	spin_lock_bh(&bat_priv->forw_bat_list_lock);
-	hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
-	spin_unlock_bh(&bat_priv->forw_bat_list_lock);
-
-	/* start timer for this packet */
-	INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
-			  send_outstanding_bat_packet);
-	queue_delayed_work(bat_event_workqueue,
-			   &forw_packet_aggr->delayed_work,
-			   send_time - jiffies);
-
-	return;
-out:
-	hardif_free_ref(if_incoming);
-}
-
-/* aggregate a new packet into the existing aggregation */
-static void aggregate(struct forw_packet *forw_packet_aggr,
-		      const unsigned char *packet_buff, int packet_len,
-		      bool direct_link)
-{
-	unsigned char *skb_buff;
-
-	skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
-	memcpy(skb_buff, packet_buff, packet_len);
-	forw_packet_aggr->packet_len += packet_len;
-	forw_packet_aggr->num_packets++;
-
-	/* save packet direct link flag status */
-	if (direct_link)
-		forw_packet_aggr->direct_link_flags |=
-			(1 << forw_packet_aggr->num_packets);
-}
-
-void add_bat_packet_to_list(struct bat_priv *bat_priv,
-			    unsigned char *packet_buff, int packet_len,
-			    struct hard_iface *if_incoming, int own_packet,
-			    unsigned long send_time)
-{
-	/**
-	 * _aggr -> pointer to the packet we want to aggregate with
-	 * _pos -> pointer to the position in the queue
-	 */
-	struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
-	struct hlist_node *tmp_node;
-	struct batman_ogm_packet *batman_ogm_packet;
-	bool direct_link;
-
-	batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
-	direct_link = batman_ogm_packet->flags & DIRECTLINK ? 1 : 0;
-
-	/* find position for the packet in the forward queue */
-	spin_lock_bh(&bat_priv->forw_bat_list_lock);
-	/* own packets are not to be aggregated */
-	if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
-		hlist_for_each_entry(forw_packet_pos, tmp_node,
-				     &bat_priv->forw_bat_list, list) {
-			if (can_aggregate_with(batman_ogm_packet,
-					       bat_priv,
-					       packet_len,
-					       send_time,
-					       direct_link,
-					       if_incoming,
-					       forw_packet_pos)) {
-				forw_packet_aggr = forw_packet_pos;
-				break;
-			}
-		}
-	}
-
-	/* nothing to aggregate with - either aggregation disabled or no
-	 * suitable aggregation packet found */
-	if (!forw_packet_aggr) {
-		/* the following section can run without the lock */
-		spin_unlock_bh(&bat_priv->forw_bat_list_lock);
-
-		/**
-		 * if we could not aggregate this packet with one of the others
-		 * we hold it back for a while, so that it might be aggregated
-		 * later on
-		 */
-		if ((!own_packet) &&
-		    (atomic_read(&bat_priv->aggregated_ogms)))
-			send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
-
-		new_aggregated_packet(packet_buff, packet_len,
-				      send_time, direct_link,
-				      if_incoming, own_packet);
-	} else {
-		aggregate(forw_packet_aggr,
-			  packet_buff, packet_len,
-			  direct_link);
-		spin_unlock_bh(&bat_priv->forw_bat_list_lock);
-	}
-}
diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h
deleted file mode 100644
index 7a92e4c..0000000
--- a/net/batman-adv/aggregation.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-#ifndef _NET_BATMAN_ADV_AGGREGATION_H_
-#define _NET_BATMAN_ADV_AGGREGATION_H_
-
-#include "main.h"
-
-/* is there another aggregated packet here? */
-static inline int aggregated_packet(int buff_pos, int packet_len,
-				    int tt_num_changes)
-{
-	int next_buff_pos = buff_pos + BATMAN_OGM_LEN + tt_len(tt_num_changes);
-
-	return (next_buff_pos <= packet_len) &&
-		(next_buff_pos <= MAX_AGGREGATION_BYTES);
-}
-
-void add_bat_packet_to_list(struct bat_priv *bat_priv,
-			    unsigned char *packet_buff, int packet_len,
-			    struct hard_iface *if_incoming, int own_packet,
-			    unsigned long send_time);
-
-#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 468bd5e..3512e25 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -67,6 +67,27 @@ void bat_ogm_update_mac(struct hard_iface *hard_iface)
 	       hard_iface->net_dev->dev_addr, ETH_ALEN);
 }
 
+/* when do we schedule our own ogm to be sent */
+static unsigned long bat_ogm_emit_send_time(const struct bat_priv *bat_priv)
+{
+	return jiffies + msecs_to_jiffies(
+		   atomic_read(&bat_priv->orig_interval) -
+		   JITTER + (random32() % 2*JITTER));
+}
+
+/* when do we schedule a ogm packet to be sent */
+static unsigned long bat_ogm_fwd_send_time(void)
+{
+	return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
+}
+
+/* apply hop penalty for a normal link */
+static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv)
+{
+	int hop_penalty = atomic_read(&bat_priv->hop_penalty);
+	return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE);
+}
+
 /* is there another aggregated packet here? */
 static int bat_ogm_aggr_packet(int buff_pos, int packet_len,
 			       int tt_num_changes)
@@ -77,6 +98,480 @@ static int bat_ogm_aggr_packet(int buff_pos, int packet_len,
 		(next_buff_pos <= MAX_AGGREGATION_BYTES);
 }
 
+/* send a batman ogm to a given interface */
+static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
+			       struct hard_iface *hard_iface)
+{
+	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+	char *fwd_str;
+	uint8_t packet_num;
+	int16_t buff_pos;
+	struct batman_ogm_packet *batman_ogm_packet;
+	struct sk_buff *skb;
+
+	if (hard_iface->if_status != IF_ACTIVE)
+		return;
+
+	packet_num = 0;
+	buff_pos = 0;
+	batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
+
+	/* adjust all flags and log packets */
+	while (bat_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
+				   batman_ogm_packet->tt_num_changes)) {
+
+		/* we might have aggregated direct link packets with an
+		 * ordinary base packet */
+		if ((forw_packet->direct_link_flags & (1 << packet_num)) &&
+		    (forw_packet->if_incoming == hard_iface))
+			batman_ogm_packet->flags |= DIRECTLINK;
+		else
+			batman_ogm_packet->flags &= ~DIRECTLINK;
+
+		fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
+							    "Sending own" :
+							    "Forwarding"));
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
+			" IDF %s, ttvn %d) on interface %s [%pM]\n",
+			fwd_str, (packet_num > 0 ? "aggregated " : ""),
+			batman_ogm_packet->orig,
+			ntohl(batman_ogm_packet->seqno),
+			batman_ogm_packet->tq, batman_ogm_packet->ttl,
+			(batman_ogm_packet->flags & DIRECTLINK ?
+			 "on" : "off"),
+			batman_ogm_packet->ttvn, hard_iface->net_dev->name,
+			hard_iface->net_dev->dev_addr);
+
+		buff_pos += BATMAN_OGM_LEN +
+				tt_len(batman_ogm_packet->tt_num_changes);
+		packet_num++;
+		batman_ogm_packet = (struct batman_ogm_packet *)
+					(forw_packet->skb->data + buff_pos);
+	}
+
+	/* create clone because function is called more than once */
+	skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
+	if (skb)
+		send_skb_packet(skb, hard_iface, broadcast_addr);
+}
+
+/* send a batman ogm packet */
+void bat_ogm_emit(struct forw_packet *forw_packet)
+{
+	struct hard_iface *hard_iface;
+	struct net_device *soft_iface;
+	struct bat_priv *bat_priv;
+	struct hard_iface *primary_if = NULL;
+	struct batman_ogm_packet *batman_ogm_packet;
+	unsigned char directlink;
+
+	batman_ogm_packet = (struct batman_ogm_packet *)
+						(forw_packet->skb->data);
+	directlink = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
+
+	if (!forw_packet->if_incoming) {
+		pr_err("Error - can't forward packet: incoming iface not "
+		       "specified\n");
+		goto out;
+	}
+
+	soft_iface = forw_packet->if_incoming->soft_iface;
+	bat_priv = netdev_priv(soft_iface);
+
+	if (forw_packet->if_incoming->if_status != IF_ACTIVE)
+		goto out;
+
+	primary_if = primary_if_get_selected(bat_priv);
+	if (!primary_if)
+		goto out;
+
+	/* multihomed peer assumed */
+	/* non-primary OGMs are only broadcasted on their interface */
+	if ((directlink && (batman_ogm_packet->ttl == 1)) ||
+	    (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
+
+		/* FIXME: what about aggregated packets ? */
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"%s packet (originator %pM, seqno %d, TTL %d) "
+			"on interface %s [%pM]\n",
+			(forw_packet->own ? "Sending own" : "Forwarding"),
+			batman_ogm_packet->orig,
+			ntohl(batman_ogm_packet->seqno),
+			batman_ogm_packet->ttl,
+			forw_packet->if_incoming->net_dev->name,
+			forw_packet->if_incoming->net_dev->dev_addr);
+
+		/* skb is only used once and than forw_packet is free'd */
+		send_skb_packet(forw_packet->skb, forw_packet->if_incoming,
+				broadcast_addr);
+		forw_packet->skb = NULL;
+
+		goto out;
+	}
+
+	/* broadcast on every interface */
+	rcu_read_lock();
+	list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
+		if (hard_iface->soft_iface != soft_iface)
+			continue;
+
+		bat_ogm_send_to_if(forw_packet, hard_iface);
+	}
+	rcu_read_unlock();
+
+out:
+	if (primary_if)
+		hardif_free_ref(primary_if);
+}
+
+/* return true if new_packet can be aggregated with forw_packet */
+static bool bat_ogm_can_aggregate(const struct batman_ogm_packet
+							*new_batman_ogm_packet,
+				  struct bat_priv *bat_priv,
+				  int packet_len, unsigned long send_time,
+				  bool directlink,
+				  const struct hard_iface *if_incoming,
+				  const struct forw_packet *forw_packet)
+{
+	struct batman_ogm_packet *batman_ogm_packet;
+	int aggregated_bytes = forw_packet->packet_len + packet_len;
+	struct hard_iface *primary_if = NULL;
+	bool res = false;
+
+	batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
+
+	/**
+	 * we can aggregate the current packet to this aggregated packet
+	 * if:
+	 *
+	 * - the send time is within our MAX_AGGREGATION_MS time
+	 * - the resulting packet wont be bigger than
+	 *   MAX_AGGREGATION_BYTES
+	 */
+
+	if (time_before(send_time, forw_packet->send_time) &&
+	    time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS),
+					forw_packet->send_time) &&
+	    (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
+
+		/**
+		 * check aggregation compatibility
+		 * -> direct link packets are broadcasted on
+		 *    their interface only
+		 * -> aggregate packet if the current packet is
+		 *    a "global" packet as well as the base
+		 *    packet
+		 */
+
+		primary_if = primary_if_get_selected(bat_priv);
+		if (!primary_if)
+			goto out;
+
+		/* packets without direct link flag and high TTL
+		 * are flooded through the net  */
+		if ((!directlink) &&
+		    (!(batman_ogm_packet->flags & DIRECTLINK)) &&
+		    (batman_ogm_packet->ttl != 1) &&
+
+		    /* own packets originating non-primary
+		     * interfaces leave only that interface */
+		    ((!forw_packet->own) ||
+		     (forw_packet->if_incoming == primary_if))) {
+			res = true;
+			goto out;
+		}
+
+		/* if the incoming packet is sent via this one
+		 * interface only - we still can aggregate */
+		if ((directlink) &&
+		    (new_batman_ogm_packet->ttl == 1) &&
+		    (forw_packet->if_incoming == if_incoming) &&
+
+		    /* packets from direct neighbors or
+		     * own secondary interface packets
+		     * (= secondary interface packets in general) */
+		    (batman_ogm_packet->flags & DIRECTLINK ||
+		     (forw_packet->own &&
+		      forw_packet->if_incoming != primary_if))) {
+			res = true;
+			goto out;
+		}
+	}
+
+out:
+	if (primary_if)
+		hardif_free_ref(primary_if);
+	return res;
+}
+
+/* create a new aggregated packet and add this packet to it */
+static void bat_ogm_aggregate_new(const unsigned char *packet_buff,
+				  int packet_len, unsigned long send_time,
+				  bool direct_link,
+				  struct hard_iface *if_incoming,
+				  int own_packet)
+{
+	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+	struct forw_packet *forw_packet_aggr;
+	unsigned char *skb_buff;
+
+	if (!atomic_inc_not_zero(&if_incoming->refcount))
+		return;
+
+	/* own packet should always be scheduled */
+	if (!own_packet) {
+		if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
+			bat_dbg(DBG_BATMAN, bat_priv,
+				"batman packet queue full\n");
+			goto out;
+		}
+	}
+
+	forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC);
+	if (!forw_packet_aggr) {
+		if (!own_packet)
+			atomic_inc(&bat_priv->batman_queue_left);
+		goto out;
+	}
+
+	if ((atomic_read(&bat_priv->aggregated_ogms)) &&
+	    (packet_len < MAX_AGGREGATION_BYTES))
+		forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
+						      sizeof(struct ethhdr));
+	else
+		forw_packet_aggr->skb = dev_alloc_skb(packet_len +
+						      sizeof(struct ethhdr));
+
+	if (!forw_packet_aggr->skb) {
+		if (!own_packet)
+			atomic_inc(&bat_priv->batman_queue_left);
+		kfree(forw_packet_aggr);
+		goto out;
+	}
+	skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
+
+	INIT_HLIST_NODE(&forw_packet_aggr->list);
+
+	skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
+	forw_packet_aggr->packet_len = packet_len;
+	memcpy(skb_buff, packet_buff, packet_len);
+
+	forw_packet_aggr->own = own_packet;
+	forw_packet_aggr->if_incoming = if_incoming;
+	forw_packet_aggr->num_packets = 0;
+	forw_packet_aggr->direct_link_flags = NO_FLAGS;
+	forw_packet_aggr->send_time = send_time;
+
+	/* save packet direct link flag status */
+	if (direct_link)
+		forw_packet_aggr->direct_link_flags |= 1;
+
+	/* add new packet to packet list */
+	spin_lock_bh(&bat_priv->forw_bat_list_lock);
+	hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
+	spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
+	/* start timer for this packet */
+	INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
+			  send_outstanding_bat_ogm_packet);
+	queue_delayed_work(bat_event_workqueue,
+			   &forw_packet_aggr->delayed_work,
+			   send_time - jiffies);
+
+	return;
+out:
+	hardif_free_ref(if_incoming);
+}
+
+/* aggregate a new packet into the existing ogm packet */
+static void bat_ogm_aggregate(struct forw_packet *forw_packet_aggr,
+			      const unsigned char *packet_buff,
+			      int packet_len, bool direct_link)
+{
+	unsigned char *skb_buff;
+
+	skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
+	memcpy(skb_buff, packet_buff, packet_len);
+	forw_packet_aggr->packet_len += packet_len;
+	forw_packet_aggr->num_packets++;
+
+	/* save packet direct link flag status */
+	if (direct_link)
+		forw_packet_aggr->direct_link_flags |=
+			(1 << forw_packet_aggr->num_packets);
+}
+
+static void bat_ogm_queue_add(struct bat_priv *bat_priv,
+			      unsigned char *packet_buff,
+			      int packet_len, struct hard_iface *if_incoming,
+			      int own_packet, unsigned long send_time)
+{
+	/**
+	 * _aggr -> pointer to the packet we want to aggregate with
+	 * _pos -> pointer to the position in the queue
+	 */
+	struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
+	struct hlist_node *tmp_node;
+	struct batman_ogm_packet *batman_ogm_packet;
+	bool direct_link;
+
+	batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
+	direct_link = batman_ogm_packet->flags & DIRECTLINK ? 1 : 0;
+
+	/* find position for the packet in the forward queue */
+	spin_lock_bh(&bat_priv->forw_bat_list_lock);
+	/* own packets are not to be aggregated */
+	if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
+		hlist_for_each_entry(forw_packet_pos, tmp_node,
+				     &bat_priv->forw_bat_list, list) {
+			if (bat_ogm_can_aggregate(batman_ogm_packet,
+						  bat_priv, packet_len,
+						  send_time, direct_link,
+						  if_incoming,
+						  forw_packet_pos)) {
+				forw_packet_aggr = forw_packet_pos;
+				break;
+			}
+		}
+	}
+
+	/* nothing to aggregate with - either aggregation disabled or no
+	 * suitable aggregation packet found */
+	if (!forw_packet_aggr) {
+		/* the following section can run without the lock */
+		spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
+		/**
+		 * if we could not aggregate this packet with one of the others
+		 * we hold it back for a while, so that it might be aggregated
+		 * later on
+		 */
+		if ((!own_packet) &&
+		    (atomic_read(&bat_priv->aggregated_ogms)))
+			send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
+
+		bat_ogm_aggregate_new(packet_buff, packet_len,
+				      send_time, direct_link,
+				      if_incoming, own_packet);
+	} else {
+		bat_ogm_aggregate(forw_packet_aggr, packet_buff, packet_len,
+				  direct_link);
+		spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+	}
+}
+
+static void bat_ogm_forward(struct orig_node *orig_node,
+			    const struct ethhdr *ethhdr,
+			    struct batman_ogm_packet *batman_ogm_packet,
+			    int directlink, struct hard_iface *if_incoming)
+{
+	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+	struct neigh_node *router;
+	uint8_t in_tq, in_ttl, tq_avg = 0;
+	uint8_t tt_num_changes;
+
+	if (batman_ogm_packet->ttl <= 1) {
+		bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
+		return;
+	}
+
+	router = orig_node_get_router(orig_node);
+
+	in_tq = batman_ogm_packet->tq;
+	in_ttl = batman_ogm_packet->ttl;
+	tt_num_changes = batman_ogm_packet->tt_num_changes;
+
+	batman_ogm_packet->ttl--;
+	memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
+
+	/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
+	 * of our best tq value */
+	if (router && router->tq_avg != 0) {
+
+		/* rebroadcast ogm of best ranking neighbor as is */
+		if (!compare_eth(router->addr, ethhdr->h_source)) {
+			batman_ogm_packet->tq = router->tq_avg;
+
+			if (router->last_ttl)
+				batman_ogm_packet->ttl = router->last_ttl - 1;
+		}
+
+		tq_avg = router->tq_avg;
+	}
+
+	if (router)
+		neigh_node_free_ref(router);
+
+	/* apply hop penalty */
+	batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv);
+
+	bat_dbg(DBG_BATMAN, bat_priv,
+		"Forwarding packet: tq_orig: %i, tq_avg: %i, "
+		"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
+		in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1,
+		batman_ogm_packet->ttl);
+
+	batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno);
+	batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc);
+
+	/* switch of primaries first hop flag when forwarding */
+	batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP;
+	if (directlink)
+		batman_ogm_packet->flags |= DIRECTLINK;
+	else
+		batman_ogm_packet->flags &= ~DIRECTLINK;
+
+	bat_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet,
+			  BATMAN_OGM_LEN + tt_len(tt_num_changes),
+			  if_incoming, 0, bat_ogm_fwd_send_time());
+}
+
+void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes)
+{
+	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+	struct batman_ogm_packet *batman_ogm_packet;
+	struct hard_iface *primary_if;
+	int vis_server;
+
+	vis_server = atomic_read(&bat_priv->vis_mode);
+	primary_if = primary_if_get_selected(bat_priv);
+
+	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
+
+	/* change sequence number to network order */
+	batman_ogm_packet->seqno =
+			htonl((uint32_t)atomic_read(&hard_iface->seqno));
+
+	batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn);
+	batman_ogm_packet->tt_crc = htons((uint16_t)
+						atomic_read(&bat_priv->tt_crc));
+	if (tt_num_changes >= 0)
+		batman_ogm_packet->tt_num_changes = tt_num_changes;
+
+	if (vis_server == VIS_TYPE_SERVER_SYNC)
+		batman_ogm_packet->flags |= VIS_SERVER;
+	else
+		batman_ogm_packet->flags &= ~VIS_SERVER;
+
+	if ((hard_iface == primary_if) &&
+	    (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
+		batman_ogm_packet->gw_flags =
+				(uint8_t)atomic_read(&bat_priv->gw_bandwidth);
+	else
+		batman_ogm_packet->gw_flags = NO_FLAGS;
+
+	atomic_inc(&hard_iface->seqno);
+
+	slide_own_bcast_window(hard_iface);
+	bat_ogm_queue_add(bat_priv, hard_iface->packet_buff,
+			  hard_iface->packet_len, hard_iface, 1,
+			  bat_ogm_emit_send_time(bat_priv));
+
+	if (primary_if)
+		hardif_free_ref(primary_if);
+}
+
 static void bat_ogm_orig_update(struct bat_priv *bat_priv,
 				struct orig_node *orig_node,
 				const struct ethhdr *ethhdr,
@@ -605,8 +1100,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 	if (is_single_hop_neigh) {
 
 		/* mark direct link on incoming interface */
-		schedule_forward_packet(orig_node, ethhdr, batman_ogm_packet,
-					1, if_incoming);
+		bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
+				1, if_incoming);
 
 		bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
 			"rebroadcast neighbor packet with direct link flag\n");
@@ -628,8 +1123,7 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 
 	bat_dbg(DBG_BATMAN, bat_priv,
 		"Forwarding packet: rebroadcast originator packet\n");
-	schedule_forward_packet(orig_node, ethhdr, batman_ogm_packet,
-				0, if_incoming);
+	bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet, 0, if_incoming);
 
 out_neigh:
 	if ((orig_neigh_node) && (!is_single_hop_neigh))
diff --git a/net/batman-adv/bat_ogm.h b/net/batman-adv/bat_ogm.h
index 7809b92..69329c1 100644
--- a/net/batman-adv/bat_ogm.h
+++ b/net/batman-adv/bat_ogm.h
@@ -27,6 +27,8 @@
 void bat_ogm_init(struct hard_iface *hard_iface);
 void bat_ogm_init_primary(struct hard_iface *hard_iface);
 void bat_ogm_update_mac(struct hard_iface *hard_iface);
+void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes);
+void bat_ogm_emit(struct forw_packet *forw_packet);
 void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
 		     int packet_len, struct hard_iface *if_incoming);
 
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 2a15582..0cc0f04 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -360,7 +360,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 			hard_iface->net_dev->name);
 
 	/* begin scheduling originator messages on that interface */
-	schedule_own_packet(hard_iface);
+	schedule_bat_ogm(hard_iface);
 
 out:
 	return 0;
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 40a5fcd..8a684eb 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -26,33 +26,12 @@
 #include "soft-interface.h"
 #include "hard-interface.h"
 #include "vis.h"
-#include "aggregation.h"
 #include "gateway_common.h"
 #include "originator.h"
+#include "bat_ogm.h"
 
 static void send_outstanding_bcast_packet(struct work_struct *work);
 
-/* apply hop penalty for a normal link */
-static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv)
-{
-	int hop_penalty = atomic_read(&bat_priv->hop_penalty);
-	return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE);
-}
-
-/* when do we schedule our own packet to be sent */
-static unsigned long own_send_time(const struct bat_priv *bat_priv)
-{
-	return jiffies + msecs_to_jiffies(
-		   atomic_read(&bat_priv->orig_interval) -
-		   JITTER + (random32() % 2*JITTER));
-}
-
-/* when do we schedule a forwarded packet to be sent */
-static unsigned long forward_send_time(void)
-{
-	return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
-}
-
 /* send out an already prepared packet to the given address via the
  * specified batman interface */
 int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
@@ -99,133 +78,6 @@ send_skb_err:
 	return NET_XMIT_DROP;
 }
 
-/* Send a packet to a given interface */
-static void send_packet_to_if(struct forw_packet *forw_packet,
-			      struct hard_iface *hard_iface)
-{
-	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
-	char *fwd_str;
-	uint8_t packet_num;
-	int16_t buff_pos;
-	struct batman_ogm_packet *batman_ogm_packet;
-	struct sk_buff *skb;
-
-	if (hard_iface->if_status != IF_ACTIVE)
-		return;
-
-	packet_num = 0;
-	buff_pos = 0;
-	batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
-
-	/* adjust all flags and log packets */
-	while (aggregated_packet(buff_pos,
-				 forw_packet->packet_len,
-				 batman_ogm_packet->tt_num_changes)) {
-
-		/* we might have aggregated direct link packets with an
-		 * ordinary base packet */
-		if ((forw_packet->direct_link_flags & (1 << packet_num)) &&
-		    (forw_packet->if_incoming == hard_iface))
-			batman_ogm_packet->flags |= DIRECTLINK;
-		else
-			batman_ogm_packet->flags &= ~DIRECTLINK;
-
-		fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
-							    "Sending own" :
-							    "Forwarding"));
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
-			" IDF %s, ttvn %d) on interface %s [%pM]\n",
-			fwd_str, (packet_num > 0 ? "aggregated " : ""),
-			batman_ogm_packet->orig,
-			ntohl(batman_ogm_packet->seqno),
-			batman_ogm_packet->tq, batman_ogm_packet->ttl,
-			(batman_ogm_packet->flags & DIRECTLINK ?
-			 "on" : "off"),
-			batman_ogm_packet->ttvn, hard_iface->net_dev->name,
-			hard_iface->net_dev->dev_addr);
-
-		buff_pos += BATMAN_OGM_LEN +
-				tt_len(batman_ogm_packet->tt_num_changes);
-		packet_num++;
-		batman_ogm_packet = (struct batman_ogm_packet *)
-					(forw_packet->skb->data + buff_pos);
-	}
-
-	/* create clone because function is called more than once */
-	skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
-	if (skb)
-		send_skb_packet(skb, hard_iface, broadcast_addr);
-}
-
-/* send a batman packet */
-static void send_packet(struct forw_packet *forw_packet)
-{
-	struct hard_iface *hard_iface;
-	struct net_device *soft_iface;
-	struct bat_priv *bat_priv;
-	struct hard_iface *primary_if = NULL;
-	struct batman_ogm_packet *batman_ogm_packet =
-			(struct batman_ogm_packet *)(forw_packet->skb->data);
-	unsigned char directlink;
-
-	directlink = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
-
-	if (!forw_packet->if_incoming) {
-		pr_err("Error - can't forward packet: incoming iface not "
-		       "specified\n");
-		goto out;
-	}
-
-	soft_iface = forw_packet->if_incoming->soft_iface;
-	bat_priv = netdev_priv(soft_iface);
-
-	if (forw_packet->if_incoming->if_status != IF_ACTIVE)
-		goto out;
-
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-
-	/* multihomed peer assumed */
-	/* non-primary OGMs are only broadcasted on their interface */
-	if ((directlink && (batman_ogm_packet->ttl == 1)) ||
-	    (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
-
-		/* FIXME: what about aggregated packets ? */
-		bat_dbg(DBG_BATMAN, bat_priv,
-			"%s packet (originator %pM, seqno %d, TTL %d) "
-			"on interface %s [%pM]\n",
-			(forw_packet->own ? "Sending own" : "Forwarding"),
-			batman_ogm_packet->orig,
-			ntohl(batman_ogm_packet->seqno),
-			batman_ogm_packet->ttl,
-			forw_packet->if_incoming->net_dev->name,
-			forw_packet->if_incoming->net_dev->dev_addr);
-
-		/* skb is only used once and than forw_packet is free'd */
-		send_skb_packet(forw_packet->skb, forw_packet->if_incoming,
-				broadcast_addr);
-		forw_packet->skb = NULL;
-
-		goto out;
-	}
-
-	/* broadcast on every interface */
-	rcu_read_lock();
-	list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
-		if (hard_iface->soft_iface != soft_iface)
-			continue;
-
-		send_packet_to_if(forw_packet, hard_iface);
-	}
-	rcu_read_unlock();
-
-out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
-}
-
 static void realloc_packet_buffer(struct hard_iface *hard_iface,
 				  int new_len)
 {
@@ -245,11 +97,10 @@ static void realloc_packet_buffer(struct hard_iface *hard_iface,
 }
 
 /* when calling this function (hard_iface == primary_if) has to be true */
-static void prepare_packet_buffer(struct bat_priv *bat_priv,
+static int prepare_packet_buffer(struct bat_priv *bat_priv,
 				  struct hard_iface *hard_iface)
 {
 	int new_len;
-	struct batman_ogm_packet *batman_ogm_packet;
 
 	new_len = BATMAN_OGM_LEN +
 		  tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes));
@@ -260,45 +111,34 @@ static void prepare_packet_buffer(struct bat_priv *bat_priv,
 		new_len = BATMAN_OGM_LEN;
 
 	realloc_packet_buffer(hard_iface, new_len);
-	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
 
 	atomic_set(&bat_priv->tt_crc, tt_local_crc(bat_priv));
 
 	/* reset the sending counter */
 	atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX);
 
-	batman_ogm_packet->tt_num_changes = tt_changes_fill_buffer(bat_priv,
-				hard_iface->packet_buff + BATMAN_OGM_LEN,
-				hard_iface->packet_len - BATMAN_OGM_LEN);
-
+	return tt_changes_fill_buffer(bat_priv,
+				      hard_iface->packet_buff + BATMAN_OGM_LEN,
+				      hard_iface->packet_len - BATMAN_OGM_LEN);
 }
 
-static void reset_packet_buffer(struct bat_priv *bat_priv,
+static int reset_packet_buffer(struct bat_priv *bat_priv,
 				struct hard_iface *hard_iface)
 {
-	struct batman_ogm_packet *batman_ogm_packet;
-
 	realloc_packet_buffer(hard_iface, BATMAN_OGM_LEN);
-
-	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
-	batman_ogm_packet->tt_num_changes = 0;
+	return 0;
 }
 
-void schedule_own_packet(struct hard_iface *hard_iface)
+void schedule_bat_ogm(struct hard_iface *hard_iface)
 {
 	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 	struct hard_iface *primary_if;
-	unsigned long send_time;
-	struct batman_ogm_packet *batman_ogm_packet;
-	int vis_server;
+	int tt_num_changes = -1;
 
 	if ((hard_iface->if_status == IF_NOT_IN_USE) ||
 	    (hard_iface->if_status == IF_TO_BE_REMOVED))
 		return;
 
-	vis_server = atomic_read(&bat_priv->vis_mode);
-	primary_if = primary_if_get_selected(bat_priv);
-
 	/**
 	 * the interface gets activated here to avoid race conditions between
 	 * the moment of activating the interface in
@@ -309,125 +149,26 @@ void schedule_own_packet(struct hard_iface *hard_iface)
 	if (hard_iface->if_status == IF_TO_BE_ACTIVATED)
 		hard_iface->if_status = IF_ACTIVE;
 
+	primary_if = primary_if_get_selected(bat_priv);
+
 	if (hard_iface == primary_if) {
 		/* if at least one change happened */
 		if (atomic_read(&bat_priv->tt_local_changes) > 0) {
 			tt_commit_changes(bat_priv);
-			prepare_packet_buffer(bat_priv, hard_iface);
+			tt_num_changes = prepare_packet_buffer(bat_priv,
+							       hard_iface);
 		}
 
 		/* if the changes have been sent often enough */
 		if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))
-			reset_packet_buffer(bat_priv, hard_iface);
+			tt_num_changes = reset_packet_buffer(bat_priv,
+							     hard_iface);
 	}
 
-	/**
-	 * NOTE: packet_buff might just have been re-allocated in
-	 * prepare_packet_buffer() or in reset_packet_buffer()
-	 */
-	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
-
-	/* change sequence number to network order */
-	batman_ogm_packet->seqno =
-			htonl((uint32_t)atomic_read(&hard_iface->seqno));
-
-	batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn);
-	batman_ogm_packet->tt_crc = htons((uint16_t)
-						atomic_read(&bat_priv->tt_crc));
-
-	if (vis_server == VIS_TYPE_SERVER_SYNC)
-		batman_ogm_packet->flags |= VIS_SERVER;
-	else
-		batman_ogm_packet->flags &= ~VIS_SERVER;
-
-	if ((hard_iface == primary_if) &&
-	    (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
-		batman_ogm_packet->gw_flags =
-				(uint8_t)atomic_read(&bat_priv->gw_bandwidth);
-	else
-		batman_ogm_packet->gw_flags = NO_FLAGS;
-
-	atomic_inc(&hard_iface->seqno);
-
-	slide_own_bcast_window(hard_iface);
-	send_time = own_send_time(bat_priv);
-	add_bat_packet_to_list(bat_priv,
-			       hard_iface->packet_buff,
-			       hard_iface->packet_len,
-			       hard_iface, 1, send_time);
-
 	if (primary_if)
 		hardif_free_ref(primary_if);
-}
-
-void schedule_forward_packet(struct orig_node *orig_node,
-			     const struct ethhdr *ethhdr,
-			     struct batman_ogm_packet *batman_ogm_packet,
-			     int directlink,
-			     struct hard_iface *if_incoming)
-{
-	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
-	struct neigh_node *router;
-	uint8_t in_tq, in_ttl, tq_avg = 0;
-	unsigned long send_time;
-	uint8_t tt_num_changes;
-
-	if (batman_ogm_packet->ttl <= 1) {
-		bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
-		return;
-	}
-
-	router = orig_node_get_router(orig_node);
-
-	in_tq = batman_ogm_packet->tq;
-	in_ttl = batman_ogm_packet->ttl;
-	tt_num_changes = batman_ogm_packet->tt_num_changes;
-
-	batman_ogm_packet->ttl--;
-	memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
-
-	/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
-	 * of our best tq value */
-	if (router && router->tq_avg != 0) {
-
-		/* rebroadcast ogm of best ranking neighbor as is */
-		if (!compare_eth(router->addr, ethhdr->h_source)) {
-			batman_ogm_packet->tq = router->tq_avg;
-
-			if (router->last_ttl)
-				batman_ogm_packet->ttl = router->last_ttl - 1;
-		}
-
-		tq_avg = router->tq_avg;
-	}
-
-	if (router)
-		neigh_node_free_ref(router);
-
-	/* apply hop penalty */
-	batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv);
-
-	bat_dbg(DBG_BATMAN, bat_priv,
-		"Forwarding packet: tq_orig: %i, tq_avg: %i, "
-		"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
-		in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1,
-		batman_ogm_packet->ttl);
-
-	batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno);
-	batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc);
-
-	/* switch of primaries first hop flag when forwarding */
-	batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP;
-	if (directlink)
-		batman_ogm_packet->flags |= DIRECTLINK;
-	else
-		batman_ogm_packet->flags &= ~DIRECTLINK;
 
-	send_time = forward_send_time();
-	add_bat_packet_to_list(bat_priv,
-			       (unsigned char *)batman_ogm_packet,
-			       BATMAN_OGM_LEN + tt_len(tt_num_changes),
-			       if_incoming, 0, send_time);
+	bat_ogm_schedule(hard_iface, tt_num_changes);
 }
 
 static void forw_packet_free(struct forw_packet *forw_packet)
@@ -561,7 +302,7 @@ out:
 	atomic_inc(&bat_priv->bcast_queue_left);
 }
 
-void send_outstanding_bat_packet(struct work_struct *work)
+void send_outstanding_bat_ogm_packet(struct work_struct *work)
 {
 	struct delayed_work *delayed_work =
 		container_of(work, struct delayed_work, work);
@@ -577,7 +318,7 @@ void send_outstanding_bat_packet(struct work_struct *work)
 	if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
 		goto out;
 
-	send_packet(forw_packet);
+	bat_ogm_emit(forw_packet);
 
 	/**
 	 * we have to have at least one packet in the queue
@@ -585,7 +326,7 @@ void send_outstanding_bat_packet(struct work_struct *work)
 	 * shutting down
 	 */
 	if (forw_packet->own)
-		schedule_own_packet(forw_packet->if_incoming);
+		schedule_bat_ogm(forw_packet->if_incoming);
 
 out:
 	/* don't count own packet */
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 8a22d84..c8ca3ef 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -24,15 +24,10 @@
 
 int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
 		    const uint8_t *dst_addr);
-void schedule_own_packet(struct hard_iface *hard_iface);
-void schedule_forward_packet(struct orig_node *orig_node,
-			     const struct ethhdr *ethhdr,
-			     struct batman_ogm_packet *batman_ogm_packet,
-			     int directlink,
-			     struct hard_iface *if_outgoing);
+void schedule_bat_ogm(struct hard_iface *hard_iface);
 int add_bcast_packet_to_list(struct bat_priv *bat_priv,
 			     const struct sk_buff *skb, unsigned long delay);
-void send_outstanding_bat_packet(struct work_struct *work);
+void send_outstanding_bat_ogm_packet(struct work_struct *work);
 void purge_outstanding_packets(struct bat_priv *bat_priv,
 			       const struct hard_iface *hard_iface);
 
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 5/7] batman-adv: update README (date & ap isolation sysfs file)
From: Marek Lindner @ 2011-09-08 16:40 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner,
	Simon Wunderlich
In-Reply-To: <1315500051-1122-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

From: Simon Wunderlich <siwu-MaAgPAbsBIVS8oHt8HbXEIQuADTiUCJX@public.gmane.org>

Signed-off-by: Simon Wunderlich <siwu-MaAgPAbsBIVS8oHt8HbXEIQuADTiUCJX@public.gmane.org>
Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
---
 Documentation/networking/batman-adv.txt |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt
index 88d4afb..c86d03f 100644
--- a/Documentation/networking/batman-adv.txt
+++ b/Documentation/networking/batman-adv.txt
@@ -1,4 +1,4 @@
-[state: 17-04-2011]
+[state: 21-08-2011]
 
 BATMAN-ADV
 ----------
@@ -68,9 +68,9 @@ All  mesh  wide  settings  can be found in batman's own interface
 folder:
 
 #  ls  /sys/class/net/bat0/mesh/
-#  aggregated_ogms  gw_bandwidth  hop_penalty
-#  bonding          gw_mode       orig_interval
-#  fragmentation    gw_sel_class  vis_mode
+# aggregated_ogms   fragmentation gw_sel_class   vis_mode
+# ap_isolation      gw_bandwidth  hop_penalty
+# bonding           gw_mode       orig_interval
 
 
 There is a special folder for debugging information:
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 6/7] batman-adv: update internal version number
From: Marek Lindner @ 2011-09-08 16:40 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
In-Reply-To: <1315500051-1122-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

From: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>

Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
---
 net/batman-adv/main.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 60b3696..964ad4d 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -28,7 +28,7 @@
 #define DRIVER_DEVICE "batman-adv"
 
 #ifndef SOURCE_VERSION
-#define SOURCE_VERSION "2011.3.0"
+#define SOURCE_VERSION "2011.4.0"
 #endif
 
 /* B.A.T.M.A.N. parameters */
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 7/7] batman-adv: Remove unnecessary OOM logging messages
From: Marek Lindner @ 2011-09-08 16:40 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Joe Perches, netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
In-Reply-To: <1315500051-1122-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

From: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>

Removing unnecessary messages saves code and text.

Site specific OOM messages are duplications of a generic MM
out of memory message and aren't really useful, so just
delete them.

Signed-off-by: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
---
 net/batman-adv/hard-interface.c |    5 +----
 net/batman-adv/main.c           |    2 --
 net/batman-adv/originator.c     |   16 ++++------------
 net/batman-adv/soft-interface.c |    4 +---
 net/batman-adv/vis.c            |    4 +---
 5 files changed, 7 insertions(+), 24 deletions(-)

diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 0cc0f04..7704df4 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -434,11 +434,8 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
 	dev_hold(net_dev);
 
 	hard_iface = kmalloc(sizeof(*hard_iface), GFP_ATOMIC);
-	if (!hard_iface) {
-		pr_err("Can't add interface (%s): out of memory\n",
-		       net_dev->name);
+	if (!hard_iface)
 		goto release_dev;
-	}
 
 	ret = sysfs_add_hardif(&hard_iface->hardif_obj, net_dev);
 	if (ret)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 79b9ae5..fb87bdc 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -117,8 +117,6 @@ int mesh_init(struct net_device *soft_iface)
 	goto end;
 
 err:
-	pr_err("Unable to allocate memory for mesh information structures: "
-	       "out of mem ?\n");
 	mesh_free(soft_iface);
 	return -1;
 
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index cd7d256..0e5b772 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -492,10 +492,8 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
 
 	data_ptr = kmalloc(max_if_num * sizeof(unsigned long) * NUM_WORDS,
 			   GFP_ATOMIC);
-	if (!data_ptr) {
-		pr_err("Can't resize orig: out of memory\n");
+	if (!data_ptr)
 		return -1;
-	}
 
 	memcpy(data_ptr, orig_node->bcast_own,
 	       (max_if_num - 1) * sizeof(unsigned long) * NUM_WORDS);
@@ -503,10 +501,8 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
 	orig_node->bcast_own = data_ptr;
 
 	data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
-	if (!data_ptr) {
-		pr_err("Can't resize orig: out of memory\n");
+	if (!data_ptr)
 		return -1;
-	}
 
 	memcpy(data_ptr, orig_node->bcast_own_sum,
 	       (max_if_num - 1) * sizeof(uint8_t));
@@ -561,10 +557,8 @@ static int orig_node_del_if(struct orig_node *orig_node,
 
 	chunk_size = sizeof(unsigned long) * NUM_WORDS;
 	data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
-	if (!data_ptr) {
-		pr_err("Can't resize orig: out of memory\n");
+	if (!data_ptr)
 		return -1;
-	}
 
 	/* copy first part */
 	memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size);
@@ -582,10 +576,8 @@ free_bcast_own:
 		goto free_own_sum;
 
 	data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
-	if (!data_ptr) {
-		pr_err("Can't resize orig: out of memory\n");
+	if (!data_ptr)
 		return -1;
-	}
 
 	memcpy(data_ptr, orig_node->bcast_own_sum,
 	       del_if_num * sizeof(uint8_t));
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 7d8332e..aceeabc 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -801,10 +801,8 @@ struct net_device *softif_create(const char *name)
 
 	soft_iface = alloc_netdev(sizeof(*bat_priv), name, interface_setup);
 
-	if (!soft_iface) {
-		pr_err("Unable to allocate the batman interface: %s\n", name);
+	if (!soft_iface)
 		goto out;
-	}
 
 	ret = register_netdevice(soft_iface);
 	if (ret < 0) {
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index fb9b19f..f81a6b6 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -887,10 +887,8 @@ int vis_init(struct bat_priv *bat_priv)
 	}
 
 	bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
-	if (!bat_priv->my_vis_info) {
-		pr_err("Can't initialize vis packet\n");
+	if (!bat_priv->my_vis_info)
 		goto err;
-	}
 
 	bat_priv->my_vis_info->skb_packet = dev_alloc_skb(sizeof(*packet) +
 							  MAX_VIS_PACKET_SIZE +
-- 
1.7.5.4

^ permalink raw reply related

* Re: pull request: batman-adv 2011-09-08
From: Marek Lindner @ 2011-09-08 17:31 UTC (permalink / raw)
  To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1315500051-1122-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

On Thursday, September 08, 2011 18:40:44 Marek Lindner wrote:
> here comes the next batch batch I'd like to get the pulled into 
> net-next-2.6/3.2. These patches mainly focus restructering the 
> routing code in order to allow the kernel module the handling
> of the current routing algorithm and the upcoming one. 
> 
> To ensure a smooth transition and efficient testing later, we 
> decided to offer a choice of routing algorithm but have not     
> come to a final decision on how to design this choice yet. It
> either will be a compile time option, a module parameter or a
> runtime switch. Any suggestions / best practice tips ?
> 
> Note: The new algorithm has been designed with backward 
> compatibility in mind (using TLVs). We are trying to address
> the incompatibility issue you and others have pointed out.

Forgot to mention: We are well aware of the difficulties after 
the kernel.org intrusion. If you can't pull our patches right
now, feel free to do it whenever kernel.org is back online.

Regards,
Marek

^ permalink raw reply

* Re: [net-next-2.6 PATCH 0/3 RFC] macvlan: MAC Address filtering support for passthru mode
From: Sridhar Samudrala @ 2011-09-08 17:42 UTC (permalink / raw)
  To: Roopa Prabhu
  Cc: Michael S. Tsirkin, netdev, dragos.tatulea, arnd, dwang2, benve,
	kaber, davem, eric.dumazet, mchan, kvm
In-Reply-To: <CA8E3924.33B60%roprabhu@cisco.com>

On Thu, 2011-09-08 at 09:19 -0700, Roopa Prabhu wrote:
> 
> 
> On 9/8/11 4:08 AM, "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Sep 07, 2011 at 10:20:28PM -0700, Roopa Prabhu wrote:
> >> On 9/7/11 5:34 AM, "Michael S. Tsirkin" <mst@redhat.com> wrote:
> >> 
> >>> On Tue, Sep 06, 2011 at 03:35:40PM -0700, Roopa Prabhu wrote:
> >>>> This patch is an attempt at providing address filtering support for macvtap
> >>>> devices in PASSTHRU mode. Its still a work in progress.
> >>>> Briefly tested for basic functionality. Wanted to get some feedback on the
> >>>> direction before proceeding.
> >>>> 
> >>> 
> >>> Good work, thanks.
> >>> 
> >> 
> >> Thanks.
> >> 
> >>>> I have hopefully CC'ed all concerned people.
> >>> 
> >>> kvm crowd might also be interested.
> >>> Try using ./scripts/get_maintainer.pl as well.
> >>> 
> >> Thanks for the tip. Expanded CC list a bit more.
> >> 
> >>>> PASSTHRU mode today sets the lowerdev in promiscous mode. In PASSTHRU mode
> >>>> there is a 1-1 mapping between macvtap device and physical nic or VF. And
> >>>> all
> >>>> filtering is done in lowerdev hw. The lowerdev does not need to be in
> >>>> promiscous mode as long as the guest filters are passed down to the
> >>>> lowerdev.
> >>>> This patch tries to remove the need for putting the lowerdev in promiscous
> >>>> mode. 
> >>>> I have also referred to the thread below where TUNSETTXFILTER was mentioned
> >>>> in 
> >>>> this context: 
> >>>>  http://patchwork.ozlabs.org/patch/69297/
> >>>> 
> >>>> This patch basically passes the addresses got by TUNSETTXFILTER to macvlan
> >>>> lowerdev.
> >>>> 
> >>>> I have looked at previous work and discussions on this for qemu-kvm
> >>>> by Michael Tsirkin, Alex Williamson and Dragos Tatulea
> >>>> http://patchwork.ozlabs.org/patch/78595/
> >>>> http://patchwork.ozlabs.org/patch/47160/
> >>>> https://patchwork.kernel.org/patch/474481/
> >>>> 
> >>>> Redhat bugzilla by Michael Tsirkin:
> >>>> https://bugzilla.redhat.com/show_bug.cgi?id=655013
> >>>> 
> >>>> I used Michael's qemu-kvm patch for testing the changes with KVM
> >>>> 
> >>>> I would like to cover both MAC and vlan filtering in this work.
> >>>> 
> >>>> Open Questions/Issues:
> >>>> - There is a need for vlan filtering to complete the patch. It will require
> >>>>   a new tap ioctl cmd for vlans.
> >>>>   Some ideas on this are:
> >>>> 
> >>>>   a) TUNSETVLANFILTER: This will entail we send the whole vlan bitmap
> >>>> filter
> >>>> (similar to tun_filter for addresses). Passing the vlan id's to lower
> >>>> device will mean going thru the whole list of vlans every time.
> >>>> 
> >>>>   OR
> >>>> 
> >>>>   b) TUNSETVLAN with vlan id and flag to set/unset
> >>>> 
> >>>>   Does option 'b' sound ok ?
> >>>> 
> >>>> - In this implementation we make the macvlan address list same as the
> >>>> address
> >>>>   list that came in the filter with TUNSETTXFILTER. This will not cover
> >>>> cases
> >>>>   where the macvlan device needs to have other addresses that are not
> >>>>   necessarily in the filter. Is this a problem ?
> >>> 
> >>> What cases do you have in mind?
> >>> 
> >> This patch targets only macvlan PASSTHRU mode and for PASSTHRU mode I don't
> >> see a problem with uc/mc address list being the same in all the stacked
> >> netdevs in the path. I called that out above to make sure I was not missing
> >> any case in PASSTHRU mode where this might be invalid. Otherwise I don't see
> >> a problem in the simple PASSTHRU use case this patch supports.
> >> 
> >>>> - The patch currently only supports passing of IFF_PROMISC and
> >>>> IFF_MULTICAST
> >>>> filter flags to lowerdev
> >>>> 
> >>>> This patch series implements the following
> >>>> 01/3 - macvlan: Add support for unicast filtering in macvlan
> >>>> 02/3 - macvlan: Add function to set addr filter on lower device in passthru
> >>>> mode
> >>>> 03/3 - macvtap: Add support for TUNSETTXFILTER
> >>>> 
> >>>> Please comment. Thanks.
> >>>> 
> >>>> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
> >>>> Signed-off-by: Christian Benvenuti <benve@cisco.com>
> >>>> Signed-off-by: David Wang <dwang2@cisco.com>
> >>> 
> >>> The security isn't lower than with promisc, so I don't see
> >>> a problem with this as such.
> >>> 
> >>> There are more features we'll want down the road though,
> >>> so let's see whether the interface will be able to
> >>> satisfy them in a backwards compatible way before we
> >>> set it in stone. Here's what I came up with:
> >>> 
> >>> How will the filtering table be partitioned within guests?
> >> 
> >> Since this patch supports macvlan PASSTHRU mode only, in which the lower
> >> device has 1-1 mapping to the guest nic, it does not require any
> >> partitioning of filtering table within guests. Unless I missed understanding
> >> something. 
> >> If the lower device were being shared by multiple guest network interfaces
> >> (non PASSTHRU mode), only then we will need to maintain separate filter
> >> tables for each guest network interface in macvlan and forward the pkt to
> >> respective guest interface after a filter lookup. This could affect
> >> performance too I think.
> > 
> > Not with hardware filtering support. Which is where we'd need to
> > partition the host nic mac table between guests.
> > 
> I need to understand this more. In non passthru case when a VF or physical
> nic is shared between guests, the nic does not really know about the guests,
> so I was thinking we do the same thing as we do for the passthru case (ie
> send all the address filters from macvlan to the physical nic). So at the
> hardware, filtering is done for all guests sharing the nic. But if we want
> each virtio-net nic or guest to get exactly what it asked for
> macvlan/macvtap needs to maintain a copy of each guest filter and do a
> lookup and send only the requested traffic to the guest. Here is the
> performance hit that I was seeing. Please see my next comment for further
> details. 
> 
> 
> >> I chose to support PASSTHRU Mode only at first because its simpler and all
> >> code additions are in control path only.
> > 
> > I agree. It would be a bit silly to have a dedicated interface
> > for passthough and a completely separate one for
> > non passthrough.
> >
> Agree. The reason I did not focus on non-passthru case in the initial
> version was because I was thinking things to do in the non-passthru case
> will be just add-ons to the passthru case. But true Better to flush out the
> non-pasthru case details.
> 
> After dwelling on this a bit more how about the below:
> 
> Phase 1: Goal: Enable hardware filtering for all macvlan modes
>     - In macvlan passthru mode the single guest virtio-nic connected will
> receive traffic that he requested for
Currently the guest receives all the packets seen on the interface as it
is put in promiscuous mode. With your patch it only sees the packets
that he requested for. Have you tried creating a macvlan interface on
top of the guest virtio-net interface? Is the new mac address propagated
all the way to the host nic?

I think the main usecase for passthru mode is to assign a SR-IOV VF to
a single guest.

>     - In macvlan non-passthru mode all guest virtio-nics sharing the
>       physical nic will see all other guest traffic
>       but the filtering at guest virtio-nic will make sure each guest
>       eventually sees traffic he asked for. This is still better than
> putting the physical nic in promiscuous mode.

With the default macvlan mode (vepa), i think each guest will only see
its own traffic. But currently adding a secondary mac address on a guest
will not work as it is not propagated all the way down to the host.


> (This is mainly what my patch does...but will need to remove the passthru
> check and see if there are any thing else needed for non-passthru case)
> 
> 
> Phase 2: Goal: Enable filtering at macvlan so that each guest virtio-nic
> receives only what he requested for.
>     - In this case, in addition to pushing the filters down to the physical
> nic we will have to maintain the same filter in macvlan and do a filter
> lookup before forwarding the traffic to a virtio-nic.
> 
> But I am thinking phase 2 might be redundant given virtio-nic already does
> filtering for the guest. In which case we might not need phase 2 at all. I
> might have been over complicating things.

I think filtering at macvlan will be more efficient than replicating all
the packets to all the guest virtio-nics.

Thanks
Sridhar


^ permalink raw reply

* Re: [PATCH v2 9/9] Add documentation about kmem_cgroup
From: Randy Dunlap @ 2011-09-08 17:46 UTC (permalink / raw)
  To: Glauber Costa
  Cc: linux-kernel, linux-mm, containers, netdev, xemul,
	David S. Miller, Hiroyouki Kamezawa, Eric W. Biederman
In-Reply-To: <1315369399-3073-10-git-send-email-glommer@parallels.com>

On 09/06/11 21:23, Glauber Costa wrote:
> Signed-off-by: Glauber Costa <glommer@parallels.com>
> CC: David S. Miller <davem@davemloft.net>
> CC: Hiroyouki Kamezawa <kamezawa.hiroyu@jp.fujitsu.com>
> CC: Eric W. Biederman <ebiederm@xmission.com>
> CC: Randy Dunlap <rdunlap@xenotime.net>
> ---
>  Documentation/cgroups/kmem_cgroups.txt |   27 +++++++++++++++++++++++++++
>  1 files changed, 27 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/cgroups/kmem_cgroups.txt
> 
> diff --git a/Documentation/cgroups/kmem_cgroups.txt b/Documentation/cgroups/kmem_cgroups.txt
> new file mode 100644
> index 0000000..930e069
> --- /dev/null
> +++ b/Documentation/cgroups/kmem_cgroups.txt
> @@ -0,0 +1,27 @@
> +Kernel Memory Cgroup
> +====================
> +
> +This document briefly describes the kernel memory cgroup, or "kmem cgroup".
> +Unlike user memory, kernel memory cannot be swapped. This effectively means
> +that rogue processes can start operations that pin kernel objects permanently
> +into memory, exhausting resources of all other processes in the system.
> +
> +kmem_cgroup main goal is to control the amount of memory a group of processes

   kmem_cgroup's main goal

> +can pin at any given point in time. Other uses of this infrastructure are
> +expected to come up with time. Right now, the only resource effectively limited

                                                      resources

> +are tcp send and receive buffers.

or:
                                             the only resource effectively limited
  is TCP network buffers.

> +
> +TCP network buffers
> +===================
> +
> +TCP network buffers, both on the send and receive sides, can be controlled
> +by the kmem cgroup. Once a socket is created, it is attached to the cgroup of
> +the controller process, where it stays until the end of its lifetime.
> +
> +Files
> +=====
> +	kmem.tcp_maxmem: control the maximum amount in bytes that can be used by

	                 controls the maximum amount of memory in bytes ...


> +	tcp sockets inside the cgroup. 
> +
> +	kmem.tcp_current_memory: current amount in bytes used by all sockets in

	                         current amount of memory in bytes ...

> +	this cgroup


-- 
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

--
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: [PATCH 08/11] netlink: implement memory mapped sendmsg()
From: Michał Mirosław @ 2011-09-08 18:08 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: davem, netfilter-devel, netdev
In-Reply-To: <4E688BD5.5030909@trash.net>

On Thu, Sep 08, 2011 at 11:33:09AM +0200, Patrick McHardy wrote:
> Am 07.09.2011 22:03, schrieb Michał Mirosław:
> > On Wed, Sep 07, 2011 at 05:22:00PM +0200, Patrick McHardy wrote:
> >> On 04.09.2011 18:18, Michał Mirosław wrote:
> >>> On Sat, Sep 03, 2011 at 07:26:08PM +0200, kaber@trash.net wrote:
> >>>> From: Patrick McHardy <kaber@trash.net>
> >>>>
> >>>> Add support for memory mapped sendmsg() to netlink. Userspace queued to
> >>>> be processed frames into the TX ring and invokes sendmsg with
> >>>> msg.iov.iov_base = NULL to trigger processing of all pending messages.
> >>>>
> >>>> Since the kernel usually performs full message validation before beginning
> >>>> processing, userspace must be prevented from modifying the message
> >>>> contents while the kernel is processing them. In order to do so, the
> >>>> frames contents are copied to an allocated skb in case the the ring is
> >>>> mapped more than once or the file descriptor is shared (f.i. through
> >>>> AF_UNIX file descriptor passing).
> >>>>
> >>>> Otherwise an skb without a data area is allocated, the data pointer set
> >>>> to point to the data area of the ring frame and the skb is processed.
> >>>> Once the skb is freed, the destructor releases the frame back to userspace
> >>>> by setting the status to NL_MMAP_STATUS_UNUSED.
> >>>
> >>> Is this protected from threads? Like: one thread waits on sendmsg() and
> >>> another (same process) changes the buffer.
> >> Yes, if the ring is mapped multiple times (or the file descriptor
> >> is changed), the contents are copied to an allocated skb.
> > 
> > I mean:
> > 
> > [1] mmap()
> > [1] fill buffers
> > [1] pthread_create() [creates: 2]
> > [1] sendmsg() starts
> > [2] modify buffers
> > [1] sendmsg() returns
> > 
> > So: no multiple mmaps, and no touching of the fd. I haven't dug into
> > filesystem layer to see if threads affect file->f_count, but there
> > sure are no multiple mappings here.
> If CLONE_VM is given to clone(), the mapping is visible in both
> threads and thus we have multiple mappings (vma_ops->open() is
> invoked through clone()). Without CLONE_VM, the second thread
> can't access the ring unless it mmap()s it itself, in case we'd
> also have multiple mappings.

I made a quick look into kernel/fork.c, and it looks to me that if CLONE_VM
is set, then vma->open() is actually avoided --- it's called via dup_mm()
and dup_mmap() only if CLONE_VM is not there and the VMA needs to be copied.

Best Regards,
Michał Mirosław
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v3] net/smsc911x: add device tree probe support
From: Grant Likely @ 2011-09-08 18:29 UTC (permalink / raw)
  To: Dave Martin
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Steve Glendinning,
	David S. Miller,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20110908145946.GE2070-5wv7dgnIgG8@public.gmane.org>

On Thu, Sep 08, 2011 at 03:59:46PM +0100, Dave Martin wrote:
> Hi Shawn,
> 
> On Sun, Jul 31, 2011 at 02:26:00AM +0800, Shawn Guo wrote:
> > It adds device tree probe support for smsc911x driver.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > Cc: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
> > Cc: Steve Glendinning <steve.glendinning-sdUf+H5yV5I@public.gmane.org>
> > Cc: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> > Reviewed-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
> > ---
> > Changes since v2:
> >  * Fix a typo in smsc911x.txt
> > 
> > Changes since v1:
> >  * Instead of getting irq line from gpio number, it use irq domain
> >    to keep platform_get_resource(IORESOURCE_IRQ) works for dt too.
> >  * Use 'lan9115' the first model that smsc911x supports in the match
> >    table
> >  * Use reg-shift and reg-io-width which already used in of_serial for
> >    shift and access size binding
> 
> When using this patch with vexpress, I found that 16-bit register access
> mode doesn't seem to be getting set correctly.
> 
> Can you take a look at this additional patch and let me know if it looks
> correct?
> 
> Cheers
> ---Dave
> 
> From: Dave Martin <dave.martin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Date: Wed, 7 Sep 2011 17:26:31 +0100
> Subject: [PATCH] net/smsc911x: Correctly configure 16-bit register access from DT
> 
> The SMSC911X_USE_16BIT needs to be set when using 16-bit register
> access.  However, currently no flag is set if the DT doesn't specify
> 32-bit access.
> 
> This patch should set the SMSC911X_USE_16BIT flag in a manner consistent
> with the documented DT bindings.
> 
> Signed-off-by: Dave Martin <dave.martin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  drivers/net/smsc911x.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
> index 75c08a5..1a35c25 100644
> --- a/drivers/net/smsc911x.c
> +++ b/drivers/net/smsc911x.c
> @@ -2121,6 +2121,8 @@ static int __devinit smsc911x_probe_config_dt(
>  	of_property_read_u32(np, "reg-io-width", &width);
>  	if (width == 4)
>  		config->flags |= SMSC911X_USE_32BIT;
> +	else
> +		config->flags |= SMSC911X_USE_16BIT;

Would it be better to do "else if (width == 2)"?  (completely
uninformed comment.  I've not looked at what the non-DT probe path
does on this driver.)

g.

^ permalink raw reply


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