[dpdk-dev] examples/ipsec-secgw: fix usage of incorrect port
Checks
Commit Message
When security offload is enabled, the packet should be forwarded on the
port configured in the SA. Security session will be configured on that
port only, and sending the packet on other ports could result in
unencrypted packets being sent out.
This would have performance improvements too, as the per packet LPM
lookup would be avoided for IPsec packets, in inline mode.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Signed-off-by: Anoob Joseph <anoob.joseph@cavium.com>
---
examples/ipsec-secgw/ipsec-secgw.c | 92 ++++++++++++++++++++++++++++++++------
1 file changed, 78 insertions(+), 14 deletions(-)
Comments
Hi,
Comments below
On 13-11-2017 22:53, Radu Nicolau wrote:
> Hi,
>
> Comments below
>
> On 11/13/2017 4:13 PM, Anoob Joseph wrote:
>> When security offload is enabled, the packet should be forwarded on the
>> port configured in the SA. Security session will be configured on that
>> port only, and sending the packet on other ports could result in
>> unencrypted packets being sent out.
> With a properly configured SP, SA and routing rule this will not
> happen, so we don't need to do this fix to make up for a wrongly
> written configuration file.
> I'm almost sure that the app will behave in the same way (i.e. forward
> unencrypted) for lookaside crypto if the configuration is incorrect.
The lookaside crypto will ensure encryption, even if the LPM port is
different.
>>
>> This would have performance improvements too, as the per packet LPM
>> lookup would be avoided for IPsec packets, in inline mode.
> Yes, there will be some performance gain, but not sure how much
> considering that LPM lookup is reasonably fast.
The 2nd lookup is significant for inline protocol for which I plan to
submit some patches. In case of inline protocol, the packet need not
have final headers by the time it is submitted to the ethernet driver.
For example, in case of ESP in tunnel mode, tunnel IPs from the SA need
to be used for LPM lookup. So all such cases(tunnel/transport, ipv4
tunnel in ipv6 and vice versa etc) need to be valuated and the final
addresses need to be determined before an LPM lookup can be done, which
adds significant overhead per packet.
>
> So I'm not sure if ack or nack, maybe Sergio can give a second opinion.
> But if ack, you will have to update the patch to include in the doc
> this behavior, the port configured in the SA takes precedence over the
> one in the routing rule.
>
> Regards,
> Radu
Thanks,
Anoob
Hi,
Please send a v2 with the doc update that describes the new behavior and I will ack it.
Regards,
Radu
> -----Original Message-----
> From: Anoob Joseph [mailto:ajoseph@caviumnetworks.com]
> Sent: Monday, November 13, 2017 7:25 PM
> To: Nicolau, Radu <radu.nicolau@intel.com>; Anoob Joseph
> <anoob.joseph@cavium.com>; Akhil Goyal <akhil.goyal@nxp.com>;
> Doherty, Declan <declan.doherty@intel.com>; Gonzalez Monroy, Sergio
> <sergio.gonzalez.monroy@intel.com>
> Cc: narayanaprasad.athreya@cavium.com;
> jerin.jacobkollanukkaran@cavium.com; dev@dpdk.org
> Subject: Re: [PATCH] examples/ipsec-secgw: fix usage of incorrect port
>
> Hi,
>
> Comments below
>
>
> On 13-11-2017 22:53, Radu Nicolau wrote:
> > Hi,
> >
> > Comments below
> >
> > On 11/13/2017 4:13 PM, Anoob Joseph wrote:
> >> When security offload is enabled, the packet should be forwarded on
> >> the port configured in the SA. Security session will be configured on
> >> that port only, and sending the packet on other ports could result in
> >> unencrypted packets being sent out.
> > With a properly configured SP, SA and routing rule this will not
> > happen, so we don't need to do this fix to make up for a wrongly
> > written configuration file.
> > I'm almost sure that the app will behave in the same way (i.e. forward
> > unencrypted) for lookaside crypto if the configuration is incorrect.
> The lookaside crypto will ensure encryption, even if the LPM port is different.
> >>
> >> This would have performance improvements too, as the per packet LPM
> >> lookup would be avoided for IPsec packets, in inline mode.
> > Yes, there will be some performance gain, but not sure how much
> > considering that LPM lookup is reasonably fast.
> The 2nd lookup is significant for inline protocol for which I plan to submit
> some patches. In case of inline protocol, the packet need not have final
> headers by the time it is submitted to the ethernet driver.
> For example, in case of ESP in tunnel mode, tunnel IPs from the SA need to
> be used for LPM lookup. So all such cases(tunnel/transport, ipv4 tunnel in
> ipv6 and vice versa etc) need to be valuated and the final addresses need to
> be determined before an LPM lookup can be done, which adds significant
> overhead per packet.
> >
> > So I'm not sure if ack or nack, maybe Sergio can give a second opinion.
> > But if ack, you will have to update the patch to include in the doc
> > this behavior, the port configured in the SA takes precedence over the
> > one in the routing rule.
> >
> > Regards,
> > Radu
>
> Thanks,
> Anoob
@@ -585,31 +585,72 @@ process_pkts_outbound_nosp(struct ipsec_ctx *ipsec_ctx,
traffic->ip6.num = nb_pkts_out;
}
+static inline int32_t
+get_hop_for_offload_pkt(struct rte_mbuf *pkt)
+{
+ struct ipsec_mbuf_metadata *priv;
+ struct ipsec_sa *sa;
+
+ priv = get_priv(pkt);
+
+ sa = priv->sa;
+ if (unlikely(sa == NULL)) {
+ RTE_LOG(ERR, IPSEC, "SA not saved in private data\n");
+ return -1;
+ }
+
+ return sa->portid;
+}
+
static inline void
route4_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts)
{
uint32_t hop[MAX_PKT_BURST * 2];
uint32_t dst_ip[MAX_PKT_BURST * 2];
+ int32_t pkt_hop = 0;
uint16_t i, offset;
+ uint16_t lpm_pkts = 0;
if (nb_pkts == 0)
return;
+ /* Need to do an LPM lookup for non-offload packets. Offload packets
+ * will have port ID in the SA
+ */
+
for (i = 0; i < nb_pkts; i++) {
- offset = offsetof(struct ip, ip_dst);
- dst_ip[i] = *rte_pktmbuf_mtod_offset(pkts[i],
- uint32_t *, offset);
- dst_ip[i] = rte_be_to_cpu_32(dst_ip[i]);
+ if (!(pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD)) {
+ /* Security offload not enabled. So an LPM lookup is
+ * required to get the hop
+ */
+ offset = offsetof(struct ip, ip_dst);
+ dst_ip[lpm_pkts] = *rte_pktmbuf_mtod_offset(pkts[i],
+ uint32_t *, offset);
+ dst_ip[lpm_pkts] = rte_be_to_cpu_32(dst_ip[lpm_pkts]);
+ lpm_pkts++;
+ }
}
- rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip, hop, nb_pkts);
+ rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip, hop, lpm_pkts);
+
+ lpm_pkts = 0;
for (i = 0; i < nb_pkts; i++) {
- if ((hop[i] & RTE_LPM_LOOKUP_SUCCESS) == 0) {
+ if ((pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD)) {
+ /* Read hop from the SA */
+ pkt_hop = get_hop_for_offload_pkt(pkts[i]);
+ } else {
+ /* Need to use hop returned by lookup */
+ pkt_hop = hop[lpm_pkts++];
+ if ((pkt_hop & RTE_LPM_LOOKUP_SUCCESS) == 0)
+ pkt_hop = -1;
+ }
+
+ if (pkt_hop == -1) {
rte_pktmbuf_free(pkts[i]);
continue;
}
- send_single_packet(pkts[i], hop[i] & 0xff);
+ send_single_packet(pkts[i], pkt_hop & 0xff);
}
}
@@ -619,26 +660,49 @@ route6_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts)
int32_t hop[MAX_PKT_BURST * 2];
uint8_t dst_ip[MAX_PKT_BURST * 2][16];
uint8_t *ip6_dst;
+ int32_t pkt_hop = 0;
uint16_t i, offset;
+ uint16_t lpm_pkts = 0;
if (nb_pkts == 0)
return;
+ /* Need to do an LPM lookup for non-offload packets. Offload packets
+ * will have port ID in the SA
+ */
+
for (i = 0; i < nb_pkts; i++) {
- offset = offsetof(struct ip6_hdr, ip6_dst);
- ip6_dst = rte_pktmbuf_mtod_offset(pkts[i], uint8_t *, offset);
- memcpy(&dst_ip[i][0], ip6_dst, 16);
+ if (!(pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD)) {
+ /* Security offload not enabled. So an LPM lookup is
+ * required to get the hop
+ */
+ offset = offsetof(struct ip6_hdr, ip6_dst);
+ ip6_dst = rte_pktmbuf_mtod_offset(pkts[i], uint8_t *,
+ offset);
+ memcpy(&dst_ip[lpm_pkts][0], ip6_dst, 16);
+ lpm_pkts++;
+ }
}
- rte_lpm6_lookup_bulk_func((struct rte_lpm6 *)rt_ctx, dst_ip,
- hop, nb_pkts);
+ rte_lpm6_lookup_bulk_func((struct rte_lpm6 *)rt_ctx, dst_ip, hop,
+ lpm_pkts);
+
+ lpm_pkts = 0;
for (i = 0; i < nb_pkts; i++) {
- if (hop[i] == -1) {
+ if ((pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD) == 0) {
+ /* Read hop from the SA */
+ pkt_hop = get_hop_for_offload_pkt(pkts[i]);
+ } else {
+ /* Need to use hop returned by lookup */
+ pkt_hop = hop[lpm_pkts++];
+ }
+
+ if (pkt_hop == -1) {
rte_pktmbuf_free(pkts[i]);
continue;
}
- send_single_packet(pkts[i], hop[i] & 0xff);
+ send_single_packet(pkts[i], pkt_hop & 0xff);
}
}