Updated diff. The idea is to use already existing pipex API for
pipex_session creation and destruction. pppx_if now holds a reference
to pipex_session.

Index: sys/net/if_pppx.c
===================================================================
RCS file: /cvs/src/sys/net/if_pppx.c,v
retrieving revision 1.78
diff -u -p -r1.78 if_pppx.c
--- sys/net/if_pppx.c   1 Apr 2020 07:15:59 -0000       1.78
+++ sys/net/if_pppx.c   1 Apr 2020 09:50:19 -0000
@@ -155,7 +155,7 @@ struct pppx_if {
        int                     pxi_unit;
        struct ifnet            pxi_if;
        struct pppx_dev         *pxi_dev;
-       struct pipex_session    pxi_session;
+       struct pipex_session    *pxi_session;
        struct pipex_iface_context      pxi_ifcontext;
 };
 
@@ -655,15 +655,10 @@ int
 pppx_add_session(struct pppx_dev *pxd, struct pipex_session_req *req)
 {
        struct pppx_if *pxi;
-       struct pipex_session *session;
-       struct pipex_hash_head *chain;
        struct ifnet *ifp;
        int unit, error = 0;
        struct in_ifaddr *ia;
        struct sockaddr_in ifaddr;
-#ifdef PIPEX_PPPOE
-       struct ifnet *over_ifp = NULL;
-#endif
 
        /*
         * XXX: As long as `session' is allocated as part of a `pxi'
@@ -673,157 +668,16 @@ pppx_add_session(struct pppx_dev *pxd, s
        if (req->pr_timeout_sec != 0)
                return (EINVAL);
 
-       switch (req->pr_protocol) {
-#ifdef PIPEX_PPPOE
-       case PIPEX_PROTO_PPPOE:
-               over_ifp = ifunit(req->pr_proto.pppoe.over_ifname);
-               if (over_ifp == NULL)
-                       return (EINVAL);
-               if (req->pr_peer_address.ss_family != AF_UNSPEC)
-                       return (EINVAL);
-               break;
-#endif
-#if defined(PIPEX_PPTP) || defined(PIPEX_L2TP)
-       case PIPEX_PROTO_PPTP:
-       case PIPEX_PROTO_L2TP:
-               switch (req->pr_peer_address.ss_family) {
-               case AF_INET:
-                       if (req->pr_peer_address.ss_len != sizeof(struct 
sockaddr_in))
-                               return (EINVAL);
-                       break;
-#ifdef INET6
-               case AF_INET6:
-                       if (req->pr_peer_address.ss_len != sizeof(struct 
sockaddr_in6))
-                               return (EINVAL);
-                       break;
-#endif
-               default:
-                       return (EPROTONOSUPPORT);
-               }
-               if (req->pr_peer_address.ss_family !=
-                   req->pr_local_address.ss_family ||
-                   req->pr_peer_address.ss_len !=
-                   req->pr_local_address.ss_len)
-                       return (EINVAL);
-               break;
-#endif /* defined(PIPEX_PPTP) || defined(PIPEX_L2TP) */
-       default:
-               return (EPROTONOSUPPORT);
-       }
-
        pxi = pool_get(pppx_if_pl, PR_WAITOK | PR_ZERO);
-       if (pxi == NULL)
-               return (ENOMEM);
-
-       session = &pxi->pxi_session;
        ifp = &pxi->pxi_if;
 
