So util.c has a few functions to pretty print interface information like media and link state. These functions are highly system specific and only used by kroute.c and in bgpctl to show kroute internals. This diffs creates a ctl_show_interface struct used in the imsgs between bgpd and bgpctl. The media and link state are passed as strings and so bgpd/kroute.c can create these. This way the code can be moved out of util.c and moved in the more OS specific code.
OK? -- :wq Claudio Index: usr.sbin/bgpctl/bgpctl.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v retrieving revision 1.230 diff -u -p -r1.230 bgpctl.c --- usr.sbin/bgpctl/bgpctl.c 19 Feb 2019 09:15:21 -0000 1.230 +++ usr.sbin/bgpctl/bgpctl.c 21 Feb 2019 10:31:31 -0000 @@ -1080,22 +1080,12 @@ show_nexthop_msg(struct imsg *imsg) printf("unknown address family\n"); return (0); } - if (p->kif.ifname[0]) { - char *s1; - if (p->kif.baudrate) { - if (asprintf(&s1, ", %s", - get_baudrate(p->kif.baudrate, - "bps")) == -1) - err(1, NULL); - } else if (asprintf(&s1, ", %s", get_linkstate( - p->kif.if_type, p->kif.link_state)) == -1) - err(1, NULL); - if (asprintf(&s, "%s (%s%s)", p->kif.ifname, - p->kif.flags & IFF_UP ? "UP" : "DOWN", s1) == -1) - err(1, NULL); - printf("%-15s", s); - free(s1); - free(s); + if (p->iface.ifname[0]) { + printf("%s (%s, %s)", p->iface.ifname, + p->iface.is_up ? "UP" : "DOWN", + p->iface.baudrate ? + get_baudrate(p->iface.baudrate, "bps") : + p->iface.linkstate); } printf("\n"); break; @@ -1120,24 +1110,22 @@ show_interface_head(void) int show_interface_msg(struct imsg *imsg) { - struct kif *k; - uint64_t ifms_type; + struct ctl_show_interface *iface; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_INTERFACE: - k = imsg->data; - printf("%-15s", k->ifname); - printf("%-9u", k->rdomain); - printf("%-9s", k->nh_reachable ? "ok" : "invalid"); - printf("%-7s", k->flags & IFF_UP ? "UP" : ""); + iface = imsg->data; + printf("%-15s", iface->ifname); + printf("%-9u", iface->rdomain); + printf("%-9s", iface->nh_reachable ? "ok" : "invalid"); + printf("%-7s", iface->is_up ? "UP" : ""); + + if (iface->media[0]) + printf("%s, ", iface->media); + printf("%s", iface->linkstate); - if ((ifms_type = ift2ifm(k->if_type)) != 0) - printf("%s, ", get_media_descr(ifms_type)); - - printf("%s", get_linkstate(k->if_type, k->link_state)); - - if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) - printf(", %s", get_baudrate(k->baudrate, "Bit/s")); + if (iface->baudrate > 0) + printf(", %s", get_baudrate(iface->baudrate, "Bit/s")); printf("\n"); break; case IMSG_CTL_END: Index: usr.sbin/bgpd/bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.373 diff -u -p -r1.373 bgpd.h --- usr.sbin/bgpd/bgpd.h 19 Feb 2019 09:13:23 -0000 1.373 +++ usr.sbin/bgpd/bgpd.h 21 Feb 2019 10:26:59 -0000 @@ -656,15 +656,25 @@ struct pftable_msg { u_int8_t len; }; +struct ctl_show_interface { + char ifname[IFNAMSIZ]; + char linkstate[32]; + char media[32]; + u_int64_t baudrate; + u_int rdomain; + u_int8_t nh_reachable; + u_int8_t is_up; +}; + struct ctl_show_nexthop { - struct bgpd_addr addr; - struct kif kif; + struct bgpd_addr addr; + struct ctl_show_interface iface; union { struct kroute kr4; struct kroute6 kr6; } kr; - u_int8_t valid; - u_int8_t krvalid; + u_int8_t valid; + u_int8_t krvalid; }; struct ctl_neighbor { @@ -1292,9 +1302,6 @@ sa_family_t aid2af(u_int8_t); int af2aid(sa_family_t, u_int8_t, u_int8_t *); struct sockaddr *addr2sa(struct bgpd_addr *, u_int16_t, socklen_t *); void sa2addr(struct sockaddr *, struct bgpd_addr *); -uint64_t ift2ifm(uint8_t); -const char * get_media_descr(uint64_t); -const char * get_linkstate(uint8_t, int); const char * get_baudrate(unsigned long long, char *); static const char * const log_procnames[] = { Index: usr.sbin/bgpd/kroute.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v retrieving revision 1.232 diff -u -p -r1.232 kroute.c --- usr.sbin/bgpd/kroute.c 18 Feb 2019 09:58:19 -0000 1.232 +++ usr.sbin/bgpd/kroute.c 21 Feb 2019 10:28:20 -0000 @@ -26,6 +26,7 @@ #include <arpa/inet.h> #include <net/if.h> #include <net/if_dl.h> +#include <net/if_media.h> #include <net/if_types.h> #include <net/route.h> #include <netmpls/mpls.h> @@ -171,6 +172,9 @@ int protect_lo(struct ktable *); u_int8_t prefixlen_classful(in_addr_t); u_int8_t mask2prefixlen(in_addr_t); u_int8_t mask2prefixlen6(struct sockaddr_in6 *); +uint64_t ift2ifm(uint8_t); +const char *get_media_descr(uint64_t); +const char *get_linkstate(uint8_t, int); void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); void if_change(u_short, int, struct if_data *, u_int); void if_announce(void *, u_int); @@ -1011,6 +1015,30 @@ kr_nexthop_delete(u_int rtableid, struct knexthop_remove(kt, kn); } +static struct ctl_show_interface * +kr_show_interface(struct kif *kif) +{ + static struct ctl_show_interface iface; + uint64_t ifms_type; + + bzero(&iface, sizeof(iface)); + strlcpy(iface.ifname, kif->ifname, sizeof(iface.ifname)); + + snprintf(iface.linkstate, sizeof(iface.linkstate), + "%s", get_linkstate(kif->if_type, kif->link_state)); + + if ((ifms_type = ift2ifm(kif->if_type)) != 0) + snprintf(iface.media, sizeof(iface.media), + "%s", get_media_descr(ifms_type)); + + iface.baudrate = kif->baudrate; + iface.rdomain = kif->rdomain; + iface.nh_reachable = kif->nh_reachable; + iface.is_up = (kif->flags & IFF_UP) == IFF_UP; + + return &iface; +} + void kr_show_route(struct imsg *imsg) { @@ -1125,8 +1153,9 @@ kr_show_route(struct imsg *imsg) break; } if ((kif = kif_find(ifindex)) != NULL) - memcpy(&snh.kif, &kif->k, - sizeof(snh.kif)); + memcpy(&snh.iface, + kr_show_interface(&kif->k), + sizeof(snh.iface)); } send_imsg_session(IMSG_CTL_SHOW_NEXTHOP, imsg->hdr.pid, &snh, sizeof(snh)); @@ -1135,7 +1164,8 @@ kr_show_route(struct imsg *imsg) case IMSG_CTL_SHOW_INTERFACE: RB_FOREACH(kif, kif_tree, &kit) send_imsg_session(IMSG_CTL_SHOW_INTERFACE, - imsg->hdr.pid, &kif->k, sizeof(kif->k)); + imsg->hdr.pid, kr_show_interface(&kif->k), + sizeof(struct ctl_show_interface)); break; case IMSG_CTL_SHOW_FIB_TABLES: for (i = 0; i < krt_size; i++) { @@ -2627,6 +2657,54 @@ prefixlen2mask6(u_int8_t prefixlen) mask.s6_addr[prefixlen / 8] = 0xff00 >> i; return (&mask); +} + +const struct if_status_description + if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; +const struct ifmedia_description + ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; + +uint64_t +ift2ifm(uint8_t if_type) +{ + switch (if_type) { + case IFT_ETHER: + return (IFM_ETHER); + case IFT_FDDI: + return (IFM_FDDI); + case IFT_CARP: + return (IFM_CARP); + case IFT_IEEE80211: + return (IFM_IEEE80211); + default: + return (0); + } +} + +const char * +get_media_descr(uint64_t media_type) +{ + const struct ifmedia_description *p; + + for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) + if (media_type == p->ifmt_word) + return (p->ifmt_string); + + return ("unknown media"); +} + +const char * +get_linkstate(uint8_t if_type, int link_state) +{ + const struct if_status_description *p; + static char buf[8]; + + for (p = if_status_descriptions; p->ifs_string != NULL; p++) { + if (LINK_STATE_DESC_MATCH(p, if_type, link_state)) + return (p->ifs_string); + } + snprintf(buf, sizeof(buf), "[#%d]", link_state); + return (buf); } #define ROUNDUP(a) \ Index: usr.sbin/bgpd/util.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/util.c,v retrieving revision 1.45 diff -u -p -r1.45 util.c --- usr.sbin/bgpd/util.c 18 Feb 2019 12:35:08 -0000 1.45 +++ usr.sbin/bgpd/util.c 21 Feb 2019 10:07:56 -0000 @@ -18,9 +18,6 @@ */ #include <sys/types.h> #include <sys/socket.h> -#include <net/if.h> -#include <net/if_media.h> -#include <net/if_types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> @@ -888,68 +885,23 @@ sa2addr(struct sockaddr *sa, struct bgpd } } -const struct if_status_description - if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; -const struct ifmedia_description - ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; - -uint64_t -ift2ifm(uint8_t if_type) -{ - switch (if_type) { - case IFT_ETHER: - return (IFM_ETHER); - case IFT_FDDI: - return (IFM_FDDI); - case IFT_CARP: - return (IFM_CARP); - case IFT_IEEE80211: - return (IFM_IEEE80211); - default: - return (0); - } -} - -const char * -get_media_descr(uint64_t media_type) -{ - const struct ifmedia_description *p; - - for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) - if (media_type == p->ifmt_word) - return (p->ifmt_string); - - return ("unknown media"); -} - -const char * -get_linkstate(uint8_t if_type, int link_state) -{ - const struct if_status_description *p; - static char buf[8]; - - for (p = if_status_descriptions; p->ifs_string != NULL; p++) { - if (LINK_STATE_DESC_MATCH(p, if_type, link_state)) - return (p->ifs_string); - } - snprintf(buf, sizeof(buf), "[#%d]", link_state); - return (buf); -} - const char * get_baudrate(unsigned long long baudrate, char *unit) { static char bbuf[16]; + const unsigned long long kilo = 1000; + const unsigned long long mega = 1000ULL * kilo; + const unsigned long long giga = 1000ULL * mega; - if (baudrate > IF_Gbps(1)) + if (baudrate > giga) snprintf(bbuf, sizeof(bbuf), "%llu G%s", - baudrate / IF_Gbps(1), unit); - else if (baudrate > IF_Mbps(1)) + baudrate / giga, unit); + else if (baudrate > mega) snprintf(bbuf, sizeof(bbuf), "%llu M%s", - baudrate / IF_Mbps(1), unit); - else if (baudrate > IF_Kbps(1)) + baudrate / mega, unit); + else if (baudrate > kilo) snprintf(bbuf, sizeof(bbuf), "%llu K%s", - baudrate / IF_Kbps(1), unit); + baudrate / kilo, unit); else snprintf(bbuf, sizeof(bbuf), "%llu %s", baudrate, unit);