]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add burst parameter to limit
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 3 Aug 2015 13:56:27 +0000 (15:56 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 23 Sep 2015 10:16:53 +0000 (12:16 +0200)
... limit rate 1024 mbytes/second burst 10240 bytes
... limit rate 1/second burst 3 packets

This parameter is optional.

You need a Linux kernel >= 4.3-rc1.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/datatype.h
include/statement.h
src/datatype.c
src/netlink_delinearize.c
src/netlink_linearize.c
src/parser_bison.y
src/scanner.l
src/statement.c

index ebafa6550259c4ed3d767b1fbf99e8f2980c1267..07fedce8f451f5407c0f3ceae71b77958af9bbb1 100644 (file)
@@ -239,4 +239,7 @@ extern struct error_record *rate_parse(const struct location *loc,
                                       const char *str, uint64_t *rate,
                                       uint64_t *unit);
 
+extern struct error_record *data_unit_parse(const struct location *loc,
+                                           const char *str, uint64_t *rate);
+
 #endif /* NFTABLES_DATATYPE_H */
index d2d0852e3c118f9a13b3bd15246135d194e4db1c..bead0a6f17bdf26e39a3a19f075938abb2b8e32d 100644 (file)
@@ -52,6 +52,7 @@ struct limit_stmt {
        uint64_t                rate;
        uint64_t                unit;
        enum nft_limit_type     type;
+       uint32_t                burst;
 };
 
 extern struct stmt *limit_stmt_alloc(const struct location *loc);
index e5a486fb2d5e61a38c459778081eb2739eb5e1ff..f56763b91087dbc0644cc03a6cc1a49c73a9ff33 100644 (file)
@@ -996,8 +996,8 @@ static struct error_record *time_unit_parse(const struct location *loc,
        return NULL;
 }
 
-static struct error_record *data_unit_parse(const struct location *loc,
-                                           const char *str, uint64_t *rate)
+struct error_record *data_unit_parse(const struct location *loc,
+                                    const char *str, uint64_t *rate)
 {
        if (strncmp(str, "bytes", strlen("bytes")) == 0)
                *rate = 1ULL;
index 4c639a16b1cb57ccd5cd190631ba4c0fe0444797..2360681d5d128e15a1eb23a691e5e8823bd19d46 100644 (file)
@@ -584,6 +584,7 @@ static void netlink_parse_limit(struct netlink_parse_ctx *ctx,
        stmt->limit.rate = nftnl_expr_get_u64(nle, NFTNL_EXPR_LIMIT_RATE);
        stmt->limit.unit = nftnl_expr_get_u64(nle, NFTNL_EXPR_LIMIT_UNIT);
        stmt->limit.type = nftnl_expr_get_u32(nle, NFTNL_EXPR_LIMIT_TYPE);
+       stmt->limit.burst = nftnl_expr_get_u32(nle, NFTNL_EXPR_LIMIT_BURST);
        list_add_tail(&stmt->list, &ctx->rule->stmts);
 }
 
index 47092d33c0706b9d08e5ef5ea299267791c8782c..f697ea52210da09672a413867e3070d97ef96a1a 100644 (file)
@@ -709,6 +709,10 @@ static void netlink_gen_limit_stmt(struct netlink_linearize_ctx *ctx,
        nftnl_expr_set_u64(nle, NFTNL_EXPR_LIMIT_RATE, stmt->limit.rate);
        nftnl_expr_set_u64(nle, NFTNL_EXPR_LIMIT_UNIT, stmt->limit.unit);
        nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_TYPE, stmt->limit.type);
+       if (stmt->limit.burst > 0)
+               nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_BURST,
+                                  stmt->limit.burst);
+
        nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
index ec44a2cdd3f25fa18ec9871afbe0dd7b8b6d9e64..385e2140c7af96666eaff540705897850b2aae55 100644 (file)
@@ -364,6 +364,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 
 %token LIMIT                   "limit"
 %token RATE                    "rate"
+%token BURST                   "burst"
 
 %token NANOSECOND              "nanosecond"
 %token MICROSECOND             "microsecond"
@@ -450,7 +451,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %type <val>                    level_type
 %type <stmt>                   limit_stmt
 %destructor { stmt_free($$); } limit_stmt
-%type <val>                    time_unit
+%type <val>                    limit_burst time_unit
 %type <stmt>                   reject_stmt reject_stmt_alloc
 %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc
 %type <stmt>                   nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc
@@ -1441,14 +1442,15 @@ level_type              :       LEVEL_EMERG     { $$ = LOG_EMERG; }
                        |       LEVEL_DEBUG     { $$ = LOG_DEBUG; }
                        ;
 
-limit_stmt             :       LIMIT   RATE    NUM     SLASH   time_unit
+limit_stmt             :       LIMIT   RATE    NUM     SLASH   time_unit       limit_burst
                        {
                                $$ = limit_stmt_alloc(&@$);
                                $$->limit.rate  = $3;
                                $$->limit.unit  = $5;
+                               $$->limit.burst = $6;
                                $$->limit.type  = NFT_LIMIT_PKTS;
                        }
-                       |       LIMIT RATE      NUM     STRING
+                       |       LIMIT RATE      NUM     STRING  limit_burst
                        {
                                struct error_record *erec;
                                uint64_t rate, unit;
@@ -1462,10 +1464,28 @@ limit_stmt              :       LIMIT   RATE    NUM     SLASH   time_unit
                                $$ = limit_stmt_alloc(&@$);
                                $$->limit.rate  = rate * $3;
                                $$->limit.unit  = unit;
+                               $$->limit.burst = $5;
                                $$->limit.type  = NFT_LIMIT_PKT_BYTES;
                        }
                        ;
 
+limit_burst            :       /* empty */                     { $$ = 0; }
+                       |       BURST   NUM     PACKETS         { $$ = $2; }
+                       |       BURST   NUM     BYTES           { $$ = $2; }
+                       |       BURST   NUM     STRING
+                       {
+                               struct error_record *erec;
+                               uint64_t rate;
+
+                               erec = data_unit_parse(&@$, $3, &rate);
+                               if (erec != NULL) {
+                                       erec_queue(erec, state->msgs);
+                                       YYERROR;
+                               }
+                               $$ = $2 * rate;
+                       }
+                       ;
+
 time_unit              :       SECOND          { $$ = 1ULL; }
                        |       MINUTE          { $$ = 1ULL * 60; }
                        |       HOUR            { $$ = 1ULL * 60 * 60; }
index 2d9871d0195ce3991b3620d0359f82daa85dd2b0..bd8e5726d54c10998a68a87e8513459bbc420e51 100644 (file)
@@ -309,6 +309,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 
 "limit"                        { return LIMIT; }
 "rate"                 { return RATE; }
+"burst"                        { return BURST; }
 
 "nanosecond"           { return NANOSECOND; }
 "microsecond"          { return MICROSECOND; }
index ba7b8be2b2db7bf945973c104d17ac97d33a2aac..d620d1ba3605388961f0c32ac4570edffed4043a 100644 (file)
@@ -220,12 +220,20 @@ static void limit_stmt_print(const struct stmt *stmt)
        case NFT_LIMIT_PKTS:
                printf("limit rate %" PRIu64 "/%s",
                       stmt->limit.rate, get_unit(stmt->limit.unit));
+               if (stmt->limit.burst > 0)
+                       printf(" burst %u packets", stmt->limit.burst);
                break;
        case NFT_LIMIT_PKT_BYTES:
                data_unit = get_rate(stmt->limit.rate, &rate);
 
                printf("limit rate %" PRIu64 " %s/%s",
                       rate, data_unit, get_unit(stmt->limit.unit));
+               if (stmt->limit.burst > 0) {
+                       uint64_t burst;
+
+                       data_unit = get_rate(stmt->limit.burst, &burst);
+                       printf(" burst %"PRIu64" %s", burst, data_unit);
+               }
                break;
        }
 }