summaryrefslogtreecommitdiffstats
path: root/drivers/staging/batman-adv/soft-interface.c
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2010-09-05 01:58:34 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-09-05 00:29:49 -0700
commit6a0e9fa88df9e3a517a2fd317706aefa10a43191 (patch)
tree2dcf657e159d168a65af81cb65d21108cae48ead /drivers/staging/batman-adv/soft-interface.c
parentbf3264f6d1039e68ec9881447808327c0260ae61 (diff)
downloadop-kernel-dev-6a0e9fa88df9e3a517a2fd317706aefa10a43191.zip
op-kernel-dev-6a0e9fa88df9e3a517a2fd317706aefa10a43191.tar.gz
Staging: batman-adv: attach each hard-interface to a soft-interface
This patch replaces the static bat0 interface with a dynamic/abstracted approach. It is now possible to create multiple batX interfaces by assigning hard interfaces to them. Each batX interface acts as an independent mesh network. A soft interface is removed once no hard interface references it any longer. Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> [sven.eckelmann@gmx.de: Rework on top of current version] Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/batman-adv/soft-interface.c')
-rw-r--r--drivers/staging/batman-adv/soft-interface.c118
1 files changed, 98 insertions, 20 deletions
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c
index e8be209..864f85d 100644
--- a/drivers/staging/batman-adv/soft-interface.c
+++ b/drivers/staging/batman-adv/soft-interface.c
@@ -22,8 +22,14 @@
#include "main.h"
#include "soft-interface.h"
#include "hard-interface.h"
+#include "routing.h"
+#include "send.h"
+#include "bat_debugfs.h"
#include "translation-table.h"
+#include "types.h"
+#include "hash.h"
#include "send.h"
+#include "bat_sysfs.h"
#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
@@ -92,12 +98,13 @@ static int interface_release(struct net_device *dev)
static struct net_device_stats *interface_stats(struct net_device *dev)
{
- struct bat_priv *priv = netdev_priv(dev);
- return &priv->stats;
+ struct bat_priv *bat_priv = netdev_priv(dev);
+ return &bat_priv->stats;
}
static int interface_set_mac_addr(struct net_device *dev, void *p)
{
+ struct bat_priv *bat_priv = netdev_priv(dev);
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
@@ -105,8 +112,9 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
/* only modify hna-table if it has been initialised before */
if (atomic_read(&module_state) == MODULE_ACTIVE) {
- hna_local_remove(dev->dev_addr, "mac address changed");
- hna_local_add(addr->sa_data);
+ hna_local_remove(bat_priv, dev->dev_addr,
+ "mac address changed");
+ hna_local_add(dev, addr->sa_data);
}
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -117,7 +125,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
static int interface_change_mtu(struct net_device *dev, int new_mtu)
{
/* check ranges */
- if ((new_mtu < 68) || (new_mtu > hardif_min_mtu()))
+ if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev)))
return -EINVAL;
dev->mtu = new_mtu;
@@ -125,19 +133,20 @@ static int interface_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-int interface_tx(struct sk_buff *skb, struct net_device *dev)
+int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
{
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
- struct bat_priv *bat_priv = netdev_priv(dev);
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
struct bcast_packet *bcast_packet;
int data_len = skb->len, ret;
if (atomic_read(&module_state) != MODULE_ACTIVE)
goto dropped;
- dev->trans_start = jiffies;
+ soft_iface->trans_start = jiffies;
+
/* TODO: check this for locks */
- hna_local_add(ethhdr->h_source);
+ hna_local_add(soft_iface, ethhdr->h_source);
/* ethernet packet should be broadcasted */
if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) {
@@ -160,7 +169,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
bcast_packet->seqno = htonl(bcast_seqno);
/* broadcast packet. on success, increase seqno. */
- if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK)
+ if (add_bcast_packet_to_list(bat_priv, skb) == NETDEV_TX_OK)
bcast_seqno++;
/* a copy is stored in the bcast list, therefore removing
@@ -187,10 +196,10 @@ end:
return NETDEV_TX_OK;
}
-void interface_rx(struct sk_buff *skb, int hdr_size)
+void interface_rx(struct net_device *soft_iface,
+ struct sk_buff *skb, int hdr_size)
{
- struct net_device *dev = soft_device;
- struct bat_priv *priv = netdev_priv(dev);
+ struct bat_priv *priv = netdev_priv(soft_iface);
/* check if enough space is available for pulling, and pull */
if (!pskb_may_pull(skb, hdr_size)) {
@@ -200,8 +209,8 @@ void interface_rx(struct sk_buff *skb, int hdr_size)
skb_pull_rcsum(skb, hdr_size);
/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
- skb->dev = dev;
- skb->protocol = eth_type_trans(skb, dev);
+ skb->dev = soft_iface;
+ skb->protocol = eth_type_trans(skb, soft_iface);
/* should not be neccesary anymore as we use skb_pull_rcsum()
* TODO: please verify this and remove this TODO
@@ -215,7 +224,7 @@ void interface_rx(struct sk_buff *skb, int hdr_size)
priv->stats.rx_packets++;
priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
- dev->last_rx = jiffies;
+ soft_iface->last_rx = jiffies;
netif_rx(skb);
}
@@ -232,7 +241,7 @@ static const struct net_device_ops bat_netdev_ops = {
};
#endif
-void interface_setup(struct net_device *dev)
+static void interface_setup(struct net_device *dev)
{
struct bat_priv *priv = netdev_priv(dev);
char dev_addr[ETH_ALEN];
@@ -251,9 +260,11 @@ void interface_setup(struct net_device *dev)
#endif
dev->destructor = free_netdev;
- dev->mtu = ETH_DATA_LEN; /* can't call min_mtu, because the
- * needed variables have not been
- * initialized yet */
+ /**
+ * can't call min_mtu, because the needed variables
+ * have not been initialized yet
+ */
+ dev->mtu = ETH_DATA_LEN;
dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
* skbuff for our header */
@@ -266,6 +277,73 @@ void interface_setup(struct net_device *dev)
memset(priv, 0, sizeof(struct bat_priv));
}
+struct net_device *softif_create(char *name)
+{
+ struct net_device *soft_iface;
+ struct bat_priv *bat_priv;
+ int ret;
+
+ soft_iface = alloc_netdev(sizeof(struct bat_priv) , name,
+ interface_setup);
+
+ if (!soft_iface) {
+ pr_err("Unable to allocate the batman interface: %s\n", name);
+ goto out;
+ }
+
+ ret = register_netdev(soft_iface);
+
+ if (ret < 0) {
+ pr_err("Unable to register the batman interface '%s': %i\n",
+ name, ret);
+ goto free_soft_iface;
+ }
+
+ bat_priv = netdev_priv(soft_iface);
+
+ atomic_set(&bat_priv->aggregation_enabled, 1);
+ atomic_set(&bat_priv->bonding_enabled, 0);
+ atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
+ atomic_set(&bat_priv->orig_interval, 1000);
+ atomic_set(&bat_priv->log_level, 0);
+ atomic_set(&bat_priv->frag_enabled, 1);
+ atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN);
+ atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN);
+
+ bat_priv->primary_if = NULL;
+ bat_priv->num_ifaces = 0;
+
+ ret = sysfs_add_meshif(soft_iface);
+
+ if (ret < 0)
+ goto unreg_soft_iface;
+
+ ret = debugfs_add_meshif(soft_iface);
+
+ if (ret < 0)
+ goto unreg_sysfs;
+
+ return soft_iface;
+
+unreg_sysfs:
+ sysfs_del_meshif(soft_iface);
+unreg_soft_iface:
+ unregister_netdev(soft_iface);
+ return NULL;
+
+free_soft_iface:
+ free_netdev(soft_iface);
+out:
+ return NULL;
+}
+
+void softif_destroy(struct net_device *soft_iface)
+{
+ debugfs_del_meshif(soft_iface);
+ sysfs_del_meshif(soft_iface);
+ unregister_netdevice(soft_iface);
+}
+
/* ethtool */
static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
OpenPOWER on IntegriCloud