aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHans Schillstrom <hans.schillstrom@ericsson.com>2011-01-03 08:44:51 -0500
committerSimon Horman <horms@verge.net.au>2011-01-12 20:30:27 -0500
commit9330419d9aa4f97df412ac9be9fc0388c67dd315 (patch)
tree3fdd9103f299fcd2dfafcf0f51d1b5c4430987c2 /net
parent88fe2d372793a71ae4f6319a16f537d56a83906c (diff)
IPVS: netns, use ip_vs_proto_data as param.
ip_vs_protocol *pp is replaced by ip_vs_proto_data *pd in function call in ip_vs_protocol struct i.e. :, - timeout_change() - state_transition() ip_vs_protocol_timeout_change() got ipvs as param, due to above and a upcoming patch - defence work Most of this changes are triggered by Julians comment: "tcp_timeout_change should work with the new struct ip_vs_proto_data so that tcp_state_table will go to pd->state_table and set_tcp_state will get pd instead of pp" *v3 Mostly comments from Julian The pp -> pd conversion should start from functions like ip_vs_out() that use pp = ip_vs_proto_get(iph.protocol), now they should use ip_vs_proto_data_get(net, iph.protocol). conn_in_get() and conn_out_get() unused param *pp, removed. *v4 ip_vs_protocol_timeout_change() walk the proto_data path. Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com> Acked-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c77
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c55
-rw-r--r--net/netfilter/ipvs/ip_vs_proto.c21
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_ah_esp.c10
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_sctp.c16
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_tcp.c27
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_udp.c11
-rw-r--r--net/netfilter/xt_ipvs.c2
9 files changed, 123 insertions, 98 deletions
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 7a0e79e3ad0..a7aba6a4697 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -329,7 +329,6 @@ ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb,
329 329
330struct ip_vs_conn * 330struct ip_vs_conn *
331ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, 331ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb,
332 struct ip_vs_protocol *pp,
333 const struct ip_vs_iphdr *iph, 332 const struct ip_vs_iphdr *iph,
334 unsigned int proto_off, int inverse) 333 unsigned int proto_off, int inverse)
335{ 334{
@@ -428,7 +427,6 @@ struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p)
428 427
429struct ip_vs_conn * 428struct ip_vs_conn *
430ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, 429ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb,
431 struct ip_vs_protocol *pp,
432 const struct ip_vs_iphdr *iph, 430 const struct ip_vs_iphdr *iph,
433 unsigned int proto_off, int inverse) 431 unsigned int proto_off, int inverse)
434{ 432{
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index d0616ea1eeb..9317affc5ea 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -177,11 +177,11 @@ ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc)
177static inline int 177static inline int
178ip_vs_set_state(struct ip_vs_conn *cp, int direction, 178ip_vs_set_state(struct ip_vs_conn *cp, int direction,
179 const struct sk_buff *skb, 179 const struct sk_buff *skb,
180 struct ip_vs_protocol *pp) 180 struct ip_vs_proto_data *pd)
181{ 181{
182 if (unlikely(!pp->state_transition)) 182 if (unlikely(!pd->pp->state_transition))
183 return 0; 183 return 0;
184 return pp->state_transition(cp, direction, skb, pp); 184 return pd->pp->state_transition(cp, direction, skb, pd);
185} 185}
186 186
187static inline int 187static inline int
@@ -378,8 +378,9 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
378 */ 378 */
379struct ip_vs_conn * 379struct ip_vs_conn *
380ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, 380ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
381 struct ip_vs_protocol *pp, int *ignored) 381 struct ip_vs_proto_data *pd, int *ignored)
382{ 382{
383 struct ip_vs_protocol *pp = pd->pp;
383 struct ip_vs_conn *cp = NULL; 384 struct ip_vs_conn *cp = NULL;
384 struct ip_vs_iphdr iph; 385 struct ip_vs_iphdr iph;
385 struct ip_vs_dest *dest; 386 struct ip_vs_dest *dest;
@@ -408,7 +409,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
408 * Do not schedule replies from local real server. 409 * Do not schedule replies from local real server.
409 */ 410 */
410 if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) && 411 if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) &&
411 (cp = pp->conn_in_get(svc->af, skb, pp, &iph, iph.len, 1))) { 412 (cp = pp->conn_in_get(svc->af, skb, &iph, iph.len, 1))) {
412 IP_VS_DBG_PKT(12, svc->af, pp, skb, 0, 413 IP_VS_DBG_PKT(12, svc->af, pp, skb, 0,
413 "Not scheduling reply for existing connection"); 414 "Not scheduling reply for existing connection");
414 __ip_vs_conn_put(cp); 415 __ip_vs_conn_put(cp);
@@ -479,11 +480,12 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
479 * no destination is available for a new connection. 480 * no destination is available for a new connection.
480 */ 481 */
481int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, 482int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
482 struct ip_vs_protocol *pp) 483 struct ip_vs_proto_data *pd)
483{ 484{
484 __be16 _ports[2], *pptr; 485 __be16 _ports[2], *pptr;
485 struct ip_vs_iphdr iph; 486 struct ip_vs_iphdr iph;
486 int unicast; 487 int unicast;
488
487 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); 489 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
488 490
489 pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports); 491 pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
@@ -530,10 +532,10 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
530 ip_vs_in_stats(cp, skb); 532 ip_vs_in_stats(cp, skb);
531 533
532 /* set state */ 534 /* set state */
533 cs = ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pp); 535 cs = ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd);
534 536
535 /* transmit the first SYN packet */ 537 /* transmit the first SYN packet */
536 ret = cp->packet_xmit(skb, cp, pp); 538 ret = cp->packet_xmit(skb, cp, pd->pp);
537 /* do not touch skb anymore */ 539 /* do not touch skb anymore */
538 540
539 atomic_inc(&cp->in_pkts); 541 atomic_inc(&cp->in_pkts);
@@ -840,7 +842,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related,
840 842
841 ip_vs_fill_iphdr(AF_INET, cih, &ciph); 843 ip_vs_fill_iphdr(AF_INET, cih, &ciph);
842 /* The embedded headers contain source and dest in reverse order */ 844 /* The embedded headers contain source and dest in reverse order */
843 cp = pp->conn_out_get(AF_INET, skb, pp, &ciph, offset, 1); 845 cp = pp->conn_out_get(AF_INET, skb, &ciph, offset, 1);
844 if (!cp) 846 if (!cp)
845 return NF_ACCEPT; 847 return NF_ACCEPT;
846 848
@@ -917,7 +919,7 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related,
917 919
918 ip_vs_fill_iphdr(AF_INET6, cih, &ciph); 920 ip_vs_fill_iphdr(AF_INET6, cih, &ciph);
919 /* The embedded headers contain source and dest in reverse order */ 921 /* The embedded headers contain source and dest in reverse order */
920 cp = pp->conn_out_get(AF_INET6, skb, pp, &ciph, offset, 1); 922 cp = pp->conn_out_get(AF_INET6, skb, &ciph, offset, 1);
921 if (!cp) 923 if (!cp)
922 return NF_ACCEPT; 924 return NF_ACCEPT;
923 925
@@ -956,9 +958,11 @@ static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len)
956 * Used for NAT and local client. 958 * Used for NAT and local client.
957 */ 959 */
958static unsigned int 960static unsigned int
959handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, 961handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
960 struct ip_vs_conn *cp, int ihl) 962 struct ip_vs_conn *cp, int ihl)
961{ 963{
964 struct ip_vs_protocol *pp = pd->pp;
965
962 IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet"); 966 IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet");
963 967
964 if (!skb_make_writable(skb, ihl)) 968 if (!skb_make_writable(skb, ihl))
@@ -1007,7 +1011,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
1007 IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT"); 1011 IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT");
1008 1012
1009 ip_vs_out_stats(cp, skb); 1013 ip_vs_out_stats(cp, skb);
1010 ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); 1014 ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pd);
1011 skb->ipvs_property = 1; 1015 skb->ipvs_property = 1;
1012 if (!(cp->flags & IP_VS_CONN_F_NFCT)) 1016 if (!(cp->flags & IP_VS_CONN_F_NFCT))
1013 ip_vs_notrack(skb); 1017 ip_vs_notrack(skb);
@@ -1034,6 +1038,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
1034 struct net *net = NULL; 1038 struct net *net = NULL;
1035 struct ip_vs_iphdr iph; 1039 struct ip_vs_iphdr iph;
1036 struct ip_vs_protocol *pp; 1040 struct ip_vs_protocol *pp;
1041 struct ip_vs_proto_data *pd;
1037 struct ip_vs_conn *cp; 1042 struct ip_vs_conn *cp;
1038 1043
1039 EnterFunction(11); 1044 EnterFunction(11);
@@ -1079,9 +1084,10 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
1079 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); 1084 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1080 } 1085 }
1081 1086
1082 pp = ip_vs_proto_get(iph.protocol); 1087 pd = ip_vs_proto_data_get(net, iph.protocol);
1083 if (unlikely(!pp)) 1088 if (unlikely(!pd))
1084 return NF_ACCEPT; 1089 return NF_ACCEPT;
1090 pp = pd->pp;
1085 1091
1086 /* reassemble IP fragments */ 1092 /* reassemble IP fragments */
1087#ifdef CONFIG_IP_VS_IPV6 1093#ifdef CONFIG_IP_VS_IPV6
@@ -1107,10 +1113,10 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
1107 /* 1113 /*
1108 * Check if the packet belongs to an existing entry 1114 * Check if the packet belongs to an existing entry
1109 */ 1115 */
1110 cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0); 1116 cp = pp->conn_out_get(af, skb, &iph, iph.len, 0);
1111 1117
1112 if (likely(cp)) 1118 if (likely(cp))
1113 return handle_response(af, skb, pp, cp, iph.len); 1119 return handle_response(af, skb, pd, cp, iph.len);
1114 if (sysctl_ip_vs_nat_icmp_send && 1120 if (sysctl_ip_vs_nat_icmp_send &&
1115 (pp->protocol == IPPROTO_TCP || 1121 (pp->protocol == IPPROTO_TCP ||
1116 pp->protocol == IPPROTO_UDP || 1122 pp->protocol == IPPROTO_UDP ||
@@ -1236,12 +1242,14 @@ ip_vs_local_reply6(unsigned int hooknum, struct sk_buff *skb,
1236static int 1242static int
1237ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) 1243ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1238{ 1244{
1245 struct net *net = NULL;
1239 struct iphdr *iph; 1246 struct iphdr *iph;
1240 struct icmphdr _icmph, *ic; 1247 struct icmphdr _icmph, *ic;
1241 struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */ 1248 struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */
1242 struct ip_vs_iphdr ciph; 1249 struct ip_vs_iphdr ciph;
1243 struct ip_vs_conn *cp; 1250 struct ip_vs_conn *cp;
1244 struct ip_vs_protocol *pp; 1251 struct ip_vs_protocol *pp;
1252 struct ip_vs_proto_data *pd;
1245 unsigned int offset, ihl, verdict; 1253 unsigned int offset, ihl, verdict;
1246 union nf_inet_addr snet; 1254 union nf_inet_addr snet;
1247 1255
@@ -1283,9 +1291,11 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1283 if (cih == NULL) 1291 if (cih == NULL)
1284 return NF_ACCEPT; /* The packet looks wrong, ignore */ 1292 return NF_ACCEPT; /* The packet looks wrong, ignore */
1285 1293
1286 pp = ip_vs_proto_get(cih->protocol); 1294 net = skb_net(skb);
1287 if (!pp) 1295 pd = ip_vs_proto_data_get(net, cih->protocol);
1296 if (!pd)
1288 return NF_ACCEPT; 1297 return NF_ACCEPT;
1298 pp = pd->pp;
1289 1299
1290 /* Is the embedded protocol header present? */ 1300 /* Is the embedded protocol header present? */
1291 if (unlikely(cih->frag_off & htons(IP_OFFSET) && 1301 if (unlikely(cih->frag_off & htons(IP_OFFSET) &&
@@ -1299,10 +1309,10 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1299 1309
1300 ip_vs_fill_iphdr(AF_INET, cih, &ciph); 1310 ip_vs_fill_iphdr(AF_INET, cih, &ciph);
1301 /* The embedded headers contain source and dest in reverse order */ 1311 /* The embedded headers contain source and dest in reverse order */
1302 cp = pp->conn_in_get(AF_INET, skb, pp, &ciph, offset, 1); 1312 cp = pp->conn_in_get(AF_INET, skb, &ciph, offset, 1);
1303 if (!cp) { 1313 if (!cp) {
1304 /* The packet could also belong to a local client */ 1314 /* The packet could also belong to a local client */
1305 cp = pp->conn_out_get(AF_INET, skb, pp, &ciph, offset, 1); 1315 cp = pp->conn_out_get(AF_INET, skb, &ciph, offset, 1);
1306 if (cp) { 1316 if (cp) {
1307 snet.ip = iph->saddr; 1317 snet.ip = iph->saddr;
1308 return handle_response_icmp(AF_INET, skb, &snet, 1318 return handle_response_icmp(AF_INET, skb, &snet,
@@ -1346,6 +1356,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1346static int 1356static int
1347ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) 1357ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1348{ 1358{
1359 struct net *net = NULL;
1349 struct ipv6hdr *iph; 1360 struct ipv6hdr *iph;
1350 struct icmp6hdr _icmph, *ic; 1361 struct icmp6hdr _icmph, *ic;
1351 struct ipv6hdr _ciph, *cih; /* The ip header contained 1362 struct ipv6hdr _ciph, *cih; /* The ip header contained
@@ -1353,6 +1364,7 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1353 struct ip_vs_iphdr ciph; 1364 struct ip_vs_iphdr ciph;
1354 struct ip_vs_conn *cp; 1365 struct ip_vs_conn *cp;
1355 struct ip_vs_protocol *pp; 1366 struct ip_vs_protocol *pp;
1367 struct ip_vs_proto_data *pd;
1356 unsigned int offset, verdict; 1368 unsigned int offset, verdict;
1357 union nf_inet_addr snet; 1369 union nf_inet_addr snet;
1358 struct rt6_info *rt; 1370 struct rt6_info *rt;
@@ -1395,9 +1407,11 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1395 if (cih == NULL) 1407 if (cih == NULL)
1396 return NF_ACCEPT; /* The packet looks wrong, ignore */ 1408 return NF_ACCEPT; /* The packet looks wrong, ignore */
1397 1409
1398 pp = ip_vs_proto_get(cih->nexthdr); 1410 net = skb_net(skb);
1399 if (!pp) 1411 pd = ip_vs_proto_data_get(net, cih->nexthdr);
1412 if (!pd)
1400 return NF_ACCEPT; 1413 return NF_ACCEPT;
1414 pp = pd->pp;
1401 1415
1402 /* Is the embedded protocol header present? */ 1416 /* Is the embedded protocol header present? */
1403 /* TODO: we don't support fragmentation at the moment anyways */ 1417 /* TODO: we don't support fragmentation at the moment anyways */
@@ -1411,10 +1425,10 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1411 1425
1412 ip_vs_fill_iphdr(AF_INET6, cih, &ciph); 1426 ip_vs_fill_iphdr(AF_INET6, cih, &ciph);
1413 /* The embedded headers contain source and dest in reverse order */ 1427 /* The embedded headers contain source and dest in reverse order */
1414 cp = pp->conn_in_get(AF_INET6, skb, pp, &ciph, offset, 1); 1428 cp = pp->conn_in_get(AF_INET6, skb, &ciph, offset, 1);
1415 if (!cp) { 1429 if (!cp) {
1416 /* The packet could also belong to a local client */ 1430 /* The packet could also belong to a local client */
1417 cp = pp->conn_out_get(AF_INET6, skb, pp, &ciph, offset, 1); 1431 cp = pp->conn_out_get(AF_INET6, skb, &ciph, offset, 1);
1418 if (cp) { 1432 if (cp) {
1419 ipv6_addr_copy(&snet.in6, &iph->saddr); 1433 ipv6_addr_copy(&snet.in6, &iph->saddr);
1420 return handle_response_icmp(AF_INET6, skb, &snet, 1434 return handle_response_icmp(AF_INET6, skb, &snet,
@@ -1457,8 +1471,10 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1457static unsigned int 1471static unsigned int
1458ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) 1472ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
1459{ 1473{
1474 struct net *net = NULL;
1460 struct ip_vs_iphdr iph; 1475 struct ip_vs_iphdr iph;
1461 struct ip_vs_protocol *pp; 1476 struct ip_vs_protocol *pp;
1477 struct ip_vs_proto_data *pd;
1462 struct ip_vs_conn *cp; 1478 struct ip_vs_conn *cp;
1463 int ret, restart, pkts; 1479 int ret, restart, pkts;
1464 1480
@@ -1514,20 +1530,21 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
1514 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); 1530 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1515 } 1531 }
1516 1532
1533 net = skb_net(skb);
1517 /* Protocol supported? */ 1534 /* Protocol supported? */
1518 pp = ip_vs_proto_get(iph.protocol); 1535 pd = ip_vs_proto_data_get(net, iph.protocol);
1519 if (unlikely(!pp)) 1536 if (unlikely(!pd))
1520 return NF_ACCEPT; 1537 return NF_ACCEPT;
1521 1538 pp = pd->pp;
1522 /* 1539 /*
1523 * Check if the packet belongs to an existing connection entry 1540 * Check if the packet belongs to an existing connection entry
1524 */ 1541 */
1525 cp = pp->conn_in_get(af, skb, pp, &iph, iph.len, 0); 1542 cp = pp->conn_in_get(af, skb, &iph, iph.len, 0);
1526 1543
1527 if (unlikely(!cp)) { 1544 if (unlikely(!cp)) {
1528 int v; 1545 int v;
1529 1546
1530 if (!pp->conn_schedule(af, skb, pp, &v, &cp)) 1547 if (!pp->conn_schedule(af, skb, pd, &v, &cp))
1531 return v; 1548 return v;
1532 } 1549 }
1533 1550
@@ -1555,7 +1572,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
1555 } 1572 }
1556 1573
1557 ip_vs_in_stats(cp, skb); 1574 ip_vs_in_stats(cp, skb);
1558 restart = ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pp); 1575 restart = ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd);
1559 if (cp->packet_xmit) 1576 if (cp->packet_xmit)
1560 ret = cp->packet_xmit(skb, cp, pp); 1577 ret = cp->packet_xmit(skb, cp, pp);
1561 /* do not touch skb anymore */ 1578 /* do not touch skb anymore */
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 2d7c96bd211..88474f1e828 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -38,6 +38,7 @@
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39 39
40#include <net/net_namespace.h> 40#include <net/net_namespace.h>
41#include <linux/nsproxy.h>
41#include <net/ip.h> 42#include <net/ip.h>
42#ifdef CONFIG_IP_VS_IPV6 43#ifdef CONFIG_IP_VS_IPV6
43#include <net/ipv6.h> 44#include <net/ipv6.h>
@@ -125,7 +126,7 @@ static int __ip_vs_addr_is_local_v6(const struct in6_addr *addr)
125 * update_defense_level is called from keventd and from sysctl, 126 * update_defense_level is called from keventd and from sysctl,
126 * so it needs to protect itself from softirqs 127 * so it needs to protect itself from softirqs
127 */ 128 */
128static void update_defense_level(void) 129static void update_defense_level(struct netns_ipvs *ipvs)
129{ 130{
130 struct sysinfo i; 131 struct sysinfo i;
131 static int old_secure_tcp = 0; 132 static int old_secure_tcp = 0;
@@ -239,7 +240,8 @@ static void update_defense_level(void)
239 } 240 }
240 old_secure_tcp = sysctl_ip_vs_secure_tcp; 241 old_secure_tcp = sysctl_ip_vs_secure_tcp;
241 if (to_change >= 0) 242 if (to_change >= 0)
242 ip_vs_protocol_timeout_change(sysctl_ip_vs_secure_tcp>1); 243 ip_vs_protocol_timeout_change(ipvs,
244 sysctl_ip_vs_secure_tcp > 1);
243 spin_unlock(&ip_vs_securetcp_lock); 245 spin_unlock(&ip_vs_securetcp_lock);
244 246
245 local_bh_enable(); 247 local_bh_enable();
@@ -255,7 +257,10 @@ static DECLARE_DELAYED_WORK(defense_work, defense_work_handler);
255 257
256static void defense_work_handler(struct work_struct *work) 258static void defense_work_handler(struct work_struct *work)
257{ 259{
258 update_defense_level(); 260 struct net *net = &init_net;
261 struct netns_ipvs *ipvs = net_ipvs(net);
262
263 update_defense_level(ipvs);
259 if (atomic_read(&ip_vs_dropentry)) 264 if (atomic_read(&ip_vs_dropentry))
260 ip_vs_random_dropentry(); 265 ip_vs_random_dropentry();
261 266
@@ -1502,6 +1507,7 @@ static int
1502proc_do_defense_mode(ctl_table *table, int write, 1507proc_do_defense_mode(ctl_table *table, int write,
1503 void __user *buffer, size_t *lenp, loff_t *ppos) 1508 void __user *buffer, size_t *lenp, loff_t *ppos)
1504{ 1509{
1510 struct net *net = current->nsproxy->net_ns;
1505 int *valp = table->data; 1511 int *valp = table->data;
1506 int val = *valp; 1512 int val = *valp;
1507 int rc; 1513 int rc;
@@ -1512,7 +1518,7 @@ proc_do_defense_mode(ctl_table *table, int write,
1512 /* Restore the correct value */ 1518 /* Restore the correct value */
1513 *valp = val; 1519 *valp = val;
1514 } else { 1520 } else {
1515 update_defense_level(); 1521 update_defense_level(net_ipvs(net));
1516 } 1522 }
1517 } 1523 }
1518 return rc; 1524 return rc;
@@ -2033,8 +2039,10 @@ static const struct file_operations ip_vs_stats_fops = {
2033/* 2039/*
2034 * Set timeout values for tcp tcpfin udp in the timeout_table. 2040 * Set timeout values for tcp tcpfin udp in the timeout_table.
2035 */ 2041 */
2036static int ip_vs_set_timeout(struct ip_vs_timeout_user *u) 2042static int ip_vs_set_timeout(struct net *net, struct ip_vs_timeout_user *u)
2037{ 2043{
2044 struct ip_vs_proto_data *pd;
2045
2038 IP_VS_DBG(2, "Setting timeout tcp:%d tcpfin:%d udp:%d\n", 2046 IP_VS_DBG(2, "Setting timeout tcp:%d tcpfin:%d udp:%d\n",
2039 u->tcp_timeout, 2047 u->tcp_timeout,
2040 u->tcp_fin_timeout, 2048 u->tcp_fin_timeout,
@@ -2042,19 +2050,22 @@ static int ip_vs_set_timeout(struct ip_vs_timeout_user *u)
2042 2050
2043#ifdef CONFIG_IP_VS_PROTO_TCP 2051#ifdef CONFIG_IP_VS_PROTO_TCP
2044 if (u->tcp_timeout) { 2052 if (u->tcp_timeout) {
2045 ip_vs_protocol_tcp.timeout_table[IP_VS_TCP_S_ESTABLISHED] 2053 pd = ip_vs_proto_data_get(net, IPPROTO_TCP);
2054 pd->timeout_table[IP_VS_TCP_S_ESTABLISHED]
2046 = u->tcp_timeout * HZ; 2055 = u->tcp_timeout * HZ;
2047 } 2056 }
2048 2057
2049 if (u->tcp_fin_timeout) { 2058 if (u->tcp_fin_timeout) {
2050 ip_vs_protocol_tcp.timeout_table[IP_VS_TCP_S_FIN_WAIT] 2059 pd = ip_vs_proto_data_get(net, IPPROTO_TCP);
2060 pd->timeout_table[IP_VS_TCP_S_FIN_WAIT]
2051 = u->tcp_fin_timeout * HZ; 2061 = u->tcp_fin_timeout * HZ;
2052 } 2062 }
2053#endif 2063#endif
2054 2064
2055#ifdef CONFIG_IP_VS_PROTO_UDP 2065#ifdef CONFIG_IP_VS_PROTO_UDP
2056 if (u->udp_timeout) { 2066 if (u->udp_timeout) {
2057 ip_vs_protocol_udp.timeout_table[IP_VS_UDP_S_NORMAL] 2067 pd = ip_vs_proto_data_get(net, IPPROTO_UDP);
2068 pd->timeout_table[IP_VS_UDP_S_NORMAL]
2058 = u->udp_timeout * HZ; 2069 = u->udp_timeout * HZ;
2059 } 2070 }
2060#endif 2071#endif
@@ -2158,7 +2169,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2158 goto out_unlock; 2169 goto out_unlock;
2159 } else if (cmd == IP_VS_SO_SET_TIMEOUT) { 2170 } else if (cmd == IP_VS_SO_SET_TIMEOUT) {
2160 /* Set timeout values for (tcp tcpfin udp) */ 2171 /* Set timeout values for (tcp tcpfin udp) */
2161 ret = ip_vs_set_timeout((struct ip_vs_timeout_user *)arg); 2172 ret = ip_vs_set_timeout(net, (struct ip_vs_timeout_user *)arg);
2162 goto out_unlock; 2173 goto out_unlock;
2163 } else if (cmd == IP_VS_SO_SET_STARTDAEMON) { 2174 } else if (cmd == IP_VS_SO_SET_STARTDAEMON) {
2164 struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg; 2175 struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
@@ -2370,17 +2381,19 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get,
2370} 2381}
2371 2382
2372static inline void 2383static inline void
2373__ip_vs_get_timeouts(struct ip_vs_timeout_user *u) 2384__ip_vs_get_timeouts(struct net *net, struct ip_vs_timeout_user *u)
2374{ 2385{
2386 struct ip_vs_proto_data *pd;
2387
2375#ifdef CONFIG_IP_VS_PROTO_TCP 2388#ifdef CONFIG_IP_VS_PROTO_TCP
2376 u->tcp_timeout = 2389 pd = ip_vs_proto_data_get(net, IPPROTO_TCP);
2377 ip_vs_protocol_tcp.timeout_table[IP_VS_TCP_S_ESTABLISHED] / HZ; 2390 u->tcp_timeout = pd->timeout_table[IP_VS_TCP_S_ESTABLISHED] / HZ;
2378 u->tcp_fin_timeout = 2391 u->tcp_fin_timeout = pd->timeout_table[IP_VS_TCP_S_FIN_WAIT] / HZ;
2379 ip_vs_protocol_tcp.timeout_table[IP_VS_TCP_S_FIN_WAIT] / HZ;
2380#endif 2392#endif
2381#ifdef CONFIG_IP_VS_PROTO_UDP 2393#ifdef CONFIG_IP_VS_PROTO_UDP
2394 pd = ip_vs_proto_data_get(net, IPPROTO_UDP);
2382 u->udp_timeout = 2395 u->udp_timeout =
2383 ip_vs_protocol_udp.timeout_table[IP_VS_UDP_S_NORMAL] / HZ; 2396 pd->timeout_table[IP_VS_UDP_S_NORMAL] / HZ;
2384#endif 2397#endif
2385} 2398}
2386 2399
@@ -2521,7 +2534,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2521 { 2534 {
2522 struct ip_vs_timeout_user t; 2535 struct ip_vs_timeout_user t;
2523 2536
2524 __ip_vs_get_timeouts(&t); 2537 __ip_vs_get_timeouts(net, &t);
2525 if (copy_to_user(user, &t, sizeof(t)) != 0) 2538 if (copy_to_user(user, &t, sizeof(t)) != 0)
2526 ret = -EFAULT; 2539 ret = -EFAULT;
2527 } 2540 }
@@ -3092,11 +3105,11 @@ static int ip_vs_genl_del_daemon(struct nlattr **attrs)
3092 return stop_sync_thread(nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE])); 3105 return stop_sync_thread(nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]));
3093} 3106}
3094 3107
3095static int ip_vs_genl_set_config(struct nlattr **attrs) 3108static int ip_vs_genl_set_config(struct net *net, struct nlattr **attrs)
3096{ 3109{
3097 struct ip_vs_timeout_user t; 3110 struct ip_vs_timeout_user t;
3098 3111
3099 __ip_vs_get_timeouts(&t); 3112 __ip_vs_get_timeouts(net, &t);
3100 3113
3101 if (attrs[IPVS_CMD_ATTR_TIMEOUT_TCP]) 3114 if (attrs[IPVS_CMD_ATTR_TIMEOUT_TCP])
3102 t.tcp_timeout = nla_get_u32(attrs[IPVS_CMD_ATTR_TIMEOUT_TCP]); 3115 t.tcp_timeout = nla_get_u32(attrs[IPVS_CMD_ATTR_TIMEOUT_TCP]);
@@ -3108,7 +3121,7 @@ static int ip_vs_genl_set_config(struct nlattr **attrs)
3108 if (attrs[IPVS_CMD_ATTR_TIMEOUT_UDP]) 3121 if (attrs[IPVS_CMD_ATTR_TIMEOUT_UDP])
3109 t.udp_timeout = nla_get_u32(attrs[IPVS_CMD_ATTR_TIMEOUT_UDP]); 3122 t.udp_timeout = nla_get_u32(attrs[IPVS_CMD_ATTR_TIMEOUT_UDP]);
3110 3123
3111 return ip_vs_set_timeout(&t); 3124 return ip_vs_set_timeout(net, &t);
3112} 3125}
3113 3126
3114static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) 3127static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
@@ -3129,7 +3142,7 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
3129 ret = ip_vs_flush(net); 3142 ret = ip_vs_flush(net);
3130 goto out; 3143 goto out;
3131 } else if (cmd == IPVS_CMD_SET_CONFIG) { 3144 } else if (cmd == IPVS_CMD_SET_CONFIG) {
3132 ret = ip_vs_genl_set_config(info->attrs); 3145 ret = ip_vs_genl_set_config(net, info->attrs);
3133 goto out; 3146 goto out;
3134 } else if (cmd == IPVS_CMD_NEW_DAEMON || 3147 } else if (cmd == IPVS_CMD_NEW_DAEMON ||
3135 cmd == IPVS_CMD_DEL_DAEMON) { 3148 cmd == IPVS_CMD_DEL_DAEMON) {
@@ -3281,7 +3294,7 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
3281 { 3294 {
3282 struct ip_vs_timeout_user t; 3295 struct ip_vs_timeout_user t;
3283 3296
3284 __ip_vs_get_timeouts(&t); 3297 __ip_vs_get_timeouts(net, &t);
3285#ifdef CONFIG_IP_VS_PROTO_TCP 3298#ifdef CONFIG_IP_VS_PROTO_TCP
3286 NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP, t.tcp_timeout); 3299 NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP, t.tcp_timeout);
3287 NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP_FIN, 3300 NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP_FIN,
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 9f609d4d5d5..6ac986cdcff 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -152,9 +152,8 @@ EXPORT_SYMBOL(ip_vs_proto_get);
152 * get ip_vs_protocol object data by netns and proto 152 * get ip_vs_protocol object data by netns and proto
153 */ 153 */
154struct ip_vs_proto_data * 154struct ip_vs_proto_data *
155ip_vs_proto_data_get(struct net *net, unsigned short proto) 155__ipvs_proto_data_get(struct netns_ipvs *ipvs, unsigned short proto)
156{ 156{
157 struct netns_ipvs *ipvs = net_ipvs(net);
158 struct ip_vs_proto_data *pd; 157 struct ip_vs_proto_data *pd;
159 unsigned hash = IP_VS_PROTO_HASH(proto); 158 unsigned hash = IP_VS_PROTO_HASH(proto);
160 159
@@ -165,20 +164,28 @@ ip_vs_proto_data_get(struct net *net, unsigned short proto)
165 164
166 return NULL; 165 return NULL;
167} 166}
167
168struct ip_vs_proto_data *
169ip_vs_proto_data_get(struct net *net, unsigned short proto)
170{
171 struct netns_ipvs *ipvs = net_ipvs(net);
172
173 return __ipvs_proto_data_get(ipvs, proto);
174}
168EXPORT_SYMBOL(ip_vs_proto_data_get); 175EXPORT_SYMBOL(ip_vs_proto_data_get);
169 176
170/* 177/*
171 * Propagate event for state change to all protocols 178 * Propagate event for state change to all protocols
172 */ 179 */
173void ip_vs_protocol_timeout_change(int flags) 180void ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags)
174{ 181{
175 struct ip_vs_protocol *pp; 182 struct ip_vs_proto_data *pd;
176 int i; 183 int i;
177 184
178 for (i = 0; i < IP_VS_PROTO_TAB_SIZE; i++) { 185 for (i = 0; i < IP_VS_PROTO_TAB_SIZE; i++) {
179 for (pp = ip_vs_proto_table[i]; pp; pp = pp->next) { 186 for (pd = ipvs->proto_data_table[i]; pd; pd = pd->next) {
180 if (pp->timeout_change) 187 if (pd->pp->timeout_change)
181 pp->timeout_change(pp, flags); 188 pd->pp->timeout_change(pd, flags);
182 } 189 }
183 } 190 }
184} 191}
diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
index b8b37fafc98..28039cbfcff 100644
--- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
@@ -55,7 +55,7 @@ ah_esp_conn_fill_param_proto(int af, const struct ip_vs_iphdr *iph,
55} 55}
56 56
57static struct ip_vs_conn * 57static struct ip_vs_conn *
58ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, 58ah_esp_conn_in_get(int af, const struct sk_buff *skb,
59 const struct ip_vs_iphdr *iph, unsigned int proto_off, 59 const struct ip_vs_iphdr *iph, unsigned int proto_off,
60 int inverse) 60 int inverse)
61{ 61{
@@ -72,7 +72,7 @@ ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
72 IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for outin packet " 72 IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for outin packet "
73 "%s%s %s->%s\n", 73 "%s%s %s->%s\n",
74 inverse ? "ICMP+" : "", 74 inverse ? "ICMP+" : "",
75 pp->name, 75 ip_vs_proto_get(iph->protocol)->name,
76 IP_VS_DBG_ADDR(af, &iph->saddr), 76 IP_VS_DBG_ADDR(af, &iph->saddr),
77 IP_VS_DBG_ADDR(af, &iph->daddr)); 77 IP_VS_DBG_ADDR(af, &iph->daddr));
78 } 78 }
@@ -83,7 +83,6 @@ ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
83 83
84static struct ip_vs_conn * 84static struct ip_vs_conn *
85ah_esp_conn_out_get(int af, const struct sk_buff *skb, 85ah_esp_conn_out_get(int af, const struct sk_buff *skb,
86 struct ip_vs_protocol *pp,
87 const struct ip_vs_iphdr *iph, 86 const struct ip_vs_iphdr *iph,
88 unsigned int proto_off, 87 unsigned int proto_off,
89 int inverse) 88 int inverse)
@@ -97,7 +96,7 @@ ah_esp_conn_out_get(int af, const struct sk_buff *skb,
97 IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet " 96 IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet "
98 "%s%s %s->%s\n", 97 "%s%s %s->%s\n",
99 inverse ? "ICMP+" : "", 98 inverse ? "ICMP+" : "",
100 pp->name, 99 ip_vs_proto_get(iph->protocol)->name,
101 IP_VS_DBG_ADDR(af, &iph->saddr), 100 IP_VS_DBG_ADDR(af, &iph->saddr),
102 IP_VS_DBG_ADDR(af, &iph->daddr)); 101 IP_VS_DBG_ADDR(af, &iph->daddr));
103 } 102 }
@@ -107,7 +106,7 @@ ah_esp_conn_out_get(int af, const struct sk_buff *skb,
107 106
108 107
109static int 108static int
110ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, 109ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
111 int *verdict, struct ip_vs_conn **cpp) 110 int *verdict, struct ip_vs_conn **cpp)
112{ 111{
113 /* 112 /*
@@ -137,7 +136,6 @@ struct ip_vs_protocol ip_vs_protocol_ah = {
137 .app_conn_bind = NULL, 136 .app_conn_bind = NULL,
138 .debug_packet = ip_vs_tcpudp_debug_packet, 137 .debug_packet = ip_vs_tcpudp_debug_packet,
139 .timeout_change = NULL, /* ISAKMP */ 138 .timeout_change = NULL, /* ISAKMP */
140 .set_state_timeout = NULL,
141}; 139};
142#endif 140#endif
143 141
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index f826dd1e463..19bc37976ea 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -9,7 +9,7 @@
9#include <net/ip_vs.h> 9#include <net/ip_vs.h>
10 10
11static int 11static int
12sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, 12sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
13 int *verdict, struct ip_vs_conn **cpp) 13 int *verdict, struct ip_vs_conn **cpp)
14{ 14{
15 struct net *net; 15 struct net *net;
@@ -47,10 +47,10 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
47 * Let the virtual server select a real server for the 47 * Let the virtual server select a real server for the
48 * incoming connection, and create a connection entry. 48 * incoming connection, and create a connection entry.
49 */ 49 */
50 *cpp = ip_vs_schedule(svc, skb, pp, &ignored); 50 *cpp = ip_vs_schedule(svc, skb, pd, &ignored);
51 if (!*cpp && ignored <= 0) { 51 if (!*cpp && ignored <= 0) {
52 if (!ignored) 52 if (!ignored)
53 *verdict = ip_vs_leave(svc, skb, pp); 53 *verdict = ip_vs_leave(svc, skb, pd);
54 else { 54 else {
55 ip_vs_service_put(svc); 55 ip_vs_service_put(svc);
56 *verdict = NF_DROP; 56 *verdict = NF_DROP;
@@ -907,14 +907,13 @@ static const char *sctp_state_name(int state)
907} 907}
908 908
909static inline int 909static inline int
910set_sctp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp, 910set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
911 int direction, const struct sk_buff *skb) 911 int direction, const struct sk_buff *skb)
912{ 912{
913 sctp_chunkhdr_t _sctpch, *sch; 913 sctp_chunkhdr_t _sctpch, *sch;
914 unsigned char chunk_type; 914 unsigned char chunk_type;
915 int event, next_state; 915 int event, next_state;
916 int ihl; 916 int ihl;
917 struct ip_vs_proto_data *pd;
918 917
919#ifdef CONFIG_IP_VS_IPV6 918#ifdef CONFIG_IP_VS_IPV6
920 ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr); 919 ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
@@ -966,7 +965,7 @@ set_sctp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
966 965
967 IP_VS_DBG_BUF(8, "%s %s %s:%d->" 966 IP_VS_DBG_BUF(8, "%s %s %s:%d->"
968 "%s:%d state: %s->%s conn->refcnt:%d\n", 967 "%s:%d state: %s->%s conn->refcnt:%d\n",
969 pp->name, 968 pd->pp->name,
970 ((direction == IP_VS_DIR_OUTPUT) ? 969 ((direction == IP_VS_DIR_OUTPUT) ?
971 "output " : "input "), 970 "output " : "input "),
972 IP_VS_DBG_ADDR(cp->af, &cp->daddr), 971 IP_VS_DBG_ADDR(cp->af, &cp->daddr),
@@ -990,7 +989,6 @@ set_sctp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
990 } 989 }
991 } 990 }
992 } 991 }
993 pd = ip_vs_proto_data_get(&init_net, pp->protocol); /* tmp fix */
994 if (likely(pd)) 992 if (likely(pd))
995 cp->timeout = pd->timeout_table[cp->state = next_state]; 993 cp->timeout = pd->timeout_table[cp->state = next_state];
996 else /* What to do ? */ 994 else /* What to do ? */
@@ -1001,12 +999,12 @@ set_sctp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
1001 999
1002static int 1000static int
1003sctp_state_transition(struct ip_vs_conn *cp, int direction, 1001sctp_state_transition(struct ip_vs_conn *cp, int direction,
1004 const struct sk_buff *skb, struct ip_vs_protocol *pp) 1002 const struct sk_buff *skb, struct ip_vs_proto_data *pd)
1005{ 1003{
1006 int ret = 0; 1004 int ret = 0;
1007 1005
1008 spin_lock(&cp->lock); 1006 spin_lock(&cp->lock);
1009 ret = set_sctp_state(pp, cp, direction, skb); 1007 ret = set_sctp_state(pd, cp, direction, skb);
1010 spin_unlock(&cp->lock); 1008 spin_unlock(&cp->lock);
1011 1009
1012 return ret; 1010 return ret;
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index 9d9df3d6109..d7c24553279 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -32,7 +32,7 @@
32#include <net/ip_vs.h> 32#include <net/ip_vs.h>
33 33
34static int 34static int
35tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, 35tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
36 int *verdict, struct ip_vs_conn **cpp) 36 int *verdict, struct ip_vs_conn **cpp)
37{ 37{
38 struct net *net; 38 struct net *net;
@@ -68,10 +68,10 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
68 * Let the virtual server select a real server for the 68 * Let the virtual server select a real server for the
69 * incoming connection, and create a connection entry. 69 * incoming connection, and create a connection entry.
70 */ 70 */
71 *cpp = ip_vs_schedule(svc, skb, pp, &ignored); 71 *cpp = ip_vs_schedule(svc, skb, pd, &ignored);
72 if (!*cpp && ignored <= 0) { 72 if (!*cpp && ignored <= 0) {
73 if (!ignored) 73 if (!ignored)
74 *verdict = ip_vs_leave(svc, skb, pp); 74 *verdict = ip_vs_leave(svc, skb, pd);
75 else { 75 else {
76 ip_vs_service_put(svc); 76 ip_vs_service_put(svc);
77 *verdict = NF_DROP; 77 *verdict = NF_DROP;
@@ -448,10 +448,7 @@ static struct tcp_states_t tcp_states_dos [] = {
448/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sCL }}, 448/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sCL }},
449}; 449};
450 450
451static struct tcp_states_t *tcp_state_table = tcp_states; 451static void tcp_timeout_change(struct ip_vs_proto_data *pd, int flags)
452
453
454static void tcp_timeout_change(struct ip_vs_protocol *pp, int flags)
455{ 452{
456 int on = (flags & 1); /* secure_tcp */ 453 int on = (flags & 1); /* secure_tcp */
457 454
@@ -461,7 +458,7 @@ static void tcp_timeout_change(struct ip_vs_protocol *pp, int flags)
461 ** for most if not for all of the applications. Something 458 ** for most if not for all of the applications. Something
462 ** like "capabilities" (flags) for each object. 459 ** like "capabilities" (flags) for each object.
463 */ 460 */
464 tcp_state_table = (on? tcp_states_dos : tcp_states); 461 pd->tcp_state_table = (on ? tcp_states_dos : tcp_states);
465} 462}
466 463
467static inline int tcp_state_idx(struct tcphdr *th) 464static inline int tcp_state_idx(struct tcphdr *th)
@@ -478,13 +475,12 @@ static inline int tcp_state_idx(struct tcphdr *th)
478} 475}
479 476
480static inline void 477static inline void
481set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp, 478set_tcp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
482 int direction, struct tcphdr *th) 479 int direction, struct tcphdr *th)
483{ 480{
484 int state_idx; 481 int state_idx;
485 int new_state = IP_VS_TCP_S_CLOSE; 482 int new_state = IP_VS_TCP_S_CLOSE;
486 int state_off = tcp_state_off[direction]; 483 int state_off = tcp_state_off[direction];
487 struct ip_vs_proto_data *pd; /* Temp fix */
488 484
489 /* 485 /*
490 * Update state offset to INPUT_ONLY if necessary 486 * Update state offset to INPUT_ONLY if necessary
@@ -502,7 +498,8 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
502 goto tcp_state_out; 498 goto tcp_state_out;
503 } 499 }
504 500
505 new_state = tcp_state_table[state_off+state_idx].next_state[cp->state]; 501 new_state =
502 pd->tcp_state_table[state_off+state_idx].next_state[cp->state];
506 503
507 tcp_state_out: 504 tcp_state_out:
508 if (new_state != cp->state) { 505 if (new_state != cp->state) {
@@ -510,7 +507,7 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
510 507
511 IP_VS_DBG_BUF(8, "%s %s [%c%c%c%c] %s:%d->" 508 IP_VS_DBG_BUF(8, "%s %s [%c%c%c%c] %s:%d->"
512 "%s:%d state: %s->%s conn->refcnt:%d\n", 509 "%s:%d state: %s->%s conn->refcnt:%d\n",
513 pp->name, 510 pd->pp->name,
514 ((state_off == TCP_DIR_OUTPUT) ? 511 ((state_off == TCP_DIR_OUTPUT) ?
515 "output " : "input "), 512 "output " : "input "),
516 th->syn ? 'S' : '.', 513 th->syn ? 'S' : '.',
@@ -540,7 +537,6 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
540 } 537 }
541 } 538 }
542 539
543 pd = ip_vs_proto_data_get(&init_net, pp->protocol);
544 if (likely(pd)) 540 if (likely(pd))
545 cp->timeout = pd->timeout_table[cp->state = new_state]; 541 cp->timeout = pd->timeout_table[cp->state = new_state];
546 else /* What to do ? */ 542 else /* What to do ? */
@@ -553,7 +549,7 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
553static int 549static int
554tcp_state_transition(struct ip_vs_conn *cp, int direction, 550tcp_state_transition(struct ip_vs_conn *cp, int direction,
555 const struct sk_buff *skb, 551 const struct sk_buff *skb,
556 struct ip_vs_protocol *pp) 552 struct ip_vs_proto_data *pd)
557{ 553{
558 struct tcphdr _tcph, *th; 554 struct tcphdr _tcph, *th;
559 555
@@ -568,7 +564,7 @@ tcp_state_transition(struct ip_vs_conn *cp, int direction,
568 return 0; 564 return 0;
569 565
570 spin_lock(&cp->lock); 566 spin_lock(&cp->lock);
571 set_tcp_state(pp, cp, direction, th); 567 set_tcp_state(pd, cp, direction, th);
572 spin_unlock(&cp->lock); 568 spin_unlock(&cp->lock);
573 569
574 return 1; 570 return 1;
@@ -691,6 +687,7 @@ static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
691 spin_lock_init(&ipvs->tcp_app_lock); 687 spin_lock_init(&ipvs->tcp_app_lock);
692 pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts, 688 pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts,
693 sizeof(tcp_timeouts)); 689 sizeof(tcp_timeouts));
690 pd->tcp_state_table = tcp_states;
694} 691}
695 692
696static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd) 693static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd)
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index 71a4721a8f8..aa85df2f14a 100644
--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -29,7 +29,7 @@
29#include <net/ip6_checksum.h> 29#include <net/ip6_checksum.h>
30 30
31static int 31static int
32udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, 32udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
33 int *verdict, struct ip_vs_conn **cpp) 33 int *verdict, struct ip_vs_conn **cpp)
34{ 34{
35 struct net *net; 35 struct net *net;
@@ -64,10 +64,10 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
64 * Let the virtual server select a real server for the 64 * Let the virtual server select a real server for the
65 * incoming connection, and create a connection entry. 65 * incoming connection, and create a connection entry.
66 */ 66 */
67 *cpp = ip_vs_schedule(svc, skb, pp, &ignored); 67 *cpp = ip_vs_schedule(svc, skb, pd, &ignored);
68 if (!*cpp && ignored <= 0) { 68 if (!*cpp && ignored <= 0) {
69 if (!ignored) 69 if (!ignored)
70 *verdict = ip_vs_leave(svc, skb, pp); 70 *verdict = ip_vs_leave(svc, skb, pd);
71 else { 71 else {
72 ip_vs_service_put(svc); 72 ip_vs_service_put(svc);
73 *verdict = NF_DROP; 73 *verdict = NF_DROP;
@@ -457,11 +457,8 @@ static const char * udp_state_name(int state)
457static int 457static int
458udp_state_transition(struct ip_vs_conn *cp, int direction, 458udp_state_transition(struct ip_vs_conn *cp, int direction,
459 const struct sk_buff *skb, 459 const struct sk_buff *skb,
460 struct ip_vs_protocol *pp) 460 struct ip_vs_proto_data *pd)
461{ 461{
462 struct ip_vs_proto_data *pd; /* Temp fix, pp will be replaced by pd */
463
464 pd = ip_vs_proto_data_get(&init_net, IPPROTO_UDP);
465 if (unlikely(!pd)) { 462 if (unlikely(!pd)) {
466 pr_err("UDP no ns data\n"); 463 pr_err("UDP no ns data\n");
467 return 0; 464 return 0;
diff --git a/net/netfilter/xt_ipvs.c b/net/netfilter/xt_ipvs.c
index 9127a3d8aa3..bb10b0717f1 100644
--- a/net/netfilter/xt_ipvs.c
+++ b/net/netfilter/xt_ipvs.c
@@ -85,7 +85,7 @@ ipvs_mt(const struct sk_buff *skb, struct xt_action_param *par)
85 /* 85 /*
86 * Check if the packet belongs to an existing entry 86 * Check if the packet belongs to an existing entry
87 */ 87 */
88 cp = pp->conn_out_get(family, skb, pp, &iph, iph.len, 1 /* inverse */); 88 cp = pp->conn_out_get(family, skb, &iph, iph.len, 1 /* inverse */);
89 if (unlikely(cp == NULL)) { 89 if (unlikely(cp == NULL)) {
90 match = false; 90 match = false;
91 goto out; 91 goto out;