Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135257822
D30992.id91642.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D30992.id91642.diff
View Options
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -874,6 +874,12 @@
ifa_free(&ia->ia_ifa);
break;
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ case PRC_MSGSIZE:
+ if (IPSEC_ENABLED(ipv4))
+ IPSEC_CTLINPUT(ipv4, cmd, sa, vip);
+ break;
+#endif
}
}
diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h
--- a/sys/netipsec/ipsec.h
+++ b/sys/netipsec/ipsec.h
@@ -246,6 +246,7 @@
#define IPSECCTL_ECN 11
#define IPSECCTL_DEBUG 12
#define IPSECCTL_ESP_RANDPAD 13
+#define IPSECCTL_MIN_PMTU 14
#ifdef _KERNEL
#include <sys/counter.h>
@@ -277,6 +278,7 @@
VNET_DECLARE(int, ip4_ah_trans_deflev);
VNET_DECLARE(int, ip4_ah_net_deflev);
VNET_DECLARE(int, ip4_ipsec_dfbit);
+VNET_DECLARE(int, ip4_ipsec_min_pmtu);
VNET_DECLARE(int, ip4_ipsec_ecn);
VNET_DECLARE(int, crypto_support);
VNET_DECLARE(int, async_crypto);
@@ -289,6 +291,7 @@
#define V_ip4_ah_trans_deflev VNET(ip4_ah_trans_deflev)
#define V_ip4_ah_net_deflev VNET(ip4_ah_net_deflev)
#define V_ip4_ipsec_dfbit VNET(ip4_ipsec_dfbit)
+#define V_ip4_ipsec_min_pmtu VNET(ip4_ipsec_min_pmtu)
#define V_ip4_ipsec_ecn VNET(ip4_ipsec_ecn)
#define V_crypto_support VNET(crypto_support)
#define V_async_crypto VNET(async_crypto)
@@ -341,6 +344,7 @@
int ipsec4_output(struct mbuf *, struct inpcb *);
int ipsec4_capability(struct mbuf *, u_int);
int ipsec4_common_input_cb(struct mbuf *, struct secasvar *, int, int);
+int ipsec4_ctlinput(int, struct sockaddr *, void *);
int ipsec4_process_packet(struct mbuf *, struct secpolicy *, struct inpcb *);
int ipsec_process_done(struct mbuf *, struct secpolicy *, struct secasvar *,
u_int);
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -112,6 +112,7 @@
/* DF bit on encap. 0: clear 1: set 2: copy */
VNET_DEFINE(int, ip4_ipsec_dfbit) = 0;
+VNET_DEFINE(int, ip4_ipsec_min_pmtu) = 576;
VNET_DEFINE(int, ip4_esp_trans_deflev) = IPSEC_LEVEL_USE;
VNET_DEFINE(int, ip4_esp_net_deflev) = IPSEC_LEVEL_USE;
VNET_DEFINE(int, ip4_ah_trans_deflev) = IPSEC_LEVEL_USE;
@@ -196,6 +197,9 @@
SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT, dfbit,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_dfbit), 0,
"Do not fragment bit on encap.");
+SYSCTL_INT(_net_inet_ipsec, IPSECCTL_MIN_PMTU, min_pmtu,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_min_pmtu), 0,
+ "Lowest acceptable PMTU value.");
SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN, ecn,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_ecn), 0,
"Explicit Congestion Notification handling.");
diff --git a/sys/netipsec/ipsec6.h b/sys/netipsec/ipsec6.h
--- a/sys/netipsec/ipsec6.h
+++ b/sys/netipsec/ipsec6.h
@@ -73,6 +73,7 @@
int ipsec6_output(struct mbuf *, struct inpcb *);
int ipsec6_capability(struct mbuf *, u_int);
int ipsec6_common_input_cb(struct mbuf *, struct secasvar *, int, int);
+int ipsec6_ctlinput(int, struct sockaddr *, void *);
int ipsec6_process_packet(struct mbuf *, struct secpolicy *, struct inpcb *);
int ip6_ipsec_filtertunnel(struct mbuf *);
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c
--- a/sys/netipsec/ipsec_input.c
+++ b/sys/netipsec/ipsec_input.c
@@ -68,7 +68,9 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
#include <netinet/in_var.h>
+#include <netinet/tcp_var.h>
#include <netinet/ip6.h>
#ifdef INET6
@@ -266,6 +268,40 @@
return (0);
}
+int
+ipsec4_ctlinput(int code, struct sockaddr *sa, void *v)
+{
+ struct in_conninfo inc;
+ struct secasvar *sav;
+ struct icmp *icp;
+ struct ip *ip = v;
+ uint32_t pmtu, spi;
+
+ if (code != PRC_MSGSIZE || ip == NULL)
+ return (EINVAL);
+ if (sa->sa_family != AF_INET ||
+ sa->sa_len != sizeof(struct sockaddr_in))
+ return (EAFNOSUPPORT);
+
+ icp = __containerof(ip, struct icmp, icmp_ip);
+ pmtu = ntohs(icp->icmp_nextmtu);
+
+ if (pmtu < V_ip4_ipsec_min_pmtu)
+ return (EINVAL);
+
+ memcpy(&spi, (caddr_t)ip + (ip->ip_hl << 2), sizeof(spi));
+ sav = key_allocsa((union sockaddr_union *)sa, ip->ip_p, spi);
+ if (sav == NULL)
+ return (ENOENT);
+
+ key_freesav(&sav);
+
+ memset(&inc, 0, sizeof(inc));
+ inc.inc_faddr = satosin(sa)->sin_addr;
+ tcp_hc_updatemtu(&inc, pmtu);
+ return (0);
+}
+
/*
* IPsec input callback for INET protocols.
* This routine is called as the transform callback.
@@ -482,6 +518,12 @@
return (0);
}
+int
+ipsec6_ctlinput(int code, struct sockaddr *sa, void *v)
+{
+ return (0);
+}
+
/*
* IPsec input callback, called by the transform callback. Takes care of
* filtering and other sanity checks on the processed packet.
diff --git a/sys/netipsec/ipsec_mod.c b/sys/netipsec/ipsec_mod.c
--- a/sys/netipsec/ipsec_mod.c
+++ b/sys/netipsec/ipsec_mod.c
@@ -63,6 +63,7 @@
.pcbctl = ipsec4_pcbctl,
.capability = ipsec4_capability,
.check_policy = ipsec4_in_reject,
+ .ctlinput = ipsec4_ctlinput,
.hdrsize = ipsec_hdrsiz_inpcb,
.udp_input = udp_ipsec_input,
.udp_pcbctl = udp_ipsec_pcbctl,
@@ -84,6 +85,7 @@
.pcbctl = ipsec6_pcbctl,
.capability = ipsec6_capability,
.check_policy = ipsec6_in_reject,
+ .ctlinput = ipsec6_ctlinput,
.hdrsize = ipsec_hdrsiz_inpcb,
};
#ifndef KLD_MODULE
diff --git a/sys/netipsec/ipsec_support.h b/sys/netipsec/ipsec_support.h
--- a/sys/netipsec/ipsec_support.h
+++ b/sys/netipsec/ipsec_support.h
@@ -134,6 +134,8 @@
(*(proto ## _ipsec_support)->methods->capability)(m, __VA_ARGS__)
#define IPSEC_HDRSIZE(proto, inp) \
(*(proto ## _ipsec_support)->methods->hdrsize)(inp)
+#define IPSEC_CTLINPUT(proto, code, sa, v) \
+ (*(proto ## _ipsec_support)->methods->ctlinput)(code, sa, v)
#define UDPENCAP_INPUT(m, ...) \
(*ipv4_ipsec_support->methods->udp_input)(m, __VA_ARGS__)
@@ -162,6 +164,8 @@
struct sockopt *);
int ipsec_kmod_capability(struct ipsec_support * const, struct mbuf *, u_int);
size_t ipsec_kmod_hdrsize(struct ipsec_support * const, struct inpcb *);
+int ipsec_kmod_ctlinput(struct ipsec_support * const, int,
+ struct sockaddr *, void *);
int ipsec_kmod_udp_input(struct ipsec_support * const, struct mbuf *, int, int);
int ipsec_kmod_udp_pcbctl(struct ipsec_support * const, struct inpcb *,
struct sockopt *);
@@ -185,6 +189,8 @@
ipsec_kmod_capability(proto ## _ipsec_support, __VA_ARGS__)
#define IPSEC_HDRSIZE(proto, ...) \
ipsec_kmod_hdrsize(proto ## _ipsec_support, __VA_ARGS__)
+#define IPSEC_CTLINPUT(proto, ...) \
+ ipsec_kmod_ctlinput(proto ## _ipsec_support, __VA_ARGS__)
#endif /* IPSEC_SUPPORT */
#endif /* _KERNEL */
#endif /* _NETIPSEC_IPSEC_SUPPORT_H_ */
diff --git a/sys/netipsec/subr_ipsec.c b/sys/netipsec/subr_ipsec.c
--- a/sys/netipsec/subr_ipsec.c
+++ b/sys/netipsec/subr_ipsec.c
@@ -366,6 +366,11 @@
(m)
)
+IPSEC_KMOD_METHOD(int, ipsec_kmod_ctlinput, sc,
+ ctlinput, METHOD_DECL(struct ipsec_support * const sc, int code,
+ struct sockaddr *sa, void *v), METHOD_ARGS(code, sa, v)
+)
+
IPSEC_KMOD_METHOD(int, ipsec_kmod_output, sc,
output, METHOD_DECL(struct ipsec_support * const sc, struct mbuf *m,
struct inpcb *inp), METHOD_ARGS(m, inp)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 9, 1:26 AM (2 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25056182
Default Alt Text
D30992.id91642.diff (6 KB)
Attached To
Mode
D30992: ipsec: Handle ICMP NEEDFRAG message.
Attached
Detach File
Event Timeline
Log In to Comment