rtnl: update function rtnl_link_status to get bond slave info
Update function rtnl_link_status to get bond slave info. Pass the slave index to call back functions. i.e. port_link_status. Also check the interface index of rtnl message in function rtnl_link_status. Then we don't need to check it in port_link_status. Add ifndef IFLA_BOND_MAX in case we build linuxptp on kernel before v3.13-rc1. Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>master
parent
05bba46198
commit
80bc4d4c2f
36
missing.h
36
missing.h
|
@ -69,6 +69,42 @@ static inline int clock_adjtime(clockid_t id, struct timex *tx)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef IFLA_BOND_MAX
|
||||||
|
enum {
|
||||||
|
IFLA_BOND_UNSPEC,
|
||||||
|
IFLA_BOND_MODE,
|
||||||
|
IFLA_BOND_ACTIVE_SLAVE,
|
||||||
|
IFLA_BOND_MIIMON,
|
||||||
|
IFLA_BOND_UPDELAY,
|
||||||
|
IFLA_BOND_DOWNDELAY,
|
||||||
|
IFLA_BOND_USE_CARRIER,
|
||||||
|
IFLA_BOND_ARP_INTERVAL,
|
||||||
|
IFLA_BOND_ARP_IP_TARGET,
|
||||||
|
IFLA_BOND_ARP_VALIDATE,
|
||||||
|
IFLA_BOND_ARP_ALL_TARGETS,
|
||||||
|
IFLA_BOND_PRIMARY,
|
||||||
|
IFLA_BOND_PRIMARY_RESELECT,
|
||||||
|
IFLA_BOND_FAIL_OVER_MAC,
|
||||||
|
IFLA_BOND_XMIT_HASH_POLICY,
|
||||||
|
IFLA_BOND_RESEND_IGMP,
|
||||||
|
IFLA_BOND_NUM_PEER_NOTIF,
|
||||||
|
IFLA_BOND_ALL_SLAVES_ACTIVE,
|
||||||
|
IFLA_BOND_MIN_LINKS,
|
||||||
|
IFLA_BOND_LP_INTERVAL,
|
||||||
|
IFLA_BOND_PACKETS_PER_SLAVE,
|
||||||
|
IFLA_BOND_AD_LACP_RATE,
|
||||||
|
IFLA_BOND_AD_SELECT,
|
||||||
|
IFLA_BOND_AD_INFO,
|
||||||
|
IFLA_BOND_AD_ACTOR_SYS_PRIO,
|
||||||
|
IFLA_BOND_AD_USER_PORT_KEY,
|
||||||
|
IFLA_BOND_AD_ACTOR_SYSTEM,
|
||||||
|
IFLA_BOND_TLB_DYNAMIC_LB,
|
||||||
|
__IFLA_BOND_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
|
||||||
|
#endif /*IFLA_BOND_MAX*/
|
||||||
|
|
||||||
#ifdef __UCLIBC__
|
#ifdef __UCLIBC__
|
||||||
|
|
||||||
#if (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L) && \
|
#if (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L) && \
|
||||||
|
|
6
port.c
6
port.c
|
@ -2221,11 +2221,11 @@ 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 linkup, int ts_index)
|
||||||
{
|
{
|
||||||
struct port *p = ctx;
|
struct port *p = ctx;
|
||||||
|
|
||||||
if (index != if_nametoindex(p->name) || p->link_status == linkup)
|
if (p->link_status == linkup)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p->link_status = linkup;
|
p->link_status = linkup;
|
||||||
|
@ -2280,7 +2280,7 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
||||||
|
|
||||||
case FD_RTNL:
|
case FD_RTNL:
|
||||||
pr_debug("port %hu: received link status notification", portnum(p));
|
pr_debug("port %hu: received link status notification", portnum(p));
|
||||||
rtnl_link_status(fd, port_link_status, p);
|
rtnl_link_status(fd, p->name, port_link_status, p);
|
||||||
return port_link_status_get(p) ? EV_FAULT_CLEARED : EV_FAULT_DETECTED;
|
return port_link_status_get(p) ? EV_FAULT_CLEARED : EV_FAULT_DETECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
96
rtnl.c
96
rtnl.c
|
@ -26,6 +26,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "missing.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "rtnl.h"
|
#include "rtnl.h"
|
||||||
|
|
||||||
|
@ -84,15 +85,79 @@ int rtnl_link_query(int fd, char *device)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtnl_link_status(int fd, rtnl_callback cb, void *ctx)
|
static inline __u32 rta_getattr_u32(const struct rtattr *rta)
|
||||||
{
|
{
|
||||||
int index, len;
|
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);
|
||||||
|
while (RTA_OK(rta, len)) {
|
||||||
|
type = rta->rta_type;
|
||||||
|
if ((type < max) && (!tb[type]))
|
||||||
|
tb[type] = rta;
|
||||||
|
rta = RTA_NEXT(rta, len);
|
||||||
|
}
|
||||||
|
if (len) {
|
||||||
|
pr_err("Length mismatch: len %d, rta_len=%d\n", len, rta->rta_len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int rtnl_nested_rtattr_parse(struct rtattr *tb[], int max, struct rtattr *rta)
|
||||||
|
{
|
||||||
|
return rtnl_rtattr_parse(tb, max, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtnl_linkinfo_parse(struct rtattr *rta)
|
||||||
|
{
|
||||||
|
int index = -1;
|
||||||
|
const char *kind;
|
||||||
|
struct rtattr *linkinfo[IFLA_INFO_MAX];
|
||||||
|
struct rtattr *bond[IFLA_BOND_MAX];
|
||||||
|
|
||||||
|
if (rtnl_nested_rtattr_parse(linkinfo, IFLA_INFO_MAX, rta) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (linkinfo[IFLA_INFO_KIND]) {
|
||||||
|
kind = rta_getattr_str(linkinfo[IFLA_INFO_KIND]);
|
||||||
|
|
||||||
|
if (kind && !strncmp(kind, "bond", 4) &&
|
||||||
|
linkinfo[IFLA_INFO_DATA]) {
|
||||||
|
if (rtnl_nested_rtattr_parse(bond, IFLA_BOND_MAX,
|
||||||
|
linkinfo[IFLA_INFO_DATA]) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (bond[IFLA_BOND_ACTIVE_SLAVE]) {
|
||||||
|
index = rta_getattr_u32(bond[IFLA_BOND_ACTIVE_SLAVE]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtnl_link_status(int fd, char *device, rtnl_callback cb, void *ctx)
|
||||||
|
{
|
||||||
|
int index, len, link_up;
|
||||||
|
int slave_index = -1;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
struct sockaddr_nl sa;
|
struct sockaddr_nl sa;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct nlmsghdr *nh;
|
struct nlmsghdr *nh;
|
||||||
struct ifinfomsg *info = NULL;
|
struct ifinfomsg *info = NULL;
|
||||||
|
struct rtattr *tb[IFLA_MAX+1];
|
||||||
|
|
||||||
|
index = if_nametoindex(device);
|
||||||
if (!rtnl_buf) {
|
if (!rtnl_buf) {
|
||||||
rtnl_len = 4096;
|
rtnl_len = 4096;
|
||||||
rtnl_buf = malloc(rtnl_len);
|
rtnl_buf = malloc(rtnl_len);
|
||||||
|
@ -135,14 +200,27 @@ int rtnl_link_status(int fd, rtnl_callback cb, void *ctx)
|
||||||
nh = (struct nlmsghdr *) rtnl_buf;
|
nh = (struct nlmsghdr *) rtnl_buf;
|
||||||
|
|
||||||
for ( ; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
|
for ( ; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
|
||||||
if (nh->nlmsg_type == RTM_NEWLINK) {
|
if (nh->nlmsg_type != RTM_NEWLINK)
|
||||||
info = NLMSG_DATA(nh);
|
continue;
|
||||||
index = info->ifi_index;
|
|
||||||
pr_debug("interface index %d is %s", index,
|
info = NLMSG_DATA(nh);
|
||||||
info->ifi_flags & IFF_RUNNING ? "up" : "down");
|
if (index != info->ifi_index)
|
||||||
cb(ctx, index, info->ifi_flags & IFF_RUNNING ? 1 : 0);
|
continue;
|
||||||
}
|
|
||||||
|
link_up = info->ifi_flags & IFF_RUNNING ? 1 : 0;
|
||||||
|
pr_debug("interface index %d is %s", index,
|
||||||
|
link_up ? "up" : "down");
|
||||||
|
|
||||||
|
rtnl_rtattr_parse(tb, IFLA_MAX, IFLA_RTA(info),
|
||||||
|
IFLA_PAYLOAD(nh));
|
||||||
|
|
||||||
|
if (tb[IFLA_LINKINFO])
|
||||||
|
slave_index = rtnl_linkinfo_parse(tb[IFLA_LINKINFO]);
|
||||||
|
|
||||||
|
if (cb)
|
||||||
|
cb(ctx, link_up, slave_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
rtnl.h
13
rtnl.h
|
@ -20,7 +20,7 @@
|
||||||
#ifndef HAVE_RTNL_H
|
#ifndef HAVE_RTNL_H
|
||||||
#define HAVE_RTNL_H
|
#define HAVE_RTNL_H
|
||||||
|
|
||||||
typedef void (*rtnl_callback)(void *ctx, int index, int linkup);
|
typedef void (*rtnl_callback)(void *ctx, int linkup, int ts_index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close a RT netlink socket.
|
* Close a RT netlink socket.
|
||||||
|
@ -39,12 +39,13 @@ int rtnl_link_query(int fd, char *device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read kernel messages looking for a link up/down events.
|
* Read kernel messages looking for a link up/down events.
|
||||||
* @param fd Readable socket obtained via rtnl_open().
|
* @param fd Readable socket obtained via rtnl_open().
|
||||||
* @param cb Callback function to be invoked on each event.
|
* @param device The device which we need to get link info.
|
||||||
* @param ctx Private context passed to the callback.
|
* @param cb Callback function to be invoked on each event.
|
||||||
* @return Zero on success, non-zero otherwise.
|
* @param ctx Private context passed to the callback.
|
||||||
|
* @return Zero on success, non-zero otherwise.
|
||||||
*/
|
*/
|
||||||
int rtnl_link_status(int fd, rtnl_callback cb, void *ctx);
|
int rtnl_link_status(int fd, char *device, rtnl_callback cb, void *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a RT netlink socket for monitoring link state.
|
* Open a RT netlink socket for monitoring link state.
|
||||||
|
|
Loading…
Reference in New Issue