Hi Simon, There is a show stopper for IPv6 in this patch. ip_vs_conn_fill_param() doesn't handle IPv6. On Monday 04 October 2010 15:46:28 Simon Horman wrote: > Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx> > Acked-by: Julian Anastasov <ja@xxxxxx> > > --- > > The motivation for this is to allow persistence engine modules to > fill in the parameters. > > v0.3 > * Add missing changes to ip_vs_ftp.c > > v2 > * make "union nf_inet_addr fwmark" const > * Update for the recent addition of ip_vs_nfct.c > > v3 > * As suggested by Julian Anastasov > - Correct logic for inverse case in ip_vs_conn_fill_param_proto() > and ah_esp_conn_fill_param_proto() > - Update ip_vs_conn_out_get()'s comments as its parameters have changed > - Add missing call to ip_vs_conn_fill_param() before the second > invocation of ip_vs_conn_new() in ip_vs_sched_persist() > * Trivial re-diff > > v4 > * As suggested by Julian Anastasov > - Fix logic in ip_vs_conn_out_get_proto() > + An error occurs if ip_vs_conn_fill_param_proto is non-zero, > not if it is zero > v5+ * IPv6 addr copy in ip_vs_conn_fill_param() > Index: lvs-test-2.6/include/net/ip_vs.h > =================================================================== > --- lvs-test-2.6.orig/include/net/ip_vs.h 2010-10-04 17:00:28.000000000 +0900 > +++ lvs-test-2.6/include/net/ip_vs.h 2010-10-04 17:49:20.000000000 +0900 > @@ -357,6 +357,15 @@ struct ip_vs_protocol { > > extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); > > +struct ip_vs_conn_param { > + const union nf_inet_addr *caddr; > + const union nf_inet_addr *vaddr; > + __be16 cport; > + __be16 vport; > + __u16 protocol; > + u16 af; > +}; > + > /* > * IP_VS structure allocated for each dynamically scheduled connection > */ > @@ -626,13 +635,23 @@ enum { > IP_VS_DIR_LAST, > }; > > -extern struct ip_vs_conn *ip_vs_conn_in_get > -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, > - const union nf_inet_addr *d_addr, __be16 d_port); > - > -extern struct ip_vs_conn *ip_vs_ct_in_get > -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, > - const union nf_inet_addr *d_addr, __be16 d_port); > +static inline void ip_vs_conn_fill_param(int af, int protocol, > + const union nf_inet_addr *caddr, > + __be16 cport, > + const union nf_inet_addr *vaddr, > + __be16 vport, > + struct ip_vs_conn_param *p) > +{ > + p->af = af; > + p->protocol = protocol; #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { ipv6_addr_copy(&p->caddr, caddr); ipv6_addr_copy(&p->caddr, caddr); } else #else } p->caddr = caddr; p->vaddr = vaddr; } +#endif > + p->caddr = caddr; remove line above > + p->cport = cport; > + p->vaddr = vaddr; > + p->vport = vport; remove line above > +} > + > +struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p); > +struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p); > > struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, > struct ip_vs_protocol *pp, > @@ -640,9 +659,7 @@ struct ip_vs_conn * ip_vs_conn_in_get_pr > unsigned int proto_off, > int inverse); > > -extern struct ip_vs_conn *ip_vs_conn_out_get > -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, > - const union nf_inet_addr *d_addr, __be16 d_port); > +struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p); > > struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, > struct ip_vs_protocol *pp, > @@ -658,11 +675,10 @@ static inline void __ip_vs_conn_put(stru > extern void ip_vs_conn_put(struct ip_vs_conn *cp); > extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport); > > -extern struct ip_vs_conn * > -ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, > - const union nf_inet_addr *vaddr, __be16 vport, > - const union nf_inet_addr *daddr, __be16 dport, unsigned flags, > - struct ip_vs_dest *dest); > +struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p, > + const union nf_inet_addr *daddr, > + __be16 dport, unsigned flags, > + struct ip_vs_dest *dest); > extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp); > > extern const char * ip_vs_state_name(__u16 proto, int state); > Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_conn.c > =================================================================== > --- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_conn.c 2010-10-04 17:00:28.000000000 +0900 > +++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_conn.c 2010-10-04 17:49:20.000000000 +0900 > @@ -218,27 +218,26 @@ static inline int ip_vs_conn_unhash(stru > /* > * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. > * Called for pkts coming from OUTside-to-INside. > - * s_addr, s_port: pkt source address (foreign host) > - * d_addr, d_port: pkt dest address (load balancer) > + * p->caddr, p->cport: pkt source address (foreign host) > + * p->vaddr, p->vport: pkt dest address (load balancer) > */ > -static inline struct ip_vs_conn *__ip_vs_conn_in_get > -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, > - const union nf_inet_addr *d_addr, __be16 d_port) > +static inline struct ip_vs_conn * > +__ip_vs_conn_in_get(const struct ip_vs_conn_param *p) > { > unsigned hash; > struct ip_vs_conn *cp; > > - hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port); > + hash = ip_vs_conn_hashkey(p->af, p->protocol, p->caddr, p->cport); > > ct_read_lock(hash); > > list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { > - if (cp->af == af && > - ip_vs_addr_equal(af, s_addr, &cp->caddr) && > - ip_vs_addr_equal(af, d_addr, &cp->vaddr) && > - s_port == cp->cport && d_port == cp->vport && > - ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && > - protocol == cp->protocol) { > + if (cp->af == p->af && > + ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) && > + ip_vs_addr_equal(p->af, p->vaddr, &cp->vaddr) && > + p->cport == cp->cport && p->vport == cp->vport && > + ((!p->cport) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && > + p->protocol == cp->protocol) { > /* HIT */ > atomic_inc(&cp->refcnt); > ct_read_unlock(hash); > @@ -251,71 +250,82 @@ static inline struct ip_vs_conn *__ip_vs > return NULL; > } > > -struct ip_vs_conn *ip_vs_conn_in_get > -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, > - const union nf_inet_addr *d_addr, __be16 d_port) > +struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p) > { > struct ip_vs_conn *cp; > > - cp = __ip_vs_conn_in_get(af, protocol, s_addr, s_port, d_addr, d_port); > - if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) > - cp = __ip_vs_conn_in_get(af, protocol, s_addr, 0, d_addr, > - d_port); > + cp = __ip_vs_conn_in_get(p); > + if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) { > + struct ip_vs_conn_param cport_zero_p = *p; > + cport_zero_p.cport = 0; > + cp = __ip_vs_conn_in_get(&cport_zero_p); > + } > > IP_VS_DBG_BUF(9, "lookup/in %s %s:%d->%s:%d %s\n", > - ip_vs_proto_name(protocol), > - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), > - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), > + ip_vs_proto_name(p->protocol), > + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), > + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), > cp ? "hit" : "not hit"); > > return cp; > } > > +static int > +ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb, > + const struct ip_vs_iphdr *iph, > + unsigned int proto_off, int inverse, > + struct ip_vs_conn_param *p) > +{ > + __be16 _ports[2], *pptr; > + > + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); > + if (pptr == NULL) > + return 1; > + > + if (likely(!inverse)) > + ip_vs_conn_fill_param(af, iph->protocol, &iph->saddr, pptr[0], > + &iph->daddr, pptr[1], p); > + else > + ip_vs_conn_fill_param(af, iph->protocol, &iph->daddr, pptr[1], > + &iph->saddr, pptr[0], p); > + return 0; > +} > + > struct ip_vs_conn * > ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, > struct ip_vs_protocol *pp, > const struct ip_vs_iphdr *iph, > unsigned int proto_off, int inverse) > { > - __be16 _ports[2], *pptr; > + struct ip_vs_conn_param p; > > - pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); > - if (pptr == NULL) > + if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p)) > return NULL; > > - if (likely(!inverse)) > - return ip_vs_conn_in_get(af, iph->protocol, > - &iph->saddr, pptr[0], > - &iph->daddr, pptr[1]); > - else > - return ip_vs_conn_in_get(af, iph->protocol, > - &iph->daddr, pptr[1], > - &iph->saddr, pptr[0]); > + return ip_vs_conn_in_get(&p); > } > EXPORT_SYMBOL_GPL(ip_vs_conn_in_get_proto); > > /* Get reference to connection template */ > -struct ip_vs_conn *ip_vs_ct_in_get > -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, > - const union nf_inet_addr *d_addr, __be16 d_port) > +struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p) > { > unsigned hash; > struct ip_vs_conn *cp; > > - hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port); > + hash = ip_vs_conn_hashkey(p->af, p->protocol, p->caddr, p->cport); > > ct_read_lock(hash); > > list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { > - if (cp->af == af && > - ip_vs_addr_equal(af, s_addr, &cp->caddr) && > + if (cp->af == p->af && > + ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) && > /* protocol should only be IPPROTO_IP if > - * d_addr is a fwmark */ > - ip_vs_addr_equal(protocol == IPPROTO_IP ? AF_UNSPEC : af, > - d_addr, &cp->vaddr) && > - s_port == cp->cport && d_port == cp->vport && > + * p->vaddr is a fwmark */ > + ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC : > + p->af, p->vaddr, &cp->vaddr) && > + p->cport == cp->cport && p->vport == cp->vport && > cp->flags & IP_VS_CONN_F_TEMPLATE && > - protocol == cp->protocol) { > + p->protocol == cp->protocol) { > /* HIT */ > atomic_inc(&cp->refcnt); > goto out; > @@ -327,23 +337,19 @@ struct ip_vs_conn *ip_vs_ct_in_get > ct_read_unlock(hash); > > IP_VS_DBG_BUF(9, "template lookup/in %s %s:%d->%s:%d %s\n", > - ip_vs_proto_name(protocol), > - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), > - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), > + ip_vs_proto_name(p->protocol), > + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), > + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), > cp ? "hit" : "not hit"); > > return cp; > } > > -/* > - * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. > - * Called for pkts coming from inside-to-OUTside. > - * s_addr, s_port: pkt source address (inside host) > - * d_addr, d_port: pkt dest address (foreign host) > - */ > -struct ip_vs_conn *ip_vs_conn_out_get > -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, > - const union nf_inet_addr *d_addr, __be16 d_port) > +/* Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. > + * Called for pkts coming from inside-to-OUTside. > + * p->caddr, p->cport: pkt source address (inside host) > + * p->vaddr, p->vport: pkt dest address (foreign host) */ > +struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p) > { > unsigned hash; > struct ip_vs_conn *cp, *ret=NULL; > @@ -351,16 +357,16 @@ struct ip_vs_conn *ip_vs_conn_out_get > /* > * Check for "full" addressed entries > */ > - hash = ip_vs_conn_hashkey(af, protocol, d_addr, d_port); > + hash = ip_vs_conn_hashkey(p->af, p->protocol, p->vaddr, p->vport); > > ct_read_lock(hash); > > list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { > - if (cp->af == af && > - ip_vs_addr_equal(af, d_addr, &cp->caddr) && > - ip_vs_addr_equal(af, s_addr, &cp->daddr) && > - d_port == cp->cport && s_port == cp->dport && > - protocol == cp->protocol) { > + if (cp->af == p->af && > + ip_vs_addr_equal(p->af, p->vaddr, &cp->caddr) && > + ip_vs_addr_equal(p->af, p->caddr, &cp->daddr) && > + p->vport == cp->cport && p->cport == cp->dport && > + p->protocol == cp->protocol) { > /* HIT */ > atomic_inc(&cp->refcnt); > ret = cp; > @@ -371,9 +377,9 @@ struct ip_vs_conn *ip_vs_conn_out_get > ct_read_unlock(hash); > > IP_VS_DBG_BUF(9, "lookup/out %s %s:%d->%s:%d %s\n", > - ip_vs_proto_name(protocol), > - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), > - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), > + ip_vs_proto_name(p->protocol), > + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), > + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), > ret ? "hit" : "not hit"); > > return ret; > @@ -385,20 +391,12 @@ ip_vs_conn_out_get_proto(int af, const s > const struct ip_vs_iphdr *iph, > unsigned int proto_off, int inverse) > { > - __be16 _ports[2], *pptr; > + struct ip_vs_conn_param p; > > - pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); > - if (pptr == NULL) > + if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p)) > return NULL; > > - if (likely(!inverse)) > - return ip_vs_conn_out_get(af, iph->protocol, > - &iph->saddr, pptr[0], > - &iph->daddr, pptr[1]); > - else > - return ip_vs_conn_out_get(af, iph->protocol, > - &iph->daddr, pptr[1], > - &iph->saddr, pptr[0]); > + return ip_vs_conn_out_get(&p); > } > EXPORT_SYMBOL_GPL(ip_vs_conn_out_get_proto); > > @@ -758,13 +756,12 @@ void ip_vs_conn_expire_now(struct ip_vs_ > * Create a new connection entry and hash it into the ip_vs_conn_tab > */ > struct ip_vs_conn * > -ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, > - const union nf_inet_addr *vaddr, __be16 vport, > +ip_vs_conn_new(const struct ip_vs_conn_param *p, > const union nf_inet_addr *daddr, __be16 dport, unsigned flags, > struct ip_vs_dest *dest) > { > struct ip_vs_conn *cp; > - struct ip_vs_protocol *pp = ip_vs_proto_get(proto); > + struct ip_vs_protocol *pp = ip_vs_proto_get(p->protocol); > > cp = kmem_cache_zalloc(ip_vs_conn_cachep, GFP_ATOMIC); > if (cp == NULL) { > @@ -774,14 +771,14 @@ ip_vs_conn_new(int af, int proto, const > > INIT_LIST_HEAD(&cp->c_list); > setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp); > - cp->af = af; > - cp->protocol = proto; > - ip_vs_addr_copy(af, &cp->caddr, caddr); > - cp->cport = cport; > - ip_vs_addr_copy(af, &cp->vaddr, vaddr); > - cp->vport = vport; > + cp->af = p->af; > + cp->protocol = p->protocol; > + ip_vs_addr_copy(p->af, &cp->caddr, p->caddr); > + cp->cport = p->cport; > + ip_vs_addr_copy(p->af, &cp->vaddr, p->vaddr); > + cp->vport = p->vport; > /* proto should only be IPPROTO_IP if d_addr is a fwmark */ > - ip_vs_addr_copy(proto == IPPROTO_IP ? AF_UNSPEC : af, > + ip_vs_addr_copy(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af, > &cp->daddr, daddr); > cp->dport = dport; > cp->flags = flags; > @@ -810,7 +807,7 @@ ip_vs_conn_new(int af, int proto, const > > /* Bind its packet transmitter */ > #ifdef CONFIG_IP_VS_IPV6 > - if (af == AF_INET6) > + if (p->af == AF_INET6) > ip_vs_bind_xmit_v6(cp); > else > #endif > Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_core.c > =================================================================== > --- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_core.c 2010-10-04 17:00:45.000000000 +0900 > +++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_core.c 2010-10-04 17:49:20.000000000 +0900 > @@ -193,14 +193,11 @@ ip_vs_sched_persist(struct ip_vs_service > struct ip_vs_iphdr iph; > struct ip_vs_dest *dest; > struct ip_vs_conn *ct; > - int protocol = iph.protocol; > __be16 dport = 0; /* destination port to forward */ > - __be16 vport = 0; /* virtual service port */ > unsigned int flags; > + struct ip_vs_conn_param param; > union nf_inet_addr snet; /* source network of the client, > after masking */ > - const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; > - const union nf_inet_addr *vaddr = &iph.daddr; > > ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); > > @@ -232,6 +229,11 @@ ip_vs_sched_persist(struct ip_vs_service > * is created for other persistent services. > */ > { > + int protocol = iph.protocol; > + const union nf_inet_addr *vaddr = &iph.daddr; > + const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; > + __be16 vport = 0; > + > if (ports[1] == svc->port) { > /* non-FTP template: > * <protocol, caddr, 0, vaddr, vport, daddr, dport> > @@ -253,11 +255,12 @@ ip_vs_sched_persist(struct ip_vs_service > vaddr = &fwmark; > } > } > + ip_vs_conn_fill_param(svc->af, protocol, &snet, 0, > + vaddr, vport, ¶m); > } > > /* Check if a template already exists */ > - ct = ip_vs_ct_in_get(svc->af, protocol, &snet, 0, vaddr, vport); > - > + ct = ip_vs_ct_in_get(¶m); > if (!ct || !ip_vs_check_template(ct)) { > /* No template found or the dest of the connection > * template is not available. > @@ -272,8 +275,7 @@ ip_vs_sched_persist(struct ip_vs_service > dport = dest->port; > > /* Create a template */ > - ct = ip_vs_conn_new(svc->af, protocol, &snet, 0,vaddr, vport, > - &dest->addr, dport, > + ct = ip_vs_conn_new(¶m, &dest->addr, dport, > IP_VS_CONN_F_TEMPLATE, dest); > if (ct == NULL) > return NULL; > @@ -294,12 +296,9 @@ ip_vs_sched_persist(struct ip_vs_service > /* > * Create a new connection according to the template > */ > - cp = ip_vs_conn_new(svc->af, iph.protocol, > - &iph.saddr, ports[0], > - &iph.daddr, ports[1], > - &dest->addr, dport, > - flags, > - dest); > + ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, ports[0], > + &iph.daddr, ports[1], ¶m); > + cp = ip_vs_conn_new(¶m, &dest->addr, dport, flags, dest); > if (cp == NULL) { > ip_vs_conn_put(ct); > return NULL; > @@ -366,14 +365,16 @@ ip_vs_schedule(struct ip_vs_service *svc > /* > * Create a connection entry. > */ > - cp = ip_vs_conn_new(svc->af, iph.protocol, > - &iph.saddr, pptr[0], > - &iph.daddr, pptr[1], > - &dest->addr, dest->port ? dest->port : pptr[1], > - flags, > - dest); > - if (cp == NULL) > - return NULL; > + { > + struct ip_vs_conn_param p; > + ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, > + pptr[0], &iph.daddr, pptr[1], &p); > + cp = ip_vs_conn_new(&p, &dest->addr, > + dest->port ? dest->port : pptr[1], > + flags, dest); > + if (!cp) > + return NULL; > + } > > IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u " > "d:%s:%u conn->flags:%X conn->refcnt:%d\n", > @@ -429,14 +430,17 @@ int ip_vs_leave(struct ip_vs_service *sv > > /* create a new connection entry */ > IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__); > - cp = ip_vs_conn_new(svc->af, iph.protocol, > - &iph.saddr, pptr[0], > - &iph.daddr, pptr[1], > - &daddr, 0, > - IP_VS_CONN_F_BYPASS | flags, > - NULL); > - if (cp == NULL) > - return NF_DROP; > + { > + struct ip_vs_conn_param p; > + ip_vs_conn_fill_param(svc->af, iph.protocol, > + &iph.saddr, pptr[0], > + &iph.daddr, pptr[1], &p); > + cp = ip_vs_conn_new(&p, &daddr, 0, > + IP_VS_CONN_F_BYPASS | flags, > + NULL); > + if (!cp) > + return NF_DROP; > + } > > /* statistics */ > ip_vs_in_stats(cp, skb); > Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_ftp.c > =================================================================== > --- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_ftp.c 2010-10-04 16:58:31.000000000 +0900 > +++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_ftp.c 2010-10-04 17:00:45.000000000 +0900 > @@ -195,13 +195,17 @@ static int ip_vs_ftp_out(struct ip_vs_ap > /* > * Now update or create an connection entry for it > */ > - n_cp = ip_vs_conn_out_get(AF_INET, iph->protocol, &from, port, > - &cp->caddr, 0); > + { > + struct ip_vs_conn_param p; > + ip_vs_conn_fill_param(AF_INET, iph->protocol, > + &from, port, &cp->caddr, 0, &p); > + n_cp = ip_vs_conn_out_get(&p); > + } > if (!n_cp) { > - n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP, > - &cp->caddr, 0, > - &cp->vaddr, port, > - &from, port, > + struct ip_vs_conn_param p; > + ip_vs_conn_fill_param(AF_INET, IPPROTO_TCP, &cp->caddr, > + 0, &cp->vaddr, port, &p); > + n_cp = ip_vs_conn_new(&p, &from, port, > IP_VS_CONN_F_NO_CPORT | > IP_VS_CONN_F_NFCT, > cp->dest); > @@ -347,21 +351,22 @@ static int ip_vs_ftp_in(struct ip_vs_app > ip_vs_proto_name(iph->protocol), > &to.ip, ntohs(port), &cp->vaddr.ip, 0); > > - n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol, > - &to, port, > - &cp->vaddr, htons(ntohs(cp->vport)-1)); > - if (!n_cp) { > - n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP, > - &to, port, > + { > + struct ip_vs_conn_param p; > + ip_vs_conn_fill_param(AF_INET, iph->protocol, &to, port, > &cp->vaddr, htons(ntohs(cp->vport)-1), > - &cp->daddr, htons(ntohs(cp->dport)-1), > - IP_VS_CONN_F_NFCT, > - cp->dest); > - if (!n_cp) > - return 0; > + &p); > + n_cp = ip_vs_conn_in_get(&p); > + if (!n_cp) { > + n_cp = ip_vs_conn_new(&p, &cp->daddr, > + htons(ntohs(cp->dport)-1), > + IP_VS_CONN_F_NFCT, cp->dest); > + if (!n_cp) > + return 0; > > - /* add its controller */ > - ip_vs_control_add(n_cp, cp); > + /* add its controller */ > + ip_vs_control_add(n_cp, cp); > + } > } > > /* > Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_nfct.c > =================================================================== > --- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_nfct.c 2010-10-04 16:58:31.000000000 +0900 > +++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_nfct.c 2010-10-04 17:00:45.000000000 +0900 > @@ -140,6 +140,7 @@ static void ip_vs_nfct_expect_callback(s > { > struct nf_conntrack_tuple *orig, new_reply; > struct ip_vs_conn *cp; > + struct ip_vs_conn_param p; > > if (exp->tuple.src.l3num != PF_INET) > return; > @@ -154,9 +155,10 @@ static void ip_vs_nfct_expect_callback(s > > /* RS->CLIENT */ > orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; > - cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum, > - &orig->src.u3, orig->src.u.tcp.port, > - &orig->dst.u3, orig->dst.u.tcp.port); > + ip_vs_conn_fill_param(exp->tuple.src.l3num, orig->dst.protonum, > + &orig->src.u3, orig->src.u.tcp.port, > + &orig->dst.u3, orig->dst.u.tcp.port, &p); > + cp = ip_vs_conn_out_get(&p); > if (cp) { > /* Change reply CLIENT->RS to CLIENT->VS */ > new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; > @@ -176,9 +178,7 @@ static void ip_vs_nfct_expect_callback(s > } > > /* CLIENT->VS */ > - cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum, > - &orig->src.u3, orig->src.u.tcp.port, > - &orig->dst.u3, orig->dst.u.tcp.port); > + cp = ip_vs_conn_in_get(&p); > if (cp) { > /* Change reply VS->CLIENT to RS->CLIENT */ > new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; > Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_proto_ah_esp.c > =================================================================== > --- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_proto_ah_esp.c 2010-10-04 16:58:31.000000000 +0900 > +++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_proto_ah_esp.c 2010-10-04 17:00:45.000000000 +0900 > @@ -40,6 +40,19 @@ struct isakmp_hdr { > > #define PORT_ISAKMP 500 > > +static void > +ah_esp_conn_fill_param_proto(int af, const struct ip_vs_iphdr *iph, > + int inverse, struct ip_vs_conn_param *p) > +{ > + if (likely(!inverse)) > + ip_vs_conn_fill_param(af, IPPROTO_UDP, > + &iph->saddr, htons(PORT_ISAKMP), > + &iph->daddr, htons(PORT_ISAKMP), p); > + else > + ip_vs_conn_fill_param(af, IPPROTO_UDP, > + &iph->daddr, htons(PORT_ISAKMP), > + &iph->saddr, htons(PORT_ISAKMP), p); > +} > > static struct ip_vs_conn * > ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, > @@ -47,21 +60,10 @@ ah_esp_conn_in_get(int af, const struct > int inverse) > { > struct ip_vs_conn *cp; > + struct ip_vs_conn_param p; > > - if (likely(!inverse)) { > - cp = ip_vs_conn_in_get(af, IPPROTO_UDP, > - &iph->saddr, > - htons(PORT_ISAKMP), > - &iph->daddr, > - htons(PORT_ISAKMP)); > - } else { > - cp = ip_vs_conn_in_get(af, IPPROTO_UDP, > - &iph->daddr, > - htons(PORT_ISAKMP), > - &iph->saddr, > - htons(PORT_ISAKMP)); > - } > - > + ah_esp_conn_fill_param_proto(af, iph, inverse, &p); > + cp = ip_vs_conn_in_get(&p); > if (!cp) { > /* > * We are not sure if the packet is from our > @@ -87,21 +89,10 @@ ah_esp_conn_out_get(int af, const struct > int inverse) > { > struct ip_vs_conn *cp; > + struct ip_vs_conn_param p; > > - if (likely(!inverse)) { > - cp = ip_vs_conn_out_get(af, IPPROTO_UDP, > - &iph->saddr, > - htons(PORT_ISAKMP), > - &iph->daddr, > - htons(PORT_ISAKMP)); > - } else { > - cp = ip_vs_conn_out_get(af, IPPROTO_UDP, > - &iph->daddr, > - htons(PORT_ISAKMP), > - &iph->saddr, > - htons(PORT_ISAKMP)); > - } > - > + ah_esp_conn_fill_param_proto(af, iph, inverse, &p); > + cp = ip_vs_conn_out_get(&p); > if (!cp) { > IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet " > "%s%s %s->%s\n", > Index: lvs-test-2.6/net/netfilter/ipvs/ip_vs_sync.c > =================================================================== > --- lvs-test-2.6.orig/net/netfilter/ipvs/ip_vs_sync.c 2010-10-04 16:58:31.000000000 +0900 > +++ lvs-test-2.6/net/netfilter/ipvs/ip_vs_sync.c 2010-10-04 17:49:20.000000000 +0900 > @@ -301,6 +301,7 @@ static void ip_vs_process_message(const > struct ip_vs_conn *cp; > struct ip_vs_protocol *pp; > struct ip_vs_dest *dest; > + struct ip_vs_conn_param param; > char *p; > int i; > > @@ -370,18 +371,17 @@ static void ip_vs_process_message(const > } > } > > - if (!(flags & IP_VS_CONN_F_TEMPLATE)) > - cp = ip_vs_conn_in_get(AF_INET, s->protocol, > - (union nf_inet_addr *)&s->caddr, > - s->cport, > - (union nf_inet_addr *)&s->vaddr, > - s->vport); > - else > - cp = ip_vs_ct_in_get(AF_INET, s->protocol, > - (union nf_inet_addr *)&s->caddr, > - s->cport, > - (union nf_inet_addr *)&s->vaddr, > - s->vport); > + { > + ip_vs_conn_fill_param(AF_INET, s->protocol, > + (union nf_inet_addr *)&s->caddr, > + s->cport, > + (union nf_inet_addr *)&s->vaddr, > + s->vport, ¶m); > + if (!(flags & IP_VS_CONN_F_TEMPLATE)) > + cp = ip_vs_conn_in_get(¶m); > + else > + cp = ip_vs_ct_in_get(¶m); > + } > if (!cp) { > /* > * Find the appropriate destination for the connection. > @@ -406,14 +406,9 @@ static void ip_vs_process_message(const > else > flags &= ~IP_VS_CONN_F_INACTIVE; > } > - cp = ip_vs_conn_new(AF_INET, s->protocol, > - (union nf_inet_addr *)&s->caddr, > - s->cport, > - (union nf_inet_addr *)&s->vaddr, > - s->vport, > + cp = ip_vs_conn_new(¶m, > (union nf_inet_addr *)&s->daddr, > - s->dport, > - flags, dest); > + s->dport, flags, dest); > if (dest) > atomic_dec(&dest->refcnt); > if (!cp) { > > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > Patch applied for patch :-) iff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 52fbe23..7646ff7 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -670,9 +670,19 @@ static inline void ip_vs_conn_fill_param(int af, int protocol, { p->af = af; p->protocol = protocol; - p->caddr = caddr; p->cport = cport; - p->vaddr = vaddr; +#ifdef CONFIG_IP_VS_IPV6 + if (af == AF_INET6) { + ipv6_addr_copy(&p->caddr, caddr); + ipv6_addr_copy(&p->caddr, caddr); + } + else +#else + } + p->caddr = caddr; + p->vaddr = vaddr; + } +#endif p->vport = vport; p->pe = NULL; p->pe_data = NULL; -- Regards Hans Schillstrom <hans.schillstrom@xxxxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe netfilter" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html