Initial commit
This commit is contained in:
12
package/qca/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch
Normal file
12
package/qca/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -66,8 +66,7 @@ endif
|
||||
# Define ECM_FRONT_END_SFE_ENABLE=y in order to select
|
||||
# sfe as ECM's front end.
|
||||
# #############################################################################
|
||||
-ifeq ($(SoC),$(filter $(SoC),ipq806x ipq40xx))
|
||||
-ECM_FRONT_END_SFE_ENABLE=y
|
||||
+ifeq ($(ECM_FRONT_END_SFE_ENABLE), y)
|
||||
ecm-$(ECM_FRONT_END_SFE_ENABLE) += frontends/sfe/ecm_sfe_ipv4.o
|
||||
ecm-$(ECM_FRONT_END_SFE_ENABLE) += frontends/sfe/ecm_sfe_ported_ipv4.o
|
||||
ccflags-$(ECM_FRONT_END_SFE_ENABLE) += -DECM_FRONT_END_SFE_ENABLE
|
||||
1276
package/qca/qca-nss-ecm/patches/100-kernel-5.4-support.patch
Normal file
1276
package/qca/qca-nss-ecm/patches/100-kernel-5.4-support.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,60 @@
|
||||
diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c
|
||||
index 1ce4b61..29e70ba 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv4.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv4.c
|
||||
@@ -2171,6 +2171,10 @@ sync_conntrack:
|
||||
|
||||
timeouts = nf_ct_timeout_lookup(ct);
|
||||
|
||||
+ /* Copy of udp_get_timeouts in kernel */
|
||||
+ if (!timeouts)
|
||||
+ timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts;
|
||||
+
|
||||
spin_lock_bh(&ct->lock);
|
||||
ct->timeout = jiffies + timeouts[UDP_CT_REPLIED];
|
||||
spin_unlock_bh(&ct->lock);
|
||||
diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c
|
||||
index 2adc5ec..08253b6 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv6.c
|
||||
@@ -1883,6 +1883,10 @@ sync_conntrack:
|
||||
|
||||
timeouts = nf_ct_timeout_lookup(ct);
|
||||
|
||||
+ /* Copy of udp_get_timeouts in kernel */
|
||||
+ if (!timeouts)
|
||||
+ timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts;
|
||||
+
|
||||
spin_lock_bh(&ct->lock);
|
||||
ct->timeout = jiffies + timeouts[UDP_CT_REPLIED];
|
||||
spin_unlock_bh(&ct->lock);
|
||||
diff --git a/frontends/sfe/ecm_sfe_ipv4.c b/frontends/sfe/ecm_sfe_ipv4.c
|
||||
index 7cfe4fc..8f525ee 100644
|
||||
--- a/frontends/sfe/ecm_sfe_ipv4.c
|
||||
+++ b/frontends/sfe/ecm_sfe_ipv4.c
|
||||
@@ -1608,6 +1608,10 @@ sync_conntrack:
|
||||
|
||||
timeouts = nf_ct_timeout_lookup(ct);
|
||||
|
||||
+ /* Copy of udp_get_timeouts in kernel */
|
||||
+ if (!timeouts)
|
||||
+ timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts;
|
||||
+
|
||||
spin_lock_bh(&ct->lock);
|
||||
ct->timeout = jiffies + timeouts[UDP_CT_REPLIED];
|
||||
spin_unlock_bh(&ct->lock);
|
||||
diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c
|
||||
index dfde309..47c531a 100644
|
||||
--- a/frontends/sfe/ecm_sfe_ipv6.c
|
||||
+++ b/frontends/sfe/ecm_sfe_ipv6.c
|
||||
@@ -1321,6 +1321,10 @@ sync_conntrack:
|
||||
|
||||
timeouts = nf_ct_timeout_lookup(ct);
|
||||
|
||||
+ /* Copy of udp_get_timeouts in kernel */
|
||||
+ if (!timeouts)
|
||||
+ timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts;
|
||||
+
|
||||
spin_lock_bh(&ct->lock);
|
||||
ct->timeout = jiffies + timeouts[UDP_CT_REPLIED];
|
||||
spin_unlock_bh(&ct->lock);
|
||||
44
package/qca/qca-nss-ecm/patches/200-resolve-high-load.patch
Normal file
44
package/qca/qca-nss-ecm/patches/200-resolve-high-load.patch
Normal file
@@ -0,0 +1,44 @@
|
||||
The sync update work queue tasks is calling uninterruptible sleep function, which is
|
||||
causing high CPU load. Changed to interruptible sleep function. The stats update
|
||||
task should be interruptible.
|
||||
|
||||
--- a/frontends/nss/ecm_nss_ipv4.c
|
||||
+++ b.frontends/nss/ecm_nss_ipv4.c
|
||||
@@ -2411,7 +2411,7 @@ static void ecm_nss_ipv4_stats_sync_req_
|
||||
}
|
||||
spin_unlock_bh(&ecm_nss_ipv4_lock);
|
||||
|
||||
- usleep_range(ECM_NSS_IPV4_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV4_STATS_SYNC_UDELAY);
|
||||
+ msleep_interruptible(ECM_NSS_IPV4_STATS_SYNC_UDELAY / 1000);
|
||||
|
||||
/*
|
||||
* If index is 0, we are starting a new round, but if we still have time remain
|
||||
@@ -2425,7 +2425,7 @@ static void ecm_nss_ipv4_stats_sync_req_
|
||||
}
|
||||
|
||||
if (ecm_nss_ipv4_next_req_time > current_jiffies) {
|
||||
- msleep(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies));
|
||||
+ msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies));
|
||||
}
|
||||
ecm_nss_ipv4_roll_check_jiffies = jiffies;
|
||||
ecm_nss_ipv4_next_req_time = ecm_nss_ipv4_roll_check_jiffies + ECM_NSS_IPV4_STATS_SYNC_PERIOD;
|
||||
--- a/frontends/nss/ecm_nss_ipv6.c
|
||||
+++ b.frontends/nss/ecm_nss_ipv6.c
|
||||
@@ -2128,7 +2128,7 @@ static void ecm_nss_ipv6_stats_sync_req_
|
||||
}
|
||||
spin_unlock_bh(&ecm_nss_ipv6_lock);
|
||||
|
||||
- usleep_range(ECM_NSS_IPV6_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV6_STATS_SYNC_UDELAY);
|
||||
+ msleep_interruptible(ECM_NSS_IPV6_STATS_SYNC_UDELAY / 1000);
|
||||
|
||||
/*
|
||||
* If index is 0, we are starting a new round, but if we still have time remain
|
||||
@@ -2142,7 +2142,7 @@ static void ecm_nss_ipv6_stats_sync_req_
|
||||
}
|
||||
|
||||
if (ecm_nss_ipv6_next_req_time > current_jiffies) {
|
||||
- msleep(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies));
|
||||
+ msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies));
|
||||
}
|
||||
ecm_nss_ipv6_roll_check_jiffies = jiffies;
|
||||
ecm_nss_ipv6_next_req_time = ecm_nss_ipv6_roll_check_jiffies + ECM_NSS_IPV6_STATS_SYNC_PERIOD;
|
||||
@@ -0,0 +1,20 @@
|
||||
--- a/ecm_conntrack_notifier.c
|
||||
+++ b/ecm_conntrack_notifier.c
|
||||
@@ -411,7 +411,7 @@ int ecm_conntrack_notifier_init(struct d
|
||||
/*
|
||||
* Eventing subsystem is available so we register a notifier hook to get fast notifications of expired connections
|
||||
*/
|
||||
- result = nf_conntrack_register_notifier(&init_net, &ecm_conntrack_notifier);
|
||||
+ result = nf_conntrack_register_chain_notifier(&init_net, &ecm_conntrack_notifier);
|
||||
if (result < 0) {
|
||||
DEBUG_ERROR("Can't register nf notifier hook.\n");
|
||||
debugfs_remove_recursive(ecm_conntrack_notifier_dentry);
|
||||
@@ -430,7 +430,7 @@ void ecm_conntrack_notifier_exit(void)
|
||||
{
|
||||
DEBUG_INFO("ECM Conntrack Notifier exit\n");
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
- nf_conntrack_unregister_notifier(&init_net, &ecm_conntrack_notifier);
|
||||
+ nf_conntrack_unregister_chain_notifier(&init_net, &ecm_conntrack_notifier);
|
||||
#endif
|
||||
/*
|
||||
* Remove the debugfs files recursively.
|
||||
@@ -0,0 +1,236 @@
|
||||
From 90cace88a342e77ee8ca1e961cf7b7a7930d4c89 Mon Sep 17 00:00:00 2001
|
||||
From: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Date: Mon, 9 Mar 2020 12:51:03 -0700
|
||||
Subject: [qca-nss-ecm] Check TCP/UDP conntrack state earlier
|
||||
|
||||
Check the conntrack state before processing the flow
|
||||
and adding it to the database. The unconfirmed
|
||||
connections can be changed after the confirmation.
|
||||
|
||||
Changed the TCP tracker connection state matrix to set the
|
||||
state of the connection as ESTABLISHED when any of the src or
|
||||
dest side is set as ESTABLISHED. With this change ECM will not
|
||||
handle the SYN and SYN-ACK packets of the TCP handshake. Only the
|
||||
ACK and FIN flaged packets will be used during the creation and
|
||||
closing the connection respectively.
|
||||
|
||||
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Change-Id: I3e0a58d604df4c6a85478ca9c05f24d50cd8c894
|
||||
---
|
||||
ecm_classifier_default.c | 36 ++++++++----------------------------
|
||||
ecm_tracker_tcp.c | 4 ++--
|
||||
frontends/nss/ecm_nss_ported_ipv4.c | 17 +++++++++++++++++
|
||||
frontends/nss/ecm_nss_ported_ipv6.c | 17 +++++++++++++++++
|
||||
frontends/sfe/ecm_sfe_ported_ipv4.c | 17 +++++++++++++++++
|
||||
frontends/sfe/ecm_sfe_ported_ipv6.c | 17 +++++++++++++++++
|
||||
6 files changed, 78 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/ecm_classifier_default.c b/ecm_classifier_default.c
|
||||
index 22c4bec..d04cdfa 100644
|
||||
--- a/ecm_classifier_default.c
|
||||
+++ b/ecm_classifier_default.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
|
||||
+ * Copyright (c) 2014-2016, 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.
|
||||
@@ -285,12 +285,12 @@ static void ecm_classifier_default_process(struct ecm_classifier_instance *aci,
|
||||
}
|
||||
|
||||
/*
|
||||
- * Check the TCP connection state.
|
||||
+ * Check the TCP connection state, when the ct is NULL.
|
||||
+ * ct valid case was already checked in the ecm_nss{sfe}_ported_ipv4{6}_process functions.
|
||||
* If we are not established then we deny acceleration.
|
||||
- * Take lead from conntrack if exists.
|
||||
*/
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
- if (ct == NULL) {
|
||||
+ if (!ct) {
|
||||
DEBUG_TRACE("%p: No Conntrack found for packet, using ECM tracker state\n", cdii);
|
||||
if (unlikely(prevailing_state != ECM_TRACKER_CONNECTION_STATE_ESTABLISHED)) {
|
||||
cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
|
||||
@@ -298,29 +298,10 @@ static void ecm_classifier_default_process(struct ecm_classifier_instance *aci,
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
- * Unconfirmed connection may be dropped by Linux at the final step,
|
||||
- * So we don't allow acceleration for the unconfirmed connections.
|
||||
- */
|
||||
- if (!nf_ct_is_confirmed(ct)) {
|
||||
- DEBUG_TRACE("%p: Unconfirmed connection\n", ct);
|
||||
- cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
|
||||
- goto return_response;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * Don't try to manage a non-established connection.
|
||||
- */
|
||||
- if (!test_bit(IPS_ASSURED_BIT, &ct->status)) {
|
||||
- DEBUG_TRACE("%p: Non-established connection\n", ct);
|
||||
- cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
|
||||
- goto return_response;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * If the connection is shutting down do not manage it.
|
||||
- * state can not be SYN_SENT, SYN_RECV because connection is assured
|
||||
- * Not managed states: FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE.
|
||||
- */
|
||||
+ * If the connection is shutting down do not manage it.
|
||||
+ * state can not be SYN_SENT, SYN_RECV because connection is assured
|
||||
+ * Not managed states: FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE.
|
||||
+ */
|
||||
spin_lock_bh(&ct->lock);
|
||||
if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) {
|
||||
spin_unlock_bh(&ct->lock);
|
||||
@@ -333,7 +314,6 @@ static void ecm_classifier_default_process(struct ecm_classifier_instance *aci,
|
||||
|
||||
return_response:
|
||||
;
|
||||
-
|
||||
/*
|
||||
* Return the process response
|
||||
*/
|
||||
diff --git a/ecm_tracker_tcp.c b/ecm_tracker_tcp.c
|
||||
index f073c36..e5b327a 100644
|
||||
--- a/ecm_tracker_tcp.c
|
||||
+++ b/ecm_tracker_tcp.c
|
||||
@@ -257,9 +257,9 @@ static DEFINE_SPINLOCK(ecm_tracker_tcp_lock); /* Global lock for the tracker gl
|
||||
*/
|
||||
static ecm_tracker_connection_state_t ecm_tracker_tcp_connection_state_matrix[ECM_TRACKER_SENDER_STATE_MAX][ECM_TRACKER_SENDER_STATE_MAX] =
|
||||
{ /* Unknown Establishing Established Closing Closed Fault */
|
||||
- /* Unknown */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT},
|
||||
+ /* Unknown */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT},
|
||||
/* Establishing */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT},
|
||||
- /* Established */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_FAULT},
|
||||
+ /* Established */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_FAULT},
|
||||
/* Closing */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_FAULT},
|
||||
/* Closed */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSED, ECM_TRACKER_CONNECTION_STATE_FAULT},
|
||||
/* Fault */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT},
|
||||
diff --git a/frontends/nss/ecm_nss_ported_ipv4.c b/frontends/nss/ecm_nss_ported_ipv4.c
|
||||
index 1435ec0..34c056f 100644
|
||||
--- a/frontends/nss/ecm_nss_ported_ipv4.c
|
||||
+++ b/frontends/nss/ecm_nss_ported_ipv4.c
|
||||
@@ -2002,8 +2002,25 @@ unsigned int ecm_nss_ported_ipv4_process(struct net_device *out_dev, struct net_
|
||||
int protocol = (int)orig_tuple->dst.protonum;
|
||||
__be16 *layer4hdr = NULL;
|
||||
|
||||
+ /*
|
||||
+ * Unconfirmed connection may be dropped by Linux at the final step,
|
||||
+ * So we don't allow acceleration for the unconfirmed connections.
|
||||
+ */
|
||||
+ if (likely(ct) && !nf_ct_is_confirmed(ct)) {
|
||||
+ DEBUG_WARN("%p: Unconfirmed connection\n", ct);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+
|
||||
if (protocol == IPPROTO_TCP) {
|
||||
/*
|
||||
+ * Don't try to manage a non-established connection.
|
||||
+ */
|
||||
+ if (likely(ct) && !test_bit(IPS_ASSURED_BIT, &ct->status)) {
|
||||
+ DEBUG_WARN("%p: Non-established TCP connection\n", ct);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Extract TCP header to obtain port information
|
||||
*/
|
||||
tcp_hdr = ecm_tracker_tcp_check_header_and_read(skb, iph, &tcp_hdr_buff);
|
||||
diff --git a/frontends/nss/ecm_nss_ported_ipv6.c b/frontends/nss/ecm_nss_ported_ipv6.c
|
||||
index 4c154a6..bd6349b 100644
|
||||
--- a/frontends/nss/ecm_nss_ported_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_ported_ipv6.c
|
||||
@@ -1914,8 +1914,25 @@ unsigned int ecm_nss_ported_ipv6_process(struct net_device *out_dev,
|
||||
int protocol = (int)orig_tuple->dst.protonum;
|
||||
__be16 *layer4hdr = NULL;
|
||||
|
||||
+ /*
|
||||
+ * Unconfirmed connection may be dropped by Linux at the final step,
|
||||
+ * So we don't allow acceleration for the unconfirmed connections.
|
||||
+ */
|
||||
+ if (likely(ct) && !nf_ct_is_confirmed(ct)) {
|
||||
+ DEBUG_WARN("%p: Unconfirmed connection\n", ct);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+
|
||||
if (protocol == IPPROTO_TCP) {
|
||||
/*
|
||||
+ * Don't try to manage a non-established connection.
|
||||
+ */
|
||||
+ if (likely(ct) && !test_bit(IPS_ASSURED_BIT, &ct->status)) {
|
||||
+ DEBUG_WARN("%p: Non-established TCP connection\n", ct);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Extract TCP header to obtain port information
|
||||
*/
|
||||
tcp_hdr = ecm_tracker_tcp_check_header_and_read(skb, iph, &tcp_hdr_buff);
|
||||
diff --git a/frontends/sfe/ecm_sfe_ported_ipv4.c b/frontends/sfe/ecm_sfe_ported_ipv4.c
|
||||
index e034cde..df1ce57 100644
|
||||
--- a/frontends/sfe/ecm_sfe_ported_ipv4.c
|
||||
+++ b/frontends/sfe/ecm_sfe_ported_ipv4.c
|
||||
@@ -1805,8 +1805,25 @@ unsigned int ecm_sfe_ported_ipv4_process(struct net_device *out_dev, struct net_
|
||||
int protocol = (int)orig_tuple->dst.protonum;
|
||||
__be16 *layer4hdr = NULL;
|
||||
|
||||
+ /*
|
||||
+ * Unconfirmed connection may be dropped by Linux at the final step,
|
||||
+ * So we don't allow acceleration for the unconfirmed connections.
|
||||
+ */
|
||||
+ if (likely(ct) && !nf_ct_is_confirmed(ct)) {
|
||||
+ DEBUG_WARN("%p: Unconfirmed connection\n", ct);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+
|
||||
if (protocol == IPPROTO_TCP) {
|
||||
/*
|
||||
+ * Don't try to manage a non-established connection.
|
||||
+ */
|
||||
+ if (likely(ct) && !test_bit(IPS_ASSURED_BIT, &ct->status)) {
|
||||
+ DEBUG_WARN("%p: Non-established TCP connection\n", ct);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Extract TCP header to obtain port information
|
||||
*/
|
||||
tcp_hdr = ecm_tracker_tcp_check_header_and_read(skb, iph, &tcp_hdr_buff);
|
||||
diff --git a/frontends/sfe/ecm_sfe_ported_ipv6.c b/frontends/sfe/ecm_sfe_ported_ipv6.c
|
||||
index 6ac05ad..657a1c7 100644
|
||||
--- a/frontends/sfe/ecm_sfe_ported_ipv6.c
|
||||
+++ b/frontends/sfe/ecm_sfe_ported_ipv6.c
|
||||
@@ -1746,8 +1746,25 @@ unsigned int ecm_sfe_ported_ipv6_process(struct net_device *out_dev,
|
||||
int protocol = (int)orig_tuple->dst.protonum;
|
||||
__be16 *layer4hdr = NULL;
|
||||
|
||||
+ /*
|
||||
+ * Unconfirmed connection may be dropped by Linux at the final step,
|
||||
+ * So we don't allow acceleration for the unconfirmed connections.
|
||||
+ */
|
||||
+ if (likely(ct) && !nf_ct_is_confirmed(ct)) {
|
||||
+ DEBUG_WARN("%p: Unconfirmed connection\n", ct);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+
|
||||
if (protocol == IPPROTO_TCP) {
|
||||
/*
|
||||
+ * Don't try to manage a non-established connection.
|
||||
+ */
|
||||
+ if (likely(ct) && !test_bit(IPS_ASSURED_BIT, &ct->status)) {
|
||||
+ DEBUG_WARN("%p: Non-established TCP connection\n", ct);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Extract TCP header to obtain port information
|
||||
*/
|
||||
tcp_hdr = ecm_tracker_tcp_check_header_and_read(skb, iph, &tcp_hdr_buff);
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
From 9ad19ffdcfdf77baf3abd4fcc933fd3dc8e791a5 Mon Sep 17 00:00:00 2001
|
||||
From: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Date: Sat, 20 Jun 2020 09:41:01 -0700
|
||||
Subject: [qca-nss-ecm] Fix NSS stats request roll over issue
|
||||
|
||||
Use the correct timer API to check the next request time
|
||||
when jiffies wrap happens.
|
||||
|
||||
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Change-Id: I18646d28df7e17daeff2986dfe4bd73866d47668
|
||||
---
|
||||
frontends/nss/ecm_nss_ipv4.c | 4 ++--
|
||||
frontends/nss/ecm_nss_ipv6.c | 4 ++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c
|
||||
index 3eaf5d8..80e1aee 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv4.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv4.c
|
||||
@@ -2421,10 +2421,10 @@ static void ecm_nss_ipv4_stats_sync_req_work(struct work_struct *work)
|
||||
current_jiffies = jiffies;
|
||||
|
||||
if (time_is_after_jiffies(ecm_nss_ipv4_roll_check_jiffies)) {
|
||||
- ecm_nss_ipv4_next_req_time = 0;
|
||||
+ ecm_nss_ipv4_next_req_time = jiffies + ECM_NSS_IPV4_STATS_SYNC_PERIOD;
|
||||
}
|
||||
|
||||
- if (ecm_nss_ipv4_next_req_time > current_jiffies) {
|
||||
+ if (time_after(ecm_nss_ipv4_next_req_time, current_jiffies)) {
|
||||
msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies));
|
||||
}
|
||||
ecm_nss_ipv4_roll_check_jiffies = jiffies;
|
||||
diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c
|
||||
index 288dc55..483421e 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv6.c
|
||||
@@ -2135,10 +2135,10 @@ static void ecm_nss_ipv6_stats_sync_req_work(struct work_struct *work)
|
||||
current_jiffies = jiffies;
|
||||
|
||||
if (time_is_after_jiffies(ecm_nss_ipv6_roll_check_jiffies)) {
|
||||
- ecm_nss_ipv6_next_req_time = 0;
|
||||
+ ecm_nss_ipv6_next_req_time = jiffies + ECM_NSS_IPV6_STATS_SYNC_PERIOD;
|
||||
}
|
||||
|
||||
- if (ecm_nss_ipv6_next_req_time > current_jiffies) {
|
||||
+ if (time_after(ecm_nss_ipv6_next_req_time, current_jiffies)) {
|
||||
msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies));
|
||||
}
|
||||
ecm_nss_ipv6_roll_check_jiffies = jiffies;
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
From 4b41703a181b7187d9ff8cb744eb96d09997387c Mon Sep 17 00:00:00 2001
|
||||
From: Suman Ghosh <sumaghos@codeaurora.org>
|
||||
Date: Wed, 19 Feb 2020 15:09:19 +0530
|
||||
Subject: [qca-nss-ecm] Fix for ref leak during multicast 'to' hierarchy
|
||||
creation
|
||||
|
||||
Change-Id: I89df9dbe5ea054cf3b87d55ce68a751cb1d6c24f
|
||||
Signed-off-by: Suman Ghosh <sumaghos@codeaurora.org>
|
||||
---
|
||||
ecm_interface.c | 34 ++++++++++++++++++++++++++++++----
|
||||
1 file changed, 30 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ecm_interface.c b/ecm_interface.c
|
||||
index 4f7a886..2a0ca5b 100644
|
||||
--- a/ecm_interface.c
|
||||
+++ b/ecm_interface.c
|
||||
@@ -3885,13 +3885,13 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
dest_dev = dev_get_by_index(&init_net, *dst_if_index);
|
||||
if (!dest_dev) {
|
||||
if (!src_dev_is_bridge) {
|
||||
- int i;
|
||||
-
|
||||
/*
|
||||
* If already constructed any interface heirarchies before hitting
|
||||
* this error condition then Deref all interface heirarchies.
|
||||
*/
|
||||
if (valid_if > 0) {
|
||||
+ int i;
|
||||
+
|
||||
for (i = 0; i < valid_if; i++) {
|
||||
ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i);
|
||||
ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces);
|
||||
@@ -3902,11 +3902,14 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
/*
|
||||
* If valid netdev not found, Return 0
|
||||
*/
|
||||
+ if (br_dev_src) {
|
||||
+ dev_put(br_dev_src);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
dest_dev = br_dev_src;
|
||||
-
|
||||
}
|
||||
|
||||
dest_dev_type = dest_dev->type;
|
||||
@@ -3945,6 +3948,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
}
|
||||
}
|
||||
|
||||
+ if (br_dev_src && (dest_dev != br_dev_src)) {
|
||||
+ dev_put(br_dev_src);
|
||||
+ }
|
||||
+
|
||||
dev_put(dest_dev);
|
||||
return 0;
|
||||
}
|
||||
@@ -3972,6 +3979,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]);
|
||||
}
|
||||
|
||||
+ if (br_dev_src && (dest_dev != br_dev_src)) {
|
||||
+ dev_put(br_dev_src);
|
||||
+ }
|
||||
+
|
||||
dev_put(dest_dev);
|
||||
dev_put(mc_br_slave_dev);
|
||||
return 0;
|
||||
@@ -3997,6 +4008,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
}
|
||||
}
|
||||
|
||||
+ if (br_dev_src && (dest_dev != br_dev_src)) {
|
||||
+ dev_put(br_dev_src);
|
||||
+ }
|
||||
+
|
||||
dev_put(dest_dev);
|
||||
dev_put(mc_br_slave_dev);
|
||||
return 0;
|
||||
@@ -4032,6 +4047,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
}
|
||||
}
|
||||
|
||||
+ if (br_dev_src && (dest_dev != br_dev_src)) {
|
||||
+ dev_put(br_dev_src);
|
||||
+ }
|
||||
+
|
||||
dev_put(dest_dev);
|
||||
return 0;
|
||||
}
|
||||
@@ -4042,8 +4061,15 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
valid_if++;
|
||||
}
|
||||
|
||||
- dev_put(dest_dev);
|
||||
+ if (dest_dev != br_dev_src) {
|
||||
+ dev_put(dest_dev);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (br_dev_src) {
|
||||
+ dev_put(br_dev_src);
|
||||
+ }
|
||||
+
|
||||
return total_ii_count;
|
||||
}
|
||||
EXPORT_SYMBOL(ecm_interface_multicast_heirarchy_construct_routed);
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
From 72e3ae508906553e7bc982bf3c0d99bb1cbe9008 Mon Sep 17 00:00:00 2001
|
||||
From: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Date: Wed, 20 Nov 2019 16:23:06 -0800
|
||||
Subject: [qca-nss-ecm] Fix neighbour solicitation send function.
|
||||
|
||||
dst_ops->neigh_lookup function pointer is set to the
|
||||
ip6_neigh_lookup function. This function returns an
|
||||
error pointer with the ERR_PTR() macro. So, we should
|
||||
check the return value of this function pointer with
|
||||
the IS_ERR() macro.
|
||||
|
||||
Change-Id: I188a6e53278faaa68f1854524f612efc1f7451fe
|
||||
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||
---
|
||||
ecm_interface.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ecm_interface.c b/ecm_interface.c
|
||||
index 3f8554b..36509f0 100644
|
||||
--- a/ecm_interface.c
|
||||
+++ b/ecm_interface.c
|
||||
@@ -1100,7 +1100,7 @@ void ecm_interface_send_neighbour_solicitation(struct net_device *dev, ip_addr_t
|
||||
#else
|
||||
neigh = rt6i->dst.ops->neigh_lookup(&rt6i->dst, NULL, &dst_addr);
|
||||
#endif
|
||||
- if (neigh == NULL) {
|
||||
+ if (IS_ERR(neigh)) {
|
||||
DEBUG_TRACE("Neighbour lookup failure for destination IPv6 address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr));
|
||||
dst_release(&rt6i->dst);
|
||||
return;
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
From 7c0610828b835b2aab96dd50ec841a3a28689112 Mon Sep 17 00:00:00 2001
|
||||
From: Suman Ghosh <sumaghos@codeaurora.org>
|
||||
Date: Mon, 16 Mar 2020 15:22:18 +0530
|
||||
Subject: [qca-nss-ecm] Reference leak during multicast + PPPoE bridge
|
||||
|
||||
Signed-off-by: Suman Ghosh <sumaghos@codeaurora.org>
|
||||
Change-Id: I4472035f1bbb087e637169762ae2648c0fda792a
|
||||
---
|
||||
ecm_interface.c | 136 +++++++++++++++++++++++++-------------------------------
|
||||
1 file changed, 60 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/ecm_interface.c b/ecm_interface.c
|
||||
index 1614336..c0d2357 100644
|
||||
--- a/ecm_interface.c
|
||||
+++ b/ecm_interface.c
|
||||
@@ -3796,6 +3796,25 @@ fail:
|
||||
}
|
||||
|
||||
/*
|
||||
+ * ecm_interface_hierarchy_delete()
|
||||
+ * Delete hierarchy of the requested interfaces.
|
||||
+ */
|
||||
+static inline void ecm_interface_hierarchy_delete(struct ecm_db_iface_instance *interfaces,
|
||||
+ uint32_t *interface_first_base,
|
||||
+ int valid_if)
|
||||
+{
|
||||
+ struct ecm_db_iface_instance *to_list_single[ECM_DB_IFACE_HEIRARCHY_MAX];
|
||||
+ struct ecm_db_iface_instance *ifaces;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < valid_if; i++) {
|
||||
+ ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i);
|
||||
+ ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces);
|
||||
+ ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* ecm_interface_multicast_heirarchy_construct_routed()
|
||||
* Create destination interface heirarchy for a routed multicast connectiona
|
||||
*
|
||||
@@ -3816,7 +3835,6 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
uint32_t *interface_first_base, bool mfc_update,
|
||||
__be16 *layer4hdr, struct sk_buff *skb)
|
||||
{
|
||||
- struct ecm_db_iface_instance *to_list_single[ECM_DB_IFACE_HEIRARCHY_MAX];
|
||||
struct ecm_db_iface_instance *ifaces;
|
||||
struct net_device *dest_dev = NULL;
|
||||
struct net_device *br_dev_src = NULL;
|
||||
@@ -3829,7 +3847,7 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
int if_index;
|
||||
int ii_cnt;
|
||||
int total_ii_count = 0;
|
||||
- bool src_dev_is_bridge = false;
|
||||
+ bool src_dev_is_bridge = false, dest_dev_is_br_dev_src = false;
|
||||
|
||||
DEBUG_TRACE("Construct interface heirarchy for dest_addr: " ECM_IP_ADDR_DOT_FMT " src_addr: " ECM_IP_ADDR_DOT_FMT "total destination ifs %d\n",
|
||||
ECM_IP_ADDR_TO_DOT(packet_dest_addr), ECM_IP_ADDR_TO_DOT(packet_src_addr), max_if);
|
||||
@@ -3876,6 +3894,7 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
continue;
|
||||
}
|
||||
|
||||
+ dest_dev_is_br_dev_src = false;
|
||||
dest_dev = dev_get_by_index(&init_net, *dst_if_index);
|
||||
if (!dest_dev) {
|
||||
if (!src_dev_is_bridge) {
|
||||
@@ -3884,26 +3903,23 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
* this error condition then Deref all interface heirarchies.
|
||||
*/
|
||||
if (valid_if > 0) {
|
||||
- int i;
|
||||
-
|
||||
- for (i = 0; i < valid_if; i++) {
|
||||
- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i);
|
||||
- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces);
|
||||
- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]);
|
||||
- }
|
||||
+ ecm_interface_hierarchy_delete(interfaces, interface_first_base, valid_if);
|
||||
}
|
||||
|
||||
- /*
|
||||
- * If valid netdev not found, Return 0
|
||||
- */
|
||||
- if (br_dev_src) {
|
||||
- dev_put(br_dev_src);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ goto fail1;
|
||||
}
|
||||
|
||||
dest_dev = br_dev_src;
|
||||
+
|
||||
+ /*
|
||||
+ * In some cases when WAN interface is added to bridge and traffic is downstream,
|
||||
+ * the bridge device is part of the destination list from MFC, and at the same time
|
||||
+ * 'src_dev_is_bridge' will be true as well. In such cases we will need to release
|
||||
+ * the hold on the bridge device separately for dest_dev and br_dev_src.
|
||||
+ * Setting this flag to true indicates that this is not the case,
|
||||
+ * and that releasing the hold once is enough
|
||||
+ */
|
||||
+ dest_dev_is_br_dev_src = true;
|
||||
}
|
||||
|
||||
dest_dev_type = dest_dev->type;
|
||||
@@ -3927,7 +3943,6 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
}
|
||||
|
||||
if ((if_num < 0) || (if_num > ECM_DB_MULTICAST_IF_MAX)) {
|
||||
- int i;
|
||||
DEBUG_WARN("MCS is not ready\n");
|
||||
|
||||
/*
|
||||
@@ -3935,19 +3950,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
* this error condition then Deref all interface heirarchies.
|
||||
*/
|
||||
if (valid_if > 0) {
|
||||
- for (i = 0; i < valid_if; i++) {
|
||||
- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i);
|
||||
- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces);
|
||||
- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]);
|
||||
- }
|
||||
+ ecm_interface_hierarchy_delete(interfaces, interface_first_base, valid_if);
|
||||
}
|
||||
|
||||
- if (br_dev_src && (dest_dev != br_dev_src)) {
|
||||
- dev_put(br_dev_src);
|
||||
- }
|
||||
-
|
||||
- dev_put(dest_dev);
|
||||
- return 0;
|
||||
+ goto fail2;
|
||||
}
|
||||
|
||||
if (in_dev && !mfc_update) {
|
||||
@@ -3955,34 +3961,20 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
}
|
||||
|
||||
for (br_if = 0; br_if < if_num; br_if++) {
|
||||
+ int total_if = valid_if + br_if;
|
||||
+
|
||||
mc_br_slave_dev = dev_get_by_index(&init_net, mc_dst_if_index[br_if]);
|
||||
if (!mc_br_slave_dev) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- if ((valid_if + br_if) > ECM_DB_MULTICAST_IF_MAX) {
|
||||
- int i;
|
||||
-
|
||||
- /*
|
||||
- * If already constructed any interface heirarchies before hitting
|
||||
- * this error condition then Deref all interface heirarchies.
|
||||
- */
|
||||
- for (i = 0; i < (valid_if + br_if); i++) {
|
||||
- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i);
|
||||
- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces);
|
||||
- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]);
|
||||
- }
|
||||
-
|
||||
- if (br_dev_src && (dest_dev != br_dev_src)) {
|
||||
- dev_put(br_dev_src);
|
||||
- }
|
||||
-
|
||||
- dev_put(dest_dev);
|
||||
+ if (total_if > ECM_DB_MULTICAST_IF_MAX) {
|
||||
+ ecm_interface_hierarchy_delete(interfaces, interface_first_base, total_if);
|
||||
dev_put(mc_br_slave_dev);
|
||||
- return 0;
|
||||
+ goto fail2;
|
||||
}
|
||||
|
||||
- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, valid_if + br_if);
|
||||
+ ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, total_if);
|
||||
/*
|
||||
* Construct a single interface heirarchy of a multicast dev.
|
||||
*/
|
||||
@@ -3993,25 +3985,15 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
* If already constructed any interface heirarchies before hitting
|
||||
* this error condition then Deref all interface heirarchies.
|
||||
*/
|
||||
- if ((valid_if + br_if) > 0) {
|
||||
- int i;
|
||||
- for (i = 0; i < (valid_if + br_if); i++) {
|
||||
- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i);
|
||||
- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces);
|
||||
- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (br_dev_src && (dest_dev != br_dev_src)) {
|
||||
- dev_put(br_dev_src);
|
||||
+ if (total_if > 0) {
|
||||
+ ecm_interface_hierarchy_delete(interfaces, interface_first_base, total_if);
|
||||
}
|
||||
|
||||
- dev_put(dest_dev);
|
||||
dev_put(mc_br_slave_dev);
|
||||
- return 0;
|
||||
+ goto fail2;
|
||||
}
|
||||
|
||||
- interface_first = ecm_db_multicast_if_first_get_at_index(interface_first_base, (valid_if + br_if));
|
||||
+ interface_first = ecm_db_multicast_if_first_get_at_index(interface_first_base, total_if);
|
||||
*interface_first = ii_cnt;
|
||||
total_ii_count += ii_cnt;
|
||||
dev_put(mc_br_slave_dev);
|
||||
@@ -4033,20 +4015,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
* this error condition then Deref all interface heirarchies.
|
||||
*/
|
||||
if (valid_if > 0) {
|
||||
- int i;
|
||||
- for (i = 0; i < valid_if; i++) {
|
||||
- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i);
|
||||
- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces);
|
||||
- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (br_dev_src && (dest_dev != br_dev_src)) {
|
||||
- dev_put(br_dev_src);
|
||||
+ ecm_interface_hierarchy_delete(interfaces, interface_first_base, valid_if);
|
||||
}
|
||||
|
||||
- dev_put(dest_dev);
|
||||
- return 0;
|
||||
+ goto fail2;
|
||||
}
|
||||
|
||||
interface_first = ecm_db_multicast_if_first_get_at_index(interface_first_base, valid_if);
|
||||
@@ -4055,7 +4027,7 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
valid_if++;
|
||||
}
|
||||
|
||||
- if (dest_dev != br_dev_src) {
|
||||
+ if (!dest_dev_is_br_dev_src) {
|
||||
dev_put(dest_dev);
|
||||
}
|
||||
}
|
||||
@@ -4065,6 +4037,18 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_
|
||||
}
|
||||
|
||||
return total_ii_count;
|
||||
+
|
||||
+fail2:
|
||||
+ if (!dest_dev_is_br_dev_src) {
|
||||
+ dev_put(dest_dev);
|
||||
+ }
|
||||
+
|
||||
+fail1:
|
||||
+ if (br_dev_src) {
|
||||
+ dev_put(br_dev_src);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ecm_interface_multicast_heirarchy_construct_routed);
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
From 65a49ebd1bd12b9952dfa214de0a2da43ba2abed Mon Sep 17 00:00:00 2001
|
||||
From: Bhaskar Valaboju <bhaskarv@codeaurora.org>
|
||||
Date: Tue, 13 Aug 2019 14:21:03 +0530
|
||||
Subject: [qca-nss-ecm]: Access global ipv4/ipv6 accelerated count under lock
|
||||
|
||||
Flow accelerated count maintained as global variables are accessed
|
||||
in multiple kernel contexts. These counters are updated under lock,
|
||||
but read without lock. Read is in kernel thread context (workqueue)
|
||||
and sometimes it is taking stale entry (0) and doesn't change.
|
||||
Lock is added to read correct value.
|
||||
|
||||
Change-Id: I74cf27fe5097c6ae7dfcc06319762a8a322d79a3
|
||||
Signed-off-by: Bhaskar Valaboju <bhaskarv@codeaurora.org>
|
||||
---
|
||||
frontends/nss/ecm_nss_ipv4.c | 3 +++
|
||||
frontends/nss/ecm_nss_ipv6.c | 3 +++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
(limited to 'frontends')
|
||||
|
||||
diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c
|
||||
index afd660e..4e66cdf 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv4.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv4.c
|
||||
@@ -2288,10 +2288,13 @@ static void ecm_nss_ipv4_stats_sync_req_work(struct work_struct *work)
|
||||
int retry = 3;
|
||||
unsigned long int current_jiffies;
|
||||
|
||||
+ spin_lock_bh(&ecm_nss_ipv4_lock);
|
||||
if (ecm_nss_ipv4_accelerated_count == 0) {
|
||||
+ spin_unlock_bh(&ecm_nss_ipv4_lock);
|
||||
DEBUG_TRACE("There is no accelerated IPv4 connection\n");
|
||||
goto reschedule;
|
||||
}
|
||||
+ spin_unlock_bh(&ecm_nss_ipv4_lock);
|
||||
|
||||
usleep_range(ECM_NSS_IPV4_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV4_STATS_SYNC_UDELAY);
|
||||
|
||||
diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c
|
||||
index 1f7f51e..55849e7 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv6.c
|
||||
@@ -1998,10 +1998,13 @@ static void ecm_nss_ipv6_stats_sync_req_work(struct work_struct *work)
|
||||
int retry = 3;
|
||||
unsigned long int current_jiffies;
|
||||
|
||||
+ spin_lock_bh(&ecm_nss_ipv6_lock);
|
||||
if (ecm_nss_ipv6_accelerated_count == 0) {
|
||||
+ spin_unlock_bh(&ecm_nss_ipv6_lock);
|
||||
DEBUG_TRACE("There is no accelerated IPv6 connection\n");
|
||||
goto reschedule;
|
||||
}
|
||||
+ spin_unlock_bh(&ecm_nss_ipv6_lock);
|
||||
|
||||
usleep_range(ECM_NSS_IPV6_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV6_STATS_SYNC_UDELAY);
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
From b96002061178f399c1e58a9ad821e5096a64f788 Mon Sep 17 00:00:00 2001
|
||||
From: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Date: Mon, 23 Mar 2020 10:59:39 -0700
|
||||
Subject: [qca-nss-ecm] Fix IPv6 neighbor solicitation request
|
||||
|
||||
Send the solicitation request to the GW address, when
|
||||
a GW address is found, while establishing the node instance.
|
||||
|
||||
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Change-Id: I2187569bcfd05b0d091cf8c79171ee3c41c39cb9
|
||||
---
|
||||
frontends/nss/ecm_nss_ipv6.c | 7 ++++---
|
||||
frontends/nss/ecm_nss_multicast_ipv6.c | 9 +++++++++
|
||||
frontends/sfe/ecm_sfe_ipv6.c | 7 ++++---
|
||||
3 files changed, 17 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c
|
||||
index c7dd37f..9011e18 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv6.c
|
||||
@@ -527,13 +527,14 @@ struct ecm_db_node_instance *ecm_nss_ipv6_node_establish_and_ref(struct ecm_fron
|
||||
struct net_device *master;
|
||||
master = ecm_interface_get_and_hold_dev_master(dev);
|
||||
DEBUG_ASSERT(master, "Expected a master\n");
|
||||
- ecm_interface_send_neighbour_solicitation(master, addr);
|
||||
+ ecm_interface_send_neighbour_solicitation(master, gw_addr);
|
||||
dev_put(master);
|
||||
} else {
|
||||
- ecm_interface_send_neighbour_solicitation(dev, addr);
|
||||
+ ecm_interface_send_neighbour_solicitation(dev, gw_addr);
|
||||
}
|
||||
|
||||
- DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr));
|
||||
+ DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT " gw: " ECM_IP_ADDR_OCTAL_FMT "\n",
|
||||
+ ECM_IP_ADDR_TO_OCTAL(addr), ECM_IP_ADDR_TO_OCTAL(gw_addr));
|
||||
return NULL;
|
||||
}
|
||||
done:
|
||||
diff --git a/frontends/nss/ecm_nss_multicast_ipv6.c b/frontends/nss/ecm_nss_multicast_ipv6.c
|
||||
index a361eec..38fde95 100644
|
||||
--- a/frontends/nss/ecm_nss_multicast_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_multicast_ipv6.c
|
||||
@@ -2558,6 +2558,15 @@ static struct ecm_db_node_instance *ecm_nss_multicast_ipv6_node_establish_and_re
|
||||
#endif
|
||||
if (!ecm_interface_mac_addr_get(addr, node_addr, &on_link, gw_addr)) {
|
||||
DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr));
|
||||
+
|
||||
+ /*
|
||||
+ * If there is a gw_addr found during the lookup, use that address
|
||||
+ * for neighbour solicitation request.
|
||||
+ */
|
||||
+ if (!ECM_IP_ADDR_IS_NULL(gw_addr)) {
|
||||
+ ECM_IP_ADDR_COPY(addr, gw_addr);
|
||||
+ }
|
||||
+
|
||||
if (ecm_front_end_is_bridge_port(dev)) {
|
||||
struct net_device *master;
|
||||
master = ecm_interface_get_and_hold_dev_master(dev);
|
||||
diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c
|
||||
index 3fd5d46..51a9ccb 100644
|
||||
--- a/frontends/sfe/ecm_sfe_ipv6.c
|
||||
+++ b/frontends/sfe/ecm_sfe_ipv6.c
|
||||
@@ -256,13 +256,14 @@ struct ecm_db_node_instance *ecm_sfe_ipv6_node_establish_and_ref(struct ecm_fron
|
||||
struct net_device *master;
|
||||
master = ecm_interface_get_and_hold_dev_master(dev);
|
||||
DEBUG_ASSERT(master, "Expected a master\n");
|
||||
- ecm_interface_send_neighbour_solicitation(master, addr);
|
||||
+ ecm_interface_send_neighbour_solicitation(master, gw_addr);
|
||||
dev_put(master);
|
||||
} else {
|
||||
- ecm_interface_send_neighbour_solicitation(dev, addr);
|
||||
+ ecm_interface_send_neighbour_solicitation(dev, gw_addr);
|
||||
}
|
||||
|
||||
- DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr));
|
||||
+ DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT " gw: " ECM_IP_ADDR_OCTAL_FMT "\n",
|
||||
+ ECM_IP_ADDR_TO_OCTAL(addr), ECM_IP_ADDR_TO_OCTAL(gw_addr));
|
||||
return NULL;
|
||||
}
|
||||
done:
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From 5b51ae2f1eca61c6f68e40a05333da5a362ff327 Mon Sep 17 00:00:00 2001
|
||||
From: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Date: Mon, 13 Apr 2020 09:01:48 -0700
|
||||
Subject: [qca-nss-ecm] IPv6 solicitation fix with zero gateway address
|
||||
|
||||
The ECM function can find a zero gateway address for
|
||||
a host IP address. In this case, we need to use the
|
||||
host IP address while sending the solicitation request.
|
||||
|
||||
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
|
||||
Change-Id: I1979834088ddfe1843566f51f64348f79e2df0fc
|
||||
---
|
||||
frontends/nss/ecm_nss_ipv6.c | 11 ++++++++++-
|
||||
frontends/sfe/ecm_sfe_ipv6.c | 11 ++++++++++-
|
||||
2 files changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c
|
||||
index a05781b..9eb591c 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv6.c
|
||||
@@ -516,7 +516,16 @@ struct ecm_db_node_instance *ecm_nss_ipv6_node_establish_and_ref(struct ecm_fron
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- DEBUG_TRACE("Have a gw address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(gw_addr));
|
||||
+ /*
|
||||
+ * The found gateway address can be all zeros,
|
||||
+ * so in this case use the host address.
|
||||
+ */
|
||||
+ if (ECM_IP_ADDR_IS_NULL(gw_addr)) {
|
||||
+ DEBUG_TRACE("GW address is found as zeros, so use host IP\n");
|
||||
+ ECM_IP_ADDR_COPY(gw_addr, addr);
|
||||
+ } else {
|
||||
+ DEBUG_TRACE("Have a gw address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(gw_addr));
|
||||
+ }
|
||||
|
||||
if (ecm_interface_mac_addr_get_no_route(dev, gw_addr, node_addr)) {
|
||||
DEBUG_TRACE("Found the mac address for gateway\n");
|
||||
diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c
|
||||
index 51a9ccb..e609df7 100644
|
||||
--- a/frontends/sfe/ecm_sfe_ipv6.c
|
||||
+++ b/frontends/sfe/ecm_sfe_ipv6.c
|
||||
@@ -245,7 +245,16 @@ struct ecm_db_node_instance *ecm_sfe_ipv6_node_establish_and_ref(struct ecm_fron
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- DEBUG_TRACE("Have a gw address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(gw_addr));
|
||||
+ /*
|
||||
+ * The found gateway address can be all zeros,
|
||||
+ * so in this case use the host address.
|
||||
+ */
|
||||
+ if (ECM_IP_ADDR_IS_NULL(gw_addr)) {
|
||||
+ DEBUG_TRACE("GW address is found as zeros, so use host IP\n");
|
||||
+ ECM_IP_ADDR_COPY(gw_addr, addr);
|
||||
+ } else {
|
||||
+ DEBUG_TRACE("Have a gw address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(gw_addr));
|
||||
+ }
|
||||
|
||||
if (ecm_interface_mac_addr_get_no_route(dev, gw_addr, node_addr)) {
|
||||
DEBUG_TRACE("Found the mac address for gateway\n");
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
From e23eabd570eabde1d1fc803127a97fd101642467 Mon Sep 17 00:00:00 2001
|
||||
From: Varsha Mishra <varsham@codeaurora.org>
|
||||
Date: Fri, 12 Jun 2020 01:06:58 +0530
|
||||
Subject: [qca-nss-ecm] Allow egress on same port when bridge hairpin is
|
||||
enabled.
|
||||
|
||||
When bridge hairpin is enabled, allow egress on same port. Wi-Fi intrabss
|
||||
frames are getting exceptioned to stack. Bridge gets to make the decision
|
||||
whether these frames need to be forwarded or dropped.
|
||||
|
||||
Signed-off-by: Varsha Mishra <varsham@codeaurora.org>
|
||||
Change-Id: Ibdd72264d8887330ba0297ed12cbcfc390065bff
|
||||
---
|
||||
frontends/nss/ecm_nss_ipv4.c | 28 ++++++++++++++++++++++------
|
||||
frontends/nss/ecm_nss_ipv6.c | 28 ++++++++++++++++++++++------
|
||||
2 files changed, 44 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c
|
||||
index 60f799b..51c9ebf 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv4.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv4.c
|
||||
@@ -1756,7 +1756,9 @@ static unsigned int ecm_nss_ipv4_bridge_post_routing_hook(void *priv,
|
||||
* Case 2:
|
||||
* For routed packets the skb will have the src mac matching the bridge mac.
|
||||
* Case 3:
|
||||
- * If the packet was not local (case 1) or routed (case 2) then we process.
|
||||
+ * If the packet was not local (case 1) or routed (case 2) then
|
||||
+ * we process. There is an exception to case 2: when hairpin mode
|
||||
+ * is enabled, we process.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -1768,14 +1770,28 @@ static unsigned int ecm_nss_ipv4_bridge_post_routing_hook(void *priv,
|
||||
dev_put(bridge);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * This flag needs to be checked in slave port(eth0/ath0)
|
||||
+ * and not on master interface(br-lan). Hairpin flag can be
|
||||
+ * enabled/disabled for ports individually.
|
||||
+ */
|
||||
if (in == out) {
|
||||
- DEBUG_TRACE("skb: %p, bridge: %p (%s), port bounce on %p (%s)\n", skb, bridge, bridge->name, out, out->name);
|
||||
- dev_put(in);
|
||||
- dev_put(bridge);
|
||||
- return NF_ACCEPT;
|
||||
+ if (!br_is_hairpin_enabled(in)) {
|
||||
+ DEBUG_TRACE("skb: %p, bridge: %p (%s), ignoring"
|
||||
+ "the packet, hairpin not enabled"
|
||||
+ "on port %p (%s)\n", skb, bridge,
|
||||
+ bridge->name, out, out->name);
|
||||
+ dev_put(in);
|
||||
+ dev_put(bridge);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+ DEBUG_TRACE("skb: %p, bridge: %p (%s), hairpin enabled on port"
|
||||
+ "%p (%s)\n", skb, bridge, bridge->name, out, out->name);
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Case 2: Routed trafffic would be handled by the INET post routing.
|
||||
+ */
|
||||
if (!ecm_mac_addr_equal(skb_eth_hdr->h_source, bridge->dev_addr)) {
|
||||
- /*
|
||||
- * Case 2: Routed trafffic would be handled by the INET post routing.
|
||||
- */
|
||||
DEBUG_TRACE("skb: %p, Ignoring routed packet to bridge: %p (%s)\n", skb, bridge, bridge->name);
|
||||
goto skip_ipv4_bridge_flow;
|
||||
}
|
||||
diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c
|
||||
index 6ad425e..160c94c 100644
|
||||
--- a/frontends/nss/ecm_nss_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_ipv6.c
|
||||
@@ -1498,7 +1498,9 @@ static unsigned int ecm_nss_ipv6_bridge_post_routing_hook(void *priv,
|
||||
* Case 2:
|
||||
* For routed packets the skb will have the src mac matching the bridge mac.
|
||||
* Case 3:
|
||||
- * If the packet was not local (case 1) or routed (case 2) then we process.
|
||||
+ * If the packet was not local (case 1) or routed (case 2) then
|
||||
+ * we process. There is an exception to case 2: when hairpin mode
|
||||
+ * is enabled, we process.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -1510,14 +1512,28 @@ static unsigned int ecm_nss_ipv6_bridge_post_routing_hook(void *priv,
|
||||
dev_put(bridge);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * This flag needs to be checked in slave port(eth0/ath0)
|
||||
+ * and not on master interface(br-lan). Hairpin flag can be
|
||||
+ * enabled/disabled for ports individually.
|
||||
+ */
|
||||
if (in == out) {
|
||||
- DEBUG_TRACE("skb: %p, bridge: %p (%s), port bounce on %p (%s)\n", skb, bridge, bridge->name, out, out->name);
|
||||
- dev_put(in);
|
||||
- dev_put(bridge);
|
||||
- return NF_ACCEPT;
|
||||
+ if (!br_is_hairpin_enabled(in)) {
|
||||
+ DEBUG_TRACE("skb: %p, bridge: %p (%s), ignoring"
|
||||
+ "the packet, hairpin not enabled"
|
||||
+ "on port %p (%s)\n", skb, bridge,
|
||||
+ bridge->name, out, out->name);
|
||||
+ dev_put(in);
|
||||
+ dev_put(bridge);
|
||||
+ return NF_ACCEPT;
|
||||
+ }
|
||||
+ DEBUG_TRACE("skb: %p, bridge: %p (%s), hairpin enabled on port"
|
||||
+ "%p (%s)\n", skb, bridge, bridge->name, out, out->name);
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Case 2: Routed trafffic would be handled by the INET post routing.
|
||||
+ */
|
||||
if (!ecm_mac_addr_equal(skb_eth_hdr->h_source, bridge->dev_addr)) {
|
||||
- /*
|
||||
- * Case 2: Routed trafffic would be handled by the INET post routing.
|
||||
- */
|
||||
DEBUG_TRACE("skb: %p, Ignoring routed packet to bridge: %p (%s)\n", skb, bridge, bridge->name);
|
||||
goto skip_ipv6_bridge_flow;
|
||||
}
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
Reference in New Issue
Block a user