Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 145344 Details for
Bug 212381
sys-kernel/gentoo-sources [PATCH] allow more than 200 ipsec connections with ipsec-tools
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
linux-2.6.24-large-sasp-dump.patch
linux-2.6.24-large-sasp-dump.patch (text/plain), 20.62 KB, created by
Natanael Copa
on 2008-03-05 12:51:48 UTC
(
hide
)
Description:
linux-2.6.24-large-sasp-dump.patch
Filename:
MIME Type:
Creator:
Natanael Copa
Created:
2008-03-05 12:51:48 UTC
Size:
20.62 KB
patch
obsolete
>Index: linux-2.6.24/include/linux/xfrm.h >=================================================================== >--- linux-2.6.24.orig/include/linux/xfrm.h 2008-03-05 08:59:14.000000000 +0200 >+++ linux-2.6.24/include/linux/xfrm.h 2008-03-05 09:00:19.000000000 +0200 >@@ -106,7 +106,8 @@ > { > XFRM_POLICY_TYPE_MAIN = 0, > XFRM_POLICY_TYPE_SUB = 1, >- XFRM_POLICY_TYPE_MAX = 2 >+ XFRM_POLICY_TYPE_MAX = 2, >+ XFRM_POLICY_TYPE_ANY = 255 > }; > > enum >Index: linux-2.6.24/include/net/xfrm.h >=================================================================== >--- linux-2.6.24.orig/include/net/xfrm.h 2008-03-05 08:59:14.000000000 +0200 >+++ linux-2.6.24/include/net/xfrm.h 2008-03-05 09:00:19.000000000 +0200 >@@ -107,6 +107,7 @@ > struct xfrm_state > { > /* Note: bydst is re-used during gc */ >+ struct list_head all; > struct hlist_node bydst; > struct hlist_node bysrc; > struct hlist_node byspi; >@@ -365,6 +366,7 @@ > struct xfrm_policy > { > struct xfrm_policy *next; >+ struct list_head bytype; > struct hlist_node bydst; > struct hlist_node byidx; > >@@ -979,6 +981,18 @@ > int priority; > }; > >+struct xfrm_state_walk { >+ struct xfrm_state *state; >+ int count; >+ u8 proto; >+}; >+ >+struct xfrm_policy_walk { >+ struct xfrm_policy *policy; >+ int count; >+ u8 type, cur_type; >+}; >+ > extern void xfrm_init(void); > extern void xfrm4_init(void); > extern void xfrm6_init(void); >@@ -988,7 +1002,23 @@ > extern void xfrm6_state_init(void); > extern void xfrm6_state_fini(void); > >-extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *); >+static inline void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto) >+{ >+ walk->proto = proto; >+ walk->state = NULL; >+ walk->count = 0; >+} >+ >+static inline void xfrm_state_walk_done(struct xfrm_state_walk *walk) >+{ >+ if (walk->state != NULL) { >+ xfrm_state_put(walk->state); >+ walk->state = NULL; >+ } >+} >+ >+extern int xfrm_state_walk(struct xfrm_state_walk *walk, >+ int (*func)(struct xfrm_state *, int, void*), void *); > extern struct xfrm_state *xfrm_state_alloc(void); > extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, > struct flowi *fl, struct xfrm_tmpl *tmpl, >@@ -1100,7 +1130,25 @@ > #endif > > struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); >-extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *); >+ >+static inline void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type) >+{ >+ walk->cur_type = XFRM_POLICY_TYPE_MAIN; >+ walk->type = type; >+ walk->policy = NULL; >+ walk->count = 0; >+} >+ >+static inline void xfrm_policy_walk_done(struct xfrm_policy_walk *walk) >+{ >+ if (walk->policy != NULL) { >+ xfrm_pol_put(walk->policy); >+ walk->policy = NULL; >+ } >+} >+ >+extern int xfrm_policy_walk(struct xfrm_policy_walk *walk, >+ int (*func)(struct xfrm_policy *, int, int, void*), void *); > int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); > struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, > struct xfrm_selector *sel, >Index: linux-2.6.24/net/key/af_key.c >=================================================================== >--- linux-2.6.24.orig/net/key/af_key.c 2008-03-05 08:59:14.000000000 +0200 >+++ linux-2.6.24/net/key/af_key.c 2008-03-05 09:01:18.000000000 +0200 >@@ -48,6 +48,17 @@ > struct sock sk; > int registered; > int promisc; >+ >+ struct { >+ uint8_t msg_version; >+ uint32_t msg_pid; >+ int (*dump)(struct pfkey_sock *sk); >+ void (*done)(struct pfkey_sock *sk); >+ union { >+ struct xfrm_policy_walk policy; >+ struct xfrm_state_walk state; >+ } u; >+ } dump; > }; > > static inline struct pfkey_sock *pfkey_sk(struct sock *sk) >@@ -55,6 +66,27 @@ > return (struct pfkey_sock *)sk; > } > >+static int pfkey_can_dump(struct sock *sk) >+{ >+ if (3 * atomic_read(&sk->sk_rmem_alloc) <= 2 * sk->sk_rcvbuf) >+ return 1; >+ return 0; >+} >+ >+static int pfkey_do_dump(struct pfkey_sock *pfk) >+{ >+ int rc; >+ >+ rc = pfk->dump.dump(pfk); >+ if (rc == -ENOBUFS) >+ return 0; >+ >+ pfk->dump.done(pfk); >+ pfk->dump.dump = NULL; >+ pfk->dump.done = NULL; >+ return rc; >+} >+ > static void pfkey_sock_destruct(struct sock *sk) > { > skb_queue_purge(&sk->sk_receive_queue); >@@ -1709,45 +1741,60 @@ > return 0; > } > >-struct pfkey_dump_data >-{ >- struct sk_buff *skb; >- struct sadb_msg *hdr; >- struct sock *sk; >-}; >- > static int dump_sa(struct xfrm_state *x, int count, void *ptr) > { >- struct pfkey_dump_data *data = ptr; >+ struct pfkey_sock *pfk = ptr; > struct sk_buff *out_skb; > struct sadb_msg *out_hdr; > >+ if (!pfkey_can_dump(&pfk->sk)) >+ return -ENOBUFS; >+ > out_skb = pfkey_xfrm_state2msg(x); > if (IS_ERR(out_skb)) > return PTR_ERR(out_skb); > > out_hdr = (struct sadb_msg *) out_skb->data; >- out_hdr->sadb_msg_version = data->hdr->sadb_msg_version; >+ out_hdr->sadb_msg_version = pfk->dump.msg_version; > out_hdr->sadb_msg_type = SADB_DUMP; > out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto); > out_hdr->sadb_msg_errno = 0; > out_hdr->sadb_msg_reserved = 0; > out_hdr->sadb_msg_seq = count; >- out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid; >- pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk); >+ out_hdr->sadb_msg_pid = pfk->dump.msg_pid; >+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk); > return 0; > } > >+static int pfkey_dump_sa(struct pfkey_sock *pfk) >+{ >+ return xfrm_state_walk(&pfk->dump.u.state, dump_sa, (void *) pfk); >+} >+ >+static void pfkey_dump_sa_done(struct pfkey_sock *pfk) >+{ >+ xfrm_state_walk_done(&pfk->dump.u.state); >+} >+ > static int pfkey_dump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) > { > u8 proto; >- struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk }; >+ struct pfkey_sock *pfk = pfkey_sk(sk); >+ >+ if (pfk->dump.dump != NULL) >+ return -EBUSY; > > proto = pfkey_satype2proto(hdr->sadb_msg_satype); > if (proto == 0) > return -EINVAL; > >- return xfrm_state_walk(proto, dump_sa, &data); >+ pfk->dump.msg_version = hdr->sadb_msg_version; >+ pfk->dump.msg_pid = hdr->sadb_msg_pid; >+ pfk->dump.dump = pfkey_dump_sa; >+ pfk->dump.done = pfkey_dump_sa_done; >+ xfrm_state_walk_init(&pfk->dump.u.state, proto); >+ >+ return pfkey_do_dump(pfk); > } > > static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) >@@ -1780,7 +1827,9 @@ > > static u32 gen_reqid(void) > { >+ struct xfrm_policy_walk walk; > u32 start; >+ int rc; > static u32 reqid = IPSEC_MANUAL_REQID_MAX; > > start = reqid; >@@ -1788,8 +1837,10 @@ > ++reqid; > if (reqid == 0) > reqid = IPSEC_MANUAL_REQID_MAX+1; >- if (xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, check_reqid, >- (void*)&reqid) != -EEXIST) >+ xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); >+ rc = xfrm_policy_walk(&walk, check_reqid, (void*)&reqid); >+ xfrm_policy_walk_done(&walk); >+ if (rc != -EEXIST) > return reqid; > } while (reqid != start); > return 0; >@@ -2638,11 +2689,14 @@ > > static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) > { >- struct pfkey_dump_data *data = ptr; >+ struct pfkey_sock *pfk = ptr; > struct sk_buff *out_skb; > struct sadb_msg *out_hdr; > int err; > >+ if (!pfkey_can_dump(&pfk->sk)) >+ return -ENOBUFS; >+ > out_skb = pfkey_xfrm_policy2msg_prep(xp); > if (IS_ERR(out_skb)) > return PTR_ERR(out_skb); >@@ -2652,21 +2706,40 @@ > return err; > > out_hdr = (struct sadb_msg *) out_skb->data; >- out_hdr->sadb_msg_version = data->hdr->sadb_msg_version; >+ out_hdr->sadb_msg_version = pfk->dump.msg_version; > out_hdr->sadb_msg_type = SADB_X_SPDDUMP; > out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; > out_hdr->sadb_msg_errno = 0; > out_hdr->sadb_msg_seq = count; >- out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid; >- pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk); >+ out_hdr->sadb_msg_pid = pfk->dump.msg_pid; >+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk); > return 0; > } > >+static int pfkey_dump_sp(struct pfkey_sock *pfk) >+{ >+ return xfrm_policy_walk(&pfk->dump.u.policy, dump_sp, (void *) pfk); >+} >+ >+static void pfkey_dump_sp_done(struct pfkey_sock *pfk) >+{ >+ xfrm_policy_walk_done(&pfk->dump.u.policy); >+} >+ > static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) > { >- struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk }; >+ struct pfkey_sock *pfk = pfkey_sk(sk); >+ >+ if (pfk->dump.dump != NULL) >+ return -EBUSY; >+ >+ pfk->dump.msg_version = hdr->sadb_msg_version; >+ pfk->dump.msg_pid = hdr->sadb_msg_pid; >+ pfk->dump.dump = pfkey_dump_sp; >+ pfk->dump.done = pfkey_dump_sp_done; >+ xfrm_policy_walk_init(&pfk->dump.u.policy, XFRM_POLICY_TYPE_MAIN); > >- return xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_sp, &data); >+ return pfkey_do_dump(pfk); > } > > static int key_notify_policy_flush(struct km_event *c) >@@ -3672,6 +3745,7 @@ > int flags) > { > struct sock *sk = sock->sk; >+ struct pfkey_sock *pfk = pfkey_sk(sk); > struct sk_buff *skb; > int copied, err; > >@@ -3699,6 +3773,10 @@ > > err = (flags & MSG_TRUNC) ? skb->len : copied; > >+ if (pfk->dump.dump != NULL && >+ 3 * atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) >+ pfkey_do_dump(pfk); >+ > out_free: > skb_free_datagram(sk, skb); > out: >Index: linux-2.6.24/net/xfrm/xfrm_policy.c >=================================================================== >--- linux-2.6.24.orig/net/xfrm/xfrm_policy.c 2008-03-05 08:59:14.000000000 +0200 >+++ linux-2.6.24/net/xfrm/xfrm_policy.c 2008-03-05 09:00:19.000000000 +0200 >@@ -35,6 +35,7 @@ > > static DEFINE_RWLOCK(xfrm_policy_lock); > >+static struct list_head xfrm_policy_bytype[XFRM_POLICY_TYPE_MAX]; > unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; > EXPORT_SYMBOL(xfrm_policy_count); > >@@ -192,6 +193,7 @@ > policy = kzalloc(sizeof(struct xfrm_policy), gfp); > > if (policy) { >+ INIT_LIST_HEAD(&policy->bytype); > INIT_HLIST_NODE(&policy->bydst); > INIT_HLIST_NODE(&policy->byidx); > rwlock_init(&policy->lock); >@@ -215,6 +217,10 @@ > if (del_timer(&policy->timer)) > BUG(); > >+ write_lock_bh(&xfrm_policy_lock); >+ list_del(&policy->bytype); >+ write_unlock_bh(&xfrm_policy_lock); >+ > security_xfrm_policy_free(policy); > kfree(policy); > } >@@ -553,6 +559,7 @@ > policy->curlft.use_time = 0; > if (!mod_timer(&policy->timer, jiffies + HZ)) > xfrm_pol_hold(policy); >+ list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]); > write_unlock_bh(&xfrm_policy_lock); > > if (delpol) >@@ -791,57 +798,60 @@ > } > EXPORT_SYMBOL(xfrm_policy_flush); > >-int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), >+int xfrm_policy_walk(struct xfrm_policy_walk *walk, >+ int (*func)(struct xfrm_policy *, int, int, void*), > void *data) > { >- struct xfrm_policy *pol, *last = NULL; >- struct hlist_node *entry; >- int dir, last_dir = 0, count, error; >+ struct xfrm_policy *old, *pol, *last = NULL; >+ int error = 0; >+ >+ if (walk->type >= XFRM_POLICY_TYPE_MAX && >+ walk->type != XFRM_POLICY_TYPE_ANY) >+ return -EINVAL; > >+ if (walk->policy == NULL && walk->count != 0) >+ return 0; >+ >+ old = pol = walk->policy; >+ walk->policy = NULL; > read_lock_bh(&xfrm_policy_lock); >- count = 0; > >- for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { >- struct hlist_head *table = xfrm_policy_bydst[dir].table; >- int i; >+ for (; walk->cur_type < XFRM_POLICY_TYPE_MAX; walk->cur_type++) { >+ if (walk->type != walk->cur_type && >+ walk->type != XFRM_POLICY_TYPE_ANY) >+ continue; > >- hlist_for_each_entry(pol, entry, >- &xfrm_policy_inexact[dir], bydst) { >- if (pol->type != type) >+ if (pol == NULL) { >+ pol = list_first_entry(&xfrm_policy_bytype[walk->cur_type], >+ struct xfrm_policy, bytype); >+ } >+ list_for_each_entry_from(pol, &xfrm_policy_bytype[walk->cur_type], bytype) { >+ if (pol->dead) > continue; > if (last) { >- error = func(last, last_dir % XFRM_POLICY_MAX, >- count, data); >- if (error) >+ error = func(last, xfrm_policy_id2dir(last->index), >+ walk->count, data); >+ if (error) { >+ xfrm_pol_hold(last); >+ walk->policy = last; > goto out; >- } >- last = pol; >- last_dir = dir; >- count++; >- } >- for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { >- hlist_for_each_entry(pol, entry, table + i, bydst) { >- if (pol->type != type) >- continue; >- if (last) { >- error = func(last, last_dir % XFRM_POLICY_MAX, >- count, data); >- if (error) >- goto out; > } >- last = pol; >- last_dir = dir; >- count++; > } >+ last = pol; >+ walk->count++; > } >+ pol = NULL; > } >- if (count == 0) { >+ if (walk->count == 0) { > error = -ENOENT; > goto out; > } >- error = func(last, last_dir % XFRM_POLICY_MAX, 0, data); >+ if (last) >+ error = func(last, xfrm_policy_id2dir(last->index), 0, data); > out: > read_unlock_bh(&xfrm_policy_lock); >+ if (old != NULL) >+ xfrm_pol_put(old); > return error; > } > EXPORT_SYMBOL(xfrm_policy_walk); >@@ -2112,6 +2122,9 @@ > panic("XFRM: failed to allocate bydst hash\n"); > } > >+ for (dir = 0; dir < XFRM_POLICY_TYPE_MAX; dir++) >+ INIT_LIST_HEAD(&xfrm_policy_bytype[dir]); >+ > INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task); > register_netdevice_notifier(&xfrm_dev_notifier); > } >Index: linux-2.6.24/net/xfrm/xfrm_state.c >=================================================================== >--- linux-2.6.24.orig/net/xfrm/xfrm_state.c 2008-03-05 08:59:14.000000000 +0200 >+++ linux-2.6.24/net/xfrm/xfrm_state.c 2008-03-05 09:00:19.000000000 +0200 >@@ -49,6 +49,7 @@ > * Main use is finding SA after policy selected tunnel or transport mode. > * Also, it can be used by ah/esp icmp error handler to find offending SA. > */ >+static LIST_HEAD(xfrm_state_all); > static struct hlist_head *xfrm_state_bydst __read_mostly; > static struct hlist_head *xfrm_state_bysrc __read_mostly; > static struct hlist_head *xfrm_state_byspi __read_mostly; >@@ -501,6 +502,7 @@ > if (x) { > atomic_set(&x->refcnt, 1); > atomic_set(&x->tunnel_users, 0); >+ INIT_LIST_HEAD(&x->all); > INIT_HLIST_NODE(&x->bydst); > INIT_HLIST_NODE(&x->bysrc); > INIT_HLIST_NODE(&x->byspi); >@@ -527,6 +529,10 @@ > { > BUG_TRAP(x->km.state == XFRM_STATE_DEAD); > >+ spin_lock_bh(&xfrm_state_lock); >+ list_del(&x->all); >+ spin_unlock_bh(&xfrm_state_lock); >+ > spin_lock_bh(&xfrm_state_gc_lock); > hlist_add_head(&x->bydst, &xfrm_state_gc_list); > spin_unlock_bh(&xfrm_state_gc_lock); >@@ -901,6 +907,8 @@ > > x->genid = ++xfrm_state_genid; > >+ list_add_tail(&x->all, &xfrm_state_all); >+ > h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr, > x->props.reqid, x->props.family); > hlist_add_head(&x->bydst, xfrm_state_bydst+h); >@@ -1511,36 +1519,47 @@ > } > EXPORT_SYMBOL(xfrm_alloc_spi); > >-int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), >+int xfrm_state_walk(struct xfrm_state_walk *walk, >+ int (*func)(struct xfrm_state *, int, void*), > void *data) > { >- int i; >- struct xfrm_state *x, *last = NULL; >- struct hlist_node *entry; >- int count = 0; >+ struct xfrm_state *old, *x, *last = NULL; > int err = 0; > >+ if (walk->state == NULL && walk->count != 0) >+ return 0; >+ >+ old = x = walk->state; >+ walk->state = NULL; > spin_lock_bh(&xfrm_state_lock); >- for (i = 0; i <= xfrm_state_hmask; i++) { >- hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { >- if (!xfrm_id_proto_match(x->id.proto, proto)) >- continue; >- if (last) { >- err = func(last, count, data); >- if (err) >- goto out; >+ if (x == NULL) >+ x = list_first_entry(&xfrm_state_all, struct xfrm_state, all); >+ list_for_each_entry_from(x, &xfrm_state_all, all) { >+ if (x->km.state == XFRM_STATE_DEAD) >+ continue; >+ if (!xfrm_id_proto_match(x->id.proto, walk->proto)) >+ continue; >+ if (last) { >+ err = func(last, walk->count, data); >+ if (err) { >+ xfrm_state_hold(last); >+ walk->state = last; >+ goto out; > } >- last = x; >- count++; > } >+ last = x; >+ walk->count++; > } >- if (count == 0) { >+ if (walk->count == 0) { > err = -ENOENT; > goto out; > } >- err = func(last, 0, data); >+ if (last) >+ err = func(last, 0, data); > out: > spin_unlock_bh(&xfrm_state_lock); >+ if (old != NULL) >+ xfrm_state_put(old); > return err; > } > EXPORT_SYMBOL(xfrm_state_walk); >Index: linux-2.6.24/net/xfrm/xfrm_user.c >=================================================================== >--- linux-2.6.24.orig/net/xfrm/xfrm_user.c 2008-03-05 08:59:14.000000000 +0200 >+++ linux-2.6.24/net/xfrm/xfrm_user.c 2008-03-05 09:00:19.000000000 +0200 >@@ -472,8 +472,6 @@ > struct sk_buff *out_skb; > u32 nlmsg_seq; > u16 nlmsg_flags; >- int start_idx; >- int this_idx; > }; > > static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb) >@@ -538,9 +536,6 @@ > struct nlmsghdr *nlh; > int err; > >- if (sp->this_idx < sp->start_idx) >- goto out; >- > nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq, > XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags); > if (nlh == NULL) >@@ -553,8 +548,6 @@ > goto nla_put_failure; > > nlmsg_end(skb, nlh); >-out: >- sp->this_idx++; > return 0; > > nla_put_failure: >@@ -562,18 +555,32 @@ > return err; > } > >+static int xfrm_dump_sa_done(struct netlink_callback *cb) >+{ >+ struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; >+ xfrm_state_walk_done(walk); >+ return 0; >+} >+ > static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) > { >+ struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; > struct xfrm_dump_info info; > >+ BUILD_BUG_ON(sizeof(struct xfrm_state_walk) > >+ sizeof(cb->args) - sizeof(cb->args[0])); >+ > info.in_skb = cb->skb; > info.out_skb = skb; > info.nlmsg_seq = cb->nlh->nlmsg_seq; > info.nlmsg_flags = NLM_F_MULTI; >- info.this_idx = 0; >- info.start_idx = cb->args[0]; >- (void) xfrm_state_walk(0, dump_one_state, &info); >- cb->args[0] = info.this_idx; >+ >+ if (!cb->args[0]) { >+ cb->args[0] = 1; >+ xfrm_state_walk_init(walk, 0); >+ } >+ >+ (void) xfrm_state_walk(walk, dump_one_state, &info); > > return skb->len; > } >@@ -592,7 +599,6 @@ > info.out_skb = skb; > info.nlmsg_seq = seq; > info.nlmsg_flags = 0; >- info.this_idx = info.start_idx = 0; > > if (dump_one_state(x, 0, &info)) { > kfree_skb(skb); >@@ -1169,9 +1175,6 @@ > struct sk_buff *skb = sp->out_skb; > struct nlmsghdr *nlh; > >- if (sp->this_idx < sp->start_idx) >- goto out; >- > nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq, > XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags); > if (nlh == NULL) >@@ -1187,8 +1190,6 @@ > goto nlmsg_failure; > > nlmsg_end(skb, nlh); >-out: >- sp->this_idx++; > return 0; > > nlmsg_failure: >@@ -1196,21 +1197,33 @@ > return -EMSGSIZE; > } > >+static int xfrm_dump_policy_done(struct netlink_callback *cb) >+{ >+ struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; >+ >+ xfrm_policy_walk_done(walk); >+ return 0; >+} >+ > static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) > { >+ struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; > struct xfrm_dump_info info; > >+ BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) > >+ sizeof(cb->args) - sizeof(cb->args[0])); >+ > info.in_skb = cb->skb; > info.out_skb = skb; > info.nlmsg_seq = cb->nlh->nlmsg_seq; > info.nlmsg_flags = NLM_F_MULTI; >- info.this_idx = 0; >- info.start_idx = cb->args[0]; >- (void) xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_one_policy, &info); >-#ifdef CONFIG_XFRM_SUB_POLICY >- (void) xfrm_policy_walk(XFRM_POLICY_TYPE_SUB, dump_one_policy, &info); >-#endif >- cb->args[0] = info.this_idx; >+ >+ if (!cb->args[0]) { >+ cb->args[0] = 1; >+ xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY); >+ } >+ >+ (void) xfrm_policy_walk(walk, dump_one_policy, &info); > > return skb->len; > } >@@ -1230,7 +1243,6 @@ > info.out_skb = skb; > info.nlmsg_seq = seq; > info.nlmsg_flags = 0; >- info.this_idx = info.start_idx = 0; > > if (dump_one_policy(xp, dir, 0, &info) < 0) { > kfree_skb(skb); >@@ -1827,15 +1839,18 @@ > static struct xfrm_link { > int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **); > int (*dump)(struct sk_buff *, struct netlink_callback *); >+ int (*done)(struct netlink_callback *); > } xfrm_dispatch[XFRM_NR_MSGTYPES] = { > [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, > [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa }, > [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa, >- .dump = xfrm_dump_sa }, >+ .dump = xfrm_dump_sa, >+ .done = xfrm_dump_sa_done }, > [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, > [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy }, > [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, >- .dump = xfrm_dump_policy }, >+ .dump = xfrm_dump_policy, >+ .done = xfrm_dump_policy_done }, > [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, > [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire }, > [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_sa_expire }, >@@ -1874,7 +1889,7 @@ > if (link->dump == NULL) > return -EINVAL; > >- return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, NULL); >+ return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, link->done); > } > > err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 212381
: 145344