diff options
author | Matthew Vick <matthew.vick@intel.com> | 2015-01-29 02:17:22 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2015-03-03 04:07:21 -0500 |
commit | 8c1a90aa497dc4e2f971028c4484566629757357 (patch) | |
tree | f32bb06ba0904ef78696b6f9ee035df82822b844 /drivers/net/ethernet | |
parent | b898441f4ece44933af90b116b467f7864dd1ae7 (diff) |
fm10k: Modify tunnel length header check when offloading
The FM10000 host interface can only support up to 184 bytes when
performing tunnel offloads. Because of this, a check was added to
prevent the driver from attempting to feed a header to the hardware too
big for it to parse. Make this check a little more robust by calculating
the inner L4 header length based on whether it is TCP or UDP.
Cc: Joe Stringer <joestringer@nicira.com>
Signed-off-by: Matthew Vick <matthew.vick@intel.com>
Tested-by: Krishneil Singh <Krishneil.k.singh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_main.c | 33 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_type.h | 3 |
2 files changed, 27 insertions, 9 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index 84ab9eea2768..a7d379802e7c 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c | |||
@@ -711,10 +711,6 @@ static struct ethhdr *fm10k_gre_is_nvgre(struct sk_buff *skb) | |||
711 | if (nvgre_hdr->flags & FM10K_NVGRE_RESERVED0_FLAGS) | 711 | if (nvgre_hdr->flags & FM10K_NVGRE_RESERVED0_FLAGS) |
712 | return NULL; | 712 | return NULL; |
713 | 713 | ||
714 | /* verify protocol is transparent Ethernet bridging */ | ||
715 | if (nvgre_hdr->proto != htons(ETH_P_TEB)) | ||
716 | return NULL; | ||
717 | |||
718 | /* report start of ethernet header */ | 714 | /* report start of ethernet header */ |
719 | if (nvgre_hdr->flags & NVGRE_TNI) | 715 | if (nvgre_hdr->flags & NVGRE_TNI) |
720 | return (struct ethhdr *)(nvgre_hdr + 1); | 716 | return (struct ethhdr *)(nvgre_hdr + 1); |
@@ -724,13 +720,11 @@ static struct ethhdr *fm10k_gre_is_nvgre(struct sk_buff *skb) | |||
724 | 720 | ||
725 | static __be16 fm10k_tx_encap_offload(struct sk_buff *skb) | 721 | static __be16 fm10k_tx_encap_offload(struct sk_buff *skb) |
726 | { | 722 | { |
723 | u8 l4_hdr = 0, inner_l4_hdr = 0, inner_l4_hlen; | ||
727 | struct ethhdr *eth_hdr; | 724 | struct ethhdr *eth_hdr; |
728 | u8 l4_hdr = 0; | ||
729 | 725 | ||
730 | /* fm10k supports 184 octets of outer+inner headers. Minus 20 for inner L4. */ | 726 | if (skb->inner_protocol_type != ENCAP_TYPE_ETHER || |
731 | #define FM10K_MAX_ENCAP_TRANSPORT_OFFSET 164 | 727 | skb->inner_protocol != htons(ETH_P_TEB)) |
732 | if (skb_inner_transport_header(skb) - skb_mac_header(skb) > | ||
733 | FM10K_MAX_ENCAP_TRANSPORT_OFFSET) | ||
734 | return 0; | 728 | return 0; |
735 | 729 | ||
736 | switch (vlan_get_protocol(skb)) { | 730 | switch (vlan_get_protocol(skb)) { |
@@ -760,12 +754,33 @@ static __be16 fm10k_tx_encap_offload(struct sk_buff *skb) | |||
760 | 754 | ||
761 | switch (eth_hdr->h_proto) { | 755 | switch (eth_hdr->h_proto) { |
762 | case htons(ETH_P_IP): | 756 | case htons(ETH_P_IP): |
757 | inner_l4_hdr = inner_ip_hdr(skb)->protocol; | ||
758 | break; | ||
763 | case htons(ETH_P_IPV6): | 759 | case htons(ETH_P_IPV6): |
760 | inner_l4_hdr = inner_ipv6_hdr(skb)->nexthdr; | ||
764 | break; | 761 | break; |
765 | default: | 762 | default: |
766 | return 0; | 763 | return 0; |
767 | } | 764 | } |
768 | 765 | ||
766 | switch (inner_l4_hdr) { | ||
767 | case IPPROTO_TCP: | ||
768 | inner_l4_hlen = inner_tcp_hdrlen(skb); | ||
769 | break; | ||
770 | case IPPROTO_UDP: | ||
771 | inner_l4_hlen = 8; | ||
772 | break; | ||
773 | default: | ||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | /* The hardware allows tunnel offloads only if the combined inner and | ||
778 | * outer header is 184 bytes or less | ||
779 | */ | ||
780 | if (skb_inner_transport_header(skb) + inner_l4_hlen - | ||
781 | skb_mac_header(skb) > FM10K_TUNNEL_HEADER_LENGTH) | ||
782 | return 0; | ||
783 | |||
769 | return eth_hdr->h_proto; | 784 | return eth_hdr->h_proto; |
770 | } | 785 | } |
771 | 786 | ||
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_type.h b/drivers/net/ethernet/intel/fm10k/fm10k_type.h index 7c6d9d5a8ae5..abb8a03824ac 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_type.h +++ b/drivers/net/ethernet/intel/fm10k/fm10k_type.h | |||
@@ -356,6 +356,9 @@ struct fm10k_hw; | |||
356 | #define FM10K_QUEUE_DISABLE_TIMEOUT 100 | 356 | #define FM10K_QUEUE_DISABLE_TIMEOUT 100 |
357 | #define FM10K_RESET_TIMEOUT 150 | 357 | #define FM10K_RESET_TIMEOUT 150 |
358 | 358 | ||
359 | /* Maximum supported combined inner and outer header length for encapsulation */ | ||
360 | #define FM10K_TUNNEL_HEADER_LENGTH 184 | ||
361 | |||
359 | /* VF registers */ | 362 | /* VF registers */ |
360 | #define FM10K_VFCTRL 0x00000 | 363 | #define FM10K_VFCTRL 0x00000 |
361 | #define FM10K_VFCTRL_RST 0x00000008 | 364 | #define FM10K_VFCTRL_RST 0x00000008 |