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");

Reply via email to