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;

Reply via email to