> On 25 Jun 2020, at 20:13, Christiano F. Haesbaert <haesba...@haesbaert.org> 
> wrote:
> 
> You can.
> 
> The idea is that ifindex is always monotonically increased, so to actually
> get a new interface you would have to have "overflowed" 65k interfaces,
> which is unreal.
> 
> So if your interface is gone, you can be sure if_get will give you NULL.

No I can’t :) It’s *not* the operational infinity you talks about.

You can run:
while true ; do ifconfig tun0 create ; ifconfig tun0 destroy ; done

And after couple of minutes you will see is very real to have *counter* be
overflowed. Not the interface count.

> 
> On Thu, Jun 25, 2020, 18:55 Vitaliy Makkoveev <henscheltig...@yahoo.com>
> wrote:
> 
>> Updated diff.
>> 
>> OpenBSD uses 16 bit counter for allocate interface indexes. So we can't
>> store index in session and be sure if_get(9) returned `ifnet' is our
>> original `ifnet'.
>> 
>> Now each pipex(4) session has it's own reference to `ifnet'. Also pppoe
>> related sessions has the reference to it's ethernet interface.
>> 
>> All `ifnet's are obtained by if_get(9) and we use `if_index' from stored
>> reference to `ifnet'.
>> 
>> Index: net/if_pppx.c
>> ===================================================================
>> RCS file: /cvs/src/sys/net/if_pppx.c,v
>> retrieving revision 1.90
>> diff -u -p -r1.90 if_pppx.c
>> --- net/if_pppx.c       24 Jun 2020 08:52:53 -0000      1.90
>> +++ net/if_pppx.c       25 Jun 2020 16:41:25 -0000
>> @@ -714,15 +714,15 @@ pppx_add_session(struct pppx_dev *pxd, s
>>        ifp->if_softc = pxi;
>>        /* ifp->if_rdomain = req->pr_rdomain; */
>> 
>> -       error = pipex_link_session(session, &pxi->pxi_ifcontext);
>> -       if (error)
>> -               goto remove;
>> -
>>        /* XXXSMP breaks atomicity */
>>        NET_UNLOCK();
>>        if_attach(ifp);
>>        NET_LOCK();
>> 
>> +       error = pipex_link_session(session, &pxi->pxi_ifcontext);
>> +       if (error)
>> +               goto detach;
>> +
>>        if_addgroup(ifp, "pppx");
>>        if_alloc_sadl(ifp);
>> 
>> @@ -771,7 +771,12 @@ pppx_add_session(struct pppx_dev *pxd, s
>> 
>>        return (error);
>> 
>> -remove:
>> +detach:
>> +       /* XXXSMP breaks atomicity */
>> +       NET_UNLOCK();
>> +       if_detach(ifp);
>> +       NET_LOCK();
>> +
>>        if (RBT_REMOVE(pppx_ifs, &pppx_ifs, pxi) == NULL)
>>                panic("%s: inconsistent RB tree", __func__);
>>        LIST_REMOVE(pxi, pxi_list);
>> @@ -860,13 +865,13 @@ pppx_if_destroy(struct pppx_dev *pxd, st
>>        CLR(ifp->if_flags, IFF_RUNNING);
>> 
>>        pipex_unlink_session(session);
>> +       pipex_rele_session(session);
>> 
>>        /* XXXSMP breaks atomicity */
>>        NET_UNLOCK();
>>        if_detach(ifp);
>>        NET_LOCK();
>> 
>> -       pipex_rele_session(session);
>>        if (RBT_REMOVE(pppx_ifs, &pppx_ifs, pxi) == NULL)
>>                panic("%s: inconsistent RB tree", __func__);
>>        LIST_REMOVE(pxi, pxi_list);
>> Index: net/pipex.c
>> ===================================================================
>> RCS file: /cvs/src/sys/net/pipex.c,v
>> retrieving revision 1.116
>> diff -u -p -r1.116 pipex.c
>> --- net/pipex.c 22 Jun 2020 09:38:15 -0000      1.116
>> +++ net/pipex.c 25 Jun 2020 16:41:25 -0000
>> @@ -148,7 +148,7 @@ pipex_iface_init(struct pipex_iface_cont
>>        struct pipex_session *session;
>> 
>>        pipex_iface->pipexmode = 0;
>> -       pipex_iface->ifnet_this = ifp;
>> +       pipex_iface->ifnet_this = if_get(ifp->if_index);
>> 
>>        if (pipex_rd_head4 == NULL) {
>>                if (!rn_inithead((void **)&pipex_rd_head4,
>> @@ -165,6 +165,7 @@ pipex_iface_init(struct pipex_iface_cont
>>        session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
>>        session->is_multicast = 1;
>>        session->pipex_iface = pipex_iface;
>> +       session->ifnet_this = if_get(ifp->if_index);
>>        pipex_iface->multicast_session = session;
>> }
>> 
>> @@ -194,10 +195,11 @@ pipex_iface_stop(struct pipex_iface_cont
>> 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();
>> +       pipex_rele_session(pipex_iface->multicast_session);
>> +       if_put(pipex_iface->ifnet_this);
>> }
>> 
>> int
>> @@ -358,7 +360,7 @@ pipex_init_session(struct pipex_session
>>                    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;
>> +               session->proto.pppoe.over_iface =
>> if_get(over_ifp->if_index);
>> #endif
>> #ifdef PIPEX_PPTP
>>        if (req->pr_protocol == PIPEX_PROTO_PPTP) {
>> @@ -421,6 +423,13 @@ pipex_init_session(struct pipex_session
>> void
>> pipex_rele_session(struct pipex_session *session)
>> {
>> +#ifdef PIPEX_PPPOE
>> +       if (session->protocol == PIPEX_PROTO_PPPOE)
>> +               if_put(session->proto.pppoe.over_iface);
>> +#endif
>> +       if (session->ifnet_this) {
>> +               if_put(session->ifnet_this);
>> +       }
>>        if (session->mppe_recv.old_session_keys)
>>                pool_put(&mppe_key_pool,
>> session->mppe_recv.old_session_keys);
>>        pool_put(&pipex_session_pool, session);
>> @@ -439,6 +448,7 @@ pipex_link_session(struct pipex_session
>>                return (EEXIST);
>> 
>>        session->pipex_iface = iface;
>> +       session->ifnet_this = if_get(iface->ifnet_this->if_index);
>> 
>>        LIST_INSERT_HEAD(&pipex_session_list, session, session_list);
>>        chain = PIPEX_ID_HASHTABLE(session->session_id);
>> @@ -655,7 +665,7 @@ pipex_destroy_session(struct pipex_sessi
>>        }
>> 
>>        pipex_unlink_session(session);
>> -       pool_put(&pipex_session_pool, session);
>> +       pipex_rele_session(session);
>> 
>>        return (0);
>> }
>> @@ -919,7 +929,7 @@ pipex_ip_output(struct mbuf *m0, struct
>>        struct ifnet *ifp;
>> 
>>        /* output succeed here as a interface */
>> -       ifp = session->pipex_iface->ifnet_this;
>> +       ifp = session->ifnet_this;
>>        ifp->if_opackets++;
>>        ifp->if_obytes+=m0->m_pkthdr.len;
>> 
>> @@ -1038,7 +1048,7 @@ pipex_ppp_input(struct mbuf *m0, struct
>> 
>> #if NBPFILTER > 0
>>            {
>> -               struct ifnet *ifp = session->pipex_iface->ifnet_this;
>> +               struct ifnet *ifp = session->ifnet_this;
>>                if (ifp->if_bpf && ifp->if_type == IFT_PPP)
>>                        bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_IN);
>>            }
>> @@ -1105,7 +1115,7 @@ pipex_ip_input(struct mbuf *m0, struct p
>>        int is_idle;
>> 
>>        /* change recvif */
>> -       ifp = session->pipex_iface->ifnet_this;
>> +       ifp = session->ifnet_this;
>>        m0->m_pkthdr.ph_ifidx = ifp->if_index;
>> 
>>        if (ISSET(session->ppp_flags, PIPEX_PPP_INGRESS_FILTER)) {
>> @@ -1174,7 +1184,7 @@ pipex_ip6_input(struct mbuf *m0, struct
>>        int len;
>> 
>>        /* change recvif */
>> -       ifp = session->pipex_iface->ifnet_this;
>> +       ifp = session->ifnet_this;
>>        m0->m_pkthdr.ph_ifidx = ifp->if_index;
>> 
>>        /*
>> @@ -1346,7 +1356,8 @@ pipex_pppoe_lookup_session(struct mbuf *
>>                PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found
>> (id=%d)",
>>                    __func__, pppoe.session_id));
>> #endif
>> -       if (session && session->proto.pppoe.over_ifidx !=
>> m0->m_pkthdr.ph_ifidx)
>> +       if (session && session->proto.pppoe.over_iface->if_index !=
>> +           m0->m_pkthdr.ph_ifidx)
>>                session = NULL;
>> 
>>        return (session);
>> @@ -1407,19 +1418,12 @@ pipex_pppoe_output(struct mbuf *m0, stru
>>        pppoe->session_id = htons(session->session_id);
>>        pppoe->length = htons(len);
>> 
>> -       m0->m_pkthdr.ph_ifidx = session->proto.pppoe.over_ifidx;
>> +       ifp = session->proto.pppoe.over_iface;
>> +       m0->m_pkthdr.ph_ifidx = ifp->if_index;
>>        m0->m_flags &= ~(M_BCAST|M_MCAST);
>> -
>> -       ifp = if_get(session->proto.pppoe.over_ifidx);
>> -       if (ifp != NULL) {
>> -               ifp->if_output(ifp, m0, &session->peer.sa, NULL);
>> -               session->stat.opackets++;
>> -               session->stat.obytes += len;
>> -       } else {
>> -               m_freem(m0);
>> -               session->stat.oerrors++;
>> -       }
>> -       if_put(ifp);
>> +       ifp->if_output(ifp, m0, &session->peer.sa, NULL);
>> +       session->stat.opackets++;
>> +       session->stat.obytes += len;
>> }
>> #endif /* PIPEX_PPPOE */
>> 
>> Index: net/pipex_local.h
>> ===================================================================
>> RCS file: /cvs/src/sys/net/pipex_local.h,v
>> retrieving revision 1.35
>> diff -u -p -r1.35 pipex_local.h
>> --- net/pipex_local.h   18 Jun 2020 14:20:12 -0000      1.35
>> +++ net/pipex_local.h   25 Jun 2020 16:41:25 -0000
>> @@ -78,7 +78,7 @@ struct pipex_mppe {
>> 
>> #ifdef PIPEX_PPPOE
>> struct pipex_pppoe_session {
>> -       u_int    over_ifidx;                    /* [I] ether interface */
>> +       struct ifnet *over_iface;               /* [I] ether interface */
>> };
>> #endif /* PIPEX_PPPOE */
>> 
>> @@ -183,6 +183,7 @@ struct pipex_session {
>>        int             ip6_prefixlen;   /* [I] remote IPv6 prefixlen */
>> 
>>        struct pipex_iface_context* pipex_iface; /* [I] context for
>> interface */
>> +       struct ifnet    *ifnet_this;            /* [k] outer interface */
>> 
>>        uint32_t        ppp_flags;              /* [I] configure flags */
>> #ifdef PIPEX_MPPE
>> 

Reply via email to