]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
src: xml: consolidate common XML code via nft_mxml_num_parse
authorArturo Borrero <arturo.borrero.glez@gmail.com>
Thu, 25 Jul 2013 16:46:35 +0000 (18:46 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 25 Jul 2013 18:03:21 +0000 (20:03 +0200)
This patch moves common XML parsing code to nft_mxml_num_parse().
To handle this, the nft_strtoi() helper fuction is included.

I've changed some MXML_DESCEND[_FIRST] flags to avoid match a nested node under
some circumstances, ie, matching two nodes with the same name that are descendant.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
13 files changed:
src/chain.c
src/expr/bitwise.c
src/expr/byteorder.c
src/expr/ct.c
src/expr/data_reg.c
src/expr/exthdr.c
src/expr/limit.c
src/expr/log.c
src/internal.h
src/mxml.c
src/rule.c
src/table.c
src/utils.c

index 4f9741a90452c58920049fd34177d68d860eff02..1e070449038ff32111c80391d1ce5f58f9b4a782 100644 (file)
@@ -576,18 +576,12 @@ static int nft_chain_xml_parse(struct nft_chain *c, char *xml)
        c->flags |= (1 << NFT_CHAIN_ATTR_TABLE);
 
        /* Get and set <prio> */
-       node = mxmlFindElement(tree, tree, "prio", NULL, NULL, MXML_DESCEND);
-       if (node == NULL) {
-               mxmlDelete(tree);
-               return -1;
-       }
-       tmp = strtoll(node->child->value.opaque, &endptr, 10);
-       if (tmp > INT32_MAX || tmp < INT32_MIN || *endptr) {
+       if (nft_mxml_num_parse(tree, "prio", MXML_DESCEND, BASE_DEC, &c->prio,
+                              NFT_TYPE_S32) != 0) {
                mxmlDelete(tree);
                return -1;
        }
 
-       memcpy(&c->prio, &tmp, sizeof(c->prio));
        c->flags |= (1 << NFT_CHAIN_ATTR_PRIO);
 
        /* Ignore <use> (cannot be set)*/
index 84de249d13a3d47be1c31d645f467ab096fa0684..f0a2effe326793878e7fc1f531e7a6529b24a05f 100644 (file)
@@ -201,6 +201,12 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        bitwise->dreg = reg;
        e->flags |= (1 << NFT_EXPR_BITWISE_DREG);
 
+       if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST,
+                              BASE_DEC, &bitwise->len, NFT_TYPE_U8) != 0)
+               return -1;
+
+       e->flags |= (1 << NFT_EXPR_BITWISE_LEN);
+
        if (nft_mxml_data_reg_parse(tree, "mask",
                                    &bitwise->mask) != DATA_VALUE)
                return -1;
index e3b9a5ec726ba9cedd43b4b1a2f58fa6807acf33..a931ffaa26cd01980dc97575fdcc99fb06b84507 100644 (file)
@@ -187,8 +187,6 @@ nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
 #ifdef XML_PARSING
        struct nft_expr_byteorder *byteorder = nft_expr_data(e);
        mxml_node_t *node = NULL;
-       uint64_t tmp;
-       char *endptr = NULL;
        int32_t reg;
 
        reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
@@ -218,26 +216,16 @@ nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
 
        e->flags |= (1 << NFT_EXPR_BYTEORDER_OP);
 
-       node = mxmlFindElement(tree, tree, "len", NULL, NULL, MXML_DESCEND);
-       if (node == NULL)
-               goto err;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT8_MAX || tmp < 0 || *endptr)
+       if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
+                              &byteorder->len, NFT_TYPE_U8) != 0)
                goto err;
 
-       byteorder->len = tmp;
        e->flags |= (1 << NFT_EXPR_BYTEORDER_LEN);
 
-       node = mxmlFindElement(tree, tree, "size", NULL, NULL, MXML_DESCEND);
-       if (node == NULL)
-               goto err;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT8_MAX || tmp < 0 || *endptr)
+       if (nft_mxml_num_parse(tree, "size", MXML_DESCEND_FIRST, BASE_DEC,
+                              &byteorder->size, NFT_TYPE_U8) != 0)
                goto err;
 
-       byteorder->size = tmp;
        e->flags |= (1 << NFT_EXPR_BYTEORDER_SIZE);
 
        return 0;
