diff options
| -rw-r--r-- | net/netfilter/ipset/ip_set_list_set.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index a47c32982f06..f4a46c0d25f3 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c | |||
| @@ -43,14 +43,19 @@ struct list_set { | |||
| 43 | static inline struct set_elem * | 43 | static inline struct set_elem * |
| 44 | list_set_elem(const struct list_set *map, u32 id) | 44 | list_set_elem(const struct list_set *map, u32 id) |
| 45 | { | 45 | { |
| 46 | return (struct set_elem *)((char *)map->members + id * map->dsize); | 46 | return (struct set_elem *)((void *)map->members + id * map->dsize); |
| 47 | } | ||
| 48 | |||
| 49 | static inline struct set_telem * | ||
| 50 | list_set_telem(const struct list_set *map, u32 id) | ||
| 51 | { | ||
| 52 | return (struct set_telem *)((void *)map->members + id * map->dsize); | ||
| 47 | } | 53 | } |
| 48 | 54 | ||
| 49 | static inline bool | 55 | static inline bool |
| 50 | list_set_timeout(const struct list_set *map, u32 id) | 56 | list_set_timeout(const struct list_set *map, u32 id) |
| 51 | { | 57 | { |
| 52 | const struct set_telem *elem = | 58 | const struct set_telem *elem = list_set_telem(map, id); |
| 53 | (const struct set_telem *) list_set_elem(map, id); | ||
| 54 | 59 | ||
| 55 | return ip_set_timeout_test(elem->timeout); | 60 | return ip_set_timeout_test(elem->timeout); |
| 56 | } | 61 | } |
| @@ -58,19 +63,11 @@ list_set_timeout(const struct list_set *map, u32 id) | |||
| 58 | static inline bool | 63 | static inline bool |
| 59 | list_set_expired(const struct list_set *map, u32 id) | 64 | list_set_expired(const struct list_set *map, u32 id) |
| 60 | { | 65 | { |
| 61 | const struct set_telem *elem = | 66 | const struct set_telem *elem = list_set_telem(map, id); |
| 62 | (const struct set_telem *) list_set_elem(map, id); | ||
| 63 | 67 | ||
| 64 | return ip_set_timeout_expired(elem->timeout); | 68 | return ip_set_timeout_expired(elem->timeout); |
| 65 | } | 69 | } |
| 66 | 70 | ||
| 67 | static inline int | ||
| 68 | list_set_exist(const struct set_telem *elem) | ||
| 69 | { | ||
| 70 | return elem->id != IPSET_INVALID_ID && | ||
| 71 | !ip_set_timeout_expired(elem->timeout); | ||
| 72 | } | ||
| 73 | |||
| 74 | /* Set list without and with timeout */ | 71 | /* Set list without and with timeout */ |
| 75 | 72 | ||
| 76 | static int | 73 | static int |
| @@ -146,11 +143,11 @@ list_elem_tadd(struct list_set *map, u32 i, ip_set_id_t id, | |||
| 146 | struct set_telem *e; | 143 | struct set_telem *e; |
| 147 | 144 | ||
| 148 | for (; i < map->size; i++) { | 145 | for (; i < map->size; i++) { |
| 149 | e = (struct set_telem *)list_set_elem(map, i); | 146 | e = list_set_telem(map, i); |
| 150 | swap(e->id, id); | 147 | swap(e->id, id); |
| 148 | swap(e->timeout, timeout); | ||
| 151 | if (e->id == IPSET_INVALID_ID) | 149 | if (e->id == IPSET_INVALID_ID) |
| 152 | break; | 150 | break; |
| 153 | swap(e->timeout, timeout); | ||
| 154 | } | 151 | } |
| 155 | } | 152 | } |
| 156 | 153 | ||
| @@ -164,7 +161,7 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id, | |||
| 164 | /* Last element replaced: e.g. add new,before,last */ | 161 | /* Last element replaced: e.g. add new,before,last */ |
| 165 | ip_set_put_byindex(e->id); | 162 | ip_set_put_byindex(e->id); |
| 166 | if (with_timeout(map->timeout)) | 163 | if (with_timeout(map->timeout)) |
| 167 | list_elem_tadd(map, i, id, timeout); | 164 | list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); |
| 168 | else | 165 | else |
| 169 | list_elem_add(map, i, id); | 166 | list_elem_add(map, i, id); |
| 170 | 167 | ||
| @@ -172,11 +169,11 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id, | |||
| 172 | } | 169 | } |
| 173 | 170 | ||
| 174 | static int | 171 | static int |
| 175 | list_set_del(struct list_set *map, ip_set_id_t id, u32 i) | 172 | list_set_del(struct list_set *map, u32 i) |
| 176 | { | 173 | { |
| 177 | struct set_elem *a = list_set_elem(map, i), *b; | 174 | struct set_elem *a = list_set_elem(map, i), *b; |
| 178 | 175 | ||
| 179 | ip_set_put_byindex(id); | 176 | ip_set_put_byindex(a->id); |
| 180 | 177 | ||
| 181 | for (; i < map->size - 1; i++) { | 178 | for (; i < map->size - 1; i++) { |
| 182 | b = list_set_elem(map, i + 1); | 179 | b = list_set_elem(map, i + 1); |
| @@ -308,11 +305,11 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 308 | (before == 0 || | 305 | (before == 0 || |
| 309 | (before > 0 && | 306 | (before > 0 && |
| 310 | next_id_eq(map, i, refid)))) | 307 | next_id_eq(map, i, refid)))) |
| 311 | ret = list_set_del(map, id, i); | 308 | ret = list_set_del(map, i); |
| 312 | else if (before < 0 && | 309 | else if (before < 0 && |
| 313 | elem->id == refid && | 310 | elem->id == refid && |
| 314 | next_id_eq(map, i, id)) | 311 | next_id_eq(map, i, id)) |
| 315 | ret = list_set_del(map, id, i + 1); | 312 | ret = list_set_del(map, i + 1); |
| 316 | } | 313 | } |
| 317 | break; | 314 | break; |
| 318 | default: | 315 | default: |
| @@ -460,17 +457,15 @@ list_set_gc(unsigned long ul_set) | |||
| 460 | struct list_set *map = set->data; | 457 | struct list_set *map = set->data; |
| 461 | struct set_telem *e; | 458 | struct set_telem *e; |
| 462 | u32 i; | 459 | u32 i; |
| 463 | 460 | ||
| 464 | /* We run parallel with other readers (test element) | 461 | /* nfnl_lock should be called */ |
| 465 | * but adding/deleting new entries is locked out */ | 462 | write_lock_bh(&set->lock); |
| 466 | read_lock_bh(&set->lock); | 463 | for (i = 0; i < map->size; i++) { |
| 467 | for (i = map->size - 1; i >= 0; i--) { | 464 | e = list_set_telem(map, i); |
| 468 | e = (struct set_telem *) list_set_elem(map, i); | 465 | if (e->id != IPSET_INVALID_ID && list_set_expired(map, i)) |
| 469 | if (e->id != IPSET_INVALID_ID && | 466 | list_set_del(map, i); |
| 470 | list_set_expired(map, i)) | ||
| 471 | list_set_del(map, e->id, i); | ||
| 472 | } | 467 | } |
| 473 | read_unlock_bh(&set->lock); | 468 | write_unlock_bh(&set->lock); |
| 474 | 469 | ||
| 475 | map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; | 470 | map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; |
| 476 | add_timer(&map->gc); | 471 | add_timer(&map->gc); |
