]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
parser: add `limit_rate_pkts` and `limit_rate_bytes` rules
authorJeremy Sowden <jeremy@azazel.net>
Fri, 29 Oct 2021 20:40:08 +0000 (21:40 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 3 Nov 2021 11:48:19 +0000 (12:48 +0100)
Factor the `N / time-unit` and `N byte-unit / time-unit` expressions
from limit expressions out into separate `limit_rate_pkts` and
`limit_rate_bytes` rules respectively.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/datatype.h
src/parser_bison.y

index 448be57fbc7fe3c3b2065e1316160bb556a1419f..7ddd3566d459d97f5f523455d7fa25303840cd40 100644 (file)
@@ -309,6 +309,10 @@ extern struct error_record *rate_parse(const struct location *loc,
 extern struct error_record *data_unit_parse(const struct location *loc,
                                            const char *str, uint64_t *rate);
 
+struct limit_rate {
+       uint64_t rate, unit;
+};
+
 extern void expr_chain_export(const struct expr *e, char *chain);
 
 #endif /* NFTABLES_DATATYPE_H */
index 3acd80317456125e90ebfbcfda447da741e4ae57..cf1e139d42f39bda3219f9106ca46357f0061fef 100644 (file)
@@ -186,6 +186,7 @@ int nft_lex(void *, void *, void *);
        struct handle_spec      handle_spec;
        struct position_spec    position_spec;
        struct prio_spec        prio_spec;
+       struct limit_rate       limit_rate;
 }
 
 %token TOKEN_EOF 0             "end of file"
@@ -607,6 +608,9 @@ int nft_lex(void *, void *, void *);
 %token IN                      "in"
 %token OUT                     "out"
 
+%type <limit_rate>             limit_rate_pkts
+%type <limit_rate>             limit_rate_bytes
+
 %type <string>                 identifier type_identifier string comment_spec
 %destructor { xfree($$); }     identifier type_identifier string comment_spec
 
@@ -3145,42 +3149,31 @@ log_flag_tcp            :       SEQUENCE
                        }
                        ;
 
