summaryrefslogtreecommitdiffstats
path: root/sys/netpfil/ipfw/ip_fw_table_algo.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netpfil/ipfw/ip_fw_table_algo.c')
-rw-r--r--sys/netpfil/ipfw/ip_fw_table_algo.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/sys/netpfil/ipfw/ip_fw_table_algo.c b/sys/netpfil/ipfw/ip_fw_table_algo.c
index dab6640..3dcde55 100644
--- a/sys/netpfil/ipfw/ip_fw_table_algo.c
+++ b/sys/netpfil/ipfw/ip_fw_table_algo.c
@@ -331,6 +331,7 @@ struct radix_addr_entry {
struct sockaddr_in addr;
uint32_t value;
uint64_t bcnt;
+ uint64_t mac;
uint64_t pcnt;
time_t timestamp;
uint8_t masklen;
@@ -348,6 +349,7 @@ struct radix_addr_xentry {
struct sa_in6 addr6;
uint32_t value;
uint64_t bcnt;
+ uint64_t mac;
uint64_t pcnt;
time_t timestamp;
uint8_t masklen;
@@ -378,7 +380,7 @@ struct ta_buf_radix
};
static int ta_lookup_radix(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te);
+ uint32_t *val, uint8_t *ea, uint8_t *ea, void **te);
static int ta_init_radix(struct ip_fw_chain *ch, void **ta_state,
struct table_info *ti, char *data, uint8_t tflags);
static int flush_radix_entry(struct radix_node *rn, void *arg);
@@ -412,7 +414,7 @@ static int ta_zero_cnt_radix_tentry(void *ta_state, struct table_info *ti,
static int
ta_lookup_radix(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
struct radix_node_head *rnh;
@@ -424,6 +426,11 @@ ta_lookup_radix(struct table_info *ti, void *key, uint32_t keylen,
rnh = (struct radix_node_head *)ti->state;
ent = (struct radix_addr_entry *)(rnh->rnh_matchaddr(&sa, &rnh->rh));
if (ent != NULL) {
+ if (ent->mac != 0 && ea == NULL)
+ return (0);
+ if (ent->mac != 0 &&
+ memcmp(ea, &ent->mac, ETHER_ADDR_LEN) != 0)
+ return (0);
*val = ent->value;
if (te != NULL)
*te = (void *)ent;
@@ -437,6 +444,11 @@ ta_lookup_radix(struct table_info *ti, void *key, uint32_t keylen,
rnh = (struct radix_node_head *)ti->xstate;
xent = (struct radix_addr_xentry *)(rnh->rnh_matchaddr(&sa6, &rnh->rh));
if (xent != NULL) {
+ if (xent->mac != 0 && ea == NULL)
+ return (0);
+ if (xent->mac != 0 &&
+ memcmp(ea, &xent->mac, ETHER_ADDR_LEN) != 0)
+ return (0);
*val = xent->value;
if (te != NULL)
*te = (void *)xent;
@@ -539,6 +551,7 @@ ta_dump_radix_tentry(void *ta_state, struct table_info *ti, void *e,
tent->masklen = n->masklen;
tent->subtype = AF_INET;
tent->v.kidx = n->value;
+ tent->mac = n->mac;
tent->bcnt = n->bcnt;
tent->pcnt = n->pcnt;
tent->timestamp = n->timestamp;
@@ -549,6 +562,7 @@ ta_dump_radix_tentry(void *ta_state, struct table_info *ti, void *e,
tent->masklen = xn->masklen;
tent->subtype = AF_INET6;
tent->v.kidx = xn->value;
+ tent->mac = n->mac;
tent->bcnt = n->bcnt;
tent->pcnt = n->pcnt;
tent->timestamp = n->timestamp;
@@ -739,9 +753,11 @@ ta_add_radix(void *ta_state, struct table_info *ti, struct tentry_info *tei,
/* Save current entry value from @tei */
if (tei->subtype == AF_INET) {
rnh = ti->state;
+ ((struct radix_addr_entry *)tb->ent_ptr)->mac = tei->mac;
((struct radix_addr_entry *)tb->ent_ptr)->value = tei->value;
} else {
rnh = ti->xstate;
+ ((struct radix_addr_xentry *)tb->ent_ptr)->mac = tei->mac;
((struct radix_addr_xentry *)tb->ent_ptr)->value = tei->value;
}
@@ -1034,11 +1050,11 @@ static __inline uint32_t hash_ip6_al(struct in6_addr *addr6, void *key, int mask
int hsize);
#endif
static int ta_lookup_chash_slow(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te);
+ uint32_t *val, uint8_t *ea, void **te);
static int ta_lookup_chash_aligned(struct table_info *ti, void *key,
- uint32_t keylen, uint32_t *val, void **te);
+ uint32_t keylen, uint32_t *val, uint8_t *ea, void **te);
static int ta_lookup_chash_64(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te);
+ uint32_t *val, uint8_t *ea, void **te);
static int chash_parse_opts(struct chash_cfg *cfg, char *data);
static void ta_print_chash_config(void *ta_state, struct table_info *ti,
char *buf, size_t bufsize);
@@ -1139,7 +1155,7 @@ hash_ip6_al(struct in6_addr *addr6, void *key, int mask, int hsize)
static int
ta_lookup_chash_slow(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
struct chashbhead *head;
struct chashentry *ent;
@@ -1188,7 +1204,7 @@ ta_lookup_chash_slow(struct table_info *ti, void *key, uint32_t keylen,
static int
ta_lookup_chash_aligned(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
struct chashbhead *head;
struct chashentry *ent;
@@ -1241,7 +1257,7 @@ ta_lookup_chash_aligned(struct table_info *ti, void *key, uint32_t keylen,
static int
ta_lookup_chash_64(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
struct chashbhead *head;
struct chashentry *ent;
@@ -2124,7 +2140,7 @@ struct ta_buf_ifidx
int compare_ifidx(const void *k, const void *v);
static struct ifidx * ifidx_find(struct table_info *ti, void *key);
static int ta_lookup_ifidx(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te);
+ uint32_t *val, uint8_t *ea, void **te);
static int ta_init_ifidx(struct ip_fw_chain *ch, void **ta_state,
struct table_info *ti, char *data, uint8_t tflags);
static void ta_change_ti_ifidx(void *ta_state, struct table_info *ti);
@@ -2270,7 +2286,7 @@ ifidx_find(struct table_info *ti, void *key)
static int
ta_lookup_ifidx(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
struct ifidx *ifi;
@@ -2895,7 +2911,7 @@ struct ta_buf_numarray
int compare_numarray(const void *k, const void *v);
static struct numarray *numarray_find(struct table_info *ti, void *key);
static int ta_lookup_numarray(struct table_info *ti, void *key,
- uint32_t keylen, uint32_t *val, void **te);
+ uint32_t keylen, uint32_t *val, uint8_t *ea, void **te);
static int ta_init_numarray(struct ip_fw_chain *ch, void **ta_state,
struct table_info *ti, char *data, uint8_t tflags);
static void ta_destroy_numarray(void *ta_state, struct table_info *ti);
@@ -2958,7 +2974,7 @@ numarray_find(struct table_info *ti, void *key)
static int
ta_lookup_numarray(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
struct numarray *ri;
@@ -3406,7 +3422,7 @@ static __inline uint32_t hash_flow4(struct fhashentry4 *f, int hsize);
static __inline uint32_t hash_flow6(struct fhashentry6 *f, int hsize);
static uint32_t hash_flow_ent(struct fhashentry *ent, uint32_t size);
static int ta_lookup_fhash(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te);
+ uint32_t *val, uint8_t *ea, void **te);
static int ta_init_fhash(struct ip_fw_chain *ch, void **ta_state,
struct table_info *ti, char *data, uint8_t tflags);
static void ta_destroy_fhash(void *ta_state, struct table_info *ti);
@@ -3496,7 +3512,7 @@ hash_flow_ent(struct fhashentry *ent, uint32_t size)
static int
ta_lookup_fhash(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
struct fhashbhead *head;
struct fhashentry *ent;
@@ -4151,7 +4167,7 @@ struct table_algo flow_hash = {
*/
static int ta_lookup_kfib(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te);
+ uint32_t *val, uint8_t *ea, void **te);
static int kfib_parse_opts(int *pfib, char *data);
static void ta_print_kfib_config(void *ta_state, struct table_info *ti,
char *buf, size_t bufsize);
@@ -4173,7 +4189,7 @@ static void ta_foreach_kfib(void *ta_state, struct table_info *ti,
static int
ta_lookup_kfib(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
#ifdef INET
struct nhop4_basic nh4;
@@ -4506,7 +4522,7 @@ ta_print_mhash_config(void *ta_state, struct table_info *ti, char *buf,
static __inline int
ta_lookup_find_mhash(struct mhashbhead *head, uint32_t hash2,
- struct macdata *mac, uint32_t *val, void **te)
+ struct macdata *mac, uint32_t *val, uint8_t *ea, void **te)
{
struct macdata any;
struct mhashentry *ent;
@@ -4527,7 +4543,7 @@ ta_lookup_find_mhash(struct mhashbhead *head, uint32_t hash2,
static int
ta_lookup_mhash(struct table_info *ti, void *key, uint32_t keylen,
- uint32_t *val, void **te)
+ uint32_t *val, uint8_t *ea, void **te)
{
struct macdata mac;
struct mhashbhead *head;
@@ -4541,21 +4557,21 @@ ta_lookup_mhash(struct table_info *ti, void *key, uint32_t keylen,
hsize = 1 << (ti->data & 0xFF);
hash2 = hash_mac2(key, hsize);
if (ta_lookup_find_mhash(head, hash2,
- (struct macdata *)key, val, te) == 1)
+ (struct macdata *)key, val, NULL, te) == 1)
return (1);
/* src any */
memcpy(mac.addr, key, 6);
memset(mac.addr + 6, 0, 6);
hash2 = hash_mac2(mac.addr, hsize);
- if (ta_lookup_find_mhash(head, hash2, &mac, val, te) == 1)
+ if (ta_lookup_find_mhash(head, hash2, &mac, val, NULL, te) == 1)
return (1);
/* dst any */
memset(mac.addr, 0, 6);
memcpy(mac.addr + 6, (uintptr_t *)key + 6, 6);
hash2 = hash_mac2(mac.addr, hsize);
- if (ta_lookup_find_mhash(head, hash2, &mac, val, te) == 1)
+ if (ta_lookup_find_mhash(head, hash2, &mac, val, NULL, te) == 1)
return (1);
return (0);
OpenPOWER on IntegriCloud