From: Donald Sharp Date: Thu, 30 Mar 2017 19:51:29 +0000 (-0400) Subject: zebra: Retrieve interface speed when creating interface X-Git-Tag: frr-3.1-dev~9^2~3 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=535fe877a9b70084db581e4897452fb4a8dd4e85;p=matthieu%2Ffrr.git zebra: Retrieve interface speed when creating interface 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 --- diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 0a1cafd87e..b1d4dd81d9 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -22,6 +22,8 @@ #include #include +#include +#include #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. */