diff options
author | David S. Miller <davem@davemloft.net> | 2013-03-28 14:34:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-28 14:34:23 -0400 |
commit | ea407f0b97ad6a1fed8e72121bd19d66f02524f6 (patch) | |
tree | 51a0ff3f3dbb7228150380aca2795e3eeb06b5bf /net | |
parent | 9631d79e815197dbe90080aedfbab6de41218d85 (diff) | |
parent | 0c81465357ffe29da9ff20103afe4a59908e0d30 (diff) |
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Included changes:
- A fix for the network coding component which has been added within the last
pull request (so it is in linux-3.10). The problem has been spotted thanks to
Fengguang Wu's automated daily checks on our tree.
- Implementation of the RTNL API for virtual interface creation/deletion and slave
manipulation
- substitution of seq_printf with seq_puts when possible
- minor cleanups
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/batman-adv/Makefile | 2 | ||||
-rw-r--r-- | net/batman-adv/gateway_client.c | 2 | ||||
-rw-r--r-- | net/batman-adv/hard-interface.c | 66 | ||||
-rw-r--r-- | net/batman-adv/hard-interface.h | 13 | ||||
-rw-r--r-- | net/batman-adv/main.c | 4 | ||||
-rw-r--r-- | net/batman-adv/main.h | 3 | ||||
-rw-r--r-- | net/batman-adv/network-coding.c | 10 | ||||
-rw-r--r-- | net/batman-adv/originator.c | 4 | ||||
-rw-r--r-- | net/batman-adv/packet.h | 2 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.c | 269 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.h | 3 | ||||
-rw-r--r-- | net/batman-adv/sysfs.c | 6 | ||||
-rw-r--r-- | net/batman-adv/vis.c | 4 |
13 files changed, 268 insertions, 120 deletions
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile index 4b8f192a9e43..acbac2a9c62f 100644 --- a/net/batman-adv/Makefile +++ b/net/batman-adv/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | # | 1 | # |
2 | # Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: | 2 | # Copyright (C) 2007-2013 B.A.T.M.A.N. contributors: |
3 | # | 3 | # |
4 | # Marek Lindner, Simon Wunderlich | 4 | # Marek Lindner, Simon Wunderlich |
5 | # | 5 | # |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 34f99a46ec1d..f105219f4a4b 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -500,7 +500,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) | |||
500 | rcu_read_unlock(); | 500 | rcu_read_unlock(); |
501 | 501 | ||
502 | if (gw_count == 0) | 502 | if (gw_count == 0) |
503 | seq_printf(seq, "No gateways in range ...\n"); | 503 | seq_puts(seq, "No gateways in range ...\n"); |
504 | 504 | ||
505 | out: | 505 | out: |
506 | if (primary_if) | 506 | if (primary_if) |
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 368219e026a9..522243aff2f3 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -307,11 +307,35 @@ batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface) | |||
307 | batadv_update_min_mtu(hard_iface->soft_iface); | 307 | batadv_update_min_mtu(hard_iface->soft_iface); |
308 | } | 308 | } |
309 | 309 | ||
310 | /** | ||
311 | * batadv_master_del_slave - remove hard_iface from the current master interface | ||
312 | * @slave: the interface enslaved in another master | ||
313 | * @master: the master from which slave has to be removed | ||
314 | * | ||
315 | * Invoke ndo_del_slave on master passing slave as argument. In this way slave | ||
316 | * is free'd and master can correctly change its internal state. | ||
317 | * Return 0 on success, a negative value representing the error otherwise | ||
318 | */ | ||
319 | static int batadv_master_del_slave(struct batadv_hard_iface *slave, | ||
320 | struct net_device *master) | ||
321 | { | ||
322 | int ret; | ||
323 | |||
324 | if (!master) | ||
325 | return 0; | ||
326 | |||
327 | ret = -EBUSY; | ||
328 | if (master->netdev_ops->ndo_del_slave) | ||
329 | ret = master->netdev_ops->ndo_del_slave(master, slave->net_dev); | ||
330 | |||
331 | return ret; | ||
332 | } | ||
333 | |||
310 | int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | 334 | int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, |
311 | const char *iface_name) | 335 | const char *iface_name) |
312 | { | 336 | { |
313 | struct batadv_priv *bat_priv; | 337 | struct batadv_priv *bat_priv; |
314 | struct net_device *soft_iface; | 338 | struct net_device *soft_iface, *master; |
315 | __be16 ethertype = __constant_htons(ETH_P_BATMAN); | 339 | __be16 ethertype = __constant_htons(ETH_P_BATMAN); |
316 | int ret; | 340 | int ret; |
317 | 341 | ||
@@ -321,11 +345,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | |||
321 | if (!atomic_inc_not_zero(&hard_iface->refcount)) | 345 | if (!atomic_inc_not_zero(&hard_iface->refcount)) |
322 | goto out; | 346 | goto out; |
323 | 347 | ||
324 | /* hard-interface is part of a bridge */ | ||
325 | if (hard_iface->net_dev->priv_flags & IFF_BRIDGE_PORT) | ||
326 | pr_err("You are about to enable batman-adv on '%s' which already is part of a bridge. Unless you know exactly what you are doing this is probably wrong and won't work the way you think it would.\n", | ||
327 | hard_iface->net_dev->name); | ||
328 | |||
329 | soft_iface = dev_get_by_name(&init_net, iface_name); | 348 | soft_iface = dev_get_by_name(&init_net, iface_name); |
330 | 349 | ||
331 | if (!soft_iface) { | 350 | if (!soft_iface) { |
@@ -347,12 +366,24 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | |||
347 | goto err_dev; | 366 | goto err_dev; |
348 | } | 367 | } |
349 | 368 | ||
369 | /* check if the interface is enslaved in another virtual one and | ||
370 | * in that case unlink it first | ||
371 | */ | ||
372 | master = netdev_master_upper_dev_get(hard_iface->net_dev); | ||
373 | ret = batadv_master_del_slave(hard_iface, master); | ||
374 | if (ret) | ||
375 | goto err_dev; | ||
376 | |||
350 | hard_iface->soft_iface = soft_iface; | 377 | hard_iface->soft_iface = soft_iface; |
351 | bat_priv = netdev_priv(hard_iface->soft_iface); | 378 | bat_priv = netdev_priv(hard_iface->soft_iface); |
352 | 379 | ||
380 | ret = netdev_master_upper_dev_link(hard_iface->net_dev, soft_iface); | ||
381 | if (ret) | ||
382 | goto err_dev; | ||
383 | |||
353 | ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface); | 384 | ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface); |
354 | if (ret < 0) | 385 | if (ret < 0) |
355 | goto err_dev; | 386 | goto err_upper; |
356 | 387 | ||
357 | hard_iface->if_num = bat_priv->num_ifaces; | 388 | hard_iface->if_num = bat_priv->num_ifaces; |
358 | bat_priv->num_ifaces++; | 389 | bat_priv->num_ifaces++; |
@@ -362,7 +393,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | |||
362 | bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); | 393 | bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); |
363 | bat_priv->num_ifaces--; | 394 | bat_priv->num_ifaces--; |
364 | hard_iface->if_status = BATADV_IF_NOT_IN_USE; | 395 | hard_iface->if_status = BATADV_IF_NOT_IN_USE; |
365 | goto err_dev; | 396 | goto err_upper; |
366 | } | 397 | } |
367 | 398 | ||
368 | hard_iface->batman_adv_ptype.type = ethertype; | 399 | hard_iface->batman_adv_ptype.type = ethertype; |
@@ -401,14 +432,18 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | |||
401 | out: | 432 | out: |
402 | return 0; | 433 | return 0; |
403 | 434 | ||
435 | err_upper: | ||
436 | netdev_upper_dev_unlink(hard_iface->net_dev, soft_iface); | ||
404 | err_dev: | 437 | err_dev: |
438 | hard_iface->soft_iface = NULL; | ||
405 | dev_put(soft_iface); | 439 | dev_put(soft_iface); |
406 | err: | 440 | err: |
407 | batadv_hardif_free_ref(hard_iface); | 441 | batadv_hardif_free_ref(hard_iface); |
408 | return ret; | 442 | return ret; |
409 | } | 443 | } |
410 | 444 | ||
411 | void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface) | 445 | void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, |
446 | enum batadv_hard_if_cleanup autodel) | ||
412 | { | 447 | { |
413 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | 448 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
414 | struct batadv_hard_iface *primary_if = NULL; | 449 | struct batadv_hard_iface *primary_if = NULL; |
@@ -446,9 +481,10 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface) | |||
446 | dev_put(hard_iface->soft_iface); | 481 | dev_put(hard_iface->soft_iface); |
447 | 482 | ||
448 | /* nobody uses this interface anymore */ | 483 | /* nobody uses this interface anymore */ |
449 | if (!bat_priv->num_ifaces) | 484 | if (!bat_priv->num_ifaces && autodel == BATADV_IF_CLEANUP_AUTO) |
450 | batadv_softif_destroy(hard_iface->soft_iface); | 485 | batadv_softif_destroy_sysfs(hard_iface->soft_iface); |
451 | 486 | ||
487 | netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface); | ||
452 | hard_iface->soft_iface = NULL; | 488 | hard_iface->soft_iface = NULL; |
453 | batadv_hardif_free_ref(hard_iface); | 489 | batadv_hardif_free_ref(hard_iface); |
454 | 490 | ||
@@ -533,7 +569,8 @@ static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface) | |||
533 | 569 | ||
534 | /* first deactivate interface */ | 570 | /* first deactivate interface */ |
535 | if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) | 571 | if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) |
536 | batadv_hardif_disable_interface(hard_iface); | 572 | batadv_hardif_disable_interface(hard_iface, |
573 | BATADV_IF_CLEANUP_AUTO); | ||
537 | 574 | ||
538 | if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) | 575 | if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) |
539 | return; | 576 | return; |
@@ -563,6 +600,11 @@ static int batadv_hard_if_event(struct notifier_block *this, | |||
563 | struct batadv_hard_iface *primary_if = NULL; | 600 | struct batadv_hard_iface *primary_if = NULL; |
564 | struct batadv_priv *bat_priv; | 601 | struct batadv_priv *bat_priv; |
565 | 602 | ||
603 | if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) { | ||
604 | batadv_sysfs_add_meshif(net_dev); | ||
605 | return NOTIFY_DONE; | ||
606 | } | ||
607 | |||
566 | hard_iface = batadv_hardif_get_by_netdev(net_dev); | 608 | hard_iface = batadv_hardif_get_by_netdev(net_dev); |
567 | if (!hard_iface && event == NETDEV_REGISTER) | 609 | if (!hard_iface && event == NETDEV_REGISTER) |
568 | hard_iface = batadv_hardif_add_interface(net_dev); | 610 | hard_iface = batadv_hardif_add_interface(net_dev); |
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index 308437d52e22..49892881a7c5 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h | |||
@@ -29,13 +29,24 @@ enum batadv_hard_if_state { | |||
29 | BATADV_IF_I_WANT_YOU, | 29 | BATADV_IF_I_WANT_YOU, |
30 | }; | 30 | }; |
31 | 31 | ||
32 | /** | ||
33 | * enum batadv_hard_if_cleanup - Cleanup modi for soft_iface after slave removal | ||
34 | * @BATADV_IF_CLEANUP_KEEP: Don't automatically delete soft-interface | ||
35 | * @BATADV_IF_CLEANUP_AUTO: Delete soft-interface after last slave was removed | ||
36 | */ | ||
37 | enum batadv_hard_if_cleanup { | ||
38 | BATADV_IF_CLEANUP_KEEP, | ||
39 | BATADV_IF_CLEANUP_AUTO, | ||
40 | }; | ||
41 | |||
32 | extern struct notifier_block batadv_hard_if_notifier; | 42 | extern struct notifier_block batadv_hard_if_notifier; |
33 | 43 | ||
34 | struct batadv_hard_iface* | 44 | struct batadv_hard_iface* |
35 | batadv_hardif_get_by_netdev(const struct net_device *net_dev); | 45 | batadv_hardif_get_by_netdev(const struct net_device *net_dev); |
36 | int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | 46 | int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, |
37 | const char *iface_name); | 47 | const char *iface_name); |
38 | void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface); | 48 | void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, |
49 | enum batadv_hard_if_cleanup autodel); | ||
39 | void batadv_hardif_remove_interfaces(void); | 50 | void batadv_hardif_remove_interfaces(void); |
40 | int batadv_hardif_min_mtu(struct net_device *soft_iface); | 51 | int batadv_hardif_min_mtu(struct net_device *soft_iface); |
41 | void batadv_update_min_mtu(struct net_device *soft_iface); | 52 | void batadv_update_min_mtu(struct net_device *soft_iface); |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 0495a7dc7505..6277735cd89e 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -71,6 +71,7 @@ static int __init batadv_init(void) | |||
71 | batadv_debugfs_init(); | 71 | batadv_debugfs_init(); |
72 | 72 | ||
73 | register_netdevice_notifier(&batadv_hard_if_notifier); | 73 | register_netdevice_notifier(&batadv_hard_if_notifier); |
74 | rtnl_link_register(&batadv_link_ops); | ||
74 | 75 | ||
75 | pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", | 76 | pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", |
76 | BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION); | 77 | BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION); |
@@ -81,6 +82,7 @@ static int __init batadv_init(void) | |||
81 | static void __exit batadv_exit(void) | 82 | static void __exit batadv_exit(void) |
82 | { | 83 | { |
83 | batadv_debugfs_destroy(); | 84 | batadv_debugfs_destroy(); |
85 | rtnl_link_unregister(&batadv_link_ops); | ||
84 | unregister_netdevice_notifier(&batadv_hard_if_notifier); | 86 | unregister_netdevice_notifier(&batadv_hard_if_notifier); |
85 | batadv_hardif_remove_interfaces(); | 87 | batadv_hardif_remove_interfaces(); |
86 | 88 | ||
@@ -417,7 +419,7 @@ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset) | |||
417 | { | 419 | { |
418 | struct batadv_algo_ops *bat_algo_ops; | 420 | struct batadv_algo_ops *bat_algo_ops; |
419 | 421 | ||
420 | seq_printf(seq, "Available routing algorithms:\n"); | 422 | seq_puts(seq, "Available routing algorithms:\n"); |
421 | 423 | ||
422 | hlist_for_each_entry(bat_algo_ops, &batadv_algo_list, list) { | 424 | hlist_for_each_entry(bat_algo_ops, &batadv_algo_list, list) { |
423 | seq_printf(seq, "%s\n", bat_algo_ops->name); | 425 | seq_printf(seq, "%s\n", bat_algo_ops->name); |
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 0afd4ee7708b..f90f5bc8e426 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #define BATADV_DRIVER_DEVICE "batman-adv" | 26 | #define BATADV_DRIVER_DEVICE "batman-adv" |
27 | 27 | ||
28 | #ifndef BATADV_SOURCE_VERSION | 28 | #ifndef BATADV_SOURCE_VERSION |
29 | #define BATADV_SOURCE_VERSION "2013.1.0" | 29 | #define BATADV_SOURCE_VERSION "2013.2.0" |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | /* B.A.T.M.A.N. parameters */ | 32 | /* B.A.T.M.A.N. parameters */ |
@@ -152,6 +152,7 @@ enum batadv_uev_type { | |||
152 | #include <linux/percpu.h> | 152 | #include <linux/percpu.h> |
153 | #include <linux/slab.h> | 153 | #include <linux/slab.h> |
154 | #include <net/sock.h> /* struct sock */ | 154 | #include <net/sock.h> /* struct sock */ |
155 | #include <net/rtnetlink.h> | ||
155 | #include <linux/jiffies.h> | 156 | #include <linux/jiffies.h> |
156 | #include <linux/seq_file.h> | 157 | #include <linux/seq_file.h> |
157 | #include "types.h" | 158 | #include "types.h" |
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 57280797bf4e..6b9a54485314 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c | |||
@@ -654,7 +654,7 @@ static bool batadv_can_nc_with_orig(struct batadv_priv *bat_priv, | |||
654 | struct batadv_orig_node *orig_node, | 654 | struct batadv_orig_node *orig_node, |
655 | struct batadv_ogm_packet *ogm_packet) | 655 | struct batadv_ogm_packet *ogm_packet) |
656 | { | 656 | { |
657 | if (orig_node->last_real_seqno != ogm_packet->seqno) | 657 | if (orig_node->last_real_seqno != ntohl(ogm_packet->seqno)) |
658 | return false; | 658 | return false; |
659 | if (orig_node->last_ttl != ogm_packet->header.ttl + 1) | 659 | if (orig_node->last_ttl != ogm_packet->header.ttl + 1) |
660 | return false; | 660 | return false; |
@@ -1760,23 +1760,23 @@ int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset) | |||
1760 | hlist_for_each_entry_rcu(orig_node, head, hash_entry) { | 1760 | hlist_for_each_entry_rcu(orig_node, head, hash_entry) { |
1761 | seq_printf(seq, "Node: %pM\n", orig_node->orig); | 1761 | seq_printf(seq, "Node: %pM\n", orig_node->orig); |
1762 | 1762 | ||
1763 | seq_printf(seq, " Ingoing: "); | 1763 | seq_puts(seq, " Ingoing: "); |
1764 | /* For each in_nc_node to this orig_node */ | 1764 | /* For each in_nc_node to this orig_node */ |
1765 | list_for_each_entry_rcu(nc_node, | 1765 | list_for_each_entry_rcu(nc_node, |
1766 | &orig_node->in_coding_list, | 1766 | &orig_node->in_coding_list, |
1767 | list) | 1767 | list) |
1768 | seq_printf(seq, "%pM ", | 1768 | seq_printf(seq, "%pM ", |
1769 | nc_node->addr); | 1769 | nc_node->addr); |
1770 | seq_printf(seq, "\n"); | 1770 | seq_puts(seq, "\n"); |
1771 | 1771 | ||
1772 | seq_printf(seq, " Outgoing: "); | 1772 | seq_puts(seq, " Outgoing: "); |
1773 | /* For out_nc_node to this orig_node */ | 1773 | /* For out_nc_node to this orig_node */ |
1774 | list_for_each_entry_rcu(nc_node, | 1774 | list_for_each_entry_rcu(nc_node, |
1775 | &orig_node->out_coding_list, | 1775 | &orig_node->out_coding_list, |
1776 | list) | 1776 | list) |
1777 | seq_printf(seq, "%pM ", | 1777 | seq_printf(seq, "%pM ", |
1778 | nc_node->addr); | 1778 | nc_node->addr); |
1779 | seq_printf(seq, "\n\n"); | 1779 | seq_puts(seq, "\n\n"); |
1780 | } | 1780 | } |
1781 | rcu_read_unlock(); | 1781 | rcu_read_unlock(); |
1782 | } | 1782 | } |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 585e684a380b..2f3452546636 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -465,7 +465,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) | |||
465 | neigh_node_tmp->tq_avg); | 465 | neigh_node_tmp->tq_avg); |
466 | } | 466 | } |
467 | 467 | ||
468 | seq_printf(seq, "\n"); | 468 | seq_puts(seq, "\n"); |
469 | batman_count++; | 469 | batman_count++; |
470 | 470 | ||
471 | next: | 471 | next: |
@@ -475,7 +475,7 @@ next: | |||
475 | } | 475 | } |
476 | 476 | ||
477 | if (batman_count == 0) | 477 | if (batman_count == 0) |
478 | seq_printf(seq, "No batman nodes in range ...\n"); | 478 | seq_puts(seq, "No batman nodes in range ...\n"); |
479 | 479 | ||
480 | out: | 480 | out: |
481 | if (primary_if) | 481 | if (primary_if) |
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index a07995834b84..a51ccfc39da4 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h | |||
@@ -308,7 +308,7 @@ struct batadv_coded_packet { | |||
308 | uint8_t second_source[ETH_ALEN]; | 308 | uint8_t second_source[ETH_ALEN]; |
309 | uint8_t second_orig_dest[ETH_ALEN]; | 309 | uint8_t second_orig_dest[ETH_ALEN]; |
310 | __be32 second_crc; | 310 | __be32 second_crc; |
311 | uint16_t coded_len; | 311 | __be16 coded_len; |
312 | }; | 312 | }; |
313 | 313 | ||
314 | #endif /* _NET_BATMAN_ADV_PACKET_H_ */ | 314 | #endif /* _NET_BATMAN_ADV_PACKET_H_ */ |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index f93ae42abb58..403b8c46085e 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -402,55 +402,6 @@ static void batadv_set_lockdep_class(struct net_device *dev) | |||
402 | } | 402 | } |
403 | 403 | ||
404 | /** | 404 | /** |
405 | * batadv_softif_init - Late stage initialization of soft interface | ||
406 | * @dev: registered network device to modify | ||
407 | * | ||
408 | * Returns error code on failures | ||
409 | */ | ||
410 | static int batadv_softif_init(struct net_device *dev) | ||
411 | { | ||
412 | batadv_set_lockdep_class(dev); | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static const struct net_device_ops batadv_netdev_ops = { | ||
418 | .ndo_init = batadv_softif_init, | ||
419 | .ndo_open = batadv_interface_open, | ||
420 | .ndo_stop = batadv_interface_release, | ||
421 | .ndo_get_stats = batadv_interface_stats, | ||
422 | .ndo_set_mac_address = batadv_interface_set_mac_addr, | ||
423 | .ndo_change_mtu = batadv_interface_change_mtu, | ||
424 | .ndo_start_xmit = batadv_interface_tx, | ||
425 | .ndo_validate_addr = eth_validate_addr | ||
426 | }; | ||
427 | |||
428 | static void batadv_interface_setup(struct net_device *dev) | ||
429 | { | ||
430 | struct batadv_priv *priv = netdev_priv(dev); | ||
431 | |||
432 | ether_setup(dev); | ||
433 | |||
434 | dev->netdev_ops = &batadv_netdev_ops; | ||
435 | dev->destructor = free_netdev; | ||
436 | dev->tx_queue_len = 0; | ||
437 | |||
438 | /* can't call min_mtu, because the needed variables | ||
439 | * have not been initialized yet | ||
440 | */ | ||
441 | dev->mtu = ETH_DATA_LEN; | ||
442 | /* reserve more space in the skbuff for our header */ | ||
443 | dev->hard_header_len = BATADV_HEADER_LEN; | ||
444 | |||
445 | /* generate random address */ | ||
446 | eth_hw_addr_random(dev); | ||
447 | |||
448 | SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops); | ||
449 | |||
450 | memset(priv, 0, sizeof(*priv)); | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * batadv_softif_destroy_finish - cleans up the remains of a softif | 405 | * batadv_softif_destroy_finish - cleans up the remains of a softif |
455 | * @work: work queue item | 406 | * @work: work queue item |
456 | * | 407 | * |
@@ -466,7 +417,6 @@ static void batadv_softif_destroy_finish(struct work_struct *work) | |||
466 | cleanup_work); | 417 | cleanup_work); |
467 | soft_iface = bat_priv->soft_iface; | 418 | soft_iface = bat_priv->soft_iface; |
468 | 419 | ||
469 | batadv_debugfs_del_meshif(soft_iface); | ||
470 | batadv_sysfs_del_meshif(soft_iface); | 420 | batadv_sysfs_del_meshif(soft_iface); |
471 | 421 | ||
472 | rtnl_lock(); | 422 | rtnl_lock(); |
@@ -474,21 +424,22 @@ static void batadv_softif_destroy_finish(struct work_struct *work) | |||
474 | rtnl_unlock(); | 424 | rtnl_unlock(); |
475 | } | 425 | } |
476 | 426 | ||
477 | struct net_device *batadv_softif_create(const char *name) | 427 | /** |
428 | * batadv_softif_init_late - late stage initialization of soft interface | ||
429 | * @dev: registered network device to modify | ||
430 | * | ||
431 | * Returns error code on failures | ||
432 | */ | ||
433 | static int batadv_softif_init_late(struct net_device *dev) | ||
478 | { | 434 | { |
479 | struct net_device *soft_iface; | ||
480 | struct batadv_priv *bat_priv; | 435 | struct batadv_priv *bat_priv; |
481 | int ret; | 436 | int ret; |
482 | size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM; | 437 | size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM; |
483 | 438 | ||
484 | soft_iface = alloc_netdev(sizeof(*bat_priv), name, | 439 | batadv_set_lockdep_class(dev); |
485 | batadv_interface_setup); | ||
486 | |||
487 | if (!soft_iface) | ||
488 | goto out; | ||
489 | 440 | ||
490 | bat_priv = netdev_priv(soft_iface); | 441 | bat_priv = netdev_priv(dev); |
491 | bat_priv->soft_iface = soft_iface; | 442 | bat_priv->soft_iface = dev; |
492 | INIT_WORK(&bat_priv->cleanup_work, batadv_softif_destroy_finish); | 443 | INIT_WORK(&bat_priv->cleanup_work, batadv_softif_destroy_finish); |
493 | 444 | ||
494 | /* batadv_interface_stats() needs to be available as soon as | 445 | /* batadv_interface_stats() needs to be available as soon as |
@@ -496,14 +447,7 @@ struct net_device *batadv_softif_create(const char *name) | |||
496 | */ | 447 | */ |
497 | bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); | 448 | bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); |
498 | if (!bat_priv->bat_counters) | 449 | if (!bat_priv->bat_counters) |
499 | goto free_soft_iface; | 450 | return -ENOMEM; |
500 | |||
501 | ret = register_netdevice(soft_iface); | ||
502 | if (ret < 0) { | ||
503 | pr_err("Unable to register the batman interface '%s': %i\n", | ||
504 | name, ret); | ||
505 | goto free_bat_counters; | ||
506 | } | ||
507 | 451 | ||
508 | atomic_set(&bat_priv->aggregated_ogms, 1); | 452 | atomic_set(&bat_priv->aggregated_ogms, 1); |
509 | atomic_set(&bat_priv->bonding, 0); | 453 | atomic_set(&bat_priv->bonding, 0); |
@@ -541,51 +485,189 @@ struct net_device *batadv_softif_create(const char *name) | |||
541 | bat_priv->primary_if = NULL; | 485 | bat_priv->primary_if = NULL; |
542 | bat_priv->num_ifaces = 0; | 486 | bat_priv->num_ifaces = 0; |
543 | 487 | ||
544 | ret = batadv_algo_select(bat_priv, batadv_routing_algo); | ||
545 | if (ret < 0) | ||
546 | goto unreg_soft_iface; | ||
547 | |||
548 | batadv_nc_init_bat_priv(bat_priv); | 488 | batadv_nc_init_bat_priv(bat_priv); |
549 | 489 | ||
550 | ret = batadv_sysfs_add_meshif(soft_iface); | 490 | ret = batadv_algo_select(bat_priv, batadv_routing_algo); |
551 | if (ret < 0) | 491 | if (ret < 0) |
552 | goto unreg_soft_iface; | 492 | goto free_bat_counters; |
553 | 493 | ||
554 | ret = batadv_debugfs_add_meshif(soft_iface); | 494 | ret = batadv_debugfs_add_meshif(dev); |
555 | if (ret < 0) | 495 | if (ret < 0) |
556 | goto unreg_sysfs; | 496 | goto free_bat_counters; |
557 | 497 | ||
558 | ret = batadv_mesh_init(soft_iface); | 498 | ret = batadv_mesh_init(dev); |
559 | if (ret < 0) | 499 | if (ret < 0) |
560 | goto unreg_debugfs; | 500 | goto unreg_debugfs; |
561 | 501 | ||
562 | return soft_iface; | 502 | return 0; |
563 | 503 | ||
564 | unreg_debugfs: | 504 | unreg_debugfs: |
565 | batadv_debugfs_del_meshif(soft_iface); | 505 | batadv_debugfs_del_meshif(dev); |
566 | unreg_sysfs: | ||
567 | batadv_sysfs_del_meshif(soft_iface); | ||
568 | unreg_soft_iface: | ||
569 | free_percpu(bat_priv->bat_counters); | ||
570 | unregister_netdevice(soft_iface); | ||
571 | return NULL; | ||
572 | |||
573 | free_bat_counters: | 506 | free_bat_counters: |
574 | free_percpu(bat_priv->bat_counters); | 507 | free_percpu(bat_priv->bat_counters); |
575 | free_soft_iface: | 508 | |
576 | free_netdev(soft_iface); | 509 | return ret; |
510 | } | ||
511 | |||
512 | /** | ||
513 | * batadv_softif_slave_add - Add a slave interface to a batadv_soft_interface | ||
514 | * @dev: batadv_soft_interface used as master interface | ||
515 | * @slave_dev: net_device which should become the slave interface | ||
516 | * | ||
517 | * Return 0 if successful or error otherwise. | ||
518 | */ | ||
519 | static int batadv_softif_slave_add(struct net_device *dev, | ||
520 | struct net_device *slave_dev) | ||
521 | { | ||
522 | struct batadv_hard_iface *hard_iface; | ||
523 | int ret = -EINVAL; | ||
524 | |||
525 | hard_iface = batadv_hardif_get_by_netdev(slave_dev); | ||
526 | if (!hard_iface || hard_iface->soft_iface != NULL) | ||
527 | goto out; | ||
528 | |||
529 | ret = batadv_hardif_enable_interface(hard_iface, dev->name); | ||
530 | |||
577 | out: | 531 | out: |
578 | return NULL; | 532 | if (hard_iface) |
533 | batadv_hardif_free_ref(hard_iface); | ||
534 | return ret; | ||
535 | } | ||
536 | |||
537 | /** | ||
538 | * batadv_softif_slave_del - Delete a slave iface from a batadv_soft_interface | ||
539 | * @dev: batadv_soft_interface used as master interface | ||
540 | * @slave_dev: net_device which should be removed from the master interface | ||
541 | * | ||
542 | * Return 0 if successful or error otherwise. | ||
543 | */ | ||
544 | static int batadv_softif_slave_del(struct net_device *dev, | ||
545 | struct net_device *slave_dev) | ||
546 | { | ||
547 | struct batadv_hard_iface *hard_iface; | ||
548 | int ret = -EINVAL; | ||
549 | |||
550 | hard_iface = batadv_hardif_get_by_netdev(slave_dev); | ||
551 | |||
552 | if (!hard_iface || hard_iface->soft_iface != dev) | ||
553 | goto out; | ||
554 | |||
555 | batadv_hardif_disable_interface(hard_iface, BATADV_IF_CLEANUP_KEEP); | ||
556 | ret = 0; | ||
557 | |||
558 | out: | ||
559 | if (hard_iface) | ||
560 | batadv_hardif_free_ref(hard_iface); | ||
561 | return ret; | ||
562 | } | ||
563 | |||
564 | static const struct net_device_ops batadv_netdev_ops = { | ||
565 | .ndo_init = batadv_softif_init_late, | ||
566 | .ndo_open = batadv_interface_open, | ||
567 | .ndo_stop = batadv_interface_release, | ||
568 | .ndo_get_stats = batadv_interface_stats, | ||
569 | .ndo_set_mac_address = batadv_interface_set_mac_addr, | ||
570 | .ndo_change_mtu = batadv_interface_change_mtu, | ||
571 | .ndo_start_xmit = batadv_interface_tx, | ||
572 | .ndo_validate_addr = eth_validate_addr, | ||
573 | .ndo_add_slave = batadv_softif_slave_add, | ||
574 | .ndo_del_slave = batadv_softif_slave_del, | ||
575 | }; | ||
576 | |||
577 | /** | ||
578 | * batadv_softif_free - Deconstructor of batadv_soft_interface | ||
579 | * @dev: Device to cleanup and remove | ||
580 | */ | ||
581 | static void batadv_softif_free(struct net_device *dev) | ||
582 | { | ||
583 | batadv_debugfs_del_meshif(dev); | ||
584 | batadv_mesh_free(dev); | ||
585 | free_netdev(dev); | ||
579 | } | 586 | } |
580 | 587 | ||
581 | void batadv_softif_destroy(struct net_device *soft_iface) | 588 | /** |
589 | * batadv_softif_init_early - early stage initialization of soft interface | ||
590 | * @dev: registered network device to modify | ||
591 | */ | ||
592 | static void batadv_softif_init_early(struct net_device *dev) | ||
593 | { | ||
594 | struct batadv_priv *priv = netdev_priv(dev); | ||
595 | |||
596 | ether_setup(dev); | ||
597 | |||
598 | dev->netdev_ops = &batadv_netdev_ops; | ||
599 | dev->destructor = batadv_softif_free; | ||
600 | dev->tx_queue_len = 0; | ||
601 | |||
602 | /* can't call min_mtu, because the needed variables | ||
603 | * have not been initialized yet | ||
604 | */ | ||
605 | dev->mtu = ETH_DATA_LEN; | ||
606 | /* reserve more space in the skbuff for our header */ | ||
607 | dev->hard_header_len = BATADV_HEADER_LEN; | ||
608 | |||
609 | /* generate random address */ | ||
610 | eth_hw_addr_random(dev); | ||
611 | |||
612 | SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops); | ||
613 | |||
614 | memset(priv, 0, sizeof(*priv)); | ||
615 | } | ||
616 | |||
617 | struct net_device *batadv_softif_create(const char *name) | ||
618 | { | ||
619 | struct net_device *soft_iface; | ||
620 | int ret; | ||
621 | |||
622 | soft_iface = alloc_netdev(sizeof(struct batadv_priv), name, | ||
623 | batadv_softif_init_early); | ||
624 | if (!soft_iface) | ||
625 | return NULL; | ||
626 | |||
627 | soft_iface->rtnl_link_ops = &batadv_link_ops; | ||
628 | |||
629 | ret = register_netdevice(soft_iface); | ||
630 | if (ret < 0) { | ||
631 | pr_err("Unable to register the batman interface '%s': %i\n", | ||
632 | name, ret); | ||
633 | free_netdev(soft_iface); | ||
634 | return NULL; | ||
635 | } | ||
636 | |||
637 | return soft_iface; | ||
638 | } | ||
639 | |||
640 | /** | ||
641 | * batadv_softif_destroy_sysfs - deletion of batadv_soft_interface via sysfs | ||
642 | * @soft_iface: the to-be-removed batman-adv interface | ||
643 | */ | ||
644 | void batadv_softif_destroy_sysfs(struct net_device *soft_iface) | ||
582 | { | 645 | { |
583 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 646 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
584 | 647 | ||
585 | batadv_mesh_free(soft_iface); | ||
586 | queue_work(batadv_event_workqueue, &bat_priv->cleanup_work); | 648 | queue_work(batadv_event_workqueue, &bat_priv->cleanup_work); |
587 | } | 649 | } |
588 | 650 | ||
651 | /** | ||
652 | * batadv_softif_destroy_netlink - deletion of batadv_soft_interface via netlink | ||
653 | * @soft_iface: the to-be-removed batman-adv interface | ||
654 | * @head: list pointer | ||
655 | */ | ||
656 | static void batadv_softif_destroy_netlink(struct net_device *soft_iface, | ||
657 | struct list_head *head) | ||
658 | { | ||
659 | struct batadv_hard_iface *hard_iface; | ||
660 | |||
661 | list_for_each_entry(hard_iface, &batadv_hardif_list, list) { | ||
662 | if (hard_iface->soft_iface == soft_iface) | ||
663 | batadv_hardif_disable_interface(hard_iface, | ||
664 | BATADV_IF_CLEANUP_KEEP); | ||
665 | } | ||
666 | |||
667 | batadv_sysfs_del_meshif(soft_iface); | ||
668 | unregister_netdevice_queue(soft_iface, head); | ||
669 | } | ||
670 | |||
589 | int batadv_softif_is_valid(const struct net_device *net_dev) | 671 | int batadv_softif_is_valid(const struct net_device *net_dev) |
590 | { | 672 | { |
591 | if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) | 673 | if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) |
@@ -594,6 +676,13 @@ int batadv_softif_is_valid(const struct net_device *net_dev) | |||
594 | return 0; | 676 | return 0; |
595 | } | 677 | } |
596 | 678 | ||
679 | struct rtnl_link_ops batadv_link_ops __read_mostly = { | ||
680 | .kind = "batadv", | ||
681 | .priv_size = sizeof(struct batadv_priv), | ||
682 | .setup = batadv_softif_init_early, | ||
683 | .dellink = batadv_softif_destroy_netlink, | ||
684 | }; | ||
685 | |||
597 | /* ethtool */ | 686 | /* ethtool */ |
598 | static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 687 | static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
599 | { | 688 | { |
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index 43182e5e603a..2f2472c2ea0d 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h | |||
@@ -25,7 +25,8 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
25 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, | 25 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, |
26 | int hdr_size, struct batadv_orig_node *orig_node); | 26 | int hdr_size, struct batadv_orig_node *orig_node); |
27 | struct net_device *batadv_softif_create(const char *name); | 27 | struct net_device *batadv_softif_create(const char *name); |
28 | void batadv_softif_destroy(struct net_device *soft_iface); | 28 | void batadv_softif_destroy_sysfs(struct net_device *soft_iface); |
29 | int batadv_softif_is_valid(const struct net_device *net_dev); | 29 | int batadv_softif_is_valid(const struct net_device *net_dev); |
30 | extern struct rtnl_link_ops batadv_link_ops; | ||
30 | 31 | ||
31 | #endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */ | 32 | #endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */ |
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index ce39f62f751e..15a22efa9a67 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c | |||
@@ -588,13 +588,15 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj, | |||
588 | } | 588 | } |
589 | 589 | ||
590 | if (status_tmp == BATADV_IF_NOT_IN_USE) { | 590 | if (status_tmp == BATADV_IF_NOT_IN_USE) { |
591 | batadv_hardif_disable_interface(hard_iface); | 591 | batadv_hardif_disable_interface(hard_iface, |
592 | BATADV_IF_CLEANUP_AUTO); | ||
592 | goto unlock; | 593 | goto unlock; |
593 | } | 594 | } |
594 | 595 | ||
595 | /* if the interface already is in use */ | 596 | /* if the interface already is in use */ |
596 | if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) | 597 | if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) |
597 | batadv_hardif_disable_interface(hard_iface); | 598 | batadv_hardif_disable_interface(hard_iface, |
599 | BATADV_IF_CLEANUP_AUTO); | ||
598 | 600 | ||
599 | ret = batadv_hardif_enable_interface(hard_iface, buff); | 601 | ret = batadv_hardif_enable_interface(hard_iface, buff); |
600 | 602 | ||
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index c053244b97bd..962ccf3b8382 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c | |||
@@ -149,7 +149,7 @@ static void batadv_vis_data_read_prim_sec(struct seq_file *seq, | |||
149 | 149 | ||
150 | hlist_for_each_entry(entry, if_list, list) { | 150 | hlist_for_each_entry(entry, if_list, list) { |
151 | if (entry->primary) | 151 | if (entry->primary) |
152 | seq_printf(seq, "PRIMARY, "); | 152 | seq_puts(seq, "PRIMARY, "); |
153 | else | 153 | else |
154 | seq_printf(seq, "SEC %pM, ", entry->addr); | 154 | seq_printf(seq, "SEC %pM, ", entry->addr); |
155 | } | 155 | } |
@@ -207,7 +207,7 @@ static void batadv_vis_data_read_entries(struct seq_file *seq, | |||
207 | if (batadv_compare_eth(entry->addr, packet->vis_orig)) | 207 | if (batadv_compare_eth(entry->addr, packet->vis_orig)) |
208 | batadv_vis_data_read_prim_sec(seq, list); | 208 | batadv_vis_data_read_prim_sec(seq, list); |
209 | 209 | ||
210 | seq_printf(seq, "\n"); | 210 | seq_puts(seq, "\n"); |
211 | } | 211 | } |
212 | } | 212 | } |
213 | 213 | ||