summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhenning <henning@openbsd.org>2006-07-06 13:25:40 +0000
committerhenning <henning@openbsd.org>2006-07-06 13:25:40 +0000
commit7552bd941f25694a10d04a3fd02196e8ee355041 (patch)
tree00b48b0652b938c9d37ba0a78413460a9f397a63
parentIn rt_invalidate() skip all as_ext routes if routes matching a specific area (diff)
downloadwireguard-openbsd-7552bd941f25694a10d04a3fd02196e8ee355041.tar.xz
wireguard-openbsd-7552bd941f25694a10d04a3fd02196e8ee355041.zip
allow rules to point to an alternate routing table, and tag packets
matching that rule so that the forwarding code later can use the alternate routing table fo lookups (not implemented yet). the tagging is "sticky", every matching rule modifies, just like the regular "tag". ok claudio hshoexer, hacked at r2k6
-rw-r--r--sys/net/pf.c53
-rw-r--r--sys/net/pf_ioctl.c10
-rw-r--r--sys/net/pfvar.h6
3 files changed, 50 insertions, 19 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 6fa88d6220a..61f174f3cb1 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.512 2006/05/17 14:50:47 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.513 2006/07/06 13:25:40 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1601,8 +1601,12 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af,
}
if (tag)
pf_mtag->flags |= PF_TAG_GENERATED;
+
pf_mtag->tag = rtag;
+ if (r != NULL && r->rtableid >= 0)
+ pf_mtag->rtableid = r->rtableid;
+
#ifdef ALTQ
if (r != NULL && r->qid) {
pf_mtag->qid = r->qid;
@@ -1727,6 +1731,9 @@ pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
return;
pf_mtag->flags |= PF_TAG_GENERATED;
+ if (r->rtableid >= 0)
+ pf_mtag->rtableid = r->rtableid;
+
#ifdef ALTQ
if (r->qid) {
pf_mtag->qid = r->qid;
@@ -1887,15 +1894,18 @@ pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag,
}
int
-pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag)
+pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag, int rtableid)
{
- if (tag <= 0)
+ if (tag <= 0 && rtableid < 0)
return (0);
if (pf_mtag == NULL)
if ((pf_mtag = pf_get_mtag(m)) == NULL)
return (1);
- pf_mtag->tag = tag;
+ if (tag > 0)
+ pf_mtag->tag = tag;
+ if (rtableid >= 0)
+ pf_mtag->rtableid = rtableid;
return (0);
}
@@ -2355,6 +2365,7 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
struct pf_rule *r, *rm = NULL;
struct pf_ruleset *ruleset = NULL;
int tag = -1;
+ int rtableid = -1;
int asd = 0;
r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
@@ -2407,6 +2418,8 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
else {
if (r->tag)
tag = r->tag;
+ if (r->rtableid >= 0)
+ rtableid = r->rtableid;
if (r->anchor == NULL) {
rm = r;
} else
@@ -2415,7 +2428,7 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
if (r == NULL)
pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, NULL);
}
- if (pf_tag_packet(m, pd->pf_mtag, tag))
+ if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid))
return (NULL);
if (rm != NULL && (rm->action == PF_NONAT ||
rm->action == PF_NORDR || rm->action == PF_NOBINAT))
@@ -2821,7 +2834,7 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pf_src_node *nsn = NULL;
u_short reason;
int rewrite = 0;
- int tag = -1;
+ int tag = -1, rtableid = -1;
u_int16_t mss = tcp_mssdflt;
int asd = 0;
@@ -2910,6 +2923,8 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
else {
if (r->tag)
tag = r->tag;
+ if (r->rtableid >= 0)
+ rtableid = r->rtableid;
if (r->anchor == NULL) {
*rm = r;
*am = a;
@@ -2978,7 +2993,7 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->action == PF_DROP)
return (PF_DROP);
- if (pf_tag_packet(m, pd->pf_mtag, tag)) {
+ if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
REASON_SET(&reason, PFRES_MEMORY);
return (PF_DROP);
}
@@ -3198,7 +3213,7 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pf_src_node *nsn = NULL;
u_short reason;
int rewrite = 0;
- int tag = -1;
+ int tag = -1, rtableid = -1;
int asd = 0;
if (pf_check_congestion(ifq)) {
@@ -3283,6 +3298,8 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
else {
if (r->tag)
tag = r->tag;
+ if (r->rtableid >= 0)
+ rtableid = r->rtableid;
if (r->anchor == NULL) {
*rm = r;
*am = a;
@@ -3337,7 +3354,7 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->action == PF_DROP)
return (PF_DROP);
- if (pf_tag_packet(m, pd->pf_mtag, tag)) {
+ if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
REASON_SET(&reason, PFRES_MEMORY);
return (PF_DROP);
}
@@ -3476,7 +3493,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
sa_family_t af = pd->af;
u_int8_t icmptype, icmpcode;
int state_icmp = 0;
- int tag = -1;
+ int tag = -1, rtableid = -1;
#ifdef INET6
int rewrite = 0;
#endif /* INET6 */
@@ -3610,6 +3627,8 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
else {
if (r->tag)
tag = r->tag;
+ if (r->rtableid >= 0)
+ rtableid = r->rtableid;
if (r->anchor == NULL) {
*rm = r;
*am = a;
@@ -3644,7 +3663,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->action != PF_PASS)
return (PF_DROP);
- if (pf_tag_packet(m, pd->pf_mtag, tag)) {
+ if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
REASON_SET(&reason, PFRES_MEMORY);
return (PF_DROP);
}
@@ -3780,7 +3799,7 @@ pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pf_addr *saddr = pd->src, *daddr = pd->dst;
sa_family_t af = pd->af;
u_short reason;
- int tag = -1;
+ int tag = -1, rtableid = -1;
int asd = 0;
if (pf_check_congestion(ifq)) {
@@ -3865,6 +3884,8 @@ pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
else {
if (r->tag)
tag = r->tag;
+ if (r->rtableid >= 0)
+ rtableid = r->rtableid;
if (r->anchor == NULL) {
*rm = r;
*am = a;
@@ -3927,7 +3948,7 @@ pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->action != PF_PASS)
return (PF_DROP);
- if (pf_tag_packet(m, pd->pf_mtag, tag)) {
+ if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
REASON_SET(&reason, PFRES_MEMORY);
return (PF_DROP);
}
@@ -4104,7 +4125,7 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
if (r->action != PF_PASS)
return (PF_DROP);
- if (pf_tag_packet(m, pd->pf_mtag, tag)) {
+ if (pf_tag_packet(m, pd->pf_mtag, tag, -1)) {
REASON_SET(&reason, PFRES_MEMORY);
return (PF_DROP);
}
@@ -6046,7 +6067,7 @@ done:
}
if (s && s->tag)
- pf_tag_packet(m, pd.pf_mtag, s->tag);
+ pf_tag_packet(m, pd.pf_mtag, s->tag, r->rtableid);
#ifdef ALTQ
if (action == PF_PASS && r->qid) {
@@ -6392,7 +6413,7 @@ done:
/* XXX handle IPv6 options, if not allowed. not implemented. */
if (s && s->tag)
- pf_tag_packet(m, pd.pf_mtag, s->tag);
+ pf_tag_packet(m, pd.pf_mtag, s->tag, r->rtableid);
#ifdef ALTQ
if (action == PF_PASS && r->qid) {
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index d4485b8f4ca..5eebce9d22c 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.166 2006/05/28 02:45:45 mcbride Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.167 2006/07/06 13:25:40 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -170,6 +170,7 @@ pfattach(int num)
pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next;
pf_default_rule.action = PF_PASS;
pf_default_rule.nr = -1;
+ pf_default_rule.rtableid = -1;
/* initialize default timeouts */
timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
@@ -1393,6 +1394,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pfi_kif_ref(rule->kif, PFI_KIF_REF_RULE);
}
+ if (rule->rtableid > 0 && !rtable_exists(rule->rtableid))
+ error = EBUSY;
+
#ifdef ALTQ
/* set queue IDs */
if (rule->qname[0] != 0) {
@@ -1619,6 +1623,10 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
} else
newrule->kif = NULL;
+ if (newrule->rtableid > 0 &&
+ !rtable_exists(newrule->rtableid))
+ error = EBUSY;
+
#ifdef ALTQ
/* set queue IDs */
if (newrule->qname[0] != 0) {
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 1d77ed28d92..21eebdd3836 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.235 2006/05/28 02:45:45 mcbride Exp $ */
+/* $OpenBSD: pfvar.h,v 1.236 2006/07/06 13:25:40 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -530,6 +530,7 @@ struct pf_rule {
pf_osfp_t os_fingerprint;
+ int rtableid;
u_int32_t timeout[PFTM_MAX];
u_int32_t states;
u_int32_t max_states;
@@ -1153,6 +1154,7 @@ struct pf_altq {
struct pf_mtag {
void *hdr; /* saved hdr pos in mbuf, for ECN */
+ u_int rtableid; /* alternate routing table id */
u_int32_t qid; /* queue id */
u_int16_t tag; /* tag id */
u_int8_t flags;
@@ -1586,7 +1588,7 @@ u_int16_t pf_tagname2tag(char *);
void pf_tag2tagname(u_int16_t, char *);
void pf_tag_ref(u_int16_t);
void pf_tag_unref(u_int16_t);
-int pf_tag_packet(struct mbuf *, struct pf_mtag *, int);
+int pf_tag_packet(struct mbuf *, struct pf_mtag *, int, int);
u_int32_t pf_qname2qid(char *);
void pf_qid2qname(u_int32_t, char *);
void pf_qid_unref(u_int32_t);