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