netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Dillow <dave@thedillows.org>
To: netdev@oss.sgi.com
Cc: dave@thedillows.org
Subject: [RFC BK 20/22] xfrm offload v2: typhoon: add management of outbound bundles
Date: Mon, 10 Jan 2005 10:37:02 -0500	[thread overview]
Message-ID: <20040110014300.29@ori.thedillows.org> (raw)
In-Reply-To: 20040110014300.28@ori.thedillows.org

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/01/10 01:05:38-05:00 dave@thedillows.org 
#   Add the offloading of outbound bundles.
#   
#   This is a tricky business, because there are restrictions on
#   the types and order of the xfrms we can offload. Some combinations
#   also yield incorrect results, so we have to reduce the amount of
#   offloading we do in those cases.
#   
#   Signed-off-by: David Dillow <dave@thedillows.org>
# 
# drivers/net/typhoon.c
#   2005/01/10 01:05:20-05:00 dave@thedillows.org +167 -0
#   Add the offloading of outbound bundles.
#   
#   This is a tricky business, because there are restrictions on
#   the types and order of the xfrms we can offload. Some combinations
#   also yield incorrect results, so we have to reduce the amount of
#   offloading we do in those cases.
#   
#   Signed-off-by: David Dillow <dave@thedillows.org>
# 
diff -Nru a/drivers/net/typhoon.c b/drivers/net/typhoon.c
--- a/drivers/net/typhoon.c	2005-01-10 01:16:43 -05:00
+++ b/drivers/net/typhoon.c	2005-01-10 01:16:43 -05:00
@@ -358,6 +358,12 @@
 #define TSO_OFFLOAD_ON		0
 #endif
 
+/* We need room for a maximum of 5 dst_entries -- the longest chain of
+ * headers we support for offloading is (inner -> outer):
+ * ESP AH IP2 ESP AH IP1 -- and IP2 is part of the second ESP dst
+ * (tunnel mode)
+ */
+#define TYPHOON_MAX_HEADERS	5
 #define IPSEC_NUM_DESCRIPTORS	1
 
 struct typhoon_xfrm_offload {
@@ -2584,6 +2590,167 @@
 					"offload (%d)\n", tp->name, -err);
 	}
 	spin_unlock_bh(&tp->offload_lock);
