With multiple lports created per netdev, the packet_type structure is no
longer sufficient for receive demux.  Instead we need to match on the fabric
ID.

Signed-off-by: Chris Leech <[email protected]>
---

 drivers/scsi/fcoe/fcoe.c |   70 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 381e4e2..86d8b23 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -146,10 +146,48 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct 
net_device *dev,
                         struct net_device *orig_dev)
 {
        struct fcoe_softc *fc;
+       struct fc_lport *tlp, *lp = NULL;
+       struct Scsi_Host *shost;
+       struct fc_vport *vport;
+       unsigned long flags;
+       u32 d_id;
+       struct fc_frame_header *fh;
+       struct fip_header *fiph;
+
+       fiph = (void *)skb->data;
+       fh = ((void *)skb->data) + sizeof(*fiph);
+       d_id = ntoh24(fh->fh_d_id);
 
        fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
+       tlp = fc->ctlr.lp;
+
+       /* Might be an NPIV port, check the vport list */
+
+       if (d_id == fc_host_port_id(tlp->host) ||
+           !fc_host_port_id(tlp->host)) {
+               lp = tlp;
+       } else {
+               shost = tlp->host;
+               spin_lock_irqsave(shost->host_lock, flags);
+               list_for_each_entry(vport, &fc_host_vports(shost), peers) {
+                       tlp = vport->dd_data;
+                       if (d_id == fc_host_port_id(tlp->host) ||
+                           !fc_host_port_id(tlp->host)) {
+                               lp = tlp;
+                               break;
+                       }
+               }
+               spin_unlock_irqrestore(shost->host_lock, flags);
+       }
+       if (unlikely(!lp))
+               goto err;
+
+       fc = lport_priv(lp);
        fcoe_ctlr_recv(&fc->ctlr, skb);
        return 0;
+err:
+       kfree(skb);
+       return 0;
 }
 
 /**
@@ -821,21 +859,24 @@ static struct notifier_block fcoe_cpu_notifier = {
 int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
             struct packet_type *ptype, struct net_device *olddev)
 {
-       struct fc_lport *lp;
+       struct fc_lport *lp = NULL, *tlp;
        struct fcoe_rcv_info *fr;
        struct fcoe_softc *fc;
        struct fc_frame_header *fh;
        struct fcoe_percpu_s *fps;
        unsigned short oxid;
        unsigned int cpu = 0;
+       struct fc_vport *vport;
+       struct Scsi_Host *shost;
+       unsigned long flags;
 
        fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
-       lp = fc->ctlr.lp;
-       if (unlikely(lp == NULL)) {
+       tlp = fc->ctlr.lp;
+       if (unlikely(tlp == NULL)) {
                FCOE_NETDEV_DBG(dev, "Cannot find hba structure");
                goto err2;
        }
-       if (!lp->link_up)
+       if (!tlp->link_up)
                goto err2;
 
        FCOE_NETDEV_DBG(dev, "skb_info: len:%d data_len:%d head:%p "
@@ -863,6 +904,27 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
 
        oxid = ntohs(fh->fh_ox_id);
 
+       /* Might be an NPIV port, check the vport list */
+
+       if (ntoh24(fh->fh_d_id) == fc_host_port_id(tlp->host) ||
+           !fc_host_port_id(tlp->host)) {
+               lp = tlp;
+       } else {
+               shost = tlp->host;
+               spin_lock_irqsave(shost->host_lock, flags);
+               list_for_each_entry(vport, &fc_host_vports(shost), peers) {
+                       tlp = vport->dd_data;
+                       if (ntoh24(fh->fh_d_id) == fc_host_port_id(tlp->host) ||
+                           !fc_host_port_id(tlp->host)) {
+                               lp = tlp;
+                               break;
+                       }
+               }
+               spin_unlock_irqrestore(shost->host_lock, flags);
+       }
+       if (unlikely(!lp))
+               goto err2;
+
        fr = fcoe_dev_from_skb(skb);
        fr->fr_dev = lp;
        fr->ptype = ptype;

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to