Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 212381
Collapse All | Expand All

(-)linux-2.6.24.orig/include/linux/xfrm.h (-1 / +2 lines)
Lines 106-112 Link Here
106
{
106
{
107
	XFRM_POLICY_TYPE_MAIN	= 0,
107
	XFRM_POLICY_TYPE_MAIN	= 0,
108
	XFRM_POLICY_TYPE_SUB	= 1,
108
	XFRM_POLICY_TYPE_SUB	= 1,
109
	XFRM_POLICY_TYPE_MAX	= 2
109
	XFRM_POLICY_TYPE_MAX	= 2,
110
	XFRM_POLICY_TYPE_ANY	= 255
110
};
111
};
111
112
112
enum
113
enum
(-)linux-2.6.24.orig/include/net/xfrm.h (-2 / +50 lines)
Lines 107-112 Link Here
107
struct xfrm_state
107
struct xfrm_state
108
{
108
{
109
	/* Note: bydst is re-used during gc */
109
	/* Note: bydst is re-used during gc */
110
	struct list_head	all;
110
	struct hlist_node	bydst;
111
	struct hlist_node	bydst;
111
	struct hlist_node	bysrc;
112
	struct hlist_node	bysrc;
112
	struct hlist_node	byspi;
113
	struct hlist_node	byspi;
Lines 365-370 Link Here
365
struct xfrm_policy
366
struct xfrm_policy
366
{
367
{
367
	struct xfrm_policy	*next;
368
	struct xfrm_policy	*next;
369
	struct list_head	bytype;
368
	struct hlist_node	bydst;
370
	struct hlist_node	bydst;
369
	struct hlist_node	byidx;
371
	struct hlist_node	byidx;
370
372
Lines 979-984 Link Here
979
	int priority;
981
	int priority;
980
};
982
};
981
983
984
struct xfrm_state_walk {
985
	struct xfrm_state *state;
986
	int count;
987
	u8 proto;
988
};
989
990
struct xfrm_policy_walk {
991
	struct xfrm_policy *policy;
992
	int count;
993
	u8 type, cur_type;
994
};
995
982
extern void xfrm_init(void);
996
extern void xfrm_init(void);
983
extern void xfrm4_init(void);
997
extern void xfrm4_init(void);
984
extern void xfrm6_init(void);
998
extern void xfrm6_init(void);
Lines 988-994 Link Here
988
extern void xfrm6_state_init(void);
1002
extern void xfrm6_state_init(void);
989
extern void xfrm6_state_fini(void);
1003
extern void xfrm6_state_fini(void);
990
1004
991
extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *);
1005
static inline void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
1006
{
1007
	walk->proto = proto;
1008
	walk->state = NULL;
1009
	walk->count = 0;
1010
}
1011
1012
static inline void xfrm_state_walk_done(struct xfrm_state_walk *walk)
1013
{
1014
	if (walk->state != NULL) {
1015
		xfrm_state_put(walk->state);
1016
		walk->state = NULL;
1017
	}
1018
}
1019
1020
extern int xfrm_state_walk(struct xfrm_state_walk *walk,
1021
			   int (*func)(struct xfrm_state *, int, void*), void *);
992
extern struct xfrm_state *xfrm_state_alloc(void);
1022
extern struct xfrm_state *xfrm_state_alloc(void);
993
extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 
1023
extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 
994
					  struct flowi *fl, struct xfrm_tmpl *tmpl,
1024
					  struct flowi *fl, struct xfrm_tmpl *tmpl,
Lines 1100-1106 Link Here
1100
#endif
1130
#endif
1101
1131
1102
struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
1132
struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
1103
extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *);
1133
1134
static inline void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type)
1135
{
1136
	walk->cur_type = XFRM_POLICY_TYPE_MAIN;
1137
	walk->type = type;
1138
	walk->policy = NULL;
1139
	walk->count = 0;
1140
}
1141
1142
static inline void xfrm_policy_walk_done(struct xfrm_policy_walk *walk)
1143
{
1144
	if (walk->policy != NULL) {
1145
		xfrm_pol_put(walk->policy);
1146
		walk->policy = NULL;
1147
	}
1148
}
1149
1150
extern int xfrm_policy_walk(struct xfrm_policy_walk *walk,
1151
	int (*func)(struct xfrm_policy *, int, int, void*), void *);
1104
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
1152
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
1105
struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
1153
struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
1106
					  struct xfrm_selector *sel,
1154
					  struct xfrm_selector *sel,
(-)linux-2.6.24.orig/net/key/af_key.c (-21 / +99 lines)
Lines 48-53 Link Here
48
	struct sock	sk;
48
	struct sock	sk;
49
	int		registered;
49
	int		registered;
50
	int		promisc;
50
	int		promisc;
