diff options
author | Masahide NAKAMURA <nakam@linux-ipv6.org> | 2006-08-24 01:43:30 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:08:34 -0400 |
commit | 4e81bb8336a0ac50289d4d4c7a55e559b994ee8f (patch) | |
tree | fefa71843c3f8152dd0a008b3b40fe2e42d204d7 /include | |
parent | c11f1a15c522ddd3bbd2c32b5ce3e0b1831b22f2 (diff) |
[XFRM] POLICY: sub policy support.
Sub policy is introduced. Main and sub policy are applied the same flow.
(Policy that current kernel uses is named as main.)
It is required another transformation policy management to keep IPsec
and Mobile IPv6 lives separate.
Policy which lives shorter time in kernel should be a sub i.e. normally
main is for IPsec and sub is for Mobile IPv6.
(Such usage as two IPsec policies on different database can be used, too.)
Limitation or TODOs:
- Sub policy is not supported for per socket one (it is always inserted as main).
- Current kernel makes cached outbound with flowi to skip searching database.
However this patch makes it disabled only when "two policies are used and
the first matched one is bypass case" because neither flowi nor bundle
information knows about transformation template size.
Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/xfrm.h | 7 | ||||
-rw-r--r-- | include/net/xfrm.h | 45 |
2 files changed, 44 insertions, 8 deletions
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 4009f4445fa9..492fb9818747 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h | |||
@@ -104,6 +104,13 @@ struct xfrm_stats { | |||
104 | 104 | ||
105 | enum | 105 | enum |
106 | { | 106 | { |
107 | XFRM_POLICY_TYPE_MAIN = 0, | ||
108 | XFRM_POLICY_TYPE_SUB = 1, | ||
109 | XFRM_POLICY_TYPE_MAX = 2 | ||
110 | }; | ||
111 | |||
112 | enum | ||
113 | { | ||
107 | XFRM_POLICY_IN = 0, | 114 | XFRM_POLICY_IN = 0, |
108 | XFRM_POLICY_OUT = 1, | 115 | XFRM_POLICY_OUT = 1, |
109 | XFRM_POLICY_FWD = 2, | 116 | XFRM_POLICY_FWD = 2, |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 0b223eed4c9b..4655ca25f808 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -341,6 +341,7 @@ struct xfrm_policy | |||
341 | atomic_t refcnt; | 341 | atomic_t refcnt; |
342 | struct timer_list timer; | 342 | struct timer_list timer; |
343 | 343 | ||
344 | u8 type; | ||
344 | u32 priority; | 345 | u32 priority; |
345 | u32 index; | 346 | u32 index; |
346 | struct xfrm_selector selector; | 347 | struct xfrm_selector selector; |
@@ -389,6 +390,19 @@ extern int xfrm_unregister_km(struct xfrm_mgr *km); | |||
389 | 390 | ||
390 | 391 | ||
391 | extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2]; | 392 | extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2]; |
393 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
394 | extern struct xfrm_policy *xfrm_policy_list_sub[XFRM_POLICY_MAX*2]; | ||
395 | |||
396 | static inline int xfrm_policy_lists_empty(int dir) | ||
397 | { | ||
398 | return (!xfrm_policy_list[dir] && !xfrm_policy_list_sub[dir]); | ||
399 | } | ||
400 | #else | ||
401 | static inline int xfrm_policy_lists_empty(int dir) | ||
402 | { | ||
403 | return (!xfrm_policy_list[dir]); | ||
404 | } | ||
405 | #endif | ||
392 | 406 | ||
393 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) | 407 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) |
394 | { | 408 | { |
@@ -404,6 +418,20 @@ static inline void xfrm_pol_put(struct xfrm_policy *policy) | |||
404 | __xfrm_policy_destroy(policy); | 418 | __xfrm_policy_destroy(policy); |
405 | } | 419 | } |
406 | 420 | ||
421 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
422 | static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) | ||
423 | { | ||
424 | int i; | ||
425 | for (i = npols - 1; i >= 0; --i) | ||
426 | xfrm_pol_put(pols[i]); | ||
427 | } | ||
428 | #else | ||
429 | static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) | ||
430 | { | ||
431 | xfrm_pol_put(pols[0]); | ||
432 | } | ||
433 | #endif | ||
434 | |||
407 | #define XFRM_DST_HSIZE 1024 | 435 | #define XFRM_DST_HSIZE 1024 |
408 | 436 | ||
409 | static __inline__ | 437 | static __inline__ |
@@ -737,8 +765,8 @@ static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *sk | |||
737 | { | 765 | { |
738 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) | 766 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) |
739 | return __xfrm_policy_check(sk, dir, skb, family); | 767 | return __xfrm_policy_check(sk, dir, skb, family); |
740 | 768 | ||
741 | return (!xfrm_policy_list[dir] && !skb->sp) || | 769 | return (xfrm_policy_lists_empty(dir) && !skb->sp) || |
742 | (skb->dst->flags & DST_NOPOLICY) || | 770 | (skb->dst->flags & DST_NOPOLICY) || |
743 | __xfrm_policy_check(sk, dir, skb, family); | 771 | __xfrm_policy_check(sk, dir, skb, family); |
744 | } | 772 | } |
@@ -758,7 +786,7 @@ extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family); | |||
758 | 786 | ||
759 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) | 787 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) |
760 | { | 788 | { |
761 | return !xfrm_policy_list[XFRM_POLICY_OUT] || | 789 | return xfrm_policy_lists_empty(XFRM_POLICY_OUT) || |
762 | (skb->dst->flags & DST_NOXFRM) || | 790 | (skb->dst->flags & DST_NOXFRM) || |
763 | __xfrm_route_forward(skb, family); | 791 | __xfrm_route_forward(skb, family); |
764 | } | 792 | } |
@@ -1023,18 +1051,19 @@ static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsig | |||
1023 | #endif | 1051 | #endif |
1024 | 1052 | ||
1025 | struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); | 1053 | struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); |
1026 | extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); | 1054 | extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *); |
1027 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); | 1055 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); |
1028 | struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel, | 1056 | struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, |
1057 | struct xfrm_selector *sel, | ||
1029 | struct xfrm_sec_ctx *ctx, int delete); | 1058 | struct xfrm_sec_ctx *ctx, int delete); |
1030 | struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); | 1059 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete); |
1031 | void xfrm_policy_flush(void); | 1060 | void xfrm_policy_flush(u8 type); |
1032 | u32 xfrm_get_acqseq(void); | 1061 | u32 xfrm_get_acqseq(void); |
1033 | void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); | 1062 | void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); |
1034 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | 1063 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, |
1035 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 1064 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
1036 | int create, unsigned short family); | 1065 | int create, unsigned short family); |
1037 | extern void xfrm_policy_flush(void); | 1066 | extern void xfrm_policy_flush(u8 type); |
1038 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 1067 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
1039 | extern int xfrm_flush_bundles(void); | 1068 | extern int xfrm_flush_bundles(void); |
1040 | extern void xfrm_flush_all_bundles(void); | 1069 | extern void xfrm_flush_all_bundles(void); |