diff options
| author | Sean Hefty <sean.hefty@intel.com> | 2009-11-19 15:55:22 -0500 |
|---|---|---|
| committer | Roland Dreier <rolandd@cisco.com> | 2009-11-19 15:55:22 -0500 |
| commit | d2e0886245aa9eebc1a4710c861d263b09eac493 (patch) | |
| tree | 0343fc239b6bc63b992878b2721af320feb39101 | |
| parent | 6266ed6e4164466177238b11ecb825a3a108a3e4 (diff) | |
IB/addr: Verify source and destination address families match
If a source address is provided, verify that the address family matches
that of the destination address. If the source is not specified, use the
same address family as the destination.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
| -rw-r--r-- | drivers/infiniband/core/addr.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 788a02ef01dd..b59ba7ccef0e 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
| @@ -461,18 +461,27 @@ int rdma_resolve_ip(struct rdma_addr_client *client, | |||
| 461 | if (!req) | 461 | if (!req) |
| 462 | return -ENOMEM; | 462 | return -ENOMEM; |
| 463 | 463 | ||
| 464 | if (src_addr) | 464 | src_in = (struct sockaddr *) &req->src_addr; |
| 465 | memcpy(&req->src_addr, src_addr, ip_addr_size(src_addr)); | 465 | dst_in = (struct sockaddr *) &req->dst_addr; |
| 466 | memcpy(&req->dst_addr, dst_addr, ip_addr_size(dst_addr)); | 466 | |
| 467 | if (src_addr) { | ||
| 468 | if (src_addr->sa_family != dst_addr->sa_family) { | ||
| 469 | ret = -EINVAL; | ||
| 470 | goto err; | ||
| 471 | } | ||
| 472 | |||
| 473 | memcpy(src_in, src_addr, ip_addr_size(src_addr)); | ||
| 474 | } else { | ||
| 475 | src_in->sa_family = dst_addr->sa_family; | ||
| 476 | } | ||
| 477 | |||
| 478 | memcpy(dst_in, dst_addr, ip_addr_size(dst_addr)); | ||
| 467 | req->addr = addr; | 479 | req->addr = addr; |
| 468 | req->callback = callback; | 480 | req->callback = callback; |
| 469 | req->context = context; | 481 | req->context = context; |
| 470 | req->client = client; | 482 | req->client = client; |
| 471 | atomic_inc(&client->refcount); | 483 | atomic_inc(&client->refcount); |
| 472 | 484 | ||
| 473 | src_in = (struct sockaddr *) &req->src_addr; | ||
| 474 | dst_in = (struct sockaddr *) &req->dst_addr; | ||
| 475 | |||
| 476 | req->status = addr_resolve_local(src_in, dst_in, addr); | 485 | req->status = addr_resolve_local(src_in, dst_in, addr); |
| 477 | if (req->status == -EADDRNOTAVAIL) | 486 | if (req->status == -EADDRNOTAVAIL) |
| 478 | req->status = addr_resolve_remote(src_in, dst_in, addr); | 487 | req->status = addr_resolve_remote(src_in, dst_in, addr); |
| @@ -490,10 +499,12 @@ int rdma_resolve_ip(struct rdma_addr_client *client, | |||
| 490 | default: | 499 | default: |
| 491 | ret = req->status; | 500 | ret = req->status; |
| 492 | atomic_dec(&client->refcount); | 501 | atomic_dec(&client->refcount); |
| 493 | kfree(req); | 502 | goto err; |
| 494 | break; | ||
| 495 | } | 503 | } |
| 496 | return ret; | 504 | return ret; |
| 505 | err: | ||
| 506 | kfree(req); | ||
| 507 | return ret; | ||
| 497 | } | 508 | } |
| 498 | EXPORT_SYMBOL(rdma_resolve_ip); | 509 | EXPORT_SYMBOL(rdma_resolve_ip); |
| 499 | 510 | ||
