summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFlavio Leitner <fbl@sysclose.org>2020-02-14 10:03:36 -0300
committerIlya Maximets <i.maximets@ovn.org>2020-02-26 15:24:15 +0100
commit35b5586ba7ab2d7f53decb978df6bfea4600f6d4 (patch)
tree20405cf429d942ad6338477e47266091bf674f64 /lib
parent8c5163fe81ea05313eaefcd61cf036dd3fd2ae07 (diff)
downloadopenvswitch-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.c21
-rw-r--r--lib/netdev-linux.c1
-rw-r--r--lib/netdev-provider.h3
-rw-r--r--lib/netdev.c6
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);