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/ecsv/linux-merge

+292 -138
-1
net/batman-adv/aggregation.c
··· 95 95 return false; 96 96 } 97 97 98 - #define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) 99 98 /* create a new aggregated packet and add this packet to it */ 100 99 static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, 101 100 unsigned long send_time, bool direct_link,
+27 -18
net/batman-adv/gateway_client.c
··· 127 127 return; 128 128 129 129 curr_gw = gw_get_selected_gw_node(bat_priv); 130 - if (!curr_gw) 130 + if (curr_gw) 131 131 goto out; 132 132 133 133 rcu_read_lock(); ··· 310 310 struct hlist_node *node; 311 311 struct gw_node *gw_node, *curr_gw; 312 312 313 + /** 314 + * Note: We don't need a NULL check here, since curr_gw never gets 315 + * dereferenced. If curr_gw is NULL we also should not exit as we may 316 + * have this gateway in our list (duplication check!) even though we 317 + * have no currently selected gateway. 318 + */ 313 319 curr_gw = gw_get_selected_gw_node(bat_priv); 314 - if (!curr_gw) 315 - goto out; 316 320 317 321 rcu_read_lock(); 318 322 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { ··· 354 350 gw_deselect(bat_priv); 355 351 unlock: 356 352 rcu_read_unlock(); 357 - out: 353 + 358 354 if (curr_gw) 359 355 gw_node_free_ref(curr_gw); 360 356 } ··· 439 435 { 440 436 struct net_device *net_dev = (struct net_device *)seq->private; 441 437 struct bat_priv *bat_priv = netdev_priv(net_dev); 438 + struct hard_iface *primary_if; 442 439 struct gw_node *gw_node; 443 440 struct hlist_node *node; 444 - int gw_count = 0; 441 + int gw_count = 0, ret = 0; 445 442 446 - if (!bat_priv->primary_if) { 447 - 448 - return seq_printf(seq, "BATMAN mesh %s disabled - please " 449 - "specify interfaces to enable it\n", 450 - net_dev->name); 443 + primary_if = primary_if_get_selected(bat_priv); 444 + if (!primary_if) { 445 + ret = seq_printf(seq, "BATMAN mesh %s disabled - please " 446 + "specify interfaces to enable it\n", 447 + net_dev->name); 448 + goto out; 451 449 } 452 450 453 - if (bat_priv->primary_if->if_status != IF_ACTIVE) { 454 - 455 - return seq_printf(seq, "BATMAN mesh %s disabled - " 456 - "primary interface not active\n", 457 - net_dev->name); 451 + if (primary_if->if_status != IF_ACTIVE) { 452 + ret = seq_printf(seq, "BATMAN mesh %s disabled - " 453 + "primary interface not active\n", 454 + net_dev->name); 455 + goto out; 458 456 } 459 457 460 458 seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... " 461 459 "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", 462 460 "Gateway", "#", TQ_MAX_VALUE, "Nexthop", 463 461 "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR, 464 - bat_priv->primary_if->net_dev->name, 465 - bat_priv->primary_if->net_dev->dev_addr, net_dev->name); 462 + primary_if->net_dev->name, 463 + primary_if->net_dev->dev_addr, net_dev->name); 466 464 467 465 rcu_read_lock(); 468 466 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { ··· 482 476 if (gw_count == 0) 483 477 seq_printf(seq, "No gateways in range ...\n"); 484 478 485 - return 0; 479 + out: 480 + if (primary_if) 481 + hardif_free_ref(primary_if); 482 + return ret; 486 483 } 487 484 488 485 int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
+57 -26
net/batman-adv/hard-interface.c
··· 110 110 return hard_iface; 111 111 } 112 112 113 - static void update_primary_addr(struct bat_priv *bat_priv) 113 + static void primary_if_update_addr(struct bat_priv *bat_priv) 114 114 { 115 115 struct vis_packet *vis_packet; 116 + struct hard_iface *primary_if; 117 + 118 + primary_if = primary_if_get_selected(bat_priv); 119 + if (!primary_if) 120 + goto out; 116 121 117 122 vis_packet = (struct vis_packet *) 118 123 bat_priv->my_vis_info->skb_packet->data; 119 - memcpy(vis_packet->vis_orig, 120 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 124 + memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); 121 125 memcpy(vis_packet->sender_orig, 122 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 126 + primary_if->net_dev->dev_addr, ETH_ALEN); 127 + 128 + out: 129 + if (primary_if) 130 + hardif_free_ref(primary_if); 123 131 } 124 132 125 - static void set_primary_if(struct bat_priv *bat_priv, 126 - struct hard_iface *hard_iface) 133 + static void primary_if_select(struct bat_priv *bat_priv, 134 + struct hard_iface *new_hard_iface) 127 135 { 136 + struct hard_iface *curr_hard_iface; 128 137 struct batman_packet *batman_packet; 129 - struct hard_iface *old_if; 130 138 131 - if (hard_iface && !atomic_inc_not_zero(&hard_iface->refcount)) 132 - hard_iface = NULL; 139 + spin_lock_bh(&hardif_list_lock); 133 140 134 - old_if = bat_priv->primary_if; 135 - bat_priv->primary_if = hard_iface; 141 + if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount)) 142 + new_hard_iface = NULL; 136 143 137 - if (old_if) 138 - hardif_free_ref(old_if); 144 + curr_hard_iface = bat_priv->primary_if; 145 + rcu_assign_pointer(bat_priv->primary_if, new_hard_iface); 139 146 140 - if (!bat_priv->primary_if) 141 - return; 147 + if (curr_hard_iface) 148 + hardif_free_ref(curr_hard_iface); 142 149 143 - batman_packet = (struct batman_packet *)(hard_iface->packet_buff); 150 + if (!new_hard_iface) 151 + goto out; 152 + 153 + batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff); 144 154 batman_packet->flags = PRIMARIES_FIRST_HOP; 145 155 batman_packet->ttl = TTL; 146 156 147 - update_primary_addr(bat_priv); 157 + primary_if_update_addr(bat_priv); 148 158 149 159 /*** 150 160 * hacky trick to make sure that we send the HNA information via 151 161 * our new primary interface 152 162 */ 153 163 atomic_set(&bat_priv->hna_local_changed, 1); 164 + 165 + out: 166 + spin_unlock_bh(&hardif_list_lock); 154 167 } 155 168 156 169 static bool hardif_is_iface_up(struct hard_iface *hard_iface) ··· 249 236 static void hardif_activate_interface(struct hard_iface *hard_iface) 250 237 { 251 238 struct bat_priv *bat_priv; 239 + struct hard_iface *primary_if = NULL; 252 240 253 241 if (hard_iface->if_status != IF_INACTIVE) 254 - return; 242 + goto out; 255 243 256 244 bat_priv = netdev_priv(hard_iface->soft_iface); 257 245 ··· 263 249 * the first active interface becomes our primary interface or 264 250 * the next active interface after the old primay interface was removed 265 251 */ 266 - if (!bat_priv->primary_if) 267 - set_primary_if(bat_priv, hard_iface); 252 + primary_if = primary_if_get_selected(bat_priv); 253 + if (!primary_if) 254 + primary_if_select(bat_priv, hard_iface); 268 255 269 256 bat_info(hard_iface->soft_iface, "Interface activated: %s\n", 270 257 hard_iface->net_dev->name); 271 258 272 259 update_min_mtu(hard_iface->soft_iface); 273 - return; 260 + 261 + out: 262 + if (primary_if) 263 + hardif_free_ref(primary_if); 274 264 } 275 265 276 266 static void hardif_deactivate_interface(struct hard_iface *hard_iface) ··· 404 386 void hardif_disable_interface(struct hard_iface *hard_iface) 405 387 { 406 388 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 389 + struct hard_iface *primary_if = NULL; 407 390 408 391 if (hard_iface->if_status == IF_ACTIVE) 409 392 hardif_deactivate_interface(hard_iface); 410 393 411 394 if (hard_iface->if_status != IF_INACTIVE) 412 - return; 395 + goto out; 413 396 414 397 bat_info(hard_iface->soft_iface, "Removing interface: %s\n", 415 398 hard_iface->net_dev->name); ··· 419 400 bat_priv->num_ifaces--; 420 401 orig_hash_del_if(hard_iface, bat_priv->num_ifaces); 421 402 422 - if (hard_iface == bat_priv->primary_if) { 403 + primary_if = primary_if_get_selected(bat_priv); 404 + if (hard_iface == primary_if) { 423 405 struct hard_iface *new_if; 424 406 425 407 new_if = hardif_get_active(hard_iface->soft_iface); 426 - set_primary_if(bat_priv, new_if); 408 + primary_if_select(bat_priv, new_if); 427 409 428 410 if (new_if) 429 411 hardif_free_ref(new_if); ··· 445 425 446 426 hard_iface->soft_iface = NULL; 447 427 hardif_free_ref(hard_iface); 428 + 429 + out: 430 + if (primary_if) 431 + hardif_free_ref(primary_if); 448 432 } 449 433 450 434 static struct hard_iface *hardif_add_interface(struct net_device *net_dev) ··· 538 514 { 539 515 struct net_device *net_dev = (struct net_device *)ptr; 540 516 struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); 517 + struct hard_iface *primary_if = NULL; 541 518 struct bat_priv *bat_priv; 542 519 543 520 if (!hard_iface && event == NETDEV_REGISTER) ··· 574 549 update_mac_addresses(hard_iface); 575 550 576 551 bat_priv = netdev_priv(hard_iface->soft_iface); 577 - if (hard_iface == bat_priv->primary_if) 578 - update_primary_addr(bat_priv); 552 + primary_if = primary_if_get_selected(bat_priv); 553 + if (!primary_if) 554 + goto hardif_put; 555 + 556 + if (hard_iface == primary_if) 557 + primary_if_update_addr(bat_priv); 579 558 break; 580 559 default: 581 560 break; ··· 588 559 hardif_put: 589 560 hardif_free_ref(hard_iface); 590 561 out: 562 + if (primary_if) 563 + hardif_free_ref(primary_if); 591 564 return NOTIFY_DONE; 592 565 } 593 566
+18
net/batman-adv/hard-interface.h
··· 45 45 call_rcu(&hard_iface->rcu, hardif_free_rcu); 46 46 } 47 47 48 + static inline struct hard_iface *primary_if_get_selected( 49 + struct bat_priv *bat_priv) 50 + { 51 + struct hard_iface *hard_iface; 52 + 53 + rcu_read_lock(); 54 + hard_iface = rcu_dereference(bat_priv->primary_if); 55 + if (!hard_iface) 56 + goto out; 57 + 58 + if (!atomic_inc_not_zero(&hard_iface->refcount)) 59 + hard_iface = NULL; 60 + 61 + out: 62 + rcu_read_unlock(); 63 + return hard_iface; 64 + } 65 + 48 66 #endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
+14 -5
net/batman-adv/icmp_socket.c
··· 153 153 { 154 154 struct socket_client *socket_client = file->private_data; 155 155 struct bat_priv *bat_priv = socket_client->bat_priv; 156 + struct hard_iface *primary_if = NULL; 156 157 struct sk_buff *skb; 157 158 struct icmp_packet_rr *icmp_packet; 158 159 ··· 168 167 return -EINVAL; 169 168 } 170 169 171 - if (!bat_priv->primary_if) 172 - return -EFAULT; 170 + primary_if = primary_if_get_selected(bat_priv); 171 + 172 + if (!primary_if) { 173 + len = -EFAULT; 174 + goto out; 175 + } 173 176 174 177 if (len >= sizeof(struct icmp_packet_rr)) 175 178 packet_len = sizeof(struct icmp_packet_rr); 176 179 177 180 skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr)); 178 - if (!skb) 179 - return -ENOMEM; 181 + if (!skb) { 182 + len = -ENOMEM; 183 + goto out; 184 + } 180 185 181 186 skb_reserve(skb, sizeof(struct ethhdr)); 182 187 icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len); ··· 240 233 goto dst_unreach; 241 234 242 235 memcpy(icmp_packet->orig, 243 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 236 + primary_if->net_dev->dev_addr, ETH_ALEN); 244 237 245 238 if (packet_len == sizeof(struct icmp_packet_rr)) 246 239 memcpy(icmp_packet->rr, ··· 255 248 free_skb: 256 249 kfree_skb(skb); 257 250 out: 251 + if (primary_if) 252 + hardif_free_ref(primary_if); 258 253 if (neigh_node) 259 254 neigh_node_free_ref(neigh_node); 260 255 if (orig_node)
+2
net/batman-adv/main.h
··· 175 175 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 176 176 } 177 177 178 + #define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) 179 + 178 180 #endif /* _NET_BATMAN_ADV_MAIN_H_ */
+21 -13
net/batman-adv/originator.c
··· 405 405 struct hashtable_t *hash = bat_priv->orig_hash; 406 406 struct hlist_node *node, *node_tmp; 407 407 struct hlist_head *head; 408 + struct hard_iface *primary_if; 408 409 struct orig_node *orig_node; 409 410 struct neigh_node *neigh_node, *neigh_node_tmp; 410 411 int batman_count = 0; 411 412 int last_seen_secs; 412 413 int last_seen_msecs; 413 - int i; 414 + int i, ret = 0; 414 415 415 - if ((!bat_priv->primary_if) || 416 - (bat_priv->primary_if->if_status != IF_ACTIVE)) { 417 - if (!bat_priv->primary_if) 418 - return seq_printf(seq, "BATMAN mesh %s disabled - " 419 - "please specify interfaces to enable it\n", 420 - net_dev->name); 416 + primary_if = primary_if_get_selected(bat_priv); 421 417 422 - return seq_printf(seq, "BATMAN mesh %s " 423 - "disabled - primary interface not active\n", 424 - net_dev->name); 418 + if (!primary_if) { 419 + ret = seq_printf(seq, "BATMAN mesh %s disabled - " 420 + "please specify interfaces to enable it\n", 421 + net_dev->name); 422 + goto out; 423 + } 424 + 425 + if (primary_if->if_status != IF_ACTIVE) { 426 + ret = seq_printf(seq, "BATMAN mesh %s " 427 + "disabled - primary interface not active\n", 428 + net_dev->name); 429 + goto out; 425 430 } 426 431 427 432 seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", 428 433 SOURCE_VERSION, REVISION_VERSION_STR, 429 - bat_priv->primary_if->net_dev->name, 430 - bat_priv->primary_if->net_dev->dev_addr, net_dev->name); 434 + primary_if->net_dev->name, 435 + primary_if->net_dev->dev_addr, net_dev->name); 431 436 seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", 432 437 "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", 433 438 "outgoingIF", "Potential nexthops"); ··· 479 474 if (batman_count == 0) 480 475 seq_printf(seq, "No batman nodes in range ...\n"); 481 476 482 - return 0; 477 + out: 478 + if (primary_if) 479 + hardif_free_ref(primary_if); 480 + return ret; 483 481 } 484 482 485 483 static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
+14 -20
net/batman-adv/routing.c
··· 904 904 static int recv_my_icmp_packet(struct bat_priv *bat_priv, 905 905 struct sk_buff *skb, size_t icmp_len) 906 906 { 907 + struct hard_iface *primary_if = NULL; 907 908 struct orig_node *orig_node = NULL; 908 909 struct neigh_node *router = NULL; 909 910 struct icmp_packet_rr *icmp_packet; ··· 918 917 goto out; 919 918 } 920 919 921 - if (!bat_priv->primary_if) 920 + primary_if = primary_if_get_selected(bat_priv); 921 + if (!primary_if) 922 922 goto out; 923 923 924 924 /* answer echo request (ping) */ ··· 939 937 icmp_packet = (struct icmp_packet_rr *)skb->data; 940 938 941 939 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 942 - memcpy(icmp_packet->orig, 943 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 940 + memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); 944 941 icmp_packet->msg_type = ECHO_REPLY; 945 942 icmp_packet->ttl = TTL; 946 943 ··· 947 946 ret = NET_RX_SUCCESS; 948 947 949 948 out: 949 + if (primary_if) 950 + hardif_free_ref(primary_if); 950 951 if (router) 951 952 neigh_node_free_ref(router); 952 953 if (orig_node) ··· 959 956 static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, 960 957 struct sk_buff *skb) 961 958 { 959 + struct hard_iface *primary_if = NULL; 962 960 struct orig_node *orig_node = NULL; 963 961 struct neigh_node *router = NULL; 964 962 struct icmp_packet *icmp_packet; ··· 975 971 goto out; 976 972 } 977 973 978 - if (!bat_priv->primary_if) 974 + primary_if = primary_if_get_selected(bat_priv); 975 + if (!primary_if) 979 976 goto out; 980 977 981 978 /* get routing information */ ··· 995 990 icmp_packet = (struct icmp_packet *)skb->data; 996 991 997 992 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 998 - memcpy(icmp_packet->orig, 999 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 993 + memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); 1000 994 icmp_packet->msg_type = TTL_EXCEEDED; 1001 995 icmp_packet->ttl = TTL; 1002 996 ··· 1003 999 ret = NET_RX_SUCCESS; 1004 1000 1005 1001 out: 1002 + if (primary_if) 1003 + hardif_free_ref(primary_if); 1006 1004 if (router) 1007 1005 neigh_node_free_ref(router); 1008 1006 if (orig_node) ··· 1316 1310 } 1317 1311 1318 1312 /* get routing information */ 1319 - rcu_read_lock(); 1320 1313 orig_node = orig_hash_find(bat_priv, unicast_packet->dest); 1321 1314 1322 1315 if (!orig_node) 1323 - goto unlock; 1324 - 1325 - rcu_read_unlock(); 1316 + goto out; 1326 1317 1327 1318 /* find_router() increases neigh_nodes refcount if found. */ 1328 1319 neigh_node = find_router(bat_priv, orig_node, recv_if); ··· 1365 1362 /* route it */ 1366 1363 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1367 1364 ret = NET_RX_SUCCESS; 1368 - goto out; 1369 1365 1370 - unlock: 1371 - rcu_read_unlock(); 1372 1366 out: 1373 1367 if (neigh_node) 1374 1368 neigh_node_free_ref(neigh_node); ··· 1464 1464 if (bcast_packet->ttl < 2) 1465 1465 goto out; 1466 1466 1467 - rcu_read_lock(); 1468 1467 orig_node = orig_hash_find(bat_priv, bcast_packet->orig); 1469 1468 1470 1469 if (!orig_node) 1471 - goto rcu_unlock; 1472 - 1473 - rcu_read_unlock(); 1470 + goto out; 1474 1471 1475 1472 spin_lock_bh(&orig_node->bcast_seqno_lock); 1476 1473 ··· 1498 1501 ret = NET_RX_SUCCESS; 1499 1502 goto out; 1500 1503 1501 - rcu_unlock: 1502 - rcu_read_unlock(); 1503 - goto out; 1504 1504 spin_unlock: 1505 1505 spin_unlock_bh(&orig_node->bcast_seqno_lock); 1506 1506 out:
+13 -5
net/batman-adv/send.c
··· 244 244 void schedule_own_packet(struct hard_iface *hard_iface) 245 245 { 246 246 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 247 + struct hard_iface *primary_if; 247 248 unsigned long send_time; 248 249 struct batman_packet *batman_packet; 249 250 int vis_server; ··· 254 253 return; 255 254 256 255 vis_server = atomic_read(&bat_priv->vis_mode); 256 + primary_if = primary_if_get_selected(bat_priv); 257 257 258 258 /** 259 259 * the interface gets activated here to avoid race conditions between ··· 268 266 269 267 /* if local hna has changed and interface is a primary interface */ 270 268 if ((atomic_read(&bat_priv->hna_local_changed)) && 271 - (hard_iface == bat_priv->primary_if)) 269 + (hard_iface == primary_if)) 272 270 rebuild_batman_packet(bat_priv, hard_iface); 273 271 274 272 /** ··· 286 284 else 287 285 batman_packet->flags &= ~VIS_SERVER; 288 286 289 - if ((hard_iface == bat_priv->primary_if) && 287 + if ((hard_iface == primary_if) && 290 288 (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) 291 289 batman_packet->gw_flags = 292 290 (uint8_t)atomic_read(&bat_priv->gw_bandwidth); ··· 301 299 hard_iface->packet_buff, 302 300 hard_iface->packet_len, 303 301 hard_iface, 1, send_time); 302 + 303 + if (primary_if) 304 + hardif_free_ref(primary_if); 304 305 } 305 306 306 307 void schedule_forward_packet(struct orig_node *orig_node, ··· 398 393 send_time); 399 394 } 400 395 401 - #define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) 402 396 /* add a broadcast packet to the queue and setup timers. broadcast packets 403 397 * are sent multiple times to increase probability for beeing received. 404 398 * ··· 408 404 * skb is freed. */ 409 405 int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb) 410 406 { 407 + struct hard_iface *primary_if = NULL; 411 408 struct forw_packet *forw_packet; 412 409 struct bcast_packet *bcast_packet; 413 410 ··· 417 412 goto out; 418 413 } 419 414 420 - if (!bat_priv->primary_if) 415 + primary_if = primary_if_get_selected(bat_priv); 416 + if (!primary_if) 421 417 goto out; 422 418 423 419 forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); ··· 437 431 skb_reset_mac_header(skb); 438 432 439 433 forw_packet->skb = skb; 440 - forw_packet->if_incoming = bat_priv->primary_if; 434 + forw_packet->if_incoming = primary_if; 441 435 442 436 /* how often did we send the bcast packet ? */ 443 437 forw_packet->num_packets = 0; ··· 450 444 out_and_inc: 451 445 atomic_inc(&bat_priv->bcast_queue_left); 452 446 out: 447 + if (primary_if) 448 + hardif_free_ref(primary_if); 453 449 return NETDEV_TX_BUSY; 454 450 } 455 451
+45 -19
net/batman-adv/soft-interface.c
··· 211 211 struct net_device *net_dev = (struct net_device *)seq->private; 212 212 struct bat_priv *bat_priv = netdev_priv(net_dev); 213 213 struct softif_neigh *softif_neigh; 214 + struct hard_iface *primary_if; 214 215 struct hlist_node *node; 215 216 struct softif_neigh *curr_softif_neigh; 217 + int ret = 0; 216 218 217 - if (!bat_priv->primary_if) { 218 - return seq_printf(seq, "BATMAN mesh %s disabled - " 219 - "please specify interfaces to enable it\n", 220 - net_dev->name); 219 + primary_if = primary_if_get_selected(bat_priv); 220 + if (!primary_if) { 221 + ret = seq_printf(seq, "BATMAN mesh %s disabled - " 222 + "please specify interfaces to enable it\n", 223 + net_dev->name); 224 + goto out; 225 + } 226 + 227 + if (primary_if->if_status != IF_ACTIVE) { 228 + ret = seq_printf(seq, "BATMAN mesh %s " 229 + "disabled - primary interface not active\n", 230 + net_dev->name); 231 + goto out; 221 232 } 222 233 223 234 seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); ··· 245 234 if (curr_softif_neigh) 246 235 softif_neigh_free_ref(curr_softif_neigh); 247 236 248 - return 0; 237 + out: 238 + if (primary_if) 239 + hardif_free_ref(primary_if); 240 + return ret; 249 241 } 250 242 251 243 static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, ··· 257 243 struct bat_priv *bat_priv = netdev_priv(dev); 258 244 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 259 245 struct batman_packet *batman_packet; 260 - struct softif_neigh *softif_neigh; 246 + struct softif_neigh *softif_neigh = NULL; 247 + struct hard_iface *primary_if = NULL; 261 248 struct softif_neigh *curr_softif_neigh = NULL; 262 249 263 250 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) ··· 268 253 batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN); 269 254 270 255 if (batman_packet->version != COMPAT_VERSION) 271 - goto err; 256 + goto out; 272 257 273 258 if (batman_packet->packet_type != BAT_PACKET) 274 - goto err; 259 + goto out; 275 260 276 261 if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) 277 - goto err; 262 + goto out; 278 263 279 264 if (is_my_mac(batman_packet->orig)) 280 - goto err; 265 + goto out; 281 266 282 267 softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid); 283 - 284 268 if (!softif_neigh) 285 - goto err; 269 + goto out; 286 270 287 271 curr_softif_neigh = softif_neigh_get_selected(bat_priv); 272 + if (!curr_softif_neigh) 273 + goto out; 274 + 288 275 if (curr_softif_neigh == softif_neigh) 289 276 goto out; 290 277 278 + primary_if = primary_if_get_selected(bat_priv); 279 + if (!primary_if) 280 + goto out; 281 + 291 282 /* we got a neighbor but its mac is 'bigger' than ours */ 292 - if (memcmp(bat_priv->primary_if->net_dev->dev_addr, 283 + if (memcmp(primary_if->net_dev->dev_addr, 293 284 softif_neigh->addr, ETH_ALEN) < 0) 294 285 goto out; 295 286 ··· 317 296 /* close own batX device and use softif_neigh as exit node */ 318 297 if ((!curr_softif_neigh) && 319 298 (memcmp(softif_neigh->addr, 320 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) { 299 + primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) { 321 300 bat_dbg(DBG_ROUTES, bat_priv, 322 301 "Setting mesh exit point to %pM (vid: %d).\n", 323 302 softif_neigh->addr, softif_neigh->vid); ··· 327 306 } 328 307 329 308 out: 330 - softif_neigh_free_ref(softif_neigh); 331 - err: 332 309 kfree_skb(skb); 310 + if (softif_neigh) 311 + softif_neigh_free_ref(softif_neigh); 333 312 if (curr_softif_neigh) 334 313 softif_neigh_free_ref(curr_softif_neigh); 335 - 314 + if (primary_if) 315 + hardif_free_ref(primary_if); 336 316 return; 337 317 } 338 318 ··· 389 367 { 390 368 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 391 369 struct bat_priv *bat_priv = netdev_priv(soft_iface); 370 + struct hard_iface *primary_if = NULL; 392 371 struct bcast_packet *bcast_packet; 393 372 struct vlan_ethhdr *vhdr; 394 373 struct softif_neigh *curr_softif_neigh = NULL; ··· 439 416 440 417 /* ethernet packet should be broadcasted */ 441 418 if (do_bcast) { 442 - if (!bat_priv->primary_if) 419 + primary_if = primary_if_get_selected(bat_priv); 420 + if (!primary_if) 443 421 goto dropped; 444 422 445 423 if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0) ··· 456 432 /* hw address of first interface is the orig mac because only 457 433 * this mac is known throughout the mesh */ 458 434 memcpy(bcast_packet->orig, 459 - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 435 + primary_if->net_dev->dev_addr, ETH_ALEN); 460 436 461 437 /* set broadcast sequence number */ 462 438 bcast_packet->seqno = ··· 486 462 end: 487 463 if (curr_softif_neigh) 488 464 softif_neigh_free_ref(curr_softif_neigh); 465 + if (primary_if) 466 + hardif_free_ref(primary_if); 489 467 return NETDEV_TX_OK; 490 468 } 491 469
+43 -14
net/batman-adv/translation-table.c
··· 22 22 #include "main.h" 23 23 #include "translation-table.h" 24 24 #include "soft-interface.h" 25 + #include "hard-interface.h" 25 26 #include "hash.h" 26 27 #include "originator.h" 27 28 ··· 238 237 struct bat_priv *bat_priv = netdev_priv(net_dev); 239 238 struct hashtable_t *hash = bat_priv->hna_local_hash; 240 239 struct hna_local_entry *hna_local_entry; 240 + struct hard_iface *primary_if; 241 241 struct hlist_node *node; 242 242 struct hlist_head *head; 243 243 size_t buf_size, pos; 244 244 char *buff; 245 - int i; 245 + int i, ret = 0; 246 246 247 - if (!bat_priv->primary_if) { 248 - return seq_printf(seq, "BATMAN mesh %s disabled - " 249 - "please specify interfaces to enable it\n", 250 - net_dev->name); 247 + primary_if = primary_if_get_selected(bat_priv); 248 + if (!primary_if) { 249 + ret = seq_printf(seq, "BATMAN mesh %s disabled - " 250 + "please specify interfaces to enable it\n", 251 + net_dev->name); 252 + goto out; 253 + } 254 + 255 + if (primary_if->if_status != IF_ACTIVE) { 256 + ret = seq_printf(seq, "BATMAN mesh %s disabled - " 257 + "primary interface not active\n", 258 + net_dev->name); 259 + goto out; 251 260 } 252 261 253 262 seq_printf(seq, "Locally retrieved addresses (from %s) " ··· 280 269 buff = kmalloc(buf_size, GFP_ATOMIC); 281 270 if (!buff) { 282 271 spin_unlock_bh(&bat_priv->hna_lhash_lock); 283 - return -ENOMEM; 272 + ret = -ENOMEM; 273 + goto out; 284 274 } 285 275 286 276 buff[0] = '\0'; ··· 303 291 304 292 seq_printf(seq, "%s", buff); 305 293 kfree(buff); 306 - return 0; 294 + out: 295 + if (primary_if) 296 + hardif_free_ref(primary_if); 297 + return ret; 307 298 } 308 299 309 300 static void _hna_local_del(struct hlist_node *node, void *arg) ··· 483 468 struct bat_priv *bat_priv = netdev_priv(net_dev); 484 469 struct hashtable_t *hash = bat_priv->hna_global_hash; 485 470 struct hna_global_entry *hna_global_entry; 471 + struct hard_iface *primary_if; 486 472 struct hlist_node *node; 487 473 struct hlist_head *head; 488 474 size_t buf_size, pos; 489 475 char *buff; 490 - int i; 476 + int i, ret = 0; 491 477 492 - if (!bat_priv->primary_if) { 493 - return seq_printf(seq, "BATMAN mesh %s disabled - " 494 - "please specify interfaces to enable it\n", 495 - net_dev->name); 478 + primary_if = primary_if_get_selected(bat_priv); 479 + if (!primary_if) { 480 + ret = seq_printf(seq, "BATMAN mesh %s disabled - please " 481 + "specify interfaces to enable it\n", 482 + net_dev->name); 483 + goto out; 484 + } 485 + 486 + if (primary_if->if_status != IF_ACTIVE) { 487 + ret = seq_printf(seq, "BATMAN mesh %s disabled - " 488 + "primary interface not active\n", 489 + net_dev->name); 490 + goto out; 496 491 } 497 492 498 493 seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", ··· 524 499 buff = kmalloc(buf_size, GFP_ATOMIC); 525 500 if (!buff) { 526 501 spin_unlock_bh(&bat_priv->hna_ghash_lock); 527 - return -ENOMEM; 502 + ret = -ENOMEM; 503 + goto out; 528 504 } 529 505 buff[0] = '\0'; 530 506 pos = 0; ··· 548 522 549 523 seq_printf(seq, "%s", buff); 550 524 kfree(buff); 551 - return 0; 525 + out: 526 + if (primary_if) 527 + hardif_free_ref(primary_if); 528 + return ret; 552 529 } 553 530 554 531 static void _hna_global_del_orig(struct bat_priv *bat_priv,
+1 -1
net/batman-adv/types.h
··· 149 149 struct hlist_head softif_neigh_list; 150 150 struct softif_neigh __rcu *softif_neigh; 151 151 struct debug_log *debug_log; 152 - struct hard_iface *primary_if; 153 152 struct kobject *mesh_obj; 154 153 struct dentry *debug_dir; 155 154 struct hlist_head forw_bat_list; ··· 173 174 struct delayed_work orig_work; 174 175 struct delayed_work vis_work; 175 176 struct gw_node __rcu *curr_gw; /* rcu protected pointer */ 177 + struct hard_iface __rcu *primary_if; /* rcu protected pointer */ 176 178 struct vis_info *my_vis_info; 177 179 }; 178 180
+11 -5
net/batman-adv/unicast.c
··· 221 221 struct hard_iface *hard_iface, uint8_t dstaddr[]) 222 222 { 223 223 struct unicast_packet tmp_uc, *unicast_packet; 224 + struct hard_iface *primary_if; 224 225 struct sk_buff *frag_skb; 225 226 struct unicast_frag_packet *frag1, *frag2; 226 227 int uc_hdr_len = sizeof(struct unicast_packet); 227 228 int ucf_hdr_len = sizeof(struct unicast_frag_packet); 228 229 int data_len = skb->len - uc_hdr_len; 229 - int large_tail = 0; 230 + int large_tail = 0, ret = NET_RX_DROP; 230 231 uint16_t seqno; 231 232 232 - if (!bat_priv->primary_if) 233 + primary_if = primary_if_get_selected(bat_priv); 234 + if (!primary_if) 233 235 goto dropped; 234 236 235 237 frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); ··· 256 254 frag1->version = COMPAT_VERSION; 257 255 frag1->packet_type = BAT_UNICAST_FRAG; 258 256 259 - memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 257 + memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN); 260 258 memcpy(frag2, frag1, sizeof(struct unicast_frag_packet)); 261 259 262 260 if (data_len & 1) ··· 271 269 272 270 send_skb_packet(skb, hard_iface, dstaddr); 273 271 send_skb_packet(frag_skb, hard_iface, dstaddr); 274 - return NET_RX_SUCCESS; 272 + ret = NET_RX_SUCCESS; 273 + goto out; 275 274 276 275 drop_frag: 277 276 kfree_skb(frag_skb); 278 277 dropped: 279 278 kfree_skb(skb); 280 - return NET_RX_DROP; 279 + out: 280 + if (primary_if) 281 + hardif_free_ref(primary_if); 282 + return ret; 281 283 } 282 284 283 285 int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
+26 -11
net/batman-adv/vis.c
··· 204 204 205 205 int vis_seq_print_text(struct seq_file *seq, void *offset) 206 206 { 207 + struct hard_iface *primary_if; 207 208 struct hlist_node *node; 208 209 struct hlist_head *head; 209 210 struct vis_info *info; ··· 216 215 HLIST_HEAD(vis_if_list); 217 216 struct if_list_entry *entry; 218 217 struct hlist_node *pos, *n; 219 - int i, j; 218 + int i, j, ret = 0; 220 219 int vis_server = atomic_read(&bat_priv->vis_mode); 221 220 size_t buff_pos, buf_size; 222 221 char *buff; 223 222 int compare; 224 223 225 - if ((!bat_priv->primary_if) || 226 - (vis_server == VIS_TYPE_CLIENT_UPDATE)) 227 - return 0; 224 + primary_if = primary_if_get_selected(bat_priv); 225 + if (!primary_if) 226 + goto out; 227 + 228 + if (vis_server == VIS_TYPE_CLIENT_UPDATE) 229 + goto out; 228 230 229 231 buf_size = 1; 230 232 /* Estimate length */ ··· 274 270 buff = kmalloc(buf_size, GFP_ATOMIC); 275 271 if (!buff) { 276 272 spin_unlock_bh(&bat_priv->vis_hash_lock); 277 - return -ENOMEM; 273 + ret = -ENOMEM; 274 + goto out; 278 275 } 279 276 buff[0] = '\0'; 280 277 buff_pos = 0; ··· 333 328 seq_printf(seq, "%s", buff); 334 329 kfree(buff); 335 330 336 - return 0; 331 + out: 332 + if (primary_if) 333 + hardif_free_ref(primary_if); 334 + return ret; 337 335 } 338 336 339 337 /* add the info packet to the send list, if it was not ··· 823 815 /* only send one vis packet. called from send_vis_packets() */ 824 816 static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) 825 817 { 818 + struct hard_iface *primary_if; 826 819 struct vis_packet *packet; 820 + 821 + primary_if = primary_if_get_selected(bat_priv); 822 + if (!primary_if) 823 + goto out; 827 824 828 825 packet = (struct vis_packet *)info->skb_packet->data; 829 826 if (packet->ttl < 2) { 830 827 pr_debug("Error - can't send vis packet: ttl exceeded\n"); 831 - return; 828 + goto out; 832 829 } 833 830 834 - memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr, 835 - ETH_ALEN); 831 + memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN); 836 832 packet->ttl--; 837 833 838 834 if (is_broadcast_ether_addr(packet->target_orig)) ··· 844 832 else 845 833 unicast_vis_packet(bat_priv, info); 846 834 packet->ttl++; /* restore TTL */ 835 + 836 + out: 837 + if (primary_if) 838 + hardif_free_ref(primary_if); 847 839 } 848 840 849 841 /* called from timer; send (and maybe generate) vis packet. */ ··· 874 858 kref_get(&info->refcount); 875 859 spin_unlock_bh(&bat_priv->vis_hash_lock); 876 860 877 - if (bat_priv->primary_if) 878 - send_vis_packet(bat_priv, info); 861 + send_vis_packet(bat_priv, info); 879 862 880 863 spin_lock_bh(&bat_priv->vis_hash_lock); 881 864 send_list_del(info);