Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / net / netfilter / ipset / ip_set_list_set.c
index 0ed19b5e675e62859845bbfcbd79a8ad011589a6..3e2317f3cf68625848edf5bc1d270b37d7d2af51 100644 (file)
@@ -16,7 +16,8 @@
 #include <linux/netfilter/ipset/ip_set_list.h>
 
 #define IPSET_TYPE_REV_MIN     0
-#define IPSET_TYPE_REV_MAX     1 /* Counters support added */
+/*                             1    Counters support added */
+#define IPSET_TYPE_REV_MAX     2 /* Comments support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
@@ -28,28 +29,6 @@ struct set_elem {
        ip_set_id_t id;
 };
 
-struct sett_elem {
-       struct {
-               ip_set_id_t id;
-       } __attribute__ ((aligned));
-       unsigned long timeout;
-};
-
-struct setc_elem {
-       struct {
-               ip_set_id_t id;
-       } __attribute__ ((aligned));
-       struct ip_set_counter counter;
-};
-
-struct setct_elem {
-       struct {
-               ip_set_id_t id;
-       } __attribute__ ((aligned));
-       struct ip_set_counter counter;
-       unsigned long timeout;
-};
-
 struct set_adt_elem {
        ip_set_id_t id;
        ip_set_id_t refid;
@@ -58,24 +37,14 @@ struct set_adt_elem {
 
 /* Type structure */
 struct list_set {
-       size_t dsize;           /* element size */
-       size_t offset[IPSET_EXT_ID_MAX]; /* Offsets to extensions */
        u32 size;               /* size of set list array */
-       u32 timeout;            /* timeout value */
        struct timer_list gc;   /* garbage collection */
+       struct net *net;        /* namespace */
        struct set_elem members[0]; /* the set members */
 };
 
-static inline struct set_elem *
-list_set_elem(const struct list_set *map, u32 id)
-{
-       return (struct set_elem *)((void *)map->members + id * map->dsize);
-}
-
-#define ext_timeout(e, m)      \
-(unsigned long *)((void *)(e) + (m)->offset[IPSET_EXT_ID_TIMEOUT])
-#define ext_counter(e, m)      \
-(struct ip_set_counter *)((void *)(e) + (m)->offset[IPSET_EXT_ID_COUNTER])
+#define list_set_elem(set, map, id)    \
+       (struct set_elem *)((void *)(map)->members + (id) * (set)->dsize)
 
 static int
 list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
@@ -92,16 +61,16 @@ list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
        if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)
                opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE;
        for (i = 0; i < map->size; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                if (e->id == IPSET_INVALID_ID)
                        return 0;
                if (SET_WITH_TIMEOUT(set) &&
-                   ip_set_timeout_expired(ext_timeout(e, map)))
+                   ip_set_timeout_expired(ext_timeout(e, set)))
                        continue;
                ret = ip_set_test(e->id, skb, par, opt);
                if (ret > 0) {
                        if (SET_WITH_COUNTER(set))
-                               ip_set_update_counter(ext_counter(e, map),
+                               ip_set_update_counter(ext_counter(e, set),
                                                      ext, &opt->ext,
                                                      cmdflags);
                        return ret;
@@ -121,11 +90,11 @@ list_set_kadd(struct ip_set *set, const struct sk_buff *skb,
        int ret;
 
        for (i = 0; i < map->size; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                if (e->id == IPSET_INVALID_ID)
                        return 0;
                if (SET_WITH_TIMEOUT(set) &&
-                   ip_set_timeout_expired(ext_timeout(e, map)))
+                   ip_set_timeout_expired(ext_timeout(e, set)))
                        continue;
                ret = ip_set_add(e->id, skb, par, opt);
                if (ret == 0)
@@ -145,11 +114,11 @@ list_set_kdel(struct ip_set *set, const struct sk_buff *skb,
        int ret;
 
        for (i = 0; i < map->size; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                if (e->id == IPSET_INVALID_ID)
                        return 0;
                if (SET_WITH_TIMEOUT(set) &&
-                   ip_set_timeout_expired(ext_timeout(e, map)))
+                   ip_set_timeout_expired(ext_timeout(e, set)))
                        continue;
                ret = ip_set_del(e->id, skb, par, opt);
                if (ret == 0)
@@ -163,8 +132,7 @@ list_set_kadt(struct ip_set *set, const struct sk_buff *skb,
              const struct xt_action_param *par,
              enum ipset_adt adt, struct ip_set_adt_opt *opt)
 {
-       struct list_set *map = set->data;
-       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map);
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
 
        switch (adt) {
        case IPSET_TEST:
@@ -188,10 +156,10 @@ id_eq(const struct ip_set *set, u32 i, ip_set_id_t id)
        if (i >= map->size)
                return 0;
 
-       e = list_set_elem(map, i);
+       e = list_set_elem(set, map, i);
        return !!(e->id == id &&
                 !(SET_WITH_TIMEOUT(set) &&
-                  ip_set_timeout_expired(ext_timeout(e, map))));
+                  ip_set_timeout_expired(ext_timeout(e, set))));
 }
 
 static int
@@ -199,28 +167,36 @@ list_set_add(struct ip_set *set, u32 i, struct set_adt_elem *d,
             const struct ip_set_ext *ext)
 {
        struct list_set *map = set->data;
-       struct set_elem *e = list_set_elem(map, i);
+       struct set_elem *e = list_set_elem(set, map, i);
 
        if (e->id != IPSET_INVALID_ID) {
-               if (i == map->size - 1)
+               if (i == map->size - 1) {
                        /* Last element replaced: e.g. add new,before,last */
-                       ip_set_put_byindex(e->id);
-               else {
-                       struct set_elem *x = list_set_elem(map, map->size - 1);
+                       ip_set_put_byindex(map->net, e->id);
+                       ip_set_ext_destroy(set, e);
+               } else {
+                       struct set_elem *x = list_set_elem(set, map,
+                                                          map->size - 1);
 
                        /* Last element pushed off */
-                       if (x->id != IPSET_INVALID_ID)
-                               ip_set_put_byindex(x->id);
-                       memmove(list_set_elem(map, i + 1), e,
-                               map->dsize * (map->size - (i + 1)));
+                       if (x->id != IPSET_INVALID_ID) {
+                               ip_set_put_byindex(map->net, x->id);
+                               ip_set_ext_destroy(set, x);
+                       }
+                       memmove(list_set_elem(set, map, i + 1), e,
+                               set->dsize * (map->size - (i + 1)));
+                       /* Extensions must be initialized to zero */
+                       memset(e, 0, set->dsize);
                }
        }
 
        e->id = d->id;
        if (SET_WITH_TIMEOUT(set))
-               ip_set_timeout_set(ext_timeout(e, map), ext->timeout);
+               ip_set_timeout_set(ext_timeout(e, set), ext->timeout);
        if (SET_WITH_COUNTER(set))
-               ip_set_init_counter(ext_counter(e, map), ext);
+               ip_set_init_counter(ext_counter(e, set), ext);
+       if (SET_WITH_COMMENT(set))
+               ip_set_init_comment(ext_comment(e, set), ext);
        return 0;
 }
 
@@ -228,16 +204,17 @@ static int
 list_set_del(struct ip_set *set, u32 i)
 {
        struct list_set *map = set->data;
-       struct set_elem *e = list_set_elem(map, i);
+       struct set_elem *e = list_set_elem(set, map, i);
 
-       ip_set_put_byindex(e->id);
+       ip_set_put_byindex(map->net, e->id);
+       ip_set_ext_destroy(set, e);
 
        if (i < map->size - 1)
-               memmove(e, list_set_elem(map, i + 1),
-                       map->dsize * (map->size - (i + 1)));
+               memmove(e, list_set_elem(set, map, i + 1),
+                       set->dsize * (map->size - (i + 1)));
 
        /* Last element */
-       e = list_set_elem(map, map->size - 1);
+       e = list_set_elem(set, map, map->size - 1);
        e->id = IPSET_INVALID_ID;
        return 0;
 }
@@ -247,13 +224,16 @@ set_cleanup_entries(struct ip_set *set)
 {
        struct list_set *map = set->data;
        struct set_elem *e;
-       u32 i;
+       u32 i = 0;
 
-       for (i = 0; i < map->size; i++) {
-               e = list_set_elem(map, i);
+       while (i < map->size) {
+               e = list_set_elem(set, map, i);
                if (e->id != IPSET_INVALID_ID &&
-                   ip_set_timeout_expired(ext_timeout(e, map)))
+                   ip_set_timeout_expired(ext_timeout(e, set)))
                        list_set_del(set, i);
+                       /* Check element moved to position i in next loop */
+               else
+                       i++;
        }
 }
 
@@ -268,11 +248,11 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext,
        int ret;
 
        for (i = 0; i < map->size; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                if (e->id == IPSET_INVALID_ID)
                        return 0;
                else if (SET_WITH_TIMEOUT(set) &&
-                        ip_set_timeout_expired(ext_timeout(e, map)))
+                        ip_set_timeout_expired(ext_timeout(e, set)))
                        continue;
                else if (e->id != d->id)
                        continue;
@@ -299,14 +279,14 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
        bool flag_exist = flags & IPSET_FLAG_EXIST;
        u32 i, ret = 0;
 
+       if (SET_WITH_TIMEOUT(set))
+               set_cleanup_entries(set);
+
        /* Check already added element */
        for (i = 0; i < map->size; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                if (e->id == IPSET_INVALID_ID)
                        goto insert;
-               else if (SET_WITH_TIMEOUT(set) &&
-                        ip_set_timeout_expired(ext_timeout(e, map)))
-                       continue;
                else if (e->id != d->id)
                        continue;
 
@@ -319,18 +299,22 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
                        /* Can't re-add */
                        return -IPSET_ERR_EXIST;
                /* Update extensions */
+               ip_set_ext_destroy(set, e);
+
                if (SET_WITH_TIMEOUT(set))
-                       ip_set_timeout_set(ext_timeout(e, map), ext->timeout);
+                       ip_set_timeout_set(ext_timeout(e, set), ext->timeout);
                if (SET_WITH_COUNTER(set))
-                       ip_set_init_counter(ext_counter(e, map), ext);
+                       ip_set_init_counter(ext_counter(e, set), ext);
+               if (SET_WITH_COMMENT(set))
+                       ip_set_init_comment(ext_comment(e, set), ext);
                /* Set is already added to the list */
-               ip_set_put_byindex(d->id);
+               ip_set_put_byindex(map->net, d->id);
                return 0;
        }
 insert:
        ret = -IPSET_ERR_LIST_FULL;
        for (i = 0; i < map->size && ret == -IPSET_ERR_LIST_FULL; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                if (e->id == IPSET_INVALID_ID)
                        ret = d->before != 0 ? -IPSET_ERR_REF_EXIST
                                : list_set_add(set, i, d, ext);
@@ -355,12 +339,12 @@ list_set_udel(struct ip_set *set, void *value, const struct ip_set_ext *ext,
        u32 i;
 
        for (i = 0; i < map->size; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                if (e->id == IPSET_INVALID_ID)
                        return d->before != 0 ? -IPSET_ERR_REF_EXIST
                                              : -IPSET_ERR_EXIST;
                else if (SET_WITH_TIMEOUT(set) &&
-                        ip_set_timeout_expired(ext_timeout(e, map)))
+                        ip_set_timeout_expired(ext_timeout(e, set)))
                        continue;
                else if (e->id != d->id)
                        continue;
@@ -386,7 +370,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
        struct list_set *map = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct set_adt_elem e = { .refid = IPSET_INVALID_ID };
-       struct ip_set_ext ext = IP_SET_INIT_UEXT(map);
+       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
        struct ip_set *s;
        int ret = 0;
 
@@ -403,7 +387,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
        ret = ip_set_get_extensions(set, tb, &ext);
        if (ret)
                return ret;
-       e.id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s);
+       e.id = ip_set_get_byname(map->net, nla_data(tb[IPSET_ATTR_NAME]), &s);
        if (e.id == IPSET_INVALID_ID)
                return -IPSET_ERR_NAME;
        /* "Loop detection" */
@@ -423,7 +407,8 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
        }
 
        if (tb[IPSET_ATTR_NAMEREF]) {
-               e.refid = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAMEREF]),
+               e.refid = ip_set_get_byname(map->net,
+                                           nla_data(tb[IPSET_ATTR_NAMEREF]),
                                            &s);
                if (e.refid == IPSET_INVALID_ID) {
                        ret = -IPSET_ERR_NAMEREF;
@@ -439,9 +424,9 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
 
 finish:
        if (e.refid != IPSET_INVALID_ID)
-               ip_set_put_byindex(e.refid);
+               ip_set_put_byindex(map->net, e.refid);
        if (adt != IPSET_ADD || ret)
-               ip_set_put_byindex(e.id);
+               ip_set_put_byindex(map->net, e.id);
 
        return ip_set_eexist(ret, flags) ? 0 : ret;
 }
@@ -454,9 +439,10 @@ list_set_flush(struct ip_set *set)
        u32 i;
 
        for (i = 0; i < map->size; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                if (e->id != IPSET_INVALID_ID) {
-                       ip_set_put_byindex(e->id);
+                       ip_set_put_byindex(map->net, e->id);
+                       ip_set_ext_destroy(set, e);
                        e->id = IPSET_INVALID_ID;
                }
        }
@@ -485,14 +471,11 @@ list_set_head(struct ip_set *set, struct sk_buff *skb)
        if (!nested)
                goto nla_put_failure;
        if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) ||
-           (SET_WITH_TIMEOUT(set) &&
-            nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) ||
-           (SET_WITH_COUNTER(set) &&
-            nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
-                          htonl(IPSET_FLAG_WITH_COUNTERS))) ||
            nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
            nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
-                         htonl(sizeof(*map) + map->size * map->dsize)))
+                         htonl(sizeof(*map) + map->size * set->dsize)))
+               goto nla_put_failure;
+       if (unlikely(ip_set_put_flags(skb, set)))
                goto nla_put_failure;
        ipset_nest_end(skb, nested);
 
