This is per FC-BB-5 Annex-D recommendation and per that if address checking fails then drop the frame.
FIP code paths are already doing this so only needed for fcoe frames. The src address checking is limited to only fip mode since this might break non-fip mode used in p2p due to used OUI based addressing in some p2p code paths, going forward FIP will be the only mode, therefore limited this to only FIP mode so that it won't break non-fip p2p mode for now. Signed-off-by: Vasu Dev <[email protected]> --- drivers/scsi/fcoe/fcoe.c | 22 +++++++++++++++++++++- include/scsi/libfcoe.h | 10 ++++++++++ 2 files changed, 31 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 44a0759..ab9a094 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -1210,6 +1210,8 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, struct fcoe_interface *fcoe; struct fc_frame_header *fh; struct fcoe_percpu_s *fps; + struct fcoe_port *port; + struct ethhdr *eh; unsigned int cpu; fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type); @@ -1228,11 +1230,29 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, skb->csum, skb->dev ? skb->dev->name : "<NULL>"); /* check for FCOE packet type */ - if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { + eh = eth_hdr(skb); + if (unlikely(eh->h_proto != htons(ETH_P_FCOE))) { FCOE_NETDEV_DBG(netdev, "Wrong FC type frame"); goto err; } + /* check for mac addresses */ + port = lport_priv(lport); + if (compare_ether_addr(eh->h_dest, port->data_src_addr) && + compare_ether_addr(eh->h_dest, fcoe->ctlr.ctl_src_addr) && + compare_ether_addr(eh->h_dest, (u8[6])FC_FCOE_FLOGI_MAC)) { + FCOE_NETDEV_DBG(netdev, "wrong destination mac address:%pM\n", + eh->h_dest); + goto err; + } + + if (is_fip_mode(&fcoe->ctlr) && + compare_ether_addr(eh->h_source, fcoe->ctlr.dest_addr)) { + FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n", + eh->h_source); + goto err; + } + /* * Check for minimum frame length, and make sure required FCoE * and FC headers are pulled into the linear data area. diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index ec13f51..81aee1c 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -170,4 +170,14 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *, u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); +/** + * is_fip_mode() - returns true if FIP mode selected. + * @fip: FCoE controller. + */ +static inline bool is_fip_mode(struct fcoe_ctlr *fip) +{ + return fip->state == FIP_ST_ENABLED; +} + + #endif /* _LIBFCOE_H */ _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
