On Mon, Sep 14, 2020 at 02:09:27PM +0900, YASUOKA Masahiko wrote:
> When pf rule with a "on rdomain n" with nonexisting rdomain n causes
> 
>   /etc/pf.conf:XXX: rdomain n does not exist
Actually, that should just work regardless of whether the rounting
domain exists at ruleset creation time;  just like it is the case with
interface names/groups which may come and go at runtime without
requiring changes to the ruleset.

Rules on nonexistent interfaces won't match, routing domains (and
ultimately routing tables) should behave the same, I think.

Here's a diff that does this for routing domains allowing me to always
use `on rdomain 5' - I've tested it with a few examplatory rulesets and
behaviour is as expected.

It will need more eye balling and I am not pushing such changes before
release, but if that is a general direction we agree, your proposed
`rtable' fix could move along and become just as flexible instead.

Discussed with claudio at k2k20.


Index: /sys/net/pf_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.356
diff -u -p -r1.356 pf_ioctl.c
--- /sys/net/pf_ioctl.c 24 Aug 2020 15:41:15 -0000      1.356
+++ /sys/net/pf_ioctl.c 14 Sep 2020 22:27:55 -0000
@@ -2820,10 +2820,8 @@ pf_rule_copyin(struct pf_rule *from, str
        if (to->rtableid >= 0 && !rtable_exists(to->rtableid))
                return (EBUSY);
        to->onrdomain = from->onrdomain;
-       if (to->onrdomain >= 0 && !rtable_exists(to->onrdomain))
-               return (EBUSY);
-       if (to->onrdomain >= 0)         /* make sure it is a real rdomain */
-               to->onrdomain = rtable_l2(to->onrdomain);
+       if (to->rtableid < 0 || to->rtableid > RT_TABLEID_MAX)
+               return (EINVAL);
 
        for (i = 0; i < PFTM_MAX; i++)
                to->timeout[i] = from->timeout[i];
Index: sbin/pfctl/parse.y
===================================================================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.701
diff -u -p -r1.701 parse.y
--- sbin/pfctl/parse.y  28 Jan 2020 15:40:35 -0000      1.701
+++ sbin/pfctl/parse.y  14 Sep 2020 21:52:54 -0000
@@ -392,7 +392,6 @@ 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     filteropts_to_rule(struct pf_rule *, struct filter_opts *);
 
 TAILQ_HEAD(loadanchorshead, loadanchors)
@@ -2475,8 +2474,6 @@ if_item           : STRING                        {
                | RDOMAIN NUMBER                {
                        if ($2 < 0 || $2 > RT_TABLEID_MAX)
                                yyerror("rdomain %lld outside range", $2);
-                       else if (rdomain_exists($2) != 1)
-                               yyerror("rdomain %lld does not exist", $2);
 
                        $$ = calloc(1, sizeof(struct node_if));
                        if ($$ == NULL)
@@ -5865,40 +5862,6 @@ map_tos(char *s, int *val)
                return (1);
        }
        return (0);
-}
-
-int
-rdomain_exists(u_int rdomain)
-{
-       size_t                   len;
-       struct rt_tableinfo      info;
-       int                      mib[6];
-       static u_int             found[RT_TABLEID_MAX+1];
-
-       if (found[rdomain] == 1)
-               return 1;
-
-       mib[0] = CTL_NET;
-       mib[1] = PF_ROUTE;
-       mib[2] = 0;
-       mib[3] = 0;
-       mib[4] = NET_RT_TABLE;
-       mib[5] = rdomain;
-
-       len = sizeof(info);
-       if (sysctl(mib, 6, &info, &len, NULL, 0) == -1) {
-               if (errno == ENOENT) {
-                       /* table nonexistent */
-                       return 0;
-               }
-               err(1, "%s", __func__);
-       }
-       if (info.rti_domainid == rdomain) {
-               found[rdomain] = 1;
-               return 1;
-       }
-       /* rdomain is a table, but not an rdomain */
-       return 0;
 }
 
 int

Reply via email to