aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/originator.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-05-24 00:32:30 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-24 00:32:30 -0400
commit54e5c4def0614ab540fbdf68e45342a4af141702 (patch)
tree95a2f61c72336932e83d9e4180cd9739106d624b /net/batman-adv/originator.c
parentbe65de7174123e02477bd488db1a657caf0f9947 (diff)
parent1ee1ceafb572f1a925809168267a7962a4289de8 (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.c62
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,
501static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu) 501static 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 */
714static void
715batadv_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
1030out: 1081out:
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