Révision e09ca1b8
Ajouté par Ermal il y a presque 10 ans
patches/stable/10/CP_speedup.diff | ||
---|---|---|
1 | 1 |
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c |
2 |
index 577d644..d76a97e 100644
|
|
2 |
index 577d644..7d82d34 100644
|
|
3 | 3 |
--- a/sbin/ipfw/ipfw2.c |
4 | 4 |
+++ b/sbin/ipfw/ipfw2.c |
5 | 5 |
@@ -4115,8 +4115,9 @@ ipfw_flush(int force) |
... | ... | |
140 | 140 |
/* Port or any other key */ |
141 | 141 |
key = strtol(arg, &p, 10); |
142 | 142 |
/* Skip non-base 10 entries like 'fa1' */ |
143 |
@@ -4304,9 +4328,92 @@ table_fill_xentry(char *arg, ipfw_table_xentry *xent)
|
|
143 |
@@ -4304,9 +4328,103 @@ table_fill_xentry(char *arg, ipfw_table_xentry *xent)
|
|
144 | 144 |
addrlen = sizeof(struct in_addr); |
145 | 145 |
} |
146 | 146 |
|
147 | 147 |
+ ac--; av++; |
148 |
+ if (ac > 1 && av) { |
|
149 |
+ if (_substrcmp(*av, "mac") == 0) { |
|
150 |
+ uint8_t _mask[8]; |
|
151 |
+ |
|
152 |
+ if (type == 0) |
|
153 |
+ type = IPFW_TABLE_CIDR; |
|
154 |
+ get_mac_addr_mask(av[1], (uint8_t *)xent->mac_addr, _mask); |
|
155 |
+ ac-=2; av+=2; |
|
156 |
+ } |
|
157 |
+ } |
|
158 |
+ |
|
148 | 159 |
+ if (do_add && ac > 0) { |
149 | 160 |
+ unsigned int tval; |
150 | 161 |
+ /* isdigit is a bit of a hack here.. */ |
... | ... | |
234 | 245 |
} |
235 | 246 |
|
236 | 247 |
static void |
237 |
@@ -4338,6 +4445,7 @@ table_list(uint16_t num, int need_header)
|
|
248 |
@@ -4338,6 +4456,7 @@ table_list(uint16_t num, int need_header)
|
|
238 | 249 |
l = *a; |
239 | 250 |
tbl = safe_calloc(1, l); |
240 | 251 |
tbl->opheader.opcode = IP_FW_TABLE_XLIST; |
... | ... | |
242 | 253 |
tbl->tbl = num; |
243 | 254 |
if (do_cmd(IP_FW3, tbl, (uintptr_t)&l) < 0) |
244 | 255 |
err(EX_OSERR, "getsockopt(IP_FW_TABLE_XLIST)"); |
245 |
@@ -4377,6 +4485,23 @@ table_list(uint16_t num, int need_header)
|
|
256 |
@@ -4377,6 +4496,23 @@ table_list(uint16_t num, int need_header)
|
|
246 | 257 |
inet_ntoa(*(struct in_addr *)&tval)); |
247 | 258 |
} else |
248 | 259 |
printf("%s %u\n", xent->k.iface, tval); |
... | ... | |
266 | 277 |
} |
267 | 278 |
|
268 | 279 |
if (sz < xent->len) |
280 |
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c |
|
281 |
index 1a6ac08..226bb21 100644 |
|
282 |
--- a/sys/net/if_ethersubr.c |
|
283 |
+++ b/sys/net/if_ethersubr.c |
|
284 |
@@ -742,6 +742,8 @@ ether_demux(struct ifnet *ifp, struct mbuf *m) |
|
285 |
|
|
286 |
if (i != 0 || m == NULL) |
|
287 |
return; |
|
288 |
+ |
|
289 |
+ i = m->m_flags & M_FASTFWD_OURS; |
|
290 |
} |
|
291 |
|
|
292 |
eh = mtod(m, struct ether_header *); |
|
293 |
@@ -781,6 +783,8 @@ ether_demux(struct ifnet *ifp, struct mbuf *m) |
|
294 |
*/ |
|
295 |
m->m_flags &= ~M_VLANTAG; |
|
296 |
m_clrprotoflags(m); |
|
297 |
+ if (i) |
|
298 |
+ m->m_flags |= M_FASTFWD_OURS; |
|
299 |
m_adj(m, ETHER_HDR_LEN); |
|
300 |
|
|
301 |
/* |
|
269 | 302 |
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h |
270 |
index 14b08f5..7b64bf5 100644
|
|
303 |
index 14b08f5..2eedd0b 100644
|
|
271 | 304 |
--- a/sys/netinet/ip_fw.h |
272 | 305 |
+++ b/sys/netinet/ip_fw.h |
273 | 306 |
@@ -74,6 +74,8 @@ typedef struct _ip_fw3_opheader { |
... | ... | |
279 | 312 |
|
280 | 313 |
/* |
281 | 314 |
* The kernel representation of ipfw rules is made of a list of |
282 |
@@ -600,7 +602,9 @@ struct _ipfw_dyn_rule {
|
|
315 |
@@ -600,13 +602,16 @@ struct _ipfw_dyn_rule {
|
|
283 | 316 |
|
284 | 317 |
#define IPFW_TABLE_CIDR 1 /* Table for holding IPv4/IPv6 prefixes */ |
285 | 318 |
#define IPFW_TABLE_INTERFACE 2 /* Table for holding interface names */ |
... | ... | |
290 | 323 |
|
291 | 324 |
typedef struct _ipfw_table_entry { |
292 | 325 |
in_addr_t addr; /* network address */ |
293 |
@@ -617,9 +621,25 @@ typedef struct _ipfw_table_xentry { |
|
326 |
u_int32_t value; /* value */ |
|
327 |
u_int16_t tbl; /* table number */ |
|
328 |
u_int8_t masklen; /* mask length */ |
|
329 |
+ uint64_t mac_addr; |
|
330 |
} ipfw_table_entry; |
|
331 |
|
|
332 |
typedef struct _ipfw_table_xentry { |
|
333 |
@@ -617,9 +622,26 @@ typedef struct _ipfw_table_xentry { |
|
294 | 334 |
uint32_t value; /* value */ |
295 | 335 |
union { |
296 | 336 |
/* Longest field needs to be aligned by 4-byte boundary */ |
... | ... | |
310 | 350 |
struct in6_addr addr6; /* IPv6 address */ |
311 | 351 |
char iface[IF_NAMESIZE]; /* interface name */ |
312 | 352 |
} k; |
353 |
+ uint64_t mac_addr; |
|
313 | 354 |
+ uint64_t bytes; |
314 | 355 |
+ uint64_t packets; |
315 | 356 |
+ uint32_t timestamp; |
... | ... | |
317 | 358 |
|
318 | 359 |
typedef struct _ipfw_table { |
319 | 360 |
diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c |
320 |
index cd466bd..f16c356 100644
|
|
361 |
index cd466bd..f2f117e 100644
|
|
321 | 362 |
--- a/sys/netpfil/ipfw/ip_fw2.c |
322 | 363 |
+++ b/sys/netpfil/ipfw/ip_fw2.c |
323 | 364 |
@@ -358,8 +358,8 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd, struct ip_fw_chain *chain, uin |
... | ... | |
327 | 368 |
- return ipfw_lookup_table_extended(chain, cmd->p.glob, |
328 | 369 |
- ifp->if_xname, tablearg, IPFW_TABLE_INTERFACE); |
329 | 370 |
+ return (ipfw_lookup_table_extended(chain, cmd->p.glob, |
330 |
+ ifp->if_xname, tablearg, IPFW_TABLE_INTERFACE) != NULL); |
|
371 |
+ ifp->if_xname, tablearg, IPFW_TABLE_INTERFACE, NULL) != NULL);
|
|
331 | 372 |
/* Check name */ |
332 | 373 |
if (cmd->p.glob) { |
333 | 374 |
if (fnmatch(cmd->name, ifp->if_xname, 0) == 0) |
... | ... | |
356 | 397 |
break; |
357 | 398 |
|
358 | 399 |
case O_LAYER2: |
359 |
@@ -1437,7 +1439,35 @@ do { \ |
|
360 |
|
|
400 |
@@ -1438,11 +1440,18 @@ do { \ |
|
361 | 401 |
case O_IP_SRC_LOOKUP: |
362 | 402 |
case O_IP_DST_LOOKUP: |
363 |
- if (is_ipv4) { |
|
364 |
+ if (args->eh) { |
|
365 |
+ struct { |
|
366 |
+ struct in_addr addr; |
|
367 |
+ char mac[ETHER_ADDR_LEN]; |
|
368 |
+ } mix; |
|
369 |
+ void *pkey = &mix; |
|
370 |
+ uint32_t v = 0; |
|
371 |
+ |
|
372 |
+ if (is_ipv4) { |
|
373 |
+ mix.addr.s_addr = (cmd->opcode == O_IP_DST_LOOKUP) ? |
|
374 |
+ dst_ip.s_addr : src_ip.s_addr; |
|
375 |
+ memcpy(mix.mac,(cmd->opcode == O_IP_DST_LOOKUP) ? |
|
376 |
+ args->eh->ether_dhost : |
|
377 |
+ args->eh->ether_shost, ETHER_ADDR_LEN); |
|
378 |
+ tblent = ipfw_lookup_table_extended(chain, |
|
379 |
+ cmd->arg1, pkey, &v, |
|
380 |
+ IPFW_TABLE_MIX); |
|
381 |
+ if (tblent == NULL) { |
|
382 |
+ match = 0; |
|
383 |
+ break; |
|
384 |
+ } else |
|
385 |
+ match = 1; |
|
386 |
+ if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) |
|
387 |
+ match = ((ipfw_insn_u32 *)cmd)->d[0] == v; |
|
388 |
+ if (match) |
|
389 |
+ tablearg = v; |
|
403 |
if (is_ipv4) { |
|
404 |
+ struct ether_addr *ea = NULL; |
|
390 | 405 |
+ |
391 |
+ } |
|
392 |
+ } else if (is_ipv4) { |
|
393 | 406 |
uint32_t key = |
394 | 407 |
(cmd->opcode == O_IP_DST_LOOKUP) ? |
395 | 408 |
dst_ip.s_addr : src_ip.s_addr; |
396 |
@@ -1497,9 +1527,9 @@ do { \ |
|
409 |
uint32_t v = 0; |
|
410 |
|
|
411 |
+ if (args->eh) { |
|
412 |
+ ea = (struct ether_addr*)((cmd->opcode == O_IP_DST_LOOKUP) ? |
|
413 |
+ args->eh->ether_dhost : |
|
414 |
+ args->eh->ether_shost); |
|
415 |
+ } |
|
416 |
if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { |
|
417 |
/* generic lookup. The key must be |
|
418 |
* in 32bit big-endian format. |
|
419 |
@@ -1484,22 +1493,37 @@ do { \ |
|
420 |
} else |
|
421 |
break; |
|
422 |
} |
|
423 |
- match = ipfw_lookup_table(chain, |
|
424 |
- cmd->arg1, key, &v); |
|
425 |
- if (!match) |
|
426 |
+ tblent = ipfw_lookup_table_extended(chain, |
|
427 |
+ cmd->arg1, &key, &v, IPFW_TABLE_CIDR, ea); |
|
428 |
+ if (tblent == NULL) { |
|
429 |
+ match = 0; |
|
430 |
break; |
|
431 |
+ } else |
|
432 |
+ match = 1; |
|
433 |
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) |
|
434 |
match = |
|
435 |
((ipfw_insn_u32 *)cmd)->d[0] == v; |
|
436 |
- else |
|
437 |
+ if (match) |
|
438 |
tablearg = v; |
|
439 |
} else if (is_ipv6) { |
|
440 |
+ struct ether_addr *ea = NULL; |
|
397 | 441 |
uint32_t v = 0; |
442 |
+ |
|
443 |
+ if (args->eh) { |
|
444 |
+ ea = (struct ether_addr*)((cmd->opcode == O_IP_DST_LOOKUP) ? |
|
445 |
+ args->eh->ether_dhost : |
|
446 |
+ args->eh->ether_shost); |
|
447 |
+ } |
|
398 | 448 |
void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ? |
399 | 449 |
&args->f_id.dst_ip6: &args->f_id.src_ip6; |
400 | 450 |
- match = ipfw_lookup_table_extended(chain, |
401 |
+ match = (ipfw_lookup_table_extended(chain,
|
|
451 |
+ tblent = ipfw_lookup_table_extended(chain,
|
|
402 | 452 |
cmd->arg1, pkey, &v, |
403 | 453 |
- IPFW_TABLE_CIDR); |
404 |
+ IPFW_TABLE_CIDR) != NULL); |
|
454 |
+ IPFW_TABLE_CIDR, ea); |
|
455 |
+ if (tblent == NULL) { |
|
456 |
+ match = 0; |
|
457 |
+ break; |
|
458 |
+ } else |
|
459 |
+ match = 1; |
|
405 | 460 |
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) |
406 | 461 |
match = ((ipfw_insn_u32 *)cmd)->d[0] == v; |
407 | 462 |
if (match) |
408 |
@@ -2314,8 +2344,7 @@ do { \
|
|
463 |
@@ -2314,8 +2338,7 @@ do { \
|
|
409 | 464 |
break; |
410 | 465 |
|
411 | 466 |
case O_FORWARD_IP: |
... | ... | |
415 | 470 |
if (q == NULL || q->rule != f || |
416 | 471 |
dyn_dir == MATCH_FORWARD) { |
417 | 472 |
struct sockaddr_in *sa; |
418 |
@@ -2330,6 +2359,48 @@ do { \
|
|
473 |
@@ -2330,6 +2353,48 @@ do { \
|
|
419 | 474 |
args->next_hop = sa; |
420 | 475 |
} |
421 | 476 |
} |
... | ... | |
464 | 519 |
retval = IP_FW_PASS; |
465 | 520 |
l = 0; /* exit inner loop */ |
466 | 521 |
done = 1; /* exit outer loop */ |
467 |
@@ -2337,8 +2408,7 @@ do { \
|
|
522 |
@@ -2337,8 +2402,7 @@ do { \
|
|
468 | 523 |
|
469 | 524 |
#ifdef INET6 |
470 | 525 |
case O_FORWARD_IP6: |
471 | 526 |
- if (args->eh) /* not valid on layer2 pkts */ |
472 | 527 |
- break; |
473 |
+ if (args->eh) { /* not valid on layer2 pkts */
|
|
528 |
+ if (!args->eh) {/* not valid on layer2 pkts */
|
|
474 | 529 |
if (q == NULL || q->rule != f || |
475 | 530 |
dyn_dir == MATCH_FORWARD) { |
476 | 531 |
struct sockaddr_in6 *sin6; |
477 |
@@ -2346,6 +2416,24 @@ do { \
|
|
532 |
@@ -2346,6 +2410,24 @@ do { \
|
|
478 | 533 |
sin6 = &(((ipfw_insn_sa6 *)cmd)->sa); |
479 | 534 |
args->next_hop6 = sin6; |
480 | 535 |
} |
... | ... | |
499 | 554 |
retval = IP_FW_PASS; |
500 | 555 |
l = 0; /* exit inner loop */ |
501 | 556 |
done = 1; /* exit outer loop */ |
502 |
@@ -2505,6 +2593,8 @@ do { \
|
|
557 |
@@ -2505,6 +2587,8 @@ do { \
|
|
503 | 558 |
struct ip_fw *rule = chain->map[f_pos]; |
504 | 559 |
/* Update statistics */ |
505 | 560 |
IPFW_INC_RULE_COUNTER(rule, pktlen); |
... | ... | |
568 | 623 |
return 0; |
569 | 624 |
|
570 | 625 |
diff --git a/sys/netpfil/ipfw/ip_fw_private.h b/sys/netpfil/ipfw/ip_fw_private.h |
571 |
index a8d7eea..1d8a4aa 100644
|
|
626 |
index a8d7eea..4830124 100644
|
|
572 | 627 |
--- a/sys/netpfil/ipfw/ip_fw_private.h |
573 | 628 |
+++ b/sys/netpfil/ipfw/ip_fw_private.h |
574 | 629 |
@@ -101,6 +101,7 @@ struct ip_fw_args { |
... | ... | |
579 | 634 |
struct inpcb *inp; |
580 | 635 |
|
581 | 636 |
struct _ip6dn_args dummypar; /* dummynet->ip6_output */ |
582 |
@@ -304,8 +305,11 @@ void ipfw_reap_rules(struct ip_fw *head);
|
|
637 |
@@ -304,13 +305,17 @@ void ipfw_reap_rules(struct ip_fw *head);
|
|
583 | 638 |
struct radix_node; |
584 | 639 |
int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, |
585 | 640 |
uint32_t *val); |
586 | 641 |
-int ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
642 |
- uint32_t *val, int type); |
|
643 |
+struct ether_addr; |
|
587 | 644 |
+void *ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
588 |
uint32_t *val, int type);
|
|
645 |
+ uint32_t *val, int type, struct ether_addr *);
|
|
589 | 646 |
+void ipfw_count_table_xentry_stats(void *, int); |
590 | 647 |
+int ipfw_zero_table_xentry_stats(struct ip_fw_chain *, ipfw_table_xentry *); |
591 | 648 |
+int ipfw_lookup_table_xentry(struct ip_fw_chain *, ipfw_table_xentry *); |
592 | 649 |
int ipfw_init_tables(struct ip_fw_chain *ch); |
593 | 650 |
void ipfw_destroy_tables(struct ip_fw_chain *ch); |
594 | 651 |
int ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl); |
652 |
int ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
653 |
- uint8_t plen, uint8_t mlen, uint8_t type, uint32_t value); |
|
654 |
+ uint8_t plen, uint8_t mlen, uint8_t type, u_int64_t mac_addr, uint32_t value); |
|
655 |
int ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
656 |
uint8_t plen, uint8_t mlen, uint8_t type); |
|
657 |
int ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt); |
|
595 | 658 |
diff --git a/sys/netpfil/ipfw/ip_fw_sockopt.c b/sys/netpfil/ipfw/ip_fw_sockopt.c |
596 |
index cb9c89c..491116e 100644
|
|
659 |
index cb9c89c..d98cac6 100644
|
|
597 | 660 |
--- a/sys/netpfil/ipfw/ip_fw_sockopt.c |
598 | 661 |
+++ b/sys/netpfil/ipfw/ip_fw_sockopt.c |
662 |
@@ -1124,7 +1124,7 @@ ipfw_ctl(struct sockopt *sopt) |
|
663 |
break; |
|
664 |
error = ipfw_add_table_entry(chain, ent.tbl, |
|
665 |
&ent.addr, sizeof(ent.addr), ent.masklen, |
|
666 |
- IPFW_TABLE_CIDR, ent.value); |
|
667 |
+ IPFW_TABLE_CIDR, ent.mac_addr, ent.value); |
|
668 |
} |
|
669 |
break; |
|
670 |
|
|
671 |
@@ -1162,7 +1162,7 @@ ipfw_ctl(struct sockopt *sopt) |
|
672 |
|
|
673 |
error = (opt == IP_FW_TABLE_XADD) ? |
|
674 |
ipfw_add_table_entry(chain, xent->tbl, &xent->k, |
|
675 |
- len, xent->masklen, xent->type, xent->value) : |
|
676 |
+ len, xent->masklen, xent->type, xent->mac_addr, xent->value) : |
|
677 |
ipfw_del_table_entry(chain, xent->tbl, &xent->k, |
|
678 |
len, xent->masklen, xent->type); |
|
679 |
} |
|
599 | 680 |
@@ -1245,6 +1245,47 @@ ipfw_ctl(struct sockopt *sopt) |
600 | 681 |
} |
601 | 682 |
break; |
... | ... | |
645 | 726 |
{ |
646 | 727 |
ipfw_xtable *tbl; |
647 | 728 |
diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c |
648 |
index 95cff5c..a6d0f79 100644
|
|
729 |
index 95cff5c..e916749 100644
|
|
649 | 730 |
--- a/sys/netpfil/ipfw/ip_fw_table.c |
650 | 731 |
+++ b/sys/netpfil/ipfw/ip_fw_table.c |
651 |
@@ -75,6 +75,9 @@ struct table_entry { |
|
732 |
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); |
|
733 |
#include <net/route.h> |
|
734 |
#include <net/vnet.h> |
|
735 |
|
|
736 |
+#include <net/ethernet.h> |
|
737 |
#include <netinet/in.h> |
|
738 |
#include <netinet/ip_var.h> /* struct ipfw_rule_ref */ |
|
739 |
#include <netinet/ip_fw.h> |
|
740 |
@@ -74,7 +75,11 @@ static MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables"); |
|
741 |
struct table_entry { |
|
652 | 742 |
struct radix_node rn[2]; |
653 | 743 |
struct sockaddr_in addr, mask; |
744 |
+ u_int64_t mac_addr; |
|
654 | 745 |
u_int32_t value; |
655 | 746 |
+ u_int32_t timestamp; |
656 | 747 |
+ u_int64_t bytes; |
... | ... | |
658 | 749 |
}; |
659 | 750 |
|
660 | 751 |
struct xaddr_iface { |
661 |
@@ -83,6 +86,22 @@ struct xaddr_iface {
|
|
752 |
@@ -83,6 +88,22 @@ struct xaddr_iface {
|
|
662 | 753 |
char ifname[IF_NAMESIZE]; /* Interface name */ |
663 | 754 |
}; |
664 | 755 |
|
... | ... | |
681 | 772 |
struct table_xentry { |
682 | 773 |
struct radix_node rn[2]; |
683 | 774 |
union { |
684 |
@@ -90,14 +109,25 @@ struct table_xentry {
|
|
775 |
@@ -90,14 +111,26 @@ struct table_xentry {
|
|
685 | 776 |
struct sockaddr_in6 addr6; |
686 | 777 |
#endif |
687 | 778 |
struct xaddr_iface iface; |
... | ... | |
700 | 791 |
+#endif |
701 | 792 |
+ struct xaddr_mix mixmask; |
702 | 793 |
} m; |
794 |
+ u_int64_t mac_addr; |
|
703 | 795 |
u_int32_t value; |
704 | 796 |
+ u_int32_t timestamp; |
705 | 797 |
+ u_int64_t bytes; |
... | ... | |
707 | 799 |
}; |
708 | 800 |
|
709 | 801 |
/* |
710 |
@@ -117,10 +147,17 @@ struct table_xentry {
|
|
802 |
@@ -117,10 +150,17 @@ struct table_xentry {
|
|
711 | 803 |
#define KEY_LEN_INET (offsetof(struct sockaddr_in, sin_addr) + sizeof(in_addr_t)) |
712 | 804 |
#define KEY_LEN_INET6 (offsetof(struct sockaddr_in6, sin6_addr) + sizeof(struct in6_addr)) |
713 | 805 |
#define KEY_LEN_IFACE (offsetof(struct xaddr_iface, ifname)) |
... | ... | |
725 | 817 |
|
726 | 818 |
|
727 | 819 |
#ifdef INET6 |
728 |
@@ -233,6 +270,52 @@ ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
820 |
@@ -137,7 +177,7 @@ ipv6_writemask(struct in6_addr *addr6, uint8_t mask) |
|
821 |
|
|
822 |
int |
|
823 |
ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
824 |
- uint8_t plen, uint8_t mlen, uint8_t type, uint32_t value) |
|
825 |
+ uint8_t plen, uint8_t mlen, uint8_t type, u_int64_t mac_addr, uint32_t value) |
|
826 |
{ |
|
827 |
struct radix_node_head *rnh, **rnh_ptr; |
|
828 |
struct table_entry *ent; |
|
829 |
@@ -161,6 +201,7 @@ ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
830 |
return (EINVAL); |
|
831 |
ent = malloc(sizeof(*ent), M_IPFW_TBL, M_WAITOK | M_ZERO); |
|
832 |
ent->value = value; |
|
833 |
+ ent->mac_addr = mac_addr; |
|
834 |
/* Set 'total' structure length */ |
|
835 |
KEY_LEN(ent->addr) = KEY_LEN_INET; |
|
836 |
KEY_LEN(ent->mask) = KEY_LEN_INET; |
|
837 |
@@ -182,6 +223,7 @@ ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
838 |
return (EINVAL); |
|
839 |
xent = malloc(sizeof(*xent), M_IPFW_TBL, M_WAITOK | M_ZERO); |
|
840 |
xent->value = value; |
|
841 |
+ xent->mac_addr = mac_addr; |
|
842 |
/* Set 'total' structure length */ |
|
843 |
KEY_LEN(xent->a.addr6) = KEY_LEN_INET6; |
|
844 |
KEY_LEN(xent->m.mask6) = KEY_LEN_INET6; |
|
845 |
@@ -233,6 +275,52 @@ ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
729 | 846 |
mask_ptr = NULL; |
730 | 847 |
break; |
731 | 848 |
|
... | ... | |
778 | 895 |
default: |
779 | 896 |
return (EINVAL); |
780 | 897 |
} |
781 |
@@ -367,6 +450,41 @@ ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
898 |
@@ -281,6 +369,19 @@ ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
899 |
IPFW_WUNLOCK(ch); |
|
900 |
|
|
901 |
if (rn == NULL) { |
|
902 |
+ if (type == IPFW_TABLE_CIDR) { |
|
903 |
+ /* Just update if any new value needed */ |
|
904 |
+ struct table_entry *ent2; |
|
905 |
+ |
|
906 |
+ ent2 = (struct table_entry *)(rnh->rnh_lookup(&ent->addr, NULL, rnh)); |
|
907 |
+ if (ent2 != NULL) { |
|
908 |
+ if (ent2->mac_addr) { |
|
909 |
+ if (!bcmp(&mac_addr, &ent2->mac_addr, ETHER_ADDR_LEN)) |
|
910 |
+ ent2->value = value; |
|
911 |
+ } else |
|
912 |
+ ent2->value = value; |
|
913 |
+ } |
|
914 |
+ } |
|
915 |
free(ent_ptr, M_IPFW_TBL); |
|
916 |
return (EEXIST); |
|
917 |
} |
|
918 |
@@ -367,6 +468,41 @@ ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
782 | 919 |
|
783 | 920 |
break; |
784 | 921 |
|
... | ... | |
820 | 957 |
default: |
821 | 958 |
return (EINVAL); |
822 | 959 |
} |
823 |
@@ -552,7 +670,150 @@ ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
|
|
960 |
@@ -552,9 +688,152 @@ ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
|
|
824 | 961 |
return (0); |
825 | 962 |
} |
826 | 963 |
|
... | ... | |
969 | 1106 |
+ |
970 | 1107 |
+void * |
971 | 1108 |
ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
972 |
uint32_t *val, int type) |
|
1109 |
- uint32_t *val, int type) |
|
1110 |
+ uint32_t *val, int type, struct ether_addr *ea) |
|
973 | 1111 |
{ |
974 |
@@ -562,9 +823,9 @@ ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
1112 |
struct radix_node_head *rnh; |
|
1113 |
struct table_xentry *xent; |
|
1114 |
@@ -562,15 +841,21 @@ ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
975 | 1115 |
struct xaddr_iface iface; |
976 | 1116 |
|
977 | 1117 |
if (tbl >= V_fw_tables_max) |
... | ... | |
983 | 1123 |
|
984 | 1124 |
switch (type) { |
985 | 1125 |
case IPFW_TABLE_CIDR: |
986 |
@@ -581,15 +842,37 @@ ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
1126 |
KEY_LEN(sa6) = KEY_LEN_INET6; |
|
1127 |
memcpy(&sa6.sin6_addr, paddr, sizeof(struct in6_addr)); |
|
1128 |
xent = (struct table_xentry *)(rnh->rnh_lookup(&sa6, NULL, rnh)); |
|
1129 |
+ if (xent != NULL) { |
|
1130 |
+ if (ea && xent->mac_addr) { |
|
1131 |
+ if (bcmp((u_char *)&xent->mac_addr, ea->octet, ETHER_ADDR_LEN) != 0) |
|
1132 |
+ xent = NULL; |
|
1133 |
+ } |
|
1134 |
+ } |
|
1135 |
break; |
|
1136 |
|
|
1137 |
case IPFW_TABLE_INTERFACE: |
|
1138 |
@@ -581,15 +866,37 @@ ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, |
|
987 | 1139 |
xent = (struct table_xentry *)(rnh->rnh_lookup(&iface, NULL, rnh)); |
988 | 1140 |
break; |
989 | 1141 |
|
... | ... | |
1024 | 1176 |
} |
1025 | 1177 |
|
1026 | 1178 |
static int |
1027 |
@@ -698,6 +981,9 @@ dump_table_xentry_base(struct radix_node *rn, void *arg)
|
|
1179 |
@@ -698,6 +1005,9 @@ dump_table_xentry_base(struct radix_node *rn, void *arg)
|
|
1028 | 1180 |
/* Save IPv4 address as deprecated IPv6 compatible */ |
1029 | 1181 |
xent->k.addr6.s6_addr32[3] = n->addr.sin_addr.s_addr; |
1030 | 1182 |
xent->value = n->value; |
... | ... | |
1034 | 1186 |
tbl->cnt++; |
1035 | 1187 |
return (0); |
1036 | 1188 |
} |
1037 |
@@ -735,12 +1021,31 @@ dump_table_xentry_extended(struct radix_node *rn, void *arg)
|
|
1189 |
@@ -735,12 +1045,31 @@ dump_table_xentry_extended(struct radix_node *rn, void *arg)
|
|
1038 | 1190 |
memcpy(&xent->k, &n->a.iface.ifname, IF_NAMESIZE); |
1039 | 1191 |
break; |
1040 | 1192 |
|
Formats disponibles : Unified diff
Try to fix it now!
Revert "Back out recent changes to this patch which seem to have broken building on i386 and caused amd64 snaps to not work with pf enabled."
This reverts commit eab013fe08576f0e614fdb56af34715d27a6f489.