@@ -507,19 +490,20 @@ list_set_list(const struct ip_set *set,
 {
        const struct list_set *map = set->data;
        struct nlattr *atd, *nested;
-       u32 i, first = cb->args[2];
+       u32 i, first = cb->args[IPSET_CB_ARG0];
        const struct set_elem *e;
 
        atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
        if (!atd)
                return -EMSGSIZE;
-       for (; cb->args[2] < map->size; cb->args[2]++) {
-               i = cb->args[2];
-               e = list_set_elem(map, i);
+       for (; cb->args[IPSET_CB_ARG0] < map->size;
+            cb->args[IPSET_CB_ARG0]++) {
+               i = cb->args[IPSET_CB_ARG0];
+               e = list_set_elem(set, map, i);
                if (e->id == IPSET_INVALID_ID)
                        goto finish;
                if (SET_WITH_TIMEOUT(set) &&
-                   ip_set_timeout_expired(ext_timeout(e, map)))
+                   ip_set_timeout_expired(ext_timeout(e, set)))
                        continue;
                nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
                if (!nested) {
@@ -530,28 +514,22 @@ list_set_list(const struct ip_set *set,
                                goto nla_put_failure;
                }
                if (nla_put_string(skb, IPSET_ATTR_NAME,
-                                  ip_set_name_byindex(e->id)))
+                                  ip_set_name_byindex(map->net, e->id)))
                        goto nla_put_failure;
-               if (SET_WITH_TIMEOUT(set) &&
-                   nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
-                                 htonl(ip_set_timeout_get(
-                                               ext_timeout(e, map)))))
-                       goto nla_put_failure;
-               if (SET_WITH_COUNTER(set) &&
-                   ip_set_put_counter(skb, ext_counter(e, map)))
+               if (ip_set_put_extensions(skb, set, e, true))
                        goto nla_put_failure;
                ipset_nest_end(skb, nested);
        }
 finish:
        ipset_nest_end(skb, atd);
        /* Set listing finished */
