Skip to contentSkip to conversation

STATE: Search by address using source address list.

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

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

PATCH 6/23 STATE: Search by address using source address list.

This is a support to search transformation states by its addresses by using source address list.
For Mobile IPv6 usage.
Based on MIPL2 kernel patch.

---
 include/net/xfrm.h     |   11 +++++++++++
 net/ipv4/xfrm4_state.c |   13 +++++++++++++
 net/ipv6/xfrm6_state.c |   25 ++++++++++++++++++++++++
 net/xfrm/xfrm_state.c  |   49 +++++++++++++++++++++++++++++++++++++++++++-----
 net/xfrm/xfrm_user.c   |   13 +++++++++++--
 5 files changed, 104 insertions(+), 7 deletions(-)
include/net/xfrm.h +11 -0
index 75649da..aaef1c4 100644
@@ -247,6 +247,9 @@ #endif
 						struct xfrm_tmpl *tmpl,
 						xfrm_address_t *daddr, xfrm_address_t *saddr);
 	struct xfrm_state	*(*state_lookup)(xfrm_address_t *daddr, u32 spi, u8 proto);
+#ifdef CONFIG_XFRM_ADVANCED
+	struct xfrm_state	*(*state_lookup_byaddr)(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto);
+#endif
 	struct xfrm_state	*(*find_acq)(u8 mode, u32 reqid, u8 proto, 
 					     xfrm_address_t *daddr, xfrm_address_t *saddr, 
 					     int create);
@@ -930,6 +933,14 @@ extern void xfrm_state_insert(struct xfr
 extern int xfrm_state_add(struct xfrm_state *x);
 extern int xfrm_state_update(struct xfrm_state *x);
 extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family);
+#ifdef CONFIG_XFRM_ADVANCED
+extern struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family);
+#else
+static inline struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
+{
+	return NULL;
+}
+#endif
 extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
 extern int xfrm_state_delete(struct xfrm_state *x);
 extern void xfrm_state_flush(u8 proto);
net/ipv4/xfrm4_state.c +13 -0
index 6de2ce0..8b44a75 100644
@@ -80,6 +80,16 @@ __xfrm4_state_lookup(xfrm_address_t *dad
 	return NULL;
 }
 
+#ifdef CONFIG_XFRM_ADVANCED
+/* placeholder until ipv4's code is written */
+static struct xfrm_state *
+__xfrm4_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr,
+			    u8 proto)
+{
+	return NULL;
+}
+#endif
+
 static struct xfrm_state *
 __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto, 
 		 xfrm_address_t *daddr, xfrm_address_t *saddr, 
@@ -140,6 +150,9 @@ static struct xfrm_state_afinfo xfrm4_st
 	.init_flags		= xfrm4_init_flags,
 	.init_tempsel		= __xfrm4_init_tempsel,
 	.state_lookup		= __xfrm4_state_lookup,
+#ifdef CONFIG_XFRM_ADVANCED
+	.state_lookup_byaddr	= __xfrm4_state_lookup_byaddr,
+#endif
 	.find_acq		= __xfrm4_find_acq,
 };
 
net/ipv6/xfrm6_state.c +25 -0
index 00b6c17..d141030 100644
@@ -63,6 +63,28 @@ __xfrm6_init_tempsel(struct xfrm_state *
 	x->props.family = AF_INET6;
 }
 
+#ifdef CONFIG_XFRM_ADVANCED
+static struct xfrm_state *
+__xfrm6_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr,
+			    u8 proto)
+{
+	struct xfrm_state *x = NULL;
+	unsigned h;
+
+	h = __xfrm6_src_hash(saddr);
+	list_for_each_entry(x, xfrm6_state_afinfo.state_bysrc+h, bysrc) {
+		if (x->props.family == AF_INET6 &&
+		    ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)x->id.daddr.a6) &&
+		    ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)x->props.saddr.a6) &&
+		    proto == x->id.proto) {
+			xfrm_state_hold(x);
+			return x;
+		}
+	}
+	return NULL;
+}
+#endif
+
 static struct xfrm_state *
 __xfrm6_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto)
 {
@@ -143,6 +165,9 @@ static struct xfrm_state_afinfo xfrm6_st
 	.lock			= RW_LOCK_UNLOCKED,
 	.init_tempsel		= __xfrm6_init_tempsel,
 	.state_lookup		= __xfrm6_state_lookup,
+#ifdef CONFIG_XFRM_ADVANCED
+	.state_lookup_byaddr	= __xfrm6_state_lookup_byaddr,
+#endif
 	.find_acq		= __xfrm6_find_acq,
 };
 