51
52
	struct {
53
		uint8_t		msg_version;
54
		uint32_t	msg_pid;
55
		int		(*dump)(struct pfkey_sock *sk);
56
		void		(*done)(struct pfkey_sock *sk);
57
		union {
58
			struct xfrm_policy_walk	policy;
59
			struct xfrm_state_walk	state;
60
		} u;
61
	} dump;
51
};
62
};
52
63
53
static inline struct pfkey_sock *pfkey_sk(struct sock *sk)
64
static inline struct pfkey_sock *pfkey_sk(struct sock *sk)
Lines 55-60 Link Here
55
	return (struct pfkey_sock *)sk;
66
	return (struct pfkey_sock *)sk;
56
}
67
}
57
68
69
static int pfkey_can_dump(struct sock *sk)
70
{
71
	if (3 * atomic_read(&sk->sk_rmem_alloc) <= 2 * sk->sk_rcvbuf)
72
		return 1;
73
	return 0;
74
}
75
76
static int pfkey_do_dump(struct pfkey_sock *pfk)
77
{
78
	int rc;
79
80
	rc = pfk->dump.dump(pfk);
81
	if (rc == -ENOBUFS)
82
		return 0;
83
84
	pfk->dump.done(pfk);
85
	pfk->dump.dump = NULL;
86
	pfk->dump.done = NULL;
87
	return rc;
88
}
89
58
static void pfkey_sock_destruct(struct sock *sk)
90
static void pfkey_sock_destruct(struct sock *sk)
59
{
91
{
60
	skb_queue_purge(&sk->sk_receive_queue);
92
	skb_queue_purge(&sk->sk_receive_queue);
Lines 1709-1753 Link Here
1709
	return 0;
1741
	return 0;
1710
}
1742
}
1711
1743
1712
struct pfkey_dump_data
1713
{
1714
	struct sk_buff *skb;
1715
	struct sadb_msg *hdr;
1716
	struct sock *sk;
1717
};
1718
1719
static int dump_sa(struct xfrm_state *x, int count, void *ptr)
1744
static int dump_sa(struct xfrm_state *x, int count, void *ptr)
1720
{
1745
{
1721
	struct pfkey_dump_data *data = ptr;
1746
	struct pfkey_sock *pfk = ptr;
1722
	struct sk_buff *out_skb;
1747
	struct sk_buff *out_skb;
1723
	struct sadb_msg *out_hdr;
1748
	struct sadb_msg *out_hdr;
1724
1749
1750
	if (!pfkey_can_dump(&pfk->sk))
1751
		return -ENOBUFS;
1752
1725
	out_skb = pfkey_xfrm_state2msg(x);
1753
	out_skb = pfkey_xfrm_state2msg(x);
1726
	if (IS_ERR(out_skb))
1754
	if (IS_ERR(out_skb))
1727
		return PTR_ERR(out_skb);
1755
		return PTR_ERR(out_skb);
1728
1756
1729
	out_hdr = (struct sadb_msg *) out_skb->data;
1757
	out_hdr = (struct sadb_msg *) out_skb->data;
1730
	out_hdr->sadb_msg_version = data->hdr->sadb_msg_version;
1758
	out_hdr->sadb_msg_version = pfk->dump.msg_version;
1731
	out_hdr->sadb_msg_type = SADB_DUMP;
1759
	out_hdr->sadb_msg_type = SADB_DUMP;
1732
	out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
1760
	out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
1733
	out_hdr->sadb_msg_errno = 0;
1761
	out_hdr->sadb_msg_errno = 0;
1734
	out_hdr->sadb_msg_reserved = 0;
1762
	out_hdr->sadb_msg_reserved = 0;
1735
	out_hdr->sadb_msg_seq = count;
1763
	out_hdr->sadb_msg_seq = count;
1736
	out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid;
1764
	out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
1737
	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk);
1765
	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk);
1738
	return 0;
1766
	return 0;
