diff options
author | David S. Miller <davem@davemloft.net> | 2011-03-02 14:30:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-02 14:30:24 -0500 |
commit | 3872b284087081ee5cb0e4630954c2f7a2153cf5 (patch) | |
tree | ead36598e35730e419edcf42dc788290af9e3d5b /net | |
parent | 07df5294a753dfac2cc9f75e6159fc25fdc22149 (diff) | |
parent | 8a80c79a776d1b1b54895314ffaf53d0c7604c80 (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.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipset/Kconfig | 1 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_conn.c | 52 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 28 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_lblc.c | 15 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_lblcr.c | 27 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_lc.c | 20 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_nq.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_rr.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sched.c | 25 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sed.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sh.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sync.c | 4 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_wlc.c | 22 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_wrr.c | 14 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_xmit.c | 41 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto_tcp.c | 4 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_log.c | 3 | ||||
-rw-r--r-- | net/netfilter/xt_conntrack.c | 5 |
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 @@ | |||
1 | menuconfig IP_SET | 1 | menuconfig 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 | */ |
62 | static struct list_head *ip_vs_conn_tab __read_mostly; | 62 | static struct hlist_head *ip_vs_conn_tab __read_mostly; |
63 | 63 | ||
64 | /* SLAB cache for IPVS connections */ | 64 | /* SLAB cache for IPVS connections */ |
65 | static struct kmem_cache *ip_vs_conn_cachep __read_mostly; | 65 | static 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 |
896 | struct ip_vs_iter_state { | 899 | struct 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 | ||
901 | static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos) | 904 | static 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) | |||
959 | static void ip_vs_conn_seq_stop(struct seq_file *seq, void *v) | 964 | static 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 | ||
1203 | flush_again: | 1209 | flush_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 | */ |
734 | static int handle_response_icmp(int af, struct sk_buff *skb, | 734 | static 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 | */ |
984 | static unsigned int | 983 | static unsigned int |
985 | handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | 984 | handle_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 | |||
26 | static inline unsigned int | ||
27 | ip_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 | ||
32 | EXPORT_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 | |||
154 | void 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 | |||
31 | static inline unsigned int | ||
32 | ip_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 | ||
46 | enum { | ||
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 | */ | ||
85 | static struct rtable * | 88 | static 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", |