diff options
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 38 |
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 | */ |
1024 | static void nes_addr_send_arp(u32 dst_ip) | 1024 | static 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 */ |