[qca-nss-clients] fix IPsec NATT issue
Change-Id: Ib717231d1b2e41fbfbfa97f2b5280b7b4672c3a6
Signed-off-by: Arunkumar T <athand@codeaurora.org>
Signed-off-by: mandrw <mandrw@codeaurora.org>
diff --git a/ipsecmgr/nss_ipsecmgr_sa.c b/ipsecmgr/nss_ipsecmgr_sa.c
index c7b9e46..a3fbe4a 100644
--- a/ipsecmgr/nss_ipsecmgr_sa.c
+++ b/ipsecmgr/nss_ipsecmgr_sa.c
@@ -818,6 +818,7 @@
bool nss_ipsecmgr_decap_add(struct net_device *tun, struct nss_ipsecmgr_sa *sa, struct nss_ipsecmgr_sa_data *data)
{
struct nss_ipsecmgr_priv *priv = netdev_priv(tun);
+ struct nss_ipsec_rule *ipsec_rule;
struct nss_ipsecmgr_sa_info info;
nss_ipsecmgr_info("%p:decap_add initiated\n", tun);
@@ -832,6 +833,16 @@
nss_ipsecmgr_copy_v4_sa(&info.nim, &sa->data.v4);
nss_ipsecmgr_copy_sa_data(&info.nim, data);
+ /*
+ * if NATT is set override the protocol and port numbers
+ */
+ ipsec_rule = &info.nim.msg.push;
+ if (ipsec_rule->data.nat_t_req) {
+ ipsec_rule->sel.proto_next_hdr = IPPROTO_UDP;
+ ipsec_rule->sel.dst_port = NSS_IPSECMGR_NATT_PORT_DATA;
+ ipsec_rule->sel.src_port = NSS_IPSECMGR_NATT_PORT_DATA;
+ }
+
nss_ipsecmgr_decap_v4_flow2key(&sa->data.v4, &info.child_key);
nss_ipsecmgr_v4_sa2key(&sa->data.v4, &info.sa_key);
break;
diff --git a/netlink/nss_nlipv4.c b/netlink/nss_nlipv4.c
index 9031abb..4f26813 100755
--- a/netlink/nss_nlipv4.c
+++ b/netlink/nss_nlipv4.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016, 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.
@@ -49,6 +49,8 @@
#include "nss_nl.h"
#include "nss_nlcmn_if.h"
#include "nss_nlipv4_if.h"
+#include "nss_ipsec.h"
+#include "nss_ipsecmgr.h"
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
#define DST_NEIGH_LOOKUP(dst, ip_addr) dst_neigh_lookup(dst, ip_addr)
@@ -273,6 +275,7 @@
{
struct nss_ipv4_connection_rule *conn = &msg->conn_rule;
const size_t rule_sz = sizeof(struct nss_ipv4_connection_rule);
+ bool override_mtu;
bool valid;
valid = msg->valid_flags & NSS_IPV4_RULE_CREATE_CONN_VALID;
@@ -307,10 +310,31 @@
/*
* update the flow & return MTU(s)
*/
- conn->flow_mtu = flow_dev->mtu;
conn->return_mtu = return_dev->mtu;
/*
+ * If, flow device is IPsec tunnel and protocol is ESP or NAT-T (UDP@4500)
+ * then the operation is Decapsulation. In this we would like to have the MTU
+ * of the incoming physical/virtual device. This would avoid fragmenting the
+ * packet in NSS before delivering it for IPsec decap
+ */
+ switch (msg->tuple.protocol) {
+ case IPPROTO_UDP:
+ override_mtu = (flow_dev->type == NSS_IPSEC_ARPHRD_IPSEC) && (msg->tuple.flow_ident == NSS_IPSECMGR_NATT_PORT_DATA);
+ break;
+
+ case IPPROTO_ESP:
+ override_mtu = (flow_dev->type == NSS_IPSEC_ARPHRD_IPSEC);
+ break;
+
+ default:
+ override_mtu = false;
+ break;
+ }
+
+ conn->flow_mtu = override_mtu ? conn->return_mtu : flow_dev->mtu;
+
+ /*
* update flow & return xlate info
*/
conn->flow_ip_xlate = msg->tuple.flow_ip;