Skip to contentSkip to conversation

STATE: Add source address list.

PATCH In review Masahide NAKAMURA 2 participants 4 messages Jul 29, 2006 – Aug 2, 2006

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 5/23 STATE: Add source address list.

Support source address based searching.
Mobile IPv6 will use it.
Based on MIPL2 kernel patch.

---
 include/linux/xfrm.h   |    1 +
 include/net/xfrm.h     |   32 ++++++++++++++++++++++++++++++++
 net/ipv4/xfrm4_state.c |    5 +++++
 net/ipv6/xfrm6_state.c |    5 +++++
 net/xfrm/xfrm_state.c  |   38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 81 insertions(+), 0 deletions(-)
include/linux/xfrm.h +1 -0
index 7dff1c8..55d1ce4 100644
@@ -263,6 +263,7 @@ struct xfrm_usersa_id {
 	__u32				spi;
 	__u16				family;
 	__u8				proto;
+	xfrm_address_t			saddr;
 };
 
 struct xfrm_aevent_id {
include/net/xfrm.h +32 -0
index ca537b5..75649da 100644
@@ -94,6 +94,9 @@ struct xfrm_state
 {
 	/* Note: bydst is re-used during gc */
 	struct list_head	bydst;
+#ifdef CONFIG_XFRM_ADVANCED
+	struct list_head	bysrc;
+#endif
 	struct list_head	byspi;
 
 	atomic_t		refcnt;
@@ -235,6 +238,9 @@ struct xfrm_state_afinfo {
 	unsigned short		family;
 	rwlock_t		lock;
 	struct list_head	*state_bydst;
+#ifdef CONFIG_XFRM_ADVANCED
+	struct list_head	*state_bysrc;
+#endif
 	struct list_head	*state_byspi;
 	int			(*init_flags)(struct xfrm_state *x);
 	void			(*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
@@ -411,6 +417,32 @@ unsigned xfrm_dst_hash(xfrm_address_t *a
 	return 0;
 }
 
+#ifdef CONFIG_XFRM_ADVANCED
+static __inline__
+unsigned __xfrm4_src_hash(xfrm_address_t *addr)
+{
+	return __xfrm4_dst_hash(addr);
+}
+
+static __inline__
+unsigned __xfrm6_src_hash(xfrm_address_t *addr)
+{
+	return __xfrm6_dst_hash(addr);
+}
+
+static __inline__
+unsigned xfrm_src_hash(xfrm_address_t *addr, unsigned short family)
+{
+	switch (family) {
+	case AF_INET:
+		return __xfrm4_src_hash(addr);
+	case AF_INET6:
+		return __xfrm6_src_hash(addr);
+	}
+	return 0;
+}
+#endif
+
 static __inline__
 unsigned __xfrm4_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto)
 {
net/ipv4/xfrm4_state.c +5 -0
index 171cdc5..6de2ce0 100644
@@ -122,6 +122,11 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 
 		add_timer(&x0->timer);
 		xfrm_state_hold(x0);
 		list_add_tail(&x0->bydst, xfrm4_state_afinfo.state_bydst+h);
+#ifdef CONFIG_XFRM_ADVANCED
+		h = __xfrm4_src_hash(saddr);
+		xfrm_state_hold(x0);
+		list_add_tail(&x0->bysrc, xfrm4_state_afinfo.state_bysrc+h);
+#endif
 		wake_up(&km_waitq);
 	}
 	if (x0)
net/ipv6/xfrm6_state.c +5 -0
index 71c40bb..00b6c17 100644
@@ -126,6 +126,11 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 
 		add_timer(&x0->timer);
 		xfrm_state_hold(x0);
 		list_add_tail(&x0->bydst, xfrm6_state_afinfo.state_bydst+h);
+#ifdef CONFIG_XFRM_ADVANCED
+		h = __xfrm6_src_hash(saddr);
+		xfrm_state_hold(x0);
+		list_add_tail(&x0->bysrc, xfrm6_state_afinfo.state_bysrc+h);
+#endif
 		wake_up(&km_waitq);
 	}
 	if (x0)
net/xfrm/xfrm_state.c +38 -0
index 6cf080f..1942bb1 100644
@@ -45,6 +45,9 @@ static DEFINE_SPINLOCK(xfrm_state_lock);
  * Also, it can be used by ah/esp icmp error handler to find offending SA.
  */
 static struct list_head xfrm_state_bydst[XFRM_DST_HSIZE];
+#ifdef CONFIG_XFRM_ADVANCED
+static struct list_head xfrm_state_bysrc[XFRM_DST_HSIZE];
+#endif
 static struct list_head xfrm_state_byspi[XFRM_DST_HSIZE];
 
 DECLARE_WAIT_QUEUE_HEAD(km_waitq);
@@ -199,6 +202,9 @@ struct xfrm_state *xfrm_state_alloc(void
 		atomic_set(&x->refcnt, 1);
 		atomic_set(&x->tunnel_users, 0);
 		INIT_LIST_HEAD(&x->bydst);
+#ifdef CONFIG_XFRM_ADVANCED
+		INIT_LIST_HEAD(&x->bysrc);
+#endif
 		INIT_LIST_HEAD(&x->byspi);
 		init_timer(&x->timer);
 		x->timer.function = xfrm_timer_handler;
@@ -239,6 +245,10 @@ int __xfrm_state_delete(struct xfrm_stat
 		spin_lock(&xfrm_state_lock);
 		list_del(&x->bydst);
 		__xfrm_state_put(x);
+#ifdef CONFIG_XFRM_ADVANCED
+		list_del(&x->bysrc);
+		__xfrm_state_put(x);
+#endif
 		if (x->id.spi) {
 			list_del(&x->byspi);
 			__xfrm_state_put(x);
@@ -406,6 +416,10 @@ xfrm_state_find(xfrm_address_t *daddr, x
 			x->km.state = XFRM_STATE_ACQ;
 			list_add_tail(&x->bydst, xfrm_state_bydst+h);
 			xfrm_state_hold(x);
+#ifdef CONFIG_XFRM_ADVANCED
+			list_add_tail(&x->bysrc, xfrm_state_bysrc+h);
+			xfrm_state_hold(x);
+#endif
 			if (x->id.spi) {
 				h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
 				list_add(&x->byspi, xfrm_state_byspi+h);
@@ -439,10 +453,25 @@ static void __xfrm_state_insert(struct x
 	list_add(&x->bydst, xfrm_state_bydst+h);
 	xfrm_state_hold(x);
 
+#ifdef CONFIG_XFRM_ADVANCED
+	h = xfrm_src_hash(&x->props.saddr, x->props.family);
+
+	list_add(&x->bysrc, xfrm_state_bysrc+h);
+	xfrm_state_hold(x);
+
+	if (xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY)) {
+		h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto,
+				  x->props.family);
+
+		list_add(&x->byspi, xfrm_state_byspi+h);
+		xfrm_state_hold(x);
+	}
+#else
 	h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, x->props.family);
 
 	list_add(&x->byspi, xfrm_state_byspi+h);
 	xfrm_state_hold(x);
+#endif
 
 	if (!mod_timer(&x->timer, jiffies + HZ))
 		xfrm_state_hold(x);
@@ -1066,6 +1095,9 @@ int xfrm_state_register_afinfo(struct xf
 		err = -ENOBUFS;
 	else {
 		afinfo->state_bydst = xfrm_state_bydst;
+#ifdef CONFIG_XFRM_ADVANCED
+		afinfo->state_bysrc = xfrm_state_bysrc;
+#endif
 		afinfo->state_byspi = xfrm_state_byspi;
 		xfrm_state_afinfo[afinfo->family] = afinfo;
 	}
@@ -1088,6 +1120,9 @@ int xfrm_state_unregister_afinfo(struct 
 		else {
 			xfrm_state_afinfo[afinfo->family] = NULL;
 			afinfo->state_byspi = NULL;
+#ifdef CONFIG_XFRM_ADVANCED
+			afinfo->state_bysrc = NULL;
+#endif
 			afinfo->state_bydst = NULL;
 		}
 	}
@@ -1210,6 +1245,9 @@ void __init xfrm_state_init(void)
 
 	for (i=0; i<XFRM_DST_HSIZE; i++) {
 		INIT_LIST_HEAD(&xfrm_state_bydst[i]);
+#ifdef CONFIG_XFRM_ADVANCED
+		INIT_LIST_HEAD(&xfrm_state_bysrc[i]);
+#endif
 		INIT_LIST_HEAD(&xfrm_state_byspi[i]);
 	}
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task, NULL);
Signature · 1 line
1.4.1
maintainer
#1 lore raw

From: Masahide NAKAMURA <[email protected]>
Date: Sat, 29 Jul 2006 18:30:12 +0900

include/linux/xfrm.h struct xfrm_usersa_id { · line 269

Quoted 8 lines
include/linux/xfrm.h +1 -0
@@ -263,6 +263,7 @@ struct xfrm_usersa_id {
 	__u32				spi;
 	__u16				family;
 	__u8				proto;
+	xfrm_address_t			saddr;
 };
 
 struct xfrm_aevent_id {

This is a userspace exported structure, therefore you cannot make changes to it like this, it will break the userland API.

If you need to provide the source address, you need to pass it in via a new xfrm netlink attribute or use an existing data structure member which records the source address (if any such thing does exist).

#2 lore raw
Quoted 2 lines · David Miller

This is a userspace exported structure, therefore you cannot make changes to it like this, it will break the userland API.

OK.

Quoted 3 lines

If you need to provide the source address, you need to pass it in via a new xfrm netlink attribute or use an existing data structure member which records the source address (if any such thing does exist).

There is no xfrm netlink attribute to carry source address. I'll add it like XFRMA_SRCADDR.

BTW another patch newly defined XFRMA_ADDR to carry care-of address. This would be changed e.g. XFRMA_COADDR or something, too.

Signature · 1 line
Masahide NAKAMURA
maintainer
#3 lore raw

From: Masahide NAKAMURA <[email protected]>
Date: Wed, 02 Aug 2006 10:42:51 +0900

Quoted 10 lines
Quoted 3 lines · David Miller

If you need to provide the source address, you need to pass it in via a new xfrm netlink attribute or use an existing data structure member which records the source address (if any such thing does exist).

There is no xfrm netlink attribute to carry source address. I'll add it like XFRMA_SRCADDR.

BTW another patch newly defined XFRMA_ADDR to carry care-of address. This would be changed e.g. XFRMA_COADDR or something, too.

This sounds fine, thank you.