diff options
Diffstat (limited to 'drivers/staging/batman-adv')
35 files changed, 0 insertions, 7625 deletions
diff --git a/drivers/staging/batman-adv/CHANGELOG b/drivers/staging/batman-adv/CHANGELOG deleted file mode 100644 index c8f9d9e06bb..00000000000 --- a/drivers/staging/batman-adv/CHANGELOG +++ /dev/null @@ -1,51 +0,0 @@ -batman-adv 0.2.1: - -* support latest kernels (2.6.20 - 2.6.33) -* receive packets directly using skbs, remove old sockets and threads -* fix various regressions in the vis server -* don't disable interrupts while sending -* replace internal logging mechanism with standard kernel logging -* move vis formats into userland, one general format remains in the kernel -* allow MAC address to be set, correctly initialize them -* code refactoring and cleaning for coding style -* many bugs (null pointers, locking, hash iterators) squashed - - -- Sun, 21 Mar 2010 20:46:47 +0100 - -batman-adv 0.2: - -* support latest kernels (2.6.20 - 2.6.31) -* temporary routing loops / TTL code bug / ghost entries in originator table fixed -* internal packet queue for packet aggregation & transmission retry (ARQ) - for payload broadcasts added -* interface detection converted to event based handling to avoid timers -* major linux coding style adjustments applied -* all kernel version compatibility functions has been moved to compat.h -* use random ethernet address generator from the kernel -* /sys/module/batman_adv/version to export kernel module version -* vis: secondary interface export for dot draw format + JSON output format added -* many bugs (alignment issues, race conditions, deadlocks, etc) squashed - - -- Sat, 07 Nov 2009 15:44:31 +0100 - -batman-adv 0.1: - -* support latest kernels (2.6.20 - 2.6.28) -* LOTS of cleanup: locking, stack usage, memory leaks -* Change Ethertype from 0x0842 to 0x4305 - unregistered at IEEE, if you want to sponsor an official Ethertype ($2500) - please contact us - - -- Sun, 28 Dec 2008 00:44:31 +0100 - -batman-adv 0.1-beta: - -* layer 2 meshing based on BATMAN TQ algorithm in kernelland -* operates on any ethernet like interface -* supports IPv4, IPv6, DHCP, etc -* is controlled via /proc/net/batman-adv/ -* bridging via brctl is supported -* interface watchdog (interfaces can be (de)activated dynamically) -* offers integrated vis server which meshes/syncs with other vis servers in range - - -- Mon, 05 May 2008 14:10:04 +0200 diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig deleted file mode 100644 index 1e7e0a8dbc8..00000000000 --- a/drivers/staging/batman-adv/Kconfig +++ /dev/null @@ -1,26 +0,0 @@ -# -# B.A.T.M.A.N meshing protocol -# - -config BATMAN_ADV - tristate "B.A.T.M.A.N. Advanced Meshing Protocol" - depends on PROC_FS && NET - default n - ---help--- - - B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is - a routing protocol for multi-hop ad-hoc mesh networks. The - networks may be wired or wireless. See - http://www.open-mesh.org/ for more information and user space - tools. - -config BATMAN_ADV_DEBUG - bool "B.A.T.M.A.N. debugging" - depends on BATMAN_ADV != n - ---help--- - - This is an option for use by developers; most people should - say N here. This enables compilation of support for - outputting debugging information to the kernel log. The - output is controlled via the module parameter debug. - diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile deleted file mode 100644 index f25068c0fae..00000000000 --- a/drivers/staging/batman-adv/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# -# 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 -# - -obj-m += batman-adv.o -batman-adv-objs := main.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README deleted file mode 100644 index 14244a2c4e4..00000000000 --- a/drivers/staging/batman-adv/README +++ /dev/null @@ -1,240 +0,0 @@ -[state: 03-05-2010] - -BATMAN-ADV ----------- - -Batman advanced is a new approach to wireless networking which -does no longer operate on the IP basis. Unlike the batman daemon, -which exchanges information using UDP packets and sets routing -tables, batman-advanced operates on ISO/OSI Layer 2 only and uses -and routes (or better: bridges) Ethernet Frames. It emulates a -virtual network switch of all nodes participating. Therefore all -nodes appear to be link local, thus all higher operating proto- -cols won't be affected by any changes within the network. You can -run almost any protocol above batman advanced, prominent examples -are: IPv4, IPv6, DHCP, IPX. - -Batman advanced was implemented as a Linux kernel driver to re- -duce the overhead to a minimum. It does not depend on any (other) -network driver, and can be used on wifi as well as ethernet lan, -vpn, etc ... (anything with ethernet-style layer 2). - -CONFIGURATION -------------- - -Load the batman-adv module into your kernel: - -# insmod batman-adv.ko - -The module is now waiting for activation. You must add some in- -terfaces on which batman can operate. After loading the module -batman advanced will scan your systems interfaces to search for -compatible interfaces. Once found, it will create subfolders in -the /sys directories of each supported interface, e.g. - -# ls /sys/class/net/eth0/batman_adv/ -# iface_status mesh_iface - -If an interface does not have the "batman_adv" subfolder it prob- -ably is not supported. Not supported interfaces are: loopback, -non-ethernet and batman's own interfaces. - -Note: After the module was loaded it will continuously watch for -new interfaces to verify the compatibility. There is no need to -reload the module if you plug your USB wifi adapter into your ma- -chine after batman advanced was initially loaded. - -To activate a given interface simply write "bat0" into its -"mesh_iface" file inside the batman_adv subfolder: - -# echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface - -Repeat this step for all interfaces you wish to add. Now batman -starts using/broadcasting on this/these interface(s). - -By reading the "iface_status" file you can check its status: - -# cat /sys/class/net/eth0/batman_adv/iface_status -# active - -To deactivate an interface you have to write "none" into its -"mesh_iface" file: - -# echo none > /sys/class/net/eth0/batman_adv/mesh_iface - - -All mesh wide settings can be found in batman's own interface -folder: - -# ls /sys/class/net/bat0/mesh/ -# aggregate_ogm originators transtable_global vis_mode -# orig_interval transtable_local vis_data - - -Some of the files contain all sort of status information regard- -ing the mesh network. For example, you can view the table of -originators (mesh participants) with: - -# cat /sys/class/net/bat0/mesh/originators - -Other files allow to change batman's behaviour to better fit your -requirements. For instance, you can check the current originator -interval (value in milliseconds which determines how often batman -sends its broadcast packets): - -# cat /sys/class/net/bat0/mesh/orig_interval -# status: 1000 - -and also change its value: - -# echo 3000 > /sys/class/net/bat0/mesh/orig_interval - -In very mobile scenarios, you might want to adjust the originator -interval to a lower value. This will make the mesh more respon- -sive to topology changes, but will also increase the overhead. - - -USAGE ------ - -To make use of your newly created mesh, batman advanced provides -a new interface "bat0" which you should use from this point on. -All interfaces added to batman advanced are not relevant any -longer because batman handles them for you. Basically, one "hands -over" the data by using the batman interface and batman will make -sure it reaches its destination. - -The "bat0" interface can be used like any other regular inter- -face. It needs an IP address which can be either statically con- -figured or dynamically (by using DHCP or similar services): - -# NodeA: ifconfig bat0 192.168.0.1 -# NodeB: ifconfig bat0 192.168.0.2 -# NodeB: ping 192.168.0.1 - -Note: In order to avoid problems remove all IP addresses previ- -ously assigned to interfaces now used by batman advanced, e.g. - -# ifconfig eth0 0.0.0.0 - - -VISUALIZATION -------------- - -If you want topology visualization, at least one mesh node must -be configured as VIS-server: - -# echo "server" > /sys/class/net/bat0/mesh/vis_mode - -Each node is either configured as "server" or as "client" (de- -fault: "client"). Clients send their topology data to the server -next to them, and server synchronize with other servers. If there -is no server configured (default) within the mesh, no topology -information will be transmitted. With these "synchronizing -servers", there can be 1 or more vis servers sharing the same (or -at least very similar) data. - -When configured as server, you can get a topology snapshot of -your mesh: - -# cat /sys/class/net/bat0/mesh/vis_data - -This raw output is intended to be easily parsable and convertable -with other tools. Have a look at the batctl README if you want a -vis output in dot or json format for instance and how those out- -puts could then be visualised in an image. - -The raw format consists of comma separated values per entry where -each entry is giving information about a certain source inter- -face. Each entry can/has to have the following values: --> "mac" - mac address of an originator's source interface - (each line begins with it) --> "TQ mac value" - src mac's link quality towards mac address - of a neighbor originator's interface which - is being used for routing --> "HNA mac" - HNA announced by source mac --> "PRIMARY" - this is a primary interface --> "SEC mac" - secondary mac address of source - (requires preceding PRIMARY) - -The TQ value has a range from 4 to 255 with 255 being the best. -The HNA entries are showing which hosts are connected to the mesh -via bat0 or being bridged into the mesh network. The PRIMARY/SEC -values are only applied on primary interfaces - - -LOGGING/DEBUGGING ------------------ - -All error messages, warnings and information messages are sent to -the kernel log. Depending on your operating system distribution -this can be read in one of a number of ways. Try using the com- -mands: dmesg, logread, or looking in the files /var/log/kern.log -or /var/log/syslog. All batman-adv messages are prefixed with -"batman-adv:" So to see just these messages try - -# dmesg | grep batman-adv - -When investigating problems with your mesh network it is some- -times necessary to see more detail debug messages. This must be -enabled when compiling the batman-adv module. When building bat- -man-adv as part of kernel, use "make menuconfig" and enable the -option "B.A.T.M.A.N. debugging". - -The additional debug output is by default disabled. It can be en- -abled either at kernel modules load time or during run time. To -enable debug output at module load time, add the module parameter -debug=<value>. <value> can take one of four values. - -0 - All debug output disabled -1 - Enable messages related to routing / flooding / broadcasting -2 - Enable route or hna added / changed / deleted -3 - Enable all messages - -e.g. - -# modprobe batman-adv debug=2 - -will load the module and enable debug messages for when routes or -HNAs change. - -The debug output can also be changed at runtime using the file -/sys/module/batman-adv/parameters/debug. e.g. - -# echo 2 > /sys/module/batman-adv/parameters/debug - -enables debug messages for when routes or HNAs - -The debug output is sent to the kernel logs. So try dmesg, lo- -gread, etc to see the debug messages. - - -BATCTL ------- - -As batman advanced operates on layer 2 all hosts participating in -the virtual switch are completely transparent for all protocols -above layer 2. Therefore the common diagnosis tools do not work -as expected. To overcome these problems batctl was created. At -the moment the batctl contains ping, traceroute, tcpdump and -interfaces to the kernel module settings. - -For more information, please see the manpage (man batctl). - -batctl is available on http://www.open-mesh.org/ - - -CONTACT -------- - -Please send us comments, experiences, questions, anything :) - -IRC: #batman on irc.freenode.org -Mailing-list: b.a.t.m.a.n@open-mesh.net (optional subscription - at https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) - -You can also contact the Authors: - -Marek Lindner <lindner_marek@yahoo.de> -Simon Wunderlich <siwu@hrz.tu-chemnitz.de> - diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO deleted file mode 100644 index 518db7fd41b..00000000000 --- a/drivers/staging/batman-adv/TODO +++ /dev/null @@ -1,10 +0,0 @@ -Request a review. -Process the comments from the review. -Move into mainline proper. - -Please send all patches to: - Marek Lindner <lindner_marek@yahoo.de> - Simon Wunderlich <siwu@hrz.tu-chemnitz.de> - Andrew Lunn <andrew@lunn.ch> - b.a.t.m.a.n@lists.open-mesh.net - Greg Kroah-Hartman <gregkh@suse.de> diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c deleted file mode 100644 index ce8b8a6e5ae..00000000000 --- a/drivers/staging/batman-adv/aggregation.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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 "aggregation.h" -#include "send.h" -#include "routing.h" - -/* calculate the size of the hna information for a given packet */ -static int hna_len(struct batman_packet *batman_packet) -{ - return batman_packet->num_hna * ETH_ALEN; -} - -/* return true if new_packet can be aggregated with forw_packet */ -static bool can_aggregate_with(struct batman_packet *new_batman_packet, - int packet_len, - unsigned long send_time, - bool directlink, - struct batman_if *if_incoming, - struct forw_packet *forw_packet) -{ - struct batman_packet *batman_packet = - (struct batman_packet *)forw_packet->packet_buff; - int aggregated_bytes = forw_packet->packet_len + packet_len; - - /** - * 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 - */ - - /* packets without direct link flag and high TTL - * are flooded through the net */ - if ((!directlink) && - (!(batman_packet->flags & DIRECTLINK)) && - (batman_packet->ttl != 1) && - - /* own packets originating non-primary - * interfaces leave only that interface */ - ((!forw_packet->own) || - (forw_packet->if_incoming->if_num == 0))) - return true; - - /* if the incoming packet is sent via this one - * interface only - we still can aggregate */ - if ((directlink) && - (new_batman_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 || - (forw_packet->own && - forw_packet->if_incoming->if_num != 0))) - return true; - } - - return false; -} - -#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) -/* create a new aggregated packet and add this packet to it */ -static void new_aggregated_packet(unsigned char *packet_buff, - int packet_len, - unsigned long send_time, - bool direct_link, - struct batman_if *if_incoming, - int own_packet) -{ - struct forw_packet *forw_packet_aggr; - unsigned long flags; - - /* own packet should always be scheduled */ - if (!own_packet) { - if (!atomic_dec_not_zero(&batman_queue_left)) { - bat_dbg(DBG_BATMAN, "batman packet queue full\n"); - return; - } - } - - forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); - if (!forw_packet_aggr) { - if (!own_packet) - atomic_inc(&batman_queue_left); - return; - } - - forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES, - GFP_ATOMIC); - if (!forw_packet_aggr->packet_buff) { - if (!own_packet) - atomic_inc(&batman_queue_left); - kfree(forw_packet_aggr); - return; - } - - INIT_HLIST_NODE(&forw_packet_aggr->list); - - forw_packet_aggr->packet_len = packet_len; - memcpy(forw_packet_aggr->packet_buff, - packet_buff, - forw_packet_aggr->packet_len); - - forw_packet_aggr->skb = NULL; - 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 = 0; - 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_irqsave(&forw_bat_list_lock, flags); - hlist_add_head(&forw_packet_aggr->list, &forw_bat_list); - spin_unlock_irqrestore(&forw_bat_list_lock, flags); - - /* 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); -} - -/* aggregate a new packet into the existing aggregation */ -static void aggregate(struct forw_packet *forw_packet_aggr, - unsigned char *packet_buff, - int packet_len, - bool direct_link) -{ - memcpy((forw_packet_aggr->packet_buff + forw_packet_aggr->packet_len), - 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 batman_if *if_incoming, char 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_packet *batman_packet = - (struct batman_packet *)packet_buff; - bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; - unsigned long flags; - - /* find position for the packet in the forward queue */ - spin_lock_irqsave(&forw_bat_list_lock, flags); - /* own packets are not to be aggregated */ - if ((atomic_read(&bat_priv->aggregation_enabled)) && (!own_packet)) { - hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list, - list) { - if (can_aggregate_with(batman_packet, - 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 == NULL) { - /* the following section can run without the lock */ - spin_unlock_irqrestore(&forw_bat_list_lock, flags); - - /** - * 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->aggregation_enabled))) - 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_irqrestore(&forw_bat_list_lock, flags); - } -} - -/* unpack the aggregated packets and process them one by one */ -void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, - int packet_len, struct batman_if *if_incoming) -{ - struct batman_packet *batman_packet; - int buff_pos = 0; - unsigned char *hna_buff; - - batman_packet = (struct batman_packet *)packet_buff; - - while (aggregated_packet(buff_pos, packet_len, - batman_packet->num_hna)) { - - /* network to host order for our 16bit seqno, and the - orig_interval. */ - batman_packet->seqno = ntohs(batman_packet->seqno); - - hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN; - receive_bat_packet(ethhdr, batman_packet, - hna_buff, hna_len(batman_packet), - if_incoming); - - buff_pos += BAT_PACKET_LEN + hna_len(batman_packet); - batman_packet = (struct batman_packet *) - (packet_buff + buff_pos); - } -} diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h deleted file mode 100644 index 84401ca24c3..00000000000 --- a/drivers/staging/batman-adv/aggregation.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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" - -/* is there another aggregated packet here? */ -static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) -{ - int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN); - - 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 batman_if *if_incoming, char own_packet, - unsigned long send_time); -void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, - int packet_len, struct batman_if *if_incoming); diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c deleted file mode 100644 index 212bc21e6d6..00000000000 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (C) 2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * 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_sysfs.h" -#include "translation-table.h" -#include "originator.h" -#include "hard-interface.h" -#include "vis.h" - -#define to_dev(obj) container_of(obj, struct device, kobj) - -struct bat_attribute { - struct attribute attr; - ssize_t (*show)(struct kobject *kobj, struct attribute *attr, - char *buf); - ssize_t (*store)(struct kobject *kobj, struct attribute *attr, - char *buf, size_t count); -}; - -struct hardif_attribute { - struct attribute attr; - ssize_t (*show)(struct kobject *kobj, struct attribute *attr, - char *buf); - ssize_t (*store)(struct kobject *kobj, struct attribute *attr, - char *buf, size_t count); -}; - -#define BAT_ATTR(_name, _mode, _show, _store) \ -struct bat_attribute bat_attr_##_name = { \ - .attr = {.name = __stringify(_name), \ - .mode = _mode }, \ - .show = _show, \ - .store = _store, \ -}; - -#define BAT_BIN_ATTR(_name, _mode, _read, _write) \ -struct bin_attribute bat_attr_##_name = { \ - .attr = { .name = __stringify(_name), \ - .mode = _mode, }, \ - .read = _read, \ - .write = _write, \ -}; - -#define HARDIF_ATTR(_name, _mode, _show, _store) \ -struct hardif_attribute hardif_attr_##_name = { \ - .attr = {.name = __stringify(_name), \ - .mode = _mode }, \ - .show = _show, \ - .store = _store, \ -}; - -static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int aggr_status = atomic_read(&bat_priv->aggregation_enabled); - - return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1\n", - aggr_status == 0 ? "disabled" : "enabled"); -} - -static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct bat_priv *bat_priv = netdev_priv(net_dev); - int aggr_tmp = -1; - - if (((count == 2) && (buff[0] == '1')) || - (strncmp(buff, "enable", 6) == 0)) - aggr_tmp = 1; - - if (((count == 2) && (buff[0] == '0')) || - (strncmp(buff, "disable", 7) == 0)) - aggr_tmp = 0; - - if (aggr_tmp < 0) { - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - printk(KERN_INFO "batman-adv:Invalid parameter for 'aggregate OGM' setting on mesh %s received: %s\n", - net_dev->name, buff); - return -EINVAL; - } - - if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp) - return count; - - printk(KERN_INFO "batman-adv:Changing aggregation from: %s to: %s on mesh: %s\n", - atomic_read(&bat_priv->aggregation_enabled) == 1 ? - "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : "disabled", - net_dev->name); - - atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp); - return count; -} - -static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int vis_mode = atomic_read(&bat_priv->vis_mode); - - return sprintf(buff, "status: %s\ncommands: client, server, %d, %d\n", - vis_mode == VIS_TYPE_CLIENT_UPDATE ? - "client" : "server", - VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE); -} - -static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct bat_priv *bat_priv = netdev_priv(net_dev); - unsigned long val; - int ret, vis_mode_tmp = -1; - - ret = strict_strtoul(buff, 10, &val); - - if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) || - (strncmp(buff, "client", 6) == 0)) - vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE; - - if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) || - (strncmp(buff, "server", 6) == 0)) - vis_mode_tmp = VIS_TYPE_SERVER_SYNC; - - if (vis_mode_tmp < 0) { - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - printk(KERN_INFO "batman-adv:Invalid parameter for 'vis mode' setting on mesh %s received: %s\n", - net_dev->name, buff); - return -EINVAL; - } - - if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp) - return count; - - printk(KERN_INFO "batman-adv:Changing vis mode from: %s to: %s on mesh: %s\n", - atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ? - "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ? - "client" : "server", net_dev->name); - - atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp); - return count; -} - -static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - - return sprintf(buff, "status: %i\n", - atomic_read(&bat_priv->orig_interval)); -} - -static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct bat_priv *bat_priv = netdev_priv(net_dev); - unsigned long orig_interval_tmp; - int ret; - - ret = strict_strtoul(buff, 10, &orig_interval_tmp); - if (ret) { - printk(KERN_INFO "batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n", - net_dev->name, buff); - return -EINVAL; - } - - if (orig_interval_tmp <= JITTER * 2) { - printk(KERN_INFO "batman-adv:New originator interval too small: %li (min: %i)\n", - orig_interval_tmp, JITTER * 2); - return -EINVAL; - } - - if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp) - return count; - - printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li on mesh: %s\n", - atomic_read(&bat_priv->orig_interval), - orig_interval_tmp, net_dev->name); - - atomic_set(&bat_priv->orig_interval, orig_interval_tmp); - return count; -} - -static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR, - show_aggr_ogm, store_aggr_ogm); -static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); -static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR, - show_orig_interval, store_orig_interval); - -static struct bat_attribute *mesh_attrs[] = { - &bat_attr_aggregate_ogm, - &bat_attr_vis_mode, - &bat_attr_orig_interval, - NULL, -}; - -static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - - return hna_local_fill_buffer_text(net_dev, buff, count, off); -} - -static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - - return hna_global_fill_buffer_text(net_dev, buff, count, off); -} - -static ssize_t originators_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - - return orig_fill_buffer_text(net_dev, buff, count, off); -} - -static ssize_t vis_data_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - - return vis_fill_buffer_text(net_dev, buff, count, off); -} - -static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL); -static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL); -static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL); -static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL); - -static struct bin_attribute *mesh_bin_attrs[] = { - &bat_attr_transtable_local, - &bat_attr_transtable_global, - &bat_attr_originators, - &bat_attr_vis_data, - NULL, -}; - -int sysfs_add_meshif(struct net_device *dev) -{ - struct kobject *batif_kobject = &dev->dev.kobj; - struct bat_priv *bat_priv = netdev_priv(dev); - struct bat_attribute **bat_attr; - struct bin_attribute **bin_attr; - int err; - - /* FIXME: should be done in the general mesh setup - routine as soon as we have it */ - atomic_set(&bat_priv->aggregation_enabled, 1); - atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); - atomic_set(&bat_priv->orig_interval, 1000); - bat_priv->primary_if = NULL; - bat_priv->num_ifaces = 0; - - bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, - batif_kobject); - if (!bat_priv->mesh_obj) { - printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n", - dev->name, SYSFS_IF_MESH_SUBDIR); - goto out; - } - - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) { - err = sysfs_create_file(bat_priv->mesh_obj, - &((*bat_attr)->attr)); - if (err) { - printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_MESH_SUBDIR, - ((*bat_attr)->attr).name); - goto rem_attr; - } - } - - for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) { - err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr)); - if (err) { - printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_MESH_SUBDIR, - ((*bin_attr)->attr).name); - goto rem_bin_attr; - } - } - - return 0; - -rem_bin_attr: - for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) - sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr)); -rem_attr: - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) - sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); - - kobject_put(bat_priv->mesh_obj); - bat_priv->mesh_obj = NULL; -out: - return -ENOMEM; -} - -void sysfs_del_meshif(struct net_device *dev) -{ - struct bat_priv *bat_priv = netdev_priv(dev); - struct bat_attribute **bat_attr; - struct bin_attribute **bin_attr; - - for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) - sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr)); - - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) - sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); - - kobject_put(bat_priv->mesh_obj); - bat_priv->mesh_obj = NULL; -} - -static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); - - if (!batman_if) - return 0; - - return sprintf(buff, "status: %s\ncommands: none, bat0\n", - batman_if->if_status == IF_NOT_IN_USE ? - "none" : "bat0"); -} - -static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); - int status_tmp = -1; - - if (!batman_if) - return count; - - if (strncmp(buff, "none", 4) == 0) - status_tmp = IF_NOT_IN_USE; - - if (strncmp(buff, "bat0", 4) == 0) - status_tmp = IF_I_WANT_YOU; - - if (status_tmp < 0) { - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - printk(KERN_ERR "batman-adv:Invalid parameter for 'mesh_iface' setting received: %s\n", - buff); - return -EINVAL; - } - - if ((batman_if->if_status == status_tmp) || - ((status_tmp == IF_I_WANT_YOU) && - (batman_if->if_status != IF_NOT_IN_USE))) - return count; - - if (status_tmp == IF_I_WANT_YOU) - status_tmp = hardif_enable_interface(batman_if); - else - hardif_disable_interface(batman_if); - - return (status_tmp < 0 ? status_tmp : count); -} - -static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); - - if (!batman_if) - return 0; - - switch (batman_if->if_status) { - case IF_TO_BE_REMOVED: - return sprintf(buff, "disabling\n"); - case IF_INACTIVE: - return sprintf(buff, "inactive\n"); - case IF_ACTIVE: - return sprintf(buff, "active\n"); - case IF_TO_BE_ACTIVATED: - return sprintf(buff, "enabling\n"); - case IF_NOT_IN_USE: - default: - return sprintf(buff, "not in use\n"); - } -} - -static HARDIF_ATTR(mesh_iface, S_IRUGO | S_IWUSR, - show_mesh_iface, store_mesh_iface); -static HARDIF_ATTR(iface_status, S_IRUGO, show_iface_status, NULL); - -static struct hardif_attribute *batman_attrs[] = { - &hardif_attr_mesh_iface, - &hardif_attr_iface_status, - NULL, -}; - -int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) -{ - struct kobject *hardif_kobject = &dev->dev.kobj; - struct hardif_attribute **hardif_attr; - int err; - - *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR, - hardif_kobject); - - if (!*hardif_obj) { - printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n", - dev->name, SYSFS_IF_BAT_SUBDIR); - goto out; - } - - for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) { - err = sysfs_create_file(*hardif_obj, &((*hardif_attr)->attr)); - if (err) { - printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_BAT_SUBDIR, - ((*hardif_attr)->attr).name); - goto rem_attr; - } - } - - return 0; - -rem_attr: - for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) - sysfs_remove_file(*hardif_obj, &((*hardif_attr)->attr)); -out: - return -ENOMEM; -} - -void sysfs_del_hardif(struct kobject **hardif_obj) -{ - kobject_put(*hardif_obj); - *hardif_obj = NULL; -} diff --git a/drivers/staging/batman-adv/bat_sysfs.h b/drivers/staging/batman-adv/bat_sysfs.h deleted file mode 100644 index e1893411871..00000000000 --- a/drivers/staging/batman-adv/bat_sysfs.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * 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 - * - */ - - -#define SYSFS_IF_MESH_SUBDIR "mesh" -#define SYSFS_IF_BAT_SUBDIR "batman_adv" - -int sysfs_add_meshif(struct net_device *dev); -void sysfs_del_meshif(struct net_device *dev); -int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev); -void sysfs_del_hardif(struct kobject **hardif_obj); diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c deleted file mode 100644 index 2fef6e35f8c..00000000000 --- a/drivers/staging/batman-adv/bitarray.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * 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 "bitarray.h" - -/* returns true if the corresponding bit in the given seq_bits indicates true - * and curr_seqno is within range of last_seqno */ -uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno, - uint16_t curr_seqno) -{ - int16_t diff, word_offset, word_num; - - diff = last_seqno - curr_seqno; - if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) { - return 0; - } else { - /* which word */ - word_num = (last_seqno - curr_seqno) / WORD_BIT_SIZE; - /* which position in the selected word */ - word_offset = (last_seqno - curr_seqno) % WORD_BIT_SIZE; - - if (seq_bits[word_num] & 1 << word_offset) - return 1; - else - return 0; - } -} - -/* turn corresponding bit on, so we can remember that we got the packet */ -void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n) -{ - int32_t word_offset, word_num; - - /* if too old, just drop it */ - if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE) - return; - - /* which word */ - word_num = n / WORD_BIT_SIZE; - /* which position in the selected word */ - word_offset = n % WORD_BIT_SIZE; - - seq_bits[word_num] |= 1 << word_offset; /* turn the position on */ -} - -/* shift the packet array by n places. */ -void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n) -{ - int32_t word_offset, word_num; - int32_t i; - - if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE) - return; - - word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */ - word_num = n / WORD_BIT_SIZE; /* shift over how much (full) words */ - - for (i = NUM_WORDS - 1; i > word_num; i--) { - /* going from old to new, so we don't overwrite the data we copy - * from. - * - * left is high, right is low: FEDC BA98 7654 3210 - * ^^ ^^ - * vvvv - * ^^^^ = from, vvvvv =to, we'd have word_num==1 and - * word_offset==WORD_BIT_SIZE/2 ????? in this example. - * (=24 bits) - * - * our desired output would be: 9876 5432 1000 0000 - * */ - - seq_bits[i] = - (seq_bits[i - word_num] << word_offset) + - /* take the lower port from the left half, shift it left - * to its final position */ - (seq_bits[i - word_num - 1] >> - (WORD_BIT_SIZE-word_offset)); - /* and the upper part of the right half and shift it left to - * it's position */ - /* for our example that would be: word[0] = 9800 + 0076 = - * 9876 */ - } - /* now for our last word, i==word_num, we only have the it's "left" - * half. that's the 1000 word in our example.*/ - - seq_bits[i] = (seq_bits[i - word_num] << word_offset); - - /* pad the rest with 0, if there is anything */ - i--; - - for (; i >= 0; i--) - seq_bits[i] = 0; -} - -static void bit_reset_window(TYPE_OF_WORD *seq_bits) -{ - int i; - for (i = 0; i < NUM_WORDS; i++) - seq_bits[i] = 0; -} - - -/* receive and process one packet within the sequence number window. - * - * returns: - * 1 if the window was moved (either new or very old) - * 0 if the window was not moved/shifted. - */ -char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff, - int8_t set_mark) -{ - /* sequence number is slightly older. We already got a sequence number - * higher than this one, so we just mark it. */ - - if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { - if (set_mark) - bit_mark(seq_bits, -seq_num_diff); - return 0; - } - - /* sequence number is slightly newer, so we shift the window and - * set the mark if required */ - - if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { - bit_shift(seq_bits, seq_num_diff); - - if (set_mark) - bit_mark(seq_bits, 0); - return 1; - } - - /* sequence number is much newer, probably missed a lot of packets */ - - if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) - || (seq_num_diff < EXPECTED_SEQNO_RANGE)) { - bat_dbg(DBG_BATMAN, - "We missed a lot of packets (%i) !\n", - seq_num_diff - 1); - bit_reset_window(seq_bits); - if (set_mark) - bit_mark(seq_bits, 0); - return 1; - } - - /* received a much older packet. The other host either restarted - * or the old packet got delayed somewhere in the network. The - * packet should be dropped without calling this function if the - * seqno window is protected. */ - - if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) - || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - - bat_dbg(DBG_BATMAN, - "Other host probably restarted!\n"); - - bit_reset_window(seq_bits); - if (set_mark) - bit_mark(seq_bits, 0); - - return 1; - } - - /* never reached */ - return 0; -} - -/* count the hamming weight, how many good packets did we receive? just count - * the 1's. The inner loop uses the Kernighan algorithm, see - * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan - */ -int bit_packet_count(TYPE_OF_WORD *seq_bits) -{ - int i, hamming = 0; - TYPE_OF_WORD word; - - for (i = 0; i < NUM_WORDS; i++) { - word = seq_bits[i]; - - while (word) { - word &= word-1; - hamming++; - } - } - return hamming; -} diff --git a/drivers/staging/batman-adv/bitarray.h b/drivers/staging/batman-adv/bitarray.h deleted file mode 100644 index 76ad24c9f3d..00000000000 --- a/drivers/staging/batman-adv/bitarray.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * 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 - * - */ - - -/* you should choose something big, if you don't want to waste cpu */ -#define TYPE_OF_WORD unsigned long -#define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8) - -/* returns true if the corresponding bit in the given seq_bits indicates true - * and curr_seqno is within range of last_seqno */ -uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno, - uint16_t curr_seqno); - -/* turn corresponding bit on, so we can remember that we got the packet */ -void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n); - -/* shift the packet array by n places. */ -void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n); - - -/* receive and process one packet, returns 1 if received seq_num is considered - * new, 0 if old */ -char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff, - int8_t set_mark); - -/* count the hamming weight, how many good packets did we receive? */ -int bit_packet_count(TYPE_OF_WORD *seq_bits); diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c deleted file mode 100644 index 32204b5572d..00000000000 --- a/drivers/staging/batman-adv/device.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * 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 <linux/device.h> -#include <linux/slab.h> -#include "main.h" -#include "device.h" -#include "send.h" -#include "types.h" -#include "hash.h" -#include "hard-interface.h" - -static struct class *batman_class; - -static int Major; /* Major number assigned to our device driver */ - -static const struct file_operations fops = { - .open = bat_device_open, - .release = bat_device_release, - .read = bat_device_read, - .write = bat_device_write, - .poll = bat_device_poll, -}; - -static struct device_client *device_client_hash[256]; - -void bat_device_init(void) -{ - memset(device_client_hash, 0, sizeof(device_client_hash)); -} - -int bat_device_setup(void) -{ - int tmp_major; - - if (Major) - return 1; - - /* register our device - kernel assigns a free major number */ - tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops); - if (tmp_major < 0) { - printk(KERN_ERR "batman-adv:" - "Registering the character device failed with %d\n", - tmp_major); - return 0; - } - - batman_class = class_create(THIS_MODULE, "batman-adv"); - - if (IS_ERR(batman_class)) { - printk(KERN_ERR "batman-adv:" - "Could not register class 'batman-adv'\n"); - return 0; - } - - device_create(batman_class, NULL, MKDEV(tmp_major, 0), NULL, - "batman-adv"); - - Major = tmp_major; - return 1; -} - -void bat_device_destroy(void) -{ - if (!Major) - return; - - device_destroy(batman_class, MKDEV(Major, 0)); - class_destroy(batman_class); - - /* Unregister the device */ - unregister_chrdev(Major, DRIVER_DEVICE); - - Major = 0; -} - -int bat_device_open(struct inode *inode, struct file *file) -{ - unsigned int i; - struct device_client *device_client; - - device_client = kmalloc(sizeof(struct device_client), GFP_KERNEL); - - if (!device_client) - return -ENOMEM; - - for (i = 0; i < ARRAY_SIZE(device_client_hash); i++) { - if (!device_client_hash[i]) { - device_client_hash[i] = device_client; - break; - } - } - - if (i == ARRAY_SIZE(device_client_hash)) { - printk(KERN_ERR "batman-adv:" - "Error - can't add another packet client: " - "maximum number of clients reached\n"); - kfree(device_client); - return -EXFULL; - } - - INIT_LIST_HEAD(&device_client->queue_list); - device_client->queue_len = 0; - device_client->index = i; - spin_lock_init(&device_client->lock); - init_waitqueue_head(&device_client->queue_wait); - - file->private_data = device_client; - - inc_module_count(); - return 0; -} - -int bat_device_release(struct inode *inode, struct file *file) -{ - struct device_client *device_client = - (struct device_client *)file->private_data; - struct device_packet *device_packet; - struct list_head *list_pos, *list_pos_tmp; - unsigned long flags; - - spin_lock_irqsave(&device_client->lock, flags); - - /* for all packets in the queue ... */ - list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) { - device_packet = list_entry(list_pos, - struct device_packet, list); - - list_del(list_pos); - kfree(device_packet); - } - - device_client_hash[device_client->index] = NULL; - spin_unlock_irqrestore(&device_client->lock, flags); - - kfree(device_client); - dec_module_count(); - - return 0; -} - -ssize_t bat_device_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - struct device_client *device_client = - (struct device_client *)file->private_data; - struct device_packet *device_packet; - int error; - unsigned long flags; - - if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0)) - return -EAGAIN; - - if ((!buf) || (count < sizeof(struct icmp_packet))) - return -EINVAL; - - if (!access_ok(VERIFY_WRITE, buf, count)) - return -EFAULT; - - error = wait_event_interruptible(device_client->queue_wait, - device_client->queue_len); - - if (error) - return error; - - spin_lock_irqsave(&device_client->lock, flags); - - device_packet = list_first_entry(&device_client->queue_list, - struct device_packet, list); - list_del(&device_packet->list); - device_client->queue_len--; - - spin_unlock_irqrestore(&device_client->lock, flags); - - error = __copy_to_user(buf, &device_packet->icmp_packet, - sizeof(struct icmp_packet)); - - kfree(device_packet); - - if (error) - return -EFAULT; - - return sizeof(struct icmp_packet); -} - -ssize_t bat_device_write(struct file *file, const char __user *buff, - size_t len, loff_t *off) -{ - struct device_client *device_client = - (struct device_client *)file->private_data; - struct icmp_packet icmp_packet; - struct orig_node *orig_node; - struct batman_if *batman_if; - uint8_t dstaddr[ETH_ALEN]; - unsigned long flags; - - if (len < sizeof(struct icmp_packet)) { - bat_dbg(DBG_BATMAN, "batman-adv:" - "Error - can't send packet from char device: " - "invalid packet size\n"); - return -EINVAL; - } - - if (!access_ok(VERIFY_READ, buff, sizeof(struct icmp_packet))) - return -EFAULT; - - if (__copy_from_user(&icmp_packet, buff, sizeof(icmp_packet))) - return -EFAULT; - - if (icmp_packet.packet_type != BAT_ICMP) { - bat_dbg(DBG_BATMAN, "batman-adv:" - "Error - can't send packet from char device: " - "got bogus packet type (expected: BAT_ICMP)\n"); - return -EINVAL; - } - - if (icmp_packet.msg_type != ECHO_REQUEST) { - bat_dbg(DBG_BATMAN, "batman-adv:" - "Error - can't send packet from char device: " - "got bogus message type (expected: ECHO_REQUEST)\n"); - return -EINVAL; - } - - icmp_packet.uid = device_client->index; - - if (icmp_packet.version != COMPAT_VERSION) { - icmp_packet.msg_type = PARAMETER_PROBLEM; - icmp_packet.ttl = COMPAT_VERSION; - bat_device_add_packet(device_client, &icmp_packet); - goto out; - } - - if (atomic_read(&module_state) != MODULE_ACTIVE) - goto dst_unreach; - - spin_lock_irqsave(&orig_hash_lock, flags); - orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst)); - - if (!orig_node) - goto unlock; - - if (!orig_node->router) - goto unlock; - - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - - spin_unlock_irqrestore(&orig_hash_lock, flags); - - if (!batman_if) - goto dst_unreach; - - if (batman_if->if_status != IF_ACTIVE) - goto dst_unreach; - - memcpy(icmp_packet.orig, - batman_if->net_dev->dev_addr, - ETH_ALEN); - - send_raw_packet((unsigned char *)&icmp_packet, - sizeof(struct icmp_packet), - batman_if, dstaddr); - - goto out; - -unlock: - spin_unlock_irqrestore(&orig_hash_lock, flags); -dst_unreach: - icmp_packet.msg_type = DESTINATION_UNREACHABLE; - bat_device_add_packet(device_client, &icmp_packet); -out: - return len; -} - -unsigned int bat_device_poll(struct file *file, poll_table *wait) -{ - struct device_client *device_client = - (struct device_client *)file->private_data; - - poll_wait(file, &device_client->queue_wait, wait); - - if (device_client->queue_len > 0) - return POLLIN | POLLRDNORM; - - return 0; -} - -void bat_device_add_packet(struct device_client *device_client, - struct icmp_packet *icmp_packet) -{ - struct device_packet *device_packet; - unsigned long flags; - - device_packet = kmalloc(sizeof(struct device_packet), GFP_ATOMIC); - - if (!device_packet) - return; - - INIT_LIST_HEAD(&device_packet->list); - memcpy(&device_packet->icmp_packet, icmp_packet, - sizeof(struct icmp_packet)); - - spin_lock_irqsave(&device_client->lock, flags); - - /* while waiting for the lock the device_client could have been - * deleted */ - if (!device_client_hash[icmp_packet->uid]) { - spin_unlock_irqrestore(&device_client->lock, flags); - kfree(device_packet); - return; - } - - list_add_tail(&device_packet->list, &device_client->queue_list); - device_client->queue_len++; - - if (device_client->queue_len > 100) { - device_packet = list_first_entry(&device_client->queue_list, - struct device_packet, list); - - list_del(&device_packet->list); - kfree(device_packet); - device_client->queue_len--; - } - - spin_unlock_irqrestore(&device_client->lock, flags); - - wake_up(&device_client->queue_wait); -} - -void bat_device_receive_packet(struct icmp_packet *icmp_packet) -{ - struct device_client *hash = device_client_hash[icmp_packet->uid]; - - if (hash) - bat_device_add_packet(hash, icmp_packet); -} diff --git a/drivers/staging/batman-adv/device.h b/drivers/staging/batman-adv/device.h deleted file mode 100644 index eb14b371cea..00000000000 --- a/drivers/staging/batman-adv/device.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * 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 "types.h" - -void bat_device_init(void); -int bat_device_setup(void); -void bat_device_destroy(void); -int bat_device_open(struct inode *inode, struct file *file); -int bat_device_release(struct inode *inode, struct file *file); -ssize_t bat_device_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos); -ssize_t bat_device_write(struct file *file, const char __user *buff, - size_t len, loff_t *off); -unsigned int bat_device_poll(struct file *file, poll_table *wait); -void bat_device_add_packet(struct device_client *device_client, - struct icmp_packet *icmp_packet); -void bat_device_receive_packet(struct icmp_packet *icmp_packet); diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c deleted file mode 100644 index 7a582e80de1..00000000000 --- a/drivers/staging/batman-adv/hard-interface.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * 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> - -#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->br_port != NULL) - 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 = 0; - 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) -{ - 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; - - printk(KERN_WARNING "batman-adv:" - "The newly added mac address (%pM) already exists on: %s\n", - addr, batman_if->dev); - printk(KERN_WARNING "batman-adv:" - "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 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); - - printk(KERN_INFO "batman-adv: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 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; - - printk(KERN_INFO "batman-adv: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) { - printk(KERN_ERR "batman-adv:" - "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); - printk(KERN_INFO "batman-adv:Adding interface: %s\n", batman_if->dev); - - if (hardif_is_iface_up(batman_if)) - hardif_activate_interface(bat_priv, batman_if); - else - printk(KERN_ERR "batman-adv:" - "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(batman_if); - - if (batman_if->if_status != IF_INACTIVE) - return; - - printk(KERN_INFO "batman-adv: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; - - batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); - if (!batman_if) { - printk(KERN_ERR "batman-adv:" - "Can't add interface (%s): out of memory\n", - net_dev->name); - goto out; - } - - 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; - 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); -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); - 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) - goto out; - - switch (event) { - case NETDEV_REGISTER: - break; - case NETDEV_UP: - hardif_activate_interface(bat_priv, batman_if); - break; - case NETDEV_GOING_DOWN: - case NETDEV_DOWN: - hardif_deactivate_interface(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; -} - -/* 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 batman_packet *batman_packet; - struct batman_if *batman_if; - struct net_device_stats *stats; - 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; - - /* 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; - - stats = (struct net_device_stats *)dev_get_stats(skb->dev); - if (stats) { - stats->rx_packets++; - stats->rx_bytes += skb->len; - } - - batman_packet = (struct batman_packet *)skb->data; - - if (batman_packet->version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, - "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); - 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, -}; diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h deleted file mode 100644 index 1e5fc3e720f..00000000000 --- a/drivers/staging/batman-adv/hard-interface.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 - * - */ - -#define IF_NOT_IN_USE 0 -#define IF_TO_BE_REMOVED 1 -#define IF_INACTIVE 2 -#define IF_ACTIVE 3 -#define IF_TO_BE_ACTIVATED 4 -#define IF_I_WANT_YOU 5 - -extern struct notifier_block hard_if_notifier; - -struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev); -int hardif_enable_interface(struct batman_if *batman_if); -void hardif_disable_interface(struct batman_if *batman_if); -void hardif_remove_interfaces(void); -int batman_skb_recv(struct sk_buff *skb, - struct net_device *dev, - struct packet_type *ptype, - struct net_device *orig_dev); -int hardif_min_mtu(void); -void update_min_mtu(void); diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c deleted file mode 100644 index d4a4adc5704..00000000000 --- a/drivers/staging/batman-adv/hash.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * 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 "hash.h" - -/* clears the hash */ -void hash_init(struct hashtable_t *hash) -{ - int i; - - hash->elements = 0; - - for (i = 0 ; i < hash->size; i++) - hash->table[i] = NULL; -} - -/* remove the hash structure. if hashdata_free_cb != NULL, this function will be - * called to remove the elements inside of the hash. if you don't remove the - * elements, memory might be leaked. */ -void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb) -{ - struct element_t *bucket, *last_bucket; - int i; - - for (i = 0; i < hash->size; i++) { - bucket = hash->table[i]; - - while (bucket != NULL) { - if (free_cb != NULL) - free_cb(bucket->data); - - last_bucket = bucket; - bucket = bucket->next; - kfree(last_bucket); - } - } - - hash_destroy(hash); -} - -/* free only the hashtable and the hash itself. */ -void hash_destroy(struct hashtable_t *hash) -{ - kfree(hash->table); - kfree(hash); -} - -/* iterate though the hash. First element is selected if an iterator - * initialized with HASHIT() is supplied as iter. Use the returned - * (or supplied) iterator to access the elements until hash_iterate returns - * NULL. */ - -struct hash_it_t *hash_iterate(struct hashtable_t *hash, - struct hash_it_t *iter) -{ - if (!hash) - return NULL; - if (!iter) - return NULL; - - /* sanity checks first (if our bucket got deleted in the last - * iteration): */ - if (iter->bucket != NULL) { - if (iter->first_bucket != NULL) { - /* we're on the first element and it got removed after - * the last iteration. */ - if ((*iter->first_bucket) != iter->bucket) { - /* there are still other elements in the list */ - if ((*iter->first_bucket) != NULL) { - iter->prev_bucket = NULL; - iter->bucket = (*iter->first_bucket); - iter->first_bucket = - &hash->table[iter->index]; - return iter; - } else { - iter->bucket = NULL; - } - } - } else if (iter->prev_bucket != NULL) { - /* - * we're not on the first element, and the bucket got - * removed after the last iteration. the last bucket's - * next pointer is not pointing to our actual bucket - * anymore. select the next. - */ - if (iter->prev_bucket->next != iter->bucket) - iter->bucket = iter->prev_bucket; - } - } - - /* now as we are sane, select the next one if there is some */ - if (iter->bucket != NULL) { - if (iter->bucket->next != NULL) { - iter->prev_bucket = iter->bucket; - iter->bucket = iter->bucket->next; - iter->first_bucket = NULL; - return iter; - } - } - - /* if not returned yet, we've reached the last one on the index and have - * to search forward */ - iter->index++; - /* go through the entries of the hash table */ - while (iter->index < hash->size) { - if ((hash->table[iter->index]) != NULL) { - iter->prev_bucket = NULL; - iter->bucket = hash->table[iter->index]; - iter->first_bucket = &hash->table[iter->index]; - return iter; - } else { - iter->index++; - } - } - - /* nothing to iterate over anymore */ - return NULL; -} - -/* allocates and clears the hash */ -struct hashtable_t *hash_new(int size, hashdata_compare_cb compare, - hashdata_choose_cb choose) -{ - struct hashtable_t *hash; - - hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC); - - if (hash == NULL) - return NULL; - - hash->size = size; - hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC); - - if (hash->table == NULL) { - kfree(hash); - return NULL; - } - - hash_init(hash); - - hash->compare = compare; - hash->choose = choose; - - return hash; -} - -/* adds data to the hashtable. returns 0 on success, -1 on error */ -int hash_add(struct hashtable_t *hash, void *data) -{ - int index; - struct element_t *bucket, *prev_bucket = NULL; - - if (!hash) - return -1; - - index = hash->choose(data, hash->size); - bucket = hash->table[index]; - - while (bucket != NULL) { - if (hash->compare(bucket->data, data)) - return -1; - - prev_bucket = bucket; - bucket = bucket->next; - } - - /* found the tail of the list, add new element */ - bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); - - if (bucket == NULL) - return -1; - - bucket->data = data; - bucket->next = NULL; - - /* and link it */ - if (prev_bucket == NULL) - hash->table[index] = bucket; - else - prev_bucket->next = bucket; - - hash->elements++; - return 0; -} - -/* finds data, based on the key in keydata. returns the found data on success, - * or NULL on error */ -void *hash_find(struct hashtable_t *hash, void *keydata) -{ - int index; - struct element_t *bucket; - - if (!hash) - return NULL; - - index = hash->choose(keydata , hash->size); - bucket = hash->table[index]; - - while (bucket != NULL) { - if (hash->compare(bucket->data, keydata)) - return bucket->data; - - bucket = bucket->next; - } - - return NULL; -} - -/* remove bucket (this might be used in hash_iterate() if you already found the - * bucket you want to delete and don't need the overhead to find it again with - * hash_remove(). But usually, you don't want to use this function, as it - * fiddles with hash-internals. */ -void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t) -{ - void *data_save; - - data_save = hash_it_t->bucket->data; - - if (hash_it_t->prev_bucket != NULL) - hash_it_t->prev_bucket->next = hash_it_t->bucket->next; - else if (hash_it_t->first_bucket != NULL) - (*hash_it_t->first_bucket) = hash_it_t->bucket->next; - - kfree(hash_it_t->bucket); - hash->elements--; - - return data_save; -} - -/* removes data from hash, if found. returns pointer do data on success, so you - * can remove the used structure yourself, or NULL on error . data could be the - * structure you use with just the key filled, we just need the key for - * comparing. */ -void *hash_remove(struct hashtable_t *hash, void *data) -{ - struct hash_it_t hash_it_t; - - hash_it_t.index = hash->choose(data, hash->size); - hash_it_t.bucket = hash->table[hash_it_t.index]; - hash_it_t.prev_bucket = NULL; - - while (hash_it_t.bucket != NULL) { - if (hash->compare(hash_it_t.bucket->data, data)) { - hash_it_t.first_bucket = - (hash_it_t.bucket == - hash->table[hash_it_t.index] ? - &hash->table[hash_it_t.index] : NULL); - return hash_remove_bucket(hash, &hash_it_t); - } - - hash_it_t.prev_bucket = hash_it_t.bucket; - hash_it_t.bucket = hash_it_t.bucket->next; - } - - return NULL; -} - -/* resize the hash, returns the pointer to the new hash or NULL on - * error. removes the old hash on success. */ -struct hashtable_t *hash_resize(struct hashtable_t *hash, int size) -{ - struct hashtable_t *new_hash; - struct element_t *bucket; - int i; - - /* initialize a new hash with the new size */ - new_hash = hash_new(size, hash->compare, hash->choose); - - if (new_hash == NULL) - return NULL; - - /* copy the elements */ - for (i = 0; i < hash->size; i++) { - bucket = hash->table[i]; - - while (bucket != NULL) { - hash_add(new_hash, bucket->data); - bucket = bucket->next; - } - } - - /* remove hash and eventual overflow buckets but not the content - * itself. */ - hash_delete(hash, NULL); - - return new_hash; -} diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h deleted file mode 100644 index ea6d21e0125..00000000000 --- a/drivers/staging/batman-adv/hash.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * 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 _BATMAN_HASH_H -#define _BATMAN_HASH_H -#define HASHIT(name) struct hash_it_t name = { \ - .index = -1, .bucket = NULL, \ - .prev_bucket = NULL, \ - .first_bucket = NULL } - - -typedef int (*hashdata_compare_cb)(void *, void *); -typedef int (*hashdata_choose_cb)(void *, int); -typedef void (*hashdata_free_cb)(void *); - -struct element_t { - void *data; /* pointer to the data */ - struct element_t *next; /* overflow bucket pointer */ -}; - -struct hash_it_t { - int index; - struct element_t *bucket; - struct element_t *prev_bucket; - struct element_t **first_bucket; -}; - -struct hashtable_t { - struct element_t **table; /* the hashtable itself, with the buckets */ - int elements; /* number of elements registered */ - int size; /* size of hashtable */ - hashdata_compare_cb compare;/* callback to a compare function. should - * compare 2 element datas for their keys, - * return 0 if same and not 0 if not - * same */ - hashdata_choose_cb choose; /* the hashfunction, should return an index - * based on the key in the data of the first - * argument and the size the second */ -}; - -/* clears the hash */ -void hash_init(struct hashtable_t *hash); - -/* allocates and clears the hash */ -struct hashtable_t *hash_new(int size, hashdata_compare_cb compare, - hashdata_choose_cb choose); - -/* remove bucket (this might be used in hash_iterate() if you already found the - * bucket you want to delete and don't need the overhead to find it again with - * hash_remove(). But usually, you don't want to use this function, as it - * fiddles with hash-internals. */ -void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t); - -/* remove the hash structure. if hashdata_free_cb != NULL, this function will be - * called to remove the elements inside of the hash. if you don't remove the - * elements, memory might be leaked. */ -void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb); - -/* free only the hashtable and the hash itself. */ -void hash_destroy(struct hashtable_t *hash); - -/* adds data to the hashtable. returns 0 on success, -1 on error */ -int hash_add(struct hashtable_t *hash, void *data); - -/* removes data from hash, if found. returns pointer do data on success, so you - * can remove the used structure yourself, or NULL on error . data could be the - * structure you use with just the key filled, we just need the key for - * comparing. */ -void *hash_remove(struct hashtable_t *hash, void *data); - -/* finds data, based on the key in keydata. returns the found data on success, - * or NULL on error */ -void *hash_find(struct hashtable_t *hash, void *keydata); - -/* resize the hash, returns the pointer to the new hash or NULL on - * error. removes the old hash on success */ -struct hashtable_t *hash_resize(struct hashtable_t *hash, int size); - -/* iterate though the hash. first element is selected with iter_in NULL. use - * the returned iterator to access the elements until hash_it_t returns NULL. */ -struct hash_it_t *hash_iterate(struct hashtable_t *hash, - struct hash_it_t *iter_in); - -/* print the hash table for debugging */ -void hash_debug(struct hashtable_t *hash); -#endif diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c deleted file mode 100644 index 74c70d589a9..00000000000 --- a/drivers/staging/batman-adv/main.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * 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 "bat_sysfs.h" -#include "routing.h" -#include "send.h" -#include "originator.h" -#include "soft-interface.h" -#include "device.h" -#include "translation-table.h" -#include "hard-interface.h" -#include "types.h" -#include "vis.h" -#include "hash.h" - -struct list_head if_list; -struct hlist_head forw_bat_list; -struct hlist_head forw_bcast_list; -struct hashtable_t *orig_hash; - -DEFINE_SPINLOCK(orig_hash_lock); -DEFINE_SPINLOCK(forw_bat_list_lock); -DEFINE_SPINLOCK(forw_bcast_list_lock); - -atomic_t vis_interval; -atomic_t bcast_queue_left; -atomic_t batman_queue_left; - -int16_t num_hna; - -struct net_device *soft_device; - -unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -atomic_t module_state; - -static struct packet_type batman_adv_packet_type __read_mostly = { - .type = __constant_htons(ETH_P_BATMAN), - .func = batman_skb_recv, -}; - -struct workqueue_struct *bat_event_workqueue; - -#ifdef CONFIG_BATMAN_ADV_DEBUG -int debug; - -module_param(debug, int, 0644); - -int bat_debug_type(int type) -{ - return debug & type; -} -#endif - -int init_module(void) -{ - int retval; - - INIT_LIST_HEAD(&if_list); - INIT_HLIST_HEAD(&forw_bat_list); - INIT_HLIST_HEAD(&forw_bcast_list); - - atomic_set(&module_state, MODULE_INACTIVE); - - atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only - * for debugging now. */ - atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN); - atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN); - - /* the name should not be longer than 10 chars - see - * http://lwn.net/Articles/23634/ */ - bat_event_workqueue = create_singlethread_workqueue("bat_events"); - - if (!bat_event_workqueue) - return -ENOMEM; - - bat_device_init(); - - /* initialize layer 2 interface */ - soft_device = alloc_netdev(sizeof(struct bat_priv) , "bat%d", - interface_setup); - - if (!soft_device) { - printk(KERN_ERR "batman-adv:" - "Unable to allocate the batman interface\n"); - goto end; - } - - retval = register_netdev(soft_device); - - if (retval < 0) { - printk(KERN_ERR "batman-adv:" - "Unable to register the batman interface: %i\n", retval); - goto free_soft_device; - } - - retval = sysfs_add_meshif(soft_device); - - if (retval < 0) - goto unreg_soft_device; - - register_netdevice_notifier(&hard_if_notifier); - dev_add_pack(&batman_adv_packet_type); - - printk(KERN_INFO "batman-adv:" - "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n", - SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION); - - return 0; - -unreg_soft_device: - unregister_netdev(soft_device); - soft_device = NULL; - return -ENOMEM; - -free_soft_device: - free_netdev(soft_device); - soft_device = NULL; -end: - return -ENOMEM; -} - -void cleanup_module(void) -{ - deactivate_module(); - - unregister_netdevice_notifier(&hard_if_notifier); - hardif_remove_interfaces(); - - if (soft_device) { - sysfs_del_meshif(soft_device); - unregister_netdev(soft_device); - soft_device = NULL; - } - - dev_remove_pack(&batman_adv_packet_type); - - destroy_workqueue(bat_event_workqueue); - bat_event_workqueue = NULL; -} - -/* activates the module, creates bat device, starts timer ... */ -void activate_module(void) -{ - if (originator_init() < 1) - goto err; - - if (hna_local_init() < 1) - goto err; - - if (hna_global_init() < 1) - goto err; - - hna_local_add(soft_device->dev_addr); - - if (bat_device_setup() < 1) - goto end; - - if (vis_init() < 1) - goto err; - - update_min_mtu(); - atomic_set(&module_state, MODULE_ACTIVE); - goto end; - -err: - printk(KERN_ERR "batman-adv:" - "Unable to allocate memory for mesh information structures: " - "out of mem ?\n"); - deactivate_module(); -end: - return; -} - -/* shuts down the whole module.*/ -void deactivate_module(void) -{ - atomic_set(&module_state, MODULE_DEACTIVATING); - - purge_outstanding_packets(NULL); - flush_workqueue(bat_event_workqueue); - - vis_quit(); - - /* TODO: unregister BATMAN pack */ - - originator_free(); - - hna_local_free(); - hna_global_free(); - - synchronize_net(); - bat_device_destroy(); - - synchronize_rcu(); - atomic_set(&module_state, MODULE_INACTIVE); -} - -void inc_module_count(void) -{ - try_module_get(THIS_MODULE); -} - -void dec_module_count(void) -{ - module_put(THIS_MODULE); -} - -int addr_to_string(char *buff, uint8_t *addr) -{ - return sprintf(buff, MAC_FMT, - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); -} - -/* returns 1 if they are the same originator */ - -int compare_orig(void *data1, void *data2) -{ - return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); -} - -/* hashfunction to choose an entry in a hash table of given size */ -/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ -int choose_orig(void *data, int32_t size) -{ - unsigned char *key = data; - uint32_t hash = 0; - size_t i; - - for (i = 0; i < 6; i++) { - hash += key[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash % size; -} - -int is_my_mac(uint8_t *addr) -{ - struct batman_if *batman_if; - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if ((batman_if->net_dev) && - (compare_orig(batman_if->net_dev->dev_addr, addr))) { - rcu_read_unlock(); - return 1; - } - } - rcu_read_unlock(); - return 0; - -} - -int is_bcast(uint8_t *addr) -{ - return (addr[0] == (uint8_t)0xff) && (addr[1] == (uint8_t)0xff); -} - -int is_mcast(uint8_t *addr) -{ - return *addr & 0x01; -} - -MODULE_LICENSE("GPL"); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE); -#ifdef REVISION_VERSION -MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION); -#else -MODULE_VERSION(SOURCE_VERSION); -#endif diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h deleted file mode 100644 index 5f8343d360f..00000000000 --- a/drivers/staging/batman-adv/main.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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 - * - */ - -/* Kernel Programming */ -#define LINUX - -#define DRIVER_AUTHOR "Marek Lindner <lindner_marek@yahoo.de>, " \ - "Simon Wunderlich <siwu@hrz.tu-chemnitz.de>" -#define DRIVER_DESC "B.A.T.M.A.N. advanced" -#define DRIVER_DEVICE "batman-adv" - -#define SOURCE_VERSION "0.2.2-beta" - - -/* B.A.T.M.A.N. parameters */ - -#define TQ_MAX_VALUE 255 -#define JITTER 20 -#define TTL 50 /* Time To Live of broadcast messages */ - -#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no - * valid packet comes in -> TODO: check - * influence on TQ_LOCAL_WINDOW_SIZE */ -#define LOCAL_HNA_TIMEOUT 3600000 - -#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator - * messages in squence numbers (should be a - * multiple of our word size) */ -#define TQ_GLOBAL_WINDOW_SIZE 5 -#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1 -#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1 -#define TQ_TOTAL_BIDRECT_LIMIT 1 - -#define TQ_HOP_PENALTY 10 - -#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE) - -#define PACKBUFF_SIZE 2000 -#define LOG_BUF_LEN 8192 /* has to be a power of 2 */ -#define ETH_STR_LEN 20 - -#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or - * change the size of - * forw_packet->direct_link_flags */ -#define MAX_AGGREGATION_MS 100 - -#define RESET_PROTECTION_MS 30000 -#define EXPECTED_SEQNO_RANGE 4096 -/* don't reset again within 30 seconds */ - -#define MODULE_INACTIVE 0 -#define MODULE_ACTIVE 1 -#define MODULE_DEACTIVATING 2 - -#define BCAST_QUEUE_LEN 256 -#define BATMAN_QUEUE_LEN 256 - -/* - * Debug Messages - */ - -#define DBG_BATMAN 1 /* all messages related to routing / flooding / - * broadcasting / etc */ -#define DBG_ROUTES 2 /* route or hna added / changed / deleted */ - -#ifdef CONFIG_BATMAN_ADV_DEBUG -extern int debug; - -extern int bat_debug_type(int type); -#define bat_dbg(type, fmt, arg...) do { \ - if (bat_debug_type(type)) \ - printk(KERN_DEBUG "batman-adv:" fmt, ## arg); \ - } \ - while (0) -#else /* !CONFIG_BATMAN_ADV_DEBUG */ -#define bat_dbg(type, fmt, arg...) do { \ - } \ - while (0) -#endif - -/* - * Vis - */ - -/* #define VIS_SUBCLUSTERS_DISABLED */ - -/* - * Kernel headers - */ - -#include <linux/mutex.h> /* mutex */ -#include <linux/module.h> /* needed by all modules */ -#include <linux/netdevice.h> /* netdevice */ -#include <linux/if_ether.h> /* ethernet header */ -#include <linux/poll.h> /* poll_table */ -#include <linux/kthread.h> /* kernel threads */ -#include <linux/pkt_sched.h> /* schedule types */ -#include <linux/workqueue.h> /* workqueue */ -#include <linux/slab.h> -#include <net/sock.h> /* struct sock */ -#include <linux/jiffies.h> -#include "types.h" - -#ifndef REVISION_VERSION -#define REVISION_VERSION_STR "" -#else -#define REVISION_VERSION_STR " "REVISION_VERSION -#endif - -extern struct list_head if_list; -extern struct hlist_head forw_bat_list; -extern struct hlist_head forw_bcast_list; -extern struct hashtable_t *orig_hash; - -extern spinlock_t orig_hash_lock; -extern spinlock_t forw_bat_list_lock; -extern spinlock_t forw_bcast_list_lock; - -extern atomic_t vis_interval; -extern atomic_t bcast_queue_left; -extern atomic_t batman_queue_left; -extern int16_t num_hna; - -extern struct net_device *soft_device; - -extern unsigned char broadcastAddr[]; -extern atomic_t module_state; -extern struct workqueue_struct *bat_event_workqueue; - -void activate_module(void); -void deactivate_module(void); -void inc_module_count(void); -void dec_module_count(void); -int addr_to_string(char *buff, uint8_t *addr); -int compare_orig(void *data1, void *data2); -int choose_orig(void *data, int32_t size); -int is_my_mac(uint8_t *addr); -int is_bcast(uint8_t *addr); -int is_mcast(uint8_t *addr); diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c deleted file mode 100644 index 568aef8371b..00000000000 --- a/drivers/staging/batman-adv/originator.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright (C) 2009-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 - * - */ - -/* increase the reference counter for this originator */ - -#include "main.h" -#include "originator.h" -#include "hash.h" -#include "translation-table.h" -#include "routing.h" -#include "hard-interface.h" - -static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig); - -static void start_purge_timer(void) -{ - queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ); -} - -int originator_init(void) -{ - unsigned long flags; - if (orig_hash) - return 1; - - spin_lock_irqsave(&orig_hash_lock, flags); - orig_hash = hash_new(128, compare_orig, choose_orig); - - if (!orig_hash) - goto err; - - spin_unlock_irqrestore(&orig_hash_lock, flags); - start_purge_timer(); - return 1; - -err: - spin_unlock_irqrestore(&orig_hash_lock, flags); - return 0; -} - -void originator_free(void) -{ - unsigned long flags; - - if (!orig_hash) - return; - - cancel_delayed_work_sync(&purge_orig_wq); - - spin_lock_irqsave(&orig_hash_lock, flags); - hash_delete(orig_hash, free_orig_node); - orig_hash = NULL; - spin_unlock_irqrestore(&orig_hash_lock, flags); -} - -struct neigh_node * -create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, - uint8_t *neigh, struct batman_if *if_incoming) -{ - struct neigh_node *neigh_node; - - bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n"); - - neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC); - if (!neigh_node) - return NULL; - - INIT_LIST_HEAD(&neigh_node->list); - - memcpy(neigh_node->addr, neigh, ETH_ALEN); - neigh_node->orig_node = orig_neigh_node; - neigh_node->if_incoming = if_incoming; - - list_add_tail(&neigh_node->list, &orig_node->neigh_list); - return neigh_node; -} - -void free_orig_node(void *data) -{ - struct list_head *list_pos, *list_pos_tmp; - struct neigh_node *neigh_node; - struct orig_node *orig_node = (struct orig_node *)data; - - /* for all neighbors towards this originator ... */ - list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { - neigh_node = list_entry(list_pos, struct neigh_node, list); - - list_del(list_pos); - kfree(neigh_node); - } - - hna_global_del_orig(orig_node, "originator timed out"); - - kfree(orig_node->bcast_own); - kfree(orig_node->bcast_own_sum); - kfree(orig_node); -} - -/* this function finds or creates an originator entry for the given - * address if it does not exits */ -struct orig_node *get_orig_node(uint8_t *addr) -{ - /* FIXME: each batman_if will be attached to a softif */ - struct bat_priv *bat_priv = netdev_priv(soft_device); - struct orig_node *orig_node; - struct hashtable_t *swaphash; - int size; - - orig_node = ((struct orig_node *)hash_find(orig_hash, addr)); - - if (orig_node != NULL) - return orig_node; - - bat_dbg(DBG_BATMAN, "Creating new originator: %pM\n", addr); - - orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC); - if (!orig_node) - return NULL; - - INIT_LIST_HEAD(&orig_node->neigh_list); - - memcpy(orig_node->orig, addr, ETH_ALEN); - orig_node->router = NULL; - orig_node->hna_buff = NULL; - orig_node->bcast_seqno_reset = jiffies - 1 - - msecs_to_jiffies(RESET_PROTECTION_MS); - orig_node->batman_seqno_reset = jiffies - 1 - - msecs_to_jiffies(RESET_PROTECTION_MS); - - size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS; - - orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); - if (!orig_node->bcast_own) - goto free_orig_node; - - size = bat_priv->num_ifaces * sizeof(uint8_t); - orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); - if (!orig_node->bcast_own_sum) - goto free_bcast_own; - - if (hash_add(orig_hash, orig_node) < 0) - goto free_bcast_own_sum; - - if (orig_hash->elements * 4 > orig_hash->size) { - swaphash = hash_resize(orig_hash, orig_hash->size * 2); - - if (swaphash == NULL) - printk(KERN_ERR - "batman-adv:Couldn't resize orig hash table\n"); - else - orig_hash = swaphash; - } - - return orig_node; -free_bcast_own_sum: - kfree(orig_node->bcast_own_sum); -free_bcast_own: - kfree(orig_node->bcast_own); -free_orig_node: - kfree(orig_node); - return NULL; -} - -static bool purge_orig_neighbors(struct orig_node *orig_node, - struct neigh_node **best_neigh_node) -{ - struct list_head *list_pos, *list_pos_tmp; - struct neigh_node *neigh_node; - bool neigh_purged = false; - - *best_neigh_node = NULL; - - /* for all neighbors towards this originator ... */ - list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { - neigh_node = list_entry(list_pos, struct neigh_node, list); - - if ((time_after(jiffies, - (neigh_node->last_valid + - ((PURGE_TIMEOUT * HZ) / 1000)))) || - (neigh_node->if_incoming->if_status == - IF_TO_BE_REMOVED)) { - - if (neigh_node->if_incoming->if_status == - IF_TO_BE_REMOVED) - bat_dbg(DBG_BATMAN, - "neighbor purge: originator %pM, " - "neighbor: %pM, iface: %s\n", - orig_node->orig, neigh_node->addr, - neigh_node->if_incoming->dev); - else - bat_dbg(DBG_BATMAN, - "neighbor timeout: originator %pM, " - "neighbor: %pM, last_valid: %lu\n", - orig_node->orig, neigh_node->addr, - (neigh_node->last_valid / HZ)); - - neigh_purged = true; - list_del(list_pos); - kfree(neigh_node); - } else { - if ((*best_neigh_node == NULL) || - (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) - *best_neigh_node = neigh_node; - } - } - return neigh_purged; -} - -static bool purge_orig_node(struct orig_node *orig_node) -{ - struct neigh_node *best_neigh_node; - - if (time_after(jiffies, - (orig_node->last_valid + - ((2 * PURGE_TIMEOUT * HZ) / 1000)))) { - - bat_dbg(DBG_BATMAN, - "Originator timeout: originator %pM, last_valid %lu\n", - orig_node->orig, (orig_node->last_valid / HZ)); - return true; - } else { - if (purge_orig_neighbors(orig_node, &best_neigh_node)) - update_routes(orig_node, best_neigh_node, - orig_node->hna_buff, - orig_node->hna_buff_len); - } - - return false; -} - -void purge_orig(struct work_struct *work) -{ - HASHIT(hashit); - struct orig_node *orig_node; - unsigned long flags; - - spin_lock_irqsave(&orig_hash_lock, flags); - - /* for all origins... */ - while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit.bucket->data; - if (purge_orig_node(orig_node)) { - hash_remove_bucket(orig_hash, &hashit); - free_orig_node(orig_node); - } - } - - spin_unlock_irqrestore(&orig_hash_lock, flags); - - /* if work == NULL we were not called by the timer - * and thus do not need to re-arm the timer */ - if (work) - start_purge_timer(); -} - -ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, - size_t count, loff_t off) -{ - HASHIT(hashit); - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct orig_node *orig_node; - struct neigh_node *neigh_node; - size_t hdr_len, tmp_len; - int batman_count = 0, bytes_written = 0; - unsigned long flags; - char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; - - if (!bat_priv->primary_if) { - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - - if (bat_priv->primary_if->if_status != IF_ACTIVE && off == 0) - return sprintf(buff, - "BATMAN mesh %s " - "disabled - primary interface not active\n", - net_dev->name); - else if (bat_priv->primary_if->if_status != IF_ACTIVE) - return 0; - - rcu_read_lock(); - hdr_len = sprintf(buff, - " %-14s (%s/%i) %17s [%10s]: %20s " - "... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n", - "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", - "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, - bat_priv->primary_if->dev, bat_priv->primary_if->addr_str, - net_dev->name); - rcu_read_unlock(); - - if (off < hdr_len) - bytes_written = hdr_len; - - spin_lock_irqsave(&orig_hash_lock, flags); - - while (hash_iterate(orig_hash, &hashit)) { - - orig_node = hashit.bucket->data; - - if (!orig_node->router) - continue; - - if (orig_node->router->tq_avg == 0) - continue; - - /* estimated line length */ - if (count < bytes_written + 200) - break; - - addr_to_string(orig_str, orig_node->orig); - addr_to_string(router_str, orig_node->router->addr); - - tmp_len = sprintf(buff + bytes_written, - "%-17s (%3i) %17s [%10s]:", - orig_str, orig_node->router->tq_avg, - router_str, - orig_node->router->if_incoming->dev); - - list_for_each_entry(neigh_node, &orig_node->neigh_list, list) { - addr_to_string(orig_str, neigh_node->addr); - tmp_len += sprintf(buff + bytes_written + tmp_len, - " %17s (%3i)", orig_str, - neigh_node->tq_avg); - } - - tmp_len += sprintf(buff + bytes_written + tmp_len, "\n"); - - batman_count++; - hdr_len += tmp_len; - - if (off >= hdr_len) - continue; - - bytes_written += tmp_len; - } - - spin_unlock_irqrestore(&orig_hash_lock, flags); - - if ((batman_count == 0) && (off == 0)) - bytes_written += sprintf(buff + bytes_written, - "No batman nodes in range ...\n"); - - return bytes_written; -} - -static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) -{ - void *data_ptr; - - data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS, - GFP_ATOMIC); - if (!data_ptr) { - printk(KERN_ERR - "batman-adv:Can't resize orig: out of memory\n"); - return -1; - } - - memcpy(data_ptr, orig_node->bcast_own, - (max_if_num - 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS); - kfree(orig_node->bcast_own); - orig_node->bcast_own = data_ptr; - - data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); - if (!data_ptr) { - printk(KERN_ERR - "batman-adv:Can't resize orig: out of memory\n"); - return -1; - } - - memcpy(data_ptr, orig_node->bcast_own_sum, - (max_if_num - 1) * sizeof(uint8_t)); - kfree(orig_node->bcast_own_sum); - orig_node->bcast_own_sum = data_ptr; - - return 0; -} - -int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) -{ - struct orig_node *orig_node; - HASHIT(hashit); - - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on - * if_num */ - spin_lock(&orig_hash_lock); - - while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit.bucket->data; - - if (orig_node_add_if(orig_node, max_if_num) == -1) - goto err; - } - - spin_unlock(&orig_hash_lock); - return 0; - -err: - spin_unlock(&orig_hash_lock); - return -ENOMEM; -} - -static int orig_node_del_if(struct orig_node *orig_node, - int max_if_num, int del_if_num) -{ - void *data_ptr = NULL; - int chunk_size; - - /* last interface was removed */ - if (max_if_num == 0) - goto free_bcast_own; - - chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS; - data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); - if (!data_ptr) { - printk(KERN_ERR - "batman-adv:Can't resize orig: out of memory\n"); - return -1; - } - - /* copy first part */ - memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); - - /* copy second part */ - memcpy(data_ptr, - orig_node->bcast_own + ((del_if_num + 1) * chunk_size), - (max_if_num - del_if_num) * chunk_size); - -free_bcast_own: - kfree(orig_node->bcast_own); - orig_node->bcast_own = data_ptr; - - if (max_if_num == 0) - goto free_own_sum; - - data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); - if (!data_ptr) { - printk(KERN_ERR - "batman-adv:Can't resize orig: out of memory\n"); - return -1; - } - - memcpy(data_ptr, orig_node->bcast_own_sum, - del_if_num * sizeof(uint8_t)); - - memcpy(data_ptr, - orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)), - (max_if_num - del_if_num) * sizeof(uint8_t)); - -free_own_sum: - kfree(orig_node->bcast_own_sum); - orig_node->bcast_own_sum = data_ptr; - - return 0; -} - -int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) -{ - struct batman_if *batman_if_tmp; - struct orig_node *orig_node; - HASHIT(hashit); - int ret; - - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on - * if_num */ - spin_lock(&orig_hash_lock); - - while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit.bucket->data; - - ret = orig_node_del_if(orig_node, max_if_num, - batman_if->if_num); - - if (ret == -1) - goto err; - } - - /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ - rcu_read_lock(); - list_for_each_entry_rcu(batman_if_tmp, &if_list, list) { - if (batman_if_tmp->if_status == IF_NOT_IN_USE) - continue; - - if (batman_if == batman_if_tmp) - continue; - - if (batman_if_tmp->if_num > batman_if->if_num) - batman_if_tmp->if_num--; - } - rcu_read_unlock(); - - batman_if->if_num = -1; - spin_unlock(&orig_hash_lock); - return 0; - -err: - spin_unlock(&orig_hash_lock); - return -ENOMEM; -} diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h deleted file mode 100644 index afbc7c0e8aa..00000000000 --- a/drivers/staging/batman-adv/originator.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 - * - */ - -int originator_init(void); -void free_orig_node(void *data); -void originator_free(void); -void purge_orig(struct work_struct *work); -struct orig_node *orig_find(char *mac); -struct orig_node *get_orig_node(uint8_t *addr); -struct neigh_node * -create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, - uint8_t *neigh, struct batman_if *if_incoming); -ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, - size_t count, loff_t off); -int orig_hash_add_if(struct batman_if *batman_if, int max_if_num); -int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h deleted file mode 100644 index 152f57b1c6c..00000000000 --- a/drivers/staging/batman-adv/packet.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 - * - */ - -#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ - -#define BAT_PACKET 0x01 -#define BAT_ICMP 0x02 -#define BAT_UNICAST 0x03 -#define BAT_BCAST 0x04 -#define BAT_VIS 0x05 - -/* this file is included by batctl which needs these defines */ -#define COMPAT_VERSION 8 -#define DIRECTLINK 0x40 -#define VIS_SERVER 0x20 - -/* ICMP message types */ -#define ECHO_REPLY 0 -#define DESTINATION_UNREACHABLE 3 -#define ECHO_REQUEST 8 -#define TTL_EXCEEDED 11 -#define PARAMETER_PROBLEM 12 - -/* vis defines */ -#define VIS_TYPE_SERVER_SYNC 0 -#define VIS_TYPE_CLIENT_UPDATE 1 - -struct batman_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */ - uint8_t tq; - uint16_t seqno; - uint8_t orig[6]; - uint8_t prev_sender[6]; - uint8_t ttl; - uint8_t num_hna; -} __attribute__((packed)); - -#define BAT_PACKET_LEN sizeof(struct batman_packet) - -struct icmp_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t msg_type; /* see ICMP message types above */ - uint8_t ttl; - uint8_t dst[6]; - uint8_t orig[6]; - uint16_t seqno; - uint8_t uid; -} __attribute__((packed)); - -struct unicast_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t dest[6]; - uint8_t ttl; -} __attribute__((packed)); - -struct bcast_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t orig[6]; - uint16_t seqno; -} __attribute__((packed)); - -struct vis_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t vis_type; /* which type of vis-participant sent this? */ - uint8_t seqno; /* sequence number */ - uint8_t entries; /* number of entries behind this struct */ - uint8_t ttl; /* TTL */ - uint8_t vis_orig[6]; /* originator that informs about its - * neighbors */ - uint8_t target_orig[6]; /* who should receive this packet */ - uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ -} __attribute__((packed)); diff --git a/drivers/staging/batman-adv/ring_buffer.c b/drivers/staging/batman-adv/ring_buffer.c deleted file mode 100644 index defd37c9be1..00000000000 --- a/drivers/staging/batman-adv/ring_buffer.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * 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 "ring_buffer.h" - -void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value) -{ - lq_recv[*lq_index] = value; - *lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE; -} - -uint8_t ring_buffer_avg(uint8_t lq_recv[]) -{ - uint8_t *ptr; - uint16_t count = 0, i = 0, sum = 0; - - ptr = lq_recv; - - while (i < TQ_GLOBAL_WINDOW_SIZE) { - if (*ptr != 0) { - count++; - sum += *ptr; - } - - i++; - ptr++; - } - - if (count == 0) - return 0; - - return (uint8_t)(sum / count); -} diff --git a/drivers/staging/batman-adv/ring_buffer.h b/drivers/staging/batman-adv/ring_buffer.h deleted file mode 100644 index b8c9456558b..00000000000 --- a/drivers/staging/batman-adv/ring_buffer.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * 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 - * - */ - -void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value); -uint8_t ring_buffer_avg(uint8_t lq_recv[]); diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c deleted file mode 100644 index 066dc8b3881..00000000000 --- a/drivers/staging/batman-adv/routing.c +++ /dev/null @@ -1,1067 +0,0 @@ -/* - * 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 "routing.h" -#include "send.h" -#include "hash.h" -#include "soft-interface.h" -#include "hard-interface.h" -#include "device.h" -#include "translation-table.h" -#include "originator.h" -#include "types.h" -#include "ring_buffer.h" -#include "vis.h" -#include "aggregation.h" - -DECLARE_WAIT_QUEUE_HEAD(thread_wait); - -void slide_own_bcast_window(struct batman_if *batman_if) -{ - HASHIT(hashit); - struct orig_node *orig_node; - TYPE_OF_WORD *word; - unsigned long flags; - - spin_lock_irqsave(&orig_hash_lock, flags); - - while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit.bucket->data; - word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]); - - bit_get_packet(word, 1, 0); - orig_node->bcast_own_sum[batman_if->if_num] = - bit_packet_count(word); - } - - spin_unlock_irqrestore(&orig_hash_lock, flags); -} - -static void update_HNA(struct orig_node *orig_node, - unsigned char *hna_buff, int hna_buff_len) -{ - if ((hna_buff_len != orig_node->hna_buff_len) || - ((hna_buff_len > 0) && - (orig_node->hna_buff_len > 0) && - (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) { - - if (orig_node->hna_buff_len > 0) - hna_global_del_orig(orig_node, - "originator changed hna"); - - if ((hna_buff_len > 0) && (hna_buff != NULL)) - hna_global_add_orig(orig_node, hna_buff, hna_buff_len); - } -} - -static void update_route(struct orig_node *orig_node, - struct neigh_node *neigh_node, - unsigned char *hna_buff, int hna_buff_len) -{ - /* route deleted */ - if ((orig_node->router != NULL) && (neigh_node == NULL)) { - - bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n", - orig_node->orig); - hna_global_del_orig(orig_node, "originator timed out"); - - /* route added */ - } else if ((orig_node->router == NULL) && (neigh_node != NULL)) { - - bat_dbg(DBG_ROUTES, - "Adding route towards: %pM (via %pM)\n", - orig_node->orig, neigh_node->addr); - hna_global_add_orig(orig_node, hna_buff, hna_buff_len); - - /* route changed */ - } else { - bat_dbg(DBG_ROUTES, - "Changing route towards: %pM " - "(now via %pM - was via %pM)\n", - orig_node->orig, neigh_node->addr, - orig_node->router->addr); - } - - orig_node->router = neigh_node; -} - - -void update_routes(struct orig_node *orig_node, - struct neigh_node *neigh_node, - unsigned char *hna_buff, int hna_buff_len) -{ - - if (orig_node == NULL) - return; - - if (orig_node->router != neigh_node) - update_route(orig_node, neigh_node, hna_buff, hna_buff_len); - /* may be just HNA changed */ - else - update_HNA(orig_node, hna_buff, hna_buff_len); -} - -static int isBidirectionalNeigh(struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - struct batman_packet *batman_packet, - struct batman_if *if_incoming) -{ - struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; - unsigned char total_count; - - if (orig_node == orig_neigh_node) { - list_for_each_entry(tmp_neigh_node, - &orig_node->neigh_list, - list) { - - if (compare_orig(tmp_neigh_node->addr, - orig_neigh_node->orig) && - (tmp_neigh_node->if_incoming == if_incoming)) - neigh_node = tmp_neigh_node; - } - - if (!neigh_node) - neigh_node = create_neighbor(orig_node, - orig_neigh_node, - orig_neigh_node->orig, - if_incoming); - /* create_neighbor failed, return 0 */ - if (!neigh_node) - return 0; - - neigh_node->last_valid = jiffies; - } else { - /* find packet count of corresponding one hop neighbor */ - list_for_each_entry(tmp_neigh_node, - &orig_neigh_node->neigh_list, list) { - - if (compare_orig(tmp_neigh_node->addr, - orig_neigh_node->orig) && - (tmp_neigh_node->if_incoming == if_incoming)) - neigh_node = tmp_neigh_node; - } - - if (!neigh_node) - neigh_node = create_neighbor(orig_neigh_node, - orig_neigh_node, - orig_neigh_node->orig, - if_incoming); - /* create_neighbor failed, return 0 */ - if (!neigh_node) - return 0; - } - - orig_node->last_valid = jiffies; - - /* pay attention to not get a value bigger than 100 % */ - total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > - neigh_node->real_packet_count ? - neigh_node->real_packet_count : - orig_neigh_node->bcast_own_sum[if_incoming->if_num]); - - /* 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_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) - orig_neigh_node->tq_own = 0; - else - /* neigh_node->real_packet_count is never zero as we - * only purge old information when getting new - * information */ - orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / - neigh_node->real_packet_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 - */ - orig_neigh_node->tq_asym_penalty = - TQ_MAX_VALUE - - (TQ_MAX_VALUE * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / - (TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE); - - batman_packet->tq = ((batman_packet->tq * - orig_neigh_node->tq_own * - orig_neigh_node->tq_asym_penalty) / - (TQ_MAX_VALUE * TQ_MAX_VALUE)); - - bat_dbg(DBG_BATMAN, - "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_node->real_packet_count, orig_neigh_node->tq_own, - orig_neigh_node->tq_asym_penalty, batman_packet->tq); - - /* if link has the minimum required transmission quality - * consider it bidirectional */ - if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) - return 1; - - return 0; -} - -static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - struct batman_if *if_incoming, - unsigned char *hna_buff, int hna_buff_len, - char is_duplicate) -{ - struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; - int tmp_hna_buff_len; - - bat_dbg(DBG_BATMAN, "update_originator(): " - "Searching and updating originator entry of received packet\n"); - - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { - if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && - (tmp_neigh_node->if_incoming == if_incoming)) { - neigh_node = tmp_neigh_node; - continue; - } - - if (is_duplicate) - continue; - - 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); - } - - if (!neigh_node) { - struct orig_node *orig_tmp; - - orig_tmp = get_orig_node(ethhdr->h_source); - if (!orig_tmp) - return; - - neigh_node = create_neighbor(orig_node, - orig_tmp, - ethhdr->h_source, if_incoming); - if (!neigh_node) - return; - } else - bat_dbg(DBG_BATMAN, - "Updating existing last-hop neighbor of originator\n"); - - orig_node->flags = batman_packet->flags; - neigh_node->last_valid = jiffies; - - ring_buffer_set(neigh_node->tq_recv, - &neigh_node->tq_index, - batman_packet->tq); - neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); - - if (!is_duplicate) { - orig_node->last_ttl = batman_packet->ttl; - neigh_node->last_ttl = batman_packet->ttl; - } - - tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? - batman_packet->num_hna * ETH_ALEN : hna_buff_len); - - /* if this neighbor already is our next hop there is nothing - * to change */ - if (orig_node->router == neigh_node) - goto update_hna; - - /* if this neighbor does not offer a better TQ we won't consider it */ - if ((orig_node->router) && - (orig_node->router->tq_avg > neigh_node->tq_avg)) - goto update_hna; - - /* if the TQ is the same and the link not more symetric we - * won't consider it either */ - if ((orig_node->router) && - ((neigh_node->tq_avg == orig_node->router->tq_avg) && - (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] - >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) - goto update_hna; - - update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len); - return; - -update_hna: - update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len); -} - -/* 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(int16_t seq_num_diff, - unsigned long *last_reset) -{ - if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) - || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - if (time_after(jiffies, *last_reset + - msecs_to_jiffies(RESET_PROTECTION_MS))) { - - *last_reset = jiffies; - bat_dbg(DBG_BATMAN, - "old packet received, start protection\n"); - - return 0; - } else - return 1; - } - 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 char count_real_packets(struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - struct batman_if *if_incoming) -{ - struct orig_node *orig_node; - struct neigh_node *tmp_neigh_node; - char is_duplicate = 0; - int16_t seq_diff; - int need_update = 0; - int set_mark; - - orig_node = get_orig_node(batman_packet->orig); - if (orig_node == NULL) - return 0; - - seq_diff = batman_packet->seqno - orig_node->last_real_seqno; - - /* signalize caller that the packet is to be dropped. */ - if (window_protected(seq_diff, &orig_node->batman_seqno_reset)) - return -1; - - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { - - is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, - orig_node->last_real_seqno, - batman_packet->seqno); - - if (compare_orig(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(tmp_neigh_node->real_bits, - seq_diff, set_mark); - - tmp_neigh_node->real_packet_count = - bit_packet_count(tmp_neigh_node->real_bits); - } - - if (need_update) { - bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d\n", - orig_node->last_real_seqno, batman_packet->seqno); - orig_node->last_real_seqno = batman_packet->seqno; - } - - return is_duplicate; -} - -void receive_bat_packet(struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - unsigned char *hna_buff, int hna_buff_len, - struct batman_if *if_incoming) -{ - struct batman_if *batman_if; - struct orig_node *orig_neigh_node, *orig_node; - char has_directlink_flag; - char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; - char is_broadcast = 0, is_bidirectional, is_single_hop_neigh; - char is_duplicate; - unsigned short 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_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) - 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); - - is_single_hop_neigh = (compare_orig(ethhdr->h_source, - batman_packet->orig) ? 1 : 0); - - bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] " - "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, " - "TTL %d, V %d, IDF %d)\n", - ethhdr->h_source, if_incoming->dev, if_incoming->addr_str, - batman_packet->orig, batman_packet->prev_sender, - batman_packet->seqno, batman_packet->tq, batman_packet->ttl, - batman_packet->version, has_directlink_flag); - - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->if_status != IF_ACTIVE) - continue; - - if (compare_orig(ethhdr->h_source, - batman_if->net_dev->dev_addr)) - is_my_addr = 1; - - if (compare_orig(batman_packet->orig, - batman_if->net_dev->dev_addr)) - is_my_orig = 1; - - if (compare_orig(batman_packet->prev_sender, - batman_if->net_dev->dev_addr)) - is_my_oldorig = 1; - - if (compare_orig(ethhdr->h_source, broadcastAddr)) - is_broadcast = 1; - } - - if (batman_packet->version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, - "Drop packet: incompatible batman version (%i)\n", - batman_packet->version); - return; - } - - if (is_my_addr) { - bat_dbg(DBG_BATMAN, - "Drop packet: received my own broadcast (sender: %pM" - ")\n", - ethhdr->h_source); - return; - } - - if (is_broadcast) { - bat_dbg(DBG_BATMAN, "Drop packet: " - "ignoring all packets with broadcast source addr (sender: %pM" - ")\n", ethhdr->h_source); - return; - } - - if (is_my_orig) { - TYPE_OF_WORD *word; - int offset; - - orig_neigh_node = get_orig_node(ethhdr->h_source); - - if (!orig_neigh_node) - return; - - /* neighbor has to indicate direct link and it has to - * come via the corresponding interface */ - /* if received seqno equals last send seqno save new - * seqno for bidirectional check */ - if (has_directlink_flag && - compare_orig(if_incoming->net_dev->dev_addr, - batman_packet->orig) && - (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { - offset = if_incoming->if_num * NUM_WORDS; - word = &(orig_neigh_node->bcast_own[offset]); - bit_mark(word, 0); - orig_neigh_node->bcast_own_sum[if_incoming->if_num] = - bit_packet_count(word); - } - - bat_dbg(DBG_BATMAN, "Drop packet: " - "originator packet from myself (via neighbor)\n"); - return; - } - - if (is_my_oldorig) { - bat_dbg(DBG_BATMAN, - "Drop packet: ignoring all rebroadcast echos (sender: " - "%pM)\n", ethhdr->h_source); - return; - } - - orig_node = get_orig_node(batman_packet->orig); - if (orig_node == NULL) - return; - - is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); - - if (is_duplicate == -1) { - bat_dbg(DBG_BATMAN, - "Drop packet: packet within seqno protection time " - "(sender: %pM)\n", ethhdr->h_source); - return; - } - - if (batman_packet->tq == 0) { - bat_dbg(DBG_BATMAN, - "Drop packet: originator packet with tq equal 0\n"); - return; - } - - /* avoid temporary routing loops */ - if ((orig_node->router) && - (orig_node->router->orig_node->router) && - (compare_orig(orig_node->router->addr, - batman_packet->prev_sender)) && - !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && - (compare_orig(orig_node->router->addr, - orig_node->router->orig_node->router->addr))) { - bat_dbg(DBG_BATMAN, - "Drop packet: ignoring all rebroadcast packets that " - "may make me loop (sender: %pM)\n", ethhdr->h_source); - return; - } - - /* if sender is a direct neighbor the sender mac equals - * originator mac */ - orig_neigh_node = (is_single_hop_neigh ? - orig_node : get_orig_node(ethhdr->h_source)); - if (orig_neigh_node == NULL) - return; - - /* drop packet if sender is not a direct neighbor and if we - * don't route towards it */ - if (!is_single_hop_neigh && - (orig_neigh_node->router == NULL)) { - bat_dbg(DBG_BATMAN, "Drop packet: OGM via unknown neighbor!\n"); - return; - } - - is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node, - batman_packet, if_incoming); - - /* 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(orig_node, ethhdr, batman_packet, - if_incoming, hna_buff, hna_buff_len, 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, - 1, hna_buff_len, if_incoming); - - bat_dbg(DBG_BATMAN, "Forwarding packet: " - "rebroadcast neighbor packet with direct link flag\n"); - return; - } - - /* multihop originator */ - if (!is_bidirectional) { - bat_dbg(DBG_BATMAN, - "Drop packet: not received via bidirectional link\n"); - return; - } - - if (is_duplicate) { - bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n"); - return; - } - - bat_dbg(DBG_BATMAN, - "Forwarding packet: rebroadcast originator packet\n"); - schedule_forward_packet(orig_node, ethhdr, batman_packet, - 0, hna_buff_len, if_incoming); -} - -int recv_bat_packet(struct sk_buff *skb, - struct batman_if *batman_if) -{ - struct ethhdr *ethhdr; - unsigned long flags; - struct sk_buff *skb_old; - - /* drop packet if it has not necessary minimum size */ - if (skb_headlen(skb) < sizeof(struct batman_packet)) - return NET_RX_DROP; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with broadcast indication but unicast recipient */ - if (!is_bcast(ethhdr->h_dest)) - return NET_RX_DROP; - - /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) - return NET_RX_DROP; - - /* TODO: we use headlen instead of "length", because - * only this data is paged in. */ - - /* create a copy of the skb, if needed, to modify it. */ - if (!skb_clone_writable(skb, skb_headlen(skb))) { - skb_old = skb; - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) - return NET_RX_DROP; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - kfree_skb(skb_old); - } - - spin_lock_irqsave(&orig_hash_lock, flags); - receive_aggr_bat_packet(ethhdr, - skb->data, - skb_headlen(skb), - batman_if); - spin_unlock_irqrestore(&orig_hash_lock, flags); - - kfree_skb(skb); - return NET_RX_SUCCESS; -} - -static int recv_my_icmp_packet(struct sk_buff *skb) -{ - struct orig_node *orig_node; - struct icmp_packet *icmp_packet; - struct ethhdr *ethhdr; - struct sk_buff *skb_old; - struct batman_if *batman_if; - int ret; - unsigned long flags; - uint8_t dstaddr[ETH_ALEN]; - - icmp_packet = (struct icmp_packet *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* add data to device queue */ - if (icmp_packet->msg_type != ECHO_REQUEST) { - bat_device_receive_packet(icmp_packet); - return NET_RX_DROP; - } - - /* answer echo request (ping) */ - /* get routing information */ - spin_lock_irqsave(&orig_hash_lock, flags); - orig_node = ((struct orig_node *)hash_find(orig_hash, - icmp_packet->orig)); - ret = NET_RX_DROP; - - if ((orig_node != NULL) && - (orig_node->router != NULL)) { - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&orig_hash_lock, flags); - - /* create a copy of the skb, if needed, to modify it. */ - skb_old = NULL; - if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) { - skb_old = skb; - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) - return NET_RX_DROP; - - icmp_packet = (struct icmp_packet *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - kfree_skb(skb_old); - } - - memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); - memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); - icmp_packet->msg_type = ECHO_REPLY; - icmp_packet->ttl = TTL; - - send_skb_packet(skb, batman_if, dstaddr); - ret = NET_RX_SUCCESS; - - } else - spin_unlock_irqrestore(&orig_hash_lock, flags); - - return ret; -} - -static int recv_icmp_ttl_exceeded(struct sk_buff *skb) -{ - struct orig_node *orig_node; - struct icmp_packet *icmp_packet; - struct ethhdr *ethhdr; - struct sk_buff *skb_old; - struct batman_if *batman_if; - int ret; - unsigned long flags; - uint8_t dstaddr[ETH_ALEN]; - - icmp_packet = (struct icmp_packet *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* send TTL exceeded if packet is an echo request (traceroute) */ - if (icmp_packet->msg_type != ECHO_REQUEST) { - printk(KERN_WARNING "batman-adv:" - "Warning - can't forward icmp packet from %pM to %pM: " - "ttl exceeded\n", - icmp_packet->orig, icmp_packet->dst); - return NET_RX_DROP; - } - - /* get routing information */ - spin_lock_irqsave(&orig_hash_lock, flags); - orig_node = ((struct orig_node *) - hash_find(orig_hash, icmp_packet->orig)); - ret = NET_RX_DROP; - - if ((orig_node != NULL) && - (orig_node->router != NULL)) { - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&orig_hash_lock, flags); - - /* create a copy of the skb, if needed, to modify it. */ - if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) { - skb_old = skb; - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) - return NET_RX_DROP; - icmp_packet = (struct icmp_packet *) skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - kfree_skb(skb_old); - } - - memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); - memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); - icmp_packet->msg_type = TTL_EXCEEDED; - icmp_packet->ttl = TTL; - - send_skb_packet(skb, batman_if, dstaddr); - ret = NET_RX_SUCCESS; - - } else - spin_unlock_irqrestore(&orig_hash_lock, flags); - - return ret; -} - - -int recv_icmp_packet(struct sk_buff *skb) -{ - struct icmp_packet *icmp_packet; - struct ethhdr *ethhdr; - struct orig_node *orig_node; - struct sk_buff *skb_old; - struct batman_if *batman_if; - int hdr_size = sizeof(struct icmp_packet); - int ret; - unsigned long flags; - uint8_t dstaddr[ETH_ALEN]; - - /* drop packet if it has not necessary minimum size */ - if (skb_headlen(skb) < hdr_size) - return NET_RX_DROP; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with unicast indication but broadcast recipient */ - if (is_bcast(ethhdr->h_dest)) - return NET_RX_DROP; - - /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) - return NET_RX_DROP; - - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - return NET_RX_DROP; - - icmp_packet = (struct icmp_packet *)skb->data; - - /* packet for me */ - if (is_my_mac(icmp_packet->dst)) - return recv_my_icmp_packet(skb); - - /* TTL exceeded */ - if (icmp_packet->ttl < 2) - return recv_icmp_ttl_exceeded(skb); - - ret = NET_RX_DROP; - - /* get routing information */ - spin_lock_irqsave(&orig_hash_lock, flags); - orig_node = ((struct orig_node *) - hash_find(orig_hash, icmp_packet->dst)); - - if ((orig_node != NULL) && - (orig_node->router != NULL)) { - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&orig_hash_lock, flags); - - /* create a copy of the skb, if needed, to modify it. */ - if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) { - skb_old = skb; - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) - return NET_RX_DROP; - icmp_packet = (struct icmp_packet *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - kfree_skb(skb_old); - } - - /* decrement ttl */ - icmp_packet->ttl--; - - /* route it */ - send_skb_packet(skb, batman_if, dstaddr); - ret = NET_RX_SUCCESS; - - } else - spin_unlock_irqrestore(&orig_hash_lock, flags); - - return ret; -} - -int recv_unicast_packet(struct sk_buff *skb) -{ - struct unicast_packet *unicast_packet; - struct orig_node *orig_node; - struct ethhdr *ethhdr; - struct batman_if *batman_if; - struct sk_buff *skb_old; - uint8_t dstaddr[ETH_ALEN]; - int hdr_size = sizeof(struct unicast_packet); - int ret; - unsigned long flags; - - /* drop packet if it has not necessary minimum size */ - if (skb_headlen(skb) < hdr_size) - return NET_RX_DROP; - - ethhdr = (struct ethhdr *) skb_mac_header(skb); - - /* packet with unicast indication but broadcast recipient */ - if (is_bcast(ethhdr->h_dest)) - return NET_RX_DROP; - - /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) - return NET_RX_DROP; - - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - return NET_RX_DROP; - - unicast_packet = (struct unicast_packet *) skb->data; - - /* packet for me */ - if (is_my_mac(unicast_packet->dest)) { - interface_rx(skb, hdr_size); - return NET_RX_SUCCESS; - } - - /* TTL exceeded */ - if (unicast_packet->ttl < 2) { - printk(KERN_WARNING "batman-adv:Warning - " - "can't forward unicast packet from %pM to %pM: " - "ttl exceeded\n", - ethhdr->h_source, unicast_packet->dest); - return NET_RX_DROP; - } - - ret = NET_RX_DROP; - /* get routing information */ - spin_lock_irqsave(&orig_hash_lock, flags); - orig_node = ((struct orig_node *) - hash_find(orig_hash, unicast_packet->dest)); - - if ((orig_node != NULL) && - (orig_node->router != NULL)) { - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&orig_hash_lock, flags); - - /* create a copy of the skb, if needed, to modify it. */ - if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) { - skb_old = skb; - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) - return NET_RX_DROP; - unicast_packet = (struct unicast_packet *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - kfree_skb(skb_old); - } - /* decrement ttl */ - unicast_packet->ttl--; - - /* route it */ - send_skb_packet(skb, batman_if, dstaddr); - ret = NET_RX_SUCCESS; - - } else - spin_unlock_irqrestore(&orig_hash_lock, flags); - - return ret; -} - -int recv_bcast_packet(struct sk_buff *skb) -{ - struct orig_node *orig_node; - struct bcast_packet *bcast_packet; - struct ethhdr *ethhdr; - int hdr_size = sizeof(struct bcast_packet); - int16_t seq_diff; - unsigned long flags; - - /* drop packet if it has not necessary minimum size */ - if (skb_headlen(skb) < hdr_size) - return NET_RX_DROP; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with broadcast indication but unicast recipient */ - if (!is_bcast(ethhdr->h_dest)) - return NET_RX_DROP; - - /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) - return NET_RX_DROP; - - /* ignore broadcasts sent by myself */ - if (is_my_mac(ethhdr->h_source)) - return NET_RX_DROP; - - bcast_packet = (struct bcast_packet *)skb->data; - - /* ignore broadcasts originated by myself */ - if (is_my_mac(bcast_packet->orig)) - return NET_RX_DROP; - - spin_lock_irqsave(&orig_hash_lock, flags); - orig_node = ((struct orig_node *) - hash_find(orig_hash, bcast_packet->orig)); - - if (orig_node == NULL) { - spin_unlock_irqrestore(&orig_hash_lock, flags); - return NET_RX_DROP; - } - - /* check whether the packet is a duplicate */ - if (get_bit_status(orig_node->bcast_bits, - orig_node->last_bcast_seqno, - ntohs(bcast_packet->seqno))) { - spin_unlock_irqrestore(&orig_hash_lock, flags); - return NET_RX_DROP; - } - - seq_diff = ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno; - - /* check whether the packet is old and the host just restarted. */ - if (window_protected(seq_diff, &orig_node->bcast_seqno_reset)) { - spin_unlock_irqrestore(&orig_hash_lock, flags); - return NET_RX_DROP; - } - - /* mark broadcast in flood history, update window position - * if required. */ - if (bit_get_packet(orig_node->bcast_bits, seq_diff, 1)) - orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno); - - spin_unlock_irqrestore(&orig_hash_lock, flags); - /* rebroadcast packet */ - add_bcast_packet_to_list(skb); - - /* broadcast for me */ - interface_rx(skb, hdr_size); - - return NET_RX_SUCCESS; -} - -int recv_vis_packet(struct sk_buff *skb) -{ - struct vis_packet *vis_packet; - struct ethhdr *ethhdr; - struct bat_priv *bat_priv; - int hdr_size = sizeof(struct vis_packet); - - if (skb_headlen(skb) < hdr_size) - return NET_RX_DROP; - - vis_packet = (struct vis_packet *) skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - return NET_RX_DROP; - - /* ignore own packets */ - if (is_my_mac(vis_packet->vis_orig)) - return NET_RX_DROP; - - if (is_my_mac(vis_packet->sender_orig)) - return NET_RX_DROP; - - /* FIXME: each batman_if will be attached to a softif */ - bat_priv = netdev_priv(soft_device); - - switch (vis_packet->vis_type) { - case VIS_TYPE_SERVER_SYNC: - /* TODO: handle fragmented skbs properly */ - receive_server_sync_packet(bat_priv, vis_packet, - skb_headlen(skb)); - break; - - case VIS_TYPE_CLIENT_UPDATE: - /* TODO: handle fragmented skbs properly */ - receive_client_update_packet(bat_priv, vis_packet, - skb_headlen(skb)); - break; - - default: /* ignore unknown packet */ - break; - } - - /* We take a copy of the data in the packet, so we should - always free the skbuf. */ - return NET_RX_DROP; -} diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h deleted file mode 100644 index 8288decea37..00000000000 --- a/drivers/staging/batman-adv/routing.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 "types.h" - -extern wait_queue_head_t thread_wait; - -void slide_own_bcast_window(struct batman_if *batman_if); -void receive_bat_packet(struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - unsigned char *hna_buff, int hna_buff_len, - struct batman_if *if_incoming); -void update_routes(struct orig_node *orig_node, - struct neigh_node *neigh_node, - unsigned char *hna_buff, int hna_buff_len); -int recv_icmp_packet(struct sk_buff *skb); -int recv_unicast_packet(struct sk_buff *skb); -int recv_bcast_packet(struct sk_buff *skb); -int recv_vis_packet(struct sk_buff *skb); -int recv_bat_packet(struct sk_buff *skb, - struct batman_if *batman_if); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c deleted file mode 100644 index ac69ed871a7..00000000000 --- a/drivers/staging/batman-adv/send.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * 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 "send.h" -#include "routing.h" -#include "translation-table.h" -#include "soft-interface.h" -#include "hard-interface.h" -#include "types.h" -#include "vis.h" -#include "aggregation.h" - -/* apply hop penalty for a normal link */ -static uint8_t hop_penalty(const uint8_t tq) -{ - return (tq * (TQ_MAX_VALUE - TQ_HOP_PENALTY)) / (TQ_MAX_VALUE); -} - -/* when do we schedule our own packet to be sent */ -static unsigned long own_send_time(struct bat_priv *bat_priv) -{ - return jiffies + - (((atomic_read(&bat_priv->orig_interval) - JITTER + - (random32() % 2*JITTER)) * HZ) / 1000); -} - -/* when do we schedule a forwarded packet to be sent */ -static unsigned long forward_send_time(struct bat_priv *bat_priv) -{ - return jiffies + (((random32() % (JITTER/2)) * HZ) / 1000); -} - -/* send out an already prepared packet to the given address via the - * specified batman interface */ -int send_skb_packet(struct sk_buff *skb, - struct batman_if *batman_if, - uint8_t *dst_addr) -{ - struct ethhdr *ethhdr; - - if (batman_if->if_status != IF_ACTIVE) - goto send_skb_err; - - if (unlikely(!batman_if->net_dev)) - goto send_skb_err; - - if (!(batman_if->net_dev->flags & IFF_UP)) { - printk(KERN_WARNING - "batman-adv:Interface %s " - "is not up - can't send packet via that interface!\n", - batman_if->dev); - goto send_skb_err; - } - - /* push to the ethernet header. */ - if (my_skb_push(skb, sizeof(struct ethhdr)) < 0) - goto send_skb_err; - - skb_reset_mac_header(skb); - - ethhdr = (struct ethhdr *) skb_mac_header(skb); - memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN); - memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); - ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); - - skb_set_network_header(skb, ETH_HLEN); - skb->priority = TC_PRIO_CONTROL; - skb->protocol = __constant_htons(ETH_P_BATMAN); - - skb->dev = batman_if->net_dev; - - /* dev_queue_xmit() returns a negative result on error. However on - * congestion and traffic shaping, it drops and returns NET_XMIT_DROP - * (which is > 0). This will not be treated as an error. */ - - return dev_queue_xmit(skb); -send_skb_err: - kfree_skb(skb); - return NET_XMIT_DROP; -} - -/* sends a raw packet. */ -void send_raw_packet(unsigned char *pack_buff, int pack_buff_len, - struct batman_if *batman_if, uint8_t *dst_addr) -{ - struct sk_buff *skb; - char *data; - - skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr)); - if (!skb) - return; - data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr)); - memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len); - /* pull back to the batman "network header" */ - skb_pull(skb, sizeof(struct ethhdr)); - send_skb_packet(skb, batman_if, dst_addr); -} - -/* Send a packet to a given interface */ -static void send_packet_to_if(struct forw_packet *forw_packet, - struct batman_if *batman_if) -{ - char *fwd_str; - uint8_t packet_num; - int16_t buff_pos; - struct batman_packet *batman_packet; - - if (batman_if->if_status != IF_ACTIVE) - return; - - packet_num = 0; - buff_pos = 0; - batman_packet = (struct batman_packet *) - (forw_packet->packet_buff); - - /* adjust all flags and log packets */ - while (aggregated_packet(buff_pos, - forw_packet->packet_len, - batman_packet->num_hna)) { - - /* 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 == batman_if)) - batman_packet->flags |= DIRECTLINK; - else - batman_packet->flags &= ~DIRECTLINK; - - fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? - "Sending own" : - "Forwarding")); - bat_dbg(DBG_BATMAN, - "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," - " IDF %s) on interface %s [%s]\n", - fwd_str, (packet_num > 0 ? "aggregated " : ""), - batman_packet->orig, ntohs(batman_packet->seqno), - batman_packet->tq, batman_packet->ttl, - (batman_packet->flags & DIRECTLINK ? - "on" : "off"), - batman_if->dev, batman_if->addr_str); - - buff_pos += sizeof(struct batman_packet) + - (batman_packet->num_hna * ETH_ALEN); - packet_num++; - batman_packet = (struct batman_packet *) - (forw_packet->packet_buff + buff_pos); - } - - send_raw_packet(forw_packet->packet_buff, - forw_packet->packet_len, - batman_if, broadcastAddr); -} - -/* send a batman packet */ -static void send_packet(struct forw_packet *forw_packet) -{ - struct batman_if *batman_if; - struct batman_packet *batman_packet = - (struct batman_packet *)(forw_packet->packet_buff); - unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); - - if (!forw_packet->if_incoming) { - printk(KERN_ERR "batman-adv: Error - can't forward packet: " - "incoming iface not specified\n"); - return; - } - - if (forw_packet->if_incoming->if_status != IF_ACTIVE) - return; - - /* multihomed peer assumed */ - /* non-primary OGMs are only broadcasted on their interface */ - if ((directlink && (batman_packet->ttl == 1)) || - (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) { - - /* FIXME: what about aggregated packets ? */ - bat_dbg(DBG_BATMAN, - "%s packet (originator %pM, seqno %d, TTL %d) " - "on interface %s [%s]\n", - (forw_packet->own ? "Sending own" : "Forwarding"), - batman_packet->orig, ntohs(batman_packet->seqno), - batman_packet->ttl, forw_packet->if_incoming->dev, - forw_packet->if_incoming->addr_str); - - send_raw_packet(forw_packet->packet_buff, - forw_packet->packet_len, - forw_packet->if_incoming, - broadcastAddr); - return; - } - - /* broadcast on every interface */ - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) - send_packet_to_if(forw_packet, batman_if); - rcu_read_unlock(); -} - -static void rebuild_batman_packet(struct batman_if *batman_if) -{ - int new_len; - unsigned char *new_buff; - struct batman_packet *batman_packet; - - new_len = sizeof(struct batman_packet) + (num_hna * ETH_ALEN); - new_buff = kmalloc(new_len, GFP_ATOMIC); - - /* keep old buffer if kmalloc should fail */ - if (new_buff) { - memcpy(new_buff, batman_if->packet_buff, - sizeof(struct batman_packet)); - batman_packet = (struct batman_packet *)new_buff; - - batman_packet->num_hna = hna_local_fill_buffer( - new_buff + sizeof(struct batman_packet), - new_len - sizeof(struct batman_packet)); - - kfree(batman_if->packet_buff); - batman_if->packet_buff = new_buff; - batman_if->packet_len = new_len; - } -} - -void schedule_own_packet(struct batman_if *batman_if) -{ - /* FIXME: each batman_if will be attached to a softif */ - struct bat_priv *bat_priv = netdev_priv(soft_device); - unsigned long send_time; - struct batman_packet *batman_packet; - int vis_server; - - if ((batman_if->if_status == IF_NOT_IN_USE) || - (batman_if->if_status == IF_TO_BE_REMOVED)) - return; - - vis_server = atomic_read(&bat_priv->vis_mode); - - /** - * the interface gets activated here to avoid race conditions between - * the moment of activating the interface in - * hardif_activate_interface() where the originator mac is set and - * outdated packets (especially uninitialized mac addresses) in the - * packet queue - */ - if (batman_if->if_status == IF_TO_BE_ACTIVATED) - batman_if->if_status = IF_ACTIVE; - - /* if local hna has changed and interface is a primary interface */ - if ((atomic_read(&hna_local_changed)) && - (batman_if == bat_priv->primary_if)) - rebuild_batman_packet(batman_if); - - /** - * NOTE: packet_buff might just have been re-allocated in - * rebuild_batman_packet() - */ - batman_packet = (struct batman_packet *)batman_if->packet_buff; - - /* change sequence number to network order */ - batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno)); - - if (vis_server == VIS_TYPE_SERVER_SYNC) - batman_packet->flags = VIS_SERVER; - else - batman_packet->flags &= ~VIS_SERVER; - - /* could be read by receive_bat_packet() */ - atomic_inc(&batman_if->seqno); - - slide_own_bcast_window(batman_if); - send_time = own_send_time(bat_priv); - add_bat_packet_to_list(bat_priv, - batman_if->packet_buff, - batman_if->packet_len, - batman_if, 1, send_time); -} - -void schedule_forward_packet(struct orig_node *orig_node, - struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - uint8_t directlink, int hna_buff_len, - struct batman_if *if_incoming) -{ - /* FIXME: each batman_if will be attached to a softif */ - struct bat_priv *bat_priv = netdev_priv(soft_device); - unsigned char in_tq, in_ttl, tq_avg = 0; - unsigned long send_time; - - if (batman_packet->ttl <= 1) { - bat_dbg(DBG_BATMAN, "ttl exceeded\n"); - return; - } - - in_tq = batman_packet->tq; - in_ttl = batman_packet->ttl; - - batman_packet->ttl--; - memcpy(batman_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 ((orig_node->router) && (orig_node->router->tq_avg != 0)) { - - /* rebroadcast ogm of best ranking neighbor as is */ - if (!compare_orig(orig_node->router->addr, ethhdr->h_source)) { - batman_packet->tq = orig_node->router->tq_avg; - - if (orig_node->router->last_ttl) - batman_packet->ttl = orig_node->router->last_ttl - - 1; - } - - tq_avg = orig_node->router->tq_avg; - } - - /* apply hop penalty */ - batman_packet->tq = hop_penalty(batman_packet->tq); - - bat_dbg(DBG_BATMAN, "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); - - batman_packet->seqno = htons(batman_packet->seqno); - - if (directlink) - batman_packet->flags |= DIRECTLINK; - else - batman_packet->flags &= ~DIRECTLINK; - - send_time = forward_send_time(bat_priv); - add_bat_packet_to_list(bat_priv, - (unsigned char *)batman_packet, - sizeof(struct batman_packet) + hna_buff_len, - if_incoming, 0, send_time); -} - -static void forw_packet_free(struct forw_packet *forw_packet) -{ - if (forw_packet->skb) - kfree_skb(forw_packet->skb); - kfree(forw_packet->packet_buff); - kfree(forw_packet); -} - -static void _add_bcast_packet_to_list(struct forw_packet *forw_packet, - unsigned long send_time) -{ - unsigned long flags; - INIT_HLIST_NODE(&forw_packet->list); - - /* add new packet to packet list */ - spin_lock_irqsave(&forw_bcast_list_lock, flags); - hlist_add_head(&forw_packet->list, &forw_bcast_list); - spin_unlock_irqrestore(&forw_bcast_list_lock, flags); - - /* start timer for this packet */ - INIT_DELAYED_WORK(&forw_packet->delayed_work, - send_outstanding_bcast_packet); - queue_delayed_work(bat_event_workqueue, &forw_packet->delayed_work, - send_time); -} - -#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) -/* add a broadcast packet to the queue and setup timers. broadcast packets - * are sent multiple times to increase probability for beeing received. - * - * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on - * errors. - * - * The skb is not consumed, so the caller should make sure that the - * skb is freed. */ -int add_bcast_packet_to_list(struct sk_buff *skb) -{ - struct forw_packet *forw_packet; - - if (!atomic_dec_not_zero(&bcast_queue_left)) { - bat_dbg(DBG_BATMAN, "bcast packet queue full\n"); - goto out; - } - - forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); - - if (!forw_packet) - goto out_and_inc; - - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) - goto packet_free; - - skb_reset_mac_header(skb); - - forw_packet->skb = skb; - forw_packet->packet_buff = NULL; - - /* how often did we send the bcast packet ? */ - forw_packet->num_packets = 0; - - _add_bcast_packet_to_list(forw_packet, 1); - return NETDEV_TX_OK; - -packet_free: - kfree(forw_packet); -out_and_inc: - atomic_inc(&bcast_queue_left); -out: - return NETDEV_TX_BUSY; -} - -void send_outstanding_bcast_packet(struct work_struct *work) -{ - struct batman_if *batman_if; - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct forw_packet *forw_packet = - container_of(delayed_work, struct forw_packet, delayed_work); - unsigned long flags; - struct sk_buff *skb1; - - spin_lock_irqsave(&forw_bcast_list_lock, flags); - hlist_del(&forw_packet->list); - spin_unlock_irqrestore(&forw_bcast_list_lock, flags); - - if (atomic_read(&module_state) == MODULE_DEACTIVATING) - goto out; - - /* rebroadcast packet */ - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - /* send a copy of the saved skb */ - skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC); - if (skb1) - send_skb_packet(skb1, - batman_if, broadcastAddr); - } - rcu_read_unlock(); - - forw_packet->num_packets++; - - /* if we still have some more bcasts to send */ - if (forw_packet->num_packets < 3) { - _add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000)); - return; - } - -out: - forw_packet_free(forw_packet); - atomic_inc(&bcast_queue_left); -} - -void send_outstanding_bat_packet(struct work_struct *work) -{ - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct forw_packet *forw_packet = - container_of(delayed_work, struct forw_packet, delayed_work); - unsigned long flags; - - spin_lock_irqsave(&forw_bat_list_lock, flags); - hlist_del(&forw_packet->list); - spin_unlock_irqrestore(&forw_bat_list_lock, flags); - - if (atomic_read(&module_state) == MODULE_DEACTIVATING) - goto out; - - send_packet(forw_packet); - - /** - * we have to have at least one packet in the queue - * to determine the queues wake up time unless we are - * shutting down - */ - if (forw_packet->own) - schedule_own_packet(forw_packet->if_incoming); - -out: - /* don't count own packet */ - if (!forw_packet->own) - atomic_inc(&batman_queue_left); - - forw_packet_free(forw_packet); -} - -void purge_outstanding_packets(struct batman_if *batman_if) -{ - struct forw_packet *forw_packet; - struct hlist_node *tmp_node, *safe_tmp_node; - unsigned long flags; - - if (batman_if) - bat_dbg(DBG_BATMAN, "purge_outstanding_packets(): %s\n", - batman_if->dev); - else - bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n"); - - /* free bcast list */ - spin_lock_irqsave(&forw_bcast_list_lock, flags); - hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, - &forw_bcast_list, list) { - - /** - * if purge_outstanding_packets() was called with an argmument - * we delete only packets belonging to the given interface - */ - if ((batman_if) && - (forw_packet->if_incoming != batman_if)) - continue; - - spin_unlock_irqrestore(&forw_bcast_list_lock, flags); - - /** - * send_outstanding_bcast_packet() will lock the list to - * delete the item from the list - */ - cancel_delayed_work_sync(&forw_packet->delayed_work); - spin_lock_irqsave(&forw_bcast_list_lock, flags); - } - spin_unlock_irqrestore(&forw_bcast_list_lock, flags); - - /* free batman packet list */ - spin_lock_irqsave(&forw_bat_list_lock, flags); - hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, - &forw_bat_list, list) { - - /** - * if purge_outstanding_packets() was called with an argmument - * we delete only packets belonging to the given interface - */ - if ((batman_if) && - (forw_packet->if_incoming != batman_if)) - continue; - - spin_unlock_irqrestore(&forw_bat_list_lock, flags); - - /** - * send_outstanding_bat_packet() will lock the list to - * delete the item from the list - */ - cancel_delayed_work_sync(&forw_packet->delayed_work); - spin_lock_irqsave(&forw_bat_list_lock, flags); - } - spin_unlock_irqrestore(&forw_bat_list_lock, flags); -} diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h deleted file mode 100644 index feaa2fc7f9a..00000000000 --- a/drivers/staging/batman-adv/send.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 "types.h" - -void send_own_packet_work(struct work_struct *work); -int send_skb_packet(struct sk_buff *skb, - struct batman_if *batman_if, - uint8_t *dst_addr); -void send_raw_packet(unsigned char *pack_buff, int pack_buff_len, - struct batman_if *batman_if, uint8_t *dst_addr); -void schedule_own_packet(struct batman_if *batman_if); -void schedule_forward_packet(struct orig_node *orig_node, - struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - uint8_t directlink, int hna_buff_len, - struct batman_if *if_outgoing); -int add_bcast_packet_to_list(struct sk_buff *skb); -void send_outstanding_bcast_packet(struct work_struct *work); -void send_outstanding_bat_packet(struct work_struct *work); -void purge_outstanding_packets(struct batman_if *batman_if); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c deleted file mode 100644 index 51c40b77c8d..00000000000 --- a/drivers/staging/batman-adv/soft-interface.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * 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 "soft-interface.h" -#include "hard-interface.h" -#include "send.h" -#include "translation-table.h" -#include "types.h" -#include "hash.h" -#include <linux/slab.h> -#include <linux/ethtool.h> -#include <linux/etherdevice.h> - -static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid - * broadcast storms */ -static int32_t skb_packets; -static int32_t skb_bad_packets; - -unsigned char mainIfAddr[ETH_ALEN]; -static unsigned char mainIfAddr_default[ETH_ALEN]; -static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); -static void bat_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info); -static u32 bat_get_msglevel(struct net_device *dev); -static void bat_set_msglevel(struct net_device *dev, u32 value); -static u32 bat_get_link(struct net_device *dev); -static u32 bat_get_rx_csum(struct net_device *dev); -static int bat_set_rx_csum(struct net_device *dev, u32 data); - -static const struct ethtool_ops bat_ethtool_ops = { - .get_settings = bat_get_settings, - .get_drvinfo = bat_get_drvinfo, - .get_msglevel = bat_get_msglevel, - .set_msglevel = bat_set_msglevel, - .get_link = bat_get_link, - .get_rx_csum = bat_get_rx_csum, - .set_rx_csum = bat_set_rx_csum -}; - -void set_main_if_addr(uint8_t *addr) -{ - memcpy(mainIfAddr, addr, ETH_ALEN); -} - -int main_if_was_up(void) -{ - return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0); -} - -int my_skb_push(struct sk_buff *skb, unsigned int len) -{ - int result = 0; - - skb_packets++; - if (skb_headroom(skb) < len) { - skb_bad_packets++; - result = pskb_expand_head(skb, len, 0, GFP_ATOMIC); - - if (result < 0) - return result; - } - - skb_push(skb, len); - return 0; -} - -#ifdef HAVE_NET_DEVICE_OPS -static const struct net_device_ops bat_netdev_ops = { - .ndo_open = interface_open, - .ndo_stop = interface_release, - .ndo_get_stats = interface_stats, - .ndo_set_mac_address = interface_set_mac_addr, - .ndo_change_mtu = interface_change_mtu, - .ndo_start_xmit = interface_tx, - .ndo_validate_addr = eth_validate_addr -}; -#endif - -void interface_setup(struct net_device *dev) -{ - struct bat_priv *priv = netdev_priv(dev); - char dev_addr[ETH_ALEN]; - - ether_setup(dev); - -#ifdef HAVE_NET_DEVICE_OPS - dev->netdev_ops = &bat_netdev_ops; -#else - dev->open = interface_open; - dev->stop = interface_release; - dev->get_stats = interface_stats; - dev->set_mac_address = interface_set_mac_addr; - dev->change_mtu = interface_change_mtu; - dev->hard_start_xmit = interface_tx; -#endif - dev->destructor = free_netdev; - - dev->mtu = hardif_min_mtu(); - dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the - * skbuff for our header */ - - /* generate random address */ - random_ether_addr(dev_addr); - memcpy(dev->dev_addr, dev_addr, ETH_ALEN); - - SET_ETHTOOL_OPS(dev, &bat_ethtool_ops); - - memset(priv, 0, sizeof(struct bat_priv)); -} - -int interface_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; -} - -int interface_release(struct net_device *dev) -{ - netif_stop_queue(dev); - return 0; -} - -struct net_device_stats *interface_stats(struct net_device *dev) -{ - struct bat_priv *priv = netdev_priv(dev); - return &priv->stats; -} - -int interface_set_mac_addr(struct net_device *dev, void *p) -{ - struct sockaddr *addr = p; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - /* 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); - } - - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - - return 0; -} - -int interface_change_mtu(struct net_device *dev, int new_mtu) -{ - /* check ranges */ - if ((new_mtu < 68) || (new_mtu > hardif_min_mtu())) - return -EINVAL; - - dev->mtu = new_mtu; - - return 0; -} - -int interface_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct unicast_packet *unicast_packet; - struct bcast_packet *bcast_packet; - struct orig_node *orig_node; - struct ethhdr *ethhdr = (struct ethhdr *)skb->data; - struct bat_priv *priv = netdev_priv(dev); - struct batman_if *batman_if; - struct bat_priv *bat_priv; - uint8_t dstaddr[6]; - int data_len = skb->len; - unsigned long flags; - - if (atomic_read(&module_state) != MODULE_ACTIVE) - goto dropped; - - /* FIXME: each batman_if will be attached to a softif */ - bat_priv = netdev_priv(soft_device); - - dev->trans_start = jiffies; - /* TODO: check this for locks */ - hna_local_add(ethhdr->h_source); - - /* ethernet packet should be broadcasted */ - if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) { - - if (my_skb_push(skb, sizeof(struct bcast_packet)) < 0) - goto dropped; - - bcast_packet = (struct bcast_packet *)skb->data; - bcast_packet->version = COMPAT_VERSION; - - /* batman packet type: broadcast */ - bcast_packet->packet_type = BAT_BCAST; - - /* hw address of first interface is the orig mac because only - * this mac is known throughout the mesh */ - memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN); - - /* set broadcast sequence number */ - bcast_packet->seqno = htons(bcast_seqno); - - /* broadcast packet. on success, increase seqno. */ - if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK) - bcast_seqno++; - - /* a copy is stored in the bcast list, therefore removing - * the original skb. */ - kfree_skb(skb); - - /* unicast packet */ - } else { - spin_lock_irqsave(&orig_hash_lock, flags); - /* get routing information */ - orig_node = ((struct orig_node *)hash_find(orig_hash, - ethhdr->h_dest)); - - /* check for hna host */ - if (!orig_node) - orig_node = transtable_search(ethhdr->h_dest); - - if ((orig_node) && - (orig_node->router)) { - struct neigh_node *router = orig_node->router; - - if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0) - goto unlock; - - unicast_packet = (struct unicast_packet *)skb->data; - - unicast_packet->version = COMPAT_VERSION; - /* batman packet type: unicast */ - unicast_packet->packet_type = BAT_UNICAST; - /* set unicast ttl */ - unicast_packet->ttl = TTL; - /* copy the destination for faster routing */ - memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); - - /* net_dev won't be available when not active */ - if (router->if_incoming->if_status != IF_ACTIVE) - goto unlock; - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - - batman_if = router->if_incoming; - memcpy(dstaddr, router->addr, ETH_ALEN); - spin_unlock_irqrestore(&orig_hash_lock, flags); - - send_skb_packet(skb, batman_if, dstaddr); - } else { - goto unlock; - } - } - - priv->stats.tx_packets++; - priv->stats.tx_bytes += data_len; - goto end; - -unlock: - spin_unlock_irqrestore(&orig_hash_lock, flags); -dropped: - priv->stats.tx_dropped++; - kfree_skb(skb); -end: - return NETDEV_TX_OK; -} - -void interface_rx(struct sk_buff *skb, int hdr_size) -{ - struct net_device *dev = soft_device; - struct bat_priv *priv = netdev_priv(dev); - - /* check if enough space is available for pulling, and pull */ - if (!pskb_may_pull(skb, hdr_size)) { - kfree_skb(skb); - return; - } - skb_pull_rcsum(skb, hdr_size); -/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/ - - skb->dev = dev; - skb->protocol = eth_type_trans(skb, dev); - - /* should not be neccesary anymore as we use skb_pull_rcsum() - * TODO: please verify this and remove this TODO - * -- Dec 21st 2009, Simon Wunderlich */ - -/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/ - - /* TODO: set skb->pkt_type to PACKET_BROADCAST, PACKET_MULTICAST, - * PACKET_OTHERHOST or PACKET_HOST */ - - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len; - - dev->last_rx = jiffies; - - netif_rx(skb); -} - -/* ethtool */ -static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - cmd->supported = 0; - cmd->advertising = 0; - cmd->speed = SPEED_10; - cmd->duplex = DUPLEX_FULL; - cmd->port = PORT_TP; - cmd->phy_address = 0; - cmd->transceiver = XCVR_INTERNAL; - cmd->autoneg = AUTONEG_DISABLE; - cmd->maxtxpkt = 0; - cmd->maxrxpkt = 0; - - return 0; -} - -static void bat_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "B.A.T.M.A.N. advanced"); - strcpy(info->version, SOURCE_VERSION); - strcpy(info->fw_version, "N/A"); - strcpy(info->bus_info, "batman"); -} - -static u32 bat_get_msglevel(struct net_device *dev) -{ - return -EOPNOTSUPP; -} - -static void bat_set_msglevel(struct net_device *dev, u32 value) -{ -} - -static u32 bat_get_link(struct net_device *dev) -{ - return 1; -} - -static u32 bat_get_rx_csum(struct net_device *dev) -{ - return 0; -} - -static int bat_set_rx_csum(struct net_device *dev, u32 data) -{ - return -EOPNOTSUPP; -} diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h deleted file mode 100644 index e7f59af7df3..00000000000 --- a/drivers/staging/batman-adv/soft-interface.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * 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 - * - */ - -void set_main_if_addr(uint8_t *addr); -int main_if_was_up(void); -void interface_setup(struct net_device *dev); -int interface_open(struct net_device *dev); -int interface_release(struct net_device *dev); -struct net_device_stats *interface_stats(struct net_device *dev); -int interface_set_mac_addr(struct net_device *dev, void *addr); -int interface_change_mtu(struct net_device *dev, int new_mtu); -int interface_tx(struct sk_buff *skb, struct net_device *dev); -void interface_rx(struct sk_buff *skb, int hdr_size); -int my_skb_push(struct sk_buff *skb, unsigned int len); - -extern unsigned char mainIfAddr[]; diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c deleted file mode 100644 index e01ff2151f7..00000000000 --- a/drivers/staging/batman-adv/translation-table.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * 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 "translation-table.h" -#include "soft-interface.h" -#include "types.h" -#include "hash.h" - -struct hashtable_t *hna_local_hash; -static struct hashtable_t *hna_global_hash; -atomic_t hna_local_changed; - -DEFINE_SPINLOCK(hna_local_hash_lock); -static DEFINE_SPINLOCK(hna_global_hash_lock); - -static DECLARE_DELAYED_WORK(hna_local_purge_wq, hna_local_purge); - -static void hna_local_start_timer(void) -{ - queue_delayed_work(bat_event_workqueue, &hna_local_purge_wq, 10 * HZ); -} - -int hna_local_init(void) -{ - if (hna_local_hash) - return 1; - - hna_local_hash = hash_new(128, compare_orig, choose_orig); - - if (!hna_local_hash) - return 0; - - atomic_set(&hna_local_changed, 0); - hna_local_start_timer(); - - return 1; -} - -void hna_local_add(uint8_t *addr) -{ - struct hna_local_entry *hna_local_entry; - struct hna_global_entry *hna_global_entry; - struct hashtable_t *swaphash; - unsigned long flags; - - spin_lock_irqsave(&hna_local_hash_lock, flags); - hna_local_entry = - ((struct hna_local_entry *)hash_find(hna_local_hash, addr)); - spin_unlock_irqrestore(&hna_local_hash_lock, flags); - - if (hna_local_entry != NULL) { - hna_local_entry->last_seen = jiffies; - return; - } - - /* only announce as many hosts as possible in the batman-packet and - space in batman_packet->num_hna That also should give a limit to - MAC-flooding. */ - if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || - (num_hna + 1 > 255)) { - bat_dbg(DBG_ROUTES, - "Can't add new local hna entry (%pM): " - "number of local hna entries exceeds packet size\n", - addr); - return; - } - - bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM\n", - addr); - - hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); - if (!hna_local_entry) - return; - - memcpy(hna_local_entry->addr, addr, ETH_ALEN); - hna_local_entry->last_seen = jiffies; - - /* the batman interface mac address should never be purged */ - if (compare_orig(addr, soft_device->dev_addr)) - hna_local_entry->never_purge = 1; - else - hna_local_entry->never_purge = 0; - - spin_lock_irqsave(&hna_local_hash_lock, flags); - - hash_add(hna_local_hash, hna_local_entry); - num_hna++; - atomic_set(&hna_local_changed, 1); - - if (hna_local_hash->elements * 4 > hna_local_hash->size) { - swaphash = hash_resize(hna_local_hash, - hna_local_hash->size * 2); - - if (swaphash == NULL) - printk(KERN_ERR "batman-adv:" - "Couldn't resize local hna hash table\n"); - else - hna_local_hash = swaphash; - } - - spin_unlock_irqrestore(&hna_local_hash_lock, flags); - - /* remove address from global hash if present */ - spin_lock_irqsave(&hna_global_hash_lock, flags); - - hna_global_entry = - ((struct hna_global_entry *)hash_find(hna_global_hash, addr)); - - if (hna_global_entry != NULL) - _hna_global_del_orig(hna_global_entry, "local hna received"); - - spin_unlock_irqrestore(&hna_global_hash_lock, flags); -} - -int hna_local_fill_buffer(unsigned char *buff, int buff_len) -{ - struct hna_local_entry *hna_local_entry; - HASHIT(hashit); - int i = 0; - unsigned long flags; - - spin_lock_irqsave(&hna_local_hash_lock, flags); - - while (hash_iterate(hna_local_hash, &hashit)) { - - if (buff_len < (i + 1) * ETH_ALEN) - break; - - hna_local_entry = hashit.bucket->data; - memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN); - - i++; - } - - /* if we did not get all new local hnas see you next time ;-) */ - if (i == num_hna) - atomic_set(&hna_local_changed, 0); - - spin_unlock_irqrestore(&hna_local_hash_lock, flags); - - return i; -} - -int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, - size_t count, loff_t off) -{ - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct hna_local_entry *hna_local_entry; - HASHIT(hashit); - int bytes_written = 0; - unsigned long flags; - size_t hdr_len; - - if (!bat_priv->primary_if) { - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - - hdr_len = sprintf(buff, - "Locally retrieved addresses (from %s) " - "announced via HNA:\n", - net_dev->name); - - if (off < hdr_len) - bytes_written = hdr_len; - - spin_lock_irqsave(&hna_local_hash_lock, flags); - - while (hash_iterate(hna_local_hash, &hashit)) { - hdr_len += 21; - - if (count < bytes_written + 22) - break; - - if (off >= hdr_len) - continue; - - hna_local_entry = hashit.bucket->data; - - bytes_written += snprintf(buff + bytes_written, 22, - " * " MAC_FMT "\n", - hna_local_entry->addr[0], - hna_local_entry->addr[1], - hna_local_entry->addr[2], - hna_local_entry->addr[3], - hna_local_entry->addr[4], - hna_local_entry->addr[5]); - } - - spin_unlock_irqrestore(&hna_local_hash_lock, flags); - return bytes_written; -} - -static void _hna_local_del(void *data) -{ - kfree(data); - num_hna--; - atomic_set(&hna_local_changed, 1); -} - -static void hna_local_del(struct hna_local_entry *hna_local_entry, - char *message) -{ - bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s\n", - hna_local_entry->addr, message); - - hash_remove(hna_local_hash, hna_local_entry->addr); - _hna_local_del(hna_local_entry); -} - -void hna_local_remove(uint8_t *addr, char *message) -{ - struct hna_local_entry *hna_local_entry; - unsigned long flags; - - spin_lock_irqsave(&hna_local_hash_lock, flags); - - hna_local_entry = (struct hna_local_entry *) - hash_find(hna_local_hash, addr); - if (hna_local_entry) - hna_local_del(hna_local_entry, message); - - spin_unlock_irqrestore(&hna_local_hash_lock, flags); -} - -void hna_local_purge(struct work_struct *work) -{ - struct hna_local_entry *hna_local_entry; - HASHIT(hashit); - unsigned long flags; - unsigned long timeout; - - spin_lock_irqsave(&hna_local_hash_lock, flags); - - while (hash_iterate(hna_local_hash, &hashit)) { - hna_local_entry = hashit.bucket->data; - - timeout = hna_local_entry->last_seen + - ((LOCAL_HNA_TIMEOUT / 1000) * HZ); - if ((!hna_local_entry->never_purge) && - time_after(jiffies, timeout)) - hna_local_del(hna_local_entry, "address timed out"); - } - - spin_unlock_irqrestore(&hna_local_hash_lock, flags); - hna_local_start_timer(); -} - -void hna_local_free(void) -{ - if (!hna_local_hash) - return; - - cancel_delayed_work_sync(&hna_local_purge_wq); - hash_delete(hna_local_hash, _hna_local_del); - hna_local_hash = NULL; -} - -int hna_global_init(void) -{ - if (hna_global_hash) - return 1; - - hna_global_hash = hash_new(128, compare_orig, choose_orig); - - if (!hna_global_hash) - return 0; - - return 1; -} - -void hna_global_add_orig(struct orig_node *orig_node, - unsigned char *hna_buff, int hna_buff_len) -{ - struct hna_global_entry *hna_global_entry; - struct hna_local_entry *hna_local_entry; - struct hashtable_t *swaphash; - int hna_buff_count = 0; - unsigned long flags; - unsigned char *hna_ptr; - - while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { - spin_lock_irqsave(&hna_global_hash_lock, flags); - - hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); - hna_global_entry = (struct hna_global_entry *) - hash_find(hna_global_hash, hna_ptr); - - if (hna_global_entry == NULL) { - spin_unlock_irqrestore(&hna_global_hash_lock, flags); - - hna_global_entry = - kmalloc(sizeof(struct hna_global_entry), - GFP_ATOMIC); - - if (!hna_global_entry) - break; - - memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); - - bat_dbg(DBG_ROUTES, - "Creating new global hna entry: " - "%pM (via %pM)\n", - hna_global_entry->addr, orig_node->orig); - - spin_lock_irqsave(&hna_global_hash_lock, flags); - hash_add(hna_global_hash, hna_global_entry); - - } - - hna_global_entry->orig_node = orig_node; - spin_unlock_irqrestore(&hna_global_hash_lock, flags); - - /* remove address from local hash if present */ - spin_lock_irqsave(&hna_local_hash_lock, flags); - - hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); - hna_local_entry = (struct hna_local_entry *) - hash_find(hna_local_hash, hna_ptr); - - if (hna_local_entry != NULL) - hna_local_del(hna_local_entry, "global hna received"); - - spin_unlock_irqrestore(&hna_local_hash_lock, flags); - - hna_buff_count++; - } - - /* initialize, and overwrite if malloc succeeds */ - orig_node->hna_buff = NULL; - orig_node->hna_buff_len = 0; - - if (hna_buff_len > 0) { - orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC); - if (orig_node->hna_buff) { - memcpy(orig_node->hna_buff, hna_buff, hna_buff_len); - orig_node->hna_buff_len = hna_buff_len; - } - } - - spin_lock_irqsave(&hna_global_hash_lock, flags); - - if (hna_global_hash->elements * 4 > hna_global_hash->size) { - swaphash = hash_resize(hna_global_hash, - hna_global_hash->size * 2); - - if (swaphash == NULL) - printk(KERN_ERR "batman-adv:" - "Couldn't resize global hna hash table\n"); - else - hna_global_hash = swaphash; - } - - spin_unlock_irqrestore(&hna_global_hash_lock, flags); -} - -int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, - size_t count, loff_t off) -{ - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct hna_global_entry *hna_global_entry; - HASHIT(hashit); - int bytes_written = 0; - unsigned long flags; - size_t hdr_len; - - if (!bat_priv->primary_if) { - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - - hdr_len = sprintf(buff, - "Globally announced HNAs received via the mesh %s " - "(translation table):\n", - net_dev->name); - - if (off < hdr_len) - bytes_written = hdr_len; - - spin_lock_irqsave(&hna_global_hash_lock, flags); - - while (hash_iterate(hna_global_hash, &hashit)) { - hdr_len += 43; - - if (count < bytes_written + 44) - break; - - if (off >= hdr_len) - continue; - - hna_global_entry = hashit.bucket->data; - - bytes_written += snprintf(buff + bytes_written, 44, - " * " MAC_FMT " via " MAC_FMT "\n", - hna_global_entry->addr[0], - hna_global_entry->addr[1], - hna_global_entry->addr[2], - hna_global_entry->addr[3], - hna_global_entry->addr[4], - hna_global_entry->addr[5], - hna_global_entry->orig_node->orig[0], - hna_global_entry->orig_node->orig[1], - hna_global_entry->orig_node->orig[2], - hna_global_entry->orig_node->orig[3], - hna_global_entry->orig_node->orig[4], - hna_global_entry->orig_node->orig[5]); - } - - spin_unlock_irqrestore(&hna_global_hash_lock, flags); - return bytes_written; -} - -void _hna_global_del_orig(struct hna_global_entry *hna_global_entry, - char *message) -{ - bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s\n", - hna_global_entry->addr, hna_global_entry->orig_node->orig, - message); - - hash_remove(hna_global_hash, hna_global_entry->addr); - kfree(hna_global_entry); -} - -void hna_global_del_orig(struct orig_node *orig_node, char *message) -{ - struct hna_global_entry *hna_global_entry; - int hna_buff_count = 0; - unsigned long flags; - unsigned char *hna_ptr; - - if (orig_node->hna_buff_len == 0) - return; - - spin_lock_irqsave(&hna_global_hash_lock, flags); - - while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { - hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); - hna_global_entry = (struct hna_global_entry *) - hash_find(hna_global_hash, hna_ptr); - - if ((hna_global_entry != NULL) && - (hna_global_entry->orig_node == orig_node)) - _hna_global_del_orig(hna_global_entry, message); - - hna_buff_count++; - } - - spin_unlock_irqrestore(&hna_global_hash_lock, flags); - - orig_node->hna_buff_len = 0; - kfree(orig_node->hna_buff); - orig_node->hna_buff = NULL; -} - -static void hna_global_del(void *data) -{ - kfree(data); -} - -void hna_global_free(void) -{ - if (!hna_global_hash) - return; - - hash_delete(hna_global_hash, hna_global_del); - hna_global_hash = NULL; -} - -struct orig_node *transtable_search(uint8_t *addr) -{ - struct hna_global_entry *hna_global_entry; - unsigned long flags; - - spin_lock_irqsave(&hna_global_hash_lock, flags); - hna_global_entry = (struct hna_global_entry *) - hash_find(hna_global_hash, addr); - spin_unlock_irqrestore(&hna_global_hash_lock, flags); - - if (hna_global_entry == NULL) - return NULL; - - return hna_global_entry->orig_node; -} diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h deleted file mode 100644 index 8f412fca87f..00000000000 --- a/drivers/staging/batman-adv/translation-table.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 "types.h" - -int hna_local_init(void); -void hna_local_add(uint8_t *addr); -void hna_local_remove(uint8_t *addr, char *message); -int hna_local_fill_buffer(unsigned char *buff, int buff_len); -int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, - size_t count, loff_t off); -void hna_local_purge(struct work_struct *work); -void hna_local_free(void); -int hna_global_init(void); -void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff, - int hna_buff_len); -int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, - size_t count, loff_t off); -void _hna_global_del_orig(struct hna_global_entry *hna_global_entry, - char *orig_str); -void hna_global_del_orig(struct orig_node *orig_node, char *message); -void hna_global_free(void); -struct orig_node *transtable_search(uint8_t *addr); - -extern spinlock_t hna_local_hash_lock; -extern struct hashtable_t *hna_local_hash; -extern atomic_t hna_local_changed; diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h deleted file mode 100644 index 86007c7eb44..00000000000 --- a/drivers/staging/batman-adv/types.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 - * - */ - - - - - -#ifndef TYPES_H -#define TYPES_H - -#include "packet.h" -#include "bitarray.h" - -#define BAT_HEADER_LEN (sizeof(struct ethhdr) + \ - ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \ - sizeof(struct unicast_packet) : \ - sizeof(struct bcast_packet)))) - - -struct batman_if { - struct list_head list; - int16_t if_num; - char *dev; - char if_status; - char addr_str[ETH_STR_LEN]; - struct net_device *net_dev; - atomic_t seqno; - unsigned char *packet_buff; - int packet_len; - struct kobject *hardif_obj; - struct rcu_head rcu; - -}; - -/** - * orig_node - structure for orig_list maintaining nodes of mesh - * @last_valid: when last packet from this node was received - * @bcast_seqno_reset: time when the broadcast seqno window was reset - * @batman_seqno_reset: time when the batman seqno window was reset - * @flags: for now only VIS_SERVER flag - * @last_real_seqno: last and best known squence number - * @last_ttl: ttl of last received packet - * @last_bcast_seqno: last broadcast sequence number received by this host - */ -struct orig_node { - uint8_t orig[ETH_ALEN]; - struct neigh_node *router; - TYPE_OF_WORD *bcast_own; - uint8_t *bcast_own_sum; - uint8_t tq_own; - int tq_asym_penalty; - unsigned long last_valid; - unsigned long bcast_seqno_reset; - unsigned long batman_seqno_reset; - uint8_t flags; - unsigned char *hna_buff; - int16_t hna_buff_len; - uint16_t last_real_seqno; - uint8_t last_ttl; - TYPE_OF_WORD bcast_bits[NUM_WORDS]; - uint16_t last_bcast_seqno; - struct list_head neigh_list; -}; - -/** - * neigh_node - * @last_valid: when last packet via this neighbor was received - */ -struct neigh_node { - struct list_head list; - uint8_t addr[ETH_ALEN]; - uint8_t real_packet_count; - uint8_t tq_recv[TQ_GLOBAL_WINDOW_SIZE]; - uint8_t tq_index; - uint8_t tq_avg; - uint8_t last_ttl; - unsigned long last_valid; - TYPE_OF_WORD real_bits[NUM_WORDS]; - struct orig_node *orig_node; - struct batman_if *if_incoming; -}; - -struct bat_priv { - struct net_device_stats stats; - atomic_t aggregation_enabled; - atomic_t vis_mode; - atomic_t orig_interval; - char num_ifaces; - struct batman_if *primary_if; - struct kobject *mesh_obj; -}; - -struct device_client { - struct list_head queue_list; - unsigned int queue_len; - unsigned char index; - spinlock_t lock; - wait_queue_head_t queue_wait; -}; - -struct device_packet { - struct list_head list; - struct icmp_packet icmp_packet; -}; - -struct hna_local_entry { - uint8_t addr[ETH_ALEN]; - unsigned long last_seen; - char never_purge; -}; - -struct hna_global_entry { - uint8_t addr[ETH_ALEN]; - struct orig_node *orig_node; -}; - -/** - * forw_packet - structure for forw_list maintaining packets to be - * send/forwarded - */ -struct forw_packet { - struct hlist_node list; - unsigned long send_time; - uint8_t own; - struct sk_buff *skb; - unsigned char *packet_buff; - uint16_t packet_len; - uint32_t direct_link_flags; - uint8_t num_packets; - struct delayed_work delayed_work; - struct batman_if *if_incoming; -}; - -/* While scanning for vis-entries of a particular vis-originator - * this list collects its interfaces to create a subgraph/cluster - * out of them later - */ -struct if_list_entry { - uint8_t addr[ETH_ALEN]; - bool primary; - struct hlist_node list; -}; - -#endif diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c deleted file mode 100644 index 1d3d954847f..00000000000 --- a/drivers/staging/batman-adv/vis.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: - * - * 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 "send.h" -#include "translation-table.h" -#include "vis.h" -#include "soft-interface.h" -#include "hard-interface.h" -#include "hash.h" - -/* Returns the smallest signed integer in two's complement with the sizeof x */ -#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u))) - -/* Checks if a sequence number x is a predecessor/successor of y. - they handle overflows/underflows and can correctly check for a - predecessor/successor unless the variable sequence number has grown by - more then 2**(bitwidth(x)-1)-1. - This means that for a uint8_t with the maximum value 255, it would think: - * when adding nothing - it is neither a predecessor nor a successor - * before adding more than 127 to the starting value - it is a predecessor, - * when adding 128 - it is neither a predecessor nor a successor, - * after adding more than 127 to the starting value - it is a successor */ -#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \ - _dummy > smallest_signed_int(_dummy); }) -#define seq_after(x, y) seq_before(y, x) - -struct hashtable_t *vis_hash; -DEFINE_SPINLOCK(vis_hash_lock); -static DEFINE_SPINLOCK(recv_list_lock); -static struct vis_info *my_vis_info; -static struct list_head send_list; /* always locked with vis_hash_lock */ - -static void start_vis_timer(void); - -/* free the info */ -static void free_info(struct kref *ref) -{ - struct vis_info *info = container_of(ref, struct vis_info, refcount); - struct recvlist_node *entry, *tmp; - unsigned long flags; - - list_del_init(&info->send_list); - spin_lock_irqsave(&recv_list_lock, flags); - list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { - list_del(&entry->list); - kfree(entry); - } - spin_unlock_irqrestore(&recv_list_lock, flags); - kfree(info); -} - -/* Compare two vis packets, used by the hashing algorithm */ -static int vis_info_cmp(void *data1, void *data2) -{ - struct vis_info *d1, *d2; - d1 = data1; - d2 = data2; - return compare_orig(d1->packet.vis_orig, d2->packet.vis_orig); -} - -/* hash function to choose an entry in a hash table of given size */ -/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ -static int vis_info_choose(void *data, int size) -{ - struct vis_info *vis_info = data; - unsigned char *key; - uint32_t hash = 0; - size_t i; - - key = vis_info->packet.vis_orig; - for (i = 0; i < ETH_ALEN; i++) { - hash += key[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash % size; -} - -/* insert interface to the list of interfaces of one originator, if it - * does not already exist in the list */ -static void vis_data_insert_interface(const uint8_t *interface, - struct hlist_head *if_list, - bool primary) -{ - struct if_list_entry *entry; - struct hlist_node *pos; - - hlist_for_each_entry(entry, pos, if_list, list) { - if (compare_orig(entry->addr, (void *)interface)) - return; - } - - /* its a new address, add it to the list */ - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return; - memcpy(entry->addr, interface, ETH_ALEN); - entry->primary = primary; - hlist_add_head(&entry->list, if_list); -} - -static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list) -{ - struct if_list_entry *entry; - struct hlist_node *pos; - char tmp_addr_str[ETH_STR_LEN]; - size_t len = 0; - - hlist_for_each_entry(entry, pos, if_list, list) { - if (entry->primary) - len += sprintf(buff + len, "PRIMARY, "); - else { - addr_to_string(tmp_addr_str, entry->addr); - len += sprintf(buff + len, "SEC %s, ", tmp_addr_str); - } - } - - return len; -} - -/* read an entry */ -static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry, - uint8_t *src, bool primary) -{ - char to[40]; - - addr_to_string(to, entry->dest); - if (primary && entry->quality == 0) - return sprintf(buff, "HNA %s, ", to); - else if (compare_orig(entry->src, src)) - return sprintf(buff, "TQ %s %d, ", to, entry->quality); - - return 0; -} - -ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff, - size_t count, loff_t off) -{ - HASHIT(hashit); - struct vis_info *info; - struct vis_info_entry *entries; - struct bat_priv *bat_priv = netdev_priv(net_dev); - HLIST_HEAD(vis_if_list); - struct if_list_entry *entry; - struct hlist_node *pos, *n; - size_t hdr_len, tmp_len; - int i, bytes_written = 0; - char tmp_addr_str[ETH_STR_LEN]; - unsigned long flags; - int vis_server = atomic_read(&bat_priv->vis_mode); - - if ((!bat_priv->primary_if) || - (vis_server == VIS_TYPE_CLIENT_UPDATE)) - return 0; - - hdr_len = 0; - - spin_lock_irqsave(&vis_hash_lock, flags); - while (hash_iterate(vis_hash, &hashit)) { - info = hashit.bucket->data; - entries = (struct vis_info_entry *) - ((char *)info + sizeof(struct vis_info)); - - /* estimated line length */ - if (count < bytes_written + 200) - break; - - for (i = 0; i < info->packet.entries; i++) { - if (entries[i].quality == 0) - continue; - vis_data_insert_interface(entries[i].src, &vis_if_list, - compare_orig(entries[i].src, - info->packet.vis_orig)); - } - - hlist_for_each_entry(entry, pos, &vis_if_list, list) { - addr_to_string(tmp_addr_str, entry->addr); - tmp_len = sprintf(buff + bytes_written, - "%s,", tmp_addr_str); - - for (i = 0; i < info->packet.entries; i++) - tmp_len += vis_data_read_entry( - buff + bytes_written + tmp_len, - &entries[i], entry->addr, - entry->primary); - - /* add primary/secondary records */ - if (compare_orig(entry->addr, info->packet.vis_orig)) - tmp_len += vis_data_read_prim_sec( - buff + bytes_written + tmp_len, - &vis_if_list); - - tmp_len += sprintf(buff + bytes_written + tmp_len, - "\n"); - - hdr_len += tmp_len; - - if (off >= hdr_len) - continue; - - bytes_written += tmp_len; - } - - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { - hlist_del(&entry->list); - kfree(entry); - } - } - spin_unlock_irqrestore(&vis_hash_lock, flags); - - return bytes_written; -} - -/* add the info packet to the send list, if it was not - * already linked in. */ -static void send_list_add(struct vis_info *info) -{ - if (list_empty(&info->send_list)) { - kref_get(&info->refcount); - list_add_tail(&info->send_list, &send_list); - } -} - -/* delete the info packet from the send list, if it was - * linked in. */ -static void send_list_del(struct vis_info *info) -{ - if (!list_empty(&info->send_list)) { - list_del_init(&info->send_list); - kref_put(&info->refcount, free_info); - } -} - -/* tries to add one entry to the receive list. */ -static void recv_list_add(struct list_head *recv_list, char *mac) -{ - struct recvlist_node *entry; - unsigned long flags; - - entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC); - if (!entry) - return; - - memcpy(entry->mac, mac, ETH_ALEN); - spin_lock_irqsave(&recv_list_lock, flags); - list_add_tail(&entry->list, recv_list); - spin_unlock_irqrestore(&recv_list_lock, flags); -} - -/* returns 1 if this mac is in the recv_list */ -static int recv_list_is_in(struct list_head *recv_list, char *mac) -{ - struct recvlist_node *entry; - unsigned long flags; - - spin_lock_irqsave(&recv_list_lock, flags); - list_for_each_entry(entry, recv_list, list) { - if (memcmp(entry->mac, mac, ETH_ALEN) == 0) { - spin_unlock_irqrestore(&recv_list_lock, flags); - return 1; - } - } - spin_unlock_irqrestore(&recv_list_lock, flags); - return 0; -} - -/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old, - * broken.. ). vis hash must be locked outside. is_new is set when the packet - * is newer than old entries in the hash. */ -static struct vis_info *add_packet(struct vis_packet *vis_packet, - int vis_info_len, int *is_new, - int make_broadcast) -{ - struct vis_info *info, *old_info; - struct vis_info search_elem; - - *is_new = 0; - /* sanity check */ - if (vis_hash == NULL) - return NULL; - - /* see if the packet is already in vis_hash */ - memcpy(search_elem.packet.vis_orig, vis_packet->vis_orig, ETH_ALEN); - old_info = hash_find(vis_hash, &search_elem); - - if (old_info != NULL) { - if (!seq_after(vis_packet->seqno, old_info->packet.seqno)) { - if (old_info->packet.seqno == vis_packet->seqno) { - recv_list_add(&old_info->recv_list, - vis_packet->sender_orig); - return old_info; - } else { - /* newer packet is already in hash. */ - return NULL; - } - } - /* remove old entry */ - hash_remove(vis_hash, old_info); - send_list_del(old_info); - kref_put(&old_info->refcount, free_info); - } - - info = kmalloc(sizeof(struct vis_info) + vis_info_len, GFP_ATOMIC); - if (info == NULL) - return NULL; - - kref_init(&info->refcount); - INIT_LIST_HEAD(&info->send_list); - INIT_LIST_HEAD(&info->recv_list); - info->first_seen = jiffies; - memcpy(&info->packet, vis_packet, - sizeof(struct vis_packet) + vis_info_len); - - /* initialize and add new packet. */ - *is_new = 1; - - /* Make it a broadcast packet, if required */ - if (make_broadcast) - memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); - - /* repair if entries is longer than packet. */ - if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len) - info->packet.entries = vis_info_len / - sizeof(struct vis_info_entry); - - recv_list_add(&info->recv_list, info->packet.sender_orig); - - /* try to add it */ - if (hash_add(vis_hash, info) < 0) { - /* did not work (for some reason) */ - kref_put(&old_info->refcount, free_info); - info = NULL; - } - - return info; -} - -/* handle the server sync packet, forward if needed. */ -void receive_server_sync_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len) -{ - struct vis_info *info; - int is_new, make_broadcast; - unsigned long flags; - int vis_server = atomic_read(&bat_priv->vis_mode); - - make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); - - spin_lock_irqsave(&vis_hash_lock, flags); - info = add_packet(vis_packet, vis_info_len, &is_new, make_broadcast); - if (info == NULL) - goto end; - - /* only if we are server ourselves and packet is newer than the one in - * hash.*/ - if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) - send_list_add(info); -end: - spin_unlock_irqrestore(&vis_hash_lock, flags); -} - -/* handle an incoming client update packet and schedule forward if needed. */ -void receive_client_update_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len) -{ - struct vis_info *info; - int is_new; - unsigned long flags; - int vis_server = atomic_read(&bat_priv->vis_mode); - int are_target = 0; - - /* clients shall not broadcast. */ - if (is_bcast(vis_packet->target_orig)) - return; - - /* Are we the target for this VIS packet? */ - if (vis_server == VIS_TYPE_SERVER_SYNC && - is_my_mac(vis_packet->target_orig)) - are_target = 1; - - spin_lock_irqsave(&vis_hash_lock, flags); - info = add_packet(vis_packet, vis_info_len, &is_new, are_target); - if (info == NULL) - goto end; - /* note that outdated packets will be dropped at this point. */ - - - /* send only if we're the target server or ... */ - if (are_target && is_new) { - info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ - send_list_add(info); - - /* ... we're not the recipient (and thus need to forward). */ - } else if (!is_my_mac(info->packet.target_orig)) { - send_list_add(info); - } -end: - spin_unlock_irqrestore(&vis_hash_lock, flags); -} - -/* Walk the originators and find the VIS server with the best tq. Set the packet - * address to its address and return the best_tq. - * - * Must be called with the originator hash locked */ -static int find_best_vis_server(struct vis_info *info) -{ - HASHIT(hashit); - struct orig_node *orig_node; - int best_tq = -1; - - while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit.bucket->data; - if ((orig_node != NULL) && - (orig_node->router != NULL) && - (orig_node->flags & VIS_SERVER) && - (orig_node->router->tq_avg > best_tq)) { - best_tq = orig_node->router->tq_avg; - memcpy(info->packet.target_orig, orig_node->orig, - ETH_ALEN); - } - } - return best_tq; -} - -/* Return true if the vis packet is full. */ -static bool vis_packet_full(struct vis_info *info) -{ - if (info->packet.entries + 1 > - (1000 - sizeof(struct vis_info)) / sizeof(struct vis_info_entry)) - return true; - return false; -} - -/* generates a packet of own vis data, - * returns 0 on success, -1 if no packet could be generated */ -static int generate_vis_packet(struct bat_priv *bat_priv) -{ - HASHIT(hashit_local); - HASHIT(hashit_global); - struct orig_node *orig_node; - struct vis_info *info = (struct vis_info *)my_vis_info; - struct vis_info_entry *entry, *entry_array; - struct hna_local_entry *hna_local_entry; - int best_tq = -1; - unsigned long flags; - - info->first_seen = jiffies; - info->packet.vis_type = atomic_read(&bat_priv->vis_mode); - - spin_lock_irqsave(&orig_hash_lock, flags); - memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); - info->packet.ttl = TTL; - info->packet.seqno++; - info->packet.entries = 0; - - if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) { - best_tq = find_best_vis_server(info); - if (best_tq < 0) { - spin_unlock_irqrestore(&orig_hash_lock, flags); - return -1; - } - } - - entry_array = (struct vis_info_entry *) - ((char *)info + sizeof(struct vis_info)); - - while (hash_iterate(orig_hash, &hashit_global)) { - orig_node = hashit_global.bucket->data; - if (orig_node->router != NULL - && compare_orig(orig_node->router->addr, - orig_node->orig) - && (orig_node->router->if_incoming->if_status == - IF_ACTIVE) - && orig_node->router->tq_avg > 0) { - - /* fill one entry into buffer. */ - entry = &entry_array[info->packet.entries]; - memcpy(entry->src, - orig_node->router->if_incoming->net_dev->dev_addr, - ETH_ALEN); - memcpy(entry->dest, orig_node->orig, ETH_ALEN); - entry->quality = orig_node->router->tq_avg; - info->packet.entries++; - - if (vis_packet_full(info)) { - spin_unlock_irqrestore(&orig_hash_lock, flags); - return 0; - } - } - } - - spin_unlock_irqrestore(&orig_hash_lock, flags); - - spin_lock_irqsave(&hna_local_hash_lock, flags); - while (hash_iterate(hna_local_hash, &hashit_local)) { - hna_local_entry = hashit_local.bucket->data; - entry = &entry_array[info->packet.entries]; - memset(entry->src, 0, ETH_ALEN); - memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN); - entry->quality = 0; /* 0 means HNA */ - info->packet.entries++; - - if (vis_packet_full(info)) { - spin_unlock_irqrestore(&hna_local_hash_lock, flags); - return 0; - } - } - spin_unlock_irqrestore(&hna_local_hash_lock, flags); - return 0; -} - -/* free old vis packets. Must be called with this vis_hash_lock - * held */ -static void purge_vis_packets(void) -{ - HASHIT(hashit); - struct vis_info *info; - - while (hash_iterate(vis_hash, &hashit)) { - info = hashit.bucket->data; - if (info == my_vis_info) /* never purge own data. */ - continue; - if (time_after(jiffies, - info->first_seen + (VIS_TIMEOUT*HZ)/1000)) { - hash_remove_bucket(vis_hash, &hashit); - send_list_del(info); - kref_put(&info->refcount, free_info); - } - } -} - -static void broadcast_vis_packet(struct vis_info *info, int packet_length) -{ - HASHIT(hashit); - struct orig_node *orig_node; - unsigned long flags; - struct batman_if *batman_if; - uint8_t dstaddr[ETH_ALEN]; - - spin_lock_irqsave(&orig_hash_lock, flags); - - /* send to all routers in range. */ - while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit.bucket->data; - - /* if it's a vis server and reachable, send it. */ - if ((!orig_node) || (!orig_node->router)) - continue; - if (!(orig_node->flags & VIS_SERVER)) - continue; - /* don't send it if we already received the packet from - * this node. */ - if (recv_list_is_in(&info->recv_list, orig_node->orig)) - continue; - - memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN); - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&orig_hash_lock, flags); - - send_raw_packet((unsigned char *)&info->packet, - packet_length, batman_if, dstaddr); - - spin_lock_irqsave(&orig_hash_lock, flags); - - } - spin_unlock_irqrestore(&orig_hash_lock, flags); - memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); -} - -static void unicast_vis_packet(struct vis_info *info, int packet_length) -{ - struct orig_node *orig_node; - unsigned long flags; - struct batman_if *batman_if; - uint8_t dstaddr[ETH_ALEN]; - - spin_lock_irqsave(&orig_hash_lock, flags); - orig_node = ((struct orig_node *) - hash_find(orig_hash, info->packet.target_orig)); - - if ((!orig_node) || (!orig_node->router)) - goto out; - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&orig_hash_lock, flags); - - send_raw_packet((unsigned char *)&info->packet, - packet_length, batman_if, dstaddr); - return; - -out: - spin_unlock_irqrestore(&orig_hash_lock, flags); -} - -/* only send one vis packet. called from send_vis_packets() */ -static void send_vis_packet(struct vis_info *info) -{ - int packet_length; - - if (info->packet.ttl < 2) { - printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n"); - return; - } - - memcpy(info->packet.sender_orig, mainIfAddr, ETH_ALEN); - info->packet.ttl--; - - packet_length = sizeof(struct vis_packet) + - info->packet.entries * sizeof(struct vis_info_entry); - - if (is_bcast(info->packet.target_orig)) - broadcast_vis_packet(info, packet_length); - else - unicast_vis_packet(info, packet_length); - info->packet.ttl++; /* restore TTL */ -} - -/* called from timer; send (and maybe generate) vis packet. */ -static void send_vis_packets(struct work_struct *work) -{ - struct vis_info *info, *temp; - unsigned long flags; - /* FIXME: each batman_if will be attached to a softif */ - struct bat_priv *bat_priv = netdev_priv(soft_device); - - spin_lock_irqsave(&vis_hash_lock, flags); - - purge_vis_packets(); - - if (generate_vis_packet(bat_priv) == 0) { - /* schedule if generation was successful */ - send_list_add(my_vis_info); - } - - list_for_each_entry_safe(info, temp, &send_list, send_list) { - - kref_get(&info->refcount); - spin_unlock_irqrestore(&vis_hash_lock, flags); - - send_vis_packet(info); - - spin_lock_irqsave(&vis_hash_lock, flags); - send_list_del(info); - kref_put(&info->refcount, free_info); - } - spin_unlock_irqrestore(&vis_hash_lock, flags); - start_vis_timer(); -} -static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets); - -/* init the vis server. this may only be called when if_list is already - * initialized (e.g. bat0 is initialized, interfaces have been added) */ -int vis_init(void) -{ - unsigned long flags; - if (vis_hash) - return 1; - - spin_lock_irqsave(&vis_hash_lock, flags); - - vis_hash = hash_new(256, vis_info_cmp, vis_info_choose); - if (!vis_hash) { - printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n"); - goto err; - } - - my_vis_info = kmalloc(1000, GFP_ATOMIC); - if (!my_vis_info) { - printk(KERN_ERR "batman-adv:Can't initialize vis packet\n"); - goto err; - } - - /* prefill the vis info */ - my_vis_info->first_seen = jiffies - atomic_read(&vis_interval); - INIT_LIST_HEAD(&my_vis_info->recv_list); - INIT_LIST_HEAD(&my_vis_info->send_list); - kref_init(&my_vis_info->refcount); - my_vis_info->packet.version = COMPAT_VERSION; - my_vis_info->packet.packet_type = BAT_VIS; - my_vis_info->packet.ttl = TTL; - my_vis_info->packet.seqno = 0; - my_vis_info->packet.entries = 0; - - INIT_LIST_HEAD(&send_list); - - memcpy(my_vis_info->packet.vis_orig, mainIfAddr, ETH_ALEN); - memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN); - - if (hash_add(vis_hash, my_vis_info) < 0) { - printk(KERN_ERR - "batman-adv:Can't add own vis packet into hash\n"); - /* not in hash, need to remove it manually. */ - kref_put(&my_vis_info->refcount, free_info); - goto err; - } - - spin_unlock_irqrestore(&vis_hash_lock, flags); - start_vis_timer(); - return 1; - -err: - spin_unlock_irqrestore(&vis_hash_lock, flags); - vis_quit(); - return 0; -} - -/* Decrease the reference count on a hash item info */ -static void free_info_ref(void *data) -{ - struct vis_info *info = data; - - send_list_del(info); - kref_put(&info->refcount, free_info); -} - -/* shutdown vis-server */ -void vis_quit(void) -{ - unsigned long flags; - if (!vis_hash) - return; - - cancel_delayed_work_sync(&vis_timer_wq); - - spin_lock_irqsave(&vis_hash_lock, flags); - /* properly remove, kill timers ... */ - hash_delete(vis_hash, free_info_ref); - vis_hash = NULL; - my_vis_info = NULL; - spin_unlock_irqrestore(&vis_hash_lock, flags); -} - -/* schedule packets for (re)transmission */ -static void start_vis_timer(void) -{ - queue_delayed_work(bat_event_workqueue, &vis_timer_wq, - (atomic_read(&vis_interval) * HZ) / 1000); -} diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h deleted file mode 100644 index 9c1fd771cba..00000000000 --- a/drivers/staging/batman-adv/vis.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * 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 - * - */ - -#define VIS_TIMEOUT 200000 - -struct vis_info { - unsigned long first_seen; - struct list_head recv_list; - /* list of server-neighbors we received a vis-packet - * from. we should not reply to them. */ - struct list_head send_list; - struct kref refcount; - /* this packet might be part of the vis send queue. */ - struct vis_packet packet; - /* vis_info may follow here*/ -} __attribute__((packed)); - -struct vis_info_entry { - uint8_t src[ETH_ALEN]; - uint8_t dest[ETH_ALEN]; - uint8_t quality; /* quality = 0 means HNA */ -} __attribute__((packed)); - -struct recvlist_node { - struct list_head list; - uint8_t mac[ETH_ALEN]; -}; - -extern struct hashtable_t *vis_hash; -extern spinlock_t vis_hash_lock; - -ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff, - size_t count, loff_t off); -void receive_server_sync_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len); -void receive_client_update_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len); -int vis_init(void); -void vis_quit(void); |
