[qca-nss-clients] expand tailroom or headroom
When packets arrive for IPsec transmit expand the headroom
or tailroom if it is less than the desired values
Change-Id: I9e1e703000bc970aed2cea3ce340df4d7a91a161
Signed-off-by: Samarjeet Banerjee <banerjee@codeaurora.org>
diff --git a/nss_ipsecmgr.c b/nss_ipsecmgr.c
index e1dded0..92f45bc 100644
--- a/nss_ipsecmgr.c
+++ b/nss_ipsecmgr.c
@@ -19,6 +19,7 @@
*/
#include <linux/types.h>
#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <linux/skbuff.h>
#include <linux/module.h>
#include <linux/netdevice.h>
@@ -883,15 +884,18 @@
*/
static netdev_tx_t nss_ipsecmgr_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
- uint32_t if_num;
- struct iphdr *inner_ip;
struct nss_ipsecmgr_priv *priv;
struct nss_ipsecmgr_tbl *encap;
+ int nhead, ntail;
+ uint32_t if_num;
if_num = NSS_IPSEC_ENCAP_IF_NUMBER;
priv = netdev_priv(dev);
encap = &priv->encap;
+ nhead = dev->needed_headroom;
+ ntail = dev->needed_tailroom;
+
if (skb_is_nonlinear(skb)) {
nss_ipsecmgr_error("%p: NSS IPSEC does not support fragments %p\n", priv->nss_ctx, skb);
goto fail;
@@ -906,15 +910,18 @@
}
/*
- * Check the packet head room & tail room
+ * Check and expand the packet head room and tail room
*/
- if (unlikely(skb_headroom(skb) < dev->needed_headroom)) {
- nss_ipsecmgr_error("%p: Insufficient head room :%d in skb: %p\n", priv->nss_ctx, skb_headroom(skb), skb);
+ if ((skb_headroom(skb) < nhead) && pskb_expand_head(skb, nhead, ntail, GFP_KERNEL)) {
+ nss_ipsecmgr_error("%p: unable to expand headroom & tailroom(0x%p)\n", priv->nss_ctx, skb);
goto fail;
}
- if (unlikely(skb_tailroom(skb) < dev->needed_tailroom)) {
- nss_ipsecmgr_error("%p: Insufficient tail room:%d in skb: %p\n", priv->nss_ctx, skb_tailroom(skb), skb);
+ /*
+ * Check and expand the packet tail room only
+ */
+ if ((skb_tailroom(skb) < ntail) && pskb_expand_head(skb, 0, ntail, GFP_KERNEL)) {
+ nss_ipsecmgr_error("%p: unable to expand tailroom(0x%p)\n", priv->nss_ctx, skb);
goto fail;
}
@@ -926,22 +933,16 @@
goto fail;
}
- inner_ip = (struct iphdr *)ip_hdr(skb);
+ switch (skb->protocol) {
+ case htons(ETH_P_IP):
+ BUG_ON(ip_hdr(skb)->ttl == 0);
+ break;
- /*
- * Validate if packet has ip options
- */
- if ((inner_ip->version != IPVERSION) || (inner_ip->ihl != 5)) {
- nss_ipsecmgr_error("%p: Unsupported IP header ipver: 0x%x iphdr_len: 0x%x\n", priv->nss_ctx,
- inner_ip->version, inner_ip->ihl);
- goto fail;
- }
+ case htons(ETH_P_IPV6):
+ BUG_ON(ipv6_hdr(skb)->hop_limit == 0);
+ break;
- /*
- * Check the TTL value
- */
- if ((inner_ip->ttl == 0)) {
- nss_ipsecmgr_error("%p: IP TTL is zero, unabled to transmit\n", priv->nss_ctx);
+ default:
goto fail;
}