Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Dec 2009 00:37:30 +0000 (UTC)
From:      Luigi Rizzo <luigi@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r200973 - user/luigi/ipfw3-head/sys/netinet/ipfw
Message-ID:  <200912250037.nBP0bU8b045509@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: luigi
Date: Fri Dec 25 00:37:29 2009
New Revision: 200973
URL: http://svn.freebsd.org/changeset/base/200973

Log:
  document the assumption on the layout of addr and mask in the table code,
  and use a couple of macros to make sure the assumptions hold.

Modified:
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_table.c

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_table.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_table.c	Fri Dec 25 00:23:47 2009	(r200972)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_table.c	Fri Dec 25 00:37:29 2009	(r200973)
@@ -79,6 +79,18 @@ struct table_entry {
 	u_int32_t		value;
 };
 
+/*
+ * The radix code expects addr and mask to be array of bytes,
+ * with the first byte being the length of the array. rn_inithead
+ * is called with the offset in bits of the lookup key within the
+ * array. If we use a sockaddr_in as the underlying type,
+ * sin_len is conveniently located at offset 0, sin_addr is at
+ * offset 4 and normally aligned.
+ * But for portability, let's avoid assumption and make the code explicit
+ */
+#define KEY_LEN(v)	*((uint8_t *)&(v))
+#define KEY_OFS		(8*offsetof(struct sockaddr_in, sin_addr))
+
 int
 ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
     uint8_t mlen, uint32_t value)
@@ -94,7 +106,7 @@ ipfw_add_table_entry(struct ip_fw_chain 
 	if (ent == NULL)
 		return (ENOMEM);
 	ent->value = value;
-	ent->addr.sin_len = ent->mask.sin_len = 8;
+	KEY_LEN(ent->addr) = KEY_LEN(ent->mask) = 8;
 	ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
 	ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr;
 	IPFW_WLOCK(ch);
@@ -119,7 +131,7 @@ ipfw_del_table_entry(struct ip_fw_chain 
 	if (tbl >= IPFW_TABLES_MAX)
 		return (EINVAL);
 	rnh = ch->tables[tbl];
-	sa.sin_len = mask.sin_len = 8;
+	KEY_LEN(sa) = KEY_LEN(mask) = 8;
 	mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
 	sa.sin_addr.s_addr = addr & mask.sin_addr.s_addr;
 	IPFW_WLOCK(ch);
@@ -179,7 +191,7 @@ ipfw_init_tables(struct ip_fw_chain *ch)
 	uint16_t j;
 
 	for (i = 0; i < IPFW_TABLES_MAX; i++) {
-		if (!rn_inithead((void **)&ch->tables[i], 32)) {
+		if (!rn_inithead((void **)&ch->tables[i], KEY_OFS)) {
 			for (j = 0; j < i; j++) {
 				(void) ipfw_flush_table(ch, j);
 			}
@@ -200,7 +212,7 @@ ipfw_lookup_table(struct ip_fw_chain *ch
 	if (tbl >= IPFW_TABLES_MAX)
 		return (0);
 	rnh = ch->tables[tbl];
-	sa.sin_len = 8;
+	KEY_LEN(sa) = 8;
 	sa.sin_addr.s_addr = addr;
 	ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh));
 	if (ent != NULL) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200912250037.nBP0bU8b045509>