aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ipvs-sysctl.txt13
-rw-r--r--include/net/ip_vs.h84
-rw-r--r--include/net/net_namespace.h2
-rw-r--r--include/uapi/linux/ip_vs.h6
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h2
-rw-r--r--include/uapi/linux/netfilter/xt_socket.h7
-rw-r--r--kernel/sysctl_binary.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c12
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c4
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c21
-rw-r--r--net/netfilter/ipvs/ip_vs_dh.c10
-rw-r--r--net/netfilter/ipvs/ip_vs_lblc.c12
-rw-r--r--net/netfilter/ipvs/ip_vs_lblcr.c12
-rw-r--r--net/netfilter/ipvs/ip_vs_lc.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_nq.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_sctp.c860
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_tcp.c14
-rw-r--r--net/netfilter/ipvs/ip_vs_rr.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_sed.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_sh.c108
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c19
-rw-r--r--net/netfilter/ipvs/ip_vs_wlc.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_wrr.c3
-rw-r--r--net/netfilter/nf_conntrack_netlink.c30
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c6
-rw-r--r--net/netfilter/nfnetlink_cthelper.c16
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c6
-rw-r--r--net/netfilter/nfnetlink_queue_core.c16
-rw-r--r--net/netfilter/xt_socket.c70
29 files changed, 529 insertions, 820 deletions
diff --git a/Documentation/networking/ipvs-sysctl.txt b/Documentation/networking/ipvs-sysctl.txt
index 9573d0c48c6e..7a3c04729591 100644
--- a/Documentation/networking/ipvs-sysctl.txt
+++ b/Documentation/networking/ipvs-sysctl.txt
@@ -181,6 +181,19 @@ snat_reroute - BOOLEAN
181 always be the same as the original route so it is an optimisation 181 always be the same as the original route so it is an optimisation
182 to disable snat_reroute and avoid the recalculation. 182 to disable snat_reroute and avoid the recalculation.
183 183
184sync_persist_mode - INTEGER
185 default 0
186
187 Controls the synchronisation of connections when using persistence
188
189 0: All types of connections are synchronised
190 1: Attempt to reduce the synchronisation traffic depending on
191 the connection type. For persistent services avoid synchronisation
192 for normal connections, do it only for persistence templates.
193 In such case, for TCP and SCTP it may need enabling sloppy_tcp and
194 sloppy_sctp flags on backup servers. For non-persistent services
195 such optimization is not applied, mode 0 is assumed.
196
184sync_version - INTEGER 197sync_version - INTEGER
185 default 1 198 default 1
186 199
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 4405886980c7..f0d70f066f3d 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -197,31 +197,6 @@ ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr)
197 } 197 }
198} 198}
199 199
200/* This function is a faster version of ip_vs_fill_iph_skb().
201 * Where we only populate {s,d}addr (and avoid calling ipv6_find_hdr()).
202 * This is used by the some of the ip_vs_*_schedule() functions.
203 * (Mostly done to avoid ABI breakage of external schedulers)
204 */
205static inline void
206ip_vs_fill_iph_addr_only(int af, const struct sk_buff *skb,
207 struct ip_vs_iphdr *iphdr)
208{
209#ifdef CONFIG_IP_VS_IPV6
210 if (af == AF_INET6) {
211 const struct ipv6hdr *iph =
212 (struct ipv6hdr *)skb_network_header(skb);
213 iphdr->saddr.in6 = iph->saddr;
214 iphdr->daddr.in6 = iph->daddr;
215 } else
216#endif
217 {
218 const struct iphdr *iph =
219 (struct iphdr *)skb_network_header(skb);
220 iphdr->saddr.ip = iph->saddr;
221 iphdr->daddr.ip = iph->daddr;
222 }
223}
224
225static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst, 200static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst,
226 const union nf_inet_addr *src) 201 const union nf_inet_addr *src)
227{ 202{
@@ -405,17 +380,18 @@ enum {
405 */ 380 */
406enum ip_vs_sctp_states { 381enum ip_vs_sctp_states {
407 IP_VS_SCTP_S_NONE, 382 IP_VS_SCTP_S_NONE,
408 IP_VS_SCTP_S_INIT_CLI, 383 IP_VS_SCTP_S_INIT1,
409 IP_VS_SCTP_S_INIT_SER, 384 IP_VS_SCTP_S_INIT,
410 IP_VS_SCTP_S_INIT_ACK_CLI, 385 IP_VS_SCTP_S_COOKIE_SENT,
411 IP_VS_SCTP_S_INIT_ACK_SER, 386 IP_VS_SCTP_S_COOKIE_REPLIED,
412 IP_VS_SCTP_S_ECHO_CLI, 387 IP_VS_SCTP_S_COOKIE_WAIT,
413 IP_VS_SCTP_S_ECHO_SER, 388 IP_VS_SCTP_S_COOKIE,
389 IP_VS_SCTP_S_COOKIE_ECHOED,
414 IP_VS_SCTP_S_ESTABLISHED, 390 IP_VS_SCTP_S_ESTABLISHED,
415 IP_VS_SCTP_S_SHUT_CLI, 391 IP_VS_SCTP_S_SHUTDOWN_SENT,
416 IP_VS_SCTP_S_SHUT_SER, 392 IP_VS_SCTP_S_SHUTDOWN_RECEIVED,
417 IP_VS_SCTP_S_SHUT_ACK_CLI, 393 IP_VS_SCTP_S_SHUTDOWN_ACK_SENT,
418 IP_VS_SCTP_S_SHUT_ACK_SER, 394 IP_VS_SCTP_S_REJECTED,
419 IP_VS_SCTP_S_CLOSED, 395 IP_VS_SCTP_S_CLOSED,
420 IP_VS_SCTP_S_LAST 396 IP_VS_SCTP_S_LAST
421}; 397};
@@ -814,7 +790,8 @@ struct ip_vs_scheduler {
814 790
815 /* selecting a server from the given service */ 791 /* selecting a server from the given service */
816 struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc, 792 struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc,
817 const struct sk_buff *skb); 793 const struct sk_buff *skb,
794 struct ip_vs_iphdr *iph);
818}; 795};
819 796
820/* The persistence engine object */ 797/* The persistence engine object */
@@ -998,10 +975,13 @@ struct netns_ipvs {
998 int sysctl_snat_reroute; 975 int sysctl_snat_reroute;
999 int sysctl_sync_ver; 976 int sysctl_sync_ver;
1000 int sysctl_sync_ports; 977 int sysctl_sync_ports;
978 int sysctl_sync_persist_mode;
1001 unsigned long sysctl_sync_qlen_max; 979 unsigned long sysctl_sync_qlen_max;
1002 int sysctl_sync_sock_size; 980 int sysctl_sync_sock_size;
1003 int sysctl_cache_bypass; 981 int sysctl_cache_bypass;
1004 int sysctl_expire_nodest_conn; 982 int sysctl_expire_nodest_conn;
983 int sysctl_sloppy_tcp;
984 int sysctl_sloppy_sctp;
1005 int sysctl_expire_quiescent_template; 985 int sysctl_expire_quiescent_template;
1006 int sysctl_sync_threshold[2]; 986 int sysctl_sync_threshold[2];
1007 unsigned int sysctl_sync_refresh_period; 987 unsigned int sysctl_sync_refresh_period;
@@ -1044,6 +1024,8 @@ struct netns_ipvs {
1044#define DEFAULT_SYNC_THRESHOLD 3 1024#define DEFAULT_SYNC_THRESHOLD 3
1045#define DEFAULT_SYNC_PERIOD 50 1025#define DEFAULT_SYNC_PERIOD 50
1046#define DEFAULT_SYNC_VER 1 1026#define DEFAULT_SYNC_VER 1
1027#define DEFAULT_SLOPPY_TCP 0
1028#define DEFAULT_SLOPPY_SCTP 0
1047#define DEFAULT_SYNC_REFRESH_PERIOD (0U * HZ) 1029#define DEFAULT_SYNC_REFRESH_PERIOD (0U * HZ)
1048#define DEFAULT_SYNC_RETRIES 0 1030#define DEFAULT_SYNC_RETRIES 0
1049#define IPVS_SYNC_WAKEUP_RATE 8 1031#define IPVS_SYNC_WAKEUP_RATE 8
@@ -1080,11 +1062,26 @@ static inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
1080 return ipvs->sysctl_sync_ver; 1062 return ipvs->sysctl_sync_ver;
1081} 1063}
1082 1064
1065static inline int sysctl_sloppy_tcp(struct netns_ipvs *ipvs)
1066{
1067 return ipvs->sysctl_sloppy_tcp;
1068}
1069
1070static inline int sysctl_sloppy_sctp(struct netns_ipvs *ipvs)
1071{
1072 return ipvs->sysctl_sloppy_sctp;
1073}
1074
1083static inline int sysctl_sync_ports(struct netns_ipvs *ipvs) 1075static inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
1084{ 1076{
1085 return ACCESS_ONCE(ipvs->sysctl_sync_ports); 1077 return ACCESS_ONCE(ipvs->sysctl_sync_ports);
1086} 1078}
1087 1079
1080static inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs)
1081{
1082 return ipvs->sysctl_sync_persist_mode;
1083}
1084
1088static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs) 1085static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
1089{ 1086{
1090 return ipvs->sysctl_sync_qlen_max; 1087 return ipvs->sysctl_sync_qlen_max;
@@ -1133,11 +1130,26 @@ static inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
1133 return DEFAULT_SYNC_VER; 1130 return DEFAULT_SYNC_VER;
1134} 1131}
1135 1132
1133static inline int sysctl_sloppy_tcp(struct netns_ipvs *ipvs)
1134{
1135 return DEFAULT_SLOPPY_TCP;
1136}
1137
1138static inline int sysctl_sloppy_sctp(struct netns_ipvs *ipvs)
1139{
1140 return DEFAULT_SLOPPY_SCTP;
1141}
1142
1136static inline int sysctl_sync_ports(struct netns_ipvs *ipvs) 1143static inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
1137{ 1144{
1138 return 1; 1145 return 1;
1139} 1146}
1140 1147
1148static inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs)
1149{
1150 return 0;
1151}
1152
1141static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs) 1153static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
1142{ 1154{
1143 return IPVS_SYNC_QLEN_MAX; 1155 return IPVS_SYNC_QLEN_MAX;
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 495bc57f292c..84e37b1ca9e1 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -115,7 +115,9 @@ struct net {
115#ifdef CONFIG_XFRM 115#ifdef CONFIG_XFRM
116 struct netns_xfrm xfrm; 116 struct netns_xfrm xfrm;
117#endif 117#endif
118#if IS_ENABLED(CONFIG_IP_VS)
118 struct netns_ipvs *ipvs; 119 struct netns_ipvs *ipvs;
120#endif
119 struct sock *diag_nlsk; 121 struct sock *diag_nlsk;
120 atomic_t rt_genid; 122 atomic_t rt_genid;
121 atomic_t fnhe_genid; 123 atomic_t fnhe_genid;
diff --git a/include/uapi/linux/ip_vs.h b/include/uapi/linux/ip_vs.h
index a24537725e80..29458223d044 100644
--- a/include/uapi/linux/ip_vs.h
+++ b/include/uapi/linux/ip_vs.h
@@ -20,6 +20,12 @@
20#define IP_VS_SVC_F_PERSISTENT 0x0001 /* persistent port */ 20#define IP_VS_SVC_F_PERSISTENT 0x0001 /* persistent port */
21#define IP_VS_SVC_F_HASHED 0x0002 /* hashed entry */ 21#define IP_VS_SVC_F_HASHED 0x0002 /* hashed entry */
22#define IP_VS_SVC_F_ONEPACKET 0x0004 /* one-packet scheduling */ 22#define IP_VS_SVC_F_ONEPACKET 0x0004 /* one-packet scheduling */
23#define IP_VS_SVC_F_SCHED1 0x0008 /* scheduler flag 1 */
24#define IP_VS_SVC_F_SCHED2 0x0010 /* scheduler flag 2 */
25#define IP_VS_SVC_F_SCHED3 0x0020 /* scheduler flag 3 */
26
27#define IP_VS_SVC_F_SCHED_SH_FALLBACK IP_VS_SVC_F_SCHED1 /* SH fallback */
28#define IP_VS_SVC_F_SCHED_SH_PORT IP_VS_SVC_F_SCHED2 /* SH use port */
23 29
24/* 30/*
25 * Destination Server Flags 31 * Destination Server Flags
diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
index a2308ae5a73d..3a9b92147339 100644
--- a/include/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/include/uapi/linux/netfilter/nfnetlink_queue.h
@@ -105,5 +105,7 @@ enum nfqnl_attr_config {
105#define NFQA_SKB_CSUMNOTREADY (1 << 0) 105#define NFQA_SKB_CSUMNOTREADY (1 << 0)
106/* packet is GSO (i.e., exceeds device mtu) */ 106/* packet is GSO (i.e., exceeds device mtu) */
107#define NFQA_SKB_GSO (1 << 1) 107#define NFQA_SKB_GSO (1 << 1)
108/* csum not validated (incoming device doesn't support hw checksum, etc.) */
109#define NFQA_SKB_CSUM_NOTVERIFIED (1 << 2)
108 110
109#endif /* _NFNETLINK_QUEUE_H */ 111#endif /* _NFNETLINK_QUEUE_H */
diff --git a/include/uapi/linux/netfilter/xt_socket.h b/include/uapi/linux/netfilter/xt_socket.h
index 26d7217bd4f1..6315e2ac3474 100644
--- a/include/uapi/linux/netfilter/xt_socket.h
+++ b/include/uapi/linux/netfilter/xt_socket.h
@@ -5,10 +5,17 @@
5 5
6enum { 6enum {
7 XT_SOCKET_TRANSPARENT = 1 << 0, 7 XT_SOCKET_TRANSPARENT = 1 << 0,
8 XT_SOCKET_NOWILDCARD = 1 << 1,
8}; 9};
9 10
10struct xt_socket_mtinfo1 { 11struct xt_socket_mtinfo1 {
11 __u8 flags; 12 __u8 flags;
12}; 13};
14#define XT_SOCKET_FLAGS_V1 XT_SOCKET_TRANSPARENT
15
16struct xt_socket_mtinfo2 {
17 __u8 flags;
18};
19#define XT_SOCKET_FLAGS_V2 (XT_SOCKET_TRANSPARENT | XT_SOCKET_NOWILDCARD)
13 20
14#endif /* _XT_SOCKET_H */ 21#endif /* _XT_SOCKET_H */
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
index aea4a9ea6fc8..b609213ca9a2 100644
--- a/kernel/sysctl_binary.c
+++ b/kernel/sysctl_binary.c
@@ -3,7 +3,6 @@
3#include "../fs/xfs/xfs_sysctl.h" 3#include "../fs/xfs/xfs_sysctl.h"
4#include <linux/sunrpc/debug.h> 4#include <linux/sunrpc/debug.h>
5#include <linux/string.h> 5#include <linux/string.h>
6#include <net/ip_vs.h>
7#include <linux/syscalls.h> 6#include <linux/syscalls.h>
8#include <linux/namei.h> 7#include <linux/namei.h>
9#include <linux/mount.h> 8#include <linux/mount.h>
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index c8c52a98590b..4c8e5c0aa1ab 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1231,6 +1231,18 @@ void ip_vs_random_dropentry(struct net *net)
1231 default: 1231 default:
1232 continue; 1232 continue;
1233 } 1233 }
1234 } else if (cp->protocol == IPPROTO_SCTP) {
1235 switch (cp->state) {
1236 case IP_VS_SCTP_S_INIT1:
1237 case IP_VS_SCTP_S_INIT:
1238 break;
1239 case IP_VS_SCTP_S_ESTABLISHED:
1240 if (todrop_entry(cp))
1241 break;
1242 continue;
1243 default:
1244 continue;
1245 }
1234 } else { 1246 } else {
1235 if (!todrop_entry(cp)) 1247 if (!todrop_entry(cp))
1236 continue; 1248 continue;
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 05565d2b3a61..e9b0330f220d 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -305,7 +305,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
305 * return *ignored=0 i.e. ICMP and NF_DROP 305 * return *ignored=0 i.e. ICMP and NF_DROP
306 */ 306 */
307 sched = rcu_dereference(svc->scheduler); 307 sched = rcu_dereference(svc->scheduler);
308 dest = sched->schedule(svc, skb); 308 dest = sched->schedule(svc, skb, iph);
309 if (!dest) { 309 if (!dest) {
310 IP_VS_DBG(1, "p-schedule: no dest found.\n"); 310 IP_VS_DBG(1, "p-schedule: no dest found.\n");
311 kfree(param.pe_data); 311 kfree(param.pe_data);
@@ -452,7 +452,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
452 } 452 }
453 453
454 sched = rcu_dereference(svc->scheduler); 454 sched = rcu_dereference(svc->scheduler);
455 dest = sched->schedule(svc, skb); 455 dest = sched->schedule(svc, skb, iph);
456 if (dest == NULL) { 456 if (dest == NULL) {
457 IP_VS_DBG(1, "Schedule: no dest found.\n"); 457 IP_VS_DBG(1, "Schedule: no dest found.\n");
458 return NULL; 458 return NULL;
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 47e510819f54..c8148e487386 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1715,6 +1715,12 @@ static struct ctl_table vs_vars[] = {
1715 .proc_handler = &proc_do_sync_ports, 1715 .proc_handler = &proc_do_sync_ports,
1716 }, 1716 },
1717 { 1717 {
1718 .procname = "sync_persist_mode",
1719 .maxlen = sizeof(int),
1720 .mode = 0644,
1721 .proc_handler = proc_dointvec,
1722 },
1723 {
1718 .procname = "sync_qlen_max", 1724 .procname = "sync_qlen_max",
1719 .maxlen = sizeof(unsigned long), 1725 .maxlen = sizeof(unsigned long),
1720 .mode = 0644, 1726 .mode = 0644,
@@ -1739,6 +1745,18 @@ static struct ctl_table vs_vars[] = {
1739 .proc_handler = proc_dointvec, 1745 .proc_handler = proc_dointvec,
1740 }, 1746 },
1741 { 1747 {
1748 .procname = "sloppy_tcp",
1749 .maxlen = sizeof(int),
1750 .mode = 0644,
1751 .proc_handler = proc_dointvec,
1752 },
1753 {
1754 .procname = "sloppy_sctp",
1755 .maxlen = sizeof(int),
1756 .mode = 0644,
1757 .proc_handler = proc_dointvec,
1758 },
1759 {
1742 .procname = "expire_quiescent_template", 1760 .procname = "expire_quiescent_template",
1743 .maxlen = sizeof(int), 1761 .maxlen = sizeof(int),
1744 .mode = 0644, 1762 .mode = 0644,
@@ -3717,12 +3735,15 @@ static int __net_init ip_vs_control_net_init_sysctl(struct net *net)
3717 tbl[idx++].data = &ipvs->sysctl_sync_ver; 3735 tbl[idx++].data = &ipvs->sysctl_sync_ver;
3718 ipvs->sysctl_sync_ports = 1; 3736 ipvs->sysctl_sync_ports = 1;
3719 tbl[idx++].data = &ipvs->sysctl_sync_ports; 3737 tbl[idx++].data = &ipvs->sysctl_sync_ports;
3738 tbl[idx++].data = &ipvs->sysctl_sync_persist_mode;
3720 ipvs->sysctl_sync_qlen_max = nr_free_buffer_pages() / 32; 3739 ipvs->sysctl_sync_qlen_max = nr_free_buffer_pages() / 32;
3721 tbl[idx++].data = &ipvs->sysctl_sync_qlen_max; 3740 tbl[idx++].data = &ipvs->sysctl_sync_qlen_max;
3722 ipvs->sysctl_sync_sock_size = 0; 3741 ipvs->sysctl_sync_sock_size = 0;
3723 tbl[idx++].data = &ipvs->sysctl_sync_sock_size; 3742 tbl[idx++].data = &ipvs->sysctl_sync_sock_size;
3724 tbl[idx++].data = &ipvs->sysctl_cache_bypass; 3743 tbl[idx++].data = &ipvs->sysctl_cache_bypass;
3725 tbl[idx++].data = &ipvs->sysctl_expire_nodest_conn; 3744 tbl[idx++].data = &ipvs->sysctl_expire_nodest_conn;
3745 tbl[idx++].data = &ipvs->sysctl_sloppy_tcp;
3746 tbl[idx++].data = &ipvs->sysctl_sloppy_sctp;
3726 tbl[idx++].data = &ipvs->sysctl_expire_quiescent_template; 3747 tbl[idx++].data = &ipvs->sysctl_expire_quiescent_template;
3727 ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD; 3748 ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD;
3728 ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD; 3749 ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD;
diff --git a/net/netfilter/ipvs/ip_vs_dh.c b/net/netfilter/ipvs/ip_vs_dh.c
index ccab120df45e..c3b84546ea9e 100644
--- a/net/netfilter/ipvs/ip_vs_dh.c
+++ b/net/netfilter/ipvs/ip_vs_dh.c
@@ -214,18 +214,16 @@ static inline int is_overloaded(struct ip_vs_dest *dest)
214 * Destination hashing scheduling 214 * Destination hashing scheduling
215 */ 215 */
216static struct ip_vs_dest * 216static struct ip_vs_dest *
217ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 217ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
218 struct ip_vs_iphdr *iph)
218{ 219{
219 struct ip_vs_dest *dest; 220 struct ip_vs_dest *dest;
220 struct ip_vs_dh_state *s; 221 struct ip_vs_dh_state *s;
221 struct ip_vs_iphdr iph;
222
223 ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
224 222
225 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); 223 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
226 224
227 s = (struct ip_vs_dh_state *) svc->sched_data; 225 s = (struct ip_vs_dh_state *) svc->sched_data;
228 dest = ip_vs_dh_get(svc->af, s, &iph.daddr); 226 dest = ip_vs_dh_get(svc->af, s, &iph->daddr);
229 if (!dest 227 if (!dest
230 || !(dest->flags & IP_VS_DEST_F_AVAILABLE) 228 || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
231 || atomic_read(&dest->weight) <= 0 229 || atomic_read(&dest->weight) <= 0
@@ -235,7 +233,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
235 } 233 }
236 234
237 IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n", 235 IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n",
238 IP_VS_DBG_ADDR(svc->af, &iph.daddr), 236 IP_VS_DBG_ADDR(svc->af, &iph->daddr),
239 IP_VS_DBG_ADDR(svc->af, &dest->addr), 237 IP_VS_DBG_ADDR(svc->af, &dest->addr),
240 ntohs(dest->port)); 238 ntohs(dest->port));
241 239
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 44595b8ae37f..1383b0eadc0e 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -487,19 +487,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
487 * Locality-Based (weighted) Least-Connection scheduling 487 * Locality-Based (weighted) Least-Connection scheduling
488 */ 488 */
489static struct ip_vs_dest * 489static struct ip_vs_dest *
490ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 490ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
491 struct ip_vs_iphdr *iph)
491{ 492{
492 struct ip_vs_lblc_table *tbl = svc->sched_data; 493 struct ip_vs_lblc_table *tbl = svc->sched_data;
493 struct ip_vs_iphdr iph;
494 struct ip_vs_dest *dest = NULL; 494 struct ip_vs_dest *dest = NULL;
495 struct ip_vs_lblc_entry *en; 495 struct ip_vs_lblc_entry *en;
496 496
497 ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
498
499 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); 497 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
500 498
501 /* First look in our cache */ 499 /* First look in our cache */
502 en = ip_vs_lblc_get(svc->af, tbl, &iph.daddr); 500 en = ip_vs_lblc_get(svc->af, tbl, &iph->daddr);
503 if (en) { 501 if (en) {
504 /* We only hold a read lock, but this is atomic */ 502 /* We only hold a read lock, but this is atomic */
505 en->lastuse = jiffies; 503 en->lastuse = jiffies;
@@ -529,12 +527,12 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
529 /* If we fail to create a cache entry, we'll just use the valid dest */ 527 /* If we fail to create a cache entry, we'll just use the valid dest */
530 spin_lock_bh(&svc->sched_lock); 528 spin_lock_bh(&svc->sched_lock);
531 if (!tbl->dead) 529 if (!tbl->dead)
532 ip_vs_lblc_new(tbl, &iph.daddr, dest); 530 ip_vs_lblc_new(tbl, &iph->daddr, dest);
533 spin_unlock_bh(&svc->sched_lock); 531 spin_unlock_bh(&svc->sched_lock);
534 532
535out: 533out:
536 IP_VS_DBG_BUF(6, "LBLC: destination IP address %s --> server %s:%d\n", 534 IP_VS_DBG_BUF(6, "LBLC: destination IP address %s --> server %s:%d\n",
537 IP_VS_DBG_ADDR(svc->af, &iph.daddr), 535 IP_VS_DBG_ADDR(svc->af, &iph->daddr),
538 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port)); 536 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
539 537
540 return dest; 538 return dest;
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index 876937db0bf4..3cd85b2fc67c 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -655,19 +655,17 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
655 * Locality-Based (weighted) Least-Connection scheduling 655 * Locality-Based (weighted) Least-Connection scheduling
656 */ 656 */
657static struct ip_vs_dest * 657static struct ip_vs_dest *
658ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 658ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
659 struct ip_vs_iphdr *iph)
659{ 660{
660 struct ip_vs_lblcr_table *tbl = svc->sched_data; 661 struct ip_vs_lblcr_table *tbl = svc->sched_data;
661 struct ip_vs_iphdr iph;
662 struct ip_vs_dest *dest; 662 struct ip_vs_dest *dest;
663 struct ip_vs_lblcr_entry *en; 663 struct ip_vs_lblcr_entry *en;
664 664
665 ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
666
667 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); 665 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
668 666
669 /* First look in our cache */ 667 /* First look in our cache */
670 en = ip_vs_lblcr_get(svc->af, tbl, &iph.daddr); 668 en = ip_vs_lblcr_get(svc->af, tbl, &iph->daddr);
671 if (en) { 669 if (en) {
672 en->lastuse = jiffies; 670 en->lastuse = jiffies;
673 671
@@ -718,12 +716,12 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
718 /* If we fail to create a cache entry, we'll just use the valid dest */ 716 /* If we fail to create a cache entry, we'll just use the valid dest */
719 spin_lock_bh(&svc->sched_lock); 717 spin_lock_bh(&svc->sched_lock);
720 if (!tbl->dead) 718 if (!tbl->dead)
721 ip_vs_lblcr_new(tbl, &iph.daddr, dest); 719 ip_vs_lblcr_new(tbl, &iph->daddr, dest);
722 spin_unlock_bh(&svc->sched_lock); 720 spin_unlock_bh(&svc->sched_lock);
723 721
724out: 722out:
725 IP_VS_DBG_BUF(6, "LBLCR: destination IP address %s --> server %s:%d\n", 723 IP_VS_DBG_BUF(6, "LBLCR: destination IP address %s --> server %s:%d\n",
726 IP_VS_DBG_ADDR(svc->af, &iph.daddr), 724 IP_VS_DBG_ADDR(svc->af, &iph->daddr),
727 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port)); 725 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
728 726
729 return dest; 727 return dest;
diff --git a/net/netfilter/ipvs/ip_vs_lc.c b/net/netfilter/ipvs/ip_vs_lc.c
index 5128e338a749..2bdcb1cf2127 100644
--- a/net/netfilter/ipvs/ip_vs_lc.c
+++ b/net/netfilter/ipvs/ip_vs_lc.c
@@ -26,7 +26,8 @@
26 * Least Connection scheduling 26 * Least Connection scheduling
27 */ 27 */
28static struct ip_vs_dest * 28static struct ip_vs_dest *
29ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 29ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
30 struct ip_vs_iphdr *iph)
30{ 31{
31 struct ip_vs_dest *dest, *least = NULL; 32 struct ip_vs_dest *dest, *least = NULL;
32 unsigned int loh = 0, doh; 33 unsigned int loh = 0, doh;
diff --git a/net/netfilter/ipvs/ip_vs_nq.c b/net/netfilter/ipvs/ip_vs_nq.c
index 646cfd4baa73..d8d9860934fe 100644
--- a/net/netfilter/ipvs/ip_vs_nq.c
+++ b/net/netfilter/ipvs/ip_vs_nq.c
@@ -55,7 +55,8 @@ ip_vs_nq_dest_overhead(struct ip_vs_dest *dest)
55 * Weighted Least Connection scheduling 55 * Weighted Least Connection scheduling
56 */ 56 */
57static struct ip_vs_dest * 57static struct ip_vs_dest *
58ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 58ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
59 struct ip_vs_iphdr *iph)
59{ 60{
60 struct ip_vs_dest *dest, *least = NULL; 61 struct ip_vs_dest *dest, *least = NULL;
61 unsigned int loh = 0, doh; 62 unsigned int loh = 0, doh;
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index 86464881cd20..3c0da8728036 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -15,6 +15,7 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
15{ 15{
16 struct net *net; 16 struct net *net;
17 struct ip_vs_service *svc; 17 struct ip_vs_service *svc;
18 struct netns_ipvs *ipvs;
18 sctp_chunkhdr_t _schunkh, *sch; 19 sctp_chunkhdr_t _schunkh, *sch;
19 sctp_sctphdr_t *sh, _sctph; 20 sctp_sctphdr_t *sh, _sctph;
20 21
@@ -27,13 +28,14 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
27 if (sch == NULL) 28 if (sch == NULL)
28 return 0; 29 return 0;
29 net = skb_net(skb); 30 net = skb_net(skb);
31 ipvs = net_ipvs(net);
30 rcu_read_lock(); 32 rcu_read_lock();
31 if ((sch->type == SCTP_CID_INIT) && 33 if ((sch->type == SCTP_CID_INIT || sysctl_sloppy_sctp(ipvs)) &&
32 (svc = ip_vs_service_find(net, af, skb->mark, iph->protocol, 34 (svc = ip_vs_service_find(net, af, skb->mark, iph->protocol,
33 &iph->daddr, sh->dest))) { 35 &iph->daddr, sh->dest))) {
34 int ignored; 36 int ignored;
35 37
36 if (ip_vs_todrop(net_ipvs(net))) { 38 if (ip_vs_todrop(ipvs)) {
37 /* 39 /*
38 * It seems that we are very loaded. 40 * It seems that we are very loaded.
39 * We have to drop this packet :( 41 * We have to drop this packet :(
@@ -183,710 +185,159 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
183 return 1; 185 return 1;
184} 186}
185 187
186struct ipvs_sctp_nextstate {
187 int next_state;
188};
189enum ipvs_sctp_event_t { 188enum ipvs_sctp_event_t {
190 IP_VS_SCTP_EVE_DATA_CLI, 189 IP_VS_SCTP_DATA = 0, /* DATA, SACK, HEARTBEATs */
191 IP_VS_SCTP_EVE_DATA_SER, 190 IP_VS_SCTP_INIT,
192 IP_VS_SCTP_EVE_INIT_CLI, 191 IP_VS_SCTP_INIT_ACK,
193 IP_VS_SCTP_EVE_INIT_SER, 192 IP_VS_SCTP_COOKIE_ECHO,
194 IP_VS_SCTP_EVE_INIT_ACK_CLI, 193 IP_VS_SCTP_COOKIE_ACK,
195 IP_VS_SCTP_EVE_INIT_ACK_SER, 194 IP_VS_SCTP_SHUTDOWN,
196 IP_VS_SCTP_EVE_COOKIE_ECHO_CLI, 195 IP_VS_SCTP_SHUTDOWN_ACK,
197 IP_VS_SCTP_EVE_COOKIE_ECHO_SER, 196 IP_VS_SCTP_SHUTDOWN_COMPLETE,
198 IP_VS_SCTP_EVE_COOKIE_ACK_CLI, 197 IP_VS_SCTP_ERROR,
199 IP_VS_SCTP_EVE_COOKIE_ACK_SER, 198 IP_VS_SCTP_ABORT,
200 IP_VS_SCTP_EVE_ABORT_CLI, 199 IP_VS_SCTP_EVENT_LAST
201 IP_VS_SCTP_EVE__ABORT_SER,
202 IP_VS_SCTP_EVE_SHUT_CLI,
203 IP_VS_SCTP_EVE_SHUT_SER,
204 IP_VS_SCTP_EVE_SHUT_ACK_CLI,
205 IP_VS_SCTP_EVE_SHUT_ACK_SER,
206 IP_VS_SCTP_EVE_SHUT_COM_CLI,
207 IP_VS_SCTP_EVE_SHUT_COM_SER,
208 IP_VS_SCTP_EVE_LAST
209}; 200};
210 201
211static enum ipvs_sctp_event_t sctp_events[256] = { 202/* RFC 2960, 3.2 Chunk Field Descriptions */
212 IP_VS_SCTP_EVE_DATA_CLI, 203static __u8 sctp_events[] = {
213 IP_VS_SCTP_EVE_INIT_CLI, 204 [SCTP_CID_DATA] = IP_VS_SCTP_DATA,
214 IP_VS_SCTP_EVE_INIT_ACK_CLI, 205 [SCTP_CID_INIT] = IP_VS_SCTP_INIT,
215 IP_VS_SCTP_EVE_DATA_CLI, 206 [SCTP_CID_INIT_ACK] = IP_VS_SCTP_INIT_ACK,
216 IP_VS_SCTP_EVE_DATA_CLI, 207 [SCTP_CID_SACK] = IP_VS_SCTP_DATA,
217 IP_VS_SCTP_EVE_DATA_CLI, 208 [SCTP_CID_HEARTBEAT] = IP_VS_SCTP_DATA,
218 IP_VS_SCTP_EVE_ABORT_CLI, 209 [SCTP_CID_HEARTBEAT_ACK] = IP_VS_SCTP_DATA,
219 IP_VS_SCTP_EVE_SHUT_CLI, 210 [SCTP_CID_ABORT] = IP_VS_SCTP_ABORT,
220 IP_VS_SCTP_EVE_SHUT_ACK_CLI, 211 [SCTP_CID_SHUTDOWN] = IP_VS_SCTP_SHUTDOWN,
221 IP_VS_SCTP_EVE_DATA_CLI, 212 [SCTP_CID_SHUTDOWN_ACK] = IP_VS_SCTP_SHUTDOWN_ACK,
222 IP_VS_SCTP_EVE_COOKIE_ECHO_CLI, 213 [SCTP_CID_ERROR] = IP_VS_SCTP_ERROR,
223 IP_VS_SCTP_EVE_COOKIE_ACK_CLI, 214 [SCTP_CID_COOKIE_ECHO] = IP_VS_SCTP_COOKIE_ECHO,
224 IP_VS_SCTP_EVE_DATA_CLI, 215 [SCTP_CID_COOKIE_ACK] = IP_VS_SCTP_COOKIE_ACK,
225 IP_VS_SCTP_EVE_DATA_CLI, 216 [SCTP_CID_ECN_ECNE] = IP_VS_SCTP_DATA,
226 IP_VS_SCTP_EVE_SHUT_COM_CLI, 217 [SCTP_CID_ECN_CWR] = IP_VS_SCTP_DATA,
218 [SCTP_CID_SHUTDOWN_COMPLETE] = IP_VS_SCTP_SHUTDOWN_COMPLETE,
227}; 219};
228 220
229static struct ipvs_sctp_nextstate 221/* SCTP States:
230 sctp_states_table[IP_VS_SCTP_S_LAST][IP_VS_SCTP_EVE_LAST] = { 222 * See RFC 2960, 4. SCTP Association State Diagram
231 /* 223 *
232 * STATE : IP_VS_SCTP_S_NONE 224 * New states (not in diagram):
233 */ 225 * - INIT1 state: use shorter timeout for dropped INIT packets
234 /*next state *//*event */ 226 * - REJECTED state: use shorter timeout if INIT is rejected with ABORT
235 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ }, 227 * - INIT, COOKIE_SENT, COOKIE_REPLIED, COOKIE states: for better debugging
236 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ }, 228 *
237 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ }, 229 * The states are as seen in real server. In the diagram, INIT1, INIT,
238 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ }, 230 * COOKIE_SENT and COOKIE_REPLIED processing happens in CLOSED state.
239 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ }, 231 *
240 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ }, 232 * States as per packets from client (C) and server (S):
241 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ }, 233 *
242 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ }, 234 * Setup of client connection:
243 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ }, 235 * IP_VS_SCTP_S_INIT1: First C:INIT sent, wait for S:INIT-ACK
244 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ }, 236 * IP_VS_SCTP_S_INIT: Next C:INIT sent, wait for S:INIT-ACK
245 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ }, 237 * IP_VS_SCTP_S_COOKIE_SENT: S:INIT-ACK sent, wait for C:COOKIE-ECHO
246 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ }, 238 * IP_VS_SCTP_S_COOKIE_REPLIED: C:COOKIE-ECHO sent, wait for S:COOKIE-ACK
247 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ }, 239 *
248 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ }, 240 * Setup of server connection:
249 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ }, 241 * IP_VS_SCTP_S_COOKIE_WAIT: S:INIT sent, wait for C:INIT-ACK
250 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ }, 242 * IP_VS_SCTP_S_COOKIE: C:INIT-ACK sent, wait for S:COOKIE-ECHO
251 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ }, 243 * IP_VS_SCTP_S_COOKIE_ECHOED: S:COOKIE-ECHO sent, wait for C:COOKIE-ACK
252 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }, 244 */
253 },
254 /*
255 * STATE : IP_VS_SCTP_S_INIT_CLI
256 * Cient sent INIT and is waiting for reply from server(In ECHO_WAIT)
257 */
258 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
259 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
260 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
261 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
262 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
263 {IP_VS_SCTP_S_INIT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
264 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ECHO_CLI */ },
265 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_ECHO_SER */ },
266 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
267 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
268 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
269 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
270 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
271 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
272 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
273 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
274 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
275 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
276 },
277 /*
278 * State : IP_VS_SCTP_S_INIT_SER
279 * Server sent INIT and waiting for INIT ACK from the client
280 */
281 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
282 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
283 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
284 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
285 {IP_VS_SCTP_S_INIT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
286 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
287 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
288 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
289 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
290 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
291 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
292 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
293 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
294 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
295 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
296 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
297 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
298 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
299 },
300 /*
301 * State : IP_VS_SCTP_S_INIT_ACK_CLI
302 * Client sent INIT ACK and waiting for ECHO from the server
303 */
304 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
305 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
306 /*
307 * We have got an INIT from client. From the spec.“Upon receipt of
308 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
309 * an INIT ACK using the same parameters it sent in its original
310 * INIT chunk (including its Initiate Tag, unchanged”).
311 */
312 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
313 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
314 /*
315 * INIT_ACK has been resent by the client, let us stay is in
316 * the same state
317 */
318 {IP_VS_SCTP_S_INIT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
319 /*
320 * INIT_ACK sent by the server, close the connection
321 */
322 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
323 /*
324 * ECHO by client, it should not happen, close the connection
325 */
326 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
327 /*
328 * ECHO by server, this is what we are expecting, move to ECHO_SER
329 */
330 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
331 /*
332 * COOKIE ACK from client, it should not happen, close the connection
333 */
334 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
335 /*
336 * Unexpected COOKIE ACK from server, staty in the same state
337 */
338 {IP_VS_SCTP_S_INIT_ACK_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
339 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
340 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
341 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
342 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
343 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
344 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
345 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
346 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
347 },
348 /*
349 * State : IP_VS_SCTP_S_INIT_ACK_SER
350 * Server sent INIT ACK and waiting for ECHO from the client
351 */
352 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
353 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
354 /*
355 * We have got an INIT from client. From the spec.“Upon receipt of
356 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
357 * an INIT ACK using the same parameters it sent in its original
358 * INIT chunk (including its Initiate Tag, unchanged”).
359 */
360 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
361 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
362 /*
363 * Unexpected INIT_ACK by the client, let us close the connection
364 */
365 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
366 /*
367 * INIT_ACK resent by the server, let us move to same state
368 */
369 {IP_VS_SCTP_S_INIT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
370 /*
371 * Client send the ECHO, this is what we are expecting,
372 * move to ECHO_CLI
373 */
374 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
375 /*
376 * ECHO received from the server, Not sure what to do,
377 * let us close it
378 */
379 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
380 /*
381 * COOKIE ACK from client, let us stay in the same state
382 */
383 {IP_VS_SCTP_S_INIT_ACK_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
384 /*
385 * COOKIE ACK from server, hmm... this should not happen, lets close
386 * the connection.
387 */
388 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
389 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
390 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
391 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
392 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
393 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
394 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
395 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
396 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
397 },
398 /*
399 * State : IP_VS_SCTP_S_ECHO_CLI
400 * Cient sent ECHO and waiting COOKEI ACK from the Server
401 */
402 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
403 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
404 /*
405 * We have got an INIT from client. From the spec.“Upon receipt of
406 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
407 * an INIT ACK using the same parameters it sent in its original
408 * INIT chunk (including its Initiate Tag, unchanged”).
409 */
410 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
411 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
412 /*
413 * INIT_ACK has been by the client, let us close the connection
414 */
415 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
416 /*
417 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
418 * “If an INIT ACK is received by an endpoint in any state other
419 * than the COOKIE-WAIT state, the endpoint should discard the
420 * INIT ACK chunk”. Stay in the same state
421 */
422 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
423 /*
424 * Client resent the ECHO, let us stay in the same state
425 */
426 {IP_VS_SCTP_S_ECHO_CLI /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
427 /*
428 * ECHO received from the server, Not sure what to do,
429 * let us close it
430 */
431 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
432 /*
433 * COOKIE ACK from client, this shoud not happen, let's close the
434 * connection
435 */
436 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
437 /*
438 * COOKIE ACK from server, this is what we are awaiting,lets move to
439 * ESTABLISHED.
440 */
441 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
442 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
443 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
444 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
445 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
446 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
447 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
448 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
449 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
450 },
451 /*
452 * State : IP_VS_SCTP_S_ECHO_SER
453 * Server sent ECHO and waiting COOKEI ACK from the client
454 */
455 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
456 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
457 /*
458 * We have got an INIT from client. From the spec.“Upon receipt of
459 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
460 * an INIT ACK using the same parameters it sent in its original
461 * INIT chunk (including its Initiate Tag, unchanged”).
462 */
463 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
464 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
465 /*
466 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
467 * “If an INIT ACK is received by an endpoint in any state other
468 * than the COOKIE-WAIT state, the endpoint should discard the
469 * INIT ACK chunk”. Stay in the same state
470 */
471 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
472 /*
473 * INIT_ACK has been by the server, let us close the connection
474 */
475 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
476 /*
477 * Client sent the ECHO, not sure what to do, let's close the
478 * connection.
479 */
480 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
481 /*
482 * ECHO resent by the server, stay in the same state
483 */
484 {IP_VS_SCTP_S_ECHO_SER /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
485 /*
486 * COOKIE ACK from client, this is what we are expecting, let's move
487 * to ESTABLISHED.
488 */
489 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
490 /*
491 * COOKIE ACK from server, this should not happen, lets close the
492 * connection.
493 */
494 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
495 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
496 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
497 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
498 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
499 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
500 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
501 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
502 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
503 },
504 /*
505 * State : IP_VS_SCTP_S_ESTABLISHED
506 * Association established
507 */
508 {{IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_DATA_CLI */ },
509 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_DATA_SER */ },
510 /*
511 * We have got an INIT from client. From the spec.“Upon receipt of
512 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
513 * an INIT ACK using the same parameters it sent in its original
514 * INIT chunk (including its Initiate Tag, unchanged”).
515 */
516 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
517 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
518 /*
519 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
520 * “If an INIT ACK is received by an endpoint in any state other
521 * than the COOKIE-WAIT state, the endpoint should discard the
522 * INIT ACK chunk”. Stay in the same state
523 */
524 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
525 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
526 /*
527 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
528 * peer and peer shall move to the ESTABISHED. if it doesn't handle
529 * it will send ERROR chunk. So, stay in the same state
530 */
531 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
532 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
533 /*
534 * COOKIE ACK from client, not sure what to do stay in the same state
535 */
536 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
537 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
538 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
539 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
540 /*
541 * SHUTDOWN from the client, move to SHUDDOWN_CLI
542 */
543 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
544 /*
545 * SHUTDOWN from the server, move to SHUTDOWN_SER
546 */
547 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
548 /*
549 * client sent SHUDTDOWN_ACK, this should not happen, let's close
550 * the connection
551 */
552 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
553 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
554 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
555 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
556 },
557 /*
558 * State : IP_VS_SCTP_S_SHUT_CLI
559 * SHUTDOWN sent from the client, waitinf for SHUT ACK from the server
560 */
561 /*
562 * We received the data chuck, keep the state unchanged. I assume
563 * that still data chuncks can be received by both the peers in
564 * SHUDOWN state
565 */
566
567 {{IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_DATA_CLI */ },
568 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_DATA_SER */ },
569 /*
570 * We have got an INIT from client. From the spec.“Upon receipt of
571 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
572 * an INIT ACK using the same parameters it sent in its original
573 * INIT chunk (including its Initiate Tag, unchanged”).
574 */
575 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
576 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
577 /*
578 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
579 * “If an INIT ACK is received by an endpoint in any state other
580 * than the COOKIE-WAIT state, the endpoint should discard the
581 * INIT ACK chunk”. Stay in the same state
582 */
583 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
584 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
585 /*
586 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
587 * peer and peer shall move to the ESTABISHED. if it doesn't handle
588 * it will send ERROR chunk. So, stay in the same state
589 */
590 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
591 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
592 /*
593 * COOKIE ACK from client, not sure what to do stay in the same state
594 */
595 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
596 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
597 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
598 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
599 /*
600 * SHUTDOWN resent from the client, move to SHUDDOWN_CLI
601 */
602 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
603 /*
604 * SHUTDOWN from the server, move to SHUTDOWN_SER
605 */
606 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
607 /*
608 * client sent SHUDTDOWN_ACK, this should not happen, let's close
609 * the connection
610 */
611 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
612 /*
613 * Server sent SHUTDOWN ACK, this is what we are expecting, let's move
614 * to SHUDOWN_ACK_SER
615 */
616 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
617 /*
618 * SHUTDOWN COM from client, this should not happen, let's close the
619 * connection
620 */
621 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
622 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
623 },
624 /*
625 * State : IP_VS_SCTP_S_SHUT_SER
626 * SHUTDOWN sent from the server, waitinf for SHUTDOWN ACK from client
627 */
628 /*
629 * We received the data chuck, keep the state unchanged. I assume
630 * that still data chuncks can be received by both the peers in
631 * SHUDOWN state
632 */
633
634 {{IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_DATA_CLI */ },
635 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_DATA_SER */ },
636 /*
637 * We have got an INIT from client. From the spec.“Upon receipt of
638 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
639 * an INIT ACK using the same parameters it sent in its original
640 * INIT chunk (including its Initiate Tag, unchanged”).
641 */
642 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
643 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
644 /*
645 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
646 * “If an INIT ACK is received by an endpoint in any state other
647 * than the COOKIE-WAIT state, the endpoint should discard the
648 * INIT ACK chunk”. Stay in the same state
649 */
650 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
651 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
652 /*
653 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
654 * peer and peer shall move to the ESTABISHED. if it doesn't handle
655 * it will send ERROR chunk. So, stay in the same state
656 */
657 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
658 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
659 /*
660 * COOKIE ACK from client, not sure what to do stay in the same state
661 */
662 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
663 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
664 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
665 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
666 /*
667 * SHUTDOWN resent from the client, move to SHUDDOWN_CLI
668 */
669 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
670 /*
671 * SHUTDOWN resent from the server, move to SHUTDOWN_SER
672 */
673 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
674 /*
675 * client sent SHUDTDOWN_ACK, this is what we are expecting, let's
676 * move to SHUT_ACK_CLI
677 */
678 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
679 /*
680 * Server sent SHUTDOWN ACK, this should not happen, let's close the
681 * connection
682 */
683 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
684 /*
685 * SHUTDOWN COM from client, this should not happen, let's close the
686 * connection
687 */
688 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
689 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
690 },
691
692 /*
693 * State : IP_VS_SCTP_S_SHUT_ACK_CLI
694 * SHUTDOWN ACK from the client, awaiting for SHUTDOWN COM from server
695 */
696 /*
697 * We received the data chuck, keep the state unchanged. I assume
698 * that still data chuncks can be received by both the peers in
699 * SHUDOWN state
700 */
701
702 {{IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_DATA_CLI */ },
703 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_DATA_SER */ },
704 /*
705 * We have got an INIT from client. From the spec.“Upon receipt of
706 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with
707 * an INIT ACK using the same parameters it sent in its original
708 * INIT chunk (including its Initiate Tag, unchanged”).
709 */
710 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
711 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
712 /*
713 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says,
714 * “If an INIT ACK is received by an endpoint in any state other
715 * than the COOKIE-WAIT state, the endpoint should discard the
716 * INIT ACK chunk”. Stay in the same state
717 */
718 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
719 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
720 /*
721 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the
722 * peer and peer shall move to the ESTABISHED. if it doesn't handle
723 * it will send ERROR chunk. So, stay in the same state
724 */
725 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
726 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
727 /*
728 * COOKIE ACK from client, not sure what to do stay in the same state
729 */
730 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
731 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
732 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
733 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
734 /*
735 * SHUTDOWN sent from the client, move to SHUDDOWN_CLI
736 */
737 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ },
738 /*
739 * SHUTDOWN sent from the server, move to SHUTDOWN_SER
740 */
741 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ },
742 /*
743 * client resent SHUDTDOWN_ACK, let's stay in the same state
744 */
745 {IP_VS_SCTP_S_SHUT_ACK_CLI /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
746 /*
747 * Server sent SHUTDOWN ACK, this should not happen, let's close the
748 * connection
749 */
750 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
751 /*
752 * SHUTDOWN COM from client, this should not happen, let's close the
753 * connection
754 */
755 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
756 /*
757 * SHUTDOWN COMPLETE from server this is what we are expecting.
758 */
759 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
760 },
761
762 /*
763 * State : IP_VS_SCTP_S_SHUT_ACK_SER
764 * SHUTDOWN ACK from the server, awaiting for SHUTDOWN COM from client
765 */
766 /*
767 * We received the data chuck, keep the state unchanged. I assume
768 * that still data chuncks can be received by both the peers in
769 * SHUDOWN state
770 */
771 245
772 {{IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_DATA_CLI */ }, 246#define sNO IP_VS_SCTP_S_NONE
773 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_DATA_SER */ }, 247#define sI1 IP_VS_SCTP_S_INIT1
774 /* 248#define sIN IP_VS_SCTP_S_INIT
775 * We have got an INIT from client. From the spec.“Upon receipt of 249#define sCS IP_VS_SCTP_S_COOKIE_SENT
776 * an INIT in the COOKIE-WAIT state, an endpoint MUST respond with 250#define sCR IP_VS_SCTP_S_COOKIE_REPLIED
777 * an INIT ACK using the same parameters it sent in its original 251#define sCW IP_VS_SCTP_S_COOKIE_WAIT
778 * INIT chunk (including its Initiate Tag, unchanged”). 252#define sCO IP_VS_SCTP_S_COOKIE
779 */ 253#define sCE IP_VS_SCTP_S_COOKIE_ECHOED
780 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ }, 254#define sES IP_VS_SCTP_S_ESTABLISHED
781 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ }, 255#define sSS IP_VS_SCTP_S_SHUTDOWN_SENT
782 /* 256#define sSR IP_VS_SCTP_S_SHUTDOWN_RECEIVED
783 * INIT_ACK sent by the server, Unexpected INIT ACK, spec says, 257#define sSA IP_VS_SCTP_S_SHUTDOWN_ACK_SENT
784 * “If an INIT ACK is received by an endpoint in any state other 258#define sRJ IP_VS_SCTP_S_REJECTED
785 * than the COOKIE-WAIT state, the endpoint should discard the 259#define sCL IP_VS_SCTP_S_CLOSED
786 * INIT ACK chunk”. Stay in the same state 260
787 */ 261static const __u8 sctp_states
788 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ }, 262 [IP_VS_DIR_LAST][IP_VS_SCTP_EVENT_LAST][IP_VS_SCTP_S_LAST] = {
789 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_INIT_ACK_SER */ }, 263 { /* INPUT */
790 /* 264/* sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
791 * Client sent ECHO, Spec(sec 5.2.4) says it may be handled by the 265/* d */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
792 * peer and peer shall move to the ESTABISHED. if it doesn't handle 266/* i */{sI1, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sIN, sIN},
793 * it will send ERROR chunk. So, stay in the same state 267/* i_a */{sCW, sCW, sCW, sCS, sCR, sCO, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
794 */ 268/* c_e */{sCR, sIN, sIN, sCR, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
795 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ }, 269/* c_a */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sES, sES, sSS, sSR, sSA, sRJ, sCL},
796 {IP_VS_SCTP_S_ESTABLISHED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ }, 270/* s */{sSR, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sSR, sSS, sSR, sSA, sRJ, sCL},
797 /* 271/* s_a */{sCL, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sES, sCL, sSR, sCL, sRJ, sCL},
798 * COOKIE ACK from client, not sure what to do stay in the same state 272/* s_c */{sCL, sCL, sCL, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sCL, sRJ, sCL},
799 */ 273/* err */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCL, sES, sSS, sSR, sSA, sRJ, sCL},
800 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ }, 274/* ab */{sCL, sCL, sCL, sCL, sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
801 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ }, 275 },
802 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ }, 276 { /* OUTPUT */
803 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ }, 277/* sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
804 /* 278/* d */{sES, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
805 * SHUTDOWN sent from the client, move to SHUDDOWN_CLI 279/* i */{sCW, sCW, sCW, sCW, sCW, sCW, sCW, sCW, sES, sCW, sCW, sCW, sCW, sCW},
806 */ 280/* i_a */{sCS, sCS, sCS, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
807 {IP_VS_SCTP_S_SHUT_CLI /* IP_VS_SCTP_EVE_SHUT_CLI */ }, 281/* c_e */{sCE, sCE, sCE, sCE, sCE, sCE, sCE, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
808 /* 282/* c_a */{sES, sES, sES, sES, sES, sES, sES, sES, sES, sSS, sSR, sSA, sRJ, sCL},
809 * SHUTDOWN sent from the server, move to SHUTDOWN_SER 283/* s */{sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSS, sSR, sSA, sRJ, sCL},
810 */ 284/* s_a */{sSA, sSA, sSA, sSA, sSA, sCW, sCO, sCE, sES, sSA, sSA, sSA, sRJ, sCL},
811 {IP_VS_SCTP_S_SHUT_SER /* IP_VS_SCTP_EVE_SHUT_SER */ }, 285/* s_c */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
812 /* 286/* err */{sCL, sCL, sCL, sCL, sCL, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
813 * client sent SHUDTDOWN_ACK, this should not happen let's close 287/* ab */{sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
814 * the connection. 288 },
815 */ 289 { /* INPUT-ONLY */
816 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ }, 290/* sNO, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL*/
817 /* 291/* d */{sES, sI1, sIN, sCS, sCR, sES, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
818 * Server resent SHUTDOWN ACK, stay in the same state 292/* i */{sI1, sIN, sIN, sIN, sIN, sIN, sCO, sCE, sES, sSS, sSR, sSA, sIN, sIN},
819 */ 293/* i_a */{sCE, sCE, sCE, sCE, sCE, sCE, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
820 {IP_VS_SCTP_S_SHUT_ACK_SER /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ }, 294/* c_e */{sES, sES, sES, sES, sES, sES, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
821 /* 295/* c_a */{sES, sI1, sIN, sES, sES, sCW, sES, sES, sES, sSS, sSR, sSA, sRJ, sCL},
822 * SHUTDOWN COM from client, this what we are expecting, let's close 296/* s */{sSR, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sSR, sSS, sSR, sSA, sRJ, sCL},
823 * the connection 297/* s_a */{sCL, sIN, sIN, sCS, sCR, sCW, sCO, sCE, sCL, sCL, sSR, sCL, sRJ, sCL},
824 */ 298/* s_c */{sCL, sCL, sCL, sCL, sCL, sCW, sCO, sCE, sES, sSS, sCL, sCL, sRJ, sCL},
825 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ }, 299/* err */{sCL, sI1, sIN, sCS, sCR, sCW, sCO, sCE, sES, sSS, sSR, sSA, sRJ, sCL},
826 /* 300/* ab */{sCL, sCL, sCL, sCL, sCL, sRJ, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
827 * SHUTDOWN COMPLETE from server this should not happen. 301 },
828 */
829 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
830 },
831 /*
832 * State : IP_VS_SCTP_S_CLOSED
833 */
834 {{IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_CLI */ },
835 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_DATA_SER */ },
836 {IP_VS_SCTP_S_INIT_CLI /* IP_VS_SCTP_EVE_INIT_CLI */ },
837 {IP_VS_SCTP_S_INIT_SER /* IP_VS_SCTP_EVE_INIT_SER */ },
838 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_CLI */ },
839 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_INIT_ACK_SER */ },
840 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_CLI */ },
841 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ECHO_SER */ },
842 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_CLI */ },
843 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_COOKIE_ACK_SER */ },
844 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_CLI */ },
845 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_ABORT_SER */ },
846 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_CLI */ },
847 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_SER */ },
848 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_CLI */ },
849 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_ACK_SER */ },
850 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_CLI */ },
851 {IP_VS_SCTP_S_CLOSED /* IP_VS_SCTP_EVE_SHUT_COM_SER */ }
852 }
853}; 302};
854 303
855/* 304#define IP_VS_SCTP_MAX_RTO ((60 + 1) * HZ)
856 * Timeout table[state] 305
857 */ 306/* Timeout table[state] */
858static const int sctp_timeouts[IP_VS_SCTP_S_LAST + 1] = { 307static const int sctp_timeouts[IP_VS_SCTP_S_LAST + 1] = {
859 [IP_VS_SCTP_S_NONE] = 2 * HZ, 308 [IP_VS_SCTP_S_NONE] = 2 * HZ,
860 [IP_VS_SCTP_S_INIT_CLI] = 1 * 60 * HZ, 309 [IP_VS_SCTP_S_INIT1] = (0 + 3 + 1) * HZ,
861 [IP_VS_SCTP_S_INIT_SER] = 1 * 60 * HZ, 310 [IP_VS_SCTP_S_INIT] = IP_VS_SCTP_MAX_RTO,
862 [IP_VS_SCTP_S_INIT_ACK_CLI] = 1 * 60 * HZ, 311 [IP_VS_SCTP_S_COOKIE_SENT] = IP_VS_SCTP_MAX_RTO,
863 [IP_VS_SCTP_S_INIT_ACK_SER] = 1 * 60 * HZ, 312 [IP_VS_SCTP_S_COOKIE_REPLIED] = IP_VS_SCTP_MAX_RTO,
864 [IP_VS_SCTP_S_ECHO_CLI] = 1 * 60 * HZ, 313 [IP_VS_SCTP_S_COOKIE_WAIT] = IP_VS_SCTP_MAX_RTO,
865 [IP_VS_SCTP_S_ECHO_SER] = 1 * 60 * HZ, 314 [IP_VS_SCTP_S_COOKIE] = IP_VS_SCTP_MAX_RTO,
866 [IP_VS_SCTP_S_ESTABLISHED] = 15 * 60 * HZ, 315 [IP_VS_SCTP_S_COOKIE_ECHOED] = IP_VS_SCTP_MAX_RTO,
867 [IP_VS_SCTP_S_SHUT_CLI] = 1 * 60 * HZ, 316 [IP_VS_SCTP_S_ESTABLISHED] = 15 * 60 * HZ,
868 [IP_VS_SCTP_S_SHUT_SER] = 1 * 60 * HZ, 317 [IP_VS_SCTP_S_SHUTDOWN_SENT] = IP_VS_SCTP_MAX_RTO,
869 [IP_VS_SCTP_S_SHUT_ACK_CLI] = 1 * 60 * HZ, 318 [IP_VS_SCTP_S_SHUTDOWN_RECEIVED] = IP_VS_SCTP_MAX_RTO,
870 [IP_VS_SCTP_S_SHUT_ACK_SER] = 1 * 60 * HZ, 319 [IP_VS_SCTP_S_SHUTDOWN_ACK_SENT] = IP_VS_SCTP_MAX_RTO,
871 [IP_VS_SCTP_S_CLOSED] = 10 * HZ, 320 [IP_VS_SCTP_S_REJECTED] = (0 + 3 + 1) * HZ,
872 [IP_VS_SCTP_S_LAST] = 2 * HZ, 321 [IP_VS_SCTP_S_CLOSED] = IP_VS_SCTP_MAX_RTO,
322 [IP_VS_SCTP_S_LAST] = 2 * HZ,
873}; 323};
874 324
875static const char *sctp_state_name_table[IP_VS_SCTP_S_LAST + 1] = { 325static const char *sctp_state_name_table[IP_VS_SCTP_S_LAST + 1] = {
876 [IP_VS_SCTP_S_NONE] = "NONE", 326 [IP_VS_SCTP_S_NONE] = "NONE",
877 [IP_VS_SCTP_S_INIT_CLI] = "INIT_CLI", 327 [IP_VS_SCTP_S_INIT1] = "INIT1",
878 [IP_VS_SCTP_S_INIT_SER] = "INIT_SER", 328 [IP_VS_SCTP_S_INIT] = "INIT",
879 [IP_VS_SCTP_S_INIT_ACK_CLI] = "INIT_ACK_CLI", 329 [IP_VS_SCTP_S_COOKIE_SENT] = "C-SENT",
880 [IP_VS_SCTP_S_INIT_ACK_SER] = "INIT_ACK_SER", 330 [IP_VS_SCTP_S_COOKIE_REPLIED] = "C-REPLIED",
881 [IP_VS_SCTP_S_ECHO_CLI] = "COOKIE_ECHO_CLI", 331 [IP_VS_SCTP_S_COOKIE_WAIT] = "C-WAIT",
882 [IP_VS_SCTP_S_ECHO_SER] = "COOKIE_ECHO_SER", 332 [IP_VS_SCTP_S_COOKIE] = "COOKIE",
883 [IP_VS_SCTP_S_ESTABLISHED] = "ESTABISHED", 333 [IP_VS_SCTP_S_COOKIE_ECHOED] = "C-ECHOED",
884 [IP_VS_SCTP_S_SHUT_CLI] = "SHUTDOWN_CLI", 334 [IP_VS_SCTP_S_ESTABLISHED] = "ESTABLISHED",
885 [IP_VS_SCTP_S_SHUT_SER] = "SHUTDOWN_SER", 335 [IP_VS_SCTP_S_SHUTDOWN_SENT] = "S-SENT",
886 [IP_VS_SCTP_S_SHUT_ACK_CLI] = "SHUTDOWN_ACK_CLI", 336 [IP_VS_SCTP_S_SHUTDOWN_RECEIVED] = "S-RECEIVED",
887 [IP_VS_SCTP_S_SHUT_ACK_SER] = "SHUTDOWN_ACK_SER", 337 [IP_VS_SCTP_S_SHUTDOWN_ACK_SENT] = "S-ACK-SENT",
888 [IP_VS_SCTP_S_CLOSED] = "CLOSED", 338 [IP_VS_SCTP_S_REJECTED] = "REJECTED",
889 [IP_VS_SCTP_S_LAST] = "BUG!" 339 [IP_VS_SCTP_S_CLOSED] = "CLOSED",
340 [IP_VS_SCTP_S_LAST] = "BUG!",
890}; 341};
891 342
892 343
@@ -943,17 +394,20 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
943 } 394 }
944 } 395 }
945 396
946 event = sctp_events[chunk_type]; 397 event = (chunk_type < sizeof(sctp_events)) ?
398 sctp_events[chunk_type] : IP_VS_SCTP_DATA;
947 399
948 /* 400 /* Update direction to INPUT_ONLY if necessary
949 * If the direction is IP_VS_DIR_OUTPUT, this event is from server 401 * or delete NO_OUTPUT flag if output packet detected
950 */
951 if (direction == IP_VS_DIR_OUTPUT)
952 event++;
953 /*
954 * get next state
955 */ 402 */
956 next_state = sctp_states_table[cp->state][event].next_state; 403 if (cp->flags & IP_VS_CONN_F_NOOUTPUT) {
404 if (direction == IP_VS_DIR_OUTPUT)
405 cp->flags &= ~IP_VS_CONN_F_NOOUTPUT;
406 else
407 direction = IP_VS_DIR_INPUT_ONLY;
408 }
409
410 next_state = sctp_states[direction][event][cp->state];
957 411
958 if (next_state != cp->state) { 412 if (next_state != cp->state) {
959 struct ip_vs_dest *dest = cp->dest; 413 struct ip_vs_dest *dest = cp->dest;
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index 50a15944c6c1..e3a697234a98 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -39,6 +39,7 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
39 struct net *net; 39 struct net *net;
40 struct ip_vs_service *svc; 40 struct ip_vs_service *svc;
41 struct tcphdr _tcph, *th; 41 struct tcphdr _tcph, *th;
42 struct netns_ipvs *ipvs;
42 43
43 th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph); 44 th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph);
44 if (th == NULL) { 45 if (th == NULL) {
@@ -46,14 +47,15 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
46 return 0; 47 return 0;
47 } 48 }
48 net = skb_net(skb); 49 net = skb_net(skb);
50 ipvs = net_ipvs(net);
49 /* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */ 51 /* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */
50 rcu_read_lock(); 52 rcu_read_lock();
51 if (th->syn && 53 if ((th->syn || sysctl_sloppy_tcp(ipvs)) && !th->rst &&
52 (svc = ip_vs_service_find(net, af, skb->mark, iph->protocol, 54 (svc = ip_vs_service_find(net, af, skb->mark, iph->protocol,
53 &iph->daddr, th->dest))) { 55 &iph->daddr, th->dest))) {
54 int ignored; 56 int ignored;
55 57
56 if (ip_vs_todrop(net_ipvs(net))) { 58 if (ip_vs_todrop(ipvs)) {
57 /* 59 /*
58 * It seems that we are very loaded. 60 * It seems that we are very loaded.
59 * We have to drop this packet :( 61 * We have to drop this packet :(
@@ -401,7 +403,7 @@ static struct tcp_states_t tcp_states [] = {
401/* sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA */ 403/* sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA */
402/*syn*/ {{sSR, sES, sES, sSR, sSR, sSR, sSR, sSR, sSR, sSR, sSR }}, 404/*syn*/ {{sSR, sES, sES, sSR, sSR, sSR, sSR, sSR, sSR, sSR, sSR }},
403/*fin*/ {{sCL, sCW, sSS, sTW, sTW, sTW, sCL, sCW, sLA, sLI, sTW }}, 405/*fin*/ {{sCL, sCW, sSS, sTW, sTW, sTW, sCL, sCW, sLA, sLI, sTW }},
404/*ack*/ {{sCL, sES, sSS, sES, sFW, sTW, sCL, sCW, sCL, sLI, sES }}, 406/*ack*/ {{sES, sES, sSS, sES, sFW, sTW, sCL, sCW, sCL, sLI, sES }},
405/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sSR }}, 407/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sSR }},
406 408
407/* OUTPUT */ 409/* OUTPUT */
@@ -415,7 +417,7 @@ static struct tcp_states_t tcp_states [] = {
415/* sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA */ 417/* sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA */
416/*syn*/ {{sSR, sES, sES, sSR, sSR, sSR, sSR, sSR, sSR, sSR, sSR }}, 418/*syn*/ {{sSR, sES, sES, sSR, sSR, sSR, sSR, sSR, sSR, sSR, sSR }},
417/*fin*/ {{sCL, sFW, sSS, sTW, sFW, sTW, sCL, sCW, sLA, sLI, sTW }}, 419/*fin*/ {{sCL, sFW, sSS, sTW, sFW, sTW, sCL, sCW, sLA, sLI, sTW }},
418/*ack*/ {{sCL, sES, sSS, sES, sFW, sTW, sCL, sCW, sCL, sLI, sES }}, 420/*ack*/ {{sES, sES, sSS, sES, sFW, sTW, sCL, sCW, sCL, sLI, sES }},
419/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sCL }}, 421/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sCL }},
420}; 422};
421 423
@@ -424,7 +426,7 @@ static struct tcp_states_t tcp_states_dos [] = {
424/* sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA */ 426/* sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA */
425/*syn*/ {{sSR, sES, sES, sSR, sSR, sSR, sSR, sSR, sSR, sSR, sSA }}, 427/*syn*/ {{sSR, sES, sES, sSR, sSR, sSR, sSR, sSR, sSR, sSR, sSA }},
426/*fin*/ {{sCL, sCW, sSS, sTW, sTW, sTW, sCL, sCW, sLA, sLI, sSA }}, 428/*fin*/ {{sCL, sCW, sSS, sTW, sTW, sTW, sCL, sCW, sLA, sLI, sSA }},
427/*ack*/ {{sCL, sES, sSS, sSR, sFW, sTW, sCL, sCW, sCL, sLI, sSA }}, 429/*ack*/ {{sES, sES, sSS, sSR, sFW, sTW, sCL, sCW, sCL, sLI, sSA }},
428/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sCL }}, 430/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sCL }},
429 431
430/* OUTPUT */ 432/* OUTPUT */
@@ -438,7 +440,7 @@ static struct tcp_states_t tcp_states_dos [] = {
438/* sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA */ 440/* sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA */
439/*syn*/ {{sSA, sES, sES, sSR, sSA, sSA, sSA, sSA, sSA, sSA, sSA }}, 441/*syn*/ {{sSA, sES, sES, sSR, sSA, sSA, sSA, sSA, sSA, sSA, sSA }},
440/*fin*/ {{sCL, sFW, sSS, sTW, sFW, sTW, sCL, sCW, sLA, sLI, sTW }}, 442/*fin*/ {{sCL, sFW, sSS, sTW, sFW, sTW, sCL, sCW, sLA, sLI, sTW }},
441/*ack*/ {{sCL, sES, sSS, sES, sFW, sTW, sCL, sCW, sCL, sLI, sES }}, 443/*ack*/ {{sES, sES, sSS, sES, sFW, sTW, sCL, sCW, sCL, sLI, sES }},
442/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sCL }}, 444/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sCL }},
443}; 445};
444 446
diff --git a/net/netfilter/ipvs/ip_vs_rr.c b/net/netfilter/ipvs/ip_vs_rr.c
index c35986c793d9..176b87c35e34 100644
--- a/net/netfilter/ipvs/ip_vs_rr.c
+++ b/net/netfilter/ipvs/ip_vs_rr.c
@@ -55,7 +55,8 @@ static int ip_vs_rr_del_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest)
55 * Round-Robin Scheduling 55 * Round-Robin Scheduling
56 */ 56 */
57static struct ip_vs_dest * 57static struct ip_vs_dest *
58ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 58ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
59 struct ip_vs_iphdr *iph)
59{ 60{
60 struct list_head *p; 61 struct list_head *p;
61 struct ip_vs_dest *dest, *last; 62 struct ip_vs_dest *dest, *last;
diff --git a/net/netfilter/ipvs/ip_vs_sed.c b/net/netfilter/ipvs/ip_vs_sed.c
index f3205925359a..a5284cc3d882 100644
--- a/net/netfilter/ipvs/ip_vs_sed.c
+++ b/net/netfilter/ipvs/ip_vs_sed.c
@@ -59,7 +59,8 @@ ip_vs_sed_dest_overhead(struct ip_vs_dest *dest)
59 * Weighted Least Connection scheduling 59 * Weighted Least Connection scheduling
60 */ 60 */
61static struct ip_vs_dest * 61static struct ip_vs_dest *
62ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 62ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
63 struct ip_vs_iphdr *iph)
63{ 64{
64 struct ip_vs_dest *dest, *least; 65 struct ip_vs_dest *dest, *least;
65 unsigned int loh, doh; 66 unsigned int loh, doh;
diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c
index a65edfe4b16c..f16c027df15b 100644
--- a/net/netfilter/ipvs/ip_vs_sh.c
+++ b/net/netfilter/ipvs/ip_vs_sh.c
@@ -48,6 +48,10 @@
48 48
49#include <net/ip_vs.h> 49#include <net/ip_vs.h>
50 50
51#include <net/tcp.h>
52#include <linux/udp.h>
53#include <linux/sctp.h>
54
51 55
52/* 56/*
53 * IPVS SH bucket 57 * IPVS SH bucket
@@ -71,10 +75,19 @@ struct ip_vs_sh_state {
71 struct ip_vs_sh_bucket buckets[IP_VS_SH_TAB_SIZE]; 75 struct ip_vs_sh_bucket buckets[IP_VS_SH_TAB_SIZE];
72}; 76};
73 77
78/* Helper function to determine if server is unavailable */
79static inline bool is_unavailable(struct ip_vs_dest *dest)
80{
81 return atomic_read(&dest->weight) <= 0 ||
82 dest->flags & IP_VS_DEST_F_OVERLOAD;
83}
84
74/* 85/*
75 * Returns hash value for IPVS SH entry 86 * Returns hash value for IPVS SH entry
76 */ 87 */
77static inline unsigned int ip_vs_sh_hashkey(int af, const union nf_inet_addr *addr) 88static inline unsigned int
89ip_vs_sh_hashkey(int af, const union nf_inet_addr *addr,
90 __be16 port, unsigned int offset)
78{ 91{
79 __be32 addr_fold = addr->ip; 92 __be32 addr_fold = addr->ip;
80 93
@@ -83,7 +96,8 @@ static inline unsigned int ip_vs_sh_hashkey(int af, const union nf_inet_addr *ad
83 addr_fold = addr->ip6[0]^addr->ip6[1]^ 96 addr_fold = addr->ip6[0]^addr->ip6[1]^
84 addr->ip6[2]^addr->ip6[3]; 97 addr->ip6[2]^addr->ip6[3];
85#endif 98#endif
86 return (ntohl(addr_fold)*2654435761UL) & IP_VS_SH_TAB_MASK; 99 return (offset + (ntohs(port) + ntohl(addr_fold))*2654435761UL) &
100 IP_VS_SH_TAB_MASK;
87} 101}
88 102
89 103
@@ -91,12 +105,42 @@ static inline unsigned int ip_vs_sh_hashkey(int af, const union nf_inet_addr *ad
91 * Get ip_vs_dest associated with supplied parameters. 105 * Get ip_vs_dest associated with supplied parameters.
92 */ 106 */
93static inline struct ip_vs_dest * 107static inline struct ip_vs_dest *
94ip_vs_sh_get(int af, struct ip_vs_sh_state *s, const union nf_inet_addr *addr) 108ip_vs_sh_get(struct ip_vs_service *svc, struct ip_vs_sh_state *s,
109 const union nf_inet_addr *addr, __be16 port)
95{ 110{
96 return rcu_dereference(s->buckets[ip_vs_sh_hashkey(af, addr)].dest); 111 unsigned int hash = ip_vs_sh_hashkey(svc->af, addr, port, 0);
112 struct ip_vs_dest *dest = rcu_dereference(s->buckets[hash].dest);
113
114 return (!dest || is_unavailable(dest)) ? NULL : dest;
97} 115}
98 116
99 117
118/* As ip_vs_sh_get, but with fallback if selected server is unavailable */
119static inline struct ip_vs_dest *
120ip_vs_sh_get_fallback(struct ip_vs_service *svc, struct ip_vs_sh_state *s,
121 const union nf_inet_addr *addr, __be16 port)
122{
123 unsigned int offset;
124 unsigned int hash;
125 struct ip_vs_dest *dest;
126
127 for (offset = 0; offset < IP_VS_SH_TAB_SIZE; offset++) {
128 hash = ip_vs_sh_hashkey(svc->af, addr, port, offset);
129 dest = rcu_dereference(s->buckets[hash].dest);
130 if (!dest)
131 break;
132 if (is_unavailable(dest))
133 IP_VS_DBG_BUF(6, "SH: selected unavailable server "
134 "%s:%d (offset %d)",
135 IP_VS_DBG_ADDR(svc->af, &dest->addr),
136 ntohs(dest->port), offset);
137 else
138 return dest;
139 }
140
141 return NULL;
142}
143
100/* 144/*
101 * Assign all the hash buckets of the specified table with the service. 145 * Assign all the hash buckets of the specified table with the service.
102 */ 146 */
@@ -213,13 +257,33 @@ static int ip_vs_sh_dest_changed(struct ip_vs_service *svc,
213} 257}
214 258
215 259
216/* 260/* Helper function to get port number */
217 * If the dest flags is set with IP_VS_DEST_F_OVERLOAD, 261static inline __be16
218 * consider that the server is overloaded here. 262ip_vs_sh_get_port(const struct sk_buff *skb, struct ip_vs_iphdr *iph)
219 */
220static inline int is_overloaded(struct ip_vs_dest *dest)
221{ 263{
222 return dest->flags & IP_VS_DEST_F_OVERLOAD; 264 __be16 port;
265 struct tcphdr _tcph, *th;
266 struct udphdr _udph, *uh;
267 sctp_sctphdr_t _sctph, *sh;
268
269 switch (iph->protocol) {
270 case IPPROTO_TCP:
271 th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph);
272 port = th->source;
273 break;
274 case IPPROTO_UDP:
275 uh = skb_header_pointer(skb, iph->len, sizeof(_udph), &_udph);
276 port = uh->source;
277 break;
278 case IPPROTO_SCTP:
279 sh = skb_header_pointer(skb, iph->len, sizeof(_sctph), &_sctph);
280 port = sh->source;
281 break;
282 default:
283 port = 0;
284 }
285
286 return port;
223} 287}
224 288
225 289
@@ -227,28 +291,32 @@ static inline int is_overloaded(struct ip_vs_dest *dest)
227 * Source Hashing scheduling 291 * Source Hashing scheduling
228 */ 292 */
229static struct ip_vs_dest * 293static struct ip_vs_dest *
230ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 294ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
295 struct ip_vs_iphdr *iph)
231{ 296{
232 struct ip_vs_dest *dest; 297 struct ip_vs_dest *dest;
233 struct ip_vs_sh_state *s; 298 struct ip_vs_sh_state *s;
234 struct ip_vs_iphdr iph; 299 __be16 port = 0;
235
236 ip_vs_fill_iph_addr_only(svc->af, skb, &iph);
237 300
238 IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n"); 301 IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
239 302
303 if (svc->flags & IP_VS_SVC_F_SCHED_SH_PORT)
304 port = ip_vs_sh_get_port(skb, iph);
305
240 s = (struct ip_vs_sh_state *) svc->sched_data; 306 s = (struct ip_vs_sh_state *) svc->sched_data;
241 dest = ip_vs_sh_get(svc->af, s, &iph.saddr); 307
242 if (!dest 308 if (svc->flags & IP_VS_SVC_F_SCHED_SH_FALLBACK)
243 || !(dest->flags & IP_VS_DEST_F_AVAILABLE) 309 dest = ip_vs_sh_get_fallback(svc, s, &iph->saddr, port);
244 || atomic_read(&dest->weight) <= 0 310 else
245 || is_overloaded(dest)) { 311 dest = ip_vs_sh_get(svc, s, &iph->saddr, port);
312
313 if (!dest) {
246 ip_vs_scheduler_err(svc, "no destination available"); 314 ip_vs_scheduler_err(svc, "no destination available");
247 return NULL; 315 return NULL;
248 } 316 }
249 317
250 IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n", 318 IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
251 IP_VS_DBG_ADDR(svc->af, &iph.saddr), 319 IP_VS_DBG_ADDR(svc->af, &iph->saddr),
252 IP_VS_DBG_ADDR(svc->af, &dest->addr), 320 IP_VS_DBG_ADDR(svc->af, &dest->addr),
253 ntohs(dest->port)); 321 ntohs(dest->port));
254 322
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index f6046d9af8d3..f4484719f3e6 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -425,6 +425,16 @@ ip_vs_sync_buff_create_v0(struct netns_ipvs *ipvs)
425 return sb; 425 return sb;
426} 426}
427 427
428/* Check if connection is controlled by persistence */
429static inline bool in_persistence(struct ip_vs_conn *cp)
430{
431 for (cp = cp->control; cp; cp = cp->control) {
432 if (cp->flags & IP_VS_CONN_F_TEMPLATE)
433 return true;
434 }
435 return false;
436}
437
428/* Check if conn should be synced. 438/* Check if conn should be synced.
429 * pkts: conn packets, use sysctl_sync_threshold to avoid packet check 439 * pkts: conn packets, use sysctl_sync_threshold to avoid packet check
430 * - (1) sync_refresh_period: reduce sync rate. Additionally, retry 440 * - (1) sync_refresh_period: reduce sync rate. Additionally, retry
@@ -447,6 +457,8 @@ static int ip_vs_sync_conn_needed(struct netns_ipvs *ipvs,
447 /* Check if we sync in current state */ 457 /* Check if we sync in current state */
448 if (unlikely(cp->flags & IP_VS_CONN_F_TEMPLATE)) 458 if (unlikely(cp->flags & IP_VS_CONN_F_TEMPLATE))
449 force = 0; 459 force = 0;
460 else if (unlikely(sysctl_sync_persist_mode(ipvs) && in_persistence(cp)))
461 return 0;
450 else if (likely(cp->protocol == IPPROTO_TCP)) { 462 else if (likely(cp->protocol == IPPROTO_TCP)) {
451 if (!((1 << cp->state) & 463 if (!((1 << cp->state) &
452 ((1 << IP_VS_TCP_S_ESTABLISHED) | 464 ((1 << IP_VS_TCP_S_ESTABLISHED) |
@@ -461,9 +473,10 @@ static int ip_vs_sync_conn_needed(struct netns_ipvs *ipvs,
461 } else if (unlikely(cp->protocol == IPPROTO_SCTP)) { 473 } else if (unlikely(cp->protocol == IPPROTO_SCTP)) {
462 if (!((1 << cp->state) & 474 if (!((1 << cp->state) &
463 ((1 << IP_VS_SCTP_S_ESTABLISHED) | 475 ((1 << IP_VS_SCTP_S_ESTABLISHED) |
464 (1 << IP_VS_SCTP_S_CLOSED) | 476 (1 << IP_VS_SCTP_S_SHUTDOWN_SENT) |
465 (1 << IP_VS_SCTP_S_SHUT_ACK_CLI) | 477 (1 << IP_VS_SCTP_S_SHUTDOWN_RECEIVED) |
466 (1 << IP_VS_SCTP_S_SHUT_ACK_SER)))) 478 (1 << IP_VS_SCTP_S_SHUTDOWN_ACK_SENT) |
479 (1 << IP_VS_SCTP_S_CLOSED))))
467 return 0; 480 return 0;
468 force = cp->state != cp->old_state; 481 force = cp->state != cp->old_state;
469 if (force && cp->state != IP_VS_SCTP_S_ESTABLISHED) 482 if (force && cp->state != IP_VS_SCTP_S_ESTABLISHED)
diff --git a/net/netfilter/ipvs/ip_vs_wlc.c b/net/netfilter/ipvs/ip_vs_wlc.c
index c60a81c4ce9a..6dc1fa128840 100644
--- a/net/netfilter/ipvs/ip_vs_wlc.c
+++ b/net/netfilter/ipvs/ip_vs_wlc.c
@@ -31,7 +31,8 @@
31 * Weighted Least Connection scheduling 31 * Weighted Least Connection scheduling
32 */ 32 */
33static struct ip_vs_dest * 33static struct ip_vs_dest *
34ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 34ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
35 struct ip_vs_iphdr *iph)
35{ 36{
36 struct ip_vs_dest *dest, *least; 37 struct ip_vs_dest *dest, *least;
37 unsigned int loh, doh; 38 unsigned int loh, doh;
diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c
index 0e68555bceb9..0546cd572d6b 100644
--- a/net/netfilter/ipvs/ip_vs_wrr.c
+++ b/net/netfilter/ipvs/ip_vs_wrr.c
@@ -162,7 +162,8 @@ static int ip_vs_wrr_dest_changed(struct ip_vs_service *svc,
162 * Weighted Round-Robin Scheduling 162 * Weighted Round-Robin Scheduling
163 */ 163 */
164static struct ip_vs_dest * 164static struct ip_vs_dest *
165ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 165ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
166 struct ip_vs_iphdr *iph)
166{ 167{
167 struct ip_vs_dest *dest, *last, *stop = NULL; 168 struct ip_vs_dest *dest, *last, *stop = NULL;
168 struct ip_vs_wrr_mark *mark = svc->sched_data; 169 struct ip_vs_wrr_mark *mark = svc->sched_data;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 6d0f8a17c5b7..f83a52298efe 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -828,7 +828,9 @@ ctnetlink_parse_tuple_ip(struct nlattr *attr, struct nf_conntrack_tuple *tuple)
828 struct nf_conntrack_l3proto *l3proto; 828 struct nf_conntrack_l3proto *l3proto;
829 int ret = 0; 829 int ret = 0;
830 830
831 nla_parse_nested(tb, CTA_IP_MAX, attr, NULL); 831 ret = nla_parse_nested(tb, CTA_IP_MAX, attr, NULL);
832 if (ret < 0)
833 return ret;
832 834
833 rcu_read_lock(); 835 rcu_read_lock();
834 l3proto = __nf_ct_l3proto_find(tuple->src.l3num); 836 l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
@@ -895,7 +897,9 @@ ctnetlink_parse_tuple(const struct nlattr * const cda[],
895 897
896 memset(tuple, 0, sizeof(*tuple)); 898 memset(tuple, 0, sizeof(*tuple));
897 899
898 nla_parse_nested(tb, CTA_TUPLE_MAX, cda[type], tuple_nla_policy); 900 err = nla_parse_nested(tb, CTA_TUPLE_MAX, cda[type], tuple_nla_policy);
901 if (err < 0)
902 return err;
899 903
900 if (!tb[CTA_TUPLE_IP]) 904 if (!tb[CTA_TUPLE_IP])
901 return -EINVAL; 905 return -EINVAL;
@@ -946,9 +950,12 @@ static inline int
946ctnetlink_parse_help(const struct nlattr *attr, char **helper_name, 950ctnetlink_parse_help(const struct nlattr *attr, char **helper_name,
947 struct nlattr **helpinfo) 951 struct nlattr **helpinfo)
948{ 952{
953 int err;
949 struct nlattr *tb[CTA_HELP_MAX+1]; 954 struct nlattr *tb[CTA_HELP_MAX+1];
950 955
951 nla_parse_nested(tb, CTA_HELP_MAX, attr, help_nla_policy); 956 err = nla_parse_nested(tb, CTA_HELP_MAX, attr, help_nla_policy);
957 if (err < 0)
958 return err;
952 959
953 if (!tb[CTA_HELP_NAME]) 960 if (!tb[CTA_HELP_NAME])
954 return -EINVAL; 961 return -EINVAL;
@@ -1431,7 +1438,9 @@ ctnetlink_change_protoinfo(struct nf_conn *ct, const struct nlattr * const cda[]
1431 struct nf_conntrack_l4proto *l4proto; 1438 struct nf_conntrack_l4proto *l4proto;
1432 int err = 0; 1439 int err = 0;
1433 1440
1434 nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, protoinfo_policy); 1441 err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, protoinfo_policy);
1442 if (err < 0)
1443 return err;
1435 1444
1436 rcu_read_lock(); 1445 rcu_read_lock();
1437 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); 1446 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
@@ -1452,9 +1461,12 @@ static const struct nla_policy nat_seq_policy[CTA_NAT_SEQ_MAX+1] = {
1452static inline int 1461static inline int
1453change_nat_seq_adj(struct nf_nat_seq *natseq, const struct nlattr * const attr) 1462change_nat_seq_adj(struct nf_nat_seq *natseq, const struct nlattr * const attr)
1454{ 1463{
1464 int err;
1455 struct nlattr *cda[CTA_NAT_SEQ_MAX+1]; 1465 struct nlattr *cda[CTA_NAT_SEQ_MAX+1];
1456 1466
1457 nla_parse_nested(cda, CTA_NAT_SEQ_MAX, attr, nat_seq_policy); 1467 err = nla_parse_nested(cda, CTA_NAT_SEQ_MAX, attr, nat_seq_policy);
1468 if (err < 0)
1469 return err;
1458 1470
1459 if (!cda[CTA_NAT_SEQ_CORRECTION_POS]) 1471 if (!cda[CTA_NAT_SEQ_CORRECTION_POS])
1460 return -EINVAL; 1472 return -EINVAL;
@@ -2115,7 +2127,9 @@ ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct)
2115 struct nlattr *cda[CTA_MAX+1]; 2127 struct nlattr *cda[CTA_MAX+1];
2116 int ret; 2128 int ret;
2117 2129
2118 nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy); 2130 ret = nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy);
2131 if (ret < 0)
2132 return ret;
2119 2133
2120 spin_lock_bh(&nf_conntrack_lock); 2134 spin_lock_bh(&nf_conntrack_lock);
2121 ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct); 2135 ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
@@ -2710,7 +2724,9 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr,
2710 struct nf_conntrack_tuple nat_tuple = {}; 2724 struct nf_conntrack_tuple nat_tuple = {};
2711 int err; 2725 int err;
2712 2726
2713 nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr, exp_nat_nla_policy); 2727 err = nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr, exp_nat_nla_policy);
2728 if (err < 0)
2729 return err;
2714 2730
2715 if (!tb[CTA_EXPECT_NAT_DIR] || !tb[CTA_EXPECT_NAT_TUPLE]) 2731 if (!tb[CTA_EXPECT_NAT_DIR] || !tb[CTA_EXPECT_NAT_TUPLE])
2716 return -EINVAL; 2732 return -EINVAL;
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 4d4d8f1d01fc..7dcc376eea5f 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1043,6 +1043,12 @@ static int tcp_packet(struct nf_conn *ct,
1043 nf_ct_kill_acct(ct, ctinfo, skb); 1043 nf_ct_kill_acct(ct, ctinfo, skb);
1044 return NF_ACCEPT; 1044 return NF_ACCEPT;
1045 } 1045 }
1046 /* ESTABLISHED without SEEN_REPLY, i.e. mid-connection
1047 * pickup with loose=1. Avoid large ESTABLISHED timeout.
1048 */
1049 if (new_state == TCP_CONNTRACK_ESTABLISHED &&
1050 timeout > timeouts[TCP_CONNTRACK_UNACK])
1051 timeout = timeouts[TCP_CONNTRACK_UNACK];
1046 } else if (!test_bit(IPS_ASSURED_BIT, &ct->status) 1052 } else if (!test_bit(IPS_ASSURED_BIT, &ct->status)
1047 && (old_state == TCP_CONNTRACK_SYN_RECV 1053 && (old_state == TCP_CONNTRACK_SYN_RECV
1048 || old_state == TCP_CONNTRACK_ESTABLISHED) 1054 || old_state == TCP_CONNTRACK_ESTABLISHED)
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index a191b6db657e..9e287cb56a04 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -67,9 +67,12 @@ static int
67nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, 67nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple,
68 const struct nlattr *attr) 68 const struct nlattr *attr)
69{ 69{
70 int err;
70 struct nlattr *tb[NFCTH_TUPLE_MAX+1]; 71 struct nlattr *tb[NFCTH_TUPLE_MAX+1];
71 72
72 nla_parse_nested(tb, NFCTH_TUPLE_MAX, attr, nfnl_cthelper_tuple_pol); 73 err = nla_parse_nested(tb, NFCTH_TUPLE_MAX, attr, nfnl_cthelper_tuple_pol);
74 if (err < 0)
75 return err;
73 76
74 if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM]) 77 if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM])
75 return -EINVAL; 78 return -EINVAL;
@@ -121,9 +124,12 @@ static int
121nfnl_cthelper_expect_policy(struct nf_conntrack_expect_policy *expect_policy, 124nfnl_cthelper_expect_policy(struct nf_conntrack_expect_policy *expect_policy,
122 const struct nlattr *attr) 125 const struct nlattr *attr)
123{ 126{
127 int err;
124 struct nlattr *tb[NFCTH_POLICY_MAX+1]; 128 struct nlattr *tb[NFCTH_POLICY_MAX+1];
125 129
126 nla_parse_nested(tb, NFCTH_POLICY_MAX, attr, nfnl_cthelper_expect_pol); 130 err = nla_parse_nested(tb, NFCTH_POLICY_MAX, attr, nfnl_cthelper_expect_pol);
131 if (err < 0)
132 return err;
127 133
128 if (!tb[NFCTH_POLICY_NAME] || 134 if (!tb[NFCTH_POLICY_NAME] ||
129 !tb[NFCTH_POLICY_EXPECT_MAX] || 135 !tb[NFCTH_POLICY_EXPECT_MAX] ||
@@ -153,8 +159,10 @@ nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper,
153 struct nf_conntrack_expect_policy *expect_policy; 159 struct nf_conntrack_expect_policy *expect_policy;
154 struct nlattr *tb[NFCTH_POLICY_SET_MAX+1]; 160 struct nlattr *tb[NFCTH_POLICY_SET_MAX+1];
155 161
156 nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr, 162 ret = nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr,
157 nfnl_cthelper_expect_policy_set); 163 nfnl_cthelper_expect_policy_set);
164 if (ret < 0)
165 return ret;
158 166
159 if (!tb[NFCTH_POLICY_SET_NUM]) 167 if (!tb[NFCTH_POLICY_SET_NUM])
160 return -EINVAL; 168 return -EINVAL;
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 65074dfb9383..50580494148d 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -59,8 +59,10 @@ ctnl_timeout_parse_policy(struct ctnl_timeout *timeout,
59 if (likely(l4proto->ctnl_timeout.nlattr_to_obj)) { 59 if (likely(l4proto->ctnl_timeout.nlattr_to_obj)) {
60 struct nlattr *tb[l4proto->ctnl_timeout.nlattr_max+1]; 60 struct nlattr *tb[l4proto->ctnl_timeout.nlattr_max+1];
61 61
62 nla_parse_nested(tb, l4proto->ctnl_timeout.nlattr_max, 62 ret = nla_parse_nested(tb, l4proto->ctnl_timeout.nlattr_max,
63 attr, l4proto->ctnl_timeout.nla_policy); 63 attr, l4proto->ctnl_timeout.nla_policy);
64 if (ret < 0)
65 return ret;
64 66
65 ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, 67 ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net,
66 &timeout->data); 68 &timeout->data);
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 299a48ae5dc9..971ea145ab3e 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -280,12 +280,17 @@ nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
280 skb_shinfo(to)->nr_frags = j; 280 skb_shinfo(to)->nr_frags = j;
281} 281}
282 282
283static int nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet) 283static int
284nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet,
285 bool csum_verify)
284{ 286{
285 __u32 flags = 0; 287 __u32 flags = 0;
286 288
287 if (packet->ip_summed == CHECKSUM_PARTIAL) 289 if (packet->ip_summed == CHECKSUM_PARTIAL)
288 flags = NFQA_SKB_CSUMNOTREADY; 290 flags = NFQA_SKB_CSUMNOTREADY;
291 else if (csum_verify)
292 flags = NFQA_SKB_CSUM_NOTVERIFIED;
293
289 if (skb_is_gso(packet)) 294 if (skb_is_gso(packet))
290 flags |= NFQA_SKB_GSO; 295 flags |= NFQA_SKB_GSO;
291 296
@@ -310,6 +315,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
310 struct net_device *outdev; 315 struct net_device *outdev;
311 struct nf_conn *ct = NULL; 316 struct nf_conn *ct = NULL;
312 enum ip_conntrack_info uninitialized_var(ctinfo); 317 enum ip_conntrack_info uninitialized_var(ctinfo);
318 bool csum_verify;
313 319
314 size = nlmsg_total_size(sizeof(struct nfgenmsg)) 320 size = nlmsg_total_size(sizeof(struct nfgenmsg))
315 + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) 321 + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -327,6 +333,12 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
327 if (entskb->tstamp.tv64) 333 if (entskb->tstamp.tv64)
328 size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp)); 334 size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
329 335
336 if (entry->hook <= NF_INET_FORWARD ||
337 (entry->hook == NF_INET_POST_ROUTING && entskb->sk == NULL))
338 csum_verify = !skb_csum_unnecessary(entskb);
339 else
340 csum_verify = false;
341
330 outdev = entry->outdev; 342 outdev = entry->outdev;
331 343
332 switch ((enum nfqnl_config_mode)ACCESS_ONCE(queue->copy_mode)) { 344 switch ((enum nfqnl_config_mode)ACCESS_ONCE(queue->copy_mode)) {
@@ -476,7 +488,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
476 nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len))) 488 nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len)))
477 goto nla_put_failure; 489 goto nla_put_failure;
478 490
479 if (nfqnl_put_packet_info(skb, entskb)) 491 if (nfqnl_put_packet_info(skb, entskb, csum_verify))
480 goto nla_put_failure; 492 goto nla_put_failure;
481 493
482 if (data_len) { 494 if (data_len) {
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index 02704245710e..f8b71911037a 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -163,8 +163,11 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
163 bool wildcard; 163 bool wildcard;
164 bool transparent = true; 164 bool transparent = true;
165 165
166 /* Ignore sockets listening on INADDR_ANY */ 166 /* Ignore sockets listening on INADDR_ANY,
167 wildcard = (sk->sk_state != TCP_TIME_WAIT && 167 * unless XT_SOCKET_NOWILDCARD is set
168 */
169 wildcard = (!(info->flags & XT_SOCKET_NOWILDCARD) &&
170 sk->sk_state != TCP_TIME_WAIT &&
168 inet_sk(sk)->inet_rcv_saddr == 0); 171 inet_sk(sk)->inet_rcv_saddr == 0);
169 172
170 /* Ignore non-transparent sockets, 173 /* Ignore non-transparent sockets,
@@ -197,7 +200,7 @@ socket_mt4_v0(const struct sk_buff *skb, struct xt_action_param *par)
197} 200}
198 201
199static bool 202static bool
200socket_mt4_v1(const struct sk_buff *skb, struct xt_action_param *par) 203socket_mt4_v1_v2(const struct sk_buff *skb, struct xt_action_param *par)
201{ 204{
202 return socket_match(skb, par, par->matchinfo); 205 return socket_match(skb, par, par->matchinfo);
203} 206}
@@ -259,7 +262,7 @@ extract_icmp6_fields(const struct sk_buff *skb,
259} 262}
260 263
261static bool 264static bool
262socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) 265socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par)
263{ 266{
264 struct ipv6hdr *iph = ipv6_hdr(skb); 267 struct ipv6hdr *iph = ipv6_hdr(skb);
265 struct udphdr _hdr, *hp = NULL; 268 struct udphdr _hdr, *hp = NULL;
@@ -302,8 +305,11 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
302 bool wildcard; 305 bool wildcard;
303 bool transparent = true; 306 bool transparent = true;
304 307
305 /* Ignore sockets listening on INADDR_ANY */ 308 /* Ignore sockets listening on INADDR_ANY
306 wildcard = (sk->sk_state != TCP_TIME_WAIT && 309 * unless XT_SOCKET_NOWILDCARD is set
310 */
311 wildcard = (!(info->flags & XT_SOCKET_NOWILDCARD) &&
312 sk->sk_state != TCP_TIME_WAIT &&
307 ipv6_addr_any(&inet6_sk(sk)->rcv_saddr)); 313 ipv6_addr_any(&inet6_sk(sk)->rcv_saddr));
308 314
309 /* Ignore non-transparent sockets, 315 /* Ignore non-transparent sockets,
@@ -331,6 +337,28 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
331} 337}
332#endif 338#endif
333 339
340static int socket_mt_v1_check(const struct xt_mtchk_param *par)
341{
342 const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
343
344 if (info->flags & ~XT_SOCKET_FLAGS_V1) {
345 pr_info("unknown flags 0x%x\n", info->flags & ~XT_SOCKET_FLAGS_V1);
346 return -EINVAL;
347 }
348 return 0;
349}
350
351static int socket_mt_v2_check(const struct xt_mtchk_param *par)
352{
353 const struct xt_socket_mtinfo2 *info = (struct xt_socket_mtinfo2 *) par->matchinfo;
354
355 if (info->flags & ~XT_SOCKET_FLAGS_V2) {
356 pr_info("unknown flags 0x%x\n", info->flags & ~XT_SOCKET_FLAGS_V2);
357 return -EINVAL;
358 }
359 return 0;
360}
361
334static struct xt_match socket_mt_reg[] __read_mostly = { 362static struct xt_match socket_mt_reg[] __read_mostly = {
335 { 363 {
336 .name = "socket", 364 .name = "socket",
@@ -345,7 +373,8 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
345 .name = "socket", 373 .name = "socket",
346 .revision = 1, 374 .revision = 1,
347 .family = NFPROTO_IPV4, 375 .family = NFPROTO_IPV4,
348 .match = socket_mt4_v1, 376 .match = socket_mt4_v1_v2,
377 .checkentry = socket_mt_v1_check,
349 .matchsize = sizeof(struct xt_socket_mtinfo1), 378 .matchsize = sizeof(struct xt_socket_mtinfo1),
350 .hooks = (1 << NF_INET_PRE_ROUTING) | 379 .hooks = (1 << NF_INET_PRE_ROUTING) |
351 (1 << NF_INET_LOCAL_IN), 380 (1 << NF_INET_LOCAL_IN),
@@ -356,7 +385,32 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
356 .name = "socket", 385 .name = "socket",
357 .revision = 1, 386 .revision = 1,
358 .family = NFPROTO_IPV6, 387 .family = NFPROTO_IPV6,
359 .match = socket_mt6_v1, 388 .match = socket_mt6_v1_v2,
389 .checkentry = socket_mt_v1_check,
390 .matchsize = sizeof(struct xt_socket_mtinfo1),
391 .hooks = (1 << NF_INET_PRE_ROUTING) |
392 (1 << NF_INET_LOCAL_IN),
393 .me = THIS_MODULE,
394 },
395#endif
396 {
397 .name = "socket",
398 .revision = 2,
399 .family = NFPROTO_IPV4,
400 .match = socket_mt4_v1_v2,
401 .checkentry = socket_mt_v2_check,
402 .matchsize = sizeof(struct xt_socket_mtinfo1),
403 .hooks = (1 << NF_INET_PRE_ROUTING) |
404 (1 << NF_INET_LOCAL_IN),
405 .me = THIS_MODULE,
406 },
407#ifdef XT_SOCKET_HAVE_IPV6
408 {
409 .name = "socket",
410 .revision = 2,
411 .family = NFPROTO_IPV6,
412 .match = socket_mt6_v1_v2,
413 .checkentry = socket_mt_v2_check,
360 .matchsize = sizeof(struct xt_socket_mtinfo1), 414 .matchsize = sizeof(struct xt_socket_mtinfo1),
361 .hooks = (1 << NF_INET_PRE_ROUTING) | 415 .hooks = (1 << NF_INET_PRE_ROUTING) |
362 (1 << NF_INET_LOCAL_IN), 416 (1 << NF_INET_LOCAL_IN),