Skip to content

Commit

Permalink
ipvs: fix active FTP
Browse files Browse the repository at this point in the history
- Do not create expectation when forwarding the PORT
  command to avoid blocking the connection. The problem is that
  nf_conntrack_ftp.c:help() tries to create the same expectation later in
  POST_ROUTING and drops the packet with "dropping packet" message after
  failure in nf_ct_expect_related.

- Change ip_vs_update_conntrack to alter the conntrack
  for related connections from real server. If we do not alter the reply in
  this direction the next packet from client sent to vport 20 comes as NEW
  connection. We alter it but may be some collision happens for both
  conntracks and the second conntrack gets destroyed immediately. The
  connection stucks too.

Signed-off-by: Julian Anastasov <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Julian Anastasov authored and davem330 committed Sep 8, 2010
1 parent 64289c8 commit 6523ce1
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 12 deletions.
3 changes: 3 additions & 0 deletions include/net/ip_vs.h
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,9 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
return csum_partial(diff, sizeof(diff), oldsum);
}

extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
int outin);

#endif /* __KERNEL__ */

#endif /* _NET_IP_VS_H */
1 change: 1 addition & 0 deletions net/netfilter/ipvs/ip_vs_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,

ip_vs_out_stats(cp, skb);
ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
ip_vs_update_conntrack(skb, cp, 0);
ip_vs_conn_put(cp);

skb->ipvs_property = 1;
Expand Down
6 changes: 0 additions & 6 deletions net/netfilter/ipvs/ip_vs_ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
union nf_inet_addr to;
__be16 port;
struct ip_vs_conn *n_cp;
struct nf_conn *ct;

#ifdef CONFIG_IP_VS_IPV6
/* This application helper doesn't work with IPv6 yet,
Expand Down Expand Up @@ -497,11 +496,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
ip_vs_control_add(n_cp, cp);
}

ct = (struct nf_conn *)skb->nfct;
if (ct && ct != &nf_conntrack_untracked)
ip_vs_expect_related(skb, ct, n_cp,
IPPROTO_TCP, &n_cp->dport, 1);

/*
* Move tunnel to listen state
*/
Expand Down
18 changes: 12 additions & 6 deletions net/netfilter/ipvs/ip_vs_xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
}
#endif

static void
ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp)
void
ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin)
{
struct nf_conn *ct = (struct nf_conn *)skb->nfct;
struct nf_conntrack_tuple new_tuple;
Expand All @@ -365,11 +365,17 @@ ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp)
* real-server we will see RIP->DIP.
*/
new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
new_tuple.src.u3 = cp->daddr;
if (outin)
new_tuple.src.u3 = cp->daddr;
else
new_tuple.dst.u3 = cp->vaddr;
/*
* This will also take care of UDP and other protocols.
*/
new_tuple.src.u.tcp.port = cp->dport;
if (outin)
new_tuple.src.u.tcp.port = cp->dport;
else
new_tuple.dst.u.tcp.port = cp->vport;
nf_conntrack_alter_reply(ct, &new_tuple);
}

Expand Down Expand Up @@ -428,7 +434,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,

IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT");

ip_vs_update_conntrack(skb, cp);
ip_vs_update_conntrack(skb, cp, 1);

/* FIXME: when application helper enlarges the packet and the length
is larger than the MTU of outgoing device, there will be still
Expand Down Expand Up @@ -506,7 +512,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,

IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT");

ip_vs_update_conntrack(skb, cp);
ip_vs_update_conntrack(skb, cp, 1);

/* FIXME: when application helper enlarges the packet and the length
is larger than the MTU of outgoing device, there will be still
Expand Down

0 comments on commit 6523ce1

Please sign in to comment.