summaryrefslogtreecommitdiff
path: root/net/netfilter/ipvs/ip_vs_core.c
diff options
context:
space:
mode:
authorAlex Gartrell <agartrell@fb.com>2015-08-26 09:40:37 -0700
committerSimon Horman <horms@verge.net.au>2015-09-01 10:33:55 +0900
commit6044eeffafbe35154c5d3b04b73e8938a62e5d39 (patch)
treef3ed8b842b49cc270e1b52c667183e27fd559403 /net/netfilter/ipvs/ip_vs_core.c
parent1471f35efa86407fc180ca6d55363c684d166ef6 (diff)
ipvs: attempt to schedule icmp packets
Invoke the try_to_schedule logic from the icmp path and update it to the appropriate ip_vs_conn_put function. The schedule functions have been updated to reject the packets immediately for now. Signed-off-by: Alex Gartrell <agartrell@fb.com> Acked-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/netfilter/ipvs/ip_vs_core.c')
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 6465e7b3e891..99be6801c795 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1409,7 +1409,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
struct ip_vs_protocol *pp;
struct ip_vs_proto_data *pd;
unsigned int offset, offset2, ihl, verdict;
- bool ipip;
+ bool ipip, new_cp = false;
*related = 1;
@@ -1487,8 +1487,17 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
* For IPIP this is error for request, not for reply.
*/
cp = pp->conn_in_get(AF_INET, skb, &ciph);
- if (!cp)
- return NF_ACCEPT;
+
+ if (!cp) {
+ int v;
+
+ if (!sysctl_schedule_icmp(net_ipvs(net)))
+ return NF_ACCEPT;
+
+ if (!ip_vs_try_to_schedule(AF_INET, skb, pd, &v, &cp, &ciph))
+ return v;
+ new_cp = true;
+ }
verdict = NF_DROP;
@@ -1565,7 +1574,10 @@ ignore_ipip:
verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum, &ciph);
out:
- __ip_vs_conn_put(cp);
+ if (likely(!new_cp))
+ __ip_vs_conn_put(cp);
+ else
+ ip_vs_conn_put(cp);
return verdict;
}
@@ -1581,6 +1593,7 @@ static int ip_vs_in_icmp_v6(struct sk_buff *skb, int *related,
struct ip_vs_protocol *pp;
struct ip_vs_proto_data *pd;
unsigned int offset, verdict;
+ bool new_cp = false;
*related = 1;
@@ -1631,13 +1644,23 @@ static int ip_vs_in_icmp_v6(struct sk_buff *skb, int *related,
*/
cp = pp->conn_in_get(AF_INET6, skb, &ciph);
- if (!cp)
- return NF_ACCEPT;
+ if (!cp) {
+ int v;
+
+ if (!sysctl_schedule_icmp(net_ipvs(net)))
+ return NF_ACCEPT;
+
+ if (!ip_vs_try_to_schedule(AF_INET6, skb, pd, &v, &cp, &ciph))
+ return v;
+
+ new_cp = true;
+ }
+
/* VS/TUN, VS/DR and LOCALNODE just let it go */
if ((hooknum == NF_INET_LOCAL_OUT) &&
(IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)) {
- __ip_vs_conn_put(cp);
- return NF_ACCEPT;
+ verdict = NF_ACCEPT;
+ goto out;
}
/* do the statistics and put it back */
@@ -1651,7 +1674,11 @@ static int ip_vs_in_icmp_v6(struct sk_buff *skb, int *related,
verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset, hooknum, &ciph);
- __ip_vs_conn_put(cp);
+out:
+ if (likely(!new_cp))
+ __ip_vs_conn_put(cp);
+ else
+ ip_vs_conn_put(cp);
return verdict;
}