1739
}
1767
}
1740
1768
1769
static int pfkey_dump_sa(struct pfkey_sock *pfk)
1770
{
1771
	return xfrm_state_walk(&pfk->dump.u.state, dump_sa, (void *) pfk);
1772
}
1773
1774
static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
1775
{
1776
	xfrm_state_walk_done(&pfk->dump.u.state);
1777
}
1778
1741
static int pfkey_dump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1779
static int pfkey_dump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1742
{
1780
{
1743
	u8 proto;
1781
	u8 proto;
1744
	struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk };
1782
	struct pfkey_sock *pfk = pfkey_sk(sk);
1783
1784
	if (pfk->dump.dump != NULL)
1785
		return -EBUSY;
1745
1786
1746
	proto = pfkey_satype2proto(hdr->sadb_msg_satype);
1787
	proto = pfkey_satype2proto(hdr->sadb_msg_satype);
1747
	if (proto == 0)
1788
	if (proto == 0)
1748
		return -EINVAL;
1789
		return -EINVAL;
1749
1790
1750
	return xfrm_state_walk(proto, dump_sa, &data);
1791
	pfk->dump.msg_version = hdr->sadb_msg_version;
1792
	pfk->dump.msg_pid = hdr->sadb_msg_pid;
1793
	pfk->dump.dump = pfkey_dump_sa;
1794
	pfk->dump.done = pfkey_dump_sa_done;
1795
	xfrm_state_walk_init(&pfk->dump.u.state, proto);
1796
1797
	return pfkey_do_dump(pfk);
1751
}
1798
}
1752
1799
1753
static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1800
static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
Lines 1780-1786 Link Here
1780
1827
1781
static u32 gen_reqid(void)
1828
static u32 gen_reqid(void)
1782
{
1829
{
1830
	struct xfrm_policy_walk walk;
1783
	u32 start;
1831
	u32 start;
1832
	int rc;
1784
	static u32 reqid = IPSEC_MANUAL_REQID_MAX;
1833
	static u32 reqid = IPSEC_MANUAL_REQID_MAX;
1785
1834
1786
	start = reqid;
1835
	start = reqid;
Lines 1788-1795 Link Here
1788
		++reqid;
1837
		++reqid;
1789
		if (reqid == 0)
1838
		if (reqid == 0)
1790
			reqid = IPSEC_MANUAL_REQID_MAX+1;
1839
			reqid = IPSEC_MANUAL_REQID_MAX+1;
1791
		if (xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, check_reqid,
1840
		xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN);
1792
				     (void*)&reqid) != -EEXIST)
1841
		rc = xfrm_policy_walk(&walk, check_reqid, (void*)&reqid);
1842
		xfrm_policy_walk_done(&walk);
1843
		if (rc != -EEXIST)
1793
			return reqid;
1844
			return reqid;
1794
	} while (reqid != start);
1845
	} while (reqid != start);
1795
	return 0;
1846
	return 0;
Lines 2638-2648 Link Here
2638
2689
2639
static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
2690
static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
2640
{
2691
{
2641
	struct pfkey_dump_data *data = ptr;
2692
	struct pfkey_sock *pfk = ptr;
2642
	struct sk_buff *out_skb;
2693
	struct sk_buff *out_skb;
2643
	struct sadb_msg *out_hdr;
2694
	struct sadb_msg *out_hdr;
2644
	int err;
2695
	int err;
2645
2696
2697
	if (!pfkey_can_dump(&pfk->sk))
2698
		return -ENOBUFS;
2699
2646
	out_skb = pfkey_xfrm_policy2msg_prep(xp);
2700
	out_skb = pfkey_xfrm_policy2msg_prep(xp);
2647
	if (IS_ERR(out_skb))
2701
	if (IS_ERR(out_skb))
2648
		return PTR_ERR(out_skb);
2702
		return PTR_ERR(out_skb);
Lines 2652-2672 Link Here
2652
		return err;
2706
		return err;
2653
2707
2654
	out_hdr = (struct sadb_msg *) out_skb->data;
2708
	out_hdr = (struct sadb_msg *) out_skb->data;
2655
	out_hdr->sadb_msg_version = data->hdr->sadb_msg_version;
2709
	out_hdr->sadb_msg_version = pfk->dump.msg_version;
2656
	out_hdr->sadb_msg_type = SADB_X_SPDDUMP;
2710
	out_hdr->sadb_msg_type = SADB_X_SPDDUMP;
2657
	out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
2711
	out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
2658
	out_hdr->sadb_msg_errno = 0;
2712
	out_hdr->sadb_msg_errno = 0;
2659
	out_hdr->sadb_msg_seq = count;
2713
	out_hdr->sadb_msg_seq = count;
2660
	out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid;
2714
	out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
2661
	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk);
2715
	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk);
2662
	return 0;
2716
	return 0;
2663
}
2717
}
2664
2718
2719
static int pfkey_dump_sp(struct pfkey_sock *pfk)
2720
{
2721
	return xfrm_policy_walk(&pfk->dump.u.policy, dump_sp, (void *) pfk);
2722
}
2723
2724
static void pfkey_dump_sp_done(struct pfkey_sock *pfk)
2725
{
2726
	xfrm_policy_walk_done(&pfk->dump.u.policy);
2727
}
2728
2665
static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
2729
static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
2666
{
2730
{
2667
	struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk };
2731
	struct pfkey_sock *pfk = pfkey_sk(sk);
2732
2733
	if (pfk->dump.dump != NULL)
2734
		return -EBUSY;
2735
2736
	pfk->dump.msg_version = hdr->sadb_msg_version;
2737
	pfk->dump.msg_pid = hdr->sadb_msg_pid;
2738
	pfk->dump.dump = pfkey_dump_sp;
2739
	pfk->dump.done = pfkey_dump_sp_done;
2740
	xfrm_policy_walk_init(&pfk->dump.u.policy, XFRM_POLICY_TYPE_MAIN);
2668
2741
2669
	return xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_sp, &data);
