aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2013-04-23 09:39:58 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-09 15:22:27 -0400
commit414254e342a0d58144de40c3da777521ebaeeb07 (patch)
treea292367d064dd72f4b7a095382e11a9974d685af
parentef26157747d42254453f6b3ac2bd8bd3c53339c3 (diff)
batman-adv: tvlv - gateway download/upload bandwidth container
Prior to this patch batman-adv read the advertised uplink bandwidth from userspace and compressed this information into a single byte called "gateway class". Now the download & upload bandwidth information is sent as-is. No userspace change is necessary since the sysfs API always allowed to specify a bandwidth. Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Spyros Gasteratos <morfeas3000@gmail.com> Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
-rw-r--r--net/batman-adv/bat_iv_ogm.c23
-rw-r--r--net/batman-adv/gateway_client.c187
-rw-r--r--net/batman-adv/gateway_client.h2
-rw-r--r--net/batman-adv/gateway_common.c230
-rw-r--r--net/batman-adv/gateway_common.h14
-rw-r--r--net/batman-adv/main.c5
-rw-r--r--net/batman-adv/originator.c4
-rw-r--r--net/batman-adv/packet.h21
-rw-r--r--net/batman-adv/soft-interface.c3
-rw-r--r--net/batman-adv/sysfs.c17
-rw-r--r--net/batman-adv/types.h12
11 files changed, 327 insertions, 191 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index f7dd7e51fff4..f0f02d1a10d7 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -135,6 +135,7 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
135 batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION; 135 batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
136 batadv_ogm_packet->header.ttl = 2; 136 batadv_ogm_packet->header.ttl = 2;
137 batadv_ogm_packet->flags = BATADV_NO_FLAGS; 137 batadv_ogm_packet->flags = BATADV_NO_FLAGS;
138 batadv_ogm_packet->reserved = 0;
138 batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; 139 batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
139 batadv_ogm_packet->tt_num_changes = 0; 140 batadv_ogm_packet->tt_num_changes = 0;
140 batadv_ogm_packet->ttvn = 0; 141 batadv_ogm_packet->ttvn = 0;
@@ -690,7 +691,6 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
690 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len; 691 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
691 int vis_server, tt_num_changes = 0; 692 int vis_server, tt_num_changes = 0;
692 uint32_t seqno; 693 uint32_t seqno;
693 uint8_t bandwidth;
694 uint16_t tvlv_len = 0; 694 uint16_t tvlv_len = 0;
695 695
696 vis_server = atomic_read(&bat_priv->vis_mode); 696 vis_server = atomic_read(&bat_priv->vis_mode);
@@ -719,14 +719,6 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
719 else 719 else
720 batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER; 720 batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
721 721
722 if (hard_iface == primary_if &&
723 atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) {
724 bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
725 batadv_ogm_packet->gw_flags = bandwidth;
726 } else {
727 batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
728 }
729
730 batadv_iv_ogm_slide_own_bcast_window(hard_iface); 722 batadv_iv_ogm_slide_own_bcast_window(hard_iface);
731 batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff, 723 batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
732 hard_iface->bat_iv.ogm_buff_len, hard_iface, 1, 724 hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
@@ -861,19 +853,6 @@ update_tt:
861 batadv_ogm_packet->tt_num_changes, 853 batadv_ogm_packet->tt_num_changes,
862 batadv_ogm_packet->ttvn, 854 batadv_ogm_packet->ttvn,
863 ntohs(batadv_ogm_packet->tt_crc)); 855 ntohs(batadv_ogm_packet->tt_crc));
864
865 if (orig_node->gw_flags != batadv_ogm_packet->gw_flags)
866 batadv_gw_node_update(bat_priv, orig_node,
867 batadv_ogm_packet->gw_flags);
868
869 orig_node->gw_flags = batadv_ogm_packet->gw_flags;
870
871 /* restart gateway selection if fast or late switching was enabled */
872 if ((orig_node->gw_flags) &&
873 (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
874 (atomic_read(&bat_priv->gw_sel_class) > 2))
875 batadv_gw_check_election(bat_priv, orig_node);
876
877 goto out; 856 goto out;
878 857
879unlock: 858unlock:
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 1ce4b8763ef2..1bce63aa5f5f 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -118,7 +118,6 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
118 uint32_t max_gw_factor = 0, tmp_gw_factor = 0; 118 uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
119 uint32_t gw_divisor; 119 uint32_t gw_divisor;
120 uint8_t max_tq = 0; 120 uint8_t max_tq = 0;
121 int down, up;
122 uint8_t tq_avg; 121 uint8_t tq_avg;
123 struct batadv_orig_node *orig_node; 122 struct batadv_orig_node *orig_node;
124 123
@@ -142,10 +141,9 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
142 141
143 switch (atomic_read(&bat_priv->gw_sel_class)) { 142 switch (atomic_read(&bat_priv->gw_sel_class)) {
144 case 1: /* fast connection */ 143 case 1: /* fast connection */
145 batadv_gw_bandwidth_to_kbit(orig_node->gw_flags, 144 tmp_gw_factor = tq_avg * tq_avg;
146 &down, &up); 145 tmp_gw_factor *= gw_node->bandwidth_down;
147 146 tmp_gw_factor *= 100 * 100;
148 tmp_gw_factor = tq_avg * tq_avg * down * 100 * 100;
149 tmp_gw_factor /= gw_divisor; 147 tmp_gw_factor /= gw_divisor;
150 148
151 if ((tmp_gw_factor > max_gw_factor) || 149 if ((tmp_gw_factor > max_gw_factor) ||
@@ -258,16 +256,22 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
258 NULL); 256 NULL);
259 } else if ((!curr_gw) && (next_gw)) { 257 } else if ((!curr_gw) && (next_gw)) {
260 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 258 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
261 "Adding route to gateway %pM (gw_flags: %i, tq: %i)\n", 259 "Adding route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
262 next_gw->orig_node->orig, 260 next_gw->orig_node->orig,
263 next_gw->orig_node->gw_flags, router->tq_avg); 261 next_gw->bandwidth_down / 10,
262 next_gw->bandwidth_down % 10,
263 next_gw->bandwidth_up / 10,
264 next_gw->bandwidth_up % 10, router->tq_avg);
264 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD, 265 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
265 gw_addr); 266 gw_addr);
266 } else { 267 } else {
267 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 268 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
268 "Changing route to gateway %pM (gw_flags: %i, tq: %i)\n", 269 "Changing route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
269 next_gw->orig_node->orig, 270 next_gw->orig_node->orig,
270 next_gw->orig_node->gw_flags, router->tq_avg); 271 next_gw->bandwidth_down / 10,
272 next_gw->bandwidth_down % 10,
273 next_gw->bandwidth_up / 10,
274 next_gw->bandwidth_up % 10, router->tq_avg);
271 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE, 275 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
272 gw_addr); 276 gw_addr);
273 } 277 }
@@ -337,12 +341,20 @@ out:
337 return; 341 return;
338} 342}
339 343
344/**
345 * batadv_gw_node_add - add gateway node to list of available gateways
346 * @bat_priv: the bat priv with all the soft interface information
347 * @orig_node: originator announcing gateway capabilities
348 * @gateway: announced bandwidth information
349 */
340static void batadv_gw_node_add(struct batadv_priv *bat_priv, 350static void batadv_gw_node_add(struct batadv_priv *bat_priv,
341 struct batadv_orig_node *orig_node, 351 struct batadv_orig_node *orig_node,
342 uint8_t new_gwflags) 352 struct batadv_tvlv_gateway_data *gateway)
343{ 353{
344 struct batadv_gw_node *gw_node; 354 struct batadv_gw_node *gw_node;
345 int down, up; 355
356 if (gateway->bandwidth_down == 0)
357 return;
346 358
347 gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); 359 gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC);
348 if (!gw_node) 360 if (!gw_node)
@@ -356,73 +368,116 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
356 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list); 368 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list);
357 spin_unlock_bh(&bat_priv->gw.list_lock); 369 spin_unlock_bh(&bat_priv->gw.list_lock);
358 370
359 batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up);
360 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 371 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
361 "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", 372 "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
362 orig_node->orig, new_gwflags, 373 orig_node->orig,
363 (down > 2048 ? down / 1024 : down), 374 ntohl(gateway->bandwidth_down) / 10,
364 (down > 2048 ? "MBit" : "KBit"), 375 ntohl(gateway->bandwidth_down) % 10,
365 (up > 2048 ? up / 1024 : up), 376 ntohl(gateway->bandwidth_up) / 10,
366 (up > 2048 ? "MBit" : "KBit")); 377 ntohl(gateway->bandwidth_up) % 10);
367} 378}
368 379
369void batadv_gw_node_update(struct batadv_priv *bat_priv, 380/**
370 struct batadv_orig_node *orig_node, 381 * batadv_gw_node_get - retrieve gateway node from list of available gateways
371 uint8_t new_gwflags) 382 * @bat_priv: the bat priv with all the soft interface information
383 * @orig_node: originator announcing gateway capabilities
384 *
385 * Returns gateway node if found or NULL otherwise.
386 */
387static struct batadv_gw_node *
388batadv_gw_node_get(struct batadv_priv *bat_priv,
389 struct batadv_orig_node *orig_node)
372{ 390{
373 struct batadv_gw_node *gw_node, *curr_gw; 391 struct batadv_gw_node *gw_node_tmp, *gw_node = NULL;
374
375 /* Note: We don't need a NULL check here, since curr_gw never gets
376 * dereferenced. If curr_gw is NULL we also should not exit as we may
377 * have this gateway in our list (duplication check!) even though we
378 * have no currently selected gateway.
379 */
380 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
381 392
382 rcu_read_lock(); 393 rcu_read_lock();
383 hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) { 394 hlist_for_each_entry_rcu(gw_node_tmp, &bat_priv->gw.list, list) {
384 if (gw_node->orig_node != orig_node) 395 if (gw_node_tmp->orig_node != orig_node)
385 continue; 396 continue;
386 397
387 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 398 if (gw_node_tmp->deleted)
388 "Gateway class of originator %pM changed from %i to %i\n", 399 continue;
389 orig_node->orig, gw_node->orig_node->gw_flags,
390 new_gwflags);
391 400
392 gw_node->deleted = 0; 401 if (!atomic_inc_not_zero(&gw_node_tmp->refcount))
402 continue;
393 403
394 if (new_gwflags == BATADV_NO_FLAGS) { 404 gw_node = gw_node_tmp;
395 gw_node->deleted = jiffies; 405 break;
396 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 406 }
397 "Gateway %pM removed from gateway list\n", 407 rcu_read_unlock();
398 orig_node->orig);
399 408
400 if (gw_node == curr_gw) 409 return gw_node;
401 goto deselect; 410}
402 }
403 411
404 goto unlock; 412/**
413 * batadv_gw_node_update - update list of available gateways with changed
414 * bandwidth information
415 * @bat_priv: the bat priv with all the soft interface information
416 * @orig_node: originator announcing gateway capabilities
417 * @gateway: announced bandwidth information
418 */
419void batadv_gw_node_update(struct batadv_priv *bat_priv,
420 struct batadv_orig_node *orig_node,
421 struct batadv_tvlv_gateway_data *gateway)
422{
423 struct batadv_gw_node *gw_node, *curr_gw = NULL;
424
425 gw_node = batadv_gw_node_get(bat_priv, orig_node);
426 if (!gw_node) {
427 batadv_gw_node_add(bat_priv, orig_node, gateway);
428 goto out;
405 } 429 }
406 430
407 if (new_gwflags == BATADV_NO_FLAGS) 431 if ((gw_node->bandwidth_down == ntohl(gateway->bandwidth_down)) &&
408 goto unlock; 432 (gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)))
433 goto out;
409 434
410 batadv_gw_node_add(bat_priv, orig_node, new_gwflags); 435 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
411 goto unlock; 436 "Gateway bandwidth of originator %pM changed from %u.%u/%u.%u MBit to %u.%u/%u.%u MBit\n",
437 orig_node->orig,
438 gw_node->bandwidth_down / 10,
439 gw_node->bandwidth_down % 10,
440 gw_node->bandwidth_up / 10,
441 gw_node->bandwidth_up % 10,
442 ntohl(gateway->bandwidth_down) / 10,
443 ntohl(gateway->bandwidth_down) % 10,
444 ntohl(gateway->bandwidth_up) / 10,
445 ntohl(gateway->bandwidth_up) % 10);
446
447 gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
448 gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
449
450 gw_node->deleted = 0;
451 if (ntohl(gateway->bandwidth_down) == 0) {
452 gw_node->deleted = jiffies;
453 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
454 "Gateway %pM removed from gateway list\n",
455 orig_node->orig);
412 456
413deselect: 457 /* Note: We don't need a NULL check here, since curr_gw never
414 batadv_gw_deselect(bat_priv); 458 * gets dereferenced.
415unlock: 459 */
416 rcu_read_unlock(); 460 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
461 if (gw_node == curr_gw)
462 batadv_gw_deselect(bat_priv);
463 }
417 464
465out:
418 if (curr_gw) 466 if (curr_gw)
419 batadv_gw_node_free_ref(curr_gw); 467 batadv_gw_node_free_ref(curr_gw);
468 if (gw_node)
469 batadv_gw_node_free_ref(gw_node);
420} 470}
421 471
422void batadv_gw_node_delete(struct batadv_priv *bat_priv, 472void batadv_gw_node_delete(struct batadv_priv *bat_priv,
423 struct batadv_orig_node *orig_node) 473 struct batadv_orig_node *orig_node)
424{ 474{
425 batadv_gw_node_update(bat_priv, orig_node, 0); 475 struct batadv_tvlv_gateway_data gateway;
476
477 gateway.bandwidth_down = 0;
478 gateway.bandwidth_up = 0;
479
480 batadv_gw_node_update(bat_priv, orig_node, &gateway);
426} 481}
427 482
428void batadv_gw_node_purge(struct batadv_priv *bat_priv) 483void batadv_gw_node_purge(struct batadv_priv *bat_priv)
@@ -467,9 +522,7 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
467{ 522{
468 struct batadv_gw_node *curr_gw; 523 struct batadv_gw_node *curr_gw;
469 struct batadv_neigh_node *router; 524 struct batadv_neigh_node *router;
470 int down, up, ret = -1; 525 int ret = -1;
471
472 batadv_gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
473 526
474 router = batadv_orig_node_get_router(gw_node->orig_node); 527 router = batadv_orig_node_get_router(gw_node->orig_node);
475 if (!router) 528 if (!router)
@@ -477,16 +530,15 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
477 530
478 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 531 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
479 532
480 ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", 533 ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
481 (curr_gw == gw_node ? "=>" : " "), 534 (curr_gw == gw_node ? "=>" : " "),
482 gw_node->orig_node->orig, 535 gw_node->orig_node->orig,
483 router->tq_avg, router->addr, 536 router->tq_avg, router->addr,
484 router->if_incoming->net_dev->name, 537 router->if_incoming->net_dev->name,
485 gw_node->orig_node->gw_flags, 538 gw_node->bandwidth_down / 10,
486 (down > 2048 ? down / 1024 : down), 539 gw_node->bandwidth_down % 10,
487 (down > 2048 ? "MBit" : "KBit"), 540 gw_node->bandwidth_up / 10,
488 (up > 2048 ? up / 1024 : up), 541 gw_node->bandwidth_up % 10);
489 (up > 2048 ? "MBit" : "KBit"));
490 542
491 batadv_neigh_node_free_ref(router); 543 batadv_neigh_node_free_ref(router);
492 if (curr_gw) 544 if (curr_gw)
@@ -508,7 +560,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
508 goto out; 560 goto out;
509 561
510 seq_printf(seq, 562 seq_printf(seq,
511 " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", 563 " %-12s (%s/%i) %17s [%10s]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
512 "Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF", 564 "Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF",
513 BATADV_SOURCE_VERSION, primary_if->net_dev->name, 565 BATADV_SOURCE_VERSION, primary_if->net_dev->name,
514 primary_if->net_dev->dev_addr, net_dev->name); 566 primary_if->net_dev->dev_addr, net_dev->name);
@@ -675,7 +727,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
675{ 727{
676 struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL; 728 struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL;
677 struct batadv_orig_node *orig_dst_node = NULL; 729 struct batadv_orig_node *orig_dst_node = NULL;
678 struct batadv_gw_node *curr_gw = NULL; 730 struct batadv_gw_node *gw_node = NULL, *curr_gw = NULL;
679 struct ethhdr *ethhdr; 731 struct ethhdr *ethhdr;
680 bool ret, out_of_range = false; 732 bool ret, out_of_range = false;
681 unsigned int header_len = 0; 733 unsigned int header_len = 0;
@@ -691,7 +743,8 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
691 if (!orig_dst_node) 743 if (!orig_dst_node)
692 goto out; 744 goto out;
693 745
694 if (!orig_dst_node->gw_flags) 746 gw_node = batadv_gw_node_get(bat_priv, orig_dst_node);
747 if (!gw_node->bandwidth_down == 0)
695 goto out; 748 goto out;
696 749
697 ret = batadv_is_type_dhcprequest(skb, header_len); 750 ret = batadv_is_type_dhcprequest(skb, header_len);
@@ -742,6 +795,8 @@ out:
742 batadv_orig_node_free_ref(orig_dst_node); 795 batadv_orig_node_free_ref(orig_dst_node);
743 if (curr_gw) 796 if (curr_gw)
744 batadv_gw_node_free_ref(curr_gw); 797 batadv_gw_node_free_ref(curr_gw);
798 if (gw_node)
799 batadv_gw_node_free_ref(gw_node);
745 if (neigh_old) 800 if (neigh_old)
746 batadv_neigh_node_free_ref(neigh_old); 801 batadv_neigh_node_free_ref(neigh_old);
747 if (neigh_curr) 802 if (neigh_curr)
diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h
index ceef4ebe8bcd..d95c2d23195e 100644
--- a/net/batman-adv/gateway_client.h
+++ b/net/batman-adv/gateway_client.h
@@ -29,7 +29,7 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
29 struct batadv_orig_node *orig_node); 29 struct batadv_orig_node *orig_node);
30void batadv_gw_node_update(struct batadv_priv *bat_priv, 30void batadv_gw_node_update(struct batadv_priv *bat_priv,
31 struct batadv_orig_node *orig_node, 31 struct batadv_orig_node *orig_node,
32 uint8_t new_gwflags); 32 struct batadv_tvlv_gateway_data *gateway);
33void batadv_gw_node_delete(struct batadv_priv *bat_priv, 33void batadv_gw_node_delete(struct batadv_priv *bat_priv,
34 struct batadv_orig_node *orig_node); 34 struct batadv_orig_node *orig_node);
35void batadv_gw_node_purge(struct batadv_priv *bat_priv); 35void batadv_gw_node_purge(struct batadv_priv *bat_priv);
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index 84bb2b18d711..b211b0f9cb78 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -21,64 +21,23 @@
21#include "gateway_common.h" 21#include "gateway_common.h"
22#include "gateway_client.h" 22#include "gateway_client.h"
23 23
24/* calculates the gateway class from kbit */ 24/**
25static void batadv_kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) 25 * batadv_parse_gw_bandwidth - parse supplied string buffer to extract download
26{ 26 * and upload bandwidth information
27 int mdown = 0, tdown, tup, difference; 27 * @net_dev: the soft interface net device
28 uint8_t sbit, part; 28 * @buff: string buffer to parse
29 29 * @down: pointer holding the returned download bandwidth information
30 *gw_srv_class = 0; 30 * @up: pointer holding the returned upload bandwidth information
31 difference = 0x0FFFFFFF; 31 *
32 32 * Returns false on parse error and true otherwise.
33 /* test all downspeeds */ 33 */
34 for (sbit = 0; sbit < 2; sbit++) {
35 for (part = 0; part < 16; part++) {
36 tdown = 32 * (sbit + 2) * (1 << part);
37
38 if (abs(tdown - down) < difference) {
39 *gw_srv_class = (sbit << 7) + (part << 3);
40 difference = abs(tdown - down);
41 mdown = tdown;
42 }
43 }
44 }
45
46 /* test all upspeeds */
47 difference = 0x0FFFFFFF;
48
49 for (part = 0; part < 8; part++) {
50 tup = ((part + 1) * (mdown)) / 8;
51
52 if (abs(tup - up) < difference) {
53 *gw_srv_class = (*gw_srv_class & 0xF8) | part;
54 difference = abs(tup - up);
55 }
56 }
57}
58
59/* returns the up and downspeeds in kbit, calculated from the class */
60void batadv_gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up)
61{
62 int sbit = (gw_srv_class & 0x80) >> 7;
63 int dpart = (gw_srv_class & 0x78) >> 3;
64 int upart = (gw_srv_class & 0x07);
65
66 if (!gw_srv_class) {
67 *down = 0;
68 *up = 0;
69 return;
70 }
71
72 *down = 32 * (sbit + 2) * (1 << dpart);
73 *up = ((upart + 1) * (*down)) / 8;
74}
75
76static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, 34static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
77 int *up, int *down) 35 uint32_t *down, uint32_t *up)
78{ 36{
79 int ret, multi = 1; 37 enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT;
80 char *slash_ptr, *tmp_ptr; 38 char *slash_ptr, *tmp_ptr;
81 long ldown, lup; 39 long ldown, lup;
40 int ret;
82 41
83 slash_ptr = strchr(buff, '/'); 42 slash_ptr = strchr(buff, '/');
84 if (slash_ptr) 43 if (slash_ptr)
@@ -88,10 +47,10 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
88 tmp_ptr = buff + strlen(buff) - 4; 47 tmp_ptr = buff + strlen(buff) - 4;
89 48
90 if (strnicmp(tmp_ptr, "mbit", 4) == 0) 49 if (strnicmp(tmp_ptr, "mbit", 4) == 0)
91 multi = 1024; 50 bw_unit_type = BATADV_BW_UNIT_MBIT;
92 51
93 if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || 52 if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
94 (multi > 1)) 53 (bw_unit_type == BATADV_BW_UNIT_MBIT))
95 *tmp_ptr = '\0'; 54 *tmp_ptr = '\0';
96 } 55 }
97 56
@@ -103,20 +62,28 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
103 return false; 62 return false;
104 } 63 }
105 64
106 *down = ldown * multi; 65 switch (bw_unit_type) {
66 case BATADV_BW_UNIT_MBIT:
67 *down = ldown * 10;
68 break;
69 case BATADV_BW_UNIT_KBIT:
70 default:
71 *down = ldown / 100;
72 break;
73 }
107 74
108 /* we also got some upload info */ 75 /* we also got some upload info */
109 if (slash_ptr) { 76 if (slash_ptr) {
110 multi = 1; 77 bw_unit_type = BATADV_BW_UNIT_KBIT;
111 78
112 if (strlen(slash_ptr + 1) > 4) { 79 if (strlen(slash_ptr + 1) > 4) {
113 tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); 80 tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1);
114 81
115 if (strnicmp(tmp_ptr, "mbit", 4) == 0) 82 if (strnicmp(tmp_ptr, "mbit", 4) == 0)
116 multi = 1024; 83 bw_unit_type = BATADV_BW_UNIT_MBIT;
117 84
118 if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || 85 if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
119 (multi > 1)) 86 (bw_unit_type == BATADV_BW_UNIT_MBIT))
120 *tmp_ptr = '\0'; 87 *tmp_ptr = '\0';
121 } 88 }
122 89
@@ -128,52 +95,149 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
128 return false; 95 return false;
129 } 96 }
130 97
131 *up = lup * multi; 98 switch (bw_unit_type) {
99 case BATADV_BW_UNIT_MBIT:
100 *up = lup * 10;
101 break;
102 case BATADV_BW_UNIT_KBIT:
103 default:
104 *up = lup / 100;
105 break;
106 }
132 } 107 }
133 108
134 return true; 109 return true;
135} 110}
136 111
112/**
113 * batadv_gw_tvlv_container_update - update the gw tvlv container after gateway
114 * setting change
115 * @bat_priv: the bat priv with all the soft interface information
116 */
117void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
118{
119 struct batadv_tvlv_gateway_data gw;
120 uint32_t down, up;
121 char gw_mode;
122
123 gw_mode = atomic_read(&bat_priv->gw_mode);
124
125 switch (gw_mode) {
126 case BATADV_GW_MODE_OFF:
127 case BATADV_GW_MODE_CLIENT:
128 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
129 break;
130 case BATADV_GW_MODE_SERVER:
131 down = atomic_read(&bat_priv->gw.bandwidth_down);
132 up = atomic_read(&bat_priv->gw.bandwidth_up);
133 gw.bandwidth_down = htonl(down);
134 gw.bandwidth_up = htonl(up);
135 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1,
136 &gw, sizeof(gw));
137 break;
138 }
139}
140
137ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, 141ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
138 size_t count) 142 size_t count)
139{ 143{
140 struct batadv_priv *bat_priv = netdev_priv(net_dev); 144 struct batadv_priv *bat_priv = netdev_priv(net_dev);
141 long gw_bandwidth_tmp = 0; 145 uint32_t down_curr, up_curr, down_new = 0, up_new = 0;
142 int up = 0, down = 0;
143 bool ret; 146 bool ret;
144 147
145 ret = batadv_parse_gw_bandwidth(net_dev, buff, &up, &down); 148 down_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_down);
149 up_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_up);
150
151 ret = batadv_parse_gw_bandwidth(net_dev, buff, &down_new, &up_new);
146 if (!ret) 152 if (!ret)
147 goto end; 153 goto end;
148 154
149 if ((!down) || (down < 256)) 155 if (!down_new)
150 down = 2000; 156 down_new = 1;
151
152 if (!up)
153 up = down / 5;
154 157
155 batadv_kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); 158 if (!up_new)
159 up_new = down_new / 5;
156 160
157 /* the gw bandwidth we guessed above might not match the given 161 if (!up_new)
158 * speeds, hence we need to calculate it back to show the number 162 up_new = 1;
159 * that is going to be propagated
160 */
161 batadv_gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up);
162 163
163 if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp) 164 if ((down_curr == down_new) && (up_curr == up_new))
164 return count; 165 return count;
165 166
166 batadv_gw_deselect(bat_priv); 167 batadv_gw_deselect(bat_priv);
167 batadv_info(net_dev, 168 batadv_info(net_dev,
168 "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n", 169 "Changing gateway bandwidth from: '%u.%u/%u.%u MBit' to: '%u.%u/%u.%u MBit'\n",
169 atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, 170 down_curr / 10, down_curr % 10, up_curr / 10, up_curr % 10,
170 (down > 2048 ? down / 1024 : down), 171 down_new / 10, down_new % 10, up_new / 10, up_new % 10);
171 (down > 2048 ? "MBit" : "KBit"),
172 (up > 2048 ? up / 1024 : up),
173 (up > 2048 ? "MBit" : "KBit"));
174 172
175 atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); 173 atomic_set(&bat_priv->gw.bandwidth_down, down_new);
174 atomic_set(&bat_priv->gw.bandwidth_up, up_new);
175 batadv_gw_tvlv_container_update(bat_priv);
176 176
177end: 177end:
178 return count; 178 return count;
179} 179}
180
181/**
182 * batadv_gw_tvlv_ogm_handler_v1 - process incoming gateway tvlv container
183 * @bat_priv: the bat priv with all the soft interface information
184 * @orig: the orig_node of the ogm
185 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
186 * @tvlv_value: tvlv buffer containing the gateway data
187 * @tvlv_value_len: tvlv buffer length
188 */
189static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
190 struct batadv_orig_node *orig,
191 uint8_t flags,
192 void *tvlv_value,
193 uint16_t tvlv_value_len)
194{
195 struct batadv_tvlv_gateway_data gateway, *gateway_ptr;
196
197 /* only fetch the tvlv value if the handler wasn't called via the
198 * CIFNOTFND flag and if there is data to fetch
199 */
200 if ((flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) ||
201 (tvlv_value_len < sizeof(gateway))) {
202 gateway.bandwidth_down = 0;
203 gateway.bandwidth_up = 0;
204 } else {
205 gateway_ptr = tvlv_value;
206 gateway.bandwidth_down = gateway_ptr->bandwidth_down;
207 gateway.bandwidth_up = gateway_ptr->bandwidth_up;
208 if ((gateway.bandwidth_down == 0) ||
209 (gateway.bandwidth_up == 0)) {
210 gateway.bandwidth_down = 0;
211 gateway.bandwidth_up = 0;
212 }
213 }
214
215 batadv_gw_node_update(bat_priv, orig, &gateway);
216
217 /* restart gateway selection if fast or late switching was enabled */
218 if ((gateway.bandwidth_down != 0) &&
219 (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
220 (atomic_read(&bat_priv->gw_sel_class) > 2))
221 batadv_gw_check_election(bat_priv, orig);
222}
223
224/**
225 * batadv_gw_init - initialise the gateway handling internals
226 * @bat_priv: the bat priv with all the soft interface information
227 */
228void batadv_gw_init(struct batadv_priv *bat_priv)
229{
230 batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
231 NULL, BATADV_TVLV_GW, 1,
232 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
233}
234
235/**
236 * batadv_gw_free - free the gateway handling internals
237 * @bat_priv: the bat priv with all the soft interface information
238 */
239void batadv_gw_free(struct batadv_priv *bat_priv)
240{
241 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
242 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_GW, 1);
243}
diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h
index 509b2bf8c2f4..56384a4cd18c 100644
--- a/net/batman-adv/gateway_common.h
+++ b/net/batman-adv/gateway_common.h
@@ -26,12 +26,24 @@ enum batadv_gw_modes {
26 BATADV_GW_MODE_SERVER, 26 BATADV_GW_MODE_SERVER,
27}; 27};
28 28
29/**
30 * enum batadv_bandwidth_units - bandwidth unit types
31 * @BATADV_BW_UNIT_KBIT: unit type kbit
32 * @BATADV_BW_UNIT_MBIT: unit type mbit
33 */
34enum batadv_bandwidth_units {
35 BATADV_BW_UNIT_KBIT,
36 BATADV_BW_UNIT_MBIT,
37};
38
29#define BATADV_GW_MODE_OFF_NAME "off" 39#define BATADV_GW_MODE_OFF_NAME "off"
30#define BATADV_GW_MODE_CLIENT_NAME "client" 40#define BATADV_GW_MODE_CLIENT_NAME "client"
31#define BATADV_GW_MODE_SERVER_NAME "server" 41#define BATADV_GW_MODE_SERVER_NAME "server"
32 42
33void batadv_gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up);
34ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, 43ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
35 size_t count); 44 size_t count);
45void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv);
46void batadv_gw_init(struct batadv_priv *bat_priv);
47void batadv_gw_free(struct batadv_priv *bat_priv);
36 48
37#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ 49#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index e2de68a5b0c6..cb9a446baba8 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -37,6 +37,7 @@
37#include "bridge_loop_avoidance.h" 37#include "bridge_loop_avoidance.h"
38#include "distributed-arp-table.h" 38#include "distributed-arp-table.h"
39#include "unicast.h" 39#include "unicast.h"
40#include "gateway_common.h"
40#include "vis.h" 41#include "vis.h"
41#include "hash.h" 42#include "hash.h"
42#include "bat_algo.h" 43#include "bat_algo.h"
@@ -152,6 +153,8 @@ int batadv_mesh_init(struct net_device *soft_iface)
152 if (ret < 0) 153 if (ret < 0)
153 goto err; 154 goto err;
154 155
156 batadv_gw_init(bat_priv);
157
155 atomic_set(&bat_priv->gw.reselect, 0); 158 atomic_set(&bat_priv->gw.reselect, 0);
156 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); 159 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
157 160
@@ -190,6 +193,8 @@ void batadv_mesh_free(struct net_device *soft_iface)
190 */ 193 */
191 batadv_originator_free(bat_priv); 194 batadv_originator_free(bat_priv);
192 195
196 batadv_gw_free(bat_priv);
197
193 free_percpu(bat_priv->bat_counters); 198 free_percpu(bat_priv->bat_counters);
194 bat_priv->bat_counters = NULL; 199 bat_priv->bat_counters = NULL;
195 200
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index f50553a7de62..5d53d2f38377 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -388,9 +388,7 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
388 hlist_for_each_entry_safe(orig_node, node_tmp, 388 hlist_for_each_entry_safe(orig_node, node_tmp,
389 head, hash_entry) { 389 head, hash_entry) {
390 if (batadv_purge_orig_node(bat_priv, orig_node)) { 390 if (batadv_purge_orig_node(bat_priv, orig_node)) {
391 if (orig_node->gw_flags) 391 batadv_gw_node_delete(bat_priv, orig_node);
392 batadv_gw_node_delete(bat_priv,
393 orig_node);
394 hlist_del_rcu(&orig_node->hash_entry); 392 hlist_del_rcu(&orig_node->hash_entry);
395 batadv_orig_node_free_ref(orig_node); 393 batadv_orig_node_free_ref(orig_node);
396 continue; 394 continue;
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index b5c21c418a5f..6d0b3a73cee7 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -118,6 +118,14 @@ enum batadv_bla_claimframe {
118 BATADV_CLAIM_TYPE_REQUEST = 0x03, 118 BATADV_CLAIM_TYPE_REQUEST = 0x03,
119}; 119};
120 120
121/**
122 * enum batadv_tvlv_type - tvlv type definitions
123 * @BATADV_TVLV_GW: gateway tvlv
124 */
125enum batadv_tvlv_type {
126 BATADV_TVLV_GW = 0x01,
127};
128
121/* the destination hardware field in the ARP frame is used to 129/* the destination hardware field in the ARP frame is used to
122 * transport the claim type and the group id 130 * transport the claim type and the group id
123 */ 131 */
@@ -147,7 +155,7 @@ struct batadv_ogm_packet {
147 __be32 seqno; 155 __be32 seqno;
148 uint8_t orig[ETH_ALEN]; 156 uint8_t orig[ETH_ALEN];
149 uint8_t prev_sender[ETH_ALEN]; 157 uint8_t prev_sender[ETH_ALEN];
150 uint8_t gw_flags; /* flags related to gateway class */ 158 uint8_t reserved;
151 uint8_t tq; 159 uint8_t tq;
152 uint8_t tt_num_changes; 160 uint8_t tt_num_changes;
153 uint8_t ttvn; /* translation table version number */ 161 uint8_t ttvn; /* translation table version number */
@@ -352,4 +360,15 @@ struct batadv_tvlv_hdr {
352 __be16 len; 360 __be16 len;
353}; 361};
354 362
363/**
364 * struct batadv_tvlv_gateway_data - gateway data propagated through gw tvlv
365 * container
366 * @bandwidth_down: advertised uplink download bandwidth
367 * @bandwidth_up: advertised uplink upload bandwidth
368 */
369struct batadv_tvlv_gateway_data {
370 __be32 bandwidth_down;
371 __be32 bandwidth_up;
372};
373
355#endif /* _NET_BATMAN_ADV_PACKET_H_ */ 374#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 813db4e64602..84623a955d52 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -472,7 +472,8 @@ static int batadv_softif_init_late(struct net_device *dev)
472 atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE); 472 atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
473 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); 473 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
474 atomic_set(&bat_priv->gw_sel_class, 20); 474 atomic_set(&bat_priv->gw_sel_class, 20);
475 atomic_set(&bat_priv->gw_bandwidth, 41); 475 atomic_set(&bat_priv->gw.bandwidth_down, 100);
476 atomic_set(&bat_priv->gw.bandwidth_up, 20);
476 atomic_set(&bat_priv->orig_interval, 1000); 477 atomic_set(&bat_priv->orig_interval, 1000);
477 atomic_set(&bat_priv->hop_penalty, 30); 478 atomic_set(&bat_priv->hop_penalty, 30);
478#ifdef CONFIG_BATMAN_ADV_DEBUG 479#ifdef CONFIG_BATMAN_ADV_DEBUG
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 4114b961bc2c..68793f53f182 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -390,6 +390,7 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
390 */ 390 */
391 batadv_gw_check_client_stop(bat_priv); 391 batadv_gw_check_client_stop(bat_priv);
392 atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp); 392 atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
393 batadv_gw_tvlv_container_update(bat_priv);
393 return count; 394 return count;
394} 395}
395 396
@@ -397,15 +398,13 @@ static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
397 struct attribute *attr, char *buff) 398 struct attribute *attr, char *buff)
398{ 399{
399 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 400 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
400 int down, up; 401 uint32_t down, up;
401 int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); 402
402 403 down = atomic_read(&bat_priv->gw.bandwidth_down);
403 batadv_gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); 404 up = atomic_read(&bat_priv->gw.bandwidth_up);
404 return sprintf(buff, "%i%s/%i%s\n", 405
405 (down > 2048 ? down / 1024 : down), 406 return sprintf(buff, "%u.%u/%u.%u MBit\n", down / 10,
406 (down > 2048 ? "MBit" : "KBit"), 407 down % 10, up / 10, up % 10);
407 (up > 2048 ? up / 1024 : up),
408 (up > 2048 ? "MBit" : "KBit"));
409} 408}
410 409
411static ssize_t batadv_store_gw_bwidth(struct kobject *kobj, 410static ssize_t batadv_store_gw_bwidth(struct kobject *kobj,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 4bdea16bc70c..b22a04391f6c 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -99,7 +99,6 @@ struct batadv_hard_iface {
99 * @last_seen: time when last packet from this node was received 99 * @last_seen: time when last packet from this node was received
100 * @bcast_seqno_reset: time when the broadcast seqno window was reset 100 * @bcast_seqno_reset: time when the broadcast seqno window was reset
101 * @batman_seqno_reset: time when the batman seqno window was reset 101 * @batman_seqno_reset: time when the batman seqno window was reset
102 * @gw_flags: flags related to gateway class
103 * @flags: for now only VIS_SERVER flag 102 * @flags: for now only VIS_SERVER flag
104 * @last_ttvn: last seen translation table version number 103 * @last_ttvn: last seen translation table version number
105 * @tt_crc: CRC of the translation table 104 * @tt_crc: CRC of the translation table
@@ -147,7 +146,6 @@ struct batadv_orig_node {
147 unsigned long last_seen; 146 unsigned long last_seen;
148 unsigned long bcast_seqno_reset; 147 unsigned long bcast_seqno_reset;
149 unsigned long batman_seqno_reset; 148 unsigned long batman_seqno_reset;
150 uint8_t gw_flags;
151 uint8_t flags; 149 uint8_t flags;
152 atomic_t last_ttvn; 150 atomic_t last_ttvn;
153 uint16_t tt_crc; 151 uint16_t tt_crc;
@@ -189,6 +187,8 @@ struct batadv_orig_node {
189 * struct batadv_gw_node - structure for orig nodes announcing gw capabilities 187 * struct batadv_gw_node - structure for orig nodes announcing gw capabilities
190 * @list: list node for batadv_priv_gw::list 188 * @list: list node for batadv_priv_gw::list
191 * @orig_node: pointer to corresponding orig node 189 * @orig_node: pointer to corresponding orig node
190 * @bandwidth_down: advertised uplink download bandwidth
191 * @bandwidth_up: advertised uplink upload bandwidth
192 * @deleted: this struct is scheduled for deletion 192 * @deleted: this struct is scheduled for deletion
193 * @refcount: number of contexts the object is used 193 * @refcount: number of contexts the object is used
194 * @rcu: struct used for freeing in an RCU-safe manner 194 * @rcu: struct used for freeing in an RCU-safe manner
@@ -196,6 +196,8 @@ struct batadv_orig_node {
196struct batadv_gw_node { 196struct batadv_gw_node {
197 struct hlist_node list; 197 struct hlist_node list;
198 struct batadv_orig_node *orig_node; 198 struct batadv_orig_node *orig_node;
199 uint32_t bandwidth_down;
200 uint32_t bandwidth_up;
199 unsigned long deleted; 201 unsigned long deleted;
200 atomic_t refcount; 202 atomic_t refcount;
201 struct rcu_head rcu; 203 struct rcu_head rcu;
@@ -420,12 +422,16 @@ struct batadv_priv_debug_log {
420 * @list: list of available gateway nodes 422 * @list: list of available gateway nodes
421 * @list_lock: lock protecting gw_list & curr_gw 423 * @list_lock: lock protecting gw_list & curr_gw
422 * @curr_gw: pointer to currently selected gateway node 424 * @curr_gw: pointer to currently selected gateway node
425 * @bandwidth_down: advertised uplink download bandwidth (if gw_mode server)
426 * @bandwidth_up: advertised uplink upload bandwidth (if gw_mode server)
423 * @reselect: bool indicating a gateway re-selection is in progress 427 * @reselect: bool indicating a gateway re-selection is in progress
424 */ 428 */
425struct batadv_priv_gw { 429struct batadv_priv_gw {
426 struct hlist_head list; 430 struct hlist_head list;
427 spinlock_t list_lock; /* protects gw_list & curr_gw */ 431 spinlock_t list_lock; /* protects gw_list & curr_gw */
428 struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */ 432 struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
433 atomic_t bandwidth_down;
434 atomic_t bandwidth_up;
429 atomic_t reselect; 435 atomic_t reselect;
430}; 436};
431 437
@@ -521,7 +527,6 @@ struct batadv_priv_nc {
521 * @vis_mode: vis operation: client or server (see batadv_vis_packettype) 527 * @vis_mode: vis operation: client or server (see batadv_vis_packettype)
522 * @gw_mode: gateway operation: off, client or server (see batadv_gw_modes) 528 * @gw_mode: gateway operation: off, client or server (see batadv_gw_modes)
523 * @gw_sel_class: gateway selection class (applies if gw_mode client) 529 * @gw_sel_class: gateway selection class (applies if gw_mode client)
524 * @gw_bandwidth: gateway announced bandwidth (applies if gw_mode server)
525 * @orig_interval: OGM broadcast interval in milliseconds 530 * @orig_interval: OGM broadcast interval in milliseconds
526 * @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop 531 * @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop
527 * @log_level: configured log level (see batadv_dbg_level) 532 * @log_level: configured log level (see batadv_dbg_level)
@@ -569,7 +574,6 @@ struct batadv_priv {
569 atomic_t vis_mode; 574 atomic_t vis_mode;
570 atomic_t gw_mode; 575 atomic_t gw_mode;
571 atomic_t gw_sel_class; 576 atomic_t gw_sel_class;
572 atomic_t gw_bandwidth;
573 atomic_t orig_interval; 577 atomic_t orig_interval;
574 atomic_t hop_penalty; 578 atomic_t hop_penalty;
575#ifdef CONFIG_BATMAN_ADV_DEBUG 579#ifdef CONFIG_BATMAN_ADV_DEBUG