shortcut-fe: fix ipsec forwarding issue
SKBs to IPSEC can't be accelerated because they need further
encapsultion in XFRM stack before leaving a network interface.
But on the other direction, SKBs from IPSEC can be forwarded to
an interface directly. In this fix, we accelerate one direction
of XFRM tunnel flows.
Change-Id: I51a7561a7fb12843f8f4bd9455c43ad7c095081c
Signed-off-by: Zhi Chen <zhichen@codeaurora.org>
diff --git a/shortcut-fe/sfe_cm.c b/shortcut-fe/sfe_cm.c
index d463c16..cee000e 100644
--- a/shortcut-fe/sfe_cm.c
+++ b/shortcut-fe/sfe_cm.c
@@ -252,6 +252,16 @@
return NF_ACCEPT;
}
+#ifdef CONFIG_XFRM
+ /*
+ * Packet to xfrm for encapsulation, we can't process it
+ */
+ if (unlikely(skb_dst(skb)->xfrm)) {
+ DEBUG_TRACE("packet to xfrm, ignoring\n");
+ return NF_ACCEPT;
+ }
+#endif
+
/*
* Don't process packets that are not being forwarded.
*/
@@ -392,6 +402,28 @@
return NF_ACCEPT;
}
+#ifdef CONFIG_XFRM
+ sic.original_accel = 1;
+ sic.reply_accel = 1;
+
+ /*
+ * For packets de-capsulated from xfrm, we still can accelerate it
+ * on the direction we just received the packet.
+ */
+ if (unlikely(skb->sp)) {
+ if (sic.protocol == IPPROTO_TCP &&
+ !(sic.flags & SFE_CREATE_FLAG_NO_SEQ_CHECK)) {
+ return NF_ACCEPT;
+ }
+
+ if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) {
+ sic.reply_accel = 0;
+ } else {
+ sic.original_accel = 0;
+ }
+ }
+#endif
+
/*
* Get the net device and MAC addresses that correspond to the various source and
* destination host addresses.
diff --git a/shortcut-fe/sfe_cm.h b/shortcut-fe/sfe_cm.h
index 594cdd9..a437788 100644
--- a/shortcut-fe/sfe_cm.h
+++ b/shortcut-fe/sfe_cm.h
@@ -57,6 +57,10 @@
uint32_t dest_td_end;
uint32_t dest_td_max_end;
uint32_t mark;
+#ifdef CONFIG_XFRM
+ uint32_t original_accel;
+ uint32_t reply_accel;
+#endif
};
/*
diff --git a/shortcut-fe/sfe_ipv4.c b/shortcut-fe/sfe_ipv4.c
index 4b8a5da..055242f 100644
--- a/shortcut-fe/sfe_ipv4.c
+++ b/shortcut-fe/sfe_ipv4.c
@@ -195,6 +195,9 @@
#ifdef CONFIG_NF_FLOW_COOKIE
uint32_t flow_cookie; /* used flow cookie, for debug */
#endif
+#ifdef CONFIG_XFRM
+ uint32_t flow_accel; /* The flow accelerated or not */
+#endif
/*
* Connection state that we track once we match.
@@ -1281,6 +1284,18 @@
return 0;
}
+#ifdef CONFIG_XFRM
+ /*
+ * We can't accelerate the flow on this direction, just let it go
+ * through the slow path.
+ */
+ if (unlikely(!cm->flow_accel)) {
+ si->packets_not_forwarded++;
+ spin_unlock(&si->lock);
+ return 0;
+ }
+#endif
+
/*
* Does our TTL allow forwarding?
*/
@@ -1638,6 +1653,17 @@
return 0;
}
+#ifdef CONFIG_XFRM
+ /*
+ * We can't accelerate the flow on this direction, just let it go
+ * through the slow path.
+ */
+ if (unlikely(!cm->flow_accel)) {
+ si->packets_not_forwarded++;
+ spin_unlock(&si->lock);
+ return 0;
+ }
+#endif
/*
* Does our TTL allow forwarding?
*/
@@ -2500,6 +2526,9 @@
#ifdef CONFIG_NF_FLOW_COOKIE
original_cm->flow_cookie = 0;
#endif
+#ifdef CONFIG_XFRM
+ original_cm->flow_accel = sic->original_accel;
+#endif
original_cm->active_next = NULL;
original_cm->active_prev = NULL;
original_cm->active = false;
@@ -2548,6 +2577,9 @@
#ifdef CONFIG_NF_FLOW_COOKIE
reply_cm->flow_cookie = 0;
#endif
+#ifdef CONFIG_XFRM
+ reply_cm->flow_accel = sic->reply_accel;
+#endif
reply_cm->active_next = NULL;
reply_cm->active_prev = NULL;
reply_cm->active = false;
diff --git a/shortcut-fe/sfe_ipv6.c b/shortcut-fe/sfe_ipv6.c
index 3f5d6c0..b2958c6 100644
--- a/shortcut-fe/sfe_ipv6.c
+++ b/shortcut-fe/sfe_ipv6.c
@@ -225,6 +225,9 @@
#ifdef CONFIG_NF_FLOW_COOKIE
uint32_t flow_cookie; /* used flow cookie, for debug */
#endif
+#ifdef CONFIG_XFRM
+ uint32_t flow_accel; /* The flow accelerated or not */
+#endif
/*
* Connection state that we track once we match.
@@ -1346,6 +1349,18 @@
return 0;
}
+#ifdef CONFIG_XFRM
+ /*
+ * We can't accelerate the flow on this direction, just let it go
+ * through the slow path.
+ */
+ if (unlikely(!cm->flow_accel)) {
+ si->packets_not_forwarded++;
+ spin_unlock(&si->lock);
+ return 0;
+ }
+#endif
+
/*
* Does our hop_limit allow forwarding?
*/
@@ -1682,6 +1697,18 @@
return 0;
}
+#ifdef CONFIG_XFRM
+ /*
+ * We can't accelerate the flow on this direction, just let it go
+ * through the slow path.
+ */
+ if (unlikely(!cm->flow_accel)) {
+ si->packets_not_forwarded++;
+ spin_unlock(&si->lock);
+ return 0;
+ }
+#endif
+
/*
* Does our hop_limit allow forwarding?
*/
@@ -2519,6 +2546,9 @@
#ifdef CONFIG_NF_FLOW_COOKIE
original_cm->flow_cookie = 0;
#endif
+#ifdef CONFIG_XFRM
+ original_cm->flow_accel = sic->original_accel;
+#endif
original_cm->active_next = NULL;
original_cm->active_prev = NULL;
original_cm->active = false;
@@ -2567,6 +2597,9 @@
#ifdef CONFIG_NF_FLOW_COOKIE
reply_cm->flow_cookie = 0;
#endif
+#ifdef CONFIG_XFRM
+ reply_cm->flow_accel = sic->reply_accel;
+#endif
reply_cm->active_next = NULL;
reply_cm->active_prev = NULL;
reply_cm->active = false;