STATE: Add source address list.
Subsystems (3)
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
@@ -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
@@ -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 *areturn 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
@@ -122,6 +122,11 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8add_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
@@ -126,6 +126,11 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8add_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
@@ -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(voidatomic_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_statspin_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 xlist_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(structelse { 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
David Miller
maintainerFrom: 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).
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
David Miller
maintainerFrom: 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_ADDRto carry care-of address. This would be changed e.g.XFRMA_COADDRor something, too.
This sounds fine, thank you.