Projet

Général

Profil

« Précédent | Suivant » 

Révision e09ca1b8

Ajouté par Ermal il y a presque 10 ans

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.

Voir les différences:

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