diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-03-30 21:51:29 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-04-03 20:49:35 +0200 |
commit | 535fe877a9b70084db581e4897452fb4a8dd4e85 (patch) | |
tree | 5e438c831e8b6762d111506d3ac112bbb2bb771b /zebra | |
parent | lib, zebra: Add ability to pass interface speed up from zebra (diff) | |
download | frr-535fe877a9b70084db581e4897452fb4a8dd4e85.tar.xz frr-535fe877a9b70084db581e4897452fb4a8dd4e85.zip |
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 <sharpd@cumulusnetworks.com>
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/if_netlink.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 0a1cafd87..b1d4dd81d 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -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. */ |