Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102683407
D37193.id112326.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D37193.id112326.diff
View Options
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -109,6 +109,7 @@
char tagname[PF_TAG_NAME_SIZE];
uint16_t dnpipe;
uint32_t dnflags;
+ char bridge_to[IFNAMSIZ];
uint8_t action;
struct pfctl_eth_anchor *anchor;
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -664,6 +664,9 @@
rule->anchor_relative = nvlist_get_number(nvl, "anchor_relative");
rule->anchor_wildcard = nvlist_get_number(nvl, "anchor_wildcard");
+ strlcpy(rule->bridge_to, nvlist_get_string(nvl, "bridge_to"),
+ IFNAMSIZ);
+
rule->action = nvlist_get_number(nvl, "action");
}
@@ -811,6 +814,8 @@
nvlist_add_number(nvl, "dnpipe", r->dnpipe);
nvlist_add_number(nvl, "dnflags", r->dnflags);
+ nvlist_add_string(nvl, "bridge_to", r->bridge_to);
+
nvlist_add_number(nvl, "action", r->action);
packed = nvlist_pack(nvl, &size);
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -351,7 +351,8 @@
void expand_eth_rule(struct pfctl_eth_rule *,
struct node_if *, struct node_etherproto *,
struct node_mac *, struct node_mac *,
- struct node_host *, struct node_host *, const char *);
+ struct node_host *, struct node_host *, const char *,
+ const char *);
void expand_rule(struct pfctl_rule *, struct node_if *,
struct node_host *, struct node_proto *, struct node_os *,
struct node_host *, struct node_port *, struct node_host *,
@@ -432,6 +433,7 @@
struct {
struct node_mac *mac;
} etheraddr;
+ char *bridge_to;
struct {
struct node_host *host;
u_int8_t rt;
@@ -503,7 +505,7 @@
%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
-%token DIVERTTO DIVERTREPLY
+%token DIVERTTO DIVERTREPLY BRIDGE_TO
%token <v.string> STRING
%token <v.number> NUMBER
%token <v.i> PORTBINARY
@@ -563,6 +565,7 @@
%type <v.etherproto> etherproto etherproto_list etherproto_item
%type <v.etherfromto> etherfromto
%type <v.etheraddr> etherfrom etherto
+%type <v.bridge_to> bridge
%type <v.mac> xmac mac mac_list macspec
%%
@@ -1195,7 +1198,7 @@
}
;
-etherrule : ETHER action dir quick interface etherproto etherfromto l3fromto etherfilter_opts
+etherrule : ETHER action dir quick interface bridge etherproto etherfromto l3fromto etherfilter_opts
{
struct pfctl_eth_rule r;
@@ -1207,23 +1210,23 @@
r.action = $2.b1;
r.direction = $3;
r.quick = $4.quick;
- if ($9.tag != NULL)
- memcpy(&r.tagname, $9.tag, sizeof(r.tagname));
- if ($9.match_tag)
- if (strlcpy(r.match_tagname, $9.match_tag,
+ if ($10.tag != NULL)
+ memcpy(&r.tagname, $10.tag, sizeof(r.tagname));
+ if ($10.match_tag)
+ if (strlcpy(r.match_tagname, $10.match_tag,
PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
yyerror("tag too long, max %u chars",
PF_TAG_NAME_SIZE - 1);
YYERROR;
}
- r.match_tag_not = $9.match_tag_not;
- if ($9.queues.qname != NULL)
- memcpy(&r.qname, $9.queues.qname, sizeof(r.qname));
- r.dnpipe = $9.dnpipe;
- r.dnflags = $9.free_flags;
+ r.match_tag_not = $10.match_tag_not;
+ if ($10.queues.qname != NULL)
+ memcpy(&r.qname, $10.queues.qname, sizeof(r.qname));
+ r.dnpipe = $10.dnpipe;
+ r.dnflags = $10.free_flags;
- expand_eth_rule(&r, $5, $6, $7.src, $7.dst,
- $8.src.host, $8.dst.host, "");
+ expand_eth_rule(&r, $5, $7, $8.src, $8.dst,
+ $9.src.host, $9.dst.host, $6, "");
}
;
@@ -1315,7 +1318,7 @@
r.quick = $5.quick;
expand_eth_rule(&r, $6, $7, $8.src, $8.dst,
- $9.src.host, $9.dst.host,
+ $9.src.host, $9.dst.host, NULL,
pf->eastack[pf->asd + 1] ? pf->ealast->name : $3);
free($3);
@@ -1361,6 +1364,14 @@
}
;
+bridge : /* empty */ {
+ $$ = NULL;
+ }
+ | BRIDGE_TO STRING {
+ $$ = strdup($2);
+ }
+ ;
+
scrubrule : scrubaction dir logquick interface af proto fromto scrub_opts
{
struct pfctl_rule r;
@@ -5801,7 +5812,8 @@
expand_eth_rule(struct pfctl_eth_rule *r,
struct node_if *interfaces, struct node_etherproto *protos,
struct node_mac *srcs, struct node_mac *dsts,
- struct node_host *ipsrcs, struct node_host *ipdsts, const char *anchor_call)
+ struct node_host *ipsrcs, struct node_host *ipdsts,
+ const char *bridge_to, const char *anchor_call)
{
char tagname[PF_TAG_NAME_SIZE];
char match_tagname[PF_TAG_NAME_SIZE];
@@ -5852,6 +5864,9 @@
if (strlcpy(r->qname, qname, sizeof(r->qname)) >= sizeof(r->qname))
errx(1, "expand_eth_rule: r->qname");
+ if (bridge_to)
+ strlcpy(r->bridge_to, bridge_to, sizeof(r->bridge_to));
+
pfctl_append_eth_rule(pf, r, anchor_call);
))))));
@@ -6110,6 +6125,7 @@
{ "bitmask", BITMASK},
{ "block", BLOCK},
{ "block-policy", BLOCKPOLICY},
+ { "bridge-to", BRIDGE_TO},
{ "buckets", BUCKETS},
{ "cbq", CBQ},
{ "code", CODE},
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -772,6 +772,8 @@
else
printf(" on %s", r->ifname);
}
+ if (r->bridge_to[0])
+ printf(" bridge-to %s", r->bridge_to);
if (r->proto)
printf(" proto 0x%04x", r->proto);
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -28,7 +28,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd March 9, 2022
+.Dd October 28, 2022
.Dt PF.CONF 5
.Os
.Sh NAME
@@ -710,6 +710,9 @@
.Ic group
keyword in
.Xr ifconfig 8 .
+.It Ar bridge-to Aq interface
+Packets matching this rule will be sent out of the specified interface without
+futher processing.
.It Ar proto Aq Ar protocol
This rule applies only to packets of this protocol.
Note that Ethernet protocol numbers are different from those used in
@@ -3076,8 +3079,9 @@
[ "keepcounters" ] )
ether-rule = "ether" etheraction [ ( "in" | "out" ) ]
- [ "quick" ] [ "on" ifspec ] [ etherprotospec ]
- etherhosts [ "l3" hosts ] [ etherfilteropt-list ]
+ [ "quick" ] [ "on" ifspec ] [ "bridge-to" interface-name ]
+ [ etherprotospec ] etherhosts [ "l3" hosts ]
+ [ etherfilteropt-list ]
pf-rule = action [ ( "in" | "out" ) ]
[ "log" [ "(" logopts ")"] ] [ "quick" ]
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -690,6 +690,8 @@
int qid;
char tagname[PF_TAG_NAME_SIZE];
uint16_t tag;
+ char bridge_to_name[IFNAMSIZ];
+ struct pfi_kkif *bridge_to;
uint8_t action;
uint16_t dnpipe;
uint32_t dnflags;
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -3833,6 +3833,17 @@
(r->match_tag_not && r->match_tag != *tag));
}
+static void
+pf_bridge_to(struct pfi_kkif *kif, struct mbuf *m)
+{
+ /* If we don't have the interface drop the packet. */
+ if (kif->pfik_ifp == NULL) {
+ m_freem(m);
+ return;
+ }
+ kif->pfik_ifp->if_transmit(kif->pfik_ifp, m);
+}
+
static int
pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0)
{
@@ -4092,6 +4103,11 @@
action = r->action;
+ if (action == PF_PASS && r->bridge_to) {
+ pf_bridge_to(r->bridge_to, *m0);
+ *m0 = NULL; /* We've eaten the packet. */
+ }
+
PF_RULES_RUNLOCK();
return (action);
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -522,6 +522,8 @@
pf_qid_unref(rule->qid);
#endif
+ if (rule->bridge_to)
+ pfi_kkif_unref(rule->bridge_to);
if (rule->kif)
pfi_kkif_unref(rule->kif);
@@ -2809,7 +2811,7 @@
void *nvlpacked = NULL;
struct pf_keth_rule *rule = NULL, *tail = NULL;
struct pf_keth_ruleset *ruleset = NULL;
- struct pfi_kkif *kif = NULL;
+ struct pfi_kkif *kif = NULL, *bridge_to_kif = NULL;
const char *anchor = "", *anchor_call = "";
#define ERROUT(x) ERROUT_IOCTL(DIOCADDETHRULE_error, x)
@@ -2861,6 +2863,8 @@
if (rule->ifname[0])
kif = pf_kkif_create(M_WAITOK);
+ if (rule->bridge_to_name[0])
+ bridge_to_kif = pf_kkif_create(M_WAITOK);
rule->evaluations = counter_u64_alloc(M_WAITOK);
for (int i = 0; i < 2; i++) {
rule->packets[i] = counter_u64_alloc(M_WAITOK);
@@ -2876,6 +2880,12 @@
pfi_kkif_ref(rule->kif);
} else
rule->kif = NULL;
+ if (rule->bridge_to_name[0]) {
+ rule->bridge_to = pfi_kkif_attach(bridge_to_kif,
+ rule->bridge_to_name);
+ pfi_kkif_ref(rule->bridge_to);
+ } else
+ rule->bridge_to = NULL;
#ifdef ALTQ
/* set queue IDs */
diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c
--- a/sys/netpfil/pf/pf_nv.c
+++ b/sys/netpfil/pf/pf_nv.c
@@ -1114,6 +1114,7 @@
nvlist_add_number(nvl, "anchor_relative", krule->anchor_relative);
nvlist_add_number(nvl, "anchor_wildcard", krule->anchor_wildcard);
+ nvlist_add_string(nvl, "bridge_to", krule->bridge_to_name);
nvlist_add_number(nvl, "action", krule->action);
return (nvl);
@@ -1182,6 +1183,8 @@
PFNV_CHK(pf_nvuint16_opt(nvl, "dnpipe", &krule->dnpipe, 0));
PFNV_CHK(pf_nvuint32_opt(nvl, "dnflags", &krule->dnflags, 0));
+ PFNV_CHK(pf_nvstring(nvl, "bridge_to", krule->bridge_to_name,
+ sizeof(krule->bridge_to_name)));
PFNV_CHK(pf_nvuint8(nvl, "action", &krule->action));
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 16, 7:57 PM (20 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14663784
Default Alt Text
D37193.id112326.diff (9 KB)
Attached To
Mode
D37193: pf: bridge-to
Attached
Detach File
Event Timeline
Log In to Comment