aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasahide NAKAMURA <nakam@linux-ipv6.org>2006-08-24 01:43:30 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:08:34 -0400
commit4e81bb8336a0ac50289d4d4c7a55e559b994ee8f (patch)
treefefa71843c3f8152dd0a008b3b40fe2e42d204d7
parentc11f1a15c522ddd3bbd2c32b5ce3e0b1831b22f2 (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>
-rw-r--r--include/linux/xfrm.h7
-rw-r--r--include/net/xfrm.h45
-rw-r--r--net/xfrm/xfrm_policy.c252
3 files changed, 260 insertions, 44 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
105enum 105enum
106{ 106{
107 XFRM_POLICY_TYPE_MAIN = 0,
108 XFRM_POLICY_TYPE_SUB = 1,
109 XFRM_POLICY_TYPE_MAX = 2
110};
111
112enum
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
391extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2]; 392extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
393#ifdef CONFIG_XFRM_SUB_POLICY
394extern struct xfrm_policy *xfrm_policy_list_sub[XFRM_POLICY_MAX*2];
395
396static inline int xfrm_policy_lists_empty(int dir)
397{
398 return (!xfrm_policy_list[dir] && !xfrm_policy_list_sub[dir]);
399}
400#else
401static inline int xfrm_policy_lists_empty(int dir)
402{
403 return (!xfrm_policy_list[dir]);
404}
405#endif
392 406
393static inline void xfrm_pol_hold(struct xfrm_policy *policy) 407static 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
422static 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
429static 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
409static __inline__ 437static __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
759static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) 787static 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
1025struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); 1053struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
1026extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); 1054extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *);
1027int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); 1055int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
1028struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel, 1056struct 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);
1030struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); 1059struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete);
1031void xfrm_policy_flush(void); 1060void xfrm_policy_flush(u8 type);
1032u32 xfrm_get_acqseq(void); 1061u32 xfrm_get_acqseq(void);
1033void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); 1062void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
1034struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, 1063struct 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);
1037extern void xfrm_policy_flush(void); 1066extern void xfrm_policy_flush(u8 type);
1038extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); 1067extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
1039extern int xfrm_flush_bundles(void); 1068extern int xfrm_flush_bundles(void);
1040extern void xfrm_flush_all_bundles(void); 1069extern void xfrm_flush_all_bundles(void);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d125a2649037..96de6c76ed57 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -32,6 +32,24 @@ static DEFINE_RWLOCK(xfrm_policy_lock);
32 32
33struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2]; 33struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
34EXPORT_SYMBOL(xfrm_policy_list); 34EXPORT_SYMBOL(xfrm_policy_list);
35#ifdef CONFIG_XFRM_SUB_POLICY
36struct xfrm_policy *xfrm_policy_list_sub[XFRM_POLICY_MAX*2];
37EXPORT_SYMBOL(xfrm_policy_list_sub);
38
39#define XFRM_POLICY_LISTS(type) \
40 ((type == XFRM_POLICY_TYPE_SUB) ? xfrm_policy_list_sub : \
41 xfrm_policy_list)
42#define XFRM_POLICY_LISTHEAD(type, dir) \
43 ((type == XFRM_POLICY_TYPE_SUB) ? xfrm_policy_list_sub[dir] : \
44 xfrm_policy_list[dir])
45#define XFRM_POLICY_LISTHEADP(type, dir) \
46 ((type == XFRM_POLICY_TYPE_SUB) ? &xfrm_policy_list_sub[dir] : \
47 &xfrm_policy_list[dir])
48#else
49#define XFRM_POLICY_LISTS(type) xfrm_policy_list
50#define XFRM_POLICY_LISTHEAD(type, dif) xfrm_policy_list[dir]
51#define XFRM_POLICY_LISTHEADP(type, dif) &xfrm_policy_list[dir]
52#endif
35 53
36static DEFINE_RWLOCK(xfrm_policy_afinfo_lock); 54static DEFINE_RWLOCK(xfrm_policy_afinfo_lock);
37static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO]; 55static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO];
@@ -397,7 +415,7 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
397 415
398/* Generate new index... KAME seems to generate them ordered by cost 416/* Generate new index... KAME seems to generate them ordered by cost
399 * of an absolute inpredictability of ordering of rules. This will not pass. */ 417 * of an absolute inpredictability of ordering of rules. This will not pass. */
400static u32 xfrm_gen_index(int dir) 418static u32 xfrm_gen_index(u8 type, int dir)
401{ 419{
402 u32 idx; 420 u32 idx;
403 struct xfrm_policy *p; 421 struct xfrm_policy *p;
@@ -408,7 +426,7 @@ static u32 xfrm_gen_index(int dir)
408 idx_generator += 8; 426 idx_generator += 8;
409 if (idx == 0) 427 if (idx == 0)
410 idx = 8; 428 idx = 8;
411 for (p = xfrm_policy_list[dir]; p; p = p->next) { 429 for (p = XFRM_POLICY_LISTHEAD(type, dir); p; p = p->next) {
412 if (p->index == idx) 430 if (p->index == idx)
413 break; 431 break;
414 } 432 }
@@ -425,7 +443,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
425 struct dst_entry *gc_list; 443 struct dst_entry *gc_list;
426 444
427 write_lock_bh(&xfrm_policy_lock); 445 write_lock_bh(&xfrm_policy_lock);
428 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { 446 for (p = XFRM_POLICY_LISTHEADP(policy->type, dir); (pol=*p)!=NULL;) {
429 if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0 && 447 if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0 &&
430 xfrm_sec_ctx_match(pol->security, policy->security)) { 448 xfrm_sec_ctx_match(pol->security, policy->security)) {
431 if (excl) { 449 if (excl) {
@@ -452,7 +470,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
452 policy->next = *p; 470 policy->next = *p;
453 *p = policy; 471 *p = policy;
454 atomic_inc(&flow_cache_genid); 472 atomic_inc(&flow_cache_genid);
455 policy->index = delpol ? delpol->index : xfrm_gen_index(dir); 473 policy->index = delpol ? delpol->index : xfrm_gen_index(policy->type, dir);
456 policy->curlft.add_time = (unsigned long)xtime.tv_sec; 474 policy->curlft.add_time = (unsigned long)xtime.tv_sec;
457 policy->curlft.use_time = 0; 475 policy->curlft.use_time = 0;
458 if (!mod_timer(&policy->timer, jiffies + HZ)) 476 if (!mod_timer(&policy->timer, jiffies + HZ))
@@ -493,13 +511,14 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
493} 511}
494EXPORT_SYMBOL(xfrm_policy_insert); 512EXPORT_SYMBOL(xfrm_policy_insert);
495 513
496struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel, 514struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
515 struct xfrm_selector *sel,
497 struct xfrm_sec_ctx *ctx, int delete) 516 struct xfrm_sec_ctx *ctx, int delete)
498{ 517{
499 struct xfrm_policy *pol, **p; 518 struct xfrm_policy *pol, **p;
500 519
501 write_lock_bh(&xfrm_policy_lock); 520 write_lock_bh(&xfrm_policy_lock);
502 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) { 521 for (p = XFRM_POLICY_LISTHEADP(type, dir); (pol=*p)!=NULL; p = &pol->next) {
503 if ((memcmp(sel, &pol->selector, sizeof(*sel)) == 0) && 522 if ((memcmp(sel, &pol->selector, sizeof(*sel)) == 0) &&
504 (xfrm_sec_ctx_match(ctx, pol->security))) { 523 (xfrm_sec_ctx_match(ctx, pol->security))) {
505 xfrm_pol_hold(pol); 524 xfrm_pol_hold(pol);
@@ -518,12 +537,12 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
518} 537}
519EXPORT_SYMBOL(xfrm_policy_bysel_ctx); 538EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
520 539
521struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete) 540struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete)
522{ 541{
523 struct xfrm_policy *pol, **p; 542 struct xfrm_policy *pol, **p;
524 543
525 write_lock_bh(&xfrm_policy_lock); 544 write_lock_bh(&xfrm_policy_lock);
526 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) { 545 for (p = XFRM_POLICY_LISTHEADP(type, dir); (pol=*p)!=NULL; p = &pol->next) {
527 if (pol->index == id) { 546 if (pol->index == id) {
528 xfrm_pol_hold(pol); 547 xfrm_pol_hold(pol);
529 if (delete) 548 if (delete)
@@ -541,15 +560,16 @@ struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
541} 560}
542EXPORT_SYMBOL(xfrm_policy_byid); 561EXPORT_SYMBOL(xfrm_policy_byid);
543 562
544void xfrm_policy_flush(void) 563void xfrm_policy_flush(u8 type)
545{ 564{
546 struct xfrm_policy *xp; 565 struct xfrm_policy *xp;
566 struct xfrm_policy **p_list = XFRM_POLICY_LISTS(type);
547 int dir; 567 int dir;
548 568
549 write_lock_bh(&xfrm_policy_lock); 569 write_lock_bh(&xfrm_policy_lock);
550 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { 570 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
551 while ((xp = xfrm_policy_list[dir]) != NULL) { 571 while ((xp = p_list[dir]) != NULL) {
552 xfrm_policy_list[dir] = xp->next; 572 p_list[dir] = xp->next;
553 write_unlock_bh(&xfrm_policy_lock); 573 write_unlock_bh(&xfrm_policy_lock);
554 574
555 xfrm_policy_kill(xp); 575 xfrm_policy_kill(xp);
@@ -562,7 +582,7 @@ void xfrm_policy_flush(void)
562} 582}
563EXPORT_SYMBOL(xfrm_policy_flush); 583EXPORT_SYMBOL(xfrm_policy_flush);
564 584
565int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), 585int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*),
566 void *data) 586 void *data)
567{ 587{
568 struct xfrm_policy *xp; 588 struct xfrm_policy *xp;
@@ -572,7 +592,7 @@ int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*),
572 592
573 read_lock_bh(&xfrm_policy_lock); 593 read_lock_bh(&xfrm_policy_lock);
574 for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { 594 for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) {
575 for (xp = xfrm_policy_list[dir]; xp; xp = xp->next) 595 for (xp = XFRM_POLICY_LISTHEAD(type, dir); xp; xp = xp->next)
576 count++; 596 count++;
577 } 597 }
578 598
@@ -582,7 +602,7 @@ int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*),
582 } 602 }
583 603
584 for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { 604 for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) {
585 for (xp = xfrm_policy_list[dir]; xp; xp = xp->next) { 605 for (xp = XFRM_POLICY_LISTHEAD(type, dir); xp; xp = xp->next) {
586 error = func(xp, dir%XFRM_POLICY_MAX, --count, data); 606 error = func(xp, dir%XFRM_POLICY_MAX, --count, data);
587 if (error) 607 if (error)
588 goto out; 608 goto out;
@@ -597,13 +617,13 @@ EXPORT_SYMBOL(xfrm_policy_walk);
597 617
598/* Find policy to apply to this flow. */ 618/* Find policy to apply to this flow. */
599 619
600static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, 620static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
601 void **objp, atomic_t **obj_refp) 621 u16 family, u8 dir)
602{ 622{
603 struct xfrm_policy *pol; 623 struct xfrm_policy *pol;
604 624
605 read_lock_bh(&xfrm_policy_lock); 625 read_lock_bh(&xfrm_policy_lock);
606 for (pol = xfrm_policy_list[dir]; pol; pol = pol->next) { 626 for (pol = XFRM_POLICY_LISTHEAD(type, dir); pol; pol = pol->next) {
607 struct xfrm_selector *sel = &pol->selector; 627 struct xfrm_selector *sel = &pol->selector;
608 int match; 628 int match;
609 629
@@ -620,6 +640,25 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
620 } 640 }
621 } 641 }
622 read_unlock_bh(&xfrm_policy_lock); 642 read_unlock_bh(&xfrm_policy_lock);
643
644 return pol;
645}
646
647static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
648 void **objp, atomic_t **obj_refp)
649{
650 struct xfrm_policy *pol;
651
652#ifdef CONFIG_XFRM_SUB_POLICY
653 pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir);
654 if (pol)
655 goto end;
656#endif
657 pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir);
658
659#ifdef CONFIG_XFRM_SUB_POLICY
660 end:
661#endif
623 if ((*objp = (void *) pol) != NULL) 662 if ((*objp = (void *) pol) != NULL)
624 *obj_refp = &pol->refcnt; 663 *obj_refp = &pol->refcnt;
625} 664}
@@ -665,8 +704,10 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc
665 704
666static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) 705static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
667{ 706{
668 pol->next = xfrm_policy_list[dir]; 707 struct xfrm_policy **p_list = XFRM_POLICY_LISTS(pol->type);
669 xfrm_policy_list[dir] = pol; 708
709 pol->next = p_list[dir];
710 p_list[dir] = pol;
670 xfrm_pol_hold(pol); 711 xfrm_pol_hold(pol);
671} 712}
672 713
@@ -675,7 +716,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
675{ 716{
676 struct xfrm_policy **polp; 717 struct xfrm_policy **polp;
677 718
678 for (polp = &xfrm_policy_list[dir]; 719 for (polp = XFRM_POLICY_LISTHEADP(pol->type, dir);
679 *polp != NULL; polp = &(*polp)->next) { 720 *polp != NULL; polp = &(*polp)->next) {
680 if (*polp == pol) { 721 if (*polp == pol) {
681 *polp = pol->next; 722 *polp = pol->next;
@@ -704,12 +745,17 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
704{ 745{
705 struct xfrm_policy *old_pol; 746 struct xfrm_policy *old_pol;
706 747
748#ifdef CONFIG_XFRM_SUB_POLICY
749 if (pol && pol->type != XFRM_POLICY_TYPE_MAIN)
750 return -EINVAL;
751#endif
752
707 write_lock_bh(&xfrm_policy_lock); 753 write_lock_bh(&xfrm_policy_lock);
708 old_pol = sk->sk_policy[dir]; 754 old_pol = sk->sk_policy[dir];
709 sk->sk_policy[dir] = pol; 755 sk->sk_policy[dir] = pol;
710 if (pol) { 756 if (pol) {
711 pol->curlft.add_time = (unsigned long)xtime.tv_sec; 757 pol->curlft.add_time = (unsigned long)xtime.tv_sec;
712 pol->index = xfrm_gen_index(XFRM_POLICY_MAX+dir); 758 pol->index = xfrm_gen_index(pol->type, XFRM_POLICY_MAX+dir);
713 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); 759 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
714 } 760 }
715 if (old_pol) 761 if (old_pol)
@@ -738,6 +784,7 @@ static struct xfrm_policy *clone_policy(struct xfrm_policy *old, int dir)
738 newp->flags = old->flags; 784 newp->flags = old->flags;
739 newp->xfrm_nr = old->xfrm_nr; 785 newp->xfrm_nr = old->xfrm_nr;
740 newp->index = old->index; 786 newp->index = old->index;
787 newp->type = old->type;
741 memcpy(newp->xfrm_vec, old->xfrm_vec, 788 memcpy(newp->xfrm_vec, old->xfrm_vec,
742 newp->xfrm_nr*sizeof(struct xfrm_tmpl)); 789 newp->xfrm_nr*sizeof(struct xfrm_tmpl));
743 write_lock_bh(&xfrm_policy_lock); 790 write_lock_bh(&xfrm_policy_lock);
@@ -764,9 +811,9 @@ int __xfrm_sk_clone_policy(struct sock *sk)
764/* Resolve list of templates for the flow, given policy. */ 811/* Resolve list of templates for the flow, given policy. */
765 812
766static int 813static int
767xfrm_tmpl_resolve(struct xfrm_policy *policy, struct flowi *fl, 814xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl,
768 struct xfrm_state **xfrm, 815 struct xfrm_state **xfrm,
769 unsigned short family) 816 unsigned short family)
770{ 817{
771 int nx; 818 int nx;
772 int i, error; 819 int i, error;
@@ -809,6 +856,38 @@ fail:
809 return error; 856 return error;
810} 857}
811 858
859static int
860xfrm_tmpl_resolve(struct xfrm_policy **pols, int npols, struct flowi *fl,
861 struct xfrm_state **xfrm,
862 unsigned short family)
863{
864 int cnx = 0;
865 int error;
866 int ret;
867 int i;
868
869 for (i = 0; i < npols; i++) {
870 if (cnx + pols[i]->xfrm_nr >= XFRM_MAX_DEPTH) {
871 error = -ENOBUFS;
872 goto fail;
873 }
874 ret = xfrm_tmpl_resolve_one(pols[i], fl, &xfrm[cnx], family);
875 if (ret < 0) {
876 error = ret;
877 goto fail;
878 } else
879 cnx += ret;
880 }
881
882 return cnx;
883
884 fail:
885 for (cnx--; cnx>=0; cnx--)
886 xfrm_state_put(xfrm[cnx]);
887 return error;
888
889}
890
812/* Check that the bundle accepts the flow and its components are 891/* Check that the bundle accepts the flow and its components are
813 * still valid. 892 * still valid.
814 */ 893 */
@@ -855,6 +934,11 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
855 struct sock *sk, int flags) 934 struct sock *sk, int flags)
856{ 935{
857 struct xfrm_policy *policy; 936 struct xfrm_policy *policy;
937 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
938 int npols;
939 int pol_dead;
940 int xfrm_nr;
941 int pi;
858 struct xfrm_state *xfrm[XFRM_MAX_DEPTH]; 942 struct xfrm_state *xfrm[XFRM_MAX_DEPTH];
859 struct dst_entry *dst, *dst_orig = *dst_p; 943 struct dst_entry *dst, *dst_orig = *dst_p;
860 int nx = 0; 944 int nx = 0;
@@ -866,12 +950,18 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
866restart: 950restart:
867 genid = atomic_read(&flow_cache_genid); 951 genid = atomic_read(&flow_cache_genid);
868 policy = NULL; 952 policy = NULL;
953 for (pi = 0; pi < ARRAY_SIZE(pols); pi++)
954 pols[pi] = NULL;
955 npols = 0;
956 pol_dead = 0;
957 xfrm_nr = 0;
958
869 if (sk && sk->sk_policy[1]) 959 if (sk && sk->sk_policy[1])
870 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); 960 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
871 961
872 if (!policy) { 962 if (!policy) {
873 /* To accelerate a bit... */ 963 /* To accelerate a bit... */
874 if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT]) 964 if ((dst_orig->flags & DST_NOXFRM) || xfrm_policy_lists_empty(XFRM_POLICY_OUT))
875 return 0; 965 return 0;
876 966
877 policy = flow_cache_lookup(fl, dst_orig->ops->family, 967 policy = flow_cache_lookup(fl, dst_orig->ops->family,
@@ -883,6 +973,9 @@ restart:
883 973
884 family = dst_orig->ops->family; 974 family = dst_orig->ops->family;
885 policy->curlft.use_time = (unsigned long)xtime.tv_sec; 975 policy->curlft.use_time = (unsigned long)xtime.tv_sec;
976 pols[0] = policy;
977 npols ++;
978 xfrm_nr += pols[0]->xfrm_nr;
886 979
887 switch (policy->action) { 980 switch (policy->action) {
888 case XFRM_POLICY_BLOCK: 981 case XFRM_POLICY_BLOCK:
@@ -891,11 +984,13 @@ restart:
891 goto error; 984 goto error;
892 985
893 case XFRM_POLICY_ALLOW: 986 case XFRM_POLICY_ALLOW:
987#ifndef CONFIG_XFRM_SUB_POLICY
894 if (policy->xfrm_nr == 0) { 988 if (policy->xfrm_nr == 0) {
895 /* Flow passes not transformed. */ 989 /* Flow passes not transformed. */
896 xfrm_pol_put(policy); 990 xfrm_pol_put(policy);
897 return 0; 991 return 0;
898 } 992 }
993#endif
899 994
900 /* Try to find matching bundle. 995 /* Try to find matching bundle.
901 * 996 *
@@ -911,7 +1006,36 @@ restart:
911 if (dst) 1006 if (dst)
912 break; 1007 break;
913 1008
914 nx = xfrm_tmpl_resolve(policy, fl, xfrm, family); 1009#ifdef CONFIG_XFRM_SUB_POLICY
1010 if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) {
1011 pols[1] = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN,
1012 fl, family,
1013 XFRM_POLICY_OUT);
1014 if (pols[1]) {
1015 if (pols[1]->action == XFRM_POLICY_BLOCK) {
1016 err = -EPERM;
1017 goto error;
1018 }
1019 npols ++;
1020 xfrm_nr += pols[1]->xfrm_nr;
1021 }
1022 }
1023
1024 /*
1025 * Because neither flowi nor bundle information knows about
1026 * transformation template size. On more than one policy usage
1027 * we can realize whether all of them is bypass or not after
1028 * they are searched. See above not-transformed bypass
1029 * is surrounded by non-sub policy configuration, too.
1030 */
1031 if (xfrm_nr == 0) {
1032 /* Flow passes not transformed. */
1033 xfrm_pols_put(pols, npols);
1034 return 0;
1035 }
1036
1037#endif
1038 nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
915 1039
916 if (unlikely(nx<0)) { 1040 if (unlikely(nx<0)) {
917 err = nx; 1041 err = nx;
@@ -924,7 +1048,7 @@ restart:
924 set_current_state(TASK_RUNNING); 1048 set_current_state(TASK_RUNNING);
925 remove_wait_queue(&km_waitq, &wait); 1049 remove_wait_queue(&km_waitq, &wait);
926 1050
927 nx = xfrm_tmpl_resolve(policy, fl, xfrm, family); 1051 nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
928 1052
929 if (nx == -EAGAIN && signal_pending(current)) { 1053 if (nx == -EAGAIN && signal_pending(current)) {
930 err = -ERESTART; 1054 err = -ERESTART;
@@ -932,7 +1056,7 @@ restart:
932 } 1056 }
933 if (nx == -EAGAIN || 1057 if (nx == -EAGAIN ||
934 genid != atomic_read(&flow_cache_genid)) { 1058 genid != atomic_read(&flow_cache_genid)) {
935 xfrm_pol_put(policy); 1059 xfrm_pols_put(pols, npols);
936 goto restart; 1060 goto restart;
937 } 1061 }
938 err = nx; 1062 err = nx;
@@ -942,7 +1066,7 @@ restart:
942 } 1066 }
943 if (nx == 0) { 1067 if (nx == 0) {
944 /* Flow passes not transformed. */ 1068 /* Flow passes not transformed. */
945 xfrm_pol_put(policy); 1069 xfrm_pols_put(pols, npols);
946 return 0; 1070 return 0;
947 } 1071 }
948 1072
@@ -956,8 +1080,14 @@ restart:
956 goto error; 1080 goto error;
957 } 1081 }
958 1082
1083 for (pi = 0; pi < npols; pi++) {
1084 read_lock_bh(&pols[pi]->lock);
1085 pol_dead |= pols[pi]->dead;
1086 read_unlock_bh(&pols[pi]->lock);
1087 }
1088
959 write_lock_bh(&policy->lock); 1089 write_lock_bh(&policy->lock);
960 if (unlikely(policy->dead || stale_bundle(dst))) { 1090 if (unlikely(pol_dead || stale_bundle(dst))) {
961 /* Wow! While we worked on resolving, this 1091 /* Wow! While we worked on resolving, this
962 * policy has gone. Retry. It is not paranoia, 1092 * policy has gone. Retry. It is not paranoia,
963 * we just cannot enlist new bundle to dead object. 1093 * we just cannot enlist new bundle to dead object.
@@ -977,12 +1107,12 @@ restart:
977 } 1107 }
978 *dst_p = dst; 1108 *dst_p = dst;
979 dst_release(dst_orig); 1109 dst_release(dst_orig);
980 xfrm_pol_put(policy); 1110 xfrm_pols_put(pols, npols);
981 return 0; 1111 return 0;
982 1112
983error: 1113error:
984 dst_release(dst_orig); 1114 dst_release(dst_orig);
985 xfrm_pol_put(policy); 1115 xfrm_pols_put(pols, npols);
986 *dst_p = NULL; 1116 *dst_p = NULL;
987 return err; 1117 return err;
988} 1118}
@@ -1090,6 +1220,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1090 unsigned short family) 1220 unsigned short family)
1091{ 1221{
1092 struct xfrm_policy *pol; 1222 struct xfrm_policy *pol;
1223 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
1224 int npols = 0;
1225 int xfrm_nr;
1226 int pi;
1093 struct flowi fl; 1227 struct flowi fl;
1094 u8 fl_dir = policy_to_flow_dir(dir); 1228 u8 fl_dir = policy_to_flow_dir(dir);
1095 int xerr_idx = -1; 1229 int xerr_idx = -1;
@@ -1128,22 +1262,50 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1128 1262
1129 pol->curlft.use_time = (unsigned long)xtime.tv_sec; 1263 pol->curlft.use_time = (unsigned long)xtime.tv_sec;
1130 1264
1265 pols[0] = pol;
1266 npols ++;
1267#ifdef CONFIG_XFRM_SUB_POLICY
1268 if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) {
1269 pols[1] = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN,
1270 &fl, family,
1271 XFRM_POLICY_IN);
1272 if (pols[1]) {
1273 pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec;
1274 npols ++;
1275 }
1276 }
1277#endif
1278
1131 if (pol->action == XFRM_POLICY_ALLOW) { 1279 if (pol->action == XFRM_POLICY_ALLOW) {
1132 struct sec_path *sp; 1280 struct sec_path *sp;
1133 static struct sec_path dummy; 1281 static struct sec_path dummy;
1282 struct xfrm_tmpl *tp[XFRM_MAX_DEPTH];
1283 struct xfrm_tmpl **tpp = tp;
1284 int ti = 0;
1134 int i, k; 1285 int i, k;
1135 1286
1136 if ((sp = skb->sp) == NULL) 1287 if ((sp = skb->sp) == NULL)
1137 sp = &dummy; 1288 sp = &dummy;
1138 1289
1290 for (pi = 0; pi < npols; pi++) {
1291 if (pols[pi] != pol &&
1292 pols[pi]->action != XFRM_POLICY_ALLOW)
1293 goto reject;
1294 if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH)
1295 goto reject_error;
1296 for (i = 0; i < pols[pi]->xfrm_nr; i++)
1297 tpp[ti++] = &pols[pi]->xfrm_vec[i];
1298 }
1299 xfrm_nr = ti;
1300
1139 /* For each tunnel xfrm, find the first matching tmpl. 1301 /* For each tunnel xfrm, find the first matching tmpl.
1140 * For each tmpl before that, find corresponding xfrm. 1302 * For each tmpl before that, find corresponding xfrm.
1141 * Order is _important_. Later we will implement 1303 * Order is _important_. Later we will implement
1142 * some barriers, but at the moment barriers 1304 * some barriers, but at the moment barriers
1143 * are implied between each two transformations. 1305 * are implied between each two transformations.
1144 */ 1306 */
1145 for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) { 1307 for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
1146 k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family); 1308 k = xfrm_policy_ok(tpp[i], sp, k, family);
1147 if (k < 0) { 1309 if (k < 0) {
1148 if (k < -1 && xerr_idxp) 1310 if (k < -1 && xerr_idxp)
1149 *xerr_idxp = -(2+k); 1311 *xerr_idxp = -(2+k);
@@ -1154,13 +1316,14 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1154 if (secpath_has_nontransport(sp, k, xerr_idxp)) 1316 if (secpath_has_nontransport(sp, k, xerr_idxp))
1155 goto reject; 1317 goto reject;
1156 1318
1157 xfrm_pol_put(pol); 1319 xfrm_pols_put(pols, npols);
1158 return 1; 1320 return 1;
1159 } 1321 }
1160 1322
1161reject: 1323reject:
1162 xfrm_secpath_reject(xerr_idx, skb, &fl); 1324 xfrm_secpath_reject(xerr_idx, skb, &fl);
1163 xfrm_pol_put(pol); 1325reject_error:
1326 xfrm_pols_put(pols, npols);
1164 return 0; 1327 return 0;
1165} 1328}
1166EXPORT_SYMBOL(__xfrm_policy_check); 1329EXPORT_SYMBOL(__xfrm_policy_check);
@@ -1246,6 +1409,23 @@ static void xfrm_prune_bundles(int (*func)(struct dst_entry *))
1246 1409
1247 read_lock_bh(&xfrm_policy_lock); 1410 read_lock_bh(&xfrm_policy_lock);
1248 for (i=0; i<2*XFRM_POLICY_MAX; i++) { 1411 for (i=0; i<2*XFRM_POLICY_MAX; i++) {
1412#ifdef CONFIG_XFRM_SUB_POLICY
1413 for (pol = xfrm_policy_list_sub[i]; pol; pol = pol->next) {
1414 write_lock(&pol->lock);
1415 dstp = &pol->bundles;
1416 while ((dst=*dstp) != NULL) {
1417 if (func(dst)) {
1418 *dstp = dst->next;
1419 dst->next = gc_list;
1420 gc_list = dst;
1421 } else {
1422 dstp = &dst->next;
1423 }
1424 }
1425 write_unlock(&pol->lock);
1426 }
1427
1428#endif
1249 for (pol = xfrm_policy_list[i]; pol; pol = pol->next) { 1429 for (pol = xfrm_policy_list[i]; pol; pol = pol->next) {
1250 write_lock(&pol->lock); 1430 write_lock(&pol->lock);
1251 dstp = &pol->bundles; 1431 dstp = &pol->bundles;