+}
+
+static int inline
+typhoon_bundle_list(struct dst_entry *bundle, struct dst_entry *dst_list[],
+						int max_entries)
+{
+	/* While putting the bundle into the dst_list so we can iterate it
+	 * in reverse, scan for problematic offload sequences. Skip over
+	 * the last xfrm in the sequence, so that we still offload as much
+	 * as possible.
+	 *
+	 * This list was generated using runtime 03.001.002, but the
+	 * problems are still present in 03.001.008. I have not re-investigated
+	 * the problems to determine if the symptoms have changed.
+	 *
+	 * inner AH tunnel, outer AH transport
+	 *	--> 3XP seems to put the inner hash at the wrong location
+	 * inner AH tunnel, outer ESP tunnel
+	 *	--> 3XP corrupts outer hash, maybe wrong place?
+	 * inner AH transport, outer ESP tunnel
+	 *	--> 3XP seems to encrypt the wrong portion of the packet
+	 * inner ESP transport, outer AH tunnel
+	 *	--> 3XP lockup, requires reset
+	 *
+	 * No problematic offloads start with ESP in tunnel mode, so pretend
+	 * that was the last one we looked at.
+	 */
+	int last_was_ah = 0, last_was_tunnel = 1;
+	struct dst_entry *dst = bundle;
+	struct xfrm_state *x;
+	int start = max_entries;
+	int bundle_size = 0;
+	int proto, problem;
+
+	while(bundle) {
+		x = bundle->xfrm;
+		proto = x ? x->type->proto : IPPROTO_IP;
+
+		problem = 0;
+		if(proto == IPPROTO_AH && !x->props.mode &&
+				(last_was_ah && last_was_tunnel))
+			problem = 1;
+		else if(proto == IPPROTO_AH && x->props.mode &&
+				!(last_was_ah || last_was_tunnel))
+			problem = 1;
+		else if(proto == IPPROTO_ESP && x->props.mode && last_was_ah)
+			problem = 1;
+
+		if(problem) {
+			/* We hit a snag -- forget about the xfrms we've
+			 * seen before the current one.
+			 */
+			bundle_size = 1;
+			dst = bundle;
+		} else {
+			bundle_size++;
+			if(bundle_size > max_entries)
+				dst = dst->child;
+		}
+
+		last_was_ah = (proto == IPPROTO_AH);
+		last_was_tunnel = x ? x->props.mode : 0;
+		bundle = bundle->child;
+	}
+
+	if(bundle_size < max_entries)
+		start = bundle_size;
+
+	bundle_size = 0;
+	while(dst) {
+		dst_list[--start] = dst;
+		dst = dst->child;
+		bundle_size++;
+	}
+
+	return bundle_size;
+}
+
+static void
+typhoon_xfrm_bundle_add(struct net_device *dev, struct dst_entry *bundle)
+{
+	/* Walk from the outermost dst back up the chain, offloading
+	 * until we hit something we cannot deal with.
+	 */
+	struct typhoon *tp = netdev_priv(dev);
+	struct xfrm_state *x;
+	struct xfrm_offload *xol;
+	struct typhoon_xfrm_offload *txo;
+	struct dst_entry *dst_list[TYPHOON_MAX_HEADERS];
+	struct dst_entry *dst;
+	int list_size;
+	int i, proto;
+	int level = 0;
+	int last = -1;
+
+	smp_rmb();
+	if(tp->card_state != Running)
+		return;
+
+	list_size = typhoon_bundle_list(bundle, dst_list, TYPHOON_MAX_HEADERS);
+
+	for(i = 0; i < list_size; i++) {
+		dst = dst_list[i];
+		x = dst->xfrm;
+
+		/* Only support IPv4 */
+		if(dst->ops->family != AF_INET)
+			goto cannot_offload;
+
+		proto = x ? x->type->proto : IPPROTO_IP;
+
+		switch(proto) {
+		case IPPROTO_IP:
+		case IPPROTO_IPIP:
+			if(last == IPPROTO_IP || last == IPPROTO_IPIP)
+				goto cannot_offload;
+			if(level)
+				level++;
+			last = proto;
+			continue;
+		case IPPROTO_ESP:
+			if(last != IPPROTO_AH)
+				level++;
+			break;
+		case IPPROTO_AH:
+			level++;
+			break;
+		default:
+			goto cannot_offload;
+		}
+
+		last = proto;
+
+		/* We only support two layers of IPSEC, seperated by
+		 * an IP header. Given AH3 IP3 AH2 IP2 AH1 IP1, only
+		 * offload AH1 and AH2, etc.
+		 */
+		if(level > 2)
+			goto cannot_offload;
+
+		if(dst->xfrm_offload)
+			continue;
+
+		xol = xfrm_offload_get(x, dev);
+		if(!xol) {
+			xol = typhoon_offload_ipsec(tp, x);
+			if(xol)
+				xfrm_offload_hold(xol);
+		}
+
+		if(!xol)
+			goto cannot_offload;
+
+		dst->xfrm_offload = xol;
+		txo = xfrm_offload_priv(xol);
+		if(txo->tunnel)
+			last = IPPROTO_IPIP;
+	}
+
+cannot_offload:
+	return;
 }
 
 static void

  reply	other threads:[~2005-01-10 15:37 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-10 15:36 [RFC BK 0/22] xfrm offload v2: Add hardware assist for IPSEC crypto David Dillow
2005-01-10 15:36 ` [RFC BK 1/22] xfrm offload v2: Add direction information to xfrm_state David Dillow
2005-01-10 15:36   ` [RFC BK 2/22] xfrm offload v2: Add xfrm offload management calls to struct netdevice David Dillow
2005-01-10 15:36     ` [RFC BK 3/22] xfrm offload v2: Add offload management routines David Dillow
2005-01-10 15:36       ` [RFC BK 4/22] xfrm offload v2: Try to offload inbound xfrm_states David Dillow
2005-01-10 15:37         ` [RFC BK 5/22] xfrm offload v2: Attempt to offload bundled xfrm_states for outbound xfrms David Dillow
2005-01-10 15:37           ` [RFC BK 6/22] xfrm offload v2: add a parameter to xfrm_prune_bundles() David Dillow
2005-01-10 15:37             ` [RFC BK 7/22] xfrm offload v2: Allow device drivers to force recalculation of offloads David Dillow
2005-01-10 15:37               ` [RFC BK 8/22] xfrm offload v2: Add routines to manage applied offloads per skb David Dillow
2005-01-10 15:37                 ` [RFC BK 9/22] xfrm offload v2: Split AH header initialization from zeroing of mutable fields David Dillow
2005-01-10 15:37                   ` [RFC BK 10/22] xfrm offload v2: Add offloading of outbound AH & ESP packets David Dillow
2005-01-10 15:37                     ` [RFC BK 11/22] xfrm offload v2: Add offloading of inbound " David Dillow
2005-01-10 15:37                       ` [RFC BK 12/22] xfrm offload v2: Add ethtool support for crypto offload control David Dillow
2005-01-10 15:37                         ` [RFC BK 13/22] xfrm offload v2: typhoon: Make the ipsec descriptor match actual usage David Dillow
2005-01-10 15:37                           ` [RFC BK 14/22] xfrm offload v2: typhoon: add inbound offload result processing David Dillow
2005-01-10 15:37                             ` [RFC BK 15/22] xfrm offload v2: typhoon: add outbound offload processing David Dillow
2005-01-10 15:37                               ` [RFC BK 16/22] xfrm offload v2: typhoon: collect crypto offload capabilities David Dillow
2005-01-10 15:37                                 ` [RFC BK 17/22] xfrm offload v2: typhoon: split out setting of offloaded tasks David Dillow
2005-01-10 15:37                                   ` [RFC BK 18/22] xfrm offload v2: typhoon: add validation of offloaded xfrm_states David Dillow
2005-01-10 15:37                                     ` [RFC BK 19/22] xfrm offload v2: typhoon: add loading of xfrm_states to hardware David Dillow
2005-01-10 15:37                                       ` David Dillow [this message]
2005-01-10 15:37                                         ` [RFC BK 21/22] xfrm offload v2: typhoon: add callbacks to support crypto offload David Dillow
2005-01-10 15:37                                           ` [RFC BK 22/22] xfrm offload v2: Add some documentation for the IPSEC " David Dillow
2005-01-17 19:00 ` [RFC BK 0/22] xfrm offload v2: Add hardware assist for IPSEC crypto James Morris
2005-01-20 17:22   ` Dave Dillow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040110014300.29@ori.thedillows.org \
    --to=dave@thedillows.org \
    --cc=netdev@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).