On Mon, 24 Aug 2020 20:07:48 +0300
Vitaliy Makkoveev <m...@openbsd.org> wrote:
> I pointed some comments inline.

Thanks,

>> +    case PIPEXASESSION:
>> +        {
>> +            struct pipex_session_req *req =
>> +                (struct pipex_session_req *)data;
>> +            if ((error = pipex_init_session(&session, req)) != 0)
>> +                    break;
>> +            error = pipex_link_session(session, &sc->sc_if, sc);
>> +            break;
>> +        }
> 
> If pipex_link_session() fails `session' will be leaked.

Yes, it's a good catch.

>> +    case PIPEXDSESSION:
>> +        {
>> +            struct pipex_session_close_req *req =
>> +                (struct pipex_session_close_req *)data;
>> +            session = pipex_lookup_by_session_id(req->pcr_protocol,
>> +                req->pcr_session_id);
>> +            if (session == NULL || session->ifindex != sc->sc_if.if_index) {
> 
> Can you compare with `session->ownersc' instead of `ifindex' like other
> code does? For consistency with other code.

Yes, it's better.

> What about to introduce pppac_{add,del}_session() and move related code
> into them?

Also I agreed.

> Also I see no such reason to kill pipex_{add,destroy}_session() because
> they play with `pipex_rd_head{4,6}' and you don't need newly introduced
> `session->is_pppx' which you use only once for that reason. 

pipex_{add,destroy}_session() should be killed since they are only for pppac.  
I think such functions should have "pppac_" prefix and placed in if_pppx.c.  
Also I'd like to move pipex_rd_head{4,6} things to pppac_{add,del}_session with 
a next step.  Yes, we might be able to kill is_pppx.  But I'd like to discuss 
that as a next step as well.


I'd like to commit this for this moment, and continue further discussion.

ok?

Index: sys/net/if_pppx.c
===================================================================
RCS file: /cvs/src/sys/net/if_pppx.c,v
retrieving revision 1.101
diff -u -p -r1.101 if_pppx.c
--- sys/net/if_pppx.c   14 Aug 2020 11:05:38 -0000      1.101
+++ sys/net/if_pppx.c   26 Aug 2020 06:25:34 -0000
@@ -163,7 +163,6 @@ struct pppx_if {
        struct ifnet            pxi_if;
        struct pppx_dev         *pxi_dev;               /* [I] */
        struct pipex_session    *pxi_session;           /* [I] */
-       struct pipex_iface_context      pxi_ifcontext;  /* [N] */
 };
 
 static inline int
@@ -181,12 +180,6 @@ int                pppx_add_session(struct pppx_dev *,
                    struct pipex_session_req *);
 int            pppx_del_session(struct pppx_dev *,
                    struct pipex_session_close_req *);
-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_get_closed(struct pppx_dev *,
-                   struct pipex_session_list_req *);
 int            pppx_set_session_descr(struct pppx_dev *,
                    struct pipex_session_descr_req *);
 
