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);

Reply via email to