Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 8961
b: refs/heads/master
c: 87375ab
h: refs/heads/master
i:
  8959: 854e93c
v: v3
  • Loading branch information
Julian Anastasov authored and David S. Miller committed Sep 15, 2005
1 parent b6b04d4 commit 6a65454
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f5e229db9cdb27f83594712ca4bb98d9377eb6ed
refs/heads/master: 87375ab47cd0ba04124c6d3fd80db5c368f5dcb6
3 changes: 3 additions & 0 deletions trunk/include/net/ip_vs.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#define IP_VS_CONN_F_IN_SEQ 0x0400 /* must do input seq adjust */
#define IP_VS_CONN_F_SEQ_MASK 0x0600 /* in/out sequence mask */
#define IP_VS_CONN_F_NO_CPORT 0x0800 /* no client port set yet */
#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */

/* Move it to better place one day, for now keep it unique */
#define NFC_IPVS_PROPERTY 0x10000
Expand Down Expand Up @@ -739,6 +740,8 @@ enum {

extern struct ip_vs_conn *ip_vs_conn_in_get
(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
extern struct ip_vs_conn *ip_vs_ct_in_get
(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
extern struct ip_vs_conn *ip_vs_conn_out_get
(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);

Expand Down
41 changes: 38 additions & 3 deletions trunk/net/ipv4/ipvs/ip_vs_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get
list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
if (s_addr==cp->caddr && s_port==cp->cport &&
d_port==cp->vport && d_addr==cp->vaddr &&
((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) &&
protocol==cp->protocol) {
/* HIT */
atomic_inc(&cp->refcnt);
Expand Down Expand Up @@ -227,6 +228,40 @@ struct ip_vs_conn *ip_vs_conn_in_get
return cp;
}

/* Get reference to connection template */
struct ip_vs_conn *ip_vs_ct_in_get
(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
{
unsigned hash;
struct ip_vs_conn *cp;

hash = ip_vs_conn_hashkey(protocol, s_addr, s_port);

ct_read_lock(hash);

list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
if (s_addr==cp->caddr && s_port==cp->cport &&
d_port==cp->vport && d_addr==cp->vaddr &&
cp->flags & IP_VS_CONN_F_TEMPLATE &&
protocol==cp->protocol) {
/* HIT */
atomic_inc(&cp->refcnt);
goto out;
}
}
cp = NULL;

out:
ct_read_unlock(hash);

IP_VS_DBG(7, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
ip_vs_proto_name(protocol),
NIPQUAD(s_addr), ntohs(s_port),
NIPQUAD(d_addr), ntohs(d_port),
cp?"hit":"not hit");

return cp;
}

/*
* Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab.
Expand Down Expand Up @@ -367,7 +402,7 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
atomic_read(&dest->refcnt));

/* Update the connection counters */
if (cp->cport || (cp->flags & IP_VS_CONN_F_NO_CPORT)) {
if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) {
/* It is a normal connection, so increase the inactive
connection counter because it is in TCP SYNRECV
state (inactive) or other protocol inacive state */
Expand Down Expand Up @@ -406,7 +441,7 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
atomic_read(&dest->refcnt));

/* Update the connection counters */
if (cp->cport || (cp->flags & IP_VS_CONN_F_NO_CPORT)) {
if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) {
/* It is a normal connection, so decrease the inactconns
or activeconns counter */
if (cp->flags & IP_VS_CONN_F_INACTIVE) {
Expand Down Expand Up @@ -776,7 +811,7 @@ void ip_vs_random_dropentry(void)
ct_write_lock_bh(hash);

list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
if (!cp->cport && !(cp->flags & IP_VS_CONN_F_NO_CPORT))
if (cp->flags & IP_VS_CONN_F_TEMPLATE)
/* connection template */
continue;

Expand Down
16 changes: 8 additions & 8 deletions trunk/net/ipv4/ipvs/ip_vs_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
if (ports[1] == svc->port) {
/* Check if a template already exists */
if (svc->port != FTPPORT)
ct = ip_vs_conn_in_get(iph->protocol, snet, 0,
ct = ip_vs_ct_in_get(iph->protocol, snet, 0,
iph->daddr, ports[1]);
else
ct = ip_vs_conn_in_get(iph->protocol, snet, 0,
ct = ip_vs_ct_in_get(iph->protocol, snet, 0,
iph->daddr, 0);

if (!ct || !ip_vs_check_template(ct)) {
Expand All @@ -272,14 +272,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
iph->daddr,
ports[1],
dest->addr, dest->port,
0,
IP_VS_CONN_F_TEMPLATE,
dest);
else
ct = ip_vs_conn_new(iph->protocol,
snet, 0,
iph->daddr, 0,
dest->addr, 0,
0,
IP_VS_CONN_F_TEMPLATE,
dest);
if (ct == NULL)
return NULL;
Expand All @@ -298,10 +298,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
* port zero template: <protocol,caddr,0,vaddr,0,daddr,0>
*/
if (svc->fwmark)
ct = ip_vs_conn_in_get(IPPROTO_IP, snet, 0,
ct = ip_vs_ct_in_get(IPPROTO_IP, snet, 0,
htonl(svc->fwmark), 0);
else
ct = ip_vs_conn_in_get(iph->protocol, snet, 0,
ct = ip_vs_ct_in_get(iph->protocol, snet, 0,
iph->daddr, 0);

if (!ct || !ip_vs_check_template(ct)) {
Expand All @@ -326,14 +326,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
snet, 0,
htonl(svc->fwmark), 0,
dest->addr, 0,
0,
IP_VS_CONN_F_TEMPLATE,
dest);
else
ct = ip_vs_conn_new(iph->protocol,
snet, 0,
iph->daddr, 0,
dest->addr, 0,
0,
IP_VS_CONN_F_TEMPLATE,
dest);
if (ct == NULL)
return NULL;
Expand Down
20 changes: 14 additions & 6 deletions trunk/net/ipv4/ipvs/ip_vs_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,24 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)

p = (char *)buffer + sizeof(struct ip_vs_sync_mesg);
for (i=0; i<m->nr_conns; i++) {
unsigned flags;

s = (struct ip_vs_sync_conn *)p;
cp = ip_vs_conn_in_get(s->protocol,
s->caddr, s->cport,
s->vaddr, s->vport);
flags = ntohs(s->flags);
if (!(flags & IP_VS_CONN_F_TEMPLATE))
cp = ip_vs_conn_in_get(s->protocol,
s->caddr, s->cport,
s->vaddr, s->vport);
else
cp = ip_vs_ct_in_get(s->protocol,
s->caddr, s->cport,
s->vaddr, s->vport);
if (!cp) {
cp = ip_vs_conn_new(s->protocol,
s->caddr, s->cport,
s->vaddr, s->vport,
s->daddr, s->dport,
ntohs(s->flags), NULL);
flags, NULL);
if (!cp) {
IP_VS_ERR("ip_vs_conn_new failed\n");
return;
Expand All @@ -315,11 +323,11 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
} else if (!cp->dest) {
/* it is an entry created by the synchronization */
cp->state = ntohs(s->state);
cp->flags = ntohs(s->flags) | IP_VS_CONN_F_HASHED;
cp->flags = flags | IP_VS_CONN_F_HASHED;
} /* Note that we don't touch its state and flags
if it is a normal entry. */

if (ntohs(s->flags) & IP_VS_CONN_F_SEQ_MASK) {
if (flags & IP_VS_CONN_F_SEQ_MASK) {
opt = (struct ip_vs_sync_conn_options *)&s[1];
memcpy(&cp->in_seq, opt, sizeof(*opt));
p += FULL_CONN_SIZE;
Expand Down

0 comments on commit 6a65454

Please sign in to comment.