Page MenuHomeFreeBSD

D37193.id.diff
No OneTemporary

D37193.id.diff

diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -110,6 +110,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
@@ -665,6 +665,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");
}
@@ -812,6 +815,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
@@ -774,6 +774,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,32 @@
(r->match_tag_not && r->match_tag != *tag));
}
+static void
+pf_bridge_to(struct pfi_kkif *kif, struct mbuf *m)
+{
+ struct ifnet *ifp = kif->pfik_ifp;
+
+ /* If we don't have the interface drop the packet. */
+ if (ifp == NULL) {
+ m_freem(m);
+ return;
+ }
+
+ switch (ifp->if_type) {
+ case IFT_ETHER:
+ case IFT_XETHER:
+ case IFT_L2VLAN:
+ case IFT_BRIDGE:
+ case IFT_IEEE8023ADLAG:
+ break;
+ default:
+ 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 +4118,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

Mime Type
text/plain
Expires
Sat, Sep 28, 12:12 AM (8 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12954914
Default Alt Text
D37193.id.diff (9 KB)

Event Timeline