Index: iked.conf.5 =================================================================== RCS file: /cvs/src/sbin/iked/iked.conf.5,v diff -u -p -r1.98 iked.conf.5 --- iked.conf.5 13 Jul 2024 12:58:51 -0000 1.98 +++ iked.conf.5 31 Oct 2024 23:08:54 -0000 @@ -348,6 +348,10 @@ and the default is .Ar tunnel . .Pp +.It Op Ar natt +.Ar natt +forces negotiation of NAT-Traversal after the initial handshake. +.Pp .It Op Ar encap .Ar encap specifies the encapsulation protocol to be used. Index: iked.h =================================================================== RCS file: /cvs/src/sbin/iked/iked.h,v diff -u -p -r1.232 iked.h --- iked.h 15 Sep 2024 11:08:50 -0000 1.232 +++ iked.h 31 Oct 2024 23:08:54 -0000 @@ -250,16 +250,17 @@ struct iked_policy { #define IKED_SKIP_COUNT 4 struct iked_policy *pol_skip[IKED_SKIP_COUNT]; - uint8_t pol_flags; -#define IKED_POLICY_PASSIVE 0x00 -#define IKED_POLICY_DEFAULT 0x01 -#define IKED_POLICY_ACTIVE 0x02 -#define IKED_POLICY_REFCNT 0x04 -#define IKED_POLICY_QUICK 0x08 -#define IKED_POLICY_SKIP 0x10 -#define IKED_POLICY_IPCOMP 0x20 -#define IKED_POLICY_TRANSPORT 0x40 -#define IKED_POLICY_ROUTING 0x80 + unsigned int pol_flags; +#define IKED_POLICY_PASSIVE 0x000 +#define IKED_POLICY_DEFAULT 0x001 +#define IKED_POLICY_ACTIVE 0x002 +#define IKED_POLICY_REFCNT 0x004 +#define IKED_POLICY_QUICK 0x008 +#define IKED_POLICY_SKIP 0x010 +#define IKED_POLICY_IPCOMP 0x020 +#define IKED_POLICY_TRANSPORT 0x040 +#define IKED_POLICY_ROUTING 0x080 +#define IKED_POLICY_NATT_FORCE 0x100 int pol_refcnt; Index: ikev2.c =================================================================== RCS file: /cvs/src/sbin/iked/ikev2.c,v diff -u -p -r1.388 ikev2.c --- ikev2.c 15 Sep 2024 11:08:50 -0000 1.388 +++ ikev2.c 31 Oct 2024 23:08:54 -0000 @@ -70,7 +70,6 @@ struct iked_sa * ikev2_getimsgdata(struct iked *, struct imsg *, struct iked_sahdr *, uint8_t *, uint8_t **, size_t *); -void ikev2_recv(struct iked *, struct iked_message *); int ikev2_ike_auth_compatible(struct iked_sa *, uint8_t, uint8_t); int ikev2_ike_auth_recv(struct iked *, struct iked_sa *, struct iked_message *); @@ -2334,6 +2333,7 @@ ikev2_nat_detection(struct iked *env, st uint64_t rspi, ispi; struct ibuf *buf; uint32_t rnd; + int natt_force = 0; if (ptr == NULL) return (mdlen); @@ -2401,7 +2401,14 @@ ikev2_nat_detection(struct iked *env, st goto done; } - if (env->sc_nattmode == NATT_FORCE) { + if (env->sc_nattmode == NATT_FORCE) + natt_force = 1; + else if (msg->msg_policy != NULL) { + if (msg->msg_policy->pol_flags & IKED_POLICY_NATT_FORCE) + natt_force = 1; + } + + if (natt_force) { /* Enforce NAT-T/UDP-encapsulation by distorting the digest */ rnd = arc4random(); EVP_DigestUpdate(ctx, &rnd, sizeof(rnd)); @@ -3395,6 +3402,7 @@ ikev2_resp_ike_sa_init(struct iked *env, resp.msg_fd = msg->msg_fd; resp.msg_natt = msg->msg_natt; resp.msg_msgid = 0; + resp.msg_policy = sa->sa_policy; /* IKE header */ if ((hdr = ikev2_add_header(buf, sa, resp.msg_msgid, @@ -3702,6 +3710,7 @@ ikev2_send_init_error(struct iked *env, resp.msg_fd = msg->msg_fd; resp.msg_natt = msg->msg_natt; resp.msg_msgid = 0; + resp.msg_policy = sa->sa_policy; /* IKE header */ if ((hdr = ikev2_add_header(buf, sa, resp.msg_msgid, Index: parse.y =================================================================== RCS file: /cvs/src/sbin/iked/parse.y,v diff -u -p -r1.147 parse.y --- parse.y 13 Jul 2024 12:22:46 -0000 1.147 +++ parse.y 31 Oct 2024 23:08:54 -0000 @@ -383,7 +383,7 @@ int create_ike(char *, int, struct ip int, struct ipsec_hosts *, struct ipsec_hosts *, struct ipsec_mode *, struct ipsec_mode *, uint8_t, - uint8_t, char *, char *, + unsigned int, char *, char *, uint32_t, struct iked_lifetime *, struct iked_auth *, struct ipsec_filters *, struct ipsec_addr_wrap *, char *); @@ -411,7 +411,7 @@ struct ipsec_addr_wrap *iftab; typedef struct { union { int64_t number; - uint8_t ikemode; + unsigned int ikemode; uint8_t dir; uint8_t satype; uint8_t accounting; @@ -459,7 +459,7 @@ typedef struct { %token CERTPARTIALCHAIN %token REQUEST IFACE %token RADIUS ACCOUNTING SERVER SECRET MAX_TRIES MAX_FAILOVERS -%token CLIENT DAE LISTEN ON +%token CLIENT DAE LISTEN ON NATT %token STRING %token NUMBER %type string @@ -475,7 +475,8 @@ typedef struct { %type id %type transforms %type filters -%type ikeflags ikematch ikemode ipcomp tmode +%type ikeflags +%type ikematch ikemode ipcomp tmode natt_force %type ikeauth %type keyspec %type ike_sas child_sas @@ -1022,7 +1023,9 @@ child_sa : CHILDSA { } ; -ikeflags : ikematch ikemode ipcomp tmode { $$ = $1 | $2 | $3 | $4; } +ikeflags : ikematch ikemode ipcomp tmode natt_force { + $$ = $1 | $2 | $3 | $4 | $5; + } ; ikematch : /* empty */ { $$ = 0; } @@ -1045,6 +1048,10 @@ tmode : /* empty */ { $$ = 0; } | TRANSPORT { $$ = IKED_POLICY_TRANSPORT; } ; +natt_force : /* empty */ { $$ = 0; } + | NATT { $$ = IKED_POLICY_NATT_FORCE; } + ; + ikeauth : /* empty */ { $$.auth_method = IKEV2_AUTH_SIG_ANY; /* default */ $$.auth_eap = 0; @@ -1601,6 +1608,7 @@ lookup(char *s) { "maxage", MAXAGE }, { "mobike", MOBIKE }, { "name", NAME }, + { "natt", NATT }, { "noenforcesingleikesa", NOENFORCESINGLEIKESA }, { "noesn", NOESN }, { "nofragmentation", NOFRAGMENTATION }, @@ -2707,7 +2715,7 @@ create_ike(char *name, int af, struct ip int rdomain, struct ipsec_hosts *hosts, struct ipsec_hosts *peers, struct ipsec_mode *ike_sa, struct ipsec_mode *ipsec_sa, uint8_t saproto, - uint8_t flags, char *srcid, char *dstid, + unsigned int flags, char *srcid, char *dstid, uint32_t ikelifetime, struct iked_lifetime *lt, struct iked_auth *authtype, struct ipsec_filters *filter, struct ipsec_addr_wrap *ikecfg, char *iface) Index: print.c =================================================================== RCS file: /cvs/src/sbin/iked/print.c,v diff -u -p -r1.4 print.c --- print.c 13 Jun 2023 12:34:12 -0000 1.4 +++ print.c 31 Oct 2024 23:08:54 -0000 @@ -88,6 +88,9 @@ print_policy(struct iked_policy *pol) else print_verbose(" tunnel"); + if (pol->pol_flags & IKED_POLICY_NATT_FORCE) + print_verbose(" natt"); + print_verbose(" %s", print_xf(pol->pol_saproto, 0, saxfs)); if (pol->pol_nipproto > 0) {