Page MenuHomeFreeBSD

D46577.id143385.diff
No OneTemporary

D46577.id143385.diff

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

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)

Event Timeline