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

Merge branch 'batman-adv/next' of git://git.open-mesh.org/linux-merge

+1281 -1275
+4 -4
Documentation/networking/batman-adv.txt
··· 1 - [state: 17-04-2011] 1 + [state: 21-08-2011] 2 2 3 3 BATMAN-ADV 4 4 ---------- ··· 68 68 folder: 69 69 70 70 # ls /sys/class/net/bat0/mesh/ 71 - # aggregated_ogms gw_bandwidth hop_penalty 72 - # bonding gw_mode orig_interval 73 - # fragmentation gw_sel_class vis_mode 71 + # aggregated_ogms fragmentation gw_sel_class vis_mode 72 + # ap_isolation gw_bandwidth hop_penalty 73 + # bonding gw_mode orig_interval 74 74 75 75 76 76 There is a special folder for debugging information:
+1 -1
net/batman-adv/Makefile
··· 19 19 # 20 20 21 21 obj-$(CONFIG_BATMAN_ADV) += batman-adv.o 22 - batman-adv-y += aggregation.o 23 22 batman-adv-y += bat_debugfs.o 23 + batman-adv-y += bat_iv_ogm.o 24 24 batman-adv-y += bat_sysfs.o 25 25 batman-adv-y += bitarray.o 26 26 batman-adv-y += gateway_client.o
-293
net/batman-adv/aggregation.c
··· 1 - /* 2 - * Copyright (C) 2007-2011 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 "aggregation.h" 25 - #include "send.h" 26 - #include "routing.h" 27 - #include "hard-interface.h" 28 - 29 - /* return true if new_packet can be aggregated with forw_packet */ 30 - static bool can_aggregate_with(const struct batman_packet *new_batman_packet, 31 - struct bat_priv *bat_priv, 32 - int packet_len, 33 - unsigned long send_time, 34 - bool directlink, 35 - const struct hard_iface *if_incoming, 36 - const struct forw_packet *forw_packet) 37 - { 38 - struct batman_packet *batman_packet = 39 - (struct batman_packet *)forw_packet->skb->data; 40 - int aggregated_bytes = forw_packet->packet_len + packet_len; 41 - struct hard_iface *primary_if = NULL; 42 - bool res = false; 43 - 44 - /** 45 - * we can aggregate the current packet to this aggregated packet 46 - * if: 47 - * 48 - * - the send time is within our MAX_AGGREGATION_MS time 49 - * - the resulting packet wont be bigger than 50 - * MAX_AGGREGATION_BYTES 51 - */ 52 - 53 - if (time_before(send_time, forw_packet->send_time) && 54 - time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), 55 - forw_packet->send_time) && 56 - (aggregated_bytes <= MAX_AGGREGATION_BYTES)) { 57 - 58 - /** 59 - * check aggregation compatibility 60 - * -> direct link packets are broadcasted on 61 - * their interface only 62 - * -> aggregate packet if the current packet is 63 - * a "global" packet as well as the base 64 - * packet 65 - */ 66 - 67 - primary_if = primary_if_get_selected(bat_priv); 68 - if (!primary_if) 69 - goto out; 70 - 71 - /* packets without direct link flag and high TTL 72 - * are flooded through the net */ 73 - if ((!directlink) && 74 - (!(batman_packet->flags & DIRECTLINK)) && 75 - (batman_packet->ttl != 1) && 76 - 77 - /* own packets originating non-primary 78 - * interfaces leave only that interface */ 79 - ((!forw_packet->own) || 80 - (forw_packet->if_incoming == primary_if))) { 81 - res = true; 82 - goto out; 83 - } 84 - 85 - /* if the incoming packet is sent via this one 86 - * interface only - we still can aggregate */ 87 - if ((directlink) && 88 - (new_batman_packet->ttl == 1) && 89 - (forw_packet->if_incoming == if_incoming) && 90 - 91 - /* packets from direct neighbors or 92 - * own secondary interface packets 93 - * (= secondary interface packets in general) */ 94 - (batman_packet->flags & DIRECTLINK || 95 - (forw_packet->own && 96 - forw_packet->if_incoming != primary_if))) { 97 - res = true; 98 - goto out; 99 - } 100 - } 101 - 102 - out: 103 - if (primary_if) 104 - hardif_free_ref(primary_if); 105 - return res; 106 - } 107 - 108 - /* create a new aggregated packet and add this packet to it */ 109 - static void new_aggregated_packet(const unsigned char *packet_buff, 110 - int packet_len, unsigned long send_time, 111 - bool direct_link, 112 - struct hard_iface *if_incoming, 113 - int own_packet) 114 - { 115 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 116 - struct forw_packet *forw_packet_aggr; 117 - unsigned char *skb_buff; 118 - 119 - if (!atomic_inc_not_zero(&if_incoming->refcount)) 120 - return; 121 - 122 - /* own packet should always be scheduled */ 123 - if (!own_packet) { 124 - if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) { 125 - bat_dbg(DBG_BATMAN, bat_priv, 126 - "batman packet queue full\n"); 127 - goto out; 128 - } 129 - } 130 - 131 - forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC); 132 - if (!forw_packet_aggr) { 133 - if (!own_packet) 134 - atomic_inc(&bat_priv->batman_queue_left); 135 - goto out; 136 - } 137 - 138 - if ((atomic_read(&bat_priv->aggregated_ogms)) && 139 - (packet_len < MAX_AGGREGATION_BYTES)) 140 - forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES + 141 - sizeof(struct ethhdr)); 142 - else 143 - forw_packet_aggr->skb = dev_alloc_skb(packet_len + 144 - sizeof(struct ethhdr)); 145 - 146 - if (!forw_packet_aggr->skb) { 147 - if (!own_packet) 148 - atomic_inc(&bat_priv->batman_queue_left); 149 - kfree(forw_packet_aggr); 150 - goto out; 151 - } 152 - skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr)); 153 - 154 - INIT_HLIST_NODE(&forw_packet_aggr->list); 155 - 156 - skb_buff = skb_put(forw_packet_aggr->skb, packet_len); 157 - forw_packet_aggr->packet_len = packet_len; 158 - memcpy(skb_buff, packet_buff, packet_len); 159 - 160 - forw_packet_aggr->own = own_packet; 161 - forw_packet_aggr->if_incoming = if_incoming; 162 - forw_packet_aggr->num_packets = 0; 163 - forw_packet_aggr->direct_link_flags = NO_FLAGS; 164 - forw_packet_aggr->send_time = send_time; 165 - 166 - /* save packet direct link flag status */ 167 - if (direct_link) 168 - forw_packet_aggr->direct_link_flags |= 1; 169 - 170 - /* add new packet to packet list */ 171 - spin_lock_bh(&bat_priv->forw_bat_list_lock); 172 - hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list); 173 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 174 - 175 - /* start timer for this packet */ 176 - INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, 177 - send_outstanding_bat_packet); 178 - queue_delayed_work(bat_event_workqueue, 179 - &forw_packet_aggr->delayed_work, 180 - send_time - jiffies); 181 - 182 - return; 183 - out: 184 - hardif_free_ref(if_incoming); 185 - } 186 - 187 - /* aggregate a new packet into the existing aggregation */ 188 - static void aggregate(struct forw_packet *forw_packet_aggr, 189 - const unsigned char *packet_buff, int packet_len, 190 - bool direct_link) 191 - { 192 - unsigned char *skb_buff; 193 - 194 - skb_buff = skb_put(forw_packet_aggr->skb, packet_len); 195 - memcpy(skb_buff, packet_buff, packet_len); 196 - forw_packet_aggr->packet_len += packet_len; 197 - forw_packet_aggr->num_packets++; 198 - 199 - /* save packet direct link flag status */ 200 - if (direct_link) 201 - forw_packet_aggr->direct_link_flags |= 202 - (1 << forw_packet_aggr->num_packets); 203 - } 204 - 205 - void add_bat_packet_to_list(struct bat_priv *bat_priv, 206 - unsigned char *packet_buff, int packet_len, 207 - struct hard_iface *if_incoming, int own_packet, 208 - unsigned long send_time) 209 - { 210 - /** 211 - * _aggr -> pointer to the packet we want to aggregate with 212 - * _pos -> pointer to the position in the queue 213 - */ 214 - struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL; 215 - struct hlist_node *tmp_node; 216 - struct batman_packet *batman_packet = 217 - (struct batman_packet *)packet_buff; 218 - bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; 219 - 220 - /* find position for the packet in the forward queue */ 221 - spin_lock_bh(&bat_priv->forw_bat_list_lock); 222 - /* own packets are not to be aggregated */ 223 - if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { 224 - hlist_for_each_entry(forw_packet_pos, tmp_node, 225 - &bat_priv->forw_bat_list, list) { 226 - if (can_aggregate_with(batman_packet, 227 - bat_priv, 228 - packet_len, 229 - send_time, 230 - direct_link, 231 - if_incoming, 232 - forw_packet_pos)) { 233 - forw_packet_aggr = forw_packet_pos; 234 - break; 235 - } 236 - } 237 - } 238 - 239 - /* nothing to aggregate with - either aggregation disabled or no 240 - * suitable aggregation packet found */ 241 - if (!forw_packet_aggr) { 242 - /* the following section can run without the lock */ 243 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 244 - 245 - /** 246 - * if we could not aggregate this packet with one of the others 247 - * we hold it back for a while, so that it might be aggregated 248 - * later on 249 - */ 250 - if ((!own_packet) && 251 - (atomic_read(&bat_priv->aggregated_ogms))) 252 - send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); 253 - 254 - new_aggregated_packet(packet_buff, packet_len, 255 - send_time, direct_link, 256 - if_incoming, own_packet); 257 - } else { 258 - aggregate(forw_packet_aggr, 259 - packet_buff, packet_len, 260 - direct_link); 261 - spin_unlock_bh(&bat_priv->forw_bat_list_lock); 262 - } 263 - } 264 - 265 - /* unpack the aggregated packets and process them one by one */ 266 - void receive_aggr_bat_packet(const struct ethhdr *ethhdr, 267 - unsigned char *packet_buff, int packet_len, 268 - struct hard_iface *if_incoming) 269 - { 270 - struct batman_packet *batman_packet; 271 - int buff_pos = 0; 272 - unsigned char *tt_buff; 273 - 274 - batman_packet = (struct batman_packet *)packet_buff; 275 - 276 - do { 277 - /* network to host order for our 32bit seqno and the 278 - orig_interval */ 279 - batman_packet->seqno = ntohl(batman_packet->seqno); 280 - batman_packet->tt_crc = ntohs(batman_packet->tt_crc); 281 - 282 - tt_buff = packet_buff + buff_pos + BAT_PACKET_LEN; 283 - 284 - receive_bat_packet(ethhdr, batman_packet, tt_buff, if_incoming); 285 - 286 - buff_pos += BAT_PACKET_LEN + 287 - tt_len(batman_packet->tt_num_changes); 288 - 289 - batman_packet = (struct batman_packet *) 290 - (packet_buff + buff_pos); 291 - } while (aggregated_packet(buff_pos, packet_len, 292 - batman_packet->tt_num_changes)); 293 - }
+10 -20
net/batman-adv/aggregation.h net/batman-adv/bat_ogm.h
··· 19 19 * 20 20 */ 21 21 22 - #ifndef _NET_BATMAN_ADV_AGGREGATION_H_ 23 - #define _NET_BATMAN_ADV_AGGREGATION_H_ 22 + #ifndef _NET_BATMAN_ADV_OGM_H_ 23 + #define _NET_BATMAN_ADV_OGM_H_ 24 24 25 25 #include "main.h" 26 26 27 - /* is there another aggregated packet here? */ 28 - static inline int aggregated_packet(int buff_pos, int packet_len, 29 - int tt_num_changes) 30 - { 31 - int next_buff_pos = buff_pos + BAT_PACKET_LEN + tt_len(tt_num_changes); 27 + void bat_ogm_init(struct hard_iface *hard_iface); 28 + void bat_ogm_init_primary(struct hard_iface *hard_iface); 29 + void bat_ogm_update_mac(struct hard_iface *hard_iface); 30 + void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes); 31 + void bat_ogm_emit(struct forw_packet *forw_packet); 32 + void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff, 33 + int packet_len, struct hard_iface *if_incoming); 32 34 33 - return (next_buff_pos <= packet_len) && 34 - (next_buff_pos <= MAX_AGGREGATION_BYTES); 35 - } 36 - 37 - void add_bat_packet_to_list(struct bat_priv *bat_priv, 38 - unsigned char *packet_buff, int packet_len, 39 - struct hard_iface *if_incoming, int own_packet, 40 - unsigned long send_time); 41 - void receive_aggr_bat_packet(const struct ethhdr *ethhdr, 42 - unsigned char *packet_buff, int packet_len, 43 - struct hard_iface *if_incoming); 44 - 45 - #endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */ 35 + #endif /* _NET_BATMAN_ADV_OGM_H_ */
+1170
net/batman-adv/bat_iv_ogm.c
··· 1 + /* 2 + * Copyright (C) 2007-2011 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_ogm.h" 24 + #include "translation-table.h" 25 + #include "ring_buffer.h" 26 + #include "originator.h" 27 + #include "routing.h" 28 + #include "gateway_common.h" 29 + #include "gateway_client.h" 30 + #include "hard-interface.h" 31 + #include "send.h" 32 + 33 + void bat_ogm_init(struct hard_iface *hard_iface) 34 + { 35 + struct batman_ogm_packet *batman_ogm_packet; 36 + 37 + hard_iface->packet_len = BATMAN_OGM_LEN; 38 + hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC); 39 + 40 + batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; 41 + batman_ogm_packet->packet_type = BAT_OGM; 42 + batman_ogm_packet->version = COMPAT_VERSION; 43 + batman_ogm_packet->flags = NO_FLAGS; 44 + batman_ogm_packet->ttl = 2; 45 + batman_ogm_packet->tq = TQ_MAX_VALUE; 46 + batman_ogm_packet->tt_num_changes = 0; 47 + batman_ogm_packet->ttvn = 0; 48 + } 49 + 50 + void bat_ogm_init_primary(struct hard_iface *hard_iface) 51 + { 52 + struct batman_ogm_packet *batman_ogm_packet; 53 + 54 + batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; 55 + batman_ogm_packet->flags = PRIMARIES_FIRST_HOP; 56 + batman_ogm_packet->ttl = TTL; 57 + } 58 + 59 + void bat_ogm_update_mac(struct hard_iface *hard_iface) 60 + { 61 + struct batman_ogm_packet *batman_ogm_packet; 62 + 63 + batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; 64 + memcpy(batman_ogm_packet->orig, 65 + hard_iface->net_dev->dev_addr, ETH_ALEN); 66 + memcpy(batman_ogm_packet->prev_sender, 67 + hard_iface->net_dev->dev_addr, ETH_ALEN); 68 + } 69 + 70 + /* when do we schedule our own ogm to be sent */ 71 + static unsigned long bat_ogm_emit_send_time(const struct bat_priv *bat_priv) 72 + { 73 + return jiffies + msecs_to_jiffies( 74 + atomic_read(&bat_priv->orig_interval) - 75 + JITTER + (random32() % 2*JITTER)); 76 + } 77 + 78 + /* when do we schedule a ogm packet to be sent */ 79 + static unsigned long bat_ogm_fwd_send_time(void) 80 + { 81 + return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); 82 + } 83 + 84 + /* apply hop penalty for a normal link */ 85 + static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv) 86 + { 87 + int hop_penalty = atomic_read(&bat_priv->hop_penalty); 88 + return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); 89 + } 90 + 91 + /* is there another aggregated packet here? */ 92 + static int bat_ogm_aggr_packet(int buff_pos, int packet_len, 93 + int tt_num_changes) 94 + { 95 + int next_buff_pos = buff_pos + BATMAN_OGM_LEN + tt_len(tt_num_changes); 96 + 97 + return (next_buff_pos <= packet_len) && 98 + (next_buff_pos <= MAX_AGGREGATION_BYTES); 99 + } 100 + 101 + /* send a batman ogm to a given interface */ 102 + static void bat_ogm_send_to_if(struct forw_packet *forw_packet, 103 + struct hard_iface *hard_iface) 104 + { 105 + struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 106 + char *fwd_str; 107 + uint8_t packet_num; 108 + int16_t buff_pos; 109 + struct batman_ogm_packet *batman_ogm_packet; 110 + struct sk_buff *skb; 111 + 112 + if (hard_iface->if_status != IF_ACTIVE) 113 + return; 114 + 115 + packet_num = 0; 116 + buff_pos = 0; 117 + batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data; 118 + 119 + /* adjust all flags and log packets */ 120 + while (bat_ogm_aggr_packet(buff_pos, forw_packet->packet_len, 121 + batman_ogm_packet->tt_num_changes)) { 122 + 123 + /* we might have aggregated direct link packets with an 124 + * ordinary base packet */ 125 + if ((forw_packet->direct_link_flags & (1 << packet_num)) && 126 + (forw_packet->if_incoming == hard_iface)) 127 + batman_ogm_packet->flags |= DIRECTLINK; 128 + else 129 + batman_ogm_packet->flags &= ~DIRECTLINK; 130 + 131 + fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? 132 + "Sending own" : 133 + "Forwarding")); 134 + bat_dbg(DBG_BATMAN, bat_priv, 135 + "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," 136 + " IDF %s, ttvn %d) on interface %s [%pM]\n", 137 + fwd_str, (packet_num > 0 ? "aggregated " : ""), 138 + batman_ogm_packet->orig, 139 + ntohl(batman_ogm_packet->seqno), 140 + batman_ogm_packet->tq, batman_ogm_packet->ttl, 141 + (batman_ogm_packet->flags & DIRECTLINK ? 142 + "on" : "off"), 143 + batman_ogm_packet->ttvn, hard_iface->net_dev->name, 144 + hard_iface->net_dev->dev_addr); 145 + 146 + buff_pos += BATMAN_OGM_LEN + 147 + tt_len(batman_ogm_packet->tt_num_changes); 148 + packet_num++; 149 + batman_ogm_packet = (struct batman_ogm_packet *) 150 + (forw_packet->skb->data + buff_pos); 151 + } 152 + 153 + /* create clone because function is called more than once */ 154 + skb = skb_clone(forw_packet->skb, GFP_ATOMIC); 155 + if (skb) 156 + send_skb_packet(skb, hard_iface, broadcast_addr); 157 + } 158 + 159 + /* send a batman ogm packet */ 160 + void bat_ogm_emit(struct forw_packet *forw_packet) 161 + { 162 + struct hard_iface *hard_iface; 163 + struct net_device *soft_iface; 164 + struct bat_priv *bat_priv; 165 + struct hard_iface *primary_if = NULL; 166 + struct batman_ogm_packet *batman_ogm_packet; 167 + unsigned char directlink; 168 + 169 + batman_ogm_packet = (struct batman_ogm_packet *) 170 + (forw_packet->skb->data); 171 + directlink = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0); 172 + 173 + if (!forw_packet->if_incoming) { 174 + pr_err("Error - can't forward packet: incoming iface not " 175 + "specified\n"); 176 + goto out; 177 + } 178 + 179 + soft_iface = forw_packet->if_incoming->soft_iface; 180 + bat_priv = netdev_priv(soft_iface); 181 + 182 + if (forw_packet->if_incoming->if_status != IF_ACTIVE) 183 + goto out; 184 + 185 + primary_if = primary_if_get_selected(bat_priv); 186 + if (!primary_if) 187 + goto out; 188 + 189 + /* multihomed peer assumed */ 190 + /* non-primary OGMs are only broadcasted on their interface */ 191 + if ((directlink && (batman_ogm_packet->ttl == 1)) || 192 + (forw_packet->own && (forw_packet->if_incoming != primary_if))) { 193 + 194 + /* FIXME: what about aggregated packets ? */ 195 + bat_dbg(DBG_BATMAN, bat_priv, 196 + "%s packet (originator %pM, seqno %d, TTL %d) " 197 + "on interface %s [%pM]\n", 198 + (forw_packet->own ? "Sending own" : "Forwarding"), 199 + batman_ogm_packet->orig, 200 + ntohl(batman_ogm_packet->seqno), 201 + batman_ogm_packet->ttl, 202 + forw_packet->if_incoming->net_dev->name, 203 + forw_packet->if_incoming->net_dev->dev_addr); 204 + 205 + /* skb is only used once and than forw_packet is free'd */ 206 + send_skb_packet(forw_packet->skb, forw_packet->if_incoming, 207 + broadcast_addr); 208 + forw_packet->skb = NULL; 209 + 210 + goto out; 211 + } 212 + 213 + /* broadcast on every interface */ 214 + rcu_read_lock(); 215 + list_for_each_entry_rcu(hard_iface, &hardif_list, list) { 216 + if (hard_iface->soft_iface != soft_iface) 217 + continue; 218 + 219 + bat_ogm_send_to_if(forw_packet, hard_iface); 220 + } 221 + rcu_read_unlock(); 222 + 223 + out: 224 + if (primary_if) 225 + hardif_free_ref(primary_if); 226 + } 227 + 228 + /* return true if new_packet can be aggregated with forw_packet */ 229 + static bool bat_ogm_can_aggregate(const struct batman_ogm_packet 230 + *new_batman_ogm_packet, 231 + struct bat_priv *bat_priv, 232 + int packet_len, unsigned long send_time, 233 + bool directlink, 234 + const struct hard_iface *if_incoming, 235 + const struct forw_packet *forw_packet) 236 + { 237 + struct batman_ogm_packet *batman_ogm_packet; 238 + int aggregated_bytes = forw_packet->packet_len + packet_len; 239 + struct hard_iface *primary_if = NULL; 240 + bool res = false; 241 + 242 + batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data; 243 + 244 + /** 245 + * we can aggregate the current packet to this aggregated packet 246 + * if: 247 + * 248 + * - the send time is within our MAX_AGGREGATION_MS time 249 + * - the resulting packet wont be bigger than 250 + * MAX_AGGREGATION_BYTES 251 + */ 252 + 253 + if (time_before(send_time, forw_packet->send_time) && 254 + time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), 255 + forw_packet->send_time) && 256 + (aggregated_bytes <= MAX_AGGREGATION_BYTES)) { 257 + 258 + /** 259 + * check aggregation compatibility 260 + * -> direct link packets are broadcasted on 261 + * their interface only 262 + * -> aggregate packet if the current packet is 263 + * a "global" packet as well as the base 264 + * packet 265 + */ 266 + 267 + primary_if = primary_if_get_selected(bat_priv); 268 + if (!primary_if) 269 + goto out; 270 + 271 + /* packets without direct link flag and high TTL 272 + * are flooded through the net */ 273 + if ((!directlink) && 274 + (!(batman_ogm_packet->flags & DIRECTLINK)) && 275 + (batman_ogm_packet->ttl != 1) && 276 + 277 + /* own packets originating non-primary 278 + * interfaces leave only that interface */ 279 + ((!forw_packet->own) || 280 + (forw_packet->if_incoming == primary_if))) { 281 + res = true; 282 + goto out; 283 + } 284 + 285 + /* if the incoming packet is sent via this one 286 + * interface only - we still can aggregate */ 287 + if ((directlink) && 288 + (new_batman_ogm_packet->ttl == 1) && 289 + (forw_packet->if_incoming == if_incoming) && 290 + 291 + /* packets from direct neighbors or 292 + * own secondary interface packets 293 + * (= secondary interface packets in general) */ 294 + (batman_ogm_packet->flags & DIRECTLINK || 295 + (forw_packet->own && 296 + forw_packet->if_incoming != primary_if))) { 297 + res = true; 298 + goto out; 299 + } 300 + } 301 + 302 + out: 303 + if (primary_if) 304 + hardif_free_ref(primary_if); 305 + return res; 306 + } 307 + 308 + /* create a new aggregated packet and add this packet to it */ 309 + static void bat_ogm_aggregate_new(const unsigned char *packet_buff, 310 + int packet_len, unsigned long send_time, 311 + bool direct_link, 312 + struct hard_iface *if_incoming, 313 + int own_packet) 314 + { 315 + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 316 + struct forw_packet *forw_packet_aggr; 317 + unsigned char *skb_buff; 318 + 319 + if (!atomic_inc_not_zero(&if_incoming->refcount)) 320 + return; 321 + 322 + /* own packet should always be scheduled */ 323 + if (!own_packet) { 324 + if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) { 325 + bat_dbg(DBG_BATMAN, bat_priv, 326 + "batman packet queue full\n"); 327 + goto out; 328 + } 329 + } 330 + 331 + forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC); 332 + if (!forw_packet_aggr) { 333 + if (!own_packet) 334 + atomic_inc(&bat_priv->batman_queue_left); 335 + goto out; 336 + } 337 + 338 + if ((atomic_read(&bat_priv->aggregated_ogms)) && 339 + (packet_len < MAX_AGGREGATION_BYTES)) 340 + forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES + 341 + sizeof(struct ethhdr)); 342 + else 343 + forw_packet_aggr->skb = dev_alloc_skb(packet_len + 344 + sizeof(struct ethhdr)); 345 + 346 + if (!forw_packet_aggr->skb) { 347 + if (!own_packet) 348 + atomic_inc(&bat_priv->batman_queue_left); 349 + kfree(forw_packet_aggr); 350 + goto out; 351 + } 352 + skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr)); 353 + 354 + INIT_HLIST_NODE(&forw_packet_aggr->list); 355 + 356 + skb_buff = skb_put(forw_packet_aggr->skb, packet_len); 357 + forw_packet_aggr->packet_len = packet_len; 358 + memcpy(skb_buff, packet_buff, packet_len); 359 + 360 + forw_packet_aggr->own = own_packet; 361 + forw_packet_aggr->if_incoming = if_incoming; 362 + forw_packet_aggr->num_packets = 0; 363 + forw_packet_aggr->direct_link_flags = NO_FLAGS; 364 + forw_packet_aggr->send_time = send_time; 365 + 366 + /* save packet direct link flag status */ 367 + if (direct_link) 368 + forw_packet_aggr->direct_link_flags |= 1; 369 + 370 + /* add new packet to packet list */ 371 + spin_lock_bh(&bat_priv->forw_bat_list_lock); 372 + hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list); 373 + spin_unlock_bh(&bat_priv->forw_bat_list_lock); 374 + 375 + /* start timer for this packet */ 376 + INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, 377 + send_outstanding_bat_ogm_packet); 378 + queue_delayed_work(bat_event_workqueue, 379 + &forw_packet_aggr->delayed_work, 380 + send_time - jiffies); 381 + 382 + return; 383 + out: 384 + hardif_free_ref(if_incoming); 385 + } 386 + 387 + /* aggregate a new packet into the existing ogm packet */ 388 + static void bat_ogm_aggregate(struct forw_packet *forw_packet_aggr, 389 + const unsigned char *packet_buff, 390 + int packet_len, bool direct_link) 391 + { 392 + unsigned char *skb_buff; 393 + 394 + skb_buff = skb_put(forw_packet_aggr->skb, packet_len); 395 + memcpy(skb_buff, packet_buff, packet_len); 396 + forw_packet_aggr->packet_len += packet_len; 397 + forw_packet_aggr->num_packets++; 398 + 399 + /* save packet direct link flag status */ 400 + if (direct_link) 401 + forw_packet_aggr->direct_link_flags |= 402 + (1 << forw_packet_aggr->num_packets); 403 + } 404 + 405 + static void bat_ogm_queue_add(struct bat_priv *bat_priv, 406 + unsigned char *packet_buff, 407 + int packet_len, struct hard_iface *if_incoming, 408 + int own_packet, unsigned long send_time) 409 + { 410 + /** 411 + * _aggr -> pointer to the packet we want to aggregate with 412 + * _pos -> pointer to the position in the queue 413 + */ 414 + struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL; 415 + struct hlist_node *tmp_node; 416 + struct batman_ogm_packet *batman_ogm_packet; 417 + bool direct_link; 418 + 419 + batman_ogm_packet = (struct batman_ogm_packet *)packet_buff; 420 + direct_link = batman_ogm_packet->flags & DIRECTLINK ? 1 : 0; 421 + 422 + /* find position for the packet in the forward queue */ 423 + spin_lock_bh(&bat_priv->forw_bat_list_lock); 424 + /* own packets are not to be aggregated */ 425 + if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { 426 + hlist_for_each_entry(forw_packet_pos, tmp_node, 427 + &bat_priv->forw_bat_list, list) { 428 + if (bat_ogm_can_aggregate(batman_ogm_packet, 429 + bat_priv, packet_len, 430 + send_time, direct_link, 431 + if_incoming, 432 + forw_packet_pos)) { 433 + forw_packet_aggr = forw_packet_pos; 434 + break; 435 + } 436 + } 437 + } 438 + 439 + /* nothing to aggregate with - either aggregation disabled or no 440 + * suitable aggregation packet found */ 441 + if (!forw_packet_aggr) { 442 + /* the following section can run without the lock */ 443 + spin_unlock_bh(&bat_priv->forw_bat_list_lock); 444 + 445 + /** 446 + * if we could not aggregate this packet with one of the others 447 + * we hold it back for a while, so that it might be aggregated 448 + * later on 449 + */ 450 + if ((!own_packet) && 451 + (atomic_read(&bat_priv->aggregated_ogms))) 452 + send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); 453 + 454 + bat_ogm_aggregate_new(packet_buff, packet_len, 455 + send_time, direct_link, 456 + if_incoming, own_packet); 457 + } else { 458 + bat_ogm_aggregate(forw_packet_aggr, packet_buff, packet_len, 459 + direct_link); 460 + spin_unlock_bh(&bat_priv->forw_bat_list_lock); 461 + } 462 + } 463 + 464 + static void bat_ogm_forward(struct orig_node *orig_node, 465 + const struct ethhdr *ethhdr, 466 + struct batman_ogm_packet *batman_ogm_packet, 467 + int directlink, struct hard_iface *if_incoming) 468 + { 469 + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 470 + struct neigh_node *router; 471 + uint8_t in_tq, in_ttl, tq_avg = 0; 472 + uint8_t tt_num_changes; 473 + 474 + if (batman_ogm_packet->ttl <= 1) { 475 + bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n"); 476 + return; 477 + } 478 + 479 + router = orig_node_get_router(orig_node); 480 + 481 + in_tq = batman_ogm_packet->tq; 482 + in_ttl = batman_ogm_packet->ttl; 483 + tt_num_changes = batman_ogm_packet->tt_num_changes; 484 + 485 + batman_ogm_packet->ttl--; 486 + memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); 487 + 488 + /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast 489 + * of our best tq value */ 490 + if (router && router->tq_avg != 0) { 491 + 492 + /* rebroadcast ogm of best ranking neighbor as is */ 493 + if (!compare_eth(router->addr, ethhdr->h_source)) { 494 + batman_ogm_packet->tq = router->tq_avg; 495 + 496 + if (router->last_ttl) 497 + batman_ogm_packet->ttl = router->last_ttl - 1; 498 + } 499 + 500 + tq_avg = router->tq_avg; 501 + } 502 + 503 + if (router) 504 + neigh_node_free_ref(router); 505 + 506 + /* apply hop penalty */ 507 + batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); 508 + 509 + bat_dbg(DBG_BATMAN, bat_priv, 510 + "Forwarding packet: tq_orig: %i, tq_avg: %i, " 511 + "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", 512 + in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1, 513 + batman_ogm_packet->ttl); 514 + 515 + batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); 516 + batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); 517 + 518 + /* switch of primaries first hop flag when forwarding */ 519 + batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; 520 + if (directlink) 521 + batman_ogm_packet->flags |= DIRECTLINK; 522 + else 523 + batman_ogm_packet->flags &= ~DIRECTLINK; 524 + 525 + bat_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet, 526 + BATMAN_OGM_LEN + tt_len(tt_num_changes), 527 + if_incoming, 0, bat_ogm_fwd_send_time()); 528 + } 529 + 530 + void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes) 531 + { 532 + struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 533 + struct batman_ogm_packet *batman_ogm_packet; 534 + struct hard_iface *primary_if; 535 + int vis_server; 536 + 537 + vis_server = atomic_read(&bat_priv->vis_mode); 538 + primary_if = primary_if_get_selected(bat_priv); 539 + 540 + batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; 541 + 542 + /* change sequence number to network order */ 543 + batman_ogm_packet->seqno = 544 + htonl((uint32_t)atomic_read(&hard_iface->seqno)); 545 + 546 + batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn); 547 + batman_ogm_packet->tt_crc = htons((uint16_t) 548 + atomic_read(&bat_priv->tt_crc)); 549 + if (tt_num_changes >= 0) 550 + batman_ogm_packet->tt_num_changes = tt_num_changes; 551 + 552 + if (vis_server == VIS_TYPE_SERVER_SYNC) 553 + batman_ogm_packet->flags |= VIS_SERVER; 554 + else 555 + batman_ogm_packet->flags &= ~VIS_SERVER; 556 + 557 + if ((hard_iface == primary_if) && 558 + (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) 559 + batman_ogm_packet->gw_flags = 560 + (uint8_t)atomic_read(&bat_priv->gw_bandwidth); 561 + else 562 + batman_ogm_packet->gw_flags = NO_FLAGS; 563 + 564 + atomic_inc(&hard_iface->seqno); 565 + 566 + slide_own_bcast_window(hard_iface); 567 + bat_ogm_queue_add(bat_priv, hard_iface->packet_buff, 568 + hard_iface->packet_len, hard_iface, 1, 569 + bat_ogm_emit_send_time(bat_priv)); 570 + 571 + if (primary_if) 572 + hardif_free_ref(primary_if); 573 + } 574 + 575 + static void bat_ogm_orig_update(struct bat_priv *bat_priv, 576 + struct orig_node *orig_node, 577 + const struct ethhdr *ethhdr, 578 + const struct batman_ogm_packet 579 + *batman_ogm_packet, 580 + struct hard_iface *if_incoming, 581 + const unsigned char *tt_buff, int is_duplicate) 582 + { 583 + struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 584 + struct neigh_node *router = NULL; 585 + struct orig_node *orig_node_tmp; 586 + struct hlist_node *node; 587 + uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; 588 + 589 + bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " 590 + "Searching and updating originator entry of received packet\n"); 591 + 592 + rcu_read_lock(); 593 + hlist_for_each_entry_rcu(tmp_neigh_node, node, 594 + &orig_node->neigh_list, list) { 595 + if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && 596 + (tmp_neigh_node->if_incoming == if_incoming) && 597 + atomic_inc_not_zero(&tmp_neigh_node->refcount)) { 598 + if (neigh_node) 599 + neigh_node_free_ref(neigh_node); 600 + neigh_node = tmp_neigh_node; 601 + continue; 602 + } 603 + 604 + if (is_duplicate) 605 + continue; 606 + 607 + spin_lock_bh(&tmp_neigh_node->tq_lock); 608 + ring_buffer_set(tmp_neigh_node->tq_recv, 609 + &tmp_neigh_node->tq_index, 0); 610 + tmp_neigh_node->tq_avg = 611 + ring_buffer_avg(tmp_neigh_node->tq_recv); 612 + spin_unlock_bh(&tmp_neigh_node->tq_lock); 613 + } 614 + 615 + if (!neigh_node) { 616 + struct orig_node *orig_tmp; 617 + 618 + orig_tmp = get_orig_node(bat_priv, ethhdr->h_source); 619 + if (!orig_tmp) 620 + goto unlock; 621 + 622 + neigh_node = create_neighbor(orig_node, orig_tmp, 623 + ethhdr->h_source, if_incoming); 624 + 625 + orig_node_free_ref(orig_tmp); 626 + if (!neigh_node) 627 + goto unlock; 628 + } else 629 + bat_dbg(DBG_BATMAN, bat_priv, 630 + "Updating existing last-hop neighbor of originator\n"); 631 + 632 + rcu_read_unlock(); 633 + 634 + orig_node->flags = batman_ogm_packet->flags; 635 + neigh_node->last_valid = jiffies; 636 + 637 + spin_lock_bh(&neigh_node->tq_lock); 638 + ring_buffer_set(neigh_node->tq_recv, 639 + &neigh_node->tq_index, 640 + batman_ogm_packet->tq); 641 + neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); 642 + spin_unlock_bh(&neigh_node->tq_lock); 643 + 644 + if (!is_duplicate) { 645 + orig_node->last_ttl = batman_ogm_packet->ttl; 646 + neigh_node->last_ttl = batman_ogm_packet->ttl; 647 + } 648 + 649 + bonding_candidate_add(orig_node, neigh_node); 650 + 651 + /* if this neighbor already is our next hop there is nothing 652 + * to change */ 653 + router = orig_node_get_router(orig_node); 654 + if (router == neigh_node) 655 + goto update_tt; 656 + 657 + /* if this neighbor does not offer a better TQ we won't consider it */ 658 + if (router && (router->tq_avg > neigh_node->tq_avg)) 659 + goto update_tt; 660 + 661 + /* if the TQ is the same and the link not more symmetric we 662 + * won't consider it either */ 663 + if (router && (neigh_node->tq_avg == router->tq_avg)) { 664 + orig_node_tmp = router->orig_node; 665 + spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 666 + bcast_own_sum_orig = 667 + orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 668 + spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 669 + 670 + orig_node_tmp = neigh_node->orig_node; 671 + spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 672 + bcast_own_sum_neigh = 673 + orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 674 + spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 675 + 676 + if (bcast_own_sum_orig >= bcast_own_sum_neigh) 677 + goto update_tt; 678 + } 679 + 680 + update_route(bat_priv, orig_node, neigh_node); 681 + 682 + update_tt: 683 + /* I have to check for transtable changes only if the OGM has been 684 + * sent through a primary interface */ 685 + if (((batman_ogm_packet->orig != ethhdr->h_source) && 686 + (batman_ogm_packet->ttl > 2)) || 687 + (batman_ogm_packet->flags & PRIMARIES_FIRST_HOP)) 688 + tt_update_orig(bat_priv, orig_node, tt_buff, 689 + batman_ogm_packet->tt_num_changes, 690 + batman_ogm_packet->ttvn, 691 + batman_ogm_packet->tt_crc); 692 + 693 + if (orig_node->gw_flags != batman_ogm_packet->gw_flags) 694 + gw_node_update(bat_priv, orig_node, 695 + batman_ogm_packet->gw_flags); 696 + 697 + orig_node->gw_flags = batman_ogm_packet->gw_flags; 698 + 699 + /* restart gateway selection if fast or late switching was enabled */ 700 + if ((orig_node->gw_flags) && 701 + (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) && 702 + (atomic_read(&bat_priv->gw_sel_class) > 2)) 703 + gw_check_election(bat_priv, orig_node); 704 + 705 + goto out; 706 + 707 + unlock: 708 + rcu_read_unlock(); 709 + out: 710 + if (neigh_node) 711 + neigh_node_free_ref(neigh_node); 712 + if (router) 713 + neigh_node_free_ref(router); 714 + } 715 + 716 + static int bat_ogm_calc_tq(struct orig_node *orig_node, 717 + struct orig_node *orig_neigh_node, 718 + struct batman_ogm_packet *batman_ogm_packet, 719 + struct hard_iface *if_incoming) 720 + { 721 + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 722 + struct neigh_node *neigh_node = NULL, *tmp_neigh_node; 723 + struct hlist_node *node; 724 + uint8_t total_count; 725 + uint8_t orig_eq_count, neigh_rq_count, tq_own; 726 + int tq_asym_penalty, ret = 0; 727 + 728 + /* find corresponding one hop neighbor */ 729 + rcu_read_lock(); 730 + hlist_for_each_entry_rcu(tmp_neigh_node, node, 731 + &orig_neigh_node->neigh_list, list) { 732 + 733 + if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig)) 734 + continue; 735 + 736 + if (tmp_neigh_node->if_incoming != if_incoming) 737 + continue; 738 + 739 + if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) 740 + continue; 741 + 742 + neigh_node = tmp_neigh_node; 743 + break; 744 + } 745 + rcu_read_unlock(); 746 + 747 + if (!neigh_node) 748 + neigh_node = create_neighbor(orig_neigh_node, 749 + orig_neigh_node, 750 + orig_neigh_node->orig, 751 + if_incoming); 752 + 753 + if (!neigh_node) 754 + goto out; 755 + 756 + /* if orig_node is direct neighbor update neigh_node last_valid */ 757 + if (orig_node == orig_neigh_node) 758 + neigh_node->last_valid = jiffies; 759 + 760 + orig_node->last_valid = jiffies; 761 + 762 + /* find packet count of corresponding one hop neighbor */ 763 + spin_lock_bh(&orig_node->ogm_cnt_lock); 764 + orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num]; 765 + neigh_rq_count = neigh_node->real_packet_count; 766 + spin_unlock_bh(&orig_node->ogm_cnt_lock); 767 + 768 + /* pay attention to not get a value bigger than 100 % */ 769 + total_count = (orig_eq_count > neigh_rq_count ? 770 + neigh_rq_count : orig_eq_count); 771 + 772 + /* if we have too few packets (too less data) we set tq_own to zero */ 773 + /* if we receive too few packets it is not considered bidirectional */ 774 + if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || 775 + (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) 776 + tq_own = 0; 777 + else 778 + /* neigh_node->real_packet_count is never zero as we 779 + * only purge old information when getting new 780 + * information */ 781 + tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count; 782 + 783 + /* 784 + * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does 785 + * affect the nearly-symmetric links only a little, but 786 + * punishes asymmetric links more. This will give a value 787 + * between 0 and TQ_MAX_VALUE 788 + */ 789 + tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE * 790 + (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) * 791 + (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) * 792 + (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) / 793 + (TQ_LOCAL_WINDOW_SIZE * 794 + TQ_LOCAL_WINDOW_SIZE * 795 + TQ_LOCAL_WINDOW_SIZE); 796 + 797 + batman_ogm_packet->tq = ((batman_ogm_packet->tq * tq_own 798 + * tq_asym_penalty) / 799 + (TQ_MAX_VALUE * TQ_MAX_VALUE)); 800 + 801 + bat_dbg(DBG_BATMAN, bat_priv, 802 + "bidirectional: " 803 + "orig = %-15pM neigh = %-15pM => own_bcast = %2i, " 804 + "real recv = %2i, local tq: %3i, asym_penalty: %3i, " 805 + "total tq: %3i\n", 806 + orig_node->orig, orig_neigh_node->orig, total_count, 807 + neigh_rq_count, tq_own, tq_asym_penalty, batman_ogm_packet->tq); 808 + 809 + /* if link has the minimum required transmission quality 810 + * consider it bidirectional */ 811 + if (batman_ogm_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) 812 + ret = 1; 813 + 814 + out: 815 + if (neigh_node) 816 + neigh_node_free_ref(neigh_node); 817 + return ret; 818 + } 819 + 820 + /* processes a batman packet for all interfaces, adjusts the sequence number and 821 + * finds out whether it is a duplicate. 822 + * returns: 823 + * 1 the packet is a duplicate 824 + * 0 the packet has not yet been received 825 + * -1 the packet is old and has been received while the seqno window 826 + * was protected. Caller should drop it. 827 + */ 828 + static int bat_ogm_update_seqnos(const struct ethhdr *ethhdr, 829 + const struct batman_ogm_packet 830 + *batman_ogm_packet, 831 + const struct hard_iface *if_incoming) 832 + { 833 + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 834 + struct orig_node *orig_node; 835 + struct neigh_node *tmp_neigh_node; 836 + struct hlist_node *node; 837 + int is_duplicate = 0; 838 + int32_t seq_diff; 839 + int need_update = 0; 840 + int set_mark, ret = -1; 841 + 842 + orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); 843 + if (!orig_node) 844 + return 0; 845 + 846 + spin_lock_bh(&orig_node->ogm_cnt_lock); 847 + seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno; 848 + 849 + /* signalize caller that the packet is to be dropped. */ 850 + if (window_protected(bat_priv, seq_diff, 851 + &orig_node->batman_seqno_reset)) 852 + goto out; 853 + 854 + rcu_read_lock(); 855 + hlist_for_each_entry_rcu(tmp_neigh_node, node, 856 + &orig_node->neigh_list, list) { 857 + 858 + is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, 859 + orig_node->last_real_seqno, 860 + batman_ogm_packet->seqno); 861 + 862 + if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && 863 + (tmp_neigh_node->if_incoming == if_incoming)) 864 + set_mark = 1; 865 + else 866 + set_mark = 0; 867 + 868 + /* if the window moved, set the update flag. */ 869 + need_update |= bit_get_packet(bat_priv, 870 + tmp_neigh_node->real_bits, 871 + seq_diff, set_mark); 872 + 873 + tmp_neigh_node->real_packet_count = 874 + bit_packet_count(tmp_neigh_node->real_bits); 875 + } 876 + rcu_read_unlock(); 877 + 878 + if (need_update) { 879 + bat_dbg(DBG_BATMAN, bat_priv, 880 + "updating last_seqno: old %d, new %d\n", 881 + orig_node->last_real_seqno, batman_ogm_packet->seqno); 882 + orig_node->last_real_seqno = batman_ogm_packet->seqno; 883 + } 884 + 885 + ret = is_duplicate; 886 + 887 + out: 888 + spin_unlock_bh(&orig_node->ogm_cnt_lock); 889 + orig_node_free_ref(orig_node); 890 + return ret; 891 + } 892 + 893 + static void bat_ogm_process(const struct ethhdr *ethhdr, 894 + struct batman_ogm_packet *batman_ogm_packet, 895 + const unsigned char *tt_buff, 896 + struct hard_iface *if_incoming) 897 + { 898 + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 899 + struct hard_iface *hard_iface; 900 + struct orig_node *orig_neigh_node, *orig_node; 901 + struct neigh_node *router = NULL, *router_router = NULL; 902 + struct neigh_node *orig_neigh_router = NULL; 903 + int has_directlink_flag; 904 + int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; 905 + int is_broadcast = 0, is_bidirectional, is_single_hop_neigh; 906 + int is_duplicate; 907 + uint32_t if_incoming_seqno; 908 + 909 + /* Silently drop when the batman packet is actually not a 910 + * correct packet. 911 + * 912 + * This might happen if a packet is padded (e.g. Ethernet has a 913 + * minimum frame length of 64 byte) and the aggregation interprets 914 + * it as an additional length. 915 + * 916 + * TODO: A more sane solution would be to have a bit in the 917 + * batman_ogm_packet to detect whether the packet is the last 918 + * packet in an aggregation. Here we expect that the padding 919 + * is always zero (or not 0x01) 920 + */ 921 + if (batman_ogm_packet->packet_type != BAT_OGM) 922 + return; 923 + 924 + /* could be changed by schedule_own_packet() */ 925 + if_incoming_seqno = atomic_read(&if_incoming->seqno); 926 + 927 + has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0); 928 + 929 + is_single_hop_neigh = (compare_eth(ethhdr->h_source, 930 + batman_ogm_packet->orig) ? 1 : 0); 931 + 932 + bat_dbg(DBG_BATMAN, bat_priv, 933 + "Received BATMAN packet via NB: %pM, IF: %s [%pM] " 934 + "(from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, " 935 + "crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", 936 + ethhdr->h_source, if_incoming->net_dev->name, 937 + if_incoming->net_dev->dev_addr, batman_ogm_packet->orig, 938 + batman_ogm_packet->prev_sender, batman_ogm_packet->seqno, 939 + batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc, 940 + batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq, 941 + batman_ogm_packet->ttl, batman_ogm_packet->version, 942 + has_directlink_flag); 943 + 944 + rcu_read_lock(); 945 + list_for_each_entry_rcu(hard_iface, &hardif_list, list) { 946 + if (hard_iface->if_status != IF_ACTIVE) 947 + continue; 948 + 949 + if (hard_iface->soft_iface != if_incoming->soft_iface) 950 + continue; 951 + 952 + if (compare_eth(ethhdr->h_source, 953 + hard_iface->net_dev->dev_addr)) 954 + is_my_addr = 1; 955 + 956 + if (compare_eth(batman_ogm_packet->orig, 957 + hard_iface->net_dev->dev_addr)) 958 + is_my_orig = 1; 959 + 960 + if (compare_eth(batman_ogm_packet->prev_sender, 961 + hard_iface->net_dev->dev_addr)) 962 + is_my_oldorig = 1; 963 + 964 + if (is_broadcast_ether_addr(ethhdr->h_source)) 965 + is_broadcast = 1; 966 + } 967 + rcu_read_unlock(); 968 + 969 + if (batman_ogm_packet->version != COMPAT_VERSION) { 970 + bat_dbg(DBG_BATMAN, bat_priv, 971 + "Drop packet: incompatible batman version (%i)\n", 972 + batman_ogm_packet->version); 973 + return; 974 + } 975 + 976 + if (is_my_addr) { 977 + bat_dbg(DBG_BATMAN, bat_priv, 978 + "Drop packet: received my own broadcast (sender: %pM" 979 + ")\n", 980 + ethhdr->h_source); 981 + return; 982 + } 983 + 984 + if (is_broadcast) { 985 + bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " 986 + "ignoring all packets with broadcast source addr (sender: %pM" 987 + ")\n", ethhdr->h_source); 988 + return; 989 + } 990 + 991 + if (is_my_orig) { 992 + unsigned long *word; 993 + int offset; 994 + 995 + orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source); 996 + if (!orig_neigh_node) 997 + return; 998 + 999 + /* neighbor has to indicate direct link and it has to 1000 + * come via the corresponding interface */ 1001 + /* save packet seqno for bidirectional check */ 1002 + if (has_directlink_flag && 1003 + compare_eth(if_incoming->net_dev->dev_addr, 1004 + batman_ogm_packet->orig)) { 1005 + offset = if_incoming->if_num * NUM_WORDS; 1006 + 1007 + spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); 1008 + word = &(orig_neigh_node->bcast_own[offset]); 1009 + bit_mark(word, 1010 + if_incoming_seqno - 1011 + batman_ogm_packet->seqno - 2); 1012 + orig_neigh_node->bcast_own_sum[if_incoming->if_num] = 1013 + bit_packet_count(word); 1014 + spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); 1015 + } 1016 + 1017 + bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " 1018 + "originator packet from myself (via neighbor)\n"); 1019 + orig_node_free_ref(orig_neigh_node); 1020 + return; 1021 + } 1022 + 1023 + if (is_my_oldorig) { 1024 + bat_dbg(DBG_BATMAN, bat_priv, 1025 + "Drop packet: ignoring all rebroadcast echos (sender: " 1026 + "%pM)\n", ethhdr->h_source); 1027 + return; 1028 + } 1029 + 1030 + orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); 1031 + if (!orig_node) 1032 + return; 1033 + 1034 + is_duplicate = bat_ogm_update_seqnos(ethhdr, batman_ogm_packet, 1035 + if_incoming); 1036 + 1037 + if (is_duplicate == -1) { 1038 + bat_dbg(DBG_BATMAN, bat_priv, 1039 + "Drop packet: packet within seqno protection time " 1040 + "(sender: %pM)\n", ethhdr->h_source); 1041 + goto out; 1042 + } 1043 + 1044 + if (batman_ogm_packet->tq == 0) { 1045 + bat_dbg(DBG_BATMAN, bat_priv, 1046 + "Drop packet: originator packet with tq equal 0\n"); 1047 + goto out; 1048 + } 1049 + 1050 + router = orig_node_get_router(orig_node); 1051 + if (router) 1052 + router_router = orig_node_get_router(router->orig_node); 1053 + 1054 + /* avoid temporary routing loops */ 1055 + if (router && router_router && 1056 + (compare_eth(router->addr, batman_ogm_packet->prev_sender)) && 1057 + !(compare_eth(batman_ogm_packet->orig, 1058 + batman_ogm_packet->prev_sender)) && 1059 + (compare_eth(router->addr, router_router->addr))) { 1060 + bat_dbg(DBG_BATMAN, bat_priv, 1061 + "Drop packet: ignoring all rebroadcast packets that " 1062 + "may make me loop (sender: %pM)\n", ethhdr->h_source); 1063 + goto out; 1064 + } 1065 + 1066 + /* if sender is a direct neighbor the sender mac equals 1067 + * originator mac */ 1068 + orig_neigh_node = (is_single_hop_neigh ? 1069 + orig_node : 1070 + get_orig_node(bat_priv, ethhdr->h_source)); 1071 + if (!orig_neigh_node) 1072 + goto out; 1073 + 1074 + orig_neigh_router = orig_node_get_router(orig_neigh_node); 1075 + 1076 + /* drop packet if sender is not a direct neighbor and if we 1077 + * don't route towards it */ 1078 + if (!is_single_hop_neigh && (!orig_neigh_router)) { 1079 + bat_dbg(DBG_BATMAN, bat_priv, 1080 + "Drop packet: OGM via unknown neighbor!\n"); 1081 + goto out_neigh; 1082 + } 1083 + 1084 + is_bidirectional = bat_ogm_calc_tq(orig_node, orig_neigh_node, 1085 + batman_ogm_packet, if_incoming); 1086 + 1087 + bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet); 1088 + 1089 + /* update ranking if it is not a duplicate or has the same 1090 + * seqno and similar ttl as the non-duplicate */ 1091 + if (is_bidirectional && 1092 + (!is_duplicate || 1093 + ((orig_node->last_real_seqno == batman_ogm_packet->seqno) && 1094 + (orig_node->last_ttl - 3 <= batman_ogm_packet->ttl)))) 1095 + bat_ogm_orig_update(bat_priv, orig_node, ethhdr, 1096 + batman_ogm_packet, if_incoming, 1097 + tt_buff, is_duplicate); 1098 + 1099 + /* is single hop (direct) neighbor */ 1100 + if (is_single_hop_neigh) { 1101 + 1102 + /* mark direct link on incoming interface */ 1103 + bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet, 1104 + 1, if_incoming); 1105 + 1106 + bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " 1107 + "rebroadcast neighbor packet with direct link flag\n"); 1108 + goto out_neigh; 1109 + } 1110 + 1111 + /* multihop originator */ 1112 + if (!is_bidirectional) { 1113 + bat_dbg(DBG_BATMAN, bat_priv, 1114 + "Drop packet: not received via bidirectional link\n"); 1115 + goto out_neigh; 1116 + } 1117 + 1118 + if (is_duplicate) { 1119 + bat_dbg(DBG_BATMAN, bat_priv, 1120 + "Drop packet: duplicate packet received\n"); 1121 + goto out_neigh; 1122 + } 1123 + 1124 + bat_dbg(DBG_BATMAN, bat_priv, 1125 + "Forwarding packet: rebroadcast originator packet\n"); 1126 + bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet, 0, if_incoming); 1127 + 1128 + out_neigh: 1129 + if ((orig_neigh_node) && (!is_single_hop_neigh)) 1130 + orig_node_free_ref(orig_neigh_node); 1131 + out: 1132 + if (router) 1133 + neigh_node_free_ref(router); 1134 + if (router_router) 1135 + neigh_node_free_ref(router_router); 1136 + if (orig_neigh_router) 1137 + neigh_node_free_ref(orig_neigh_router); 1138 + 1139 + orig_node_free_ref(orig_node); 1140 + } 1141 + 1142 + void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff, 1143 + int packet_len, struct hard_iface *if_incoming) 1144 + { 1145 + struct batman_ogm_packet *batman_ogm_packet; 1146 + int buff_pos = 0; 1147 + unsigned char *tt_buff; 1148 + 1149 + batman_ogm_packet = (struct batman_ogm_packet *)packet_buff; 1150 + 1151 + /* unpack the aggregated packets and process them one by one */ 1152 + do { 1153 + /* network to host order for our 32bit seqno and the 1154 + orig_interval */ 1155 + batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno); 1156 + batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc); 1157 + 1158 + tt_buff = packet_buff + buff_pos + BATMAN_OGM_LEN; 1159 + 1160 + bat_ogm_process(ethhdr, batman_ogm_packet, 1161 + tt_buff, if_incoming); 1162 + 1163 + buff_pos += BATMAN_OGM_LEN + 1164 + tt_len(batman_ogm_packet->tt_num_changes); 1165 + 1166 + batman_ogm_packet = (struct batman_ogm_packet *) 1167 + (packet_buff + buff_pos); 1168 + } while (bat_ogm_aggr_packet(buff_pos, packet_len, 1169 + batman_ogm_packet->tt_num_changes)); 1170 + }
+15 -39
net/batman-adv/hard-interface.c
··· 28 28 #include "bat_sysfs.h" 29 29 #include "originator.h" 30 30 #include "hash.h" 31 + #include "bat_ogm.h" 31 32 32 33 #include <linux/if_arp.h> 33 34 ··· 132 131 struct hard_iface *new_hard_iface) 133 132 { 134 133 struct hard_iface *curr_hard_iface; 135 - struct batman_packet *batman_packet; 136 134 137 135 ASSERT_RTNL(); 138 136 ··· 147 147 if (!new_hard_iface) 148 148 return; 149 149 150 - batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff); 151 - batman_packet->flags = PRIMARIES_FIRST_HOP; 152 - batman_packet->ttl = TTL; 153 - 150 + bat_ogm_init_primary(new_hard_iface); 154 151 primary_if_update_addr(bat_priv); 155 152 } 156 153 ··· 157 160 return true; 158 161 159 162 return false; 160 - } 161 - 162 - static void update_mac_addresses(struct hard_iface *hard_iface) 163 - { 164 - memcpy(((struct batman_packet *)(hard_iface->packet_buff))->orig, 165 - hard_iface->net_dev->dev_addr, ETH_ALEN); 166 - memcpy(((struct batman_packet *)(hard_iface->packet_buff))->prev_sender, 167 - hard_iface->net_dev->dev_addr, ETH_ALEN); 168 163 } 169 164 170 165 static void check_known_mac_addr(const struct net_device *net_dev) ··· 233 244 234 245 bat_priv = netdev_priv(hard_iface->soft_iface); 235 246 236 - update_mac_addresses(hard_iface); 247 + bat_ogm_update_mac(hard_iface); 237 248 hard_iface->if_status = IF_TO_BE_ACTIVATED; 238 249 239 250 /** ··· 272 283 const char *iface_name) 273 284 { 274 285 struct bat_priv *bat_priv; 275 - struct batman_packet *batman_packet; 276 286 struct net_device *soft_iface; 277 287 int ret; 278 288 ··· 306 318 307 319 hard_iface->soft_iface = soft_iface; 308 320 bat_priv = netdev_priv(hard_iface->soft_iface); 309 - hard_iface->packet_len = BAT_PACKET_LEN; 310 - hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC); 321 + 322 + bat_ogm_init(hard_iface); 311 323 312 324 if (!hard_iface->packet_buff) { 313 325 bat_err(hard_iface->soft_iface, "Can't add interface packet " ··· 315 327 ret = -ENOMEM; 316 328 goto err; 317 329 } 318 - 319 - batman_packet = (struct batman_packet *)(hard_iface->packet_buff); 320 - batman_packet->packet_type = BAT_PACKET; 321 - batman_packet->version = COMPAT_VERSION; 322 - batman_packet->flags = NO_FLAGS; 323 - batman_packet->ttl = 2; 324 - batman_packet->tq = TQ_MAX_VALUE; 325 - batman_packet->tt_num_changes = 0; 326 - batman_packet->ttvn = 0; 327 330 328 331 hard_iface->if_num = bat_priv->num_ifaces; 329 332 bat_priv->num_ifaces++; ··· 360 381 hard_iface->net_dev->name); 361 382 362 383 /* begin scheduling originator messages on that interface */ 363 - schedule_own_packet(hard_iface); 384 + schedule_bat_ogm(hard_iface); 364 385 365 386 out: 366 387 return 0; ··· 434 455 dev_hold(net_dev); 435 456 436 457 hard_iface = kmalloc(sizeof(*hard_iface), GFP_ATOMIC); 437 - if (!hard_iface) { 438 - pr_err("Can't add interface (%s): out of memory\n", 439 - net_dev->name); 458 + if (!hard_iface) 440 459 goto release_dev; 441 - } 442 460 443 461 ret = sysfs_add_hardif(&hard_iface->hardif_obj, net_dev); 444 462 if (ret) ··· 527 551 goto hardif_put; 528 552 529 553 check_known_mac_addr(hard_iface->net_dev); 530 - update_mac_addresses(hard_iface); 554 + bat_ogm_update_mac(hard_iface); 531 555 532 556 bat_priv = netdev_priv(hard_iface->soft_iface); 533 557 primary_if = primary_if_get_selected(bat_priv); ··· 556 580 struct net_device *orig_dev) 557 581 { 558 582 struct bat_priv *bat_priv; 559 - struct batman_packet *batman_packet; 583 + struct batman_ogm_packet *batman_ogm_packet; 560 584 struct hard_iface *hard_iface; 561 585 int ret; 562 586 ··· 588 612 if (hard_iface->if_status != IF_ACTIVE) 589 613 goto err_free; 590 614 591 - batman_packet = (struct batman_packet *)skb->data; 615 + batman_ogm_packet = (struct batman_ogm_packet *)skb->data; 592 616 593 - if (batman_packet->version != COMPAT_VERSION) { 617 + if (batman_ogm_packet->version != COMPAT_VERSION) { 594 618 bat_dbg(DBG_BATMAN, bat_priv, 595 619 "Drop packet: incompatible batman version (%i)\n", 596 - batman_packet->version); 620 + batman_ogm_packet->version); 597 621 goto err_free; 598 622 } 599 623 600 624 /* all receive handlers return whether they received or reused 601 625 * the supplied skb. if not, we have to free the skb. */ 602 626 603 - switch (batman_packet->packet_type) { 627 + switch (batman_ogm_packet->packet_type) { 604 628 /* batman originator packet */ 605 - case BAT_PACKET: 606 - ret = recv_bat_packet(skb, hard_iface); 629 + case BAT_OGM: 630 + ret = recv_bat_ogm_packet(skb, hard_iface); 607 631 break; 608 632 609 633 /* batman icmp packet */
-2
net/batman-adv/main.c
··· 117 117 goto end; 118 118 119 119 err: 120 - pr_err("Unable to allocate memory for mesh information structures: " 121 - "out of mem ?\n"); 122 120 mesh_free(soft_iface); 123 121 return -1; 124 122
+1 -1
net/batman-adv/main.h
··· 28 28 #define DRIVER_DEVICE "batman-adv" 29 29 30 30 #ifndef SOURCE_VERSION 31 - #define SOURCE_VERSION "2011.3.0" 31 + #define SOURCE_VERSION "2011.4.0" 32 32 #endif 33 33 34 34 /* B.A.T.M.A.N. parameters */
+5 -14
net/batman-adv/originator.c
··· 336 336 } else { 337 337 if (purge_orig_neighbors(bat_priv, orig_node, 338 338 &best_neigh_node)) { 339 - update_routes(bat_priv, orig_node, 340 - best_neigh_node); 339 + update_route(bat_priv, orig_node, best_neigh_node); 341 340 } 342 341 } 343 342 ··· 492 493 493 494 data_ptr = kmalloc(max_if_num * sizeof(unsigned long) * NUM_WORDS, 494 495 GFP_ATOMIC); 495 - if (!data_ptr) { 496 - pr_err("Can't resize orig: out of memory\n"); 496 + if (!data_ptr) 497 497 return -1; 498 - } 499 498 500 499 memcpy(data_ptr, orig_node->bcast_own, 501 500 (max_if_num - 1) * sizeof(unsigned long) * NUM_WORDS); ··· 501 504 orig_node->bcast_own = data_ptr; 502 505 503 506 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); 504 - if (!data_ptr) { 505 - pr_err("Can't resize orig: out of memory\n"); 507 + if (!data_ptr) 506 508 return -1; 507 - } 508 509 509 510 memcpy(data_ptr, orig_node->bcast_own_sum, 510 511 (max_if_num - 1) * sizeof(uint8_t)); ··· 557 562 558 563 chunk_size = sizeof(unsigned long) * NUM_WORDS; 559 564 data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); 560 - if (!data_ptr) { 561 - pr_err("Can't resize orig: out of memory\n"); 565 + if (!data_ptr) 562 566 return -1; 563 - } 564 567 565 568 /* copy first part */ 566 569 memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); ··· 576 583 goto free_own_sum; 577 584 578 585 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); 579 - if (!data_ptr) { 580 - pr_err("Can't resize orig: out of memory\n"); 586 + if (!data_ptr) 581 587 return -1; 582 - } 583 588 584 589 memcpy(data_ptr, orig_node->bcast_own_sum, 585 590 del_if_num * sizeof(uint8_t));
+9 -9
net/batman-adv/packet.h
··· 25 25 #define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ 26 26 27 27 enum bat_packettype { 28 - BAT_PACKET = 0x01, 29 - BAT_ICMP = 0x02, 30 - BAT_UNICAST = 0x03, 31 - BAT_BCAST = 0x04, 32 - BAT_VIS = 0x05, 28 + BAT_OGM = 0x01, 29 + BAT_ICMP = 0x02, 30 + BAT_UNICAST = 0x03, 31 + BAT_BCAST = 0x04, 32 + BAT_VIS = 0x05, 33 33 BAT_UNICAST_FRAG = 0x06, 34 - BAT_TT_QUERY = 0x07, 35 - BAT_ROAM_ADV = 0x08 34 + BAT_TT_QUERY = 0x07, 35 + BAT_ROAM_ADV = 0x08 36 36 }; 37 37 38 38 /* this file is included by batctl which needs these defines */ ··· 90 90 TT_CLIENT_PENDING = 1 << 10 91 91 }; 92 92 93 - struct batman_packet { 93 + struct batman_ogm_packet { 94 94 uint8_t packet_type; 95 95 uint8_t version; /* batman version field */ 96 96 uint8_t ttl; ··· 105 105 uint16_t tt_crc; 106 106 } __packed; 107 107 108 - #define BAT_PACKET_LEN sizeof(struct batman_packet) 108 + #define BATMAN_OGM_LEN sizeof(struct batman_ogm_packet) 109 109 110 110 struct icmp_packet { 111 111 uint8_t packet_type;
+18 -584
net/batman-adv/routing.c
··· 22 22 #include "main.h" 23 23 #include "routing.h" 24 24 #include "send.h" 25 - #include "hash.h" 26 25 #include "soft-interface.h" 27 26 #include "hard-interface.h" 28 27 #include "icmp_socket.h" 29 28 #include "translation-table.h" 30 29 #include "originator.h" 31 - #include "ring_buffer.h" 32 30 #include "vis.h" 33 - #include "aggregation.h" 34 - #include "gateway_common.h" 35 - #include "gateway_client.h" 36 31 #include "unicast.h" 32 + #include "bat_ogm.h" 37 33 38 34 void slide_own_bcast_window(struct hard_iface *hard_iface) 39 35 { ··· 60 64 } 61 65 } 62 66 63 - static void update_route(struct bat_priv *bat_priv, 64 - struct orig_node *orig_node, 65 - struct neigh_node *neigh_node) 67 + static void _update_route(struct bat_priv *bat_priv, 68 + struct orig_node *orig_node, 69 + struct neigh_node *neigh_node) 66 70 { 67 71 struct neigh_node *curr_router; 68 72 ··· 106 110 neigh_node_free_ref(curr_router); 107 111 } 108 112 109 - void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, 110 - struct neigh_node *neigh_node) 113 + void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, 114 + struct neigh_node *neigh_node) 111 115 { 112 116 struct neigh_node *router = NULL; 113 117 ··· 117 121 router = orig_node_get_router(orig_node); 118 122 119 123 if (router != neigh_node) 120 - update_route(bat_priv, orig_node, neigh_node); 124 + _update_route(bat_priv, orig_node, neigh_node); 121 125 122 126 out: 123 127 if (router) 124 128 neigh_node_free_ref(router); 125 - } 126 - 127 - static int is_bidirectional_neigh(struct orig_node *orig_node, 128 - struct orig_node *orig_neigh_node, 129 - struct batman_packet *batman_packet, 130 - struct hard_iface *if_incoming) 131 - { 132 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 133 - struct neigh_node *neigh_node = NULL, *tmp_neigh_node; 134 - struct hlist_node *node; 135 - uint8_t total_count; 136 - uint8_t orig_eq_count, neigh_rq_count, tq_own; 137 - int tq_asym_penalty, ret = 0; 138 - 139 - /* find corresponding one hop neighbor */ 140 - rcu_read_lock(); 141 - hlist_for_each_entry_rcu(tmp_neigh_node, node, 142 - &orig_neigh_node->neigh_list, list) { 143 - 144 - if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig)) 145 - continue; 146 - 147 - if (tmp_neigh_node->if_incoming != if_incoming) 148 - continue; 149 - 150 - if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) 151 - continue; 152 - 153 - neigh_node = tmp_neigh_node; 154 - break; 155 - } 156 - rcu_read_unlock(); 157 - 158 - if (!neigh_node) 159 - neigh_node = create_neighbor(orig_neigh_node, 160 - orig_neigh_node, 161 - orig_neigh_node->orig, 162 - if_incoming); 163 - 164 - if (!neigh_node) 165 - goto out; 166 - 167 - /* if orig_node is direct neighbor update neigh_node last_valid */ 168 - if (orig_node == orig_neigh_node) 169 - neigh_node->last_valid = jiffies; 170 - 171 - orig_node->last_valid = jiffies; 172 - 173 - /* find packet count of corresponding one hop neighbor */ 174 - spin_lock_bh(&orig_node->ogm_cnt_lock); 175 - orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num]; 176 - neigh_rq_count = neigh_node->real_packet_count; 177 - spin_unlock_bh(&orig_node->ogm_cnt_lock); 178 - 179 - /* pay attention to not get a value bigger than 100 % */ 180 - total_count = (orig_eq_count > neigh_rq_count ? 181 - neigh_rq_count : orig_eq_count); 182 - 183 - /* if we have too few packets (too less data) we set tq_own to zero */ 184 - /* if we receive too few packets it is not considered bidirectional */ 185 - if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || 186 - (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) 187 - tq_own = 0; 188 - else 189 - /* neigh_node->real_packet_count is never zero as we 190 - * only purge old information when getting new 191 - * information */ 192 - tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count; 193 - 194 - /* 195 - * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does 196 - * affect the nearly-symmetric links only a little, but 197 - * punishes asymmetric links more. This will give a value 198 - * between 0 and TQ_MAX_VALUE 199 - */ 200 - tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE * 201 - (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) * 202 - (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) * 203 - (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) / 204 - (TQ_LOCAL_WINDOW_SIZE * 205 - TQ_LOCAL_WINDOW_SIZE * 206 - TQ_LOCAL_WINDOW_SIZE); 207 - 208 - batman_packet->tq = ((batman_packet->tq * tq_own * tq_asym_penalty) / 209 - (TQ_MAX_VALUE * TQ_MAX_VALUE)); 210 - 211 - bat_dbg(DBG_BATMAN, bat_priv, 212 - "bidirectional: " 213 - "orig = %-15pM neigh = %-15pM => own_bcast = %2i, " 214 - "real recv = %2i, local tq: %3i, asym_penalty: %3i, " 215 - "total tq: %3i\n", 216 - orig_node->orig, orig_neigh_node->orig, total_count, 217 - neigh_rq_count, tq_own, tq_asym_penalty, batman_packet->tq); 218 - 219 - /* if link has the minimum required transmission quality 220 - * consider it bidirectional */ 221 - if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) 222 - ret = 1; 223 - 224 - out: 225 - if (neigh_node) 226 - neigh_node_free_ref(neigh_node); 227 - return ret; 228 129 } 229 130 230 131 /* caller must hold the neigh_list_lock */ ··· 141 248 return; 142 249 } 143 250 144 - static void bonding_candidate_add(struct orig_node *orig_node, 145 - struct neigh_node *neigh_node) 251 + void bonding_candidate_add(struct orig_node *orig_node, 252 + struct neigh_node *neigh_node) 146 253 { 147 254 struct hlist_node *node; 148 255 struct neigh_node *tmp_neigh_node, *router = NULL; ··· 212 319 } 213 320 214 321 /* copy primary address for bonding */ 215 - static void bonding_save_primary(const struct orig_node *orig_node, 216 - struct orig_node *orig_neigh_node, 217 - const struct batman_packet *batman_packet) 322 + void bonding_save_primary(const struct orig_node *orig_node, 323 + struct orig_node *orig_neigh_node, 324 + const struct batman_ogm_packet *batman_ogm_packet) 218 325 { 219 - if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) 326 + if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP)) 220 327 return; 221 328 222 329 memcpy(orig_neigh_node->primary_addr, orig_node->orig, ETH_ALEN); 223 - } 224 - 225 - static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, 226 - const struct ethhdr *ethhdr, 227 - const struct batman_packet *batman_packet, 228 - struct hard_iface *if_incoming, 229 - const unsigned char *tt_buff, int is_duplicate) 230 - { 231 - struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 232 - struct neigh_node *router = NULL; 233 - struct orig_node *orig_node_tmp; 234 - struct hlist_node *node; 235 - uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; 236 - 237 - bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " 238 - "Searching and updating originator entry of received packet\n"); 239 - 240 - rcu_read_lock(); 241 - hlist_for_each_entry_rcu(tmp_neigh_node, node, 242 - &orig_node->neigh_list, list) { 243 - if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && 244 - (tmp_neigh_node->if_incoming == if_incoming) && 245 - atomic_inc_not_zero(&tmp_neigh_node->refcount)) { 246 - if (neigh_node) 247 - neigh_node_free_ref(neigh_node); 248 - neigh_node = tmp_neigh_node; 249 - continue; 250 - } 251 - 252 - if (is_duplicate) 253 - continue; 254 - 255 - spin_lock_bh(&tmp_neigh_node->tq_lock); 256 - ring_buffer_set(tmp_neigh_node->tq_recv, 257 - &tmp_neigh_node->tq_index, 0); 258 - tmp_neigh_node->tq_avg = 259 - ring_buffer_avg(tmp_neigh_node->tq_recv); 260 - spin_unlock_bh(&tmp_neigh_node->tq_lock); 261 - } 262 - 263 - if (!neigh_node) { 264 - struct orig_node *orig_tmp; 265 - 266 - orig_tmp = get_orig_node(bat_priv, ethhdr->h_source); 267 - if (!orig_tmp) 268 - goto unlock; 269 - 270 - neigh_node = create_neighbor(orig_node, orig_tmp, 271 - ethhdr->h_source, if_incoming); 272 - 273 - orig_node_free_ref(orig_tmp); 274 - if (!neigh_node) 275 - goto unlock; 276 - } else 277 - bat_dbg(DBG_BATMAN, bat_priv, 278 - "Updating existing last-hop neighbor of originator\n"); 279 - 280 - rcu_read_unlock(); 281 - 282 - orig_node->flags = batman_packet->flags; 283 - neigh_node->last_valid = jiffies; 284 - 285 - spin_lock_bh(&neigh_node->tq_lock); 286 - ring_buffer_set(neigh_node->tq_recv, 287 - &neigh_node->tq_index, 288 - batman_packet->tq); 289 - neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); 290 - spin_unlock_bh(&neigh_node->tq_lock); 291 - 292 - if (!is_duplicate) { 293 - orig_node->last_ttl = batman_packet->ttl; 294 - neigh_node->last_ttl = batman_packet->ttl; 295 - } 296 - 297 - bonding_candidate_add(orig_node, neigh_node); 298 - 299 - /* if this neighbor already is our next hop there is nothing 300 - * to change */ 301 - router = orig_node_get_router(orig_node); 302 - if (router == neigh_node) 303 - goto update_tt; 304 - 305 - /* if this neighbor does not offer a better TQ we won't consider it */ 306 - if (router && (router->tq_avg > neigh_node->tq_avg)) 307 - goto update_tt; 308 - 309 - /* if the TQ is the same and the link not more symmetric we 310 - * won't consider it either */ 311 - if (router && (neigh_node->tq_avg == router->tq_avg)) { 312 - orig_node_tmp = router->orig_node; 313 - spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 314 - bcast_own_sum_orig = 315 - orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 316 - spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 317 - 318 - orig_node_tmp = neigh_node->orig_node; 319 - spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 320 - bcast_own_sum_neigh = 321 - orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 322 - spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 323 - 324 - if (bcast_own_sum_orig >= bcast_own_sum_neigh) 325 - goto update_tt; 326 - } 327 - 328 - update_routes(bat_priv, orig_node, neigh_node); 329 - 330 - update_tt: 331 - /* I have to check for transtable changes only if the OGM has been 332 - * sent through a primary interface */ 333 - if (((batman_packet->orig != ethhdr->h_source) && 334 - (batman_packet->ttl > 2)) || 335 - (batman_packet->flags & PRIMARIES_FIRST_HOP)) 336 - tt_update_orig(bat_priv, orig_node, tt_buff, 337 - batman_packet->tt_num_changes, 338 - batman_packet->ttvn, batman_packet->tt_crc); 339 - 340 - if (orig_node->gw_flags != batman_packet->gw_flags) 341 - gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); 342 - 343 - orig_node->gw_flags = batman_packet->gw_flags; 344 - 345 - /* restart gateway selection if fast or late switching was enabled */ 346 - if ((orig_node->gw_flags) && 347 - (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) && 348 - (atomic_read(&bat_priv->gw_sel_class) > 2)) 349 - gw_check_election(bat_priv, orig_node); 350 - 351 - goto out; 352 - 353 - unlock: 354 - rcu_read_unlock(); 355 - out: 356 - if (neigh_node) 357 - neigh_node_free_ref(neigh_node); 358 - if (router) 359 - neigh_node_free_ref(router); 360 330 } 361 331 362 332 /* checks whether the host restarted and is in the protection time. ··· 227 471 * 0 if the packet is to be accepted 228 472 * 1 if the packet is to be ignored. 229 473 */ 230 - static int window_protected(struct bat_priv *bat_priv, 231 - int32_t seq_num_diff, 232 - unsigned long *last_reset) 474 + int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, 475 + unsigned long *last_reset) 233 476 { 234 477 if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) 235 478 || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { ··· 246 491 return 0; 247 492 } 248 493 249 - /* processes a batman packet for all interfaces, adjusts the sequence number and 250 - * finds out whether it is a duplicate. 251 - * returns: 252 - * 1 the packet is a duplicate 253 - * 0 the packet has not yet been received 254 - * -1 the packet is old and has been received while the seqno window 255 - * was protected. Caller should drop it. 256 - */ 257 - static int count_real_packets(const struct ethhdr *ethhdr, 258 - const struct batman_packet *batman_packet, 259 - const struct hard_iface *if_incoming) 260 - { 261 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 262 - struct orig_node *orig_node; 263 - struct neigh_node *tmp_neigh_node; 264 - struct hlist_node *node; 265 - int is_duplicate = 0; 266 - int32_t seq_diff; 267 - int need_update = 0; 268 - int set_mark, ret = -1; 269 - 270 - orig_node = get_orig_node(bat_priv, batman_packet->orig); 271 - if (!orig_node) 272 - return 0; 273 - 274 - spin_lock_bh(&orig_node->ogm_cnt_lock); 275 - seq_diff = batman_packet->seqno - orig_node->last_real_seqno; 276 - 277 - /* signalize caller that the packet is to be dropped. */ 278 - if (window_protected(bat_priv, seq_diff, 279 - &orig_node->batman_seqno_reset)) 280 - goto out; 281 - 282 - rcu_read_lock(); 283 - hlist_for_each_entry_rcu(tmp_neigh_node, node, 284 - &orig_node->neigh_list, list) { 285 - 286 - is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, 287 - orig_node->last_real_seqno, 288 - batman_packet->seqno); 289 - 290 - if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && 291 - (tmp_neigh_node->if_incoming == if_incoming)) 292 - set_mark = 1; 293 - else 294 - set_mark = 0; 295 - 296 - /* if the window moved, set the update flag. */ 297 - need_update |= bit_get_packet(bat_priv, 298 - tmp_neigh_node->real_bits, 299 - seq_diff, set_mark); 300 - 301 - tmp_neigh_node->real_packet_count = 302 - bit_packet_count(tmp_neigh_node->real_bits); 303 - } 304 - rcu_read_unlock(); 305 - 306 - if (need_update) { 307 - bat_dbg(DBG_BATMAN, bat_priv, 308 - "updating last_seqno: old %d, new %d\n", 309 - orig_node->last_real_seqno, batman_packet->seqno); 310 - orig_node->last_real_seqno = batman_packet->seqno; 311 - } 312 - 313 - ret = is_duplicate; 314 - 315 - out: 316 - spin_unlock_bh(&orig_node->ogm_cnt_lock); 317 - orig_node_free_ref(orig_node); 318 - return ret; 319 - } 320 - 321 - void receive_bat_packet(const struct ethhdr *ethhdr, 322 - struct batman_packet *batman_packet, 323 - const unsigned char *tt_buff, 324 - struct hard_iface *if_incoming) 325 - { 326 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 327 - struct hard_iface *hard_iface; 328 - struct orig_node *orig_neigh_node, *orig_node; 329 - struct neigh_node *router = NULL, *router_router = NULL; 330 - struct neigh_node *orig_neigh_router = NULL; 331 - int has_directlink_flag; 332 - int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; 333 - int is_broadcast = 0, is_bidirectional, is_single_hop_neigh; 334 - int is_duplicate; 335 - uint32_t if_incoming_seqno; 336 - 337 - /* Silently drop when the batman packet is actually not a 338 - * correct packet. 339 - * 340 - * This might happen if a packet is padded (e.g. Ethernet has a 341 - * minimum frame length of 64 byte) and the aggregation interprets 342 - * it as an additional length. 343 - * 344 - * TODO: A more sane solution would be to have a bit in the 345 - * batman_packet to detect whether the packet is the last 346 - * packet in an aggregation. Here we expect that the padding 347 - * is always zero (or not 0x01) 348 - */ 349 - if (batman_packet->packet_type != BAT_PACKET) 350 - return; 351 - 352 - /* could be changed by schedule_own_packet() */ 353 - if_incoming_seqno = atomic_read(&if_incoming->seqno); 354 - 355 - has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0); 356 - 357 - is_single_hop_neigh = (compare_eth(ethhdr->h_source, 358 - batman_packet->orig) ? 1 : 0); 359 - 360 - bat_dbg(DBG_BATMAN, bat_priv, 361 - "Received BATMAN packet via NB: %pM, IF: %s [%pM] " 362 - "(from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, " 363 - "crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", 364 - ethhdr->h_source, if_incoming->net_dev->name, 365 - if_incoming->net_dev->dev_addr, batman_packet->orig, 366 - batman_packet->prev_sender, batman_packet->seqno, 367 - batman_packet->ttvn, batman_packet->tt_crc, 368 - batman_packet->tt_num_changes, batman_packet->tq, 369 - batman_packet->ttl, batman_packet->version, 370 - has_directlink_flag); 371 - 372 - rcu_read_lock(); 373 - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { 374 - if (hard_iface->if_status != IF_ACTIVE) 375 - continue; 376 - 377 - if (hard_iface->soft_iface != if_incoming->soft_iface) 378 - continue; 379 - 380 - if (compare_eth(ethhdr->h_source, 381 - hard_iface->net_dev->dev_addr)) 382 - is_my_addr = 1; 383 - 384 - if (compare_eth(batman_packet->orig, 385 - hard_iface->net_dev->dev_addr)) 386 - is_my_orig = 1; 387 - 388 - if (compare_eth(batman_packet->prev_sender, 389 - hard_iface->net_dev->dev_addr)) 390 - is_my_oldorig = 1; 391 - 392 - if (is_broadcast_ether_addr(ethhdr->h_source)) 393 - is_broadcast = 1; 394 - } 395 - rcu_read_unlock(); 396 - 397 - if (batman_packet->version != COMPAT_VERSION) { 398 - bat_dbg(DBG_BATMAN, bat_priv, 399 - "Drop packet: incompatible batman version (%i)\n", 400 - batman_packet->version); 401 - return; 402 - } 403 - 404 - if (is_my_addr) { 405 - bat_dbg(DBG_BATMAN, bat_priv, 406 - "Drop packet: received my own broadcast (sender: %pM" 407 - ")\n", 408 - ethhdr->h_source); 409 - return; 410 - } 411 - 412 - if (is_broadcast) { 413 - bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " 414 - "ignoring all packets with broadcast source addr (sender: %pM" 415 - ")\n", ethhdr->h_source); 416 - return; 417 - } 418 - 419 - if (is_my_orig) { 420 - unsigned long *word; 421 - int offset; 422 - 423 - orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source); 424 - if (!orig_neigh_node) 425 - return; 426 - 427 - /* neighbor has to indicate direct link and it has to 428 - * come via the corresponding interface */ 429 - /* save packet seqno for bidirectional check */ 430 - if (has_directlink_flag && 431 - compare_eth(if_incoming->net_dev->dev_addr, 432 - batman_packet->orig)) { 433 - offset = if_incoming->if_num * NUM_WORDS; 434 - 435 - spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); 436 - word = &(orig_neigh_node->bcast_own[offset]); 437 - bit_mark(word, 438 - if_incoming_seqno - batman_packet->seqno - 2); 439 - orig_neigh_node->bcast_own_sum[if_incoming->if_num] = 440 - bit_packet_count(word); 441 - spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); 442 - } 443 - 444 - bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " 445 - "originator packet from myself (via neighbor)\n"); 446 - orig_node_free_ref(orig_neigh_node); 447 - return; 448 - } 449 - 450 - if (is_my_oldorig) { 451 - bat_dbg(DBG_BATMAN, bat_priv, 452 - "Drop packet: ignoring all rebroadcast echos (sender: " 453 - "%pM)\n", ethhdr->h_source); 454 - return; 455 - } 456 - 457 - orig_node = get_orig_node(bat_priv, batman_packet->orig); 458 - if (!orig_node) 459 - return; 460 - 461 - is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); 462 - 463 - if (is_duplicate == -1) { 464 - bat_dbg(DBG_BATMAN, bat_priv, 465 - "Drop packet: packet within seqno protection time " 466 - "(sender: %pM)\n", ethhdr->h_source); 467 - goto out; 468 - } 469 - 470 - if (batman_packet->tq == 0) { 471 - bat_dbg(DBG_BATMAN, bat_priv, 472 - "Drop packet: originator packet with tq equal 0\n"); 473 - goto out; 474 - } 475 - 476 - router = orig_node_get_router(orig_node); 477 - if (router) 478 - router_router = orig_node_get_router(router->orig_node); 479 - 480 - /* avoid temporary routing loops */ 481 - if (router && router_router && 482 - (compare_eth(router->addr, batman_packet->prev_sender)) && 483 - !(compare_eth(batman_packet->orig, batman_packet->prev_sender)) && 484 - (compare_eth(router->addr, router_router->addr))) { 485 - bat_dbg(DBG_BATMAN, bat_priv, 486 - "Drop packet: ignoring all rebroadcast packets that " 487 - "may make me loop (sender: %pM)\n", ethhdr->h_source); 488 - goto out; 489 - } 490 - 491 - /* if sender is a direct neighbor the sender mac equals 492 - * originator mac */ 493 - orig_neigh_node = (is_single_hop_neigh ? 494 - orig_node : 495 - get_orig_node(bat_priv, ethhdr->h_source)); 496 - if (!orig_neigh_node) 497 - goto out; 498 - 499 - orig_neigh_router = orig_node_get_router(orig_neigh_node); 500 - 501 - /* drop packet if sender is not a direct neighbor and if we 502 - * don't route towards it */ 503 - if (!is_single_hop_neigh && (!orig_neigh_router)) { 504 - bat_dbg(DBG_BATMAN, bat_priv, 505 - "Drop packet: OGM via unknown neighbor!\n"); 506 - goto out_neigh; 507 - } 508 - 509 - is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node, 510 - batman_packet, if_incoming); 511 - 512 - bonding_save_primary(orig_node, orig_neigh_node, batman_packet); 513 - 514 - /* update ranking if it is not a duplicate or has the same 515 - * seqno and similar ttl as the non-duplicate */ 516 - if (is_bidirectional && 517 - (!is_duplicate || 518 - ((orig_node->last_real_seqno == batman_packet->seqno) && 519 - (orig_node->last_ttl - 3 <= batman_packet->ttl)))) 520 - update_orig(bat_priv, orig_node, ethhdr, batman_packet, 521 - if_incoming, tt_buff, is_duplicate); 522 - 523 - /* is single hop (direct) neighbor */ 524 - if (is_single_hop_neigh) { 525 - 526 - /* mark direct link on incoming interface */ 527 - schedule_forward_packet(orig_node, ethhdr, batman_packet, 528 - 1, if_incoming); 529 - 530 - bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " 531 - "rebroadcast neighbor packet with direct link flag\n"); 532 - goto out_neigh; 533 - } 534 - 535 - /* multihop originator */ 536 - if (!is_bidirectional) { 537 - bat_dbg(DBG_BATMAN, bat_priv, 538 - "Drop packet: not received via bidirectional link\n"); 539 - goto out_neigh; 540 - } 541 - 542 - if (is_duplicate) { 543 - bat_dbg(DBG_BATMAN, bat_priv, 544 - "Drop packet: duplicate packet received\n"); 545 - goto out_neigh; 546 - } 547 - 548 - bat_dbg(DBG_BATMAN, bat_priv, 549 - "Forwarding packet: rebroadcast originator packet\n"); 550 - schedule_forward_packet(orig_node, ethhdr, batman_packet, 551 - 0, if_incoming); 552 - 553 - out_neigh: 554 - if ((orig_neigh_node) && (!is_single_hop_neigh)) 555 - orig_node_free_ref(orig_neigh_node); 556 - out: 557 - if (router) 558 - neigh_node_free_ref(router); 559 - if (router_router) 560 - neigh_node_free_ref(router_router); 561 - if (orig_neigh_router) 562 - neigh_node_free_ref(orig_neigh_router); 563 - 564 - orig_node_free_ref(orig_node); 565 - } 566 - 567 - int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface) 494 + int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface) 568 495 { 569 496 struct ethhdr *ethhdr; 570 497 571 498 /* drop packet if it has not necessary minimum size */ 572 - if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet)))) 499 + if (unlikely(!pskb_may_pull(skb, BATMAN_OGM_LEN))) 573 500 return NET_RX_DROP; 574 501 575 502 ethhdr = (struct ethhdr *)skb_mac_header(skb); ··· 274 837 275 838 ethhdr = (struct ethhdr *)skb_mac_header(skb); 276 839 277 - receive_aggr_bat_packet(ethhdr, 278 - skb->data, 279 - skb_headlen(skb), 280 - hard_iface); 840 + bat_ogm_receive(ethhdr, skb->data, skb_headlen(skb), hard_iface); 281 841 282 842 kfree_skb(skb); 283 843 return NET_RX_SUCCESS;
+10 -7
net/batman-adv/routing.h
··· 23 23 #define _NET_BATMAN_ADV_ROUTING_H_ 24 24 25 25 void slide_own_bcast_window(struct hard_iface *hard_iface); 26 - void receive_bat_packet(const struct ethhdr *ethhdr, 27 - struct batman_packet *batman_packet, 28 - const unsigned char *tt_buff, 29 - struct hard_iface *if_incoming); 30 - void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, 31 - struct neigh_node *neigh_node); 26 + void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, 27 + struct neigh_node *neigh_node); 32 28 int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); 33 29 int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); 34 30 int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); 35 31 int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if); 36 32 int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if); 37 33 int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if); 38 - int recv_bat_packet(struct sk_buff *skb, struct hard_iface *recv_if); 34 + int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *recv_if); 39 35 int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if); 40 36 int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if); 41 37 struct neigh_node *find_router(struct bat_priv *bat_priv, ··· 39 43 const struct hard_iface *recv_if); 40 44 void bonding_candidate_del(struct orig_node *orig_node, 41 45 struct neigh_node *neigh_node); 46 + void bonding_candidate_add(struct orig_node *orig_node, 47 + struct neigh_node *neigh_node); 48 + void bonding_save_primary(const struct orig_node *orig_node, 49 + struct orig_node *orig_neigh_node, 50 + const struct batman_ogm_packet *batman_ogm_packet); 51 + int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, 52 + unsigned long *last_reset); 42 53 43 54 #endif /* _NET_BATMAN_ADV_ROUTING_H_ */
+25 -280
net/batman-adv/send.c
··· 26 26 #include "soft-interface.h" 27 27 #include "hard-interface.h" 28 28 #include "vis.h" 29 - #include "aggregation.h" 30 29 #include "gateway_common.h" 31 30 #include "originator.h" 31 + #include "bat_ogm.h" 32 32 33 33 static void send_outstanding_bcast_packet(struct work_struct *work); 34 - 35 - /* apply hop penalty for a normal link */ 36 - static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv) 37 - { 38 - int hop_penalty = atomic_read(&bat_priv->hop_penalty); 39 - return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); 40 - } 41 - 42 - /* when do we schedule our own packet to be sent */ 43 - static unsigned long own_send_time(const struct bat_priv *bat_priv) 44 - { 45 - return jiffies + msecs_to_jiffies( 46 - atomic_read(&bat_priv->orig_interval) - 47 - JITTER + (random32() % 2*JITTER)); 48 - } 49 - 50 - /* when do we schedule a forwarded packet to be sent */ 51 - static unsigned long forward_send_time(void) 52 - { 53 - return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); 54 - } 55 34 56 35 /* send out an already prepared packet to the given address via the 57 36 * specified batman interface */ ··· 78 99 return NET_XMIT_DROP; 79 100 } 80 101 81 - /* Send a packet to a given interface */ 82 - static void send_packet_to_if(struct forw_packet *forw_packet, 83 - struct hard_iface *hard_iface) 84 - { 85 - struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 86 - char *fwd_str; 87 - uint8_t packet_num; 88 - int16_t buff_pos; 89 - struct batman_packet *batman_packet; 90 - struct sk_buff *skb; 91 - 92 - if (hard_iface->if_status != IF_ACTIVE) 93 - return; 94 - 95 - packet_num = 0; 96 - buff_pos = 0; 97 - batman_packet = (struct batman_packet *)forw_packet->skb->data; 98 - 99 - /* adjust all flags and log packets */ 100 - while (aggregated_packet(buff_pos, 101 - forw_packet->packet_len, 102 - batman_packet->tt_num_changes)) { 103 - 104 - /* we might have aggregated direct link packets with an 105 - * ordinary base packet */ 106 - if ((forw_packet->direct_link_flags & (1 << packet_num)) && 107 - (forw_packet->if_incoming == hard_iface)) 108 - batman_packet->flags |= DIRECTLINK; 109 - else 110 - batman_packet->flags &= ~DIRECTLINK; 111 - 112 - fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? 113 - "Sending own" : 114 - "Forwarding")); 115 - bat_dbg(DBG_BATMAN, bat_priv, 116 - "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," 117 - " IDF %s, ttvn %d) on interface %s [%pM]\n", 118 - fwd_str, (packet_num > 0 ? "aggregated " : ""), 119 - batman_packet->orig, ntohl(batman_packet->seqno), 120 - batman_packet->tq, batman_packet->ttl, 121 - (batman_packet->flags & DIRECTLINK ? 122 - "on" : "off"), 123 - batman_packet->ttvn, hard_iface->net_dev->name, 124 - hard_iface->net_dev->dev_addr); 125 - 126 - buff_pos += sizeof(*batman_packet) + 127 - tt_len(batman_packet->tt_num_changes); 128 - packet_num++; 129 - batman_packet = (struct batman_packet *) 130 - (forw_packet->skb->data + buff_pos); 131 - } 132 - 133 - /* create clone because function is called more than once */ 134 - skb = skb_clone(forw_packet->skb, GFP_ATOMIC); 135 - if (skb) 136 - send_skb_packet(skb, hard_iface, broadcast_addr); 137 - } 138 - 139 - /* send a batman packet */ 140 - static void send_packet(struct forw_packet *forw_packet) 141 - { 142 - struct hard_iface *hard_iface; 143 - struct net_device *soft_iface; 144 - struct bat_priv *bat_priv; 145 - struct hard_iface *primary_if = NULL; 146 - struct batman_packet *batman_packet = 147 - (struct batman_packet *)(forw_packet->skb->data); 148 - int directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); 149 - 150 - if (!forw_packet->if_incoming) { 151 - pr_err("Error - can't forward packet: incoming iface not " 152 - "specified\n"); 153 - goto out; 154 - } 155 - 156 - soft_iface = forw_packet->if_incoming->soft_iface; 157 - bat_priv = netdev_priv(soft_iface); 158 - 159 - if (forw_packet->if_incoming->if_status != IF_ACTIVE) 160 - goto out; 161 - 162 - primary_if = primary_if_get_selected(bat_priv); 163 - if (!primary_if) 164 - goto out; 165 - 166 - /* multihomed peer assumed */ 167 - /* non-primary OGMs are only broadcasted on their interface */ 168 - if ((directlink && (batman_packet->ttl == 1)) || 169 - (forw_packet->own && (forw_packet->if_incoming != primary_if))) { 170 - 171 - /* FIXME: what about aggregated packets ? */ 172 - bat_dbg(DBG_BATMAN, bat_priv, 173 - "%s packet (originator %pM, seqno %d, TTL %d) " 174 - "on interface %s [%pM]\n", 175 - (forw_packet->own ? "Sending own" : "Forwarding"), 176 - batman_packet->orig, ntohl(batman_packet->seqno), 177 - batman_packet->ttl, 178 - forw_packet->if_incoming->net_dev->name, 179 - forw_packet->if_incoming->net_dev->dev_addr); 180 - 181 - /* skb is only used once and than forw_packet is free'd */ 182 - send_skb_packet(forw_packet->skb, forw_packet->if_incoming, 183 - broadcast_addr); 184 - forw_packet->skb = NULL; 185 - 186 - goto out; 187 - } 188 - 189 - /* broadcast on every interface */ 190 - rcu_read_lock(); 191 - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { 192 - if (hard_iface->soft_iface != soft_iface) 193 - continue; 194 - 195 - send_packet_to_if(forw_packet, hard_iface); 196 - } 197 - rcu_read_unlock(); 198 - 199 - out: 200 - if (primary_if) 201 - hardif_free_ref(primary_if); 202 - } 203 - 204 102 static void realloc_packet_buffer(struct hard_iface *hard_iface, 205 - int new_len) 103 + int new_len) 206 104 { 207 105 unsigned char *new_buff; 208 - struct batman_packet *batman_packet; 209 106 210 107 new_buff = kmalloc(new_len, GFP_ATOMIC); 211 108 212 109 /* keep old buffer if kmalloc should fail */ 213 110 if (new_buff) { 214 111 memcpy(new_buff, hard_iface->packet_buff, 215 - sizeof(*batman_packet)); 112 + BATMAN_OGM_LEN); 216 113 217 114 kfree(hard_iface->packet_buff); 218 115 hard_iface->packet_buff = new_buff; ··· 97 242 } 98 243 99 244 /* when calling this function (hard_iface == primary_if) has to be true */ 100 - static void prepare_packet_buffer(struct bat_priv *bat_priv, 245 + static int prepare_packet_buffer(struct bat_priv *bat_priv, 101 246 struct hard_iface *hard_iface) 102 247 { 103 248 int new_len; 104 - struct batman_packet *batman_packet; 105 249 106 - new_len = BAT_PACKET_LEN + 250 + new_len = BATMAN_OGM_LEN + 107 251 tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes)); 108 252 109 253 /* if we have too many changes for one packet don't send any 110 254 * and wait for the tt table request which will be fragmented */ 111 255 if (new_len > hard_iface->soft_iface->mtu) 112 - new_len = BAT_PACKET_LEN; 256 + new_len = BATMAN_OGM_LEN; 113 257 114 258 realloc_packet_buffer(hard_iface, new_len); 115 - batman_packet = (struct batman_packet *)hard_iface->packet_buff; 116 259 117 260 atomic_set(&bat_priv->tt_crc, tt_local_crc(bat_priv)); 118 261 119 262 /* reset the sending counter */ 120 263 atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); 121 264 122 - batman_packet->tt_num_changes = tt_changes_fill_buffer(bat_priv, 123 - hard_iface->packet_buff + BAT_PACKET_LEN, 124 - hard_iface->packet_len - BAT_PACKET_LEN); 125 - 265 + return tt_changes_fill_buffer(bat_priv, 266 + hard_iface->packet_buff + BATMAN_OGM_LEN, 267 + hard_iface->packet_len - BATMAN_OGM_LEN); 126 268 } 127 269 128 - static void reset_packet_buffer(struct bat_priv *bat_priv, 129 - struct hard_iface *hard_iface) 270 + static int reset_packet_buffer(struct bat_priv *bat_priv, 271 + struct hard_iface *hard_iface) 130 272 { 131 - struct batman_packet *batman_packet; 132 - 133 - realloc_packet_buffer(hard_iface, BAT_PACKET_LEN); 134 - 135 - batman_packet = (struct batman_packet *)hard_iface->packet_buff; 136 - batman_packet->tt_num_changes = 0; 273 + realloc_packet_buffer(hard_iface, BATMAN_OGM_LEN); 274 + return 0; 137 275 } 138 276 139 - void schedule_own_packet(struct hard_iface *hard_iface) 277 + void schedule_bat_ogm(struct hard_iface *hard_iface) 140 278 { 141 279 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 142 280 struct hard_iface *primary_if; 143 - unsigned long send_time; 144 - struct batman_packet *batman_packet; 145 - int vis_server; 281 + int tt_num_changes = -1; 146 282 147 283 if ((hard_iface->if_status == IF_NOT_IN_USE) || 148 284 (hard_iface->if_status == IF_TO_BE_REMOVED)) 149 285 return; 150 - 151 - vis_server = atomic_read(&bat_priv->vis_mode); 152 - primary_if = primary_if_get_selected(bat_priv); 153 286 154 287 /** 155 288 * the interface gets activated here to avoid race conditions between ··· 149 306 if (hard_iface->if_status == IF_TO_BE_ACTIVATED) 150 307 hard_iface->if_status = IF_ACTIVE; 151 308 309 + primary_if = primary_if_get_selected(bat_priv); 310 + 152 311 if (hard_iface == primary_if) { 153 312 /* if at least one change happened */ 154 313 if (atomic_read(&bat_priv->tt_local_changes) > 0) { 155 314 tt_commit_changes(bat_priv); 156 - prepare_packet_buffer(bat_priv, hard_iface); 315 + tt_num_changes = prepare_packet_buffer(bat_priv, 316 + hard_iface); 157 317 } 158 318 159 319 /* if the changes have been sent often enough */ 160 320 if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt)) 161 - reset_packet_buffer(bat_priv, hard_iface); 321 + tt_num_changes = reset_packet_buffer(bat_priv, 322 + hard_iface); 162 323 } 163 - 164 - /** 165 - * NOTE: packet_buff might just have been re-allocated in 166 - * prepare_packet_buffer() or in reset_packet_buffer() 167 - */ 168 - batman_packet = (struct batman_packet *)hard_iface->packet_buff; 169 - 170 - /* change sequence number to network order */ 171 - batman_packet->seqno = 172 - htonl((uint32_t)atomic_read(&hard_iface->seqno)); 173 - 174 - batman_packet->ttvn = atomic_read(&bat_priv->ttvn); 175 - batman_packet->tt_crc = htons((uint16_t)atomic_read(&bat_priv->tt_crc)); 176 - 177 - if (vis_server == VIS_TYPE_SERVER_SYNC) 178 - batman_packet->flags |= VIS_SERVER; 179 - else 180 - batman_packet->flags &= ~VIS_SERVER; 181 - 182 - if ((hard_iface == primary_if) && 183 - (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) 184 - batman_packet->gw_flags = 185 - (uint8_t)atomic_read(&bat_priv->gw_bandwidth); 186 - else 187 - batman_packet->gw_flags = NO_FLAGS; 188 - 189 - atomic_inc(&hard_iface->seqno); 190 - 191 - slide_own_bcast_window(hard_iface); 192 - send_time = own_send_time(bat_priv); 193 - add_bat_packet_to_list(bat_priv, 194 - hard_iface->packet_buff, 195 - hard_iface->packet_len, 196 - hard_iface, 1, send_time); 197 324 198 325 if (primary_if) 199 326 hardif_free_ref(primary_if); 200 - } 201 327 202 - void schedule_forward_packet(struct orig_node *orig_node, 203 - const struct ethhdr *ethhdr, 204 - struct batman_packet *batman_packet, 205 - int directlink, 206 - struct hard_iface *if_incoming) 207 - { 208 - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 209 - struct neigh_node *router; 210 - uint8_t in_tq, in_ttl, tq_avg = 0; 211 - unsigned long send_time; 212 - uint8_t tt_num_changes; 213 - 214 - if (batman_packet->ttl <= 1) { 215 - bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n"); 216 - return; 217 - } 218 - 219 - router = orig_node_get_router(orig_node); 220 - 221 - in_tq = batman_packet->tq; 222 - in_ttl = batman_packet->ttl; 223 - tt_num_changes = batman_packet->tt_num_changes; 224 - 225 - batman_packet->ttl--; 226 - memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN); 227 - 228 - /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast 229 - * of our best tq value */ 230 - if (router && router->tq_avg != 0) { 231 - 232 - /* rebroadcast ogm of best ranking neighbor as is */ 233 - if (!compare_eth(router->addr, ethhdr->h_source)) { 234 - batman_packet->tq = router->tq_avg; 235 - 236 - if (router->last_ttl) 237 - batman_packet->ttl = router->last_ttl - 1; 238 - } 239 - 240 - tq_avg = router->tq_avg; 241 - } 242 - 243 - if (router) 244 - neigh_node_free_ref(router); 245 - 246 - /* apply hop penalty */ 247 - batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv); 248 - 249 - bat_dbg(DBG_BATMAN, bat_priv, 250 - "Forwarding packet: tq_orig: %i, tq_avg: %i, " 251 - "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", 252 - in_tq, tq_avg, batman_packet->tq, in_ttl - 1, 253 - batman_packet->ttl); 254 - 255 - batman_packet->seqno = htonl(batman_packet->seqno); 256 - batman_packet->tt_crc = htons(batman_packet->tt_crc); 257 - 258 - /* switch of primaries first hop flag when forwarding */ 259 - batman_packet->flags &= ~PRIMARIES_FIRST_HOP; 260 - if (directlink) 261 - batman_packet->flags |= DIRECTLINK; 262 - else 263 - batman_packet->flags &= ~DIRECTLINK; 264 - 265 - send_time = forward_send_time(); 266 - add_bat_packet_to_list(bat_priv, 267 - (unsigned char *)batman_packet, 268 - sizeof(*batman_packet) + tt_len(tt_num_changes), 269 - if_incoming, 0, send_time); 328 + bat_ogm_schedule(hard_iface, tt_num_changes); 270 329 } 271 330 272 331 static void forw_packet_free(struct forw_packet *forw_packet) ··· 302 557 atomic_inc(&bat_priv->bcast_queue_left); 303 558 } 304 559 305 - void send_outstanding_bat_packet(struct work_struct *work) 560 + void send_outstanding_bat_ogm_packet(struct work_struct *work) 306 561 { 307 562 struct delayed_work *delayed_work = 308 563 container_of(work, struct delayed_work, work); ··· 318 573 if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) 319 574 goto out; 320 575 321 - send_packet(forw_packet); 576 + bat_ogm_emit(forw_packet); 322 577 323 578 /** 324 579 * we have to have at least one packet in the queue ··· 326 581 * shutting down 327 582 */ 328 583 if (forw_packet->own) 329 - schedule_own_packet(forw_packet->if_incoming); 584 + schedule_bat_ogm(forw_packet->if_incoming); 330 585 331 586 out: 332 587 /* don't count own packet */
+2 -7
net/batman-adv/send.h
··· 24 24 25 25 int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, 26 26 const uint8_t *dst_addr); 27 - void schedule_own_packet(struct hard_iface *hard_iface); 28 - void schedule_forward_packet(struct orig_node *orig_node, 29 - const struct ethhdr *ethhdr, 30 - struct batman_packet *batman_packet, 31 - int directlink, 32 - struct hard_iface *if_outgoing); 27 + void schedule_bat_ogm(struct hard_iface *hard_iface); 33 28 int add_bcast_packet_to_list(struct bat_priv *bat_priv, 34 29 const struct sk_buff *skb, unsigned long delay); 35 - void send_outstanding_bat_packet(struct work_struct *work); 30 + void send_outstanding_bat_ogm_packet(struct work_struct *work); 36 31 void purge_outstanding_packets(struct bat_priv *bat_priv, 37 32 const struct hard_iface *hard_iface); 38 33
+10 -11
net/batman-adv/soft-interface.c
··· 445 445 { 446 446 struct bat_priv *bat_priv = netdev_priv(dev); 447 447 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 448 - struct batman_packet *batman_packet; 448 + struct batman_ogm_packet *batman_ogm_packet; 449 449 struct softif_neigh *softif_neigh = NULL; 450 450 struct hard_iface *primary_if = NULL; 451 451 struct softif_neigh *curr_softif_neigh = NULL; 452 452 453 453 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) 454 - batman_packet = (struct batman_packet *) 454 + batman_ogm_packet = (struct batman_ogm_packet *) 455 455 (skb->data + ETH_HLEN + VLAN_HLEN); 456 456 else 457 - batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN); 457 + batman_ogm_packet = (struct batman_ogm_packet *) 458 + (skb->data + ETH_HLEN); 458 459 459 - if (batman_packet->version != COMPAT_VERSION) 460 + if (batman_ogm_packet->version != COMPAT_VERSION) 460 461 goto out; 461 462 462 - if (batman_packet->packet_type != BAT_PACKET) 463 + if (batman_ogm_packet->packet_type != BAT_OGM) 463 464 goto out; 464 465 465 - if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) 466 + if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP)) 466 467 goto out; 467 468 468 - if (is_my_mac(batman_packet->orig)) 469 + if (is_my_mac(batman_ogm_packet->orig)) 469 470 goto out; 470 471 471 - softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid); 472 + softif_neigh = softif_neigh_get(bat_priv, batman_ogm_packet->orig, vid); 472 473 if (!softif_neigh) 473 474 goto out; 474 475 ··· 801 800 802 801 soft_iface = alloc_netdev(sizeof(*bat_priv), name, interface_setup); 803 802 804 - if (!soft_iface) { 805 - pr_err("Unable to allocate the batman interface: %s\n", name); 803 + if (!soft_iface) 806 804 goto out; 807 - } 808 805 809 806 ret = register_netdevice(soft_iface); 810 807 if (ret < 0) {
+1 -3
net/batman-adv/vis.c
··· 887 887 } 888 888 889 889 bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC); 890 - if (!bat_priv->my_vis_info) { 891 - pr_err("Can't initialize vis packet\n"); 890 + if (!bat_priv->my_vis_info) 892 891 goto err; 893 - } 894 892 895 893 bat_priv->my_vis_info->skb_packet = dev_alloc_skb(sizeof(*packet) + 896 894 MAX_VIS_PACKET_SIZE +