Common storage of original MAC address
Pokala, Ravi
rpokala at panasas.com
Wed Sep 3 15:55:51 UTC 2014
-----Original Message-----
From: <Pokala>, Ravi Pokala <rpokala at panasas.com>
Date: Tuesday, August 26, 2014 at 11:35 PM
To: "freebsd-hackers at freebsd.org" <freebsd-hackers at freebsd.org>, Ryan
Stone <rysto32 at gmail.com>, Brooks Davis <brooks at freebsd.org>
Subject: Re: Common storage of original MAC address
> Doesn't this restore the original MAC on LAGG teardown?
It looks like that code does indeed restore the working MAC when the lagg
is torn down; see the example output below.
> If someone can enumerate the places where we want to restore the original
> LLADDR but currently don't, then I'll add that.
I never did hear from anyone, but it appears to be moot - as mentioned
above, the LAGG driver restores the original LLADDR.
> If what I've done so far looks good, I'll continue to the next steps:
> changing the places where we want to auto-restore the HW LLADDR (see my
> question above), and updating `ifconfig' to report and restore the HW
> LLADDR.
No one pointed my at places where we want to auto-restore, but don't.
Similarly, since we *do* auto-restore, there's no restore-related change
needed for `ifconfig'. That just leaves reporting, which is included in
the patch below.
If there are no objections to this, could a willing committer contact me
privately so we can work out the details of getting this submitted to
-CURRENT?
Thanks,
Ravi
---------------------------- ghwlladdr.patch ---------------------------
Index: sbin/ifconfig/af_link.c
===================================================================
--- sbin/ifconfig/af_link.c (revision 270916)
+++ sbin/ifconfig/af_link.c (working copy)
@@ -42,6 +42,7 @@
#include <stdlib.h>
#include <string.h>
#include <ifaddrs.h>
+#include <unistd.h>
#include <net/if_dl.h>
#include <net/if_types.h>
@@ -61,9 +62,30 @@
if ((sdl->sdl_type == IFT_ETHER ||
sdl->sdl_type == IFT_L2VLAN ||
sdl->sdl_type == IFT_BRIDGE) &&
- sdl->sdl_alen == ETHER_ADDR_LEN)
+ sdl->sdl_alen == ETHER_ADDR_LEN) {
+ struct ifreq ifr;
+ int s_hw;
printf("\tether %s\n",
ether_ntoa((struct ether_addr *)LLADDR(sdl)));
+ strncpy(ifr.ifr_name, ifa->ifa_name,
+ sizeof(ifr.ifr_name));
+ memcpy(&ifr.ifr_addr, ifa->ifa_addr,
+ sizeof(ifa->ifa_addr->sa_len));
+ ifr.ifr_addr.sa_family = AF_LOCAL;
+ if ((s_hw = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) {
+ warn("socket(AF_LOCAL,SOCK_DGRAM)");
+ return;
+ }
+ if (ioctl(s_hw, SIOCGHWLLADDR, &ifr) < 0) {
+ warn("SIOCGHWLLADDR");
+ close(s_hw);
+ return;
+ }
+ printf("\thwaddr %s\n",
+ ether_ntoa((const struct ether_addr *)
+ &ifr.ifr_addr.sa_data));
+ close(s_hw);
+ }
else {
int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0;
Index: sys/net/if.c
===================================================================
--- sys/net/if.c (revision 270916)
+++ sys/net/if.c (working copy)
@@ -2554,6 +2554,10 @@
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
break;
+ case SIOCGHWLLADDR:
+ error = if_gethwlladdr(ifp, ifr);
+ break;
+
case SIOCAIFGROUP:
{
struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr;
@@ -3427,6 +3431,33 @@
}
/*
+ * Get the link layer address that was read from the hardware at probe.
+ *
+ * At this time we only support certain types of interfaces.
+ */
+int
+if_gethwlladdr(struct ifnet *ifp, struct ifreq *ifr)
+{
+ switch (ifp->if_type) {
+ case IFT_ETHER:
+ case IFT_FDDI:
+ case IFT_XETHER:
+ case IFT_ISO88025:
+ case IFT_L2VLAN:
+ case IFT_BRIDGE:
+ case IFT_ARCNET:
+ case IFT_IEEE8023ADLAG:
+ case IFT_IEEE80211:
+ bcopy(&IFP2AC(ifp)->hw_lladdr, ifr->ifr_addr.sa_data, ETHER_ADDR_LEN);
+ ifr->ifr_addr.sa_len = ETHER_ADDR_LEN;
+ break;
+ default:
+ return (ENODEV);
+ }
+ return (0);
+}
+
+/*
* 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
Index: sys/net/if_arp.h
===================================================================
--- sys/net/if_arp.h (revision 270916)
+++ sys/net/if_arp.h (working copy)
@@ -102,9 +102,11 @@
* Structure shared between the ethernet driver modules and
* the address resolution code.
*/
+#include <net/ethernet.h>
struct arpcom {
struct ifnet *ac_ifp; /* network-visible interface */
void *ac_netgraph; /* ng_ether(4) netgraph node info */
+ struct ether_addr hw_lladdr; /* original lladdr from hardware */
};
#define IFP2AC(ifp) ((struct arpcom *)(ifp->if_l2com))
#define AC2IFP(ac) ((ac)->ac_ifp)
Index: sys/net/if_ethersubr.c
===================================================================
--- sys/net/if_ethersubr.c (revision 270916)
+++ sys/net/if_ethersubr.c (working copy)
@@ -841,6 +841,7 @@
sdl->sdl_type = IFT_ETHER;
sdl->sdl_alen = ifp->if_addrlen;
bcopy(lla, LLADDR(sdl), ifp->if_addrlen);
+ bcopy(lla, &IFP2AC(ifp)->hw_lladdr, ifp->if_addrlen);
bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN);
if (ng_ether_attach_p != NULL)
Index: sys/net/if_var.h
===================================================================
--- sys/net/if_var.h (revision 270916)
+++ sys/net/if_var.h (working copy)
@@ -501,6 +501,7 @@
void if_ref(struct ifnet *);
void if_rele(struct ifnet *);
int if_setlladdr(struct ifnet *, const u_char *, int);
+int if_gethwlladdr(struct ifnet *, struct ifreq *);
void if_up(struct ifnet *);
int ifioctl(struct socket *, u_long, caddr_t, struct thread *);
int ifpromisc(struct ifnet *, int);
Index: sys/sys/sockio.h
===================================================================
--- sys/sys/sockio.h (revision 270916)
+++ sys/sys/sockio.h (working copy)
@@ -97,6 +97,7 @@
#define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */
#define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set linklevel addr
*/
#define SIOCGI2C _IOWR('i', 61, struct ifstat) /* get I2C data */
+#define SIOCGHWLLADDR _IOWR('i', 62, struct ifreq) /* get hw lladdr */
#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif
addres */
#define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr
*/
---------------------------- example output ----------------------------
root at fbsd-X:~ # : Output from 'ifconfig'. Note the new 'hwaddr' line, and
root at fbsd-X:~ # : that it has the same value as the 'ether' line, because
no
root at fbsd-X:~ # : MAC manipulation has been done yet:
root at fbsd-X:~ # ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:9d:28:32
hwaddr 08:00:27:9d:28:32
inet 192.168.1.10 netmask 0xffffff00 broadcast 192.168.1.255
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
em1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:f0:8f:8a
hwaddr 08:00:27:f0:8f:8a
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
em2: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:d2:48:a3
hwaddr 08:00:27:d2:48:a3
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
inet 127.0.0.1 netmask 0xff000000
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
root at fbsd-X:~ # : Create a 'lagg0' from 'em1' and 'em2'
root at fbsd-X:~ # ifconfig lagg0 create laggproto lacp laggport em1 laggport
em2
root at fbsd-X:~ # : Output from 'ifconfig'. Note that 'em2's 'ether' value
has
root at fbsd-X:~ # : changed to match 'em1's 'ether' value, but 'em2's
'hwaddr'
root at fbsd-X:~ # : value is unchanged.
root at fbsd-X:~ # ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:9d:28:32
hwaddr 08:00:27:9d:28:32
inet 192.168.1.10 netmask 0xffffff00 broadcast 192.168.1.255
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
em1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:f0:8f:8a
hwaddr 08:00:27:f0:8f:8a
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
em2: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:f0:8f:8a
hwaddr 08:00:27:d2:48:a3
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
inet 127.0.0.1 netmask 0xff000000
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
lagg0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:f0:8f:8a
hwaddr 00:00:00:00:00:00
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect
status: no carrier
laggproto lacp lagghash l2,l3,l4
laggport: em2 flags=0<>
laggport: em1 flags=0<>
root at fbsd-X:~ # : Destroy lagg0
root at fbsd-X:~ # ifconfig lagg0 destroy
root at fbsd-X:~ # : Output from 'ifconfig'. Note that 'em2's 'ether' value
has
root at fbsd-X:~ # : returned to its original value, which once again matches
root at fbsd-X:~ # : 'em2's 'hwaddr' value, which has remained unchanged.
root at fbsd-X:~ # ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:9d:28:32
hwaddr 08:00:27:9d:28:32
inet 192.168.1.10 netmask 0xffffff00 broadcast 192.168.1.255
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
em1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:f0:8f:8a
hwaddr 08:00:27:f0:8f:8a
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
em2: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 08:00:27:d2:48:a3
hwaddr 08:00:27:d2:48:a3
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
inet 127.0.0.1 netmask 0xff000000
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
root at fbsd-X:~ #
More information about the freebsd-hackers
mailing list