summaryrefslogtreecommitdiffstats
path: root/sys/net/if.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 288d944..ff114b7 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -723,6 +723,11 @@ if_attach_internal(struct ifnet *ifp, int vmove, struct if_clone *ifc)
/* Reliably crash if used uninitialized. */
ifp->if_broadcastaddr = NULL;
+ if (ifp->if_type == IFT_ETHER) {
+ ifp->if_hw_addr = malloc(ifp->if_addrlen, M_IFADDR,
+ M_WAITOK | M_ZERO);
+ }
+
#if defined(INET) || defined(INET6)
/* Use defaults for TSO, if nothing is set */
if (ifp->if_hw_tsomax == 0 &&
@@ -979,6 +984,8 @@ if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp)
* Remove link ifaddr pointer and maybe decrement if_index.
* Clean up all addresses.
*/
+ free(ifp->if_hw_addr, M_IFADDR);
+ ifp->if_hw_addr = NULL;
ifp->if_addr = NULL;
/* We can now free link ifaddr. */
@@ -2619,6 +2626,10 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
break;
+ case SIOCGHWADDR:
+ error = if_gethwaddr(ifp, ifr);
+ break;
+
case SIOCAIFGROUP:
{
struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr;
@@ -3557,6 +3568,29 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
}
/*
+ * Get the link layer address that was read from the hardware at attach.
+ *
+ * This is only set by Ethernet NICs (IFT_ETHER), but laggX interfaces re-type
+ * their component interfaces as IFT_IEEE8023ADLAG.
+ */
+int
+if_gethwaddr(struct ifnet *ifp, struct ifreq *ifr)
+{
+
+ if (ifp->if_hw_addr == NULL)
+ return (ENODEV);
+
+ switch (ifp->if_type) {
+ case IFT_ETHER:
+ case IFT_IEEE8023ADLAG:
+ bcopy(ifp->if_hw_addr, ifr->ifr_addr.sa_data, ifp->if_addrlen);
+ return (0);
+ default:
+ return (ENODEV);
+ }
+}
+
+/*
* The name argument must be a pointer to storage which will last as
* long as the interface does. For physical devices, the result of
* device_get_name(dev) is a good choice and for pseudo-devices a
OpenPOWER on IntegriCloud