2742
	return pfkey_do_dump(pfk);
2670
}
2743
}
2671
2744
2672
static int key_notify_policy_flush(struct km_event *c)
2745
static int key_notify_policy_flush(struct km_event *c)
Lines 3672-3677 Link Here
3672
			 int flags)
3745
			 int flags)
3673
{
3746
{
3674
	struct sock *sk = sock->sk;
3747
	struct sock *sk = sock->sk;
3748
	struct pfkey_sock *pfk = pfkey_sk(sk);
3675
	struct sk_buff *skb;
3749
	struct sk_buff *skb;
3676
	int copied, err;
3750
	int copied, err;
3677
3751
Lines 3699-3704 Link Here
3699
3773
3700
	err = (flags & MSG_TRUNC) ? skb->len : copied;
3774
	err = (flags & MSG_TRUNC) ? skb->len : copied;
3701
3775
3776
	if (pfk->dump.dump != NULL &&
3777
	    3 * atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)
3778
		pfkey_do_dump(pfk);
3779
3702
out_free:
3780
out_free:
3703
	skb_free_datagram(sk, skb);
3781
	skb_free_datagram(sk, skb);
3704
out:
3782
out:
(-)linux-2.6.24.orig/net/xfrm/xfrm_policy.c (-33 / +46 lines)
Lines 35-40 Link Here
35
35
36
static DEFINE_RWLOCK(xfrm_policy_lock);
36
static DEFINE_RWLOCK(xfrm_policy_lock);
37
37
38
static struct list_head xfrm_policy_bytype[XFRM_POLICY_TYPE_MAX];
38
unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
39
unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
39
EXPORT_SYMBOL(xfrm_policy_count);
40
EXPORT_SYMBOL(xfrm_policy_count);
40
41
Lines 192-197 Link Here
192
	policy = kzalloc(sizeof(struct xfrm_policy), gfp);
193
	policy = kzalloc(sizeof(struct xfrm_policy), gfp);
193
194
194
	if (policy) {
195
	if (policy) {
196
		INIT_LIST_HEAD(&policy->bytype);
195
		INIT_HLIST_NODE(&policy->bydst);
197
		INIT_HLIST_NODE(&policy->bydst);
196
		INIT_HLIST_NODE(&policy->byidx);
198
		INIT_HLIST_NODE(&policy->byidx);
197
		rwlock_init(&policy->lock);
199
		rwlock_init(&policy->lock);
Lines 215-220 Link Here
215
	if (del_timer(&policy->timer))
217
	if (del_timer(&policy->timer))
216
		BUG();
218
		BUG();
217
219
220
	write_lock_bh(&xfrm_policy_lock);
221
	list_del(&policy->bytype);
222
	write_unlock_bh(&xfrm_policy_lock);
223
218
	security_xfrm_policy_free(policy);
224
	security_xfrm_policy_free(policy);
219
	kfree(policy);
225
	kfree(policy);
220
}
226
}
Lines 553-558 Link Here
553
	policy->curlft.use_time = 0;
559
	policy->curlft.use_time = 0;
554
	if (!mod_timer(&policy->timer, jiffies + HZ))
560
	if (!mod_timer(&policy->timer, jiffies + HZ))
555
		xfrm_pol_hold(policy);
561
		xfrm_pol_hold(policy);
562
	list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]);
556
	write_unlock_bh(&xfrm_policy_lock);
563
	write_unlock_bh(&xfrm_policy_lock);
557
564
558
	if (delpol)
565
	if (delpol)
Lines 791-847 Link Here
791
}
798
}
792
EXPORT_SYMBOL(xfrm_policy_flush);
799
EXPORT_SYMBOL(xfrm_policy_flush);
793
800
794
int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*),
801
int xfrm_policy_walk(struct xfrm_policy_walk *walk,
802
		     int (*func)(struct xfrm_policy *, int, int, void*),
795
		     void *data)
803
		     void *data)
