summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-10 22:55:03 -0800
committerDavid S. Miller <davem@davemloft.net>2010-01-10 22:55:03 -0800
commitd4a66e752d0b19934dd208884f8605fe385aaaa9 (patch)
tree72fb727be1d7636aae9cddfe9aa93ac9dec75daf /drivers/scsi
parentbdbec4b86ee99b020e159f9bd604003a3ae3b0ab (diff)
parentfa15e99b6bb44aa86b241a43ca8c509e91f80153 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/benet/be_cmds.h include/linux/sysctl.h
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c
index 26ffdcd5a43..2a3cf823d68 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c
@@ -1440,6 +1440,10 @@ void cxgb3i_c3cn_release(struct s3_conn *c3cn)
static int is_cxgb3_dev(struct net_device *dev)
{
struct cxgb3i_sdev_data *cdata;
+ struct net_device *ndev = dev;
+
+ if (dev->priv_flags & IFF_802_1Q_VLAN)
+ ndev = vlan_dev_real_dev(dev);
write_lock(&cdata_rwlock);
list_for_each_entry(cdata, &cdata_list, list) {
@@ -1447,7 +1451,7 @@ static int is_cxgb3_dev(struct net_device *dev)
int i;
for (i = 0; i < ports->nports; i++)
- if (dev == ports->lldevs[i]) {
+ if (ndev == ports->lldevs[i]) {
write_unlock(&cdata_rwlock);
return 1;
}
@@ -1566,6 +1570,26 @@ out_err:
return -EINVAL;
}
+/* *
+ * cxgb3i_find_dev - find the interface associated with the given address
+ * @ipaddr: ip address
+ */
+static struct net_device *
+cxgb3i_find_dev(struct net_device *dev, __be32 ipaddr)
+{
+ struct flowi fl;
+ int err;
+ struct rtable *rt;
+
+ memset(&fl, 0, sizeof(fl));
+ fl.nl_u.ip4_u.daddr = ipaddr;
+
+ err = ip_route_output_key(dev ? dev_net(dev) : &init_net, &rt, &fl);
+ if (!err)
+ return (&rt->u.dst)->dev;
+
+ return NULL;
+}
/**
* cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address
@@ -1581,6 +1605,7 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn,
struct cxgb3i_sdev_data *cdata;
struct t3cdev *cdev;
__be32 sipv4;
+ struct net_device *dstdev;
int err;
c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev);
@@ -1591,6 +1616,13 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn,
c3cn->daddr.sin_port = usin->sin_port;
c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr;
+ dstdev = cxgb3i_find_dev(dev, usin->sin_addr.s_addr);
+ if (!dstdev || !is_cxgb3_dev(dstdev))
+ return -ENETUNREACH;
+
+ if (dstdev->priv_flags & IFF_802_1Q_VLAN)
+ dev = dstdev;
+
rt = find_route(dev, c3cn->saddr.sin_addr.s_addr,
c3cn->daddr.sin_addr.s_addr,
c3cn->saddr.sin_port,