diff options
-rw-r--r-- | net/netfilter/xt_connlimit.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index d4c6db1af8ef..0220d406cbe0 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c | |||
@@ -97,13 +97,12 @@ static int count_hlist(struct net *net, | |||
97 | const struct nf_conntrack_tuple *tuple, | 97 | const struct nf_conntrack_tuple *tuple, |
98 | const union nf_inet_addr *addr, | 98 | const union nf_inet_addr *addr, |
99 | const union nf_inet_addr *mask, | 99 | const union nf_inet_addr *mask, |
100 | u_int8_t family) | 100 | u_int8_t family, bool *addit) |
101 | { | 101 | { |
102 | const struct nf_conntrack_tuple_hash *found; | 102 | const struct nf_conntrack_tuple_hash *found; |
103 | struct xt_connlimit_conn *conn; | 103 | struct xt_connlimit_conn *conn; |
104 | struct hlist_node *n; | 104 | struct hlist_node *n; |
105 | struct nf_conn *found_ct; | 105 | struct nf_conn *found_ct; |
106 | bool addit = true; | ||
107 | int matches = 0; | 106 | int matches = 0; |
108 | 107 | ||
109 | rcu_read_lock(); | 108 | rcu_read_lock(); |
@@ -126,7 +125,7 @@ static int count_hlist(struct net *net, | |||
126 | * We should not see tuples twice unless someone hooks | 125 | * We should not see tuples twice unless someone hooks |
127 | * this into a table without "-p tcp --syn". | 126 | * this into a table without "-p tcp --syn". |
128 | */ | 127 | */ |
129 | addit = false; | 128 | *addit = false; |
130 | } else if (already_closed(found_ct)) { | 129 | } else if (already_closed(found_ct)) { |
131 | /* | 130 | /* |
132 | * we do not care about connections which are | 131 | * we do not care about connections which are |
@@ -146,20 +145,22 @@ static int count_hlist(struct net *net, | |||
146 | 145 | ||
147 | rcu_read_unlock(); | 146 | rcu_read_unlock(); |
148 | 147 | ||
149 | if (addit) { | ||
150 | /* save the new connection in our list */ | ||
151 | conn = kmalloc(sizeof(*conn), GFP_ATOMIC); | ||
152 | if (conn == NULL) | ||
153 | return -ENOMEM; | ||
154 | conn->tuple = *tuple; | ||
155 | conn->addr = *addr; | ||
156 | hlist_add_head(&conn->node, head); | ||
157 | ++matches; | ||
158 | } | ||
159 | |||
160 | return matches; | 148 | return matches; |
161 | } | 149 | } |
162 | 150 | ||
151 | static bool add_hlist(struct hlist_head *head, | ||
152 | const struct nf_conntrack_tuple *tuple, | ||
153 | const union nf_inet_addr *addr) | ||
154 | { | ||
155 | struct xt_connlimit_conn *conn = kmalloc(sizeof(*conn), GFP_ATOMIC); | ||
156 | if (conn == NULL) | ||
157 | return false; | ||
158 | conn->tuple = *tuple; | ||
159 | conn->addr = *addr; | ||
160 | hlist_add_head(&conn->node, head); | ||
161 | return true; | ||
162 | } | ||
163 | |||
163 | static int count_them(struct net *net, | 164 | static int count_them(struct net *net, |
164 | struct xt_connlimit_data *data, | 165 | struct xt_connlimit_data *data, |
165 | const struct nf_conntrack_tuple *tuple, | 166 | const struct nf_conntrack_tuple *tuple, |
@@ -170,6 +171,7 @@ static int count_them(struct net *net, | |||
170 | struct hlist_head *hhead; | 171 | struct hlist_head *hhead; |
171 | int count; | 172 | int count; |
172 | u32 hash; | 173 | u32 hash; |
174 | bool addit = true; | ||
173 | 175 | ||
174 | if (family == NFPROTO_IPV6) | 176 | if (family == NFPROTO_IPV6) |
175 | hash = connlimit_iphash6(addr, mask); | 177 | hash = connlimit_iphash6(addr, mask); |
@@ -179,7 +181,13 @@ static int count_them(struct net *net, | |||
179 | hhead = &data->iphash[hash]; | 181 | hhead = &data->iphash[hash]; |
180 | 182 | ||
181 | spin_lock_bh(&data->lock); | 183 | spin_lock_bh(&data->lock); |
182 | count = count_hlist(net, hhead, tuple, addr, mask, family); | 184 | count = count_hlist(net, hhead, tuple, addr, mask, family, &addit); |
185 | if (addit) { | ||
186 | if (add_hlist(hhead, tuple, addr)) | ||
187 | count++; | ||
188 | else | ||
189 | count = -ENOMEM; | ||
190 | } | ||
183 | spin_unlock_bh(&data->lock); | 191 | spin_unlock_bh(&data->lock); |
184 | 192 | ||
185 | return count; | 193 | return count; |