Re: update ifstated parser

2018-08-25 Thread Marcus MERIGHI
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

2018-03-05 Thread Rob Pierce
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

2018-02-26 Thread Michael Graves

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