index f3992198a1d438c7983fdf71178a20b8ea51533c..a0323e1d3b8e65900b595734f36e0073b69ec0e4 100644 (file)
@@ -183,10 +183,9 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree
 #ifdef XML_PARSING
        struct nft_expr_ct *ct = nft_expr_data(e);
        mxml_node_t *node = NULL;
-       uint64_t tmp;
        int32_t reg;
-       char *endptr;
        int key;
+       uint8_t dir;
 
        reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
        if (reg < 0)
@@ -206,18 +205,14 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree
        ct->key = key;
        e->flags |= (1 << NFT_EXPR_CT_KEY);
 
-       node = mxmlFindElement(tree, tree, "dir", NULL, NULL, MXML_DESCEND);
-       if (node == NULL)
-               goto err;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT8_MAX || tmp < 0 || *endptr)
+       if (nft_mxml_num_parse(tree, "dir", MXML_DESCEND_FIRST, BASE_DEC, &dir,
+                              NFT_TYPE_U8) != 0)
                goto err;
 
-       if (tmp != IP_CT_DIR_ORIGINAL && tmp != IP_CT_DIR_REPLY)
+       if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY)
                goto err;
 
-       ct->dir = tmp;
+       ct->dir = dir;
        e->flags |= (1 << NFT_EXPR_CT_DIR);
 
        return 0;
index 260ae59dfbf0ead2666a68382df3eaca6d3a185a..b290b96ff34ce165f88f91715343fc8b0260120b 100644 (file)
@@ -134,9 +134,6 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg, char *xml)
        mxml_node_t *tree = NULL;
        mxml_node_t *node = NULL;
        int i;
-       int64_t tmp;
-       uint64_t utmp;
-       char *endptr;
        char node_name[6];
 
        tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
@@ -172,38 +169,22 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg, char *xml)
                return -1;
        }
 
-       /* Get <len> */
-       node = mxmlFindElement(tree, tree, "len", NULL, NULL, MXML_DESCEND);
-       if (node == NULL) {
+       if (nft_mxml_num_parse(tree, "len", MXML_DESCEND, BASE_DEC, &reg->len,
+                              NFT_TYPE_U8) != 0) {
                mxmlDelete(tree);
                return -1;
        }
 
-       tmp = strtoll(node->child->value.opaque, &endptr, 10);
-       if (tmp > INT64_MAX || tmp < 0 || *endptr) {
-               mxmlDelete(tree);
-               return -1;
-       }
-
-       reg->len = tmp;
-
        /* Get and set <dataN> */
        for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) {
                sprintf(node_name, "data%d", i);
 
-               node = mxmlFindElement(tree, tree, node_name, NULL,
-                                      NULL, MXML_DESCEND);
-               if (node == NULL) {
+               if (nft_mxml_num_parse(tree, node_name, MXML_DESCEND, BASE_HEX,
+                                      &reg->val[i], NFT_TYPE_U32) != 0) {
                        mxmlDelete(tree);
                        return -1;
                }
 
-               utmp = strtoull(node->child->value.opaque, &endptr, 16);
-               if (utmp == UINT64_MAX || utmp < 0 || *endptr) {
-                       mxmlDelete(tree);
-                       return -1;
-               }
-               reg->val[i] = utmp;
        }
 
        mxmlDelete(tree);
index 51e784e0394b2cf8954defa2cd216f3734d84f27..769b53c4ac21694ac3d31344164b9f6c41a27032 100644 (file)
@@ -199,8 +199,6 @@ nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
 #ifdef XML_PARSING
        struct nft_expr_exthdr *exthdr = nft_expr_data(e);
        mxml_node_t *node = NULL;
-       uint64_t tmp;
-       char *endptr;
        int32_t reg;
        int type;
 
@@ -225,28 +223,17 @@ nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        e->flags |= (1 << NFT_EXPR_EXTHDR_TYPE);
 
        /* Get and set <offset> */
-       node = mxmlFindElement(tree, tree, "offset", NULL, NULL,
-                              MXML_DESCEND);
-       if (node == NULL)
-               return -1;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT_MAX || tmp < 0 || *endptr)
+       if (nft_mxml_num_parse(tree, "offset", MXML_DESCEND_FIRST, BASE_DEC,
+                              &exthdr->offset, NFT_TYPE_U32) != 0)
                return -1;
 
-       exthdr->offset = tmp;
        e->flags |= (1 << NFT_EXPR_EXTHDR_OFFSET);
 
        /* Get and set <len> */
-       node = mxmlFindElement(tree, tree, "len", NULL, NULL, MXML_DESCEND);
-       if (node == NULL)
-               return -1;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT_MAX || tmp < 0 || *endptr)
+       if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
+                              &exthdr->len, NFT_TYPE_U32) != 0)
                return -1;
 
-       exthdr->len = tmp;
        e->flags |= (1 << NFT_EXPR_EXTHDR_LEN);
 
        return 0;
index 2ecf7cb57e9910e3ef181b358435187a15a75b79..27f880c6f227b39594d13ddc07a4fccf4f827a44 100644 (file)
@@ -122,32 +122,17 @@ static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e, mxml_node_t *t
 {
 #ifdef XML_PARSING
        struct nft_expr_limit *limit = nft_expr_data(e);
-       mxml_node_t *node = NULL;
-       uint64_t tmp;
-       char *endptr;
 
-       node = mxmlFindElement(tree, tree, "rate", NULL, NULL,
-                              MXML_DESCEND_FIRST);
-       if (node == NULL)
+       if (nft_mxml_num_parse(tree, "rate", MXML_DESCEND_FIRST, BASE_DEC,
+                              &limit->rate, NFT_TYPE_U64) != 0)
                goto err;
 
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT64_MAX || tmp < 0 || *endptr)
-               goto err;
-
-       limit->rate = tmp;
        e->flags |= (1 << NFT_EXPR_LIMIT_RATE);
 
-       node = mxmlFindElement(tree, tree, "depth", NULL, NULL,
-                              MXML_DESCEND);
-       if (node == NULL)
-               goto err;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT64_MAX || tmp < 0 || *endptr)
+       if (nft_mxml_num_parse(tree, "depth", MXML_DESCEND_FIRST, BASE_DEC,
+                              &limit->rate, NFT_TYPE_U64) != 0)
                goto err;
 
-       limit->depth = tmp;
        e->flags |= (1 << NFT_EXPR_LIMIT_DEPTH);
 
        return 0;
index 1ffd1d9589ceb94d8e47870d13a44c6bfa2c9512..9ff2d32cd45acd9c61dae2c3bfe028e4cb826ca0 100644 (file)
@@ -157,56 +157,36 @@ static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre
 #ifdef XML_PARSING
        struct nft_expr_log *log = nft_expr_data(e);
        mxml_node_t *node = NULL;
-       uint64_t tmp;
-       char *endptr;
 
        node = mxmlFindElement(tree, tree, "prefix", NULL, NULL,
                               MXML_DESCEND_FIRST);
-       if (node == NULL)
-               goto err;
+       if (node == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
 
        log->prefix = strdup(node->child->value.opaque);
        e->flags |= (1 << NFT_EXPR_LOG_PREFIX);
 
-       node = mxmlFindElement(tree, tree, "group", NULL, NULL, MXML_DESCEND);
-       if (node == NULL)
-               goto err;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT32_MAX || tmp < 0 || *endptr)
-               goto err;
+       if (nft_mxml_num_parse(tree, "group", MXML_DESCEND_FIRST, BASE_DEC,
+                              &log->group, NFT_TYPE_U32) != 0)
+               return -1;
 
-       log->group = tmp;
        e->flags |= (1 << NFT_EXPR_LOG_GROUP);
 
-       node = mxmlFindElement(tree, tree, "snaplen", NULL, NULL,
-                              MXML_DESCEND);
-       if (node == NULL)
-               goto err;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT32_MAX || tmp < 0 || *endptr)
-               goto err;
+       if (nft_mxml_num_parse(tree, "snaplen", MXML_DESCEND_FIRST, BASE_DEC,
+                              &log->snaplen, NFT_TYPE_U32) != 0)
+               return -1;
 
-       log->snaplen = tmp;
        e->flags |= (1 << NFT_EXPR_LOG_SNAPLEN);
 
-       node = mxmlFindElement(tree, tree, "qthreshold", NULL, NULL,
-                              MXML_DESCEND);
-       if (node == NULL)
-               goto err;
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT32_MAX || tmp < 0 || *endptr)
-               goto err;
+       if (nft_mxml_num_parse(tree, "qthreshold", MXML_DESCEND_FIRST,
+                              BASE_DEC, &log->qthreshold, NFT_TYPE_U32) != 0)
+               return -1;
 
-       log->qthreshold = tmp;
        e->flags |= (1 << NFT_EXPR_LOG_QTHRESHOLD);
 
        return 0;
