diff options
author | Flavio Leitner <fbl@sysclose.org> | 2020-02-14 10:03:36 -0300 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2020-02-26 15:24:15 +0100 |
commit | 35b5586ba7ab2d7f53decb978df6bfea4600f6d4 (patch) | |
tree | 20405cf429d942ad6338477e47266091bf674f64 /lib | |
parent | 8c5163fe81ea05313eaefcd61cf036dd3fd2ae07 (diff) | |
download | openvswitch-35b5586ba7ab2d7f53decb978df6bfea4600f6d4.tar.gz |
userspace TSO: SCTP checksum offload optional.
Ideally SCTP checksum offload needs be advertised by the
NIC when userspace TSO is enabled. However, very few drivers
do that and it's not a widely used protocol. So, this patch
enables SCTP checksum offload if available, otherwise userspace
TSO can still be enabled but SCTP packets will be dropped on
NICs without support.
Fixes: 29cf9c1b3b9c ("userspace: Add TCP Segmentation Offload support")
Signed-off-by: Flavio Leitner <fbl@sysclose.org>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/netdev-dpdk.c | 21 | ||||
-rw-r--r-- | lib/netdev-linux.c | 1 | ||||
-rw-r--r-- | lib/netdev-provider.h | 3 | ||||
-rw-r--r-- | lib/netdev.c | 6 |
4 files changed, 28 insertions, 3 deletions
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index ec8be64aa..7ab81864d 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -152,8 +152,10 @@ typedef uint16_t dpdk_port_t; #define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ) -/* List of required flags advertised by the hardware that will be - * used if TSO is enabled. */ +/* List of required flags advertised by the hardware that will be used + * if TSO is enabled. Ideally this should include DEV_TX_OFFLOAD_SCTP_CKSUM. + * However, very few drivers supports that the moment and SCTP is not a + * widely used protocol as TCP and UDP, so it's optional. */ #define DPDK_TX_TSO_OFFLOAD_FLAGS (DEV_TX_OFFLOAD_TCP_TSO \ | DEV_TX_OFFLOAD_TCP_CKSUM \ | DEV_TX_OFFLOAD_UDP_CKSUM \ @@ -423,6 +425,7 @@ enum dpdk_hw_ol_features { NETDEV_RX_HW_CRC_STRIP = 1 << 1, NETDEV_RX_HW_SCATTER = 1 << 2, NETDEV_TX_TSO_OFFLOAD = 1 << 3, + NETDEV_TX_SCTP_CHECKSUM_OFFLOAD = 1 << 4, }; /* @@ -1006,6 +1009,9 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq) if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { conf.txmode.offloads |= DPDK_TX_TSO_OFFLOAD_FLAGS; + if (dev->hw_ol_features & NETDEV_TX_SCTP_CHECKSUM_OFFLOAD) { + conf.txmode.offloads |= DEV_TX_OFFLOAD_SCTP_CKSUM; + } } /* Limit configured rss hash functions to only those supported @@ -1141,6 +1147,13 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) if ((info.tx_offload_capa & tx_tso_offload_capa) == tx_tso_offload_capa) { dev->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; + if (info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) { + dev->hw_ol_features |= NETDEV_TX_SCTP_CHECKSUM_OFFLOAD; + } else { + VLOG_WARN("%s: Tx SCTP checksum offload is not supported, " + "SCTP packets sent to this device will be dropped", + netdev_get_name(&dev->up)); + } } else { VLOG_WARN("%s: Tx TSO offload is not supported.", netdev_get_name(&dev->up)); @@ -5116,6 +5129,9 @@ netdev_dpdk_reconfigure(struct netdev *netdev) netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM; netdev->ol_flags |= NETDEV_TX_OFFLOAD_UDP_CKSUM; netdev->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM; + if (dev->hw_ol_features & NETDEV_TX_SCTP_CHECKSUM_OFFLOAD) { + netdev->ol_flags |= NETDEV_TX_OFFLOAD_SCTP_CKSUM; + } } dev->tx_q = netdev_dpdk_alloc_txq(netdev->n_txq); @@ -5258,6 +5274,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_TSO; netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM; netdev->ol_flags |= NETDEV_TX_OFFLOAD_UDP_CKSUM; + netdev->ol_flags |= NETDEV_TX_OFFLOAD_SCTP_CKSUM; netdev->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM; vhost_unsup_flags = 1ULL << VIRTIO_NET_F_HOST_ECN | 1ULL << VIRTIO_NET_F_HOST_UFO; diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 85f3a7367..432645601 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -924,6 +924,7 @@ netdev_linux_common_construct(struct netdev *netdev_) netdev_->ol_flags |= NETDEV_TX_OFFLOAD_TCP_TSO; netdev_->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM; netdev_->ol_flags |= NETDEV_TX_OFFLOAD_UDP_CKSUM; + netdev_->ol_flags |= NETDEV_TX_OFFLOAD_SCTP_CKSUM; netdev_->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM; } diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index 00677dc9d..6f509424b 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -41,7 +41,8 @@ enum netdev_ol_flags { NETDEV_TX_OFFLOAD_IPV4_CKSUM = 1 << 0, NETDEV_TX_OFFLOAD_TCP_CKSUM = 1 << 1, NETDEV_TX_OFFLOAD_UDP_CKSUM = 1 << 2, - NETDEV_TX_OFFLOAD_TCP_TSO = 1 << 3, + NETDEV_TX_OFFLOAD_SCTP_CKSUM = 1 << 3, + NETDEV_TX_OFFLOAD_TCP_TSO = 1 << 4, }; /* A network device (e.g. an Ethernet device). diff --git a/lib/netdev.c b/lib/netdev.c index a55f77961..8c44eee8e 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -814,6 +814,12 @@ netdev_send_prepare_packet(const uint64_t netdev_flags, VLOG_ERR_BUF(errormsg, "No UDP checksum support"); return false; } + } else if (dp_packet_hwol_l4_is_sctp(packet)) { + if (!(netdev_flags & NETDEV_TX_OFFLOAD_SCTP_CKSUM)) { + /* Fall back to SCTP csum in software. */ + VLOG_ERR_BUF(errormsg, "No SCTP checksum support"); + return false; + } } else { VLOG_ERR_BUF(errormsg, "No L4 checksum support: mask: %"PRIu64, l4_mask); |