From owner-freebsd-hackers@FreeBSD.ORG Wed Sep 3 15:55:51 2014 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2EB1A251; Wed, 3 Sep 2014 15:55:51 +0000 (UTC) Received: from mon-colo.panasas.com (mon-colo.panasas.com [209.166.131.137]) by mx1.freebsd.org (Postfix) with ESMTP id C306B1D73; Wed, 3 Sep 2014 15:55:50 +0000 (UTC) Received: from seabiscuit.panasas.com ([172.17.132.204]) by mon-colo.panasas.com with Microsoft SMTPSVC(7.0.6001.18000); Tue, 2 Sep 2014 21:38:55 -0400 Received: from SEABISCUIT.int.panasas.com ([172.17.132.204]) by seabiscuit ([172.17.132.204]) with mapi id 14.03.0181.006; Tue, 2 Sep 2014 18:38:55 -0700 From: "Pokala, Ravi" To: "freebsd-hackers@freebsd.org" , Ryan Stone , Brooks Davis Subject: Re: Common storage of original MAC address Thread-Topic: Common storage of original MAC address Thread-Index: AQHPxxfSUBEgYXTq+ky03AEN5pUz3Q== Date: Wed, 3 Sep 2014 01:38:55 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Microsoft-MacOutlook/14.4.4.140807 x-originating-ip: [172.17.142.184] Content-Type: text/plain; charset="us-ascii" Content-ID: <9D0E018AFADB1F4DA4EB71139D1C3B8A@panasas.com> Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginalArrivalTime: 03 Sep 2014 01:38:55.0977 (UTC) FILETIME=[D345B590:01CFC717] X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Sep 2014 15:55:51 -0000 -----Original Message----- From: , Ravi Pokala Date: Tuesday, August 26, 2014 at 11:35 PM To: "freebsd-hackers@freebsd.org" , Ryan Stone , Brooks Davis 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sbin/ifconfig/af_link.c (revision 270916) +++ sbin/ifconfig/af_link.c (working copy) @@ -42,6 +42,7 @@ #include #include #include +#include =20 #include #include @@ -61,9 +62,30 @@ if ((sdl->sdl_type =3D=3D IFT_ETHER || sdl->sdl_type =3D=3D IFT_L2VLAN || sdl->sdl_type =3D=3D IFT_BRIDGE) && - sdl->sdl_alen =3D=3D ETHER_ADDR_LEN) + sdl->sdl_alen =3D=3D 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 =3D AF_LOCAL; + if ((s_hw =3D 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 =3D sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; =20 Index: sys/net/if.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/net/if.c (revision 270916) +++ sys/net/if.c (working copy) @@ -2554,6 +2554,10 @@ EVENTHANDLER_INVOKE(iflladdr_event, ifp); break; =20 + case SIOCGHWLLADDR: + error =3D if_gethwlladdr(ifp, ifr); + break; + case SIOCAIFGROUP: { struct ifgroupreq *ifgr =3D (struct ifgroupreq *)ifr; @@ -3427,6 +3431,33 @@ } =20 /* + * 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 =3D 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/net/if_ethersubr.c (revision 270916) +++ sys/net/if_ethersubr.c (working copy) @@ -841,6 +841,7 @@ sdl->sdl_type =3D IFT_ETHER; sdl->sdl_alen =3D ifp->if_addrlen; bcopy(lla, LLADDR(sdl), ifp->if_addrlen); + bcopy(lla, &IFP2AC(ifp)->hw_lladdr, ifp->if_addrlen); =20 bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN); if (ng_ether_attach_p !=3D NULL) Index: sys/net/if_var.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 */ =20 #define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif addres */ #define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */ ---------------------------- example output ---------------------------- root@fbsd-X:~ # : Output from 'ifconfig'. Note the new 'hwaddr' line, and root@fbsd-X:~ # : that it has the same value as the 'ether' line, because no root@fbsd-X:~ # : MAC manipulation has been done yet: root@fbsd-X:~ # ifconfig em0: flags=3D8843 metric 0 mtu 1500 options=3D9b 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=3D29 media: Ethernet autoselect (1000baseT ) status: active em1: flags=3D8802 metric 0 mtu 1500 options=3D9b ether 08:00:27:f0:8f:8a hwaddr 08:00:27:f0:8f:8a nd6 options=3D29 media: Ethernet autoselect (1000baseT ) status: active em2: flags=3D8802 metric 0 mtu 1500 options=3D9b ether 08:00:27:d2:48:a3 hwaddr 08:00:27:d2:48:a3 nd6 options=3D29 media: Ethernet autoselect (1000baseT ) status: active lo0: flags=3D8049 metric 0 mtu 16384 options=3D600003 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 inet 127.0.0.1 netmask 0xff000000 nd6 options=3D21 root@fbsd-X:~ # : Create a 'lagg0' from 'em1' and 'em2' root@fbsd-X:~ # ifconfig lagg0 create laggproto lacp laggport em1 laggport em2 root@fbsd-X:~ # : Output from 'ifconfig'. Note that 'em2's 'ether' value has root@fbsd-X:~ # : changed to match 'em1's 'ether' value, but 'em2's 'hwaddr' root@fbsd-X:~ # : value is unchanged. root@fbsd-X:~ # ifconfig em0: flags=3D8843 metric 0 mtu 1500 options=3D9b 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=3D29 media: Ethernet autoselect (1000baseT ) status: active em1: flags=3D8802 metric 0 mtu 1500 options=3D9b ether 08:00:27:f0:8f:8a hwaddr 08:00:27:f0:8f:8a nd6 options=3D29 media: Ethernet autoselect (1000baseT ) status: active em2: flags=3D8802 metric 0 mtu 1500 options=3D9b ether 08:00:27:f0:8f:8a hwaddr 08:00:27:d2:48:a3 nd6 options=3D29 media: Ethernet autoselect (1000baseT ) status: active lo0: flags=3D8049 metric 0 mtu 16384 options=3D600003 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 inet 127.0.0.1 netmask 0xff000000 nd6 options=3D21 lagg0: flags=3D8802 metric 0 mtu 1500 options=3D9b ether 08:00:27:f0:8f:8a hwaddr 00:00:00:00:00:00 nd6 options=3D29 media: Ethernet autoselect status: no carrier laggproto lacp lagghash l2,l3,l4 laggport: em2 flags=3D0<> laggport: em1 flags=3D0<> root@fbsd-X:~ # : Destroy lagg0 root@fbsd-X:~ # ifconfig lagg0 destroy root@fbsd-X:~ # : Output from 'ifconfig'. Note that 'em2's 'ether' value has root@fbsd-X:~ # : returned to its original value, which once again matches root@fbsd-X:~ # : 'em2's 'hwaddr' value, which has remained unchanged. root@fbsd-X:~ # ifconfig em0: flags=3D8843 metric 0 mtu 1500 options=3D9b 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=3D29 media: Ethernet autoselect (1000baseT ) status: active em1: flags=3D8802 metric 0 mtu 1500 options=3D9b ether 08:00:27:f0:8f:8a hwaddr 08:00:27:f0:8f:8a nd6 options=3D29 media: Ethernet autoselect (1000baseT ) status: active em2: flags=3D8802 metric 0 mtu 1500 options=3D9b ether 08:00:27:d2:48:a3 hwaddr 08:00:27:d2:48:a3 nd6 options=3D29 media: Ethernet autoselect (1000baseT ) status: active lo0: flags=3D8049 metric 0 mtu 16384 options=3D600003 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 inet 127.0.0.1 netmask 0xff000000 nd6 options=3D21 root@fbsd-X:~ #=09