aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-10-04 04:32:28 -0400
committerDavid Howells <dhowells@redhat.com>2018-10-04 04:32:28 -0400
commit66be646bd9a7d50961afbf48c1d0df148e37d416 (patch)
treec3ef813b8b3cb2cf831e0f2146d15afae025144d /fs/afs
parent4c19bbdc7f7c76da14a7192072c47c3b9b582e80 (diff)
afs: Sort address lists so that they are in logical ascending order
Sort address lists so that they are in logical ascending order rather than being partially in ascending order of the BE representations of those values. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/addr_list.c51
1 files changed, 24 insertions, 27 deletions
diff --git a/fs/afs/addr_list.c b/fs/afs/addr_list.c
index 00e87f859b9f..89374de4785c 100644
--- a/fs/afs/addr_list.c
+++ b/fs/afs/addr_list.c
@@ -232,22 +232,23 @@ struct afs_addr_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry)
232 */ 232 */
233void afs_merge_fs_addr4(struct afs_addr_list *alist, __be32 xdr, u16 port) 233void afs_merge_fs_addr4(struct afs_addr_list *alist, __be32 xdr, u16 port)
234{ 234{
235 struct sockaddr_in6 *a; 235 struct sockaddr_in6 *p;
236 __be16 xport = htons(port); 236 u32 addr = ntohl(xdr);
237 int i; 237 int i;
238 238
239 if (alist->nr_addrs >= alist->max_addrs) 239 if (alist->nr_addrs >= alist->max_addrs)
240 return; 240 return;
241 241
242 for (i = 0; i < alist->nr_ipv4; i++) { 242 for (i = 0; i < alist->nr_ipv4; i++) {
243 a = &alist->addrs[i].transport.sin6; 243 struct sockaddr_in6 *a = &alist->addrs[i].transport.sin6;
244 if (xdr == a->sin6_addr.s6_addr32[3] && 244 u32 a_addr = ntohl(a->sin6_addr.s6_addr32[3]);
245 xport == a->sin6_port) 245 u16 a_port = ntohs(a->sin6_port);
246
247 if (addr == a_addr && port == a_port)
246 return; 248 return;
247 if (xdr == a->sin6_addr.s6_addr32[3] && 249 if (addr == a_addr && port < a_port)
248 (u16 __force)xport < (u16 __force)a->sin6_port)
249 break; 250 break;
250 if ((u32 __force)xdr < (u32 __force)a->sin6_addr.s6_addr32[3]) 251 if (addr < a_addr)
251 break; 252 break;
252 } 253 }
253 254
@@ -256,12 +257,12 @@ void afs_merge_fs_addr4(struct afs_addr_list *alist, __be32 xdr, u16 port)
256 alist->addrs + i, 257 alist->addrs + i,
257 sizeof(alist->addrs[0]) * (alist->nr_addrs - i)); 258 sizeof(alist->addrs[0]) * (alist->nr_addrs - i));
258 259
259 a = &alist->addrs[i].transport.sin6; 260 p = &alist->addrs[i].transport.sin6;
260 a->sin6_port = xport; 261 p->sin6_port = htons(port);
261 a->sin6_addr.s6_addr32[0] = 0; 262 p->sin6_addr.s6_addr32[0] = 0;
262 a->sin6_addr.s6_addr32[1] = 0; 263 p->sin6_addr.s6_addr32[1] = 0;
263 a->sin6_addr.s6_addr32[2] = htonl(0xffff); 264 p->sin6_addr.s6_addr32[2] = htonl(0xffff);
264 a->sin6_addr.s6_addr32[3] = xdr; 265 p->sin6_addr.s6_addr32[3] = xdr;
265 alist->nr_ipv4++; 266 alist->nr_ipv4++;
266 alist->nr_addrs++; 267 alist->nr_addrs++;
267} 268}
@@ -271,21 +272,20 @@ void afs_merge_fs_addr4(struct afs_addr_list *alist, __be32 xdr, u16 port)
271 */ 272 */
272void afs_merge_fs_addr6(struct afs_addr_list *alist, __be32 *xdr, u16 port) 273void afs_merge_fs_addr6(struct afs_addr_list *alist, __be32 *xdr, u16 port)
273{ 274{
274 struct sockaddr_in6 *a; 275 struct sockaddr_in6 *p;
275 __be16 xport = htons(port);
276 int i, diff; 276 int i, diff;
277 277
278 if (alist->nr_addrs >= alist->max_addrs) 278 if (alist->nr_addrs >= alist->max_addrs)
279 return; 279 return;
280 280
281 for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) { 281 for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) {
282 a = &alist->addrs[i].transport.sin6; 282 struct sockaddr_in6 *a = &alist->addrs[i].transport.sin6;
283 u16 a_port = ntohs(a->sin6_port);
284
283 diff = memcmp(xdr, &a->sin6_addr, 16); 285 diff = memcmp(xdr, &a->sin6_addr, 16);
284 if (diff == 0 && 286 if (diff == 0 && port == a_port)
285 xport == a->sin6_port)
286 return; 287 return;
287 if (diff == 0 && 288 if (diff == 0 && port < a_port)
288 (u16 __force)xport < (u16 __force)a->sin6_port)
289 break; 289 break;
290 if (diff < 0) 290 if (diff < 0)
291 break; 291 break;
@@ -296,12 +296,9 @@ void afs_merge_fs_addr6(struct afs_addr_list *alist, __be32 *xdr, u16 port)
296 alist->addrs + i, 296 alist->addrs + i,
297 sizeof(alist->addrs[0]) * (alist->nr_addrs - i)); 297 sizeof(alist->addrs[0]) * (alist->nr_addrs - i));
298 298
299 a = &alist->addrs[i].transport.sin6; 299 p = &alist->addrs[i].transport.sin6;
300 a->sin6_port = xport; 300 p->sin6_port = htons(port);
301 a->sin6_addr.s6_addr32[0] = xdr[0]; 301 memcpy(&p->sin6_addr, xdr, 16);
302 a->sin6_addr.s6_addr32[1] = xdr[1];
303 a->sin6_addr.s6_addr32[2] = xdr[2];
304 a->sin6_addr.s6_addr32[3] = xdr[3];
305 alist->nr_addrs++; 302 alist->nr_addrs++;
306} 303}
307 304