[qca-nss-sfe] 802.1Q/802.1ad VLAN support in SFE
Change-Id: I8007484b229b0dac0aff6dc284641b94090539db
Signed-off-by: Wayne Tan <quic_wtan@quicinc.com>
diff --git a/sfe_ipv6_udp.c b/sfe_ipv6_udp.c
index e5eeb9e..fc260bd 100644
--- a/sfe_ipv6_udp.c
+++ b/sfe_ipv6_udp.c
@@ -30,6 +30,7 @@
#include "sfe_flow_cookie.h"
#include "sfe_ipv6.h"
#include "sfe_pppoe.h"
+#include "sfe_vlan.h"
/*
* sfe_ipv6_udp_sk_deliver()
@@ -190,6 +191,16 @@
}
/*
+ * Do we expect an ingress VLAN tag for this flow?
+ */
+ if (unlikely(!sfe_vlan_validate_ingress_tag(skb, cm->ingress_vlan_hdr_cnt, cm->ingress_vlan_hdr, l2_info))) {
+ rcu_read_unlock();
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INGRESS_VLAN_TAG_MISMATCH);
+ DEBUG_TRACE("VLAN tag mismatch. skb=%px\n", skb);
+ return 0;
+ }
+
+ /*
* If our packet has been marked as "flush on find" we can't actually
* forward it in the fast path, but now that we've found an associated
* connection we need sync its status before exception it to slow path.
@@ -303,6 +314,16 @@
}
/*
+ * Check if skb has enough headroom to write L2 headers
+ */
+ if (unlikely(skb_headroom(skb) < cm->l2_hdr_size)) {
+ rcu_read_unlock();
+ DEBUG_WARN("%px: Not enough headroom: %u\n", skb, skb_headroom(skb));
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_NO_HEADROOM);
+ return 0;
+ }
+
+ /*
* From this point on we're good to modify the packet.
*/
@@ -310,19 +331,11 @@
* For PPPoE flows, add PPPoE header before L2 header is added.
*/
if (cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PPPOE_ENCAP) {
- if (unlikely(!sfe_pppoe_add_header(skb, cm->pppoe_session_id, PPP_IPV6))) {
- rcu_read_unlock();
- DEBUG_WARN("%px: PPPoE header addition failed\n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_NO_HEADROOM);
- }
+ sfe_pppoe_add_header(skb, cm->pppoe_session_id, PPP_IPV6);
this_cpu_inc(si->stats_pcpu->pppoe_encap_packets_forwarded64);
}
/*
- * TODO: VLAN header should be added here when they are supported.
- */
-
- /*
* UDP sock will be valid only in decap-path.
* Call encap_rcv function associated with udp_sock in cm.
*/
@@ -447,7 +460,14 @@
skb->dev = xmit_dev;
/*
- * Check to see if we need to write a header.
+ * Check to see if we need to add VLAN tags
+ */
+ if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_INSERT_EGRESS_VLAN_TAG)) {
+ sfe_vlan_add_tag(skb, cm->egress_vlan_hdr_cnt, cm->egress_vlan_hdr);
+ }
+
+ /*
+ * Check to see if we need to write an Ethernet header.
*/
if (likely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_L2_HDR)) {
if (unlikely(!(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR))) {