diff options
Diffstat (limited to 'net/batman-adv/soft-interface.c')
-rw-r--r-- | net/batman-adv/soft-interface.c | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 21c53577c8d6..b9a28d2dd3e8 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -93,7 +93,14 @@ static int batadv_interface_release(struct net_device *dev) | |||
93 | static struct net_device_stats *batadv_interface_stats(struct net_device *dev) | 93 | static struct net_device_stats *batadv_interface_stats(struct net_device *dev) |
94 | { | 94 | { |
95 | struct batadv_priv *bat_priv = netdev_priv(dev); | 95 | struct batadv_priv *bat_priv = netdev_priv(dev); |
96 | return &bat_priv->stats; | 96 | struct net_device_stats *stats = &bat_priv->stats; |
97 | |||
98 | stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX); | ||
99 | stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES); | ||
100 | stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED); | ||
101 | stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX); | ||
102 | stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES); | ||
103 | return stats; | ||
97 | } | 104 | } |
98 | 105 | ||
99 | static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) | 106 | static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) |
@@ -145,6 +152,7 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
145 | int data_len = skb->len, ret; | 152 | int data_len = skb->len, ret; |
146 | short vid __maybe_unused = -1; | 153 | short vid __maybe_unused = -1; |
147 | bool do_bcast = false; | 154 | bool do_bcast = false; |
155 | uint32_t seqno; | ||
148 | 156 | ||
149 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) | 157 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
150 | goto dropped; | 158 | goto dropped; |
@@ -226,8 +234,8 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
226 | primary_if->net_dev->dev_addr, ETH_ALEN); | 234 | primary_if->net_dev->dev_addr, ETH_ALEN); |
227 | 235 | ||
228 | /* set broadcast sequence number */ | 236 | /* set broadcast sequence number */ |
229 | bcast_packet->seqno = | 237 | seqno = atomic_inc_return(&bat_priv->bcast_seqno); |
230 | htonl(atomic_inc_return(&bat_priv->bcast_seqno)); | 238 | bcast_packet->seqno = htonl(seqno); |
231 | 239 | ||
232 | batadv_add_bcast_packet_to_list(bat_priv, skb, 1); | 240 | batadv_add_bcast_packet_to_list(bat_priv, skb, 1); |
233 | 241 | ||
@@ -249,14 +257,14 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
249 | goto dropped_freed; | 257 | goto dropped_freed; |
250 | } | 258 | } |
251 | 259 | ||
252 | bat_priv->stats.tx_packets++; | 260 | batadv_inc_counter(bat_priv, BATADV_CNT_TX); |
253 | bat_priv->stats.tx_bytes += data_len; | 261 | batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len); |
254 | goto end; | 262 | goto end; |
255 | 263 | ||
256 | dropped: | 264 | dropped: |
257 | kfree_skb(skb); | 265 | kfree_skb(skb); |
258 | dropped_freed: | 266 | dropped_freed: |
259 | bat_priv->stats.tx_dropped++; | 267 | batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); |
260 | end: | 268 | end: |
261 | if (primary_if) | 269 | if (primary_if) |
262 | batadv_hardif_free_ref(primary_if); | 270 | batadv_hardif_free_ref(primary_if); |
@@ -265,7 +273,7 @@ end: | |||
265 | 273 | ||
266 | void batadv_interface_rx(struct net_device *soft_iface, | 274 | void batadv_interface_rx(struct net_device *soft_iface, |
267 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, | 275 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, |
268 | int hdr_size) | 276 | int hdr_size, struct batadv_orig_node *orig_node) |
269 | { | 277 | { |
270 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 278 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
271 | struct ethhdr *ethhdr; | 279 | struct ethhdr *ethhdr; |
@@ -311,11 +319,16 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
311 | 319 | ||
312 | /* skb->ip_summed = CHECKSUM_UNNECESSARY; */ | 320 | /* skb->ip_summed = CHECKSUM_UNNECESSARY; */ |
313 | 321 | ||
314 | bat_priv->stats.rx_packets++; | 322 | batadv_inc_counter(bat_priv, BATADV_CNT_RX); |
315 | bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; | 323 | batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, |
324 | skb->len + ETH_HLEN); | ||
316 | 325 | ||
317 | soft_iface->last_rx = jiffies; | 326 | soft_iface->last_rx = jiffies; |
318 | 327 | ||
328 | if (orig_node) | ||
329 | batadv_tt_add_temporary_global_entry(bat_priv, orig_node, | ||
330 | ethhdr->h_source); | ||
331 | |||
319 | if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) | 332 | if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) |
320 | goto dropped; | 333 | goto dropped; |
321 | 334 | ||
@@ -382,15 +395,22 @@ struct net_device *batadv_softif_create(const char *name) | |||
382 | if (!soft_iface) | 395 | if (!soft_iface) |
383 | goto out; | 396 | goto out; |
384 | 397 | ||
398 | bat_priv = netdev_priv(soft_iface); | ||
399 | |||
400 | /* batadv_interface_stats() needs to be available as soon as | ||
401 | * register_netdevice() has been called | ||
402 | */ | ||
403 | bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); | ||
404 | if (!bat_priv->bat_counters) | ||
405 | goto free_soft_iface; | ||
406 | |||
385 | ret = register_netdevice(soft_iface); | 407 | ret = register_netdevice(soft_iface); |
386 | if (ret < 0) { | 408 | if (ret < 0) { |
387 | pr_err("Unable to register the batman interface '%s': %i\n", | 409 | pr_err("Unable to register the batman interface '%s': %i\n", |
388 | name, ret); | 410 | name, ret); |
389 | goto free_soft_iface; | 411 | goto free_bat_counters; |
390 | } | 412 | } |
391 | 413 | ||
392 | bat_priv = netdev_priv(soft_iface); | ||
393 | |||
394 | atomic_set(&bat_priv->aggregated_ogms, 1); | 414 | atomic_set(&bat_priv->aggregated_ogms, 1); |
395 | atomic_set(&bat_priv->bonding, 0); | 415 | atomic_set(&bat_priv->bonding, 0); |
396 | atomic_set(&bat_priv->bridge_loop_avoidance, 0); | 416 | atomic_set(&bat_priv->bridge_loop_avoidance, 0); |
@@ -408,29 +428,26 @@ struct net_device *batadv_softif_create(const char *name) | |||
408 | 428 | ||
409 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); | 429 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); |
410 | atomic_set(&bat_priv->bcast_seqno, 1); | 430 | atomic_set(&bat_priv->bcast_seqno, 1); |
411 | atomic_set(&bat_priv->ttvn, 0); | 431 | atomic_set(&bat_priv->tt.vn, 0); |
412 | atomic_set(&bat_priv->tt_local_changes, 0); | 432 | atomic_set(&bat_priv->tt.local_changes, 0); |
413 | atomic_set(&bat_priv->tt_ogm_append_cnt, 0); | 433 | atomic_set(&bat_priv->tt.ogm_append_cnt, 0); |
414 | atomic_set(&bat_priv->bla_num_requests, 0); | 434 | #ifdef CONFIG_BATMAN_ADV_BLA |
415 | 435 | atomic_set(&bat_priv->bla.num_requests, 0); | |
416 | bat_priv->tt_buff = NULL; | 436 | #endif |
417 | bat_priv->tt_buff_len = 0; | 437 | bat_priv->tt.last_changeset = NULL; |
418 | bat_priv->tt_poss_change = false; | 438 | bat_priv->tt.last_changeset_len = 0; |
439 | bat_priv->tt.poss_change = false; | ||
419 | 440 | ||
420 | bat_priv->primary_if = NULL; | 441 | bat_priv->primary_if = NULL; |
421 | bat_priv->num_ifaces = 0; | 442 | bat_priv->num_ifaces = 0; |
422 | 443 | ||
423 | bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); | ||
424 | if (!bat_priv->bat_counters) | ||
425 | goto unreg_soft_iface; | ||
426 | |||
427 | ret = batadv_algo_select(bat_priv, batadv_routing_algo); | 444 | ret = batadv_algo_select(bat_priv, batadv_routing_algo); |
428 | if (ret < 0) | 445 | if (ret < 0) |
429 | goto free_bat_counters; | 446 | goto unreg_soft_iface; |
430 | 447 | ||
431 | ret = batadv_sysfs_add_meshif(soft_iface); | 448 | ret = batadv_sysfs_add_meshif(soft_iface); |
432 | if (ret < 0) | 449 | if (ret < 0) |
433 | goto free_bat_counters; | 450 | goto unreg_soft_iface; |
434 | 451 | ||
435 | ret = batadv_debugfs_add_meshif(soft_iface); | 452 | ret = batadv_debugfs_add_meshif(soft_iface); |
436 | if (ret < 0) | 453 | if (ret < 0) |
@@ -446,12 +463,13 @@ unreg_debugfs: | |||
446 | batadv_debugfs_del_meshif(soft_iface); | 463 | batadv_debugfs_del_meshif(soft_iface); |
447 | unreg_sysfs: | 464 | unreg_sysfs: |
448 | batadv_sysfs_del_meshif(soft_iface); | 465 | batadv_sysfs_del_meshif(soft_iface); |
449 | free_bat_counters: | ||
450 | free_percpu(bat_priv->bat_counters); | ||
451 | unreg_soft_iface: | 466 | unreg_soft_iface: |
467 | free_percpu(bat_priv->bat_counters); | ||
452 | unregister_netdevice(soft_iface); | 468 | unregister_netdevice(soft_iface); |
453 | return NULL; | 469 | return NULL; |
454 | 470 | ||
471 | free_bat_counters: | ||
472 | free_percpu(bat_priv->bat_counters); | ||
455 | free_soft_iface: | 473 | free_soft_iface: |
456 | free_netdev(soft_iface); | 474 | free_netdev(soft_iface); |
457 | out: | 475 | out: |
@@ -521,6 +539,11 @@ static u32 batadv_get_link(struct net_device *dev) | |||
521 | static const struct { | 539 | static const struct { |
522 | const char name[ETH_GSTRING_LEN]; | 540 | const char name[ETH_GSTRING_LEN]; |
523 | } batadv_counters_strings[] = { | 541 | } batadv_counters_strings[] = { |
542 | { "tx" }, | ||
543 | { "tx_bytes" }, | ||
544 | { "tx_dropped" }, | ||
545 | { "rx" }, | ||
546 | { "rx_bytes" }, | ||
524 | { "forward" }, | 547 | { "forward" }, |
525 | { "forward_bytes" }, | 548 | { "forward_bytes" }, |
526 | { "mgmt_tx" }, | 549 | { "mgmt_tx" }, |