summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/if.h3
-rw-r--r--lib/zclient.c3
-rw-r--r--zebra/if_netlink.c44
-rw-r--r--zebra/interface.c4
-rw-r--r--zebra/zserv.c1
5 files changed, 53 insertions, 2 deletions
diff --git a/lib/if.h b/lib/if.h
index 49f2a52478..e8e84ffc88 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -229,6 +229,9 @@ struct interface
/* Interface metric */
uint32_t metric;
+ /* Interface Speed in Mb/s */
+ uint32_t speed;
+
/* Interface MTU. */
unsigned int mtu; /* IPv4 MTU */
unsigned int mtu6; /* IPv6 MTU - probably, but not neccessarily same as mtu */
diff --git a/lib/zclient.c b/lib/zclient.c
index 4455644345..71b95ae7db 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1003,6 +1003,8 @@ zebra_router_id_update_read (struct stream *s, struct prefix *rid)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | metric |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | speed |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ifmtu |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ifmtu6 |
@@ -1185,6 +1187,7 @@ zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
ifp->ptm_enable = stream_getc (s);
ifp->ptm_status = stream_getc (s);
ifp->metric = stream_getl (s);
+ ifp->speed = stream_getl (s);
ifp->mtu = stream_getl (s);
ifp->mtu6 = stream_getl (s);
ifp->bandwidth = stream_getl (s);
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 0a1cafd87e..28538fabdf 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,47 @@ 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));
+ ecmd.speed_hi = 0;
+ ecmd.speed = 0;
+ }
+
+ 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 +425,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. */
diff --git a/zebra/interface.c b/zebra/interface.c
index e9c54a629b..1d015e8588 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -1056,8 +1056,8 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
return;
}
- vty_out (vty, " index %d metric %d mtu %d ",
- ifp->ifindex, ifp->metric, ifp->mtu);
+ vty_out (vty, " index %d metric %d mtu %d speed %u ",
+ ifp->ifindex, ifp->metric, ifp->mtu, ifp->speed);
if (ifp->mtu6 != ifp->mtu)
vty_out (vty, "mtu6 %d ", ifp->mtu6);
vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
diff --git a/zebra/zserv.c b/zebra/zserv.c
index f9205a12c8..85fdd53122 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -167,6 +167,7 @@ zserv_encode_interface (struct stream *s, struct interface *ifp)
stream_putc (s, ifp->ptm_enable);
stream_putc (s, ifp->ptm_status);
stream_putl (s, ifp->metric);
+ stream_putl (s, ifp->speed);
stream_putl (s, ifp->mtu);
stream_putl (s, ifp->mtu6);
stream_putl (s, ifp->bandwidth);