aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-02 14:30:24 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-02 14:30:24 -0500
commit3872b284087081ee5cb0e4630954c2f7a2153cf5 (patch)
treeead36598e35730e419edcf42dc788290af9e3d5b /net
parent07df5294a753dfac2cc9f75e6159fc25fdc22149 (diff)
parent8a80c79a776d1b1b54895314ffaf53d0c7604c80 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/bridge/netfilter/ebtables.c2
-rw-r--r--net/netfilter/ipset/Kconfig1
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c52
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c28
-rw-r--r--net/netfilter/ipvs/ip_vs_lblc.c15
-rw-r--r--net/netfilter/ipvs/ip_vs_lblcr.c27
-rw-r--r--net/netfilter/ipvs/ip_vs_lc.c20
-rw-r--r--net/netfilter/ipvs/ip_vs_nq.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_rr.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_sched.c25
-rw-r--r--net/netfilter/ipvs/ip_vs_sed.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_sh.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c4
-rw-r--r--net/netfilter/ipvs/ip_vs_wlc.c22
-rw-r--r--net/netfilter/ipvs/ip_vs_wrr.c14
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c41
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c4
-rw-r--r--net/netfilter/nfnetlink_log.c3
-rw-r--r--net/netfilter/xt_conntrack.c5
19 files changed, 126 insertions, 145 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 5f1825df9dca..893669caa8de 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1107,6 +1107,8 @@ static int do_replace(struct net *net, const void __user *user,
1107 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) 1107 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
1108 return -ENOMEM; 1108 return -ENOMEM;
1109 1109
1110 tmp.name[sizeof(tmp.name) - 1] = 0;
1111
1110 countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids; 1112 countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids;
1111 newinfo = vmalloc(sizeof(*newinfo) + countersize); 1113 newinfo = vmalloc(sizeof(*newinfo) + countersize);
1112 if (!newinfo) 1114 if (!newinfo)
diff --git a/net/netfilter/ipset/Kconfig b/net/netfilter/ipset/Kconfig
index 3b970d343023..2c5b348eb3a8 100644
--- a/net/netfilter/ipset/Kconfig
+++ b/net/netfilter/ipset/Kconfig
@@ -1,6 +1,7 @@
1menuconfig IP_SET 1menuconfig IP_SET
2 tristate "IP set support" 2 tristate "IP set support"
3 depends on INET && NETFILTER 3 depends on INET && NETFILTER
4 depends on NETFILTER_NETLINK
4 help 5 help
5 This option adds IP set support to the kernel. 6 This option adds IP set support to the kernel.
6 In order to define and use the sets, you need the userspace utility 7 In order to define and use the sets, you need the userspace utility
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 83233fe24a08..9c2a517b69c8 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -59,7 +59,7 @@ static int ip_vs_conn_tab_mask __read_mostly;
59/* 59/*
60 * Connection hash table: for input and output packets lookups of IPVS 60 * Connection hash table: for input and output packets lookups of IPVS
61 */ 61 */
62static struct list_head *ip_vs_conn_tab __read_mostly; 62static struct hlist_head *ip_vs_conn_tab __read_mostly;
63 63
64/* SLAB cache for IPVS connections */ 64/* SLAB cache for IPVS connections */
65static struct kmem_cache *ip_vs_conn_cachep __read_mostly; 65static struct kmem_cache *ip_vs_conn_cachep __read_mostly;
@@ -201,7 +201,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)
201 spin_lock(&cp->lock); 201 spin_lock(&cp->lock);
202 202
203 if (!(cp->flags & IP_VS_CONN_F_HASHED)) { 203 if (!(cp->flags & IP_VS_CONN_F_HASHED)) {
204 list_add(&cp->c_list, &ip_vs_conn_tab[hash]); 204 hlist_add_head(&cp->c_list, &ip_vs_conn_tab[hash]);
205 cp->flags |= IP_VS_CONN_F_HASHED; 205 cp->flags |= IP_VS_CONN_F_HASHED;
206 atomic_inc(&cp->refcnt); 206 atomic_inc(&cp->refcnt);
207 ret = 1; 207 ret = 1;
@@ -234,7 +234,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
234 spin_lock(&cp->lock); 234 spin_lock(&cp->lock);
235 235
236 if (cp->flags & IP_VS_CONN_F_HASHED) { 236 if (cp->flags & IP_VS_CONN_F_HASHED) {
237 list_del(&cp->c_list); 237 hlist_del(&cp->c_list);
238 cp->flags &= ~IP_VS_CONN_F_HASHED; 238 cp->flags &= ~IP_VS_CONN_F_HASHED;
239 atomic_dec(&cp->refcnt); 239 atomic_dec(&cp->refcnt);
240 ret = 1; 240 ret = 1;
@@ -259,12 +259,13 @@ __ip_vs_conn_in_get(const struct ip_vs_conn_param *p)
259{ 259{
260 unsigned hash; 260 unsigned hash;
261 struct ip_vs_conn *cp; 261 struct ip_vs_conn *cp;
262 struct hlist_node *n;
262 263
263 hash = ip_vs_conn_hashkey_param(p, false); 264 hash = ip_vs_conn_hashkey_param(p, false);
264 265
265 ct_read_lock(hash); 266 ct_read_lock(hash);
266 267
267 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { 268 hlist_for_each_entry(cp, n, &ip_vs_conn_tab[hash], c_list) {
268 if (cp->af == p->af && 269 if (cp->af == p->af &&
269 p->cport == cp->cport && p->vport == cp->vport && 270 p->cport == cp->cport && p->vport == cp->vport &&
270 ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) && 271 ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) &&
@@ -345,12 +346,13 @@ struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p)
345{ 346{
346 unsigned hash; 347 unsigned hash;
347 struct ip_vs_conn *cp; 348 struct ip_vs_conn *cp;
349 struct hlist_node *n;
348 350
349 hash = ip_vs_conn_hashkey_param(p, false); 351 hash = ip_vs_conn_hashkey_param(p, false);
350 352
351 ct_read_lock(hash); 353 ct_read_lock(hash);
352 354
353 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { 355 hlist_for_each_entry(cp, n, &ip_vs_conn_tab[hash], c_list) {
354 if (!ip_vs_conn_net_eq(cp, p->net)) 356 if (!ip_vs_conn_net_eq(cp, p->net))
355 continue; 357 continue;
356 if (p->pe_data && p->pe->ct_match) { 358 if (p->pe_data && p->pe->ct_match) {
@@ -394,6 +396,7 @@ struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p)
394{ 396{
395 unsigned hash; 397 unsigned hash;
396 struct ip_vs_conn *cp, *ret=NULL; 398 struct ip_vs_conn *cp, *ret=NULL;
399 struct hlist_node *n;
397 400
398 /* 401 /*
399 * Check for "full" addressed entries 402 * Check for "full" addressed entries
@@ -402,7 +405,7 @@ struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p)
402 405
403 ct_read_lock(hash); 406 ct_read_lock(hash);
404 407
405 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { 408 hlist_for_each_entry(cp, n, &ip_vs_conn_tab[hash], c_list) {
406 if (cp->af == p->af && 409 if (cp->af == p->af &&
407 p->vport == cp->cport && p->cport == cp->dport && 410 p->vport == cp->cport && p->cport == cp->dport &&
408 ip_vs_addr_equal(p->af, p->vaddr, &cp->caddr) && 411 ip_vs_addr_equal(p->af, p->vaddr, &cp->caddr) &&
@@ -818,7 +821,7 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p,
818 return NULL; 821 return NULL;
819 } 822 }
820 823
821 INIT_LIST_HEAD(&cp->c_list); 824 INIT_HLIST_NODE(&cp->c_list);
822 setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp); 825 setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp);
823 ip_vs_conn_net_set(cp, p->net); 826 ip_vs_conn_net_set(cp, p->net);
824 cp->af = p->af; 827 cp->af = p->af;
@@ -894,8 +897,8 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p,
894 */ 897 */
895#ifdef CONFIG_PROC_FS 898#ifdef CONFIG_PROC_FS
896struct ip_vs_iter_state { 899struct ip_vs_iter_state {
897 struct seq_net_private p; 900 struct seq_net_private p;
898 struct list_head *l; 901 struct hlist_head *l;
899}; 902};
900 903
901static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos) 904static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos)
@@ -903,13 +906,14 @@ static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos)
903 int idx; 906 int idx;
904 struct ip_vs_conn *cp; 907 struct ip_vs_conn *cp;
905 struct ip_vs_iter_state *iter = seq->private; 908 struct ip_vs_iter_state *iter = seq->private;
909 struct hlist_node *n;
906 910
907 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) { 911 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
908 ct_read_lock_bh(idx); 912 ct_read_lock_bh(idx);
909 list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { 913 hlist_for_each_entry(cp, n, &ip_vs_conn_tab[idx], c_list) {
910 if (pos-- == 0) { 914 if (pos-- == 0) {
911 iter->l = &ip_vs_conn_tab[idx]; 915 iter->l = &ip_vs_conn_tab[idx];
912 return cp; 916 return cp;
913 } 917 }
914 } 918 }
915 ct_read_unlock_bh(idx); 919 ct_read_unlock_bh(idx);
@@ -930,7 +934,8 @@ static void *ip_vs_conn_seq_next(struct seq_file *seq, void *v, loff_t *pos)
930{ 934{
931 struct ip_vs_conn *cp = v; 935 struct ip_vs_conn *cp = v;
932 struct ip_vs_iter_state *iter = seq->private; 936 struct ip_vs_iter_state *iter = seq->private;
933 struct list_head *e, *l = iter->l; 937 struct hlist_node *e;
938 struct hlist_head *l = iter->l;
934 int idx; 939 int idx;
935 940
936 ++*pos; 941 ++*pos;
@@ -938,15 +943,15 @@ static void *ip_vs_conn_seq_next(struct seq_file *seq, void *v, loff_t *pos)
938 return ip_vs_conn_array(seq, 0); 943 return ip_vs_conn_array(seq, 0);
939 944
940 /* more on same hash chain? */ 945 /* more on same hash chain? */
941 if ((e = cp->c_list.next) != l) 946 if ((e = cp->c_list.next))
942 return list_entry(e, struct ip_vs_conn, c_list); 947 return hlist_entry(e, struct ip_vs_conn, c_list);
943 948
944 idx = l - ip_vs_conn_tab; 949 idx = l - ip_vs_conn_tab;
945 ct_read_unlock_bh(idx); 950 ct_read_unlock_bh(idx);
946 951
947 while (++idx < ip_vs_conn_tab_size) { 952 while (++idx < ip_vs_conn_tab_size) {
948 ct_read_lock_bh(idx); 953 ct_read_lock_bh(idx);
949 list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { 954 hlist_for_each_entry(cp, e, &ip_vs_conn_tab[idx], c_list) {
950 iter->l = &ip_vs_conn_tab[idx]; 955 iter->l = &ip_vs_conn_tab[idx];
951 return cp; 956 return cp;
952 } 957 }
@@ -959,7 +964,7 @@ static void *ip_vs_conn_seq_next(struct seq_file *seq, void *v, loff_t *pos)
959static void ip_vs_conn_seq_stop(struct seq_file *seq, void *v) 964static void ip_vs_conn_seq_stop(struct seq_file *seq, void *v)
960{ 965{
961 struct ip_vs_iter_state *iter = seq->private; 966 struct ip_vs_iter_state *iter = seq->private;
962 struct list_head *l = iter->l; 967 struct hlist_head *l = iter->l;
963 968
964 if (l) 969 if (l)
965 ct_read_unlock_bh(l - ip_vs_conn_tab); 970 ct_read_unlock_bh(l - ip_vs_conn_tab);
@@ -1148,13 +1153,14 @@ void ip_vs_random_dropentry(struct net *net)
1148 */ 1153 */
1149 for (idx = 0; idx < (ip_vs_conn_tab_size>>5); idx++) { 1154 for (idx = 0; idx < (ip_vs_conn_tab_size>>5); idx++) {
1150 unsigned hash = net_random() & ip_vs_conn_tab_mask; 1155 unsigned hash = net_random() & ip_vs_conn_tab_mask;
1156 struct hlist_node *n;
1151 1157
1152 /* 1158 /*
1153 * Lock is actually needed in this loop. 1159 * Lock is actually needed in this loop.
1154 */ 1160 */
1155 ct_write_lock_bh(hash); 1161 ct_write_lock_bh(hash);
1156 1162
1157 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { 1163 hlist_for_each_entry(cp, n, &ip_vs_conn_tab[hash], c_list) {
1158 if (cp->flags & IP_VS_CONN_F_TEMPLATE) 1164 if (cp->flags & IP_VS_CONN_F_TEMPLATE)
1159 /* connection template */ 1165 /* connection template */
1160 continue; 1166 continue;
@@ -1202,12 +1208,14 @@ static void ip_vs_conn_flush(struct net *net)
1202 1208
1203flush_again: 1209flush_again:
1204 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) { 1210 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
1211 struct hlist_node *n;
1212
1205 /* 1213 /*
1206 * Lock is actually needed in this loop. 1214 * Lock is actually needed in this loop.
1207 */ 1215 */
1208 ct_write_lock_bh(idx); 1216 ct_write_lock_bh(idx);
1209 1217
1210 list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { 1218 hlist_for_each_entry(cp, n, &ip_vs_conn_tab[idx], c_list) {
1211 if (!ip_vs_conn_net_eq(cp, net)) 1219 if (!ip_vs_conn_net_eq(cp, net))
1212 continue; 1220 continue;
1213 IP_VS_DBG(4, "del connection\n"); 1221 IP_VS_DBG(4, "del connection\n");
@@ -1265,8 +1273,7 @@ int __init ip_vs_conn_init(void)
1265 /* 1273 /*
1266 * Allocate the connection hash table and initialize its list heads 1274 * Allocate the connection hash table and initialize its list heads
1267 */ 1275 */
1268 ip_vs_conn_tab = vmalloc(ip_vs_conn_tab_size * 1276 ip_vs_conn_tab = vmalloc(ip_vs_conn_tab_size * sizeof(*ip_vs_conn_tab));
1269 sizeof(struct list_head));
1270 if (!ip_vs_conn_tab) 1277 if (!ip_vs_conn_tab)
1271 return -ENOMEM; 1278 return -ENOMEM;
1272 1279
@@ -1286,9 +1293,8 @@ int __init ip_vs_conn_init(void)
1286 IP_VS_DBG(0, "Each connection entry needs %Zd bytes at least\n", 1293 IP_VS_DBG(0, "Each connection entry needs %Zd bytes at least\n",
1287 sizeof(struct ip_vs_conn)); 1294 sizeof(struct ip_vs_conn));
1288 1295
1289 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) { 1296 for (idx = 0; idx < ip_vs_conn_tab_size; idx++)
1290 INIT_LIST_HEAD(&ip_vs_conn_tab[idx]); 1297 INIT_HLIST_HEAD(&ip_vs_conn_tab[idx]);
1291 }
1292 1298
1293 for (idx = 0; idx < CT_LOCKARRAY_SIZE; idx++) { 1299 for (idx = 0; idx < CT_LOCKARRAY_SIZE; idx++) {
1294 rwlock_init(&__ip_vs_conntbl_lock_array[idx].l); 1300 rwlock_init(&__ip_vs_conntbl_lock_array[idx].l);
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 4d06617fab6c..2d1f932add46 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -729,7 +729,7 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
729#endif 729#endif
730 730
731/* Handle relevant response ICMP messages - forward to the right 731/* Handle relevant response ICMP messages - forward to the right
732 * destination host. Used for NAT and local client. 732 * destination host.
733 */ 733 */
734static int handle_response_icmp(int af, struct sk_buff *skb, 734static int handle_response_icmp(int af, struct sk_buff *skb,
735 union nf_inet_addr *snet, 735 union nf_inet_addr *snet,
@@ -979,7 +979,6 @@ static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len)
979} 979}
980 980
981/* Handle response packets: rewrite addresses and send away... 981/* Handle response packets: rewrite addresses and send away...
982 * Used for NAT and local client.
983 */ 982 */
984static unsigned int 983static unsigned int
985handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, 984handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
@@ -1280,7 +1279,6 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1280 struct ip_vs_protocol *pp; 1279 struct ip_vs_protocol *pp;
1281 struct ip_vs_proto_data *pd; 1280 struct ip_vs_proto_data *pd;
1282 unsigned int offset, ihl, verdict; 1281 unsigned int offset, ihl, verdict;
1283 union nf_inet_addr snet;
1284 1282
1285 *related = 1; 1283 *related = 1;
1286 1284
@@ -1339,17 +1337,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1339 ip_vs_fill_iphdr(AF_INET, cih, &ciph); 1337 ip_vs_fill_iphdr(AF_INET, cih, &ciph);
1340 /* The embedded headers contain source and dest in reverse order */ 1338 /* The embedded headers contain source and dest in reverse order */
1341 cp = pp->conn_in_get(AF_INET, skb, &ciph, offset, 1); 1339 cp = pp->conn_in_get(AF_INET, skb, &ciph, offset, 1);
1342 if (!cp) { 1340 if (!cp)
1343 /* The packet could also belong to a local client */
1344 cp = pp->conn_out_get(AF_INET, skb, &ciph, offset, 1);
1345 if (cp) {
1346 snet.ip = iph->saddr;
1347 return handle_response_icmp(AF_INET, skb, &snet,
1348 cih->protocol, cp, pp,
1349 offset, ihl);
1350 }
1351 return NF_ACCEPT; 1341 return NF_ACCEPT;
1352 }
1353 1342
1354 verdict = NF_DROP; 1343 verdict = NF_DROP;
1355 1344
@@ -1395,7 +1384,6 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1395 struct ip_vs_protocol *pp; 1384 struct ip_vs_protocol *pp;
1396 struct ip_vs_proto_data *pd; 1385 struct ip_vs_proto_data *pd;
1397 unsigned int offset, verdict; 1386 unsigned int offset, verdict;
1398 union nf_inet_addr snet;
1399 struct rt6_info *rt; 1387 struct rt6_info *rt;
1400 1388
1401 *related = 1; 1389 *related = 1;
@@ -1455,18 +1443,8 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1455 ip_vs_fill_iphdr(AF_INET6, cih, &ciph); 1443 ip_vs_fill_iphdr(AF_INET6, cih, &ciph);
1456 /* The embedded headers contain source and dest in reverse order */ 1444 /* The embedded headers contain source and dest in reverse order */
1457 cp = pp->conn_in_get(AF_INET6, skb, &ciph, offset, 1); 1445 cp = pp->conn_in_get(AF_INET6, skb, &ciph, offset, 1);
1458 if (!cp) { 1446 if (!cp)
1459 /* The packet could also belong to a local client */
1460 cp = pp->conn_out_get(AF_INET6, skb, &ciph, offset, 1);
1461 if (cp) {
1462 ipv6_addr_copy(&snet.in6, &iph->saddr);
1463 return handle_response_icmp(AF_INET6, skb, &snet,
1464 cih->nexthdr,
1465 cp, pp, offset,
1466 sizeof(struct ipv6hdr));
1467 }
1468 return NF_ACCEPT; 1447 return NF_ACCEPT;
1469 }
1470 1448
1471 verdict = NF_DROP; 1449 verdict = NF_DROP;
1472 1450
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 00b5ffab3768..6bf7a807649c 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -389,12 +389,7 @@ __ip_vs_lblc_schedule(struct ip_vs_service *svc)
389 int loh, doh; 389 int loh, doh;
390 390
391 /* 391 /*
392 * We think the overhead of processing active connections is fifty 392 * We use the following formula to estimate the load:
393 * times higher than that of inactive connections in average. (This
394 * fifty times might not be accurate, we will change it later.) We
395 * use the following formula to estimate the overhead:
396 * dest->activeconns*50 + dest->inactconns
397 * and the load:
398 * (dest overhead) / dest->weight 393 * (dest overhead) / dest->weight
399 * 394 *
400 * Remember -- no floats in kernel mode!!! 395 * Remember -- no floats in kernel mode!!!
@@ -410,8 +405,7 @@ __ip_vs_lblc_schedule(struct ip_vs_service *svc)
410 continue; 405 continue;
411 if (atomic_read(&dest->weight) > 0) { 406 if (atomic_read(&dest->weight) > 0) {
412 least = dest; 407 least = dest;
413 loh = atomic_read(&least->activeconns) * 50 408 loh = ip_vs_dest_conn_overhead(least);
414 + atomic_read(&least->inactconns);
415 goto nextstage; 409 goto nextstage;
416 } 410 }
417 } 411 }
@@ -425,8 +419,7 @@ __ip_vs_lblc_schedule(struct ip_vs_service *svc)
425 if (dest->flags & IP_VS_DEST_F_OVERLOAD) 419 if (dest->flags & IP_VS_DEST_F_OVERLOAD)
426 continue; 420 continue;
427 421
428 doh = atomic_read(&dest->activeconns) * 50 422 doh = ip_vs_dest_conn_overhead(dest);
429 + atomic_read(&dest->inactconns);
430 if (loh * atomic_read(&dest->weight) > 423 if (loh * atomic_read(&dest->weight) >
431 doh * atomic_read(&least->weight)) { 424 doh * atomic_read(&least->weight)) {
432 least = dest; 425 least = dest;
@@ -510,7 +503,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
510 /* No cache entry or it is invalid, time to schedule */ 503 /* No cache entry or it is invalid, time to schedule */
511 dest = __ip_vs_lblc_schedule(svc); 504 dest = __ip_vs_lblc_schedule(svc);
512 if (!dest) { 505 if (!dest) {
513 IP_VS_ERR_RL("LBLC: no destination available\n"); 506 ip_vs_scheduler_err(svc, "no destination available");
514 return NULL; 507 return NULL;
515 } 508 }
516 509
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index bfa25f1ea9e4..00631765b92a 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -178,8 +178,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
178 178
179 if ((atomic_read(&least->weight) > 0) 179 if ((atomic_read(&least->weight) > 0)
180 && (least->flags & IP_VS_DEST_F_AVAILABLE)) { 180 && (least->flags & IP_VS_DEST_F_AVAILABLE)) {
181 loh = atomic_read(&least->activeconns) * 50 181 loh = ip_vs_dest_conn_overhead(least);
182 + atomic_read(&least->inactconns);
183 goto nextstage; 182 goto nextstage;
184 } 183 }
185 } 184 }
@@ -192,8 +191,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
192 if (dest->flags & IP_VS_DEST_F_OVERLOAD) 191 if (dest->flags & IP_VS_DEST_F_OVERLOAD)
193 continue; 192 continue;
194 193
195 doh = atomic_read(&dest->activeconns) * 50 194 doh = ip_vs_dest_conn_overhead(dest);
196 + atomic_read(&dest->inactconns);
197 if ((loh * atomic_read(&dest->weight) > 195 if ((loh * atomic_read(&dest->weight) >
198 doh * atomic_read(&least->weight)) 196 doh * atomic_read(&least->weight))
199 && (dest->flags & IP_VS_DEST_F_AVAILABLE)) { 197 && (dest->flags & IP_VS_DEST_F_AVAILABLE)) {
@@ -228,8 +226,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
228 list_for_each_entry(e, &set->list, list) { 226 list_for_each_entry(e, &set->list, list) {
229 most = e->dest; 227 most = e->dest;
230 if (atomic_read(&most->weight) > 0) { 228 if (atomic_read(&most->weight) > 0) {
231 moh = atomic_read(&most->activeconns) * 50 229 moh = ip_vs_dest_conn_overhead(most);
232 + atomic_read(&most->inactconns);
233 goto nextstage; 230 goto nextstage;
234 } 231 }
235 } 232 }
@@ -239,8 +236,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
239 nextstage: 236 nextstage:
240 list_for_each_entry(e, &set->list, list) { 237 list_for_each_entry(e, &set->list, list) {
241 dest = e->dest; 238 dest = e->dest;
242 doh = atomic_read(&dest->activeconns) * 50 239 doh = ip_vs_dest_conn_overhead(dest);
243 + atomic_read(&dest->inactconns);
244 /* moh/mw < doh/dw ==> moh*dw < doh*mw, where mw,dw>0 */ 240 /* moh/mw < doh/dw ==> moh*dw < doh*mw, where mw,dw>0 */
245 if ((moh * atomic_read(&dest->weight) < 241 if ((moh * atomic_read(&dest->weight) <
246 doh * atomic_read(&most->weight)) 242 doh * atomic_read(&most->weight))
@@ -563,12 +559,7 @@ __ip_vs_lblcr_schedule(struct ip_vs_service *svc)
563 int loh, doh; 559 int loh, doh;
564 560
565 /* 561 /*
566 * We think the overhead of processing active connections is fifty 562 * We use the following formula to estimate the load:
567 * times higher than that of inactive connections in average. (This
568 * fifty times might not be accurate, we will change it later.) We
569 * use the following formula to estimate the overhead:
570 * dest->activeconns*50 + dest->inactconns
571 * and the load:
572 * (dest overhead) / dest->weight 563 * (dest overhead) / dest->weight
573 * 564 *
574 * Remember -- no floats in kernel mode!!! 565 * Remember -- no floats in kernel mode!!!
@@ -585,8 +576,7 @@ __ip_vs_lblcr_schedule(struct ip_vs_service *svc)
585 576
586 if (atomic_read(&dest->weight) > 0) { 577 if (atomic_read(&dest->weight) > 0) {
587 least = dest; 578 least = dest;
588 loh = atomic_read(&least->activeconns) * 50 579 loh = ip_vs_dest_conn_overhead(least);
589 + atomic_read(&least->inactconns);
590 goto nextstage; 580 goto nextstage;
591 } 581 }
592 } 582 }
@@ -600,8 +590,7 @@ __ip_vs_lblcr_schedule(struct ip_vs_service *svc)
600 if (dest->flags & IP_VS_DEST_F_OVERLOAD) 590 if (dest->flags & IP_VS_DEST_F_OVERLOAD)
601 continue; 591 continue;
602 592
603 doh = atomic_read(&dest->activeconns) * 50 593 doh = ip_vs_dest_conn_overhead(dest);
604 + atomic_read(&dest->inactconns);
605 if (loh * atomic_read(&dest->weight) > 594 if (loh * atomic_read(&dest->weight) >
606 doh * atomic_read(&least->weight)) { 595 doh * atomic_read(&least->weight)) {
607 least = dest; 596 least = dest;
@@ -692,7 +681,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
692 /* The cache entry is invalid, time to schedule */ 681 /* The cache entry is invalid, time to schedule */
693 dest = __ip_vs_lblcr_schedule(svc); 682 dest = __ip_vs_lblcr_schedule(svc);
694 if (!dest) { 683 if (!dest) {
695 IP_VS_ERR_RL("LBLCR: no destination available\n"); 684 ip_vs_scheduler_err(svc, "no destination available");
696 read_unlock(&svc->sched_lock); 685 read_unlock(&svc->sched_lock);
697 return NULL; 686 return NULL;
698 } 687 }
diff --git a/net/netfilter/ipvs/ip_vs_lc.c b/net/netfilter/ipvs/ip_vs_lc.c
index 4f69db1fac56..f391819c0cca 100644
--- a/net/netfilter/ipvs/ip_vs_lc.c
+++ b/net/netfilter/ipvs/ip_vs_lc.c
@@ -22,22 +22,6 @@
22 22
23#include <net/ip_vs.h> 23#include <net/ip_vs.h>
24 24
25
26static inline unsigned int
27ip_vs_lc_dest_overhead(struct ip_vs_dest *dest)
28{
29 /*
30 * We think the overhead of processing active connections is 256
31 * times higher than that of inactive connections in average. (This
32 * 256 times might not be accurate, we will change it later) We
33 * use the following formula to estimate the overhead now:
34 * dest->activeconns*256 + dest->inactconns
35 */
36 return (atomic_read(&dest->activeconns) << 8) +
37 atomic_read(&dest->inactconns);
38}
39
40
41/* 25/*
42 * Least Connection scheduling 26 * Least Connection scheduling
43 */ 27 */
@@ -62,7 +46,7 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
62 if ((dest->flags & IP_VS_DEST_F_OVERLOAD) || 46 if ((dest->flags & IP_VS_DEST_F_OVERLOAD) ||
63 atomic_read(&dest->weight) == 0) 47 atomic_read(&dest->weight) == 0)
64 continue; 48 continue;
65 doh = ip_vs_lc_dest_overhead(dest); 49 doh = ip_vs_dest_conn_overhead(dest);
66 if (!least || doh < loh) { 50 if (!least || doh < loh) {
67 least = dest; 51 least = dest;
68 loh = doh; 52 loh = doh;
@@ -70,7 +54,7 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
70 } 54 }
71 55
72 if (!least) 56 if (!least)
73 IP_VS_ERR_RL("LC: no destination available\n"); 57 ip_vs_scheduler_err(svc, "no destination available");
74 else 58 else
75 IP_VS_DBG_BUF(6, "LC: server %s:%u activeconns %d " 59 IP_VS_DBG_BUF(6, "LC: server %s:%u activeconns %d "
76 "inactconns %d\n", 60 "inactconns %d\n",
diff --git a/net/netfilter/ipvs/ip_vs_nq.c b/net/netfilter/ipvs/ip_vs_nq.c
index c413e1830823..984d9c137d84 100644
--- a/net/netfilter/ipvs/ip_vs_nq.c
+++ b/net/netfilter/ipvs/ip_vs_nq.c
@@ -99,7 +99,7 @@ ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
99 } 99 }
100 100
101 if (!least) { 101 if (!least) {
102 IP_VS_ERR_RL("NQ: no destination available\n"); 102 ip_vs_scheduler_err(svc, "no destination available");
103 return NULL; 103 return NULL;
104 } 104 }
105 105
diff --git a/net/netfilter/ipvs/ip_vs_rr.c b/net/netfilter/ipvs/ip_vs_rr.c
index e210f37d8ea2..c49b388d1085 100644
--- a/net/netfilter/ipvs/ip_vs_rr.c
+++ b/net/netfilter/ipvs/ip_vs_rr.c
@@ -72,7 +72,7 @@ ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
72 q = q->next; 72 q = q->next;
73 } while (q != p); 73 } while (q != p);
74 write_unlock(&svc->sched_lock); 74 write_unlock(&svc->sched_lock);
75 IP_VS_ERR_RL("RR: no destination available\n"); 75 ip_vs_scheduler_err(svc, "no destination available");
76 return NULL; 76 return NULL;
77 77
78 out: 78 out:
diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c
index 076ebe00435d..08dbdd5bc18f 100644
--- a/net/netfilter/ipvs/ip_vs_sched.c
+++ b/net/netfilter/ipvs/ip_vs_sched.c
@@ -29,6 +29,7 @@
29 29
30#include <net/ip_vs.h> 30#include <net/ip_vs.h>
31 31
32EXPORT_SYMBOL(ip_vs_scheduler_err);
32/* 33/*
33 * IPVS scheduler list 34 * IPVS scheduler list
34 */ 35 */
@@ -146,6 +147,30 @@ void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler)
146 module_put(scheduler->module); 147 module_put(scheduler->module);
147} 148}
148 149
150/*
151 * Common error output helper for schedulers
152 */
153
154void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg)
155{
156 if (svc->fwmark) {
157 IP_VS_ERR_RL("%s: FWM %u 0x%08X - %s\n",
158 svc->scheduler->name, svc->fwmark,
159 svc->fwmark, msg);
160#ifdef CONFIG_IP_VS_IPV6
161 } else if (svc->af == AF_INET6) {
162 IP_VS_ERR_RL("%s: %s [%pI6]:%d - %s\n",
163 svc->scheduler->name,
164 ip_vs_proto_name(svc->protocol),
165 &svc->addr.in6, ntohs(svc->port), msg);
166#endif
167 } else {
168 IP_VS_ERR_RL("%s: %s %pI4:%d - %s\n",
169 svc->scheduler->name,
170 ip_vs_proto_name(svc->protocol),
171 &svc->addr.ip, ntohs(svc->port), msg);
172 }
173}
149 174
150/* 175/*
151 * Register a scheduler in the scheduler list 176 * Register a scheduler in the scheduler list
diff --git a/net/netfilter/ipvs/ip_vs_sed.c b/net/netfilter/ipvs/ip_vs_sed.c
index 1ab75a9dc400..89ead246ed3d 100644
--- a/net/netfilter/ipvs/ip_vs_sed.c
+++ b/net/netfilter/ipvs/ip_vs_sed.c
@@ -87,7 +87,7 @@ ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
87 goto nextstage; 87 goto nextstage;
88 } 88 }
89 } 89 }
90 IP_VS_ERR_RL("SED: no destination available\n"); 90 ip_vs_scheduler_err(svc, "no destination available");
91 return NULL; 91 return NULL;
92 92
93 /* 93 /*
diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c
index e6cc174fbc06..b5e2556c581a 100644
--- a/net/netfilter/ipvs/ip_vs_sh.c
+++ b/net/netfilter/ipvs/ip_vs_sh.c
@@ -223,7 +223,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
223 || !(dest->flags & IP_VS_DEST_F_AVAILABLE) 223 || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
224 || atomic_read(&dest->weight) <= 0 224 || atomic_read(&dest->weight) <= 0
225 || is_overloaded(dest)) { 225 || is_overloaded(dest)) {
226 IP_VS_ERR_RL("SH: no destination available\n"); 226 ip_vs_scheduler_err(svc, "no destination available");
227 return NULL; 227 return NULL;
228 } 228 }
229 229
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index d1b7298e5894..fecf24de4af3 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -374,8 +374,8 @@ get_curr_sync_buff(struct netns_ipvs *ipvs, unsigned long time)
374 struct ip_vs_sync_buff *sb; 374 struct ip_vs_sync_buff *sb;
375 375
376 spin_lock_bh(&ipvs->sync_buff_lock); 376 spin_lock_bh(&ipvs->sync_buff_lock);
377 if (ipvs->sync_buff && (time == 0 || 377 if (ipvs->sync_buff &&
378 time_before(jiffies - ipvs->sync_buff->firstuse, time))) { 378 time_after_eq(jiffies - ipvs->sync_buff->firstuse, time)) {
379 sb = ipvs->sync_buff; 379 sb = ipvs->sync_buff;
380 ipvs->sync_buff = NULL; 380 ipvs->sync_buff = NULL;
381 } else 381 } else
diff --git a/net/netfilter/ipvs/ip_vs_wlc.c b/net/netfilter/ipvs/ip_vs_wlc.c
index bbddfdb10db2..bc1bfc48a17f 100644
--- a/net/netfilter/ipvs/ip_vs_wlc.c
+++ b/net/netfilter/ipvs/ip_vs_wlc.c
@@ -27,22 +27,6 @@
27 27
28#include <net/ip_vs.h> 28#include <net/ip_vs.h>
29 29
30
31static inline unsigned int
32ip_vs_wlc_dest_overhead(struct ip_vs_dest *dest)
33{
34 /*
35 * We think the overhead of processing active connections is 256
36 * times higher than that of inactive connections in average. (This
37 * 256 times might not be accurate, we will change it later) We
38 * use the following formula to estimate the overhead now:
39 * dest->activeconns*256 + dest->inactconns
40 */
41 return (atomic_read(&dest->activeconns) << 8) +
42 atomic_read(&dest->inactconns);
43}
44
45
46/* 30/*
47 * Weighted Least Connection scheduling 31 * Weighted Least Connection scheduling
48 */ 32 */
@@ -71,11 +55,11 @@ ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
71 if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) && 55 if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
72 atomic_read(&dest->weight) > 0) { 56 atomic_read(&dest->weight) > 0) {
73 least = dest; 57 least = dest;
74 loh = ip_vs_wlc_dest_overhead(least); 58 loh = ip_vs_dest_conn_overhead(least);
75 goto nextstage; 59 goto nextstage;
76 } 60 }
77 } 61 }
78 IP_VS_ERR_RL("WLC: no destination available\n"); 62 ip_vs_scheduler_err(svc, "no destination available");
79 return NULL; 63 return NULL;
80 64
81 /* 65 /*
@@ -85,7 +69,7 @@ ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
85 list_for_each_entry_continue(dest, &svc->destinations, n_list) { 69 list_for_each_entry_continue(dest, &svc->destinations, n_list) {
86 if (dest->flags & IP_VS_DEST_F_OVERLOAD) 70 if (dest->flags & IP_VS_DEST_F_OVERLOAD)
87 continue; 71 continue;
88 doh = ip_vs_wlc_dest_overhead(dest); 72 doh = ip_vs_dest_conn_overhead(dest);
89 if (loh * atomic_read(&dest->weight) > 73 if (loh * atomic_read(&dest->weight) >
90 doh * atomic_read(&least->weight)) { 74 doh * atomic_read(&least->weight)) {
91 least = dest; 75 least = dest;
diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c
index 30db633f88f1..1ef41f50723c 100644
--- a/net/netfilter/ipvs/ip_vs_wrr.c
+++ b/net/netfilter/ipvs/ip_vs_wrr.c
@@ -147,8 +147,9 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
147 147
148 if (mark->cl == mark->cl->next) { 148 if (mark->cl == mark->cl->next) {
149 /* no dest entry */ 149 /* no dest entry */
150 IP_VS_ERR_RL("WRR: no destination available: " 150 ip_vs_scheduler_err(svc,
151 "no destinations present\n"); 151 "no destination available: "
152 "no destinations present");
152 dest = NULL; 153 dest = NULL;
153 goto out; 154 goto out;
154 } 155 }
@@ -162,8 +163,8 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
162 */ 163 */
163 if (mark->cw == 0) { 164 if (mark->cw == 0) {
164 mark->cl = &svc->destinations; 165 mark->cl = &svc->destinations;
165 IP_VS_ERR_RL("WRR: no destination " 166 ip_vs_scheduler_err(svc,
166 "available\n"); 167 "no destination available");
167 dest = NULL; 168 dest = NULL;
168 goto out; 169 goto out;
169 } 170 }
@@ -185,8 +186,9 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
185 /* back to the start, and no dest is found. 186 /* back to the start, and no dest is found.
186 It is only possible when all dests are OVERLOADED */ 187 It is only possible when all dests are OVERLOADED */
187 dest = NULL; 188 dest = NULL;
188 IP_VS_ERR_RL("WRR: no destination available: " 189 ip_vs_scheduler_err(svc,
189 "all destinations are overloaded\n"); 190 "no destination available: "
191 "all destinations are overloaded");
190 goto out; 192 goto out;
191 } 193 }
192 } 194 }
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 1f2a4e35fb11..a48239aba33b 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -43,6 +43,13 @@
43 43
44#include <net/ip_vs.h> 44#include <net/ip_vs.h>
45 45
46enum {
47 IP_VS_RT_MODE_LOCAL = 1, /* Allow local dest */
48 IP_VS_RT_MODE_NON_LOCAL = 2, /* Allow non-local dest */
49 IP_VS_RT_MODE_RDR = 4, /* Allow redirect from remote daddr to
50 * local
51 */
52};
46 53
47/* 54/*
48 * Destination cache to speed up outgoing route lookup 55 * Destination cache to speed up outgoing route lookup
@@ -77,11 +84,7 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)
77 return dst; 84 return dst;
78} 85}
79 86
80/* 87/* Get route to destination or remote server */
81 * Get route to destination or remote server
82 * rt_mode: flags, &1=Allow local dest, &2=Allow non-local dest,
83 * &4=Allow redirect from remote daddr to local
84 */
85static struct rtable * 88static struct rtable *
86__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, 89__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
87 __be32 daddr, u32 rtos, int rt_mode) 90 __be32 daddr, u32 rtos, int rt_mode)
@@ -126,15 +129,16 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
126 } 129 }
127 130
128 local = rt->rt_flags & RTCF_LOCAL; 131 local = rt->rt_flags & RTCF_LOCAL;
129 if (!((local ? 1 : 2) & rt_mode)) { 132 if (!((local ? IP_VS_RT_MODE_LOCAL : IP_VS_RT_MODE_NON_LOCAL) &
133 rt_mode)) {
130 IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI4\n", 134 IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI4\n",
131 (rt->rt_flags & RTCF_LOCAL) ? 135 (rt->rt_flags & RTCF_LOCAL) ?
132 "local":"non-local", &rt->rt_dst); 136 "local":"non-local", &rt->rt_dst);
133 ip_rt_put(rt); 137 ip_rt_put(rt);
134 return NULL; 138 return NULL;
135 } 139 }
136 if (local && !(rt_mode & 4) && !((ort = skb_rtable(skb)) && 140 if (local && !(rt_mode & IP_VS_RT_MODE_RDR) &&
137 ort->rt_flags & RTCF_LOCAL)) { 141 !((ort = skb_rtable(skb)) && ort->rt_flags & RTCF_LOCAL)) {
138 IP_VS_DBG_RL("Redirect from non-local address %pI4 to local " 142 IP_VS_DBG_RL("Redirect from non-local address %pI4 to local "
139 "requires NAT method, dest: %pI4\n", 143 "requires NAT method, dest: %pI4\n",
140 &ip_hdr(skb)->daddr, &rt->rt_dst); 144 &ip_hdr(skb)->daddr, &rt->rt_dst);
@@ -383,8 +387,8 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
383 387
384 EnterFunction(10); 388 EnterFunction(10);
385 389
386 if (!(rt = __ip_vs_get_out_rt(skb, NULL, iph->daddr, 390 if (!(rt = __ip_vs_get_out_rt(skb, NULL, iph->daddr, RT_TOS(iph->tos),
387 RT_TOS(iph->tos), 2))) 391 IP_VS_RT_MODE_NON_LOCAL)))
388 goto tx_error_icmp; 392 goto tx_error_icmp;
389 393
390 /* MTU checking */ 394 /* MTU checking */
@@ -512,7 +516,10 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
512 } 516 }
513 517
514 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, 518 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
515 RT_TOS(iph->tos), 1|2|4))) 519 RT_TOS(iph->tos),
520 IP_VS_RT_MODE_LOCAL |
521 IP_VS_RT_MODE_NON_LOCAL |
522 IP_VS_RT_MODE_RDR)))
516 goto tx_error_icmp; 523 goto tx_error_icmp;
517 local = rt->rt_flags & RTCF_LOCAL; 524 local = rt->rt_flags & RTCF_LOCAL;
518 /* 525 /*
@@ -755,7 +762,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
755 EnterFunction(10); 762 EnterFunction(10);
756 763
757 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, 764 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
758 RT_TOS(tos), 1|2))) 765 RT_TOS(tos), IP_VS_RT_MODE_LOCAL |
766 IP_VS_RT_MODE_NON_LOCAL)))
759 goto tx_error_icmp; 767 goto tx_error_icmp;
760 if (rt->rt_flags & RTCF_LOCAL) { 768 if (rt->rt_flags & RTCF_LOCAL) {
761 ip_rt_put(rt); 769 ip_rt_put(rt);
@@ -984,7 +992,9 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
984 EnterFunction(10); 992 EnterFunction(10);
985 993
986 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, 994 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
987 RT_TOS(iph->tos), 1|2))) 995 RT_TOS(iph->tos),
996 IP_VS_RT_MODE_LOCAL |
997 IP_VS_RT_MODE_NON_LOCAL)))
988 goto tx_error_icmp; 998 goto tx_error_icmp;
989 if (rt->rt_flags & RTCF_LOCAL) { 999 if (rt->rt_flags & RTCF_LOCAL) {
990 ip_rt_put(rt); 1000 ip_rt_put(rt);
@@ -1128,7 +1138,10 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
1128 */ 1138 */
1129 1139
1130 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, 1140 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
1131 RT_TOS(ip_hdr(skb)->tos), 1|2|4))) 1141 RT_TOS(ip_hdr(skb)->tos),
1142 IP_VS_RT_MODE_LOCAL |
1143 IP_VS_RT_MODE_NON_LOCAL |
1144 IP_VS_RT_MODE_RDR)))
1132 goto tx_error_icmp; 1145 goto tx_error_icmp;
1133 local = rt->rt_flags & RTCF_LOCAL; 1146 local = rt->rt_flags & RTCF_LOCAL;
1134 1147
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 6f38d0e2ea4a..37bf94394be0 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -227,11 +227,11 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
227 * sCL -> sIV 227 * sCL -> sIV
228 */ 228 */
229/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */ 229/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
230/*synack*/ { sIV, sSR, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sSR }, 230/*synack*/ { sIV, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR },
231/* 231/*
232 * sSS -> sSR Standard open. 232 * sSS -> sSR Standard open.
233 * sS2 -> sSR Simultaneous open 233 * sS2 -> sSR Simultaneous open
234 * sSR -> sSR Retransmitted SYN/ACK. 234 * sSR -> sIG Retransmitted SYN/ACK, ignore it.
235 * sES -> sIG Late retransmitted SYN/ACK? 235 * sES -> sIG Late retransmitted SYN/ACK?
236 * sFW -> sIG Might be SYN/ACK answering ignored SYN 236 * sFW -> sIG Might be SYN/ACK answering ignored SYN
237 * sCW -> sIG 237 * sCW -> sIG
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 91592da504b9..985e9b76c916 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -376,7 +376,6 @@ __build_packet_message(struct nfulnl_instance *inst,
376 unsigned int hooknum, 376 unsigned int hooknum,
377 const struct net_device *indev, 377 const struct net_device *indev,
378 const struct net_device *outdev, 378 const struct net_device *outdev,
379 const struct nf_loginfo *li,
380 const char *prefix, unsigned int plen) 379 const char *prefix, unsigned int plen)
381{ 380{
382 struct nfulnl_msg_packet_hdr pmsg; 381 struct nfulnl_msg_packet_hdr pmsg;
@@ -652,7 +651,7 @@ nfulnl_log_packet(u_int8_t pf,
652 inst->qlen++; 651 inst->qlen++;
653 652
654 __build_packet_message(inst, skb, data_len, pf, 653 __build_packet_message(inst, skb, data_len, pf,
655 hooknum, in, out, li, prefix, plen); 654 hooknum, in, out, prefix, plen);
656 655
657 if (inst->qlen >= qthreshold) 656 if (inst->qlen >= qthreshold)
658 __nfulnl_flush(inst); 657 __nfulnl_flush(inst);
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 4ef1b63ad73f..2c0086a4751e 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -272,6 +272,11 @@ static int conntrack_mt_check(const struct xt_mtchk_param *par)
272{ 272{
273 int ret; 273 int ret;
274 274
275 if (strcmp(par->table, "raw") == 0) {
276 pr_info("state is undetermined at the time of raw table\n");
277 return -EINVAL;
278 }
279
275 ret = nf_ct_l3proto_try_module_get(par->family); 280 ret = nf_ct_l3proto_try_module_get(par->family);
276 if (ret < 0) 281 if (ret < 0)
277 pr_info("cannot load conntrack support for proto=%u\n", 282 pr_info("cannot load conntrack support for proto=%u\n",