796
{
804
{
797
	struct xfrm_policy *pol, *last = NULL;
805
	struct xfrm_policy *old, *pol, *last = NULL;
798
	struct hlist_node *entry;
806
	int error = 0;
799
	int dir, last_dir = 0, count, error;
807
808
	if (walk->type >= XFRM_POLICY_TYPE_MAX &&
809
	    walk->type != XFRM_POLICY_TYPE_ANY)
810
		return -EINVAL;
800
811
812
	if (walk->policy == NULL && walk->count != 0)
813
		return 0;
814
815
	old = pol = walk->policy;
816
	walk->policy = NULL;
801
	read_lock_bh(&xfrm_policy_lock);
817
	read_lock_bh(&xfrm_policy_lock);
802
	count = 0;
803
818
804
	for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) {
819
	for (; walk->cur_type < XFRM_POLICY_TYPE_MAX; walk->cur_type++) {
805
		struct hlist_head *table = xfrm_policy_bydst[dir].table;
820
		if (walk->type != walk->cur_type &&
806
		int i;
821
		    walk->type != XFRM_POLICY_TYPE_ANY)
822
			continue;
807
823
808
		hlist_for_each_entry(pol, entry,
824
		if (pol == NULL) {
809
				     &xfrm_policy_inexact[dir], bydst) {
825
			pol = list_first_entry(&xfrm_policy_bytype[walk->cur_type],
810
			if (pol->type != type)
826
					       struct xfrm_policy, bytype);
827
		}
828
		list_for_each_entry_from(pol, &xfrm_policy_bytype[walk->cur_type], bytype) {
829
			if (pol->dead)
811
				continue;
830
				continue;
812
			if (last) {
831
			if (last) {
813
				error = func(last, last_dir % XFRM_POLICY_MAX,
832
				error = func(last, xfrm_policy_id2dir(last->index),
814
					     count, data);
833
					     walk->count, data);
815
				if (error)
834
				if (error) {
835
					xfrm_pol_hold(last);
836
					walk->policy = last;
816
					goto out;
837
					goto out;
817
			}
818
			last = pol;
819
			last_dir = dir;
820
			count++;
821
		}
822
		for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
823
			hlist_for_each_entry(pol, entry, table + i, bydst) {
824
				if (pol->type != type)
825
					continue;
826
				if (last) {
827
					error = func(last, last_dir % XFRM_POLICY_MAX,
828
						     count, data);
829
					if (error)
830
						goto out;
831
				}
838
				}
832
				last = pol;
833
				last_dir = dir;
834
				count++;
835
			}
839
			}
840
			last = pol;
841
			walk->count++;
836
		}
842
		}
843
		pol = NULL;
837
	}
844
	}
838
	if (count == 0) {
845
	if (walk->count == 0) {
839
		error = -ENOENT;
846
		error = -ENOENT;
840
		goto out;
847
		goto out;
841
	}
848
	}
842
	error = func(last, last_dir % XFRM_POLICY_MAX, 0, data);
849
	if (last)
850
		error = func(last, xfrm_policy_id2dir(last->index), 0, data);
843
out:
851
out:
844
	read_unlock_bh(&xfrm_policy_lock);
852
	read_unlock_bh(&xfrm_policy_lock);
853
	if (old != NULL)
854
		xfrm_pol_put(old);
845
	return error;
855
	return error;
846
}
856
}
847
EXPORT_SYMBOL(xfrm_policy_walk);
857
EXPORT_SYMBOL(xfrm_policy_walk);
Lines 2112-2117 Link Here
2112
			panic("XFRM: failed to allocate bydst hash\n");
2122
			panic("XFRM: failed to allocate bydst hash\n");
2113
	}
2123
	}
2114
2124
2125
	for (dir = 0; dir < XFRM_POLICY_TYPE_MAX; dir++)
2126
		INIT_LIST_HEAD(&xfrm_policy_bytype[dir]);
2127
2115
	INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task);
2128
	INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task);
2116
	register_netdevice_notifier(&xfrm_dev_notifier);
2129
	register_netdevice_notifier(&xfrm_dev_notifier);
2117
}
2130
}
(-)linux-2.6.24.orig/net/xfrm/xfrm_state.c (-17 / +36 lines)
Lines 49-54 Link Here
49
 * Main use is finding SA after policy selected tunnel or transport mode.
49
 * Main use is finding SA after policy selected tunnel or transport mode.
50
 * Also, it can be used by ah/esp icmp error handler to find offending SA.
50
 * Also, it can be used by ah/esp icmp error handler to find offending SA.
51
 */
51
 */
