Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7191a0a1 authored by Bob Sharp's avatar Bob Sharp Committed by Roland Dreier
Browse files

RDMA/nes: Fix routed RDMA connections



Fix routed RDMA connections to destinations where the next hop is not
the final destination.  Use neigh_*() to properly locate neighbor.

Signed-off-by: default avatarBob Sharp <bsharp@neteffect.com>
Signed-off-by: default avatarSweta Bhatt <sweta.bhatt@einfochips.com>
Signed-off-by: default avatarChien Tung <ctung@neteffect.com>
parent 7e36d3d7
Loading
Loading
Loading
Loading
+30 −8
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@
#include <linux/random.h>
#include <linux/list.h>
#include <linux/threads.h>

#include <net/arp.h>
#include <net/neighbour.h>
#include <net/route.h>
#include <net/ip_fib.h>
@@ -1019,23 +1019,43 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,


/**
 * nes_addr_send_arp
 * nes_addr_resolve_neigh
 */
static void nes_addr_send_arp(u32 dst_ip)
static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
{
	struct rtable *rt;
	struct flowi fl;
	struct neighbour *neigh;
	int rc = -1;
	DECLARE_MAC_BUF(mac);

	memset(&fl, 0, sizeof fl);
	fl.nl_u.ip4_u.daddr = htonl(dst_ip);
	if (ip_route_output_key(&init_net, &rt, &fl)) {
		printk("%s: ip_route_output_key failed for 0x%08X\n",
				__func__, dst_ip);
		return;
		return rc;
	}

	neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, nesvnic->netdev);
	if (neigh) {
		if (neigh->nud_state & NUD_VALID) {
			nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
				  " is %s, Gateway is 0x%08X \n", dst_ip,
				  print_mac(mac, neigh->ha), ntohl(rt->rt_gateway));
			nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
					     dst_ip, NES_ARP_ADD);
			rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
					   NES_ARP_RESOLVE);
		}
		neigh_release(neigh);
	}

	if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
		neigh_event_send(rt->u.dst.neighbour, NULL);

	ip_rt_put(rt);
	return rc;
}


@@ -1107,11 +1127,13 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
	cm_node->loopbackpartner = NULL;
	/* get the mac addr for the remote node */
	arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
	if (arpindex < 0) {
		arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr);
		if (arpindex < 0) {
			kfree(cm_node);
		nes_addr_send_arp(cm_info->rem_addr);
			return NULL;
		}
	}

	/* copy the mac addr to node context */
	memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN);