PERFORCE change 105342 for review
Paolo Pisati
piso at FreeBSD.org
Wed Aug 30 17:58:34 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=105342
Change 105342 by piso at piso_newluxor on 2006/08/30 17:58:23
nat_chain, redir_chain and spool_chain were converted
to use queue(3).
Affected files ...
.. //depot/projects/soc2005/libalias/sys/netinet/ip_fw.h#5 edit
.. //depot/projects/soc2005/libalias/sys/netinet/ip_fw2.c#9 edit
Differences ...
==== //depot/projects/soc2005/libalias/sys/netinet/ip_fw.h#5 (text+ko) ====
@@ -320,7 +320,7 @@
/* Server pool support (LSNAT). */
struct cfg_spool {
- struct cfg_spool *next; /* chain of spool instances */
+ LIST_ENTRY(cfg_spool) _next; /* chain of spool instances */
struct in_addr addr;
u_short port;
};
@@ -332,7 +332,7 @@
/* Nat redirect configuration. */
struct cfg_redir {
- struct cfg_redir *next; /* chain of redir instances */
+ LIST_ENTRY(cfg_redir) _next; /* chain of redir instances */
u_int16_t mode; /* type of redirect mode */
struct in_addr laddr; /* local ip address */
struct in_addr paddr; /* public ip address */
@@ -345,20 +345,21 @@
int proto; /* protocol: tcp/udp */
struct alias_link **alink;
u_int16_t spool_cnt; /* number of entry in spool chain */
- struct cfg_spool *spool_chain; /* chain of spool instances */
+ /* chain of spool instances */
+ LIST_HEAD(spool_chain, cfg_spool) spool_chain;
};
#define NAT_BUF_LEN 1024
/* Nat configuration data struct. */
struct cfg_nat {
- struct cfg_nat *next; /* chain of nat instances */
+ LIST_ENTRY(cfg_nat) _next; /* chain of nat instances */
int id; /* nat id */
struct in_addr ip; /* nat ip address */
char if_name[IF_NAMESIZE]; /* interface name */
int mode; /* aliasing mode */
struct libalias *lib; /* libalias instance */
- int redir_cnt; /* number of entry in spool chain */
- struct cfg_redir *redir_chain; /* chain of redir instances */
+ int redir_cnt; /* number of entry in spool chain */
+ LIST_HEAD(redir_chain, cfg_redir) redir_chain; /* chain of redir instances */
};
/* Nat command. */
==== //depot/projects/soc2005/libalias/sys/netinet/ip_fw2.c#9 (text+ko) ====
@@ -302,9 +302,7 @@
MODULE_DEPEND(ipfw, libalias, 1, 1, 1);
struct rwlock nat_chain_rwl;
-struct _nat_chain {
- struct cfg_nat *chain;
-} nat_chain;
+LIST_HEAD(nat_chain, cfg_nat) nat_chain = LIST_HEAD_INITIALIZER(foo);
#define NAT_LOCK_INIT(_chain) \
rw_init(_chain, "NAT instances")
@@ -2058,13 +2056,14 @@
lookup_nat(const int i) {
struct cfg_nat *ptr;
- for (ptr = nat_chain.chain; ptr != NULL; ptr = ptr->next)
- if (ptr->id == i) return(ptr);
- return(NULL);
+ LIST_FOREACH(ptr, &nat_chain, _next)
+ if (ptr->id == i)
+ return(ptr);
+ return (NULL);
}
/* Attach p to b chain. */
-static void
+__unused static void
hook_entry(struct _chain **b, struct _chain *p) {
/* XXX better to make an in-order addition... */
@@ -2074,7 +2073,7 @@
}
/* Remove p from b chain. */
-static void
+__unused static void
unhook_entry(struct _chain **b, struct _chain *p) {
NAT_WLOCK_ASSERT(&nat_chain_rwl);
@@ -2084,32 +2083,32 @@
}
#define HOOK_NAT(b, p) do { \
- NAT_WLOCK_ASSERT(&nat_chain_rwl); \
- hook_entry((struct _chain **)b, (struct _chain *)p); \
+ NAT_WLOCK_ASSERT(&nat_chain_rwl); \
+ LIST_INSERT_HEAD(b, p, _next); \
} while (0)
-#define UNHOOK_NAT(b, p) do { \
- NAT_WLOCK_ASSERT(&nat_chain_rwl); \
- unhook_entry((struct _chain **)b, (struct _chain *)p); \
+#define UNHOOK_NAT(p) do { \
+ NAT_WLOCK_ASSERT(&nat_chain_rwl); \
+ LIST_REMOVE(p, _next); \
} while (0)
#define HOOK_REDIR(b, p) do { \
- hook_entry((struct _chain **)b, (struct _chain *)p); \
+ LIST_INSERT_HEAD(b, p, _next); \
} while (0)
#define HOOK_SPOOL(b, p) do { \
- hook_entry((struct _chain **)b, (struct _chain *)p); \
+ LIST_INSERT_HEAD(b, p, _next); \
} while (0)
static void
-del_redir_spool_cfg(struct cfg_nat *n, struct cfg_redir *r) {
- struct cfg_redir *tmp_r;
- struct cfg_spool *tmp_s;
+del_redir_spool_cfg(struct cfg_nat *n, struct redir_chain *head) {
+ struct cfg_redir *r, *tmp_r;
+ struct cfg_spool *s, *tmp_s;
int i, num;
- while(r) {
+ LIST_FOREACH_SAFE(r, head, _next, tmp_r) {
num = 1; /* Number of alias_link to delete. */
- switch (r->mode) {
+ switch (r->mode) {
case REDIR_PORT:
num = r->pport_cnt;
case REDIR_ADDR:
@@ -2119,15 +2118,13 @@
LibAliasRedirectDelete(n->lib,
r->alink[i]);
/* Del spool cfg if any. */
- while(r->spool_chain) {
- tmp_s = r->spool_chain->next;
- free(r->spool_chain, M_IPFW);
- r->spool_chain = tmp_s;
+ LIST_FOREACH_SAFE(s, &r->spool_chain, _next, tmp_s) {
+ LIST_REMOVE(s, _next);
+ free(s, M_IPFW);
}
- tmp_r = r->next;
free(r->alink, M_IPFW);
+ LIST_REMOVE(r, _next);
free(r, M_IPFW);
- r = tmp_r;
break;
default:
printf("unknown redirect mode: %u\n", r->mode);
@@ -2135,7 +2132,6 @@
break;
}
}
- n->redir_chain = NULL;
}
static int
@@ -2146,31 +2142,25 @@
struct cfg_redir *r, *ser_r;
struct cfg_spool *s, *ser_s;
int cnt, off, i;
+ char *panic_err;
for(cnt = 0, off = 0; cnt < ptr->redir_cnt; cnt++) {
ser_r = (struct cfg_redir *)&buf[off];
r = malloc(sof_redir, M_IPFW, M_NOWAIT | M_ZERO);
if (r == NULL) {
- /* Try to recover:
- * set the actual number of redir entries
- * that were hooked succesfully.
- */
- ptr->redir_cnt = cnt;
- del_redir_spool_cfg(ptr, ptr->redir_chain);
- // XXX - NAT_WUNLOCK...
- return (ENOSPC);
+ panic_err = "malloc(sof_redir, ...) failed";
+ goto bad;
}
memcpy(r, ser_r, sof_redir);
+ LIST_INIT(&r->spool_chain);
off += sof_redir;
r->alink = malloc(sof_alinkp*r->pport_cnt,
M_IPFW, M_NOWAIT | M_ZERO);
- if (r->alink == NULL) {
- r->pport_cnt = 0;
- del_redir_spool_cfg(ptr, ptr->redir_chain);
- // XXX - NAT_WUNLOCK...
- return (ENOSPC);
+ if (r->alink == NULL) {
+ panic_err = "malloc(sof_alinkp*r->pport_cnt, ...) failed";
+ goto bad;
}
- switch(r->mode) {
+ switch (r->mode) {
case REDIR_ADDR:
r->alink[0] = LibAliasRedirectAddr(ptr->lib,
r->laddr,
@@ -2206,17 +2196,16 @@
printf("unknown redirect mode: %u\n", r->mode);
break;
}
- if (r->alink[0] == NULL) { /* panic?!?!? */
- free(r->alink, M_IPFW);
- printf("previous LibAliasRedirect* returned NULL!!!\n");
+ if (r->alink[0] == NULL) {
+ panic_err = "LibAliasRedirect* returned NULL!!!\n";
+ goto bad;
} else /* LSNAT handling. */
for (i=0; i < r->spool_cnt; i++) {
ser_s = (struct cfg_spool *)&buf[off];
s = malloc(sof_redir, M_IPFW, M_NOWAIT | M_ZERO);
if (s == NULL) {
- r->spool_cnt = i;
- del_redir_spool_cfg(ptr, r);
- return (ENOSPC);
+ panic_err = "malloc(sof_redir, ...) failed";
+ goto bad;
}
memcpy(s, ser_s, sof_spool);
LibAliasAddServer(ptr->lib, r->alink[0],
@@ -2230,6 +2219,9 @@
HOOK_REDIR(&ptr->redir_chain, r);
}
return (1);
+bad:
+ /* something really bad happened: panic! */
+ panic("%s\n", panic_err);
}
/*
@@ -4319,7 +4311,7 @@
NAT_WLOCK(&nat_chain_rwl);
/* Check every nat entry... */
- for (ptr = nat_chain.chain; ptr; ptr = ptr->next) {
+ LIST_FOREACH(ptr, &nat_chain, _next) {
/* ...using nic 'ifp->if_xname' as dynamic alias address. */
if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) == 0) {
mtx_lock(&ifp->if_addr_mtx);
@@ -4564,7 +4556,6 @@
{
struct cfg_nat *ptr, *ser_n;
char *buf;
- int err=0;
buf = malloc(NAT_BUF_LEN, M_IPFW, M_NOWAIT | M_ZERO);
if (buf == NULL)
@@ -4592,9 +4583,10 @@
free(buf, M_IPFW);
NAT_WUNLOCK(&nat_chain_rwl);
return(EINVAL);
- }
+ }
+ LIST_INIT(&ptr->redir_chain);
} else { /* Entry already present: temporarly unhook it. */
- UNHOOK_NAT(&nat_chain.chain, ptr);
+ UNHOOK_NAT(ptr);
flush_nat_ptrs(ser_n->id);
}
NAT_WUNLOCK(&nat_chain_rwl);
@@ -4617,16 +4609,13 @@
/*
* Redir and LSNAT configuration.
*/
- del_redir_spool_cfg(ptr, ptr->redir_chain); /* Delete old cfgs. */
- err = add_redir_spool_cfg(&buf[(sizeof(struct cfg_nat))],
- ptr); /* Add new entries. */
+ del_redir_spool_cfg(ptr, &ptr->redir_chain); /* Delete old cfgs. */
+ add_redir_spool_cfg(&buf[(sizeof(struct cfg_nat))],
+ ptr); /* Add new entries. */
free(buf, M_IPFW);
- if (err == 1) {
- NAT_WLOCK(&nat_chain_rwl);
- HOOK_NAT(&nat_chain.chain, ptr);
- NAT_WUNLOCK(&nat_chain_rwl);
- } else /* Something bad happened, redir cfg not added. */
- return(EINVAL);
+ NAT_WLOCK(&nat_chain_rwl);
+ HOOK_NAT(&nat_chain, ptr);
+ NAT_WUNLOCK(&nat_chain_rwl);
}
break;
@@ -4643,10 +4632,10 @@
NAT_WUNLOCK(&nat_chain_rwl);
break;
}
- UNHOOK_NAT(&nat_chain.chain, ptr);
+ UNHOOK_NAT(ptr);
NAT_WUNLOCK(&nat_chain_rwl);
flush_nat_ptrs(i);
- del_redir_spool_cfg(ptr, ptr->redir_chain);
+ del_redir_spool_cfg(ptr, &ptr->redir_chain);
LibAliasUninit(ptr->lib);
free(ptr, M_IPFW);
}
@@ -4668,20 +4657,26 @@
return (ENOSPC);
NAT_RLOCK(&nat_chain_rwl);
/* Serialize all the data. */
- for (n = nat_chain.chain; (n && (off + sof_nat < NAT_BUF_LEN));
- n = n->next) {
- bcopy(n, &data[off], sof_nat);
- off += sof_nat;
- for (r = n->redir_chain; (r && (off + sof_redir < NAT_BUF_LEN));
- r = r->next) {
- bcopy(r, &data[off], sof_redir);
- off += sof_redir;
- for (s = r->spool_chain; (s && (off + sof_spool < NAT_BUF_LEN));
- s = s->next) {
- bcopy(s, &data[off], sof_spool);
- off += sof_spool;
+ LIST_FOREACH(n, &nat_chain, _next) {
+ if (off + sof_nat < NAT_BUF_LEN) {
+ bcopy(n, &data[off], sof_nat);
+ off += sof_nat;
+ LIST_FOREACH(r, &n->redir_chain, _next) {
+ if (off + sof_redir < NAT_BUF_LEN) {
+ bcopy(r, &data[off], sof_redir);
+ off += sof_redir;
+ LIST_FOREACH(s, &r->spool_chain, _next) {
+ if (off + sof_spool < NAT_BUF_LEN) {
+ bcopy(s, &data[off], sof_spool);
+ off += sof_spool;
+ } else
+ break;
+ }
+ } else
+ break;
}
- }
+ } else
+ break;
}
NAT_RUNLOCK(&nat_chain_rwl);
@@ -4697,8 +4692,9 @@
int sof = LIBALIAS_BUF_SIZE;
int i, size, cnt = 0;
- NAT_RLOCK(&nat_chain_rwl);
- for (ptr = nat_chain.chain, size = i = 0; ptr; ptr = ptr->next) {
+ NAT_RLOCK(&nat_chain_rwl);
+ size = i = 0;
+ LIST_FOREACH(ptr, &nat_chain, _next) {
if (ptr->lib->logDesc == NULL)
continue;
cnt++;
@@ -4889,7 +4885,6 @@
ip_fw_ctl_ptr = ipfw_ctl;
ip_fw_chk_ptr = ipfw_chk;
callout_reset(&ipfw_timeout, hz, ipfw_tick, NULL);
- nat_chain.chain = NULL;
NAT_LOCK_INIT(&nat_chain_rwl);
ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change,
NULL, EVENTHANDLER_PRI_ANY);
@@ -4908,9 +4903,9 @@
IPFW_WLOCK(&layer3_chain);
flush_tables(&layer3_chain);
NAT_WLOCK(&nat_chain_rwl);
- for (ptr = nat_chain.chain; ptr; ptr = ptr_temp) {
- ptr_temp = ptr->next;
- del_redir_spool_cfg(ptr, ptr->redir_chain);
+ LIST_FOREACH_SAFE(ptr, &nat_chain, _next, ptr_temp) {
+ LIST_REMOVE(ptr, _next);
+ del_redir_spool_cfg(ptr, &ptr->redir_chain);
LibAliasUninit(ptr->lib);
free(ptr, M_IPFW);
}
More information about the p4-projects
mailing list