dcbnl has support to retrieve SAN MAC, add this to our lib to be used later by FIP.
Signed-off-by: Yi Zou <[email protected]> --- include/rtnetlink.h | 1 + lib/rtnetlink.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 0 deletions(-) diff --git a/include/rtnetlink.h b/include/rtnetlink.h index 167748e..13e54a4 100644 --- a/include/rtnetlink.h +++ b/include/rtnetlink.h @@ -28,6 +28,7 @@ int rtnl_set_iff_up(int ifindex, char *ifname); int vlan_create(int ifindex, int vid, char *name); int rtnl_find_vlan(int ifindex, int vid, char *ifname); int rtnl_get_linkname(int ifindex, char *name); +int rtnl_get_sanmac(const char *ifname, unsigned char *addr); static inline void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) { diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c index a8a8b0c..32b8217 100644 --- a/lib/rtnetlink.c +++ b/lib/rtnetlink.c @@ -38,6 +38,7 @@ #include <arpa/inet.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include <linux/dcbnl.h> #include "rtnetlink.h" #include "fcoemon_utils.h" @@ -46,6 +47,8 @@ #define RTNL_LOG_ERRNO(...) sa_log_err(errno, __func__, __VA_ARGS__) #define RTNL_LOG_DBG(...) sa_log_debug(__VA_ARGS__) +#define NLA_DATA(nla) ((void *)((char*)(nla) + NLA_HDRLEN)) + /** * rtnl_socket - create and bind a routing netlink socket */ @@ -426,3 +429,72 @@ out: close(s); return rc; } + +int rtnl_get_sanmac(const char *ifname, unsigned char *addr) +{ + int s; + int rc = -EIO; + struct { + struct nlmsghdr nh; + struct dcbmsg dcb; + char attrbuf[1204]; + } req = { + .nh = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct dcbmsg)), + .nlmsg_type = RTM_GETDCB, + .nlmsg_pid = getpid(), + .nlmsg_flags = NLM_F_REQUEST, + }, + .dcb = { + .cmd = DCB_CMD_GPERM_HWADDR, + .dcb_family = AF_UNSPEC, + .dcb_pad = 0, + }, + }; + + struct nlmsghdr *nh = &req.nh; + struct dcbmsg *dcb; + struct rtattr *rta; + + /* prep the message */ + memset((void *)req.attrbuf, 0, sizeof(req.attrbuf)); + add_rtattr(nh, DCB_ATTR_IFNAME, (void *)ifname, strlen(ifname) + 1); + add_rtattr(nh, DCB_ATTR_PERM_HWADDR, NULL, 0); + + s = rtnl_socket(); + if (s < 0) { + RTNL_LOG_ERRNO("failed to create the socket"); + return s; + } + + rc = send(s, (void *)nh, nh->nlmsg_len, 0); + if (rc < 0) { + RTNL_LOG_ERRNO("failed to send to the socket"); + goto err_close; + } + + memset((void *)&req, 0, sizeof(req)); + rc = recv(s, (void *)&req, sizeof(req), 0); + if (rc < 0) { + RTNL_LOG_ERRNO("failed to recv from the socket"); + rc = -EIO; + goto err_close; + } + + dcb = (struct dcbmsg *)NLMSG_DATA(nh); + rta = (struct rtattr *)(((char *)dcb) + + NLMSG_ALIGN(sizeof(struct dcbmsg))); + if ((nh->nlmsg_type != RTM_GETDCB) || + (dcb->cmd != DCB_CMD_GPERM_HWADDR) || + (rta->rta_type != DCB_ATTR_PERM_HWADDR)) { + RTNL_LOG_DBG("Unexpected netlink response for GPERM_HWADDR\n"); + rc = -EIO; + goto err_close; + } + /* SAN MAC follows the LAN MAC */ + memcpy(addr, NLA_DATA(rta) + ETH_ALEN, ETH_ALEN); + rc = 0; +err_close: + close(s); + return rc; +} _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