@@ -424,17 +417,6 @@ pppxioctl(dev_t dev, u_long cmd, caddr_t
 
        NET_LOCK();
        switch (cmd) {
-       case PIPEXSMODE:
-               /*
-                * npppd always enables on open, and only disables before
-                * closing. we cheat and let open and close do that, so lie
-                * to npppd.
-                */
-               break;
-       case PIPEXGMODE:
-               *(int *)addr = 1;
-               break;
-
        case PIPEXASESSION:
                error = pppx_add_session(pxd,
                    (struct pipex_session_req *)addr);
@@ -445,21 +427,6 @@ pppxioctl(dev_t dev, u_long cmd, caddr_t
                    (struct pipex_session_close_req *)addr);
                break;
 
-       case PIPEXCSESSION:
-               error = pppx_config_session(pxd,
-                   (struct pipex_session_config_req *)addr);
-               break;
-
-       case PIPEXGSTAT:
-               error = pppx_get_stat(pxd,
-                   (struct pipex_session_stat_req *)addr);
-               break;
-
-       case PIPEXGCLOSED:
-               error = pppx_get_closed(pxd,
-                   (struct pipex_session_list_req *)addr);
-               break;
-
        case PIPEXSIFDESCR:
                error = pppx_set_session_descr(pxd,
                    (struct pipex_session_descr_req *)addr);
@@ -472,7 +439,7 @@ pppxioctl(dev_t dev, u_long cmd, caddr_t
                break;
 
        default:
-               error = ENOTTY;
+               error = pipex_ioctl(pxd, cmd, addr);
                break;
        }
        NET_UNLOCK();
@@ -741,11 +708,7 @@ pppx_add_session(struct pppx_dev *pxd, s
                if_addrhooks_run(ifp);
        }
 
-       /* fake a pipex interface context */
-       pxi->pxi_ifcontext.ifindex = ifp->if_index;
-       pxi->pxi_ifcontext.pipexmode = PIPEX_ENABLED;
-
-       error = pipex_link_session(session, &pxi->pxi_ifcontext);
+       error = pipex_link_session(session, ifp, pxd);
        if (error)
                goto detach;
 
@@ -786,40 +749,6 @@ pppx_del_session(struct pppx_dev *pxd, s
 }
 
 int
-pppx_config_session(struct pppx_dev *pxd,
-    struct pipex_session_config_req *req)
-{
-       struct pppx_if *pxi;
-
-       pxi = pppx_if_find(pxd, req->pcr_session_id, req->pcr_protocol);
-       if (pxi == NULL)
-               return (EINVAL);
-
-       return pipex_config_session(req, &pxi->pxi_ifcontext);
-}
-
-int
-pppx_get_stat(struct pppx_dev *pxd, struct pipex_session_stat_req *req)
-{
-       struct pppx_if *pxi;
-
-       pxi = pppx_if_find(pxd, req->psr_session_id, req->psr_protocol);
-       if (pxi == NULL)
-               return (EINVAL);
-
-       return pipex_get_stat(req, &pxi->pxi_ifcontext);
-}
-
-int
-pppx_get_closed(struct pppx_dev *pxd, struct pipex_session_list_req *req)
-{
-       /* XXX: Only opened sessions exist for pppx(4) */
-       memset(req, 0, sizeof(*req));
-
-       return 0;
-}
-
-int
 pppx_set_session_descr(struct pppx_dev *pxd,
     struct pipex_session_descr_req *req)
 {
@@ -1014,8 +943,8 @@ struct pppac_softc {
        struct mutex    sc_wsel_mtx;
        struct selinfo  sc_wsel;
 
-       struct pipex_iface_context
-                       sc_pipex_iface;
+       struct pipex_session
+                       *sc_multicast_session;
 
        struct mbuf_queue
                        sc_mq;
@@ -1047,6 +976,10 @@ static struct pppac_list pppac_devs = LI
 
 static int     pppac_ioctl(struct ifnet *, u_long, caddr_t);
 
+static int     pppac_add_session(struct pppac_softc *,
+                   struct pipex_session_req *);
+static int     pppac_del_session(struct pppac_softc *,
+                   struct pipex_session_close_req *);
 static int     pppac_output(struct ifnet *, struct mbuf *, struct sockaddr *,
                    struct rtentry *);
 static void    pppac_qstart(struct ifqueue *);
@@ -1075,6 +1008,7 @@ pppacopen(dev_t dev, int flags, int mode
 {
        struct pppac_softc *sc;
        struct ifnet *ifp;
+       struct pipex_session *session;
 
        sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
        if (pppac_lookup(dev) != NULL) {
@@ -1082,6 +1016,12 @@ pppacopen(dev_t dev, int flags, int mode
                return (EBUSY);
        }
 
+       /* virtual pipex_session entry for multicast */
+       session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
+       session->is_multicast = 1;
+       session->ownersc = sc;
+       sc->sc_multicast_session = session;
+
        sc->sc_dev = dev;
 
        mtx_init(&sc->sc_rsel_mtx, IPL_SOFTNET);
@@ -1112,8 +1052,6 @@ pppacopen(dev_t dev, int flags, int mode
        bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(uint32_t));
 #endif
 
-       pipex_iface_init(&sc->sc_pipex_iface, ifp->if_index);
-
        return (0);
 }
 
@@ -1245,6 +1183,7 @@ pppacioctl(dev_t dev, u_long cmd, caddr_
        struct pppac_softc *sc = pppac_lookup(dev);
        int error = 0;
 
+       NET_LOCK();
        switch (cmd) {
        case TUNSIFMODE: /* make npppd happy */
                break;
@@ -1255,10 +1194,18 @@ pppacioctl(dev_t dev, u_long cmd, caddr_
                *(int *)data = mq_hdatalen(&sc->sc_mq);
                break;
 
+       case PIPEXASESSION:
+               error = pppac_add_session(sc, (struct pipex_session_req *)data);
+               break;
+       case PIPEXDSESSION:
+               error = pppac_del_session(sc,
+                   (struct pipex_session_close_req *)data);
+               break;
        default:
-               error = pipex_ioctl(&sc->sc_pipex_iface, cmd, data);
+               error = pipex_ioctl(sc, cmd, data);
                break;
        }
+       NET_UNLOCK();
 
        return (error);
 }
@@ -1373,7 +1320,10 @@ pppacclose(dev_t dev, int flags, int mod
 
        if_detach(ifp);
 
-       pipex_iface_fini(&sc->sc_pipex_iface);
+       pool_put(&pipex_session_pool, sc->sc_multicast_session);
+       NET_LOCK();
+       pipex_destroy_all_sessions(sc);
+       NET_UNLOCK();
 
        LIST_REMOVE(sc, sc_entry);
        free(sc, M_DEVBUF, sizeof(*sc));
@@ -1417,6 +1367,36 @@ pppac_ioctl(struct ifnet *ifp, u_long cm
 }
 
 static int
+pppac_add_session(struct pppac_softc *sc, struct pipex_session_req *req)
+{
+       int error;
+       struct pipex_session *session;
+
+       if ((error = pipex_init_session(&session, req)) != 0)
+               return (error);
+       error = pipex_link_session(session, &sc->sc_if, sc);
+       if (error != 0)
+               pipex_rele_session(session);
+
+       return (error);
+}
+
+static int
+pppac_del_session(struct pppac_softc *sc, struct pipex_session_close_req *req)
+{
+       struct pipex_session *session;
+
+       session = pipex_lookup_by_session_id(req->pcr_protocol,
+           req->pcr_session_id);
+       if (session == NULL || session->ownersc != sc)
+               return (EINVAL);
+       pipex_unlink_session(session);
+       pipex_rele_session(session);
+
+       return (0);
+}
+
+static int
 pppac_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
     struct rtentry *rt)
 {
@@ -1452,7 +1432,10 @@ pppac_qstart(struct ifqueue *ifq)
 {
        struct ifnet *ifp = ifq->ifq_if;
        struct pppac_softc *sc = ifp->if_softc;
-       struct mbuf *m;
+       struct mbuf *m, *m0;
+       struct pipex_session *session;
+       struct ip ip;
+       int rv;
 
        NET_LOCK();
        while ((m = ifq_dequeue(ifq)) != NULL) {
@@ -1463,19 +1446,45 @@ pppac_qstart(struct ifqueue *ifq)
                }
 #endif
 
-               m = pipex_output(m, m->m_pkthdr.ph_family, 0,
-                   &sc->sc_pipex_iface);
-               if (m == NULL)
+               switch (m->m_pkthdr.ph_family) {
+               case AF_INET:
+                       if (m->m_pkthdr.len < sizeof(struct ip))
+                               goto bad;
+                       m_copydata(m, 0, sizeof(struct ip), (caddr_t)&ip);
+                       if (IN_MULTICAST(ip.ip_dst.s_addr)) {
+                               /* pass a copy to pipex */
+                               m0 = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+                               if (m0 != NULL)
+                                       pipex_ip_output(m0,
+                                           sc->sc_multicast_session);
+                               else
+                                       goto bad;
+                       } else {
+                               session = pipex_lookup_by_ip_address(ip.ip_dst);
+                               if (session != NULL) {
+                                       pipex_ip_output(m, session);
+                                       m = NULL;
+                               }
+                       }
+                       break;
+               }
+               if (m == NULL)  /* handled by pipex */
                        continue;
 
                m = m_prepend(m, sizeof(uint32_t), M_DONTWAIT);
-               if (m == NULL) {
-                       /* oh well */
-                       continue;
-               }
+               if (m == NULL)
+                       goto bad;
                *mtod(m, uint32_t *) = htonl(m->m_pkthdr.ph_family);
 
-               mq_enqueue(&sc->sc_mq, m); /* qdrop */
+               rv = mq_enqueue(&sc->sc_mq, m);
+               if (rv == 1)
+                       ifp->if_collisions++;
+               continue;
+bad:
+               ifp->if_oerrors++;
+               if (m != NULL)
+                       m_freem(m);
+               continue;
        }
        NET_UNLOCK();
 
Index: sys/net/pipex.c
===================================================================
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.124
diff -u -p -r1.124 pipex.c
--- sys/net/pipex.c     12 Aug 2020 08:41:39 -0000      1.124
+++ sys/net/pipex.c     26 Aug 2020 06:25:34 -0000
@@ -141,115 +141,55 @@ pipex_init(void)
 }
 
 void
-pipex_iface_init(struct pipex_iface_context *pipex_iface, u_int ifindex)
-{
-       struct pipex_session *session;
-
-       pipex_iface->pipexmode = 0;
-       pipex_iface->ifindex = ifindex;
-
-       if (pipex_rd_head4 == NULL) {
-               if (!rn_inithead((void **)&pipex_rd_head4,
-                   offsetof(struct sockaddr_in, sin_addr)))
-                       panic("rn_inithead() failed on pipex_init()");
-       }
-       if (pipex_rd_head6 == NULL) {
-               if (!rn_inithead((void **)&pipex_rd_head6,
-                   offsetof(struct sockaddr_in6, sin6_addr)))
-                       panic("rn_inithead() failed on pipex_init()");
-       }
-
-       /* virtual pipex_session entry for multicast */
-       session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
-       session->is_multicast = 1;
-       session->pipex_iface = pipex_iface;
-       session->ifindex = ifindex;
-       pipex_iface->multicast_session = session;
-}
-
-Static void
-pipex_iface_start(struct pipex_iface_context *pipex_iface)
-{
-       pipex_iface->pipexmode = 1;
-}
-
-Static void
-pipex_iface_stop(struct pipex_iface_context *pipex_iface)
+pipex_destroy_all_sessions(void *ownersc)
 {
        struct pipex_session *session, *session_tmp;
 
-       pipex_iface->pipexmode = 0;
-       /*
-        * traversal all pipex sessions.
-        * it will become heavy if the number of pppac devices bocomes large.
-        */
+       NET_ASSERT_LOCKED();
+
        LIST_FOREACH_SAFE(session, &pipex_session_list, session_list,
            session_tmp) {
-               if (session->pipex_iface == pipex_iface)
-                       pipex_destroy_session(session);
+               if (session->ownersc == ownersc) {
+                       KASSERT(session->is_pppx == 0);
+                       pipex_unlink_session(session);
+                       pipex_rele_session(session);
+               }
        }
 }
 
-void
-pipex_iface_fini(struct pipex_iface_context *pipex_iface)
-{
-       pool_put(&pipex_session_pool, pipex_iface->multicast_session);
-       NET_LOCK();
-       pipex_iface_stop(pipex_iface);
-       NET_UNLOCK();
-}
-
 int
-pipex_ioctl(struct pipex_iface_context *pipex_iface, u_long cmd, caddr_t data)
+pipex_ioctl(void *ownersc, u_long cmd, caddr_t data)
 {
-       int pipexmode, ret = 0;
+       int ret = 0;
 
-       NET_LOCK();
+       NET_ASSERT_LOCKED();
        switch (cmd) {
        case PIPEXSMODE:
-               pipexmode = *(int *)data;
-               if (pipex_iface->pipexmode != pipexmode) {
-                       if (pipexmode)
-                               pipex_iface_start(pipex_iface);
-                       else
-                               pipex_iface_stop(pipex_iface);
-               }
                break;
 
        case PIPEXGMODE:
-               *(int *)data = pipex_iface->pipexmode;
-               break;
-
-       case PIPEXASESSION:
-               ret = pipex_add_session((struct pipex_session_req *)data,
-                   pipex_iface);
-               break;
-
-       case PIPEXDSESSION:
-               ret = pipex_close_session(
-                   (struct pipex_session_close_req *)data, pipex_iface);
+               *(int *)data = 1;
                break;
 
        case PIPEXCSESSION:
                ret = pipex_config_session(
-                   (struct pipex_session_config_req *)data, pipex_iface);
+                   (struct pipex_session_config_req *)data, ownersc);
                break;
 
        case PIPEXGSTAT:
                ret = pipex_get_stat((struct pipex_session_stat_req *)data,
-                   pipex_iface);
+                   ownersc);
                break;
 
        case PIPEXGCLOSED:
                ret = pipex_get_closed((struct pipex_session_list_req *)data,
-                   pipex_iface);
+                   ownersc);
                break;
 
        default:
                ret = ENOTTY;
                break;
        }
-       NET_UNLOCK();
 
        return (ret);
 }
@@ -426,21 +366,43 @@ pipex_rele_session(struct pipex_session 
 }
 
 int
-pipex_link_session(struct pipex_session *session,
-       struct pipex_iface_context *iface)
+pipex_link_session(struct pipex_session *session, struct ifnet *ifp,
+    void *ownersc)
 {
        struct pipex_hash_head *chain;
+       struct radix_node *rn;
 
        NET_ASSERT_LOCKED();
 
-       if (!iface->pipexmode)
-               return (ENXIO);
+       if (pipex_rd_head4 == NULL) {
+               if (!rn_inithead((void **)&pipex_rd_head4,
+                   offsetof(struct sockaddr_in, sin_addr)))
+                       panic("rn_inithead() failed on pipex_link_session()");
+       }
+       if (pipex_rd_head6 == NULL) {
+               if (!rn_inithead((void **)&pipex_rd_head6,
+                   offsetof(struct sockaddr_in6, sin6_addr)))
+                       panic("rn_inithead() failed on pipex_link_session()");
+       }
        if (pipex_lookup_by_session_id(session->protocol,
            session->session_id))
                return (EEXIST);
 
-       session->pipex_iface = iface;
-       session->ifindex = iface->ifindex;
+       session->ownersc = ownersc;
+       session->ifindex = ifp->if_index;
+       if (ifp->if_flags & IFF_POINTOPOINT)
+               session->is_pppx = 1;
+
+       if (session->is_pppx == 0 &&
+           !in_nullhost(session->ip_address.sin_addr)) {
+               if (pipex_lookup_by_ip_address(session->ip_address.sin_addr)
+                   != NULL)
+                       return (EADDRINUSE);
+               rn = rn_addroute(&session->ip_address, &session->ip_netmask,
+                   pipex_rd_head4, session->ps4_rn, RTP_STATIC);
+               if (rn == NULL)
+                       return (ENOMEM);
+       }
 
        LIST_INSERT_HEAD(&pipex_session_list, session, session_list);
        chain = PIPEX_ID_HASHTABLE(session->session_id);
@@ -466,9 +428,21 @@ pipex_link_session(struct pipex_session 
 void
 pipex_unlink_session(struct pipex_session *session)
 {
+       struct radix_node *rn;
+
        session->ifindex = 0;
 
        NET_ASSERT_LOCKED();
+       if (session->state == PIPEX_STATE_CLOSED)
+               return;
+       if (session->is_pppx == 0 &&
+           !in_nullhost(session->ip_address.sin_addr)) {
+               KASSERT(pipex_rd_head4 != NULL);
+               rn = rn_delete(&session->ip_address, &session->ip_netmask,
+                   pipex_rd_head4, (struct radix_node *)session);
+               KASSERT(rn != NULL);
+       }
+
        LIST_REMOVE(session, id_chain);
 #if defined(PIPEX_PPTP) || defined(PIPEX_L2TP)
        switch (session->protocol) {
@@ -488,54 +462,6 @@ pipex_unlink_session(struct pipex_sessio
                pipex_timer_stop();
 }
 
-Static int
-pipex_add_session(struct pipex_session_req *req,
-    struct pipex_iface_context *iface)
-{
-       struct pipex_session *session;
-       struct radix_node *rn;
-       int error;
-
-       if ((error = pipex_init_session(&session, req)) != 0)
-               goto out;
-
-       /* commit the session */
-       if (!in_nullhost(session->ip_address.sin_addr)) {
-               if (pipex_lookup_by_ip_address(session->ip_address.sin_addr)
-                   != NULL) {
-                       error = EADDRINUSE;
-                       goto free;
-               }
-
-               rn = rn_addroute(&session->ip_address, &session->ip_netmask,
-                   pipex_rd_head4, session->ps4_rn, RTP_STATIC);
-               if (rn == NULL) {
-                       error = ENOMEM;
-                       goto free;
-               }
-       }
-       if (0) { /* NOT YET */
-               rn = rn_addroute(&session->ip6_address, &session->ip6_prefixlen,
-                   pipex_rd_head6, session->ps6_rn, RTP_STATIC);
-               if (rn == NULL) {
-                       error = ENOMEM;
-                       goto free;
-               }
-       }
-
-       if ((error = pipex_link_session(session, iface)) != 0)
-               goto free;
-
-       pipex_session_log(session, LOG_INFO, "PIPEX is ready.");
-
-       return 0;
-
-free:
-       pipex_rele_session(session);
-out:
-       return error;
-}
-
 int
 pipex_notify_close_session(struct pipex_session *session)
 {
@@ -547,46 +473,8 @@ pipex_notify_close_session(struct pipex_
        return (0);
 }
 
-int
-pipex_notify_close_session_all(void)
-{
-       struct pipex_session *session;
-
-       NET_ASSERT_LOCKED();
-       LIST_FOREACH(session, &pipex_session_list, session_list)
-               if (session->state == PIPEX_STATE_OPENED)
-                       pipex_notify_close_session(session);
-       return (0);
-}
-
-Static int
-pipex_close_session(struct pipex_session_close_req *req,
-    struct pipex_iface_context *iface)
-{
-       struct pipex_session *session;
-
-       NET_ASSERT_LOCKED();
-       session = pipex_lookup_by_session_id(req->pcr_protocol,
-           req->pcr_session_id);
-       if (session == NULL)
-               return (EINVAL);
-       if (session->pipex_iface != iface)
-               return (EINVAL);
-
-       /* remove from close_wait list */
-       if (session->state == PIPEX_STATE_CLOSE_WAIT)
-               LIST_REMOVE(session, state_list);
-
-       /* get statistics before destroy the session */
-       req->pcr_stat = session->stat;
-       session->state = PIPEX_STATE_CLOSED;
-
-       return (0);
-}
-
 Static int
-pipex_config_session(struct pipex_session_config_req *req,
-    struct pipex_iface_context *iface)
+pipex_config_session(struct pipex_session_config_req *req, void *ownersc)
 {
        struct pipex_session *session;
 
@@ -595,7 +483,7 @@ pipex_config_session(struct pipex_sessio
            req->pcr_session_id);
        if (session == NULL)
                return (EINVAL);
-       if (session->pipex_iface != iface)
+       if (session->ownersc != ownersc)
                return (EINVAL);
        session->ip_forward = req->pcr_ip_forward;
 
@@ -603,8 +491,7 @@ pipex_config_session(struct pipex_sessio
 }
 
 Static int
-pipex_get_stat(struct pipex_session_stat_req *req,
-    struct pipex_iface_context *iface)
+pipex_get_stat(struct pipex_session_stat_req *req, void *ownersc)
 {
        struct pipex_session *session;
 
@@ -613,7 +500,7 @@ pipex_get_stat(struct pipex_session_stat
            req->psr_session_id);
        if (session == NULL)
                return (EINVAL);
-       if (session->pipex_iface != iface)
+       if (session->ownersc != ownersc)
                return (EINVAL);
        req->psr_stat = session->stat;
 
@@ -621,8 +508,7 @@ pipex_get_stat(struct pipex_session_stat
 }
 
 Static int
-pipex_get_closed(struct pipex_session_list_req *req,
-    struct pipex_iface_context *iface)
+pipex_get_closed(struct pipex_session_list_req *req, void *ownersc)
 {
        struct pipex_session *session, *session_tmp;
 
@@ -630,7 +516,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 (session->ownersc != ownersc)
                        continue;
                req->plr_ppp_id[req->plr_ppp_id_count++] = session->ppp_id;
                LIST_REMOVE(session, state_list);
@@ -645,32 +531,14 @@ pipex_get_closed(struct pipex_session_li
        return (0);
 }
 
-Static int
-pipex_destroy_session(struct pipex_session *session)
-{
-       struct radix_node *rn;
-
-       /* remove from radix tree and hash chain */
-       NET_ASSERT_LOCKED();
-
-       if (!in_nullhost(session->ip_address.sin_addr)) {
-               rn = rn_delete(&session->ip_address, &session->ip_netmask,
-                   pipex_rd_head4, (struct radix_node *)session);
-               KASSERT(rn != NULL);
-       }
-
-       pipex_unlink_session(session);
-       pipex_rele_session(session);
-
-       return (0);
-}
-
 Static struct pipex_session *
 pipex_lookup_by_ip_address(struct in_addr addr)
 {
        struct pipex_session *session;
        struct sockaddr_in pipex_in4, pipex_in4mask;
 
+       if (pipex_rd_head4 == NULL)
+               return (NULL);
        bzero(&pipex_in4, sizeof(pipex_in4));
        pipex_in4.sin_addr = addr;
        pipex_in4.sin_family = AF_INET;
@@ -761,18 +629,15 @@ pipex_timer(void *ignored_arg)
 
                case PIPEX_STATE_CLOSE_WAIT:
                case PIPEX_STATE_CLOSE_WAIT2:
-                       /* Wait PIPEXDSESSION from userland */
+                       /* Waiting PIPEXDSESSION from userland */
                        session->stat.idle_time++;
                        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);
+                       /* Release the sessions when timeout */
+                       pipex_unlink_session(session);
+                       KASSERTMSG(session->is_pppx == 0,
+                           "FIXME session must not be released when pppx");
+                       pipex_rele_session(session);
                        break;
 
                default:
@@ -786,55 +651,6 @@ pipex_timer(void *ignored_arg)
 /***********************************************************************
  * Common network I/O functions.  (tunnel protocol independent)
  ***********************************************************************/
-struct mbuf *
-pipex_output(struct mbuf *m0, int af, int off,
-    struct pipex_iface_context *pipex_iface)
-{
-       struct pipex_session *session;
-       struct ip ip;
-       struct mbuf *mret;
-
-       NET_ASSERT_LOCKED();
-       session = NULL;
-       mret = NULL;
-       switch (af) {
-       case AF_INET:
-               if (m0->m_pkthdr.len >= sizeof(struct ip) + off) {
-                       m_copydata(m0, off, sizeof(struct ip), (caddr_t)&ip);
-                       if (IN_MULTICAST(ip.ip_dst.s_addr))
-                               session = pipex_iface->multicast_session;
-                       else
-                               session = pipex_lookup_by_ip_address(ip.ip_dst);
-               }
-               if (session != NULL) {
-                       if (session == pipex_iface->multicast_session) {
-                               mret = m0;
-                               m0 = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
-                               if (m0 == NULL) {
-                                       m0 = mret;
-                                       mret = NULL;
-                                       goto drop;
-                               }
-                       }
-
-                       if (off > 0)
-                               m_adj(m0, off);
-
-                       pipex_ip_output(m0, session);
-                       return (mret);
-               }
-               break;
-       }
-
-       return (m0);
-
-drop:
-       m_freem(m0);
-       if (session != NULL)
-               session->stat.oerrors++;
-       return(NULL);
-}
-
 Static void
 pipex_ip_output(struct mbuf *m0, struct pipex_session *session)
 {
@@ -872,7 +688,7 @@ pipex_ip_output(struct mbuf *m0, struct 
                m0->m_flags &= ~(M_BCAST|M_MCAST);
 
                LIST_FOREACH(session_tmp, &pipex_session_list, session_list) {
-                       if (session_tmp->pipex_iface != session->pipex_iface)
+                       if (session_tmp->ownersc != session->ownersc)
                                continue;
                        if (session_tmp->ip_forward == 0 &&
                            session_tmp->ip6_forward == 0)
Index: sys/net/pipex.h
===================================================================
RCS file: /cvs/src/sys/net/pipex.h,v
retrieving revision 1.27
diff -u -p -r1.27 pipex.h
--- sys/net/pipex.h     4 Aug 2020 09:32:05 -0000       1.27
+++ sys/net/pipex.h     26 Aug 2020 06:25:34 -0000
@@ -194,13 +194,8 @@ struct pipex_iface_context {
 
 __BEGIN_DECLS
 void                  pipex_init (void);
-void                  pipex_iface_init (struct pipex_iface_context *, u_int);
 void                  pipex_iface_fini (struct pipex_iface_context *);
 
-int                   pipex_notify_close_session(struct pipex_session 
*session);
-int                   pipex_notify_close_session_all(void);
-
-struct mbuf           *pipex_output (struct mbuf *, int, int, struct 
pipex_iface_context *);
 struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
 struct mbuf           *pipex_pppoe_input (struct mbuf *, struct pipex_session 
*);
 struct pipex_session  *pipex_pptp_lookup_session (struct mbuf *);
@@ -214,7 +209,7 @@ struct mbuf           *pipex_l2tp_input 
 struct pipex_session  *pipex_l2tp_userland_lookup_session_ipv4 (struct mbuf *, 
struct in_addr);
 struct pipex_session  *pipex_l2tp_userland_lookup_session_ipv6 (struct mbuf *, 
struct in6_addr);
 struct mbuf           *pipex_l2tp_userland_output (struct mbuf *, struct 
pipex_session *);
-int                   pipex_ioctl (struct pipex_iface_context *, u_long, 
caddr_t);
+int                   pipex_ioctl (void *, u_long, caddr_t);
 void                  pipex_session_init_mppe_recv(struct pipex_session *, int,
 int, u_char *);
 void                  pipex_session_init_mppe_send(struct pipex_session *, int,
Index: sys/net/pipex_local.h
===================================================================
RCS file: /cvs/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       26 Aug 2020 06:25:34 -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_pppx: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 */
@@ -182,8 +183,8 @@ struct pipex_session {
        struct sockaddr_in6 ip6_address; /* [I] remote IPv6 address */
        int             ip6_prefixlen;   /* [I] remote IPv6 prefixlen */
 
-       struct pipex_iface_context* pipex_iface; /* [N] context for interface */
        u_int           ifindex;                /* [N] interface index */
+       void            *ownersc;               /* [I] owner context */
 
        uint32_t        ppp_flags;              /* [I] configure flags */
 #ifdef PIPEX_MPPE
@@ -285,6 +286,7 @@ extern struct pipex_hash_head       pipex_sess
 extern struct pipex_hash_head  pipex_close_wait_list;
 extern struct pipex_hash_head  pipex_peer_addr_hashtable[];
 extern struct pipex_hash_head  pipex_id_hashtable[];
+extern struct pool             pipex_session_pool;
 
 
 #define PIPEX_ID_HASHTABLE(key)                                                
\
@@ -375,24 +377,21 @@ extern struct pipex_hash_head     pipex_id_h
 #define PIPEX_TCP_OPTLEN 40
 #define        PIPEX_L2TP_MINLEN       8
 
-void                  pipex_iface_start (struct pipex_iface_context *);
-void                  pipex_iface_stop (struct pipex_iface_context *);
+void                  pipex_destroy_all_sessions (void *);
 int                   pipex_init_session(struct pipex_session **,
                                              struct pipex_session_req *);
 void                  pipex_rele_session(struct pipex_session *);
 int                   pipex_link_session(struct pipex_session *,
-                                             struct pipex_iface_context *);
+                          struct ifnet *, void *);
 void                  pipex_unlink_session(struct pipex_session *);
-int                   pipex_add_session (struct pipex_session_req *, struct 
pipex_iface_context *);
 int                   pipex_close_session (struct pipex_session_close_req *,
                           struct pipex_iface_context *);
 int                   pipex_config_session (struct pipex_session_config_req *,
-                          struct pipex_iface_context *);
+                          void *);
 int                   pipex_get_stat (struct pipex_session_stat_req *,
-                          struct pipex_iface_context *);
+                          void *);
 int                   pipex_get_closed (struct pipex_session_list_req *,
-                          struct pipex_iface_context *);
-int                   pipex_destroy_session (struct pipex_session *);
+                          void *);
 struct pipex_session  *pipex_lookup_by_ip_address (struct in_addr);
 struct pipex_session  *pipex_lookup_by_session_id (int, int);
 void                  pipex_ip_output (struct mbuf *, struct pipex_session *);

Reply via email to