aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorFaisal Latif <faisal.latif@intel.com>2009-12-09 18:54:33 -0500
committerRoland Dreier <rolandd@cisco.com>2009-12-09 18:54:33 -0500
commit7a576dfd9ed4fd0f32bb838ce4f644af201ac7df (patch)
treee7e236ce0e66d442114c7e7e9012341aecdb78a8 /drivers/infiniband
parentb1190d3e0d548615ee7c38c10b5fc376a76b7afd (diff)
RDMA/nes: Fix stale ARP issue
When the remote node's ethernet address changes, the connection keeps trying to connect using the old address. The connection wil continue failing until the driver is unloaded and loaded again (eiter reboot or rmmod). Fix this by checking that the NIC has the correct address before starting a connection. Signed-off-by: Faisal Latif <faisal.latif@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 4acf04a03e1c..39468c277036 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1098,12 +1098,13 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
1098/** 1098/**
1099 * nes_addr_resolve_neigh 1099 * nes_addr_resolve_neigh
1100 */ 1100 */
1101static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip) 1101static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex)
1102{ 1102{
1103 struct rtable *rt; 1103 struct rtable *rt;
1104 struct flowi fl; 1104 struct flowi fl;
1105 struct neighbour *neigh; 1105 struct neighbour *neigh;
1106 int rc = -1; 1106 int rc = arpindex;
1107 struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
1107 1108
1108 memset(&fl, 0, sizeof fl); 1109 memset(&fl, 0, sizeof fl);
1109 fl.nl_u.ip4_u.daddr = htonl(dst_ip); 1110 fl.nl_u.ip4_u.daddr = htonl(dst_ip);
@@ -1119,6 +1120,21 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
1119 nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" 1120 nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
1120 " is %pM, Gateway is 0x%08X \n", dst_ip, 1121 " is %pM, Gateway is 0x%08X \n", dst_ip,
1121 neigh->ha, ntohl(rt->rt_gateway)); 1122 neigh->ha, ntohl(rt->rt_gateway));
1123
1124 if (arpindex >= 0) {
1125 if (!memcmp(nesadapter->arp_table[arpindex].mac_addr,
1126 neigh->ha, ETH_ALEN)){
1127 /* Mac address same as in nes_arp_table */
1128 neigh_release(neigh);
1129 ip_rt_put(rt);
1130 return rc;
1131 }
1132
1133 nes_manage_arp_cache(nesvnic->netdev,
1134 nesadapter->arp_table[arpindex].mac_addr,
1135 dst_ip, NES_ARP_DELETE);
1136 }
1137
1122 nes_manage_arp_cache(nesvnic->netdev, neigh->ha, 1138 nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
1123 dst_ip, NES_ARP_ADD); 1139 dst_ip, NES_ARP_ADD);
1124 rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL, 1140 rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
@@ -1134,7 +1150,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
1134 return rc; 1150 return rc;
1135} 1151}
1136 1152
1137
1138/** 1153/**
1139 * make_cm_node - create a new instance of a cm node 1154 * make_cm_node - create a new instance of a cm node
1140 */ 1155 */
@@ -1144,6 +1159,7 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1144{ 1159{
1145 struct nes_cm_node *cm_node; 1160 struct nes_cm_node *cm_node;
1146 struct timespec ts; 1161 struct timespec ts;
1162 int oldarpindex = 0;
1147 int arpindex = 0; 1163 int arpindex = 0;
1148 struct nes_device *nesdev; 1164 struct nes_device *nesdev;
1149 struct nes_adapter *nesadapter; 1165 struct nes_adapter *nesadapter;
@@ -1197,17 +1213,18 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1197 nesadapter = nesdev->nesadapter; 1213 nesadapter = nesdev->nesadapter;
1198 1214
1199 cm_node->loopbackpartner = NULL; 1215 cm_node->loopbackpartner = NULL;
1216
1200 /* get the mac addr for the remote node */ 1217 /* get the mac addr for the remote node */
1201 if (ipv4_is_loopback(htonl(cm_node->rem_addr))) 1218 if (ipv4_is_loopback(htonl(cm_node->rem_addr)))
1202 arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE); 1219 arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE);
1203 else 1220 else {
1204 arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); 1221 oldarpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
1222 arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr, oldarpindex);
1223
1224 }
1205 if (arpindex < 0) { 1225 if (arpindex < 0) {
1206 arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr); 1226 kfree(cm_node);
1207 if (arpindex < 0) { 1227 return NULL;
1208 kfree(cm_node);
1209 return NULL;
1210 }
1211 } 1228 }
1212 1229
1213 /* copy the mac addr to node context */ 1230 /* copy the mac addr to node context */