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 lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
|