summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjasoni <jasoni@openbsd.org>2001-11-26 16:50:25 +0000
committerjasoni <jasoni@openbsd.org>2001-11-26 16:50:25 +0000
commitcb3a4e31184d5885c222e519a0133b7c98a69210 (patch)
tree7ebb0baf4c339d23bef8eb33370f7707244d0ba1
parentTrident 4DWAVE-DX/NX, SiS 7018, ALi M5451 Sound Driver; from SOMEYA Yoshihiko and KUROSAWA Takahiro; tested by Matt Behrens <matt@zigg.com> (diff)
downloadwireguard-openbsd-cb3a4e31184d5885c222e519a0133b7c98a69210.tar.xz
wireguard-openbsd-cb3a4e31184d5885c222e519a0133b7c98a69210.zip
add fastroute options similar to what is found in ipf
ok dhartmei@, frantzen@
-rw-r--r--sbin/pfctl/parse.y131
-rw-r--r--sbin/pfctl/pfctl_parser.c17
-rw-r--r--sys/net/if_bridge.c4
-rw-r--r--sys/net/pf.c290
-rw-r--r--sys/net/pfvar.h7
-rw-r--r--sys/netinet/ip_input.c4
-rw-r--r--sys/netinet/ip_output.c9
-rw-r--r--sys/netinet6/ip6_forward.c7
-rw-r--r--sys/netinet6/ip6_input.c8
-rw-r--r--sys/netinet6/ip6_output.c12
10 files changed, 450 insertions, 39 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 2de09e5f771..6be61af4e0e 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.43 2001/11/05 09:28:00 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.44 2001/11/26 16:50:25 jasoni Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -151,6 +151,12 @@ typedef struct {
struct {
struct peer src, dst;
} fromto;
+ struct {
+ char *string;
+ struct pf_addr *addr;
+ u_int8_t rt;
+ u_int8_t af;
+ } route;
} v;
int lineno;
} YYSTYPE;
@@ -160,7 +166,7 @@ typedef struct {
%token PASS BLOCK SCRUB RETURN IN OUT LOG LOGALL QUICK ON FROM TO FLAGS
%token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
%token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
-%token MINTTL IPV6ADDR ERROR ALLOWOPTS
+%token MINTTL IPV6ADDR ERROR ALLOWOPTS FASTROUTE ROUTETO DUPTO
%token <v.string> STRING
%token <v.number> NUMBER
%token <v.i> PORTUNARY PORTBINARY
@@ -175,6 +181,7 @@ typedef struct {
%type <v.peer> ipportspec
%type <v.host> ipspec xhost host address host_list IPV6ADDR
%type <v.port> portspec port_list port_item
+%type <v.route> route
%%
ruleset : /* empty */
@@ -198,7 +205,7 @@ varset : STRING PORTUNARY STRING
}
;
-pfrule : action dir log quick interface af proto fromto flags icmpspec keep nodf minttl allowopts
+pfrule : action dir log quick interface route af proto fromto flags icmpspec keep nodf minttl allowopts
{
struct pf_rule r;
@@ -217,20 +224,42 @@ pfrule : action dir log quick interface af proto fromto flags icmpspec keep nod
r.log = $3;
r.quick = $4;
- r.af = $6;
- r.flags = $9.b1;
- r.flagset = $9.b2;
- r.keep_state = $11;
+ r.af = $7;
+ r.flags = $10.b1;
+ r.flagset = $10.b2;
+
+ r.keep_state = $12;
- if ($12)
- r.rule_flag |= PFRULE_NODF;
if ($13)
- r.min_ttl = $13;
- r.allow_opts = $14;
+ r.rule_flag |= PFRULE_NODF;
+ if ($14)
+ r.min_ttl = $14;
+ r.allow_opts = $15;
+
+ if ($6.rt) {
+ r.rt = $6.rt;
+ if ($6.string) {
+ memcpy(r.rt_ifname, $6.string,
+ sizeof(r.rt_ifname));
+ free($6.string);
+ }
+ if ($6.addr) {
+ if (!r.af)
+ r.af = $6.af;
+ else if (r.af != $6.af) {
+ yyerror("address family"
+ " mismatch");
+ YYERROR;
+ }
+ memcpy(&r.rt_addr, $6.addr,
+ sizeof(r.rt_addr));
+ free($6.addr);
+ }
+ }
- expand_rule(&r, $5, $7, $8.src.host, $8.src.port,
- $8.dst.host, $8.dst.port, $10);
+ expand_rule(&r, $5, $8, $9.src.host, $9.src.port,
+ $9.dst.host, $9.dst.port, $11);
}
;
@@ -932,6 +961,41 @@ rport : PORT port {
$$.t = PF_RPORT_RANGE;
}
;
+
+route : /* empty */ {
+ $$.string = NULL;
+ $$.rt = 0;
+ $$.addr = NULL;
+ $$.af = 0;
+ }
+ | FASTROUTE {
+ $$.string = NULL;
+ $$.rt = PF_FASTROUTE;
+ $$.addr = NULL;
+ }
+ | ROUTETO STRING ':' address {
+ $$.string = strdup($2);
+ $$.rt = PF_ROUTETO;
+ $$.addr = &$4->addr;
+ $$.af = $4->af;
+ }
+ | ROUTETO STRING {
+ $$.string = strdup($2);
+ $$.rt = PF_ROUTETO;
+ $$.addr = NULL;
+ }
+ | DUPTO STRING ':' address {
+ $$.string = strdup($2);
+ $$.rt = PF_DUPTO;
+ $$.addr = &$4->addr;
+ $$.af = $4->af;
+ }
+ | DUPTO STRING {
+ $$.string = strdup($2);
+ $$.rt = PF_DUPTO;
+ $$.addr = NULL;
+ }
+ ;
%%
int
@@ -1081,19 +1145,37 @@ void expand_rule_hosts(struct pf_rule *r,
r->dst.port_op = dst_port->op;
r->type = icmp_type->type;
r->code = icmp_type->code;
-
- if (src_host->af &&
- dst_host->af &&
- (src_host->af !=
- dst_host->af)) {
+
+ if ((src_host->af && dst_host->af &&
+ r->af) && (src_host->af !=
+ dst_host->af ||
+ src_host->af != r->af ||
+ dst_host->af != r->af)) {
+ yyerror("address family"
+ " mismatch");
+ nomatch++;
+ } else if ((src_host->af &&
+ dst_host->af) &&
+ (src_host->af != dst_host->af)) {
+ yyerror("address family"
+ " mismatch");
+ nomatch++;
+ } else if ((src_host->af && r->af) &&
+ (src_host->af != r->af)) {
+ yyerror("address family"
+ " mismatch");
+ nomatch++;
+ } else if ((dst_host->af && r->af) &&
+ (dst_host->af != r->af)) {
yyerror("address family"
" mismatch");
nomatch++;
- } else if (src_host->af)
+ } else if (src_host->af && !r->af) {
r->af = src_host->af;
- else if (dst_host->af)
- r->af = dst_host->af;
-
+ } else if (dst_host->af && !r->af) {
+ r->af= dst_host->af;
+ }
+
if (icmp_type->proto &&
r->proto != icmp_type->proto) {
yyerror("icmp-type mismatch");
@@ -1187,7 +1269,9 @@ lookup(char *s)
{ "binat", BINAT},
{ "block", BLOCK},
{ "code", CODE},
+ { "dup-to", DUPTO},
{ "flags", FLAGS},
+ { "fastroute", FASTROUTE},
{ "from", FROM},
{ "icmp-type", ICMPTYPE},
{ "ipv6-icmp-type", ICMP6TYPE},
@@ -1212,6 +1296,7 @@ lookup(char *s)
{ "return-icmp",RETURNICMP},
{ "return-icmp6",RETURNICMP6},
{ "return-rst", RETURNRST},
+ { "route-to", ROUTETO},
{ "scrub", SCRUB},
{ "state", STATE},
{ "to", TO},
@@ -1495,7 +1580,7 @@ top:
#define allowed_in_string(x) \
(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
x != '{' && x != '}' && x != '<' && x != '>' && \
- x != '!' && x != '=' && x != '/' && x != '#' && x != ','))
+ x != '!' && x != '=' && x != '/' && x != '#' && x != ',' && x != ':'))
if (isalnum(c)) {
do {
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index ae47423cb03..78940146700 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.53 2001/10/24 09:09:32 dhartmei Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.54 2001/11/26 16:50:26 jasoni Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -652,6 +652,21 @@ print_rule(struct pf_rule *r)
printf("quick ");
if (r->ifname[0])
printf("on %s ", r->ifname);
+ if (r->rt) {
+ if (r->rt == PF_ROUTETO)
+ printf("route-to ");
+ else if (r->rt == PF_DUPTO)
+ printf("dup-to ");
+ else if (r->rt == PF_FASTROUTE)
+ printf("fastroute");
+ if (r->rt_ifname[0])
+ printf("%s", r->rt_ifname);
+ if (r->af && !PF_AZERO(&r->rt_addr, r->af)) {
+ printf(":");
+ print_addr(&r->rt_addr, NULL, r->af);
+ }
+ printf(" ");
+ }
if (r->af) {
if (r->af == AF_INET)
printf("inet ");
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 2a4479d60a5..7f1ec92aff8 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.76 2001/08/21 15:18:20 jason Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.77 2001/11/26 16:50:26 jasoni Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -2002,6 +2002,8 @@ bridge_filter(sc, dir, ifp, eh, m)
m->m_pkthdr.rcvif = ifp;
if (pf_test(dir, ifp, &m) != PF_PASS)
goto dropit;
+ if (m == NULL)
+ goto dropit;
/* Rebuild the IP header */
if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL))
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 2b6cb4d6696..70b4533cd86 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.170 2001/11/21 19:00:24 dhartmei Exp $ */
+/* $OpenBSD: pf.c,v 1.171 2001/11/26 16:50:26 jasoni Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -57,6 +57,10 @@
#include <netinet/tcp_seq.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
#include <dev/rndvar.h>
#include <net/pfvar.h>
@@ -248,6 +252,8 @@ int pf_add_sport(struct pf_port_list *, u_int16_t);
int pf_chk_sport(struct pf_port_list *, u_int16_t);
int pf_normalize_tcp(int, struct ifnet *, struct mbuf *,
int, int, void *, struct pf_pdesc *);
+void pf_route(struct mbuf *, struct pf_rule *);
+void pf_route6(struct mbuf *, struct pf_rule *);
#if NPFLOG > 0
@@ -1113,6 +1119,15 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
} else
rule->ifp = NULL;
+ if (rule->rt_ifname[0]) {
+ rule->rt_ifp = ifunit(rule->rt_ifname);
+ if (rule->rt_ifname == NULL) {
+ pool_put(&pf_rule_pl, rule);
+ error = EINVAL;
+ break;
+ }
+ } else
+ rule->rt_ifp = NULL;
rule->evaluations = rule->packets = rule->bytes = 0;
TAILQ_INSERT_TAIL(pf_rules_inactive, rule, entries);
break;
@@ -4311,6 +4326,265 @@ pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
}
#ifdef INET
+void
+pf_route(struct mbuf *m, struct pf_rule *r)
+{
+ struct mbuf *m0, *m1;
+ struct route iproute;
+ struct route *ro;
+ struct sockaddr_in *dst;
+ struct ip *ip, *mhip;
+ struct ifnet *ifp = r->rt_ifp;
+ int hlen;
+ int len, off, error = 0;
+
+ if (m == NULL)
+ return;
+
+ m0 = m_copym2(m, 0, M_COPYALL, M_NOWAIT);
+ if (m0 == NULL)
+ return;
+
+ ip = mtod(m0, struct ip *);
+ hlen = ip->ip_hl << 2;
+
+ ro = &iproute;
+ bzero((caddr_t)ro, sizeof(*ro));
+ dst = satosin(&ro->ro_dst);
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = ip->ip_dst;
+
+ if (r->rt == PF_FASTROUTE) {
+ rtalloc(ro);
+ if (ro->ro_rt == 0) {
+ ipstat.ips_noroute++;
+ goto bad;
+ }
+
+ ifp = ro->ro_rt->rt_ifp;
+ ro->ro_rt->rt_use++;
+
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst = satosin(ro->ro_rt->rt_gateway);
+ } else {
+ if (!PF_AZERO(&r->rt_addr, AF_INET))
+ dst->sin_addr.s_addr = r->rt_addr.v4.s_addr;
+ }
+
+ if (ifp == NULL)
+ goto bad;
+
+ /* Copied from ip_output. */
+ if ((u_int16_t)ip->ip_len <= ifp->if_mtu) {
+ ip->ip_len = htons((u_int16_t)ip->ip_len);
+ ip->ip_off = htons((u_int16_t)ip->ip_off);
+ if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
+ ifp->if_bridge == NULL) {
+ m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
+ ipstat.ips_outhwcsum++;
+ } else {
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m0, hlen);
+ }
+ /* Update relevant hardware checksum stats for TCP/UDP */
+ if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT)
+ tcpstat.tcps_outhwcsum++;
+ else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT)
+ udpstat.udps_outhwcsum++;
+ error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
+
+ goto done;
+ }
+
+ /*
+ * Too large for interface; fragment if possible.
+ * Must be able to put at least 8 bytes per fragment.
+ */
+ if (ip->ip_off & IP_DF) {
+ error = EMSGSIZE;
+ ipstat.ips_cantfrag++;
+ goto bad;
+ }
+ len = (ifp->if_mtu - hlen) &~ 7;
+ if (len < 8) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+ /*
+ * If we are doing fragmentation, we can't defer TCP/UDP
+ * checksumming; compute the checksum and clear the flag.
+ */
+ if (m0->m_pkthdr.csum & (M_TCPV4_CSUM_OUT | M_UDPV4_CSUM_OUT)) {
+ in_delayed_cksum(m0);
+ m0->m_pkthdr.csum &= ~(M_UDPV4_CSUM_OUT | M_TCPV4_CSUM_OUT);
+ }
+
+ {
+ int mhlen, firstlen = len;
+ struct mbuf **mnext = &m0->m_nextpkt;
+
+ /*
+ * Loop through length of segment after first fragment,
+ * make new header and copy data of each part and link onto chain.
+ */
+ m1 = m0;
+ mhlen = sizeof (struct ip);
+ for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
+ MGETHDR(m0, M_DONTWAIT, MT_HEADER);
+ if (m0 == 0) {
+ error = ENOBUFS;
+ ipstat.ips_odropped++;
+ goto sendorfree;
+ }
+ *mnext = m0;
+ mnext = &m0->m_nextpkt;
+ m0->m_data += max_linkhdr;
+ mhip = mtod(m0, struct ip *);
+ *mhip = *ip;
+ /* we must inherit MCAST and BCAST flags */
+ m0->m_flags |= m1->m_flags & (M_MCAST|M_BCAST);
+ if (hlen > sizeof (struct ip)) {
+ mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
+ mhip->ip_hl = mhlen >> 2;
+ }
+ m0->m_len = mhlen;
+ mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
+ if (ip->ip_off & IP_MF)
+ mhip->ip_off |= IP_MF;
+ if (off + len >= (u_int16_t)ip->ip_len)
+ len = (u_int16_t)ip->ip_len - off;
+ else
+ mhip->ip_off |= IP_MF;
+ mhip->ip_len = htons((u_int16_t)(len + mhlen));
+ m0->m_next = m_copy(m1, off, len);
+ if (m0->m_next == 0) {
+ error = ENOBUFS;/* ??? */
+ ipstat.ips_odropped++;
+ goto sendorfree;
+ }
+ m0->m_pkthdr.len = mhlen + len;
+ m0->m_pkthdr.rcvif = (struct ifnet *)0;
+ mhip->ip_off = htons((u_int16_t)mhip->ip_off);
+ if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
+ ifp->if_bridge == NULL) {
+ m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
+ ipstat.ips_outhwcsum++;
+ } else {
+ mhip->ip_sum = 0;
+ mhip->ip_sum = in_cksum(m0, mhlen);
+ }
+ ipstat.ips_ofragments++;
+ }
+ /*
+ * Update first fragment by trimming what's been copied out
+ * and updating header, then send each fragment (in order).
+ */
+ m0 = m1;
+ m_adj(m0, hlen + firstlen - (u_int16_t)ip->ip_len);
+ m0->m_pkthdr.len = hlen + firstlen;
+ ip->ip_len = htons((u_int16_t)m0->m_pkthdr.len);
+ ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF));
+ if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
+ ifp->if_bridge == NULL) {
+ m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
+ ipstat.ips_outhwcsum++;
+ } else {
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m0, hlen);
+ }
+sendorfree:
+ for (m0 = m1; m0; m0 = m1) {
+ m1 = m0->m_nextpkt;
+ m->m_nextpkt = 0;
+ if (error == 0)
+ error = (*ifp->if_output)(ifp, m0, sintosa(dst),
+ NULL);
+ else
+ m_freem(m0);
+ }
+
+ if (error == 0)
+ ipstat.ips_fragmented++;
+ }
+
+done:
+ if (ro == &iproute && ro->ro_rt)
+ RTFREE(ro->ro_rt);
+ return;
+
+bad:
+ m_freem(m0);
+ goto done;
+}
+#endif /* INET */
+
+#ifdef INET6
+void
+pf_route6(struct mbuf *m, struct pf_rule *r)
+{
+ struct mbuf *m0;
+ struct m_tag *mtag;
+ struct route_in6 ip6route;
+ struct route_in6 *ro;
+ struct sockaddr_in6 *dst;
+ struct ip6_hdr *ip6;
+ struct ifnet *ifp = r->rt_ifp;
+ int error = 0;
+
+ if (m == NULL)
+ return;
+
+ m0 = m_copym2(m, 0, M_COPYALL, M_NOWAIT);
+ if (m0 == NULL)
+ return;
+
+ ip6 = mtod(m0, struct ip6_hdr *);
+
+ ro = &ip6route;
+ bzero((caddr_t)ro, sizeof(*ro));
+ dst = (struct sockaddr_in6 *)&ro->ro_dst;
+ dst->sin6_family = AF_INET6;
+ dst->sin6_len = sizeof(*dst);
+ dst->sin6_addr = ip6->ip6_dst;
+
+ if (!PF_AZERO(&r->rt_addr, AF_INET6))
+ dst->sin6_addr = r->rt_addr.v6;
+
+ /* Cheat. */
+ if (r->rt == PF_FASTROUTE) {
+ mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
+ if (mtag == NULL)
+ goto bad;
+ m_tag_prepend(m0, mtag);
+ ip6_output(m0, NULL, NULL, NULL, NULL, NULL);
+ return;
+ }
+
+ if (ifp == NULL)
+ goto bad;
+
+ /*
+ * Do not fragment packets (yet). Not much is done here for dealing
+ * with errors. Actions on errors depend on whether the packet
+ * was generated locally or being forwarded.
+ */
+ if (m0->m_pkthdr.len <= ifp->if_mtu) {
+ error = (*ifp->if_output)(ifp, m0, (struct sockaddr *)dst,
+ NULL);
+ } else
+ m_freem(m0);
+
+done:
+ return;
+
+bad:
+ m_freem(m0);
+ goto done;
+}
+#endif /* INET6 */
+
+#ifdef INET
int
pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
{
@@ -4464,6 +4738,13 @@ done:
}
PFLOG_PACKET(ifp, h, m, AF_INET, dir, reason, r);
}
+ if (r && r->rt) {
+ pf_route(m, r);
+ if (r->rt != PF_DUPTO) {
+ m_freem(*m0);
+ *m0 = NULL;
+ }
+ }
return (action);
}
#endif /* INET */
@@ -4637,6 +4918,13 @@ done:
}
PFLOG_PACKET(ifp, h, m, AF_INET6, dir, reason, r);
}
+ if (r && r->rt) {
+ pf_route6(m, r);
+ if (r->rt != PF_DUPTO) {
+ m_freem(*m0);
+ *m0 = NULL;
+ }
+ }
return (action);
}
#endif /* INET6 */
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index a5d82e0bd48..ce65e0d3637 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.55 2001/11/06 11:48:29 dhartmei Exp $ */
+/* $OpenBSD: pfvar.h,v 1.56 2001/11/26 16:50:26 jasoni Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -49,6 +49,7 @@ enum { PFTM_TCP_FIRST_PACKET=0, PFTM_TCP_OPENING=1, PFTM_TCP_ESTABLISHED=2,
PFTM_UDP_FIRST_PACKET=6, PFTM_UDP_SINGLE=7, PFTM_UDP_MULTIPLE=8,
PFTM_ICMP_FIRST_PACKET=9, PFTM_ICMP_ERROR_REPLY=10, PFTM_FRAG=11,
PFTM_INTERVAL=12, PFTM_MAX=13 };
+enum { PF_FASTROUTE=1, PF_ROUTETO=2, PF_DUPTO=3 };
struct pf_addr {
union {
@@ -188,9 +189,12 @@ struct pf_rule_addr {
struct pf_rule {
char ifname[IFNAMSIZ];
+ char rt_ifname[IFNAMSIZ];
struct ifnet *ifp;
+ struct ifnet *rt_ifp;
struct pf_rule_addr src;
struct pf_rule_addr dst;
+ struct pf_addr rt_addr;
#define PF_SKIP_IFP 0
#define PF_SKIP_AF 1
@@ -229,6 +233,7 @@ struct pf_rule {
u_int8_t rule_flag;
u_int8_t min_ttl; /* minimum ttl for packet normalize */
u_int8_t allow_opts;
+ u_int8_t rt;
};
#define PFRULE_RETURNRST 0x01
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index e40d819c80f..a7e35ed31d2 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.93 2001/09/18 15:24:32 aaron Exp $ */
+/* $OpenBSD: ip_input.c,v 1.94 2001/11/26 16:50:26 jasoni Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -395,6 +395,8 @@ ipv4_input(m)
*/
if (pf_test(PF_IN, m->m_pkthdr.rcvif, &m) != PF_PASS)
goto bad;
+ if (m == NULL)
+ goto bad;
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 6a659520fc7..9514a052e50 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.139 2001/11/24 19:29:06 deraadt Exp $ */
+/* $OpenBSD: ip_output.c,v 1.140 2001/11/26 16:50:26 jasoni Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -554,6 +554,10 @@ sendit:
m_freem(m);
goto done;
}
+ if (m == NULL) {
+ splx(s);
+ goto done;
+ }
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
#endif
@@ -654,6 +658,9 @@ sendit:
m_freem(m);
goto done;
}
+ if (m == NULL)
+ goto done;
+
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
#endif
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index dab86d9c8ae..8f98801e00c 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_forward.c,v 1.17 2001/09/29 08:02:07 jasoni Exp $ */
+/* $OpenBSD: ip6_forward.c,v 1.18 2001/11/26 16:50:26 jasoni Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/*
@@ -487,10 +487,13 @@ ip6_forward(m, srcrt)
ip6->ip6_dst.s6_addr16[1] = 0;
#if NPF > 0
- if (pf_test6(PF_OUT, rt->rt_ifp, &m) != PF_PASS) {
+ if (pf_test6(PF_OUT, rt->rt_ifp, &m) != PF_PASS) {
m_freem(m);
goto senderr;
}
+ if (m == NULL)
+ goto senderr;
+
ip6 = mtod(m, struct ip6_hdr *);
#endif
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index e2a54b387f7..f368bf86560 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.35 2001/11/06 19:53:21 miod Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.36 2001/11/26 16:50:26 jasoni Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -265,8 +265,10 @@ ip6_input(m)
/*
* Packet filter
*/
- if (pf_test6(PF_IN, m->m_pkthdr.rcvif, &m) != PF_PASS)
- goto bad;
+ if (pf_test6(PF_IN, m->m_pkthdr.rcvif, &m) != PF_PASS)
+ goto bad;
+ if (m == NULL)
+ goto bad;
#endif
if (m->m_len < sizeof(struct ip6_hdr)) {
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index c4289cc5257..0ce39864fdb 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_output.c,v 1.52 2001/10/01 16:03:09 jasoni Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.53 2001/11/26 16:50:26 jasoni Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -881,11 +881,13 @@ skip_ipsec2:;
}
#if NPF > 0
- if (pf_test6(PF_OUT, ifp, &m) != PF_PASS) {
- error = EHOSTUNREACH;
+ if (pf_test6(PF_OUT, ifp, &m) != PF_PASS) {
+ error = EHOSTUNREACH;
m_freem(m);
- goto done;
- }
+ goto done;
+ }
+ if (m == NULL)
+ goto done;
ip6 = mtod(m, struct ip6_hdr *);
#endif