-/* $OpenBSD: pf.c,v 1.1200 2024/07/02 18:33:47 bluhm Exp $ */
+/* $OpenBSD: pf.c,v 1.1201 2024/07/04 12:50:08 bluhm Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
break;
case AF_INET6:
if (pd.dir == PF_IN) {
- int flags;
+ int flags = IPV6_REDIRECT;
- if (ip6_forwarding == 0) {
+ switch (ip6_forwarding) {
+ case 2:
+ SET(flags, IPV6_FORWARDING_IPSEC);
+ /* FALLTHROUGH */
+ case 1:
+ SET(flags, IPV6_FORWARDING);
+ break;
+ default:
ip6stat_inc(ip6s_cantforward);
action = PF_DROP;
goto out;
}
- flags = IPV6_FORWARDING | IPV6_REDIRECT;
ip6_forward(pd.m, NULL, flags);
} else
ip6_output(pd.m, NULL, NULL, 0, NULL, NULL);
-/* $OpenBSD: pf_norm.c,v 1.231 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.232 2024/07/04 12:50:08 bluhm Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
while ((m = ml_dequeue(&ml)) != NULL) {
m->m_pkthdr.pf.flags |= PF_TAG_REFRAGMENTED;
if (ifp == NULL) {
- ip6_forward(m, NULL, IPV6_FORWARDING);
+ int flags = 0;
+
+ switch (ip6_forwarding) {
+ case 2:
+ SET(flags, IPV6_FORWARDING_IPSEC);
+ /* FALLTHROUGH */
+ case 1:
+ SET(flags, IPV6_FORWARDING);
+ break;
+ default:
+ ip6stat_inc(ip6s_cantforward);
+ return (PF_DROP);
+ }
+ ip6_forward(m, NULL, flags);
} else if ((u_long)m->m_pkthdr.len <= ifp->if_mtu) {
ifp->if_output(ifp, m, sin6tosa(dst), rt);
} else {
-/* $OpenBSD: ip6_forward.c,v 1.119 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: ip6_forward.c,v 1.120 2024/07/04 12:50:08 bluhm Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/*
}
#endif
+#ifdef IPSEC
+ if (ISSET(flags, IPV6_FORWARDING) &&
+ ISSET(flags, IPV6_FORWARDING_IPSEC) &&
+ !ISSET(m->m_pkthdr.ph_tagsset, PACKET_TAG_IPSEC_IN_DONE)) {
+ error = EHOSTUNREACH;
+ goto senderr;
+ }
+#endif
+
error = if_output_tso(ifp, &m, dst, rt, ifp->if_mtu);
if (error)
ip6stat_inc(ip6s_cantforward);
-/* $OpenBSD: ip6_input.c,v 1.263 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.264 2024/07/04 12:50:08 bluhm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
SET(flags, IPV6_REDIRECT);
#endif
- if (ip6_forwarding != 0)
+ switch (ip6_forwarding) {
+ case 2:
+ SET(flags, IPV6_FORWARDING_IPSEC);
+ /* FALLTHROUGH */
+ case 1:
SET(flags, IPV6_FORWARDING);
+ break;
+ }
/*
* Without embedded scope ID we cannot find link-local
* must be discarded, else it may be accepted below.
*/
KERNEL_LOCK();
- error = ip6_mforward(ip6, ifp, m);
+ error = ip6_mforward(ip6, ifp, m, flags);
KERNEL_UNLOCK();
if (error) {
ip6stat_inc(ip6s_cantforward);
#ifdef MROUTING
{ IPV6CTL_MRTPROTO, &ip6_mrtproto, SYSCTL_INT_READONLY },
#endif
- { IPV6CTL_FORWARDING, &ip6_forwarding, 0, 1 },
+ { IPV6CTL_FORWARDING, &ip6_forwarding, 0, 2 },
{ IPV6CTL_SENDREDIRECTS, &ip6_sendredirects, 0, 1 },
{ IPV6CTL_DEFHLIM, &ip6_defhlim, 0, 255 },
{ IPV6CTL_MAXFRAGPACKETS, &ip6_maxfragpackets, 0, 1000 },
-/* $OpenBSD: ip6_mroute.c,v 1.142 2024/06/07 08:37:59 jsg Exp $ */
+/* $OpenBSD: ip6_mroute.c,v 1.143 2024/07/04 12:50:08 bluhm Exp $ */
/* $NetBSD: ip6_mroute.c,v 1.59 2003/12/10 09:28:38 itojun Exp $ */
/* $KAME: ip6_mroute.c,v 1.45 2001/03/25 08:38:51 itojun Exp $ */
do { } while (0)
#endif
-int ip6_mdq(struct mbuf *, struct ifnet *, struct rtentry *);
-void phyint_send6(struct ifnet *, struct ip6_hdr *, struct mbuf *);
+int ip6_mdq(struct mbuf *, struct ifnet *, struct rtentry *, int);
+void phyint_send6(struct ifnet *, struct ip6_hdr *, struct mbuf *, int);
/*
* Globals. All but ip6_mrouter, ip6_mrtproto and mrt6stat could be static,
* discard it.
*/
int
-ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
+ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m, int flags)
{
struct rtentry *rt;
struct mif6 *mifp;
/* Entry exists, so forward if necessary */
if (rt) {
- return (ip6_mdq(m, ifp, rt));
+ return (ip6_mdq(m, ifp, rt, flags));
} else {
/*
* If we don't have a route for packet's origin,
* Packet forwarding routine once entry in the cache is made
*/
int
-ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt)
+ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int flags)
{
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct mif6 *m6, *mifp = (struct mif6 *)ifp->if_mcast6;
m6->m6_pkt_out++;
m6->m6_bytes_out += plen;
- phyint_send6(ifn, ip6, m);
+ phyint_send6(ifn, ip6, m, flags);
if_put(ifn);
} while ((rt = rtable_iterate(rt)) != NULL);
}
void
-phyint_send6(struct ifnet *ifp, struct ip6_hdr *ip6, struct mbuf *m)
+phyint_send6(struct ifnet *ifp, struct ip6_hdr *ip6, struct mbuf *m, int flags)
{
struct mbuf *mb_copy;
struct sockaddr_in6 *dst6, sin6;
/* XXX: ip6_output will override ip6->ip6_hlim */
im6o.im6o_hlim = ip6->ip6_hlim;
im6o.im6o_loop = 1;
- error = ip6_output(mb_copy, NULL, NULL, IPV6_FORWARDING, &im6o,
- NULL);
+ error = ip6_output(mb_copy, NULL, NULL, flags | IPV6_FORWARDING,
+ &im6o, NULL);
return;
}
-/* $OpenBSD: ip6_output.c,v 1.291 2024/04/17 20:48:51 bluhm Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.292 2024/07/04 12:50:08 bluhm Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
*/
if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain] &&
(flags & IPV6_FORWARDING) == 0) {
- if (ip6_mforward(ip6, ifp, m) != 0) {
+ if (ip6_mforward(ip6, ifp, m, flags) != 0) {
m_freem(m);
goto done;
}
}
#endif
+#ifdef IPSEC
+ if (ISSET(flags, IPV6_FORWARDING) &&
+ ISSET(flags, IPV6_FORWARDING_IPSEC) &&
+ !ISSET(m->m_pkthdr.ph_tagsset, PACKET_TAG_IPSEC_IN_DONE)) {
+ error = EHOSTUNREACH;
+ goto bad;
+ }
+#endif
+
/*
* If the packet is not going on the wire it can be destined
* to any local address. In this case do not clear its scopes
-/* $OpenBSD: ip6_var.h,v 1.118 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.119 2024/07/04 12:50:08 bluhm Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
#define IPV6_FORWARDING 0x02 /* most of IPv6 header exists */
#define IPV6_MINMTU 0x04 /* use minimum MTU (IPV6_USE_MIN_MTU) */
#define IPV6_REDIRECT 0x08 /* redirected by pf */
+#define IPV6_FORWARDING_IPSEC 0x10 /* only packets processed by IPsec */
extern int ip6_mtudisc_timeout; /* mtu discovery */
extern struct rttimer_queue icmp6_mtudisc_timeout_q;
int ip6_get_prevhdr(struct mbuf *, int);
int ip6_nexthdr(struct mbuf *, int, int, int *);
int ip6_lasthdr(struct mbuf *, int, int, int *);
-int ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *);
+int ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *, int);
int ip6_process_hopopts(struct mbuf **, u_int8_t *, int, u_int32_t *,
u_int32_t *);
void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **);