tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: (non-)Equivalence of if_type == IFT_ETHER and (struct ethercom*) == (struct ifnet*)
Would the third option (a la FreeBSD) of moving everything to the
generic interface structure have the fewest number of casts/helper
methods?
Would it also make sharing code a little easier? (thinking of the new
wifi branch)
David
On Sat, 15 Oct 2022 at 17:18, Martin Husemann <martin%duskware.de@localhost> wrote:
>
> On Wed, Sep 28, 2022 at 08:46:52PM +0200, Martin Husemann wrote:
> > I see three options:
> >
> > - Use (a mostly unused) struct ethercom for wifi interfaces too and make
> > sure the ifp and ethercom pointers are castable. This is easy and
> > most likely the way I'll go forward.
>
> I have implemented this option on the "wifi" topic in hg, and it is
> working. It was not very intrusive, but still is a (tiny bit) wastefull
> and feels like a hack.
>
> > - Restructure if_vlan.c to have some indirection in the vlan list and
> > capability modifying operations - quite straight forward way: add
> > special in-kernel-only ioctl operations for that. For most interfaces
> > the common ether_ioctl code would deal with those and invoke the
> > vlan helpers in ether_subr.c. For wifi interfaces the ieee80211 ioctl
> > handler would catch the operations and either handle them with
> > "clones" of the current ether_subr.c helper functions or arrange for
> > different args and call them some way.
>
> I have implemented that option to see how intrusive/bad it gets - and it
> is quite ugly and very intrusive. But it properly decouples vlan interfaces
> from ethernet (and struct ethercom).
>
> The main part of the patch implementing it is below, but the (mostly
> mechanical) conversion of affected drivers makes the patch *huge*,
> so the full change (as far as I did it) is at:
>
> https://www.NetBSD.org/~martin/vlan-decoupling-2022-10-15.patch
>
> I am not sure if the cleanup is worth the churn (but on the other hand
> the ifnet -> ethercom casts are really ugly and very dangerous).
>
> The third option still is: move ethercom (and with it all vlan data)
> into struct ifnet.
>
> Opinions?
>
> Martin
>
>
>
> Index: if_ether.h
> ===================================================================
> RCS file: /cvsroot/src/sys/net/if_ether.h,v
> retrieving revision 1.89
> diff -u -p -r1.89 if_ether.h
> --- if_ether.h 20 Jun 2022 08:14:48 -0000 1.89
> +++ if_ether.h 15 Oct 2022 16:07:46 -0000
> @@ -161,9 +161,37 @@ do { \
> struct mii_data;
>
> struct ethercom;
> +struct vlancom;
>
> typedef int (*ether_cb_t)(struct ethercom *);
> -typedef int (*ether_vlancb_t)(struct ethercom *, uint16_t, bool);
> +typedef int (*vlan_cb_t)(struct ifnet *, struct vlancom *, uint16_t, bool);
> +
> +/*
> + * Structure shared between all interfaces that support vlans
> + * and the generic vlan code.
> + */
> +struct vlancom {
> + int vc_nvlans; /* # VLANs on this interface */
> + SIMPLEQ_HEAD(, vlanid_list) vc_vids; /* list of VLAN IDs */
> + int vc_capabilities; /* capabilities, provided by
> + driver */
> + int vc_capenable; /* tells hardware which
> + capabilities to enable */
> + /*
> + * Called whenever a vlan interface is configured or unconfigured.
> + * Args include the vlan tag and a flag indicating whether the tag is
> + * being added or removed.
> + */
> + vlan_cb_t vc_vlan_cb;
> + /*
> + * if this struct is part of ethercom, the lock is shared
> + */
> + kmutex_t *vc_lock;
> +};
> +
> +#define VLANCAP_VLAN_MTU 0x00000001 /* VLAN-compatible MTU */
> +#define VLANCAP_HWTAGGING 0x00000002 /* hardware VLAN tag support */
> +#define VLANCAP_HWFILTER 0x00000004 /* iface hw can filter vlan tag */
>
> /*
> * Structure shared between the ethernet driver modules and
> @@ -181,8 +209,8 @@ struct ethercom {
> int ec_capenable; /* tells hardware which
> capabilities to enable */
>
> - int ec_nvlans; /* # VLANs on this interface */
> - SIMPLEQ_HEAD(, vlanid_list) ec_vids; /* list of VLAN IDs */
> + struct vlancom ec_vlan;
> +
> /* The device handle for the MII bus child device. */
> struct mii_data *ec_mii;
> struct ifmedia *ec_ifmedia;
> @@ -192,12 +220,6 @@ struct ethercom {
> * ec_if.if_init, 0 on success, not 0 on failure.
> */
> ether_cb_t ec_ifflags_cb;
> - /*
> - * Called whenever a vlan interface is configured or unconfigured.
> - * Args include the vlan tag and a flag indicating whether the tag is
> - * being added or removed.
> - */
> - ether_vlancb_t ec_vlan_cb;
> /* Hooks called at the beginning of detach of this interface */
> khook_list_t *ec_ifdetach_hooks;
> kmutex_t *ec_lock;
> @@ -209,13 +231,11 @@ struct ethercom {
> #endif
> };
>
> -#define ETHERCAP_VLAN_MTU 0x00000001 /* VLAN-compatible MTU */
> -#define ETHERCAP_VLAN_HWTAGGING 0x00000002 /* hardware VLAN tag support */
> -#define ETHERCAP_JUMBO_MTU 0x00000004 /* 9000 byte MTU supported */
> -#define ETHERCAP_VLAN_HWFILTER 0x00000008 /* iface hw can filter vlan tag */
> -#define ETHERCAP_EEE 0x00000010 /* Energy Efficiency Ethernet */
> -#define ETHERCAP_MASK 0x0000001f
> +#define ETHERCAP_JUMBO_MTU 0x00000001 /* 9000 byte MTU supported */
> +#define ETHERCAP_EEE 0x00000002 /* Energy Efficiency Ethernet */
> +#define ETHERCAP_MASK 0x00000003
>
> +/* vlan and ether capabiliites when queried/set from userland */
> #define ECCAPBITS \
> "\020" \
> "\1VLAN_MTU" \
> @@ -224,6 +244,12 @@ struct ethercom {
> "\4VLAN_HWFILTER" \
> "\5EEE"
>
> +#define ECCAPBITS_VLAN_MTU 0x01
> +#define ECCAPBITS_VLAN_HWTAGGING 0x02
> +#define ECCAPBITS_JUMBO_MTU 0x04
> +#define ECCAPBITS_VLAN_HWFILTER 0x08
> +#define ECCAPBITS_EEE 0x10
> +
> /* ioctl() for Ethernet capabilities */
> struct eccapreq {
> char eccr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
> @@ -251,7 +277,7 @@ extern const uint8_t ether_ipmulticast_m
> extern const uint8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
>
> void ether_set_ifflags_cb(struct ethercom *, ether_cb_t);
> -void ether_set_vlan_cb(struct ethercom *, ether_vlancb_t);
> +void ether_set_vlan_cb(struct ethercom *, vlan_cb_t);
> int ether_ioctl(struct ifnet *, u_long, void *);
> int ether_addmulti(const struct sockaddr *, struct ethercom *);
> int ether_delmulti(const struct sockaddr *, struct ethercom *);
> @@ -343,6 +369,9 @@ ether_first_multi(struct ether_multistep
> #define ETHER_LOCK(ec) mutex_enter((ec)->ec_lock)
> #define ETHER_UNLOCK(ec) mutex_exit((ec)->ec_lock)
>
> +#define VLAN_LOCK(vc) mutex_enter((vc)->vc_lock)
> +#define VLAN_UNLOCK(vc) mutex_exit((vc)->vc_lock)
> +
> /*
> * Ethernet 802.1Q VLAN structures.
> */
> @@ -382,16 +411,16 @@ vlan_has_tag(struct mbuf *m)
> static __inline bool
> vlan_is_hwtag_enabled(struct ifnet *_ifp)
> {
> - struct ethercom *ec = (void *)_ifp;
> + struct vlancom *vc = if_get_vlancom(_ifp);
>
> - if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING)
> + if (vc->vc_capenable & VLANCAP_HWTAGGING)
> return true;
>
> return false;
> }
>
> /* test if any VLAN is configured for this interface */
> -#define VLAN_ATTACHED(ec) ((ec)->ec_nvlans > 0)
> +#define VLAN_ATTACHED(ec) ((ec)->ec_vlan.vc_nvlans > 0)
>
> void etherinit(void);
> void ether_ifattach(struct ifnet *, const uint8_t *);
> @@ -417,6 +446,7 @@ int ether_del_vlantag(struct ifnet *, ui
> int ether_inject_vlantag(struct mbuf **, uint16_t, uint16_t);
> struct mbuf *
> ether_strip_vlantag(struct mbuf *);
> +int ether_eccapreq_from_caps(int, int);
> #else
> /*
> * Prototype ethers(3) functions.
> Index: if.h
> ===================================================================
> RCS file: /cvsroot/src/sys/net/if.h,v
> retrieving revision 1.302
> diff -u -p -r1.302 if.h
> --- if.h 18 Sep 2022 16:58:54 -0000 1.302
> +++ if.h 15 Oct 2022 16:07:46 -0000
> @@ -819,6 +819,14 @@ struct if_announcemsghdr {
> #undef __align64
>
> /*
> + * Structure used for in-kernel ioctl operations to fetch struct vlancom
> + * from interfaces.
> + */
> +struct ifrvlan {
> + struct vlancom *ifv_vc;
> +};
> +
> +/*
> * Interface request structure used for socket
> * ioctl's. All interface ioctl's must have parameter
> * definitions which begin with ifr_name. The
> @@ -1131,6 +1139,10 @@ int if_mcast_op(ifnet_t *, const unsigne
> int if_flags_set(struct ifnet *, const u_short);
> int if_clone_list(int, char *, int *);
>
> +struct vlancom;
> +struct vlancom *if_get_vlancom(ifnet_t *);
> +int if_vlan_caps_changed(ifnet_t *);
> +
> int if_ioctl(struct ifnet *, u_long, void *);
> int if_init(struct ifnet *);
> void if_stop(struct ifnet *, int);
> Index: if.c
> ===================================================================
> RCS file: /cvsroot/src/sys/net/if.c,v
> retrieving revision 1.526
> diff -u -p -r1.526 if.c
> --- if.c 20 Sep 2022 02:23:37 -0000 1.526
> +++ if.c 15 Oct 2022 16:07:47 -0000
> @@ -2811,9 +2811,10 @@ ifpromisc(struct ifnet *ifp, int pswitch
> * Apply an ioctl command to the interface. Returns 0 on success,
> * nonzero errno(3) number on failure.
> *
> - * For SIOCADDMULTI/SIOCDELMULTI, caller need not hold locks -- it
> - * is the driver's responsibility to take any internal locks.
> - * (Kernel logic should generally invoke these only through
> + * For SIOCADDMULTI, SIOCDELMULTI and SIOCGETVLANCOM, caller need not
> + * hold locks - it is the driver's responsibility to take any internal
> + * locks.
> + * (Kernel logic should generally invoke the first two only through
> * if_mcast_op.)
> *
> * For all other ioctls, caller must hold ifp->if_ioctl_lock,
> @@ -2826,6 +2827,7 @@ if_ioctl(struct ifnet *ifp, u_long cmd,
> switch (cmd) {
> case SIOCADDMULTI:
> case SIOCDELMULTI:
> + case SIOCGETVLANCOM:
> break;
> default:
> KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
> @@ -3983,6 +3985,22 @@ if_mcast_op(ifnet_t *ifp, const unsigned
> return rc;
> }
>
> +/*
> + * if_get_vlancom(ifp) - returns the vlancom structure if the interface
> + * supports vlan(4).
> + */
> +struct vlancom *
> +if_get_vlancom(ifnet_t *ifp)
> +{
> + struct ifrvlan r;
> +
> + memset(&r, 0, sizeof(r));
> + if (if_ioctl(ifp, SIOCGETVLANCOM, &r) != 0)
> + return NULL;
> +
> + return r.ifv_vc;
> +}
> +
> static void
> sysctl_sndq_setup(struct sysctllog **clog, const char *ifname,
> struct ifaltq *ifq)
> Index: if_ethersubr.c
> ===================================================================
> RCS file: /cvsroot/src/sys/net/if_ethersubr.c,v
> retrieving revision 1.320
> diff -u -p -r1.320 if_ethersubr.c
> --- if_ethersubr.c 3 Sep 2022 02:47:59 -0000 1.320
> +++ if_ethersubr.c 15 Oct 2022 16:07:47 -0000
> @@ -788,7 +788,7 @@ ether_input(struct ifnet *ifp, struct mb
> m->m_flags &= ~M_VLANTAG;
> } else {
> #if NVLAN > 0
> - if (ec->ec_nvlans > 0) {
> + if (ec->ec_vlan.vc_nvlans > 0) {
> m = vlan_input(ifp, m);
>
> /* vlan_input() called ether_input() recursively */
> @@ -1042,8 +1042,9 @@ ether_ifattach(struct ifnet *ifp, const
> if_set_sadl(ifp, lla, ETHER_ADDR_LEN, !ETHER_IS_LOCAL(lla));
>
> LIST_INIT(&ec->ec_multiaddrs);
> - SIMPLEQ_INIT(&ec->ec_vids);
> - ec->ec_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
> + SIMPLEQ_INIT(&ec->ec_vlan.vc_vids);
> + ec->ec_vlan.vc_lock = ec->ec_lock =
> + mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
> ec->ec_flags = 0;
> ifp->if_broadcastaddr = etherbroadcastaddr;
> bpf_attach(ifp, DLT_EN10MB, sizeof(struct ether_header));
> @@ -1083,7 +1084,7 @@ ether_ifdetach(struct ifnet *ifp)
> bpf_detach(ifp);
>
> ETHER_LOCK(ec);
> - KASSERT(ec->ec_nvlans == 0);
> + KASSERT(ec->ec_vlan.vc_nvlans == 0);
> while ((enm = LIST_FIRST(&ec->ec_multiaddrs)) != NULL) {
> LIST_REMOVE(enm, enm_list);
> kmem_free(enm, sizeof(*enm));
> @@ -1092,7 +1093,7 @@ ether_ifdetach(struct ifnet *ifp)
> ETHER_UNLOCK(ec);
>
> mutex_obj_free(ec->ec_lock);
> - ec->ec_lock = NULL;
> + ec->ec_vlan.vc_lock = ec->ec_lock = NULL;
>
> ifp->if_mowner = NULL;
> MOWNER_DETACH(&ec->ec_rx_mowner);
> @@ -1445,10 +1446,10 @@ ether_set_ifflags_cb(struct ethercom *ec
> }
>
> void
> -ether_set_vlan_cb(struct ethercom *ec, ether_vlancb_t cb)
> +ether_set_vlan_cb(struct ethercom *ec, vlan_cb_t cb)
> {
>
> - ec->ec_vlan_cb = cb;
> + ec->ec_vlan.vc_vlan_cb = cb;
> }
>
> static int
> @@ -1495,6 +1496,50 @@ ether_ioctl_reinit(struct ethercom *ec)
> return 0;
> }
>
> +static int
> +ethercaps_from_eccapreq(int v)
> +{
> + int res = 0;
> +
> + if (v & ETHERCAP_JUMBO_MTU)
> + res |= ETHERCAP_JUMBO_MTU;
> + if (v & ECCAPBITS_EEE)
> + res |= ETHERCAP_EEE;
> + return res;
> +}
> +
> +static int
> +vlancaps_from_eccapreq(int v)
> +{
> + int res = 0;
> +
> + if (v & ECCAPBITS_VLAN_MTU)
> + res |= VLANCAP_VLAN_MTU;
> + if (v & ECCAPBITS_VLAN_HWTAGGING)
> + res |= VLANCAP_HWTAGGING;
> + if (v & ECCAPBITS_VLAN_HWFILTER)
> + res |= VLANCAP_HWFILTER;
> + return res;
> +}
> +
> +int
> +ether_eccapreq_from_caps(int ether_caps, int vlan_caps)
> +{
> + int res = 0;
> +
> + if (vlan_caps & VLANCAP_VLAN_MTU)
> + res |= ECCAPBITS_VLAN_MTU;
> + if (vlan_caps & VLANCAP_HWTAGGING)
> + res |= ECCAPBITS_VLAN_HWTAGGING;
> + if (vlan_caps & VLANCAP_HWFILTER)
> + res |= ECCAPBITS_VLAN_HWFILTER;
> + if (ether_caps & ETHERCAP_JUMBO_MTU)
> + res |= ECCAPBITS_JUMBO_MTU;
> + if (ether_caps & ETHERCAP_EEE)
> + res |= ECCAPBITS_EEE;
> + return res;
> +}
> +
> /*
> * Common ioctls for Ethernet interfaces. Note, we must be
> * called at splnet().
> @@ -1504,11 +1549,12 @@ ether_ioctl(struct ifnet *ifp, u_long cm
> {
> struct ethercom *ec = (void *)ifp;
> struct eccapreq *eccr;
> + struct ifrvlan *ifrvl;
> struct ifreq *ifr = (struct ifreq *)data;
> struct if_laddrreq *iflr = data;
> const struct sockaddr_dl *sdl;
> static const uint8_t zero[ETHER_ADDR_LEN];
> - int error;
> + int error, capabilities;
>
> switch (cmd) {
> case SIOCINITIFADDR:
> @@ -1560,22 +1606,39 @@ ether_ioctl(struct ifnet *ifp, u_long cm
> IFF_ALLMULTI : 0;
> }
> return error;
> + case SIOCGETVLANCOM:
> + ifrvl = (struct ifrvlan*)data;
> + if (0 == 0) { // XXX how to check?
> + /* this ioctl is in-kernel only */
> + ifrvl->ifv_vc = &ec->ec_vlan;
> + return 0;
> + }
> + return EINVAL;
> case SIOCGETHERCAP:
> eccr = (struct eccapreq *)data;
> - eccr->eccr_capabilities = ec->ec_capabilities;
> - eccr->eccr_capenable = ec->ec_capenable;
> + eccr->eccr_capabilities = ether_eccapreq_from_caps(
> + ec->ec_capabilities, ec->ec_vlan.vc_capabilities);
> + eccr->eccr_capenable = ether_eccapreq_from_caps(
> + ec->ec_capenable, ec->ec_vlan.vc_capenable);
> return 0;
> case SIOCSETHERCAP:
> eccr = (struct eccapreq *)data;
> - if ((eccr->eccr_capenable & ~ec->ec_capabilities) != 0)
> + capabilities = ether_eccapreq_from_caps(ec->ec_capabilities,
> + ec->ec_vlan.vc_capabilities);
> + if ((eccr->eccr_capenable & ~capabilities) != 0)
> return EINVAL;
> - if (eccr->eccr_capenable == ec->ec_capenable)
> + capabilities = ether_eccapreq_from_caps(ec->ec_capenable,
> + ec->ec_vlan.vc_capenable);
> + if (eccr->eccr_capenable == capabilities)
> return 0;
> #if 0 /* notyet */
> ec->ec_capenable = (ec->ec_capenable & ETHERCAP_CANTCHANGE)
> | (eccr->eccr_capenable & ~ETHERCAP_CANTCHANGE);
> #else
> - ec->ec_capenable = eccr->eccr_capenable;
> + ec->ec_capenable = ethercaps_from_eccapreq(
> + eccr->eccr_capenable);
> + ec->ec_vlan.vc_capenable = vlancaps_from_eccapreq(
> + eccr->eccr_capenable);
> #endif
> return ether_ioctl_reinit(ec);
> case SIOCADDMULTI:
> @@ -1618,10 +1681,13 @@ int
> ether_enable_vlan_mtu(struct ifnet *ifp)
> {
> int error;
> - struct ethercom *ec = (void *)ifp;
> + struct vlancom *vc = if_get_vlancom(ifp);
> +
> + if (vc == NULL)
> + return ENOTTY;
>
> /* Parent does not support VLAN's */
> - if ((ec->ec_capabilities & ETHERCAP_VLAN_MTU) == 0)
> + if ((vc->vc_capabilities & VLANCAP_VLAN_MTU) == 0)
> return -1;
>
> /*
> @@ -1629,7 +1695,7 @@ ether_enable_vlan_mtu(struct ifnet *ifp)
> * i.e. can Tx/Rx larger than ETHER_MAX_LEN frames;
> * enable it.
> */
> - ec->ec_capenable |= ETHERCAP_VLAN_MTU;
> + vc->vc_capenable |= VLANCAP_VLAN_MTU;
>
> /* Interface is down, defer for later */
> if ((ifp->if_flags & IFF_UP) == 0)
> @@ -1638,7 +1704,7 @@ ether_enable_vlan_mtu(struct ifnet *ifp)
> if ((error = if_flags_set(ifp, ifp->if_flags)) == 0)
> return 0;
>
> - ec->ec_capenable &= ~ETHERCAP_VLAN_MTU;
> + vc->vc_capenable &= ~VLANCAP_VLAN_MTU;
> return error;
> }
>
> @@ -1646,20 +1712,23 @@ int
> ether_disable_vlan_mtu(struct ifnet *ifp)
> {
> int error;
> - struct ethercom *ec = (void *)ifp;
> + struct vlancom *vc = if_get_vlancom(ifp);
> +
> + if (vc == NULL)
> + return ENOTTY;
>
> /* We still have VLAN's, defer for later */
> - if (ec->ec_nvlans != 0)
> + if (vc->vc_nvlans != 0)
> return 0;
>
> /* Parent does not support VLAB's, nothing to do. */
> - if ((ec->ec_capenable & ETHERCAP_VLAN_MTU) == 0)
> + if ((vc->vc_capenable & VLANCAP_VLAN_MTU) == 0)
> return -1;
>
> /*
> * Disable Tx/Rx of VLAN-sized frames.
> */
> - ec->ec_capenable &= ~ETHERCAP_VLAN_MTU;
> + vc->vc_capenable &= ~VLANCAP_VLAN_MTU;
>
> /* Interface is down, defer for later */
> if ((ifp->if_flags & IFF_UP) == 0)
> @@ -1668,7 +1737,7 @@ ether_disable_vlan_mtu(struct ifnet *ifp
> if ((error = if_flags_set(ifp, ifp->if_flags)) == 0)
> return 0;
>
> - ec->ec_capenable |= ETHERCAP_VLAN_MTU;
> + vc->vc_capenable |= VLANCAP_VLAN_MTU;
> return error;
> }
>
> @@ -1678,24 +1747,27 @@ ether_disable_vlan_mtu(struct ifnet *ifp
> int
> ether_add_vlantag(struct ifnet *ifp, uint16_t vtag, bool *vlanmtu_status)
> {
> - struct ethercom *ec = (void *)ifp;
> + struct vlancom *vc = if_get_vlancom(ifp);
> struct vlanid_list *vidp;
> bool vlanmtu_enabled;
> uint16_t vid = EVL_VLANOFTAG(vtag);
> int error;
>
> + if (vc == NULL)
> + return ENOTTY;
> +
> vlanmtu_enabled = false;
>
> /* Add a vid to the list */
> vidp = kmem_alloc(sizeof(*vidp), KM_SLEEP);
> vidp->vid = vid;
>
> - ETHER_LOCK(ec);
> - ec->ec_nvlans++;
> - SIMPLEQ_INSERT_TAIL(&ec->ec_vids, vidp, vid_list);
> - ETHER_UNLOCK(ec);
> + VLAN_LOCK(vc);
> + vc->vc_nvlans++;
> + SIMPLEQ_INSERT_TAIL(&vc->vc_vids, vidp, vid_list);
> + VLAN_UNLOCK(vc);
>
> - if (ec->ec_nvlans == 1) {
> + if (vc->vc_nvlans == 1) {
> IFNET_LOCK(ifp);
> error = ether_enable_vlan_mtu(ifp);
> IFNET_UNLOCK(ifp);
> @@ -1707,8 +1779,8 @@ ether_add_vlantag(struct ifnet *ifp, uin
> }
> }
>
> - if (ec->ec_vlan_cb != NULL) {
> - error = (*ec->ec_vlan_cb)(ec, vid, true);
> + if (vc->vc_vlan_cb != NULL) {
> + error = (*vc->vc_vlan_cb)(ifp, vc, vid, true);
> if (error != 0)
> goto fail;
> }
> @@ -1718,10 +1790,10 @@ ether_add_vlantag(struct ifnet *ifp, uin
>
> return 0;
> fail:
> - ETHER_LOCK(ec);
> - ec->ec_nvlans--;
> - SIMPLEQ_REMOVE(&ec->ec_vids, vidp, vlanid_list, vid_list);
> - ETHER_UNLOCK(ec);
> + VLAN_LOCK(vc);
> + vc->vc_nvlans--;
> + SIMPLEQ_REMOVE(&vc->vc_vids, vidp, vlanid_list, vid_list);
> + VLAN_UNLOCK(vc);
>
> if (vlanmtu_enabled) {
> IFNET_LOCK(ifp);
> @@ -1737,29 +1809,32 @@ fail:
> int
> ether_del_vlantag(struct ifnet *ifp, uint16_t vtag)
> {
> - struct ethercom *ec = (void *)ifp;
> + struct vlancom *vc = if_get_vlancom(ifp);
> struct vlanid_list *vidp;
> uint16_t vid = EVL_VLANOFTAG(vtag);
>
> - ETHER_LOCK(ec);
> - SIMPLEQ_FOREACH(vidp, &ec->ec_vids, vid_list) {
> + if (vc == NULL)
> + return ENOTTY;
> +
> + VLAN_LOCK(vc);
> + SIMPLEQ_FOREACH(vidp, &vc->vc_vids, vid_list) {
> if (vidp->vid == vid) {
> - SIMPLEQ_REMOVE(&ec->ec_vids, vidp,
> + SIMPLEQ_REMOVE(&vc->vc_vids, vidp,
> vlanid_list, vid_list);
> - ec->ec_nvlans--;
> + vc->vc_nvlans--;
> break;
> }
> }
> - ETHER_UNLOCK(ec);
> + VLAN_UNLOCK(vc);
>
> if (vidp == NULL)
> return ENOENT;
>
> - if (ec->ec_vlan_cb != NULL) {
> - (void)(*ec->ec_vlan_cb)(ec, vidp->vid, false);
> + if (vc->vc_vlan_cb != NULL) {
> + (void)(*vc->vc_vlan_cb)(ifp, vc, vidp->vid, false);
> }
>
> - if (ec->ec_nvlans == 0) {
> + if (vc->vc_nvlans == 0) {
> IFNET_LOCK(ifp);
> (void)ether_disable_vlan_mtu(ifp);
> IFNET_UNLOCK(ifp);
> Index: if_vlan.c
> ===================================================================
> RCS file: /cvsroot/src/sys/net/if_vlan.c,v
> retrieving revision 1.170
> diff -u -p -r1.170 if_vlan.c
> --- if_vlan.c 20 Jun 2022 08:14:48 -0000 1.170
> +++ if_vlan.c 15 Oct 2022 16:07:47 -0000
> @@ -429,7 +429,9 @@ vlan_config(struct ifvlan *ifv, struct i
> switch (p->if_type) {
> case IFT_ETHER:
> {
> - struct ethercom *ec = (void *)p;
> + struct vlancom *vc;
> +
> + vc = if_get_vlancom(p);
>
> nmib->ifvm_msw = &vlan_ether_multisw;
> nmib->ifvm_mintu = ETHERMIN;
> @@ -438,7 +440,7 @@ vlan_config(struct ifvlan *ifv, struct i
> if (error != 0)
> goto done;
>
> - if (ec->ec_capenable & ETHERCAP_VLAN_MTU) {
> + if (vc->vc_capenable & VLANCAP_VLAN_MTU) {
> nmib->ifvm_mtufudge = 0;
> } else {
> /*
> @@ -457,7 +459,7 @@ vlan_config(struct ifvlan *ifv, struct i
> * assisted checksumming flags and tcp segmentation
> * offload.
> */
> - if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) {
> + if (vc->vc_capabilities & VLANCAP_HWTAGGING) {
> ifp->if_capabilities = p->if_capabilities &
> (IFCAP_TSOv4 | IFCAP_TSOv6 |
> IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
> @@ -1195,7 +1197,7 @@ vlan_start(struct ifnet *ifp)
> {
> struct ifvlan *ifv = ifp->if_softc;
> struct ifnet *p;
> - struct ethercom *ec;
> + struct vlancom *vc;
> struct mbuf *m;
> struct ifvlan_linkmib *mib;
> struct psref psref;
> @@ -1216,7 +1218,7 @@ vlan_start(struct ifnet *ifp)
> }
>
> p = mib->ifvm_p;
> - ec = (void *)mib->ifvm_p;
> + vc = if_get_vlancom(mib->ifvm_p);
>
> ifp->if_flags |= IFF_OACTIVE;
>
> @@ -1269,7 +1271,7 @@ vlan_start(struct ifnet *ifp)
> * If the parent can insert the tag itself, just mark
> * the tag in the mbuf header.
> */
> - if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING) {
> + if (vc->vc_capenable & VLANCAP_HWTAGGING) {
> vlan_set_tag(m, mib->ifvm_tag);
> } else {
> /*
> @@ -1318,7 +1320,7 @@ vlan_transmit(struct ifnet *ifp, struct
> {
> struct ifvlan *ifv = ifp->if_softc;
> struct ifnet *p;
> - struct ethercom *ec;
> + struct vlancom *vc;
> struct ifvlan_linkmib *mib;
> struct psref psref;
> struct ether_header *eh;
> @@ -1357,7 +1359,7 @@ vlan_transmit(struct ifnet *ifp, struct
> }
>
> p = mib->ifvm_p;
> - ec = (void *)mib->ifvm_p;
> + vc = if_get_vlancom(mib->ifvm_p);
>
> bpf_mtap(ifp, m, BPF_D_OUT);
>
> @@ -1370,7 +1372,7 @@ vlan_transmit(struct ifnet *ifp, struct
> * If the parent can insert the tag itself, just mark
> * the tag in the mbuf header.
> */
> - if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING) {
> + if (vc->vc_capenable & VLANCAP_HWTAGGING) {
> vlan_set_tag(m, mib->ifvm_tag);
> } else {
> /*
Home |
Main Index |
Thread Index |
Old Index