On Mon, Aug 07, 2023 at 05:36:27PM +0200, Tobias Heider wrote: > On Mon, Aug 07, 2023 at 02:22:23PM +1000, David Gwynne wrote: > > tobhe@ wrote the iked bits, so he'll commit them when he's ready. > > > > your config looks pretty much the same as mine except you specify a lot > > more stuff around lifetimes and crypto than i do. maybe try without "tunnel > > esp"? > > > > dlg > > The config in the previous mail looks ok. You will need the "from any to any" > for now but I'm planning to adjust the default. > > Below is the latest state of my iked diff. The previous version had a small > bug in pfkey preventing SAs from getting deleted properly.
this is working well in my testing. ok by me. > > diff cfdc039572fed1d8c9081b6d9557ce9b85e89697 > a2b839af1fa9d47730731e392e3c8dd0e9f7dd1e > commit - cfdc039572fed1d8c9081b6d9557ce9b85e89697 > commit + a2b839af1fa9d47730731e392e3c8dd0e9f7dd1e > blob - 2c7fbe14af3dad6fe38af607e9f870324e2be55c > blob + 6449f3cc2d423daee6294b71ca098247a296886a > --- sbin/iked/iked.h > +++ sbin/iked/iked.h > @@ -260,6 +260,7 @@ struct iked_policy { > #define IKED_POLICY_SKIP 0x10 > #define IKED_POLICY_IPCOMP 0x20 > #define IKED_POLICY_TRANSPORT 0x40 > +#define IKED_POLICY_ROUTING 0x80 > > int pol_refcnt; > > blob - bf6bf0fb0d43ef17ebe71368dfbc4bf28628a1f8 > blob + 25e5098dd29b03426aa2d9a03c324f13dc8cdecf > --- sbin/iked/ikev2.c > +++ sbin/iked/ikev2.c > @@ -6532,63 +6532,65 @@ ikev2_childsa_enable(struct iked *env, struct iked_sa > peer_changed = (memcmp(&sa->sa_peer_loaded, &sa->sa_peer, > sizeof(sa->sa_peer_loaded)) != 0); > > - TAILQ_FOREACH(flow, &sa->sa_flows, flow_entry) { > - /* re-load the flow if the peer for the flow has changed */ > - reload = 0; > - if (flow->flow_loaded) { > - if (!peer_changed) { > - log_debug("%s: flow already loaded %p", > - __func__, flow); > - continue; > + if (!(sa->sa_policy->pol_flags & IKED_POLICY_ROUTING)) { > + TAILQ_FOREACH(flow, &sa->sa_flows, flow_entry) { > + /* re-load the flow if the peer for the flow has > changed */ > + reload = 0; > + if (flow->flow_loaded) { > + if (!peer_changed) { > + log_debug("%s: flow already loaded %p", > + __func__, flow); > + continue; > + } > + RB_REMOVE(iked_flows, &env->sc_activeflows, > flow); > + (void)pfkey_flow_delete(env, flow); > + flow->flow_loaded = 0; /* we did RB_REMOVE */ > + reload = 1; > } > - RB_REMOVE(iked_flows, &env->sc_activeflows, flow); > - (void)pfkey_flow_delete(env, flow); > - flow->flow_loaded = 0; /* we did RB_REMOVE */ > - reload = 1; > - } > > - if (pfkey_flow_add(env, flow) != 0) { > - log_debug("%s: failed to load flow", __func__); > - goto done; > - } > + if (pfkey_flow_add(env, flow) != 0) { > + log_debug("%s: failed to load flow", __func__); > + goto done; > + } > > - if ((oflow = RB_FIND(iked_flows, &env->sc_activeflows, flow)) > - != NULL) { > - log_debug("%s: replaced old flow %p with %p", > - __func__, oflow, flow); > - oflow->flow_loaded = 0; > - RB_REMOVE(iked_flows, &env->sc_activeflows, oflow); > - } > + if ((oflow = RB_FIND(iked_flows, &env->sc_activeflows, > flow)) > + != NULL) { > + log_debug("%s: replaced old flow %p with %p", > + __func__, oflow, flow); > + oflow->flow_loaded = 0; > + RB_REMOVE(iked_flows, &env->sc_activeflows, > oflow); > + } > > - RB_INSERT(iked_flows, &env->sc_activeflows, flow); > + RB_INSERT(iked_flows, &env->sc_activeflows, flow); > > - log_debug("%s: %sloaded flow %p", __func__, > - reload ? "re" : "", flow); > + log_debug("%s: %sloaded flow %p", __func__, > + reload ? "re" : "", flow); > > - /* append flow to log buffer */ > - if (flow->flow_dir == IPSP_DIRECTION_OUT && > - flow->flow_prenat.addr_af != 0) > - snprintf(prenat_mask, sizeof(prenat_mask), "%d", > - flow->flow_prenat.addr_mask); > - else > - prenat_mask[0] = '\0'; > - if (flow->flow_dir == IPSP_DIRECTION_OUT) { > - if (ftello(flowf) > 0) > - fputs(", ", flowf); > - fprintf(flowf, "%s-%s/%d%s%s%s%s%s=%s/%d(%u)%s", > - print_map(flow->flow_saproto, ikev2_saproto_map), > - print_addr(&flow->flow_src.addr), > - flow->flow_src.addr_mask, > - flow->flow_prenat.addr_af != 0 ? "[": "", > - flow->flow_prenat.addr_af != 0 ? > - print_addr(&flow->flow_prenat.addr) : "", > - flow->flow_prenat.addr_af != 0 ? "/" : "", > - flow->flow_prenat.addr_af != 0 ? prenat_mask : "", > - flow->flow_prenat.addr_af != 0 ? "]": "", > - print_addr(&flow->flow_dst.addr), > - flow->flow_dst.addr_mask, > - flow->flow_ipproto, > - reload ? "-R" : ""); > + /* append flow to log buffer */ > + if (flow->flow_dir == IPSP_DIRECTION_OUT && > + flow->flow_prenat.addr_af != 0) > + snprintf(prenat_mask, sizeof(prenat_mask), "%d", > + flow->flow_prenat.addr_mask); > + else > + prenat_mask[0] = '\0'; > + if (flow->flow_dir == IPSP_DIRECTION_OUT) { > + if (ftello(flowf) > 0) > + fputs(", ", flowf); > + fprintf(flowf, "%s-%s/%d%s%s%s%s%s=%s/%d(%u)%s", > + print_map(flow->flow_saproto, > ikev2_saproto_map), > + print_addr(&flow->flow_src.addr), > + flow->flow_src.addr_mask, > + flow->flow_prenat.addr_af != 0 ? "[": "", > + flow->flow_prenat.addr_af != 0 ? > + print_addr(&flow->flow_prenat.addr) : "", > + flow->flow_prenat.addr_af != 0 ? "/" : "", > + flow->flow_prenat.addr_af != 0 ? > prenat_mask : "", > + flow->flow_prenat.addr_af != 0 ? "]": "", > + print_addr(&flow->flow_dst.addr), > + flow->flow_dst.addr_mask, > + flow->flow_ipproto, > + reload ? "-R" : ""); > + } > } > } > > blob - 075981db3201df3c982a72832f22c41bb64ae22a > blob + 48992694fbc40f75f046e39c423106a3348f4d38 > --- sbin/iked/parse.y > +++ sbin/iked/parse.y > @@ -2519,6 +2519,10 @@ create_ike(char *name, int af, struct ipsec_addr_wrap > } > > if (iface != NULL) { > + /* sec(4) */ > + if (strncmp("sec", iface, strlen("sec")) == 0) > + pol.pol_flags |= IKED_POLICY_ROUTING; > + > pol.pol_iface = if_nametoindex(iface); > if (pol.pol_iface == 0) { > yyerror("invalid iface"); > blob - eaebe53a9904aec74ec5903e56a134a255e05c7d > blob + 4b9e4a4e12eaf87338b20f0ff114e84087b4461d > --- sbin/iked/pfkey.c > +++ sbin/iked/pfkey.c > @@ -25,6 +25,7 @@ > > #include <netinet/in.h> > #include <netinet/ip_ipsp.h> > +#include <net/if.h> > #include <net/pfkeyv2.h> > > #include <err.h> > @@ -40,7 +41,7 @@ > #include "ikev2.h" > > #define ROUNDUP(x) (((x) + (PFKEYV2_CHUNK - 1)) & ~(PFKEYV2_CHUNK - 1)) > -#define IOV_CNT 27 > +#define IOV_CNT 28 > > #define PFKEYV2_CHUNK sizeof(uint64_t) > #define PFKEY_REPLY_TIMEOUT 1000 > @@ -453,6 +454,7 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t act > int > pfkey_sa(struct iked *env, uint8_t satype, uint8_t action, struct > iked_childsa *sa) > { > + char iface[IF_NAMESIZE]; > struct sadb_msg smsg; > struct sadb_sa sadb; > struct sadb_address sa_src, sa_dst, sa_pxy; > @@ -460,6 +462,7 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t act > struct sadb_lifetime sa_ltime_hard, sa_ltime_soft; > struct sadb_x_udpencap udpencap; > struct sadb_x_tag sa_tag; > + struct sadb_x_iface sa_iface; > char *tag = NULL; > struct sadb_x_tap sa_tap; > struct sadb_x_rdomain sa_rdomain; > @@ -469,6 +472,8 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t act > struct iked_policy *pol; > struct iked_addr *dst; > struct iovec iov[IOV_CNT]; > + const char *errstr = NULL; > + uint32_t ifminor; > uint32_t jitter; > int iov_cnt; > int ret, dotap = 0; > @@ -549,6 +554,7 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t act > bzero(&udpencap, sizeof udpencap); > bzero(&sa_ltime_hard, sizeof(sa_ltime_hard)); > bzero(&sa_ltime_soft, sizeof(sa_ltime_soft)); > + bzero(&sa_iface, sizeof(sa_iface)); > > if (pol->pol_rdomain >= 0) { > bzero(&sa_rdomain, sizeof(sa_rdomain)); > @@ -688,6 +694,24 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t act > sa_tap.sadb_x_tap_unit = pol->pol_tap; > } > > + if (pol->pol_flags & IKED_POLICY_ROUTING) { > + sa_iface.sadb_x_iface_exttype = SADB_X_EXT_IFACE; > + sa_iface.sadb_x_iface_len = sizeof(sa_iface) / 8; > + if (if_indextoname(pol->pol_iface, iface) == NULL) { > + log_warnx("%s: unsupported interface %s", > + __func__, iface); > + return (-1); > + } > + ifminor = strtonum(iface + strlen("sec"), 0, UINT_MAX, &errstr); > + if (errstr != NULL) { > + log_warnx("%s: unsupported interface %s", > + __func__, iface); > + return (-1); > + } > + sa_iface.sadb_x_iface_unit = ifminor; > + sa_iface.sadb_x_iface_direction = sa->csa_dir; > + } > + > send: > > #define PAD(len) \ > @@ -816,6 +840,13 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t act > PAD(strlen(tag) + 1); > } > > + if (sa_iface.sadb_x_iface_len) { > + iov[iov_cnt].iov_base = &sa_iface; > + iov[iov_cnt].iov_len = sa_iface.sadb_x_iface_len * 8; > + smsg.sadb_msg_len += sa_iface.sadb_x_iface_len; > + iov_cnt++; > + } > + > if (dotap != 0) { > /* enc(4) device tap unit */ > iov[iov_cnt].iov_base = &sa_tap;