-       cb->args[2] = 0;
+       cb->args[IPSET_CB_ARG0] = 0;
        return 0;
 
 nla_put_failure:
        nla_nest_cancel(skb, nested);
        if (unlikely(i == first)) {
-               cb->args[2] = 0;
+               cb->args[IPSET_CB_ARG0] = 0;
                return -EMSGSIZE;
        }
        ipset_nest_end(skb, atd);
@@ -565,7 +543,7 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct list_set *y = b->data;
 
        return x->size == y->size &&
-              x->timeout == y->timeout &&
+              a->timeout == b->timeout &&
               a->extensions == b->extensions;
 }
 
@@ -594,7 +572,7 @@ list_set_gc(unsigned long ul_set)
        set_cleanup_entries(set);
        write_unlock_bh(&set->lock);
 
-       map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
+       map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
        add_timer(&map->gc);
 }
 
@@ -606,43 +584,40 @@ list_set_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
        init_timer(&map->gc);
        map->gc.data = (unsigned long) set;
        map->gc.function = gc;
-       map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
+       map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
        add_timer(&map->gc);
 }
 
 /* Create list:set type of sets */
 
-static struct list_set *
-init_list_set(struct ip_set *set, u32 size, size_t dsize,
-             unsigned long timeout)
+static bool
+init_list_set(struct net *net, struct ip_set *set, u32 size)
 {
        struct list_set *map;
        struct set_elem *e;
        u32 i;
 
-       map = kzalloc(sizeof(*map) + size * dsize, GFP_KERNEL);
+       map = kzalloc(sizeof(*map) + size * set->dsize, GFP_KERNEL);
        if (!map)
-               return NULL;
+               return false;
 
        map->size = size;
-       map->dsize = dsize;
-       map->timeout = timeout;
+       map->net = net;
        set->data = map;
 
        for (i = 0; i < size; i++) {
-               e = list_set_elem(map, i);
+               e = list_set_elem(set, map, i);
                e->id = IPSET_INVALID_ID;
        }
 
-       return map;
+       return true;
 }
 
 static int
-list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
+list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
+               u32 flags)
 {
-       struct list_set *map;
-       u32 size = IP_SET_LIST_DEFAULT_SIZE, cadt_flags = 0;
-       unsigned long timeout = 0;
+       u32 size = IP_SET_LIST_DEFAULT_SIZE;
 
        if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_SIZE) ||
                     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
@@ -654,45 +629,13 @@ list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        if (size < IP_SET_LIST_MIN_SIZE)
                size = IP_SET_LIST_MIN_SIZE;
 
-       if (tb[IPSET_ATTR_CADT_FLAGS])
-               cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
-       if (tb[IPSET_ATTR_TIMEOUT])
-               timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        set->variant = &set_variant;
-       if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
-               set->extensions |= IPSET_EXT_COUNTER;
-               if (tb[IPSET_ATTR_TIMEOUT]) {
-                       map = init_list_set(set, size,
-                                       sizeof(struct setct_elem), timeout);
-                       if (!map)
-                               return -ENOMEM;
-                       set->extensions |= IPSET_EXT_TIMEOUT;
-                       map->offset[IPSET_EXT_ID_TIMEOUT] =
-                               offsetof(struct setct_elem, timeout);
-                       map->offset[IPSET_EXT_ID_COUNTER] =
-                               offsetof(struct setct_elem, counter);
-                       list_set_gc_init(set, list_set_gc);
-               } else {
-                       map = init_list_set(set, size,
-                                           sizeof(struct setc_elem), 0);
-                       if (!map)
-                               return -ENOMEM;
-                       map->offset[IPSET_EXT_ID_COUNTER] =
-                               offsetof(struct setc_elem, counter);
-               }
-       } else if (tb[IPSET_ATTR_TIMEOUT]) {
-               map = init_list_set(set, size,
-                                   sizeof(struct sett_elem), timeout);
-               if (!map)
-                       return -ENOMEM;
-               set->extensions |= IPSET_EXT_TIMEOUT;
-               map->offset[IPSET_EXT_ID_TIMEOUT] =
-                       offsetof(struct sett_elem, timeout);
+       set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem));
+       if (!init_list_set(net, set, size))
+               return -ENOMEM;
+       if (tb[IPSET_ATTR_TIMEOUT]) {
+               set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
                list_set_gc_init(set, list_set_gc);
-       } else {
-               map = init_list_set(set, size, sizeof(struct set_elem), 0);
-               if (!map)
-                       return -ENOMEM;
        }
        return 0;
 }
@@ -721,6 +664,7 @@ static struct ip_set_type list_set_type __read_mostly = {
                [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
                [IPSET_ATTR_BYTES]      = { .type = NLA_U64 },
                [IPSET_ATTR_PACKETS]    = { .type = NLA_U64 },
+               [IPSET_ATTR_COMMENT]    = { .type = NLA_NUL_STRING },
        },
        .me             = THIS_MODULE,
 };