52
static LIST_HEAD(xfrm_state_all);
52
static struct hlist_head *xfrm_state_bydst __read_mostly;
53
static struct hlist_head *xfrm_state_bydst __read_mostly;
53
static struct hlist_head *xfrm_state_bysrc __read_mostly;
54
static struct hlist_head *xfrm_state_bysrc __read_mostly;
54
static struct hlist_head *xfrm_state_byspi __read_mostly;
55
static struct hlist_head *xfrm_state_byspi __read_mostly;
Lines 501-506 Link Here
501
	if (x) {
502
	if (x) {
502
		atomic_set(&x->refcnt, 1);
503
		atomic_set(&x->refcnt, 1);
503
		atomic_set(&x->tunnel_users, 0);
504
		atomic_set(&x->tunnel_users, 0);
505
		INIT_LIST_HEAD(&x->all);
504
		INIT_HLIST_NODE(&x->bydst);
506
		INIT_HLIST_NODE(&x->bydst);
505
		INIT_HLIST_NODE(&x->bysrc);
507
		INIT_HLIST_NODE(&x->bysrc);
506
		INIT_HLIST_NODE(&x->byspi);
508
		INIT_HLIST_NODE(&x->byspi);
Lines 527-532 Link Here
527
{
529
{
528
	BUG_TRAP(x->km.state == XFRM_STATE_DEAD);
530
	BUG_TRAP(x->km.state == XFRM_STATE_DEAD);
529
531
532
	spin_lock_bh(&xfrm_state_lock);
533
	list_del(&x->all);
534
	spin_unlock_bh(&xfrm_state_lock);
535
530
	spin_lock_bh(&xfrm_state_gc_lock);
536
	spin_lock_bh(&xfrm_state_gc_lock);
531
	hlist_add_head(&x->bydst, &xfrm_state_gc_list);
537
	hlist_add_head(&x->bydst, &xfrm_state_gc_list);
532
	spin_unlock_bh(&xfrm_state_gc_lock);
538
	spin_unlock_bh(&xfrm_state_gc_lock);
Lines 901-906 Link Here
901
907
902
	x->genid = ++xfrm_state_genid;
908
	x->genid = ++xfrm_state_genid;
903
909
910
	list_add_tail(&x->all, &xfrm_state_all);
911
904
	h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
912
	h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
905
			  x->props.reqid, x->props.family);
913
			  x->props.reqid, x->props.family);
906
	hlist_add_head(&x->bydst, xfrm_state_bydst+h);
914
	hlist_add_head(&x->bydst, xfrm_state_bydst+h);
Lines 1511-1546 Link Here
1511
}
1519
}
1512
EXPORT_SYMBOL(xfrm_alloc_spi);
1520
EXPORT_SYMBOL(xfrm_alloc_spi);
1513
1521
1514
int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*),
1522
int xfrm_state_walk(struct xfrm_state_walk *walk,
1523
		    int (*func)(struct xfrm_state *, int, void*),
1515
		    void *data)
1524
		    void *data)
1516
{
1525
{
1517
	int i;
1526
	struct xfrm_state *old, *x, *last = NULL;
1518
	struct xfrm_state *x, *last = NULL;
1519
	struct hlist_node *entry;
1520
	int count = 0;
1521
	int err = 0;
1527
	int err = 0;
1522
1528
1529
	if (walk->state == NULL && walk->count != 0)
1530
		return 0;
1531
1532
	old = x = walk->state;
1533
	walk->state = NULL;
1523
	spin_lock_bh(&xfrm_state_lock);
1534
	spin_lock_bh(&xfrm_state_lock);
1524
	for (i = 0; i <= xfrm_state_hmask; i++) {
1535
	if (x == NULL)
1525
		hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
1536
		x = list_first_entry(&xfrm_state_all, struct xfrm_state, all);
1526
			if (!xfrm_id_proto_match(x->id.proto, proto))
1537
	list_for_each_entry_from(x, &xfrm_state_all, all) {
1527
				continue;
1538
		if (x->km.state == XFRM_STATE_DEAD)
1528
			if (last) {
1539
			continue;
1529
				err = func(last, count, data);
1540
		if (!xfrm_id_proto_match(x->id.proto, walk->proto))
1530
				if (err)
1541
			continue;
1531
					goto out;
1542
		if (last) {
1543
			err = func(last, walk->count, data);
1544
			if (err) {
1545
				xfrm_state_hold(last);
1546
				walk->state = last;
1547
				goto out;
1532
			}
1548
			}
1533
			last = x;
1534
			count++;
1535
		}
1549
		}
1550
		last = x;
1551
		walk->count++;
1536
	}
1552
	}
1537
	if (count == 0) {
1553
	if (walk->count == 0) {
1538
		err = -ENOENT;
1554
		err = -ENOENT;
1539
		goto out;
1555
		goto out;
1540
	}
1556
	}
1541
	err = func(last, 0, data);
1557
	if (last)
1558
		err = func(last, 0, data);
1542
out:
1559
out:
1543
	spin_unlock_bh(&xfrm_state_lock);
1560
	spin_unlock_bh(&xfrm_state_lock);
1561
	if (old != NULL)
1562
		xfrm_state_put(old);
1544
	return err;
1563
	return err;
1545
}
1564
}
1546
EXPORT_SYMBOL(xfrm_state_walk);
1565
EXPORT_SYMBOL(xfrm_state_walk);
(-)linux-2.6.24.orig/net/xfrm/xfrm_user.c (-28 / +43 lines)
Lines 472-479 Link Here
472
	struct sk_buff *out_skb;
