Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157718785
D46577.id143385.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D46577.id143385.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
@@ -220,6 +220,7 @@
struct pf_rule_uid uid;
struct pf_rule_gid gid;
+ char rcv_ifname[IFNAMSIZ];
uint32_t rule_flag;
uint8_t action;
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1252,6 +1252,7 @@
snl_add_msg_attr_uid(nw, PF_RT_UID, &r->uid);
snl_add_msg_attr_uid(nw, PF_RT_GID, (const struct pf_rule_uid *)&r->gid);
+ snl_add_msg_attr_string(nw, PF_RT_RCV_IFNAME, r->rcv_ifname);
snl_add_msg_attr_u32(nw, PF_RT_RULE_FLAG, r->rule_flag);
snl_add_msg_attr_u8(nw, PF_RT_ACTION, r->action);
@@ -1656,6 +1657,7 @@
{ .type = PF_RT_STATES_TOTAL, .off = _OUT(r.states_tot), .cb = snl_attr_get_uint64 },
{ .type = PF_RT_SRC_NODES, .off = _OUT(r.src_nodes), .cb = snl_attr_get_uint64 },
{ .type = PF_RT_ANCHOR_CALL, .off = _OUT(anchor_call), .arg = (void*)MAXPATHLEN, .cb = snl_attr_copy_string },
+ { .type = PF_RT_RCV_IFNAME, .off = _OUT(r.rcv_ifname), .arg = (void*)IFNAMSIZ, .cb = snl_attr_copy_string },
};
static struct snl_field_parser fp_getrule[] = {};
#undef _OUT
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -241,6 +241,7 @@
#define FOM_FRAGCACHE 0x8000 /* does not exist in OpenBSD */
struct node_uid *uid;
struct node_gid *gid;
+ struct node_if *rcv;
struct {
u_int8_t b1;
u_int8_t b2;
@@ -367,7 +368,7 @@
struct node_host *, struct node_proto *, struct node_os *,
struct node_host *, struct node_port *, struct node_host *,
struct node_port *, struct node_uid *, struct node_gid *,
- struct node_icmp *, const char *);
+ struct node_if *, struct node_icmp *, const char *);
int expand_altq(struct pf_altq *, struct node_if *,
struct node_queue *, struct node_queue_bw bwspec,
struct node_queue_opt *);
@@ -516,7 +517,7 @@
%token STICKYADDRESS ENDPI MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
-%token DIVERTTO DIVERTREPLY BRIDGE_TO
+%token DIVERTTO DIVERTREPLY BRIDGE_TO RECEIVEDON
%token <v.string> STRING
%token <v.number> NUMBER
%token <v.i> PORTBINARY
@@ -1073,7 +1074,7 @@
expand_rule(&r, $5, NULL, $7, $8.src_os,
$8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
- $9.uid, $9.gid, $9.icmpspec,
+ $9.uid, $9.gid, $9.rcv, $9.icmpspec,
pf->astack[pf->asd + 1] ? pf->alast->name : $2);
free($2);
pf->astack[pf->asd + 1] = NULL;
@@ -1096,7 +1097,7 @@
expand_rule(&r, $3, NULL, $5, $6.src_os,
$6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
- 0, 0, 0, $2);
+ 0, 0, 0, 0, $2);
free($2);
}
| RDRANCHOR string interface af proto fromto rtable {
@@ -1138,7 +1139,7 @@
expand_rule(&r, $3, NULL, $5, $6.src_os,
$6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
- 0, 0, 0, $2);
+ 0, 0, 0, 0, $2);
free($2);
}
| BINATANCHOR string interface af proto fromto rtable {
@@ -1461,7 +1462,7 @@
expand_rule(&r, $4, NULL, $6, $7.src_os,
$7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
- NULL, NULL, NULL, "");
+ NULL, NULL, NULL, NULL, "");
}
;
@@ -1626,7 +1627,7 @@
if (h != NULL)
expand_rule(&r, j, NULL, NULL, NULL, h,
NULL, NULL, NULL, NULL, NULL,
- NULL, "");
+ NULL, NULL, "");
if ((i->ifa_flags & IFF_LOOPBACK) == 0) {
bzero(&r, sizeof(r));
@@ -1648,7 +1649,7 @@
if (h != NULL)
expand_rule(&r, NULL, NULL,
NULL, NULL, h, NULL, NULL,
- NULL, NULL, NULL, NULL, "");
+ NULL, NULL, NULL, NULL, NULL, "");
} else
free(hh);
}
@@ -2802,7 +2803,7 @@
expand_rule(&r, $4, $5.host, $7, $8.src_os,
$8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
- $9.uid, $9.gid, $9.icmpspec, "");
+ $9.uid, $9.gid, $9.rcv, $9.icmpspec, "");
}
;
@@ -2937,6 +2938,13 @@
filter_opts.match_tag = $3;
filter_opts.match_tag_not = $1;
}
+ | RECEIVEDON if_item {
+ if (filter_opts.rcv) {
+ yyerror("cannot respecify received-on");
+ YYERROR;
+ }
+ filter_opts.rcv = $2;
+ }
| PROBABILITY probability {
double p;
@@ -4882,7 +4890,7 @@
expand_rule(&r, $2, $9 == NULL ? NULL : $9->host, $4,
$5.src_os, $5.src.host, $5.src.port, $5.dst.host,
- $5.dst.port, 0, 0, 0, "");
+ $5.dst.port, 0, 0, 0, 0, "");
free($9);
}
;
@@ -6034,8 +6042,8 @@
struct node_proto *protos, struct node_os *src_oses,
struct node_host *src_hosts, struct node_port *src_ports,
struct node_host *dst_hosts, struct node_port *dst_ports,
- struct node_uid *uids, struct node_gid *gids, struct node_icmp *icmp_types,
- const char *anchor_call)
+ struct node_uid *uids, struct node_gid *gids, struct node_if *rcv,
+ struct node_icmp *icmp_types, const char *anchor_call)
{
sa_family_t af = r->af;
int added = 0, error = 0;
@@ -6138,6 +6146,10 @@
r->gid.op = gid->op;
r->gid.gid[0] = gid->gid[0];
r->gid.gid[1] = gid->gid[1];
+ if (rcv) {
+ strlcpy(r->rcv_ifname, rcv->ifname,
+ sizeof(r->rcv_ifname));
+ }
r->type = icmp_type->type;
r->code = icmp_type->code;
@@ -6381,6 +6393,7 @@
{ "rdr-anchor", RDRANCHOR},
{ "realtime", REALTIME},
{ "reassemble", REASSEMBLE},
+ { "received-on", RECEIVEDON},
{ "reply-to", REPLYTO},
{ "require-order", REQUIREORDER},
{ "return", RETURN},
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
@@ -960,6 +960,8 @@
}
print_fromto(&r->src, r->os_fingerprint, &r->dst, r->af, r->proto,
verbose, numeric);
+ if (r->rcv_ifname[0])
+ printf(" received-on %s", r->rcv_ifname);
if (r->uid.op)
print_ugid(r->uid.op, r->uid.uid[0], r->uid.uid[1], "user",
UID_MAX);
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -776,6 +776,7 @@
char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
uint32_t ridentifier;
char ifname[IFNAMSIZ];
+ char rcv_ifname[IFNAMSIZ];
char qname[PF_QNAME_SIZE];
char pqname[PF_QNAME_SIZE];
char tagname[PF_TAG_NAME_SIZE];
@@ -792,6 +793,7 @@
time_t *timestamp;
struct pfi_kkif *kif;
+ struct pfi_kkif *rcv_kif;
struct pf_kanchor *anchor;
struct pfr_ktable *overload_tbl;
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
@@ -375,6 +375,7 @@
static struct pf_kstate *pf_find_state(struct pfi_kkif *,
const struct pf_state_key_cmp *, u_int);
static int pf_src_connlimit(struct pf_kstate **);
+static int pf_match_rcvif(struct mbuf *, struct pf_krule *);
static void pf_overload_task(void *v, int pending);
static u_short pf_insert_src_node(struct pf_ksrc_node **,
struct pf_krule *, struct pf_addr *, sa_family_t);
@@ -3951,6 +3952,27 @@
(r->match_tag_not && r->match_tag != *tag));
}
+static int
+pf_match_rcvif(struct mbuf *m, struct pf_krule *r)
+{
+ struct ifnet *ifp = m->m_pkthdr.rcvif;
+ struct pfi_kkif *kif;
+
+ if (ifp == NULL)
+ return (0);
+
+ kif = (struct pfi_kkif *)ifp->if_pf_kif;
+
+ if (kif == NULL) {
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_test_via: kif == NULL, @%d via %s\n", r->nr,
+ r->rcv_ifname));
+ return (0);
+ }
+
+ return (pfi_kkif_match(r->rcv_kif, kif));
+}
+
int
pf_tag_packet(struct mbuf *m, struct pf_pdesc *pd, int tag)
{
@@ -5155,6 +5177,8 @@
else if (r->match_tag && !pf_match_tag(m, r, &tag,
pd->pf_mtag ? pd->pf_mtag->tag : 0))
r = TAILQ_NEXT(r, entries);
+ else if (r->rcv_kif && !pf_match_rcvif(m, r))
+ r = TAILQ_NEXT(r, entries);
else if (r->os_fingerprint != PF_OSFP_ANY &&
(pd->proto != IPPROTO_TCP || !pf_osfp_match(
pf_osfp_fingerprint(pd, m, off, th),
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
@@ -603,6 +603,8 @@
pfr_detach_table(rule->overload_tbl);
if (rule->kif)
pfi_kkif_unref(rule->kif);
+ if (rule->rcv_kif)
+ pfi_kkif_unref(rule->rcv_kif);
pf_kanchor_remove(rule);
pf_empty_kpool(&rule->rpool.list);
@@ -1306,6 +1308,7 @@
for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
PF_MD5_UPD_STR(rule, label[i]);
PF_MD5_UPD_STR(rule, ifname);
+ PF_MD5_UPD_STR(rule, rcv_ifname);
PF_MD5_UPD_STR(rule, match_tagname);
PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
@@ -2068,7 +2071,7 @@
struct pf_kruleset *ruleset;
struct pf_krule *tail;
struct pf_kpooladdr *pa;
- struct pfi_kkif *kif = NULL;
+ struct pfi_kkif *kif = NULL, *rcv_kif = NULL;
int rs_num;
int error = 0;
@@ -2081,6 +2084,8 @@
if (rule->ifname[0])
kif = pf_kkif_create(M_WAITOK);
+ if (rule->rcv_ifname[0])
+ rcv_kif = pf_kkif_create(M_WAITOK);
pf_counter_u64_init(&rule->evaluations, M_WAITOK);
for (int i = 0; i < 2; i++) {
pf_counter_u64_init(&rule->packets[i], M_WAITOK);
@@ -2143,6 +2148,13 @@
} else
rule->kif = NULL;
+ if (rule->rcv_ifname[0]) {
+ rule->rcv_kif = pfi_kkif_attach(rcv_kif, rule->rcv_ifname);
+ rcv_kif = NULL;
+ pfi_kkif_ref(rule->rcv_kif);
+ } else
+ rule->rcv_kif = NULL;
+
if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
error = EBUSY;
@@ -2242,6 +2254,7 @@
PF_RULES_WUNLOCK();
PF_CONFIG_UNLOCK();
errout_unlocked:
+ pf_kkif_free(rcv_kif);
pf_kkif_free(kif);
pf_krule_free(rule);
return (error);
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -257,6 +257,7 @@
PF_RT_STATES_TOTAL = 70, /* u64 */
PF_RT_SRC_NODES = 71, /* u64 */
PF_RT_ANCHOR_CALL = 72, /* string */
+ PF_RT_RCV_IFNAME = 73, /* string */
};
enum pf_addrule_type_t {
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -730,6 +730,7 @@
{ .type = PF_RT_SET_PRIO_REPLY, .off = _OUT(set_prio[1]), .cb = nlattr_get_uint8 },
{ .type = PF_RT_DIVERT_ADDRESS, .off = _OUT(divert.addr), .cb = nlattr_get_in6_addr },
{ .type = PF_RT_DIVERT_PORT, .off = _OUT(divert.port), .cb = nlattr_get_uint16 },
+ { .type = PF_RT_RCV_IFNAME, .off = _OUT(rcv_ifname), .arg = (void *)IFNAMSIZ, .cb = nlattr_get_chara },
};
NL_DECLARE_ATTR_PARSER(rule_parser, nla_p_rule);
#undef _OUT
@@ -941,6 +942,8 @@
nlattr_add_rule_uid(nw, PF_RT_UID, &rule->uid);
nlattr_add_rule_uid(nw, PF_RT_GID, (const struct pf_rule_uid *)&rule->gid);
+ nlattr_add_string(nw, PF_RT_RCV_IFNAME, rule->rcv_ifname);
+
nlattr_add_u32(nw, PF_RT_RULE_FLAG, rule->rule_flag);
nlattr_add_u8(nw, PF_RT_ACTION, rule->action);
nlattr_add_u8(nw, PF_RT_DIRECTION, rule->direction);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, May 25, 10:32 AM (13 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33507524
Default Alt Text
D46577.id143385.diff (10 KB)
Attached To
Mode
D46577: pf: allow filtering on the receive interface
Attached
Detach File
Event Timeline
Log In to Comment