aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorBob Sharp <bsharp@neteffect.com>2008-10-03 15:21:19 -0400
committerRoland Dreier <rolandd@cisco.com>2008-10-03 15:21:19 -0400
commit7191a0a18228c8da9abc7776433c6a3953ff1e4b (patch)
treec7c103a900a033242fd0cfda4b7e1100428234cf /drivers/infiniband
parent7e36d3d732438de894802f87a0ca21372e00fb74 (diff)
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: Bob Sharp <bsharp@neteffect.com> Signed-off-by: Sweta Bhatt <sweta.bhatt@einfochips.com> Signed-off-by: Chien Tung <ctung@neteffect.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 08f2b3e80fcb..d69226d7102e 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -52,7 +52,7 @@
52#include <linux/random.h> 52#include <linux/random.h>
53#include <linux/list.h> 53#include <linux/list.h>
54#include <linux/threads.h> 54#include <linux/threads.h>
55 55#include <net/arp.h>
56#include <net/neighbour.h> 56#include <net/neighbour.h>
57#include <net/route.h> 57#include <net/route.h>
58#include <net/ip_fib.h> 58#include <net/ip_fib.h>
@@ -1019,23 +1019,43 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
1019 1019
1020 1020
1021/** 1021/**
1022 * nes_addr_send_arp 1022 * nes_addr_resolve_neigh
1023 */ 1023 */
1024static void nes_addr_send_arp(u32 dst_ip) 1024static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
1025{ 1025{
1026 struct rtable *rt; 1026 struct rtable *rt;
1027 struct flowi fl; 1027 struct flowi fl;
1028 struct neighbour *neigh;
1029 int rc = -1;
1030 DECLARE_MAC_BUF(mac);
1028 1031
1029 memset(&fl, 0, sizeof fl); 1032 memset(&fl, 0, sizeof fl);
1030 fl.nl_u.ip4_u.daddr = htonl(dst_ip); 1033 fl.nl_u.ip4_u.daddr = htonl(dst_ip);
1031 if (ip_route_output_key(&init_net, &rt, &fl)) { 1034 if (ip_route_output_key(&init_net, &rt, &fl)) {
1032 printk("%s: ip_route_output_key failed for 0x%08X\n", 1035 printk("%s: ip_route_output_key failed for 0x%08X\n",
1033 __func__, dst_ip); 1036 __func__, dst_ip);
1034 return; 1037 return rc;
1038 }
1039
1040 neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, nesvnic->netdev);
1041 if (neigh) {
1042 if (neigh->nud_state & NUD_VALID) {
1043 nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
1044 " is %s, Gateway is 0x%08X \n", dst_ip,
1045 print_mac(mac, neigh->ha), ntohl(rt->rt_gateway));
1046 nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
1047 dst_ip, NES_ARP_ADD);
1048 rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
1049 NES_ARP_RESOLVE);
1050 }
1051 neigh_release(neigh);
1035 } 1052 }
1036 1053
1037 neigh_event_send(rt->u.dst.neighbour, NULL); 1054 if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
1055 neigh_event_send(rt->u.dst.neighbour, NULL);
1056
1038 ip_rt_put(rt); 1057 ip_rt_put(rt);
1058 return rc;
1039} 1059}
1040 1060
1041 1061
@@ -1108,9 +1128,11 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1108 /* get the mac addr for the remote node */ 1128 /* get the mac addr for the remote node */
1109 arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); 1129 arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
1110 if (arpindex < 0) { 1130 if (arpindex < 0) {
1111 kfree(cm_node); 1131 arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr);
1112 nes_addr_send_arp(cm_info->rem_addr); 1132 if (arpindex < 0) {
1113 return NULL; 1133 kfree(cm_node);
1134 return NULL;
1135 }
1114 } 1136 }
1115 1137
1116 /* copy the mac addr to node context */ 1138 /* copy the mac addr to node context */