netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 5/23] [PATCH] [XFRM] STATE: Add source address list.
@ 2006-07-29  9:30 Masahide NAKAMURA
  2006-08-01 23:57 ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Masahide NAKAMURA @ 2006-07-29  9:30 UTC (permalink / raw)
  To: davem; +Cc: yoshfuji, anttit, vnuorval, netdev, usagi-core, Masahide NAKAMURA

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(-)

diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 7dff1c8..55d1ce4 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -263,6 +263,7 @@ struct xfrm_usersa_id {
 	__u32				spi;
 	__u16				family;
 	__u8				proto;
+	xfrm_address_t			saddr;
 };
 
 struct xfrm_aevent_id {
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index ca537b5..75649da 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -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)
 {
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 171cdc5..6de2ce0 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -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)
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 71c40bb..00b6c17 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -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)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 6cf080f..1942bb1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -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);
-- 
1.4.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 5/23] [PATCH] [XFRM] STATE: Add source address list.
  2006-07-29  9:30 [PATCH 5/23] [PATCH] [XFRM] STATE: Add source address list Masahide NAKAMURA
@ 2006-08-01 23:57 ` David Miller
  2006-08-02  1:42   ` Masahide NAKAMURA
  0 siblings, 1 reply; 4+ messages in thread
From: David Miller @ 2006-08-01 23:57 UTC (permalink / raw)
  To: nakam; +Cc: yoshfuji, anttit, vnuorval, netdev, usagi-core

From: Masahide NAKAMURA <nakam@linux-ipv6.org>
Date: Sat, 29 Jul 2006 18:30:12 +0900

> @@ -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).

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 5/23] [PATCH] [XFRM] STATE: Add source address list.
  2006-08-01 23:57 ` David Miller
@ 2006-08-02  1:42   ` Masahide NAKAMURA
  2006-08-02  2:03     ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Masahide NAKAMURA @ 2006-08-02  1:42 UTC (permalink / raw)
  To: David Miller; +Cc: yoshfuji, anttit, vnuorval, netdev, usagi-core

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

OK.

> 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.

-- 
Masahide NAKAMURA

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 5/23] [PATCH] [XFRM] STATE: Add source address list.
  2006-08-02  1:42   ` Masahide NAKAMURA
@ 2006-08-02  2:03     ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2006-08-02  2:03 UTC (permalink / raw)
  To: nakam; +Cc: yoshfuji, anttit, vnuorval, netdev, usagi-core

From: Masahide NAKAMURA <nakam@linux-ipv6.org>
Date: Wed, 02 Aug 2006 10:42:51 +0900

> David Miller wrote:
> > 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.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-08-02  2:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-29  9:30 [PATCH 5/23] [PATCH] [XFRM] STATE: Add source address list Masahide NAKAMURA
2006-08-01 23:57 ` David Miller
2006-08-02  1:42   ` Masahide NAKAMURA
2006-08-02  2:03     ` David Miller

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).