18 #include <netinet/in.h>
22 #include <libmnl/libmnl.h>
23 #include <linux/netfilter/nfnetlink.h>
24 #include <linux/netfilter/nf_tables.h>
26 #include <libnftnl/set.h>
27 #include <libnftnl/rule.h>
28 #include <libnftnl/expr.h>
30 EXPORT_SYMBOL(nftnl_set_elem_alloc);
31 struct nftnl_set_elem *nftnl_set_elem_alloc(
void)
33 struct nftnl_set_elem *s;
35 s = calloc(1,
sizeof(
struct nftnl_set_elem));
42 EXPORT_SYMBOL(nftnl_set_elem_free);
43 void nftnl_set_elem_free(
struct nftnl_set_elem *s)
45 if (s->flags & (1 << NFTNL_SET_ELEM_CHAIN))
48 if (s->flags & (1 << NFTNL_SET_ELEM_EXPR))
49 nftnl_expr_free(s->expr);
51 if (s->flags & (1 << NFTNL_SET_ELEM_USERDATA))
54 if (s->flags & (1 << NFTNL_SET_ELEM_OBJREF))
60 EXPORT_SYMBOL(nftnl_set_elem_is_set);
61 bool nftnl_set_elem_is_set(
const struct nftnl_set_elem *s, uint16_t attr)
63 return s->flags & (1 << attr);
66 EXPORT_SYMBOL(nftnl_set_elem_unset);
67 void nftnl_set_elem_unset(
struct nftnl_set_elem *s, uint16_t attr)
69 if (!(s->flags & (1 << attr)))
73 case NFTNL_SET_ELEM_CHAIN:
76 case NFTNL_SET_ELEM_FLAGS:
77 case NFTNL_SET_ELEM_KEY:
78 case NFTNL_SET_ELEM_VERDICT:
79 case NFTNL_SET_ELEM_DATA:
80 case NFTNL_SET_ELEM_TIMEOUT:
81 case NFTNL_SET_ELEM_EXPIRATION:
83 case NFTNL_SET_ELEM_USERDATA:
86 case NFTNL_SET_ELEM_EXPR:
87 nftnl_expr_free(s->expr);
89 case NFTNL_SET_ELEM_OBJREF:
96 s->flags &= ~(1 << attr);
99 EXPORT_SYMBOL(nftnl_set_elem_set);
100 int nftnl_set_elem_set(
struct nftnl_set_elem *s, uint16_t attr,
101 const void *data, uint32_t data_len)
104 case NFTNL_SET_ELEM_FLAGS:
105 memcpy(&s->set_elem_flags, data,
sizeof(s->set_elem_flags));
107 case NFTNL_SET_ELEM_KEY:
108 memcpy(&s->key.val, data, data_len);
109 s->key.len = data_len;
111 case NFTNL_SET_ELEM_VERDICT:
112 memcpy(&s->data.verdict, data,
sizeof(s->data.verdict));
114 case NFTNL_SET_ELEM_CHAIN:
115 if (s->flags & (1 << NFTNL_SET_ELEM_CHAIN))
116 xfree(s->data.chain);
118 s->data.chain = strdup(data);
122 case NFTNL_SET_ELEM_DATA:
123 memcpy(s->data.val, data, data_len);
124 s->data.len = data_len;
126 case NFTNL_SET_ELEM_TIMEOUT:
127 memcpy(&s->timeout, data,
sizeof(s->timeout));
129 case NFTNL_SET_ELEM_EXPIRATION:
130 memcpy(&s->expiration, data,
sizeof(s->expiration));
132 case NFTNL_SET_ELEM_USERDATA:
133 if (s->flags & (1 << NFTNL_SET_ELEM_USERDATA))
136 s->user.data = malloc(data_len);
139 memcpy(s->user.data, data, data_len);
140 s->user.len = data_len;
142 case NFTNL_SET_ELEM_OBJREF:
143 if (s->flags & (1 << NFTNL_SET_ELEM_OBJREF))
146 s->objref = strdup(data);
151 s->flags |= (1 << attr);
155 EXPORT_SYMBOL(nftnl_set_elem_set_u32);
156 void nftnl_set_elem_set_u32(
struct nftnl_set_elem *s, uint16_t attr, uint32_t val)
158 nftnl_set_elem_set(s, attr, &val,
sizeof(uint32_t));
161 EXPORT_SYMBOL(nftnl_set_elem_set_u64);
162 void nftnl_set_elem_set_u64(
struct nftnl_set_elem *s, uint16_t attr, uint64_t val)
164 nftnl_set_elem_set(s, attr, &val,
sizeof(uint64_t));
167 EXPORT_SYMBOL(nftnl_set_elem_set_str);
168 int nftnl_set_elem_set_str(
struct nftnl_set_elem *s, uint16_t attr,
const char *str)
170 return nftnl_set_elem_set(s, attr, str, strlen(str) + 1);
173 EXPORT_SYMBOL(nftnl_set_elem_get);
174 const void *nftnl_set_elem_get(
struct nftnl_set_elem *s, uint16_t attr, uint32_t *data_len)
176 if (!(s->flags & (1 << attr)))
180 case NFTNL_SET_ELEM_FLAGS:
181 *data_len =
sizeof(s->set_elem_flags);
182 return &s->set_elem_flags;
183 case NFTNL_SET_ELEM_KEY:
184 *data_len = s->key.len;
186 case NFTNL_SET_ELEM_VERDICT:
187 *data_len =
sizeof(s->data.verdict);
188 return &s->data.verdict;
189 case NFTNL_SET_ELEM_CHAIN:
190 *data_len = strlen(s->data.chain) + 1;
191 return s->data.chain;
192 case NFTNL_SET_ELEM_DATA:
193 *data_len = s->data.len;
195 case NFTNL_SET_ELEM_TIMEOUT:
196 *data_len =
sizeof(s->timeout);
198 case NFTNL_SET_ELEM_EXPIRATION:
199 *data_len =
sizeof(s->expiration);
200 return &s->expiration;
201 case NFTNL_SET_ELEM_USERDATA:
202 *data_len = s->user.len;
204 case NFTNL_SET_ELEM_EXPR:
206 case NFTNL_SET_ELEM_OBJREF:
207 *data_len = strlen(s->objref) + 1;
213 EXPORT_SYMBOL(nftnl_set_elem_get_str);
214 const char *nftnl_set_elem_get_str(
struct nftnl_set_elem *s, uint16_t attr)
218 return nftnl_set_elem_get(s, attr, &size);
221 EXPORT_SYMBOL(nftnl_set_elem_get_u32);
222 uint32_t nftnl_set_elem_get_u32(
struct nftnl_set_elem *s, uint16_t attr)
226 memcpy(&val, nftnl_set_elem_get(s, attr, &size),
sizeof(val));
231 EXPORT_SYMBOL(nftnl_set_elem_get_u64);
232 uint64_t nftnl_set_elem_get_u64(
struct nftnl_set_elem *s, uint16_t attr)
237 memcpy(&val, nftnl_set_elem_get(s, attr, &size),
sizeof(val));
242 struct nftnl_set_elem *nftnl_set_elem_clone(
struct nftnl_set_elem *elem)
244 struct nftnl_set_elem *newelem;
246 newelem = nftnl_set_elem_alloc();
250 memcpy(newelem, elem,
sizeof(*elem));
252 if (elem->flags & (1 << NFTNL_SET_ELEM_CHAIN)) {
253 newelem->data.chain = strdup(elem->data.chain);
254 if (!newelem->data.chain)
260 nftnl_set_elem_free(newelem);
264 void nftnl_set_elem_nlmsg_build_payload(
struct nlmsghdr *nlh,
265 struct nftnl_set_elem *e)
267 if (e->flags & (1 << NFTNL_SET_ELEM_FLAGS))
268 mnl_attr_put_u32(nlh, NFTA_SET_ELEM_FLAGS, htonl(e->set_elem_flags));
269 if (e->flags & (1 << NFTNL_SET_ELEM_TIMEOUT))
270 mnl_attr_put_u64(nlh, NFTA_SET_ELEM_TIMEOUT, htobe64(e->timeout));
271 if (e->flags & (1 << NFTNL_SET_ELEM_EXPIRATION))
272 mnl_attr_put_u64(nlh, NFTA_SET_ELEM_EXPIRATION, htobe64(e->expiration));
273 if (e->flags & (1 << NFTNL_SET_ELEM_KEY)) {
274 struct nlattr *nest1;
276 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_KEY);
277 mnl_attr_put(nlh, NFTA_DATA_VALUE, e->key.len, e->key.val);
278 mnl_attr_nest_end(nlh, nest1);
280 if (e->flags & (1 << NFTNL_SET_ELEM_VERDICT)) {
281 struct nlattr *nest1, *nest2;
283 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_DATA);
284 nest2 = mnl_attr_nest_start(nlh, NFTA_DATA_VERDICT);
285 mnl_attr_put_u32(nlh, NFTA_VERDICT_CODE, htonl(e->data.verdict));
286 if (e->flags & (1 << NFTNL_SET_ELEM_CHAIN))
287 mnl_attr_put_strz(nlh, NFTA_VERDICT_CHAIN, e->data.chain);
289 mnl_attr_nest_end(nlh, nest1);
290 mnl_attr_nest_end(nlh, nest2);
292 if (e->flags & (1 << NFTNL_SET_ELEM_DATA)) {
293 struct nlattr *nest1;
295 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_DATA);
296 mnl_attr_put(nlh, NFTA_DATA_VALUE, e->data.len, e->data.val);
297 mnl_attr_nest_end(nlh, nest1);
299 if (e->flags & (1 << NFTNL_SET_ELEM_USERDATA))
300 mnl_attr_put(nlh, NFTA_SET_ELEM_USERDATA, e->user.len, e->user.data);
301 if (e->flags & (1 << NFTNL_SET_ELEM_OBJREF))
302 mnl_attr_put_strz(nlh, NFTA_SET_ELEM_OBJREF, e->objref);
305 static void nftnl_set_elem_nlmsg_build_def(
struct nlmsghdr *nlh,
306 const struct nftnl_set *s)
308 if (s->flags & (1 << NFTNL_SET_NAME))
309 mnl_attr_put_strz(nlh, NFTA_SET_ELEM_LIST_SET, s->name);
310 if (s->flags & (1 << NFTNL_SET_ID))
311 mnl_attr_put_u32(nlh, NFTA_SET_ELEM_LIST_SET_ID, htonl(s->id));
312 if (s->flags & (1 << NFTNL_SET_TABLE))
313 mnl_attr_put_strz(nlh, NFTA_SET_ELEM_LIST_TABLE, s->table);
316 static struct nlattr *nftnl_set_elem_build(
struct nlmsghdr *nlh,
317 struct nftnl_set_elem *elem,
int i)
319 struct nlattr *nest2;
321 nest2 = mnl_attr_nest_start(nlh, i);
322 nftnl_set_elem_nlmsg_build_payload(nlh, elem);
323 mnl_attr_nest_end(nlh, nest2);
328 EXPORT_SYMBOL(nftnl_set_elems_nlmsg_build_payload);
329 void nftnl_set_elems_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
331 struct nftnl_set_elem *elem;
332 struct nlattr *nest1;
335 nftnl_set_elem_nlmsg_build_def(nlh, s);
337 if (list_empty(&s->element_list))
340 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_LIST_ELEMENTS);
341 list_for_each_entry(elem, &s->element_list, head)
342 nftnl_set_elem_build(nlh, elem, ++i);
344 mnl_attr_nest_end(nlh, nest1);
347 static
int nftnl_set_elem_parse_attr_cb(const struct nlattr *attr,
void *data)
349 const struct nlattr **tb = data;
350 int type = mnl_attr_get_type(attr);
352 if (mnl_attr_type_valid(attr, NFTA_SET_MAX) < 0)
356 case NFTA_SET_ELEM_FLAGS:
357 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
360 case NFTA_SET_ELEM_TIMEOUT:
361 case NFTA_SET_ELEM_EXPIRATION:
362 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
365 case NFTA_SET_ELEM_KEY:
366 case NFTA_SET_ELEM_DATA:
367 case NFTA_SET_ELEM_EXPR:
368 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
371 case NFTA_SET_ELEM_USERDATA:
372 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
381 static int nftnl_set_elems_parse2(
struct nftnl_set *s,
const struct nlattr *nest)
383 struct nlattr *tb[NFTA_SET_ELEM_MAX+1] = {};
384 struct nftnl_set_elem *e;
387 e = nftnl_set_elem_alloc();
391 ret = mnl_attr_parse_nested(nest, nftnl_set_elem_parse_attr_cb, tb);
395 if (tb[NFTA_SET_ELEM_FLAGS]) {
397 ntohl(mnl_attr_get_u32(tb[NFTA_SET_ELEM_FLAGS]));
398 e->flags |= (1 << NFTNL_SET_ELEM_FLAGS);
400 if (tb[NFTA_SET_ELEM_TIMEOUT]) {
401 e->timeout = be64toh(mnl_attr_get_u64(tb[NFTA_SET_ELEM_TIMEOUT]));
402 e->flags |= (1 << NFTNL_SET_ELEM_TIMEOUT);
404 if (tb[NFTA_SET_ELEM_EXPIRATION]) {
405 e->expiration = be64toh(mnl_attr_get_u64(tb[NFTA_SET_ELEM_EXPIRATION]));
406 e->flags |= (1 << NFTNL_SET_ELEM_EXPIRATION);
408 if (tb[NFTA_SET_ELEM_KEY]) {
409 ret = nftnl_parse_data(&e->key, tb[NFTA_SET_ELEM_KEY], &type);
412 e->flags |= (1 << NFTNL_SET_ELEM_KEY);
414 if (tb[NFTA_SET_ELEM_DATA]) {
415 ret = nftnl_parse_data(&e->data, tb[NFTA_SET_ELEM_DATA], &type);
420 e->flags |= (1 << NFTNL_SET_ELEM_VERDICT);
423 e->flags |= (1 << NFTNL_SET_ELEM_VERDICT) |
424 (1 << NFTNL_SET_ELEM_CHAIN);
427 e->flags |= (1 << NFTNL_SET_ELEM_DATA);
431 if (tb[NFTA_SET_ELEM_EXPR]) {
432 e->expr = nftnl_expr_parse(tb[NFTA_SET_ELEM_EXPR]);
433 if (e->expr == NULL) {
437 e->flags |= (1 << NFTNL_SET_ELEM_EXPR);
439 if (tb[NFTA_SET_ELEM_USERDATA]) {
441 mnl_attr_get_payload(tb[NFTA_SET_ELEM_USERDATA]);
443 if (e->flags & (1 << NFTNL_RULE_USERDATA))
446 e->user.len = mnl_attr_get_payload_len(tb[NFTA_SET_ELEM_USERDATA]);
447 e->user.data = malloc(e->user.len);
448 if (e->user.data == NULL) {
452 memcpy(e->user.data, udata, e->user.len);
453 e->flags |= (1 << NFTNL_RULE_USERDATA);
455 if (tb[NFTA_SET_ELEM_OBJREF]) {
456 e->objref = strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_OBJREF]));
457 if (e->objref == NULL) {
461 e->flags |= (1 << NFTNL_SET_ELEM_OBJREF);
465 list_add_tail(&e->head, &s->element_list);
469 nftnl_expr_free(e->expr);
471 nftnl_set_elem_free(e);
476 nftnl_set_elem_list_parse_attr_cb(
const struct nlattr *attr,
void *data)
478 const struct nlattr **tb = data;
479 int type = mnl_attr_get_type(attr);
481 if (mnl_attr_type_valid(attr, NFTA_SET_ELEM_LIST_MAX) < 0)
485 case NFTA_SET_ELEM_LIST_TABLE:
486 case NFTA_SET_ELEM_LIST_SET:
487 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
490 case NFTA_SET_ELEM_LIST_ELEMENTS:
491 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
500 static int nftnl_set_elems_parse(
struct nftnl_set *s,
const struct nlattr *nest)
505 mnl_attr_for_each_nested(attr, nest) {
506 if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
509 ret = nftnl_set_elems_parse2(s, attr);
516 EXPORT_SYMBOL(nftnl_set_elems_nlmsg_parse);
517 int nftnl_set_elems_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_set *s)
519 struct nlattr *tb[NFTA_SET_ELEM_LIST_MAX+1] = {};
520 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
523 if (mnl_attr_parse(nlh,
sizeof(*nfg),
524 nftnl_set_elem_list_parse_attr_cb, tb) < 0)
527 if (tb[NFTA_SET_ELEM_LIST_TABLE]) {
528 if (s->flags & (1 << NFTNL_SET_TABLE))
531 strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_LIST_TABLE]));
534 s->flags |= (1 << NFTNL_SET_TABLE);
536 if (tb[NFTA_SET_ELEM_LIST_SET]) {
537 if (s->flags & (1 << NFTNL_SET_NAME))
540 strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_LIST_SET]));
543 s->flags |= (1 << NFTNL_SET_NAME);
545 if (tb[NFTA_SET_ELEM_LIST_SET_ID]) {
546 s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ELEM_LIST_SET_ID]));
547 s->flags |= (1 << NFTNL_SET_ID);
549 if (tb[NFTA_SET_ELEM_LIST_ELEMENTS]) {
550 ret = nftnl_set_elems_parse(s, tb[NFTA_SET_ELEM_LIST_ELEMENTS]);
555 s->family = nfg->nfgen_family;
556 s->flags |= (1 << NFTNL_SET_FAMILY);
561 EXPORT_SYMBOL(nftnl_set_elem_parse);
562 int nftnl_set_elem_parse(
struct nftnl_set_elem *e,
enum nftnl_parse_type type,
563 const char *data,
struct nftnl_parse_err *err)
569 EXPORT_SYMBOL(nftnl_set_elem_parse_file);
570 int nftnl_set_elem_parse_file(
struct nftnl_set_elem *e,
enum nftnl_parse_type type,
571 FILE *fp,
struct nftnl_parse_err *err)
577 static int nftnl_set_elem_snprintf_default(
char *buf,
size_t size,
578 const struct nftnl_set_elem *e)
580 int ret, remain = size, offset = 0, i;
582 ret = snprintf(buf, remain,
"element ");
583 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
585 for (i = 0; i < div_round_up(e->key.len,
sizeof(uint32_t)); i++) {
586 ret = snprintf(buf + offset, remain,
"%.8x ", e->key.val[i]);
587 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
590 ret = snprintf(buf + offset, remain,
" : ");
591 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
593 for (i = 0; i < div_round_up(e->data.len,
sizeof(uint32_t)); i++) {
594 ret = snprintf(buf + offset, remain,
"%.8x ", e->data.val[i]);
595 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
598 ret = snprintf(buf + offset, remain,
"%u [end]", e->set_elem_flags);
599 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
602 ret = snprintf(buf + offset, remain,
" userdata = {");
603 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
605 for (i = 0; i < e->user.len; i++) {
606 char *c = e->user.data;
608 ret = snprintf(buf + offset, remain,
"%c",
609 isalnum(c[i]) ? c[i] : 0);
610 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
613 ret = snprintf(buf + offset, remain,
" }\n");
614 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
620 static int nftnl_set_elem_cmd_snprintf(
char *buf,
size_t size,
621 const struct nftnl_set_elem *e,
622 uint32_t cmd, uint32_t type,
625 int ret, remain = size, offset = 0;
628 case NFTNL_OUTPUT_DEFAULT:
629 ret = nftnl_set_elem_snprintf_default(buf + offset, remain, e);
630 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
632 case NFTNL_OUTPUT_XML:
633 case NFTNL_OUTPUT_JSON:
642 EXPORT_SYMBOL(nftnl_set_elem_snprintf);
643 int nftnl_set_elem_snprintf(
char *buf,
size_t size,
644 const struct nftnl_set_elem *e,
645 uint32_t type, uint32_t flags)
650 return nftnl_set_elem_cmd_snprintf(buf, size, e, nftnl_flag2cmd(flags),
654 static int nftnl_set_elem_do_snprintf(
char *buf,
size_t size,
const void *e,
655 uint32_t cmd, uint32_t type,
658 return nftnl_set_elem_snprintf(buf, size, e, type, flags);
661 EXPORT_SYMBOL(nftnl_set_elem_fprintf);
662 int nftnl_set_elem_fprintf(FILE *fp,
struct nftnl_set_elem *se, uint32_t type,
665 return nftnl_fprintf(fp, se, NFTNL_CMD_UNSPEC, type, flags,
666 nftnl_set_elem_do_snprintf);
669 EXPORT_SYMBOL(nftnl_set_elem_foreach);
670 int nftnl_set_elem_foreach(
struct nftnl_set *s,
671 int (*cb)(
struct nftnl_set_elem *e,
void *data),
674 struct nftnl_set_elem *elem;
677 list_for_each_entry(elem, &s->element_list, head) {
678 ret = cb(elem, data);
686 const struct nftnl_set *set;
687 const struct list_head *list;
688 struct nftnl_set_elem *cur;
691 EXPORT_SYMBOL(nftnl_set_elems_iter_create);
693 nftnl_set_elems_iter_create(
const struct nftnl_set *s)
702 iter->list = &s->element_list;
703 if (list_empty(&s->element_list))
706 iter->cur = list_entry(s->element_list.next,
707 struct nftnl_set_elem, head);
712 EXPORT_SYMBOL(nftnl_set_elems_iter_cur);
713 struct nftnl_set_elem *
719 EXPORT_SYMBOL(nftnl_set_elems_iter_next);
722 struct nftnl_set_elem *s = iter->cur;
727 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_set_elem, head);
728 if (&iter->cur->head == iter->list->next)
734 EXPORT_SYMBOL(nftnl_set_elems_iter_destroy);
740 static bool nftnl_attr_nest_overflow(
struct nlmsghdr *nlh,
741 const struct nlattr *from,
742 const struct nlattr *to)
744 int len = (
void *)to + to->nla_len - (
void *)from;
750 if (len > UINT16_MAX) {
751 nlh->nlmsg_len -= to->nla_len;
757 EXPORT_SYMBOL(nftnl_set_elems_nlmsg_build_payload_iter);
758 int nftnl_set_elems_nlmsg_build_payload_iter(
struct nlmsghdr *nlh,
761 struct nftnl_set_elem *elem;
762 struct nlattr *nest1, *nest2;
765 nftnl_set_elem_nlmsg_build_def(nlh, iter->set);
768 if (list_empty(&iter->set->element_list))
771 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_LIST_ELEMENTS);
772 elem = nftnl_set_elems_iter_next(iter);
773 while (elem != NULL) {
774 nest2 = nftnl_set_elem_build(nlh, elem, ++i);
775 if (nftnl_attr_nest_overflow(nlh, nest1, nest2)) {
777 iter->cur = list_entry(iter->cur->head.prev,
778 struct nftnl_set_elem, head);
782 elem = nftnl_set_elems_iter_next(iter);
784 mnl_attr_nest_end(nlh, nest1);