> -----Original Message----- > From: Hangbin Liu [mailto:liuhang...@gmail.com] > Sent: Saturday, July 15, 2017 6:33 AM > To: linuxptp-devel@lists.sourceforge.net > Cc: Sushil Kulkarni <sukul...@redhat.com>; Jiri Benc <jb...@redhat.com> > Subject: [Linuxptp-devel] [PATCHv2 4/9] rtnl: add function rtnl_link_info > > Add function rtnl_link_info() to get bond's active interface. If there is > no slave interface, then use our own name as ts interface. > > Also add new parameter ts_iface for call back function port_link_status() > to make aware of interface change. > > Signed-off-by: Hangbin Liu <liuhang...@gmail.com> > --- > port.c | 2 +- > rtnl.c | 122 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++- > rtnl.h | 10 +++++- > 3 files changed, 131 insertions(+), 3 deletions(-) > > diff --git a/port.c b/port.c > index 21ab3ea..834eb45 100644 > --- a/port.c > +++ b/port.c > @@ -2221,7 +2221,7 @@ void port_dispatch(struct port *p, enum fsm_event > event, int mdiff) > } > } > > -static void port_link_status(void *ctx, int index, int linkup) > +static void port_link_status(void *ctx, int index, int linkup, char > *ts_iface) > { > struct port *p = ctx; > > diff --git a/rtnl.c b/rtnl.c > index 04e1918..b499467 100644 > --- a/rtnl.c > +++ b/rtnl.c > @@ -31,6 +31,9 @@ > > static int rtnl_len; > static char *rtnl_buf; > +static int rtnl_rtattr_parse(struct rtattr *tb[], int max, struct rtattr > *rta, int len); > +#define rtnl_nested_rtattr_parse(tb, max, rta) \ > + (rtnl_rtattr_parse((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))) > > int rtnl_close(int fd) > { > @@ -84,6 +87,62 @@ int rtnl_link_query(int fd, unsigned int if_index) > return 0; > } > > +static inline __u32 rta_getattr_u32(const struct rtattr *rta) > +{ > + return *(__u32 *)RTA_DATA(rta); > +} > + > +static inline const char *rta_getattr_str(const struct rtattr *rta) > +{ > + return (const char *)RTA_DATA(rta); > +} > + > +static int rtnl_rtattr_parse(struct rtattr *tb[], int max, struct rtattr > *rta, int len) > +{ > + unsigned short type; > + > + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); > + while (RTA_OK(rta, len)) { > + type = rta->rta_type; > + if ((type <= max) && (!tb[type])) > + tb[type] = rta; > + rta = RTA_NEXT(rta, len); > + } > + if (len) > + fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", > + len, rta->rta_len); > + return 0; > +} > + > +static int rtnl_linkinfo_parse(struct rtattr *rta, char *device) > +{ > + int index; > + struct rtattr *linkinfo[IFLA_INFO_MAX + 1]; > + struct rtattr *bond[IFLA_BOND_MAX + 1]; > + > + rtnl_nested_rtattr_parse(linkinfo, IFLA_INFO_MAX, rta); > + > + if (linkinfo[IFLA_INFO_KIND]) { > + const char *kind = rta_getattr_str(linkinfo[IFLA_INFO_KIND]); > + > + if (kind && !strncmp(kind, "bond", 4) && > + linkinfo[IFLA_INFO_DATA]) { > + rtnl_nested_rtattr_parse(bond, IFLA_BOND_MAX, > + linkinfo[IFLA_INFO_DATA]); > + > + if (bond[IFLA_BOND_ACTIVE_SLAVE]) { > + index = > rta_getattr_u32(bond[IFLA_BOND_ACTIVE_SLAVE]); > + > + if (!if_indextoname(index, device)) { > + pr_err("failed to get device name: %m"); > + return -1; > + } > + } > + } > + } > + return 0; > +} > + > int rtnl_link_status(int fd, rtnl_callback cb, void *ctx) > { > int index, len; > @@ -92,6 +151,18 @@ int rtnl_link_status(int fd, rtnl_callback cb, void *ctx) > struct msghdr msg; > struct nlmsghdr *nh; > struct ifinfomsg *info = NULL; > + char *device; > + struct rtattr *tb[IFLA_MAX+1]; > + > + if (cb) > + device = calloc(1, sizeof(MAX_IFNAME_SIZE + 1)); > + else > + device = (char *)ctx; > + > + if (!device) { > + fprintf(stderr, "rtnl: no enought memory for device name\n"); > + return -1; > + } > > if (!rtnl_buf) { > rtnl_len = 4096; > @@ -140,7 +211,18 @@ int rtnl_link_status(int fd, rtnl_callback cb, void *ctx) > index = info->ifi_index; > pr_debug("interface index %d is %s", index, > info->ifi_flags & IFF_RUNNING ? "up" : "down"); > - cb(ctx, index, info->ifi_flags & IFF_RUNNING ? 1 : 0); > + > + rtnl_rtattr_parse(tb, IFLA_MAX, IFLA_RTA(info), > + IFLA_PAYLOAD(nh)); > + > + if (tb[IFLA_LINKINFO]) > + rtnl_linkinfo_parse(tb[IFLA_LINKINFO], device); > + > + if (cb) { > + cb(ctx, index, info->ifi_flags & IFF_RUNNING ? > 1 : > 0, device); > + free(device); > + } > + > } > } > return 0; > @@ -167,3 +249,41 @@ int rtnl_open(void) > } > return fd; > } > + > +int rtnl_link_info(struct interface *iface) > +{ > + int fd, index; > + > + index = if_nametoindex(iface->name); > + > + if (index == 0) { > + pr_err("failed to get interface %s index: %m", iface->name); > + goto no_fd; > + } > + > + fd = rtnl_open(); > + if (fd < 0) > + goto no_fd; > + > + if (rtnl_link_query(fd, index)) > + goto no_info; > + if (rtnl_link_status(fd, NULL, iface->ts_iface)) > + goto no_info; > + > + /* If we do not have a slave, then use our own interface name > + * as ts_iface > + */ > + if (iface->ts_iface[0] == '\0') > + strncpy(iface->ts_iface, iface->name, MAX_IFNAME_SIZE); > +
Seems like we're duplicating code here just to maintain a return value? > + rtnl_close(fd); > + return 0; > + > +no_info: > + rtnl_close(fd); > +no_fd: > + if (iface->ts_iface[0] == '\0') > + strncpy(iface->ts_iface, iface->name, MAX_IFNAME_SIZE); > + > + return -1; > +} > diff --git a/rtnl.h b/rtnl.h > index b4db40e..c382088 100644 > --- a/rtnl.h > +++ b/rtnl.h > @@ -20,7 +20,9 @@ > #ifndef HAVE_RTNL_H > #define HAVE_RTNL_H > > -typedef void (*rtnl_callback)(void *ctx, int index, int linkup); > +#include "config.h" > + > +typedef void (*rtnl_callback)(void *ctx, int index, int linkup, char > *device); > > /** > * Close a RT netlink socket. > @@ -52,4 +54,10 @@ int rtnl_link_status(int fd, rtnl_callback cb, void *ctx); > */ > int rtnl_open(void); > > +/** > + * Get interface link status and ts_iface information > + * @param iface struct interface. > + * @return Zero on success, or -1 on error. > + */ > +int rtnl_link_info(struct interface *iface); > #endif > -- > 2.5.5 > > > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > _______________________________________________ > Linuxptp-devel mailing list > Linuxptp-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linuxptp-devel ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel