|
@@ -860,33 +860,12 @@ EXPORT_SYMBOL(xfrm_policy_flush);
|
|
|
int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*),
|
|
|
void *data)
|
|
|
{
|
|
|
- struct xfrm_policy *pol;
|
|
|
+ struct xfrm_policy *pol, *last = NULL;
|
|
|
struct hlist_node *entry;
|
|
|
- int dir, count, error;
|
|
|
+ int dir, last_dir = 0, count, error;
|
|
|
|
|
|
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;
|
|
|
-
|
|
|
- hlist_for_each_entry(pol, entry,
|
|
|
- &xfrm_policy_inexact[dir], bydst) {
|
|
|
- if (pol->type == type)
|
|
|
- count++;
|
|
|
- }
|
|
|
- for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
|
|
|
- hlist_for_each_entry(pol, entry, table + i, bydst) {
|
|
|
- if (pol->type == type)
|
|
|
- count++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (count == 0) {
|
|
|
- error = -ENOENT;
|
|
|
- goto out;
|
|
|
- }
|
|
|
|
|
|
for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) {
|
|
|
struct hlist_head *table = xfrm_policy_bydst[dir].table;
|
|
@@ -896,21 +875,37 @@ int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*)
|
|
|
&xfrm_policy_inexact[dir], bydst) {
|
|
|
if (pol->type != type)
|
|
|
continue;
|
|
|
- error = func(pol, dir % XFRM_POLICY_MAX, --count, data);
|
|
|
- if (error)
|
|
|
- goto out;
|
|
|
+ if (last) {
|
|
|
+ error = func(last, last_dir % XFRM_POLICY_MAX,
|
|
|
+ count, data);
|
|
|
+ if (error)
|
|
|
+ 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;
|
|
|
- error = func(pol, dir % XFRM_POLICY_MAX, --count, data);
|
|
|
- if (error)
|
|
|
- goto out;
|
|
|
+ if (last) {
|
|
|
+ error = func(last, last_dir % XFRM_POLICY_MAX,
|
|
|
+ count, data);
|
|
|
+ if (error)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ last = pol;
|
|
|
+ last_dir = dir;
|
|
|
+ count++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- error = 0;
|
|
|
+ if (count == 0) {
|
|
|
+ error = -ENOENT;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ error = func(last, last_dir % XFRM_POLICY_MAX, 0, data);
|
|
|
out:
|
|
|
read_unlock_bh(&xfrm_policy_lock);
|
|
|
return error;
|