Index: libiptc/libiptc.c
===================================================================
--- libiptc/libiptc.c	(revision 7090)
+++ libiptc/libiptc.c	(working copy)
@@ -307,16 +307,26 @@
 static struct chain_head *
 iptcc_find_chain_by_offset(TC_HANDLE_T handle, unsigned int offset)
 {
-	struct list_head *pos;
-
 	if (list_empty(&handle->chains))
 		return NULL;
 
-	list_for_each(pos, &handle->chains) {
-		struct chain_head *c = list_entry(pos, struct chain_head, list);
-		if (offset >= c->head_offset && offset <= c->foot_offset)
+	/* Find the entry pointed to by offset */
+	STRUCT_ENTRY * e = iptcb_offset2entry(handle, offset);
+
+	/* When parsing the blob (in cache_add_entry), the entry
+	   field comefrom has been modified to contain a pointer
+	   to the chain it belongs to.
+	*/
+	struct chain_head *c = (struct chain_head *)e->comefrom;
+
+	if (c) {
+		/* Extra verifying step*/
+		if (offset >= c->head_offset && offset <= c->foot_offset) {
 			return c;
-	}
+		} else
+			fprintf(stderr, "ERROR: fast chain mapping is NOT working\n");
+	} else
+		fprintf(stderr, "ERROR: fast chain mapping returns NULL\n");
 
 	return NULL;
 }
@@ -494,6 +504,14 @@
 		r->index = *num;
 		r->offset = offset;
 		memcpy(r->entry, e, e->next_offset);
+
+		/*
+		  Modify the blob entry to contain a pointer to the
+		  chain it belongs to.  Needed later to resolve jump
+		  targets faster (used in iptcc_find_chain_by_offset)
+		*/
+		e->comefrom = (unsigned int)h->chain_iterator_cur;
+
 		r->counter_map.maptype = COUNTER_MAP_NORMAL_MAP;
 		r->counter_map.mappos = r->index;
 
