]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Retrieve interface speed when creating interface
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 30 Mar 2017 19:51:29 +0000 (15:51 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 3 Apr 2017 18:49:35 +0000 (14:49 -0400)
When we get notification from the kernel about the creation
of a new interface, retrieve the speed of it from the kernel

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/if_netlink.c

index 0a1cafd87e6a98c9032452235fdfc4a99628a608..b1d4dd81d9141c18b3d63cff19c4dd6f98427168 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <zebra.h>
 #include <net/if_arp.h>
+#include <linux/sockios.h>
+#include <linux/ethtool.h>
 
 #include "linklist.h"
 #include "if.h"
@@ -298,6 +300,45 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
     }
 }
 
+static int
+get_iflink_speed (const char *ifname)
+{
+  struct ifreq ifdata;
+  struct ethtool_cmd ecmd;
+  int sd;
+  int rc;
+
+  /* initialize struct */
+  memset(&ifdata, 0, sizeof(ifdata));
+
+  /* set interface name */
+  strcpy(ifdata.ifr_name, ifname);
+
+  /* initialize ethtool interface */
+  memset(&ecmd, 0, sizeof(ecmd));
+  ecmd.cmd = ETHTOOL_GSET;  /* ETHTOOL_GLINK */
+  ifdata.ifr_data = (__caddr_t) &ecmd;
+
+  /* use ioctl to get IP address of an interface */
+  sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+  if(sd < 0) {
+    zlog_debug ("Failure to read interface %s speed: %d %s",
+                ifname, errno, safe_strerror(errno));
+    return 0;
+  }
+
+  /* Get the current link state for the interface */
+  rc = ioctl(sd, SIOCETHTOOL, (char *)&ifdata);
+  if(rc < 0) {
+    zlog_debug ("IOCTL failure to read interface %s speed: %d %s",
+                ifname, errno, safe_strerror(errno));
+  }
+
+  close(sd);
+
+  return (ecmd.speed_hi << 16 ) | ecmd.speed;
+}
+
 /* Called from interface_lookup_netlink().  This function is only used
    during bootstrap. */
 static int
@@ -382,6 +423,7 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
     SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
   ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
   ifp->metric = 0;
+  ifp->speed = get_iflink_speed (name);
   ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
 
   /* Hardware type and address. */