mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
tools: apply IPSEC_sysctl.RELENG_10.diff
This commit is contained in:
parent
fc509e3919
commit
6965f14eb6
7 changed files with 178 additions and 156 deletions
|
|
@ -697,7 +697,8 @@ int getsourcefilter(int, uint32_t, struct sockaddr *, socklen_t,
|
|||
#define IPCTL_FASTFORWARDING 14 /* use fast IP forwarding code */
|
||||
#define IPCTL_KEEPFAITH 15 /* FAITH IPv4->IPv6 translater ctl */
|
||||
#define IPCTL_GIF_TTL 16 /* default TTL for gif encap packet */
|
||||
#define IPCTL_MAXID 17
|
||||
#define IPCTL_IPSEC_INUSE 17
|
||||
#define IPCTL_MAXID 18
|
||||
|
||||
#endif /* __BSD_VISIBLE */
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,11 @@ SYSCTL_VNET_INT(_net_inet_ip, IPCTL_FORWARDING, forwarding, CTLFLAG_RW,
|
|||
&VNET_NAME(ipforwarding), 0,
|
||||
"Enable IP forwarding between interfaces");
|
||||
|
||||
VNET_DEFINE(int, ipipsec_in_use);
|
||||
SYSCTL_VNET_INT(_net_inet_ip, IPCTL_IPSEC_INUSE, ipsec_in_use, CTLFLAG_RW,
|
||||
&VNET_NAME(ipipsec_in_use), 0,
|
||||
"Enable IPSec processing of packets");
|
||||
|
||||
static VNET_DEFINE(int, ipsendredirects) = 1; /* XXX */
|
||||
#define V_ipsendredirects VNET(ipsendredirects)
|
||||
SYSCTL_VNET_INT(_net_inet_ip, IPCTL_SENDREDIRECTS, redirect, CTLFLAG_RW,
|
||||
|
|
@ -500,7 +505,7 @@ tooshort:
|
|||
/*
|
||||
* Bypass packet filtering for packets previously handled by IPsec.
|
||||
*/
|
||||
if (ip_ipsec_filtertunnel(m))
|
||||
if (V_ipipsec_in_use && ip_ipsec_filtertunnel(m))
|
||||
goto passin;
|
||||
#endif /* IPSEC */
|
||||
|
||||
|
|
@ -707,7 +712,7 @@ passin:
|
|||
m_freem(m);
|
||||
} else {
|
||||
#ifdef IPSEC
|
||||
if (ip_ipsec_fwd(m))
|
||||
if (V_ipipsec_in_use && ip_ipsec_fwd(m))
|
||||
goto bad;
|
||||
#endif /* IPSEC */
|
||||
ip_forward(m, dchg);
|
||||
|
|
@ -753,7 +758,7 @@ ours:
|
|||
* note that we do not visit this with protocols with pcb layer
|
||||
* code - like udp/tcp/raw ip.
|
||||
*/
|
||||
if (ip_ipsec_input(m))
|
||||
if (V_ipipsec_in_use && ip_ipsec_input(m))
|
||||
goto bad;
|
||||
#endif /* IPSEC */
|
||||
|
||||
|
|
@ -1547,7 +1552,8 @@ ip_forward(struct mbuf *m, int srcrt)
|
|||
* If IPsec is configured for this path,
|
||||
* override any possibly mtu value set by ip_output.
|
||||
*/
|
||||
mtu = ip_ipsec_mtu(mcopy, mtu);
|
||||
if (V_ipipsec_in_use)
|
||||
mtu = ip_ipsec_mtu(mcopy, mtu);
|
||||
#endif /* IPSEC */
|
||||
/*
|
||||
* If the MTU was set before make sure we are below the
|
||||
|
|
|
|||
|
|
@ -479,18 +479,20 @@ again:
|
|||
|
||||
sendit:
|
||||
#ifdef IPSEC
|
||||
switch(ip_ipsec_output(&m, inp, &flags, &error)) {
|
||||
case 1:
|
||||
goto bad;
|
||||
case -1:
|
||||
goto done;
|
||||
case 0:
|
||||
default:
|
||||
break; /* Continue with packet processing. */
|
||||
if (V_ipipsec_in_use) {
|
||||
switch(ip_ipsec_output(&m, inp, &flags, &error)) {
|
||||
case 1:
|
||||
goto bad;
|
||||
case -1:
|
||||
goto done;
|
||||
case 0:
|
||||
default:
|
||||
break; /* Continue with packet processing. */
|
||||
}
|
||||
/* Update variables that are affected by ipsec4_output(). */
|
||||
ip = mtod(m, struct ip *);
|
||||
hlen = ip->ip_hl << 2;
|
||||
}
|
||||
/* Update variables that are affected by ipsec4_output(). */
|
||||
ip = mtod(m, struct ip *);
|
||||
hlen = ip->ip_hl << 2;
|
||||
#endif /* IPSEC */
|
||||
|
||||
/* Jump over all PFIL processing if hooks are not active. */
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ struct sockopt;
|
|||
VNET_DECLARE(u_short, ip_id); /* ip packet ctr, for ids */
|
||||
VNET_DECLARE(int, ip_defttl); /* default IP ttl */
|
||||
VNET_DECLARE(int, ipforwarding); /* ip forwarding */
|
||||
VNET_DECLARE(int, ipipsec_in_use);
|
||||
#ifdef IPSTEALTH
|
||||
VNET_DECLARE(int, ipstealth); /* stealth forwarding */
|
||||
#endif
|
||||
|
|
@ -200,6 +201,7 @@ extern struct pr_usrreqs rip_usrreqs;
|
|||
#define V_ip_id VNET(ip_id)
|
||||
#define V_ip_defttl VNET(ip_defttl)
|
||||
#define V_ipforwarding VNET(ipforwarding)
|
||||
#define V_ipipsec_in_use VNET(ipipsec_in_use)
|
||||
#ifdef IPSTEALTH
|
||||
#define V_ipstealth VNET(ipstealth)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ static struct netisr_handler ip6_nh = {
|
|||
.nh_policy = NETISR_POLICY_FLOW,
|
||||
};
|
||||
|
||||
VNET_DECLARE(int, ipipsec_in_use);
|
||||
VNET_DECLARE(struct callout, in6_tmpaddrtimer_ch);
|
||||
#define V_in6_tmpaddrtimer_ch VNET(in6_tmpaddrtimer_ch)
|
||||
|
||||
|
|
@ -1017,6 +1018,7 @@ passin:
|
|||
}
|
||||
|
||||
#ifdef IPSEC
|
||||
if (V_ipipsec_in_use) {
|
||||
/*
|
||||
* enforce IPsec policy checking if we are seeing last header.
|
||||
* note that we do not visit this with protocols with pcb layer
|
||||
|
|
@ -1024,6 +1026,7 @@ passin:
|
|||
*/
|
||||
if (ip6_ipsec_input(m, nxt))
|
||||
goto bad;
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ static int ip6_getpmtu(struct route_in6 *, struct route_in6 *,
|
|||
struct ifnet *, struct in6_addr *, u_long *, int *, u_int);
|
||||
static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
|
||||
|
||||
VNET_DECLARE(int, ipipsec_in_use);
|
||||
|
||||
/*
|
||||
* Make an extension header from option data. hp is the source, and
|
||||
|
|
@ -294,33 +295,35 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
|||
}
|
||||
|
||||
#ifdef IPSEC
|
||||
/*
|
||||
* IPSec checking which handles several cases.
|
||||
* FAST IPSEC: We re-injected the packet.
|
||||
*/
|
||||
switch(ip6_ipsec_output(&m, inp, &flags, &error, &ifp, &sp))
|
||||
{
|
||||
case 1: /* Bad packet */
|
||||
goto freehdrs;
|
||||
case -1: /* Do IPSec */
|
||||
needipsec = 1;
|
||||
if (V_ipipsec_in_use) {
|
||||
/*
|
||||
* Do delayed checksums now, as we may send before returning.
|
||||
* IPSec checking which handles several cases.
|
||||
* FAST IPSEC: We re-injected the packet.
|
||||
*/
|
||||
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
|
||||
plen = m->m_pkthdr.len - sizeof(*ip6);
|
||||
in6_delayed_cksum(m, plen, sizeof(struct ip6_hdr));
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
|
||||
}
|
||||
switch(ip6_ipsec_output(&m, inp, &flags, &error, &ifp, &sp))
|
||||
{
|
||||
case 1: /* Bad packet */
|
||||
goto freehdrs;
|
||||
case -1: /* Do IPSec */
|
||||
needipsec = 1;
|
||||
/*
|
||||
* Do delayed checksums now, as we may send before returning.
|
||||
*/
|
||||
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
|
||||
plen = m->m_pkthdr.len - sizeof(*ip6);
|
||||
in6_delayed_cksum(m, plen, sizeof(struct ip6_hdr));
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
|
||||
}
|
||||
#ifdef SCTP
|
||||
if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) {
|
||||
sctp_delayed_cksum(m, sizeof(struct ip6_hdr));
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6;
|
||||
}
|
||||
if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) {
|
||||
sctp_delayed_cksum(m, sizeof(struct ip6_hdr));
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6;
|
||||
}
|
||||
#endif
|
||||
case 0: /* No IPSec */
|
||||
default:
|
||||
break;
|
||||
case 0: /* No IPSec */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
|
||||
|
|
@ -421,67 +424,69 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
|||
IPPROTO_ROUTING);
|
||||
|
||||
#ifdef IPSEC
|
||||
if (!needipsec)
|
||||
goto skip_ipsec2;
|
||||
if (V_ipipsec_in_use) {
|
||||
if (!needipsec)
|
||||
goto skip_ipsec2;
|
||||
|
||||
/*
|
||||
* pointers after IPsec headers are not valid any more.
|
||||
* other pointers need a great care too.
|
||||
* (IPsec routines should not mangle mbufs prior to AH/ESP)
|
||||
*/
|
||||
exthdrs.ip6e_dest2 = NULL;
|
||||
|
||||
if (exthdrs.ip6e_rthdr) {
|
||||
rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
|
||||
segleft_org = rh->ip6r_segleft;
|
||||
rh->ip6r_segleft = 0;
|
||||
}
|
||||
|
||||
bzero(&state, sizeof(state));
|
||||
state.m = m;
|
||||
error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags,
|
||||
&needipsectun);
|
||||
m = state.m;
|
||||
if (error == EJUSTRETURN) {
|
||||
/*
|
||||
* We had a SP with a level of 'use' and no SA. We
|
||||
* will just continue to process the packet without
|
||||
* IPsec processing.
|
||||
* pointers after IPsec headers are not valid any more.
|
||||
* other pointers need a great care too.
|
||||
* (IPsec routines should not mangle mbufs prior to AH/ESP)
|
||||
*/
|
||||
;
|
||||
} else if (error) {
|
||||
/* mbuf is already reclaimed in ipsec6_output_trans. */
|
||||
m = NULL;
|
||||
switch (error) {
|
||||
case EHOSTUNREACH:
|
||||
case ENETUNREACH:
|
||||
case EMSGSIZE:
|
||||
case ENOBUFS:
|
||||
case ENOMEM:
|
||||
break;
|
||||
default:
|
||||
printf("[%s:%d] (ipsec): error code %d\n",
|
||||
__func__, __LINE__, error);
|
||||
/* FALLTHROUGH */
|
||||
case ENOENT:
|
||||
/* don't show these error codes to the user */
|
||||
error = 0;
|
||||
break;
|
||||
exthdrs.ip6e_dest2 = NULL;
|
||||
|
||||
if (exthdrs.ip6e_rthdr) {
|
||||
rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
|
||||
segleft_org = rh->ip6r_segleft;
|
||||
rh->ip6r_segleft = 0;
|
||||
}
|
||||
|
||||
bzero(&state, sizeof(state));
|
||||
state.m = m;
|
||||
error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags,
|
||||
&needipsectun);
|
||||
m = state.m;
|
||||
if (error == EJUSTRETURN) {
|
||||
/*
|
||||
* We had a SP with a level of 'use' and no SA. We
|
||||
* will just continue to process the packet without
|
||||
* IPsec processing.
|
||||
*/
|
||||
;
|
||||
} else if (error) {
|
||||
/* mbuf is already reclaimed in ipsec6_output_trans. */
|
||||
m = NULL;
|
||||
switch (error) {
|
||||
case EHOSTUNREACH:
|
||||
case ENETUNREACH:
|
||||
case EMSGSIZE:
|
||||
case ENOBUFS:
|
||||
case ENOMEM:
|
||||
break;
|
||||
default:
|
||||
printf("[%s:%d] (ipsec): error code %d\n",
|
||||
__func__, __LINE__, error);
|
||||
/* FALLTHROUGH */
|
||||
case ENOENT:
|
||||
/* don't show these error codes to the user */
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
goto bad;
|
||||
} else if (!needipsectun) {
|
||||
/*
|
||||
* In the FAST IPSec case we have already
|
||||
* re-injected the packet and it has been freed
|
||||
* by the ipsec_done() function. So, just clean
|
||||
* up after ourselves.
|
||||
*/
|
||||
m = NULL;
|
||||
goto done;
|
||||
}
|
||||
if (exthdrs.ip6e_rthdr) {
|
||||
/* ah6_output doesn't modify mbuf chain */
|
||||
rh->ip6r_segleft = segleft_org;
|
||||
}
|
||||
goto bad;
|
||||
} else if (!needipsectun) {
|
||||
/*
|
||||
* In the FAST IPSec case we have already
|
||||
* re-injected the packet and it has been freed
|
||||
* by the ipsec_done() function. So, just clean
|
||||
* up after ourselves.
|
||||
*/
|
||||
m = NULL;
|
||||
goto done;
|
||||
}
|
||||
if (exthdrs.ip6e_rthdr) {
|
||||
/* ah6_output doesn't modify mbuf chain */
|
||||
rh->ip6r_segleft = segleft_org;
|
||||
}
|
||||
skip_ipsec2:;
|
||||
#endif /* IPSEC */
|
||||
|
|
@ -563,73 +568,75 @@ again:
|
|||
}
|
||||
|
||||
#ifdef IPSEC
|
||||
/*
|
||||
* We may re-inject packets into the stack here.
|
||||
*/
|
||||
if (needipsec && needipsectun) {
|
||||
struct ipsec_output_state state;
|
||||
|
||||
if (V_ipipsec_in_use) {
|
||||
/*
|
||||
* All the extension headers will become inaccessible
|
||||
* (since they can be encrypted).
|
||||
* Don't panic, we need no more updates to extension headers
|
||||
* on inner IPv6 packet (since they are now encapsulated).
|
||||
*
|
||||
* IPv6 [ESP|AH] IPv6 [extension headers] payload
|
||||
* We may re-inject packets into the stack here.
|
||||
*/
|
||||
bzero(&exthdrs, sizeof(exthdrs));
|
||||
exthdrs.ip6e_ip6 = m;
|
||||
if (needipsec && needipsectun) {
|
||||
struct ipsec_output_state state;
|
||||
|
||||
bzero(&state, sizeof(state));
|
||||
state.m = m;
|
||||
state.ro = (struct route *)ro;
|
||||
state.dst = (struct sockaddr *)dst;
|
||||
|
||||
error = ipsec6_output_tunnel(&state, sp, flags);
|
||||
|
||||
m = state.m;
|
||||
ro = (struct route_in6 *)state.ro;
|
||||
dst = (struct sockaddr_in6 *)state.dst;
|
||||
if (error == EJUSTRETURN) {
|
||||
/*
|
||||
* We had a SP with a level of 'use' and no SA. We
|
||||
* will just continue to process the packet without
|
||||
* IPsec processing.
|
||||
* All the extension headers will become inaccessible
|
||||
* (since they can be encrypted).
|
||||
* Don't panic, we need no more updates to extension headers
|
||||
* on inner IPv6 packet (since they are now encapsulated).
|
||||
*
|
||||
* IPv6 [ESP|AH] IPv6 [extension headers] payload
|
||||
*/
|
||||
;
|
||||
} else if (error) {
|
||||
/* mbuf is already reclaimed in ipsec6_output_tunnel. */
|
||||
m0 = m = NULL;
|
||||
m = NULL;
|
||||
switch (error) {
|
||||
case EHOSTUNREACH:
|
||||
case ENETUNREACH:
|
||||
case EMSGSIZE:
|
||||
case ENOBUFS:
|
||||
case ENOMEM:
|
||||
break;
|
||||
default:
|
||||
printf("[%s:%d] (ipsec): error code %d\n",
|
||||
__func__, __LINE__, error);
|
||||
/* FALLTHROUGH */
|
||||
case ENOENT:
|
||||
/* don't show these error codes to the user */
|
||||
error = 0;
|
||||
break;
|
||||
bzero(&exthdrs, sizeof(exthdrs));
|
||||
exthdrs.ip6e_ip6 = m;
|
||||
|
||||
bzero(&state, sizeof(state));
|
||||
state.m = m;
|
||||
state.ro = (struct route *)ro;
|
||||
state.dst = (struct sockaddr *)dst;
|
||||
|
||||
error = ipsec6_output_tunnel(&state, sp, flags);
|
||||
|
||||
m = state.m;
|
||||
ro = (struct route_in6 *)state.ro;
|
||||
dst = (struct sockaddr_in6 *)state.dst;
|
||||
if (error == EJUSTRETURN) {
|
||||
/*
|
||||
* We had a SP with a level of 'use' and no SA. We
|
||||
* will just continue to process the packet without
|
||||
* IPsec processing.
|
||||
*/
|
||||
;
|
||||
} else if (error) {
|
||||
/* mbuf is already reclaimed in ipsec6_output_tunnel. */
|
||||
m0 = m = NULL;
|
||||
m = NULL;
|
||||
switch (error) {
|
||||
case EHOSTUNREACH:
|
||||
case ENETUNREACH:
|
||||
case EMSGSIZE:
|
||||
case ENOBUFS:
|
||||
case ENOMEM:
|
||||
break;
|
||||
default:
|
||||
printf("[%s:%d] (ipsec): error code %d\n",
|
||||
__func__, __LINE__, error);
|
||||
/* FALLTHROUGH */
|
||||
case ENOENT:
|
||||
/* don't show these error codes to the user */
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
goto bad;
|
||||
} else {
|
||||
/*
|
||||
* In the FAST IPSec case we have already
|
||||
* re-injected the packet and it has been freed
|
||||
* by the ipsec_done() function. So, just clean
|
||||
* up after ourselves.
|
||||
*/
|
||||
m = NULL;
|
||||
goto done;
|
||||
}
|
||||
goto bad;
|
||||
} else {
|
||||
/*
|
||||
* In the FAST IPSec case we have already
|
||||
* re-injected the packet and it has been freed
|
||||
* by the ipsec_done() function. So, just clean
|
||||
* up after ourselves.
|
||||
*/
|
||||
m = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
exthdrs.ip6e_ip6 = m;
|
||||
exthdrs.ip6e_ip6 = m;
|
||||
}
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ VNET_DECLARE(int, ip6_v6only);
|
|||
#define V_ip6_rr_prune VNET(ip6_rr_prune)
|
||||
#define V_ip6_mcast_pmtu VNET(ip6_mcast_pmtu)
|
||||
#define V_ip6_v6only VNET(ip6_v6only)
|
||||
#define V_ipipsec_in_use VNET(ipipsec_in_use)
|
||||
|
||||
VNET_DECLARE(struct socket *, ip6_mrouter); /* multicast routing daemon */
|
||||
VNET_DECLARE(int, ip6_sendredirects); /* send IP redirects when forwarding? */
|
||||
|
|
|
|||
Loading…
Reference in a new issue