@@ -95,6 +95,15 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
95
95
struct rds_connection * conn ;
96
96
struct rds_transport * trans = & rds_ib_transport ;
97
97
int ret = 0 ;
98
+ /* ADDR_CHANGE event indicates that the local address has moved
99
+ * to a different device, most likely due to failover/failback.
100
+ * If this is a local connection (a connection to this host), we need
101
+ * to flush the neighbor cache entry for the peer side of the
102
+ * connection. In this case we do not need to flush this side of the
103
+ * connection. If this is not a local connection, we still flush
104
+ * the neighbor cache for the local side of the connection.
105
+ */
106
+ bool flush_local_peer = event -> event == RDMA_CM_EVENT_ADDR_CHANGE ;
98
107
int * err ;
99
108
100
109
conn = rds_ib_get_conn (cm_id );
@@ -136,7 +145,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
136
145
/* These events might indicate the IP being moved,
137
146
* hence flush the address
138
147
*/
139
- rds_ib_flush_neigh (& init_net , conn );
148
+ rds_ib_flush_neigh (& init_net , conn , flush_local_peer );
140
149
rds_rtd (RDS_RTD_CM , "Bailing, conn %p being shut down, ret: %d\n" ,
141
150
conn , ret );
142
151
goto out ;
@@ -212,7 +221,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
212
221
213
222
case RDMA_CM_EVENT_ROUTE_ERROR :
214
223
/* IP might have been moved so flush the ARP entry and retry */
215
- rds_ib_flush_neigh (& init_net , conn );
224
+ rds_ib_flush_neigh (& init_net , conn , flush_local_peer );
216
225
217
226
rds_rtd_ptr (RDS_RTD_ERR ,
218
227
"ROUTE_ERROR: conn %p, calling rds_conn_drop <%pI6c,%pI6c,%d>\n" ,
@@ -228,7 +237,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
228
237
229
238
case RDMA_CM_EVENT_ADDR_ERROR :
230
239
/* IP might have been moved so flush the ARP entry and retry */
231
- rds_ib_flush_neigh (& init_net , conn );
240
+ rds_ib_flush_neigh (& init_net , conn , flush_local_peer );
232
241
233
242
rds_rtd_ptr (RDS_RTD_ERR ,
234
243
"ADDR_ERROR: conn %p, calling rds_conn_drop <%pI6c,%pI6c,%d>\n" ,
@@ -242,7 +251,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
242
251
case RDMA_CM_EVENT_UNREACHABLE :
243
252
case RDMA_CM_EVENT_DEVICE_REMOVAL :
244
253
/* IP might have been moved so flush the ARP entry and retry */
245
- rds_ib_flush_neigh (& init_net , conn );
254
+ rds_ib_flush_neigh (& init_net , conn , flush_local_peer );
246
255
247
256
rds_rtd_ptr (RDS_RTD_ERR ,
248
257
"CONN/UNREACHABLE/RMVAL ERR: conn %p, calling rds_conn_drop <%pI6c,%pI6c,%d>\n" ,
@@ -254,7 +263,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
254
263
255
264
case RDMA_CM_EVENT_REJECTED :
256
265
/* May be due to ARP cache containing an incorrect dmac, hence flush it */
257
- rds_ib_flush_neigh (& init_net , conn );
266
+ rds_ib_flush_neigh (& init_net , conn , flush_local_peer );
258
267
259
268
err = (int * )event -> param .conn .private_data ;
260
269
@@ -300,7 +309,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
300
309
301
310
case RDMA_CM_EVENT_ADDR_CHANGE :
302
311
/* IP might have been moved so flush the ARP entry and retry */
303
- rds_ib_flush_neigh (& init_net , conn );
312
+ rds_ib_flush_neigh (& init_net , conn , flush_local_peer );
304
313
305
314
rds_rtd_ptr (RDS_RTD_CM_EXT ,
306
315
"ADDR_CHANGE event <%pI6c,%pI6c>\n" ,
@@ -315,7 +324,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
315
324
316
325
case RDMA_CM_EVENT_DISCONNECTED :
317
326
/* IP might have been moved so flush the ARP entry and retry */
318
- rds_ib_flush_neigh (& init_net , conn );
327
+ rds_ib_flush_neigh (& init_net , conn , flush_local_peer );
319
328
320
329
rds_rtd_ptr (RDS_RTD_CM ,
321
330
"DISCONNECT event - dropping conn %p <%pI6c,%pI6c,%d>\n" ,
0 commit comments