You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-patrick' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-test-2.6
This commit is contained in:
@@ -462,6 +462,18 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (manip == IP_NAT_MANIP_SRC)
|
||||
statusbit = IPS_SRC_NAT;
|
||||
else
|
||||
statusbit = IPS_DST_NAT;
|
||||
|
||||
/* Invert if this is reply dir. */
|
||||
if (dir == IP_CT_DIR_REPLY)
|
||||
statusbit ^= IPS_NAT_MASK;
|
||||
|
||||
if (!(ct->status & statusbit))
|
||||
return 1;
|
||||
|
||||
pr_debug("icmp_reply_translation: translating error %p manip %u "
|
||||
"dir %s\n", skb, manip,
|
||||
dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
|
||||
@@ -496,20 +508,9 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
|
||||
/* Change outer to look the reply to an incoming packet
|
||||
* (proto 0 means don't invert per-proto part). */
|
||||
if (manip == IP_NAT_MANIP_SRC)
|
||||
statusbit = IPS_SRC_NAT;
|
||||
else
|
||||
statusbit = IPS_DST_NAT;
|
||||
|
||||
/* Invert if this is reply dir. */
|
||||
if (dir == IP_CT_DIR_REPLY)
|
||||
statusbit ^= IPS_NAT_MASK;
|
||||
|
||||
if (ct->status & statusbit) {
|
||||
nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
|
||||
if (!manip_pkt(0, skb, 0, &target, manip))
|
||||
return 0;
|
||||
}
|
||||
nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
|
||||
if (!manip_pkt(0, skb, 0, &target, manip))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -563,6 +563,8 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
|
||||
*/
|
||||
if (!(cp->flags & IP_VS_CONN_F_TEMPLATE))
|
||||
conn_flags &= ~IP_VS_CONN_F_INACTIVE;
|
||||
/* connections inherit forwarding method from dest */
|
||||
cp->flags &= ~IP_VS_CONN_F_FWD_MASK;
|
||||
}
|
||||
cp->flags |= conn_flags;
|
||||
cp->dest = dest;
|
||||
|
||||
+414
-174
File diff suppressed because it is too large
Load Diff
@@ -777,20 +777,6 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
|
||||
conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK;
|
||||
conn_flags |= IP_VS_CONN_F_INACTIVE;
|
||||
|
||||
/* check if local node and update the flags */
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (svc->af == AF_INET6) {
|
||||
if (__ip_vs_addr_is_local_v6(&udest->addr.in6)) {
|
||||
conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
|
||||
| IP_VS_CONN_F_LOCALNODE;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (inet_addr_type(&init_net, udest->addr.ip) == RTN_LOCAL) {
|
||||
conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
|
||||
| IP_VS_CONN_F_LOCALNODE;
|
||||
}
|
||||
|
||||
/* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */
|
||||
if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) {
|
||||
conn_flags |= IP_VS_CONN_F_NOOUTPUT;
|
||||
@@ -824,6 +810,10 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
|
||||
dest->u_threshold = udest->u_threshold;
|
||||
dest->l_threshold = udest->l_threshold;
|
||||
|
||||
spin_lock(&dest->dst_lock);
|
||||
ip_vs_dst_reset(dest);
|
||||
spin_unlock(&dest->dst_lock);
|
||||
|
||||
if (add)
|
||||
ip_vs_new_estimator(&dest->stats);
|
||||
|
||||
|
||||
@@ -242,9 +242,14 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
|
||||
ret = nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
|
||||
start-data, end-start,
|
||||
buf, buf_len);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ip_vs_nfct_expect_related(skb, ct, n_cp,
|
||||
IPPROTO_TCP, 0, 0);
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
/* csum is updated */
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -172,8 +172,8 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
|
||||
else if (ih->frag_off & htons(IP_OFFSET))
|
||||
sprintf(buf, "%pI4->%pI4 frag", &ih->saddr, &ih->daddr);
|
||||
else {
|
||||
__be16 _ports[2], *pptr
|
||||
;
|
||||
__be16 _ports[2], *pptr;
|
||||
|
||||
pptr = skb_header_pointer(skb, offset + ih->ihl*4,
|
||||
sizeof(_ports), _ports);
|
||||
if (pptr == NULL)
|
||||
@@ -223,13 +223,13 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
|
||||
|
||||
|
||||
void
|
||||
ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
|
||||
ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
|
||||
const struct sk_buff *skb,
|
||||
int offset,
|
||||
const char *msg)
|
||||
{
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (skb->protocol == htons(ETH_P_IPV6))
|
||||
if (af == AF_INET6)
|
||||
ip_vs_tcpudp_debug_packet_v6(pp, skb, offset, msg);
|
||||
else
|
||||
#endif
|
||||
|
||||
@@ -117,54 +117,6 @@ ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
|
||||
int offset, const char *msg)
|
||||
{
|
||||
char buf[256];
|
||||
struct iphdr _iph, *ih;
|
||||
|
||||
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
|
||||
if (ih == NULL)
|
||||
sprintf(buf, "TRUNCATED");
|
||||
else
|
||||
sprintf(buf, "%pI4->%pI4", &ih->saddr, &ih->daddr);
|
||||
|
||||
pr_debug("%s: %s %s\n", msg, pp->name, buf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
static void
|
||||
ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
|
||||
int offset, const char *msg)
|
||||
{
|
||||
char buf[256];
|
||||
struct ipv6hdr _iph, *ih;
|
||||
|
||||
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
|
||||
if (ih == NULL)
|
||||
sprintf(buf, "TRUNCATED");
|
||||
else
|
||||
sprintf(buf, "%pI6->%pI6", &ih->saddr, &ih->daddr);
|
||||
|
||||
pr_debug("%s: %s %s\n", msg, pp->name, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
|
||||
int offset, const char *msg)
|
||||
{
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (skb->protocol == htons(ETH_P_IPV6))
|
||||
ah_esp_debug_packet_v6(pp, skb, offset, msg);
|
||||
else
|
||||
#endif
|
||||
ah_esp_debug_packet_v4(pp, skb, offset, msg);
|
||||
}
|
||||
|
||||
|
||||
static void ah_esp_init(struct ip_vs_protocol *pp)
|
||||
{
|
||||
/* nothing to do now */
|
||||
@@ -195,7 +147,7 @@ struct ip_vs_protocol ip_vs_protocol_ah = {
|
||||
.register_app = NULL,
|
||||
.unregister_app = NULL,
|
||||
.app_conn_bind = NULL,
|
||||
.debug_packet = ah_esp_debug_packet,
|
||||
.debug_packet = ip_vs_tcpudp_debug_packet,
|
||||
.timeout_change = NULL, /* ISAKMP */
|
||||
.set_state_timeout = NULL,
|
||||
};
|
||||
@@ -219,7 +171,7 @@ struct ip_vs_protocol ip_vs_protocol_esp = {
|
||||
.register_app = NULL,
|
||||
.unregister_app = NULL,
|
||||
.app_conn_bind = NULL,
|
||||
.debug_packet = ah_esp_debug_packet,
|
||||
.debug_packet = ip_vs_tcpudp_debug_packet,
|
||||
.timeout_change = NULL, /* ISAKMP */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -31,6 +31,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
if ((sch->type == SCTP_CID_INIT) &&
|
||||
(svc = ip_vs_service_get(af, skb->mark, iph.protocol,
|
||||
&iph.daddr, sh->dest))) {
|
||||
int ignored;
|
||||
|
||||
if (ip_vs_todrop()) {
|
||||
/*
|
||||
* It seems that we are very loaded.
|
||||
@@ -44,8 +46,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
* Let the virtual server select a real server for the
|
||||
* incoming connection, and create a connection entry.
|
||||
*/
|
||||
*cpp = ip_vs_schedule(svc, skb);
|
||||
if (!*cpp) {
|
||||
*cpp = ip_vs_schedule(svc, skb, pp, &ignored);
|
||||
if (!*cpp && !ignored) {
|
||||
*verdict = ip_vs_leave(svc, skb, pp);
|
||||
return 0;
|
||||
}
|
||||
@@ -174,7 +176,7 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
|
||||
|
||||
if (val != cmp) {
|
||||
/* CRC failure, dump it. */
|
||||
IP_VS_DBG_RL_PKT(0, pp, skb, 0,
|
||||
IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
|
||||
"Failed checksum for");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -43,9 +43,12 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */
|
||||
if (th->syn &&
|
||||
(svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr,
|
||||
th->dest))) {
|
||||
int ignored;
|
||||
|
||||
if (ip_vs_todrop()) {
|
||||
/*
|
||||
* It seems that we are very loaded.
|
||||
@@ -60,8 +63,8 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
* Let the virtual server select a real server for the
|
||||
* incoming connection, and create a connection entry.
|
||||
*/
|
||||
*cpp = ip_vs_schedule(svc, skb);
|
||||
if (!*cpp) {
|
||||
*cpp = ip_vs_schedule(svc, skb, pp, &ignored);
|
||||
if (!*cpp && !ignored) {
|
||||
*verdict = ip_vs_leave(svc, skb, pp);
|
||||
return 0;
|
||||
}
|
||||
@@ -101,15 +104,15 @@ tcp_partial_csum_update(int af, struct tcphdr *tcph,
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (af == AF_INET6)
|
||||
tcph->check =
|
||||
csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
|
||||
~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
|
||||
ip_vs_check_diff2(oldlen, newlen,
|
||||
~csum_unfold(tcph->check))));
|
||||
csum_unfold(tcph->check))));
|
||||
else
|
||||
#endif
|
||||
tcph->check =
|
||||
csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
|
||||
~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
|
||||
ip_vs_check_diff2(oldlen, newlen,
|
||||
~csum_unfold(tcph->check))));
|
||||
csum_unfold(tcph->check))));
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +123,7 @@ tcp_snat_handler(struct sk_buff *skb,
|
||||
struct tcphdr *tcph;
|
||||
unsigned int tcphoff;
|
||||
int oldlen;
|
||||
int payload_csum = 0;
|
||||
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (cp->af == AF_INET6)
|
||||
@@ -134,13 +138,20 @@ tcp_snat_handler(struct sk_buff *skb,
|
||||
return 0;
|
||||
|
||||
if (unlikely(cp->app != NULL)) {
|
||||
int ret;
|
||||
|
||||
/* Some checks before mangling */
|
||||
if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
|
||||
return 0;
|
||||
|
||||
/* Call application helper if needed */
|
||||
if (!ip_vs_app_pkt_out(cp, skb))
|
||||
if (!(ret = ip_vs_app_pkt_out(cp, skb)))
|
||||
return 0;
|
||||
/* ret=2: csum update is needed after payload mangling */
|
||||
if (ret == 1)
|
||||
oldlen = skb->len - tcphoff;
|
||||
else
|
||||
payload_csum = 1;
|
||||
}
|
||||
|
||||
tcph = (void *)skb_network_header(skb) + tcphoff;
|
||||
@@ -151,12 +162,13 @@ tcp_snat_handler(struct sk_buff *skb,
|
||||
tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
|
||||
htons(oldlen),
|
||||
htons(skb->len - tcphoff));
|
||||
} else if (!cp->app) {
|
||||
} else if (!payload_csum) {
|
||||
/* Only port and addr are changed, do fast csum update */
|
||||
tcp_fast_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
|
||||
cp->dport, cp->vport);
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->ip_summed = (cp->app && pp->csum_check) ?
|
||||
CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
|
||||
} else {
|
||||
/* full checksum calculation */
|
||||
tcph->check = 0;
|
||||
@@ -174,6 +186,7 @@ tcp_snat_handler(struct sk_buff *skb,
|
||||
skb->len - tcphoff,
|
||||
cp->protocol,
|
||||
skb->csum);
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
|
||||
pp->name, tcph->check,
|
||||
@@ -190,6 +203,7 @@ tcp_dnat_handler(struct sk_buff *skb,
|
||||
struct tcphdr *tcph;
|
||||
unsigned int tcphoff;
|
||||
int oldlen;
|
||||
int payload_csum = 0;
|
||||
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (cp->af == AF_INET6)
|
||||
@@ -204,6 +218,8 @@ tcp_dnat_handler(struct sk_buff *skb,
|
||||
return 0;
|
||||
|
||||
if (unlikely(cp->app != NULL)) {
|
||||
int ret;
|
||||
|
||||
/* Some checks before mangling */
|
||||
if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
|
||||
return 0;
|
||||
@@ -212,8 +228,13 @@ tcp_dnat_handler(struct sk_buff *skb,
|
||||
* Attempt ip_vs_app call.
|
||||
* It will fix ip_vs_conn and iph ack_seq stuff
|
||||
*/
|
||||
if (!ip_vs_app_pkt_in(cp, skb))
|
||||
if (!(ret = ip_vs_app_pkt_in(cp, skb)))
|
||||
return 0;
|
||||
/* ret=2: csum update is needed after payload mangling */
|
||||
if (ret == 1)
|
||||
oldlen = skb->len - tcphoff;
|
||||
else
|
||||
payload_csum = 1;
|
||||
}
|
||||
|
||||
tcph = (void *)skb_network_header(skb) + tcphoff;
|
||||
@@ -223,15 +244,16 @@ tcp_dnat_handler(struct sk_buff *skb,
|
||||
* Adjust TCP checksums
|
||||
*/
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
|
||||
tcp_partial_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr,
|
||||
htons(oldlen),
|
||||
htons(skb->len - tcphoff));
|
||||
} else if (!cp->app) {
|
||||
} else if (!payload_csum) {
|
||||
/* Only port and addr are changed, do fast csum update */
|
||||
tcp_fast_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr,
|
||||
cp->vport, cp->dport);
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->ip_summed = (cp->app && pp->csum_check) ?
|
||||
CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
|
||||
} else {
|
||||
/* full checksum calculation */
|
||||
tcph->check = 0;
|
||||
@@ -278,7 +300,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
|
||||
skb->len - tcphoff,
|
||||
ipv6_hdr(skb)->nexthdr,
|
||||
skb->csum)) {
|
||||
IP_VS_DBG_RL_PKT(0, pp, skb, 0,
|
||||
IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
|
||||
"Failed checksum for");
|
||||
return 0;
|
||||
}
|
||||
@@ -289,7 +311,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
|
||||
skb->len - tcphoff,
|
||||
ip_hdr(skb)->protocol,
|
||||
skb->csum)) {
|
||||
IP_VS_DBG_RL_PKT(0, pp, skb, 0,
|
||||
IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
|
||||
"Failed checksum for");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
svc = ip_vs_service_get(af, skb->mark, iph.protocol,
|
||||
&iph.daddr, uh->dest);
|
||||
if (svc) {
|
||||
int ignored;
|
||||
|
||||
if (ip_vs_todrop()) {
|
||||
/*
|
||||
* It seems that we are very loaded.
|
||||
@@ -60,8 +62,8 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
|
||||
* Let the virtual server select a real server for the
|
||||
* incoming connection, and create a connection entry.
|
||||
*/
|
||||
*cpp = ip_vs_schedule(svc, skb);
|
||||
if (!*cpp) {
|
||||
*cpp = ip_vs_schedule(svc, skb, pp, &ignored);
|
||||
if (!*cpp && !ignored) {
|
||||
*verdict = ip_vs_leave(svc, skb, pp);
|
||||
return 0;
|
||||
}
|
||||
@@ -102,15 +104,15 @@ udp_partial_csum_update(int af, struct udphdr *uhdr,
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (af == AF_INET6)
|
||||
uhdr->check =
|
||||
csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
|
||||
~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
|
||||
ip_vs_check_diff2(oldlen, newlen,
|
||||
~csum_unfold(uhdr->check))));
|
||||
csum_unfold(uhdr->check))));
|
||||
else
|
||||
#endif
|
||||
uhdr->check =
|
||||
csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
|
||||
~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
|
||||
ip_vs_check_diff2(oldlen, newlen,
|
||||
~csum_unfold(uhdr->check))));
|
||||
csum_unfold(uhdr->check))));
|
||||
}
|
||||
|
||||
|
||||
@@ -121,6 +123,7 @@ udp_snat_handler(struct sk_buff *skb,
|
||||
struct udphdr *udph;
|
||||
unsigned int udphoff;
|
||||
int oldlen;
|
||||
int payload_csum = 0;
|
||||
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (cp->af == AF_INET6)
|
||||
@@ -135,6 +138,8 @@ udp_snat_handler(struct sk_buff *skb,
|
||||
return 0;
|
||||
|
||||
if (unlikely(cp->app != NULL)) {
|
||||
int ret;
|
||||
|
||||
/* Some checks before mangling */
|
||||
if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
|
||||
return 0;
|
||||
@@ -142,8 +147,13 @@ udp_snat_handler(struct sk_buff *skb,
|
||||
/*
|
||||
* Call application helper if needed
|
||||
*/
|
||||
if (!ip_vs_app_pkt_out(cp, skb))
|
||||
if (!(ret = ip_vs_app_pkt_out(cp, skb)))
|
||||
return 0;
|
||||
/* ret=2: csum update is needed after payload mangling */
|
||||
if (ret == 1)
|
||||
oldlen = skb->len - udphoff;
|
||||
else
|
||||
payload_csum = 1;
|
||||
}
|
||||
|
||||
udph = (void *)skb_network_header(skb) + udphoff;
|
||||
@@ -156,12 +166,13 @@ udp_snat_handler(struct sk_buff *skb,
|
||||
udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
|
||||
htons(oldlen),
|
||||
htons(skb->len - udphoff));
|
||||
} else if (!cp->app && (udph->check != 0)) {
|
||||
} else if (!payload_csum && (udph->check != 0)) {
|
||||
/* Only port and addr are changed, do fast csum update */
|
||||
udp_fast_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
|
||||
cp->dport, cp->vport);
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->ip_summed = (cp->app && pp->csum_check) ?
|
||||
CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
|
||||
} else {
|
||||
/* full checksum calculation */
|
||||
udph->check = 0;
|
||||
@@ -181,6 +192,7 @@ udp_snat_handler(struct sk_buff *skb,
|
||||
skb->csum);
|
||||
if (udph->check == 0)
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
|
||||
pp->name, udph->check,
|
||||
(char*)&(udph->check) - (char*)udph);
|
||||
@@ -196,6 +208,7 @@ udp_dnat_handler(struct sk_buff *skb,
|
||||
struct udphdr *udph;
|
||||
unsigned int udphoff;
|
||||
int oldlen;
|
||||
int payload_csum = 0;
|
||||
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (cp->af == AF_INET6)
|
||||
@@ -210,6 +223,8 @@ udp_dnat_handler(struct sk_buff *skb,
|
||||
return 0;
|
||||
|
||||
if (unlikely(cp->app != NULL)) {
|
||||
int ret;
|
||||
|
||||
/* Some checks before mangling */
|
||||
if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
|
||||
return 0;
|
||||
@@ -218,8 +233,13 @@ udp_dnat_handler(struct sk_buff *skb,
|
||||
* Attempt ip_vs_app call.
|
||||
* It will fix ip_vs_conn
|
||||
*/
|
||||
if (!ip_vs_app_pkt_in(cp, skb))
|
||||
if (!(ret = ip_vs_app_pkt_in(cp, skb)))
|
||||
return 0;
|
||||
/* ret=2: csum update is needed after payload mangling */
|
||||
if (ret == 1)
|
||||
oldlen = skb->len - udphoff;
|
||||
else
|
||||
payload_csum = 1;
|
||||
}
|
||||
|
||||
udph = (void *)skb_network_header(skb) + udphoff;
|
||||
@@ -229,15 +249,16 @@ udp_dnat_handler(struct sk_buff *skb,
|
||||
* Adjust UDP checksums
|
||||
*/
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
|
||||
udp_partial_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr,
|
||||
htons(oldlen),
|
||||
htons(skb->len - udphoff));
|
||||
} else if (!cp->app && (udph->check != 0)) {
|
||||
} else if (!payload_csum && (udph->check != 0)) {
|
||||
/* Only port and addr are changed, do fast csum update */
|
||||
udp_fast_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr,
|
||||
cp->vport, cp->dport);
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->ip_summed = (cp->app && pp->csum_check) ?
|
||||
CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
|
||||
} else {
|
||||
/* full checksum calculation */
|
||||
udph->check = 0;
|
||||
@@ -293,7 +314,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
|
||||
skb->len - udphoff,
|
||||
ipv6_hdr(skb)->nexthdr,
|
||||
skb->csum)) {
|
||||
IP_VS_DBG_RL_PKT(0, pp, skb, 0,
|
||||
IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
|
||||
"Failed checksum for");
|
||||
return 0;
|
||||
}
|
||||
@@ -304,7 +325,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
|
||||
skb->len - udphoff,
|
||||
ip_hdr(skb)->protocol,
|
||||
skb->csum)) {
|
||||
IP_VS_DBG_RL_PKT(0, pp, skb, 0,
|
||||
IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
|
||||
"Failed checksum for");
|
||||
return 0;
|
||||
}
|
||||
|
||||
+394
-109
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user