-       /* fake a pipex interface context */
-       session->pipex_iface = &pxi->pxi_ifcontext;
-       session->pipex_iface->ifnet_this = ifp;
-       session->pipex_iface->pipexmode = PIPEX_ENABLED;
-
-       /* setup session */
-       session->state = PIPEX_STATE_OPENED;
-       session->protocol = req->pr_protocol;
-       session->session_id = req->pr_session_id;
-       session->peer_session_id = req->pr_peer_session_id;
-       session->peer_mru = req->pr_peer_mru;
-       session->timeout_sec = req->pr_timeout_sec;
-       session->ppp_flags = req->pr_ppp_flags;
-       session->ppp_id = req->pr_ppp_id;
-
-       session->ip_forward = 1;
-
-       session->ip_address.sin_family = AF_INET;
-       session->ip_address.sin_len = sizeof(struct sockaddr_in);
-       session->ip_address.sin_addr = req->pr_ip_address;
-
-       session->ip_netmask.sin_family = AF_INET;
-       session->ip_netmask.sin_len = sizeof(struct sockaddr_in);
-       session->ip_netmask.sin_addr = req->pr_ip_netmask;
-
-       if (session->ip_netmask.sin_addr.s_addr == 0L)
-               session->ip_netmask.sin_addr.s_addr = 0xffffffffL;
-       session->ip_address.sin_addr.s_addr &=
-           session->ip_netmask.sin_addr.s_addr;
-
-       if (req->pr_peer_address.ss_len > 0)
-               memcpy(&session->peer, &req->pr_peer_address,
-                   MIN(req->pr_peer_address.ss_len, sizeof(session->peer)));
-       if (req->pr_local_address.ss_len > 0)
-               memcpy(&session->local, &req->pr_local_address,
-                   MIN(req->pr_local_address.ss_len, sizeof(session->local)));
-#ifdef PIPEX_PPPOE
-       if (req->pr_protocol == PIPEX_PROTO_PPPOE)
-               session->proto.pppoe.over_ifidx = over_ifp->if_index;
-#endif
-#ifdef PIPEX_PPTP
-       if (req->pr_protocol == PIPEX_PROTO_PPTP) {
-               struct pipex_pptp_session *sess_pptp = &session->proto.pptp;
-
-               sess_pptp->snd_gap = 0;
-               sess_pptp->rcv_gap = 0;
-               sess_pptp->snd_una = req->pr_proto.pptp.snd_una;
-               sess_pptp->snd_nxt = req->pr_proto.pptp.snd_nxt;
-               sess_pptp->rcv_nxt = req->pr_proto.pptp.rcv_nxt;
-               sess_pptp->rcv_acked = req->pr_proto.pptp.rcv_acked;
-
-               sess_pptp->winsz = req->pr_proto.pptp.winsz;
-               sess_pptp->maxwinsz = req->pr_proto.pptp.maxwinsz;
-               sess_pptp->peer_maxwinsz = req->pr_proto.pptp.peer_maxwinsz;
-               /* last ack number */
-               sess_pptp->ul_snd_una = sess_pptp->snd_una - 1;
-       }
-#endif
-#ifdef PIPEX_L2TP
-       if (req->pr_protocol == PIPEX_PROTO_L2TP) {
-               struct pipex_l2tp_session *sess_l2tp = &session->proto.l2tp;
-
-               /* session keys */
-               sess_l2tp->tunnel_id = req->pr_proto.l2tp.tunnel_id;
-               sess_l2tp->peer_tunnel_id = req->pr_proto.l2tp.peer_tunnel_id;
-
-               /* protocol options */
-               sess_l2tp->option_flags = req->pr_proto.l2tp.option_flags;
-
-               /* initial state of dynamic context */
-               sess_l2tp->ns_gap = sess_l2tp->nr_gap = 0;
-               sess_l2tp->ns_nxt = req->pr_proto.l2tp.ns_nxt;
-               sess_l2tp->nr_nxt = req->pr_proto.l2tp.nr_nxt;
-               sess_l2tp->ns_una = req->pr_proto.l2tp.ns_una;
-               sess_l2tp->nr_acked = req->pr_proto.l2tp.nr_acked;
-               /* last ack number */
-               sess_l2tp->ul_ns_una = sess_l2tp->ns_una - 1;
-       }
-#endif
-#ifdef PIPEX_MPPE
-       if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ACCEPTED) != 0)
-               pipex_session_init_mppe_recv(session,
-                   req->pr_mppe_recv.stateless, req->pr_mppe_recv.keylenbits,
-                   req->pr_mppe_recv.master_key);
-       if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ENABLED) != 0)
-               pipex_session_init_mppe_send(session,
-                   req->pr_mppe_send.stateless, req->pr_mppe_send.keylenbits,
-                   req->pr_mppe_send.master_key);
-
-       if (pipex_session_is_mppe_required(session)) {
-               if (!pipex_session_is_mppe_enabled(session) ||
-                   !pipex_session_is_mppe_accepted(session)) {
-                       pool_put(pppx_if_pl, pxi);
-                       return (EINVAL);
-               }
-       }
-#endif
-
        /* try to set the interface up */
        rw_enter_write(&pppx_ifs_lk);
        unit = pppx_if_next_unit();
        if (unit < 0) {
-               pool_put(pppx_if_pl, pxi);
-               error = ENOMEM;
                rw_exit_write(&pppx_ifs_lk);
-               goto out;
+               error = ENOMEM;
+               goto err_free_iface;
        }
 
        pxi->pxi_unit = unit;