-limit_stmt             :       LIMIT   RATE    limit_mode      NUM     SLASH   time_unit       limit_burst_pkts        close_scope_limit
+limit_stmt             :       LIMIT   RATE    limit_mode      limit_rate_pkts limit_burst_pkts        close_scope_limit
                        {
-                               if ($7 == 0) {
-                                       erec_queue(error(&@7, "limit burst must be > 0"),
+                               if ($5 == 0) {
+                                       erec_queue(error(&@5, "limit burst must be > 0"),
                                                   state->msgs);
                                        YYERROR;
                                }
                                $$ = limit_stmt_alloc(&@$);
-                               $$->limit.rate  = $4;
-                               $$->limit.unit  = $6;
-                               $$->limit.burst = $7;
+                               $$->limit.rate  = $4.rate;
+                               $$->limit.unit  = $4.unit;
+                               $$->limit.burst = $5;
                                $$->limit.type  = NFT_LIMIT_PKTS;
                                $$->limit.flags = $3;
                        }
-                       |       LIMIT   RATE    limit_mode      NUM     STRING  limit_burst_bytes       close_scope_limit
+                       |       LIMIT   RATE    limit_mode      limit_rate_bytes        limit_burst_bytes       close_scope_limit
                        {
-                               struct error_record *erec;
-                               uint64_t rate, unit;
-
-                               if ($6 == 0) {
-                                       erec_queue(error(&@6, "limit burst must be > 0"),
+                               if ($5 == 0) {
+                                       erec_queue(error(&@5, "limit burst must be > 0"),
                                                   state->msgs);
                                        YYERROR;
                                }
-
-                               erec = rate_parse(&@$, $5, &rate, &unit);
-                               xfree($5);
-                               if (erec != NULL) {
-                                       erec_queue(erec, state->msgs);
-                                       YYERROR;
-                               }
-
                                $$ = limit_stmt_alloc(&@$);
-                               $$->limit.rate  = rate * $4;
-                               $$->limit.unit  = unit;
-                               $$->limit.burst = $6;
+                               $$->limit.rate  = $4.rate;
+                               $$->limit.unit  = $4.unit;
+                               $$->limit.burst = $5;
                                $$->limit.type  = NFT_LIMIT_PKT_BYTES;
                                $$->limit.flags = $3;
                        }
@@ -3250,10 +3243,33 @@ limit_burst_pkts        :       /* empty */                     { $$ = 5; }
                        |       BURST   NUM     PACKETS         { $$ = $2; }
                        ;
 
+limit_rate_pkts                :       NUM     SLASH   time_unit
+                       {
+                               $$.rate = $1;
+                               $$.unit = $3;
+                       }
+                       ;
+
 limit_burst_bytes      :       /* empty */                     { $$ = 5; }
                        |       BURST   limit_bytes             { $$ = $2; }
                        ;
 
+limit_rate_bytes       :       NUM     STRING
+                       {
+                               struct error_record *erec;
+                               uint64_t rate, unit;
+
+                               erec = rate_parse(&@$, $2, &rate, &unit);
+                               xfree($2);
+                               if (erec != NULL) {
+                                       erec_queue(erec, state->msgs);
+                                       YYERROR;
+                               }
+                               $$.rate = rate * $1;
+                               $$.unit = unit;
+                       }
+                       ;
+
 limit_bytes            :       NUM     BYTES           { $$ = $1; }
                        |       NUM     STRING
                        {
@@ -4283,44 +4299,34 @@ set_elem_stmt           :       COUNTER close_scope_counter
                                $$->counter.packets = $3;
                                $$->counter.bytes = $5;
                        }
-                       |       LIMIT   RATE    limit_mode      NUM     SLASH   time_unit       limit_burst_pkts        close_scope_limit
+                       |       LIMIT   RATE    limit_mode      limit_rate_pkts       limit_burst_pkts  close_scope_limit
                        {
-                               if ($7 == 0) {
-                                       erec_queue(error(&@7, "limit burst must be > 0"),
+                               if ($5 == 0) {
+                                       erec_queue(error(&@5, "limit burst must be > 0"),
                                                   state->msgs);
                                        YYERROR;
                                }
                                $$ = limit_stmt_alloc(&@$);
-                               $$->limit.rate  = $4;
-                               $$->limit.unit  = $6;
-                               $$->limit.burst = $7;
+                               $$->limit.rate  = $4.rate;
+                               $$->limit.unit  = $4.unit;
+                               $$->limit.burst = $5;
                                $$->limit.type  = NFT_LIMIT_PKTS;
                                $$->limit.flags = $3;
                        }
-                       |       LIMIT   RATE    limit_mode      NUM     STRING  limit_burst_bytes       close_scope_limit
+                       |       LIMIT   RATE    limit_mode      limit_rate_bytes  limit_burst_bytes     close_scope_limit
                        {
-                               struct error_record *erec;
-                               uint64_t rate, unit;
-
-                               if ($6 == 0) {
+                               if ($5 == 0) {
                                        erec_queue(error(&@6, "limit burst must be > 0"),
                                                   state->msgs);
                                        YYERROR;
                                }
-                               erec = rate_parse(&@$, $5, &rate, &unit);
-                               xfree($5);
-                               if (erec != NULL) {
-                                       erec_queue(erec, state->msgs);
-                                       YYERROR;
-                               }
-
                                $$ = limit_stmt_alloc(&@$);
-                               $$->limit.rate  = rate * $4;
-                               $$->limit.unit  = unit;
-                               $$->limit.burst = $6;
+                               $$->limit.rate  = $4.rate;
+                               $$->limit.unit  = $4.unit;
+                               $$->limit.burst = $5;
                                $$->limit.type  = NFT_LIMIT_PKT_BYTES;
                                $$->limit.flags = $3;
-                        }
+                       }
                        |       CT      COUNT   NUM     close_scope_ct
                        {
                                $$ = connlimit_stmt_alloc(&@$);
@@ -4553,34 +4559,25 @@ ct_obj_alloc            :       /* empty */
                        }
                        ;
 
-limit_config           :       RATE    limit_mode      NUM     SLASH   time_unit       limit_burst_pkts
+limit_config           :       RATE    limit_mode      limit_rate_pkts limit_burst_pkts
                        {
                                struct limit *limit;
 
                                limit = &$<obj>0->limit;
-                               limit->rate     = $3;
-                               limit->unit     = $5;
-                               limit->burst    = $6;
+                               limit->rate     = $3.rate;
+                               limit->unit     = $3.unit;
+                               limit->burst    = $4;
                                limit->type     = NFT_LIMIT_PKTS;
                                limit->flags    = $2;
                        }
-                       |       RATE    limit_mode      NUM     STRING  limit_burst_bytes
+                       |       RATE    limit_mode      limit_rate_bytes        limit_burst_bytes
                        {
                                struct limit *limit;
-                               struct error_record *erec;
-                               uint64_t rate, unit;
-
-                               erec = rate_parse(&@$, $4, &rate, &unit);
-                               xfree($4);
-                               if (erec != NULL) {
-                                       erec_queue(erec, state->msgs);
-                                       YYERROR;
-                               }
 
                                limit = &$<obj>0->limit;
-                               limit->rate     = rate * $3;
-                               limit->unit     = unit;
-                               limit->burst    = $5;
+                               limit->rate     = $3.rate;
+                               limit->unit     = $3.unit;
+                               limit->burst    = $4;
                                limit->type     = NFT_LIMIT_PKT_BYTES;
                                limit->flags    = $2;
                        }