net/xfrm/xfrm_state.c +44 -5

92 lines not on this page · raw message

net/xfrm/xfrm_user.c +11 -2
index f92d163..85051a2 100644
@@ -416,6 +416,15 @@ out:
 	return err;
 }
 
+static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p)
+{
+	if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY))
+		return xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family);
+	else
+		return xfrm_state_lookup_byaddr(&p->daddr, &p->saddr, p->proto,
+						p->family);
+}
+
 static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
 {
 	struct xfrm_state *x;
@@ -423,7 +432,7 @@ static int xfrm_del_sa(struct sk_buff *s
 	struct km_event c;
 	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
 
-	x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family);
+	x = xfrm_user_state_lookup(p);
 	if (x == NULL)
 		return -ESRCH;
 
@@ -576,7 +585,7 @@ static int xfrm_get_sa(struct sk_buff *s
 	struct sk_buff *resp_skb;
 	int err;
 
-	x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family);
+	x = xfrm_user_state_lookup(p);
 	err = -ESRCH;
 	if (x == NULL)
 		goto out_noput;
Signature · 1 line
1.4.1
maintainer
#1 lore raw

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

include/net/xfrm.h #endif · line 252

Quoted 3 lines
include/net/xfrm.h +3 -0
+#ifdef CONFIG_XFRM_ADVANCED
+	struct xfrm_state	*(*state_lookup_byaddr)(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto);
+#endif

I think we should delete XFRM_ADVANCED config option, it is only serving to make the code very ugly and full of ifdefs.

net/xfrm/xfrm_state.c int xfrm_state_add(struct xfrm_state *x) · line 508

Quoted 5 lines
net/xfrm/xfrm_state.c +5 -0
+#ifdef CONFIG_XFRM_ADVANCED
+	int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
+#else
+	int use_spi = 1;
+#endif

Why this transformation? In fact, you added several others. xfrm_id_proto_match() with userproto argument IPSEC_PROTO_ANY always evaluates to one.

If you intend to change the userproto argument in some future changeset, then add the xfrm_id_proto_match() call in that changeset.

#2 lore raw
Quoted 9 lines · David Miller

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

include/net/xfrm.h #endif · line 252

Quoted 3 lines
include/net/xfrm.h +3 -0
+#ifdef CONFIG_XFRM_ADVANCED
+	struct xfrm_state	*(*state_lookup_byaddr)(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto);
+#endif

I think we should delete XFRM_ADVANCED config option, it is only serving to make the code very ugly and full of ifdefs.

I see, I remove it.

My thought was to keep XFRM code intact as possible for users who wants only IPsec. But don't worry, it should not be changed existing logic of course then I've made regression test for IPsec behavior with both case: new config is off and on. Then I guess I can remove the config easily.

Quoted 10 lines

net/xfrm/xfrm_state.c int xfrm_state_add(struct xfrm_state *x) · line 508

Quoted 5 lines
net/xfrm/xfrm_state.c +5 -0
+#ifdef CONFIG_XFRM_ADVANCED
+	int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
+#else
+	int use_spi = 1;
+#endif

Why this transformation? In fact, you added several others. xfrm_id_proto_match() with userproto argument IPSEC_PROTO_ANY always evaluates to one.

Quoted 3 lines

If you intend to change the userproto argument in some future changeset, then add the xfrm_id_proto_match() call in that changeset.

You already find out by another mail, but I should have to change patch order to get it easily for others or write more particular commit log.

Thanks,

Signature · 1 line
Masahide NAKAMURA