@@ -833,10 +687,9 @@ pppx_add_session(struct pppx_dev *pxd, s
 
        /* this is safe without splnet since we're not modifying it */
        if (RBT_FIND(pppx_ifs, &pppx_ifs, pxi) != NULL) {
-               pool_put(pppx_if_pl, pxi);
-               error = EADDRINUSE;
                rw_exit_write(&pppx_ifs_lk);
-               goto out;
+               error = EADDRINUSE;
+               goto err_free_iface;
        }
 
        if (RBT_INSERT(pppx_ifs, &pppx_ifs, pxi) != NULL)
@@ -856,24 +709,21 @@ pppx_add_session(struct pppx_dev *pxd, s
        ifp->if_softc = pxi;
        /* ifp->if_rdomain = req->pr_rdomain; */
 
-       /* hook up pipex context */
-       chain = PIPEX_ID_HASHTABLE(session->session_id);
-       LIST_INSERT_HEAD(chain, session, id_chain);
-       LIST_INSERT_HEAD(&pipex_session_list, session, session_list);
-#if defined(PIPEX_PPTP) || defined(PIPEX_L2TP)
-       switch (req->pr_protocol) {
-       case PIPEX_PROTO_PPTP:
-       case PIPEX_PROTO_L2TP:
-               chain = PIPEX_PEER_ADDR_HASHTABLE(
-                   pipex_sockaddr_hash_key(&session->peer.sa));
-               LIST_INSERT_HEAD(chain, session, peer_addr_chain);
-               break;
+       /* pipex interface context */
+       pipex_iface_init(&pxi->pxi_ifcontext, ifp);
+       pipex_iface_start(&pxi->pxi_ifcontext);
+
+       error = pipex_add_session(req, &pxi->pxi_ifcontext);
+       if (error) {
+               goto err_free_pipex;
        }
-#endif
 
-       /* if first session is added, start timer */
-       if (LIST_NEXT(session, session_list) == NULL)
-               pipex_timer_start();
+       pxi->pxi_session = pipex_lookup_by_session_id(
+           pxi->pxi_key.pxik_protocol, pxi->pxi_key.pxik_session_id);
+       if (pxi->pxi_session == NULL) {
+               error = EINVAL;
+               goto err_free_pipex;
+       }
 
        /* XXXSMP breaks atomicity */
        NET_UNLOCK();
@@ -928,7 +778,20 @@ pppx_add_session(struct pppx_dev *pxd, s
        pxi->pxi_ready = 1;
        rw_exit_write(&pppx_ifs_lk);
 
-out:
+       return (error);
+
+err_free_pipex:
+       NET_UNLOCK();
+       pipex_iface_fini(&pxi->pxi_ifcontext);
+       NET_LOCK();
+err_free_iface:
+       rw_enter_write(&pppx_ifs_lk);
+       if (RBT_REMOVE(pppx_ifs, &pppx_ifs, pxi) == NULL)
+               panic("%s: pppx_ifs modified while lock was held", __func__);
+       LIST_REMOVE(pxi, pxi_list);
+               rw_exit_write(&pppx_ifs_lk);
+       pool_put(pppx_if_pl, pxi);
+
        return (error);
 }
 
@@ -941,7 +804,7 @@ pppx_del_session(struct pppx_dev *pxd, s
        if (pxi == NULL)
                return (EINVAL);
 
-       req->pcr_stat = pxi->pxi_session.stat;
+       req->pcr_stat = pxi->pxi_session->stat;
 
        pppx_if_destroy(pxd, pxi);
        return (0);
@@ -970,29 +833,19 @@ pppx_if_destroy(struct pppx_dev *pxd, st
        struct pipex_session *session;
 
        NET_ASSERT_LOCKED();
-       session = &pxi->pxi_session;
+       session = pxi->pxi_session;
        ifp = &pxi->pxi_if;
 
-       LIST_REMOVE(session, id_chain);
-       LIST_REMOVE(session, session_list);
-#if defined(PIPEX_PPTP) || defined(PIPEX_L2TP)
-       switch (session->protocol) {
-       case PIPEX_PROTO_PPTP:
-       case PIPEX_PROTO_L2TP:
-               LIST_REMOVE(session, peer_addr_chain);
-               break;
-       }
-#endif
-
-       /* if final session is destroyed, stop timer */
-       if (LIST_EMPTY(&pipex_session_list))
-               pipex_timer_stop();
-
        /* XXXSMP breaks atomicity */
        NET_UNLOCK();
        if_detach(ifp);
        NET_LOCK();
 
+       pipex_destroy_session(session);
+       NET_UNLOCK();
+       pipex_iface_fini(&pxi->pxi_ifcontext);
+       NET_LOCK();
+
        rw_enter_write(&pppx_ifs_lk);
        if (RBT_REMOVE(pppx_ifs, &pppx_ifs, pxi) == NULL)
                panic("%s: pppx_ifs modified while lock was held", __func__);
@@ -1024,7 +877,7 @@ pppx_if_start(struct ifnet *ifp)
                ifp->if_obytes += m->m_pkthdr.len;
                ifp->if_opackets++;
 
-               pipex_ppp_output(m, &pxi->pxi_session, proto);
+               pipex_ppp_output(m, pxi->pxi_session, proto);
        }
 }
 
@@ -1084,7 +937,7 @@ pppx_if_output(struct ifnet *ifp, struct
                }
                th = mtod(m, struct pppx_hdr *);
                th->pppx_proto = 0;     /* not used */
-               th->pppx_id = pxi->pxi_session.ppp_id;
+               th->pppx_id = pxi->pxi_session->ppp_id;
                rw_enter_read(&pppx_devs_lk);
                error = mq_enqueue(&pxi->pxi_dev->pxd_svcq, m);
                if (error == 0) {
@@ -1123,7 +976,7 @@ pppx_if_ioctl(struct ifnet *ifp, u_long 
 
        case SIOCSIFMTU:
                if (ifr->ifr_mtu < 512 ||
-                   ifr->ifr_mtu > pxi->pxi_session.peer_mru)
+                   ifr->ifr_mtu > pxi->pxi_session->peer_mru)
                        error = EINVAL;
                else
                        ifp->if_mtu = ifr->ifr_mtu;

Reply via email to