-err:
-       errno = EINVAL;
-       return -1;
 #else
        errno = EOPNOTSUPP;
        return -1;
index dc7d0c3a1fc1116de2a016d90dd0f99c5dd5ea27..3bf57b6d0bc567d84a791629060c303ca2ab10f4 100644 (file)
 
 #include <stdint.h>
 
+#define BASE_DEC 10
+#define BASE_HEX 16
+
+enum nft_type {
+       NFT_TYPE_U8,
+       NFT_TYPE_U16,
+       NFT_TYPE_U32,
+       NFT_TYPE_U64,
+       NFT_TYPE_S8,
+       NFT_TYPE_S16,
+       NFT_TYPE_S32,
+       NFT_TYPE_S64,
+};
+
 #ifdef XML_PARSING
 #include <mxml.h>
 struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node);
 int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags);
 union nft_data_reg;
 int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name, union nft_data_reg *data_reg);
+int nft_mxml_num_parse(mxml_node_t *tree, const char *node_name, uint32_t mxml_flags, int base, void *number, enum nft_type type);
 #endif
 
 #define NFT_TABLE_XML_VERSION 0
@@ -32,6 +47,7 @@ int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name, union nft_
 
 const char *nft_family2str(uint32_t family);
 int nft_str2family(const char *family);
+int nft_strtoi(const char *string, int base, void *number, enum nft_type type);
 
 struct expr_ops;
 
index 07f29ac879397dc2c3059ceb0474d8d7875b7fa1..8cb1f6cd20be8f93f8969af26e15fa527c5cc49d 100644 (file)
@@ -11,6 +11,8 @@
  */
 #include "internal.h"
 #include "expr_ops.h"
+#include <stdint.h>
+#include <limits.h>
 
 #include <linux/netfilter/nf_tables.h>
 #include <libnftables/rule.h>
@@ -58,7 +60,6 @@ err:
 int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags)
 {
        mxml_node_t *node;
-       char *endptr;
        uint64_t val;
 
        node = mxmlFindElement(tree, tree, reg_name, NULL, NULL, flags);
@@ -67,8 +68,11 @@ int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags)
                goto err;
        }
 
-       val = strtoull(node->child->value.opaque, &endptr, 10);
-       if (val > NFT_REG_MAX || val < 0 || *endptr) {
+       if (nft_strtoi(node->child->value.opaque, BASE_DEC, &val,
+                      NFT_TYPE_U64) != 0)
+               goto err;
+
+       if (val > NFT_REG_MAX) {
                errno = ERANGE;
                goto err;
        }
@@ -130,4 +134,20 @@ int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name,
 err:
        return -1;
 }
