aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2012-04-24 16:46:37 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-05-08 13:38:28 -0400
commit882a844bd5b3ffa35e059f21ee920cc113985a89 (patch)
tree62cbd6b18cf7a0b2c5aee37b3c4c26c0e62e466f /net/netfilter
parent06611f82cc0d8b957d6399f11f2799683ad002c3 (diff)
ipvs: fix ip_vs_try_bind_dest to rebind app and transmitter
Initially, when the synced connection is created we use the forwarding method provided by master but once we bind to destination it can be changed. As result, we must update the application and the transmitter. As ip_vs_try_bind_dest is called always for connections that require dest binding, there is no need to validate the cp and dest pointers. Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 1c1bb309a95..fd74f881d04 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -613,14 +613,33 @@ struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp)
613{ 613{
614 struct ip_vs_dest *dest; 614 struct ip_vs_dest *dest;
615 615
616 if ((cp) && (!cp->dest)) { 616 dest = ip_vs_find_dest(ip_vs_conn_net(cp), cp->af, &cp->daddr,
617 dest = ip_vs_find_dest(ip_vs_conn_net(cp), cp->af, &cp->daddr, 617 cp->dport, &cp->vaddr, cp->vport,
618 cp->dport, &cp->vaddr, cp->vport, 618 cp->protocol, cp->fwmark, cp->flags);
619 cp->protocol, cp->fwmark, cp->flags); 619 if (dest) {
620 struct ip_vs_proto_data *pd;
621
622 /* Applications work depending on the forwarding method
623 * but better to reassign them always when binding dest */
624 if (cp->app)
625 ip_vs_unbind_app(cp);
626
620 ip_vs_bind_dest(cp, dest); 627 ip_vs_bind_dest(cp, dest);
621 return dest; 628
622 } else 629 /* Update its packet transmitter */
623 return NULL; 630 cp->packet_xmit = NULL;
631#ifdef CONFIG_IP_VS_IPV6
632 if (cp->af == AF_INET6)
633 ip_vs_bind_xmit_v6(cp);
634 else
635#endif
636 ip_vs_bind_xmit(cp);
637
638 pd = ip_vs_proto_data_get(ip_vs_conn_net(cp), cp->protocol);
639 if (pd && atomic_read(&pd->appcnt))
640 ip_vs_bind_app(cp, pd->pp);
641 }
642 return dest;
624} 643}
625 644
626 645