472
	struct sk_buff *out_skb;
473
	u32 nlmsg_seq;
473
	u32 nlmsg_seq;
474
	u16 nlmsg_flags;
474
	u16 nlmsg_flags;
475
	int start_idx;
476
	int this_idx;
477
};
475
};
478
476
479
static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
477
static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
Lines 538-546 Link Here
538
	struct nlmsghdr *nlh;
536
	struct nlmsghdr *nlh;
539
	int err;
537
	int err;
540
538
541
	if (sp->this_idx < sp->start_idx)
542
		goto out;
543
544
	nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
539
	nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
545
			XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags);
540
			XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags);
546
	if (nlh == NULL)
541
	if (nlh == NULL)
Lines 553-560 Link Here
553
		goto nla_put_failure;
548
		goto nla_put_failure;
554
549
555
	nlmsg_end(skb, nlh);
550
	nlmsg_end(skb, nlh);
556
out:
557
	sp->this_idx++;
558
	return 0;
551
	return 0;
559
552
560
nla_put_failure:
553
nla_put_failure:
Lines 562-579 Link Here
562
	return err;
555
	return err;
563
}
556
}
564
557
558
static int xfrm_dump_sa_done(struct netlink_callback *cb)
559
{
560
	struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
561
	xfrm_state_walk_done(walk);
562
	return 0;
563
}
564
565
static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
565
static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
566
{
566
{
567
	struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
567
	struct xfrm_dump_info info;
568
	struct xfrm_dump_info info;
568
569
570
	BUILD_BUG_ON(sizeof(struct xfrm_state_walk) >
571
		     sizeof(cb->args) - sizeof(cb->args[0]));
572
569
	info.in_skb = cb->skb;
573
	info.in_skb = cb->skb;
570
	info.out_skb = skb;
574
	info.out_skb = skb;
571
	info.nlmsg_seq = cb->nlh->nlmsg_seq;
575
	info.nlmsg_seq = cb->nlh->nlmsg_seq;
572
	info.nlmsg_flags = NLM_F_MULTI;
576
	info.nlmsg_flags = NLM_F_MULTI;
573
	info.this_idx = 0;
577
574
	info.start_idx = cb->args[0];
578
	if (!cb->args[0]) {
575
	(void) xfrm_state_walk(0, dump_one_state, &info);
579
		cb->args[0] = 1;
576
	cb->args[0] = info.this_idx;
580
		xfrm_state_walk_init(walk, 0);
581
	}
582
583
	(void) xfrm_state_walk(walk, dump_one_state, &info);
577
584
578
	return skb->len;
585
	return skb->len;
579
}
586
}
Lines 592-598 Link Here
592
	info.out_skb = skb;
599
	info.out_skb = skb;
593
	info.nlmsg_seq = seq;
600
	info.nlmsg_seq = seq;
594
	info.nlmsg_flags = 0;
601
	info.nlmsg_flags = 0;
595
	info.this_idx = info.start_idx = 0;
596
602
597
	if (dump_one_state(x, 0, &info)) {
603
	if (dump_one_state(x, 0, &info)) {
598
		kfree_skb(skb);
604
		kfree_skb(skb);
Lines 1169-1177 Link Here
1169
	struct sk_buff *skb = sp->out_skb;
1175
	struct sk_buff *skb = sp->out_skb;
1170
	struct nlmsghdr *nlh;
1176
	struct nlmsghdr *nlh;
1171
1177
1172
	if (sp->this_idx < sp->start_idx)
1173
		goto out;
1174
1175
	nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
1178
	nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
1176
			XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags);
1179
			XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags);
1177
	if (nlh == NULL)
1180
	if (nlh == NULL)
Lines 1187-1194 Link Here
1187
		goto nlmsg_failure;
1190
		goto nlmsg_failure;
1188
1191
1189
	nlmsg_end(skb, nlh);
1192
	nlmsg_end(skb, nlh);
1190
out:
1191
	sp->this_idx++;
1192
	return 0;
1193
	return 0;
1193
1194
1194
nlmsg_failure:
1195
nlmsg_failure:
Lines 1196-1216 Link Here
1196
	return -EMSGSIZE;
1197
	return -EMSGSIZE;
1197
}
1198
}
1198
1199
1200
static int xfrm_dump_policy_done(struct netlink_callback *cb)
1201
{
1202
	struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
1203
1204
	xfrm_policy_walk_done(walk);
1205
	return 0;
1206
}
1207
1199
static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
1208
static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
1200
{
1209
{
1210
	struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
1201
	struct xfrm_dump_info info;
1211
	struct xfrm_dump_info info;
1202
1212
1213
	BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) >
1214
		     sizeof(cb->args) - sizeof(cb->args[0]));
