On Wed, Sep 16, 2020 at 07:49:19PM +0900, YASUOKA Masahiko wrote:
> New diff is using -1 for ENOENT.
> 
> Also domainid == 0 is a valid domain id, but previous diff cannot make
> a cache of it since 0 is the default value.  So new diff is doing
> 
> -     static u_int             found[RT_TABLEID_MAX+1];
> +     static struct {
> +             int      found;
> +             int      domainid;
> +     }                        rtables[RT_TABLEID_MAX+1];
> 
> to distinguish the default 0 and domainid 0.
This looks more complicated than it needs to be, but I also don't want
to bikeshed it;  given that the parser is happy with this and we plan to
remove this code alltogether anyway in the next release cycle:  OK kn.

Alternatively, here's a much simpler diff resembling what I had in mind.
Feel free to commit this instead (with my OK), give me an OK for it or
go ahead with yours.

It uses the same function and reflects the fact that every rdomain is a
rtable but not every rtable is also a rdomain (your choice of `domainid'
seems inconsistent with that).

Index: parse.y
===================================================================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.701
diff -u -p -r1.701 parse.y
--- parse.y     28 Jan 2020 15:40:35 -0000      1.701
+++ parse.y     16 Sep 2020 13:58:23 -0000
@@ -392,7 +392,7 @@ int  invalid_redirect(struct node_host *
 u_int16_t parseicmpspec(char *, sa_family_t);
 int     kw_casecmp(const void *, const void *);
 int     map_tos(char *string, int *);
-int     rdomain_exists(u_int);
+int     lookup_rtable(u_int);
 int     filteropts_to_rule(struct pf_rule *, struct filter_opts *);
 
 TAILQ_HEAD(loadanchorshead, loadanchors)
@@ -1216,6 +1216,9 @@ antispoof_opt     : LABEL label   {
                        if ($2 < 0 || $2 > RT_TABLEID_MAX) {
                                yyerror("invalid rtable id");
                                YYERROR;
+                       } else if (lookup_rtable($2) >= 1) {
+                               yyerror("rtable %lld does not exist", $2);
+                               YYERROR;
                        }
                        antispoof_opts.rtableid = $2;
                }
@@ -2000,6 +2003,9 @@ filter_opt        : USER uids {
                        if ($2 < 0 || $2 > RT_TABLEID_MAX) {
                                yyerror("invalid rtable id");
                                YYERROR;
+                       } else if (lookup_rtable($2) >= 1) {
+                               yyerror("rtable %lld does not exist", $2);
+                               YYERROR;
                        }
                        filter_opts.rtableid = $2;
                }
@@ -2475,7 +2481,7 @@ if_item           : STRING                        {
                | RDOMAIN NUMBER                {
                        if ($2 < 0 || $2 > RT_TABLEID_MAX)
                                yyerror("rdomain %lld outside range", $2);
-                       else if (rdomain_exists($2) != 1)
+                       else if (lookup_rtable($2) != 2)
                                yyerror("rdomain %lld does not exist", $2);
 
                        $$ = calloc(1, sizeof(struct node_if));
@@ -5868,37 +5874,38 @@ map_tos(char *s, int *val)
 }
 
 int
-rdomain_exists(u_int rdomain)
+lookup_rtable(u_int rtableid)
 {
        size_t                   len;
        struct rt_tableinfo      info;
        int                      mib[6];
        static u_int             found[RT_TABLEID_MAX+1];
 
-       if (found[rdomain] == 1)
-               return 1;
+       if (found[rtableid])
+               return found[rtableid];
 
        mib[0] = CTL_NET;
        mib[1] = PF_ROUTE;
        mib[2] = 0;
        mib[3] = 0;
        mib[4] = NET_RT_TABLE;
-       mib[5] = rdomain;
+       mib[5] = rtableid;
 
        len = sizeof(info);
        if (sysctl(mib, 6, &info, &len, NULL, 0) == -1) {
                if (errno == ENOENT) {
                        /* table nonexistent */
+                       found[rtableid] = 0;
                        return 0;
                }
                err(1, "%s", __func__);
        }
-       if (info.rti_domainid == rdomain) {
-               found[rdomain] = 1;
-               return 1;
+       if (info.rti_domainid == rtableid) {
+               found[rtableid] = 2;
+               return 2;
        }
-       /* rdomain is a table, but not an rdomain */
-       return 0;
+       found[rtableid] = 1;
+       return 1;
 }
 
 int

Reply via email to