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