Commit f11017ec authored by Simon Horman's avatar Simon Horman

IPVS: Add struct ip_vs_conn_param

Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
parent 5b57a98c
...@@ -357,6 +357,15 @@ struct ip_vs_protocol { ...@@ -357,6 +357,15 @@ struct ip_vs_protocol {
extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); 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 * IP_VS structure allocated for each dynamically scheduled connection
*/ */
...@@ -626,13 +635,23 @@ enum { ...@@ -626,13 +635,23 @@ enum {
IP_VS_DIR_LAST, IP_VS_DIR_LAST,
}; };
extern struct ip_vs_conn *ip_vs_conn_in_get static inline void ip_vs_conn_fill_param(int af, int protocol,
(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, const union nf_inet_addr *caddr,
const union nf_inet_addr *d_addr, __be16 d_port); __be16 cport,
const union nf_inet_addr *vaddr,
__be16 vport,
struct ip_vs_conn_param *p)
{
p->af = af;
p->protocol = protocol;
p->caddr = caddr;
p->cport = cport;
p->vaddr = vaddr;
p->vport = vport;
}
extern struct ip_vs_conn *ip_vs_ct_in_get struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p);
(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p);
const union nf_inet_addr *d_addr, __be16 d_port);
struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_protocol *pp,
...@@ -640,9 +659,7 @@ struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, ...@@ -640,9 +659,7 @@ struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb,
unsigned int proto_off, unsigned int proto_off,
int inverse); int inverse);
extern struct ip_vs_conn *ip_vs_conn_out_get struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p);
(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_proto(int af, const struct sk_buff *skb, struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_protocol *pp,
...@@ -658,10 +675,9 @@ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp) ...@@ -658,10 +675,9 @@ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
extern void ip_vs_conn_put(struct ip_vs_conn *cp); 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 void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);
extern struct ip_vs_conn * struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p,
ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, const union nf_inet_addr *daddr,
const union nf_inet_addr *vaddr, __be16 vport, __be16 dport, unsigned flags,
const union nf_inet_addr *daddr, __be16 dport, unsigned flags,
struct ip_vs_dest *dest); struct ip_vs_dest *dest);
extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp); extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp);
......
This diff is collapsed.
...@@ -193,14 +193,11 @@ ip_vs_sched_persist(struct ip_vs_service *svc, ...@@ -193,14 +193,11 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
struct ip_vs_iphdr iph; struct ip_vs_iphdr iph;
struct ip_vs_dest *dest; struct ip_vs_dest *dest;
struct ip_vs_conn *ct; struct ip_vs_conn *ct;
int protocol = iph.protocol;
__be16 dport = 0; /* destination port to forward */ __be16 dport = 0; /* destination port to forward */
__be16 vport = 0; /* virtual service port */
unsigned int flags; unsigned int flags;
struct ip_vs_conn_param param;
union nf_inet_addr snet; /* source network of the client, union nf_inet_addr snet; /* source network of the client,
after masking */ 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); ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
...@@ -232,6 +229,11 @@ ip_vs_sched_persist(struct ip_vs_service *svc, ...@@ -232,6 +229,11 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
* is created for other persistent services. * 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) { if (ports[1] == svc->port) {
/* non-FTP template: /* non-FTP template:
* <protocol, caddr, 0, vaddr, vport, daddr, dport> * <protocol, caddr, 0, vaddr, vport, daddr, dport>
...@@ -253,11 +255,12 @@ ip_vs_sched_persist(struct ip_vs_service *svc, ...@@ -253,11 +255,12 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
vaddr = &fwmark; vaddr = &fwmark;
} }
} }
ip_vs_conn_fill_param(svc->af, protocol, &snet, 0,
vaddr, vport, &param);
} }
/* Check if a template already exists */ /* 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(&param);
if (!ct || !ip_vs_check_template(ct)) { if (!ct || !ip_vs_check_template(ct)) {
/* No template found or the dest of the connection /* No template found or the dest of the connection
* template is not available. * template is not available.
...@@ -272,8 +275,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc, ...@@ -272,8 +275,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
dport = dest->port; dport = dest->port;
/* Create a template */ /* Create a template */
ct = ip_vs_conn_new(svc->af, protocol, &snet, 0,vaddr, vport, ct = ip_vs_conn_new(&param, &dest->addr, dport,
&dest->addr, dport,
IP_VS_CONN_F_TEMPLATE, dest); IP_VS_CONN_F_TEMPLATE, dest);
if (ct == NULL) if (ct == NULL)
return NULL; return NULL;
...@@ -294,12 +296,9 @@ ip_vs_sched_persist(struct ip_vs_service *svc, ...@@ -294,12 +296,9 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
/* /*
* Create a new connection according to the template * Create a new connection according to the template
*/ */
cp = ip_vs_conn_new(svc->af, iph.protocol, ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, ports[0],
&iph.saddr, ports[0], &iph.daddr, ports[1], &param);
&iph.daddr, ports[1], cp = ip_vs_conn_new(&param, &dest->addr, dport, flags, dest);
&dest->addr, dport,
flags,
dest);
if (cp == NULL) { if (cp == NULL) {
ip_vs_conn_put(ct); ip_vs_conn_put(ct);
return NULL; return NULL;
...@@ -366,14 +365,16 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -366,14 +365,16 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
/* /*
* Create a connection entry. * Create a connection entry.
*/ */
cp = ip_vs_conn_new(svc->af, iph.protocol, {
&iph.saddr, pptr[0], struct ip_vs_conn_param p;
&iph.daddr, pptr[1], ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr,
&dest->addr, dest->port ? dest->port : pptr[1], pptr[0], &iph.daddr, pptr[1], &p);
flags, cp = ip_vs_conn_new(&p, &dest->addr,
dest); dest->port ? dest->port : pptr[1],
if (cp == NULL) flags, dest);
if (!cp)
return NULL; return NULL;
}
IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u " IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u "
"d:%s:%u conn->flags:%X conn->refcnt:%d\n", "d:%s:%u conn->flags:%X conn->refcnt:%d\n",
...@@ -429,14 +430,17 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, ...@@ -429,14 +430,17 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
/* create a new connection entry */ /* create a new connection entry */
IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__); IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__);
cp = ip_vs_conn_new(svc->af, iph.protocol, {
struct ip_vs_conn_param p;
ip_vs_conn_fill_param(svc->af, iph.protocol,
&iph.saddr, pptr[0], &iph.saddr, pptr[0],
&iph.daddr, pptr[1], &iph.daddr, pptr[1], &p);
&daddr, 0, cp = ip_vs_conn_new(&p, &daddr, 0,
IP_VS_CONN_F_BYPASS | flags, IP_VS_CONN_F_BYPASS | flags,
NULL); NULL);
if (cp == NULL) if (!cp)
return NF_DROP; return NF_DROP;
}
/* statistics */ /* statistics */
ip_vs_in_stats(cp, skb); ip_vs_in_stats(cp, skb);
......
...@@ -195,13 +195,17 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -195,13 +195,17 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
/* /*
* Now update or create an connection entry for it * 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) { if (!n_cp) {
n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP, struct ip_vs_conn_param p;
&cp->caddr, 0, ip_vs_conn_fill_param(AF_INET, IPPROTO_TCP, &cp->caddr,
&cp->vaddr, port, 0, &cp->vaddr, port, &p);
&from, port, n_cp = ip_vs_conn_new(&p, &from, port,
IP_VS_CONN_F_NO_CPORT | IP_VS_CONN_F_NO_CPORT |
IP_VS_CONN_F_NFCT, IP_VS_CONN_F_NFCT,
cp->dest); cp->dest);
...@@ -347,22 +351,23 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -347,22 +351,23 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
ip_vs_proto_name(iph->protocol), ip_vs_proto_name(iph->protocol),
&to.ip, ntohs(port), &cp->vaddr.ip, 0); &to.ip, ntohs(port), &cp->vaddr.ip, 0);
n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol, {
&to, port, struct ip_vs_conn_param p;
&cp->vaddr, htons(ntohs(cp->vport)-1)); ip_vs_conn_fill_param(AF_INET, iph->protocol, &to, port,
if (!n_cp) {
n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
&to, port,
&cp->vaddr, htons(ntohs(cp->vport)-1), &cp->vaddr, htons(ntohs(cp->vport)-1),
&cp->daddr, htons(ntohs(cp->dport)-1), &p);
IP_VS_CONN_F_NFCT, n_cp = ip_vs_conn_in_get(&p);
cp->dest); 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) if (!n_cp)
return 0; return 0;
/* add its controller */ /* add its controller */
ip_vs_control_add(n_cp, cp); ip_vs_control_add(n_cp, cp);
} }
}
/* /*
* Move tunnel to listen state * Move tunnel to listen state
......
...@@ -140,6 +140,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct, ...@@ -140,6 +140,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
{ {
struct nf_conntrack_tuple *orig, new_reply; struct nf_conntrack_tuple *orig, new_reply;
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
struct ip_vs_conn_param p;
if (exp->tuple.src.l3num != PF_INET) if (exp->tuple.src.l3num != PF_INET)
return; return;
...@@ -154,9 +155,10 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct, ...@@ -154,9 +155,10 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
/* RS->CLIENT */ /* RS->CLIENT */
orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum, ip_vs_conn_fill_param(exp->tuple.src.l3num, orig->dst.protonum,
&orig->src.u3, orig->src.u.tcp.port, &orig->src.u3, orig->src.u.tcp.port,
&orig->dst.u3, orig->dst.u.tcp.port); &orig->dst.u3, orig->dst.u.tcp.port, &p);
cp = ip_vs_conn_out_get(&p);
if (cp) { if (cp) {
/* Change reply CLIENT->RS to CLIENT->VS */ /* Change reply CLIENT->RS to CLIENT->VS */
new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
...@@ -176,9 +178,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct, ...@@ -176,9 +178,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
} }
/* CLIENT->VS */ /* CLIENT->VS */
cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum, cp = ip_vs_conn_in_get(&p);
&orig->src.u3, orig->src.u.tcp.port,
&orig->dst.u3, orig->dst.u.tcp.port);
if (cp) { if (cp) {
/* Change reply VS->CLIENT to RS->CLIENT */ /* Change reply VS->CLIENT to RS->CLIENT */
new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
......
...@@ -40,6 +40,19 @@ struct isakmp_hdr { ...@@ -40,6 +40,19 @@ struct isakmp_hdr {
#define PORT_ISAKMP 500 #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 * static struct ip_vs_conn *
ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, 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 sk_buff *skb, struct ip_vs_protocol *pp, ...@@ -47,21 +60,10 @@ ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
int inverse) int inverse)
{ {
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
struct ip_vs_conn_param p;
if (likely(!inverse)) { ah_esp_conn_fill_param_proto(af, iph, inverse, &p);
cp = ip_vs_conn_in_get(af, IPPROTO_UDP, cp = ip_vs_conn_in_get(&p);
&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));
}
if (!cp) { if (!cp) {
/* /*
* We are not sure if the packet is from our * We are not sure if the packet is from our
...@@ -87,21 +89,10 @@ ah_esp_conn_out_get(int af, const struct sk_buff *skb, ...@@ -87,21 +89,10 @@ ah_esp_conn_out_get(int af, const struct sk_buff *skb,
int inverse) int inverse)
{ {
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
struct ip_vs_conn_param p;
if (likely(!inverse)) { ah_esp_conn_fill_param_proto(af, iph, inverse, &p);
cp = ip_vs_conn_out_get(af, IPPROTO_UDP, cp = ip_vs_conn_out_get(&p);
&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));
}
if (!cp) { if (!cp) {
IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet " IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet "
"%s%s %s->%s\n", "%s%s %s->%s\n",
......
...@@ -301,6 +301,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) ...@@ -301,6 +301,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
struct ip_vs_protocol *pp; struct ip_vs_protocol *pp;
struct ip_vs_dest *dest; struct ip_vs_dest *dest;
struct ip_vs_conn_param param;
char *p; char *p;
int i; int i;
...@@ -370,18 +371,17 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) ...@@ -370,18 +371,17 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
} }
} }
if (!(flags & IP_VS_CONN_F_TEMPLATE)) {
cp = ip_vs_conn_in_get(AF_INET, s->protocol, ip_vs_conn_fill_param(AF_INET, s->protocol,
(union nf_inet_addr *)&s->caddr, (union nf_inet_addr *)&s->caddr,
s->cport, s->cport,
(union nf_inet_addr *)&s->vaddr, (union nf_inet_addr *)&s->vaddr,
s->vport); s->vport, &param);
if (!(flags & IP_VS_CONN_F_TEMPLATE))
cp = ip_vs_conn_in_get(&param);
else else
cp = ip_vs_ct_in_get(AF_INET, s->protocol, cp = ip_vs_ct_in_get(&param);
(union nf_inet_addr *)&s->caddr, }
s->cport,
(union nf_inet_addr *)&s->vaddr,
s->vport);
if (!cp) { if (!cp) {
/* /*
* Find the appropriate destination for the connection. * Find the appropriate destination for the connection.
...@@ -406,14 +406,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) ...@@ -406,14 +406,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
else else
flags &= ~IP_VS_CONN_F_INACTIVE; flags &= ~IP_VS_CONN_F_INACTIVE;
} }
cp = ip_vs_conn_new(AF_INET, s->protocol, cp = ip_vs_conn_new(&param,
(union nf_inet_addr *)&s->caddr,
s->cport,
(union nf_inet_addr *)&s->vaddr,
s->vport,
(union nf_inet_addr *)&s->daddr, (union nf_inet_addr *)&s->daddr,
s->dport, s->dport, flags, dest);
flags, dest);
if (dest) if (dest)
atomic_dec(&dest->refcnt); atomic_dec(&dest->refcnt);
if (!cp) { if (!cp) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment