diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c index 5c9641bc485..7058b7dca4d 100644 --- a/sys/contrib/pf/net/pf.c +++ b/sys/contrib/pf/net/pf.c @@ -320,7 +320,7 @@ u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, sa_family_t); u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, - u_int16_t); + int, u_int16_t); void pf_set_rt_ifp(struct pf_state *, struct pf_addr *); int pf_check_proto_cksum(struct mbuf *, int, int, @@ -3137,7 +3137,7 @@ pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) } u_int16_t -pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) +pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer) { #ifdef INET struct sockaddr_in *dst; @@ -3166,11 +3166,7 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) dst->sin_len = sizeof(*dst); dst->sin_addr = addr->v4; #ifdef __FreeBSD__ -#ifdef RTF_PRCLONING - rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); -#else /* !RTF_PRCLONING */ - in_rtalloc_ign(&ro, 0, 0); -#endif + in_rtalloc_ign(&ro, 0, rtableid); #else /* ! __FreeBSD__ */ rtalloc_noclone(&ro, NO_CLONING); #endif @@ -3186,12 +3182,7 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) dst6->sin6_len = sizeof(*dst6); dst6->sin6_addr = addr->v6; #ifdef __FreeBSD__ -#ifdef RTF_PRCLONING - rtalloc_ign((struct route *)&ro6, - (RTF_CLONING | RTF_PRCLONING)); -#else /* !RTF_PRCLONING */ - rtalloc_ign((struct route *)&ro6, 0); -#endif + in6_rtalloc_ign(&ro6, 0, rtableid); #else /* ! __FreeBSD__ */ rtalloc_noclone((struct route *)&ro6, NO_CLONING); #endif @@ -3532,14 +3523,14 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO].ptr; else if (PF_MISMATCHAW(&r->src.addr, saddr, af, - r->src.neg, kif)) + r->src.neg, kif, M_GETFIB(m))) r = r->skip[PF_SKIP_SRC_ADDR].ptr; /* tcp/udp only. port_op always 0 in other cases */ else if (r->src.port_op && !pf_match_port(r->src.port_op, r->src.port[0], r->src.port[1], sport)) r = r->skip[PF_SKIP_SRC_PORT].ptr; else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, - r->dst.neg, NULL)) + r->dst.neg, NULL, M_GETFIB(m))) r = r->skip[PF_SKIP_DST_ADDR].ptr; /* tcp/udp only. port_op always 0 in other cases */ else if (r->dst.port_op && !pf_match_port(r->dst.port_op, @@ -3988,9 +3979,10 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, } s->src.seqhi = htonl(arc4random()); /* Find mss option */ + int rtid = M_GETFIB(m); mss = pf_get_mss(m, off, th->th_off, pd->af); - mss = pf_calc_mss(pd->src, pd->af, mss); - mss = pf_calc_mss(pd->dst, pd->af, mss); + mss = pf_calc_mss(pd->src, pd->af, rtid, mss); + mss = pf_calc_mss(pd->dst, pd->af, rtid, mss); s->src.mss = mss; #ifdef __FreeBSD__ pf_send_tcp(NULL, r, pd->af, pd->dst, pd->src, th->th_dport, @@ -4072,10 +4064,10 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO].ptr; else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, - r->src.neg, kif)) + r->src.neg, kif, M_GETFIB(m))) r = r->skip[PF_SKIP_SRC_ADDR].ptr; else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, - r->dst.neg, NULL)) + r->dst.neg, NULL, M_GETFIB(m))) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->tos && !(r->tos == pd->tos)) r = TAILQ_NEXT(r, entries); @@ -5677,7 +5669,8 @@ pf_pull_hdr(struct mbuf *m, int off, void *p, int len, } int -pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif) +pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif, + int rtableid) { #ifdef __FreeBSD__ #ifdef RADIX_MPATH @@ -5751,13 +5744,21 @@ pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif) goto out; #ifdef __FreeBSD__ -/* XXX MRT not always INET */ /* stick with table 0 though */ -#ifdef INET - if (af == AF_INET) - in_rtalloc_ign((struct route *)&ro, 0, 0); - else + switch (af) { +#ifdef INET6 + case AF_INET6: + in6_rtalloc_ign(&ro, 0, rtableid); + break; #endif - rtalloc_ign((struct route *)&ro, 0); +#ifdef INET + case AF_INET: + in_rtalloc_ign((struct route *)&ro, 0, rtableid); + break; +#endif + default: + rtalloc_ign((struct route *)&ro, 0); /* No/default FIB. */ + break; + } #else /* ! __FreeBSD__ */ rtalloc_noclone((struct route *)&ro, NO_CLONING); #endif @@ -5803,7 +5804,8 @@ out: } int -pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) +pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw, + int rtableid) { struct sockaddr_in *dst; #ifdef INET6 @@ -5835,16 +5837,21 @@ pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) } #ifdef __FreeBSD__ -# ifdef RTF_PRCLONING - rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING)); -# else /* !RTF_PRCLONING */ -#ifdef INET - if (af == AF_INET) - in_rtalloc_ign((struct route *)&ro, 0, 0); - else + switch (af) { +#ifdef INET6 + case AF_INET6: + in6_rtalloc_ign(&ro, 0, rtableid); + break; #endif +#ifdef INET + case AF_INET: + in_rtalloc_ign((struct route *)&ro, 0, rtableid); + break; +#endif + default: rtalloc_ign((struct route *)&ro, 0); -# endif + break; + } #else /* ! __FreeBSD__ */ rtalloc_noclone((struct route *)&ro, NO_CLONING); #endif @@ -5927,7 +5934,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, if (r->rt == PF_FASTROUTE) { #ifdef __FreeBSD__ - in_rtalloc(ro, 0); + in_rtalloc_ign(ro, 0, M_GETFIB(m0)); #else rtalloc(ro); #endif @@ -6893,7 +6900,7 @@ done: ("pf: dropping packet with ip options\n")); } - if ((s && s->tag) || r->rtableid) + if ((s && s->tag) || r->rtableid >= 0) #ifdef __FreeBSD__ pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag); #else @@ -7437,7 +7444,7 @@ done: ("pf: dropping packet with dangerous v6 headers\n")); } - if ((s && s->tag) || r->rtableid) + if ((s && s->tag) || r->rtableid >= 0) #ifdef __FreeBSD__ pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag); #else diff --git a/sys/contrib/pf/net/pf_ioctl.c b/sys/contrib/pf/net/pf_ioctl.c index e78c8ffec7b..468f3d76933 100644 --- a/sys/contrib/pf/net/pf_ioctl.c +++ b/sys/contrib/pf/net/pf_ioctl.c @@ -1754,7 +1754,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } #ifdef __FreeBSD__ /* ROUTING */ - if (rule->rtableid > 0 && rule->rtableid > rt_numfibs) + if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs) #else if (rule->rtableid > 0 && !rtable_exists(rule->rtableid)) #endif @@ -2035,7 +2035,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (newrule->rtableid > 0 && #ifdef __FreeBSD__ /* ROUTING */ - newrule->rtableid > rt_numfibs) + newrule->rtableid >= rt_numfibs) #else !rtable_exists(newrule->rtableid)) #endif diff --git a/sys/contrib/pf/net/pf_lb.c b/sys/contrib/pf/net/pf_lb.c index f4c9a00844c..4adc6f00e8d 100644 --- a/sys/contrib/pf/net/pf_lb.c +++ b/sys/contrib/pf/net/pf_lb.c @@ -261,7 +261,7 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO].ptr; else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, - src->neg, kif)) + src->neg, kif, M_GETFIB(m))) r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : PF_SKIP_DST_ADDR].ptr; else if (src->port_op && !pf_match_port(src->port_op, @@ -269,10 +269,11 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : PF_SKIP_DST_PORT].ptr; else if (dst != NULL && - PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL)) + PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL, + M_GETFIB(m))) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, - 0, NULL)) + 0, NULL, M_GETFIB(m))) r = TAILQ_NEXT(r, entries); else if (dst != NULL && dst->port_op && !pf_match_port(dst->port_op, dst->port[0], diff --git a/sys/contrib/pf/net/pf_norm.c b/sys/contrib/pf/net/pf_norm.c index 6c04eee99ff..2b20c85b246 100644 --- a/sys/contrib/pf/net/pf_norm.c +++ b/sys/contrib/pf/net/pf_norm.c @@ -1163,11 +1163,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason, r = r->skip[PF_SKIP_PROTO].ptr; else if (PF_MISMATCHAW(&r->src.addr, (struct pf_addr *)&h->ip_src.s_addr, AF_INET, - r->src.neg, kif)) + r->src.neg, kif, M_GETFIB(m))) r = r->skip[PF_SKIP_SRC_ADDR].ptr; else if (PF_MISMATCHAW(&r->dst.addr, (struct pf_addr *)&h->ip_dst.s_addr, AF_INET, - r->dst.neg, NULL)) + r->dst.neg, NULL, M_GETFIB(m))) r = r->skip[PF_SKIP_DST_ADDR].ptr; #ifdef __FreeBSD__ else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag)) @@ -1428,11 +1428,11 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif, #endif else if (PF_MISMATCHAW(&r->src.addr, (struct pf_addr *)&h->ip6_src, AF_INET6, - r->src.neg, kif)) + r->src.neg, kif, M_GETFIB(m))) r = r->skip[PF_SKIP_SRC_ADDR].ptr; else if (PF_MISMATCHAW(&r->dst.addr, (struct pf_addr *)&h->ip6_dst, AF_INET6, - r->dst.neg, NULL)) + r->dst.neg, NULL, M_GETFIB(m))) r = r->skip[PF_SKIP_DST_ADDR].ptr; else break; @@ -1593,13 +1593,13 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff, else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO].ptr; else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, - r->src.neg, kif)) + r->src.neg, kif, M_GETFIB(m))) r = r->skip[PF_SKIP_SRC_ADDR].ptr; else if (r->src.port_op && !pf_match_port(r->src.port_op, r->src.port[0], r->src.port[1], th->th_sport)) r = r->skip[PF_SKIP_SRC_PORT].ptr; else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, - r->dst.neg, NULL)) + r->dst.neg, NULL, M_GETFIB(m))) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, r->dst.port[0], r->dst.port[1], th->th_dport)) diff --git a/sys/contrib/pf/net/pfvar.h b/sys/contrib/pf/net/pfvar.h index fe4c0ced945..85fef1d2322 100644 --- a/sys/contrib/pf/net/pfvar.h +++ b/sys/contrib/pf/net/pfvar.h @@ -402,14 +402,18 @@ extern struct mtx pf_task_mtx; #endif /* PF_INET6_ONLY */ #endif /* PF_INET_INET6 */ -#define PF_MISMATCHAW(aw, x, af, neg, ifp) \ +/* + * XXX callers not FIB-aware in our version of pf yet. + * OpenBSD fixed it later it seems, 2010/05/07 13:33:16 claudio. + */ +#define PF_MISMATCHAW(aw, x, af, neg, ifp, rtid) \ ( \ (((aw)->type == PF_ADDR_NOROUTE && \ - pf_routable((x), (af), NULL)) || \ + pf_routable((x), (af), NULL, (rtid))) || \ (((aw)->type == PF_ADDR_URPFFAILED && (ifp) != NULL && \ - pf_routable((x), (af), (ifp))) || \ + pf_routable((x), (af), (ifp), (rtid))) || \ ((aw)->type == PF_ADDR_RTLABEL && \ - !pf_rtlabel_match((x), (af), (aw))) || \ + !pf_rtlabel_match((x), (af), (aw), (rtid))) || \ ((aw)->type == PF_ADDR_TABLE && \ !pfr_match_addr((aw)->p.tbl, (x), (af))) || \ ((aw)->type == PF_ADDR_DYNIFTL && \ @@ -1977,8 +1981,10 @@ int pf_normalize_tcp_stateful(struct mbuf *, int, struct pf_pdesc *, u_int32_t pf_state_expires(const struct pf_state *); void pf_purge_expired_fragments(void); -int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *); -int pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *); +int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *, + int); +int pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *, + int); #ifdef __FreeBSD__ int pf_socket_lookup(int, struct pf_pdesc *, struct inpcb *); #else