aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_metrics.c
diff options
context:
space:
mode:
authorChristoph Paasch <christoph.paasch@uclouvain.be>2014-01-08 10:05:58 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-10 17:38:18 -0500
commitbbf852b96ebdc6d1be7a67143824523280bbcf44 (patch)
tree094f5b5d883ce7f1f50c8f65d0bfb2e8e8cd1bb3 /net/ipv4/tcp_metrics.c
parent8a59359cb80f448923a7bc9f555d477e74547d7a (diff)
tcp: metrics: Delete all entries matching a certain destination
As we now can have multiple entries per destination-IP, the "ip tcp_metrics delete address ADDRESS" command deletes all of them. Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_metrics.c')
-rw-r--r--net/ipv4/tcp_metrics.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 199659f7a871..e150f264c8e2 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -982,7 +982,7 @@ static int tcp_metrics_flush_all(struct net *net)
982static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info) 982static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
983{ 983{
984 struct tcpm_hash_bucket *hb; 984 struct tcpm_hash_bucket *hb;
985 struct tcp_metrics_block *tm; 985 struct tcp_metrics_block *tm, *tmlist = NULL;
986 struct tcp_metrics_block __rcu **pp; 986 struct tcp_metrics_block __rcu **pp;
987 struct inetpeer_addr daddr; 987 struct inetpeer_addr daddr;
988 unsigned int hash; 988 unsigned int hash;
@@ -999,17 +999,22 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
999 hb = net->ipv4.tcp_metrics_hash + hash; 999 hb = net->ipv4.tcp_metrics_hash + hash;
1000 pp = &hb->chain; 1000 pp = &hb->chain;
1001 spin_lock_bh(&tcp_metrics_lock); 1001 spin_lock_bh(&tcp_metrics_lock);
1002 for (tm = deref_locked_genl(*pp); tm; 1002 for (tm = deref_locked_genl(*pp); tm; tm = deref_locked_genl(*pp)) {
1003 pp = &tm->tcpm_next, tm = deref_locked_genl(*pp)) {
1004 if (addr_same(&tm->tcpm_daddr, &daddr)) { 1003 if (addr_same(&tm->tcpm_daddr, &daddr)) {
1005 *pp = tm->tcpm_next; 1004 *pp = tm->tcpm_next;
1006 break; 1005 tm->tcpm_next = tmlist;
1006 tmlist = tm;
1007 } else {
1008 pp = &tm->tcpm_next;
1007 } 1009 }
1008 } 1010 }
1009 spin_unlock_bh(&tcp_metrics_lock); 1011 spin_unlock_bh(&tcp_metrics_lock);
1010 if (!tm) 1012 if (!tmlist)
1011 return -ESRCH; 1013 return -ESRCH;
1012 kfree_rcu(tm, rcu_head); 1014 for (tm = tmlist; tm; tm = tmlist) {
1015 tmlist = tm->tcpm_next;
1016 kfree_rcu(tm, rcu_head);
1017 }
1013 return 0; 1018 return 0;
1014} 1019}
1015 1020