+
+int
+nft_mxml_num_parse(mxml_node_t *tree, const char *node_name,
+                  uint32_t mxml_flags, int base, void *number,
+                  enum nft_type type)
+{
+       mxml_node_t *node = NULL;
+
+       node = mxmlFindElement(tree, tree, node_name, NULL, NULL, mxml_flags);
+       if (node == NULL || node->child == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       return nft_strtoi(node->child->value.opaque, base, number, type);
+}
 #endif
index e48497f30ce4412dafcb8a82a602e965b0e69344..c3cc75adde5d5985ab134983983aad26f9ddf2a1 100644 (file)
@@ -551,19 +551,12 @@ static int nft_rule_xml_parse(struct nft_rule *r, char *xml)
        r->flags |= (1 << NFT_RULE_ATTR_HANDLE);
 
        /* get and set <rule_flags> */
-       node = mxmlFindElement(tree, tree, "rule_flags", NULL, NULL,
-                              MXML_DESCEND_FIRST);
-       if (node == NULL) {
-               mxmlDelete(tree);
-               return -1;
-       }
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
+       if (nft_mxml_num_parse(tree, "rule_flags", MXML_DESCEND_FIRST,
+                              BASE_DEC, &r->rule_flags, NFT_TYPE_U32) != 0) {
                mxmlDelete(tree);
                return -1;
        }
 
-       r->rule_flags = (uint32_t)tmp;
        r->flags |= (1 << NFT_RULE_ATTR_FLAGS);
 
        /* <compat_proto> is optional */
index e9e6d59bdef0777b2dc83f1035dae78260abd028..d814668edb7adcc52f64b9efecd5e15de6fe62fc 100644 (file)
@@ -224,7 +224,6 @@ static int nft_table_xml_parse(struct nft_table *t, char *xml)
        mxml_node_t *tree = NULL;
        mxml_node_t *node = NULL;
        char *endptr = NULL;
-       uint64_t tmp;
        int64_t stmp;
        int family;
 
@@ -280,20 +279,12 @@ static int nft_table_xml_parse(struct nft_table *t, char *xml)
        t->flags |= (1 << NFT_TABLE_ATTR_FAMILY);
 
        /* Get and set <table_flags> */
-       node = mxmlFindElement(tree, tree, "table_flags", NULL, NULL,
-                              MXML_DESCEND);
-       if (node == NULL) {
-               mxmlDelete(tree);
-               return -1;
-       }
-
-       tmp = strtoull(node->child->value.opaque, &endptr, 10);
-       if (tmp > UINT32_MAX || *endptr || tmp < 0) {
+       if (nft_mxml_num_parse(tree, "table_flags", MXML_DESCEND, BASE_DEC,
+                              &t->table_flags, NFT_TYPE_U32) != 0) {
                mxmlDelete(tree);
                return -1;
        }
 
-       t->table_flags = (uint32_t)tmp;
        t->flags |= (1 << NFT_TABLE_ATTR_FLAGS);
 
        mxmlDelete(tree);
index be1b5d8e86f86e42e2992a0c9ab112a56261b4db..4a0bb9cb17b251b551ee5ba326b0d4172fe95ce4 100644 (file)
@@ -14,6 +14,8 @@
 #include <limits.h>
 #include <stdint.h>
 #include <arpa/inet.h>
+#include <errno.h>
+#include <inttypes.h>
 
 const char *nft_family2str(uint32_t family)
 {
@@ -44,3 +46,74 @@ int nft_str2family(const char *family)
 
        return -1;
 }
+
+static struct {
+       int len;
+       int64_t min;
+       uint64_t max;
+} basetype[] = {
+       [NFT_TYPE_U8]   = { .len = sizeof(uint8_t), .max = UINT8_MAX },
+       [NFT_TYPE_U16]  = { .len = sizeof(uint16_t), .max = UINT16_MAX },
+       [NFT_TYPE_U32]  = { .len = sizeof(uint32_t), .max = UINT32_MAX },
+       [NFT_TYPE_U64]  = { .len = sizeof(uint64_t), .max = UINT64_MAX },
+       [NFT_TYPE_S8]   = { .len = sizeof(int8_t), .min = INT8_MIN, .max = INT8_MAX },
+       [NFT_TYPE_S16]  = { .len = sizeof(int16_t), .min = INT16_MIN, .max = INT16_MAX },
+       [NFT_TYPE_S32]  = { .len = sizeof(int32_t), .min = INT32_MIN, .max = INT32_MAX },
+       [NFT_TYPE_S64]  = { .len = sizeof(int64_t), .min = INT64_MIN, .max = INT64_MAX },
+};
+
+int nft_strtoi(const char *string, int base, void *out, enum nft_type type)
+{
+       int64_t sval = 0;
+       uint64_t uval = -1;
+       char *endptr;
+
+       switch (type) {
+       case NFT_TYPE_U8:
+       case NFT_TYPE_U16:
+       case NFT_TYPE_U32:
+       case NFT_TYPE_U64:
+               uval = strtoll(string, &endptr, base);
+               break;
+       case NFT_TYPE_S8:
+       case NFT_TYPE_S16:
+       case NFT_TYPE_S32:
+       case NFT_TYPE_S64:
+               sval = strtoull(string, &endptr, base);
+               break;
+       default:
+               errno = EINVAL;
+               return -1;
+       }
+
+       if (*endptr) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       switch (type) {
+       case NFT_TYPE_U8:
+       case NFT_TYPE_U16:
+       case NFT_TYPE_U32:
+       case NFT_TYPE_U64:
+               if (uval > basetype[type].max) {
+                       errno = ERANGE;
+                       return -1;
+               }
+               memcpy(out, &uval, basetype[type].len);
+               break;
+       case NFT_TYPE_S8:
+       case NFT_TYPE_S16:
+       case NFT_TYPE_S32:
+       case NFT_TYPE_S64:
+               if (sval < basetype[type].min ||
+                   sval > (int64_t)basetype[type].max) {
+                       errno = ERANGE;
+                       return -1;
+               }
+               memcpy(out, &sval, basetype[type].len);
+               break;
+       }
+
+       return 0;
+}