ip_fw_table.c (200838) | ip_fw_table.c (201120) |
---|---|
1/*- 2 * Copyright (c) 2004 Ruslan Ermilov and Vsevolod Lobko. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 10 unchanged lines hidden (view full) --- 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2004 Ruslan Ermilov and Vsevolod Lobko. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 10 unchanged lines hidden (view full) --- 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> |
27__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_fw_table.c 200838 2009-12-22 13:53:34Z luigi $"); | 27__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_fw_table.c 201120 2009-12-28 10:12:35Z luigi $"); |
28 29/* 30 * Lookup table support for ipfw 31 * 32 * Lookup tables are implemented (at the moment) using the radix 33 * tree used for routing tables. Tables store key-value entries, where 34 * keys are network prefixes (addr/masklen), and values are integers. 35 * As a degenerate case we can interpret keys as 32-bit integers --- 38 unchanged lines hidden (view full) --- 74MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables"); 75 76struct table_entry { 77 struct radix_node rn[2]; 78 struct sockaddr_in addr, mask; 79 u_int32_t value; 80}; 81 | 28 29/* 30 * Lookup table support for ipfw 31 * 32 * Lookup tables are implemented (at the moment) using the radix 33 * tree used for routing tables. Tables store key-value entries, where 34 * keys are network prefixes (addr/masklen), and values are integers. 35 * As a degenerate case we can interpret keys as 32-bit integers --- 38 unchanged lines hidden (view full) --- 74MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables"); 75 76struct table_entry { 77 struct radix_node rn[2]; 78 struct sockaddr_in addr, mask; 79 u_int32_t value; 80}; 81 |
82/* 83 * The radix code expects addr and mask to be array of bytes, 84 * with the first byte being the length of the array. rn_inithead 85 * is called with the offset in bits of the lookup key within the 86 * array. If we use a sockaddr_in as the underlying type, 87 * sin_len is conveniently located at offset 0, sin_addr is at 88 * offset 4 and normally aligned. 89 * But for portability, let's avoid assumption and make the code explicit 90 */ 91#define KEY_LEN(v) *((uint8_t *)&(v)) 92#define KEY_OFS (8*offsetof(struct sockaddr_in, sin_addr)) 93 |
|
82int 83ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, 84 uint8_t mlen, uint32_t value) 85{ 86 struct radix_node_head *rnh; 87 struct table_entry *ent; 88 struct radix_node *rn; 89 90 if (tbl >= IPFW_TABLES_MAX) 91 return (EINVAL); 92 rnh = ch->tables[tbl]; 93 ent = malloc(sizeof(*ent), M_IPFW_TBL, M_NOWAIT | M_ZERO); 94 if (ent == NULL) 95 return (ENOMEM); 96 ent->value = value; | 94int 95ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, 96 uint8_t mlen, uint32_t value) 97{ 98 struct radix_node_head *rnh; 99 struct table_entry *ent; 100 struct radix_node *rn; 101 102 if (tbl >= IPFW_TABLES_MAX) 103 return (EINVAL); 104 rnh = ch->tables[tbl]; 105 ent = malloc(sizeof(*ent), M_IPFW_TBL, M_NOWAIT | M_ZERO); 106 if (ent == NULL) 107 return (ENOMEM); 108 ent->value = value; |
97 ent->addr.sin_len = ent->mask.sin_len = 8; | 109 KEY_LEN(ent->addr) = KEY_LEN(ent->mask) = 8; |
98 ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0); 99 ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr; 100 IPFW_WLOCK(ch); 101 rn = rnh->rnh_addaddr(&ent->addr, &ent->mask, rnh, (void *)ent); 102 if (rn == NULL) { 103 IPFW_WUNLOCK(ch); 104 free(ent, M_IPFW_TBL); 105 return (EEXIST); --- 8 unchanged lines hidden (view full) --- 114{ 115 struct radix_node_head *rnh; 116 struct table_entry *ent; 117 struct sockaddr_in sa, mask; 118 119 if (tbl >= IPFW_TABLES_MAX) 120 return (EINVAL); 121 rnh = ch->tables[tbl]; | 110 ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0); 111 ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr; 112 IPFW_WLOCK(ch); 113 rn = rnh->rnh_addaddr(&ent->addr, &ent->mask, rnh, (void *)ent); 114 if (rn == NULL) { 115 IPFW_WUNLOCK(ch); 116 free(ent, M_IPFW_TBL); 117 return (EEXIST); --- 8 unchanged lines hidden (view full) --- 126{ 127 struct radix_node_head *rnh; 128 struct table_entry *ent; 129 struct sockaddr_in sa, mask; 130 131 if (tbl >= IPFW_TABLES_MAX) 132 return (EINVAL); 133 rnh = ch->tables[tbl]; |
122 sa.sin_len = mask.sin_len = 8; | 134 KEY_LEN(sa) = KEY_LEN(mask) = 8; |
123 mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0); 124 sa.sin_addr.s_addr = addr & mask.sin_addr.s_addr; 125 IPFW_WLOCK(ch); 126 ent = (struct table_entry *)rnh->rnh_deladdr(&sa, &mask, rnh); 127 if (ent == NULL) { 128 IPFW_WUNLOCK(ch); 129 return (ESRCH); 130 } --- 43 unchanged lines hidden (view full) --- 174 175int 176ipfw_init_tables(struct ip_fw_chain *ch) 177{ 178 int i; 179 uint16_t j; 180 181 for (i = 0; i < IPFW_TABLES_MAX; i++) { | 135 mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0); 136 sa.sin_addr.s_addr = addr & mask.sin_addr.s_addr; 137 IPFW_WLOCK(ch); 138 ent = (struct table_entry *)rnh->rnh_deladdr(&sa, &mask, rnh); 139 if (ent == NULL) { 140 IPFW_WUNLOCK(ch); 141 return (ESRCH); 142 } --- 43 unchanged lines hidden (view full) --- 186 187int 188ipfw_init_tables(struct ip_fw_chain *ch) 189{ 190 int i; 191 uint16_t j; 192 193 for (i = 0; i < IPFW_TABLES_MAX; i++) { |
182 if (!rn_inithead((void **)&ch->tables[i], 32)) { | 194 if (!rn_inithead((void **)&ch->tables[i], KEY_OFS)) { |
183 for (j = 0; j < i; j++) { 184 (void) ipfw_flush_table(ch, j); 185 } 186 return (ENOMEM); 187 } 188 } 189 return (0); 190} --- 4 unchanged lines hidden (view full) --- 195{ 196 struct radix_node_head *rnh; 197 struct table_entry *ent; 198 struct sockaddr_in sa; 199 200 if (tbl >= IPFW_TABLES_MAX) 201 return (0); 202 rnh = ch->tables[tbl]; | 195 for (j = 0; j < i; j++) { 196 (void) ipfw_flush_table(ch, j); 197 } 198 return (ENOMEM); 199 } 200 } 201 return (0); 202} --- 4 unchanged lines hidden (view full) --- 207{ 208 struct radix_node_head *rnh; 209 struct table_entry *ent; 210 struct sockaddr_in sa; 211 212 if (tbl >= IPFW_TABLES_MAX) 213 return (0); 214 rnh = ch->tables[tbl]; |
203 sa.sin_len = 8; | 215 KEY_LEN(sa) = 8; |
204 sa.sin_addr.s_addr = addr; 205 ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh)); 206 if (ent != NULL) { 207 *val = ent->value; 208 return (1); 209 } 210 return (0); 211} --- 57 unchanged lines hidden --- | 216 sa.sin_addr.s_addr = addr; 217 ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh)); 218 if (ent != NULL) { 219 *val = ent->value; 220 return (1); 221 } 222 return (0); 223} --- 57 unchanged lines hidden --- |