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.

On Thu, Jun 25, 2020, 18:55 Vitaliy Makkoveev <[email protected]>
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