Page MenuHomeFreeBSD

Persistently store NIC's hardware MAC address, and add a way to retrive it
ClosedPublic

Authored by rpokala on May 5 2017, 8:47 AM.

Details

Summary

The MAC address reported by `ifconfig ${nic} ether' does not always match
the address in the hardware, as reported by the driver during attach. In
particular, NICs which are components of a lagg(4) interface all report the
same MAC.

When attaching, the NIC driver passes the MAC address it read from the
hardware as an argument to ether_ifattach(). Keep a second copy of it, and
create ioctl(SIOCGHWADDR) to return it. Teach `ifconfig' to report it along
with the active MAC address.

Test Plan

% ifconfig ix0 ether # both "ether" and "hwaddr" end in "3b"
ix0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3b
hwaddr 0c:c4:7a:7c:0d:3b
% ifconfig ix1 ether # both "ether" and "hwaddr" end in "3a"
ix1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3a
hwaddr 0c:c4:7a:7c:0d:3a
% sudo ifconfig lagg0 create # Create a lagg device
% ifconfig lagg0 ether # "ether" is zeroed, and "hwaddr" does not exist
lagg0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=800000<>
ether 00:00:00:00:00:00
% sudo ifconfig lagg0 laggport ix0 # Add ix0 to lagg0
% ifconfig lagg0 ether # The lagg's "ether" is now the same as ix0's
lagg0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3b
% ifconfig ix0 ether # No change to ix0's "ether" or "hwaddr"
ix0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3b
hwaddr 0c:c4:7a:7c:0d:3b
% ifconfig ix1 ether # No change to ix1's "ether" or "hwaddr"
ix1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3a
hwaddr 0c:c4:7a:7c:0d:3a
% sudo ifconfig lagg0 laggport ix1 # Add ix1 to lagg0
% ifconfig lagg0 ether # No change to lagg0's "ether"
lagg0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3b
% ifconfig ix0 ether # No change to ix0's "ether" or "hwaddr"
ix0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3b
hwaddr 0c:c4:7a:7c:0d:3b
% ifconfig ix1 ether # ix1's "ether" changed to match lagg0's ; "hwaddr" unchanged
ix1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3b
hwaddr 0c:c4:7a:7c:0d:3a
% sudo ifconfig lagg0 destroy # Destroy lagg0
% ifconfig ix0 ether # No change to ix0's "ether" or "hwaddr"
ix0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3b
hwaddr 0c:c4:7a:7c:0d:3b
% ifconfig ix1 ether # ix1's "ether" returned to original "3a" value; "hwaddr" never changed
ix1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=e407bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6>
ether 0c:c4:7a:7c:0d:3a
hwaddr 0c:c4:7a:7c:0d:3a

Diff Detail

Repository
rS FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

brooks added inline comments.
sys/net/if.c
748 ↗(On Diff #28052)

I wonder if it makes more sense to allocate in ether_ifattach.

sys/net/if.c
748 ↗(On Diff #28052)

ether_ifattach() doesn't do any allocations, while most of the allocations for the ifnet are here, so that's what I went with.

sys/net/if.c
748 ↗(On Diff #28052)

Is it possible to at least make it conditional on the interface type? It seems like a poor idea to allocate memory isn't used.

sys/net/if.c
748 ↗(On Diff #28052)

Good point. I'll make it conditional on (ifp->if_type == IFT_ETHER), and also add a NULL-check in if_gethwaddr().

Address review comments from brooks: only store / retrieve for IFT_ETHER.

@glebius - Please review at your earliest convenience. If you don't think you can get to it in the next week, I'll find someone else. Thanks!

This revision is now accepted and ready to land.May 10 2017, 9:48 PM
This revision was automatically updated to reflect the committed changes.