[qca-nss-clients] Avoid fragmentation for wan to lan direction
Added support for pre-fragmentation scenario for gre_redir.
Change-Id: If6a43c64edb04d260a95b4f4f1db61eb787ff638
Signed-off-by: Himanshu Joshi <himajosh@codeaurora.org>
diff --git a/netlink/nss_nlgre_redir_cmd.c b/netlink/nss_nlgre_redir_cmd.c
index 3653bea..d9f8364 100644
--- a/netlink/nss_nlgre_redir_cmd.c
+++ b/netlink/nss_nlgre_redir_cmd.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2015-2016,2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016,2018-2020, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -29,6 +29,8 @@
#include "nss_nlgre_redir_cmd.h"
#include "nss_nlgre_redir_cmn.h"
#include "nss_nlgre_redir_lag.h"
+#include "nss_nlipv6_if.h"
+#include "nss_nlipv4_if.h"
/*
* To get lock on deploy_mode
@@ -425,10 +427,25 @@
* nss_nlgre_redir_cmd_get_ifnum()
* Get the interface number corresponding to netdev
*/
-int nss_nlgre_redir_cmd_get_ifnum(struct net_device* dev, enum nss_dynamic_interface_type type)
+int nss_nlgre_redir_cmd_get_ifnum(struct net_device *dev, uint8_t proto)
{
+ enum nss_dynamic_interface_type type;
int ifnum;
+ switch (proto) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
+ type = NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER;
+ break;
+ case IPPROTO_GRE:
+ type = NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER;
+ break;
+ default:
+ nss_nl_error("Invalid protocol %d\n", proto);
+ return -1;
+ }
+
/*
* Get the interface number depending upon the dev and type
*/
@@ -441,3 +458,38 @@
return ifnum;
}
+/*
+ * nss_nlgre_redir_cmd_get_mtu()
+ * Returns the mtu based on the device passed
+ */
+int nss_nlgre_redir_cmd_get_mtu(struct net_device *dev, uint8_t iptype, int ifnum)
+{
+ enum nss_dynamic_interface_type type;
+ struct nss_ctx_instance *nss_ctx;
+ int mtu = dev->mtu;
+
+ nss_ctx = nss_gre_redir_get_context();
+ type = nss_dynamic_interface_get_type(nss_ctx, ifnum);
+ switch (iptype) {
+ case NSS_GRE_REDIR_IP_HDR_TYPE_IPV4:
+ if (type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER) {
+ mtu = NSS_NLIPV4_MAX_MTU;
+ } else if (mtu < NSS_NLIPV4_MIN_MTU) {
+ mtu = NSS_NLIPV4_MIN_MTU;
+ }
+
+ break;
+ case NSS_GRE_REDIR_IP_HDR_TYPE_IPV6:
+ if (type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER) {
+ mtu = NSS_NLIPV6_MAX_MTU;
+ } else if (mtu < NSS_NLIPV6_MIN_MTU) {
+ mtu = NSS_NLIPV6_MIN_MTU;
+ }
+
+ break;
+ }
+
+ return mtu;
+}
+
+
diff --git a/netlink/nss_nlgre_redir_cmd.h b/netlink/nss_nlgre_redir_cmd.h
index 858f82a..9e759f0 100644
--- a/netlink/nss_nlgre_redir_cmd.h
+++ b/netlink/nss_nlgre_redir_cmd.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014-2015,2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015,2019-2020, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -46,6 +46,12 @@
* nss_nlgre_redir_cmd_get_ifnum()
* Get the interface number corresponding to netdev
*/
-int nss_nlgre_redir_cmd_get_ifnum(struct net_device* dev, enum nss_dynamic_interface_type type);
+int nss_nlgre_redir_cmd_get_ifnum(struct net_device *dev, uint8_t proto);
+
+/*
+ * nss_nlgre_redir_cmd_get_mtu()
+ * Returns the mtu based on the device passed
+ */
+int nss_nlgre_redir_cmd_get_mtu(struct net_device *dev, uint8_t iptype, int ifnum);
#endif /* __NSS_NLGRE_REDIR_CMD_H */
diff --git a/netlink/nss_nlgre_redir_cmn.c b/netlink/nss_nlgre_redir_cmn.c
index f927a9d..7a1b7e0 100644
--- a/netlink/nss_nlgre_redir_cmn.c
+++ b/netlink/nss_nlgre_redir_cmn.c
@@ -135,14 +135,14 @@
static void nss_nlgre_redir_cmn_host_data_cb(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi)
{
struct nss_ctx_instance *nss_ctx = nss_gre_redir_get_context();
- struct nss_gre_redir_decap_per_pkt_metadata *meta_data_decap = NULL;
if (!skb) {
nss_nl_trace("%p: SKB is NULL\n", nss_ctx);
return;
}
- meta_data_decap = (struct nss_gre_redir_decap_per_pkt_metadata *)(skb->data - NSS_GRE_REDIR_PER_PACKET_METADATA_OFFSET);
+ nss_nl_trace("%p: Exception packet on host inner:\n", skb);
+ nss_nlgre_redir_cmn_print_hex_dump(skb);
skb->protocol = eth_type_trans(skb, netdev);
netif_receive_skb(skb);
}
@@ -153,9 +153,17 @@
*/
static void nss_nlgre_redir_cmn_wifi_offl_data_cb(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi)
{
+ struct nss_ctx_instance *nss_ctx = nss_gre_redir_get_context();
+
+ if (!skb) {
+ nss_nl_warn("%p: SKB is NULL\n", nss_ctx);
+ return;
+ }
+
nss_nl_trace("%p: Exception packet on wifi offld inner:\n", skb);
- nss_nlgre_redir_cmn_print_skb(skb);
- dev_kfree_skb(skb);
+ nss_nlgre_redir_cmn_print_hex_dump(skb);
+ skb->protocol = eth_type_trans(skb, netdev);
+ netif_receive_skb(skb);
}
/*
@@ -165,7 +173,7 @@
static void nss_nlgre_redir_cmn_sjack_data_cb(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi)
{
nss_nl_trace("%p: Exception packet on sjack inner node:\n", skb);
- nss_nlgre_redir_cmn_print_skb(skb);
+ nss_nlgre_redir_cmn_print_hex_dump(skb);
dev_kfree_skb(skb);
}
@@ -176,7 +184,7 @@
static void nss_nlgre_redir_cmn_outer_data_cb(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi)
{
nss_nl_trace("%p: Exception packet on outer node:\n", skb);
- nss_nlgre_redir_cmn_print_skb(skb);
+ nss_nlgre_redir_cmn_print_hex_dump(skb);
dev_kfree_skb(skb);
}
@@ -286,7 +294,7 @@
/*
* Configuring gre_redir meta data.
*/
- meta_data_encap = (struct nss_gre_redir_encap_per_pkt_metadata *)(skb->data - NSS_GRE_REDIR_PER_PACKET_METADATA_OFFSET);
+ meta_data_encap = (struct nss_gre_redir_encap_per_pkt_metadata *)(skb->head + NSS_GRE_REDIR_PER_PACKET_METADATA_OFFSET);
memset(meta_data_encap, 0, sizeof(struct nss_gre_redir_encap_per_pkt_metadata));
meta_data_encap->gre_flags = 0;
meta_data_encap->gre_prio = 0;
@@ -398,6 +406,27 @@
};
/*
+ * nss_nlgre_redir_cmn_print_hex_dump()
+ * To print hex dump of packet received
+ */
+void nss_nlgre_redir_cmn_print_hex_dump(struct sk_buff *skb)
+{
+ int16_t dump_sz = (skb->len < NSS_NLGRE_REDIR_PKT_DUMP_SZ) ? skb->len : NSS_NLGRE_REDIR_PKT_DUMP_SZ;
+
+ dump_sz -= NSS_NLGRE_REDIR_PKT_DUMP_OFFSET;
+ if (dump_sz > 0) {
+ /*
+ * Enable dynamic debug to print
+ */
+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, dump_sz);
+ return;
+ }
+
+ nss_nl_warn("Could not print packet skb->len=%d, DUMP_SZ=%d, DUMP_OFFSET=%d\n",
+ skb->len, NSS_NLGRE_REDIR_PKT_DUMP_SZ, NSS_NLGRE_REDIR_PKT_DUMP_OFFSET);
+}
+
+/*
* nss_nlgre_redir_cmn_mode_str_to_enum()
* Returns the type of mode
*/
@@ -493,40 +522,6 @@
}
/*
- * nss_nlgre_redir_cmn_print_skb()
- * Prints the skb data
- */
-void nss_nlgre_redir_cmn_print_skb(struct sk_buff *skb)
-{
- int length;
- int iter;
-
- /*
- * Check if length is less than 16 bytes
- * Else bring down to minimum multiple of 16 bytes.
- */
- if (skb->len < 16) {
- nss_nl_trace("%p: Skb too small to print min size: 16 bytes\n", skb);
- return;
- }
-
- length = (skb->len / 16);
- if (length > NSS_NLGRE_REDIR_CMN_MAX_SKB_PRINT_LEN)
- length = NSS_NLGRE_REDIR_CMN_MAX_SKB_PRINT_LEN;
-
- /*
- * Print first 48 bytes of sk_buff
- */
- for (iter = 0; iter < length; iter++) {
- nss_nl_trace("%04xx: %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x\n", iter,
- skb->data[iter * 8], skb->data[iter * 8 + 1], skb->data[iter * 8 + 2], skb->data[iter * 8 + 3],
- skb->data[iter * 8 + 4], skb->data[iter * 8 + 5], skb->data[iter * 8 + 6], skb->data[iter * 8 + 7],
- skb->data[iter * 8 + 8], skb->data[iter * 8 + 9], skb->data[iter * 8 + 10], skb->data[iter * 8 + 11],
- skb->data[iter * 8 + 10], skb->data[iter * 8 + 13], skb->data[iter * 8 + 14], skb->data[iter * 8 + 15]);
- }
-}
-
-/*
* nss_gre_redir_unregister_and_deallocate()
* Unregisters and deallocates corresponding dev and node.
*/
diff --git a/netlink/nss_nlgre_redir_cmn.h b/netlink/nss_nlgre_redir_cmn.h
index 64daaaa..00138b1 100644
--- a/netlink/nss_nlgre_redir_cmn.h
+++ b/netlink/nss_nlgre_redir_cmn.h
@@ -27,6 +27,8 @@
#define NSS_NLGRE_REDIR_CMN_MAX_SKB_PRINT_LEN 3 /**< Maximum length of skb to print */
#define NSS_NLGRE_REDIR_CMN_MIN_TUNNELS 0 /**< Mininum number of tunnels required */
#define NSS_NLGRE_REDIR_CMN_IP_TTL 128 /**< Time to live for IP */
+#define NSS_NLGRE_REDIR_PKT_DUMP_SZ 64 /**< Size of packet to dump */
+#define NSS_NLGRE_REDIR_PKT_DUMP_OFFSET 0 /**< Dump offset */
/*
* netdevice private data
@@ -112,10 +114,10 @@
bool nss_nlgre_redir_cmn_unregister_and_deallocate(struct net_device *dev, uint32_t type);
/*
- * nss_nlgre_redir_cmn_print_skb()
- * Prints the first 48 bytes of skb
+ * nss_nlgre_redir_cmn_print_hex_dump()
+ * Prints the initials few bytes of packet
*/
-void nss_nlgre_redir_cmn_print_skb(struct sk_buff *skb);
+void nss_nlgre_redir_cmn_print_hex_dump(struct sk_buff *skb);
/*
* nss_nlgre_redir_cmn_create_tun()
diff --git a/netlink/nss_nlgre_redir_lag.c b/netlink/nss_nlgre_redir_lag.c
index 7b76bcc..3839df4 100644
--- a/netlink/nss_nlgre_redir_lag.c
+++ b/netlink/nss_nlgre_redir_lag.c
@@ -51,7 +51,7 @@
static void nss_nlgre_redir_lag_us_data_cb(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi)
{
nss_nl_trace("Exception packet on lag_us node:\n");
- nss_nlgre_redir_cmn_print_skb(skb);
+ nss_nlgre_redir_cmn_print_hex_dump(skb);
dev_kfree_skb_any(skb);
}
@@ -62,7 +62,7 @@
static void nss_nlgre_redir_lag_ds_data_cb(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi)
{
nss_nl_trace("Exception packet on lag_ds node:\n");
- nss_nlgre_redir_cmn_print_skb(skb);
+ nss_nlgre_redir_cmn_print_hex_dump(skb);
dev_kfree_skb_any(skb);
}
diff --git a/netlink/nss_nlipv4.c b/netlink/nss_nlipv4.c
index 80003f6..6e1fa23 100644
--- a/netlink/nss_nlipv4.c
+++ b/netlink/nss_nlipv4.c
@@ -326,15 +326,14 @@
/*
* Currently this implementation is only for gre_redir
*/
- conn->flow_interface_num = nss_nlgre_redir_cmd_get_ifnum(flow_dev,
- NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER);
+ conn->flow_interface_num = nss_nlgre_redir_cmd_get_ifnum(flow_dev, tuple->protocol);
if (conn->flow_interface_num < 0 ) {
nss_nl_error("%p: Failed to get flow interface number (dev:%s, type:%d)\n",
flow_dev, flow_dev->name, flow_iftype);
return -EINVAL;
}
- conn->flow_mtu = NSS_NLIPV4_MAX_MTU;
+ conn->flow_mtu = nss_nlgre_redir_cmd_get_mtu(flow_dev, NSS_GRE_REDIR_IP_HDR_TYPE_IPV4, conn->flow_interface_num);
break;
case NSS_NL_IFTYPE_VLAN:
@@ -384,15 +383,14 @@
break;
case NSS_NL_IFTYPE_TUNNEL_GRE:
- conn->return_interface_num = nss_nlgre_redir_cmd_get_ifnum(return_dev,
- NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER);
+ conn->return_interface_num = nss_nlgre_redir_cmd_get_ifnum(return_dev, tuple->protocol);
if (conn->return_interface_num < 0 ) {
nss_nl_error("%p: Failed to get return interface number (dev:%s, type:%d)\n",
return_dev, return_dev->name, return_iftype);
return -EINVAL;
}
- conn->return_mtu = NSS_NLIPV4_MAX_MTU;
+ conn->return_mtu = nss_nlgre_redir_cmd_get_mtu(return_dev, NSS_GRE_REDIR_IP_HDR_TYPE_IPV4, conn->return_interface_num);
break;
case NSS_NL_IFTYPE_VLAN:
diff --git a/netlink/nss_nlipv6.c b/netlink/nss_nlipv6.c
index febe480..f19e826 100644
--- a/netlink/nss_nlipv6.c
+++ b/netlink/nss_nlipv6.c
@@ -336,14 +336,14 @@
break;
case NSS_NL_IFTYPE_TUNNEL_GRE:
- conn->flow_interface_num = nss_nlgre_redir_cmd_get_ifnum(flow_dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER);
+ conn->flow_interface_num = nss_nlgre_redir_cmd_get_ifnum(flow_dev, tuple->protocol);
if (conn->flow_interface_num < 0 ) {
nss_nl_error("%p: Failed to get flow interface number (dev:%s, type:%d)\n",
flow_dev, flow_dev->name, flow_iftype);
return -EINVAL;
}
- conn->flow_mtu = NSS_NLIPV6_MAX_MTU;
+ conn->flow_mtu = nss_nlgre_redir_cmd_get_mtu(flow_dev, NSS_GRE_REDIR_IP_HDR_TYPE_IPV6, conn->flow_interface_num);
break;
case NSS_NL_IFTYPE_VLAN:
@@ -394,15 +394,14 @@
break;
case NSS_NL_IFTYPE_TUNNEL_GRE:
- conn->return_interface_num = nss_nlgre_redir_cmd_get_ifnum(return_dev,
- NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER);
+ conn->return_interface_num = nss_nlgre_redir_cmd_get_ifnum(return_dev, tuple->protocol);
if (conn->return_interface_num < 0 ) {
nss_nl_error("%p: Failed to get return interface number (dev:%s, type:%d)\n",
return_dev, return_dev->name, return_iftype);
return -EINVAL;
}
- conn->return_mtu = NSS_NLIPV6_MAX_MTU;
+ conn->return_mtu = nss_nlgre_redir_cmd_get_mtu(return_dev, NSS_GRE_REDIR_IP_HDR_TYPE_IPV6, conn->return_interface_num);
break;
case NSS_NL_IFTYPE_VLAN: