diff options
-rw-r--r-- | include/netlink-private/route/link/sriov.h | 2 | ||||
-rw-r--r-- | lib/route/link.c | 6 | ||||
-rw-r--r-- | lib/route/link/sriov.c | 138 | ||||
-rw-r--r-- | libnl-route-3.sym | 2 |
4 files changed, 148 insertions, 0 deletions
diff --git a/include/netlink-private/route/link/sriov.h b/include/netlink-private/route/link/sriov.h index ac823fa5..dccee1e9 100644 --- a/include/netlink-private/route/link/sriov.h +++ b/include/netlink-private/route/link/sriov.h @@ -21,6 +21,8 @@ extern "C" { #endif extern int rtnl_link_sriov_clone(struct rtnl_link *, struct rtnl_link *); +extern void rtnl_link_sriov_dump_details(struct rtnl_link *, struct nl_dump_params *); +extern void rtnl_link_sriov_dump_stats(struct rtnl_link *, struct nl_dump_params *); extern void rtnl_link_sriov_free_data(struct rtnl_link *); extern int rtnl_link_sriov_parse_vflist(struct rtnl_link *, struct nlattr **); diff --git a/lib/route/link.c b/lib/route/link.c index 5610ee01..8bb9f256 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -881,6 +881,9 @@ static void link_dump_details(struct nl_object *obj, struct nl_dump_params *p) link->l_info_ops->io_dump[NL_DUMP_DETAILS](link, p); do_foreach_af(link, af_dump_details, p); + + if (link->ce_mask & LINK_ATTR_VF_LIST) + rtnl_link_sriov_dump_details(link, p); } static void link_dump_stats(struct nl_object *obj, struct nl_dump_params *p) @@ -946,6 +949,9 @@ static void link_dump_stats(struct nl_object *obj, struct nl_dump_params *p) link->l_info_ops->io_dump[NL_DUMP_STATS](link, p); do_foreach_af(link, af_dump_stats, p); + + if (link->ce_mask & LINK_ATTR_VF_LIST) + rtnl_link_sriov_dump_stats(link, p); } #if 0 diff --git a/lib/route/link/sriov.c b/lib/route/link/sriov.c index 5f083e94..d91f1dab 100644 --- a/lib/route/link/sriov.c +++ b/lib/route/link/sriov.c @@ -37,6 +37,9 @@ /** @cond SKIP */ +#define SRIOVON "on" +#define SRIOVOFF "off" + #define SET_VF_STAT(link, vf_num, stb, stat, attr) \ vf_data->vf_stats[stat] = nla_get_u64(stb[attr]) @@ -131,6 +134,141 @@ int rtnl_link_sriov_clone(struct rtnl_link *dst, struct rtnl_link *src) { return 0; } +/* Dump VLAN details for each SRIOV VF */ +static void dump_sriov_vlans(nl_vf_vlans_t *vlans, + struct nl_dump_params *p) { + char buf[64]; + int cur = 0; + nl_vf_vlan_info_t *vlan_data; + uint16_t prot; + + vlan_data = vlans->vlans; + nl_dump(p, "\t VLANS:\n"); + while (cur < vlans->size) { + nl_dump(p, "\t vlan %u", vlan_data[cur].vf_vlan); + if (vlan_data[cur].vf_vlan_qos) + nl_dump(p, " qos %u", vlan_data[cur].vf_vlan_qos); + if (vlan_data[cur].vf_vlan_proto) { + prot = vlan_data[cur].vf_vlan_proto; + nl_dump(p, " proto %s", + rtnl_link_vf_vlanproto2str(prot, buf, + sizeof(buf))); + } + nl_dump(p, "\n"); + cur++; + } + + return; +} + +/* Dump details for each SRIOV VF */ +static void dump_vf_details(struct rtnl_link_vf *vf_data, + struct nl_dump_params *p) { + char buf[64]; + int err = 0; + struct nl_vf_rate vf_rate; + uint32_t v = 0; + + nl_dump(p, "\tvf %u: ", vf_data->vf_index); + if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) { + v = vf_data->vf_linkstate; + nl_dump(p, "state %s ", + rtnl_link_vf_linkstate2str(v, buf, sizeof(buf))); + } + if (vf_data->ce_mask & SRIOV_ATTR_ADDR) { + nl_dump(p, "addr %s ", + nl_addr2str(vf_data->vf_lladdr, buf, sizeof(buf))); + } + nl_dump(p, "\n"); + + v = vf_data->vf_spoofchk; + nl_dump(p, "\t spoofchk %s ", v ? SRIOVON : SRIOVOFF); + v = vf_data->vf_trust; + nl_dump(p, "trust %s ", v ? SRIOVON : SRIOVOFF); + v = vf_data->vf_rss_query_en; + nl_dump(p, "rss_query %s\n", v ? SRIOVON : SRIOVOFF); + + err = rtnl_link_vf_get_rate(vf_data, &vf_rate); + if (!err) { + if (vf_rate.api == RTNL_LINK_VF_RATE_API_OLD) + nl_dump(p, "\t rate_api old rate %u\n", + vf_rate.rate); + else if (vf_rate.api == RTNL_LINK_VF_RATE_API_NEW) + nl_dump(p, "\t rate_api new min_rate %u " + "max_rate %u\n", vf_rate.min_tx_rate, + vf_rate.max_tx_rate); + } + if (vf_data->ce_mask & SRIOV_ATTR_VLAN) + dump_sriov_vlans(vf_data->vf_vlans, p); + + return; +} + +/* Loop through SRIOV VF list dump details */ +void rtnl_link_sriov_dump_details(struct rtnl_link *link, + struct nl_dump_params *p) { + int err; + struct rtnl_link_vf *vf_data, *list, *next; + + if (!(err = rtnl_link_has_vf_list(link))) + BUG(); + + nl_dump(p, " SRIOV VF List\n"); + list = link->l_vf_list; + nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) { + if (vf_data->ce_mask & SRIOV_ATTR_INDEX) + dump_vf_details(vf_data, p); + } + + return; +} + +/* Dump stats for each SRIOV VF */ +static void dump_vf_stats(struct rtnl_link_vf *vf_data, + struct nl_dump_params *p) { + char *unit; + float res; + + nl_dump(p, " VF %" PRIu64 " Stats:\n", vf_data->vf_index); + nl_dump_line(p, "\tRX: %-14s %-10s %-10s %-10s\n", + "bytes", "packets", "multicast", "broadcast"); + + res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_BYTES], + &unit); + + nl_dump_line(p, + "\t%10.2f %3s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n", + res, unit, + vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_PACKETS], + vf_data->vf_stats[RTNL_LINK_VF_STATS_MULTICAST], + vf_data->vf_stats[RTNL_LINK_VF_STATS_BROADCAST]); + + nl_dump_line(p, "\tTX: %-14s %-10s\n", "bytes", "packets"); + + res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_BYTES], + &unit); + + nl_dump_line(p, "\t%10.2f %3s %10" PRIu64 "\n", res, unit, + vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_PACKETS]); + + return; +} + +/* Loop through SRIOV VF list dump stats */ +void rtnl_link_sriov_dump_stats(struct rtnl_link *link, + struct nl_dump_params *p) { + struct rtnl_link_vf *vf_data, *list, *next; + + list = link->l_vf_list; + nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) { + if (vf_data->ce_mask & SRIOV_ATTR_INDEX) + dump_vf_stats(vf_data, p); + } + nl_dump(p, "\n"); + + return; +} + /* Free stored SRIOV VF data */ void rtnl_link_sriov_free_data(struct rtnl_link *link) { int err = 0; diff --git a/libnl-route-3.sym b/libnl-route-3.sym index 67e705d4..a96f7403 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -988,6 +988,8 @@ global: rtnl_link_set_vf_list; rtnl_link_unset_vf_list; rtnl_link_sriov_clone; + rtnl_link_sriov_dump_details; + rtnl_link_sriov_dump_stats; rtnl_link_sriov_free_data; rtnl_link_sriov_parse_vflist; rtnl_link_vf_alloc; |