Re: [PATCH 1/4] ibacm: Replace ioctl with netlink

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ira,

> On 25 Jan 2019, at 19:02, Ira Weiny <ira.weiny@xxxxxxxxx> wrote:
> 
> On Thu, Jan 24, 2019 at 03:47:35PM +0100, Håkon Bugge wrote:
>> ibacm uses ioctl with SIOCGIFCONF to enumerate the interfaces. This
>> particular ioctl will only return interfaces that are "running".
>> 
>> This is a problem if, for example, ibacm is started before the
>> interfaces get plumbed, or when an interface gets resurrected.
>> 
>> By using netlink (nl), we avoid using the sysfs interface to read the
>> gid, as it is supplied directly by nl.
>> 
>> This commit does not change the existing functionality, but is made
>> to prepare for a fix where ibacm is unable to resurrect an interface.
>> 
>> Detailed logging added:
>> 
>> acm_if_iter: name: stib0 label:     stib0 index:  9
>> flags: broadcast,multicast,up,running,lowerup
>> addr: 192.168.200.200/24 pkey: 0x88b4 guid: 0x21280001a17c97
>> 
>> Change-Id: I6e428d1d6b2d345ccfbd74d482c69b56f8fe98da
>> Signed-off-by: Håkon Bugge <haakon.bugge@xxxxxxxxxx>
>> ---
> 
> [snip]
> 
>> diff --git a/ibacm/src/acm_util.c b/ibacm/src/acm_util.c
>> index f4654f12..fc22432c 100644
>> --- a/ibacm/src/acm_util.c
>> +++ b/ibacm/src/acm_util.c
>> @@ -27,48 +27,28 @@
>>  * SOFTWARE.
>>  */
>> 
>> +#include <arpa/inet.h>
>> +#include <asm/types.h>
>> +#include <errno.h>
>> +#include <linux/netlink.h>
>> +#include <net/if.h>
>> +#include <net/if_arp.h>
>> +#include <netlink/route/addr.h>
>> +#include <netlink/route/link.h>
>> +#include <netlink/socket.h>
>> +#include <stdbool.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> -#include <net/if_arp.h>
>> #include <string.h>
>> -#include <unistd.h>
>> -#include <arpa/inet.h>
>> #include <sys/ioctl.h>
>> -#include <net/if.h>
>> #include <sys/socket.h>
>> #include <sys/types.h>
>> -#include <errno.h>
>> +#include <unistd.h>
> 
> NIT:
> 
> Lots of noise here in moving the includes around.  It would be better if you
> did not move the include lines around so we can see that you are removing and
> adding the correct includes.

I had to insert a handful of them, and had to sort them to avoid duplicates. But I agree, nothing to do with the commit. Will fix.

On that topic, is a sort advised for includes, so dups easily can be detected? Always using <esc>X sort-lines...

> But I'm going to assume this compiles fine...

Sure does, passed our CI tests for rdma-core, which is about 100 tests with 4 different kernels...

> [snip]
> 
>> +
>> +/* pre-decl to avoid compiler warning */
>> +void acm_if_iter(struct nl_object *obj, void *_ctx_and_cb);
>> +void acm_if_iter(struct nl_object *obj, void *_ctx_and_cb)
> 
> What Jason said...

Sure, scope is not part of the signature. Got it!

>> +{
>> +	struct ctx_and_cb *ctx_cb = (struct ctx_and_cb *)_ctx_and_cb;
>> +	struct rtnl_addr *addr = (struct rtnl_addr *)obj;
>> +	uint8_t bin_addr[ACM_MAX_ADDRESS] = {};
>> +	char ip_str[INET6_ADDRSTRLEN];
>> +	struct nl_addr *link_addr;
>> +	unsigned long *guid_ptr;
>> +	struct rtnl_link *link;
>> +	char flags_str[128];
>> +	union ibv_gid sgid;
>> +	struct nl_addr *a;
>> +	uint16_t pkey;
>> +	int addr_len;
>> +	char *label;
>> +	int flags;
>> +	int ret;
>> +	int af;
>> +
>> +	link = rtnl_link_get(link_cache, rtnl_addr_get_ifindex(addr));
>> +	flags = rtnl_link_get_flags(link);
>> +
>> +	if (rtnl_link_get_arptype(link) != ARPHRD_INFINIBAND)
>> +		return;
>> +
>> +	if (!(flags & IFF_RUNNING))
>> +		return;
>> +
>> +	if (!(a = rtnl_addr_get_local(addr)))
>> +		return;
>> +
>> +	if ((addr_len = nl_addr_get_len(a)) > ACM_MAX_ADDRESS) {
>> +		acm_log(0, "address too long (%d)\n", addr_len);
>> +		return;
>> +	}
>> +
>> +	af = nl_addr_get_family(a);
>> +	if (af != AF_INET && af != AF_INET6)
>> +		return;
>> +
>> +	label = rtnl_addr_get_label(addr);
>> +	if (!label)
>> +		return;
>> +
>> +	link_addr = rtnl_link_get_addr(link);
>> +	memcpy(sgid.raw, nl_addr_get_binary_addr(link_addr) + 4, sizeof(sgid));
>> +	guid_ptr = (unsigned long *)&sgid.raw;
> 
> This does not look right to support both IPv4 and v6.

Me not understand. I am retrieving the L2 address here. It is not influenced by the choice of L3 address, is it?

>> +
>> +	ret = acm_if_get_pkey(rtnl_link_get_name(link), &pkey);
>> +	if (ret)
>> +		return;
>> +
>> +	acm_log(2, "name: %5s label: %9s index: %2d flags: %s addr: %s pkey: 0x%04x guid: 0x%lx\n",
>> +		rtnl_link_get_name(link), label,
>> +		rtnl_addr_get_ifindex(addr),
>> +		rtnl_link_flags2str(flags, flags_str, sizeof(flags_str)),
>> +		nl_addr2str(a, ip_str, sizeof(ip_str)),	pkey,
>> +		be64toh(*(guid_ptr + 1)));
> 
> Use sgid.global.interface_id to represent the guid.  That is what ibv_gid union
> is for...

Yes, thanks! Will fix.

Thanks for the review, Håkon






[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux