This diff makes pipex "idle-timeout" work with pppx(4). ok?
Index: sys/net/if_pppx.c =================================================================== RCS file: /disk/cvs/openbsd/src/sys/net/if_pppx.c,v retrieving revision 1.98 diff -u -p -r1.98 if_pppx.c --- sys/net/if_pppx.c 28 Jul 2020 09:53:36 -0000 1.98 +++ sys/net/if_pppx.c 9 Aug 2020 08:05:16 -0000 @@ -185,6 +185,7 @@ int pppx_config_session(struct pppx_dev struct pipex_session_config_req *); int pppx_get_stat(struct pppx_dev *, struct pipex_session_stat_req *); +int pppx_is_owner(void *, struct pipex_session *); int pppx_get_closed(struct pppx_dev *, struct pipex_session_list_req *); int pppx_set_session_descr(struct pppx_dev *, @@ -645,14 +646,6 @@ pppx_add_session(struct pppx_dev *pxd, s struct in_ifaddr *ia; struct sockaddr_in ifaddr; - /* - * XXX: As long as `session' is allocated as part of a `pxi' - * it isn't possible to free it separately. So disallow - * the timeout feature until this is fixed. - */ - if (req->pr_timeout_sec != 0) - return (EINVAL); - error = pipex_init_session(&session, req); if (error) return (error); @@ -812,12 +805,22 @@ pppx_get_stat(struct pppx_dev *pxd, stru } int -pppx_get_closed(struct pppx_dev *pxd, struct pipex_session_list_req *req) +pppx_is_owner(void *ctx, struct pipex_session *session) { - /* XXX: Only opened sessions exist for pppx(4) */ - memset(req, 0, sizeof(*req)); + struct pppx_dev *pxd = ctx; + struct pppx_if *pxi; - return 0; + pxi = pppx_if_find(pxd, session->session_id, session->protocol); + if (pxi != NULL) + return (1); + + return (0); +} + +int +pppx_get_closed(struct pppx_dev *pxd, struct pipex_session_list_req *req) +{ + return (pipex_get_closed(req, pppx_is_owner, pxd)); } int @@ -1059,6 +1062,7 @@ static int pppac_ioctl(struct ifnet *, u static int pppac_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); static void pppac_start(struct ifnet *); +static int pppac_is_owner(void *, struct pipex_session *); static inline struct pppac_softc * pppac_lookup(dev_t dev) @@ -1251,6 +1255,16 @@ pppacwrite(dev_t dev, struct uio *uio, i } int +pppac_is_owner(void *ctx, struct pipex_session *session) +{ + struct pppac_softc *sc = ctx; + + if (session->ifindex == sc->sc_if.if_index) + return (1); + return (0); +} + +int pppacioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) { struct pppac_softc *sc = pppac_lookup(dev); @@ -1264,6 +1278,13 @@ pppacioctl(dev_t dev, u_long cmd, caddr_ break; case FIONREAD: *(int *)data = mq_hdatalen(&sc->sc_mq); + break; + + case PIPEXGCLOSED: + NET_LOCK(); + error = pipex_get_closed((struct pipex_session_list_req *)data, + pppac_is_owner, sc); + NET_UNLOCK(); break; default: Index: sys/net/pipex.c =================================================================== RCS file: /disk/cvs/openbsd/src/sys/net/pipex.c,v retrieving revision 1.123 diff -u -p -r1.123 pipex.c --- sys/net/pipex.c 4 Aug 2020 09:32:05 -0000 1.123 +++ sys/net/pipex.c 9 Aug 2020 08:05:16 -0000 @@ -240,11 +240,6 @@ pipex_ioctl(struct pipex_iface_context * pipex_iface); break; - case PIPEXGCLOSED: - ret = pipex_get_closed((struct pipex_session_list_req *)data, - pipex_iface); - break; - default: ret = ENOTTY; break; @@ -430,6 +425,7 @@ pipex_link_session(struct pipex_session struct pipex_iface_context *iface) { struct pipex_hash_head *chain; + struct ifnet *ifp; NET_ASSERT_LOCKED(); @@ -442,6 +438,11 @@ pipex_link_session(struct pipex_session session->pipex_iface = iface; session->ifindex = iface->ifindex; + ifp = if_get(iface->ifindex); + if (ifp != NULL && ifp->if_flags & IFF_POINTOPOINT) + session->is_p2p = 1; + if_put(ifp); + LIST_INSERT_HEAD(&pipex_session_list, session, session_list); chain = PIPEX_ID_HASHTABLE(session->session_id); LIST_INSERT_HEAD(chain, session, id_chain); @@ -469,6 +470,8 @@ pipex_unlink_session(struct pipex_sessio session->ifindex = 0; NET_ASSERT_LOCKED(); + if (session->state == PIPEX_STATE_CLOSED) + return; LIST_REMOVE(session, id_chain); #if defined(PIPEX_PPTP) || defined(PIPEX_L2TP) switch (session->protocol) { @@ -622,7 +625,7 @@ pipex_get_stat(struct pipex_session_stat Static int pipex_get_closed(struct pipex_session_list_req *req, - struct pipex_iface_context *iface) + int (*isowner)(void *, struct pipex_session *), void *ctx) { struct pipex_session *session, *session_tmp; @@ -630,7 +633,7 @@ pipex_get_closed(struct pipex_session_li bzero(req, sizeof(*req)); LIST_FOREACH_SAFE(session, &pipex_close_wait_list, state_list, session_tmp) { - if (session->pipex_iface != iface) + if (!isowner(ctx, session)) continue; req->plr_ppp_id[req->plr_ppp_id_count++] = session->ppp_id; LIST_REMOVE(session, state_list); @@ -766,13 +769,13 @@ pipex_timer(void *ignored_arg) if (session->stat.idle_time < PIPEX_CLOSE_TIMEOUT) continue; - if (session->state == PIPEX_STATE_CLOSE_WAIT) - LIST_REMOVE(session, state_list); - session->state = PIPEX_STATE_CLOSED; /* FALLTHROUGH */ case PIPEX_STATE_CLOSED: - pipex_destroy_session(session); + if (session->is_p2p) + pipex_unlink_session(session); + else + pipex_destroy_session(session); break; default: Index: sys/net/pipex_local.h =================================================================== RCS file: /disk/cvs/openbsd/src/sys/net/pipex_local.h,v retrieving revision 1.39 diff -u -p -r1.39 pipex_local.h --- sys/net/pipex_local.h 4 Aug 2020 09:32:05 -0000 1.39 +++ sys/net/pipex_local.h 9 Aug 2020 08:05:16 -0000 @@ -169,7 +169,8 @@ struct pipex_session { uint16_t ip_forward:1, /* [N] {en|dis}ableIP forwarding */ ip6_forward:1, /* [I] {en|dis}able IPv6 forwarding */ is_multicast:1, /* [I] virtual entry for multicast */ - reserved:13; + is_p2p:1, /* [I] interface is point2point(pppx) */ + reserved:12; uint16_t protocol; /* [I] tunnel protocol (PK) */ uint16_t session_id; /* [I] session-id (PK) */ uint16_t peer_session_id; /* [I] peer's session-id */ @@ -391,7 +392,7 @@ int pipex_config_sessi int pipex_get_stat (struct pipex_session_stat_req *, struct pipex_iface_context *); int pipex_get_closed (struct pipex_session_list_req *, - struct pipex_iface_context *); + int (*)(void *, struct pipex_session *), void *); int pipex_destroy_session (struct pipex_session *); struct pipex_session *pipex_lookup_by_ip_address (struct in_addr); struct pipex_session *pipex_lookup_by_session_id (int, int);