]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/netfilter/ipvs/ip_vs_conn.c
ipvs: support ipv4 in ipv6 and ipv6 in ipv4 tunnel forwarding
[karo-tx-linux.git] / net / netfilter / ipvs / ip_vs_conn.c
index 610e19c0e13fc82b15eb3fa1dd8328df29d9baa2..13e9cee02c8109192dcfb90418afad56d60b3293 100644 (file)
@@ -488,7 +488,12 @@ static inline void ip_vs_bind_xmit(struct ip_vs_conn *cp)
                break;
 
        case IP_VS_CONN_F_TUNNEL:
-               cp->packet_xmit = ip_vs_tunnel_xmit;
+#ifdef CONFIG_IP_VS_IPV6
+               if (cp->daf == AF_INET6)
+                       cp->packet_xmit = ip_vs_tunnel_xmit_v6;
+               else
+#endif
+                       cp->packet_xmit = ip_vs_tunnel_xmit;
                break;
 
        case IP_VS_CONN_F_DROUTE:
@@ -514,7 +519,10 @@ static inline void ip_vs_bind_xmit_v6(struct ip_vs_conn *cp)
                break;
 
        case IP_VS_CONN_F_TUNNEL:
-               cp->packet_xmit = ip_vs_tunnel_xmit_v6;
+               if (cp->daf == AF_INET6)
+                       cp->packet_xmit = ip_vs_tunnel_xmit_v6;
+               else
+                       cp->packet_xmit = ip_vs_tunnel_xmit;
                break;
 
        case IP_VS_CONN_F_DROUTE:
@@ -616,7 +624,13 @@ void ip_vs_try_bind_dest(struct ip_vs_conn *cp)
        struct ip_vs_dest *dest;
 
        rcu_read_lock();
-       dest = ip_vs_find_dest(ip_vs_conn_net(cp), cp->af, &cp->daddr,
+
+       /* This function is only invoked by the synchronization code. We do
+        * not currently support heterogeneous pools with synchronization,
+        * so we can make the assumption that the svc_af is the same as the
+        * dest_af
+        */
+       dest = ip_vs_find_dest(ip_vs_conn_net(cp), cp->af, cp->af, &cp->daddr,
                               cp->dport, &cp->vaddr, cp->vport,
                               cp->protocol, cp->fwmark, cp->flags);
        if (dest) {
@@ -848,7 +862,7 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
  *     Create a new connection entry and hash it into the ip_vs_conn_tab
  */
 struct ip_vs_conn *
-ip_vs_conn_new(const struct ip_vs_conn_param *p,
+ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af,
               const union nf_inet_addr *daddr, __be16 dport, unsigned int flags,
               struct ip_vs_dest *dest, __u32 fwmark)
 {
@@ -867,6 +881,7 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p,
        setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp);
        ip_vs_conn_net_set(cp, p->net);
        cp->af             = p->af;
+       cp->daf            = dest_af;
        cp->protocol       = p->protocol;
        ip_vs_addr_set(p->af, &cp->caddr, p->caddr);
        cp->cport          = p->cport;
@@ -874,7 +889,7 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p,
        ip_vs_addr_set(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af,
                       &cp->vaddr, p->vaddr);
        cp->vport          = p->vport;
-       ip_vs_addr_set(p->af, &cp->daddr, daddr);
+       ip_vs_addr_set(cp->daf, &cp->daddr, daddr);
        cp->dport          = dport;
        cp->flags          = flags;
        cp->fwmark         = fwmark;