summaryrefslogtreecommitdiffstats
path: root/main/ipsec-tools/30-natt-ports-cleanup.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/ipsec-tools/30-natt-ports-cleanup.patch')
-rw-r--r--main/ipsec-tools/30-natt-ports-cleanup.patch393
1 files changed, 393 insertions, 0 deletions
diff --git a/main/ipsec-tools/30-natt-ports-cleanup.patch b/main/ipsec-tools/30-natt-ports-cleanup.patch
new file mode 100644
index 00000000000..19360347dac
--- /dev/null
+++ b/main/ipsec-tools/30-natt-ports-cleanup.patch
@@ -0,0 +1,393 @@
+From Yvan Vanhullebus: Use SADB_X_EXT_NAT_T_* consistently for passing the
+
+From: Timo Teras <timo.teras@iki.fi>
+
+NAT-T port information.
+---
+
+ src/libipsec/libpfkey.h | 12 ++++++++
+ src/libipsec/pfkey.c | 49 +++++++++++++++++++++++++++++++++
+ src/racoon/isakmp.c | 11 +++++++
+ src/racoon/isakmp_inf.c | 37 +++++++++++++------------
+ src/racoon/pfkey.c | 69 +++++++++++++++++++++++++++++++++--------------
+ src/racoon/pfkey.h | 1 +
+ 6 files changed, 140 insertions(+), 39 deletions(-)
+
+
+diff --git a/src/libipsec/libpfkey.h b/src/libipsec/libpfkey.h
+index 8a503dd..c9b228b 100644
+--- a/src/libipsec/libpfkey.h
++++ b/src/libipsec/libpfkey.h
+@@ -117,6 +117,10 @@ u_int pfkey_set_softrate __P((u_int, u_int));
+ u_int pfkey_get_softrate __P((u_int));
+ int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *,
+ struct sockaddr *, u_int32_t, u_int32_t, u_int32_t, u_int32_t));
++int pfkey_send_getspi_nat __P((int, u_int, u_int,
++ struct sockaddr *, struct sockaddr *, u_int8_t, u_int16_t, u_int16_t,
++ u_int32_t, u_int32_t, u_int32_t, u_int32_t));
++
+ int pfkey_send_update2 __P((struct pfkey_send_sa_args *));
+ int pfkey_send_add2 __P((struct pfkey_send_sa_args *));
+ int pfkey_send_delete __P((int, u_int, u_int,
+@@ -155,6 +159,14 @@ int pfkey_send_migrate __P((int, struct sockaddr *, struct sockaddr *,
+ caddr_t, int, u_int32_t));
+ #endif
+
++/* XXX should be somewhere else !!!
++ */
++#ifdef SADB_X_NAT_T_NEW_MAPPING
++#define PFKEY_ADDR_X_PORT(ext) (ntohs(((struct sadb_x_nat_t_port *)ext)->sadb_x_nat_t_port_port))
++#define PFKEY_ADDR_X_NATTYPE(ext) ( ext != NULL && ((struct sadb_x_nat_t_type *)ext)->sadb_x_nat_t_type_type )
++#endif
++
++
+ int pfkey_open __P((void));
+ void pfkey_close __P((int));
+ int pfkey_set_buffer_size __P((int, int));
+diff --git a/src/libipsec/pfkey.c b/src/libipsec/pfkey.c
+index 0a944c2..b39ffca 100644
+--- a/src/libipsec/pfkey.c
++++ b/src/libipsec/pfkey.c
+@@ -380,10 +380,12 @@ pfkey_get_softrate(type)
+ * -1 : error occured, and set errno.
+ */
+ int
+-pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
++pfkey_send_getspi_nat(so, satype, mode, src, dst, natt_type, sport, dport, min, max, reqid, seq)
+ int so;
+ u_int satype, mode;
+ struct sockaddr *src, *dst;
++ u_int8_t natt_type;
++ u_int16_t sport, dport;
+ u_int32_t min, max, reqid, seq;
+ {
+ struct sadb_msg *newmsg;
+@@ -431,6 +433,14 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
+ len += sizeof(struct sadb_spirange);
+ }
+
++#ifdef SADB_X_EXT_NAT_T_TYPE
++ if(natt_type||sport||dport){
++ len += sizeof(struct sadb_x_nat_t_type);
++ len += sizeof(struct sadb_x_nat_t_port);
++ len += sizeof(struct sadb_x_nat_t_port);
++ }
++#endif
++
+ if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
+ __ipsec_set_strerror(strerror(errno));
+ return -1;
+@@ -466,6 +476,32 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
+ return -1;
+ }
+
++#ifdef SADB_X_EXT_NAT_T_TYPE
++ /* Add nat-t messages */
++ if (natt_type) {
++ p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE,
++ natt_type);
++ if (!p) {
++ free(newmsg);
++ return -1;
++ }
++
++ p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT,
++ sport);
++ if (!p) {
++ free(newmsg);
++ return -1;
++ }
++
++ p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT,
++ dport);
++ if (!p) {
++ free(newmsg);
++ return -1;
++ }
++ }
++#endif
++
+ /* proccessing spi range */
+ if (need_spirange) {
+ struct sadb_spirange spirange;
+@@ -501,6 +537,17 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
+ return len;
+ }
+
++int
++pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
++ int so;
++ u_int satype, mode;
++ struct sockaddr *src, *dst;
++ u_int32_t min, max, reqid, seq;
++{
++ return pfkey_send_getspi_nat(so, satype, mode, src, dst, 0, 0, 0,
++ min, max, reqid, seq);
++}
++
+ /*
+ * sending SADB_UPDATE message to the kernel.
+ * The length of key material is a_keylen + e_keylen.
+diff --git a/src/racoon/isakmp.c b/src/racoon/isakmp.c
+index c8670f6..fe51653 100644
+--- a/src/racoon/isakmp.c
++++ b/src/racoon/isakmp.c
+@@ -3324,6 +3324,17 @@ purge_remote(iph1)
+ src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
+ dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+
++#ifdef SADB_X_NAT_T_NEW_MAPPING
++ if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
++ /* NAT-T is enabled for this SADB entry; copy
++ * the ports from NAT-T extensions */
++ if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL)
++ set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
++ if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL)
++ set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
++ }
++#endif
++
+ if (sa->sadb_sa_state != SADB_SASTATE_LARVAL &&
+ sa->sadb_sa_state != SADB_SASTATE_MATURE &&
+ sa->sadb_sa_state != SADB_SASTATE_DYING) {
+diff --git a/src/racoon/isakmp_inf.c b/src/racoon/isakmp_inf.c
+index 1ada07f..a712825 100644
+--- a/src/racoon/isakmp_inf.c
++++ b/src/racoon/isakmp_inf.c
+@@ -1128,8 +1128,7 @@ purge_ipsec_spi(dst0, proto, spi, n)
+ size_t i;
+ caddr_t mhp[SADB_EXT_MAX + 1];
+ #ifdef ENABLE_NATT
+- struct sadb_x_nat_t_type *natt_type;
+- struct sadb_x_nat_t_port *natt_port;
++ int natt_port_forced;
+ #endif
+
+ plog(LLV_DEBUG2, LOCATION, NULL,
+@@ -1184,22 +1183,25 @@ purge_ipsec_spi(dst0, proto, spi, n)
+ continue;
+ }
+ #ifdef ENABLE_NATT
+- natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE];
+- if (natt_type && natt_type->sadb_x_nat_t_type_type) {
++ if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
+ /* NAT-T is enabled for this SADB entry; copy
+ * the ports from NAT-T extensions */
+- natt_port = (void *)mhp[SADB_X_EXT_NAT_T_SPORT];
+- if (extract_port(src) == 0 && natt_port != NULL)
+- set_port(src, ntohs(natt_port->sadb_x_nat_t_port_port));
+-
+- natt_port = (void *)mhp[SADB_X_EXT_NAT_T_DPORT];
+- if (extract_port(dst) == 0 && natt_port != NULL)
+- set_port(dst, ntohs(natt_port->sadb_x_nat_t_port_port));
+- }else{
+- /* Force default UDP ports, so CMPSADDR will match SAs with NO encapsulation
+- */
++ if (extract_port(src) == 0 &&
++ mhp[SADB_X_EXT_NAT_T_SPORT] != NULL) {
++ set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
++ }
++
++ if (extract_port(dst) == 0 &&
++ mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) {
++ set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
++ }
++ natt_port_forced = 0;
++ } else {
++ /* Force default UDP ports, so
++ * CMPSADDR will match SAs with NO encapsulation */
+ set_port(src, PORT_ISAKMP);
+ set_port(dst, PORT_ISAKMP);
++ natt_port_forced = 1;
+ }
+ #endif
+ plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
+@@ -1215,10 +1217,9 @@ purge_ipsec_spi(dst0, proto, spi, n)
+ }
+
+ #ifdef ENABLE_NATT
+- if (natt_type == NULL ||
+- ! natt_type->sadb_x_nat_t_type_type) {
+- /* Set back port to 0 if it was forced to default UDP port
+- */
++ if (natt_port_forced) {
++ /* Set back port to 0 if it was forced
++ * to default UDP port */
+ set_port(src, 0);
+ set_port(dst, 0);
+ }
+diff --git a/src/racoon/pfkey.c b/src/racoon/pfkey.c
+index 610cc09..c210c5e 100644
+--- a/src/racoon/pfkey.c
++++ b/src/racoon/pfkey.c
+@@ -769,6 +769,28 @@ keylen_ealg(enctype, encklen)
+ return res;
+ }
+
++void
++pk_fixup_sa_addresses(mhp)
++ caddr_t *mhp;
++{
++ struct sockaddr *src, *dst;
++ src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
++ dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
++#ifdef ENABLE_NATT
++ if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
++ /* NAT-T is enabled for this SADB entry; copy
++ * the ports from NAT-T extensions */
++ if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL)
++ set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
++ if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL)
++ set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
++ }
++#else
++ set_port(src, 0);
++ set_port(dst, 0);
++#endif
++}
++
+ int
+ pfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
+ e_type, e_keylen, a_type, a_keylen, flags)
+@@ -866,6 +888,8 @@ pk_sendgetspi(iph2)
+ struct saprop *pp;
+ struct saproto *pr;
+ u_int32_t minspi, maxspi;
++ u_int8_t natt_type = 0;
++ u_int16_t sport = 0, dport = 0;
+
+ if (iph2->side == INITIATOR)
+ pp = iph2->proposal;
+@@ -919,19 +943,27 @@ pk_sendgetspi(iph2)
+ }
+
+ #ifdef ENABLE_NATT
+- if (! pr->udp_encap) {
+- /* Remove port information, that SA doesn't use it */
+- set_port(iph2->src, 0);
+- set_port(iph2->dst, 0);
++ if (pr->udp_encap) {
++ natt_type = iph2->ph1->natt_options->encaps_type;
++ sport=extract_port(src);
++ dport=extract_port(dst);
+ }
+ #endif
++ /* Always remove port information, it will be sent in
++ * SADB_X_EXT_NAT_T_[S|D]PORT if needed */
++ set_port(src, 0);
++ set_port(dst, 0);
++
+ plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
+- if (pfkey_send_getspi(
++ if (pfkey_send_getspi_nat(
+ lcconf->sock_pfkey,
+ satype,
+ mode,
+ dst, /* src of SA */
+ src, /* dst of SA */
++ natt_type,
++ dport,
++ sport,
+ minspi, maxspi,
+ pr->reqid_in, iph2->seq) < 0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+@@ -1157,13 +1189,13 @@ pk_sendupdate(iph2)
+ #ifdef SADB_X_EXT_NAT_T_FRAG
+ sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
+ #endif
+- } else {
+- /* Remove port information, that SA doesn't use it */
+- set_port(sa_args.src, 0);
+- set_port(sa_args.dst, 0);
+ }
+-
+ #endif
++ /* Always remove port information, it will be sent in
++ * SADB_X_EXT_NAT_T_[S|D]PORT if needed */
++ set_port(sa_args.src, 0);
++ set_port(sa_args.dst, 0);
++
+ /* more info to fill in */
+ sa_args.spi = pr->spi;
+ sa_args.reqid = pr->reqid_in;
+@@ -1236,6 +1268,7 @@ pk_recvupdate(mhp)
+ return -1;
+ }
+ msg = (struct sadb_msg *)mhp[0];
++ pk_fixup_sa_addresses(mhp);
+ src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
+ dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+ sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
+@@ -1328,7 +1361,6 @@ pk_recvupdate(mhp)
+ /* Force the update of ph2's ports, as there is at least one
+ * situation where they'll mismatch with ph1's values
+ */
+-
+ #ifdef ENABLE_NATT
+ set_port(iph2->src, extract_port(iph2->ph1->local));
+ set_port(iph2->dst, extract_port(iph2->ph1->remote));
+@@ -1456,17 +1488,12 @@ pk_sendadd(iph2)
+ #ifdef SADB_X_EXT_NAT_T_FRAG
+ sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
+ #endif
+- } else {
+- /* Remove port information, that SA doesn't use it */
+- set_port(sa_args.src, 0);
+- set_port(sa_args.dst, 0);
+ }
+-
+-#else
+- /* Remove port information, it is not used without NAT-T */
++#endif
++ /* Always remove port information, it will be sent in
++ * SADB_X_EXT_NAT_T_[S|D]PORT if needed */
+ set_port(sa_args.src, 0);
+ set_port(sa_args.dst, 0);
+-#endif
+
+ /* more info to fill in */
+ sa_args.spi = pr->spi_p;
+@@ -1596,6 +1623,7 @@ pk_recvexpire(mhp)
+ }
+ msg = (struct sadb_msg *)mhp[0];
+ sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
++ pk_fixup_sa_addresses(mhp);
+ src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
+ dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+
+@@ -1721,6 +1749,7 @@ pk_recvacquire(mhp)
+ }
+ msg = (struct sadb_msg *)mhp[0];
+ xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
++ pk_fixup_sa_addresses(mhp);
+ sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
+ sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+
+@@ -1971,6 +2000,7 @@ pk_recvdelete(mhp)
+ }
+ msg = (struct sadb_msg *)mhp[0];
+ sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
++ pk_fixup_sa_addresses(mhp);
+ src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
+ dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+
+@@ -2709,7 +2739,6 @@ pk_recvspddump(mhp)
+ return -1;
+ }
+ msg = (struct sadb_msg *)mhp[0];
+-
+ saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
+ daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
+ xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
+diff --git a/src/racoon/pfkey.h b/src/racoon/pfkey.h
+index a3acd1c..f1b037d 100644
+--- a/src/racoon/pfkey.h
++++ b/src/racoon/pfkey.h
+@@ -52,6 +52,7 @@ extern struct pfkey_st *pfkey_getpst __P((caddr_t *, int, int));
+ extern int pk_checkalg __P((int, int, int));
+
+ struct ph2handle;
++extern void pk_fixup_sa_addresses __P((caddr_t *mhp));
+ extern int pk_sendgetspi __P((struct ph2handle *));
+ extern int pk_sendupdate __P((struct ph2handle *));
+ extern int pk_sendadd __P((struct ph2handle *));