diff options
author | David S. Miller <davem@davemloft.net> | 2014-05-24 00:32:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-24 00:32:30 -0400 |
commit | 54e5c4def0614ab540fbdf68e45342a4af141702 (patch) | |
tree | 95a2f61c72336932e83d9e4180cd9739106d624b /net/batman-adv/originator.c | |
parent | be65de7174123e02477bd488db1a657caf0f9947 (diff) | |
parent | 1ee1ceafb572f1a925809168267a7962a4289de8 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/bonding/bond_alb.c
drivers/net/ethernet/altera/altera_msgdma.c
drivers/net/ethernet/altera/altera_sgdma.c
net/ipv6/xfrm6_output.c
Several cases of overlapping changes.
The xfrm6_output.c has a bug fix which overlaps the renaming
of skb->local_df to skb->ignore_df.
In the Altera TSE driver cases, the register access cleanups
in net-next overlapped with bug fixes done in net.
Similarly a bug fix to send ALB packets in the bonding driver using
the right source address overlaps with cleanups in net-next.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/batman-adv/originator.c')
-rw-r--r-- | net/batman-adv/originator.c | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index ffd9dfbd9b0e..6a484514cd3e 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -501,12 +501,17 @@ batadv_neigh_node_get(const struct batadv_orig_node *orig_node, | |||
501 | static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu) | 501 | static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu) |
502 | { | 502 | { |
503 | struct batadv_orig_ifinfo *orig_ifinfo; | 503 | struct batadv_orig_ifinfo *orig_ifinfo; |
504 | struct batadv_neigh_node *router; | ||
504 | 505 | ||
505 | orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu); | 506 | orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu); |
506 | 507 | ||
507 | if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT) | 508 | if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT) |
508 | batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing); | 509 | batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing); |
509 | 510 | ||
511 | /* this is the last reference to this object */ | ||
512 | router = rcu_dereference_protected(orig_ifinfo->router, true); | ||
513 | if (router) | ||
514 | batadv_neigh_node_free_ref_now(router); | ||
510 | kfree(orig_ifinfo); | 515 | kfree(orig_ifinfo); |
511 | } | 516 | } |
512 | 517 | ||
@@ -702,6 +707,47 @@ free_orig_node: | |||
702 | } | 707 | } |
703 | 708 | ||
704 | /** | 709 | /** |
710 | * batadv_purge_neigh_ifinfo - purge obsolete ifinfo entries from neighbor | ||
711 | * @bat_priv: the bat priv with all the soft interface information | ||
712 | * @neigh: orig node which is to be checked | ||
713 | */ | ||
714 | static void | ||
715 | batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv, | ||
716 | struct batadv_neigh_node *neigh) | ||
717 | { | ||
718 | struct batadv_neigh_ifinfo *neigh_ifinfo; | ||
719 | struct batadv_hard_iface *if_outgoing; | ||
720 | struct hlist_node *node_tmp; | ||
721 | |||
722 | spin_lock_bh(&neigh->ifinfo_lock); | ||
723 | |||
724 | /* for all ifinfo objects for this neighinator */ | ||
725 | hlist_for_each_entry_safe(neigh_ifinfo, node_tmp, | ||
726 | &neigh->ifinfo_list, list) { | ||
727 | if_outgoing = neigh_ifinfo->if_outgoing; | ||
728 | |||
729 | /* always keep the default interface */ | ||
730 | if (if_outgoing == BATADV_IF_DEFAULT) | ||
731 | continue; | ||
732 | |||
733 | /* don't purge if the interface is not (going) down */ | ||
734 | if ((if_outgoing->if_status != BATADV_IF_INACTIVE) && | ||
735 | (if_outgoing->if_status != BATADV_IF_NOT_IN_USE) && | ||
736 | (if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED)) | ||
737 | continue; | ||
738 | |||
739 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | ||
740 | "neighbor/ifinfo purge: neighbor %pM, iface: %s\n", | ||
741 | neigh->addr, if_outgoing->net_dev->name); | ||
742 | |||
743 | hlist_del_rcu(&neigh_ifinfo->list); | ||
744 | batadv_neigh_ifinfo_free_ref(neigh_ifinfo); | ||
745 | } | ||
746 | |||
747 | spin_unlock_bh(&neigh->ifinfo_lock); | ||
748 | } | ||
749 | |||
750 | /** | ||
705 | * batadv_purge_orig_ifinfo - purge obsolete ifinfo entries from originator | 751 | * batadv_purge_orig_ifinfo - purge obsolete ifinfo entries from originator |
706 | * @bat_priv: the bat priv with all the soft interface information | 752 | * @bat_priv: the bat priv with all the soft interface information |
707 | * @orig_node: orig node which is to be checked | 753 | * @orig_node: orig node which is to be checked |
@@ -800,6 +846,11 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv, | |||
800 | 846 | ||
801 | hlist_del_rcu(&neigh_node->list); | 847 | hlist_del_rcu(&neigh_node->list); |
802 | batadv_neigh_node_free_ref(neigh_node); | 848 | batadv_neigh_node_free_ref(neigh_node); |
849 | } else { | ||
850 | /* only necessary if not the whole neighbor is to be | ||
851 | * deleted, but some interface has been removed. | ||
852 | */ | ||
853 | batadv_purge_neigh_ifinfo(bat_priv, neigh_node); | ||
803 | } | 854 | } |
804 | } | 855 | } |
805 | 856 | ||
@@ -857,7 +908,7 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, | |||
857 | { | 908 | { |
858 | struct batadv_neigh_node *best_neigh_node; | 909 | struct batadv_neigh_node *best_neigh_node; |
859 | struct batadv_hard_iface *hard_iface; | 910 | struct batadv_hard_iface *hard_iface; |
860 | bool changed; | 911 | bool changed_ifinfo, changed_neigh; |
861 | 912 | ||
862 | if (batadv_has_timed_out(orig_node->last_seen, | 913 | if (batadv_has_timed_out(orig_node->last_seen, |
863 | 2 * BATADV_PURGE_TIMEOUT)) { | 914 | 2 * BATADV_PURGE_TIMEOUT)) { |
@@ -867,10 +918,10 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, | |||
867 | jiffies_to_msecs(orig_node->last_seen)); | 918 | jiffies_to_msecs(orig_node->last_seen)); |
868 | return true; | 919 | return true; |
869 | } | 920 | } |
870 | changed = batadv_purge_orig_ifinfo(bat_priv, orig_node); | 921 | changed_ifinfo = batadv_purge_orig_ifinfo(bat_priv, orig_node); |
871 | changed = changed || batadv_purge_orig_neighbors(bat_priv, orig_node); | 922 | changed_neigh = batadv_purge_orig_neighbors(bat_priv, orig_node); |
872 | 923 | ||
873 | if (!changed) | 924 | if (!changed_ifinfo && !changed_neigh) |
874 | return false; | 925 | return false; |
875 | 926 | ||
876 | /* first for NULL ... */ | 927 | /* first for NULL ... */ |
@@ -1028,7 +1079,8 @@ int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset) | |||
1028 | bat_priv->bat_algo_ops->bat_orig_print(bat_priv, seq, hard_iface); | 1079 | bat_priv->bat_algo_ops->bat_orig_print(bat_priv, seq, hard_iface); |
1029 | 1080 | ||
1030 | out: | 1081 | out: |
1031 | batadv_hardif_free_ref(hard_iface); | 1082 | if (hard_iface) |
1083 | batadv_hardif_free_ref(hard_iface); | ||
1032 | return 0; | 1084 | return 0; |
1033 | } | 1085 | } |
1034 | 1086 | ||