aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/ipvs/ip_vs_app.c12
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c29
-rw-r--r--net/netfilter/ipvs/ip_vs_pe.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_sched.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c13
-rw-r--r--net/netfilter/nf_flow_table_core.c3
-rw-r--r--net/netfilter/nf_tables_offload.c2
-rw-r--r--net/netfilter/nft_payload.c38
8 files changed, 76 insertions, 27 deletions
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index 4515056ef1c2..f9b16f2b2219 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -193,21 +193,29 @@ struct ip_vs_app *register_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *
193 193
194 mutex_lock(&__ip_vs_app_mutex); 194 mutex_lock(&__ip_vs_app_mutex);
195 195
196 /* increase the module use count */
197 if (!ip_vs_use_count_inc()) {
198 err = -ENOENT;
199 goto out_unlock;
200 }
201
196 list_for_each_entry(a, &ipvs->app_list, a_list) { 202 list_for_each_entry(a, &ipvs->app_list, a_list) {
197 if (!strcmp(app->name, a->name)) { 203 if (!strcmp(app->name, a->name)) {
198 err = -EEXIST; 204 err = -EEXIST;
205 /* decrease the module use count */
206 ip_vs_use_count_dec();
199 goto out_unlock; 207 goto out_unlock;
200 } 208 }
201 } 209 }
202 a = kmemdup(app, sizeof(*app), GFP_KERNEL); 210 a = kmemdup(app, sizeof(*app), GFP_KERNEL);
203 if (!a) { 211 if (!a) {
204 err = -ENOMEM; 212 err = -ENOMEM;
213 /* decrease the module use count */
214 ip_vs_use_count_dec();
205 goto out_unlock; 215 goto out_unlock;
206 } 216 }
207 INIT_LIST_HEAD(&a->incs_list); 217 INIT_LIST_HEAD(&a->incs_list);
208 list_add(&a->a_list, &ipvs->app_list); 218 list_add(&a->a_list, &ipvs->app_list);
209 /* increase the module use count */
210 ip_vs_use_count_inc();
211 219
212out_unlock: 220out_unlock:
213 mutex_unlock(&__ip_vs_app_mutex); 221 mutex_unlock(&__ip_vs_app_mutex);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 8b48e7ce1c2c..3cccc88ef817 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -93,7 +93,6 @@ static bool __ip_vs_addr_is_local_v6(struct net *net,
93static void update_defense_level(struct netns_ipvs *ipvs) 93static void update_defense_level(struct netns_ipvs *ipvs)
94{ 94{
95 struct sysinfo i; 95 struct sysinfo i;
96 static int old_secure_tcp = 0;
97 int availmem; 96 int availmem;
98 int nomem; 97 int nomem;
99 int to_change = -1; 98 int to_change = -1;
@@ -174,35 +173,35 @@ static void update_defense_level(struct netns_ipvs *ipvs)
174 spin_lock(&ipvs->securetcp_lock); 173 spin_lock(&ipvs->securetcp_lock);
175 switch (ipvs->sysctl_secure_tcp) { 174 switch (ipvs->sysctl_secure_tcp) {
176 case 0: 175 case 0:
177 if (old_secure_tcp >= 2) 176 if (ipvs->old_secure_tcp >= 2)
178 to_change = 0; 177 to_change = 0;
179 break; 178 break;
180 case 1: 179 case 1:
181 if (nomem) { 180 if (nomem) {
182 if (old_secure_tcp < 2) 181 if (ipvs->old_secure_tcp < 2)
183 to_change = 1; 182 to_change = 1;
184 ipvs->sysctl_secure_tcp = 2; 183 ipvs->sysctl_secure_tcp = 2;
185 } else { 184 } else {
186 if (old_secure_tcp >= 2) 185 if (ipvs->old_secure_tcp >= 2)
187 to_change = 0; 186 to_change = 0;
188 } 187 }
189 break; 188 break;
190 case 2: 189 case 2:
191 if (nomem) { 190 if (nomem) {
192 if (old_secure_tcp < 2) 191 if (ipvs->old_secure_tcp < 2)
193 to_change = 1; 192 to_change = 1;
194 } else { 193 } else {
195 if (old_secure_tcp >= 2) 194 if (ipvs->old_secure_tcp >= 2)
196 to_change = 0; 195 to_change = 0;
197 ipvs->sysctl_secure_tcp = 1; 196 ipvs->sysctl_secure_tcp = 1;
198 } 197 }
199 break; 198 break;
200 case 3: 199 case 3:
201 if (old_secure_tcp < 2) 200 if (ipvs->old_secure_tcp < 2)
202 to_change = 1; 201 to_change = 1;
203 break; 202 break;
204 } 203 }
205 old_secure_tcp = ipvs->sysctl_secure_tcp; 204 ipvs->old_secure_tcp = ipvs->sysctl_secure_tcp;
206 if (to_change >= 0) 205 if (to_change >= 0)
207 ip_vs_protocol_timeout_change(ipvs, 206 ip_vs_protocol_timeout_change(ipvs,
208 ipvs->sysctl_secure_tcp > 1); 207 ipvs->sysctl_secure_tcp > 1);
@@ -1275,7 +1274,8 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u,
1275 struct ip_vs_service *svc = NULL; 1274 struct ip_vs_service *svc = NULL;
1276 1275
1277 /* increase the module use count */ 1276 /* increase the module use count */
1278 ip_vs_use_count_inc(); 1277 if (!ip_vs_use_count_inc())
1278 return -ENOPROTOOPT;
1279 1279
1280 /* Lookup the scheduler by 'u->sched_name' */ 1280 /* Lookup the scheduler by 'u->sched_name' */
1281 if (strcmp(u->sched_name, "none")) { 1281 if (strcmp(u->sched_name, "none")) {
@@ -2435,9 +2435,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2435 if (copy_from_user(arg, user, len) != 0) 2435 if (copy_from_user(arg, user, len) != 0)
2436 return -EFAULT; 2436 return -EFAULT;
2437 2437
2438 /* increase the module use count */
2439 ip_vs_use_count_inc();
2440
2441 /* Handle daemons since they have another lock */ 2438 /* Handle daemons since they have another lock */
2442 if (cmd == IP_VS_SO_SET_STARTDAEMON || 2439 if (cmd == IP_VS_SO_SET_STARTDAEMON ||
2443 cmd == IP_VS_SO_SET_STOPDAEMON) { 2440 cmd == IP_VS_SO_SET_STOPDAEMON) {
@@ -2450,13 +2447,13 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2450 ret = -EINVAL; 2447 ret = -EINVAL;
2451 if (strscpy(cfg.mcast_ifn, dm->mcast_ifn, 2448 if (strscpy(cfg.mcast_ifn, dm->mcast_ifn,
2452 sizeof(cfg.mcast_ifn)) <= 0) 2449 sizeof(cfg.mcast_ifn)) <= 0)
2453 goto out_dec; 2450 return ret;
2454 cfg.syncid = dm->syncid; 2451 cfg.syncid = dm->syncid;
2455 ret = start_sync_thread(ipvs, &cfg, dm->state); 2452 ret = start_sync_thread(ipvs, &cfg, dm->state);
2456 } else { 2453 } else {
2457 ret = stop_sync_thread(ipvs, dm->state); 2454 ret = stop_sync_thread(ipvs, dm->state);
2458 } 2455 }
2459 goto out_dec; 2456 return ret;
2460 } 2457 }
2461 2458
2462 mutex_lock(&__ip_vs_mutex); 2459 mutex_lock(&__ip_vs_mutex);
@@ -2551,10 +2548,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2551 2548
2552 out_unlock: 2549 out_unlock:
2553 mutex_unlock(&__ip_vs_mutex); 2550 mutex_unlock(&__ip_vs_mutex);
2554 out_dec:
2555 /* decrease the module use count */
2556 ip_vs_use_count_dec();
2557
2558 return ret; 2551 return ret;
2559} 2552}
2560 2553
diff --git a/net/netfilter/ipvs/ip_vs_pe.c b/net/netfilter/ipvs/ip_vs_pe.c
index 8e104dff7abc..166c669f0763 100644
--- a/net/netfilter/ipvs/ip_vs_pe.c
+++ b/net/netfilter/ipvs/ip_vs_pe.c
@@ -68,7 +68,8 @@ int register_ip_vs_pe(struct ip_vs_pe *pe)
68 struct ip_vs_pe *tmp; 68 struct ip_vs_pe *tmp;
69 69
70 /* increase the module use count */ 70 /* increase the module use count */
71 ip_vs_use_count_inc(); 71 if (!ip_vs_use_count_inc())
72 return -ENOENT;
72 73
73 mutex_lock(&ip_vs_pe_mutex); 74 mutex_lock(&ip_vs_pe_mutex);
74 /* Make sure that the pe with this name doesn't exist 75 /* Make sure that the pe with this name doesn't exist
diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c
index 2f9d5cd5daee..d4903723be7e 100644
--- a/net/netfilter/ipvs/ip_vs_sched.c
+++ b/net/netfilter/ipvs/ip_vs_sched.c
@@ -179,7 +179,8 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
179 } 179 }
180 180
181 /* increase the module use count */ 181 /* increase the module use count */
182 ip_vs_use_count_inc(); 182 if (!ip_vs_use_count_inc())
183 return -ENOENT;
183 184
184 mutex_lock(&ip_vs_sched_mutex); 185 mutex_lock(&ip_vs_sched_mutex);
185 186
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index a4a78c4b06de..8dc892a9dc91 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -1762,6 +1762,10 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
1762 IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %zd bytes\n", 1762 IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %zd bytes\n",
1763 sizeof(struct ip_vs_sync_conn_v0)); 1763 sizeof(struct ip_vs_sync_conn_v0));
1764 1764
1765 /* increase the module use count */
1766 if (!ip_vs_use_count_inc())
1767 return -ENOPROTOOPT;
1768
1765 /* Do not hold one mutex and then to block on another */ 1769 /* Do not hold one mutex and then to block on another */
1766 for (;;) { 1770 for (;;) {
1767 rtnl_lock(); 1771 rtnl_lock();
@@ -1892,9 +1896,6 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
1892 mutex_unlock(&ipvs->sync_mutex); 1896 mutex_unlock(&ipvs->sync_mutex);
1893 rtnl_unlock(); 1897 rtnl_unlock();
1894 1898
1895 /* increase the module use count */
1896 ip_vs_use_count_inc();
1897
1898 return 0; 1899 return 0;
1899 1900
1900out: 1901out:
@@ -1924,11 +1925,17 @@ out:
1924 } 1925 }
1925 kfree(ti); 1926 kfree(ti);
1926 } 1927 }
1928
1929 /* decrease the module use count */
1930 ip_vs_use_count_dec();
1927 return result; 1931 return result;
1928 1932
1929out_early: 1933out_early:
1930 mutex_unlock(&ipvs->sync_mutex); 1934 mutex_unlock(&ipvs->sync_mutex);
1931 rtnl_unlock(); 1935 rtnl_unlock();
1936
1937 /* decrease the module use count */
1938 ip_vs_use_count_dec();
1932 return result; 1939 return result;
1933} 1940}
1934 1941
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index 132f5228b431..128245efe84a 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -202,6 +202,8 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow)
202{ 202{
203 int err; 203 int err;
204 204
205 flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT;
206
205 err = rhashtable_insert_fast(&flow_table->rhashtable, 207 err = rhashtable_insert_fast(&flow_table->rhashtable,
206 &flow->tuplehash[0].node, 208 &flow->tuplehash[0].node,
207 nf_flow_offload_rhash_params); 209 nf_flow_offload_rhash_params);
@@ -218,7 +220,6 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow)
218 return err; 220 return err;
219 } 221 }
220 222
221 flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT;
222 return 0; 223 return 0;
223} 224}
224EXPORT_SYMBOL_GPL(flow_offload_add); 225EXPORT_SYMBOL_GPL(flow_offload_add);
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
index e546f759b7a7..ad783f4840ef 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -347,7 +347,7 @@ int nft_flow_rule_offload_commit(struct net *net)
347 347
348 policy = nft_trans_chain_policy(trans); 348 policy = nft_trans_chain_policy(trans);
349 err = nft_flow_offload_chain(trans->ctx.chain, &policy, 349 err = nft_flow_offload_chain(trans->ctx.chain, &policy,
350 FLOW_BLOCK_BIND); 350 FLOW_BLOCK_UNBIND);
351 break; 351 break;
352 case NFT_MSG_NEWRULE: 352 case NFT_MSG_NEWRULE:
353 if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)) 353 if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD))
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 22a80eb60222..5cb2d8908d2a 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -161,13 +161,21 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
161 161
162 switch (priv->offset) { 162 switch (priv->offset) {
163 case offsetof(struct ethhdr, h_source): 163 case offsetof(struct ethhdr, h_source):
164 if (priv->len != ETH_ALEN)
165 return -EOPNOTSUPP;
166
164 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs, 167 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
165 src, ETH_ALEN, reg); 168 src, ETH_ALEN, reg);
166 break; 169 break;
167 case offsetof(struct ethhdr, h_dest): 170 case offsetof(struct ethhdr, h_dest):
171 if (priv->len != ETH_ALEN)
172 return -EOPNOTSUPP;
173
168 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs, 174 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
169 dst, ETH_ALEN, reg); 175 dst, ETH_ALEN, reg);
170 break; 176 break;
177 default:
178 return -EOPNOTSUPP;
171 } 179 }
172 180
173 return 0; 181 return 0;
@@ -181,14 +189,23 @@ static int nft_payload_offload_ip(struct nft_offload_ctx *ctx,
181 189
182 switch (priv->offset) { 190 switch (priv->offset) {
183 case offsetof(struct iphdr, saddr): 191 case offsetof(struct iphdr, saddr):
192 if (priv->len != sizeof(struct in_addr))
193 return -EOPNOTSUPP;
194
184 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src, 195 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src,
185 sizeof(struct in_addr), reg); 196 sizeof(struct in_addr), reg);
186 break; 197 break;
187 case offsetof(struct iphdr, daddr): 198 case offsetof(struct iphdr, daddr):
199 if (priv->len != sizeof(struct in_addr))
200 return -EOPNOTSUPP;
201
188 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst, 202 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst,
189 sizeof(struct in_addr), reg); 203 sizeof(struct in_addr), reg);
190 break; 204 break;
191 case offsetof(struct iphdr, protocol): 205 case offsetof(struct iphdr, protocol):
206 if (priv->len != sizeof(__u8))
207 return -EOPNOTSUPP;
208
192 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, 209 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
193 sizeof(__u8), reg); 210 sizeof(__u8), reg);
194 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT); 211 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
@@ -208,14 +225,23 @@ static int nft_payload_offload_ip6(struct nft_offload_ctx *ctx,
208 225
209 switch (priv->offset) { 226 switch (priv->offset) {
210 case offsetof(struct ipv6hdr, saddr): 227 case offsetof(struct ipv6hdr, saddr):
228 if (priv->len != sizeof(struct in6_addr))
229 return -EOPNOTSUPP;
230
211 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src, 231 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src,
212 sizeof(struct in6_addr), reg); 232 sizeof(struct in6_addr), reg);
213 break; 233 break;
214 case offsetof(struct ipv6hdr, daddr): 234 case offsetof(struct ipv6hdr, daddr):
235 if (priv->len != sizeof(struct in6_addr))
236 return -EOPNOTSUPP;
237
215 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst, 238 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst,
216 sizeof(struct in6_addr), reg); 239 sizeof(struct in6_addr), reg);
217 break; 240 break;
218 case offsetof(struct ipv6hdr, nexthdr): 241 case offsetof(struct ipv6hdr, nexthdr):
242 if (priv->len != sizeof(__u8))
243 return -EOPNOTSUPP;
244
219 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, 245 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
220 sizeof(__u8), reg); 246 sizeof(__u8), reg);
221 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT); 247 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
@@ -255,10 +281,16 @@ static int nft_payload_offload_tcp(struct nft_offload_ctx *ctx,
255 281
256 switch (priv->offset) { 282 switch (priv->offset) {
257 case offsetof(struct tcphdr, source): 283 case offsetof(struct tcphdr, source):
284 if (priv->len != sizeof(__be16))
285 return -EOPNOTSUPP;
286
258 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src, 287 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
259 sizeof(__be16), reg); 288 sizeof(__be16), reg);
260 break; 289 break;
261 case offsetof(struct tcphdr, dest): 290 case offsetof(struct tcphdr, dest):
291 if (priv->len != sizeof(__be16))
292 return -EOPNOTSUPP;
293
262 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst, 294 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
263 sizeof(__be16), reg); 295 sizeof(__be16), reg);
264 break; 296 break;
@@ -277,10 +309,16 @@ static int nft_payload_offload_udp(struct nft_offload_ctx *ctx,
277 309
278 switch (priv->offset) { 310 switch (priv->offset) {
279 case offsetof(struct udphdr, source): 311 case offsetof(struct udphdr, source):
312 if (priv->len != sizeof(__be16))
313 return -EOPNOTSUPP;
314
280 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src, 315 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
281 sizeof(__be16), reg); 316 sizeof(__be16), reg);
282 break; 317 break;
283 case offsetof(struct udphdr, dest): 318 case offsetof(struct udphdr, dest):
319 if (priv->len != sizeof(__be16))
320 return -EOPNOTSUPP;
321
284 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst, 322 NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
285 sizeof(__be16), reg); 323 sizeof(__be16), reg);
286 break; 324 break;