diff options
author | Hannes Reinecke <hare@suse.de> | 2016-07-04 04:29:23 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-07-27 00:32:08 -0400 |
commit | d242e6680e81cea0343bd93ba862efa70a91a56c (patch) | |
tree | e6c3439435768b9d262c6f58d7397d0c6fa45409 /drivers/scsi/fcoe/fcoe.c | |
parent | b195d5e2bffd3de3f07e8683e6abddf099ea0822 (diff) |
fcoe: Use default VLAN for FIP VLAN discovery
FC-BB-6 states: FIP protocols shall be performed on a per-VLAN basis. It
is recommended to use the FIP VLAN discovery protocol on the default
VLAN.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Acked-by: Johannes Thumshirn <jth@kernel.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index c8a4305c7662..197dc62ea67a 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -92,6 +92,8 @@ static struct fcoe_interface | |||
92 | 92 | ||
93 | static int fcoe_fip_recv(struct sk_buff *, struct net_device *, | 93 | static int fcoe_fip_recv(struct sk_buff *, struct net_device *, |
94 | struct packet_type *, struct net_device *); | 94 | struct packet_type *, struct net_device *); |
95 | static int fcoe_fip_vlan_recv(struct sk_buff *, struct net_device *, | ||
96 | struct packet_type *, struct net_device *); | ||
95 | 97 | ||
96 | static void fcoe_fip_send(struct fcoe_ctlr *, struct sk_buff *); | 98 | static void fcoe_fip_send(struct fcoe_ctlr *, struct sk_buff *); |
97 | static void fcoe_update_src_mac(struct fc_lport *, u8 *); | 99 | static void fcoe_update_src_mac(struct fc_lport *, u8 *); |
@@ -363,6 +365,12 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, | |||
363 | fcoe->fip_packet_type.dev = netdev; | 365 | fcoe->fip_packet_type.dev = netdev; |
364 | dev_add_pack(&fcoe->fip_packet_type); | 366 | dev_add_pack(&fcoe->fip_packet_type); |
365 | 367 | ||
368 | if (netdev != real_dev) { | ||
369 | fcoe->fip_vlan_packet_type.func = fcoe_fip_vlan_recv; | ||
370 | fcoe->fip_vlan_packet_type.type = htons(ETH_P_FIP); | ||
371 | fcoe->fip_vlan_packet_type.dev = real_dev; | ||
372 | dev_add_pack(&fcoe->fip_vlan_packet_type); | ||
373 | } | ||
366 | return 0; | 374 | return 0; |
367 | } | 375 | } |
368 | 376 | ||
@@ -450,6 +458,8 @@ static void fcoe_interface_remove(struct fcoe_interface *fcoe) | |||
450 | */ | 458 | */ |
451 | __dev_remove_pack(&fcoe->fcoe_packet_type); | 459 | __dev_remove_pack(&fcoe->fcoe_packet_type); |
452 | __dev_remove_pack(&fcoe->fip_packet_type); | 460 | __dev_remove_pack(&fcoe->fip_packet_type); |
461 | if (netdev != fcoe->realdev) | ||
462 | __dev_remove_pack(&fcoe->fip_vlan_packet_type); | ||
453 | synchronize_net(); | 463 | synchronize_net(); |
454 | 464 | ||
455 | /* Delete secondary MAC addresses */ | 465 | /* Delete secondary MAC addresses */ |
@@ -520,6 +530,29 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev, | |||
520 | } | 530 | } |
521 | 531 | ||
522 | /** | 532 | /** |
533 | * fcoe_fip_vlan_recv() - Handler for received FIP VLAN discovery frames | ||
534 | * @skb: The receive skb | ||
535 | * @netdev: The associated net device | ||
536 | * @ptype: The packet_type structure which was used to register this handler | ||
537 | * @orig_dev: The original net_device the the skb was received on. | ||
538 | * (in case dev is a bond) | ||
539 | * | ||
540 | * Returns: 0 for success | ||
541 | */ | ||
542 | static int fcoe_fip_vlan_recv(struct sk_buff *skb, struct net_device *netdev, | ||
543 | struct packet_type *ptype, | ||
544 | struct net_device *orig_dev) | ||
545 | { | ||
546 | struct fcoe_interface *fcoe; | ||
547 | struct fcoe_ctlr *ctlr; | ||
548 | |||
549 | fcoe = container_of(ptype, struct fcoe_interface, fip_vlan_packet_type); | ||
550 | ctlr = fcoe_to_ctlr(fcoe); | ||
551 | fcoe_ctlr_recv(ctlr, skb); | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | /** | ||
523 | * fcoe_port_send() - Send an Ethernet-encapsulated FIP/FCoE frame | 556 | * fcoe_port_send() - Send an Ethernet-encapsulated FIP/FCoE frame |
524 | * @port: The FCoE port | 557 | * @port: The FCoE port |
525 | * @skb: The FIP/FCoE packet to be sent | 558 | * @skb: The FIP/FCoE packet to be sent |
@@ -539,7 +572,21 @@ static void fcoe_port_send(struct fcoe_port *port, struct sk_buff *skb) | |||
539 | */ | 572 | */ |
540 | static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | 573 | static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) |
541 | { | 574 | { |
542 | skb->dev = fcoe_from_ctlr(fip)->netdev; | 575 | struct fcoe_interface *fcoe = fcoe_from_ctlr(fip); |
576 | struct fip_frame { | ||
577 | struct ethhdr eth; | ||
578 | struct fip_header fip; | ||
579 | } __packed *frame; | ||
580 | |||
581 | /* | ||
582 | * Use default VLAN for FIP VLAN discovery protocol | ||
583 | */ | ||
584 | frame = (struct fip_frame *)skb->data; | ||
585 | if (frame->fip.fip_op == ntohs(FIP_OP_VLAN) && | ||
586 | fcoe->realdev != fcoe->netdev) | ||
587 | skb->dev = fcoe->realdev; | ||
588 | else | ||
589 | skb->dev = fcoe->netdev; | ||
543 | fcoe_port_send(lport_priv(fip->lp), skb); | 590 | fcoe_port_send(lport_priv(fip->lp), skb); |
544 | } | 591 | } |
545 | 592 | ||