[qca-nss-ecm] NSS acceleration support for bridged PPPoE sessions.
- CRs-Fixed: 824100
- Accelerate bridged PPPoE session flows carrying IPv4/IPv6
payloads. In such scenarios PPPoE client/server are
running on machines connected to LAN ports.
- Fix ECM tracker issue where incorrect protocol id was being
extracted from IPv6 header.
Change-Id: I428e930d29305bc4a228210758ec295ccf556ab2
Signed-off-by: Tushar Mathur <tushar@codeaurora.org>
diff --git a/ecm_tracker.c b/ecm_tracker.c
index 4bb8a6d..69d6e1f 100644
--- a/ecm_tracker.c
+++ b/ecm_tracker.c
@@ -411,6 +411,7 @@
#ifdef ECM_IPV6_ENABLE
struct ipv6hdr *v6_hdr = NULL;
int16_t this_header;
+ int16_t prev_header;
uint32_t offset;
#endif
@@ -553,6 +554,7 @@
*/
offset = 40;
this_header = (int16_t)v6_hdr->nexthdr;
+ prev_header = this_header;
while ((remain > 0) && (this_header >= 0) && (this_header != 59)) {
struct ecm_tracker_ip_protocols *etip;
struct ecm_tracker_ip_protocol_header *etiph;
@@ -589,13 +591,14 @@
DEBUG_ASSERT(remain >= etiph->size, "v6 remain: %u goes negative after header size: %u", remain, etiph->size);
remain -= etiph->size;
+ prev_header = this_header;
this_header = next_header;
}
/*
* Generally the last protocol seen is the upper layer protocol
*/
- ip_hdr->protocol = (int)this_header;
+ ip_hdr->protocol = (int)prev_header;
return true;
#endif
diff --git a/frontends/include/ecm_front_end_common.h b/frontends/include/ecm_front_end_common.h
new file mode 100644
index 0000000..8ce3cef
--- /dev/null
+++ b/frontends/include/ecm_front_end_common.h
@@ -0,0 +1,54 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2015 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.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef _ECM_FRONT_END_COMMON_
+#define _ECM_FRONT_END_COMMON_
+
+/*
+ * ecm_front_end_l2_encap_header_len()
+ * Return length of encapsulating L2 header
+ */
+static inline uint32_t ecm_front_end_l2_encap_header_len(struct sk_buff *skb)
+{
+ switch (skb->protocol) {
+ case ntohs(ETH_P_PPP_SES):
+ return PPPOE_SES_HLEN;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * ecm_front_end_pull_l2_encap_header()
+ * Pull encapsulating L2 header
+ */
+static void ecm_front_end_pull_l2_encap_header(struct sk_buff *skb, uint32_t len)
+{
+ skb->data += len;
+ skb->network_header += len;
+}
+
+/*
+ * ecm_front_end_push_l2_encap_header()
+ * Push encapsulating L2 header
+ */
+static void ecm_front_end_push_l2_encap_header(struct sk_buff *skb, uint32_t len)
+{
+ skb->data -= len;
+ skb->network_header -= len;
+}
+
+#endif
diff --git a/frontends/nss/ecm_front_end_ipv6.c b/frontends/nss/ecm_front_end_ipv6.c
index ce70e49..0276896 100644
--- a/frontends/nss/ecm_front_end_ipv6.c
+++ b/frontends/nss/ecm_front_end_ipv6.c
@@ -39,6 +39,7 @@
#include <linux/in6.h>
#include <linux/udp.h>
#include <linux/tcp.h>
+#include <linux/ppp_defs.h>
#include <linux/inetdevice.h>
#include <linux/if_arp.h>
@@ -92,6 +93,7 @@
#include "ecm_classifier_dscp.h"
#endif
#include "ecm_interface.h"
+#include "ecm_front_end_common.h"
/*
* Magic numbers
@@ -1433,7 +1435,7 @@
*/
static void ecm_front_end_ipv6_connection_tcp_front_end_accelerate(struct ecm_front_end_connection_instance *feci,
struct ecm_classifier_process_response *pr,
- struct nf_conn *ct)
+ struct nf_conn *ct, bool is_l2_encap)
{
struct ecm_front_end_ipv6_connection_tcp_instance *fecti = (struct ecm_front_end_ipv6_connection_tcp_instance *)feci;
int32_t from_ifaces_first;
@@ -1885,6 +1887,9 @@
nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_ROUTED;
} else {
nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_BRIDGE_FLOW;
+ if (is_l2_encap) {
+ nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_L2_ENCAP;
+ }
}
/*
@@ -2886,7 +2891,7 @@
* can all use and reduce the amount of code!
*/
static void ecm_front_end_ipv6_connection_udp_front_end_accelerate(struct ecm_front_end_connection_instance *feci,
- struct ecm_classifier_process_response *pr)
+ struct ecm_classifier_process_response *pr, bool is_l2_encap)
{
struct ecm_front_end_ipv6_connection_udp_instance *fecui = (struct ecm_front_end_ipv6_connection_udp_instance *)feci;
int32_t from_ifaces_first;
@@ -3339,6 +3344,9 @@
nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_ROUTED;
} else {
nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_BRIDGE_FLOW;
+ if (is_l2_encap) {
+ nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_L2_ENCAP;
+ }
}
/*
@@ -4300,7 +4308,7 @@
* can all use and reduce the amount of code!
*/
static void ecm_front_end_ipv6_connection_non_ported_front_end_accelerate(struct ecm_front_end_connection_instance *feci,
- struct ecm_classifier_process_response *pr)
+ struct ecm_classifier_process_response *pr, bool is_l2_encap)
{
struct ecm_front_end_ipv6_connection_non_ported_instance *fecnpi = (struct ecm_front_end_ipv6_connection_non_ported_instance *)feci;
int protocol;
@@ -4765,6 +4773,9 @@
nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_ROUTED;
} else {
nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_BRIDGE_FLOW;
+ if (is_l2_encap) {
+ nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_L2_ENCAP;
+ }
}
/*
@@ -5807,7 +5818,7 @@
struct net_device *in_dev,
uint8_t *src_node_addr,
uint8_t *dest_node_addr,
- bool can_accel, bool is_routed, struct sk_buff *skb,
+ bool can_accel, bool is_routed, bool is_l2_encap, struct sk_buff *skb,
struct ecm_tracker_ip_header *iph,
struct nf_conn *ct, ecm_tracker_sender_type_t sender, ecm_db_direction_t ecm_dir,
struct nf_conntrack_tuple *orig_tuple, struct nf_conntrack_tuple *reply_tuple,
@@ -6315,7 +6326,7 @@
struct ecm_front_end_connection_instance *feci;
DEBUG_TRACE("%p: accel\n", ci);
feci = ecm_db_connection_front_end_get_and_ref(ci);
- ecm_front_end_ipv6_connection_tcp_front_end_accelerate(feci, &prevalent_pr, ct);
+ ecm_front_end_ipv6_connection_tcp_front_end_accelerate(feci, &prevalent_pr, ct, is_l2_encap);
feci->deref(feci);
}
ecm_db_connection_deref(ci);
@@ -6331,7 +6342,7 @@
struct net_device *in_dev,
uint8_t *src_node_addr,
uint8_t *dest_node_addr,
- bool can_accel, bool is_routed, struct sk_buff *skb,
+ bool can_accel, bool is_routed, bool is_l2_encap, struct sk_buff *skb,
struct ecm_tracker_ip_header *iph,
struct nf_conn *ct, ecm_tracker_sender_type_t sender, ecm_db_direction_t ecm_dir,
struct nf_conntrack_tuple *orig_tuple, struct nf_conntrack_tuple *reply_tuple,
@@ -6842,7 +6853,7 @@
struct ecm_front_end_connection_instance *feci;
DEBUG_TRACE("%p: accel\n", ci);
feci = ecm_db_connection_front_end_get_and_ref(ci);
- ecm_front_end_ipv6_connection_udp_front_end_accelerate(feci, &prevalent_pr);
+ ecm_front_end_ipv6_connection_udp_front_end_accelerate(feci, &prevalent_pr, is_l2_encap);
feci->deref(feci);
}
ecm_db_connection_deref(ci);
@@ -6858,7 +6869,7 @@
struct net_device *in_dev,
uint8_t *src_node_addr,
uint8_t *dest_node_addr,
- bool can_accel, bool is_routed, struct sk_buff *skb,
+ bool can_accel, bool is_routed, bool is_l2_encap, struct sk_buff *skb,
struct ecm_tracker_ip_header *ip_hdr,
struct nf_conn *ct, ecm_tracker_sender_type_t sender, ecm_db_direction_t ecm_dir,
struct nf_conntrack_tuple *orig_tuple, struct nf_conntrack_tuple *reply_tuple,
@@ -7325,7 +7336,7 @@
struct ecm_front_end_connection_instance *feci;
DEBUG_TRACE("%p: accel\n", ci);
feci = ecm_db_connection_front_end_get_and_ref(ci);
- ecm_front_end_ipv6_connection_non_ported_front_end_accelerate(feci, &prevalent_pr);
+ ecm_front_end_ipv6_connection_non_ported_front_end_accelerate(feci, &prevalent_pr, is_l2_encap);
feci->deref(feci);
}
ecm_db_connection_deref(ci);
@@ -7339,7 +7350,8 @@
*/
static unsigned int ecm_front_end_ipv6_ip_process(struct net_device *out_dev, struct net_device *in_dev,
uint8_t *src_node_addr, uint8_t *dest_node_addr,
- bool can_accel, bool is_routed, struct sk_buff *skb)
+ bool can_accel, bool is_routed, bool is_l2_encap,
+ struct sk_buff *skb)
{
struct ecm_tracker_ip_header ip_hdr;
struct nf_conn *ct;
@@ -7484,7 +7496,7 @@
return ecm_front_end_ipv6_tcp_process(out_dev, in_dev,
src_node_addr,
dest_node_addr,
- can_accel, is_routed, skb,
+ can_accel, is_routed, is_l2_encap, skb,
&ip_hdr,
ct, sender, ecm_dir,
&orig_tuple, &reply_tuple,
@@ -7493,7 +7505,7 @@
return ecm_front_end_ipv6_udp_process(out_dev, in_dev,
src_node_addr,
dest_node_addr,
- can_accel, is_routed, skb,
+ can_accel, is_routed, is_l2_encap, skb,
&ip_hdr,
ct, sender, ecm_dir,
&orig_tuple, &reply_tuple,
@@ -7502,7 +7514,7 @@
return ecm_front_end_ipv6_non_ported_process(out_dev, in_dev,
src_node_addr,
dest_node_addr,
- can_accel, is_routed, skb,
+ can_accel, is_routed, is_l2_encap, skb,
&ip_hdr,
ct, sender, ecm_dir,
&orig_tuple, &reply_tuple,
@@ -7578,12 +7590,48 @@
}
DEBUG_TRACE("Post routing process skb %p, out: %p, in: %p\n", skb, out, in);
- result = ecm_front_end_ipv6_ip_process((struct net_device *)out, in, NULL, NULL, can_accel, true, skb);
+ result = ecm_front_end_ipv6_ip_process((struct net_device *)out, in, NULL, NULL, can_accel, true, false, skb);
dev_put(in);
return result;
}
/*
+ * ecm_front_end_ipv6_pppoe_bridge_process()
+ * Called for PPPoE session packets that are going
+ * out to one of the bridge physical interfaces.
+ */
+static unsigned int ecm_front_end_ipv6_pppoe_bridge_process(struct net_device *out,
+ struct net_device *in,
+ struct ethhdr *skb_eth_hdr,
+ bool can_accel,
+ struct sk_buff *skb)
+{
+ unsigned int result = NF_ACCEPT;
+ struct pppoe_hdr *ph = pppoe_hdr(skb);
+ uint16_t ppp_proto = *(uint16_t *)ph->tag;
+ uint32_t encap_header_len = 0;
+
+ ppp_proto = ntohs(ppp_proto);
+ if (ppp_proto != PPP_IPV6) {
+ return NF_ACCEPT;
+ }
+
+ encap_header_len = ecm_front_end_l2_encap_header_len(skb);
+ ecm_front_end_pull_l2_encap_header(skb, encap_header_len);
+ skb->protocol = htons(ETH_P_IPV6);
+
+ result = ecm_front_end_ipv6_ip_process(out, in, skb_eth_hdr->h_source,
+ skb_eth_hdr->h_dest, can_accel,
+ false, true, skb);
+
+ ecm_front_end_push_l2_encap_header(skb, encap_header_len);
+ skb->protocol = htons(ETH_P_PPP_SES);
+
+ return result;
+}
+
+
+/*
* ecm_front_end_ipv6_bridge_post_routing_hook()
* Called for packets that are going out to one of the bridge physical interfaces.
*
@@ -7655,8 +7703,8 @@
return NF_ACCEPT;
}
eth_type = ntohs(skb_eth_hdr->h_proto);
- if (unlikely(eth_type != 0x86DD)) {
- DEBUG_TRACE("%p: Not IP\n", skb);
+ if (unlikely((eth_type != 0x86DD) && (eth_type != ETH_P_PPP_SES))) {
+ DEBUG_TRACE("%p: Not IP/PPPoE session\n", skb);
return NF_ACCEPT;
}
@@ -7733,8 +7781,17 @@
DEBUG_TRACE("Bridge process skb: %p, bridge: %p (%s), In: %p (%s), Out: %p (%s)\n",
skb, bridge, bridge->name, in, in->name, out, out->name);
+
+ if (unlikely(eth_type != 0x86DD)) {
+ result = ecm_front_end_ipv6_pppoe_bridge_process((struct net_device *)out, in, skb_eth_hdr, can_accel, skb);
+ dev_put(in);
+ dev_put(bridge);
+ return result;
+ }
+
result = ecm_front_end_ipv6_ip_process((struct net_device *)out, in,
- skb_eth_hdr->h_source, skb_eth_hdr->h_dest, can_accel, false, skb);
+ skb_eth_hdr->h_source, skb_eth_hdr->h_dest, can_accel, false, false, skb);
+
dev_put(in);
dev_put(bridge);
return result;
diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c
index c115c8b..9f7ba76 100644
--- a/frontends/nss/ecm_nss_ipv4.c
+++ b/frontends/nss/ecm_nss_ipv4.c
@@ -37,6 +37,7 @@
#include <linux/in.h>
#include <linux/udp.h>
#include <linux/tcp.h>
+#include <linux/ppp_defs.h>
#include <linux/inetdevice.h>
#include <linux/if_arp.h>
@@ -96,6 +97,8 @@
#include "ecm_nss_non_ported_ipv4.h"
#endif
+#include "ecm_front_end_common.h"
+
int ecm_nss_ipv4_no_action_limit_default = 250; /* Default no-action limit. */
int ecm_nss_ipv4_driver_fail_limit_default = 250; /* Default driver fail limit. */
int ecm_nss_ipv4_nack_limit_default = 250; /* Default nack limit. */
@@ -807,7 +810,7 @@
*/
static unsigned int ecm_nss_ipv4_ip_process(struct net_device *out_dev, struct net_device *in_dev,
uint8_t *src_node_addr, uint8_t *dest_node_addr,
- bool can_accel, bool is_routed, struct sk_buff *skb)
+ bool can_accel, bool is_routed, bool is_l2_encap, struct sk_buff *skb)
{
struct ecm_tracker_ip_header ip_hdr;
struct nf_conn *ct;
@@ -1187,7 +1190,7 @@
in_dev, in_dev_nat,
src_node_addr, src_node_addr_nat,
dest_node_addr, dest_node_addr_nat,
- can_accel, is_routed, skb,
+ can_accel, is_routed, is_l2_encap, skb,
&ip_hdr,
ct, sender, ecm_dir,
&orig_tuple, &reply_tuple,
@@ -1198,7 +1201,7 @@
in_dev, in_dev_nat,
src_node_addr, src_node_addr_nat,
dest_node_addr, dest_node_addr_nat,
- can_accel, is_routed, skb,
+ can_accel, is_routed, is_l2_encap, skb,
&ip_hdr,
ct, sender, ecm_dir,
&orig_tuple, &reply_tuple,
@@ -1278,12 +1281,47 @@
DEBUG_TRACE("Post routing process skb %p, out: %p (%s), in: %p (%s)\n", skb, out, out->name, in, in->name);
result = ecm_nss_ipv4_ip_process((struct net_device *)out, in, NULL, NULL,
- can_accel, true, skb);
+ can_accel, true, false, skb);
dev_put(in);
return result;
}
/*
+ * ecm_front_end_ipv4_pppoe_bridge_process()
+ * Called for PPPoE session packets that are going
+ * out to one of the bridge physical interfaces.
+ */
+static unsigned int ecm_front_end_ipv4_pppoe_bridge_process(struct net_device *out,
+ struct net_device *in,
+ struct ethhdr *skb_eth_hdr,
+ bool can_accel,
+ struct sk_buff *skb)
+{
+ unsigned int result = NF_ACCEPT;
+ struct pppoe_hdr *ph = pppoe_hdr(skb);
+ uint16_t ppp_proto = *(uint16_t *)ph->tag;
+ uint32_t encap_header_len = 0;
+
+ ppp_proto = ntohs(ppp_proto);
+ if (ppp_proto != PPP_IP) {
+ return NF_ACCEPT;
+ }
+
+ encap_header_len = ecm_front_end_l2_encap_header_len(skb);
+ ecm_front_end_pull_l2_encap_header(skb, encap_header_len);
+ skb->protocol = htons(ETH_P_IP);
+
+ result = ecm_nss_ipv4_ip_process(out, in, skb_eth_hdr->h_source,
+ skb_eth_hdr->h_dest, can_accel,
+ false, true, skb);
+
+ ecm_front_end_push_l2_encap_header(skb, encap_header_len);
+ skb->protocol = htons(ETH_P_PPP_SES);
+
+ return result;
+}
+
+/*
* ecm_nss_ipv4_bridge_post_routing_hook()
* Called for packets that are going out to one of the bridge physical interfaces.
*
@@ -1355,8 +1393,8 @@
return NF_ACCEPT;
}
eth_type = ntohs(skb_eth_hdr->h_proto);
- if (unlikely(eth_type != 0x0800)) {
- DEBUG_TRACE("%p: Not IP\n", skb);
+ if (unlikely((eth_type != 0x0800) && (eth_type != ETH_P_PPP_SES))) {
+ DEBUG_TRACE("%p: Not IP/PPPoE session\n", skb);
return NF_ACCEPT;
}
@@ -1433,8 +1471,18 @@
DEBUG_TRACE("Bridge process skb: %p, bridge: %p (%s), In: %p (%s), Out: %p (%s)\n",
skb, bridge, bridge->name, in, in->name, out, out->name);
+
+ if (unlikely(eth_type != 0x0800)) {
+ result = ecm_front_end_ipv4_pppoe_bridge_process((struct net_device *)out, in, skb_eth_hdr, can_accel, skb);
+ dev_put(in);
+ dev_put(bridge);
+ return result;
+ }
+
result = ecm_nss_ipv4_ip_process((struct net_device *)out, in,
- skb_eth_hdr->h_source, skb_eth_hdr->h_dest, can_accel, false, skb);
+ skb_eth_hdr->h_source, skb_eth_hdr->h_dest, can_accel, false, false, skb);
+
+
dev_put(in);
dev_put(bridge);
return result;
diff --git a/frontends/nss/ecm_nss_non_ported_ipv4.c b/frontends/nss/ecm_nss_non_ported_ipv4.c
index 98cb855..406a185 100644
--- a/frontends/nss/ecm_nss_non_ported_ipv4.c
+++ b/frontends/nss/ecm_nss_non_ported_ipv4.c
@@ -379,7 +379,7 @@
* GGG TODO Refactor this function into a single function that np, udp and tcp
* can all use and reduce the amount of code!
*/
-static void ecm_nss_non_ported_ipv4_connection_accelerate(struct ecm_front_end_connection_instance *feci,
+static void ecm_nss_non_ported_ipv4_connection_accelerate(struct ecm_front_end_connection_instance *feci, bool is_l2_encap,
struct ecm_classifier_process_response *pr)
{
struct ecm_nss_non_ported_ipv4_connection_instance *nnpci = (struct ecm_nss_non_ported_ipv4_connection_instance *)feci;
@@ -844,6 +844,9 @@
nircm->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_ROUTED;
} else {
nircm->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_BRIDGE_FLOW;
+ if (is_l2_encap) {
+ nircm->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_L2_ENCAP;
+ }
}
/*
@@ -1659,7 +1662,7 @@
struct net_device *in_dev, struct net_device *in_dev_nat,
uint8_t *src_node_addr, uint8_t *src_node_addr_nat,
uint8_t *dest_node_addr, uint8_t *dest_node_addr_nat,
- bool can_accel, bool is_routed, struct sk_buff *skb,
+ bool can_accel, bool is_routed, bool is_l2_encap, struct sk_buff *skb,
struct ecm_tracker_ip_header *ip_hdr,
struct nf_conn *ct, ecm_tracker_sender_type_t sender, ecm_db_direction_t ecm_dir,
struct nf_conntrack_tuple *orig_tuple, struct nf_conntrack_tuple *reply_tuple,
@@ -2272,7 +2275,7 @@
struct ecm_front_end_connection_instance *feci;
DEBUG_TRACE("%p: accel\n", ci);
feci = ecm_db_connection_front_end_get_and_ref(ci);
- ecm_nss_non_ported_ipv4_connection_accelerate(feci, &prevalent_pr);
+ ecm_nss_non_ported_ipv4_connection_accelerate(feci, is_l2_encap, &prevalent_pr);
feci->deref(feci);
}
ecm_db_connection_deref(ci);
diff --git a/frontends/nss/ecm_nss_non_ported_ipv4.h b/frontends/nss/ecm_nss_non_ported_ipv4.h
index 96fbba6..5c538be 100644
--- a/frontends/nss/ecm_nss_non_ported_ipv4.h
+++ b/frontends/nss/ecm_nss_non_ported_ipv4.h
@@ -18,7 +18,7 @@
struct net_device *in_dev, struct net_device *in_dev_nat,
uint8_t *src_node_addr, uint8_t *src_node_addr_nat,
uint8_t *dest_node_addr, uint8_t *dest_node_addr_nat,
- bool can_accel, bool is_routed, struct sk_buff *skb,
+ bool can_accel, bool is_routed, bool is_l2_encap, struct sk_buff *skb,
struct ecm_tracker_ip_header *ip_hdr,
struct nf_conn *ct, ecm_tracker_sender_type_t sender, ecm_db_direction_t ecm_dir,
struct nf_conntrack_tuple *orig_tuple, struct nf_conntrack_tuple *reply_tuple,
diff --git a/frontends/nss/ecm_nss_ported_ipv4.c b/frontends/nss/ecm_nss_ported_ipv4.c
index dd605e0..170105f 100644
--- a/frontends/nss/ecm_nss_ported_ipv4.c
+++ b/frontends/nss/ecm_nss_ported_ipv4.c
@@ -323,7 +323,7 @@
* can all use and reduce the amount of code!
*/
static void ecm_nss_ported_ipv4_connection_accelerate(struct ecm_front_end_connection_instance *feci,
- struct ecm_classifier_process_response *pr,
+ struct ecm_classifier_process_response *pr, bool is_l2_encap,
struct nf_conn *ct)
{
struct ecm_nss_ported_ipv4_connection_instance *npci = (struct ecm_nss_ported_ipv4_connection_instance *)feci;
@@ -776,6 +776,9 @@
nircm->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_ROUTED;
} else {
nircm->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_BRIDGE_FLOW;
+ if (is_l2_encap) {
+ nircm->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_L2_ENCAP;
+ }
}
/*
@@ -1031,7 +1034,7 @@
nircm->tcp_rule.return_end,
nircm->tcp_rule.return_max_end);
}
-
+
/*
* Ref the connection before issuing an NSS rule
* This ensures that when the NSS responds to the command - which may even be immediately -
@@ -1651,7 +1654,7 @@
DEBUG_CLEAR_MAGIC(npci);
kfree(npci);
return NULL;
- }
+ }
return npci;
}
@@ -1664,11 +1667,11 @@
struct net_device *in_dev, struct net_device *in_dev_nat,
uint8_t *src_node_addr, uint8_t *src_node_addr_nat,
uint8_t *dest_node_addr, uint8_t *dest_node_addr_nat,
- bool can_accel, bool is_routed, struct sk_buff *skb,
+ bool can_accel, bool is_routed, bool is_l2_encap, struct sk_buff *skb,
struct ecm_tracker_ip_header *iph,
struct nf_conn *ct, ecm_tracker_sender_type_t sender, ecm_db_direction_t ecm_dir,
struct nf_conntrack_tuple *orig_tuple, struct nf_conntrack_tuple *reply_tuple,
- ip_addr_t ip_src_addr, ip_addr_t ip_dest_addr,
+ ip_addr_t ip_src_addr, ip_addr_t ip_dest_addr,
ip_addr_t ip_src_addr_nat, ip_addr_t ip_dest_addr_nat)
{
struct tcphdr *tcp_hdr;
@@ -2381,7 +2384,7 @@
struct ecm_front_end_connection_instance *feci;
DEBUG_TRACE("%p: accel\n", ci);
feci = ecm_db_connection_front_end_get_and_ref(ci);
- ecm_nss_ported_ipv4_connection_accelerate(feci, &prevalent_pr, ct);
+ ecm_nss_ported_ipv4_connection_accelerate(feci, &prevalent_pr, is_l2_encap, ct);
feci->deref(feci);
}
ecm_db_connection_deref(ci);
diff --git a/frontends/nss/ecm_nss_ported_ipv4.h b/frontends/nss/ecm_nss_ported_ipv4.h
index c14bca3..c0bfc39 100644
--- a/frontends/nss/ecm_nss_ported_ipv4.h
+++ b/frontends/nss/ecm_nss_ported_ipv4.h
@@ -18,11 +18,11 @@
struct net_device *in_dev, struct net_device *in_dev_nat,
uint8_t *src_node_addr, uint8_t *src_node_addr_nat,
uint8_t *dest_node_addr, uint8_t *dest_node_addr_nat,
- bool can_accel, bool is_routed, struct sk_buff *skb,
+ bool can_accel, bool is_routed, bool is_l2_encap, struct sk_buff *skb,
struct ecm_tracker_ip_header *iph,
struct nf_conn *ct, ecm_tracker_sender_type_t sender, ecm_db_direction_t ecm_dir,
struct nf_conntrack_tuple *orig_tuple, struct nf_conntrack_tuple *reply_tuple,
- ip_addr_t ip_src_addr, ip_addr_t ip_dest_addr, ip_addr_t ip_src_addr_nat,
+ ip_addr_t ip_src_addr, ip_addr_t ip_dest_addr, ip_addr_t ip_src_addr_nat,
ip_addr_t ip_dest_addr_nat);
extern ssize_t ecm_nss_ported_ipv4_get_tcp_accelerated_count(struct device *dev,