1215
1203
	info.in_skb = cb->skb;
1216
	info.in_skb = cb->skb;
1204
	info.out_skb = skb;
1217
	info.out_skb = skb;
1205
	info.nlmsg_seq = cb->nlh->nlmsg_seq;
1218
	info.nlmsg_seq = cb->nlh->nlmsg_seq;
1206
	info.nlmsg_flags = NLM_F_MULTI;
1219
	info.nlmsg_flags = NLM_F_MULTI;
1207
	info.this_idx = 0;
1220
1208
	info.start_idx = cb->args[0];
1221
	if (!cb->args[0]) {
1209
	(void) xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_one_policy, &info);
1222
		cb->args[0] = 1;
1210
#ifdef CONFIG_XFRM_SUB_POLICY
1223
		xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY);
1211
	(void) xfrm_policy_walk(XFRM_POLICY_TYPE_SUB, dump_one_policy, &info);
1224
	}
1212
#endif
1225
1213
	cb->args[0] = info.this_idx;
1226
	(void) xfrm_policy_walk(walk, dump_one_policy, &info);
1214
1227
1215
	return skb->len;
1228
	return skb->len;
1216
}
1229
}
Lines 1230-1236 Link Here
1230
	info.out_skb = skb;
1243
	info.out_skb = skb;
1231
	info.nlmsg_seq = seq;
1244
	info.nlmsg_seq = seq;
1232
	info.nlmsg_flags = 0;
1245
	info.nlmsg_flags = 0;
1233
	info.this_idx = info.start_idx = 0;
1234
1246
1235
	if (dump_one_policy(xp, dir, 0, &info) < 0) {
1247
	if (dump_one_policy(xp, dir, 0, &info) < 0) {
1236
		kfree_skb(skb);
1248
		kfree_skb(skb);
Lines 1827-1841 Link Here
1827
static struct xfrm_link {
1839
static struct xfrm_link {
1828
	int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
1840
	int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
1829
	int (*dump)(struct sk_buff *, struct netlink_callback *);
1841
	int (*dump)(struct sk_buff *, struct netlink_callback *);
1842
	int (*done)(struct netlink_callback *);
1830
} xfrm_dispatch[XFRM_NR_MSGTYPES] = {
1843
} xfrm_dispatch[XFRM_NR_MSGTYPES] = {
1831
	[XFRM_MSG_NEWSA       - XFRM_MSG_BASE] = { .doit = xfrm_add_sa        },
1844
	[XFRM_MSG_NEWSA       - XFRM_MSG_BASE] = { .doit = xfrm_add_sa        },
1832
	[XFRM_MSG_DELSA       - XFRM_MSG_BASE] = { .doit = xfrm_del_sa        },
1845
	[XFRM_MSG_DELSA       - XFRM_MSG_BASE] = { .doit = xfrm_del_sa        },
1833
	[XFRM_MSG_GETSA       - XFRM_MSG_BASE] = { .doit = xfrm_get_sa,
1846
	[XFRM_MSG_GETSA       - XFRM_MSG_BASE] = { .doit = xfrm_get_sa,
1834
						   .dump = xfrm_dump_sa       },
1847
						   .dump = xfrm_dump_sa,
1848
						   .done = xfrm_dump_sa_done  },
1835
	[XFRM_MSG_NEWPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_add_policy    },
1849
	[XFRM_MSG_NEWPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_add_policy    },
1836
	[XFRM_MSG_DELPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_get_policy    },
1850
	[XFRM_MSG_DELPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_get_policy    },
1837
	[XFRM_MSG_GETPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_get_policy,
1851
	[XFRM_MSG_GETPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_get_policy,
1838
						   .dump = xfrm_dump_policy   },
1852
						   .dump = xfrm_dump_policy,
1853
						   .done = xfrm_dump_policy_done },
1839
	[XFRM_MSG_ALLOCSPI    - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
1854
	[XFRM_MSG_ALLOCSPI    - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
1840
	[XFRM_MSG_ACQUIRE     - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire   },
1855
	[XFRM_MSG_ACQUIRE     - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire   },
1841
	[XFRM_MSG_EXPIRE      - XFRM_MSG_BASE] = { .doit = xfrm_add_sa_expire },
1856
	[XFRM_MSG_EXPIRE      - XFRM_MSG_BASE] = { .doit = xfrm_add_sa_expire },
Lines 1874-1880 Link Here
1874
		if (link->dump == NULL)
1889
		if (link->dump == NULL)
1875
			return -EINVAL;
1890
			return -EINVAL;
1876
1891
1877
		return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, NULL);
1892
		return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, link->done);
1878
	}
1893
	}
1879
1894
1880
	err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX,
1895
	err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX,

Return to bug 212381