DPDK 18.11 为I40E/IXGBE 添加SBP(Save Bad Packet)特性

背景

业务测试验收, 甲方使用发包机 胡乱 造包 发送垃圾报文. 没有填充CRC, 导致DPDK ierror计数器 暴增.

开发DPDK, 允许没有CRC的报文通过.

设备

82599 的测试结果, 开启SBP特性, 报文会少4字节.
X710 的测试结果, 开启SBP特性, 报文一字不差.

开发

IXGBE/I40E 驱动层 支持 SAVE_BAD_PACKET / DISABLE_HW_APPAEND_CRC

补丁

sbp.diff

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 557299e..545e775 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3469,6 +3469,7 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
DEV_RX_OFFLOAD_SCATTER |
DEV_RX_OFFLOAD_VLAN_EXTEND |
DEV_RX_OFFLOAD_VLAN_FILTER |
+ DEV_RX_OFFLOAD_SAVE_BAD_PACKET |
DEV_RX_OFFLOAD_JUMBO_FRAME;

dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
@@ -3486,6 +3487,8 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
DEV_TX_OFFLOAD_IPIP_TNL_TSO |
DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
DEV_TX_OFFLOAD_MULTI_SEGS |
+ DEV_TX_OFFLOAD_DISABLE_APPEND_FRAME |
+ DEV_TX_OFFLOAD_DISABLE_APPEND_CRC |
dev_info->tx_queue_offload_capa;
dev_info->dev_capa =
RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
@@ -6296,6 +6299,23 @@ struct i40e_vsi *
return ret;
}

+//根据 RX/TX flags 设定 网卡 收包/发包 特征
+static int
+i40e_set_action(struct i40e_pf *pf)
+{
+ struct i40e_vsi *vsi = pf->main_vsi;
+ struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+ struct rte_eth_dev *dev = container_of(pf, struct i40e_adapter, pf)->eth_dev;
+ struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode;
+ struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+ bool allow_tx_hw_pad = txmode->offloads & DEV_TX_OFFLOAD_DISABLE_APPEND_FRAME ? FALSE:TRUE;
+ bool allow_tx_hw_crc = txmode->offloads & DEV_TX_OFFLOAD_DISABLE_APPEND_CRC ? FALSE:TRUE;
+ bool allow_rx_hw_sbp = rxmode->offloads & DEV_RX_OFFLOAD_SAVE_BAD_PACKET ? TRUE:FALSE;
+ i40e_aq_set_port_parameters(hw, vsi->seid, allow_rx_hw_sbp, allow_tx_hw_pad, TRUE, NULL);
+ i40e_aq_set_mac_config(hw, I40E_FRAME_SIZE_MAX, allow_tx_hw_crc, 0, NULL);
+ return 0;
+}
+
static int
i40e_dev_rxtx_init(struct i40e_pf *pf)
{
@@ -6312,6 +6332,8 @@ struct i40e_vsi *
return err;
}

+ //根据 RX/TX flags 设定 网卡 收包/发包 特征
+ i40e_set_action(pf);
return err;
}

diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index ddc7efa..a66ac58 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2433,6 +2433,8 @@ void __attribute__((cold))
DEV_TX_OFFLOAD_TCP_CKSUM |
DEV_TX_OFFLOAD_SCTP_CKSUM |
DEV_TX_OFFLOAD_TCP_TSO |
+ DEV_TX_OFFLOAD_DISABLE_APPEND_FRAME |
+ DEV_TX_OFFLOAD_DISABLE_APPEND_CRC |
DEV_TX_OFFLOAD_MULTI_SEGS;

if (hw->mac.type == ixgbe_mac_82599EB ||
@@ -2853,6 +2855,7 @@ static void __attribute__((cold))
DEV_RX_OFFLOAD_TCP_CKSUM |
DEV_RX_OFFLOAD_KEEP_CRC |
DEV_RX_OFFLOAD_JUMBO_FRAME |
+ DEV_RX_OFFLOAD_SAVE_BAD_PACKET |
DEV_RX_OFFLOAD_SCATTER;

if (hw->mac.type == ixgbe_mac_82598EB)
@@ -4850,6 +4853,13 @@ int __attribute__((cold))
fctrl |= IXGBE_FCTRL_BAM;
fctrl |= IXGBE_FCTRL_DPF;
fctrl |= IXGBE_FCTRL_PMCF;
+
+ //如果 允许 保存 错误 报文
+ if(rx_conf->offloads & DEV_RX_OFFLOAD_SAVE_BAD_PACKET)
+ {
+ fctrl |= IXGBE_FCTRL_SBP;
+ }
+
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);

/*
@@ -4998,6 +5008,7 @@ void __attribute__((cold))
uint32_t hlreg0;
uint32_t txctrl;
uint16_t i;
+ struct rte_eth_txmode *tx_conf = &dev->data->dev_conf.txmode;

PMD_INIT_FUNC_TRACE();
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -5006,7 +5017,27 @@ void __attribute__((cold))
* (TSO requirement)
*/
hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
- hlreg0 |= (IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_TXPADEN);
+
+ //如果禁用网卡 CRC 检测
+ if(tx_conf->offloads & DEV_TX_OFFLOAD_DISABLE_APPEND_CRC)
+ {
+ hlreg0 &=~IXGBE_HLREG0_TXCRCEN;
+ }
+ else
+ {
+ hlreg0 |= IXGBE_HLREG0_TXCRCEN;
+ }
+
+ //如果禁用网卡对齐
+ if(tx_conf->offloads & DEV_TX_OFFLOAD_DISABLE_APPEND_FRAME)
+ {
+ hlreg0 &= ~IXGBE_HLREG0_TXPADEN;
+ }
+ else
+ {
+ hlreg0 |= IXGBE_HLREG0_TXPADEN;
+ }
+
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);

/* Setup the Base and Length of the Tx Descriptor Rings */
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 1960f3a..379cc03 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -957,6 +957,7 @@ struct rte_eth_conf {
#define DEV_RX_OFFLOAD_KEEP_CRC 0x00010000
#define DEV_RX_OFFLOAD_SCTP_CKSUM 0x00020000
#define DEV_RX_OFFLOAD_OUTER_UDP_CKSUM 0x00040000
+#define DEV_RX_OFFLOAD_SAVE_BAD_PACKET 0x10000000 //网卡收包 保存错帧

#define DEV_RX_OFFLOAD_CHECKSUM (DEV_RX_OFFLOAD_IPV4_CKSUM | \
DEV_RX_OFFLOAD_UDP_CKSUM | \
@@ -1019,6 +1020,9 @@ struct rte_eth_conf {
*/
#define DEV_TX_OFFLOAD_MATCH_METADATA 0x00200000

+#define DEV_TX_OFFLOAD_DISABLE_APPEND_FRAME 0x10000000 //禁止网卡填充帧(发送小包时)
+#define DEV_TX_OFFLOAD_DISABLE_APPEND_CRC 0x20000000 //禁止网卡追加4字节CRC
+
#define RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP 0x00000001
/**< Device supports Rx queue setup after device started*/
#define RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP 0x00000002