zebra: set the interface link-layer socket address

* kernel_socket.c: (ifm_read) The reorganization from commit
  6fe70d1b35c189cb1e488b2c26551ba7baac6148 removed setting the
  interface link-layer socket address structure on routing socket
  platforms.  This restores saving the link-layer information because
  it might be used elsewhere: rtm_write() when no gateway is given,
  if_dump_vty() and rtadv_send_packet().
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index feeaf5d..bd129dc 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -319,6 +319,7 @@
 ifm_read (struct if_msghdr *ifm)
 {
   struct interface *ifp = NULL;
+  struct sockaddr_dl *sdl;
   char ifname[IFNAMSIZ];
   short ifnlen = 0;
   caddr_t *cp;
@@ -356,6 +357,7 @@
   RTA_ADDR_GET (NULL, RTA_GATEWAY, ifm->ifm_addrs, cp);
   RTA_ATTR_GET (NULL, RTA_NETMASK, ifm->ifm_addrs, cp);
   RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifm_addrs, cp);
+  sdl = (struct sockaddr_dl *)cp;
   RTA_NAME_GET (ifname, RTA_IFP, ifm->ifm_addrs, cp, ifnlen);
   RTA_ADDR_GET (NULL, RTA_IFA, ifm->ifm_addrs, cp);
   RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifm_addrs, cp);
@@ -454,6 +456,16 @@
 #endif /* __bsdi__ */
       if_get_metric (ifp);
 
+      /*
+       * XXX sockaddr_dl contents can be larger than the structure
+       * definition, so the user of the stored structure must be
+       * careful not to read off the end.
+       *
+       * a nonzero ifnlen from RTA_NAME_GET() means sdl is valid
+       */
+      if (ifnlen)
+	memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl));
+
       if_add_update (ifp);
     }
   else