Hello
I use ifstated(8) to track the state of the the external interface that
is
configured via dhcp and based upon the state, (re)configure a VXLAN
interface.
The ifstated.conf currently looks like
===
exif="em0"
vxif="vxlan0"
init-state state_down
state state_up {
init {
run "ifconfig vlxna0 up"
}
if ( "ifconfig em0 | grep -q inet" every 60 )
run "sleep 30 && ifconfig vxlan0 tunnel `ifconfig em0 | \
sed -nre 's/.*inet ([^ ]+).*/\1/p'` \
`dig +short name-of-remote-device`"
if $exif.link.down
set-state state_down
}
state state_down {
init {
run "ifconfig vxlan0 down"
}
if $exif.link.up
set-state state_up
}
===
The problem I ran into is that when I tried to substitute the vxlan0 and
em0
entries with exif and vxif in the 'run' statements no macro expansion
occurred.
This patch allows macro expansion within the 'run' and 'if' statements.
I appreciate any feedback.
Regards
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/ifstated/parse.y,v
retrieving revision 1.47
diff -u -p -r1.47 parse.y
--- parse.y 21 Aug 2017 17:38:55 -0000 1.47
+++ parse.y 26 Feb 2018 22:47:11 -0000
@@ -509,9 +509,10 @@ int
yylex(void)
{
u_char buf[8096];
- u_char *p, *val;
+ u_char *p, *p1, *val;
int quotec, next, c;
int token;
+ size_t x;
top:
p = buf;
@@ -575,6 +576,35 @@ top:
} else if (c == '\0') {
yyerror("syntax error");
return (findeol());
+ } else if (c == '$') {
+ p1 = p;
+ while (1) {
+ if ((c = lgetc(0)) == EOF)
+ return (0);
+ if (p1 + 1 >= buf + sizeof(buf) - 1) {
+ yyerror("string too long");
+ return (findeol());
+ }
+ if (isalnum(c) || c == '_') {
+ *p1++ = c;
+ continue;
+ }
+ *p1 = '\0';
+ lungetc(c);
+ break;
+ }
+ val = symget(p);
+ if (val == NULL) {
+ yyerror("macro '%s' not defined", buf);
+ return (findeol());
+ }
+ x = strlcpy(p,val,(buf-p));
+ if (x >= (buf-p)) {
+ yyerror("string too long");
+ return (findeol());
+ }
+ p += x;
+ continue;
}
if (p + 1 >= buf + sizeof(buf) - 1) {
yyerror("string too long");