[git] linux integration annotated tag, v2.6.36-rc3, created. v2.6.36-rc3
by postmaster@open-mesh.net
The annotated tag, v2.6.36-rc3 has been created
at 40f7ec041a61c6b6d419e418818c79f7c23a1007 (tag)
tagging 2bfc96a127bc1cc94d26bfaa40159966064f9c8c (commit)
replaces v2.6.36-rc2
tagged by Linus Torvalds
on Sun Aug 29 08:36:18 2010 -0700
- Shortlog ------------------------------------------------------------
Linux 2.6.36-rc3
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iEYEABECAAYFAkx6fncACgkQF3YsRnbiHLuq5ACfSOoCBvpMoNPl4Zbcx/aLs86V
7wsAnRV0q6sHiPY94VasJTpGSJp371as
=MKVZ
-----END PGP SIGNATURE-----
Marek Lindner (4):
Staging: batman-adv: unify orig_hash_lock spinlock handling to avoid deadlocks
Staging: batman-adv: fix batman icmp originating from secondary interface
Staging: batman-adv: always reply batman icmp packets with primary mac
Staging: batman-adv: fix own mac address detection
Sven Eckelmann (4):
Staging: batman-adv: Fix merge of linus tree
Staging: batman-adv: Create batman_if only on register event
Staging: batman-adv: Don't use net_dev after dev_put
Staging: batman-adv: Don't write in not allocated packet_buff
-----------------------------------------------------------------------
--
linux integration
12 years, 5 months
r1780 - trunk/batman-adv
by postmaster@open-mesh.org
Author: marek
Date: 2010-08-29 02:02:14 +0200 (Sun, 29 Aug 2010)
New Revision: 1780
Modified:
trunk/batman-adv/hard-interface.c
Log:
batman-adv: Don't rely on NF_HOOKs return value
If a hook returns NF_STOLEN, neither batman_skb_recv nor
batman_skb_recv_finish free the skb due to the asynchronous netfilter
handling in the kernel. Therefore not batman_skb_recv but the ok
function batman_skb_recv_finish should do the freeing when a recv
subfunction returns NET_RX_DROP instead.
Reported-by: Vasiliy Kulikov <segooon(a)gmail.com>
Signed-off-by: Linus L?\195?\188ssing <linus.luessing(a)web.de>
Modified: trunk/batman-adv/hard-interface.c
===================================================================
--- trunk/batman-adv/hard-interface.c 2010-08-29 00:02:13 UTC (rev 1779)
+++ trunk/batman-adv/hard-interface.c 2010-08-29 00:02:14 UTC (rev 1780)
@@ -497,56 +497,27 @@
static int batman_skb_recv_finish(struct sk_buff *skb)
{
- return NF_ACCEPT;
-}
-
-/* receive a packet with the batman ethertype coming on a hard
- * interface */
-int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *ptype, struct net_device *orig_dev)
-{
- struct bat_priv *bat_priv;
struct batman_packet *batman_packet;
struct batman_if *batman_if;
+ struct bat_priv *bat_priv;
int ret;
- batman_if = container_of(ptype, struct batman_if, batman_adv_ptype);
- skb = skb_share_check(skb, GFP_ATOMIC);
-
- /* skb was released by skb_share_check() */
- if (!skb)
- goto err_out;
-
- /* if netfilter/ebtables wants to block incoming batman
- * packets then give them a chance to do so here */
- ret = NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev, NULL,
- batman_skb_recv_finish);
- if (ret != 1)
- goto err_out;
-
- /* packet should hold at least type and version */
- if (unlikely(!pskb_may_pull(skb, 2)))
+ batman_if = get_batman_if_by_netdev(skb->dev);
+ if (!batman_if)
goto err_free;
- /* expect a valid ethernet header here. */
- if (unlikely(skb->mac_len != sizeof(struct ethhdr)
- || !skb_mac_header(skb)))
+ if (!batman_if->soft_iface)
goto err_free;
- if (!batman_if->soft_iface)
+ /* discard frames on not active interfaces */
+ if (batman_if->if_status != IF_ACTIVE)
goto err_free;
bat_priv = netdev_priv(batman_if->soft_iface);
-
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto err_free;
- /* discard frames on not active interfaces */
- if (batman_if->if_status != IF_ACTIVE)
- goto err_free;
-
batman_packet = (struct batman_packet *)skb->data;
-
if (batman_packet->version != COMPAT_VERSION) {
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: incompatible batman version (%i)\n",
@@ -592,18 +563,42 @@
}
if (ret == NET_RX_DROP)
- kfree_skb(skb);
+ goto err_free;
- /* return NET_RX_SUCCESS in any case as we
- * most probably dropped the packet for
- * routing-logical reasons. */
+ return 0;
- return NET_RX_SUCCESS;
+err_free:
+ kfree_skb(skb);
+ return 0;
+}
+/* receive a packet with the batman ethertype coming on a hard
+ * interface */
+int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *ptype, struct net_device *orig_dev)
+{
+ skb = skb_share_check(skb, GFP_ATOMIC);
+
+ /* skb was released by skb_share_check() */
+ if (!skb)
+ return 0;
+
+ /* packet should hold at least type and version */
+ if (unlikely(!pskb_may_pull(skb, 2)))
+ goto err_free;
+
+ /* expect a valid ethernet header here. */
+ if (unlikely(skb->mac_len != sizeof(struct ethhdr) ||
+ !skb_mac_header(skb)))
+ goto err_free;
+
+ /* if netfilter/ebtables wants to block incoming batman
+ * packets then give them a chance to do so here */
+ return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev,
+ NULL, batman_skb_recv_finish);
err_free:
kfree_skb(skb);
-err_out:
- return NET_RX_DROP;
+ return 0;
}
struct notifier_block hard_if_notifier = {
12 years, 5 months
r1779 - trunk/batman-adv
by postmaster@open-mesh.org
Author: marek
Date: 2010-08-29 02:02:13 +0200 (Sun, 29 Aug 2010)
New Revision: 1779
Modified:
trunk/batman-adv/bat_sysfs.c
trunk/batman-adv/hard-interface.c
trunk/batman-adv/soft-interface.c
Log:
batman-adv: Don't call unregister_netdev with locked rtnl semaphore
We currently try to call unregister_netdev when we can destroy a softif
after all corresponding hard-interfaces announced that they will be
removed.
This will be done when we receive a hard_if_event which already takes
the rtnl semaphore and thus we try to get it again in unregister_netdev.
This results in a deadlock. This call to unregister_netdev cannot easily
replaced by unregister_netdevice, because other parts of the batman-adv
module still call that code indirectly without holding the rtnl
semaphore.
(needs rtln_unlocked)
unregister_netdev
^
|
softif_destroy
^
|
hardif_disable_interface
^ ^
/ |
store_mesh_iface hardif_remove_interface
(rtln_unlocked) ^ ^
| \
hardif_remove_interfaces hard_if_event
^ (rtln_locked)
|
batman_exit
(rtln_unlocked)
A consistent workaround is to change store_mesh_iface and
hardif_remove_interfaces to call rtnl_lock before they call the
mentioned child function, release the semaphore afterwards and change
unregister_netdev in softif_destroy to unregister_netdevice.
Reported-by: Kazuki Shimada <zukky(a)bb.banban.jp>
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
Modified: trunk/batman-adv/bat_sysfs.c
===================================================================
--- trunk/batman-adv/bat_sysfs.c 2010-08-23 17:45:22 UTC (rev 1778)
+++ trunk/batman-adv/bat_sysfs.c 2010-08-29 00:02:13 UTC (rev 1779)
@@ -492,13 +492,18 @@
return count;
if (status_tmp == IF_NOT_IN_USE) {
+ rtnl_lock();
hardif_disable_interface(batman_if);
+ rtnl_unlock();
return count;
}
/* if the interface already is in use */
- if (batman_if->if_status != IF_NOT_IN_USE)
+ if (batman_if->if_status != IF_NOT_IN_USE) {
+ rtnl_lock();
hardif_disable_interface(batman_if);
+ rtnl_unlock();
+ }
return hardif_enable_interface(batman_if, buff);
}
Modified: trunk/batman-adv/hard-interface.c
===================================================================
--- trunk/batman-adv/hard-interface.c 2010-08-23 17:45:22 UTC (rev 1778)
+++ trunk/batman-adv/hard-interface.c 2010-08-29 00:02:13 UTC (rev 1779)
@@ -441,8 +441,11 @@
{
struct batman_if *batman_if, *batman_if_tmp;
- list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list)
+ list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
+ rtnl_lock();
hardif_remove_interface(batman_if);
+ rtnl_unlock();
+ }
}
static int hard_if_event(struct notifier_block *this,
Modified: trunk/batman-adv/soft-interface.c
===================================================================
--- trunk/batman-adv/soft-interface.c 2010-08-23 17:45:22 UTC (rev 1778)
+++ trunk/batman-adv/soft-interface.c 2010-08-29 00:02:13 UTC (rev 1779)
@@ -351,7 +351,7 @@
debugfs_del_meshif(soft_iface);
sysfs_del_meshif(soft_iface);
mesh_free(soft_iface);
- unregister_netdev(soft_iface);
+ unregister_netdevice(soft_iface);
}
/* ethtool */
12 years, 5 months
[git] linux integration annotated tag, v2.6.36-rc2, created. v2.6.36-rc2
by postmaster@open-mesh.net
The annotated tag, v2.6.36-rc2 has been created
at 58d3707b8891f71d4891e6b36129eeacd3ba63f4 (tag)
tagging 76be97c1fc945db08aae1f1b746012662d643e97 (commit)
replaces v2.6.36-rc1
tagged by Linus Torvalds
on Sun Aug 22 17:45:36 2010 -0700
- Shortlog ------------------------------------------------------------
Linux 2.6.36-rc2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
iEYEABECAAYFAkxxxL4ACgkQF3YsRnbiHLtdAACfX4fbXLdqw7VCtMEfkJhPsxg2
QjUAnjXacm+jqBMiIYgmLqY8LLNlN1W/
=moxk
-----END PGP SIGNATURE-----
-----------------------------------------------------------------------
--
linux integration
12 years, 5 months
r1778 - trunk/batctl
by postmaster@open-mesh.org
Author: marek
Date: 2010-08-23 19:45:22 +0200 (Mon, 23 Aug 2010)
New Revision: 1778
Modified:
trunk/batctl/traceroute.c
Log:
batctl: traceroute - use all received packets to retrieve neighbor mac
Traceroute used the first packet to extract the mac address of a neighbor.
If the first packet was lost the mac address could not be retrieved
although the following 2 packets also contain it.
This patch uses the first received packet to extract the mac. If the
first packet is lost it uses the second or third.
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
Modified: trunk/batctl/traceroute.c
===================================================================
--- trunk/batctl/traceroute.c 2010-08-22 18:46:27 UTC (rev 1777)
+++ trunk/batctl/traceroute.c 2010-08-23 17:45:22 UTC (rev 1778)
@@ -38,6 +38,7 @@
#define TTL_MAX 50
+#define NUM_PACKETS 3
void traceroute_usage(void)
@@ -59,7 +60,7 @@
char *dst_string, *mac_string, *return_mac, dst_reached = 0;
int ret = EXIT_FAILURE, res, trace_fd = 0, i;
int found_args = 1, optchar, seq_counter = 0, read_opt = USE_BAT_HOSTS;
- double time_delta;
+ double time_delta[NUM_PACKETS];
char *debugfs_mnt;
char icmp_socket[MAX_PATH+1];
@@ -129,8 +130,10 @@
dst_string, mac_string, TTL_MAX, sizeof(icmp_packet_out));
for (icmp_packet_out.ttl = 1; !dst_reached && icmp_packet_out.ttl < TTL_MAX; icmp_packet_out.ttl++) {
+ return_mac = NULL;
+ bat_host = NULL;
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < NUM_PACKETS; i++) {
icmp_packet_out.seqno = htons(++seq_counter);
if (write(trace_fd, (char *)&icmp_packet_out, sizeof(icmp_packet_out)) < 0) {
@@ -149,11 +152,7 @@
res = select(trace_fd + 1, &read_socket, NULL, NULL, &tv);
if (res <= 0) {
- if (i == 0)
- printf("%2hu: ", icmp_packet_out.ttl);
-
- printf(" * ");
- fflush(stdout);
+ time_delta[i] = 0.0;
continue;
}
@@ -172,34 +171,22 @@
switch (icmp_packet_in.msg_type) {
case ECHO_REPLY:
+ dst_reached = 1;
+ /* fall through */
case TTL_EXCEEDED:
- time_delta = end_timer();
+ time_delta[i] = end_timer();
- if (i > 0) {
- printf(" %.3f ms", time_delta);
- break;
+ if (!return_mac) {
+ return_mac = ether_ntoa_long((struct ether_addr *)&icmp_packet_in.orig);
+
+ if (read_opt & USE_BAT_HOSTS)
+ bat_host = bat_hosts_find_by_mac((char *)&icmp_packet_in.orig);
}
- return_mac = ether_ntoa_long((struct ether_addr *)&icmp_packet_in.orig);
-
- bat_host = NULL;
- if (read_opt & USE_BAT_HOSTS)
- bat_host = bat_hosts_find_by_mac((char *)&icmp_packet_in.orig);
-
- if (!bat_host)
- printf("%2hu: %s %.3f ms",
- icmp_packet_out.ttl, return_mac, time_delta);
- else
- printf("%2hu: %s (%s) %.3f ms",
- icmp_packet_out.ttl, bat_host->name, return_mac, time_delta);
-
- if (icmp_packet_in.msg_type == ECHO_REPLY)
- dst_reached = 1;
-
break;
case DESTINATION_UNREACHABLE:
printf("%s: Destination Host Unreachable\n", dst_string);
- break;
+ goto out;
case PARAMETER_PROBLEM:
printf("Error - the batman adv kernel module version (%d) differs from ours (%d)\n",
icmp_packet_in.ttl, COMPAT_VERSION);
@@ -211,6 +198,18 @@
}
}
+ if (!bat_host)
+ printf("%2hu: %s", icmp_packet_out.ttl, (return_mac ? return_mac : "*"));
+ else
+ printf("%2hu: %s (%s)", icmp_packet_out.ttl, bat_host->name, return_mac);
+
+ for (i = 0; i < NUM_PACKETS; i++) {
+ if (time_delta[i])
+ printf(" %.3f ms", time_delta[i]);
+ else
+ printf(" *");
+ }
+
printf("\n");
}
12 years, 5 months
r1777 - trunk/batman-adv
by postmaster@open-mesh.org
Author: simon
Date: 2010-08-22 20:46:27 +0200 (Sun, 22 Aug 2010)
New Revision: 1777
Modified:
trunk/batman-adv/soft-interface.c
Log:
batman-adv: Count Ethernet header for incoming packets
The Ethernet header is counted when transmitting a packet, so it should also
be counted when receiving a packet. With this patch, the rx_bytes and tx_bytes
statistics behave like an ordinary Ethernet interface.
Signed-off-by: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
Modified: trunk/batman-adv/soft-interface.c
===================================================================
--- trunk/batman-adv/soft-interface.c 2010-08-20 20:42:22 UTC (rev 1776)
+++ trunk/batman-adv/soft-interface.c 2010-08-22 18:46:27 UTC (rev 1777)
@@ -222,7 +222,7 @@
* PACKET_OTHERHOST or PACKET_HOST */
priv->stats.rx_packets++;
- priv->stats.rx_bytes += skb->len;
+ priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
soft_iface->last_rx = jiffies;
12 years, 5 months
[git] linux integration tag, GregKH-20100821, created. v2.6.36-rc1-459-g7fb26b6
by postmaster@open-mesh.net
The tag, GregKH-20100821 has been created
at 7fb26b6de8848c84a8064941e2cd3287a616b2fb (commit)
- Shortlog ------------------------------------------------------------
commit 7fb26b6de8848c84a8064941e2cd3287a616b2fb
Merge: e2ce755 e3a0cc9
Author: Sven Eckelmann <sven.eckelmann(a)gmx.de>
Date: Sat Aug 21 13:34:27 2010 +0200
Merge remote branch 'origin/next' into linux
-----------------------------------------------------------------------
--
linux integration
12 years, 5 months
[git] linux integration branch, linux, updated. v2.6.36-rc1-459-g7fb26b6
by postmaster@open-mesh.net
The following commit has been merged in the linux branch:
commit 7fb26b6de8848c84a8064941e2cd3287a616b2fb
Merge: e2ce75583a9ad51ec915e99206a8b39d9d36c5db e3a0cc90940915dd14e4ca6bdab6d74bbc60f4a4
Author: Sven Eckelmann <sven.eckelmann(a)gmx.de>
Date: Sat Aug 21 13:34:27 2010 +0200
Merge remote branch 'origin/next' into linux
diff --combined drivers/staging/batman-adv/hard-interface.c
index f6345c4,0000000..baa8b05
mode 100644,000000..100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@@ -1,538 -1,0 +1,541 @@@
+/*
+ * Copyright (C) 2007-2010 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 "hard-interface.h"
+#include "soft-interface.h"
+#include "send.h"
+#include "translation-table.h"
+#include "routing.h"
+#include "bat_sysfs.h"
+#include "originator.h"
+#include "hash.h"
+
+#include <linux/if_arp.h>
+#include <linux/netfilter_bridge.h>
+
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev)
+{
+ struct batman_if *batman_if;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->net_dev == net_dev)
+ goto out;
+ }
+
+ batman_if = NULL;
+
+out:
+ rcu_read_unlock();
+ return batman_if;
+}
+
+static int is_valid_iface(struct net_device *net_dev)
+{
+ if (net_dev->flags & IFF_LOOPBACK)
+ return 0;
+
+ if (net_dev->type != ARPHRD_ETHER)
+ return 0;
+
+ if (net_dev->addr_len != ETH_ALEN)
+ return 0;
+
+ /* no batman over batman */
+#ifdef HAVE_NET_DEVICE_OPS
+ if (net_dev->netdev_ops->ndo_start_xmit == interface_tx)
+ return 0;
+#else
+ if (net_dev->hard_start_xmit == interface_tx)
+ return 0;
+#endif
+
+ /* Device is being bridged */
+ /* if (net_dev->priv_flags & IFF_BRIDGE_PORT)
+ return 0; */
+
+ return 1;
+}
+
+static struct batman_if *get_active_batman_if(void)
+{
+ struct batman_if *batman_if;
+
+ /* TODO: should check interfaces belonging to bat_priv */
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->if_status == IF_ACTIVE)
+ goto out;
+ }
+
+ batman_if = NULL;
+
+out:
+ rcu_read_unlock();
+ return batman_if;
+}
+
+static void set_primary_if(struct bat_priv *bat_priv,
+ struct batman_if *batman_if)
+{
+ struct batman_packet *batman_packet;
+
+ bat_priv->primary_if = batman_if;
+
+ if (!bat_priv->primary_if)
+ return;
+
+ set_main_if_addr(batman_if->net_dev->dev_addr);
+
+ batman_packet = (struct batman_packet *)(batman_if->packet_buff);
+ batman_packet->flags = PRIMARIES_FIRST_HOP;
+ batman_packet->ttl = TTL;
+
+ /***
+ * hacky trick to make sure that we send the HNA information via
+ * our new primary interface
+ */
+ atomic_set(&hna_local_changed, 1);
+}
+
+static bool hardif_is_iface_up(struct batman_if *batman_if)
+{
+ if (batman_if->net_dev->flags & IFF_UP)
+ return true;
+
+ return false;
+}
+
+static void update_mac_addresses(struct batman_if *batman_if)
+{
++ if (!batman_if || !batman_if->packet_buff)
++ return;
++
+ addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
+
+ memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
+ batman_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender,
+ batman_if->net_dev->dev_addr, ETH_ALEN);
+}
+
+static void check_known_mac_addr(uint8_t *addr)
+{
+ struct batman_if *batman_if;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if ((batman_if->if_status != IF_ACTIVE) &&
+ (batman_if->if_status != IF_TO_BE_ACTIVATED))
+ continue;
+
+ if (!compare_orig(batman_if->net_dev->dev_addr, addr))
+ continue;
+
+ pr_warning("The newly added mac address (%pM) already exists "
+ "on: %s\n", addr, batman_if->dev);
+ pr_warning("It is strongly recommended to keep mac addresses "
+ "unique to avoid problems!\n");
+ }
+ rcu_read_unlock();
+}
+
+int hardif_min_mtu(void)
+{
+ struct batman_if *batman_if;
+ /* allow big frames if all devices are capable to do so
+ * (have MTU > 1500 + BAT_HEADER_LEN) */
+ int min_mtu = ETH_DATA_LEN;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if ((batman_if->if_status == IF_ACTIVE) ||
+ (batman_if->if_status == IF_TO_BE_ACTIVATED))
+ min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN,
+ min_mtu);
+ }
+ rcu_read_unlock();
+
+ return min_mtu;
+}
+
+/* adjusts the MTU if a new interface with a smaller MTU appeared. */
+void update_min_mtu(void)
+{
+ int min_mtu;
+
+ min_mtu = hardif_min_mtu();
+ if (soft_device->mtu != min_mtu)
+ soft_device->mtu = min_mtu;
+}
+
+static void hardif_activate_interface(struct net_device *net_dev,
+ struct bat_priv *bat_priv,
+ struct batman_if *batman_if)
+{
+ if (batman_if->if_status != IF_INACTIVE)
+ return;
+
- dev_hold(batman_if->net_dev);
-
+ update_mac_addresses(batman_if);
+ batman_if->if_status = IF_TO_BE_ACTIVATED;
+
+ /**
+ * the first active interface becomes our primary interface or
+ * the next active interface after the old primay interface was removed
+ */
+ if (!bat_priv->primary_if)
+ set_primary_if(bat_priv, batman_if);
+
+ bat_info(net_dev, "Interface activated: %s\n", batman_if->dev);
+
+ if (atomic_read(&module_state) == MODULE_INACTIVE)
+ activate_module();
+
+ update_min_mtu();
+ return;
+}
+
+static void hardif_deactivate_interface(struct net_device *net_dev,
+ struct batman_if *batman_if)
+{
+ if ((batman_if->if_status != IF_ACTIVE) &&
+ (batman_if->if_status != IF_TO_BE_ACTIVATED))
+ return;
+
- dev_put(batman_if->net_dev);
-
+ batman_if->if_status = IF_INACTIVE;
+
+ bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
+
+ update_min_mtu();
+}
+
+int hardif_enable_interface(struct batman_if *batman_if)
+{
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct batman_packet *batman_packet;
+
+ if (batman_if->if_status != IF_NOT_IN_USE)
+ goto out;
+
+ batman_if->packet_len = BAT_PACKET_LEN;
+ batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
+
+ if (!batman_if->packet_buff) {
+ bat_err(soft_device, "Can't add interface packet (%s): "
+ "out of memory\n", batman_if->dev);
+ goto err;
+ }
+
+ batman_packet = (struct batman_packet *)(batman_if->packet_buff);
+ batman_packet->packet_type = BAT_PACKET;
+ batman_packet->version = COMPAT_VERSION;
+ batman_packet->flags = 0;
+ batman_packet->ttl = 2;
+ batman_packet->tq = TQ_MAX_VALUE;
+ batman_packet->num_hna = 0;
+
+ batman_if->if_num = bat_priv->num_ifaces;
+ bat_priv->num_ifaces++;
+ batman_if->if_status = IF_INACTIVE;
+ orig_hash_add_if(batman_if, bat_priv->num_ifaces);
+
+ atomic_set(&batman_if->seqno, 1);
+ bat_info(soft_device, "Adding interface: %s\n", batman_if->dev);
+
+ if (hardif_is_iface_up(batman_if))
+ hardif_activate_interface(soft_device, bat_priv, batman_if);
+ else
+ bat_err(soft_device, "Not using interface %s "
+ "(retrying later): interface not active\n",
+ batman_if->dev);
+
+ /* begin scheduling originator messages on that interface */
+ schedule_own_packet(batman_if);
+
+out:
+ return 0;
+
+err:
+ return -ENOMEM;
+}
+
+void hardif_disable_interface(struct batman_if *batman_if)
+{
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
+
+ if (batman_if->if_status == IF_ACTIVE)
+ hardif_deactivate_interface(soft_device, batman_if);
+
+ if (batman_if->if_status != IF_INACTIVE)
+ return;
+
+ bat_info(soft_device, "Removing interface: %s\n", batman_if->dev);
+ bat_priv->num_ifaces--;
+ orig_hash_del_if(batman_if, bat_priv->num_ifaces);
+
+ if (batman_if == bat_priv->primary_if)
+ set_primary_if(bat_priv, get_active_batman_if());
+
+ kfree(batman_if->packet_buff);
+ batman_if->packet_buff = NULL;
+ batman_if->if_status = IF_NOT_IN_USE;
+
+ if ((atomic_read(&module_state) == MODULE_ACTIVE) &&
+ (bat_priv->num_ifaces == 0))
+ deactivate_module();
+}
+
+static struct batman_if *hardif_add_interface(struct net_device *net_dev)
+{
+ struct batman_if *batman_if;
+ int ret;
+
+ ret = is_valid_iface(net_dev);
+ if (ret != 1)
+ goto out;
+
++ dev_hold(net_dev);
++
+ batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
+ if (!batman_if) {
+ pr_err("Can't add interface (%s): out of memory\n",
+ net_dev->name);
- goto out;
++ goto release_dev;
+ }
+
+ batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
+ if (!batman_if->dev)
+ goto free_if;
+
+ ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev);
+ if (ret)
+ goto free_dev;
+
+ batman_if->if_num = -1;
+ batman_if->net_dev = net_dev;
+ batman_if->if_status = IF_NOT_IN_USE;
++ batman_if->packet_buff = NULL;
+ INIT_LIST_HEAD(&batman_if->list);
+
+ check_known_mac_addr(batman_if->net_dev->dev_addr);
+ list_add_tail_rcu(&batman_if->list, &if_list);
+ return batman_if;
+
+free_dev:
+ kfree(batman_if->dev);
+free_if:
+ kfree(batman_if);
++release_dev:
++ dev_put(net_dev);
+out:
+ return NULL;
+}
+
+static void hardif_free_interface(struct rcu_head *rcu)
+{
+ struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu);
+
+ /* delete all references to this batman_if */
+ purge_orig(NULL);
+ purge_outstanding_packets(batman_if);
+
+ kfree(batman_if->dev);
+ kfree(batman_if);
+}
+
+static void hardif_remove_interface(struct batman_if *batman_if)
+{
+ /* first deactivate interface */
+ if (batman_if->if_status != IF_NOT_IN_USE)
+ hardif_disable_interface(batman_if);
+
+ if (batman_if->if_status != IF_NOT_IN_USE)
+ return;
+
+ batman_if->if_status = IF_TO_BE_REMOVED;
+ list_del_rcu(&batman_if->list);
+ sysfs_del_hardif(&batman_if->hardif_obj);
++ dev_put(batman_if->net_dev);
+ call_rcu(&batman_if->rcu, hardif_free_interface);
+}
+
+void hardif_remove_interfaces(void)
+{
+ struct batman_if *batman_if, *batman_if_tmp;
+
+ list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list)
+ hardif_remove_interface(batman_if);
+}
+
+static int hard_if_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct net_device *net_dev = (struct net_device *)ptr;
+ struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
+
- if (!batman_if)
- batman_if = hardif_add_interface(net_dev);
++ if (!batman_if && event == NETDEV_REGISTER)
++ batman_if = hardif_add_interface(net_dev);
+
+ if (!batman_if)
+ goto out;
+
+ switch (event) {
- case NETDEV_REGISTER:
- break;
+ case NETDEV_UP:
+ hardif_activate_interface(soft_device, bat_priv, batman_if);
+ break;
+ case NETDEV_GOING_DOWN:
+ case NETDEV_DOWN:
+ hardif_deactivate_interface(soft_device, batman_if);
+ break;
+ case NETDEV_UNREGISTER:
+ hardif_remove_interface(batman_if);
+ break;
+ case NETDEV_CHANGENAME:
+ break;
+ case NETDEV_CHANGEADDR:
+ check_known_mac_addr(batman_if->net_dev->dev_addr);
+ update_mac_addresses(batman_if);
+ if (batman_if == bat_priv->primary_if)
+ set_primary_if(bat_priv, batman_if);
+ break;
+ default:
+ break;
+ };
+
+out:
+ return NOTIFY_DONE;
+}
+
+static int batman_skb_recv_finish(struct sk_buff *skb)
+{
+ return NF_ACCEPT;
+}
+
+/* receive a packet with the batman ethertype coming on a hard
+ * interface */
+int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *ptype, struct net_device *orig_dev)
+{
+ /* FIXME: each orig_node->batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct batman_packet *batman_packet;
+ struct batman_if *batman_if;
+ int ret;
+
+ skb = skb_share_check(skb, GFP_ATOMIC);
+
+ /* skb was released by skb_share_check() */
+ if (!skb)
+ goto err_out;
+
+ if (atomic_read(&module_state) != MODULE_ACTIVE)
+ goto err_free;
+
+ /* if netfilter/ebtables wants to block incoming batman
+ * packets then give them a chance to do so here */
+ ret = NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev, NULL,
+ batman_skb_recv_finish);
+ if (ret != 1)
+ goto err_out;
+
+ /* packet should hold at least type and version */
+ if (unlikely(skb_headlen(skb) < 2))
+ goto err_free;
+
+ /* expect a valid ethernet header here. */
+ if (unlikely(skb->mac_len != sizeof(struct ethhdr)
+ || !skb_mac_header(skb)))
+ goto err_free;
+
+ batman_if = get_batman_if_by_netdev(skb->dev);
+ if (!batman_if)
+ goto err_free;
+
+ /* discard frames on not active interfaces */
+ if (batman_if->if_status != IF_ACTIVE)
+ goto err_free;
+
+ batman_packet = (struct batman_packet *)skb->data;
+
+ if (batman_packet->version != COMPAT_VERSION) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: incompatible batman version (%i)\n",
+ batman_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) {
+ /* batman originator packet */
+ case BAT_PACKET:
+ ret = recv_bat_packet(skb, batman_if);
+ break;
+
+ /* batman icmp packet */
+ case BAT_ICMP:
+ ret = recv_icmp_packet(skb);
+ break;
+
+ /* unicast packet */
+ case BAT_UNICAST:
+ ret = recv_unicast_packet(skb, batman_if);
+ break;
+
+ /* broadcast packet */
+ case BAT_BCAST:
+ ret = recv_bcast_packet(skb);
+ break;
+
+ /* vis packet */
+ case BAT_VIS:
+ ret = recv_vis_packet(skb);
+ break;
+ default:
+ ret = NET_RX_DROP;
+ }
+
+ if (ret == NET_RX_DROP)
+ kfree_skb(skb);
+
+ /* return NET_RX_SUCCESS in any case as we
+ * most probably dropped the packet for
+ * routing-logical reasons. */
+
+ return NET_RX_SUCCESS;
+
+err_free:
+ kfree_skb(skb);
+err_out:
+ return NET_RX_DROP;
+}
+
+struct notifier_block hard_if_notifier = {
+ .notifier_call = hard_if_event,
+};
--
linux integration
12 years, 5 months
r1776 - trunk/batman-adv
by postmaster@open-mesh.org
Author: marek
Date: 2010-08-20 22:42:22 +0200 (Fri, 20 Aug 2010)
New Revision: 1776
Modified:
trunk/batman-adv/unicast.h
Log:
batman-adv: Add include guards to unicast.h
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
Modified: trunk/batman-adv/unicast.h
===================================================================
--- trunk/batman-adv/unicast.h 2010-08-20 19:16:14 UTC (rev 1775)
+++ trunk/batman-adv/unicast.h 2010-08-20 20:42:22 UTC (rev 1776)
@@ -19,6 +19,9 @@
*
*/
+#ifndef _NET_BATMAN_ADV_UNICAST_H_
+#define _NET_BATMAN_ADV_UNICAST_H_
+
#define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */
#define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */
@@ -32,3 +35,5 @@
struct unicast_frag_packet *up);
void frag_list_free(struct list_head *head);
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv);
+
+#endif /* _NET_BATMAN_ADV_UNICAST_H_ */
12 years, 5 months
r1775 - trunk/batman-adv
by postmaster@open-mesh.org
Author: marek
Date: 2010-08-20 21:16:14 +0200 (Fri, 20 Aug 2010)
New Revision: 1775
Modified:
trunk/batman-adv/hard-interface.c
Log:
batman-adv: Update mtu of bat device by changing mtu of slave device
We must reduce our own mtu when we reduce the mtu of any device we use
to transfer our packets. Otherwise we may accept to large packets which
gets dropped by the actual device.
Reported-by: Vasiliy Kulikov <segooon(a)gmail.com>
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
Modified: trunk/batman-adv/hard-interface.c
===================================================================
--- trunk/batman-adv/hard-interface.c 2010-08-20 19:16:11 UTC (rev 1774)
+++ trunk/batman-adv/hard-interface.c 2010-08-20 19:16:14 UTC (rev 1775)
@@ -469,6 +469,10 @@
case NETDEV_UNREGISTER:
hardif_remove_interface(batman_if);
break;
+ case NETDEV_CHANGEMTU:
+ if (batman_if->soft_iface)
+ update_min_mtu(batman_if->soft_iface);
+ break;
case NETDEV_CHANGEADDR:
if (batman_if->if_status == IF_NOT_IN_USE)
goto out;
12 years, 5 months