tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: rump shmif



I wrote:
>Is there a reason why shmif(4) doesn't have a fake ifmedia struct ?
>
>The tap(4) interface does have a fake one.

It doesn't set the status though, maybe it should.

>Was thinking it could return active or no carrier depending on whether
>a linkstr was set.

Have tried out the attached patch, dhcpcd(8) seems to work much better
with it.

Not tried running tests yet with shmif(4) and tap(4) changes, can anyone
think of something that would break with them ?

Index: if_shmem.c
===================================================================
RCS file: /cvsroot/src/sys/rump/net/lib/libshmif/if_shmem.c,v
retrieving revision 1.81
diff -u -r1.81 if_shmem.c
--- if_shmem.c	25 Feb 2020 03:26:18 -0000	1.81
+++ if_shmem.c	17 Aug 2020 12:02:33 -0000
@@ -43,6 +43,7 @@
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_ether.h>
+#include <net/if_media.h>
 #include <net/ether_sw_offload.h>
 
 #include <netinet/in.h>
@@ -80,11 +81,19 @@
 static void	shmif_snd(struct ifnet *, struct mbuf *);
 static void	shmif_stop(struct ifnet *, int);
 
+/*
+ * Those are needed by the if_media interface.
+ */
+
+static int	shmif_mediachange(struct ifnet *);
+static void	shmif_mediastatus(struct ifnet *, struct ifmediareq *);
+
 #include "shmifvar.h"
 
 struct shmif_sc {
 	struct ethercom sc_ec;
 	struct shmif_mem *sc_busmem;
+	struct ifmedia	sc_im;
 	int sc_memfd;
 	int sc_kq;
 	int sc_unit;
@@ -174,6 +183,24 @@
 	sc->sc_unit = unit;
 	sc->sc_uid = randnum;
 
+	/*
+	 * Why 1000baseT? Why not? You can add more.
+	 *
+	 * Note that there are 3 steps: init, one or several additions to
+	 * list of supported media, and in the end, the selection of one
+	 * of them.
+	 */
+	sc->sc_ec.ec_ifmedia = &sc->sc_im;
+	ifmedia_init(&sc->sc_im, 0, shmif_mediachange, shmif_mediastatus);
+	ifmedia_add(&sc->sc_im, IFM_ETHER | IFM_1000_T, 0, NULL);
+	ifmedia_add(&sc->sc_im, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
+	ifmedia_add(&sc->sc_im, IFM_ETHER | IFM_100_TX, 0, NULL);
+	ifmedia_add(&sc->sc_im, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
+	ifmedia_add(&sc->sc_im, IFM_ETHER | IFM_10_T, 0, NULL);
+	ifmedia_add(&sc->sc_im, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
+	ifmedia_add(&sc->sc_im, IFM_ETHER | IFM_AUTO, 0, NULL);
+	ifmedia_set(&sc->sc_im, IFM_ETHER | IFM_AUTO);
+
 	ifp = &sc->sc_ec.ec_if;
 
 	snprintf(ifp->if_xname, sizeof(ifp->if_xname), "shmif%d", unit);
@@ -199,6 +226,7 @@
 	if (error != 0) {
 		aprint_error("shmif%d: if_initialize failed(%d)\n", unit,
 		    error);
+		ifmedia_removeall(&sc->sc_im);
 		cv_destroy(&sc->sc_cv);
 		mutex_destroy(&sc->sc_mtx);
 		kmem_free(sc, sizeof(*sc));
@@ -240,6 +268,29 @@
 	return error;
 }
 
+/*
+ * This function is called by the ifmedia layer to notify the driver
+ * that the user requested a media change.  A real driver would
+ * reconfigure the hardware.
+ */
+static int
+shmif_mediachange(struct ifnet *ifp)
+{
+	return 0;
+}
+
+/*
+ * Here the user asks for the currently used media.
+ */
+static void
+shmif_mediastatus(struct ifnet *ifp, struct ifmediareq *imr)
+{
+	struct shmif_sc *sc = (struct shmif_sc *)ifp->if_softc;
+
+	imr->ifm_active = sc->sc_im.ifm_cur->ifm_media;
+	imr->ifm_status = ((sc->sc_backfile) ? IFM_ACTIVE : 0) | IFM_AVALID;
+}
+
 static int
 initbackend(struct shmif_sc *sc, int memfd)
 {
@@ -422,6 +473,7 @@
 
 	ether_ifdetach(ifp);
 	if_detach(ifp);
+	ifmedia_fini(&sc->sc_im);
 
 	cv_destroy(&sc->sc_cv);
 	mutex_destroy(&sc->sc_mtx);


Home | Main Index | Thread Index | Old Index