Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Staging: batman-adv: Remove batman-adv from staging

batman-adv is now moved to net/batman-adv/ and can be removed from
staging.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Sven Eckelmann and committed by
Greg Kroah-Hartman
63d5e5a7 45241e50

-10314
-2
drivers/staging/Kconfig
··· 129 129 130 130 source "drivers/staging/wlags49_h25/Kconfig" 131 131 132 - source "drivers/staging/batman-adv/Kconfig" 133 - 134 132 source "drivers/staging/samsung-laptop/Kconfig" 135 133 136 134 source "drivers/staging/sm7xx/Kconfig"
-1
drivers/staging/Makefile
··· 47 47 obj-$(CONFIG_ZRAM) += zram/ 48 48 obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ 49 49 obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ 50 - obj-$(CONFIG_BATMAN_ADV) += batman-adv/ 51 50 obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ 52 51 obj-$(CONFIG_FB_SM7XX) += sm7xx/ 53 52 obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
-26
drivers/staging/batman-adv/Kconfig
··· 1 - # 2 - # B.A.T.M.A.N meshing protocol 3 - # 4 - 5 - config BATMAN_ADV 6 - tristate "B.A.T.M.A.N. Advanced Meshing Protocol" 7 - depends on NET 8 - default n 9 - ---help--- 10 - 11 - B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is 12 - a routing protocol for multi-hop ad-hoc mesh networks. The 13 - networks may be wired or wireless. See 14 - http://www.open-mesh.org/ for more information and user space 15 - tools. 16 - 17 - config BATMAN_ADV_DEBUG 18 - bool "B.A.T.M.A.N. debugging" 19 - depends on BATMAN_ADV != n 20 - ---help--- 21 - 22 - This is an option for use by developers; most people should 23 - say N here. This enables compilation of support for 24 - outputting debugging information to the kernel log. The 25 - output is controlled via the module parameter debug. 26 -
-39
drivers/staging/batman-adv/Makefile
··· 1 - # 2 - # Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - # 4 - # Marek Lindner, Simon Wunderlich 5 - # 6 - # This program is free software; you can redistribute it and/or 7 - # modify it under the terms of version 2 of the GNU General Public 8 - # License as published by the Free Software Foundation. 9 - # 10 - # This program is distributed in the hope that it will be useful, but 11 - # WITHOUT ANY WARRANTY; without even the implied warranty of 12 - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - # General Public License for more details. 14 - # 15 - # You should have received a copy of the GNU General Public License 16 - # along with this program; if not, write to the Free Software 17 - # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - # 02110-1301, USA 19 - # 20 - 21 - obj-$(CONFIG_BATMAN_ADV) += batman-adv.o 22 - batman-adv-y += aggregation.o 23 - batman-adv-y += bat_debugfs.o 24 - batman-adv-y += bat_sysfs.o 25 - batman-adv-y += bitarray.o 26 - batman-adv-y += gateway_client.o 27 - batman-adv-y += gateway_common.o 28 - batman-adv-y += hard-interface.o 29 - batman-adv-y += hash.o 30 - batman-adv-y += icmp_socket.o 31 - batman-adv-y += main.o 32 - batman-adv-y += originator.o 33 - batman-adv-y += ring_buffer.o 34 - batman-adv-y += routing.o 35 - batman-adv-y += send.o 36 - batman-adv-y += soft-interface.o 37 - batman-adv-y += translation-table.o 38 - batman-adv-y += unicast.o 39 - batman-adv-y += vis.o
-240
drivers/staging/batman-adv/README
··· 1 - [state: 21-11-2010] 2 - 3 - BATMAN-ADV 4 - ---------- 5 - 6 - Batman advanced is a new approach to wireless networking which 7 - does no longer operate on the IP basis. Unlike the batman daemon, 8 - which exchanges information using UDP packets and sets routing 9 - tables, batman-advanced operates on ISO/OSI Layer 2 only and uses 10 - and routes (or better: bridges) Ethernet Frames. It emulates a 11 - virtual network switch of all nodes participating. Therefore all 12 - nodes appear to be link local, thus all higher operating proto- 13 - cols won't be affected by any changes within the network. You can 14 - run almost any protocol above batman advanced, prominent examples 15 - are: IPv4, IPv6, DHCP, IPX. 16 - 17 - Batman advanced was implemented as a Linux kernel driver to re- 18 - duce the overhead to a minimum. It does not depend on any (other) 19 - network driver, and can be used on wifi as well as ethernet lan, 20 - vpn, etc ... (anything with ethernet-style layer 2). 21 - 22 - CONFIGURATION 23 - ------------- 24 - 25 - Load the batman-adv module into your kernel: 26 - 27 - # insmod batman-adv.ko 28 - 29 - The module is now waiting for activation. You must add some in- 30 - terfaces on which batman can operate. After loading the module 31 - batman advanced will scan your systems interfaces to search for 32 - compatible interfaces. Once found, it will create subfolders in 33 - the /sys directories of each supported interface, e.g. 34 - 35 - # ls /sys/class/net/eth0/batman_adv/ 36 - # iface_status mesh_iface 37 - 38 - If an interface does not have the "batman_adv" subfolder it prob- 39 - ably is not supported. Not supported interfaces are: loopback, 40 - non-ethernet and batman's own interfaces. 41 - 42 - Note: After the module was loaded it will continuously watch for 43 - new interfaces to verify the compatibility. There is no need to 44 - reload the module if you plug your USB wifi adapter into your ma- 45 - chine after batman advanced was initially loaded. 46 - 47 - To activate a given interface simply write "bat0" into its 48 - "mesh_iface" file inside the batman_adv subfolder: 49 - 50 - # echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface 51 - 52 - Repeat this step for all interfaces you wish to add. Now batman 53 - starts using/broadcasting on this/these interface(s). 54 - 55 - By reading the "iface_status" file you can check its status: 56 - 57 - # cat /sys/class/net/eth0/batman_adv/iface_status 58 - # active 59 - 60 - To deactivate an interface you have to write "none" into its 61 - "mesh_iface" file: 62 - 63 - # echo none > /sys/class/net/eth0/batman_adv/mesh_iface 64 - 65 - 66 - All mesh wide settings can be found in batman's own interface 67 - folder: 68 - 69 - # ls /sys/class/net/bat0/mesh/ 70 - # aggregated_ogms bonding fragmentation orig_interval 71 - # vis_mode 72 - 73 - 74 - There is a special folder for debugging informations: 75 - 76 - # ls /sys/kernel/debug/batman_adv/bat0/ 77 - # originators socket transtable_global transtable_local 78 - # vis_data 79 - 80 - 81 - Some of the files contain all sort of status information regard- 82 - ing the mesh network. For example, you can view the table of 83 - originators (mesh participants) with: 84 - 85 - # cat /sys/kernel/debug/batman_adv/bat0/originators 86 - 87 - Other files allow to change batman's behaviour to better fit your 88 - requirements. For instance, you can check the current originator 89 - interval (value in milliseconds which determines how often batman 90 - sends its broadcast packets): 91 - 92 - # cat /sys/class/net/bat0/mesh/orig_interval 93 - # 1000 94 - 95 - and also change its value: 96 - 97 - # echo 3000 > /sys/class/net/bat0/mesh/orig_interval 98 - 99 - In very mobile scenarios, you might want to adjust the originator 100 - interval to a lower value. This will make the mesh more respon- 101 - sive to topology changes, but will also increase the overhead. 102 - 103 - 104 - USAGE 105 - ----- 106 - 107 - To make use of your newly created mesh, batman advanced provides 108 - a new interface "bat0" which you should use from this point on. 109 - All interfaces added to batman advanced are not relevant any 110 - longer because batman handles them for you. Basically, one "hands 111 - over" the data by using the batman interface and batman will make 112 - sure it reaches its destination. 113 - 114 - The "bat0" interface can be used like any other regular inter- 115 - face. It needs an IP address which can be either statically con- 116 - figured or dynamically (by using DHCP or similar services): 117 - 118 - # NodeA: ifconfig bat0 192.168.0.1 119 - # NodeB: ifconfig bat0 192.168.0.2 120 - # NodeB: ping 192.168.0.1 121 - 122 - Note: In order to avoid problems remove all IP addresses previ- 123 - ously assigned to interfaces now used by batman advanced, e.g. 124 - 125 - # ifconfig eth0 0.0.0.0 126 - 127 - 128 - VISUALIZATION 129 - ------------- 130 - 131 - If you want topology visualization, at least one mesh node must 132 - be configured as VIS-server: 133 - 134 - # echo "server" > /sys/class/net/bat0/mesh/vis_mode 135 - 136 - Each node is either configured as "server" or as "client" (de- 137 - fault: "client"). Clients send their topology data to the server 138 - next to them, and server synchronize with other servers. If there 139 - is no server configured (default) within the mesh, no topology 140 - information will be transmitted. With these "synchronizing 141 - servers", there can be 1 or more vis servers sharing the same (or 142 - at least very similar) data. 143 - 144 - When configured as server, you can get a topology snapshot of 145 - your mesh: 146 - 147 - # cat /sys/kernel/debug/batman_adv/bat0/vis_data 148 - 149 - This raw output is intended to be easily parsable and convertable 150 - with other tools. Have a look at the batctl README if you want a 151 - vis output in dot or json format for instance and how those out- 152 - puts could then be visualised in an image. 153 - 154 - The raw format consists of comma separated values per entry where 155 - each entry is giving information about a certain source inter- 156 - face. Each entry can/has to have the following values: 157 - -> "mac" - mac address of an originator's source interface 158 - (each line begins with it) 159 - -> "TQ mac value" - src mac's link quality towards mac address 160 - of a neighbor originator's interface which 161 - is being used for routing 162 - -> "HNA mac" - HNA announced by source mac 163 - -> "PRIMARY" - this is a primary interface 164 - -> "SEC mac" - secondary mac address of source 165 - (requires preceding PRIMARY) 166 - 167 - The TQ value has a range from 4 to 255 with 255 being the best. 168 - The HNA entries are showing which hosts are connected to the mesh 169 - via bat0 or being bridged into the mesh network. The PRIMARY/SEC 170 - values are only applied on primary interfaces 171 - 172 - 173 - LOGGING/DEBUGGING 174 - ----------------- 175 - 176 - All error messages, warnings and information messages are sent to 177 - the kernel log. Depending on your operating system distribution 178 - this can be read in one of a number of ways. Try using the com- 179 - mands: dmesg, logread, or looking in the files /var/log/kern.log 180 - or /var/log/syslog. All batman-adv messages are prefixed with 181 - "batman-adv:" So to see just these messages try 182 - 183 - # dmesg | grep batman-adv 184 - 185 - When investigating problems with your mesh network it is some- 186 - times necessary to see more detail debug messages. This must be 187 - enabled when compiling the batman-adv module. When building bat- 188 - man-adv as part of kernel, use "make menuconfig" and enable the 189 - option "B.A.T.M.A.N. debugging". 190 - 191 - Those additional debug messages can be accessed using a special 192 - file in debugfs 193 - 194 - # cat /sys/kernel/debug/batman_adv/bat0/log 195 - 196 - The additional debug output is by default disabled. It can be en- 197 - abled during run time. Following log_levels are defined: 198 - 199 - 0 - All debug output disabled 200 - 1 - Enable messages related to routing / flooding / broadcasting 201 - 2 - Enable route or hna added / changed / deleted 202 - 3 - Enable all messages 203 - 204 - The debug output can be changed at runtime using the file 205 - /sys/class/net/bat0/mesh/log_level. e.g. 206 - 207 - # echo 2 > /sys/class/net/bat0/mesh/log_level 208 - 209 - will enable debug messages for when routes or HNAs change. 210 - 211 - 212 - BATCTL 213 - ------ 214 - 215 - As batman advanced operates on layer 2 all hosts participating in 216 - the virtual switch are completely transparent for all protocols 217 - above layer 2. Therefore the common diagnosis tools do not work 218 - as expected. To overcome these problems batctl was created. At 219 - the moment the batctl contains ping, traceroute, tcpdump and 220 - interfaces to the kernel module settings. 221 - 222 - For more information, please see the manpage (man batctl). 223 - 224 - batctl is available on http://www.open-mesh.org/ 225 - 226 - 227 - CONTACT 228 - ------- 229 - 230 - Please send us comments, experiences, questions, anything :) 231 - 232 - IRC: #batman on irc.freenode.org 233 - Mailing-list: b.a.t.m.a.n@b.a.t.m.a.n@lists.open-mesh.org 234 - (optional subscription at 235 - https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) 236 - 237 - You can also contact the Authors: 238 - 239 - Marek Lindner <lindner_marek@yahoo.de> 240 - Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
-10
drivers/staging/batman-adv/TODO
··· 1 - * Request a new review 2 - * Process the comments from the review 3 - * Move into mainline proper 4 - 5 - Please send all patches to: 6 - Marek Lindner <lindner_marek@yahoo.de> 7 - Simon Wunderlich <siwu@hrz.tu-chemnitz.de> 8 - Sven Eckelmann <sven.eckelmann@gmx.de> 9 - b.a.t.m.a.n@lists.open-mesh.org 10 - Greg Kroah-Hartman <gregkh@suse.de>
-273
drivers/staging/batman-adv/aggregation.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "aggregation.h" 24 - #include "send.h" 25 - #include "routing.h" 26 - 27 - /* calculate the size of the hna information for a given packet */ 28 - static int hna_len(struct batman_packet *batman_packet) 29 - { 30 - return batman_packet->num_hna * ETH_ALEN; 31 - } 32 - 33 - /* return true if new_packet can be aggregated with forw_packet */ 34 - static bool can_aggregate_with(struct batman_packet *new_batman_packet, 35 - int packet_len, 36 - unsigned long send_time, 37 - bool directlink, 38 - struct batman_if *if_incoming, 39 - struct forw_packet *forw_packet) 40 - { 41 - struct batman_packet *batman_packet = 42 - (struct batman_packet *)forw_packet->skb->data; 43 - int aggregated_bytes = forw_packet->packet_len + packet_len; 44 - 45 - /** 46 - * we can aggregate the current packet to this aggregated packet 47 - * if: 48 - * 49 - * - the send time is within our MAX_AGGREGATION_MS time 50 - * - the resulting packet wont be bigger than 51 - * MAX_AGGREGATION_BYTES 52 - */ 53 - 54 - if (time_before(send_time, forw_packet->send_time) && 55 - time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), 56 - forw_packet->send_time) && 57 - (aggregated_bytes <= MAX_AGGREGATION_BYTES)) { 58 - 59 - /** 60 - * check aggregation compatibility 61 - * -> direct link packets are broadcasted on 62 - * their interface only 63 - * -> aggregate packet if the current packet is 64 - * a "global" packet as well as the base 65 - * packet 66 - */ 67 - 68 - /* packets without direct link flag and high TTL 69 - * are flooded through the net */ 70 - if ((!directlink) && 71 - (!(batman_packet->flags & DIRECTLINK)) && 72 - (batman_packet->ttl != 1) && 73 - 74 - /* own packets originating non-primary 75 - * interfaces leave only that interface */ 76 - ((!forw_packet->own) || 77 - (forw_packet->if_incoming->if_num == 0))) 78 - return true; 79 - 80 - /* if the incoming packet is sent via this one 81 - * interface only - we still can aggregate */ 82 - if ((directlink) && 83 - (new_batman_packet->ttl == 1) && 84 - (forw_packet->if_incoming == if_incoming) && 85 - 86 - /* packets from direct neighbors or 87 - * own secondary interface packets 88 - * (= secondary interface packets in general) */ 89 - (batman_packet->flags & DIRECTLINK || 90 - (forw_packet->own && 91 - forw_packet->if_incoming->if_num != 0))) 92 - return true; 93 - } 94 - 95 - return false; 96 - } 97 - 98 - #define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) 99 - /* create a new aggregated packet and add this packet to it */ 100 - static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, 101 - unsigned long send_time, bool direct_link, 102 - struct batman_if *if_incoming, 103 - int own_packet) 104 - { 105 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 106 - struct forw_packet *forw_packet_aggr; 107 - unsigned char *skb_buff; 108 - 109 - /* own packet should always be scheduled */ 110 - if (!own_packet) { 111 - if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) { 112 - bat_dbg(DBG_BATMAN, bat_priv, 113 - "batman packet queue full\n"); 114 - return; 115 - } 116 - } 117 - 118 - forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); 119 - if (!forw_packet_aggr) { 120 - if (!own_packet) 121 - atomic_inc(&bat_priv->batman_queue_left); 122 - return; 123 - } 124 - 125 - if ((atomic_read(&bat_priv->aggregated_ogms)) && 126 - (packet_len < MAX_AGGREGATION_BYTES)) 127 - forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES + 128 - sizeof(struct ethhdr)); 129 - else 130 - forw_packet_aggr->skb = dev_alloc_skb(packet_len + 131 - sizeof(struct ethhdr)); 132 - 133 - if (!forw_packet_aggr->skb) { 134 - if (!own_packet) 135 - atomic_inc(&bat_priv->batman_queue_left); 136 - kfree(forw_packet_aggr); 137 - return; 138 - } 139 - skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr)); 140 - 141 - INIT_HLIST_NODE(&forw_packet_aggr->list); 142 - 143 - skb_buff = skb_put(forw_packet_aggr->skb, packet_len); 144 - forw_packet_aggr->packet_len = packet_len; 145 - memcpy(skb_buff, packet_buff, packet_len); 146 - 147 - forw_packet_aggr->own = own_packet; 148 - forw_packet_aggr->if_incoming = if_incoming; 149 - forw_packet_aggr->num_packets = 0; 150 - forw_packet_aggr->direct_link_flags = 0; 151 - forw_packet_aggr->send_time = send_time; 152 - 153 - /* save packet direct link flag status */ 154 - if (direct_link) 155 - forw_packet_aggr->direct_link_flags |= 1; 156 - 157 - /* add new packet to packet list */ 158 - spin_lock_bh(&bat_priv->forw_bat_list_lock); 159 - hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list); 160 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 161 - 162 - /* start timer for this packet */ 163 - INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, 164 - send_outstanding_bat_packet); 165 - queue_delayed_work(bat_event_workqueue, 166 - &forw_packet_aggr->delayed_work, 167 - send_time - jiffies); 168 - } 169 - 170 - /* aggregate a new packet into the existing aggregation */ 171 - static void aggregate(struct forw_packet *forw_packet_aggr, 172 - unsigned char *packet_buff, 173 - int packet_len, 174 - bool direct_link) 175 - { 176 - unsigned char *skb_buff; 177 - 178 - skb_buff = skb_put(forw_packet_aggr->skb, packet_len); 179 - memcpy(skb_buff, packet_buff, packet_len); 180 - forw_packet_aggr->packet_len += packet_len; 181 - forw_packet_aggr->num_packets++; 182 - 183 - /* save packet direct link flag status */ 184 - if (direct_link) 185 - forw_packet_aggr->direct_link_flags |= 186 - (1 << forw_packet_aggr->num_packets); 187 - } 188 - 189 - void add_bat_packet_to_list(struct bat_priv *bat_priv, 190 - unsigned char *packet_buff, int packet_len, 191 - struct batman_if *if_incoming, char own_packet, 192 - unsigned long send_time) 193 - { 194 - /** 195 - * _aggr -> pointer to the packet we want to aggregate with 196 - * _pos -> pointer to the position in the queue 197 - */ 198 - struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL; 199 - struct hlist_node *tmp_node; 200 - struct batman_packet *batman_packet = 201 - (struct batman_packet *)packet_buff; 202 - bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; 203 - 204 - /* find position for the packet in the forward queue */ 205 - spin_lock_bh(&bat_priv->forw_bat_list_lock); 206 - /* own packets are not to be aggregated */ 207 - if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { 208 - hlist_for_each_entry(forw_packet_pos, tmp_node, 209 - &bat_priv->forw_bat_list, list) { 210 - if (can_aggregate_with(batman_packet, 211 - packet_len, 212 - send_time, 213 - direct_link, 214 - if_incoming, 215 - forw_packet_pos)) { 216 - forw_packet_aggr = forw_packet_pos; 217 - break; 218 - } 219 - } 220 - } 221 - 222 - /* nothing to aggregate with - either aggregation disabled or no 223 - * suitable aggregation packet found */ 224 - if (forw_packet_aggr == NULL) { 225 - /* the following section can run without the lock */ 226 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 227 - 228 - /** 229 - * if we could not aggregate this packet with one of the others 230 - * we hold it back for a while, so that it might be aggregated 231 - * later on 232 - */ 233 - if ((!own_packet) && 234 - (atomic_read(&bat_priv->aggregated_ogms))) 235 - send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); 236 - 237 - new_aggregated_packet(packet_buff, packet_len, 238 - send_time, direct_link, 239 - if_incoming, own_packet); 240 - } else { 241 - aggregate(forw_packet_aggr, 242 - packet_buff, packet_len, 243 - direct_link); 244 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 245 - } 246 - } 247 - 248 - /* unpack the aggregated packets and process them one by one */ 249 - void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, 250 - int packet_len, struct batman_if *if_incoming) 251 - { 252 - struct batman_packet *batman_packet; 253 - int buff_pos = 0; 254 - unsigned char *hna_buff; 255 - 256 - batman_packet = (struct batman_packet *)packet_buff; 257 - 258 - do { 259 - /* network to host order for our 32bit seqno, and the 260 - orig_interval. */ 261 - batman_packet->seqno = ntohl(batman_packet->seqno); 262 - 263 - hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN; 264 - receive_bat_packet(ethhdr, batman_packet, 265 - hna_buff, hna_len(batman_packet), 266 - if_incoming); 267 - 268 - buff_pos += BAT_PACKET_LEN + hna_len(batman_packet); 269 - batman_packet = (struct batman_packet *) 270 - (packet_buff + buff_pos); 271 - } while (aggregated_packet(buff_pos, packet_len, 272 - batman_packet->num_hna)); 273 - }
-43
drivers/staging/batman-adv/aggregation.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_AGGREGATION_H_ 23 - #define _NET_BATMAN_ADV_AGGREGATION_H_ 24 - 25 - #include "main.h" 26 - 27 - /* is there another aggregated packet here? */ 28 - static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) 29 - { 30 - int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN); 31 - 32 - return (next_buff_pos <= packet_len) && 33 - (next_buff_pos <= MAX_AGGREGATION_BYTES); 34 - } 35 - 36 - void add_bat_packet_to_list(struct bat_priv *bat_priv, 37 - unsigned char *packet_buff, int packet_len, 38 - struct batman_if *if_incoming, char own_packet, 39 - unsigned long send_time); 40 - void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, 41 - int packet_len, struct batman_if *if_incoming); 42 - 43 - #endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */
-360
drivers/staging/batman-adv/bat_debugfs.c
··· 1 - /* 2 - * Copyright (C) 2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - 24 - #include <linux/debugfs.h> 25 - 26 - #include "bat_debugfs.h" 27 - #include "translation-table.h" 28 - #include "originator.h" 29 - #include "hard-interface.h" 30 - #include "gateway_common.h" 31 - #include "gateway_client.h" 32 - #include "soft-interface.h" 33 - #include "vis.h" 34 - #include "icmp_socket.h" 35 - 36 - static struct dentry *bat_debugfs; 37 - 38 - #ifdef CONFIG_BATMAN_ADV_DEBUG 39 - #define LOG_BUFF_MASK (log_buff_len-1) 40 - #define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK]) 41 - 42 - static int log_buff_len = LOG_BUF_LEN; 43 - 44 - static void emit_log_char(struct debug_log *debug_log, char c) 45 - { 46 - LOG_BUFF(debug_log->log_end) = c; 47 - debug_log->log_end++; 48 - 49 - if (debug_log->log_end - debug_log->log_start > log_buff_len) 50 - debug_log->log_start = debug_log->log_end - log_buff_len; 51 - } 52 - 53 - static int fdebug_log(struct debug_log *debug_log, char *fmt, ...) 54 - { 55 - int printed_len; 56 - va_list args; 57 - static char debug_log_buf[256]; 58 - char *p; 59 - 60 - if (!debug_log) 61 - return 0; 62 - 63 - spin_lock_bh(&debug_log->lock); 64 - va_start(args, fmt); 65 - printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), 66 - fmt, args); 67 - va_end(args); 68 - 69 - for (p = debug_log_buf; *p != 0; p++) 70 - emit_log_char(debug_log, *p); 71 - 72 - spin_unlock_bh(&debug_log->lock); 73 - 74 - wake_up(&debug_log->queue_wait); 75 - 76 - return 0; 77 - } 78 - 79 - int debug_log(struct bat_priv *bat_priv, char *fmt, ...) 80 - { 81 - va_list args; 82 - char tmp_log_buf[256]; 83 - 84 - va_start(args, fmt); 85 - vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); 86 - fdebug_log(bat_priv->debug_log, "[%10u] %s", 87 - (jiffies / HZ), tmp_log_buf); 88 - va_end(args); 89 - 90 - return 0; 91 - } 92 - 93 - static int log_open(struct inode *inode, struct file *file) 94 - { 95 - nonseekable_open(inode, file); 96 - file->private_data = inode->i_private; 97 - inc_module_count(); 98 - return 0; 99 - } 100 - 101 - static int log_release(struct inode *inode, struct file *file) 102 - { 103 - dec_module_count(); 104 - return 0; 105 - } 106 - 107 - static ssize_t log_read(struct file *file, char __user *buf, 108 - size_t count, loff_t *ppos) 109 - { 110 - struct bat_priv *bat_priv = file->private_data; 111 - struct debug_log *debug_log = bat_priv->debug_log; 112 - int error, i = 0; 113 - char c; 114 - 115 - if ((file->f_flags & O_NONBLOCK) && 116 - !(debug_log->log_end - debug_log->log_start)) 117 - return -EAGAIN; 118 - 119 - if ((!buf) || (count < 0)) 120 - return -EINVAL; 121 - 122 - if (count == 0) 123 - return 0; 124 - 125 - if (!access_ok(VERIFY_WRITE, buf, count)) 126 - return -EFAULT; 127 - 128 - error = wait_event_interruptible(debug_log->queue_wait, 129 - (debug_log->log_start - debug_log->log_end)); 130 - 131 - if (error) 132 - return error; 133 - 134 - spin_lock_bh(&debug_log->lock); 135 - 136 - while ((!error) && (i < count) && 137 - (debug_log->log_start != debug_log->log_end)) { 138 - c = LOG_BUFF(debug_log->log_start); 139 - 140 - debug_log->log_start++; 141 - 142 - spin_unlock_bh(&debug_log->lock); 143 - 144 - error = __put_user(c, buf); 145 - 146 - spin_lock_bh(&debug_log->lock); 147 - 148 - buf++; 149 - i++; 150 - 151 - } 152 - 153 - spin_unlock_bh(&debug_log->lock); 154 - 155 - if (!error) 156 - return i; 157 - 158 - return error; 159 - } 160 - 161 - static unsigned int log_poll(struct file *file, poll_table *wait) 162 - { 163 - struct bat_priv *bat_priv = file->private_data; 164 - struct debug_log *debug_log = bat_priv->debug_log; 165 - 166 - poll_wait(file, &debug_log->queue_wait, wait); 167 - 168 - if (debug_log->log_end - debug_log->log_start) 169 - return POLLIN | POLLRDNORM; 170 - 171 - return 0; 172 - } 173 - 174 - static const struct file_operations log_fops = { 175 - .open = log_open, 176 - .release = log_release, 177 - .read = log_read, 178 - .poll = log_poll, 179 - .llseek = no_llseek, 180 - }; 181 - 182 - static int debug_log_setup(struct bat_priv *bat_priv) 183 - { 184 - struct dentry *d; 185 - 186 - if (!bat_priv->debug_dir) 187 - goto err; 188 - 189 - bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC); 190 - if (!bat_priv->debug_log) 191 - goto err; 192 - 193 - spin_lock_init(&bat_priv->debug_log->lock); 194 - init_waitqueue_head(&bat_priv->debug_log->queue_wait); 195 - 196 - d = debugfs_create_file("log", S_IFREG | S_IRUSR, 197 - bat_priv->debug_dir, bat_priv, &log_fops); 198 - if (d) 199 - goto err; 200 - 201 - return 0; 202 - 203 - err: 204 - return 1; 205 - } 206 - 207 - static void debug_log_cleanup(struct bat_priv *bat_priv) 208 - { 209 - kfree(bat_priv->debug_log); 210 - bat_priv->debug_log = NULL; 211 - } 212 - #else /* CONFIG_BATMAN_ADV_DEBUG */ 213 - static int debug_log_setup(struct bat_priv *bat_priv) 214 - { 215 - bat_priv->debug_log = NULL; 216 - return 0; 217 - } 218 - 219 - static void debug_log_cleanup(struct bat_priv *bat_priv) 220 - { 221 - return; 222 - } 223 - #endif 224 - 225 - static int originators_open(struct inode *inode, struct file *file) 226 - { 227 - struct net_device *net_dev = (struct net_device *)inode->i_private; 228 - return single_open(file, orig_seq_print_text, net_dev); 229 - } 230 - 231 - static int gateways_open(struct inode *inode, struct file *file) 232 - { 233 - struct net_device *net_dev = (struct net_device *)inode->i_private; 234 - return single_open(file, gw_client_seq_print_text, net_dev); 235 - } 236 - 237 - static int softif_neigh_open(struct inode *inode, struct file *file) 238 - { 239 - struct net_device *net_dev = (struct net_device *)inode->i_private; 240 - return single_open(file, softif_neigh_seq_print_text, net_dev); 241 - } 242 - 243 - static int transtable_global_open(struct inode *inode, struct file *file) 244 - { 245 - struct net_device *net_dev = (struct net_device *)inode->i_private; 246 - return single_open(file, hna_global_seq_print_text, net_dev); 247 - } 248 - 249 - static int transtable_local_open(struct inode *inode, struct file *file) 250 - { 251 - struct net_device *net_dev = (struct net_device *)inode->i_private; 252 - return single_open(file, hna_local_seq_print_text, net_dev); 253 - } 254 - 255 - static int vis_data_open(struct inode *inode, struct file *file) 256 - { 257 - struct net_device *net_dev = (struct net_device *)inode->i_private; 258 - return single_open(file, vis_seq_print_text, net_dev); 259 - } 260 - 261 - struct bat_debuginfo { 262 - struct attribute attr; 263 - const struct file_operations fops; 264 - }; 265 - 266 - #define BAT_DEBUGINFO(_name, _mode, _open) \ 267 - struct bat_debuginfo bat_debuginfo_##_name = { \ 268 - .attr = { .name = __stringify(_name), \ 269 - .mode = _mode, }, \ 270 - .fops = { .owner = THIS_MODULE, \ 271 - .open = _open, \ 272 - .read = seq_read, \ 273 - .llseek = seq_lseek, \ 274 - .release = single_release, \ 275 - } \ 276 - }; 277 - 278 - static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); 279 - static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); 280 - static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); 281 - static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open); 282 - static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); 283 - static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); 284 - 285 - static struct bat_debuginfo *mesh_debuginfos[] = { 286 - &bat_debuginfo_originators, 287 - &bat_debuginfo_gateways, 288 - &bat_debuginfo_softif_neigh, 289 - &bat_debuginfo_transtable_global, 290 - &bat_debuginfo_transtable_local, 291 - &bat_debuginfo_vis_data, 292 - NULL, 293 - }; 294 - 295 - void debugfs_init(void) 296 - { 297 - bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL); 298 - if (bat_debugfs == ERR_PTR(-ENODEV)) 299 - bat_debugfs = NULL; 300 - } 301 - 302 - void debugfs_destroy(void) 303 - { 304 - if (bat_debugfs) { 305 - debugfs_remove_recursive(bat_debugfs); 306 - bat_debugfs = NULL; 307 - } 308 - } 309 - 310 - int debugfs_add_meshif(struct net_device *dev) 311 - { 312 - struct bat_priv *bat_priv = netdev_priv(dev); 313 - struct bat_debuginfo **bat_debug; 314 - struct dentry *file; 315 - 316 - if (!bat_debugfs) 317 - goto out; 318 - 319 - bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs); 320 - if (!bat_priv->debug_dir) 321 - goto out; 322 - 323 - bat_socket_setup(bat_priv); 324 - debug_log_setup(bat_priv); 325 - 326 - for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) { 327 - file = debugfs_create_file(((*bat_debug)->attr).name, 328 - S_IFREG | ((*bat_debug)->attr).mode, 329 - bat_priv->debug_dir, 330 - dev, &(*bat_debug)->fops); 331 - if (!file) { 332 - bat_err(dev, "Can't add debugfs file: %s/%s\n", 333 - dev->name, ((*bat_debug)->attr).name); 334 - goto rem_attr; 335 - } 336 - } 337 - 338 - return 0; 339 - rem_attr: 340 - debugfs_remove_recursive(bat_priv->debug_dir); 341 - bat_priv->debug_dir = NULL; 342 - out: 343 - #ifdef CONFIG_DEBUG_FS 344 - return -ENOMEM; 345 - #else 346 - return 0; 347 - #endif /* CONFIG_DEBUG_FS */ 348 - } 349 - 350 - void debugfs_del_meshif(struct net_device *dev) 351 - { 352 - struct bat_priv *bat_priv = netdev_priv(dev); 353 - 354 - debug_log_cleanup(bat_priv); 355 - 356 - if (bat_debugfs) { 357 - debugfs_remove_recursive(bat_priv->debug_dir); 358 - bat_priv->debug_dir = NULL; 359 - } 360 - }
-33
drivers/staging/batman-adv/bat_debugfs.h
··· 1 - /* 2 - * Copyright (C) 2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - 23 - #ifndef _NET_BATMAN_ADV_DEBUGFS_H_ 24 - #define _NET_BATMAN_ADV_DEBUGFS_H_ 25 - 26 - #define DEBUGFS_BAT_SUBDIR "batman_adv" 27 - 28 - void debugfs_init(void); 29 - void debugfs_destroy(void); 30 - int debugfs_add_meshif(struct net_device *dev); 31 - void debugfs_del_meshif(struct net_device *dev); 32 - 33 - #endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */
-593
drivers/staging/batman-adv/bat_sysfs.c
··· 1 - /* 2 - * Copyright (C) 2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "bat_sysfs.h" 24 - #include "translation-table.h" 25 - #include "originator.h" 26 - #include "hard-interface.h" 27 - #include "gateway_common.h" 28 - #include "gateway_client.h" 29 - #include "vis.h" 30 - 31 - #define to_dev(obj) container_of(obj, struct device, kobj) 32 - #define kobj_to_netdev(obj) to_net_dev(to_dev(obj->parent)) 33 - #define kobj_to_batpriv(obj) netdev_priv(kobj_to_netdev(obj)) 34 - 35 - /* Use this, if you have customized show and store functions */ 36 - #define BAT_ATTR(_name, _mode, _show, _store) \ 37 - struct bat_attribute bat_attr_##_name = { \ 38 - .attr = {.name = __stringify(_name), \ 39 - .mode = _mode }, \ 40 - .show = _show, \ 41 - .store = _store, \ 42 - }; 43 - 44 - #define BAT_ATTR_STORE_BOOL(_name, _post_func) \ 45 - ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ 46 - char *buff, size_t count) \ 47 - { \ 48 - struct net_device *net_dev = kobj_to_netdev(kobj); \ 49 - struct bat_priv *bat_priv = netdev_priv(net_dev); \ 50 - return __store_bool_attr(buff, count, _post_func, attr, \ 51 - &bat_priv->_name, net_dev); \ 52 - } 53 - 54 - #define BAT_ATTR_SHOW_BOOL(_name) \ 55 - ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ 56 - char *buff) \ 57 - { \ 58 - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ 59 - return sprintf(buff, "%s\n", \ 60 - atomic_read(&bat_priv->_name) == 0 ? \ 61 - "disabled" : "enabled"); \ 62 - } \ 63 - 64 - /* Use this, if you are going to turn a [name] in bat_priv on or off */ 65 - #define BAT_ATTR_BOOL(_name, _mode, _post_func) \ 66 - static BAT_ATTR_STORE_BOOL(_name, _post_func) \ 67 - static BAT_ATTR_SHOW_BOOL(_name) \ 68 - static BAT_ATTR(_name, _mode, show_##_name, store_##_name) 69 - 70 - 71 - #define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ 72 - ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ 73 - char *buff, size_t count) \ 74 - { \ 75 - struct net_device *net_dev = kobj_to_netdev(kobj); \ 76 - struct bat_priv *bat_priv = netdev_priv(net_dev); \ 77 - return __store_uint_attr(buff, count, _min, _max, _post_func, \ 78 - attr, &bat_priv->_name, net_dev); \ 79 - } 80 - 81 - #define BAT_ATTR_SHOW_UINT(_name) \ 82 - ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ 83 - char *buff) \ 84 - { \ 85 - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ 86 - return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ 87 - } \ 88 - 89 - /* Use this, if you are going to set [name] in bat_priv to unsigned integer 90 - * values only */ 91 - #define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \ 92 - static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ 93 - static BAT_ATTR_SHOW_UINT(_name) \ 94 - static BAT_ATTR(_name, _mode, show_##_name, store_##_name) 95 - 96 - 97 - static int store_bool_attr(char *buff, size_t count, 98 - struct net_device *net_dev, 99 - char *attr_name, atomic_t *attr) 100 - { 101 - int enabled = -1; 102 - 103 - if (buff[count - 1] == '\n') 104 - buff[count - 1] = '\0'; 105 - 106 - if ((strncmp(buff, "1", 2) == 0) || 107 - (strncmp(buff, "enable", 7) == 0) || 108 - (strncmp(buff, "enabled", 8) == 0)) 109 - enabled = 1; 110 - 111 - if ((strncmp(buff, "0", 2) == 0) || 112 - (strncmp(buff, "disable", 8) == 0) || 113 - (strncmp(buff, "disabled", 9) == 0)) 114 - enabled = 0; 115 - 116 - if (enabled < 0) { 117 - bat_info(net_dev, 118 - "%s: Invalid parameter received: %s\n", 119 - attr_name, buff); 120 - return -EINVAL; 121 - } 122 - 123 - if (atomic_read(attr) == enabled) 124 - return count; 125 - 126 - bat_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, 127 - atomic_read(attr) == 1 ? "enabled" : "disabled", 128 - enabled == 1 ? "enabled" : "disabled"); 129 - 130 - atomic_set(attr, (unsigned)enabled); 131 - return count; 132 - } 133 - 134 - static inline ssize_t __store_bool_attr(char *buff, size_t count, 135 - void (*post_func)(struct net_device *), 136 - struct attribute *attr, 137 - atomic_t *attr_store, struct net_device *net_dev) 138 - { 139 - int ret; 140 - 141 - ret = store_bool_attr(buff, count, net_dev, (char *)attr->name, 142 - attr_store); 143 - if (post_func && ret) 144 - post_func(net_dev); 145 - 146 - return ret; 147 - } 148 - 149 - static int store_uint_attr(char *buff, size_t count, 150 - struct net_device *net_dev, char *attr_name, 151 - unsigned int min, unsigned int max, atomic_t *attr) 152 - { 153 - unsigned long uint_val; 154 - int ret; 155 - 156 - ret = strict_strtoul(buff, 10, &uint_val); 157 - if (ret) { 158 - bat_info(net_dev, 159 - "%s: Invalid parameter received: %s\n", 160 - attr_name, buff); 161 - return -EINVAL; 162 - } 163 - 164 - if (uint_val < min) { 165 - bat_info(net_dev, "%s: Value is too small: %lu min: %u\n", 166 - attr_name, uint_val, min); 167 - return -EINVAL; 168 - } 169 - 170 - if (uint_val > max) { 171 - bat_info(net_dev, "%s: Value is too big: %lu max: %u\n", 172 - attr_name, uint_val, max); 173 - return -EINVAL; 174 - } 175 - 176 - if (atomic_read(attr) == uint_val) 177 - return count; 178 - 179 - bat_info(net_dev, "%s: Changing from: %i to: %lu\n", 180 - attr_name, atomic_read(attr), uint_val); 181 - 182 - atomic_set(attr, uint_val); 183 - return count; 184 - } 185 - 186 - static inline ssize_t __store_uint_attr(char *buff, size_t count, 187 - int min, int max, 188 - void (*post_func)(struct net_device *), 189 - struct attribute *attr, 190 - atomic_t *attr_store, struct net_device *net_dev) 191 - { 192 - int ret; 193 - 194 - ret = store_uint_attr(buff, count, net_dev, (char *)attr->name, 195 - min, max, attr_store); 196 - if (post_func && ret) 197 - post_func(net_dev); 198 - 199 - return ret; 200 - } 201 - 202 - static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, 203 - char *buff) 204 - { 205 - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); 206 - int vis_mode = atomic_read(&bat_priv->vis_mode); 207 - 208 - return sprintf(buff, "%s\n", 209 - vis_mode == VIS_TYPE_CLIENT_UPDATE ? 210 - "client" : "server"); 211 - } 212 - 213 - static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, 214 - char *buff, size_t count) 215 - { 216 - struct net_device *net_dev = kobj_to_netdev(kobj); 217 - struct bat_priv *bat_priv = netdev_priv(net_dev); 218 - unsigned long val; 219 - int ret, vis_mode_tmp = -1; 220 - 221 - ret = strict_strtoul(buff, 10, &val); 222 - 223 - if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) || 224 - (strncmp(buff, "client", 6) == 0) || 225 - (strncmp(buff, "off", 3) == 0)) 226 - vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE; 227 - 228 - if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) || 229 - (strncmp(buff, "server", 6) == 0)) 230 - vis_mode_tmp = VIS_TYPE_SERVER_SYNC; 231 - 232 - if (vis_mode_tmp < 0) { 233 - if (buff[count - 1] == '\n') 234 - buff[count - 1] = '\0'; 235 - 236 - bat_info(net_dev, 237 - "Invalid parameter for 'vis mode' setting received: " 238 - "%s\n", buff); 239 - return -EINVAL; 240 - } 241 - 242 - if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp) 243 - return count; 244 - 245 - bat_info(net_dev, "Changing vis mode from: %s to: %s\n", 246 - atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ? 247 - "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ? 248 - "client" : "server"); 249 - 250 - atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp); 251 - return count; 252 - } 253 - 254 - static void post_gw_deselect(struct net_device *net_dev) 255 - { 256 - struct bat_priv *bat_priv = netdev_priv(net_dev); 257 - gw_deselect(bat_priv); 258 - } 259 - 260 - static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, 261 - char *buff) 262 - { 263 - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); 264 - int bytes_written; 265 - 266 - switch (atomic_read(&bat_priv->gw_mode)) { 267 - case GW_MODE_CLIENT: 268 - bytes_written = sprintf(buff, "%s\n", GW_MODE_CLIENT_NAME); 269 - break; 270 - case GW_MODE_SERVER: 271 - bytes_written = sprintf(buff, "%s\n", GW_MODE_SERVER_NAME); 272 - break; 273 - default: 274 - bytes_written = sprintf(buff, "%s\n", GW_MODE_OFF_NAME); 275 - break; 276 - } 277 - 278 - return bytes_written; 279 - } 280 - 281 - static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr, 282 - char *buff, size_t count) 283 - { 284 - struct net_device *net_dev = kobj_to_netdev(kobj); 285 - struct bat_priv *bat_priv = netdev_priv(net_dev); 286 - char *curr_gw_mode_str; 287 - int gw_mode_tmp = -1; 288 - 289 - if (buff[count - 1] == '\n') 290 - buff[count - 1] = '\0'; 291 - 292 - if (strncmp(buff, GW_MODE_OFF_NAME, strlen(GW_MODE_OFF_NAME)) == 0) 293 - gw_mode_tmp = GW_MODE_OFF; 294 - 295 - if (strncmp(buff, GW_MODE_CLIENT_NAME, 296 - strlen(GW_MODE_CLIENT_NAME)) == 0) 297 - gw_mode_tmp = GW_MODE_CLIENT; 298 - 299 - if (strncmp(buff, GW_MODE_SERVER_NAME, 300 - strlen(GW_MODE_SERVER_NAME)) == 0) 301 - gw_mode_tmp = GW_MODE_SERVER; 302 - 303 - if (gw_mode_tmp < 0) { 304 - bat_info(net_dev, 305 - "Invalid parameter for 'gw mode' setting received: " 306 - "%s\n", buff); 307 - return -EINVAL; 308 - } 309 - 310 - if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp) 311 - return count; 312 - 313 - switch (atomic_read(&bat_priv->gw_mode)) { 314 - case GW_MODE_CLIENT: 315 - curr_gw_mode_str = GW_MODE_CLIENT_NAME; 316 - break; 317 - case GW_MODE_SERVER: 318 - curr_gw_mode_str = GW_MODE_SERVER_NAME; 319 - break; 320 - default: 321 - curr_gw_mode_str = GW_MODE_OFF_NAME; 322 - break; 323 - } 324 - 325 - bat_info(net_dev, "Changing gw mode from: %s to: %s\n", 326 - curr_gw_mode_str, buff); 327 - 328 - gw_deselect(bat_priv); 329 - atomic_set(&bat_priv->gw_mode, (unsigned)gw_mode_tmp); 330 - return count; 331 - } 332 - 333 - static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr, 334 - char *buff) 335 - { 336 - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); 337 - int down, up; 338 - int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); 339 - 340 - gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); 341 - return sprintf(buff, "%i%s/%i%s\n", 342 - (down > 2048 ? down / 1024 : down), 343 - (down > 2048 ? "MBit" : "KBit"), 344 - (up > 2048 ? up / 1024 : up), 345 - (up > 2048 ? "MBit" : "KBit")); 346 - } 347 - 348 - static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, 349 - char *buff, size_t count) 350 - { 351 - struct net_device *net_dev = kobj_to_netdev(kobj); 352 - 353 - if (buff[count - 1] == '\n') 354 - buff[count - 1] = '\0'; 355 - 356 - return gw_bandwidth_set(net_dev, buff, count); 357 - } 358 - 359 - BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); 360 - BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); 361 - BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); 362 - static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); 363 - static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); 364 - BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); 365 - BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); 366 - BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, 367 - post_gw_deselect); 368 - static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, 369 - store_gw_bwidth); 370 - #ifdef CONFIG_BATMAN_ADV_DEBUG 371 - BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); 372 - #endif 373 - 374 - static struct bat_attribute *mesh_attrs[] = { 375 - &bat_attr_aggregated_ogms, 376 - &bat_attr_bonding, 377 - &bat_attr_fragmentation, 378 - &bat_attr_vis_mode, 379 - &bat_attr_gw_mode, 380 - &bat_attr_orig_interval, 381 - &bat_attr_hop_penalty, 382 - &bat_attr_gw_sel_class, 383 - &bat_attr_gw_bandwidth, 384 - #ifdef CONFIG_BATMAN_ADV_DEBUG 385 - &bat_attr_log_level, 386 - #endif 387 - NULL, 388 - }; 389 - 390 - int sysfs_add_meshif(struct net_device *dev) 391 - { 392 - struct kobject *batif_kobject = &dev->dev.kobj; 393 - struct bat_priv *bat_priv = netdev_priv(dev); 394 - struct bat_attribute **bat_attr; 395 - int err; 396 - 397 - bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, 398 - batif_kobject); 399 - if (!bat_priv->mesh_obj) { 400 - bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, 401 - SYSFS_IF_MESH_SUBDIR); 402 - goto out; 403 - } 404 - 405 - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) { 406 - err = sysfs_create_file(bat_priv->mesh_obj, 407 - &((*bat_attr)->attr)); 408 - if (err) { 409 - bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", 410 - dev->name, SYSFS_IF_MESH_SUBDIR, 411 - ((*bat_attr)->attr).name); 412 - goto rem_attr; 413 - } 414 - } 415 - 416 - return 0; 417 - 418 - rem_attr: 419 - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) 420 - sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); 421 - 422 - kobject_put(bat_priv->mesh_obj); 423 - bat_priv->mesh_obj = NULL; 424 - out: 425 - return -ENOMEM; 426 - } 427 - 428 - void sysfs_del_meshif(struct net_device *dev) 429 - { 430 - struct bat_priv *bat_priv = netdev_priv(dev); 431 - struct bat_attribute **bat_attr; 432 - 433 - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) 434 - sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); 435 - 436 - kobject_put(bat_priv->mesh_obj); 437 - bat_priv->mesh_obj = NULL; 438 - } 439 - 440 - static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, 441 - char *buff) 442 - { 443 - struct net_device *net_dev = kobj_to_netdev(kobj); 444 - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); 445 - ssize_t length; 446 - 447 - if (!batman_if) 448 - return 0; 449 - 450 - length = sprintf(buff, "%s\n", batman_if->if_status == IF_NOT_IN_USE ? 451 - "none" : batman_if->soft_iface->name); 452 - 453 - kref_put(&batman_if->refcount, hardif_free_ref); 454 - 455 - return length; 456 - } 457 - 458 - static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, 459 - char *buff, size_t count) 460 - { 461 - struct net_device *net_dev = kobj_to_netdev(kobj); 462 - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); 463 - int status_tmp = -1; 464 - int ret; 465 - 466 - if (!batman_if) 467 - return count; 468 - 469 - if (buff[count - 1] == '\n') 470 - buff[count - 1] = '\0'; 471 - 472 - if (strlen(buff) >= IFNAMSIZ) { 473 - pr_err("Invalid parameter for 'mesh_iface' setting received: " 474 - "interface name too long '%s'\n", buff); 475 - kref_put(&batman_if->refcount, hardif_free_ref); 476 - return -EINVAL; 477 - } 478 - 479 - if (strncmp(buff, "none", 4) == 0) 480 - status_tmp = IF_NOT_IN_USE; 481 - else 482 - status_tmp = IF_I_WANT_YOU; 483 - 484 - if ((batman_if->if_status == status_tmp) || ((batman_if->soft_iface) && 485 - (strncmp(batman_if->soft_iface->name, buff, IFNAMSIZ) == 0))) { 486 - kref_put(&batman_if->refcount, hardif_free_ref); 487 - return count; 488 - } 489 - 490 - if (status_tmp == IF_NOT_IN_USE) { 491 - rtnl_lock(); 492 - hardif_disable_interface(batman_if); 493 - rtnl_unlock(); 494 - kref_put(&batman_if->refcount, hardif_free_ref); 495 - return count; 496 - } 497 - 498 - /* if the interface already is in use */ 499 - if (batman_if->if_status != IF_NOT_IN_USE) { 500 - rtnl_lock(); 501 - hardif_disable_interface(batman_if); 502 - rtnl_unlock(); 503 - } 504 - 505 - ret = hardif_enable_interface(batman_if, buff); 506 - kref_put(&batman_if->refcount, hardif_free_ref); 507 - 508 - return ret; 509 - } 510 - 511 - static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, 512 - char *buff) 513 - { 514 - struct net_device *net_dev = kobj_to_netdev(kobj); 515 - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); 516 - ssize_t length; 517 - 518 - if (!batman_if) 519 - return 0; 520 - 521 - switch (batman_if->if_status) { 522 - case IF_TO_BE_REMOVED: 523 - length = sprintf(buff, "disabling\n"); 524 - break; 525 - case IF_INACTIVE: 526 - length = sprintf(buff, "inactive\n"); 527 - break; 528 - case IF_ACTIVE: 529 - length = sprintf(buff, "active\n"); 530 - break; 531 - case IF_TO_BE_ACTIVATED: 532 - length = sprintf(buff, "enabling\n"); 533 - break; 534 - case IF_NOT_IN_USE: 535 - default: 536 - length = sprintf(buff, "not in use\n"); 537 - break; 538 - } 539 - 540 - kref_put(&batman_if->refcount, hardif_free_ref); 541 - 542 - return length; 543 - } 544 - 545 - static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR, 546 - show_mesh_iface, store_mesh_iface); 547 - static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL); 548 - 549 - static struct bat_attribute *batman_attrs[] = { 550 - &bat_attr_mesh_iface, 551 - &bat_attr_iface_status, 552 - NULL, 553 - }; 554 - 555 - int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) 556 - { 557 - struct kobject *hardif_kobject = &dev->dev.kobj; 558 - struct bat_attribute **bat_attr; 559 - int err; 560 - 561 - *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR, 562 - hardif_kobject); 563 - 564 - if (!*hardif_obj) { 565 - bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, 566 - SYSFS_IF_BAT_SUBDIR); 567 - goto out; 568 - } 569 - 570 - for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) { 571 - err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); 572 - if (err) { 573 - bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", 574 - dev->name, SYSFS_IF_BAT_SUBDIR, 575 - ((*bat_attr)->attr).name); 576 - goto rem_attr; 577 - } 578 - } 579 - 580 - return 0; 581 - 582 - rem_attr: 583 - for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) 584 - sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr)); 585 - out: 586 - return -ENOMEM; 587 - } 588 - 589 - void sysfs_del_hardif(struct kobject **hardif_obj) 590 - { 591 - kobject_put(*hardif_obj); 592 - *hardif_obj = NULL; 593 - }
-42
drivers/staging/batman-adv/bat_sysfs.h
··· 1 - /* 2 - * Copyright (C) 2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - 23 - #ifndef _NET_BATMAN_ADV_SYSFS_H_ 24 - #define _NET_BATMAN_ADV_SYSFS_H_ 25 - 26 - #define SYSFS_IF_MESH_SUBDIR "mesh" 27 - #define SYSFS_IF_BAT_SUBDIR "batman_adv" 28 - 29 - struct bat_attribute { 30 - struct attribute attr; 31 - ssize_t (*show)(struct kobject *kobj, struct attribute *attr, 32 - char *buf); 33 - ssize_t (*store)(struct kobject *kobj, struct attribute *attr, 34 - char *buf, size_t count); 35 - }; 36 - 37 - int sysfs_add_meshif(struct net_device *dev); 38 - void sysfs_del_meshif(struct net_device *dev); 39 - int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev); 40 - void sysfs_del_hardif(struct kobject **hardif_obj); 41 - 42 - #endif /* _NET_BATMAN_ADV_SYSFS_H_ */
-201
drivers/staging/batman-adv/bitarray.c
··· 1 - /* 2 - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Simon Wunderlich, Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "bitarray.h" 24 - 25 - #include <linux/bitops.h> 26 - 27 - /* returns true if the corresponding bit in the given seq_bits indicates true 28 - * and curr_seqno is within range of last_seqno */ 29 - uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno, 30 - uint32_t curr_seqno) 31 - { 32 - int32_t diff, word_offset, word_num; 33 - 34 - diff = last_seqno - curr_seqno; 35 - if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) { 36 - return 0; 37 - } else { 38 - /* which word */ 39 - word_num = (last_seqno - curr_seqno) / WORD_BIT_SIZE; 40 - /* which position in the selected word */ 41 - word_offset = (last_seqno - curr_seqno) % WORD_BIT_SIZE; 42 - 43 - if (seq_bits[word_num] & 1 << word_offset) 44 - return 1; 45 - else 46 - return 0; 47 - } 48 - } 49 - 50 - /* turn corresponding bit on, so we can remember that we got the packet */ 51 - void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n) 52 - { 53 - int32_t word_offset, word_num; 54 - 55 - /* if too old, just drop it */ 56 - if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE) 57 - return; 58 - 59 - /* which word */ 60 - word_num = n / WORD_BIT_SIZE; 61 - /* which position in the selected word */ 62 - word_offset = n % WORD_BIT_SIZE; 63 - 64 - seq_bits[word_num] |= 1 << word_offset; /* turn the position on */ 65 - } 66 - 67 - /* shift the packet array by n places. */ 68 - static void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n) 69 - { 70 - int32_t word_offset, word_num; 71 - int32_t i; 72 - 73 - if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE) 74 - return; 75 - 76 - word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */ 77 - word_num = n / WORD_BIT_SIZE; /* shift over how much (full) words */ 78 - 79 - for (i = NUM_WORDS - 1; i > word_num; i--) { 80 - /* going from old to new, so we don't overwrite the data we copy 81 - * from. 82 - * 83 - * left is high, right is low: FEDC BA98 7654 3210 84 - * ^^ ^^ 85 - * vvvv 86 - * ^^^^ = from, vvvvv =to, we'd have word_num==1 and 87 - * word_offset==WORD_BIT_SIZE/2 ????? in this example. 88 - * (=24 bits) 89 - * 90 - * our desired output would be: 9876 5432 1000 0000 91 - * */ 92 - 93 - seq_bits[i] = 94 - (seq_bits[i - word_num] << word_offset) + 95 - /* take the lower port from the left half, shift it left 96 - * to its final position */ 97 - (seq_bits[i - word_num - 1] >> 98 - (WORD_BIT_SIZE-word_offset)); 99 - /* and the upper part of the right half and shift it left to 100 - * it's position */ 101 - /* for our example that would be: word[0] = 9800 + 0076 = 102 - * 9876 */ 103 - } 104 - /* now for our last word, i==word_num, we only have the it's "left" 105 - * half. that's the 1000 word in our example.*/ 106 - 107 - seq_bits[i] = (seq_bits[i - word_num] << word_offset); 108 - 109 - /* pad the rest with 0, if there is anything */ 110 - i--; 111 - 112 - for (; i >= 0; i--) 113 - seq_bits[i] = 0; 114 - } 115 - 116 - static void bit_reset_window(TYPE_OF_WORD *seq_bits) 117 - { 118 - int i; 119 - for (i = 0; i < NUM_WORDS; i++) 120 - seq_bits[i] = 0; 121 - } 122 - 123 - 124 - /* receive and process one packet within the sequence number window. 125 - * 126 - * returns: 127 - * 1 if the window was moved (either new or very old) 128 - * 0 if the window was not moved/shifted. 129 - */ 130 - char bit_get_packet(void *priv, TYPE_OF_WORD *seq_bits, 131 - int32_t seq_num_diff, int8_t set_mark) 132 - { 133 - struct bat_priv *bat_priv = (struct bat_priv *)priv; 134 - 135 - /* sequence number is slightly older. We already got a sequence number 136 - * higher than this one, so we just mark it. */ 137 - 138 - if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { 139 - if (set_mark) 140 - bit_mark(seq_bits, -seq_num_diff); 141 - return 0; 142 - } 143 - 144 - /* sequence number is slightly newer, so we shift the window and 145 - * set the mark if required */ 146 - 147 - if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { 148 - bit_shift(seq_bits, seq_num_diff); 149 - 150 - if (set_mark) 151 - bit_mark(seq_bits, 0); 152 - return 1; 153 - } 154 - 155 - /* sequence number is much newer, probably missed a lot of packets */ 156 - 157 - if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) 158 - || (seq_num_diff < EXPECTED_SEQNO_RANGE)) { 159 - bat_dbg(DBG_BATMAN, bat_priv, 160 - "We missed a lot of packets (%i) !\n", 161 - seq_num_diff - 1); 162 - bit_reset_window(seq_bits); 163 - if (set_mark) 164 - bit_mark(seq_bits, 0); 165 - return 1; 166 - } 167 - 168 - /* received a much older packet. The other host either restarted 169 - * or the old packet got delayed somewhere in the network. The 170 - * packet should be dropped without calling this function if the 171 - * seqno window is protected. */ 172 - 173 - if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) 174 - || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { 175 - 176 - bat_dbg(DBG_BATMAN, bat_priv, 177 - "Other host probably restarted!\n"); 178 - 179 - bit_reset_window(seq_bits); 180 - if (set_mark) 181 - bit_mark(seq_bits, 0); 182 - 183 - return 1; 184 - } 185 - 186 - /* never reached */ 187 - return 0; 188 - } 189 - 190 - /* count the hamming weight, how many good packets did we receive? just count 191 - * the 1's. 192 - */ 193 - int bit_packet_count(TYPE_OF_WORD *seq_bits) 194 - { 195 - int i, hamming = 0; 196 - 197 - for (i = 0; i < NUM_WORDS; i++) 198 - hamming += hweight_long(seq_bits[i]); 199 - 200 - return hamming; 201 - }
-47
drivers/staging/batman-adv/bitarray.h
··· 1 - /* 2 - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Simon Wunderlich, Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_BITARRAY_H_ 23 - #define _NET_BATMAN_ADV_BITARRAY_H_ 24 - 25 - /* you should choose something big, if you don't want to waste cpu 26 - * and keep the type in sync with bit_packet_count */ 27 - #define TYPE_OF_WORD unsigned long 28 - #define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8) 29 - 30 - /* returns true if the corresponding bit in the given seq_bits indicates true 31 - * and curr_seqno is within range of last_seqno */ 32 - uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno, 33 - uint32_t curr_seqno); 34 - 35 - /* turn corresponding bit on, so we can remember that we got the packet */ 36 - void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n); 37 - 38 - 39 - /* receive and process one packet, returns 1 if received seq_num is considered 40 - * new, 0 if old */ 41 - char bit_get_packet(void *priv, TYPE_OF_WORD *seq_bits, 42 - int32_t seq_num_diff, int8_t set_mark); 43 - 44 - /* count the hamming weight, how many good packets did we receive? */ 45 - int bit_packet_count(TYPE_OF_WORD *seq_bits); 46 - 47 - #endif /* _NET_BATMAN_ADV_BITARRAY_H_ */
-477
drivers/staging/batman-adv/gateway_client.c
··· 1 - /* 2 - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "gateway_client.h" 24 - #include "gateway_common.h" 25 - #include "hard-interface.h" 26 - #include <linux/ip.h> 27 - #include <linux/ipv6.h> 28 - #include <linux/udp.h> 29 - #include <linux/if_vlan.h> 30 - 31 - static void gw_node_free_ref(struct kref *refcount) 32 - { 33 - struct gw_node *gw_node; 34 - 35 - gw_node = container_of(refcount, struct gw_node, refcount); 36 - kfree(gw_node); 37 - } 38 - 39 - static void gw_node_free_rcu(struct rcu_head *rcu) 40 - { 41 - struct gw_node *gw_node; 42 - 43 - gw_node = container_of(rcu, struct gw_node, rcu); 44 - kref_put(&gw_node->refcount, gw_node_free_ref); 45 - } 46 - 47 - void *gw_get_selected(struct bat_priv *bat_priv) 48 - { 49 - struct gw_node *curr_gateway_tmp = bat_priv->curr_gw; 50 - 51 - if (!curr_gateway_tmp) 52 - return NULL; 53 - 54 - return curr_gateway_tmp->orig_node; 55 - } 56 - 57 - void gw_deselect(struct bat_priv *bat_priv) 58 - { 59 - struct gw_node *gw_node = bat_priv->curr_gw; 60 - 61 - bat_priv->curr_gw = NULL; 62 - 63 - if (gw_node) 64 - kref_put(&gw_node->refcount, gw_node_free_ref); 65 - } 66 - 67 - static struct gw_node *gw_select(struct bat_priv *bat_priv, 68 - struct gw_node *new_gw_node) 69 - { 70 - struct gw_node *curr_gw_node = bat_priv->curr_gw; 71 - 72 - if (new_gw_node) 73 - kref_get(&new_gw_node->refcount); 74 - 75 - bat_priv->curr_gw = new_gw_node; 76 - return curr_gw_node; 77 - } 78 - 79 - void gw_election(struct bat_priv *bat_priv) 80 - { 81 - struct hlist_node *node; 82 - struct gw_node *gw_node, *curr_gw_tmp = NULL, *old_gw_node = NULL; 83 - uint8_t max_tq = 0; 84 - uint32_t max_gw_factor = 0, tmp_gw_factor = 0; 85 - int down, up; 86 - 87 - /** 88 - * The batman daemon checks here if we already passed a full originator 89 - * cycle in order to make sure we don't choose the first gateway we 90 - * hear about. This check is based on the daemon's uptime which we 91 - * don't have. 92 - **/ 93 - if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT) 94 - return; 95 - 96 - if (bat_priv->curr_gw) 97 - return; 98 - 99 - rcu_read_lock(); 100 - if (hlist_empty(&bat_priv->gw_list)) { 101 - rcu_read_unlock(); 102 - 103 - if (bat_priv->curr_gw) { 104 - bat_dbg(DBG_BATMAN, bat_priv, 105 - "Removing selected gateway - " 106 - "no gateway in range\n"); 107 - gw_deselect(bat_priv); 108 - } 109 - 110 - return; 111 - } 112 - 113 - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 114 - if (!gw_node->orig_node->router) 115 - continue; 116 - 117 - if (gw_node->deleted) 118 - continue; 119 - 120 - switch (atomic_read(&bat_priv->gw_sel_class)) { 121 - case 1: /* fast connection */ 122 - gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, 123 - &down, &up); 124 - 125 - tmp_gw_factor = (gw_node->orig_node->router->tq_avg * 126 - gw_node->orig_node->router->tq_avg * 127 - down * 100 * 100) / 128 - (TQ_LOCAL_WINDOW_SIZE * 129 - TQ_LOCAL_WINDOW_SIZE * 64); 130 - 131 - if ((tmp_gw_factor > max_gw_factor) || 132 - ((tmp_gw_factor == max_gw_factor) && 133 - (gw_node->orig_node->router->tq_avg > max_tq))) 134 - curr_gw_tmp = gw_node; 135 - break; 136 - 137 - default: /** 138 - * 2: stable connection (use best statistic) 139 - * 3: fast-switch (use best statistic but change as 140 - * soon as a better gateway appears) 141 - * XX: late-switch (use best statistic but change as 142 - * soon as a better gateway appears which has 143 - * $routing_class more tq points) 144 - **/ 145 - if (gw_node->orig_node->router->tq_avg > max_tq) 146 - curr_gw_tmp = gw_node; 147 - break; 148 - } 149 - 150 - if (gw_node->orig_node->router->tq_avg > max_tq) 151 - max_tq = gw_node->orig_node->router->tq_avg; 152 - 153 - if (tmp_gw_factor > max_gw_factor) 154 - max_gw_factor = tmp_gw_factor; 155 - } 156 - 157 - if (bat_priv->curr_gw != curr_gw_tmp) { 158 - if ((bat_priv->curr_gw) && (!curr_gw_tmp)) 159 - bat_dbg(DBG_BATMAN, bat_priv, 160 - "Removing selected gateway - " 161 - "no gateway in range\n"); 162 - else if ((!bat_priv->curr_gw) && (curr_gw_tmp)) 163 - bat_dbg(DBG_BATMAN, bat_priv, 164 - "Adding route to gateway %pM " 165 - "(gw_flags: %i, tq: %i)\n", 166 - curr_gw_tmp->orig_node->orig, 167 - curr_gw_tmp->orig_node->gw_flags, 168 - curr_gw_tmp->orig_node->router->tq_avg); 169 - else 170 - bat_dbg(DBG_BATMAN, bat_priv, 171 - "Changing route to gateway %pM " 172 - "(gw_flags: %i, tq: %i)\n", 173 - curr_gw_tmp->orig_node->orig, 174 - curr_gw_tmp->orig_node->gw_flags, 175 - curr_gw_tmp->orig_node->router->tq_avg); 176 - 177 - old_gw_node = gw_select(bat_priv, curr_gw_tmp); 178 - } 179 - 180 - rcu_read_unlock(); 181 - 182 - /* the kfree() has to be outside of the rcu lock */ 183 - if (old_gw_node) 184 - kref_put(&old_gw_node->refcount, gw_node_free_ref); 185 - } 186 - 187 - void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) 188 - { 189 - struct gw_node *curr_gateway_tmp = bat_priv->curr_gw; 190 - uint8_t gw_tq_avg, orig_tq_avg; 191 - 192 - if (!curr_gateway_tmp) 193 - return; 194 - 195 - if (!curr_gateway_tmp->orig_node) 196 - goto deselect; 197 - 198 - if (!curr_gateway_tmp->orig_node->router) 199 - goto deselect; 200 - 201 - /* this node already is the gateway */ 202 - if (curr_gateway_tmp->orig_node == orig_node) 203 - return; 204 - 205 - if (!orig_node->router) 206 - return; 207 - 208 - gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg; 209 - orig_tq_avg = orig_node->router->tq_avg; 210 - 211 - /* the TQ value has to be better */ 212 - if (orig_tq_avg < gw_tq_avg) 213 - return; 214 - 215 - /** 216 - * if the routing class is greater than 3 the value tells us how much 217 - * greater the TQ value of the new gateway must be 218 - **/ 219 - if ((atomic_read(&bat_priv->gw_sel_class) > 3) && 220 - (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class))) 221 - return; 222 - 223 - bat_dbg(DBG_BATMAN, bat_priv, 224 - "Restarting gateway selection: better gateway found (tq curr: " 225 - "%i, tq new: %i)\n", 226 - gw_tq_avg, orig_tq_avg); 227 - 228 - deselect: 229 - gw_deselect(bat_priv); 230 - } 231 - 232 - static void gw_node_add(struct bat_priv *bat_priv, 233 - struct orig_node *orig_node, uint8_t new_gwflags) 234 - { 235 - struct gw_node *gw_node; 236 - int down, up; 237 - 238 - gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC); 239 - if (!gw_node) 240 - return; 241 - 242 - memset(gw_node, 0, sizeof(struct gw_node)); 243 - INIT_HLIST_NODE(&gw_node->list); 244 - gw_node->orig_node = orig_node; 245 - kref_init(&gw_node->refcount); 246 - 247 - spin_lock_bh(&bat_priv->gw_list_lock); 248 - hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); 249 - spin_unlock_bh(&bat_priv->gw_list_lock); 250 - 251 - gw_bandwidth_to_kbit(new_gwflags, &down, &up); 252 - bat_dbg(DBG_BATMAN, bat_priv, 253 - "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", 254 - orig_node->orig, new_gwflags, 255 - (down > 2048 ? down / 1024 : down), 256 - (down > 2048 ? "MBit" : "KBit"), 257 - (up > 2048 ? up / 1024 : up), 258 - (up > 2048 ? "MBit" : "KBit")); 259 - } 260 - 261 - void gw_node_update(struct bat_priv *bat_priv, 262 - struct orig_node *orig_node, uint8_t new_gwflags) 263 - { 264 - struct hlist_node *node; 265 - struct gw_node *gw_node; 266 - 267 - rcu_read_lock(); 268 - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 269 - if (gw_node->orig_node != orig_node) 270 - continue; 271 - 272 - bat_dbg(DBG_BATMAN, bat_priv, 273 - "Gateway class of originator %pM changed from " 274 - "%i to %i\n", 275 - orig_node->orig, gw_node->orig_node->gw_flags, 276 - new_gwflags); 277 - 278 - gw_node->deleted = 0; 279 - 280 - if (new_gwflags == 0) { 281 - gw_node->deleted = jiffies; 282 - bat_dbg(DBG_BATMAN, bat_priv, 283 - "Gateway %pM removed from gateway list\n", 284 - orig_node->orig); 285 - 286 - if (gw_node == bat_priv->curr_gw) { 287 - rcu_read_unlock(); 288 - gw_deselect(bat_priv); 289 - return; 290 - } 291 - } 292 - 293 - rcu_read_unlock(); 294 - return; 295 - } 296 - rcu_read_unlock(); 297 - 298 - if (new_gwflags == 0) 299 - return; 300 - 301 - gw_node_add(bat_priv, orig_node, new_gwflags); 302 - } 303 - 304 - void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node) 305 - { 306 - return gw_node_update(bat_priv, orig_node, 0); 307 - } 308 - 309 - void gw_node_purge(struct bat_priv *bat_priv) 310 - { 311 - struct gw_node *gw_node; 312 - struct hlist_node *node, *node_tmp; 313 - unsigned long timeout = 2 * PURGE_TIMEOUT * HZ; 314 - 315 - spin_lock_bh(&bat_priv->gw_list_lock); 316 - 317 - hlist_for_each_entry_safe(gw_node, node, node_tmp, 318 - &bat_priv->gw_list, list) { 319 - if (((!gw_node->deleted) || 320 - (time_before(jiffies, gw_node->deleted + timeout))) && 321 - atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) 322 - continue; 323 - 324 - if (bat_priv->curr_gw == gw_node) 325 - gw_deselect(bat_priv); 326 - 327 - hlist_del_rcu(&gw_node->list); 328 - call_rcu(&gw_node->rcu, gw_node_free_rcu); 329 - } 330 - 331 - 332 - spin_unlock_bh(&bat_priv->gw_list_lock); 333 - } 334 - 335 - static int _write_buffer_text(struct bat_priv *bat_priv, 336 - struct seq_file *seq, struct gw_node *gw_node) 337 - { 338 - int down, up; 339 - 340 - gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); 341 - 342 - return seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", 343 - (bat_priv->curr_gw == gw_node ? "=>" : " "), 344 - gw_node->orig_node->orig, 345 - gw_node->orig_node->router->tq_avg, 346 - gw_node->orig_node->router->addr, 347 - gw_node->orig_node->router->if_incoming->net_dev->name, 348 - gw_node->orig_node->gw_flags, 349 - (down > 2048 ? down / 1024 : down), 350 - (down > 2048 ? "MBit" : "KBit"), 351 - (up > 2048 ? up / 1024 : up), 352 - (up > 2048 ? "MBit" : "KBit")); 353 - } 354 - 355 - int gw_client_seq_print_text(struct seq_file *seq, void *offset) 356 - { 357 - struct net_device *net_dev = (struct net_device *)seq->private; 358 - struct bat_priv *bat_priv = netdev_priv(net_dev); 359 - struct gw_node *gw_node; 360 - struct hlist_node *node; 361 - int gw_count = 0; 362 - 363 - if (!bat_priv->primary_if) { 364 - 365 - return seq_printf(seq, "BATMAN mesh %s disabled - please " 366 - "specify interfaces to enable it\n", 367 - net_dev->name); 368 - } 369 - 370 - if (bat_priv->primary_if->if_status != IF_ACTIVE) { 371 - 372 - return seq_printf(seq, "BATMAN mesh %s disabled - " 373 - "primary interface not active\n", 374 - net_dev->name); 375 - } 376 - 377 - seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... " 378 - "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", 379 - "Gateway", "#", TQ_MAX_VALUE, "Nexthop", 380 - "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR, 381 - bat_priv->primary_if->net_dev->name, 382 - bat_priv->primary_if->net_dev->dev_addr, net_dev->name); 383 - 384 - rcu_read_lock(); 385 - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 386 - if (gw_node->deleted) 387 - continue; 388 - 389 - if (!gw_node->orig_node->router) 390 - continue; 391 - 392 - _write_buffer_text(bat_priv, seq, gw_node); 393 - gw_count++; 394 - } 395 - rcu_read_unlock(); 396 - 397 - if (gw_count == 0) 398 - seq_printf(seq, "No gateways in range ...\n"); 399 - 400 - return 0; 401 - } 402 - 403 - int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) 404 - { 405 - struct ethhdr *ethhdr; 406 - struct iphdr *iphdr; 407 - struct ipv6hdr *ipv6hdr; 408 - struct udphdr *udphdr; 409 - unsigned int header_len = 0; 410 - 411 - if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF) 412 - return 0; 413 - 414 - /* check for ethernet header */ 415 - if (!pskb_may_pull(skb, header_len + ETH_HLEN)) 416 - return 0; 417 - ethhdr = (struct ethhdr *)skb->data; 418 - header_len += ETH_HLEN; 419 - 420 - /* check for initial vlan header */ 421 - if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { 422 - if (!pskb_may_pull(skb, header_len + VLAN_HLEN)) 423 - return 0; 424 - ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); 425 - header_len += VLAN_HLEN; 426 - } 427 - 428 - /* check for ip header */ 429 - switch (ntohs(ethhdr->h_proto)) { 430 - case ETH_P_IP: 431 - if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr))) 432 - return 0; 433 - iphdr = (struct iphdr *)(skb->data + header_len); 434 - header_len += iphdr->ihl * 4; 435 - 436 - /* check for udp header */ 437 - if (iphdr->protocol != IPPROTO_UDP) 438 - return 0; 439 - 440 - break; 441 - case ETH_P_IPV6: 442 - if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr))) 443 - return 0; 444 - ipv6hdr = (struct ipv6hdr *)(skb->data + header_len); 445 - header_len += sizeof(struct ipv6hdr); 446 - 447 - /* check for udp header */ 448 - if (ipv6hdr->nexthdr != IPPROTO_UDP) 449 - return 0; 450 - 451 - break; 452 - default: 453 - return 0; 454 - } 455 - 456 - if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr))) 457 - return 0; 458 - udphdr = (struct udphdr *)(skb->data + header_len); 459 - header_len += sizeof(struct udphdr); 460 - 461 - /* check for bootp port */ 462 - if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && 463 - (ntohs(udphdr->dest) != 67)) 464 - return 0; 465 - 466 - if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && 467 - (ntohs(udphdr->dest) != 547)) 468 - return 0; 469 - 470 - if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER) 471 - return -1; 472 - 473 - if (!bat_priv->curr_gw) 474 - return 0; 475 - 476 - return 1; 477 - }
-36
drivers/staging/batman-adv/gateway_client.h
··· 1 - /* 2 - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ 23 - #define _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ 24 - 25 - void gw_deselect(struct bat_priv *bat_priv); 26 - void gw_election(struct bat_priv *bat_priv); 27 - void *gw_get_selected(struct bat_priv *bat_priv); 28 - void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node); 29 - void gw_node_update(struct bat_priv *bat_priv, 30 - struct orig_node *orig_node, uint8_t new_gwflags); 31 - void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node); 32 - void gw_node_purge(struct bat_priv *bat_priv); 33 - int gw_client_seq_print_text(struct seq_file *seq, void *offset); 34 - int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb); 35 - 36 - #endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
-177
drivers/staging/batman-adv/gateway_common.c
··· 1 - /* 2 - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "gateway_common.h" 24 - #include "gateway_client.h" 25 - 26 - /* calculates the gateway class from kbit */ 27 - static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) 28 - { 29 - int mdown = 0, tdown, tup, difference; 30 - uint8_t sbit, part; 31 - 32 - *gw_srv_class = 0; 33 - difference = 0x0FFFFFFF; 34 - 35 - /* test all downspeeds */ 36 - for (sbit = 0; sbit < 2; sbit++) { 37 - for (part = 0; part < 16; part++) { 38 - tdown = 32 * (sbit + 2) * (1 << part); 39 - 40 - if (abs(tdown - down) < difference) { 41 - *gw_srv_class = (sbit << 7) + (part << 3); 42 - difference = abs(tdown - down); 43 - mdown = tdown; 44 - } 45 - } 46 - } 47 - 48 - /* test all upspeeds */ 49 - difference = 0x0FFFFFFF; 50 - 51 - for (part = 0; part < 8; part++) { 52 - tup = ((part + 1) * (mdown)) / 8; 53 - 54 - if (abs(tup - up) < difference) { 55 - *gw_srv_class = (*gw_srv_class & 0xF8) | part; 56 - difference = abs(tup - up); 57 - } 58 - } 59 - } 60 - 61 - /* returns the up and downspeeds in kbit, calculated from the class */ 62 - void gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up) 63 - { 64 - char sbit = (gw_srv_class & 0x80) >> 7; 65 - char dpart = (gw_srv_class & 0x78) >> 3; 66 - char upart = (gw_srv_class & 0x07); 67 - 68 - if (!gw_srv_class) { 69 - *down = 0; 70 - *up = 0; 71 - return; 72 - } 73 - 74 - *down = 32 * (sbit + 2) * (1 << dpart); 75 - *up = ((upart + 1) * (*down)) / 8; 76 - } 77 - 78 - static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, 79 - long *up, long *down) 80 - { 81 - int ret, multi = 1; 82 - char *slash_ptr, *tmp_ptr; 83 - 84 - slash_ptr = strchr(buff, '/'); 85 - if (slash_ptr) 86 - *slash_ptr = 0; 87 - 88 - if (strlen(buff) > 4) { 89 - tmp_ptr = buff + strlen(buff) - 4; 90 - 91 - if (strnicmp(tmp_ptr, "mbit", 4) == 0) 92 - multi = 1024; 93 - 94 - if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || 95 - (multi > 1)) 96 - *tmp_ptr = '\0'; 97 - } 98 - 99 - ret = strict_strtoul(buff, 10, down); 100 - if (ret) { 101 - bat_err(net_dev, 102 - "Download speed of gateway mode invalid: %s\n", 103 - buff); 104 - return false; 105 - } 106 - 107 - *down *= multi; 108 - 109 - /* we also got some upload info */ 110 - if (slash_ptr) { 111 - multi = 1; 112 - 113 - if (strlen(slash_ptr + 1) > 4) { 114 - tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); 115 - 116 - if (strnicmp(tmp_ptr, "mbit", 4) == 0) 117 - multi = 1024; 118 - 119 - if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || 120 - (multi > 1)) 121 - *tmp_ptr = '\0'; 122 - } 123 - 124 - ret = strict_strtoul(slash_ptr + 1, 10, up); 125 - if (ret) { 126 - bat_err(net_dev, 127 - "Upload speed of gateway mode invalid: " 128 - "%s\n", slash_ptr + 1); 129 - return false; 130 - } 131 - 132 - *up *= multi; 133 - } 134 - 135 - return true; 136 - } 137 - 138 - ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) 139 - { 140 - struct bat_priv *bat_priv = netdev_priv(net_dev); 141 - long gw_bandwidth_tmp = 0, up = 0, down = 0; 142 - bool ret; 143 - 144 - ret = parse_gw_bandwidth(net_dev, buff, &up, &down); 145 - if (!ret) 146 - goto end; 147 - 148 - if ((!down) || (down < 256)) 149 - down = 2000; 150 - 151 - if (!up) 152 - up = down / 5; 153 - 154 - kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); 155 - 156 - /** 157 - * the gw bandwidth we guessed above might not match the given 158 - * speeds, hence we need to calculate it back to show the number 159 - * that is going to be propagated 160 - **/ 161 - gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, 162 - (int *)&down, (int *)&up); 163 - 164 - gw_deselect(bat_priv); 165 - bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' " 166 - "(propagating: %ld%s/%ld%s)\n", 167 - atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, 168 - (down > 2048 ? down / 1024 : down), 169 - (down > 2048 ? "MBit" : "KBit"), 170 - (up > 2048 ? up / 1024 : up), 171 - (up > 2048 ? "MBit" : "KBit")); 172 - 173 - atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); 174 - 175 - end: 176 - return count; 177 - }
-38
drivers/staging/batman-adv/gateway_common.h
··· 1 - /* 2 - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_GATEWAY_COMMON_H_ 23 - #define _NET_BATMAN_ADV_GATEWAY_COMMON_H_ 24 - 25 - enum gw_modes { 26 - GW_MODE_OFF, 27 - GW_MODE_CLIENT, 28 - GW_MODE_SERVER, 29 - }; 30 - 31 - #define GW_MODE_OFF_NAME "off" 32 - #define GW_MODE_CLIENT_NAME "client" 33 - #define GW_MODE_SERVER_NAME "server" 34 - 35 - void gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up); 36 - ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count); 37 - 38 - #endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */
-652
drivers/staging/batman-adv/hard-interface.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "hard-interface.h" 24 - #include "soft-interface.h" 25 - #include "send.h" 26 - #include "translation-table.h" 27 - #include "routing.h" 28 - #include "bat_sysfs.h" 29 - #include "originator.h" 30 - #include "hash.h" 31 - 32 - #include <linux/if_arp.h> 33 - 34 - /* protect update critical side of if_list - but not the content */ 35 - static DEFINE_SPINLOCK(if_list_lock); 36 - 37 - static void hardif_free_rcu(struct rcu_head *rcu) 38 - { 39 - struct batman_if *batman_if; 40 - 41 - batman_if = container_of(rcu, struct batman_if, rcu); 42 - dev_put(batman_if->net_dev); 43 - kref_put(&batman_if->refcount, hardif_free_ref); 44 - } 45 - 46 - struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev) 47 - { 48 - struct batman_if *batman_if; 49 - 50 - rcu_read_lock(); 51 - list_for_each_entry_rcu(batman_if, &if_list, list) { 52 - if (batman_if->net_dev == net_dev) 53 - goto out; 54 - } 55 - 56 - batman_if = NULL; 57 - 58 - out: 59 - if (batman_if) 60 - kref_get(&batman_if->refcount); 61 - 62 - rcu_read_unlock(); 63 - return batman_if; 64 - } 65 - 66 - static int is_valid_iface(struct net_device *net_dev) 67 - { 68 - if (net_dev->flags & IFF_LOOPBACK) 69 - return 0; 70 - 71 - if (net_dev->type != ARPHRD_ETHER) 72 - return 0; 73 - 74 - if (net_dev->addr_len != ETH_ALEN) 75 - return 0; 76 - 77 - /* no batman over batman */ 78 - #ifdef HAVE_NET_DEVICE_OPS 79 - if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) 80 - return 0; 81 - #else 82 - if (net_dev->hard_start_xmit == interface_tx) 83 - return 0; 84 - #endif 85 - 86 - /* Device is being bridged */ 87 - /* if (net_dev->priv_flags & IFF_BRIDGE_PORT) 88 - return 0; */ 89 - 90 - return 1; 91 - } 92 - 93 - static struct batman_if *get_active_batman_if(struct net_device *soft_iface) 94 - { 95 - struct batman_if *batman_if; 96 - 97 - rcu_read_lock(); 98 - list_for_each_entry_rcu(batman_if, &if_list, list) { 99 - if (batman_if->soft_iface != soft_iface) 100 - continue; 101 - 102 - if (batman_if->if_status == IF_ACTIVE) 103 - goto out; 104 - } 105 - 106 - batman_if = NULL; 107 - 108 - out: 109 - if (batman_if) 110 - kref_get(&batman_if->refcount); 111 - 112 - rcu_read_unlock(); 113 - return batman_if; 114 - } 115 - 116 - static void update_primary_addr(struct bat_priv *bat_priv) 117 - { 118 - struct vis_packet *vis_packet; 119 - 120 - vis_packet = (struct vis_packet *) 121 - bat_priv->my_vis_info->skb_packet->data; 122 - memcpy(vis_packet->vis_orig, 123 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 124 - memcpy(vis_packet->sender_orig, 125 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 126 - } 127 - 128 - static void set_primary_if(struct bat_priv *bat_priv, 129 - struct batman_if *batman_if) 130 - { 131 - struct batman_packet *batman_packet; 132 - struct batman_if *old_if; 133 - 134 - if (batman_if) 135 - kref_get(&batman_if->refcount); 136 - 137 - old_if = bat_priv->primary_if; 138 - bat_priv->primary_if = batman_if; 139 - 140 - if (old_if) 141 - kref_put(&old_if->refcount, hardif_free_ref); 142 - 143 - if (!bat_priv->primary_if) 144 - return; 145 - 146 - batman_packet = (struct batman_packet *)(batman_if->packet_buff); 147 - batman_packet->flags = PRIMARIES_FIRST_HOP; 148 - batman_packet->ttl = TTL; 149 - 150 - update_primary_addr(bat_priv); 151 - 152 - /*** 153 - * hacky trick to make sure that we send the HNA information via 154 - * our new primary interface 155 - */ 156 - atomic_set(&bat_priv->hna_local_changed, 1); 157 - } 158 - 159 - static bool hardif_is_iface_up(struct batman_if *batman_if) 160 - { 161 - if (batman_if->net_dev->flags & IFF_UP) 162 - return true; 163 - 164 - return false; 165 - } 166 - 167 - static void update_mac_addresses(struct batman_if *batman_if) 168 - { 169 - memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, 170 - batman_if->net_dev->dev_addr, ETH_ALEN); 171 - memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender, 172 - batman_if->net_dev->dev_addr, ETH_ALEN); 173 - } 174 - 175 - static void check_known_mac_addr(struct net_device *net_dev) 176 - { 177 - struct batman_if *batman_if; 178 - 179 - rcu_read_lock(); 180 - list_for_each_entry_rcu(batman_if, &if_list, list) { 181 - if ((batman_if->if_status != IF_ACTIVE) && 182 - (batman_if->if_status != IF_TO_BE_ACTIVATED)) 183 - continue; 184 - 185 - if (batman_if->net_dev == net_dev) 186 - continue; 187 - 188 - if (!compare_orig(batman_if->net_dev->dev_addr, 189 - net_dev->dev_addr)) 190 - continue; 191 - 192 - pr_warning("The newly added mac address (%pM) already exists " 193 - "on: %s\n", net_dev->dev_addr, 194 - batman_if->net_dev->name); 195 - pr_warning("It is strongly recommended to keep mac addresses " 196 - "unique to avoid problems!\n"); 197 - } 198 - rcu_read_unlock(); 199 - } 200 - 201 - int hardif_min_mtu(struct net_device *soft_iface) 202 - { 203 - struct bat_priv *bat_priv = netdev_priv(soft_iface); 204 - struct batman_if *batman_if; 205 - /* allow big frames if all devices are capable to do so 206 - * (have MTU > 1500 + BAT_HEADER_LEN) */ 207 - int min_mtu = ETH_DATA_LEN; 208 - 209 - if (atomic_read(&bat_priv->fragmentation)) 210 - goto out; 211 - 212 - rcu_read_lock(); 213 - list_for_each_entry_rcu(batman_if, &if_list, list) { 214 - if ((batman_if->if_status != IF_ACTIVE) && 215 - (batman_if->if_status != IF_TO_BE_ACTIVATED)) 216 - continue; 217 - 218 - if (batman_if->soft_iface != soft_iface) 219 - continue; 220 - 221 - min_mtu = min_t(int, batman_if->net_dev->mtu - BAT_HEADER_LEN, 222 - min_mtu); 223 - } 224 - rcu_read_unlock(); 225 - out: 226 - return min_mtu; 227 - } 228 - 229 - /* adjusts the MTU if a new interface with a smaller MTU appeared. */ 230 - void update_min_mtu(struct net_device *soft_iface) 231 - { 232 - int min_mtu; 233 - 234 - min_mtu = hardif_min_mtu(soft_iface); 235 - if (soft_iface->mtu != min_mtu) 236 - soft_iface->mtu = min_mtu; 237 - } 238 - 239 - static void hardif_activate_interface(struct batman_if *batman_if) 240 - { 241 - struct bat_priv *bat_priv; 242 - 243 - if (batman_if->if_status != IF_INACTIVE) 244 - return; 245 - 246 - bat_priv = netdev_priv(batman_if->soft_iface); 247 - 248 - update_mac_addresses(batman_if); 249 - batman_if->if_status = IF_TO_BE_ACTIVATED; 250 - 251 - /** 252 - * the first active interface becomes our primary interface or 253 - * the next active interface after the old primay interface was removed 254 - */ 255 - if (!bat_priv->primary_if) 256 - set_primary_if(bat_priv, batman_if); 257 - 258 - bat_info(batman_if->soft_iface, "Interface activated: %s\n", 259 - batman_if->net_dev->name); 260 - 261 - update_min_mtu(batman_if->soft_iface); 262 - return; 263 - } 264 - 265 - static void hardif_deactivate_interface(struct batman_if *batman_if) 266 - { 267 - if ((batman_if->if_status != IF_ACTIVE) && 268 - (batman_if->if_status != IF_TO_BE_ACTIVATED)) 269 - return; 270 - 271 - batman_if->if_status = IF_INACTIVE; 272 - 273 - bat_info(batman_if->soft_iface, "Interface deactivated: %s\n", 274 - batman_if->net_dev->name); 275 - 276 - update_min_mtu(batman_if->soft_iface); 277 - } 278 - 279 - int hardif_enable_interface(struct batman_if *batman_if, char *iface_name) 280 - { 281 - struct bat_priv *bat_priv; 282 - struct batman_packet *batman_packet; 283 - 284 - if (batman_if->if_status != IF_NOT_IN_USE) 285 - goto out; 286 - 287 - batman_if->soft_iface = dev_get_by_name(&init_net, iface_name); 288 - 289 - if (!batman_if->soft_iface) { 290 - batman_if->soft_iface = softif_create(iface_name); 291 - 292 - if (!batman_if->soft_iface) 293 - goto err; 294 - 295 - /* dev_get_by_name() increases the reference counter for us */ 296 - dev_hold(batman_if->soft_iface); 297 - } 298 - 299 - bat_priv = netdev_priv(batman_if->soft_iface); 300 - batman_if->packet_len = BAT_PACKET_LEN; 301 - batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC); 302 - 303 - if (!batman_if->packet_buff) { 304 - bat_err(batman_if->soft_iface, "Can't add interface packet " 305 - "(%s): out of memory\n", batman_if->net_dev->name); 306 - goto err; 307 - } 308 - 309 - batman_packet = (struct batman_packet *)(batman_if->packet_buff); 310 - batman_packet->packet_type = BAT_PACKET; 311 - batman_packet->version = COMPAT_VERSION; 312 - batman_packet->flags = 0; 313 - batman_packet->ttl = 2; 314 - batman_packet->tq = TQ_MAX_VALUE; 315 - batman_packet->num_hna = 0; 316 - 317 - batman_if->if_num = bat_priv->num_ifaces; 318 - bat_priv->num_ifaces++; 319 - batman_if->if_status = IF_INACTIVE; 320 - orig_hash_add_if(batman_if, bat_priv->num_ifaces); 321 - 322 - batman_if->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN); 323 - batman_if->batman_adv_ptype.func = batman_skb_recv; 324 - batman_if->batman_adv_ptype.dev = batman_if->net_dev; 325 - kref_get(&batman_if->refcount); 326 - dev_add_pack(&batman_if->batman_adv_ptype); 327 - 328 - atomic_set(&batman_if->seqno, 1); 329 - atomic_set(&batman_if->frag_seqno, 1); 330 - bat_info(batman_if->soft_iface, "Adding interface: %s\n", 331 - batman_if->net_dev->name); 332 - 333 - if (atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu < 334 - ETH_DATA_LEN + BAT_HEADER_LEN) 335 - bat_info(batman_if->soft_iface, 336 - "The MTU of interface %s is too small (%i) to handle " 337 - "the transport of batman-adv packets. Packets going " 338 - "over this interface will be fragmented on layer2 " 339 - "which could impact the performance. Setting the MTU " 340 - "to %zi would solve the problem.\n", 341 - batman_if->net_dev->name, batman_if->net_dev->mtu, 342 - ETH_DATA_LEN + BAT_HEADER_LEN); 343 - 344 - if (!atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu < 345 - ETH_DATA_LEN + BAT_HEADER_LEN) 346 - bat_info(batman_if->soft_iface, 347 - "The MTU of interface %s is too small (%i) to handle " 348 - "the transport of batman-adv packets. If you experience" 349 - " problems getting traffic through try increasing the " 350 - "MTU to %zi.\n", 351 - batman_if->net_dev->name, batman_if->net_dev->mtu, 352 - ETH_DATA_LEN + BAT_HEADER_LEN); 353 - 354 - if (hardif_is_iface_up(batman_if)) 355 - hardif_activate_interface(batman_if); 356 - else 357 - bat_err(batman_if->soft_iface, "Not using interface %s " 358 - "(retrying later): interface not active\n", 359 - batman_if->net_dev->name); 360 - 361 - /* begin scheduling originator messages on that interface */ 362 - schedule_own_packet(batman_if); 363 - 364 - out: 365 - return 0; 366 - 367 - err: 368 - return -ENOMEM; 369 - } 370 - 371 - void hardif_disable_interface(struct batman_if *batman_if) 372 - { 373 - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 374 - 375 - if (batman_if->if_status == IF_ACTIVE) 376 - hardif_deactivate_interface(batman_if); 377 - 378 - if (batman_if->if_status != IF_INACTIVE) 379 - return; 380 - 381 - bat_info(batman_if->soft_iface, "Removing interface: %s\n", 382 - batman_if->net_dev->name); 383 - dev_remove_pack(&batman_if->batman_adv_ptype); 384 - kref_put(&batman_if->refcount, hardif_free_ref); 385 - 386 - bat_priv->num_ifaces--; 387 - orig_hash_del_if(batman_if, bat_priv->num_ifaces); 388 - 389 - if (batman_if == bat_priv->primary_if) { 390 - struct batman_if *new_if; 391 - 392 - new_if = get_active_batman_if(batman_if->soft_iface); 393 - set_primary_if(bat_priv, new_if); 394 - 395 - if (new_if) 396 - kref_put(&new_if->refcount, hardif_free_ref); 397 - } 398 - 399 - kfree(batman_if->packet_buff); 400 - batman_if->packet_buff = NULL; 401 - batman_if->if_status = IF_NOT_IN_USE; 402 - 403 - /* delete all references to this batman_if */ 404 - purge_orig_ref(bat_priv); 405 - purge_outstanding_packets(bat_priv, batman_if); 406 - dev_put(batman_if->soft_iface); 407 - 408 - /* nobody uses this interface anymore */ 409 - if (!bat_priv->num_ifaces) 410 - softif_destroy(batman_if->soft_iface); 411 - 412 - batman_if->soft_iface = NULL; 413 - } 414 - 415 - static struct batman_if *hardif_add_interface(struct net_device *net_dev) 416 - { 417 - struct batman_if *batman_if; 418 - int ret; 419 - 420 - ret = is_valid_iface(net_dev); 421 - if (ret != 1) 422 - goto out; 423 - 424 - dev_hold(net_dev); 425 - 426 - batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); 427 - if (!batman_if) { 428 - pr_err("Can't add interface (%s): out of memory\n", 429 - net_dev->name); 430 - goto release_dev; 431 - } 432 - 433 - ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev); 434 - if (ret) 435 - goto free_if; 436 - 437 - batman_if->if_num = -1; 438 - batman_if->net_dev = net_dev; 439 - batman_if->soft_iface = NULL; 440 - batman_if->if_status = IF_NOT_IN_USE; 441 - INIT_LIST_HEAD(&batman_if->list); 442 - kref_init(&batman_if->refcount); 443 - 444 - check_known_mac_addr(batman_if->net_dev); 445 - 446 - spin_lock(&if_list_lock); 447 - list_add_tail_rcu(&batman_if->list, &if_list); 448 - spin_unlock(&if_list_lock); 449 - 450 - /* extra reference for return */ 451 - kref_get(&batman_if->refcount); 452 - return batman_if; 453 - 454 - free_if: 455 - kfree(batman_if); 456 - release_dev: 457 - dev_put(net_dev); 458 - out: 459 - return NULL; 460 - } 461 - 462 - static void hardif_remove_interface(struct batman_if *batman_if) 463 - { 464 - /* first deactivate interface */ 465 - if (batman_if->if_status != IF_NOT_IN_USE) 466 - hardif_disable_interface(batman_if); 467 - 468 - if (batman_if->if_status != IF_NOT_IN_USE) 469 - return; 470 - 471 - batman_if->if_status = IF_TO_BE_REMOVED; 472 - synchronize_rcu(); 473 - sysfs_del_hardif(&batman_if->hardif_obj); 474 - call_rcu(&batman_if->rcu, hardif_free_rcu); 475 - } 476 - 477 - void hardif_remove_interfaces(void) 478 - { 479 - struct batman_if *batman_if, *batman_if_tmp; 480 - struct list_head if_queue; 481 - 482 - INIT_LIST_HEAD(&if_queue); 483 - 484 - spin_lock(&if_list_lock); 485 - list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) { 486 - list_del_rcu(&batman_if->list); 487 - list_add_tail(&batman_if->list, &if_queue); 488 - } 489 - spin_unlock(&if_list_lock); 490 - 491 - rtnl_lock(); 492 - list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) { 493 - hardif_remove_interface(batman_if); 494 - } 495 - rtnl_unlock(); 496 - } 497 - 498 - static int hard_if_event(struct notifier_block *this, 499 - unsigned long event, void *ptr) 500 - { 501 - struct net_device *net_dev = (struct net_device *)ptr; 502 - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); 503 - struct bat_priv *bat_priv; 504 - 505 - if (!batman_if && event == NETDEV_REGISTER) 506 - batman_if = hardif_add_interface(net_dev); 507 - 508 - if (!batman_if) 509 - goto out; 510 - 511 - switch (event) { 512 - case NETDEV_UP: 513 - hardif_activate_interface(batman_if); 514 - break; 515 - case NETDEV_GOING_DOWN: 516 - case NETDEV_DOWN: 517 - hardif_deactivate_interface(batman_if); 518 - break; 519 - case NETDEV_UNREGISTER: 520 - spin_lock(&if_list_lock); 521 - list_del_rcu(&batman_if->list); 522 - spin_unlock(&if_list_lock); 523 - 524 - hardif_remove_interface(batman_if); 525 - break; 526 - case NETDEV_CHANGEMTU: 527 - if (batman_if->soft_iface) 528 - update_min_mtu(batman_if->soft_iface); 529 - break; 530 - case NETDEV_CHANGEADDR: 531 - if (batman_if->if_status == IF_NOT_IN_USE) 532 - goto hardif_put; 533 - 534 - check_known_mac_addr(batman_if->net_dev); 535 - update_mac_addresses(batman_if); 536 - 537 - bat_priv = netdev_priv(batman_if->soft_iface); 538 - if (batman_if == bat_priv->primary_if) 539 - update_primary_addr(bat_priv); 540 - break; 541 - default: 542 - break; 543 - }; 544 - 545 - hardif_put: 546 - kref_put(&batman_if->refcount, hardif_free_ref); 547 - out: 548 - return NOTIFY_DONE; 549 - } 550 - 551 - /* receive a packet with the batman ethertype coming on a hard 552 - * interface */ 553 - int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, 554 - struct packet_type *ptype, struct net_device *orig_dev) 555 - { 556 - struct bat_priv *bat_priv; 557 - struct batman_packet *batman_packet; 558 - struct batman_if *batman_if; 559 - int ret; 560 - 561 - batman_if = container_of(ptype, struct batman_if, batman_adv_ptype); 562 - skb = skb_share_check(skb, GFP_ATOMIC); 563 - 564 - /* skb was released by skb_share_check() */ 565 - if (!skb) 566 - goto err_out; 567 - 568 - /* packet should hold at least type and version */ 569 - if (unlikely(!pskb_may_pull(skb, 2))) 570 - goto err_free; 571 - 572 - /* expect a valid ethernet header here. */ 573 - if (unlikely(skb->mac_len != sizeof(struct ethhdr) 574 - || !skb_mac_header(skb))) 575 - goto err_free; 576 - 577 - if (!batman_if->soft_iface) 578 - goto err_free; 579 - 580 - bat_priv = netdev_priv(batman_if->soft_iface); 581 - 582 - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) 583 - goto err_free; 584 - 585 - /* discard frames on not active interfaces */ 586 - if (batman_if->if_status != IF_ACTIVE) 587 - goto err_free; 588 - 589 - batman_packet = (struct batman_packet *)skb->data; 590 - 591 - if (batman_packet->version != COMPAT_VERSION) { 592 - bat_dbg(DBG_BATMAN, bat_priv, 593 - "Drop packet: incompatible batman version (%i)\n", 594 - batman_packet->version); 595 - goto err_free; 596 - } 597 - 598 - /* all receive handlers return whether they received or reused 599 - * the supplied skb. if not, we have to free the skb. */ 600 - 601 - switch (batman_packet->packet_type) { 602 - /* batman originator packet */ 603 - case BAT_PACKET: 604 - ret = recv_bat_packet(skb, batman_if); 605 - break; 606 - 607 - /* batman icmp packet */ 608 - case BAT_ICMP: 609 - ret = recv_icmp_packet(skb, batman_if); 610 - break; 611 - 612 - /* unicast packet */ 613 - case BAT_UNICAST: 614 - ret = recv_unicast_packet(skb, batman_if); 615 - break; 616 - 617 - /* fragmented unicast packet */ 618 - case BAT_UNICAST_FRAG: 619 - ret = recv_ucast_frag_packet(skb, batman_if); 620 - break; 621 - 622 - /* broadcast packet */ 623 - case BAT_BCAST: 624 - ret = recv_bcast_packet(skb, batman_if); 625 - break; 626 - 627 - /* vis packet */ 628 - case BAT_VIS: 629 - ret = recv_vis_packet(skb, batman_if); 630 - break; 631 - default: 632 - ret = NET_RX_DROP; 633 - } 634 - 635 - if (ret == NET_RX_DROP) 636 - kfree_skb(skb); 637 - 638 - /* return NET_RX_SUCCESS in any case as we 639 - * most probably dropped the packet for 640 - * routing-logical reasons. */ 641 - 642 - return NET_RX_SUCCESS; 643 - 644 - err_free: 645 - kfree_skb(skb); 646 - err_out: 647 - return NET_RX_DROP; 648 - } 649 - 650 - struct notifier_block hard_if_notifier = { 651 - .notifier_call = hard_if_event, 652 - };
-53
drivers/staging/batman-adv/hard-interface.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_ 23 - #define _NET_BATMAN_ADV_HARD_INTERFACE_H_ 24 - 25 - #define IF_NOT_IN_USE 0 26 - #define IF_TO_BE_REMOVED 1 27 - #define IF_INACTIVE 2 28 - #define IF_ACTIVE 3 29 - #define IF_TO_BE_ACTIVATED 4 30 - #define IF_I_WANT_YOU 5 31 - 32 - extern struct notifier_block hard_if_notifier; 33 - 34 - struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev); 35 - int hardif_enable_interface(struct batman_if *batman_if, char *iface_name); 36 - void hardif_disable_interface(struct batman_if *batman_if); 37 - void hardif_remove_interfaces(void); 38 - int batman_skb_recv(struct sk_buff *skb, 39 - struct net_device *dev, 40 - struct packet_type *ptype, 41 - struct net_device *orig_dev); 42 - int hardif_min_mtu(struct net_device *soft_iface); 43 - void update_min_mtu(struct net_device *soft_iface); 44 - 45 - static inline void hardif_free_ref(struct kref *refcount) 46 - { 47 - struct batman_if *batman_if; 48 - 49 - batman_if = container_of(refcount, struct batman_if, refcount); 50 - kfree(batman_if); 51 - } 52 - 53 - #endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
-83
drivers/staging/batman-adv/hash.c
··· 1 - /* 2 - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Simon Wunderlich, Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "hash.h" 24 - 25 - /* clears the hash */ 26 - static void hash_init(struct hashtable_t *hash) 27 - { 28 - int i; 29 - 30 - hash->elements = 0; 31 - 32 - for (i = 0 ; i < hash->size; i++) 33 - INIT_HLIST_HEAD(&hash->table[i]); 34 - } 35 - 36 - /* free only the hashtable and the hash itself. */ 37 - void hash_destroy(struct hashtable_t *hash) 38 - { 39 - kfree(hash->table); 40 - kfree(hash); 41 - } 42 - 43 - /* allocates and clears the hash */ 44 - struct hashtable_t *hash_new(int size) 45 - { 46 - struct hashtable_t *hash; 47 - 48 - hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC); 49 - 50 - if (hash == NULL) 51 - return NULL; 52 - 53 - hash->size = size; 54 - hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC); 55 - 56 - if (hash->table == NULL) { 57 - kfree(hash); 58 - return NULL; 59 - } 60 - 61 - hash_init(hash); 62 - 63 - return hash; 64 - } 65 - 66 - /* remove bucket (this might be used in hash_iterate() if you already found the 67 - * bucket you want to delete and don't need the overhead to find it again with 68 - * hash_remove(). But usually, you don't want to use this function, as it 69 - * fiddles with hash-internals. */ 70 - void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t) 71 - { 72 - void *data_save; 73 - struct element_t *bucket; 74 - 75 - bucket = hlist_entry(hash_it_t->walk, struct element_t, hlist); 76 - data_save = bucket->data; 77 - 78 - hlist_del(hash_it_t->walk); 79 - kfree(bucket); 80 - hash->elements--; 81 - 82 - return data_save; 83 - }
-259
drivers/staging/batman-adv/hash.h
··· 1 - /* 2 - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Simon Wunderlich, Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_HASH_H_ 23 - #define _NET_BATMAN_ADV_HASH_H_ 24 - 25 - #include <linux/list.h> 26 - 27 - #define HASHIT(name) struct hash_it_t name = { \ 28 - .index = 0, .walk = NULL, \ 29 - .safe = NULL} 30 - 31 - /* callback to a compare function. should 32 - * compare 2 element datas for their keys, 33 - * return 0 if same and not 0 if not 34 - * same */ 35 - typedef int (*hashdata_compare_cb)(void *, void *); 36 - 37 - /* the hashfunction, should return an index 38 - * based on the key in the data of the first 39 - * argument and the size the second */ 40 - typedef int (*hashdata_choose_cb)(void *, int); 41 - typedef void (*hashdata_free_cb)(void *, void *); 42 - 43 - struct element_t { 44 - void *data; /* pointer to the data */ 45 - struct hlist_node hlist; /* bucket list pointer */ 46 - }; 47 - 48 - struct hash_it_t { 49 - size_t index; 50 - struct hlist_node *walk; 51 - struct hlist_node *safe; 52 - }; 53 - 54 - struct hashtable_t { 55 - struct hlist_head *table; /* the hashtable itself, with the buckets */ 56 - int elements; /* number of elements registered */ 57 - int size; /* size of hashtable */ 58 - }; 59 - 60 - /* allocates and clears the hash */ 61 - struct hashtable_t *hash_new(int size); 62 - 63 - /* remove bucket (this might be used in hash_iterate() if you already found the 64 - * bucket you want to delete and don't need the overhead to find it again with 65 - * hash_remove(). But usually, you don't want to use this function, as it 66 - * fiddles with hash-internals. */ 67 - void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t); 68 - 69 - /* free only the hashtable and the hash itself. */ 70 - void hash_destroy(struct hashtable_t *hash); 71 - 72 - /* remove the hash structure. if hashdata_free_cb != NULL, this function will be 73 - * called to remove the elements inside of the hash. if you don't remove the 74 - * elements, memory might be leaked. */ 75 - static inline void hash_delete(struct hashtable_t *hash, 76 - hashdata_free_cb free_cb, void *arg) 77 - { 78 - struct hlist_head *head; 79 - struct hlist_node *walk, *safe; 80 - struct element_t *bucket; 81 - int i; 82 - 83 - for (i = 0; i < hash->size; i++) { 84 - head = &hash->table[i]; 85 - 86 - hlist_for_each_safe(walk, safe, head) { 87 - bucket = hlist_entry(walk, struct element_t, hlist); 88 - if (free_cb != NULL) 89 - free_cb(bucket->data, arg); 90 - 91 - hlist_del(walk); 92 - kfree(bucket); 93 - } 94 - } 95 - 96 - hash_destroy(hash); 97 - } 98 - 99 - /* adds data to the hashtable. returns 0 on success, -1 on error */ 100 - static inline int hash_add(struct hashtable_t *hash, 101 - hashdata_compare_cb compare, 102 - hashdata_choose_cb choose, void *data) 103 - { 104 - int index; 105 - struct hlist_head *head; 106 - struct hlist_node *walk, *safe; 107 - struct element_t *bucket; 108 - 109 - if (!hash) 110 - return -1; 111 - 112 - index = choose(data, hash->size); 113 - head = &hash->table[index]; 114 - 115 - hlist_for_each_safe(walk, safe, head) { 116 - bucket = hlist_entry(walk, struct element_t, hlist); 117 - if (compare(bucket->data, data)) 118 - return -1; 119 - } 120 - 121 - /* no duplicate found in list, add new element */ 122 - bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); 123 - 124 - if (bucket == NULL) 125 - return -1; 126 - 127 - bucket->data = data; 128 - hlist_add_head(&bucket->hlist, head); 129 - 130 - hash->elements++; 131 - return 0; 132 - } 133 - 134 - /* removes data from hash, if found. returns pointer do data on success, so you 135 - * can remove the used structure yourself, or NULL on error . data could be the 136 - * structure you use with just the key filled, we just need the key for 137 - * comparing. */ 138 - static inline void *hash_remove(struct hashtable_t *hash, 139 - hashdata_compare_cb compare, 140 - hashdata_choose_cb choose, void *data) 141 - { 142 - struct hash_it_t hash_it_t; 143 - struct element_t *bucket; 144 - struct hlist_head *head; 145 - 146 - hash_it_t.index = choose(data, hash->size); 147 - head = &hash->table[hash_it_t.index]; 148 - 149 - hlist_for_each(hash_it_t.walk, head) { 150 - bucket = hlist_entry(hash_it_t.walk, struct element_t, hlist); 151 - if (compare(bucket->data, data)) 152 - return hash_remove_bucket(hash, &hash_it_t); 153 - } 154 - 155 - return NULL; 156 - } 157 - 158 - /* finds data, based on the key in keydata. returns the found data on success, 159 - * or NULL on error */ 160 - static inline void *hash_find(struct hashtable_t *hash, 161 - hashdata_compare_cb compare, 162 - hashdata_choose_cb choose, void *keydata) 163 - { 164 - int index; 165 - struct hlist_head *head; 166 - struct hlist_node *walk; 167 - struct element_t *bucket; 168 - 169 - if (!hash) 170 - return NULL; 171 - 172 - index = choose(keydata , hash->size); 173 - head = &hash->table[index]; 174 - 175 - hlist_for_each(walk, head) { 176 - bucket = hlist_entry(walk, struct element_t, hlist); 177 - if (compare(bucket->data, keydata)) 178 - return bucket->data; 179 - } 180 - 181 - return NULL; 182 - } 183 - 184 - /* resize the hash, returns the pointer to the new hash or NULL on 185 - * error. removes the old hash on success */ 186 - static inline struct hashtable_t *hash_resize(struct hashtable_t *hash, 187 - hashdata_choose_cb choose, 188 - int size) 189 - { 190 - struct hashtable_t *new_hash; 191 - struct hlist_head *head, *new_head; 192 - struct hlist_node *walk, *safe; 193 - struct element_t *bucket; 194 - int i, new_index; 195 - 196 - /* initialize a new hash with the new size */ 197 - new_hash = hash_new(size); 198 - 199 - if (new_hash == NULL) 200 - return NULL; 201 - 202 - /* copy the elements */ 203 - for (i = 0; i < hash->size; i++) { 204 - head = &hash->table[i]; 205 - 206 - hlist_for_each_safe(walk, safe, head) { 207 - bucket = hlist_entry(walk, struct element_t, hlist); 208 - 209 - new_index = choose(bucket->data, size); 210 - new_head = &new_hash->table[new_index]; 211 - 212 - hlist_del(walk); 213 - hlist_add_head(walk, new_head); 214 - } 215 - } 216 - 217 - hash_destroy(hash); 218 - 219 - return new_hash; 220 - } 221 - 222 - /* iterate though the hash. First element is selected if an iterator 223 - * initialized with HASHIT() is supplied as iter. Use the returned 224 - * (or supplied) iterator to access the elements until hash_iterate returns 225 - * NULL. */ 226 - static inline struct hash_it_t *hash_iterate(struct hashtable_t *hash, 227 - struct hash_it_t *iter) 228 - { 229 - if (!hash) 230 - return NULL; 231 - if (!iter) 232 - return NULL; 233 - 234 - iter->walk = iter->safe; 235 - 236 - /* we search for the next head with list entries */ 237 - if (!iter->walk) { 238 - while (iter->index < hash->size) { 239 - if (hlist_empty(&hash->table[iter->index])) 240 - iter->index++; 241 - else { 242 - iter->walk = hash->table[iter->index].first; 243 - 244 - /* search next time */ 245 - ++iter->index; 246 - break; 247 - } 248 - } 249 - } 250 - 251 - /* return iter when we found bucket otherwise null */ 252 - if (!iter->walk) 253 - return NULL; 254 - 255 - iter->safe = iter->walk->next; 256 - return iter; 257 - } 258 - 259 - #endif /* _NET_BATMAN_ADV_HASH_H_ */
-357
drivers/staging/batman-adv/icmp_socket.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include <linux/debugfs.h> 24 - #include <linux/slab.h> 25 - #include "icmp_socket.h" 26 - #include "send.h" 27 - #include "types.h" 28 - #include "hash.h" 29 - #include "originator.h" 30 - #include "hard-interface.h" 31 - 32 - 33 - static struct socket_client *socket_client_hash[256]; 34 - 35 - static void bat_socket_add_packet(struct socket_client *socket_client, 36 - struct icmp_packet_rr *icmp_packet, 37 - size_t icmp_len); 38 - 39 - void bat_socket_init(void) 40 - { 41 - memset(socket_client_hash, 0, sizeof(socket_client_hash)); 42 - } 43 - 44 - static int bat_socket_open(struct inode *inode, struct file *file) 45 - { 46 - unsigned int i; 47 - struct socket_client *socket_client; 48 - 49 - nonseekable_open(inode, file); 50 - 51 - socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL); 52 - 53 - if (!socket_client) 54 - return -ENOMEM; 55 - 56 - for (i = 0; i < ARRAY_SIZE(socket_client_hash); i++) { 57 - if (!socket_client_hash[i]) { 58 - socket_client_hash[i] = socket_client; 59 - break; 60 - } 61 - } 62 - 63 - if (i == ARRAY_SIZE(socket_client_hash)) { 64 - pr_err("Error - can't add another packet client: " 65 - "maximum number of clients reached\n"); 66 - kfree(socket_client); 67 - return -EXFULL; 68 - } 69 - 70 - INIT_LIST_HEAD(&socket_client->queue_list); 71 - socket_client->queue_len = 0; 72 - socket_client->index = i; 73 - socket_client->bat_priv = inode->i_private; 74 - spin_lock_init(&socket_client->lock); 75 - init_waitqueue_head(&socket_client->queue_wait); 76 - 77 - file->private_data = socket_client; 78 - 79 - inc_module_count(); 80 - return 0; 81 - } 82 - 83 - static int bat_socket_release(struct inode *inode, struct file *file) 84 - { 85 - struct socket_client *socket_client = file->private_data; 86 - struct socket_packet *socket_packet; 87 - struct list_head *list_pos, *list_pos_tmp; 88 - 89 - spin_lock_bh(&socket_client->lock); 90 - 91 - /* for all packets in the queue ... */ 92 - list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) { 93 - socket_packet = list_entry(list_pos, 94 - struct socket_packet, list); 95 - 96 - list_del(list_pos); 97 - kfree(socket_packet); 98 - } 99 - 100 - socket_client_hash[socket_client->index] = NULL; 101 - spin_unlock_bh(&socket_client->lock); 102 - 103 - kfree(socket_client); 104 - dec_module_count(); 105 - 106 - return 0; 107 - } 108 - 109 - static ssize_t bat_socket_read(struct file *file, char __user *buf, 110 - size_t count, loff_t *ppos) 111 - { 112 - struct socket_client *socket_client = file->private_data; 113 - struct socket_packet *socket_packet; 114 - size_t packet_len; 115 - int error; 116 - 117 - if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0)) 118 - return -EAGAIN; 119 - 120 - if ((!buf) || (count < sizeof(struct icmp_packet))) 121 - return -EINVAL; 122 - 123 - if (!access_ok(VERIFY_WRITE, buf, count)) 124 - return -EFAULT; 125 - 126 - error = wait_event_interruptible(socket_client->queue_wait, 127 - socket_client->queue_len); 128 - 129 - if (error) 130 - return error; 131 - 132 - spin_lock_bh(&socket_client->lock); 133 - 134 - socket_packet = list_first_entry(&socket_client->queue_list, 135 - struct socket_packet, list); 136 - list_del(&socket_packet->list); 137 - socket_client->queue_len--; 138 - 139 - spin_unlock_bh(&socket_client->lock); 140 - 141 - error = __copy_to_user(buf, &socket_packet->icmp_packet, 142 - socket_packet->icmp_len); 143 - 144 - packet_len = socket_packet->icmp_len; 145 - kfree(socket_packet); 146 - 147 - if (error) 148 - return -EFAULT; 149 - 150 - return packet_len; 151 - } 152 - 153 - static ssize_t bat_socket_write(struct file *file, const char __user *buff, 154 - size_t len, loff_t *off) 155 - { 156 - struct socket_client *socket_client = file->private_data; 157 - struct bat_priv *bat_priv = socket_client->bat_priv; 158 - struct sk_buff *skb; 159 - struct icmp_packet_rr *icmp_packet; 160 - 161 - struct orig_node *orig_node; 162 - struct batman_if *batman_if; 163 - size_t packet_len = sizeof(struct icmp_packet); 164 - uint8_t dstaddr[ETH_ALEN]; 165 - 166 - if (len < sizeof(struct icmp_packet)) { 167 - bat_dbg(DBG_BATMAN, bat_priv, 168 - "Error - can't send packet from char device: " 169 - "invalid packet size\n"); 170 - return -EINVAL; 171 - } 172 - 173 - if (!bat_priv->primary_if) 174 - return -EFAULT; 175 - 176 - if (len >= sizeof(struct icmp_packet_rr)) 177 - packet_len = sizeof(struct icmp_packet_rr); 178 - 179 - skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr)); 180 - if (!skb) 181 - return -ENOMEM; 182 - 183 - skb_reserve(skb, sizeof(struct ethhdr)); 184 - icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len); 185 - 186 - if (!access_ok(VERIFY_READ, buff, packet_len)) { 187 - len = -EFAULT; 188 - goto free_skb; 189 - } 190 - 191 - if (__copy_from_user(icmp_packet, buff, packet_len)) { 192 - len = -EFAULT; 193 - goto free_skb; 194 - } 195 - 196 - if (icmp_packet->packet_type != BAT_ICMP) { 197 - bat_dbg(DBG_BATMAN, bat_priv, 198 - "Error - can't send packet from char device: " 199 - "got bogus packet type (expected: BAT_ICMP)\n"); 200 - len = -EINVAL; 201 - goto free_skb; 202 - } 203 - 204 - if (icmp_packet->msg_type != ECHO_REQUEST) { 205 - bat_dbg(DBG_BATMAN, bat_priv, 206 - "Error - can't send packet from char device: " 207 - "got bogus message type (expected: ECHO_REQUEST)\n"); 208 - len = -EINVAL; 209 - goto free_skb; 210 - } 211 - 212 - icmp_packet->uid = socket_client->index; 213 - 214 - if (icmp_packet->version != COMPAT_VERSION) { 215 - icmp_packet->msg_type = PARAMETER_PROBLEM; 216 - icmp_packet->ttl = COMPAT_VERSION; 217 - bat_socket_add_packet(socket_client, icmp_packet, packet_len); 218 - goto free_skb; 219 - } 220 - 221 - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) 222 - goto dst_unreach; 223 - 224 - spin_lock_bh(&bat_priv->orig_hash_lock); 225 - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, 226 - compare_orig, choose_orig, 227 - icmp_packet->dst)); 228 - 229 - if (!orig_node) 230 - goto unlock; 231 - 232 - if (!orig_node->router) 233 - goto unlock; 234 - 235 - batman_if = orig_node->router->if_incoming; 236 - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 237 - 238 - spin_unlock_bh(&bat_priv->orig_hash_lock); 239 - 240 - if (!batman_if) 241 - goto dst_unreach; 242 - 243 - if (batman_if->if_status != IF_ACTIVE) 244 - goto dst_unreach; 245 - 246 - memcpy(icmp_packet->orig, 247 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 248 - 249 - if (packet_len == sizeof(struct icmp_packet_rr)) 250 - memcpy(icmp_packet->rr, batman_if->net_dev->dev_addr, ETH_ALEN); 251 - 252 - 253 - send_skb_packet(skb, batman_if, dstaddr); 254 - 255 - goto out; 256 - 257 - unlock: 258 - spin_unlock_bh(&bat_priv->orig_hash_lock); 259 - dst_unreach: 260 - icmp_packet->msg_type = DESTINATION_UNREACHABLE; 261 - bat_socket_add_packet(socket_client, icmp_packet, packet_len); 262 - free_skb: 263 - kfree_skb(skb); 264 - out: 265 - return len; 266 - } 267 - 268 - static unsigned int bat_socket_poll(struct file *file, poll_table *wait) 269 - { 270 - struct socket_client *socket_client = file->private_data; 271 - 272 - poll_wait(file, &socket_client->queue_wait, wait); 273 - 274 - if (socket_client->queue_len > 0) 275 - return POLLIN | POLLRDNORM; 276 - 277 - return 0; 278 - } 279 - 280 - static const struct file_operations fops = { 281 - .owner = THIS_MODULE, 282 - .open = bat_socket_open, 283 - .release = bat_socket_release, 284 - .read = bat_socket_read, 285 - .write = bat_socket_write, 286 - .poll = bat_socket_poll, 287 - .llseek = no_llseek, 288 - }; 289 - 290 - int bat_socket_setup(struct bat_priv *bat_priv) 291 - { 292 - struct dentry *d; 293 - 294 - if (!bat_priv->debug_dir) 295 - goto err; 296 - 297 - d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, 298 - bat_priv->debug_dir, bat_priv, &fops); 299 - if (d) 300 - goto err; 301 - 302 - return 0; 303 - 304 - err: 305 - return 1; 306 - } 307 - 308 - static void bat_socket_add_packet(struct socket_client *socket_client, 309 - struct icmp_packet_rr *icmp_packet, 310 - size_t icmp_len) 311 - { 312 - struct socket_packet *socket_packet; 313 - 314 - socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC); 315 - 316 - if (!socket_packet) 317 - return; 318 - 319 - INIT_LIST_HEAD(&socket_packet->list); 320 - memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len); 321 - socket_packet->icmp_len = icmp_len; 322 - 323 - spin_lock_bh(&socket_client->lock); 324 - 325 - /* while waiting for the lock the socket_client could have been 326 - * deleted */ 327 - if (!socket_client_hash[icmp_packet->uid]) { 328 - spin_unlock_bh(&socket_client->lock); 329 - kfree(socket_packet); 330 - return; 331 - } 332 - 333 - list_add_tail(&socket_packet->list, &socket_client->queue_list); 334 - socket_client->queue_len++; 335 - 336 - if (socket_client->queue_len > 100) { 337 - socket_packet = list_first_entry(&socket_client->queue_list, 338 - struct socket_packet, list); 339 - 340 - list_del(&socket_packet->list); 341 - kfree(socket_packet); 342 - socket_client->queue_len--; 343 - } 344 - 345 - spin_unlock_bh(&socket_client->lock); 346 - 347 - wake_up(&socket_client->queue_wait); 348 - } 349 - 350 - void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet, 351 - size_t icmp_len) 352 - { 353 - struct socket_client *hash = socket_client_hash[icmp_packet->uid]; 354 - 355 - if (hash) 356 - bat_socket_add_packet(hash, icmp_packet, icmp_len); 357 - }
-34
drivers/staging/batman-adv/icmp_socket.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_ 23 - #define _NET_BATMAN_ADV_ICMP_SOCKET_H_ 24 - 25 - #include "types.h" 26 - 27 - #define ICMP_SOCKET "socket" 28 - 29 - void bat_socket_init(void); 30 - int bat_socket_setup(struct bat_priv *bat_priv); 31 - void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet, 32 - size_t icmp_len); 33 - 34 - #endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */
-187
drivers/staging/batman-adv/main.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "bat_sysfs.h" 24 - #include "bat_debugfs.h" 25 - #include "routing.h" 26 - #include "send.h" 27 - #include "originator.h" 28 - #include "soft-interface.h" 29 - #include "icmp_socket.h" 30 - #include "translation-table.h" 31 - #include "hard-interface.h" 32 - #include "gateway_client.h" 33 - #include "types.h" 34 - #include "vis.h" 35 - #include "hash.h" 36 - 37 - struct list_head if_list; 38 - 39 - unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 40 - 41 - struct workqueue_struct *bat_event_workqueue; 42 - 43 - static int __init batman_init(void) 44 - { 45 - INIT_LIST_HEAD(&if_list); 46 - 47 - /* the name should not be longer than 10 chars - see 48 - * http://lwn.net/Articles/23634/ */ 49 - bat_event_workqueue = create_singlethread_workqueue("bat_events"); 50 - 51 - if (!bat_event_workqueue) 52 - return -ENOMEM; 53 - 54 - bat_socket_init(); 55 - debugfs_init(); 56 - 57 - register_netdevice_notifier(&hard_if_notifier); 58 - 59 - pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) " 60 - "loaded\n", SOURCE_VERSION, REVISION_VERSION_STR, 61 - COMPAT_VERSION); 62 - 63 - return 0; 64 - } 65 - 66 - static void __exit batman_exit(void) 67 - { 68 - debugfs_destroy(); 69 - unregister_netdevice_notifier(&hard_if_notifier); 70 - hardif_remove_interfaces(); 71 - 72 - flush_workqueue(bat_event_workqueue); 73 - destroy_workqueue(bat_event_workqueue); 74 - bat_event_workqueue = NULL; 75 - 76 - rcu_barrier(); 77 - } 78 - 79 - int mesh_init(struct net_device *soft_iface) 80 - { 81 - struct bat_priv *bat_priv = netdev_priv(soft_iface); 82 - 83 - spin_lock_init(&bat_priv->orig_hash_lock); 84 - spin_lock_init(&bat_priv->forw_bat_list_lock); 85 - spin_lock_init(&bat_priv->forw_bcast_list_lock); 86 - spin_lock_init(&bat_priv->hna_lhash_lock); 87 - spin_lock_init(&bat_priv->hna_ghash_lock); 88 - spin_lock_init(&bat_priv->gw_list_lock); 89 - spin_lock_init(&bat_priv->vis_hash_lock); 90 - spin_lock_init(&bat_priv->vis_list_lock); 91 - spin_lock_init(&bat_priv->softif_neigh_lock); 92 - 93 - INIT_HLIST_HEAD(&bat_priv->forw_bat_list); 94 - INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); 95 - INIT_HLIST_HEAD(&bat_priv->gw_list); 96 - INIT_HLIST_HEAD(&bat_priv->softif_neigh_list); 97 - 98 - if (originator_init(bat_priv) < 1) 99 - goto err; 100 - 101 - if (hna_local_init(bat_priv) < 1) 102 - goto err; 103 - 104 - if (hna_global_init(bat_priv) < 1) 105 - goto err; 106 - 107 - hna_local_add(soft_iface, soft_iface->dev_addr); 108 - 109 - if (vis_init(bat_priv) < 1) 110 - goto err; 111 - 112 - atomic_set(&bat_priv->mesh_state, MESH_ACTIVE); 113 - goto end; 114 - 115 - err: 116 - pr_err("Unable to allocate memory for mesh information structures: " 117 - "out of mem ?\n"); 118 - mesh_free(soft_iface); 119 - return -1; 120 - 121 - end: 122 - return 0; 123 - } 124 - 125 - void mesh_free(struct net_device *soft_iface) 126 - { 127 - struct bat_priv *bat_priv = netdev_priv(soft_iface); 128 - 129 - atomic_set(&bat_priv->mesh_state, MESH_DEACTIVATING); 130 - 131 - purge_outstanding_packets(bat_priv, NULL); 132 - 133 - vis_quit(bat_priv); 134 - 135 - gw_node_purge(bat_priv); 136 - originator_free(bat_priv); 137 - 138 - hna_local_free(bat_priv); 139 - hna_global_free(bat_priv); 140 - 141 - softif_neigh_purge(bat_priv); 142 - 143 - atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); 144 - } 145 - 146 - void inc_module_count(void) 147 - { 148 - try_module_get(THIS_MODULE); 149 - } 150 - 151 - void dec_module_count(void) 152 - { 153 - module_put(THIS_MODULE); 154 - } 155 - 156 - int is_my_mac(uint8_t *addr) 157 - { 158 - struct batman_if *batman_if; 159 - 160 - rcu_read_lock(); 161 - list_for_each_entry_rcu(batman_if, &if_list, list) { 162 - if (batman_if->if_status != IF_ACTIVE) 163 - continue; 164 - 165 - if (compare_orig(batman_if->net_dev->dev_addr, addr)) { 166 - rcu_read_unlock(); 167 - return 1; 168 - } 169 - } 170 - rcu_read_unlock(); 171 - return 0; 172 - 173 - } 174 - 175 - module_init(batman_init); 176 - module_exit(batman_exit); 177 - 178 - MODULE_LICENSE("GPL"); 179 - 180 - MODULE_AUTHOR(DRIVER_AUTHOR); 181 - MODULE_DESCRIPTION(DRIVER_DESC); 182 - MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE); 183 - #ifdef REVISION_VERSION 184 - MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION); 185 - #else 186 - MODULE_VERSION(SOURCE_VERSION); 187 - #endif
-180
drivers/staging/batman-adv/main.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_MAIN_H_ 23 - #define _NET_BATMAN_ADV_MAIN_H_ 24 - 25 - /* Kernel Programming */ 26 - #define LINUX 27 - 28 - #define DRIVER_AUTHOR "Marek Lindner <lindner_marek@yahoo.de>, " \ 29 - "Simon Wunderlich <siwu@hrz.tu-chemnitz.de>" 30 - #define DRIVER_DESC "B.A.T.M.A.N. advanced" 31 - #define DRIVER_DEVICE "batman-adv" 32 - 33 - #define SOURCE_VERSION "next" 34 - 35 - 36 - /* B.A.T.M.A.N. parameters */ 37 - 38 - #define TQ_MAX_VALUE 255 39 - #define JITTER 20 40 - #define TTL 50 /* Time To Live of broadcast messages */ 41 - 42 - #define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no 43 - * valid packet comes in -> TODO: check 44 - * influence on TQ_LOCAL_WINDOW_SIZE */ 45 - #define LOCAL_HNA_TIMEOUT 3600 /* in seconds */ 46 - 47 - #define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator 48 - * messages in squence numbers (should be a 49 - * multiple of our word size) */ 50 - #define TQ_GLOBAL_WINDOW_SIZE 5 51 - #define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1 52 - #define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1 53 - #define TQ_TOTAL_BIDRECT_LIMIT 1 54 - 55 - #define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE) 56 - 57 - #define PACKBUFF_SIZE 2000 58 - #define LOG_BUF_LEN 8192 /* has to be a power of 2 */ 59 - 60 - #define VIS_INTERVAL 5000 /* 5 seconds */ 61 - 62 - /* how much worse secondary interfaces may be to 63 - * to be considered as bonding candidates */ 64 - 65 - #define BONDING_TQ_THRESHOLD 50 66 - 67 - #define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or 68 - * change the size of 69 - * forw_packet->direct_link_flags */ 70 - #define MAX_AGGREGATION_MS 100 71 - 72 - #define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */ 73 - 74 - #define RESET_PROTECTION_MS 30000 75 - #define EXPECTED_SEQNO_RANGE 65536 76 - /* don't reset again within 30 seconds */ 77 - 78 - #define MESH_INACTIVE 0 79 - #define MESH_ACTIVE 1 80 - #define MESH_DEACTIVATING 2 81 - 82 - #define BCAST_QUEUE_LEN 256 83 - #define BATMAN_QUEUE_LEN 256 84 - 85 - /* 86 - * Debug Messages 87 - */ 88 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before 89 - * kernel messages */ 90 - 91 - #define DBG_BATMAN 1 /* all messages related to routing / flooding / 92 - * broadcasting / etc */ 93 - #define DBG_ROUTES 2 /* route or hna added / changed / deleted */ 94 - #define DBG_ALL 3 95 - 96 - #define LOG_BUF_LEN 8192 /* has to be a power of 2 */ 97 - 98 - 99 - /* 100 - * Vis 101 - */ 102 - 103 - /* #define VIS_SUBCLUSTERS_DISABLED */ 104 - 105 - /* 106 - * Kernel headers 107 - */ 108 - 109 - #include <linux/mutex.h> /* mutex */ 110 - #include <linux/module.h> /* needed by all modules */ 111 - #include <linux/netdevice.h> /* netdevice */ 112 - #include <linux/etherdevice.h> /* ethernet address classifaction */ 113 - #include <linux/if_ether.h> /* ethernet header */ 114 - #include <linux/poll.h> /* poll_table */ 115 - #include <linux/kthread.h> /* kernel threads */ 116 - #include <linux/pkt_sched.h> /* schedule types */ 117 - #include <linux/workqueue.h> /* workqueue */ 118 - #include <linux/slab.h> 119 - #include <net/sock.h> /* struct sock */ 120 - #include <linux/jiffies.h> 121 - #include <linux/seq_file.h> 122 - #include "types.h" 123 - 124 - #ifndef REVISION_VERSION 125 - #define REVISION_VERSION_STR "" 126 - #else 127 - #define REVISION_VERSION_STR " "REVISION_VERSION 128 - #endif 129 - 130 - extern struct list_head if_list; 131 - 132 - extern unsigned char broadcast_addr[]; 133 - extern struct workqueue_struct *bat_event_workqueue; 134 - 135 - int mesh_init(struct net_device *soft_iface); 136 - void mesh_free(struct net_device *soft_iface); 137 - void inc_module_count(void); 138 - void dec_module_count(void); 139 - int is_my_mac(uint8_t *addr); 140 - 141 - #ifdef CONFIG_BATMAN_ADV_DEBUG 142 - int debug_log(struct bat_priv *bat_priv, char *fmt, ...); 143 - 144 - #define bat_dbg(type, bat_priv, fmt, arg...) \ 145 - do { \ 146 - if (atomic_read(&bat_priv->log_level) & type) \ 147 - debug_log(bat_priv, fmt, ## arg); \ 148 - } \ 149 - while (0) 150 - #else /* !CONFIG_BATMAN_ADV_DEBUG */ 151 - static inline void bat_dbg(char type __attribute__((unused)), 152 - struct bat_priv *bat_priv __attribute__((unused)), 153 - char *fmt __attribute__((unused)), ...) 154 - { 155 - } 156 - #endif 157 - 158 - #define bat_warning(net_dev, fmt, arg...) \ 159 - do { \ 160 - struct net_device *_netdev = (net_dev); \ 161 - struct bat_priv *_batpriv = netdev_priv(_netdev); \ 162 - bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ 163 - pr_warning("%s: " fmt, _netdev->name, ## arg); \ 164 - } while (0) 165 - #define bat_info(net_dev, fmt, arg...) \ 166 - do { \ 167 - struct net_device *_netdev = (net_dev); \ 168 - struct bat_priv *_batpriv = netdev_priv(_netdev); \ 169 - bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ 170 - pr_info("%s: " fmt, _netdev->name, ## arg); \ 171 - } while (0) 172 - #define bat_err(net_dev, fmt, arg...) \ 173 - do { \ 174 - struct net_device *_netdev = (net_dev); \ 175 - struct bat_priv *_batpriv = netdev_priv(_netdev); \ 176 - bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ 177 - pr_err("%s: " fmt, _netdev->name, ## arg); \ 178 - } while (0) 179 - 180 - #endif /* _NET_BATMAN_ADV_MAIN_H_ */
-546
drivers/staging/batman-adv/originator.c
··· 1 - /* 2 - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - /* increase the reference counter for this originator */ 23 - 24 - #include "main.h" 25 - #include "originator.h" 26 - #include "hash.h" 27 - #include "translation-table.h" 28 - #include "routing.h" 29 - #include "gateway_client.h" 30 - #include "hard-interface.h" 31 - #include "unicast.h" 32 - #include "soft-interface.h" 33 - 34 - static void purge_orig(struct work_struct *work); 35 - 36 - static void start_purge_timer(struct bat_priv *bat_priv) 37 - { 38 - INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); 39 - queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ); 40 - } 41 - 42 - int originator_init(struct bat_priv *bat_priv) 43 - { 44 - if (bat_priv->orig_hash) 45 - return 1; 46 - 47 - spin_lock_bh(&bat_priv->orig_hash_lock); 48 - bat_priv->orig_hash = hash_new(128); 49 - 50 - if (!bat_priv->orig_hash) 51 - goto err; 52 - 53 - spin_unlock_bh(&bat_priv->orig_hash_lock); 54 - start_purge_timer(bat_priv); 55 - return 1; 56 - 57 - err: 58 - spin_unlock_bh(&bat_priv->orig_hash_lock); 59 - return 0; 60 - } 61 - 62 - struct neigh_node * 63 - create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, 64 - uint8_t *neigh, struct batman_if *if_incoming) 65 - { 66 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 67 - struct neigh_node *neigh_node; 68 - 69 - bat_dbg(DBG_BATMAN, bat_priv, 70 - "Creating new last-hop neighbor of originator\n"); 71 - 72 - neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC); 73 - if (!neigh_node) 74 - return NULL; 75 - 76 - INIT_LIST_HEAD(&neigh_node->list); 77 - 78 - memcpy(neigh_node->addr, neigh, ETH_ALEN); 79 - neigh_node->orig_node = orig_neigh_node; 80 - neigh_node->if_incoming = if_incoming; 81 - 82 - list_add_tail(&neigh_node->list, &orig_node->neigh_list); 83 - return neigh_node; 84 - } 85 - 86 - static void free_orig_node(void *data, void *arg) 87 - { 88 - struct list_head *list_pos, *list_pos_tmp; 89 - struct neigh_node *neigh_node; 90 - struct orig_node *orig_node = (struct orig_node *)data; 91 - struct bat_priv *bat_priv = (struct bat_priv *)arg; 92 - 93 - /* for all neighbors towards this originator ... */ 94 - list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { 95 - neigh_node = list_entry(list_pos, struct neigh_node, list); 96 - 97 - list_del(list_pos); 98 - kfree(neigh_node); 99 - } 100 - 101 - frag_list_free(&orig_node->frag_list); 102 - hna_global_del_orig(bat_priv, orig_node, "originator timed out"); 103 - 104 - kfree(orig_node->bcast_own); 105 - kfree(orig_node->bcast_own_sum); 106 - kfree(orig_node); 107 - } 108 - 109 - void originator_free(struct bat_priv *bat_priv) 110 - { 111 - if (!bat_priv->orig_hash) 112 - return; 113 - 114 - cancel_delayed_work_sync(&bat_priv->orig_work); 115 - 116 - spin_lock_bh(&bat_priv->orig_hash_lock); 117 - hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv); 118 - bat_priv->orig_hash = NULL; 119 - spin_unlock_bh(&bat_priv->orig_hash_lock); 120 - } 121 - 122 - /* this function finds or creates an originator entry for the given 123 - * address if it does not exits */ 124 - struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) 125 - { 126 - struct orig_node *orig_node; 127 - struct hashtable_t *swaphash; 128 - int size; 129 - int hash_added; 130 - 131 - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, 132 - compare_orig, choose_orig, 133 - addr)); 134 - 135 - if (orig_node) 136 - return orig_node; 137 - 138 - bat_dbg(DBG_BATMAN, bat_priv, 139 - "Creating new originator: %pM\n", addr); 140 - 141 - orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC); 142 - if (!orig_node) 143 - return NULL; 144 - 145 - INIT_LIST_HEAD(&orig_node->neigh_list); 146 - 147 - memcpy(orig_node->orig, addr, ETH_ALEN); 148 - orig_node->router = NULL; 149 - orig_node->hna_buff = NULL; 150 - orig_node->bcast_seqno_reset = jiffies - 1 151 - - msecs_to_jiffies(RESET_PROTECTION_MS); 152 - orig_node->batman_seqno_reset = jiffies - 1 153 - - msecs_to_jiffies(RESET_PROTECTION_MS); 154 - 155 - size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS; 156 - 157 - orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); 158 - if (!orig_node->bcast_own) 159 - goto free_orig_node; 160 - 161 - size = bat_priv->num_ifaces * sizeof(uint8_t); 162 - orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); 163 - 164 - INIT_LIST_HEAD(&orig_node->frag_list); 165 - orig_node->last_frag_packet = 0; 166 - 167 - if (!orig_node->bcast_own_sum) 168 - goto free_bcast_own; 169 - 170 - hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, 171 - orig_node); 172 - if (hash_added < 0) 173 - goto free_bcast_own_sum; 174 - 175 - if (bat_priv->orig_hash->elements * 4 > bat_priv->orig_hash->size) { 176 - swaphash = hash_resize(bat_priv->orig_hash, choose_orig, 177 - bat_priv->orig_hash->size * 2); 178 - 179 - if (!swaphash) 180 - bat_dbg(DBG_BATMAN, bat_priv, 181 - "Couldn't resize orig hash table\n"); 182 - else 183 - bat_priv->orig_hash = swaphash; 184 - } 185 - 186 - return orig_node; 187 - free_bcast_own_sum: 188 - kfree(orig_node->bcast_own_sum); 189 - free_bcast_own: 190 - kfree(orig_node->bcast_own); 191 - free_orig_node: 192 - kfree(orig_node); 193 - return NULL; 194 - } 195 - 196 - static bool purge_orig_neighbors(struct bat_priv *bat_priv, 197 - struct orig_node *orig_node, 198 - struct neigh_node **best_neigh_node) 199 - { 200 - struct list_head *list_pos, *list_pos_tmp; 201 - struct neigh_node *neigh_node; 202 - bool neigh_purged = false; 203 - 204 - *best_neigh_node = NULL; 205 - 206 - /* for all neighbors towards this originator ... */ 207 - list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { 208 - neigh_node = list_entry(list_pos, struct neigh_node, list); 209 - 210 - if ((time_after(jiffies, 211 - neigh_node->last_valid + PURGE_TIMEOUT * HZ)) || 212 - (neigh_node->if_incoming->if_status == IF_INACTIVE) || 213 - (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { 214 - 215 - if (neigh_node->if_incoming->if_status == 216 - IF_TO_BE_REMOVED) 217 - bat_dbg(DBG_BATMAN, bat_priv, 218 - "neighbor purge: originator %pM, " 219 - "neighbor: %pM, iface: %s\n", 220 - orig_node->orig, neigh_node->addr, 221 - neigh_node->if_incoming->net_dev->name); 222 - else 223 - bat_dbg(DBG_BATMAN, bat_priv, 224 - "neighbor timeout: originator %pM, " 225 - "neighbor: %pM, last_valid: %lu\n", 226 - orig_node->orig, neigh_node->addr, 227 - (neigh_node->last_valid / HZ)); 228 - 229 - neigh_purged = true; 230 - list_del(list_pos); 231 - kfree(neigh_node); 232 - } else { 233 - if ((*best_neigh_node == NULL) || 234 - (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) 235 - *best_neigh_node = neigh_node; 236 - } 237 - } 238 - return neigh_purged; 239 - } 240 - 241 - static bool purge_orig_node(struct bat_priv *bat_priv, 242 - struct orig_node *orig_node) 243 - { 244 - struct neigh_node *best_neigh_node; 245 - 246 - if (time_after(jiffies, 247 - orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) { 248 - 249 - bat_dbg(DBG_BATMAN, bat_priv, 250 - "Originator timeout: originator %pM, last_valid %lu\n", 251 - orig_node->orig, (orig_node->last_valid / HZ)); 252 - return true; 253 - } else { 254 - if (purge_orig_neighbors(bat_priv, orig_node, 255 - &best_neigh_node)) { 256 - update_routes(bat_priv, orig_node, 257 - best_neigh_node, 258 - orig_node->hna_buff, 259 - orig_node->hna_buff_len); 260 - /* update bonding candidates, we could have lost 261 - * some candidates. */ 262 - update_bonding_candidates(bat_priv, orig_node); 263 - } 264 - } 265 - 266 - return false; 267 - } 268 - 269 - static void _purge_orig(struct bat_priv *bat_priv) 270 - { 271 - HASHIT(hashit); 272 - struct element_t *bucket; 273 - struct orig_node *orig_node; 274 - 275 - spin_lock_bh(&bat_priv->orig_hash_lock); 276 - 277 - /* for all origins... */ 278 - while (hash_iterate(bat_priv->orig_hash, &hashit)) { 279 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 280 - orig_node = bucket->data; 281 - 282 - if (purge_orig_node(bat_priv, orig_node)) { 283 - if (orig_node->gw_flags) 284 - gw_node_delete(bat_priv, orig_node); 285 - hash_remove_bucket(bat_priv->orig_hash, &hashit); 286 - free_orig_node(orig_node, bat_priv); 287 - } 288 - 289 - if (time_after(jiffies, (orig_node->last_frag_packet + 290 - msecs_to_jiffies(FRAG_TIMEOUT)))) 291 - frag_list_free(&orig_node->frag_list); 292 - } 293 - 294 - spin_unlock_bh(&bat_priv->orig_hash_lock); 295 - 296 - gw_node_purge(bat_priv); 297 - gw_election(bat_priv); 298 - 299 - softif_neigh_purge(bat_priv); 300 - } 301 - 302 - static void purge_orig(struct work_struct *work) 303 - { 304 - struct delayed_work *delayed_work = 305 - container_of(work, struct delayed_work, work); 306 - struct bat_priv *bat_priv = 307 - container_of(delayed_work, struct bat_priv, orig_work); 308 - 309 - _purge_orig(bat_priv); 310 - start_purge_timer(bat_priv); 311 - } 312 - 313 - void purge_orig_ref(struct bat_priv *bat_priv) 314 - { 315 - _purge_orig(bat_priv); 316 - } 317 - 318 - int orig_seq_print_text(struct seq_file *seq, void *offset) 319 - { 320 - HASHIT(hashit); 321 - struct element_t *bucket; 322 - struct net_device *net_dev = (struct net_device *)seq->private; 323 - struct bat_priv *bat_priv = netdev_priv(net_dev); 324 - struct orig_node *orig_node; 325 - struct neigh_node *neigh_node; 326 - int batman_count = 0; 327 - int last_seen_secs; 328 - int last_seen_msecs; 329 - 330 - if ((!bat_priv->primary_if) || 331 - (bat_priv->primary_if->if_status != IF_ACTIVE)) { 332 - if (!bat_priv->primary_if) 333 - return seq_printf(seq, "BATMAN mesh %s disabled - " 334 - "please specify interfaces to enable it\n", 335 - net_dev->name); 336 - 337 - return seq_printf(seq, "BATMAN mesh %s " 338 - "disabled - primary interface not active\n", 339 - net_dev->name); 340 - } 341 - 342 - seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", 343 - SOURCE_VERSION, REVISION_VERSION_STR, 344 - bat_priv->primary_if->net_dev->name, 345 - bat_priv->primary_if->net_dev->dev_addr, net_dev->name); 346 - seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", 347 - "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", 348 - "outgoingIF", "Potential nexthops"); 349 - 350 - spin_lock_bh(&bat_priv->orig_hash_lock); 351 - 352 - while (hash_iterate(bat_priv->orig_hash, &hashit)) { 353 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 354 - orig_node = bucket->data; 355 - 356 - if (!orig_node->router) 357 - continue; 358 - 359 - if (orig_node->router->tq_avg == 0) 360 - continue; 361 - 362 - last_seen_secs = jiffies_to_msecs(jiffies - 363 - orig_node->last_valid) / 1000; 364 - last_seen_msecs = jiffies_to_msecs(jiffies - 365 - orig_node->last_valid) % 1000; 366 - 367 - seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", 368 - orig_node->orig, last_seen_secs, last_seen_msecs, 369 - orig_node->router->tq_avg, orig_node->router->addr, 370 - orig_node->router->if_incoming->net_dev->name); 371 - 372 - list_for_each_entry(neigh_node, &orig_node->neigh_list, list) { 373 - seq_printf(seq, " %pM (%3i)", neigh_node->addr, 374 - neigh_node->tq_avg); 375 - } 376 - 377 - seq_printf(seq, "\n"); 378 - batman_count++; 379 - } 380 - 381 - spin_unlock_bh(&bat_priv->orig_hash_lock); 382 - 383 - if ((batman_count == 0)) 384 - seq_printf(seq, "No batman nodes in range ...\n"); 385 - 386 - return 0; 387 - } 388 - 389 - static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) 390 - { 391 - void *data_ptr; 392 - 393 - data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS, 394 - GFP_ATOMIC); 395 - if (!data_ptr) { 396 - pr_err("Can't resize orig: out of memory\n"); 397 - return -1; 398 - } 399 - 400 - memcpy(data_ptr, orig_node->bcast_own, 401 - (max_if_num - 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS); 402 - kfree(orig_node->bcast_own); 403 - orig_node->bcast_own = data_ptr; 404 - 405 - data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); 406 - if (!data_ptr) { 407 - pr_err("Can't resize orig: out of memory\n"); 408 - return -1; 409 - } 410 - 411 - memcpy(data_ptr, orig_node->bcast_own_sum, 412 - (max_if_num - 1) * sizeof(uint8_t)); 413 - kfree(orig_node->bcast_own_sum); 414 - orig_node->bcast_own_sum = data_ptr; 415 - 416 - return 0; 417 - } 418 - 419 - int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) 420 - { 421 - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 422 - struct orig_node *orig_node; 423 - HASHIT(hashit); 424 - struct element_t *bucket; 425 - 426 - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 427 - * if_num */ 428 - spin_lock_bh(&bat_priv->orig_hash_lock); 429 - 430 - while (hash_iterate(bat_priv->orig_hash, &hashit)) { 431 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 432 - orig_node = bucket->data; 433 - 434 - if (orig_node_add_if(orig_node, max_if_num) == -1) 435 - goto err; 436 - } 437 - 438 - spin_unlock_bh(&bat_priv->orig_hash_lock); 439 - return 0; 440 - 441 - err: 442 - spin_unlock_bh(&bat_priv->orig_hash_lock); 443 - return -ENOMEM; 444 - } 445 - 446 - static int orig_node_del_if(struct orig_node *orig_node, 447 - int max_if_num, int del_if_num) 448 - { 449 - void *data_ptr = NULL; 450 - int chunk_size; 451 - 452 - /* last interface was removed */ 453 - if (max_if_num == 0) 454 - goto free_bcast_own; 455 - 456 - chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS; 457 - data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); 458 - if (!data_ptr) { 459 - pr_err("Can't resize orig: out of memory\n"); 460 - return -1; 461 - } 462 - 463 - /* copy first part */ 464 - memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); 465 - 466 - /* copy second part */ 467 - memcpy(data_ptr + del_if_num * chunk_size, 468 - orig_node->bcast_own + ((del_if_num + 1) * chunk_size), 469 - (max_if_num - del_if_num) * chunk_size); 470 - 471 - free_bcast_own: 472 - kfree(orig_node->bcast_own); 473 - orig_node->bcast_own = data_ptr; 474 - 475 - if (max_if_num == 0) 476 - goto free_own_sum; 477 - 478 - data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); 479 - if (!data_ptr) { 480 - pr_err("Can't resize orig: out of memory\n"); 481 - return -1; 482 - } 483 - 484 - memcpy(data_ptr, orig_node->bcast_own_sum, 485 - del_if_num * sizeof(uint8_t)); 486 - 487 - memcpy(data_ptr + del_if_num * sizeof(uint8_t), 488 - orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)), 489 - (max_if_num - del_if_num) * sizeof(uint8_t)); 490 - 491 - free_own_sum: 492 - kfree(orig_node->bcast_own_sum); 493 - orig_node->bcast_own_sum = data_ptr; 494 - 495 - return 0; 496 - } 497 - 498 - int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) 499 - { 500 - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 501 - struct batman_if *batman_if_tmp; 502 - struct orig_node *orig_node; 503 - HASHIT(hashit); 504 - struct element_t *bucket; 505 - int ret; 506 - 507 - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 508 - * if_num */ 509 - spin_lock_bh(&bat_priv->orig_hash_lock); 510 - 511 - while (hash_iterate(bat_priv->orig_hash, &hashit)) { 512 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 513 - orig_node = bucket->data; 514 - 515 - ret = orig_node_del_if(orig_node, max_if_num, 516 - batman_if->if_num); 517 - 518 - if (ret == -1) 519 - goto err; 520 - } 521 - 522 - /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ 523 - rcu_read_lock(); 524 - list_for_each_entry_rcu(batman_if_tmp, &if_list, list) { 525 - if (batman_if_tmp->if_status == IF_NOT_IN_USE) 526 - continue; 527 - 528 - if (batman_if == batman_if_tmp) 529 - continue; 530 - 531 - if (batman_if->soft_iface != batman_if_tmp->soft_iface) 532 - continue; 533 - 534 - if (batman_if_tmp->if_num > batman_if->if_num) 535 - batman_if_tmp->if_num--; 536 - } 537 - rcu_read_unlock(); 538 - 539 - batman_if->if_num = -1; 540 - spin_unlock_bh(&bat_priv->orig_hash_lock); 541 - return 0; 542 - 543 - err: 544 - spin_unlock_bh(&bat_priv->orig_hash_lock); 545 - return -ENOMEM; 546 - }
-64
drivers/staging/batman-adv/originator.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_ORIGINATOR_H_ 23 - #define _NET_BATMAN_ADV_ORIGINATOR_H_ 24 - 25 - int originator_init(struct bat_priv *bat_priv); 26 - void originator_free(struct bat_priv *bat_priv); 27 - void purge_orig_ref(struct bat_priv *bat_priv); 28 - struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr); 29 - struct neigh_node * 30 - create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, 31 - uint8_t *neigh, struct batman_if *if_incoming); 32 - int orig_seq_print_text(struct seq_file *seq, void *offset); 33 - int orig_hash_add_if(struct batman_if *batman_if, int max_if_num); 34 - int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); 35 - 36 - 37 - /* returns 1 if they are the same originator */ 38 - static inline int compare_orig(void *data1, void *data2) 39 - { 40 - return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 41 - } 42 - 43 - /* hashfunction to choose an entry in a hash table of given size */ 44 - /* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ 45 - static inline int choose_orig(void *data, int32_t size) 46 - { 47 - unsigned char *key = data; 48 - uint32_t hash = 0; 49 - size_t i; 50 - 51 - for (i = 0; i < 6; i++) { 52 - hash += key[i]; 53 - hash += (hash << 10); 54 - hash ^= (hash >> 6); 55 - } 56 - 57 - hash += (hash << 3); 58 - hash ^= (hash >> 11); 59 - hash += (hash << 15); 60 - 61 - return hash % size; 62 - } 63 - 64 - #endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */
-136
drivers/staging/batman-adv/packet.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_PACKET_H_ 23 - #define _NET_BATMAN_ADV_PACKET_H_ 24 - 25 - #define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ 26 - 27 - #define BAT_PACKET 0x01 28 - #define BAT_ICMP 0x02 29 - #define BAT_UNICAST 0x03 30 - #define BAT_BCAST 0x04 31 - #define BAT_VIS 0x05 32 - #define BAT_UNICAST_FRAG 0x06 33 - 34 - /* this file is included by batctl which needs these defines */ 35 - #define COMPAT_VERSION 12 36 - #define DIRECTLINK 0x40 37 - #define VIS_SERVER 0x20 38 - #define PRIMARIES_FIRST_HOP 0x10 39 - 40 - /* ICMP message types */ 41 - #define ECHO_REPLY 0 42 - #define DESTINATION_UNREACHABLE 3 43 - #define ECHO_REQUEST 8 44 - #define TTL_EXCEEDED 11 45 - #define PARAMETER_PROBLEM 12 46 - 47 - /* vis defines */ 48 - #define VIS_TYPE_SERVER_SYNC 0 49 - #define VIS_TYPE_CLIENT_UPDATE 1 50 - 51 - /* fragmentation defines */ 52 - #define UNI_FRAG_HEAD 0x01 53 - 54 - struct batman_packet { 55 - uint8_t packet_type; 56 - uint8_t version; /* batman version field */ 57 - uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */ 58 - uint8_t tq; 59 - uint32_t seqno; 60 - uint8_t orig[6]; 61 - uint8_t prev_sender[6]; 62 - uint8_t ttl; 63 - uint8_t num_hna; 64 - uint8_t gw_flags; /* flags related to gateway class */ 65 - uint8_t align; 66 - } __attribute__((packed)); 67 - 68 - #define BAT_PACKET_LEN sizeof(struct batman_packet) 69 - 70 - struct icmp_packet { 71 - uint8_t packet_type; 72 - uint8_t version; /* batman version field */ 73 - uint8_t msg_type; /* see ICMP message types above */ 74 - uint8_t ttl; 75 - uint8_t dst[6]; 76 - uint8_t orig[6]; 77 - uint16_t seqno; 78 - uint8_t uid; 79 - } __attribute__((packed)); 80 - 81 - #define BAT_RR_LEN 16 82 - 83 - /* icmp_packet_rr must start with all fields from imcp_packet 84 - * as this is assumed by code that handles ICMP packets */ 85 - struct icmp_packet_rr { 86 - uint8_t packet_type; 87 - uint8_t version; /* batman version field */ 88 - uint8_t msg_type; /* see ICMP message types above */ 89 - uint8_t ttl; 90 - uint8_t dst[6]; 91 - uint8_t orig[6]; 92 - uint16_t seqno; 93 - uint8_t uid; 94 - uint8_t rr_cur; 95 - uint8_t rr[BAT_RR_LEN][ETH_ALEN]; 96 - } __attribute__((packed)); 97 - 98 - struct unicast_packet { 99 - uint8_t packet_type; 100 - uint8_t version; /* batman version field */ 101 - uint8_t dest[6]; 102 - uint8_t ttl; 103 - } __attribute__((packed)); 104 - 105 - struct unicast_frag_packet { 106 - uint8_t packet_type; 107 - uint8_t version; /* batman version field */ 108 - uint8_t dest[6]; 109 - uint8_t ttl; 110 - uint8_t flags; 111 - uint8_t orig[6]; 112 - uint16_t seqno; 113 - } __attribute__((packed)); 114 - 115 - struct bcast_packet { 116 - uint8_t packet_type; 117 - uint8_t version; /* batman version field */ 118 - uint8_t orig[6]; 119 - uint8_t ttl; 120 - uint32_t seqno; 121 - } __attribute__((packed)); 122 - 123 - struct vis_packet { 124 - uint8_t packet_type; 125 - uint8_t version; /* batman version field */ 126 - uint8_t vis_type; /* which type of vis-participant sent this? */ 127 - uint8_t entries; /* number of entries behind this struct */ 128 - uint32_t seqno; /* sequence number */ 129 - uint8_t ttl; /* TTL */ 130 - uint8_t vis_orig[6]; /* originator that informs about its 131 - * neighbors */ 132 - uint8_t target_orig[6]; /* who should receive this packet */ 133 - uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ 134 - } __attribute__((packed)); 135 - 136 - #endif /* _NET_BATMAN_ADV_PACKET_H_ */
-52
drivers/staging/batman-adv/ring_buffer.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "ring_buffer.h" 24 - 25 - void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value) 26 - { 27 - lq_recv[*lq_index] = value; 28 - *lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE; 29 - } 30 - 31 - uint8_t ring_buffer_avg(uint8_t lq_recv[]) 32 - { 33 - uint8_t *ptr; 34 - uint16_t count = 0, i = 0, sum = 0; 35 - 36 - ptr = lq_recv; 37 - 38 - while (i < TQ_GLOBAL_WINDOW_SIZE) { 39 - if (*ptr != 0) { 40 - count++; 41 - sum += *ptr; 42 - } 43 - 44 - i++; 45 - ptr++; 46 - } 47 - 48 - if (count == 0) 49 - return 0; 50 - 51 - return (uint8_t)(sum / count); 52 - }
-28
drivers/staging/batman-adv/ring_buffer.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_RING_BUFFER_H_ 23 - #define _NET_BATMAN_ADV_RING_BUFFER_H_ 24 - 25 - void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value); 26 - uint8_t ring_buffer_avg(uint8_t lq_recv[]); 27 - 28 - #endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */
-1393
drivers/staging/batman-adv/routing.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "routing.h" 24 - #include "send.h" 25 - #include "hash.h" 26 - #include "soft-interface.h" 27 - #include "hard-interface.h" 28 - #include "icmp_socket.h" 29 - #include "translation-table.h" 30 - #include "originator.h" 31 - #include "types.h" 32 - #include "ring_buffer.h" 33 - #include "vis.h" 34 - #include "aggregation.h" 35 - #include "gateway_common.h" 36 - #include "gateway_client.h" 37 - #include "unicast.h" 38 - 39 - void slide_own_bcast_window(struct batman_if *batman_if) 40 - { 41 - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 42 - HASHIT(hashit); 43 - struct element_t *bucket; 44 - struct orig_node *orig_node; 45 - TYPE_OF_WORD *word; 46 - 47 - spin_lock_bh(&bat_priv->orig_hash_lock); 48 - 49 - while (hash_iterate(bat_priv->orig_hash, &hashit)) { 50 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 51 - orig_node = bucket->data; 52 - word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]); 53 - 54 - bit_get_packet(bat_priv, word, 1, 0); 55 - orig_node->bcast_own_sum[batman_if->if_num] = 56 - bit_packet_count(word); 57 - } 58 - 59 - spin_unlock_bh(&bat_priv->orig_hash_lock); 60 - } 61 - 62 - static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node, 63 - unsigned char *hna_buff, int hna_buff_len) 64 - { 65 - if ((hna_buff_len != orig_node->hna_buff_len) || 66 - ((hna_buff_len > 0) && 67 - (orig_node->hna_buff_len > 0) && 68 - (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) { 69 - 70 - if (orig_node->hna_buff_len > 0) 71 - hna_global_del_orig(bat_priv, orig_node, 72 - "originator changed hna"); 73 - 74 - if ((hna_buff_len > 0) && (hna_buff != NULL)) 75 - hna_global_add_orig(bat_priv, orig_node, 76 - hna_buff, hna_buff_len); 77 - } 78 - } 79 - 80 - static void update_route(struct bat_priv *bat_priv, 81 - struct orig_node *orig_node, 82 - struct neigh_node *neigh_node, 83 - unsigned char *hna_buff, int hna_buff_len) 84 - { 85 - /* route deleted */ 86 - if ((orig_node->router != NULL) && (neigh_node == NULL)) { 87 - 88 - bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", 89 - orig_node->orig); 90 - hna_global_del_orig(bat_priv, orig_node, 91 - "originator timed out"); 92 - 93 - /* route added */ 94 - } else if ((orig_node->router == NULL) && (neigh_node != NULL)) { 95 - 96 - bat_dbg(DBG_ROUTES, bat_priv, 97 - "Adding route towards: %pM (via %pM)\n", 98 - orig_node->orig, neigh_node->addr); 99 - hna_global_add_orig(bat_priv, orig_node, 100 - hna_buff, hna_buff_len); 101 - 102 - /* route changed */ 103 - } else { 104 - bat_dbg(DBG_ROUTES, bat_priv, 105 - "Changing route towards: %pM " 106 - "(now via %pM - was via %pM)\n", 107 - orig_node->orig, neigh_node->addr, 108 - orig_node->router->addr); 109 - } 110 - 111 - orig_node->router = neigh_node; 112 - } 113 - 114 - 115 - void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, 116 - struct neigh_node *neigh_node, unsigned char *hna_buff, 117 - int hna_buff_len) 118 - { 119 - 120 - if (orig_node == NULL) 121 - return; 122 - 123 - if (orig_node->router != neigh_node) 124 - update_route(bat_priv, orig_node, neigh_node, 125 - hna_buff, hna_buff_len); 126 - /* may be just HNA changed */ 127 - else 128 - update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len); 129 - } 130 - 131 - static int is_bidirectional_neigh(struct orig_node *orig_node, 132 - struct orig_node *orig_neigh_node, 133 - struct batman_packet *batman_packet, 134 - struct batman_if *if_incoming) 135 - { 136 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 137 - struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 138 - unsigned char total_count; 139 - 140 - if (orig_node == orig_neigh_node) { 141 - list_for_each_entry(tmp_neigh_node, 142 - &orig_node->neigh_list, 143 - list) { 144 - 145 - if (compare_orig(tmp_neigh_node->addr, 146 - orig_neigh_node->orig) && 147 - (tmp_neigh_node->if_incoming == if_incoming)) 148 - neigh_node = tmp_neigh_node; 149 - } 150 - 151 - if (!neigh_node) 152 - neigh_node = create_neighbor(orig_node, 153 - orig_neigh_node, 154 - orig_neigh_node->orig, 155 - if_incoming); 156 - /* create_neighbor failed, return 0 */ 157 - if (!neigh_node) 158 - return 0; 159 - 160 - neigh_node->last_valid = jiffies; 161 - } else { 162 - /* find packet count of corresponding one hop neighbor */ 163 - list_for_each_entry(tmp_neigh_node, 164 - &orig_neigh_node->neigh_list, list) { 165 - 166 - if (compare_orig(tmp_neigh_node->addr, 167 - orig_neigh_node->orig) && 168 - (tmp_neigh_node->if_incoming == if_incoming)) 169 - neigh_node = tmp_neigh_node; 170 - } 171 - 172 - if (!neigh_node) 173 - neigh_node = create_neighbor(orig_neigh_node, 174 - orig_neigh_node, 175 - orig_neigh_node->orig, 176 - if_incoming); 177 - /* create_neighbor failed, return 0 */ 178 - if (!neigh_node) 179 - return 0; 180 - } 181 - 182 - orig_node->last_valid = jiffies; 183 - 184 - /* pay attention to not get a value bigger than 100 % */ 185 - total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > 186 - neigh_node->real_packet_count ? 187 - neigh_node->real_packet_count : 188 - orig_neigh_node->bcast_own_sum[if_incoming->if_num]); 189 - 190 - /* if we have too few packets (too less data) we set tq_own to zero */ 191 - /* if we receive too few packets it is not considered bidirectional */ 192 - if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || 193 - (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) 194 - orig_neigh_node->tq_own = 0; 195 - else 196 - /* neigh_node->real_packet_count is never zero as we 197 - * only purge old information when getting new 198 - * information */ 199 - orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / 200 - neigh_node->real_packet_count; 201 - 202 - /* 203 - * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does 204 - * affect the nearly-symmetric links only a little, but 205 - * punishes asymmetric links more. This will give a value 206 - * between 0 and TQ_MAX_VALUE 207 - */ 208 - orig_neigh_node->tq_asym_penalty = 209 - TQ_MAX_VALUE - 210 - (TQ_MAX_VALUE * 211 - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * 212 - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * 213 - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / 214 - (TQ_LOCAL_WINDOW_SIZE * 215 - TQ_LOCAL_WINDOW_SIZE * 216 - TQ_LOCAL_WINDOW_SIZE); 217 - 218 - batman_packet->tq = ((batman_packet->tq * 219 - orig_neigh_node->tq_own * 220 - orig_neigh_node->tq_asym_penalty) / 221 - (TQ_MAX_VALUE * TQ_MAX_VALUE)); 222 - 223 - bat_dbg(DBG_BATMAN, bat_priv, 224 - "bidirectional: " 225 - "orig = %-15pM neigh = %-15pM => own_bcast = %2i, " 226 - "real recv = %2i, local tq: %3i, asym_penalty: %3i, " 227 - "total tq: %3i\n", 228 - orig_node->orig, orig_neigh_node->orig, total_count, 229 - neigh_node->real_packet_count, orig_neigh_node->tq_own, 230 - orig_neigh_node->tq_asym_penalty, batman_packet->tq); 231 - 232 - /* if link has the minimum required transmission quality 233 - * consider it bidirectional */ 234 - if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) 235 - return 1; 236 - 237 - return 0; 238 - } 239 - 240 - static void update_orig(struct bat_priv *bat_priv, 241 - struct orig_node *orig_node, 242 - struct ethhdr *ethhdr, 243 - struct batman_packet *batman_packet, 244 - struct batman_if *if_incoming, 245 - unsigned char *hna_buff, int hna_buff_len, 246 - char is_duplicate) 247 - { 248 - struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 249 - int tmp_hna_buff_len; 250 - 251 - bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " 252 - "Searching and updating originator entry of received packet\n"); 253 - 254 - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 255 - if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && 256 - (tmp_neigh_node->if_incoming == if_incoming)) { 257 - neigh_node = tmp_neigh_node; 258 - continue; 259 - } 260 - 261 - if (is_duplicate) 262 - continue; 263 - 264 - ring_buffer_set(tmp_neigh_node->tq_recv, 265 - &tmp_neigh_node->tq_index, 0); 266 - tmp_neigh_node->tq_avg = 267 - ring_buffer_avg(tmp_neigh_node->tq_recv); 268 - } 269 - 270 - if (!neigh_node) { 271 - struct orig_node *orig_tmp; 272 - 273 - orig_tmp = get_orig_node(bat_priv, ethhdr->h_source); 274 - if (!orig_tmp) 275 - return; 276 - 277 - neigh_node = create_neighbor(orig_node, orig_tmp, 278 - ethhdr->h_source, if_incoming); 279 - if (!neigh_node) 280 - return; 281 - } else 282 - bat_dbg(DBG_BATMAN, bat_priv, 283 - "Updating existing last-hop neighbor of originator\n"); 284 - 285 - orig_node->flags = batman_packet->flags; 286 - neigh_node->last_valid = jiffies; 287 - 288 - ring_buffer_set(neigh_node->tq_recv, 289 - &neigh_node->tq_index, 290 - batman_packet->tq); 291 - neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); 292 - 293 - if (!is_duplicate) { 294 - orig_node->last_ttl = batman_packet->ttl; 295 - neigh_node->last_ttl = batman_packet->ttl; 296 - } 297 - 298 - tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? 299 - batman_packet->num_hna * ETH_ALEN : hna_buff_len); 300 - 301 - /* if this neighbor already is our next hop there is nothing 302 - * to change */ 303 - if (orig_node->router == neigh_node) 304 - goto update_hna; 305 - 306 - /* if this neighbor does not offer a better TQ we won't consider it */ 307 - if ((orig_node->router) && 308 - (orig_node->router->tq_avg > neigh_node->tq_avg)) 309 - goto update_hna; 310 - 311 - /* if the TQ is the same and the link not more symetric we 312 - * won't consider it either */ 313 - if ((orig_node->router) && 314 - ((neigh_node->tq_avg == orig_node->router->tq_avg) && 315 - (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] 316 - >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) 317 - goto update_hna; 318 - 319 - update_routes(bat_priv, orig_node, neigh_node, 320 - hna_buff, tmp_hna_buff_len); 321 - goto update_gw; 322 - 323 - update_hna: 324 - update_routes(bat_priv, orig_node, orig_node->router, 325 - hna_buff, tmp_hna_buff_len); 326 - 327 - update_gw: 328 - if (orig_node->gw_flags != batman_packet->gw_flags) 329 - gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); 330 - 331 - orig_node->gw_flags = batman_packet->gw_flags; 332 - 333 - /* restart gateway selection if fast or late switching was enabled */ 334 - if ((orig_node->gw_flags) && 335 - (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) && 336 - (atomic_read(&bat_priv->gw_sel_class) > 2)) 337 - gw_check_election(bat_priv, orig_node); 338 - } 339 - 340 - /* checks whether the host restarted and is in the protection time. 341 - * returns: 342 - * 0 if the packet is to be accepted 343 - * 1 if the packet is to be ignored. 344 - */ 345 - static int window_protected(struct bat_priv *bat_priv, 346 - int32_t seq_num_diff, 347 - unsigned long *last_reset) 348 - { 349 - if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) 350 - || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { 351 - if (time_after(jiffies, *last_reset + 352 - msecs_to_jiffies(RESET_PROTECTION_MS))) { 353 - 354 - *last_reset = jiffies; 355 - bat_dbg(DBG_BATMAN, bat_priv, 356 - "old packet received, start protection\n"); 357 - 358 - return 0; 359 - } else 360 - return 1; 361 - } 362 - return 0; 363 - } 364 - 365 - /* processes a batman packet for all interfaces, adjusts the sequence number and 366 - * finds out whether it is a duplicate. 367 - * returns: 368 - * 1 the packet is a duplicate 369 - * 0 the packet has not yet been received 370 - * -1 the packet is old and has been received while the seqno window 371 - * was protected. Caller should drop it. 372 - */ 373 - static char count_real_packets(struct ethhdr *ethhdr, 374 - struct batman_packet *batman_packet, 375 - struct batman_if *if_incoming) 376 - { 377 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 378 - struct orig_node *orig_node; 379 - struct neigh_node *tmp_neigh_node; 380 - char is_duplicate = 0; 381 - int32_t seq_diff; 382 - int need_update = 0; 383 - int set_mark; 384 - 385 - orig_node = get_orig_node(bat_priv, batman_packet->orig); 386 - if (orig_node == NULL) 387 - return 0; 388 - 389 - seq_diff = batman_packet->seqno - orig_node->last_real_seqno; 390 - 391 - /* signalize caller that the packet is to be dropped. */ 392 - if (window_protected(bat_priv, seq_diff, 393 - &orig_node->batman_seqno_reset)) 394 - return -1; 395 - 396 - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 397 - 398 - is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, 399 - orig_node->last_real_seqno, 400 - batman_packet->seqno); 401 - 402 - if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && 403 - (tmp_neigh_node->if_incoming == if_incoming)) 404 - set_mark = 1; 405 - else 406 - set_mark = 0; 407 - 408 - /* if the window moved, set the update flag. */ 409 - need_update |= bit_get_packet(bat_priv, 410 - tmp_neigh_node->real_bits, 411 - seq_diff, set_mark); 412 - 413 - tmp_neigh_node->real_packet_count = 414 - bit_packet_count(tmp_neigh_node->real_bits); 415 - } 416 - 417 - if (need_update) { 418 - bat_dbg(DBG_BATMAN, bat_priv, 419 - "updating last_seqno: old %d, new %d\n", 420 - orig_node->last_real_seqno, batman_packet->seqno); 421 - orig_node->last_real_seqno = batman_packet->seqno; 422 - } 423 - 424 - return is_duplicate; 425 - } 426 - 427 - /* copy primary address for bonding */ 428 - static void mark_bonding_address(struct bat_priv *bat_priv, 429 - struct orig_node *orig_node, 430 - struct orig_node *orig_neigh_node, 431 - struct batman_packet *batman_packet) 432 - 433 - { 434 - if (batman_packet->flags & PRIMARIES_FIRST_HOP) 435 - memcpy(orig_neigh_node->primary_addr, 436 - orig_node->orig, ETH_ALEN); 437 - 438 - return; 439 - } 440 - 441 - /* mark possible bond.candidates in the neighbor list */ 442 - void update_bonding_candidates(struct bat_priv *bat_priv, 443 - struct orig_node *orig_node) 444 - { 445 - int candidates; 446 - int interference_candidate; 447 - int best_tq; 448 - struct neigh_node *tmp_neigh_node, *tmp_neigh_node2; 449 - struct neigh_node *first_candidate, *last_candidate; 450 - 451 - /* update the candidates for this originator */ 452 - if (!orig_node->router) { 453 - orig_node->bond.candidates = 0; 454 - return; 455 - } 456 - 457 - best_tq = orig_node->router->tq_avg; 458 - 459 - /* update bond.candidates */ 460 - 461 - candidates = 0; 462 - 463 - /* mark other nodes which also received "PRIMARIES FIRST HOP" packets 464 - * as "bonding partner" */ 465 - 466 - /* first, zero the list */ 467 - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 468 - tmp_neigh_node->next_bond_candidate = NULL; 469 - } 470 - 471 - first_candidate = NULL; 472 - last_candidate = NULL; 473 - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 474 - 475 - /* only consider if it has the same primary address ... */ 476 - if (memcmp(orig_node->orig, 477 - tmp_neigh_node->orig_node->primary_addr, 478 - ETH_ALEN) != 0) 479 - continue; 480 - 481 - /* ... and is good enough to be considered */ 482 - if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD) 483 - continue; 484 - 485 - /* check if we have another candidate with the same 486 - * mac address or interface. If we do, we won't 487 - * select this candidate because of possible interference. */ 488 - 489 - interference_candidate = 0; 490 - list_for_each_entry(tmp_neigh_node2, 491 - &orig_node->neigh_list, list) { 492 - 493 - if (tmp_neigh_node2 == tmp_neigh_node) 494 - continue; 495 - 496 - /* we only care if the other candidate is even 497 - * considered as candidate. */ 498 - if (tmp_neigh_node2->next_bond_candidate == NULL) 499 - continue; 500 - 501 - 502 - if ((tmp_neigh_node->if_incoming == 503 - tmp_neigh_node2->if_incoming) 504 - || (memcmp(tmp_neigh_node->addr, 505 - tmp_neigh_node2->addr, ETH_ALEN) == 0)) { 506 - 507 - interference_candidate = 1; 508 - break; 509 - } 510 - } 511 - /* don't care further if it is an interference candidate */ 512 - if (interference_candidate) 513 - continue; 514 - 515 - if (first_candidate == NULL) { 516 - first_candidate = tmp_neigh_node; 517 - tmp_neigh_node->next_bond_candidate = first_candidate; 518 - } else 519 - tmp_neigh_node->next_bond_candidate = last_candidate; 520 - 521 - last_candidate = tmp_neigh_node; 522 - 523 - candidates++; 524 - } 525 - 526 - if (candidates > 0) { 527 - first_candidate->next_bond_candidate = last_candidate; 528 - orig_node->bond.selected = first_candidate; 529 - } 530 - 531 - orig_node->bond.candidates = candidates; 532 - } 533 - 534 - void receive_bat_packet(struct ethhdr *ethhdr, 535 - struct batman_packet *batman_packet, 536 - unsigned char *hna_buff, int hna_buff_len, 537 - struct batman_if *if_incoming) 538 - { 539 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 540 - struct batman_if *batman_if; 541 - struct orig_node *orig_neigh_node, *orig_node; 542 - char has_directlink_flag; 543 - char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; 544 - char is_broadcast = 0, is_bidirectional, is_single_hop_neigh; 545 - char is_duplicate; 546 - uint32_t if_incoming_seqno; 547 - 548 - /* Silently drop when the batman packet is actually not a 549 - * correct packet. 550 - * 551 - * This might happen if a packet is padded (e.g. Ethernet has a 552 - * minimum frame length of 64 byte) and the aggregation interprets 553 - * it as an additional length. 554 - * 555 - * TODO: A more sane solution would be to have a bit in the 556 - * batman_packet to detect whether the packet is the last 557 - * packet in an aggregation. Here we expect that the padding 558 - * is always zero (or not 0x01) 559 - */ 560 - if (batman_packet->packet_type != BAT_PACKET) 561 - return; 562 - 563 - /* could be changed by schedule_own_packet() */ 564 - if_incoming_seqno = atomic_read(&if_incoming->seqno); 565 - 566 - has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0); 567 - 568 - is_single_hop_neigh = (compare_orig(ethhdr->h_source, 569 - batman_packet->orig) ? 1 : 0); 570 - 571 - bat_dbg(DBG_BATMAN, bat_priv, 572 - "Received BATMAN packet via NB: %pM, IF: %s [%pM] " 573 - "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, " 574 - "TTL %d, V %d, IDF %d)\n", 575 - ethhdr->h_source, if_incoming->net_dev->name, 576 - if_incoming->net_dev->dev_addr, batman_packet->orig, 577 - batman_packet->prev_sender, batman_packet->seqno, 578 - batman_packet->tq, batman_packet->ttl, batman_packet->version, 579 - has_directlink_flag); 580 - 581 - rcu_read_lock(); 582 - list_for_each_entry_rcu(batman_if, &if_list, list) { 583 - if (batman_if->if_status != IF_ACTIVE) 584 - continue; 585 - 586 - if (batman_if->soft_iface != if_incoming->soft_iface) 587 - continue; 588 - 589 - if (compare_orig(ethhdr->h_source, 590 - batman_if->net_dev->dev_addr)) 591 - is_my_addr = 1; 592 - 593 - if (compare_orig(batman_packet->orig, 594 - batman_if->net_dev->dev_addr)) 595 - is_my_orig = 1; 596 - 597 - if (compare_orig(batman_packet->prev_sender, 598 - batman_if->net_dev->dev_addr)) 599 - is_my_oldorig = 1; 600 - 601 - if (compare_orig(ethhdr->h_source, broadcast_addr)) 602 - is_broadcast = 1; 603 - } 604 - rcu_read_unlock(); 605 - 606 - if (batman_packet->version != COMPAT_VERSION) { 607 - bat_dbg(DBG_BATMAN, bat_priv, 608 - "Drop packet: incompatible batman version (%i)\n", 609 - batman_packet->version); 610 - return; 611 - } 612 - 613 - if (is_my_addr) { 614 - bat_dbg(DBG_BATMAN, bat_priv, 615 - "Drop packet: received my own broadcast (sender: %pM" 616 - ")\n", 617 - ethhdr->h_source); 618 - return; 619 - } 620 - 621 - if (is_broadcast) { 622 - bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " 623 - "ignoring all packets with broadcast source addr (sender: %pM" 624 - ")\n", ethhdr->h_source); 625 - return; 626 - } 627 - 628 - if (is_my_orig) { 629 - TYPE_OF_WORD *word; 630 - int offset; 631 - 632 - orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source); 633 - 634 - if (!orig_neigh_node) 635 - return; 636 - 637 - /* neighbor has to indicate direct link and it has to 638 - * come via the corresponding interface */ 639 - /* if received seqno equals last send seqno save new 640 - * seqno for bidirectional check */ 641 - if (has_directlink_flag && 642 - compare_orig(if_incoming->net_dev->dev_addr, 643 - batman_packet->orig) && 644 - (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { 645 - offset = if_incoming->if_num * NUM_WORDS; 646 - word = &(orig_neigh_node->bcast_own[offset]); 647 - bit_mark(word, 0); 648 - orig_neigh_node->bcast_own_sum[if_incoming->if_num] = 649 - bit_packet_count(word); 650 - } 651 - 652 - bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " 653 - "originator packet from myself (via neighbor)\n"); 654 - return; 655 - } 656 - 657 - if (is_my_oldorig) { 658 - bat_dbg(DBG_BATMAN, bat_priv, 659 - "Drop packet: ignoring all rebroadcast echos (sender: " 660 - "%pM)\n", ethhdr->h_source); 661 - return; 662 - } 663 - 664 - orig_node = get_orig_node(bat_priv, batman_packet->orig); 665 - if (orig_node == NULL) 666 - return; 667 - 668 - is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); 669 - 670 - if (is_duplicate == -1) { 671 - bat_dbg(DBG_BATMAN, bat_priv, 672 - "Drop packet: packet within seqno protection time " 673 - "(sender: %pM)\n", ethhdr->h_source); 674 - return; 675 - } 676 - 677 - if (batman_packet->tq == 0) { 678 - bat_dbg(DBG_BATMAN, bat_priv, 679 - "Drop packet: originator packet with tq equal 0\n"); 680 - return; 681 - } 682 - 683 - /* avoid temporary routing loops */ 684 - if ((orig_node->router) && 685 - (orig_node->router->orig_node->router) && 686 - (compare_orig(orig_node->router->addr, 687 - batman_packet->prev_sender)) && 688 - !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && 689 - (compare_orig(orig_node->router->addr, 690 - orig_node->router->orig_node->router->addr))) { 691 - bat_dbg(DBG_BATMAN, bat_priv, 692 - "Drop packet: ignoring all rebroadcast packets that " 693 - "may make me loop (sender: %pM)\n", ethhdr->h_source); 694 - return; 695 - } 696 - 697 - /* if sender is a direct neighbor the sender mac equals 698 - * originator mac */ 699 - orig_neigh_node = (is_single_hop_neigh ? 700 - orig_node : 701 - get_orig_node(bat_priv, ethhdr->h_source)); 702 - if (orig_neigh_node == NULL) 703 - return; 704 - 705 - /* drop packet if sender is not a direct neighbor and if we 706 - * don't route towards it */ 707 - if (!is_single_hop_neigh && 708 - (orig_neigh_node->router == NULL)) { 709 - bat_dbg(DBG_BATMAN, bat_priv, 710 - "Drop packet: OGM via unknown neighbor!\n"); 711 - return; 712 - } 713 - 714 - is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node, 715 - batman_packet, if_incoming); 716 - 717 - /* update ranking if it is not a duplicate or has the same 718 - * seqno and similar ttl as the non-duplicate */ 719 - if (is_bidirectional && 720 - (!is_duplicate || 721 - ((orig_node->last_real_seqno == batman_packet->seqno) && 722 - (orig_node->last_ttl - 3 <= batman_packet->ttl)))) 723 - update_orig(bat_priv, orig_node, ethhdr, batman_packet, 724 - if_incoming, hna_buff, hna_buff_len, is_duplicate); 725 - 726 - mark_bonding_address(bat_priv, orig_node, 727 - orig_neigh_node, batman_packet); 728 - update_bonding_candidates(bat_priv, orig_node); 729 - 730 - /* is single hop (direct) neighbor */ 731 - if (is_single_hop_neigh) { 732 - 733 - /* mark direct link on incoming interface */ 734 - schedule_forward_packet(orig_node, ethhdr, batman_packet, 735 - 1, hna_buff_len, if_incoming); 736 - 737 - bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " 738 - "rebroadcast neighbor packet with direct link flag\n"); 739 - return; 740 - } 741 - 742 - /* multihop originator */ 743 - if (!is_bidirectional) { 744 - bat_dbg(DBG_BATMAN, bat_priv, 745 - "Drop packet: not received via bidirectional link\n"); 746 - return; 747 - } 748 - 749 - if (is_duplicate) { 750 - bat_dbg(DBG_BATMAN, bat_priv, 751 - "Drop packet: duplicate packet received\n"); 752 - return; 753 - } 754 - 755 - bat_dbg(DBG_BATMAN, bat_priv, 756 - "Forwarding packet: rebroadcast originator packet\n"); 757 - schedule_forward_packet(orig_node, ethhdr, batman_packet, 758 - 0, hna_buff_len, if_incoming); 759 - } 760 - 761 - int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) 762 - { 763 - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 764 - struct ethhdr *ethhdr; 765 - 766 - /* drop packet if it has not necessary minimum size */ 767 - if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet)))) 768 - return NET_RX_DROP; 769 - 770 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 771 - 772 - /* packet with broadcast indication but unicast recipient */ 773 - if (!is_broadcast_ether_addr(ethhdr->h_dest)) 774 - return NET_RX_DROP; 775 - 776 - /* packet with broadcast sender address */ 777 - if (is_broadcast_ether_addr(ethhdr->h_source)) 778 - return NET_RX_DROP; 779 - 780 - /* create a copy of the skb, if needed, to modify it. */ 781 - if (skb_cow(skb, 0) < 0) 782 - return NET_RX_DROP; 783 - 784 - /* keep skb linear */ 785 - if (skb_linearize(skb) < 0) 786 - return NET_RX_DROP; 787 - 788 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 789 - 790 - spin_lock_bh(&bat_priv->orig_hash_lock); 791 - receive_aggr_bat_packet(ethhdr, 792 - skb->data, 793 - skb_headlen(skb), 794 - batman_if); 795 - spin_unlock_bh(&bat_priv->orig_hash_lock); 796 - 797 - kfree_skb(skb); 798 - return NET_RX_SUCCESS; 799 - } 800 - 801 - static int recv_my_icmp_packet(struct bat_priv *bat_priv, 802 - struct sk_buff *skb, size_t icmp_len) 803 - { 804 - struct orig_node *orig_node; 805 - struct icmp_packet_rr *icmp_packet; 806 - struct ethhdr *ethhdr; 807 - struct batman_if *batman_if; 808 - int ret; 809 - uint8_t dstaddr[ETH_ALEN]; 810 - 811 - icmp_packet = (struct icmp_packet_rr *)skb->data; 812 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 813 - 814 - /* add data to device queue */ 815 - if (icmp_packet->msg_type != ECHO_REQUEST) { 816 - bat_socket_receive_packet(icmp_packet, icmp_len); 817 - return NET_RX_DROP; 818 - } 819 - 820 - if (!bat_priv->primary_if) 821 - return NET_RX_DROP; 822 - 823 - /* answer echo request (ping) */ 824 - /* get routing information */ 825 - spin_lock_bh(&bat_priv->orig_hash_lock); 826 - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, 827 - compare_orig, choose_orig, 828 - icmp_packet->orig)); 829 - ret = NET_RX_DROP; 830 - 831 - if ((orig_node != NULL) && 832 - (orig_node->router != NULL)) { 833 - 834 - /* don't lock while sending the packets ... we therefore 835 - * copy the required data before sending */ 836 - batman_if = orig_node->router->if_incoming; 837 - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 838 - spin_unlock_bh(&bat_priv->orig_hash_lock); 839 - 840 - /* create a copy of the skb, if needed, to modify it. */ 841 - if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 842 - return NET_RX_DROP; 843 - 844 - icmp_packet = (struct icmp_packet_rr *)skb->data; 845 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 846 - 847 - memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 848 - memcpy(icmp_packet->orig, 849 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 850 - icmp_packet->msg_type = ECHO_REPLY; 851 - icmp_packet->ttl = TTL; 852 - 853 - send_skb_packet(skb, batman_if, dstaddr); 854 - ret = NET_RX_SUCCESS; 855 - 856 - } else 857 - spin_unlock_bh(&bat_priv->orig_hash_lock); 858 - 859 - return ret; 860 - } 861 - 862 - static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, 863 - struct sk_buff *skb, size_t icmp_len) 864 - { 865 - struct orig_node *orig_node; 866 - struct icmp_packet *icmp_packet; 867 - struct ethhdr *ethhdr; 868 - struct batman_if *batman_if; 869 - int ret; 870 - uint8_t dstaddr[ETH_ALEN]; 871 - 872 - icmp_packet = (struct icmp_packet *)skb->data; 873 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 874 - 875 - /* send TTL exceeded if packet is an echo request (traceroute) */ 876 - if (icmp_packet->msg_type != ECHO_REQUEST) { 877 - pr_debug("Warning - can't forward icmp packet from %pM to " 878 - "%pM: ttl exceeded\n", icmp_packet->orig, 879 - icmp_packet->dst); 880 - return NET_RX_DROP; 881 - } 882 - 883 - if (!bat_priv->primary_if) 884 - return NET_RX_DROP; 885 - 886 - /* get routing information */ 887 - spin_lock_bh(&bat_priv->orig_hash_lock); 888 - orig_node = ((struct orig_node *) 889 - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, 890 - icmp_packet->orig)); 891 - ret = NET_RX_DROP; 892 - 893 - if ((orig_node != NULL) && 894 - (orig_node->router != NULL)) { 895 - 896 - /* don't lock while sending the packets ... we therefore 897 - * copy the required data before sending */ 898 - batman_if = orig_node->router->if_incoming; 899 - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 900 - spin_unlock_bh(&bat_priv->orig_hash_lock); 901 - 902 - /* create a copy of the skb, if needed, to modify it. */ 903 - if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 904 - return NET_RX_DROP; 905 - 906 - icmp_packet = (struct icmp_packet *) skb->data; 907 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 908 - 909 - memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 910 - memcpy(icmp_packet->orig, 911 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 912 - icmp_packet->msg_type = TTL_EXCEEDED; 913 - icmp_packet->ttl = TTL; 914 - 915 - send_skb_packet(skb, batman_if, dstaddr); 916 - ret = NET_RX_SUCCESS; 917 - 918 - } else 919 - spin_unlock_bh(&bat_priv->orig_hash_lock); 920 - 921 - return ret; 922 - } 923 - 924 - 925 - int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) 926 - { 927 - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 928 - struct icmp_packet_rr *icmp_packet; 929 - struct ethhdr *ethhdr; 930 - struct orig_node *orig_node; 931 - struct batman_if *batman_if; 932 - int hdr_size = sizeof(struct icmp_packet); 933 - int ret; 934 - uint8_t dstaddr[ETH_ALEN]; 935 - 936 - /** 937 - * we truncate all incoming icmp packets if they don't match our size 938 - */ 939 - if (skb->len >= sizeof(struct icmp_packet_rr)) 940 - hdr_size = sizeof(struct icmp_packet_rr); 941 - 942 - /* drop packet if it has not necessary minimum size */ 943 - if (unlikely(!pskb_may_pull(skb, hdr_size))) 944 - return NET_RX_DROP; 945 - 946 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 947 - 948 - /* packet with unicast indication but broadcast recipient */ 949 - if (is_broadcast_ether_addr(ethhdr->h_dest)) 950 - return NET_RX_DROP; 951 - 952 - /* packet with broadcast sender address */ 953 - if (is_broadcast_ether_addr(ethhdr->h_source)) 954 - return NET_RX_DROP; 955 - 956 - /* not for me */ 957 - if (!is_my_mac(ethhdr->h_dest)) 958 - return NET_RX_DROP; 959 - 960 - icmp_packet = (struct icmp_packet_rr *)skb->data; 961 - 962 - /* add record route information if not full */ 963 - if ((hdr_size == sizeof(struct icmp_packet_rr)) && 964 - (icmp_packet->rr_cur < BAT_RR_LEN)) { 965 - memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]), 966 - ethhdr->h_dest, ETH_ALEN); 967 - icmp_packet->rr_cur++; 968 - } 969 - 970 - /* packet for me */ 971 - if (is_my_mac(icmp_packet->dst)) 972 - return recv_my_icmp_packet(bat_priv, skb, hdr_size); 973 - 974 - /* TTL exceeded */ 975 - if (icmp_packet->ttl < 2) 976 - return recv_icmp_ttl_exceeded(bat_priv, skb, hdr_size); 977 - 978 - ret = NET_RX_DROP; 979 - 980 - /* get routing information */ 981 - spin_lock_bh(&bat_priv->orig_hash_lock); 982 - orig_node = ((struct orig_node *) 983 - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, 984 - icmp_packet->dst)); 985 - 986 - if ((orig_node != NULL) && 987 - (orig_node->router != NULL)) { 988 - 989 - /* don't lock while sending the packets ... we therefore 990 - * copy the required data before sending */ 991 - batman_if = orig_node->router->if_incoming; 992 - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 993 - spin_unlock_bh(&bat_priv->orig_hash_lock); 994 - 995 - /* create a copy of the skb, if needed, to modify it. */ 996 - if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 997 - return NET_RX_DROP; 998 - 999 - icmp_packet = (struct icmp_packet_rr *)skb->data; 1000 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 1001 - 1002 - /* decrement ttl */ 1003 - icmp_packet->ttl--; 1004 - 1005 - /* route it */ 1006 - send_skb_packet(skb, batman_if, dstaddr); 1007 - ret = NET_RX_SUCCESS; 1008 - 1009 - } else 1010 - spin_unlock_bh(&bat_priv->orig_hash_lock); 1011 - 1012 - return ret; 1013 - } 1014 - 1015 - /* find a suitable router for this originator, and use 1016 - * bonding if possible. */ 1017 - struct neigh_node *find_router(struct bat_priv *bat_priv, 1018 - struct orig_node *orig_node, 1019 - struct batman_if *recv_if) 1020 - { 1021 - struct orig_node *primary_orig_node; 1022 - struct orig_node *router_orig; 1023 - struct neigh_node *router, *first_candidate, *best_router; 1024 - static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; 1025 - int bonding_enabled; 1026 - 1027 - if (!orig_node) 1028 - return NULL; 1029 - 1030 - if (!orig_node->router) 1031 - return NULL; 1032 - 1033 - /* without bonding, the first node should 1034 - * always choose the default router. */ 1035 - 1036 - bonding_enabled = atomic_read(&bat_priv->bonding); 1037 - 1038 - if ((!recv_if) && (!bonding_enabled)) 1039 - return orig_node->router; 1040 - 1041 - router_orig = orig_node->router->orig_node; 1042 - 1043 - /* if we have something in the primary_addr, we can search 1044 - * for a potential bonding candidate. */ 1045 - if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0) 1046 - return orig_node->router; 1047 - 1048 - /* find the orig_node which has the primary interface. might 1049 - * even be the same as our router_orig in many cases */ 1050 - 1051 - if (memcmp(router_orig->primary_addr, 1052 - router_orig->orig, ETH_ALEN) == 0) { 1053 - primary_orig_node = router_orig; 1054 - } else { 1055 - primary_orig_node = hash_find(bat_priv->orig_hash, compare_orig, 1056 - choose_orig, 1057 - router_orig->primary_addr); 1058 - 1059 - if (!primary_orig_node) 1060 - return orig_node->router; 1061 - } 1062 - 1063 - /* with less than 2 candidates, we can't do any 1064 - * bonding and prefer the original router. */ 1065 - 1066 - if (primary_orig_node->bond.candidates < 2) 1067 - return orig_node->router; 1068 - 1069 - 1070 - /* all nodes between should choose a candidate which 1071 - * is is not on the interface where the packet came 1072 - * in. */ 1073 - first_candidate = primary_orig_node->bond.selected; 1074 - router = first_candidate; 1075 - 1076 - if (bonding_enabled) { 1077 - /* in the bonding case, send the packets in a round 1078 - * robin fashion over the remaining interfaces. */ 1079 - do { 1080 - /* recv_if == NULL on the first node. */ 1081 - if (router->if_incoming != recv_if) 1082 - break; 1083 - 1084 - router = router->next_bond_candidate; 1085 - } while (router != first_candidate); 1086 - 1087 - primary_orig_node->bond.selected = router->next_bond_candidate; 1088 - 1089 - } else { 1090 - /* if bonding is disabled, use the best of the 1091 - * remaining candidates which are not using 1092 - * this interface. */ 1093 - best_router = first_candidate; 1094 - 1095 - do { 1096 - /* recv_if == NULL on the first node. */ 1097 - if ((router->if_incoming != recv_if) && 1098 - (router->tq_avg > best_router->tq_avg)) 1099 - best_router = router; 1100 - 1101 - router = router->next_bond_candidate; 1102 - } while (router != first_candidate); 1103 - 1104 - router = best_router; 1105 - } 1106 - 1107 - return router; 1108 - } 1109 - 1110 - static int check_unicast_packet(struct sk_buff *skb, int hdr_size) 1111 - { 1112 - struct ethhdr *ethhdr; 1113 - 1114 - /* drop packet if it has not necessary minimum size */ 1115 - if (unlikely(!pskb_may_pull(skb, hdr_size))) 1116 - return -1; 1117 - 1118 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 1119 - 1120 - /* packet with unicast indication but broadcast recipient */ 1121 - if (is_broadcast_ether_addr(ethhdr->h_dest)) 1122 - return -1; 1123 - 1124 - /* packet with broadcast sender address */ 1125 - if (is_broadcast_ether_addr(ethhdr->h_source)) 1126 - return -1; 1127 - 1128 - /* not for me */ 1129 - if (!is_my_mac(ethhdr->h_dest)) 1130 - return -1; 1131 - 1132 - return 0; 1133 - } 1134 - 1135 - int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, 1136 - int hdr_size) 1137 - { 1138 - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1139 - struct orig_node *orig_node; 1140 - struct neigh_node *router; 1141 - struct batman_if *batman_if; 1142 - uint8_t dstaddr[ETH_ALEN]; 1143 - struct unicast_packet *unicast_packet; 1144 - struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); 1145 - int ret; 1146 - struct sk_buff *new_skb; 1147 - 1148 - unicast_packet = (struct unicast_packet *)skb->data; 1149 - 1150 - /* TTL exceeded */ 1151 - if (unicast_packet->ttl < 2) { 1152 - pr_debug("Warning - can't forward unicast packet from %pM to " 1153 - "%pM: ttl exceeded\n", ethhdr->h_source, 1154 - unicast_packet->dest); 1155 - return NET_RX_DROP; 1156 - } 1157 - 1158 - /* get routing information */ 1159 - spin_lock_bh(&bat_priv->orig_hash_lock); 1160 - orig_node = ((struct orig_node *) 1161 - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, 1162 - unicast_packet->dest)); 1163 - 1164 - router = find_router(bat_priv, orig_node, recv_if); 1165 - 1166 - if (!router) { 1167 - spin_unlock_bh(&bat_priv->orig_hash_lock); 1168 - return NET_RX_DROP; 1169 - } 1170 - 1171 - /* don't lock while sending the packets ... we therefore 1172 - * copy the required data before sending */ 1173 - 1174 - batman_if = router->if_incoming; 1175 - memcpy(dstaddr, router->addr, ETH_ALEN); 1176 - 1177 - spin_unlock_bh(&bat_priv->orig_hash_lock); 1178 - 1179 - /* create a copy of the skb, if needed, to modify it. */ 1180 - if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 1181 - return NET_RX_DROP; 1182 - 1183 - unicast_packet = (struct unicast_packet *)skb->data; 1184 - 1185 - if (unicast_packet->packet_type == BAT_UNICAST && 1186 - atomic_read(&bat_priv->fragmentation) && 1187 - skb->len > batman_if->net_dev->mtu) 1188 - return frag_send_skb(skb, bat_priv, batman_if, 1189 - dstaddr); 1190 - 1191 - if (unicast_packet->packet_type == BAT_UNICAST_FRAG && 1192 - 2 * skb->len - hdr_size <= batman_if->net_dev->mtu) { 1193 - 1194 - ret = frag_reassemble_skb(skb, bat_priv, &new_skb); 1195 - 1196 - if (ret == NET_RX_DROP) 1197 - return NET_RX_DROP; 1198 - 1199 - /* packet was buffered for late merge */ 1200 - if (!new_skb) 1201 - return NET_RX_SUCCESS; 1202 - 1203 - skb = new_skb; 1204 - unicast_packet = (struct unicast_packet *)skb->data; 1205 - } 1206 - 1207 - /* decrement ttl */ 1208 - unicast_packet->ttl--; 1209 - 1210 - /* route it */ 1211 - send_skb_packet(skb, batman_if, dstaddr); 1212 - 1213 - return NET_RX_SUCCESS; 1214 - } 1215 - 1216 - int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if) 1217 - { 1218 - struct unicast_packet *unicast_packet; 1219 - int hdr_size = sizeof(struct unicast_packet); 1220 - 1221 - if (check_unicast_packet(skb, hdr_size) < 0) 1222 - return NET_RX_DROP; 1223 - 1224 - unicast_packet = (struct unicast_packet *)skb->data; 1225 - 1226 - /* packet for me */ 1227 - if (is_my_mac(unicast_packet->dest)) { 1228 - interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); 1229 - return NET_RX_SUCCESS; 1230 - } 1231 - 1232 - return route_unicast_packet(skb, recv_if, hdr_size); 1233 - } 1234 - 1235 - int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) 1236 - { 1237 - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1238 - struct unicast_frag_packet *unicast_packet; 1239 - int hdr_size = sizeof(struct unicast_frag_packet); 1240 - struct sk_buff *new_skb = NULL; 1241 - int ret; 1242 - 1243 - if (check_unicast_packet(skb, hdr_size) < 0) 1244 - return NET_RX_DROP; 1245 - 1246 - unicast_packet = (struct unicast_frag_packet *)skb->data; 1247 - 1248 - /* packet for me */ 1249 - if (is_my_mac(unicast_packet->dest)) { 1250 - 1251 - ret = frag_reassemble_skb(skb, bat_priv, &new_skb); 1252 - 1253 - if (ret == NET_RX_DROP) 1254 - return NET_RX_DROP; 1255 - 1256 - /* packet was buffered for late merge */ 1257 - if (!new_skb) 1258 - return NET_RX_SUCCESS; 1259 - 1260 - interface_rx(recv_if->soft_iface, new_skb, recv_if, 1261 - sizeof(struct unicast_packet)); 1262 - return NET_RX_SUCCESS; 1263 - } 1264 - 1265 - return route_unicast_packet(skb, recv_if, hdr_size); 1266 - } 1267 - 1268 - 1269 - int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) 1270 - { 1271 - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1272 - struct orig_node *orig_node; 1273 - struct bcast_packet *bcast_packet; 1274 - struct ethhdr *ethhdr; 1275 - int hdr_size = sizeof(struct bcast_packet); 1276 - int32_t seq_diff; 1277 - 1278 - /* drop packet if it has not necessary minimum size */ 1279 - if (unlikely(!pskb_may_pull(skb, hdr_size))) 1280 - return NET_RX_DROP; 1281 - 1282 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 1283 - 1284 - /* packet with broadcast indication but unicast recipient */ 1285 - if (!is_broadcast_ether_addr(ethhdr->h_dest)) 1286 - return NET_RX_DROP; 1287 - 1288 - /* packet with broadcast sender address */ 1289 - if (is_broadcast_ether_addr(ethhdr->h_source)) 1290 - return NET_RX_DROP; 1291 - 1292 - /* ignore broadcasts sent by myself */ 1293 - if (is_my_mac(ethhdr->h_source)) 1294 - return NET_RX_DROP; 1295 - 1296 - bcast_packet = (struct bcast_packet *)skb->data; 1297 - 1298 - /* ignore broadcasts originated by myself */ 1299 - if (is_my_mac(bcast_packet->orig)) 1300 - return NET_RX_DROP; 1301 - 1302 - if (bcast_packet->ttl < 2) 1303 - return NET_RX_DROP; 1304 - 1305 - spin_lock_bh(&bat_priv->orig_hash_lock); 1306 - orig_node = ((struct orig_node *) 1307 - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, 1308 - bcast_packet->orig)); 1309 - 1310 - if (orig_node == NULL) { 1311 - spin_unlock_bh(&bat_priv->orig_hash_lock); 1312 - return NET_RX_DROP; 1313 - } 1314 - 1315 - /* check whether the packet is a duplicate */ 1316 - if (get_bit_status(orig_node->bcast_bits, 1317 - orig_node->last_bcast_seqno, 1318 - ntohl(bcast_packet->seqno))) { 1319 - spin_unlock_bh(&bat_priv->orig_hash_lock); 1320 - return NET_RX_DROP; 1321 - } 1322 - 1323 - seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno; 1324 - 1325 - /* check whether the packet is old and the host just restarted. */ 1326 - if (window_protected(bat_priv, seq_diff, 1327 - &orig_node->bcast_seqno_reset)) { 1328 - spin_unlock_bh(&bat_priv->orig_hash_lock); 1329 - return NET_RX_DROP; 1330 - } 1331 - 1332 - /* mark broadcast in flood history, update window position 1333 - * if required. */ 1334 - if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) 1335 - orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno); 1336 - 1337 - spin_unlock_bh(&bat_priv->orig_hash_lock); 1338 - /* rebroadcast packet */ 1339 - add_bcast_packet_to_list(bat_priv, skb); 1340 - 1341 - /* broadcast for me */ 1342 - interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); 1343 - 1344 - return NET_RX_SUCCESS; 1345 - } 1346 - 1347 - int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if) 1348 - { 1349 - struct vis_packet *vis_packet; 1350 - struct ethhdr *ethhdr; 1351 - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1352 - int hdr_size = sizeof(struct vis_packet); 1353 - 1354 - /* keep skb linear */ 1355 - if (skb_linearize(skb) < 0) 1356 - return NET_RX_DROP; 1357 - 1358 - if (unlikely(!pskb_may_pull(skb, hdr_size))) 1359 - return NET_RX_DROP; 1360 - 1361 - vis_packet = (struct vis_packet *)skb->data; 1362 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 1363 - 1364 - /* not for me */ 1365 - if (!is_my_mac(ethhdr->h_dest)) 1366 - return NET_RX_DROP; 1367 - 1368 - /* ignore own packets */ 1369 - if (is_my_mac(vis_packet->vis_orig)) 1370 - return NET_RX_DROP; 1371 - 1372 - if (is_my_mac(vis_packet->sender_orig)) 1373 - return NET_RX_DROP; 1374 - 1375 - switch (vis_packet->vis_type) { 1376 - case VIS_TYPE_SERVER_SYNC: 1377 - receive_server_sync_packet(bat_priv, vis_packet, 1378 - skb_headlen(skb)); 1379 - break; 1380 - 1381 - case VIS_TYPE_CLIENT_UPDATE: 1382 - receive_client_update_packet(bat_priv, vis_packet, 1383 - skb_headlen(skb)); 1384 - break; 1385 - 1386 - default: /* ignore unknown packet */ 1387 - break; 1388 - } 1389 - 1390 - /* We take a copy of the data in the packet, so we should 1391 - always free the skbuf. */ 1392 - return NET_RX_DROP; 1393 - }
-48
drivers/staging/batman-adv/routing.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_ROUTING_H_ 23 - #define _NET_BATMAN_ADV_ROUTING_H_ 24 - 25 - #include "types.h" 26 - 27 - void slide_own_bcast_window(struct batman_if *batman_if); 28 - void receive_bat_packet(struct ethhdr *ethhdr, 29 - struct batman_packet *batman_packet, 30 - unsigned char *hna_buff, int hna_buff_len, 31 - struct batman_if *if_incoming); 32 - void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, 33 - struct neigh_node *neigh_node, unsigned char *hna_buff, 34 - int hna_buff_len); 35 - int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, 36 - int hdr_size); 37 - int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if); 38 - int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if); 39 - int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if); 40 - int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if); 41 - int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if); 42 - int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if); 43 - struct neigh_node *find_router(struct bat_priv *bat_priv, 44 - struct orig_node *orig_node, struct batman_if *recv_if); 45 - void update_bonding_candidates(struct bat_priv *bat_priv, 46 - struct orig_node *orig_node); 47 - 48 - #endif /* _NET_BATMAN_ADV_ROUTING_H_ */
-586
drivers/staging/batman-adv/send.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "send.h" 24 - #include "routing.h" 25 - #include "translation-table.h" 26 - #include "soft-interface.h" 27 - #include "hard-interface.h" 28 - #include "types.h" 29 - #include "vis.h" 30 - #include "aggregation.h" 31 - #include "gateway_common.h" 32 - #include "originator.h" 33 - 34 - 35 - static void send_outstanding_bcast_packet(struct work_struct *work); 36 - 37 - /* apply hop penalty for a normal link */ 38 - static uint8_t hop_penalty(const uint8_t tq, struct bat_priv *bat_priv) 39 - { 40 - int hop_penalty = atomic_read(&bat_priv->hop_penalty); 41 - return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); 42 - } 43 - 44 - /* when do we schedule our own packet to be sent */ 45 - static unsigned long own_send_time(struct bat_priv *bat_priv) 46 - { 47 - return jiffies + msecs_to_jiffies( 48 - atomic_read(&bat_priv->orig_interval) - 49 - JITTER + (random32() % 2*JITTER)); 50 - } 51 - 52 - /* when do we schedule a forwarded packet to be sent */ 53 - static unsigned long forward_send_time(struct bat_priv *bat_priv) 54 - { 55 - return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); 56 - } 57 - 58 - /* send out an already prepared packet to the given address via the 59 - * specified batman interface */ 60 - int send_skb_packet(struct sk_buff *skb, 61 - struct batman_if *batman_if, 62 - uint8_t *dst_addr) 63 - { 64 - struct ethhdr *ethhdr; 65 - 66 - if (batman_if->if_status != IF_ACTIVE) 67 - goto send_skb_err; 68 - 69 - if (unlikely(!batman_if->net_dev)) 70 - goto send_skb_err; 71 - 72 - if (!(batman_if->net_dev->flags & IFF_UP)) { 73 - pr_warning("Interface %s is not up - can't send packet via " 74 - "that interface!\n", batman_if->net_dev->name); 75 - goto send_skb_err; 76 - } 77 - 78 - /* push to the ethernet header. */ 79 - if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0) 80 - goto send_skb_err; 81 - 82 - skb_reset_mac_header(skb); 83 - 84 - ethhdr = (struct ethhdr *) skb_mac_header(skb); 85 - memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN); 86 - memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); 87 - ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); 88 - 89 - skb_set_network_header(skb, ETH_HLEN); 90 - skb->priority = TC_PRIO_CONTROL; 91 - skb->protocol = __constant_htons(ETH_P_BATMAN); 92 - 93 - skb->dev = batman_if->net_dev; 94 - 95 - /* dev_queue_xmit() returns a negative result on error. However on 96 - * congestion and traffic shaping, it drops and returns NET_XMIT_DROP 97 - * (which is > 0). This will not be treated as an error. */ 98 - 99 - return dev_queue_xmit(skb); 100 - send_skb_err: 101 - kfree_skb(skb); 102 - return NET_XMIT_DROP; 103 - } 104 - 105 - /* Send a packet to a given interface */ 106 - static void send_packet_to_if(struct forw_packet *forw_packet, 107 - struct batman_if *batman_if) 108 - { 109 - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 110 - char *fwd_str; 111 - uint8_t packet_num; 112 - int16_t buff_pos; 113 - struct batman_packet *batman_packet; 114 - struct sk_buff *skb; 115 - 116 - if (batman_if->if_status != IF_ACTIVE) 117 - return; 118 - 119 - packet_num = 0; 120 - buff_pos = 0; 121 - batman_packet = (struct batman_packet *)forw_packet->skb->data; 122 - 123 - /* adjust all flags and log packets */ 124 - while (aggregated_packet(buff_pos, 125 - forw_packet->packet_len, 126 - batman_packet->num_hna)) { 127 - 128 - /* we might have aggregated direct link packets with an 129 - * ordinary base packet */ 130 - if ((forw_packet->direct_link_flags & (1 << packet_num)) && 131 - (forw_packet->if_incoming == batman_if)) 132 - batman_packet->flags |= DIRECTLINK; 133 - else 134 - batman_packet->flags &= ~DIRECTLINK; 135 - 136 - fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? 137 - "Sending own" : 138 - "Forwarding")); 139 - bat_dbg(DBG_BATMAN, bat_priv, 140 - "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," 141 - " IDF %s) on interface %s [%pM]\n", 142 - fwd_str, (packet_num > 0 ? "aggregated " : ""), 143 - batman_packet->orig, ntohl(batman_packet->seqno), 144 - batman_packet->tq, batman_packet->ttl, 145 - (batman_packet->flags & DIRECTLINK ? 146 - "on" : "off"), 147 - batman_if->net_dev->name, batman_if->net_dev->dev_addr); 148 - 149 - buff_pos += sizeof(struct batman_packet) + 150 - (batman_packet->num_hna * ETH_ALEN); 151 - packet_num++; 152 - batman_packet = (struct batman_packet *) 153 - (forw_packet->skb->data + buff_pos); 154 - } 155 - 156 - /* create clone because function is called more than once */ 157 - skb = skb_clone(forw_packet->skb, GFP_ATOMIC); 158 - if (skb) 159 - send_skb_packet(skb, batman_if, broadcast_addr); 160 - } 161 - 162 - /* send a batman packet */ 163 - static void send_packet(struct forw_packet *forw_packet) 164 - { 165 - struct batman_if *batman_if; 166 - struct net_device *soft_iface; 167 - struct bat_priv *bat_priv; 168 - struct batman_packet *batman_packet = 169 - (struct batman_packet *)(forw_packet->skb->data); 170 - unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); 171 - 172 - if (!forw_packet->if_incoming) { 173 - pr_err("Error - can't forward packet: incoming iface not " 174 - "specified\n"); 175 - return; 176 - } 177 - 178 - soft_iface = forw_packet->if_incoming->soft_iface; 179 - bat_priv = netdev_priv(soft_iface); 180 - 181 - if (forw_packet->if_incoming->if_status != IF_ACTIVE) 182 - return; 183 - 184 - /* multihomed peer assumed */ 185 - /* non-primary OGMs are only broadcasted on their interface */ 186 - if ((directlink && (batman_packet->ttl == 1)) || 187 - (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) { 188 - 189 - /* FIXME: what about aggregated packets ? */ 190 - bat_dbg(DBG_BATMAN, bat_priv, 191 - "%s packet (originator %pM, seqno %d, TTL %d) " 192 - "on interface %s [%pM]\n", 193 - (forw_packet->own ? "Sending own" : "Forwarding"), 194 - batman_packet->orig, ntohl(batman_packet->seqno), 195 - batman_packet->ttl, 196 - forw_packet->if_incoming->net_dev->name, 197 - forw_packet->if_incoming->net_dev->dev_addr); 198 - 199 - /* skb is only used once and than forw_packet is free'd */ 200 - send_skb_packet(forw_packet->skb, forw_packet->if_incoming, 201 - broadcast_addr); 202 - forw_packet->skb = NULL; 203 - 204 - return; 205 - } 206 - 207 - /* broadcast on every interface */ 208 - rcu_read_lock(); 209 - list_for_each_entry_rcu(batman_if, &if_list, list) { 210 - if (batman_if->soft_iface != soft_iface) 211 - continue; 212 - 213 - send_packet_to_if(forw_packet, batman_if); 214 - } 215 - rcu_read_unlock(); 216 - } 217 - 218 - static void rebuild_batman_packet(struct bat_priv *bat_priv, 219 - struct batman_if *batman_if) 220 - { 221 - int new_len; 222 - unsigned char *new_buff; 223 - struct batman_packet *batman_packet; 224 - 225 - new_len = sizeof(struct batman_packet) + 226 - (bat_priv->num_local_hna * ETH_ALEN); 227 - new_buff = kmalloc(new_len, GFP_ATOMIC); 228 - 229 - /* keep old buffer if kmalloc should fail */ 230 - if (new_buff) { 231 - memcpy(new_buff, batman_if->packet_buff, 232 - sizeof(struct batman_packet)); 233 - batman_packet = (struct batman_packet *)new_buff; 234 - 235 - batman_packet->num_hna = hna_local_fill_buffer(bat_priv, 236 - new_buff + sizeof(struct batman_packet), 237 - new_len - sizeof(struct batman_packet)); 238 - 239 - kfree(batman_if->packet_buff); 240 - batman_if->packet_buff = new_buff; 241 - batman_if->packet_len = new_len; 242 - } 243 - } 244 - 245 - void schedule_own_packet(struct batman_if *batman_if) 246 - { 247 - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 248 - unsigned long send_time; 249 - struct batman_packet *batman_packet; 250 - int vis_server; 251 - 252 - if ((batman_if->if_status == IF_NOT_IN_USE) || 253 - (batman_if->if_status == IF_TO_BE_REMOVED)) 254 - return; 255 - 256 - vis_server = atomic_read(&bat_priv->vis_mode); 257 - 258 - /** 259 - * the interface gets activated here to avoid race conditions between 260 - * the moment of activating the interface in 261 - * hardif_activate_interface() where the originator mac is set and 262 - * outdated packets (especially uninitialized mac addresses) in the 263 - * packet queue 264 - */ 265 - if (batman_if->if_status == IF_TO_BE_ACTIVATED) 266 - batman_if->if_status = IF_ACTIVE; 267 - 268 - /* if local hna has changed and interface is a primary interface */ 269 - if ((atomic_read(&bat_priv->hna_local_changed)) && 270 - (batman_if == bat_priv->primary_if)) 271 - rebuild_batman_packet(bat_priv, batman_if); 272 - 273 - /** 274 - * NOTE: packet_buff might just have been re-allocated in 275 - * rebuild_batman_packet() 276 - */ 277 - batman_packet = (struct batman_packet *)batman_if->packet_buff; 278 - 279 - /* change sequence number to network order */ 280 - batman_packet->seqno = 281 - htonl((uint32_t)atomic_read(&batman_if->seqno)); 282 - 283 - if (vis_server == VIS_TYPE_SERVER_SYNC) 284 - batman_packet->flags |= VIS_SERVER; 285 - else 286 - batman_packet->flags &= ~VIS_SERVER; 287 - 288 - if ((batman_if == bat_priv->primary_if) && 289 - (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) 290 - batman_packet->gw_flags = 291 - (uint8_t)atomic_read(&bat_priv->gw_bandwidth); 292 - else 293 - batman_packet->gw_flags = 0; 294 - 295 - atomic_inc(&batman_if->seqno); 296 - 297 - slide_own_bcast_window(batman_if); 298 - send_time = own_send_time(bat_priv); 299 - add_bat_packet_to_list(bat_priv, 300 - batman_if->packet_buff, 301 - batman_if->packet_len, 302 - batman_if, 1, send_time); 303 - } 304 - 305 - void schedule_forward_packet(struct orig_node *orig_node, 306 - struct ethhdr *ethhdr, 307 - struct batman_packet *batman_packet, 308 - uint8_t directlink, int hna_buff_len, 309 - struct batman_if *if_incoming) 310 - { 311 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 312 - unsigned char in_tq, in_ttl, tq_avg = 0; 313 - unsigned long send_time; 314 - 315 - if (batman_packet->ttl <= 1) { 316 - bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n"); 317 - return; 318 - } 319 - 320 - in_tq = batman_packet->tq; 321 - in_ttl = batman_packet->ttl; 322 - 323 - batman_packet->ttl--; 324 - memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN); 325 - 326 - /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast 327 - * of our best tq value */ 328 - if ((orig_node->router) && (orig_node->router->tq_avg != 0)) { 329 - 330 - /* rebroadcast ogm of best ranking neighbor as is */ 331 - if (!compare_orig(orig_node->router->addr, ethhdr->h_source)) { 332 - batman_packet->tq = orig_node->router->tq_avg; 333 - 334 - if (orig_node->router->last_ttl) 335 - batman_packet->ttl = orig_node->router->last_ttl 336 - - 1; 337 - } 338 - 339 - tq_avg = orig_node->router->tq_avg; 340 - } 341 - 342 - /* apply hop penalty */ 343 - batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv); 344 - 345 - bat_dbg(DBG_BATMAN, bat_priv, 346 - "Forwarding packet: tq_orig: %i, tq_avg: %i, " 347 - "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", 348 - in_tq, tq_avg, batman_packet->tq, in_ttl - 1, 349 - batman_packet->ttl); 350 - 351 - batman_packet->seqno = htonl(batman_packet->seqno); 352 - 353 - /* switch of primaries first hop flag when forwarding */ 354 - batman_packet->flags &= ~PRIMARIES_FIRST_HOP; 355 - if (directlink) 356 - batman_packet->flags |= DIRECTLINK; 357 - else 358 - batman_packet->flags &= ~DIRECTLINK; 359 - 360 - send_time = forward_send_time(bat_priv); 361 - add_bat_packet_to_list(bat_priv, 362 - (unsigned char *)batman_packet, 363 - sizeof(struct batman_packet) + hna_buff_len, 364 - if_incoming, 0, send_time); 365 - } 366 - 367 - static void forw_packet_free(struct forw_packet *forw_packet) 368 - { 369 - if (forw_packet->skb) 370 - kfree_skb(forw_packet->skb); 371 - kfree(forw_packet); 372 - } 373 - 374 - static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, 375 - struct forw_packet *forw_packet, 376 - unsigned long send_time) 377 - { 378 - INIT_HLIST_NODE(&forw_packet->list); 379 - 380 - /* add new packet to packet list */ 381 - spin_lock_bh(&bat_priv->forw_bcast_list_lock); 382 - hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list); 383 - spin_unlock_bh(&bat_priv->forw_bcast_list_lock); 384 - 385 - /* start timer for this packet */ 386 - INIT_DELAYED_WORK(&forw_packet->delayed_work, 387 - send_outstanding_bcast_packet); 388 - queue_delayed_work(bat_event_workqueue, &forw_packet->delayed_work, 389 - send_time); 390 - } 391 - 392 - #define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) 393 - /* add a broadcast packet to the queue and setup timers. broadcast packets 394 - * are sent multiple times to increase probability for beeing received. 395 - * 396 - * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on 397 - * errors. 398 - * 399 - * The skb is not consumed, so the caller should make sure that the 400 - * skb is freed. */ 401 - int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb) 402 - { 403 - struct forw_packet *forw_packet; 404 - struct bcast_packet *bcast_packet; 405 - 406 - if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) { 407 - bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n"); 408 - goto out; 409 - } 410 - 411 - if (!bat_priv->primary_if) 412 - goto out; 413 - 414 - forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); 415 - 416 - if (!forw_packet) 417 - goto out_and_inc; 418 - 419 - skb = skb_copy(skb, GFP_ATOMIC); 420 - if (!skb) 421 - goto packet_free; 422 - 423 - /* as we have a copy now, it is safe to decrease the TTL */ 424 - bcast_packet = (struct bcast_packet *)skb->data; 425 - bcast_packet->ttl--; 426 - 427 - skb_reset_mac_header(skb); 428 - 429 - forw_packet->skb = skb; 430 - forw_packet->if_incoming = bat_priv->primary_if; 431 - 432 - /* how often did we send the bcast packet ? */ 433 - forw_packet->num_packets = 0; 434 - 435 - _add_bcast_packet_to_list(bat_priv, forw_packet, 1); 436 - return NETDEV_TX_OK; 437 - 438 - packet_free: 439 - kfree(forw_packet); 440 - out_and_inc: 441 - atomic_inc(&bat_priv->bcast_queue_left); 442 - out: 443 - return NETDEV_TX_BUSY; 444 - } 445 - 446 - static void send_outstanding_bcast_packet(struct work_struct *work) 447 - { 448 - struct batman_if *batman_if; 449 - struct delayed_work *delayed_work = 450 - container_of(work, struct delayed_work, work); 451 - struct forw_packet *forw_packet = 452 - container_of(delayed_work, struct forw_packet, delayed_work); 453 - struct sk_buff *skb1; 454 - struct net_device *soft_iface = forw_packet->if_incoming->soft_iface; 455 - struct bat_priv *bat_priv = netdev_priv(soft_iface); 456 - 457 - spin_lock_bh(&bat_priv->forw_bcast_list_lock); 458 - hlist_del(&forw_packet->list); 459 - spin_unlock_bh(&bat_priv->forw_bcast_list_lock); 460 - 461 - if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) 462 - goto out; 463 - 464 - /* rebroadcast packet */ 465 - rcu_read_lock(); 466 - list_for_each_entry_rcu(batman_if, &if_list, list) { 467 - if (batman_if->soft_iface != soft_iface) 468 - continue; 469 - 470 - /* send a copy of the saved skb */ 471 - skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); 472 - if (skb1) 473 - send_skb_packet(skb1, batman_if, broadcast_addr); 474 - } 475 - rcu_read_unlock(); 476 - 477 - forw_packet->num_packets++; 478 - 479 - /* if we still have some more bcasts to send */ 480 - if (forw_packet->num_packets < 3) { 481 - _add_bcast_packet_to_list(bat_priv, forw_packet, 482 - ((5 * HZ) / 1000)); 483 - return; 484 - } 485 - 486 - out: 487 - forw_packet_free(forw_packet); 488 - atomic_inc(&bat_priv->bcast_queue_left); 489 - } 490 - 491 - void send_outstanding_bat_packet(struct work_struct *work) 492 - { 493 - struct delayed_work *delayed_work = 494 - container_of(work, struct delayed_work, work); 495 - struct forw_packet *forw_packet = 496 - container_of(delayed_work, struct forw_packet, delayed_work); 497 - struct bat_priv *bat_priv; 498 - 499 - bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); 500 - spin_lock_bh(&bat_priv->forw_bat_list_lock); 501 - hlist_del(&forw_packet->list); 502 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 503 - 504 - if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) 505 - goto out; 506 - 507 - send_packet(forw_packet); 508 - 509 - /** 510 - * we have to have at least one packet in the queue 511 - * to determine the queues wake up time unless we are 512 - * shutting down 513 - */ 514 - if (forw_packet->own) 515 - schedule_own_packet(forw_packet->if_incoming); 516 - 517 - out: 518 - /* don't count own packet */ 519 - if (!forw_packet->own) 520 - atomic_inc(&bat_priv->batman_queue_left); 521 - 522 - forw_packet_free(forw_packet); 523 - } 524 - 525 - void purge_outstanding_packets(struct bat_priv *bat_priv, 526 - struct batman_if *batman_if) 527 - { 528 - struct forw_packet *forw_packet; 529 - struct hlist_node *tmp_node, *safe_tmp_node; 530 - 531 - if (batman_if) 532 - bat_dbg(DBG_BATMAN, bat_priv, 533 - "purge_outstanding_packets(): %s\n", 534 - batman_if->net_dev->name); 535 - else 536 - bat_dbg(DBG_BATMAN, bat_priv, 537 - "purge_outstanding_packets()\n"); 538 - 539 - /* free bcast list */ 540 - spin_lock_bh(&bat_priv->forw_bcast_list_lock); 541 - hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, 542 - &bat_priv->forw_bcast_list, list) { 543 - 544 - /** 545 - * if purge_outstanding_packets() was called with an argmument 546 - * we delete only packets belonging to the given interface 547 - */ 548 - if ((batman_if) && 549 - (forw_packet->if_incoming != batman_if)) 550 - continue; 551 - 552 - spin_unlock_bh(&bat_priv->forw_bcast_list_lock); 553 - 554 - /** 555 - * send_outstanding_bcast_packet() will lock the list to 556 - * delete the item from the list 557 - */ 558 - cancel_delayed_work_sync(&forw_packet->delayed_work); 559 - spin_lock_bh(&bat_priv->forw_bcast_list_lock); 560 - } 561 - spin_unlock_bh(&bat_priv->forw_bcast_list_lock); 562 - 563 - /* free batman packet list */ 564 - spin_lock_bh(&bat_priv->forw_bat_list_lock); 565 - hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, 566 - &bat_priv->forw_bat_list, list) { 567 - 568 - /** 569 - * if purge_outstanding_packets() was called with an argmument 570 - * we delete only packets belonging to the given interface 571 - */ 572 - if ((batman_if) && 573 - (forw_packet->if_incoming != batman_if)) 574 - continue; 575 - 576 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 577 - 578 - /** 579 - * send_outstanding_bat_packet() will lock the list to 580 - * delete the item from the list 581 - */ 582 - cancel_delayed_work_sync(&forw_packet->delayed_work); 583 - spin_lock_bh(&bat_priv->forw_bat_list_lock); 584 - } 585 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 586 - }
-41
drivers/staging/batman-adv/send.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_SEND_H_ 23 - #define _NET_BATMAN_ADV_SEND_H_ 24 - 25 - #include "types.h" 26 - 27 - int send_skb_packet(struct sk_buff *skb, 28 - struct batman_if *batman_if, 29 - uint8_t *dst_addr); 30 - void schedule_own_packet(struct batman_if *batman_if); 31 - void schedule_forward_packet(struct orig_node *orig_node, 32 - struct ethhdr *ethhdr, 33 - struct batman_packet *batman_packet, 34 - uint8_t directlink, int hna_buff_len, 35 - struct batman_if *if_outgoing); 36 - int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb); 37 - void send_outstanding_bat_packet(struct work_struct *work); 38 - void purge_outstanding_packets(struct bat_priv *bat_priv, 39 - struct batman_if *batman_if); 40 - 41 - #endif /* _NET_BATMAN_ADV_SEND_H_ */
-697
drivers/staging/batman-adv/soft-interface.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "soft-interface.h" 24 - #include "hard-interface.h" 25 - #include "routing.h" 26 - #include "send.h" 27 - #include "bat_debugfs.h" 28 - #include "translation-table.h" 29 - #include "types.h" 30 - #include "hash.h" 31 - #include "gateway_common.h" 32 - #include "gateway_client.h" 33 - #include "send.h" 34 - #include "bat_sysfs.h" 35 - #include <linux/slab.h> 36 - #include <linux/ethtool.h> 37 - #include <linux/etherdevice.h> 38 - #include <linux/if_vlan.h> 39 - #include "unicast.h" 40 - #include "routing.h" 41 - 42 - 43 - static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); 44 - static void bat_get_drvinfo(struct net_device *dev, 45 - struct ethtool_drvinfo *info); 46 - static u32 bat_get_msglevel(struct net_device *dev); 47 - static void bat_set_msglevel(struct net_device *dev, u32 value); 48 - static u32 bat_get_link(struct net_device *dev); 49 - static u32 bat_get_rx_csum(struct net_device *dev); 50 - static int bat_set_rx_csum(struct net_device *dev, u32 data); 51 - 52 - static const struct ethtool_ops bat_ethtool_ops = { 53 - .get_settings = bat_get_settings, 54 - .get_drvinfo = bat_get_drvinfo, 55 - .get_msglevel = bat_get_msglevel, 56 - .set_msglevel = bat_set_msglevel, 57 - .get_link = bat_get_link, 58 - .get_rx_csum = bat_get_rx_csum, 59 - .set_rx_csum = bat_set_rx_csum 60 - }; 61 - 62 - int my_skb_head_push(struct sk_buff *skb, unsigned int len) 63 - { 64 - int result; 65 - 66 - /** 67 - * TODO: We must check if we can release all references to non-payload 68 - * data using skb_header_release in our skbs to allow skb_cow_header to 69 - * work optimally. This means that those skbs are not allowed to read 70 - * or write any data which is before the current position of skb->data 71 - * after that call and thus allow other skbs with the same data buffer 72 - * to write freely in that area. 73 - */ 74 - result = skb_cow_head(skb, len); 75 - if (result < 0) 76 - return result; 77 - 78 - skb_push(skb, len); 79 - return 0; 80 - } 81 - 82 - static void softif_neigh_free_ref(struct kref *refcount) 83 - { 84 - struct softif_neigh *softif_neigh; 85 - 86 - softif_neigh = container_of(refcount, struct softif_neigh, refcount); 87 - kfree(softif_neigh); 88 - } 89 - 90 - static void softif_neigh_free_rcu(struct rcu_head *rcu) 91 - { 92 - struct softif_neigh *softif_neigh; 93 - 94 - softif_neigh = container_of(rcu, struct softif_neigh, rcu); 95 - kref_put(&softif_neigh->refcount, softif_neigh_free_ref); 96 - } 97 - 98 - void softif_neigh_purge(struct bat_priv *bat_priv) 99 - { 100 - struct softif_neigh *softif_neigh, *softif_neigh_tmp; 101 - struct hlist_node *node, *node_tmp; 102 - 103 - spin_lock_bh(&bat_priv->softif_neigh_lock); 104 - 105 - hlist_for_each_entry_safe(softif_neigh, node, node_tmp, 106 - &bat_priv->softif_neigh_list, list) { 107 - 108 - if ((!time_after(jiffies, softif_neigh->last_seen + 109 - msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) && 110 - (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)) 111 - continue; 112 - 113 - hlist_del_rcu(&softif_neigh->list); 114 - 115 - if (bat_priv->softif_neigh == softif_neigh) { 116 - bat_dbg(DBG_ROUTES, bat_priv, 117 - "Current mesh exit point '%pM' vanished " 118 - "(vid: %d).\n", 119 - softif_neigh->addr, softif_neigh->vid); 120 - softif_neigh_tmp = bat_priv->softif_neigh; 121 - bat_priv->softif_neigh = NULL; 122 - kref_put(&softif_neigh_tmp->refcount, 123 - softif_neigh_free_ref); 124 - } 125 - 126 - call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); 127 - } 128 - 129 - spin_unlock_bh(&bat_priv->softif_neigh_lock); 130 - } 131 - 132 - static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, 133 - uint8_t *addr, short vid) 134 - { 135 - struct softif_neigh *softif_neigh; 136 - struct hlist_node *node; 137 - 138 - rcu_read_lock(); 139 - hlist_for_each_entry_rcu(softif_neigh, node, 140 - &bat_priv->softif_neigh_list, list) { 141 - if (memcmp(softif_neigh->addr, addr, ETH_ALEN) != 0) 142 - continue; 143 - 144 - if (softif_neigh->vid != vid) 145 - continue; 146 - 147 - softif_neigh->last_seen = jiffies; 148 - goto found; 149 - } 150 - 151 - softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC); 152 - if (!softif_neigh) 153 - goto out; 154 - 155 - memcpy(softif_neigh->addr, addr, ETH_ALEN); 156 - softif_neigh->vid = vid; 157 - softif_neigh->last_seen = jiffies; 158 - kref_init(&softif_neigh->refcount); 159 - 160 - INIT_HLIST_NODE(&softif_neigh->list); 161 - spin_lock_bh(&bat_priv->softif_neigh_lock); 162 - hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list); 163 - spin_unlock_bh(&bat_priv->softif_neigh_lock); 164 - 165 - found: 166 - kref_get(&softif_neigh->refcount); 167 - out: 168 - rcu_read_unlock(); 169 - return softif_neigh; 170 - } 171 - 172 - int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) 173 - { 174 - struct net_device *net_dev = (struct net_device *)seq->private; 175 - struct bat_priv *bat_priv = netdev_priv(net_dev); 176 - struct softif_neigh *softif_neigh; 177 - struct hlist_node *node; 178 - size_t buf_size, pos; 179 - char *buff; 180 - 181 - if (!bat_priv->primary_if) { 182 - return seq_printf(seq, "BATMAN mesh %s disabled - " 183 - "please specify interfaces to enable it\n", 184 - net_dev->name); 185 - } 186 - 187 - seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); 188 - 189 - buf_size = 1; 190 - /* Estimate length for: " xx:xx:xx:xx:xx:xx\n" */ 191 - rcu_read_lock(); 192 - hlist_for_each_entry_rcu(softif_neigh, node, 193 - &bat_priv->softif_neigh_list, list) 194 - buf_size += 30; 195 - rcu_read_unlock(); 196 - 197 - buff = kmalloc(buf_size, GFP_ATOMIC); 198 - if (!buff) 199 - return -ENOMEM; 200 - 201 - buff[0] = '\0'; 202 - pos = 0; 203 - 204 - rcu_read_lock(); 205 - hlist_for_each_entry_rcu(softif_neigh, node, 206 - &bat_priv->softif_neigh_list, list) { 207 - pos += snprintf(buff + pos, 31, "%s %pM (vid: %d)\n", 208 - bat_priv->softif_neigh == softif_neigh 209 - ? "=>" : " ", softif_neigh->addr, 210 - softif_neigh->vid); 211 - } 212 - rcu_read_unlock(); 213 - 214 - seq_printf(seq, "%s", buff); 215 - kfree(buff); 216 - return 0; 217 - } 218 - 219 - static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, 220 - short vid) 221 - { 222 - struct bat_priv *bat_priv = netdev_priv(dev); 223 - struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 224 - struct batman_packet *batman_packet; 225 - struct softif_neigh *softif_neigh, *softif_neigh_tmp; 226 - 227 - if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) 228 - batman_packet = (struct batman_packet *) 229 - (skb->data + ETH_HLEN + VLAN_HLEN); 230 - else 231 - batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN); 232 - 233 - if (batman_packet->version != COMPAT_VERSION) 234 - goto err; 235 - 236 - if (batman_packet->packet_type != BAT_PACKET) 237 - goto err; 238 - 239 - if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) 240 - goto err; 241 - 242 - if (is_my_mac(batman_packet->orig)) 243 - goto err; 244 - 245 - softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid); 246 - 247 - if (!softif_neigh) 248 - goto err; 249 - 250 - if (bat_priv->softif_neigh == softif_neigh) 251 - goto out; 252 - 253 - /* we got a neighbor but its mac is 'bigger' than ours */ 254 - if (memcmp(bat_priv->primary_if->net_dev->dev_addr, 255 - softif_neigh->addr, ETH_ALEN) < 0) 256 - goto out; 257 - 258 - /* switch to new 'smallest neighbor' */ 259 - if ((bat_priv->softif_neigh) && 260 - (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr, 261 - ETH_ALEN) < 0)) { 262 - bat_dbg(DBG_ROUTES, bat_priv, 263 - "Changing mesh exit point from %pM (vid: %d) " 264 - "to %pM (vid: %d).\n", 265 - bat_priv->softif_neigh->addr, 266 - bat_priv->softif_neigh->vid, 267 - softif_neigh->addr, softif_neigh->vid); 268 - softif_neigh_tmp = bat_priv->softif_neigh; 269 - bat_priv->softif_neigh = softif_neigh; 270 - kref_put(&softif_neigh_tmp->refcount, softif_neigh_free_ref); 271 - /* we need to hold the additional reference */ 272 - goto err; 273 - } 274 - 275 - /* close own batX device and use softif_neigh as exit node */ 276 - if ((!bat_priv->softif_neigh) && 277 - (memcmp(softif_neigh->addr, 278 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) { 279 - bat_dbg(DBG_ROUTES, bat_priv, 280 - "Setting mesh exit point to %pM (vid: %d).\n", 281 - softif_neigh->addr, softif_neigh->vid); 282 - bat_priv->softif_neigh = softif_neigh; 283 - /* we need to hold the additional reference */ 284 - goto err; 285 - } 286 - 287 - out: 288 - kref_put(&softif_neigh->refcount, softif_neigh_free_ref); 289 - err: 290 - kfree_skb(skb); 291 - return; 292 - } 293 - 294 - static int interface_open(struct net_device *dev) 295 - { 296 - netif_start_queue(dev); 297 - return 0; 298 - } 299 - 300 - static int interface_release(struct net_device *dev) 301 - { 302 - netif_stop_queue(dev); 303 - return 0; 304 - } 305 - 306 - static struct net_device_stats *interface_stats(struct net_device *dev) 307 - { 308 - struct bat_priv *bat_priv = netdev_priv(dev); 309 - return &bat_priv->stats; 310 - } 311 - 312 - static int interface_set_mac_addr(struct net_device *dev, void *p) 313 - { 314 - struct bat_priv *bat_priv = netdev_priv(dev); 315 - struct sockaddr *addr = p; 316 - 317 - if (!is_valid_ether_addr(addr->sa_data)) 318 - return -EADDRNOTAVAIL; 319 - 320 - /* only modify hna-table if it has been initialised before */ 321 - if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) { 322 - hna_local_remove(bat_priv, dev->dev_addr, 323 - "mac address changed"); 324 - hna_local_add(dev, addr->sa_data); 325 - } 326 - 327 - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 328 - return 0; 329 - } 330 - 331 - static int interface_change_mtu(struct net_device *dev, int new_mtu) 332 - { 333 - /* check ranges */ 334 - if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev))) 335 - return -EINVAL; 336 - 337 - dev->mtu = new_mtu; 338 - 339 - return 0; 340 - } 341 - 342 - int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) 343 - { 344 - struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 345 - struct bat_priv *bat_priv = netdev_priv(soft_iface); 346 - struct bcast_packet *bcast_packet; 347 - struct vlan_ethhdr *vhdr; 348 - int data_len = skb->len, ret; 349 - short vid = -1; 350 - bool do_bcast = false; 351 - 352 - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) 353 - goto dropped; 354 - 355 - soft_iface->trans_start = jiffies; 356 - 357 - switch (ntohs(ethhdr->h_proto)) { 358 - case ETH_P_8021Q: 359 - vhdr = (struct vlan_ethhdr *)skb->data; 360 - vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; 361 - 362 - if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) 363 - break; 364 - 365 - /* fall through */ 366 - case ETH_P_BATMAN: 367 - softif_batman_recv(skb, soft_iface, vid); 368 - goto end; 369 - } 370 - 371 - /** 372 - * if we have a another chosen mesh exit node in range 373 - * it will transport the packets to the mesh 374 - */ 375 - if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) 376 - goto dropped; 377 - 378 - /* TODO: check this for locks */ 379 - hna_local_add(soft_iface, ethhdr->h_source); 380 - 381 - if (is_multicast_ether_addr(ethhdr->h_dest)) { 382 - ret = gw_is_target(bat_priv, skb); 383 - 384 - if (ret < 0) 385 - goto dropped; 386 - 387 - if (ret == 0) 388 - do_bcast = true; 389 - } 390 - 391 - /* ethernet packet should be broadcasted */ 392 - if (do_bcast) { 393 - if (!bat_priv->primary_if) 394 - goto dropped; 395 - 396 - if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0) 397 - goto dropped; 398 - 399 - bcast_packet = (struct bcast_packet *)skb->data; 400 - bcast_packet->version = COMPAT_VERSION; 401 - bcast_packet->ttl = TTL; 402 - 403 - /* batman packet type: broadcast */ 404 - bcast_packet->packet_type = BAT_BCAST; 405 - 406 - /* hw address of first interface is the orig mac because only 407 - * this mac is known throughout the mesh */ 408 - memcpy(bcast_packet->orig, 409 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 410 - 411 - /* set broadcast sequence number */ 412 - bcast_packet->seqno = 413 - htonl(atomic_inc_return(&bat_priv->bcast_seqno)); 414 - 415 - add_bcast_packet_to_list(bat_priv, skb); 416 - 417 - /* a copy is stored in the bcast list, therefore removing 418 - * the original skb. */ 419 - kfree_skb(skb); 420 - 421 - /* unicast packet */ 422 - } else { 423 - ret = unicast_send_skb(skb, bat_priv); 424 - if (ret != 0) 425 - goto dropped_freed; 426 - } 427 - 428 - bat_priv->stats.tx_packets++; 429 - bat_priv->stats.tx_bytes += data_len; 430 - goto end; 431 - 432 - dropped: 433 - kfree_skb(skb); 434 - dropped_freed: 435 - bat_priv->stats.tx_dropped++; 436 - end: 437 - return NETDEV_TX_OK; 438 - } 439 - 440 - void interface_rx(struct net_device *soft_iface, 441 - struct sk_buff *skb, struct batman_if *recv_if, 442 - int hdr_size) 443 - { 444 - struct bat_priv *bat_priv = netdev_priv(soft_iface); 445 - struct unicast_packet *unicast_packet; 446 - struct ethhdr *ethhdr; 447 - struct vlan_ethhdr *vhdr; 448 - short vid = -1; 449 - int ret; 450 - 451 - /* check if enough space is available for pulling, and pull */ 452 - if (!pskb_may_pull(skb, hdr_size)) 453 - goto dropped; 454 - 455 - skb_pull_rcsum(skb, hdr_size); 456 - skb_reset_mac_header(skb); 457 - 458 - ethhdr = (struct ethhdr *)skb_mac_header(skb); 459 - 460 - switch (ntohs(ethhdr->h_proto)) { 461 - case ETH_P_8021Q: 462 - vhdr = (struct vlan_ethhdr *)skb->data; 463 - vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; 464 - 465 - if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) 466 - break; 467 - 468 - /* fall through */ 469 - case ETH_P_BATMAN: 470 - goto dropped; 471 - } 472 - 473 - /** 474 - * if we have a another chosen mesh exit node in range 475 - * it will transport the packets to the non-mesh network 476 - */ 477 - if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) { 478 - skb_push(skb, hdr_size); 479 - unicast_packet = (struct unicast_packet *)skb->data; 480 - 481 - if ((unicast_packet->packet_type != BAT_UNICAST) && 482 - (unicast_packet->packet_type != BAT_UNICAST_FRAG)) 483 - goto dropped; 484 - 485 - skb_reset_mac_header(skb); 486 - 487 - memcpy(unicast_packet->dest, 488 - bat_priv->softif_neigh->addr, ETH_ALEN); 489 - ret = route_unicast_packet(skb, recv_if, hdr_size); 490 - if (ret == NET_RX_DROP) 491 - goto dropped; 492 - 493 - goto out; 494 - } 495 - 496 - /* skb->dev & skb->pkt_type are set here */ 497 - if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) 498 - goto dropped; 499 - skb->protocol = eth_type_trans(skb, soft_iface); 500 - 501 - /* should not be neccesary anymore as we use skb_pull_rcsum() 502 - * TODO: please verify this and remove this TODO 503 - * -- Dec 21st 2009, Simon Wunderlich */ 504 - 505 - /* skb->ip_summed = CHECKSUM_UNNECESSARY;*/ 506 - 507 - bat_priv->stats.rx_packets++; 508 - bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr); 509 - 510 - soft_iface->last_rx = jiffies; 511 - 512 - netif_rx(skb); 513 - return; 514 - 515 - dropped: 516 - kfree_skb(skb); 517 - out: 518 - return; 519 - } 520 - 521 - #ifdef HAVE_NET_DEVICE_OPS 522 - static const struct net_device_ops bat_netdev_ops = { 523 - .ndo_open = interface_open, 524 - .ndo_stop = interface_release, 525 - .ndo_get_stats = interface_stats, 526 - .ndo_set_mac_address = interface_set_mac_addr, 527 - .ndo_change_mtu = interface_change_mtu, 528 - .ndo_start_xmit = interface_tx, 529 - .ndo_validate_addr = eth_validate_addr 530 - }; 531 - #endif 532 - 533 - static void interface_setup(struct net_device *dev) 534 - { 535 - struct bat_priv *priv = netdev_priv(dev); 536 - char dev_addr[ETH_ALEN]; 537 - 538 - ether_setup(dev); 539 - 540 - #ifdef HAVE_NET_DEVICE_OPS 541 - dev->netdev_ops = &bat_netdev_ops; 542 - #else 543 - dev->open = interface_open; 544 - dev->stop = interface_release; 545 - dev->get_stats = interface_stats; 546 - dev->set_mac_address = interface_set_mac_addr; 547 - dev->change_mtu = interface_change_mtu; 548 - dev->hard_start_xmit = interface_tx; 549 - #endif 550 - dev->destructor = free_netdev; 551 - 552 - /** 553 - * can't call min_mtu, because the needed variables 554 - * have not been initialized yet 555 - */ 556 - dev->mtu = ETH_DATA_LEN; 557 - dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the 558 - * skbuff for our header */ 559 - 560 - /* generate random address */ 561 - random_ether_addr(dev_addr); 562 - memcpy(dev->dev_addr, dev_addr, ETH_ALEN); 563 - 564 - SET_ETHTOOL_OPS(dev, &bat_ethtool_ops); 565 - 566 - memset(priv, 0, sizeof(struct bat_priv)); 567 - } 568 - 569 - struct net_device *softif_create(char *name) 570 - { 571 - struct net_device *soft_iface; 572 - struct bat_priv *bat_priv; 573 - int ret; 574 - 575 - soft_iface = alloc_netdev(sizeof(struct bat_priv) , name, 576 - interface_setup); 577 - 578 - if (!soft_iface) { 579 - pr_err("Unable to allocate the batman interface: %s\n", name); 580 - goto out; 581 - } 582 - 583 - ret = register_netdev(soft_iface); 584 - if (ret < 0) { 585 - pr_err("Unable to register the batman interface '%s': %i\n", 586 - name, ret); 587 - goto free_soft_iface; 588 - } 589 - 590 - bat_priv = netdev_priv(soft_iface); 591 - 592 - atomic_set(&bat_priv->aggregated_ogms, 1); 593 - atomic_set(&bat_priv->bonding, 0); 594 - atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); 595 - atomic_set(&bat_priv->gw_mode, GW_MODE_OFF); 596 - atomic_set(&bat_priv->gw_sel_class, 20); 597 - atomic_set(&bat_priv->gw_bandwidth, 41); 598 - atomic_set(&bat_priv->orig_interval, 1000); 599 - atomic_set(&bat_priv->hop_penalty, 10); 600 - atomic_set(&bat_priv->log_level, 0); 601 - atomic_set(&bat_priv->fragmentation, 1); 602 - atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN); 603 - atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN); 604 - 605 - atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); 606 - atomic_set(&bat_priv->bcast_seqno, 1); 607 - atomic_set(&bat_priv->hna_local_changed, 0); 608 - 609 - bat_priv->primary_if = NULL; 610 - bat_priv->num_ifaces = 0; 611 - bat_priv->softif_neigh = NULL; 612 - 613 - ret = sysfs_add_meshif(soft_iface); 614 - if (ret < 0) 615 - goto unreg_soft_iface; 616 - 617 - ret = debugfs_add_meshif(soft_iface); 618 - if (ret < 0) 619 - goto unreg_sysfs; 620 - 621 - ret = mesh_init(soft_iface); 622 - if (ret < 0) 623 - goto unreg_debugfs; 624 - 625 - return soft_iface; 626 - 627 - unreg_debugfs: 628 - debugfs_del_meshif(soft_iface); 629 - unreg_sysfs: 630 - sysfs_del_meshif(soft_iface); 631 - unreg_soft_iface: 632 - unregister_netdev(soft_iface); 633 - return NULL; 634 - 635 - free_soft_iface: 636 - free_netdev(soft_iface); 637 - out: 638 - return NULL; 639 - } 640 - 641 - void softif_destroy(struct net_device *soft_iface) 642 - { 643 - debugfs_del_meshif(soft_iface); 644 - sysfs_del_meshif(soft_iface); 645 - mesh_free(soft_iface); 646 - unregister_netdevice(soft_iface); 647 - } 648 - 649 - /* ethtool */ 650 - static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 651 - { 652 - cmd->supported = 0; 653 - cmd->advertising = 0; 654 - cmd->speed = SPEED_10; 655 - cmd->duplex = DUPLEX_FULL; 656 - cmd->port = PORT_TP; 657 - cmd->phy_address = 0; 658 - cmd->transceiver = XCVR_INTERNAL; 659 - cmd->autoneg = AUTONEG_DISABLE; 660 - cmd->maxtxpkt = 0; 661 - cmd->maxrxpkt = 0; 662 - 663 - return 0; 664 - } 665 - 666 - static void bat_get_drvinfo(struct net_device *dev, 667 - struct ethtool_drvinfo *info) 668 - { 669 - strcpy(info->driver, "B.A.T.M.A.N. advanced"); 670 - strcpy(info->version, SOURCE_VERSION); 671 - strcpy(info->fw_version, "N/A"); 672 - strcpy(info->bus_info, "batman"); 673 - } 674 - 675 - static u32 bat_get_msglevel(struct net_device *dev) 676 - { 677 - return -EOPNOTSUPP; 678 - } 679 - 680 - static void bat_set_msglevel(struct net_device *dev, u32 value) 681 - { 682 - } 683 - 684 - static u32 bat_get_link(struct net_device *dev) 685 - { 686 - return 1; 687 - } 688 - 689 - static u32 bat_get_rx_csum(struct net_device *dev) 690 - { 691 - return 0; 692 - } 693 - 694 - static int bat_set_rx_csum(struct net_device *dev, u32 data) 695 - { 696 - return -EOPNOTSUPP; 697 - }
-35
drivers/staging/batman-adv/soft-interface.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_ 23 - #define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ 24 - 25 - int my_skb_head_push(struct sk_buff *skb, unsigned int len); 26 - int softif_neigh_seq_print_text(struct seq_file *seq, void *offset); 27 - void softif_neigh_purge(struct bat_priv *bat_priv); 28 - int interface_tx(struct sk_buff *skb, struct net_device *soft_iface); 29 - void interface_rx(struct net_device *soft_iface, 30 - struct sk_buff *skb, struct batman_if *recv_if, 31 - int hdr_size); 32 - struct net_device *softif_create(char *name); 33 - void softif_destroy(struct net_device *soft_iface); 34 - 35 - #endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
-14
drivers/staging/batman-adv/sysfs-class-net-batman-adv
··· 1 - 2 - What: /sys/class/net/<iface>/batman-adv/mesh_iface 3 - Date: May 2010 4 - Contact: Marek Lindner <lindner_marek@yahoo.de> 5 - Description: 6 - The /sys/class/net/<iface>/batman-adv/mesh_iface file 7 - displays the batman mesh interface this <iface> 8 - currently is associated with. 9 - 10 - What: /sys/class/net/<iface>/batman-adv/iface_status 11 - Date: May 2010 12 - Contact: Marek Lindner <lindner_marek@yahoo.de> 13 - Description: 14 - Indicates the status of <iface> as it is seen by batman.
-69
drivers/staging/batman-adv/sysfs-class-net-mesh
··· 1 - 2 - What: /sys/class/net/<mesh_iface>/mesh/aggregated_ogms 3 - Date: May 2010 4 - Contact: Marek Lindner <lindner_marek@yahoo.de> 5 - Description: 6 - Indicates whether the batman protocol messages of the 7 - mesh <mesh_iface> shall be aggregated or not. 8 - 9 - What: /sys/class/net/<mesh_iface>/mesh/bonding 10 - Date: June 2010 11 - Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> 12 - Description: 13 - Indicates whether the data traffic going through the 14 - mesh will be sent using multiple interfaces at the 15 - same time (if available). 16 - 17 - What: /sys/class/net/<mesh_iface>/mesh/fragmentation 18 - Date: October 2010 19 - Contact: Andreas Langer <an.langer@gmx.de> 20 - Description: 21 - Indicates whether the data traffic going through the 22 - mesh will be fragmented or silently discarded if the 23 - packet size exceeds the outgoing interface MTU. 24 - 25 - What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth 26 - Date: October 2010 27 - Contact: Marek Lindner <lindner_marek@yahoo.de> 28 - Description: 29 - Defines the bandwidth which is propagated by this 30 - node if gw_mode was set to 'server'. 31 - 32 - What: /sys/class/net/<mesh_iface>/mesh/gw_mode 33 - Date: October 2010 34 - Contact: Marek Lindner <lindner_marek@yahoo.de> 35 - Description: 36 - Defines the state of the gateway features. Can be 37 - either 'off', 'client' or 'server'. 38 - 39 - What: /sys/class/net/<mesh_iface>/mesh/gw_sel_class 40 - Date: October 2010 41 - Contact: Marek Lindner <lindner_marek@yahoo.de> 42 - Description: 43 - Defines the selection criteria this node will use 44 - to choose a gateway if gw_mode was set to 'client'. 45 - 46 - What: /sys/class/net/<mesh_iface>/mesh/orig_interval 47 - Date: May 2010 48 - Contact: Marek Lindner <lindner_marek@yahoo.de> 49 - Description: 50 - Defines the interval in milliseconds in which batman 51 - sends its protocol messages. 52 - 53 - What: /sys/class/net/<mesh_iface>/mesh/hop_penalty 54 - Date: Oct 2010 55 - Contact: Linus Lüssing <linus.luessing@web.de> 56 - Description: 57 - Defines the penalty which will be applied to an 58 - originator message's tq-field on every hop. 59 - 60 - What: /sys/class/net/<mesh_iface>/mesh/vis_mode 61 - Date: May 2010 62 - Contact: Marek Lindner <lindner_marek@yahoo.de> 63 - Description: 64 - Each batman node only maintains information about its 65 - own local neighborhood, therefore generating graphs 66 - showing the topology of the entire mesh is not easily 67 - feasible without having a central instance to collect 68 - the local topologies from all nodes. This file allows 69 - to activate the collecting (server) mode.
-528
drivers/staging/batman-adv/translation-table.c
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "translation-table.h" 24 - #include "soft-interface.h" 25 - #include "types.h" 26 - #include "hash.h" 27 - #include "originator.h" 28 - 29 - static void hna_local_purge(struct work_struct *work); 30 - static void _hna_global_del_orig(struct bat_priv *bat_priv, 31 - struct hna_global_entry *hna_global_entry, 32 - char *message); 33 - 34 - static void hna_local_start_timer(struct bat_priv *bat_priv) 35 - { 36 - INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge); 37 - queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ); 38 - } 39 - 40 - int hna_local_init(struct bat_priv *bat_priv) 41 - { 42 - if (bat_priv->hna_local_hash) 43 - return 1; 44 - 45 - bat_priv->hna_local_hash = hash_new(128); 46 - 47 - if (!bat_priv->hna_local_hash) 48 - return 0; 49 - 50 - atomic_set(&bat_priv->hna_local_changed, 0); 51 - hna_local_start_timer(bat_priv); 52 - 53 - return 1; 54 - } 55 - 56 - void hna_local_add(struct net_device *soft_iface, uint8_t *addr) 57 - { 58 - struct bat_priv *bat_priv = netdev_priv(soft_iface); 59 - struct hna_local_entry *hna_local_entry; 60 - struct hna_global_entry *hna_global_entry; 61 - struct hashtable_t *swaphash; 62 - int required_bytes; 63 - 64 - spin_lock_bh(&bat_priv->hna_lhash_lock); 65 - hna_local_entry = 66 - ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash, 67 - compare_orig, choose_orig, 68 - addr)); 69 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 70 - 71 - if (hna_local_entry) { 72 - hna_local_entry->last_seen = jiffies; 73 - return; 74 - } 75 - 76 - /* only announce as many hosts as possible in the batman-packet and 77 - space in batman_packet->num_hna That also should give a limit to 78 - MAC-flooding. */ 79 - required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN; 80 - required_bytes += BAT_PACKET_LEN; 81 - 82 - if ((required_bytes > ETH_DATA_LEN) || 83 - (atomic_read(&bat_priv->aggregated_ogms) && 84 - required_bytes > MAX_AGGREGATION_BYTES) || 85 - (bat_priv->num_local_hna + 1 > 255)) { 86 - bat_dbg(DBG_ROUTES, bat_priv, 87 - "Can't add new local hna entry (%pM): " 88 - "number of local hna entries exceeds packet size\n", 89 - addr); 90 - return; 91 - } 92 - 93 - bat_dbg(DBG_ROUTES, bat_priv, 94 - "Creating new local hna entry: %pM\n", addr); 95 - 96 - hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); 97 - if (!hna_local_entry) 98 - return; 99 - 100 - memcpy(hna_local_entry->addr, addr, ETH_ALEN); 101 - hna_local_entry->last_seen = jiffies; 102 - 103 - /* the batman interface mac address should never be purged */ 104 - if (compare_orig(addr, soft_iface->dev_addr)) 105 - hna_local_entry->never_purge = 1; 106 - else 107 - hna_local_entry->never_purge = 0; 108 - 109 - spin_lock_bh(&bat_priv->hna_lhash_lock); 110 - 111 - hash_add(bat_priv->hna_local_hash, compare_orig, choose_orig, 112 - hna_local_entry); 113 - bat_priv->num_local_hna++; 114 - atomic_set(&bat_priv->hna_local_changed, 1); 115 - 116 - if (bat_priv->hna_local_hash->elements * 4 > 117 - bat_priv->hna_local_hash->size) { 118 - swaphash = hash_resize(bat_priv->hna_local_hash, choose_orig, 119 - bat_priv->hna_local_hash->size * 2); 120 - 121 - if (!swaphash) 122 - pr_err("Couldn't resize local hna hash table\n"); 123 - else 124 - bat_priv->hna_local_hash = swaphash; 125 - } 126 - 127 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 128 - 129 - /* remove address from global hash if present */ 130 - spin_lock_bh(&bat_priv->hna_ghash_lock); 131 - 132 - hna_global_entry = ((struct hna_global_entry *) 133 - hash_find(bat_priv->hna_global_hash, 134 - compare_orig, choose_orig, addr)); 135 - 136 - if (hna_global_entry) 137 - _hna_global_del_orig(bat_priv, hna_global_entry, 138 - "local hna received"); 139 - 140 - spin_unlock_bh(&bat_priv->hna_ghash_lock); 141 - } 142 - 143 - int hna_local_fill_buffer(struct bat_priv *bat_priv, 144 - unsigned char *buff, int buff_len) 145 - { 146 - struct hna_local_entry *hna_local_entry; 147 - struct element_t *bucket; 148 - HASHIT(hashit); 149 - int i = 0; 150 - 151 - spin_lock_bh(&bat_priv->hna_lhash_lock); 152 - 153 - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { 154 - 155 - if (buff_len < (i + 1) * ETH_ALEN) 156 - break; 157 - 158 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 159 - hna_local_entry = bucket->data; 160 - memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN); 161 - 162 - i++; 163 - } 164 - 165 - /* if we did not get all new local hnas see you next time ;-) */ 166 - if (i == bat_priv->num_local_hna) 167 - atomic_set(&bat_priv->hna_local_changed, 0); 168 - 169 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 170 - return i; 171 - } 172 - 173 - int hna_local_seq_print_text(struct seq_file *seq, void *offset) 174 - { 175 - struct net_device *net_dev = (struct net_device *)seq->private; 176 - struct bat_priv *bat_priv = netdev_priv(net_dev); 177 - struct hna_local_entry *hna_local_entry; 178 - HASHIT(hashit); 179 - HASHIT(hashit_count); 180 - struct element_t *bucket; 181 - size_t buf_size, pos; 182 - char *buff; 183 - 184 - if (!bat_priv->primary_if) { 185 - return seq_printf(seq, "BATMAN mesh %s disabled - " 186 - "please specify interfaces to enable it\n", 187 - net_dev->name); 188 - } 189 - 190 - seq_printf(seq, "Locally retrieved addresses (from %s) " 191 - "announced via HNA:\n", 192 - net_dev->name); 193 - 194 - spin_lock_bh(&bat_priv->hna_lhash_lock); 195 - 196 - buf_size = 1; 197 - /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ 198 - while (hash_iterate(bat_priv->hna_local_hash, &hashit_count)) 199 - buf_size += 21; 200 - 201 - buff = kmalloc(buf_size, GFP_ATOMIC); 202 - if (!buff) { 203 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 204 - return -ENOMEM; 205 - } 206 - buff[0] = '\0'; 207 - pos = 0; 208 - 209 - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { 210 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 211 - hna_local_entry = bucket->data; 212 - 213 - pos += snprintf(buff + pos, 22, " * %pM\n", 214 - hna_local_entry->addr); 215 - } 216 - 217 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 218 - 219 - seq_printf(seq, "%s", buff); 220 - kfree(buff); 221 - return 0; 222 - } 223 - 224 - static void _hna_local_del(void *data, void *arg) 225 - { 226 - struct bat_priv *bat_priv = (struct bat_priv *)arg; 227 - 228 - kfree(data); 229 - bat_priv->num_local_hna--; 230 - atomic_set(&bat_priv->hna_local_changed, 1); 231 - } 232 - 233 - static void hna_local_del(struct bat_priv *bat_priv, 234 - struct hna_local_entry *hna_local_entry, 235 - char *message) 236 - { 237 - bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n", 238 - hna_local_entry->addr, message); 239 - 240 - hash_remove(bat_priv->hna_local_hash, compare_orig, choose_orig, 241 - hna_local_entry->addr); 242 - _hna_local_del(hna_local_entry, bat_priv); 243 - } 244 - 245 - void hna_local_remove(struct bat_priv *bat_priv, 246 - uint8_t *addr, char *message) 247 - { 248 - struct hna_local_entry *hna_local_entry; 249 - 250 - spin_lock_bh(&bat_priv->hna_lhash_lock); 251 - 252 - hna_local_entry = (struct hna_local_entry *) 253 - hash_find(bat_priv->hna_local_hash, compare_orig, choose_orig, 254 - addr); 255 - if (hna_local_entry) 256 - hna_local_del(bat_priv, hna_local_entry, message); 257 - 258 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 259 - } 260 - 261 - static void hna_local_purge(struct work_struct *work) 262 - { 263 - struct delayed_work *delayed_work = 264 - container_of(work, struct delayed_work, work); 265 - struct bat_priv *bat_priv = 266 - container_of(delayed_work, struct bat_priv, hna_work); 267 - struct hna_local_entry *hna_local_entry; 268 - HASHIT(hashit); 269 - struct element_t *bucket; 270 - unsigned long timeout; 271 - 272 - spin_lock_bh(&bat_priv->hna_lhash_lock); 273 - 274 - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { 275 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 276 - hna_local_entry = bucket->data; 277 - 278 - timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ; 279 - 280 - if ((!hna_local_entry->never_purge) && 281 - time_after(jiffies, timeout)) 282 - hna_local_del(bat_priv, hna_local_entry, 283 - "address timed out"); 284 - } 285 - 286 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 287 - hna_local_start_timer(bat_priv); 288 - } 289 - 290 - void hna_local_free(struct bat_priv *bat_priv) 291 - { 292 - if (!bat_priv->hna_local_hash) 293 - return; 294 - 295 - cancel_delayed_work_sync(&bat_priv->hna_work); 296 - hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv); 297 - bat_priv->hna_local_hash = NULL; 298 - } 299 - 300 - int hna_global_init(struct bat_priv *bat_priv) 301 - { 302 - if (bat_priv->hna_global_hash) 303 - return 1; 304 - 305 - bat_priv->hna_global_hash = hash_new(128); 306 - 307 - if (!bat_priv->hna_global_hash) 308 - return 0; 309 - 310 - return 1; 311 - } 312 - 313 - void hna_global_add_orig(struct bat_priv *bat_priv, 314 - struct orig_node *orig_node, 315 - unsigned char *hna_buff, int hna_buff_len) 316 - { 317 - struct hna_global_entry *hna_global_entry; 318 - struct hna_local_entry *hna_local_entry; 319 - struct hashtable_t *swaphash; 320 - int hna_buff_count = 0; 321 - unsigned char *hna_ptr; 322 - 323 - while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { 324 - spin_lock_bh(&bat_priv->hna_ghash_lock); 325 - 326 - hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); 327 - hna_global_entry = (struct hna_global_entry *) 328 - hash_find(bat_priv->hna_global_hash, compare_orig, 329 - choose_orig, hna_ptr); 330 - 331 - if (!hna_global_entry) { 332 - spin_unlock_bh(&bat_priv->hna_ghash_lock); 333 - 334 - hna_global_entry = 335 - kmalloc(sizeof(struct hna_global_entry), 336 - GFP_ATOMIC); 337 - 338 - if (!hna_global_entry) 339 - break; 340 - 341 - memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); 342 - 343 - bat_dbg(DBG_ROUTES, bat_priv, 344 - "Creating new global hna entry: " 345 - "%pM (via %pM)\n", 346 - hna_global_entry->addr, orig_node->orig); 347 - 348 - spin_lock_bh(&bat_priv->hna_ghash_lock); 349 - hash_add(bat_priv->hna_global_hash, compare_orig, 350 - choose_orig, hna_global_entry); 351 - 352 - } 353 - 354 - hna_global_entry->orig_node = orig_node; 355 - spin_unlock_bh(&bat_priv->hna_ghash_lock); 356 - 357 - /* remove address from local hash if present */ 358 - spin_lock_bh(&bat_priv->hna_lhash_lock); 359 - 360 - hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); 361 - hna_local_entry = (struct hna_local_entry *) 362 - hash_find(bat_priv->hna_local_hash, compare_orig, 363 - choose_orig, hna_ptr); 364 - 365 - if (hna_local_entry) 366 - hna_local_del(bat_priv, hna_local_entry, 367 - "global hna received"); 368 - 369 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 370 - 371 - hna_buff_count++; 372 - } 373 - 374 - /* initialize, and overwrite if malloc succeeds */ 375 - orig_node->hna_buff = NULL; 376 - orig_node->hna_buff_len = 0; 377 - 378 - if (hna_buff_len > 0) { 379 - orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC); 380 - if (orig_node->hna_buff) { 381 - memcpy(orig_node->hna_buff, hna_buff, hna_buff_len); 382 - orig_node->hna_buff_len = hna_buff_len; 383 - } 384 - } 385 - 386 - spin_lock_bh(&bat_priv->hna_ghash_lock); 387 - 388 - if (bat_priv->hna_global_hash->elements * 4 > 389 - bat_priv->hna_global_hash->size) { 390 - swaphash = hash_resize(bat_priv->hna_global_hash, choose_orig, 391 - bat_priv->hna_global_hash->size * 2); 392 - 393 - if (!swaphash) 394 - pr_err("Couldn't resize global hna hash table\n"); 395 - else 396 - bat_priv->hna_global_hash = swaphash; 397 - } 398 - 399 - spin_unlock_bh(&bat_priv->hna_ghash_lock); 400 - } 401 - 402 - int hna_global_seq_print_text(struct seq_file *seq, void *offset) 403 - { 404 - struct net_device *net_dev = (struct net_device *)seq->private; 405 - struct bat_priv *bat_priv = netdev_priv(net_dev); 406 - struct hna_global_entry *hna_global_entry; 407 - HASHIT(hashit); 408 - HASHIT(hashit_count); 409 - struct element_t *bucket; 410 - size_t buf_size, pos; 411 - char *buff; 412 - 413 - if (!bat_priv->primary_if) { 414 - return seq_printf(seq, "BATMAN mesh %s disabled - " 415 - "please specify interfaces to enable it\n", 416 - net_dev->name); 417 - } 418 - 419 - seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", 420 - net_dev->name); 421 - 422 - spin_lock_bh(&bat_priv->hna_ghash_lock); 423 - 424 - buf_size = 1; 425 - /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/ 426 - while (hash_iterate(bat_priv->hna_global_hash, &hashit_count)) 427 - buf_size += 43; 428 - 429 - buff = kmalloc(buf_size, GFP_ATOMIC); 430 - if (!buff) { 431 - spin_unlock_bh(&bat_priv->hna_ghash_lock); 432 - return -ENOMEM; 433 - } 434 - buff[0] = '\0'; 435 - pos = 0; 436 - 437 - while (hash_iterate(bat_priv->hna_global_hash, &hashit)) { 438 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 439 - hna_global_entry = bucket->data; 440 - 441 - pos += snprintf(buff + pos, 44, 442 - " * %pM via %pM\n", hna_global_entry->addr, 443 - hna_global_entry->orig_node->orig); 444 - } 445 - 446 - spin_unlock_bh(&bat_priv->hna_ghash_lock); 447 - 448 - seq_printf(seq, "%s", buff); 449 - kfree(buff); 450 - return 0; 451 - } 452 - 453 - static void _hna_global_del_orig(struct bat_priv *bat_priv, 454 - struct hna_global_entry *hna_global_entry, 455 - char *message) 456 - { 457 - bat_dbg(DBG_ROUTES, bat_priv, 458 - "Deleting global hna entry %pM (via %pM): %s\n", 459 - hna_global_entry->addr, hna_global_entry->orig_node->orig, 460 - message); 461 - 462 - hash_remove(bat_priv->hna_global_hash, compare_orig, choose_orig, 463 - hna_global_entry->addr); 464 - kfree(hna_global_entry); 465 - } 466 - 467 - void hna_global_del_orig(struct bat_priv *bat_priv, 468 - struct orig_node *orig_node, char *message) 469 - { 470 - struct hna_global_entry *hna_global_entry; 471 - int hna_buff_count = 0; 472 - unsigned char *hna_ptr; 473 - 474 - if (orig_node->hna_buff_len == 0) 475 - return; 476 - 477 - spin_lock_bh(&bat_priv->hna_ghash_lock); 478 - 479 - while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { 480 - hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); 481 - hna_global_entry = (struct hna_global_entry *) 482 - hash_find(bat_priv->hna_global_hash, compare_orig, 483 - choose_orig, hna_ptr); 484 - 485 - if ((hna_global_entry) && 486 - (hna_global_entry->orig_node == orig_node)) 487 - _hna_global_del_orig(bat_priv, hna_global_entry, 488 - message); 489 - 490 - hna_buff_count++; 491 - } 492 - 493 - spin_unlock_bh(&bat_priv->hna_ghash_lock); 494 - 495 - orig_node->hna_buff_len = 0; 496 - kfree(orig_node->hna_buff); 497 - orig_node->hna_buff = NULL; 498 - } 499 - 500 - static void hna_global_del(void *data, void *arg) 501 - { 502 - kfree(data); 503 - } 504 - 505 - void hna_global_free(struct bat_priv *bat_priv) 506 - { 507 - if (!bat_priv->hna_global_hash) 508 - return; 509 - 510 - hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL); 511 - bat_priv->hna_global_hash = NULL; 512 - } 513 - 514 - struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) 515 - { 516 - struct hna_global_entry *hna_global_entry; 517 - 518 - spin_lock_bh(&bat_priv->hna_ghash_lock); 519 - hna_global_entry = (struct hna_global_entry *) 520 - hash_find(bat_priv->hna_global_hash, 521 - compare_orig, choose_orig, addr); 522 - spin_unlock_bh(&bat_priv->hna_ghash_lock); 523 - 524 - if (!hna_global_entry) 525 - return NULL; 526 - 527 - return hna_global_entry->orig_node; 528 - }
-45
drivers/staging/batman-adv/translation-table.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ 23 - #define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ 24 - 25 - #include "types.h" 26 - 27 - int hna_local_init(struct bat_priv *bat_priv); 28 - void hna_local_add(struct net_device *soft_iface, uint8_t *addr); 29 - void hna_local_remove(struct bat_priv *bat_priv, 30 - uint8_t *addr, char *message); 31 - int hna_local_fill_buffer(struct bat_priv *bat_priv, 32 - unsigned char *buff, int buff_len); 33 - int hna_local_seq_print_text(struct seq_file *seq, void *offset); 34 - void hna_local_free(struct bat_priv *bat_priv); 35 - int hna_global_init(struct bat_priv *bat_priv); 36 - void hna_global_add_orig(struct bat_priv *bat_priv, 37 - struct orig_node *orig_node, 38 - unsigned char *hna_buff, int hna_buff_len); 39 - int hna_global_seq_print_text(struct seq_file *seq, void *offset); 40 - void hna_global_del_orig(struct bat_priv *bat_priv, 41 - struct orig_node *orig_node, char *message); 42 - void hna_global_free(struct bat_priv *bat_priv); 43 - struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr); 44 - 45 - #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
-271
drivers/staging/batman-adv/types.h
··· 1 - /* 2 - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Marek Lindner, Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - 23 - 24 - #ifndef _NET_BATMAN_ADV_TYPES_H_ 25 - #define _NET_BATMAN_ADV_TYPES_H_ 26 - 27 - #include "packet.h" 28 - #include "bitarray.h" 29 - 30 - #define BAT_HEADER_LEN (sizeof(struct ethhdr) + \ 31 - ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \ 32 - sizeof(struct unicast_packet) : \ 33 - sizeof(struct bcast_packet)))) 34 - 35 - 36 - struct batman_if { 37 - struct list_head list; 38 - int16_t if_num; 39 - char if_status; 40 - struct net_device *net_dev; 41 - atomic_t seqno; 42 - atomic_t frag_seqno; 43 - unsigned char *packet_buff; 44 - int packet_len; 45 - struct kobject *hardif_obj; 46 - struct kref refcount; 47 - struct packet_type batman_adv_ptype; 48 - struct net_device *soft_iface; 49 - struct rcu_head rcu; 50 - }; 51 - 52 - /** 53 - * orig_node - structure for orig_list maintaining nodes of mesh 54 - * @primary_addr: hosts primary interface address 55 - * @last_valid: when last packet from this node was received 56 - * @bcast_seqno_reset: time when the broadcast seqno window was reset 57 - * @batman_seqno_reset: time when the batman seqno window was reset 58 - * @gw_flags: flags related to gateway class 59 - * @flags: for now only VIS_SERVER flag 60 - * @last_real_seqno: last and best known squence number 61 - * @last_ttl: ttl of last received packet 62 - * @last_bcast_seqno: last broadcast sequence number received by this host 63 - * 64 - * @candidates: how many candidates are available 65 - * @selected: next bonding candidate 66 - */ 67 - struct orig_node { 68 - uint8_t orig[ETH_ALEN]; 69 - uint8_t primary_addr[ETH_ALEN]; 70 - struct neigh_node *router; 71 - TYPE_OF_WORD *bcast_own; 72 - uint8_t *bcast_own_sum; 73 - uint8_t tq_own; 74 - int tq_asym_penalty; 75 - unsigned long last_valid; 76 - unsigned long bcast_seqno_reset; 77 - unsigned long batman_seqno_reset; 78 - uint8_t gw_flags; 79 - uint8_t flags; 80 - unsigned char *hna_buff; 81 - int16_t hna_buff_len; 82 - uint32_t last_real_seqno; 83 - uint8_t last_ttl; 84 - TYPE_OF_WORD bcast_bits[NUM_WORDS]; 85 - uint32_t last_bcast_seqno; 86 - struct list_head neigh_list; 87 - struct list_head frag_list; 88 - unsigned long last_frag_packet; 89 - struct { 90 - uint8_t candidates; 91 - struct neigh_node *selected; 92 - } bond; 93 - }; 94 - 95 - struct gw_node { 96 - struct hlist_node list; 97 - struct orig_node *orig_node; 98 - unsigned long deleted; 99 - struct kref refcount; 100 - struct rcu_head rcu; 101 - }; 102 - 103 - /** 104 - * neigh_node 105 - * @last_valid: when last packet via this neighbor was received 106 - */ 107 - struct neigh_node { 108 - struct list_head list; 109 - uint8_t addr[ETH_ALEN]; 110 - uint8_t real_packet_count; 111 - uint8_t tq_recv[TQ_GLOBAL_WINDOW_SIZE]; 112 - uint8_t tq_index; 113 - uint8_t tq_avg; 114 - uint8_t last_ttl; 115 - struct neigh_node *next_bond_candidate; 116 - unsigned long last_valid; 117 - TYPE_OF_WORD real_bits[NUM_WORDS]; 118 - struct orig_node *orig_node; 119 - struct batman_if *if_incoming; 120 - }; 121 - 122 - 123 - struct bat_priv { 124 - atomic_t mesh_state; 125 - struct net_device_stats stats; 126 - atomic_t aggregated_ogms; /* boolean */ 127 - atomic_t bonding; /* boolean */ 128 - atomic_t fragmentation; /* boolean */ 129 - atomic_t vis_mode; /* VIS_TYPE_* */ 130 - atomic_t gw_mode; /* GW_MODE_* */ 131 - atomic_t gw_sel_class; /* uint */ 132 - atomic_t gw_bandwidth; /* gw bandwidth */ 133 - atomic_t orig_interval; /* uint */ 134 - atomic_t hop_penalty; /* uint */ 135 - atomic_t log_level; /* uint */ 136 - atomic_t bcast_seqno; 137 - atomic_t bcast_queue_left; 138 - atomic_t batman_queue_left; 139 - char num_ifaces; 140 - struct hlist_head softif_neigh_list; 141 - struct softif_neigh *softif_neigh; 142 - struct debug_log *debug_log; 143 - struct batman_if *primary_if; 144 - struct kobject *mesh_obj; 145 - struct dentry *debug_dir; 146 - struct hlist_head forw_bat_list; 147 - struct hlist_head forw_bcast_list; 148 - struct hlist_head gw_list; 149 - struct list_head vis_send_list; 150 - struct hashtable_t *orig_hash; 151 - struct hashtable_t *hna_local_hash; 152 - struct hashtable_t *hna_global_hash; 153 - struct hashtable_t *vis_hash; 154 - spinlock_t orig_hash_lock; /* protects orig_hash */ 155 - spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ 156 - spinlock_t forw_bcast_list_lock; /* protects */ 157 - spinlock_t hna_lhash_lock; /* protects hna_local_hash */ 158 - spinlock_t hna_ghash_lock; /* protects hna_global_hash */ 159 - spinlock_t gw_list_lock; /* protects gw_list */ 160 - spinlock_t vis_hash_lock; /* protects vis_hash */ 161 - spinlock_t vis_list_lock; /* protects vis_info::recv_list */ 162 - spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */ 163 - int16_t num_local_hna; 164 - atomic_t hna_local_changed; 165 - struct delayed_work hna_work; 166 - struct delayed_work orig_work; 167 - struct delayed_work vis_work; 168 - struct gw_node *curr_gw; 169 - struct vis_info *my_vis_info; 170 - }; 171 - 172 - struct socket_client { 173 - struct list_head queue_list; 174 - unsigned int queue_len; 175 - unsigned char index; 176 - spinlock_t lock; /* protects queue_list, queue_len, index */ 177 - wait_queue_head_t queue_wait; 178 - struct bat_priv *bat_priv; 179 - }; 180 - 181 - struct socket_packet { 182 - struct list_head list; 183 - size_t icmp_len; 184 - struct icmp_packet_rr icmp_packet; 185 - }; 186 - 187 - struct hna_local_entry { 188 - uint8_t addr[ETH_ALEN]; 189 - unsigned long last_seen; 190 - char never_purge; 191 - }; 192 - 193 - struct hna_global_entry { 194 - uint8_t addr[ETH_ALEN]; 195 - struct orig_node *orig_node; 196 - }; 197 - 198 - /** 199 - * forw_packet - structure for forw_list maintaining packets to be 200 - * send/forwarded 201 - */ 202 - struct forw_packet { 203 - struct hlist_node list; 204 - unsigned long send_time; 205 - uint8_t own; 206 - struct sk_buff *skb; 207 - uint16_t packet_len; 208 - uint32_t direct_link_flags; 209 - uint8_t num_packets; 210 - struct delayed_work delayed_work; 211 - struct batman_if *if_incoming; 212 - }; 213 - 214 - /* While scanning for vis-entries of a particular vis-originator 215 - * this list collects its interfaces to create a subgraph/cluster 216 - * out of them later 217 - */ 218 - struct if_list_entry { 219 - uint8_t addr[ETH_ALEN]; 220 - bool primary; 221 - struct hlist_node list; 222 - }; 223 - 224 - struct debug_log { 225 - char log_buff[LOG_BUF_LEN]; 226 - unsigned long log_start; 227 - unsigned long log_end; 228 - spinlock_t lock; /* protects log_buff, log_start and log_end */ 229 - wait_queue_head_t queue_wait; 230 - }; 231 - 232 - struct frag_packet_list_entry { 233 - struct list_head list; 234 - uint16_t seqno; 235 - struct sk_buff *skb; 236 - }; 237 - 238 - struct vis_info { 239 - unsigned long first_seen; 240 - struct list_head recv_list; 241 - /* list of server-neighbors we received a vis-packet 242 - * from. we should not reply to them. */ 243 - struct list_head send_list; 244 - struct kref refcount; 245 - struct bat_priv *bat_priv; 246 - /* this packet might be part of the vis send queue. */ 247 - struct sk_buff *skb_packet; 248 - /* vis_info may follow here*/ 249 - } __attribute__((packed)); 250 - 251 - struct vis_info_entry { 252 - uint8_t src[ETH_ALEN]; 253 - uint8_t dest[ETH_ALEN]; 254 - uint8_t quality; /* quality = 0 means HNA */ 255 - } __attribute__((packed)); 256 - 257 - struct recvlist_node { 258 - struct list_head list; 259 - uint8_t mac[ETH_ALEN]; 260 - }; 261 - 262 - struct softif_neigh { 263 - struct hlist_node list; 264 - uint8_t addr[ETH_ALEN]; 265 - unsigned long last_seen; 266 - short vid; 267 - struct kref refcount; 268 - struct rcu_head rcu; 269 - }; 270 - 271 - #endif /* _NET_BATMAN_ADV_TYPES_H_ */
-343
drivers/staging/batman-adv/unicast.c
··· 1 - /* 2 - * Copyright (C) 2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Andreas Langer 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "unicast.h" 24 - #include "send.h" 25 - #include "soft-interface.h" 26 - #include "gateway_client.h" 27 - #include "originator.h" 28 - #include "hash.h" 29 - #include "translation-table.h" 30 - #include "routing.h" 31 - #include "hard-interface.h" 32 - 33 - 34 - static struct sk_buff *frag_merge_packet(struct list_head *head, 35 - struct frag_packet_list_entry *tfp, 36 - struct sk_buff *skb) 37 - { 38 - struct unicast_frag_packet *up = 39 - (struct unicast_frag_packet *)skb->data; 40 - struct sk_buff *tmp_skb; 41 - struct unicast_packet *unicast_packet; 42 - int hdr_len = sizeof(struct unicast_packet), 43 - uni_diff = sizeof(struct unicast_frag_packet) - hdr_len; 44 - 45 - /* set skb to the first part and tmp_skb to the second part */ 46 - if (up->flags & UNI_FRAG_HEAD) { 47 - tmp_skb = tfp->skb; 48 - } else { 49 - tmp_skb = skb; 50 - skb = tfp->skb; 51 - } 52 - 53 - skb_pull(tmp_skb, sizeof(struct unicast_frag_packet)); 54 - if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) { 55 - /* free buffered skb, skb will be freed later */ 56 - kfree_skb(tfp->skb); 57 - return NULL; 58 - } 59 - 60 - /* move free entry to end */ 61 - tfp->skb = NULL; 62 - tfp->seqno = 0; 63 - list_move_tail(&tfp->list, head); 64 - 65 - memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len); 66 - kfree_skb(tmp_skb); 67 - 68 - memmove(skb->data + uni_diff, skb->data, hdr_len); 69 - unicast_packet = (struct unicast_packet *) skb_pull(skb, uni_diff); 70 - unicast_packet->packet_type = BAT_UNICAST; 71 - 72 - return skb; 73 - } 74 - 75 - static void frag_create_entry(struct list_head *head, struct sk_buff *skb) 76 - { 77 - struct frag_packet_list_entry *tfp; 78 - struct unicast_frag_packet *up = 79 - (struct unicast_frag_packet *)skb->data; 80 - 81 - /* free and oldest packets stand at the end */ 82 - tfp = list_entry((head)->prev, typeof(*tfp), list); 83 - kfree_skb(tfp->skb); 84 - 85 - tfp->seqno = ntohs(up->seqno); 86 - tfp->skb = skb; 87 - list_move(&tfp->list, head); 88 - return; 89 - } 90 - 91 - static int frag_create_buffer(struct list_head *head) 92 - { 93 - int i; 94 - struct frag_packet_list_entry *tfp; 95 - 96 - for (i = 0; i < FRAG_BUFFER_SIZE; i++) { 97 - tfp = kmalloc(sizeof(struct frag_packet_list_entry), 98 - GFP_ATOMIC); 99 - if (!tfp) { 100 - frag_list_free(head); 101 - return -ENOMEM; 102 - } 103 - tfp->skb = NULL; 104 - tfp->seqno = 0; 105 - INIT_LIST_HEAD(&tfp->list); 106 - list_add(&tfp->list, head); 107 - } 108 - 109 - return 0; 110 - } 111 - 112 - static struct frag_packet_list_entry *frag_search_packet(struct list_head *head, 113 - struct unicast_frag_packet *up) 114 - { 115 - struct frag_packet_list_entry *tfp; 116 - struct unicast_frag_packet *tmp_up = NULL; 117 - uint16_t search_seqno; 118 - 119 - if (up->flags & UNI_FRAG_HEAD) 120 - search_seqno = ntohs(up->seqno)+1; 121 - else 122 - search_seqno = ntohs(up->seqno)-1; 123 - 124 - list_for_each_entry(tfp, head, list) { 125 - 126 - if (!tfp->skb) 127 - continue; 128 - 129 - if (tfp->seqno == ntohs(up->seqno)) 130 - goto mov_tail; 131 - 132 - tmp_up = (struct unicast_frag_packet *)tfp->skb->data; 133 - 134 - if (tfp->seqno == search_seqno) { 135 - 136 - if ((tmp_up->flags & UNI_FRAG_HEAD) != 137 - (up->flags & UNI_FRAG_HEAD)) 138 - return tfp; 139 - else 140 - goto mov_tail; 141 - } 142 - } 143 - return NULL; 144 - 145 - mov_tail: 146 - list_move_tail(&tfp->list, head); 147 - return NULL; 148 - } 149 - 150 - void frag_list_free(struct list_head *head) 151 - { 152 - struct frag_packet_list_entry *pf, *tmp_pf; 153 - 154 - if (!list_empty(head)) { 155 - 156 - list_for_each_entry_safe(pf, tmp_pf, head, list) { 157 - kfree_skb(pf->skb); 158 - list_del(&pf->list); 159 - kfree(pf); 160 - } 161 - } 162 - return; 163 - } 164 - 165 - /* frag_reassemble_skb(): 166 - * returns NET_RX_DROP if the operation failed - skb is left intact 167 - * returns NET_RX_SUCCESS if the fragment was buffered (skb_new will be NULL) 168 - * or the skb could be reassembled (skb_new will point to the new packet and 169 - * skb was freed) 170 - */ 171 - int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, 172 - struct sk_buff **new_skb) 173 - { 174 - struct orig_node *orig_node; 175 - struct frag_packet_list_entry *tmp_frag_entry; 176 - int ret = NET_RX_DROP; 177 - struct unicast_frag_packet *unicast_packet = 178 - (struct unicast_frag_packet *)skb->data; 179 - 180 - *new_skb = NULL; 181 - spin_lock_bh(&bat_priv->orig_hash_lock); 182 - orig_node = ((struct orig_node *) 183 - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, 184 - unicast_packet->orig)); 185 - 186 - if (!orig_node) { 187 - pr_debug("couldn't find originator in orig_hash\n"); 188 - goto out; 189 - } 190 - 191 - orig_node->last_frag_packet = jiffies; 192 - 193 - if (list_empty(&orig_node->frag_list) && 194 - frag_create_buffer(&orig_node->frag_list)) { 195 - pr_debug("couldn't create frag buffer\n"); 196 - goto out; 197 - } 198 - 199 - tmp_frag_entry = frag_search_packet(&orig_node->frag_list, 200 - unicast_packet); 201 - 202 - if (!tmp_frag_entry) { 203 - frag_create_entry(&orig_node->frag_list, skb); 204 - ret = NET_RX_SUCCESS; 205 - goto out; 206 - } 207 - 208 - *new_skb = frag_merge_packet(&orig_node->frag_list, tmp_frag_entry, 209 - skb); 210 - /* if not, merge failed */ 211 - if (*new_skb) 212 - ret = NET_RX_SUCCESS; 213 - out: 214 - spin_unlock_bh(&bat_priv->orig_hash_lock); 215 - 216 - return ret; 217 - } 218 - 219 - int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, 220 - struct batman_if *batman_if, uint8_t dstaddr[]) 221 - { 222 - struct unicast_packet tmp_uc, *unicast_packet; 223 - struct sk_buff *frag_skb; 224 - struct unicast_frag_packet *frag1, *frag2; 225 - int uc_hdr_len = sizeof(struct unicast_packet); 226 - int ucf_hdr_len = sizeof(struct unicast_frag_packet); 227 - int data_len = skb->len; 228 - 229 - if (!bat_priv->primary_if) 230 - goto dropped; 231 - 232 - unicast_packet = (struct unicast_packet *) skb->data; 233 - 234 - memcpy(&tmp_uc, unicast_packet, uc_hdr_len); 235 - frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); 236 - skb_split(skb, frag_skb, data_len / 2); 237 - 238 - if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || 239 - my_skb_head_push(frag_skb, ucf_hdr_len) < 0) 240 - goto drop_frag; 241 - 242 - frag1 = (struct unicast_frag_packet *)skb->data; 243 - frag2 = (struct unicast_frag_packet *)frag_skb->data; 244 - 245 - memcpy(frag1, &tmp_uc, sizeof(struct unicast_packet)); 246 - 247 - frag1->ttl--; 248 - frag1->version = COMPAT_VERSION; 249 - frag1->packet_type = BAT_UNICAST_FRAG; 250 - 251 - memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 252 - memcpy(frag2, frag1, sizeof(struct unicast_frag_packet)); 253 - 254 - frag1->flags |= UNI_FRAG_HEAD; 255 - frag2->flags &= ~UNI_FRAG_HEAD; 256 - 257 - frag1->seqno = htons((uint16_t)atomic_inc_return( 258 - &batman_if->frag_seqno)); 259 - frag2->seqno = htons((uint16_t)atomic_inc_return( 260 - &batman_if->frag_seqno)); 261 - 262 - send_skb_packet(skb, batman_if, dstaddr); 263 - send_skb_packet(frag_skb, batman_if, dstaddr); 264 - return NET_RX_SUCCESS; 265 - 266 - drop_frag: 267 - kfree_skb(frag_skb); 268 - dropped: 269 - kfree_skb(skb); 270 - return NET_RX_DROP; 271 - } 272 - 273 - int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) 274 - { 275 - struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 276 - struct unicast_packet *unicast_packet; 277 - struct orig_node *orig_node; 278 - struct batman_if *batman_if; 279 - struct neigh_node *router; 280 - int data_len = skb->len; 281 - uint8_t dstaddr[6]; 282 - 283 - spin_lock_bh(&bat_priv->orig_hash_lock); 284 - 285 - /* get routing information */ 286 - if (is_multicast_ether_addr(ethhdr->h_dest)) 287 - orig_node = (struct orig_node *)gw_get_selected(bat_priv); 288 - else 289 - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, 290 - compare_orig, 291 - choose_orig, 292 - ethhdr->h_dest)); 293 - 294 - /* check for hna host */ 295 - if (!orig_node) 296 - orig_node = transtable_search(bat_priv, ethhdr->h_dest); 297 - 298 - router = find_router(bat_priv, orig_node, NULL); 299 - 300 - if (!router) 301 - goto unlock; 302 - 303 - /* don't lock while sending the packets ... we therefore 304 - * copy the required data before sending */ 305 - 306 - batman_if = router->if_incoming; 307 - memcpy(dstaddr, router->addr, ETH_ALEN); 308 - 309 - spin_unlock_bh(&bat_priv->orig_hash_lock); 310 - 311 - if (batman_if->if_status != IF_ACTIVE) 312 - goto dropped; 313 - 314 - if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0) 315 - goto dropped; 316 - 317 - unicast_packet = (struct unicast_packet *)skb->data; 318 - 319 - unicast_packet->version = COMPAT_VERSION; 320 - /* batman packet type: unicast */ 321 - unicast_packet->packet_type = BAT_UNICAST; 322 - /* set unicast ttl */ 323 - unicast_packet->ttl = TTL; 324 - /* copy the destination for faster routing */ 325 - memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); 326 - 327 - if (atomic_read(&bat_priv->fragmentation) && 328 - data_len + sizeof(struct unicast_packet) > 329 - batman_if->net_dev->mtu) { 330 - /* send frag skb decreases ttl */ 331 - unicast_packet->ttl++; 332 - return frag_send_skb(skb, bat_priv, batman_if, 333 - dstaddr); 334 - } 335 - send_skb_packet(skb, batman_if, dstaddr); 336 - return 0; 337 - 338 - unlock: 339 - spin_unlock_bh(&bat_priv->orig_hash_lock); 340 - dropped: 341 - kfree_skb(skb); 342 - return 1; 343 - }
-35
drivers/staging/batman-adv/unicast.h
··· 1 - /* 2 - * Copyright (C) 2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Andreas Langer 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_UNICAST_H_ 23 - #define _NET_BATMAN_ADV_UNICAST_H_ 24 - 25 - #define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */ 26 - #define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ 27 - 28 - int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, 29 - struct sk_buff **new_skb); 30 - void frag_list_free(struct list_head *head); 31 - int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv); 32 - int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, 33 - struct batman_if *batman_if, uint8_t dstaddr[]); 34 - 35 - #endif /* _NET_BATMAN_ADV_UNICAST_H_ */
-903
drivers/staging/batman-adv/vis.c
··· 1 - /* 2 - * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Simon Wunderlich 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #include "main.h" 23 - #include "send.h" 24 - #include "translation-table.h" 25 - #include "vis.h" 26 - #include "soft-interface.h" 27 - #include "hard-interface.h" 28 - #include "hash.h" 29 - #include "originator.h" 30 - 31 - #define MAX_VIS_PACKET_SIZE 1000 32 - 33 - /* Returns the smallest signed integer in two's complement with the sizeof x */ 34 - #define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u))) 35 - 36 - /* Checks if a sequence number x is a predecessor/successor of y. 37 - * they handle overflows/underflows and can correctly check for a 38 - * predecessor/successor unless the variable sequence number has grown by 39 - * more then 2**(bitwidth(x)-1)-1. 40 - * This means that for a uint8_t with the maximum value 255, it would think: 41 - * - when adding nothing - it is neither a predecessor nor a successor 42 - * - before adding more than 127 to the starting value - it is a predecessor, 43 - * - when adding 128 - it is neither a predecessor nor a successor, 44 - * - after adding more than 127 to the starting value - it is a successor */ 45 - #define seq_before(x, y) ({typeof(x) _dummy = (x - y); \ 46 - _dummy > smallest_signed_int(_dummy); }) 47 - #define seq_after(x, y) seq_before(y, x) 48 - 49 - static void start_vis_timer(struct bat_priv *bat_priv); 50 - 51 - /* free the info */ 52 - static void free_info(struct kref *ref) 53 - { 54 - struct vis_info *info = container_of(ref, struct vis_info, refcount); 55 - struct bat_priv *bat_priv = info->bat_priv; 56 - struct recvlist_node *entry, *tmp; 57 - 58 - list_del_init(&info->send_list); 59 - spin_lock_bh(&bat_priv->vis_list_lock); 60 - list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { 61 - list_del(&entry->list); 62 - kfree(entry); 63 - } 64 - 65 - spin_unlock_bh(&bat_priv->vis_list_lock); 66 - kfree_skb(info->skb_packet); 67 - } 68 - 69 - /* Compare two vis packets, used by the hashing algorithm */ 70 - static int vis_info_cmp(void *data1, void *data2) 71 - { 72 - struct vis_info *d1, *d2; 73 - struct vis_packet *p1, *p2; 74 - d1 = data1; 75 - d2 = data2; 76 - p1 = (struct vis_packet *)d1->skb_packet->data; 77 - p2 = (struct vis_packet *)d2->skb_packet->data; 78 - return compare_orig(p1->vis_orig, p2->vis_orig); 79 - } 80 - 81 - /* hash function to choose an entry in a hash table of given size */ 82 - /* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ 83 - static int vis_info_choose(void *data, int size) 84 - { 85 - struct vis_info *vis_info = data; 86 - struct vis_packet *packet; 87 - unsigned char *key; 88 - uint32_t hash = 0; 89 - size_t i; 90 - 91 - packet = (struct vis_packet *)vis_info->skb_packet->data; 92 - key = packet->vis_orig; 93 - for (i = 0; i < ETH_ALEN; i++) { 94 - hash += key[i]; 95 - hash += (hash << 10); 96 - hash ^= (hash >> 6); 97 - } 98 - 99 - hash += (hash << 3); 100 - hash ^= (hash >> 11); 101 - hash += (hash << 15); 102 - 103 - return hash % size; 104 - } 105 - 106 - /* insert interface to the list of interfaces of one originator, if it 107 - * does not already exist in the list */ 108 - static void vis_data_insert_interface(const uint8_t *interface, 109 - struct hlist_head *if_list, 110 - bool primary) 111 - { 112 - struct if_list_entry *entry; 113 - struct hlist_node *pos; 114 - 115 - hlist_for_each_entry(entry, pos, if_list, list) { 116 - if (compare_orig(entry->addr, (void *)interface)) 117 - return; 118 - } 119 - 120 - /* its a new address, add it to the list */ 121 - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 122 - if (!entry) 123 - return; 124 - memcpy(entry->addr, interface, ETH_ALEN); 125 - entry->primary = primary; 126 - hlist_add_head(&entry->list, if_list); 127 - } 128 - 129 - static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list) 130 - { 131 - struct if_list_entry *entry; 132 - struct hlist_node *pos; 133 - size_t len = 0; 134 - 135 - hlist_for_each_entry(entry, pos, if_list, list) { 136 - if (entry->primary) 137 - len += sprintf(buff + len, "PRIMARY, "); 138 - else 139 - len += sprintf(buff + len, "SEC %pM, ", entry->addr); 140 - } 141 - 142 - return len; 143 - } 144 - 145 - static size_t vis_data_count_prim_sec(struct hlist_head *if_list) 146 - { 147 - struct if_list_entry *entry; 148 - struct hlist_node *pos; 149 - size_t count = 0; 150 - 151 - hlist_for_each_entry(entry, pos, if_list, list) { 152 - if (entry->primary) 153 - count += 9; 154 - else 155 - count += 23; 156 - } 157 - 158 - return count; 159 - } 160 - 161 - /* read an entry */ 162 - static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry, 163 - uint8_t *src, bool primary) 164 - { 165 - /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ 166 - if (primary && entry->quality == 0) 167 - return sprintf(buff, "HNA %pM, ", entry->dest); 168 - else if (compare_orig(entry->src, src)) 169 - return sprintf(buff, "TQ %pM %d, ", entry->dest, 170 - entry->quality); 171 - 172 - return 0; 173 - } 174 - 175 - int vis_seq_print_text(struct seq_file *seq, void *offset) 176 - { 177 - HASHIT(hashit); 178 - HASHIT(hashit_count); 179 - struct element_t *bucket; 180 - struct vis_info *info; 181 - struct vis_packet *packet; 182 - struct vis_info_entry *entries; 183 - struct net_device *net_dev = (struct net_device *)seq->private; 184 - struct bat_priv *bat_priv = netdev_priv(net_dev); 185 - HLIST_HEAD(vis_if_list); 186 - struct if_list_entry *entry; 187 - struct hlist_node *pos, *n; 188 - int i; 189 - int vis_server = atomic_read(&bat_priv->vis_mode); 190 - size_t buff_pos, buf_size; 191 - char *buff; 192 - 193 - if ((!bat_priv->primary_if) || 194 - (vis_server == VIS_TYPE_CLIENT_UPDATE)) 195 - return 0; 196 - 197 - buf_size = 1; 198 - /* Estimate length */ 199 - spin_lock_bh(&bat_priv->vis_hash_lock); 200 - while (hash_iterate(bat_priv->vis_hash, &hashit_count)) { 201 - bucket = hlist_entry(hashit_count.walk, struct element_t, 202 - hlist); 203 - info = bucket->data; 204 - packet = (struct vis_packet *)info->skb_packet->data; 205 - entries = (struct vis_info_entry *) 206 - ((char *)packet + sizeof(struct vis_packet)); 207 - 208 - for (i = 0; i < packet->entries; i++) { 209 - if (entries[i].quality == 0) 210 - continue; 211 - vis_data_insert_interface(entries[i].src, &vis_if_list, 212 - compare_orig(entries[i].src, packet->vis_orig)); 213 - } 214 - 215 - hlist_for_each_entry(entry, pos, &vis_if_list, list) { 216 - buf_size += 18 + 26 * packet->entries; 217 - 218 - /* add primary/secondary records */ 219 - if (compare_orig(entry->addr, packet->vis_orig)) 220 - buf_size += 221 - vis_data_count_prim_sec(&vis_if_list); 222 - 223 - buf_size += 1; 224 - } 225 - 226 - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { 227 - hlist_del(&entry->list); 228 - kfree(entry); 229 - } 230 - } 231 - 232 - buff = kmalloc(buf_size, GFP_ATOMIC); 233 - if (!buff) { 234 - spin_unlock_bh(&bat_priv->vis_hash_lock); 235 - return -ENOMEM; 236 - } 237 - buff[0] = '\0'; 238 - buff_pos = 0; 239 - 240 - while (hash_iterate(bat_priv->vis_hash, &hashit)) { 241 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 242 - info = bucket->data; 243 - packet = (struct vis_packet *)info->skb_packet->data; 244 - entries = (struct vis_info_entry *) 245 - ((char *)packet + sizeof(struct vis_packet)); 246 - 247 - for (i = 0; i < packet->entries; i++) { 248 - if (entries[i].quality == 0) 249 - continue; 250 - vis_data_insert_interface(entries[i].src, &vis_if_list, 251 - compare_orig(entries[i].src, packet->vis_orig)); 252 - } 253 - 254 - hlist_for_each_entry(entry, pos, &vis_if_list, list) { 255 - buff_pos += sprintf(buff + buff_pos, "%pM,", 256 - entry->addr); 257 - 258 - for (i = 0; i < packet->entries; i++) 259 - buff_pos += vis_data_read_entry(buff + buff_pos, 260 - &entries[i], 261 - entry->addr, 262 - entry->primary); 263 - 264 - /* add primary/secondary records */ 265 - if (compare_orig(entry->addr, packet->vis_orig)) 266 - buff_pos += 267 - vis_data_read_prim_sec(buff + buff_pos, 268 - &vis_if_list); 269 - 270 - buff_pos += sprintf(buff + buff_pos, "\n"); 271 - } 272 - 273 - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { 274 - hlist_del(&entry->list); 275 - kfree(entry); 276 - } 277 - } 278 - 279 - spin_unlock_bh(&bat_priv->vis_hash_lock); 280 - 281 - seq_printf(seq, "%s", buff); 282 - kfree(buff); 283 - 284 - return 0; 285 - } 286 - 287 - /* add the info packet to the send list, if it was not 288 - * already linked in. */ 289 - static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info) 290 - { 291 - if (list_empty(&info->send_list)) { 292 - kref_get(&info->refcount); 293 - list_add_tail(&info->send_list, &bat_priv->vis_send_list); 294 - } 295 - } 296 - 297 - /* delete the info packet from the send list, if it was 298 - * linked in. */ 299 - static void send_list_del(struct vis_info *info) 300 - { 301 - if (!list_empty(&info->send_list)) { 302 - list_del_init(&info->send_list); 303 - kref_put(&info->refcount, free_info); 304 - } 305 - } 306 - 307 - /* tries to add one entry to the receive list. */ 308 - static void recv_list_add(struct bat_priv *bat_priv, 309 - struct list_head *recv_list, char *mac) 310 - { 311 - struct recvlist_node *entry; 312 - 313 - entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC); 314 - if (!entry) 315 - return; 316 - 317 - memcpy(entry->mac, mac, ETH_ALEN); 318 - spin_lock_bh(&bat_priv->vis_list_lock); 319 - list_add_tail(&entry->list, recv_list); 320 - spin_unlock_bh(&bat_priv->vis_list_lock); 321 - } 322 - 323 - /* returns 1 if this mac is in the recv_list */ 324 - static int recv_list_is_in(struct bat_priv *bat_priv, 325 - struct list_head *recv_list, char *mac) 326 - { 327 - struct recvlist_node *entry; 328 - 329 - spin_lock_bh(&bat_priv->vis_list_lock); 330 - list_for_each_entry(entry, recv_list, list) { 331 - if (memcmp(entry->mac, mac, ETH_ALEN) == 0) { 332 - spin_unlock_bh(&bat_priv->vis_list_lock); 333 - return 1; 334 - } 335 - } 336 - spin_unlock_bh(&bat_priv->vis_list_lock); 337 - return 0; 338 - } 339 - 340 - /* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old, 341 - * broken.. ). vis hash must be locked outside. is_new is set when the packet 342 - * is newer than old entries in the hash. */ 343 - static struct vis_info *add_packet(struct bat_priv *bat_priv, 344 - struct vis_packet *vis_packet, 345 - int vis_info_len, int *is_new, 346 - int make_broadcast) 347 - { 348 - struct vis_info *info, *old_info; 349 - struct vis_packet *search_packet, *old_packet; 350 - struct vis_info search_elem; 351 - struct vis_packet *packet; 352 - int hash_added; 353 - 354 - *is_new = 0; 355 - /* sanity check */ 356 - if (!bat_priv->vis_hash) 357 - return NULL; 358 - 359 - /* see if the packet is already in vis_hash */ 360 - search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet)); 361 - if (!search_elem.skb_packet) 362 - return NULL; 363 - search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet, 364 - sizeof(struct vis_packet)); 365 - 366 - memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); 367 - old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, 368 - &search_elem); 369 - kfree_skb(search_elem.skb_packet); 370 - 371 - if (old_info != NULL) { 372 - old_packet = (struct vis_packet *)old_info->skb_packet->data; 373 - if (!seq_after(ntohl(vis_packet->seqno), 374 - ntohl(old_packet->seqno))) { 375 - if (old_packet->seqno == vis_packet->seqno) { 376 - recv_list_add(bat_priv, &old_info->recv_list, 377 - vis_packet->sender_orig); 378 - return old_info; 379 - } else { 380 - /* newer packet is already in hash. */ 381 - return NULL; 382 - } 383 - } 384 - /* remove old entry */ 385 - hash_remove(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, 386 - old_info); 387 - send_list_del(old_info); 388 - kref_put(&old_info->refcount, free_info); 389 - } 390 - 391 - info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC); 392 - if (!info) 393 - return NULL; 394 - 395 - info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) + 396 - vis_info_len + sizeof(struct ethhdr)); 397 - if (!info->skb_packet) { 398 - kfree(info); 399 - return NULL; 400 - } 401 - skb_reserve(info->skb_packet, sizeof(struct ethhdr)); 402 - packet = (struct vis_packet *)skb_put(info->skb_packet, 403 - sizeof(struct vis_packet) + 404 - vis_info_len); 405 - 406 - kref_init(&info->refcount); 407 - INIT_LIST_HEAD(&info->send_list); 408 - INIT_LIST_HEAD(&info->recv_list); 409 - info->first_seen = jiffies; 410 - info->bat_priv = bat_priv; 411 - memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len); 412 - 413 - /* initialize and add new packet. */ 414 - *is_new = 1; 415 - 416 - /* Make it a broadcast packet, if required */ 417 - if (make_broadcast) 418 - memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); 419 - 420 - /* repair if entries is longer than packet. */ 421 - if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len) 422 - packet->entries = vis_info_len / sizeof(struct vis_info_entry); 423 - 424 - recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); 425 - 426 - /* try to add it */ 427 - hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, 428 - info); 429 - if (hash_added < 0) { 430 - /* did not work (for some reason) */ 431 - kref_put(&old_info->refcount, free_info); 432 - info = NULL; 433 - } 434 - 435 - return info; 436 - } 437 - 438 - /* handle the server sync packet, forward if needed. */ 439 - void receive_server_sync_packet(struct bat_priv *bat_priv, 440 - struct vis_packet *vis_packet, 441 - int vis_info_len) 442 - { 443 - struct vis_info *info; 444 - int is_new, make_broadcast; 445 - int vis_server = atomic_read(&bat_priv->vis_mode); 446 - 447 - make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); 448 - 449 - spin_lock_bh(&bat_priv->vis_hash_lock); 450 - info = add_packet(bat_priv, vis_packet, vis_info_len, 451 - &is_new, make_broadcast); 452 - if (!info) 453 - goto end; 454 - 455 - /* only if we are server ourselves and packet is newer than the one in 456 - * hash.*/ 457 - if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) 458 - send_list_add(bat_priv, info); 459 - end: 460 - spin_unlock_bh(&bat_priv->vis_hash_lock); 461 - } 462 - 463 - /* handle an incoming client update packet and schedule forward if needed. */ 464 - void receive_client_update_packet(struct bat_priv *bat_priv, 465 - struct vis_packet *vis_packet, 466 - int vis_info_len) 467 - { 468 - struct vis_info *info; 469 - struct vis_packet *packet; 470 - int is_new; 471 - int vis_server = atomic_read(&bat_priv->vis_mode); 472 - int are_target = 0; 473 - 474 - /* clients shall not broadcast. */ 475 - if (is_broadcast_ether_addr(vis_packet->target_orig)) 476 - return; 477 - 478 - /* Are we the target for this VIS packet? */ 479 - if (vis_server == VIS_TYPE_SERVER_SYNC && 480 - is_my_mac(vis_packet->target_orig)) 481 - are_target = 1; 482 - 483 - spin_lock_bh(&bat_priv->vis_hash_lock); 484 - info = add_packet(bat_priv, vis_packet, vis_info_len, 485 - &is_new, are_target); 486 - 487 - if (!info) 488 - goto end; 489 - /* note that outdated packets will be dropped at this point. */ 490 - 491 - packet = (struct vis_packet *)info->skb_packet->data; 492 - 493 - /* send only if we're the target server or ... */ 494 - if (are_target && is_new) { 495 - packet->vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ 496 - send_list_add(bat_priv, info); 497 - 498 - /* ... we're not the recipient (and thus need to forward). */ 499 - } else if (!is_my_mac(packet->target_orig)) { 500 - send_list_add(bat_priv, info); 501 - } 502 - 503 - end: 504 - spin_unlock_bh(&bat_priv->vis_hash_lock); 505 - } 506 - 507 - /* Walk the originators and find the VIS server with the best tq. Set the packet 508 - * address to its address and return the best_tq. 509 - * 510 - * Must be called with the originator hash locked */ 511 - static int find_best_vis_server(struct bat_priv *bat_priv, 512 - struct vis_info *info) 513 - { 514 - HASHIT(hashit); 515 - struct element_t *bucket; 516 - struct orig_node *orig_node; 517 - struct vis_packet *packet; 518 - int best_tq = -1; 519 - 520 - packet = (struct vis_packet *)info->skb_packet->data; 521 - 522 - while (hash_iterate(bat_priv->orig_hash, &hashit)) { 523 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 524 - orig_node = bucket->data; 525 - if ((orig_node) && (orig_node->router) && 526 - (orig_node->flags & VIS_SERVER) && 527 - (orig_node->router->tq_avg > best_tq)) { 528 - best_tq = orig_node->router->tq_avg; 529 - memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); 530 - } 531 - } 532 - return best_tq; 533 - } 534 - 535 - /* Return true if the vis packet is full. */ 536 - static bool vis_packet_full(struct vis_info *info) 537 - { 538 - struct vis_packet *packet; 539 - packet = (struct vis_packet *)info->skb_packet->data; 540 - 541 - if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry) 542 - < packet->entries + 1) 543 - return true; 544 - return false; 545 - } 546 - 547 - /* generates a packet of own vis data, 548 - * returns 0 on success, -1 if no packet could be generated */ 549 - static int generate_vis_packet(struct bat_priv *bat_priv) 550 - { 551 - HASHIT(hashit_local); 552 - HASHIT(hashit_global); 553 - struct element_t *bucket; 554 - struct orig_node *orig_node; 555 - struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info; 556 - struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; 557 - struct vis_info_entry *entry; 558 - struct hna_local_entry *hna_local_entry; 559 - int best_tq = -1; 560 - 561 - info->first_seen = jiffies; 562 - packet->vis_type = atomic_read(&bat_priv->vis_mode); 563 - 564 - spin_lock_bh(&bat_priv->orig_hash_lock); 565 - memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); 566 - packet->ttl = TTL; 567 - packet->seqno = htonl(ntohl(packet->seqno) + 1); 568 - packet->entries = 0; 569 - skb_trim(info->skb_packet, sizeof(struct vis_packet)); 570 - 571 - if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) { 572 - best_tq = find_best_vis_server(bat_priv, info); 573 - 574 - if (best_tq < 0) { 575 - spin_unlock_bh(&bat_priv->orig_hash_lock); 576 - return -1; 577 - } 578 - } 579 - 580 - while (hash_iterate(bat_priv->orig_hash, &hashit_global)) { 581 - bucket = hlist_entry(hashit_global.walk, struct element_t, 582 - hlist); 583 - orig_node = bucket->data; 584 - 585 - if (!orig_node->router) 586 - continue; 587 - 588 - if (!compare_orig(orig_node->router->addr, orig_node->orig)) 589 - continue; 590 - 591 - if (orig_node->router->if_incoming->if_status != IF_ACTIVE) 592 - continue; 593 - 594 - if (orig_node->router->tq_avg < 1) 595 - continue; 596 - 597 - /* fill one entry into buffer. */ 598 - entry = (struct vis_info_entry *) 599 - skb_put(info->skb_packet, sizeof(*entry)); 600 - memcpy(entry->src, 601 - orig_node->router->if_incoming->net_dev->dev_addr, 602 - ETH_ALEN); 603 - memcpy(entry->dest, orig_node->orig, ETH_ALEN); 604 - entry->quality = orig_node->router->tq_avg; 605 - packet->entries++; 606 - 607 - if (vis_packet_full(info)) { 608 - spin_unlock_bh(&bat_priv->orig_hash_lock); 609 - return 0; 610 - } 611 - } 612 - 613 - spin_unlock_bh(&bat_priv->orig_hash_lock); 614 - 615 - spin_lock_bh(&bat_priv->hna_lhash_lock); 616 - while (hash_iterate(bat_priv->hna_local_hash, &hashit_local)) { 617 - bucket = hlist_entry(hashit_local.walk, struct element_t, 618 - hlist); 619 - hna_local_entry = bucket->data; 620 - entry = (struct vis_info_entry *)skb_put(info->skb_packet, 621 - sizeof(*entry)); 622 - memset(entry->src, 0, ETH_ALEN); 623 - memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN); 624 - entry->quality = 0; /* 0 means HNA */ 625 - packet->entries++; 626 - 627 - if (vis_packet_full(info)) { 628 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 629 - return 0; 630 - } 631 - } 632 - 633 - spin_unlock_bh(&bat_priv->hna_lhash_lock); 634 - return 0; 635 - } 636 - 637 - /* free old vis packets. Must be called with this vis_hash_lock 638 - * held */ 639 - static void purge_vis_packets(struct bat_priv *bat_priv) 640 - { 641 - HASHIT(hashit); 642 - struct element_t *bucket; 643 - struct vis_info *info; 644 - 645 - while (hash_iterate(bat_priv->vis_hash, &hashit)) { 646 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 647 - info = bucket->data; 648 - 649 - /* never purge own data. */ 650 - if (info == bat_priv->my_vis_info) 651 - continue; 652 - 653 - if (time_after(jiffies, 654 - info->first_seen + VIS_TIMEOUT * HZ)) { 655 - hash_remove_bucket(bat_priv->vis_hash, &hashit); 656 - send_list_del(info); 657 - kref_put(&info->refcount, free_info); 658 - } 659 - } 660 - } 661 - 662 - static void broadcast_vis_packet(struct bat_priv *bat_priv, 663 - struct vis_info *info) 664 - { 665 - HASHIT(hashit); 666 - struct element_t *bucket; 667 - struct orig_node *orig_node; 668 - struct vis_packet *packet; 669 - struct sk_buff *skb; 670 - struct batman_if *batman_if; 671 - uint8_t dstaddr[ETH_ALEN]; 672 - 673 - 674 - spin_lock_bh(&bat_priv->orig_hash_lock); 675 - packet = (struct vis_packet *)info->skb_packet->data; 676 - 677 - /* send to all routers in range. */ 678 - while (hash_iterate(bat_priv->orig_hash, &hashit)) { 679 - bucket = hlist_entry(hashit.walk, struct element_t, hlist); 680 - orig_node = bucket->data; 681 - 682 - /* if it's a vis server and reachable, send it. */ 683 - if ((!orig_node) || (!orig_node->router)) 684 - continue; 685 - if (!(orig_node->flags & VIS_SERVER)) 686 - continue; 687 - /* don't send it if we already received the packet from 688 - * this node. */ 689 - if (recv_list_is_in(bat_priv, &info->recv_list, 690 - orig_node->orig)) 691 - continue; 692 - 693 - memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); 694 - batman_if = orig_node->router->if_incoming; 695 - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 696 - spin_unlock_bh(&bat_priv->orig_hash_lock); 697 - 698 - skb = skb_clone(info->skb_packet, GFP_ATOMIC); 699 - if (skb) 700 - send_skb_packet(skb, batman_if, dstaddr); 701 - 702 - spin_lock_bh(&bat_priv->orig_hash_lock); 703 - 704 - } 705 - 706 - spin_unlock_bh(&bat_priv->orig_hash_lock); 707 - } 708 - 709 - static void unicast_vis_packet(struct bat_priv *bat_priv, 710 - struct vis_info *info) 711 - { 712 - struct orig_node *orig_node; 713 - struct sk_buff *skb; 714 - struct vis_packet *packet; 715 - struct batman_if *batman_if; 716 - uint8_t dstaddr[ETH_ALEN]; 717 - 718 - spin_lock_bh(&bat_priv->orig_hash_lock); 719 - packet = (struct vis_packet *)info->skb_packet->data; 720 - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, 721 - compare_orig, choose_orig, 722 - packet->target_orig)); 723 - 724 - if ((!orig_node) || (!orig_node->router)) 725 - goto out; 726 - 727 - /* don't lock while sending the packets ... we therefore 728 - * copy the required data before sending */ 729 - batman_if = orig_node->router->if_incoming; 730 - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 731 - spin_unlock_bh(&bat_priv->orig_hash_lock); 732 - 733 - skb = skb_clone(info->skb_packet, GFP_ATOMIC); 734 - if (skb) 735 - send_skb_packet(skb, batman_if, dstaddr); 736 - 737 - return; 738 - 739 - out: 740 - spin_unlock_bh(&bat_priv->orig_hash_lock); 741 - } 742 - 743 - /* only send one vis packet. called from send_vis_packets() */ 744 - static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) 745 - { 746 - struct vis_packet *packet; 747 - 748 - packet = (struct vis_packet *)info->skb_packet->data; 749 - if (packet->ttl < 2) { 750 - pr_debug("Error - can't send vis packet: ttl exceeded\n"); 751 - return; 752 - } 753 - 754 - memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr, 755 - ETH_ALEN); 756 - packet->ttl--; 757 - 758 - if (is_broadcast_ether_addr(packet->target_orig)) 759 - broadcast_vis_packet(bat_priv, info); 760 - else 761 - unicast_vis_packet(bat_priv, info); 762 - packet->ttl++; /* restore TTL */ 763 - } 764 - 765 - /* called from timer; send (and maybe generate) vis packet. */ 766 - static void send_vis_packets(struct work_struct *work) 767 - { 768 - struct delayed_work *delayed_work = 769 - container_of(work, struct delayed_work, work); 770 - struct bat_priv *bat_priv = 771 - container_of(delayed_work, struct bat_priv, vis_work); 772 - struct vis_info *info, *temp; 773 - 774 - spin_lock_bh(&bat_priv->vis_hash_lock); 775 - purge_vis_packets(bat_priv); 776 - 777 - if (generate_vis_packet(bat_priv) == 0) { 778 - /* schedule if generation was successful */ 779 - send_list_add(bat_priv, bat_priv->my_vis_info); 780 - } 781 - 782 - list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list, 783 - send_list) { 784 - 785 - kref_get(&info->refcount); 786 - spin_unlock_bh(&bat_priv->vis_hash_lock); 787 - 788 - if (bat_priv->primary_if) 789 - send_vis_packet(bat_priv, info); 790 - 791 - spin_lock_bh(&bat_priv->vis_hash_lock); 792 - send_list_del(info); 793 - kref_put(&info->refcount, free_info); 794 - } 795 - spin_unlock_bh(&bat_priv->vis_hash_lock); 796 - start_vis_timer(bat_priv); 797 - } 798 - 799 - /* init the vis server. this may only be called when if_list is already 800 - * initialized (e.g. bat0 is initialized, interfaces have been added) */ 801 - int vis_init(struct bat_priv *bat_priv) 802 - { 803 - struct vis_packet *packet; 804 - int hash_added; 805 - 806 - if (bat_priv->vis_hash) 807 - return 1; 808 - 809 - spin_lock_bh(&bat_priv->vis_hash_lock); 810 - 811 - bat_priv->vis_hash = hash_new(256); 812 - if (!bat_priv->vis_hash) { 813 - pr_err("Can't initialize vis_hash\n"); 814 - goto err; 815 - } 816 - 817 - bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC); 818 - if (!bat_priv->my_vis_info) { 819 - pr_err("Can't initialize vis packet\n"); 820 - goto err; 821 - } 822 - 823 - bat_priv->my_vis_info->skb_packet = dev_alloc_skb( 824 - sizeof(struct vis_packet) + 825 - MAX_VIS_PACKET_SIZE + 826 - sizeof(struct ethhdr)); 827 - if (!bat_priv->my_vis_info->skb_packet) 828 - goto free_info; 829 - 830 - skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr)); 831 - packet = (struct vis_packet *)skb_put( 832 - bat_priv->my_vis_info->skb_packet, 833 - sizeof(struct vis_packet)); 834 - 835 - /* prefill the vis info */ 836 - bat_priv->my_vis_info->first_seen = jiffies - 837 - msecs_to_jiffies(VIS_INTERVAL); 838 - INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list); 839 - INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list); 840 - kref_init(&bat_priv->my_vis_info->refcount); 841 - bat_priv->my_vis_info->bat_priv = bat_priv; 842 - packet->version = COMPAT_VERSION; 843 - packet->packet_type = BAT_VIS; 844 - packet->ttl = TTL; 845 - packet->seqno = 0; 846 - packet->entries = 0; 847 - 848 - INIT_LIST_HEAD(&bat_priv->vis_send_list); 849 - 850 - hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, 851 - bat_priv->my_vis_info); 852 - if (hash_added < 0) { 853 - pr_err("Can't add own vis packet into hash\n"); 854 - /* not in hash, need to remove it manually. */ 855 - kref_put(&bat_priv->my_vis_info->refcount, free_info); 856 - goto err; 857 - } 858 - 859 - spin_unlock_bh(&bat_priv->vis_hash_lock); 860 - start_vis_timer(bat_priv); 861 - return 1; 862 - 863 - free_info: 864 - kfree(bat_priv->my_vis_info); 865 - bat_priv->my_vis_info = NULL; 866 - err: 867 - spin_unlock_bh(&bat_priv->vis_hash_lock); 868 - vis_quit(bat_priv); 869 - return 0; 870 - } 871 - 872 - /* Decrease the reference count on a hash item info */ 873 - static void free_info_ref(void *data, void *arg) 874 - { 875 - struct vis_info *info = data; 876 - 877 - send_list_del(info); 878 - kref_put(&info->refcount, free_info); 879 - } 880 - 881 - /* shutdown vis-server */ 882 - void vis_quit(struct bat_priv *bat_priv) 883 - { 884 - if (!bat_priv->vis_hash) 885 - return; 886 - 887 - cancel_delayed_work_sync(&bat_priv->vis_work); 888 - 889 - spin_lock_bh(&bat_priv->vis_hash_lock); 890 - /* properly remove, kill timers ... */ 891 - hash_delete(bat_priv->vis_hash, free_info_ref, NULL); 892 - bat_priv->vis_hash = NULL; 893 - bat_priv->my_vis_info = NULL; 894 - spin_unlock_bh(&bat_priv->vis_hash_lock); 895 - } 896 - 897 - /* schedule packets for (re)transmission */ 898 - static void start_vis_timer(struct bat_priv *bat_priv) 899 - { 900 - INIT_DELAYED_WORK(&bat_priv->vis_work, send_vis_packets); 901 - queue_delayed_work(bat_event_workqueue, &bat_priv->vis_work, 902 - msecs_to_jiffies(VIS_INTERVAL)); 903 - }
-37
drivers/staging/batman-adv/vis.h
··· 1 - /* 2 - * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: 3 - * 4 - * Simon Wunderlich, Marek Lindner 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of version 2 of the GNU General Public 8 - * License as published by the Free Software Foundation. 9 - * 10 - * This program is distributed in the hope that it will be useful, but 11 - * WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - * General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 - * 02110-1301, USA 19 - * 20 - */ 21 - 22 - #ifndef _NET_BATMAN_ADV_VIS_H_ 23 - #define _NET_BATMAN_ADV_VIS_H_ 24 - 25 - #define VIS_TIMEOUT 200 /* timeout of vis packets in seconds */ 26 - 27 - int vis_seq_print_text(struct seq_file *seq, void *offset); 28 - void receive_server_sync_packet(struct bat_priv *bat_priv, 29 - struct vis_packet *vis_packet, 30 - int vis_info_len); 31 - void receive_client_update_packet(struct bat_priv *bat_priv, 32 - struct vis_packet *vis_packet, 33 - int vis_info_len); 34 - int vis_init(struct bat_priv *bat_priv); 35 - void vis_quit(struct bat_priv *bat_priv); 36 - 37 - #endif /* _NET_BATMAN_ADV_VIS_H_ */