Hi,
When pf rule with a "on rdomain n" with nonexisting rdomain n causes
/etc/pf.conf:XXX: rdomain n does not exist
error. But with a "rtable n" with nonexisting rtable n will cause
pfctl: DIOCADDRULE: Device busy
error. It is hard to find the cause by this error message.
/etc/pf.conf:XXX: rtable n does not exist
is better.
ok?
Make pfctl check if the rtable really exists when parsing the config.
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 04:54:39 -0000
@@ -393,6 +393,7 @@ u_int16_t parseicmpspec(char *, sa_famil
int kw_casecmp(const void *, const void *);
int map_tos(char *string, int *);
int rdomain_exists(u_int);
+int rtable_exists(u_int);
int filteropts_to_rule(struct pf_rule *, struct filter_opts *);
TAILQ_HEAD(loadanchorshead, loadanchors)
@@ -1217,6 +1218,10 @@ antispoof_opt : LABEL label {
yyerror("invalid rtable id");
YYERROR;
}
+ else if (rtable_exists($2) != 1) {
+ yyerror("rtable %lld does not exist", $2);
+ YYERROR;
+ }
antispoof_opts.rtableid = $2;
}
;
@@ -2001,6 +2006,10 @@ filter_opt : USER uids {
yyerror("invalid rtable id");
YYERROR;
}
+ else if (rtable_exists($2) != 1) {
+ yyerror("rtable %lld does not exist", $2);
+ YYERROR;
+ }
filter_opts.rtableid = $2;
}
| DIVERTTO STRING PORT portplain {
@@ -5899,6 +5908,36 @@ rdomain_exists(u_int rdomain)
}
/* rdomain is a table, but not an rdomain */
return 0;
+}
+
+int
+rtable_exists(u_int rtable)
+{
+ size_t len;
+ struct rt_tableinfo info;
+ int mib[6];
+ static u_int found[RT_TABLEID_MAX+1];
+
+ if (found[rtable] == 1)
+ return 1;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0;
+ mib[3] = 0;
+ mib[4] = NET_RT_TABLE;
+ mib[5] = rtable;
+
+ len = sizeof(info);
+ if (sysctl(mib, 6, &info, &len, NULL, 0) == -1) {
+ if (errno == ENOENT) {
+ /* table nonexistent */
+ return 0;
+ }
+ err(1, "%s", __func__);
+ }
+ found[rtable] = 1;
+ return 1;
}
int