Re: update ifstated parser
Hello, cleaning up my inbox I stumbled over this, it would be handy, still applies and compiles. But... it does not like my config when running "ifstated -n -v -f /etc/ifstated.conf", as opposed to ifstated *before* the patch. part of /etc/ifstated.conf init-state auto wireif = 'em0' waveif = 'iwn0' wire_act = '( "ifconfig wire | grep -q \"status: active$\"" every 10 )' wave_act = '( "ifconfig wlan | grep -q \"status: active$\"" every 10 )' output of "ifstated -n -v -f /etc/ifstated.conf" wireif = "em0" waveif = "iwn0" /etc/ifstated.conf:6: macro '( "ifconfig wire | grep -q \"status: active\' not defined /etc/ifstated.conf:6: syntax error Is there anything I can do apart from learning C? BTW, rob@'s ifstated.conf.5 clarification was commited, thus documentation and reality are aligned. Marcus r...@2keys.ca (Rob Pierce), 2018.03.05 (Mon) 19:55 (CET): > On Mon, Feb 26, 2018 at 05:10:43PM -0600, Michael Graves wrote: > > 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 - 1.47 > > +++ parse.y 26 Feb 2018 22:47:11 - > > @@ -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"); > > Hey Michael, > > Thank you for your email. I have been playing with your diff and will send you > some comments shortly. This might be worth future consideration. > > For now, I think we should update the man page to clearly state that macro > expansion does not take place inside quotes as is currently done in the other > man pages. > > Ok? > > Index: ifstated.conf.5 > === > RCS file: /cvs/src/usr.sbin/ifstated/ifstated.conf.5,v
Re: update ifstated parser
On Mon, Feb 26, 2018 at 05:10:43PM -0600, Michael Graves wrote: > 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 - 1.47 > +++ parse.y 26 Feb 2018 22:47:11 - > @@ -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"); Hey Michael, Thank you for your email. I have been playing with your diff and will send you some comments shortly. This might be worth future consideration. For now, I think we should update the man page to clearly state that macro expansion does not take place inside quotes as is currently done in the other man pages. Ok? Index: ifstated.conf.5 === RCS file: /cvs/src/usr.sbin/ifstated/ifstated.conf.5,v retrieving revision 1.11 diff -u -p -r1.11 ifstated.conf.5 --- ifstated.conf.5 3 Mar 2018 02:57:17 - 1.11 +++ ifstated.conf.5 5 Mar 2018 18:39:06 - @@ -55,6 +55,8 @@ instead of using the first state defined Macros can be defined that will later be expanded in context. Macro names must start with a letter, digit, or underscore, and may contain any of those characters. +Macros are not expanded inside quotes. +.Pp Macro names may not be reserved words like, for example, .Ar state or
update ifstated parser
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 - 1.47 +++ parse.y 26 Feb 2018 22:47:11 - @@ -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");