On Thu, Aug 20, 2020 at 02:32:57PM +0900, YASUOKA Masahiko wrote: Hello.
I pointed some comments inline. > Hi, > > Thank you for your comments. > > On Mon, 17 Aug 2020 00:15:08 +0300 > Vitaliy Makkoveev <m...@openbsd.org> wrote: > > I like your idea to kill `pipex_iface_context'. I had trying to keep it > > by myself and this was wrong way. Could you rework your diff to be > > against the recent sources? > > I'm sorry the diff was for the old version. > > >> @@ -1122,8 +1051,11 @@ pppacopen(dev_t dev, int flags, int mode, struct > >> proc *p) > >> #if NBPFILTER > 0 > >> bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(uint32_t)); > >> #endif > >> - > >> - pipex_iface_init(&sc->sc_pipex_iface, ifp->if_index); > >> + /* virtual pipex_session entry for multicast */ > >> + session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO); > >> + session->is_multicast = 1; > >> + session->ifindex = ifp->if_index; > >> + sc->sc_multicast_session = session; > >> > > Interface index is not required for multicast session, because it's > > never used. Also I like to alloc `sc_multicast_session' before > > if_attach(). > > The diff was to use `ifindex' to select all sessions associated the > same pppac(4). But the latest diff uses `ownersc' instead for the > same purpose. Also the allocation was moved to earlier part of the > function. > > >> @@ -1382,7 +1340,10 @@ pppacclose(dev_t dev, int flags, int mode, struct > >> proc *p) > >> klist_invalidate(&sc->sc_wsel.si_note); > >> splx(s); > >> > >> - 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(); > >> > >> if_detach(ifp); > > > > The recent sources has pppac(4) with unlocked start routine. I like you > > detach `ifp' before destroy `sc_multicast_session'. > > The lines were moved after if_detach(). > > I'll test this more on this weekend, then I'll ask ok for this. > > 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 20 Aug 2020 05:19:55 -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; > @@ -1075,6 +1004,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 +1012,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 +1048,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); > } > > @@ -1244,7 +1178,9 @@ pppacioctl(dev_t dev, u_long cmd, caddr_ > { > struct pppac_softc *sc = pppac_lookup(dev); > int error = 0; > + struct pipex_session *session; > > + NET_LOCK(); > switch (cmd) { > case TUNSIFMODE: /* make npppd happy */ > break; > @@ -1255,10 +1191,34 @@ pppacioctl(dev_t dev, u_long cmd, caddr_ > *(int *)data = mq_hdatalen(&sc->sc_mq); > break; > > + 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. > + 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. What about to introduce pppac_{add,del}_session() and move related code into them? 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. > + error = EINVAL; > + break; > + } > + pipex_unlink_session(session); > + pipex_rele_session(session); > + break; > + } > default: > - error = pipex_ioctl(&sc->sc_pipex_iface, cmd, data); > + error = pipex_ioctl(sc, cmd, data); > break; > } > + NET_UNLOCK(); > > return (error); > } > @@ -1373,7 +1333,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)); > @@ -1452,7 +1415,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 +1429,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++; Could you use "counters_inc(ifp->if_counters, ifc_collisions);" here? For consistency with pppacwrite() which uses percpu counters. > + continue; > +bad: > + ifp->if_oerrors++; Could you use "counters_inc(ifp->if_counters, ifc_oerrors);" here? For consistency with pppacwrite() which uses percpu counters. > + 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 20 Aug 2020 05:19:56 -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()"); > + } Since you will initialize `pipex_rd_head{4,6}' for pppx(4) sessions too, may be it's better to move this initialization to pipex_init(). > 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 20 Aug 2020 05:19:56 -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 20 Aug 2020 05:19:56 -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 > *); >