Re: fun with smtpd, (two bugs)

2014-05-10 Thread Denis Fondras
Le 10/05/2014 17:54, Creamy a écrit :
 
 table creamy db:/etc/mail/creamy.db
 table secrets db:/etc/mail/secrets.db
 accept sender creamy for domain example.com relay via 
 smtps+auth://foo...@smtp.creamylan.lan auth secrets
 

Shouldn't it be :
accept sender creamy for domain example.com ...



Re: network autoconfig

2014-07-13 Thread Denis Fondras
 
 from the user's PoV, there shouldn't be more needed than
   ifconfig if inet autoconf
   ifconfig if inet6 autoconf
 aka inet/inet6 autoconf in hostname.if.
 

I'm curious to see what will come out of it as I cannot envision any
added value of these autoconf compared to dhclient.

Denis



urndis(4) manpage : add Geeksphone ONE

2011-05-08 Thread Denis Fondras

Hello tech@,

Just a tiny diff to add another supported/tested phone to the manpage of 
urndis(4).


Denis

---

Index: src/share/man/man4/urndis.4
===
RCS file: /cvs/src/share/man/man4/urndis.4,v
retrieving revision 1.8
diff -u -r1.8 urndis.4
--- src/share/man/man4/urndis.4 29 Apr 2011 17:04:33 -  1.8
+++ src/share/man/man4/urndis.4 8 May 2011 13:03:19 -
@@ -61,6 +61,8 @@
 HTC Wildfire
 .It
 Samsung Nexus S
+.It
+Geeksphone ONE
 .El
 .Pp
 The



Re: DNSSEC and OpenBSD default BIND

2010-08-16 Thread Denis Fondras

Hello,

Following my previous message from July, 18th, I am back to BIND as my 
tests with nsd/unbound are not really conclusive (can't make both work 
with only one IP and they don't support views).


So I rolled up my sleeves and started to port OpenBSD changes to 
BIND-9.7.1-P2. Changing str-functions to strl-functions was the easy part :)
Unfortunately, I have a hard time with privileges separation and port 
randomization. In fact I don't know where to place them.
I made a diff between OpenBSD version and BIND-9.4.2-P2 and tried to 
port it to BIND-9.7.1-P2 but it seems there was a huge change in socket 
and pidfile handling.


Is anyone willing to help understanding these changes ?

Thank you in advance,
Denis



Re: bgpd.conf macros on 5.5 and up

2015-02-03 Thread Denis Fondras
Hi all,

Here is a patch to revert back to 5.4 behaviour so the manual example with
braces works again :

# cat /etc/bgpd.conf

  
AS 65001
router-id 10.0.0.1

neighbor 10.0.2.0 {
remote-as   65004
descr   upstream2
local-address   10.0.0.8
ipsec ah ike
}

deny from any prefix { 192.168.0.0/16, 10.0.0.0/8 or-longer }
good={ 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
bad={ 224.0.0.0/4 prefixlen = 4, 240.0.0.0/4 prefixlen = 4 }
ugly={ 127.0.0.1/8, 169.254.0.0/16 }
deny from any prefix { $good $bad $ugly }


# bgpd -dnv
good = { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
bad = { 224.0.0.0/4 prefixlen = 4, 240.0.0.0/4 prefixlen = 4 }
ugly = { 127.0.0.1/8, 169.254.0.0/16 }
AS 65001
router-id 10.0.0.1
socket /var/run/bgpd.sock
holdtime min 3
fib-priority 48


rde rib Adj-RIB-In no evaluate
rde rib Loc-RIB rtable 0 fib-update yes


neighbor 10.0.2.0 {
descr upstream2
remote-as 65004
local-address 10.0.0.8
announce self
enforce neighbor-as yes
ipsec ah ike
announce IPv4 unicast
softreconfig in yes
softreconfig out yes
}

deny from any prefix 10.0.0.0/8 prefixlen = 8 
deny from any prefix 192.168.0.0/16 
deny from any prefix 10.0.0.0/8 
deny from any prefix 172.16.0.0/12 
deny from any prefix 192.168.0.0/16 
deny from any prefix 240.0.0.0/4 prefixlen = 4 
deny from any prefix 224.0.0.0/4 prefixlen = 4 
deny from any prefix 169.254.0.0/16 
deny from any prefix 127.0.0.1/8 


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.275
diff -u -p -r1.275 parse.y
--- parse.y 20 Nov 2014 05:51:20 -  1.275
+++ parse.y 3 Feb 2015 16:39:40 -
@@ -211,7 +211,8 @@ typedef struct {
 %type  v.prefixlen   prefixlenop
 %type  v.filter_set  filter_set_opt
 %type  v.filter_set_head filter_set filter_set_l
-%type  v.filter_prefix   filter_prefix filter_prefix_l filter_prefix_h
+%type  v.filter_prefix   filter_prefix filter_prefix_l 
+%type  v.filter_prefix   filter_prefix_h filter_prefix_m
 %type  v.u8  unaryop binaryop filter_as_type
 %type  v.encspec encspec
 %%
@@ -1518,10 +1519,23 @@ filter_prefix_h : IPV4 prefixlenop
{
}
}
| PREFIX filter_prefix  { $$ = $2; }
-   | PREFIX '{' filter_prefix_l '}'{ $$ = $3; }
+   | PREFIX '{' filter_prefix_m '}'{ $$ = $3; }
;
 
-filter_prefix_l: filter_prefix { $$ = $1; }
+filter_prefix_m: filter_prefix_l
+   | '{' filter_prefix_l '}'   { $$ = $2; }
+   | '{' filter_prefix_l '}' filter_prefix_m
+   {
+   struct filter_prefix_l  *p;
+
+   /* merge, both can be lists */
+   for (p = $2; p != NULL  p-next != NULL; p = p-next)
+   ;   /* nothing */
+   if (p != NULL)
+   p-next = $4;
+   $$ = $2;
+   }
+filter_prefix_l: filter_prefix { $$ = $1; }
| filter_prefix_l comma filter_prefix   {
$3-next = $1;
$$ = $3;



Re: [Patch] New item to the Migrating to OpenBSD guide

2015-06-28 Thread Denis Fondras
 This patch is regarding the fact that there are no binary updates, which is a
 given thing
 

What you missed : https://stable.mtier.org/



Update to /etc/services

2015-07-26 Thread Denis Fondras
Hello,

Following is a patch to add BFD specific ports (RFC5881) and move RDP entry so
the list is ordered.

Denis

Index: etc/services
===
RCS file: /cvs/src/etc/services,v
retrieving revision 1.93
diff -u -p -r1.93 services
--- etc/services31 Dec 2014 11:52:22 -  1.93
+++ etc/services26 Jul 2015 08:52:33 -
@@ -228,12 +228,16 @@ eppc  3031/tcp# Remote
AppleEvents/PP
 eppc   3031/udp# Remote AppleEvents/PPC Toolbox
 iscsi  3260/tcp# ISCSI
 mysql  3306/tcp# MySQL
+rdp3389/tcp# Microsoft Remote Desktop
Protocol
 iapp   3517/tcp802-11-iapp # IEEE 802.11f IAPP
 iapp   3517/udp802-11-iapp # IEEE 802.11f IAPP
 daap   3689/tcp# Digital Audio Access Protocol
 daap   3689/udp# Digital Audio Access Protocol
 svn3690/tcp# Subversion
-rdp3389/tcp# Microsoft Remote Desktop
Protocol
+bfd-control 3784/tcp   # BFD Control Protocol
+bfd-control 3784/udp   # BFD Control Protocol
+bfd-echo3785/tcp   # BFD Echo Protocol
+bfd-echo3785/udp   # BFD Echo Protocol
 sieve  4190/tcp# ManageSieve Protocol
 sieve  4190/udp# ManageSieve Protocol
 krb524 /tcp# Kerberos 5-4



Re: Update to /etc/services

2015-07-26 Thread Denis Fondras
 Are both TCP and UDP actually used for these? If not, please only list the
 protocols which are used (not just reserved).
 

Only UDP is used currently.

Index: services
===
RCS file: /cvs/src/etc/services,v
retrieving revision 1.93
diff -u -p -r1.93 services
--- services31 Dec 2014 11:52:22 -  1.93
+++ services26 Jul 2015 19:02:41 -
@@ -228,12 +228,14 @@ eppc  3031/tcp# Remote
AppleEvents/PP
 eppc   3031/udp# Remote AppleEvents/PPC Toolbox
 iscsi  3260/tcp# ISCSI
 mysql  3306/tcp# MySQL
+rdp3389/tcp# Microsoft Remote Desktop 
Protocol
 iapp   3517/tcp802-11-iapp # IEEE 802.11f IAPP
 iapp   3517/udp802-11-iapp # IEEE 802.11f IAPP
 daap   3689/tcp# Digital Audio Access Protocol
 daap   3689/udp# Digital Audio Access Protocol
 svn3690/tcp# Subversion
-rdp3389/tcp# Microsoft Remote Desktop 
Protocol
+bfd-control 3784/udp   # BFD Control Protocol
+bfd-echo3785/udp   # BFD Echo Protocol
 sieve  4190/tcp# ManageSieve Protocol
 sieve  4190/udp# ManageSieve Protocol
 krb524 /tcp# Kerberos 5-4



Re: Weak Diffie-Hellman default in nginx port

2015-07-21 Thread Denis Fondras
On Tue, Jul 21, 2015 at 12:31:33PM +0200, lophos wrote:
 The nginx config (although disabled by default) supports weak Diffie Hellman 
 cipher according to ssllabs.com test 
 (Grade B).
 

You'd better generate stronger DH-param than disable DHE.



Re: Bulkget & snmpd

2015-10-09 Thread Denis Fondras
On Thu, Oct 08, 2015 at 08:39:40AM +0100, Stuart Henderson wrote:
> > O. And now I find Gerhard Roth's post
> > 
> > https://marc.info/?l=openbsd-tech=143375327425321=2
> > 

Oh! I missed this one. Thank you very much Stuart.

Denis



[patch] httpd: fcgi/PATH_INFO not handled correctly

2015-08-26 Thread Denis Fondras
Hello,

While using httpd together uwsgi and Flask, I noticed that GET requests to /
returned 404. The same setup with nginx was returning 200.

The culprit is that PATH_INFO is not set when REQUEST_URI is /.
The following patch correctly set PATH_INFO in every case.

Denis


Index: httpd.c
===
RCS file: /cvs/src/usr.sbin/httpd/httpd.c,v
retrieving revision 1.39
diff -u -p -r1.39 httpd.c
--- httpd.c 20 Aug 2015 13:00:23 -  1.39
+++ httpd.c 26 Aug 2015 18:12:34 -
@@ -695,7 +695,7 @@ path_info(char *path)
 
for (p = end; p  start; p--) {
/* Scan every path component from the end and at each '/' */
-   if (p  end  *p != '/')
+   if (p = end  *p != '/')
continue;
 
/* Temporarily cut the path component out */



Re: virtualization support

2015-09-01 Thread Denis Fondras
> TL;DR - a native hypervisor is coming. stay tuned.
> 

Good job !
Getting rid of systemdOS by 5.9 would be a blast :D



Re: IPv6 - 6rd support

2015-09-16 Thread Denis Fondras
On Wed, Sep 16, 2015 at 03:38:22PM +0100, Stuart Henderson wrote:
> On 2015/09/16 09:39, David Hill wrote:
> > So I need to attach an IP somewhere.  Both the FreeBSD and NetBSD in the
> > u6rd manpage say I need an IPv6 address on tun0.
> > 
> >NetBSD 5.1
> >  # ifconfig tun0 create
> >  # ifconfig tun0 inet6 2001:db8:cb00:7101::1/32
> 
> This works if you put it into tap mode (ifconfig tun0 link0) but that
> is probably not what your application needs.
> 
> Same if you remove the /32 prefix.
> 
> Interestingly doing the same on gif or gre does work.
> 

Setting link0 sets IFF_MULTICAST.

The main difference between Free and OpenBSD is that tun(4) interfaces are
created with IFF_MULTICAST with FBSD :

if_tun.c from FreeBSD (line 380) :
ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;

IPv6 requires multicast :)

Denis



Giving love to ospf6d

2015-12-15 Thread Denis Fondras
Hello,

I want to use ospf6d but it is a bit rough around the edge.
A simple "ospf6ctl reload" makes it crash ! Come on, this is far from the
expected OpenBSD quality :p

I made a patch that make it crash less often. I still stumble on some "lost
interface" or "unknown interface" from time to time, lsa addresses are
often duplicated but it is better (from my point of view).

Concerning the duplicated lsa, this is what I get before reload :
orig_link_lsa: interface rl0
orig_link_lsa: link local address fe80::20a:e4ff:fe03:87b4
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: prefix 2001:7a8:b5ad:2030::

And after reload :
orig_link_lsa: interface rl0
orig_link_lsa: link local address fe80::20a:e4ff:fe03:87b4
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: link local address fe80::20a:e4ff:fe03:87b4
orig_link_lsa: interface rl0
orig_link_lsa: link local address fe80::20a:e4ff:fe03:87b4
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: link local address fe80::20a:e4ff:fe03:87b4
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: interface rl0
orig_link_lsa: link local address fe80::20a:e4ff:fe03:87b4
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: link local address fe80::20a:e4ff:fe03:87b4
orig_link_lsa: prefix 2001:7a8:b5ad:2030::
orig_link_lsa: prefix 2001:7a8:b5ad:2030::

The fix would be (I think, I am still investigating) to check for existing LSA
before adding a new one in ospfe_dispatch_main() (ospfe.c) when handling
IMSG_IFADDRNEW. Perhaps use a tree instead of a list ?

Would someone help me to give some love to ospf6d to improve it and make it
usable ?

Denis

Index: interface.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v
retrieving revision 1.22
diff -u -p -r1.22 interface.c
--- interface.c 27 Sep 2015 17:31:50 -  1.22
+++ interface.c 15 Dec 2015 16:40:33 -
@@ -170,8 +170,7 @@ int
 if_init(void)
 {
TAILQ_INIT();
-
-   return (fetchifs(0));
+   return (0);
 }
 
 /* XXX using a linked list should be OK for now */
Index: ospf6d.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.c,v
retrieving revision 1.29
diff -u -p -r1.29 ospf6d.c
--- ospf6d.c5 Dec 2015 13:12:41 -   1.29
+++ ospf6d.c15 Dec 2015 16:40:34 -
@@ -597,6 +597,7 @@ ospf_reload(void)
 {
struct area *area;
struct ospfd_conf   *xconf;
+   struct iface*iface;
 
if ((xconf = parse_config(conffile, ospfd_conf->opts)) == NULL)
return (-1);
@@ -605,10 +606,16 @@ ospf_reload(void)
if (ospf_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
return (-1);
 
-   /* send areas, interfaces happen out of band */
+   /* send areas & interfaces */
LIST_FOREACH(area, >area_list, entry) {
if (ospf_sendboth(IMSG_RECONF_AREA, area, sizeof(*area)) == -1)
return (-1);
+
+   LIST_FOREACH(iface, >iface_list, entry) {
+   if (ospf_sendboth(IMSG_RECONF_IFACE, iface,
+   sizeof(*iface)) == -1)
+   return (-1);
+   }
}
 
if (ospf_sendboth(IMSG_RECONF_END, NULL, 0) == -1)
Index: ospf6d.h
===
RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.h,v
retrieving revision 1.29
diff -u -p -r1.29 ospf6d.h
--- ospf6d.h27 Sep 2015 17:31:50 -  1.29
+++ ospf6d.h15 Dec 2015 16:40:34 -
@@ -121,6 +121,7 @@ enum imsg_type {
IMSG_ABR_DOWN,
IMSG_RECONF_CONF,
IMSG_RECONF_AREA,
+   IMSG_RECONF_IFACE,
IMSG_RECONF_END,
IMSG_DEMOTE
 };
Index: ospfe.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v
retrieving revision 1.47
diff -u -p -r1.47 ospfe.c
--- ospfe.c 5 Dec 2015 13:12:41 -   1.47
+++ ospfe.c 15 Dec 2015 16:40:34 -
@@ -250,6 +250,7 @@ ospfe_dispatch_main(int fd, short event,
static struct area  *narea;
struct area *area;
struct iface*iface, *ifp;
+   struct iface*niface;
struct ifaddrchange *ifc;
struct iface_addr   *ia, *nia;
struct imsg  imsg;
@@ -388,6 +389,19 @@ ospfe_dispatch_main(int fd, short event,
RB_INIT(>lsa_tree);
 
LIST_INSERT_HEAD(>area_list, narea, entry);
+   break;
+   case IMSG_RECONF_IFACE:
+   if ((niface = malloc(sizeof(struct iface))) == NULL)
+   fatal(NULL);
+
+   memcpy(niface, imsg.data, 

Re: Giving love to ospf6d

2015-12-20 Thread Denis Fondras
Hello,

Here is the second iteration of the patch. It fixes a crash and it is a
refactoring.

Denis

Index: area.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/area.c,v
retrieving revision 1.4
diff -u -p -r1.4 area.c
--- area.c  28 Dec 2008 20:08:31 -  1.4
+++ area.c  20 Dec 2015 20:38:00 -
@@ -57,7 +57,6 @@ area_del(struct area *area)
/* clean lists */
while ((iface = LIST_FIRST(>iface_list)) != NULL) {
LIST_REMOVE(iface, entry);
-   if_del(iface);
}
 
while ((n = LIST_FIRST(>nbr_list)) != NULL)
Index: interface.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v
retrieving revision 1.22
diff -u -p -r1.22 interface.c
--- interface.c 27 Sep 2015 17:31:50 -  1.22
+++ interface.c 20 Dec 2015 20:38:00 -
@@ -170,8 +170,7 @@ int
 if_init(void)
 {
TAILQ_INIT();
-
-   return (fetchifs(0));
+   return (0);
 }
 
 /* XXX using a linked list should be OK for now */
Index: ospf6d.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.c,v
retrieving revision 1.29
diff -u -p -r1.29 ospf6d.c
--- ospf6d.c5 Dec 2015 13:12:41 -   1.29
+++ ospf6d.c20 Dec 2015 20:38:01 -
@@ -597,6 +597,7 @@ ospf_reload(void)
 {
struct area *area;
struct ospfd_conf   *xconf;
+   struct iface*iface;
 
if ((xconf = parse_config(conffile, ospfd_conf->opts)) == NULL)
return (-1);
@@ -605,10 +606,16 @@ ospf_reload(void)
if (ospf_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
return (-1);
 
-   /* send areas, interfaces happen out of band */
+   /* send areas & interfaces */
LIST_FOREACH(area, >area_list, entry) {
if (ospf_sendboth(IMSG_RECONF_AREA, area, sizeof(*area)) == -1)
return (-1);
+
+   LIST_FOREACH(iface, >iface_list, entry) {
+   if (ospf_sendboth(IMSG_RECONF_IFACE, iface,
+   sizeof(*iface)) == -1)
+   return (-1);
+   }
}
 
if (ospf_sendboth(IMSG_RECONF_END, NULL, 0) == -1)
Index: ospf6d.h
===
RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.h,v
retrieving revision 1.29
diff -u -p -r1.29 ospf6d.h
--- ospf6d.h27 Sep 2015 17:31:50 -  1.29
+++ ospf6d.h20 Dec 2015 20:38:01 -
@@ -121,6 +121,7 @@ enum imsg_type {
IMSG_ABR_DOWN,
IMSG_RECONF_CONF,
IMSG_RECONF_AREA,
+   IMSG_RECONF_IFACE,
IMSG_RECONF_END,
IMSG_DEMOTE
 };
Index: ospfe.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v
retrieving revision 1.47
diff -u -p -r1.47 ospfe.c
--- ospfe.c 5 Dec 2015 13:12:41 -   1.47
+++ ospfe.c 20 Dec 2015 20:38:02 -
@@ -250,6 +250,7 @@ ospfe_dispatch_main(int fd, short event,
static struct area  *narea;
struct area *area;
struct iface*iface, *ifp;
+   struct iface*niface;
struct ifaddrchange *ifc;
struct iface_addr   *ia, *nia;
struct imsg  imsg;
@@ -388,6 +389,19 @@ ospfe_dispatch_main(int fd, short event,
RB_INIT(>lsa_tree);
 
LIST_INSERT_HEAD(>area_list, narea, entry);
+   break;
+   case IMSG_RECONF_IFACE:
+   if ((niface = malloc(sizeof(struct iface))) == NULL)
+   fatal(NULL);
+
+   memcpy(niface, imsg.data, sizeof(struct iface));
+
+   LIST_INIT(>nbr_list);
+   TAILQ_INIT(>ls_ack_list);
+   RB_INIT(>lsa_tree);
+
+   narea = area_find(nconf, niface->area_id);
+   LIST_INSERT_HEAD(>iface_list, niface, entry);
break;
case IMSG_RECONF_END:
if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER) !=
Index: parse.y
===
RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v
retrieving revision 1.27
diff -u -p -r1.27 parse.y
--- parse.y 20 Nov 2014 05:51:20 -  1.27
+++ parse.y 20 Dec 2015 20:38:02 -
@@ -924,6 +924,7 @@ parse_config(char *filename, int opts)
LIST_INIT(>area_list);
LIST_INIT(>cand_list);
SIMPLEQ_INIT(>redist_list);
+   fetchifs(0);
 
yyparse();
errors = file->errors;
Index: rde.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v
retrieving revision 1.65
diff -u -p -r1.65 rde.c
--- 

bgpd: print AS range

2016-06-04 Thread Denis Fondras
With the support of AS range filtering, we need to print the configuration
accordingly.

Before :
# bgpd -dnv
[...]
deny from any AS 0
deny from any AS 0 
deny from any AS 65535
deny from any AS 0
deny from any AS 0
deny from any AS 0
deny from any AS 4294967295 

After :
# bgpd -dnv
[...]
deny from any AS 64496 - 64496 
deny from any AS 64512 - 64512 
deny from any AS 65535 
deny from any AS 65536 - 65536 
deny from any AS 65552 - 65552 
deny from any AS 42 - 42 
deny from any AS 4294967295 


Index: printconf.c
===
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
retrieving revision 1.96
diff -u -p -r1.96 printconf.c
--- printconf.c 21 Sep 2015 09:47:15 -  1.96
+++ printconf.c 4 Jun 2016 20:06:52 -
@@ -41,6 +41,7 @@ void   print_peer(struct peer_config *, 
 const char *print_auth_alg(u_int8_t);
 const char *print_enc_alg(u_int8_t);
 voidprint_announce(struct peer_config *, const char *);
+voidprint_as(struct filter_rule *);
 voidprint_rule(struct peer *, struct filter_rule *);
 const char *mrt_type(enum mrt_type);
 voidprint_mrt(struct bgpd_config *, u_int32_t, u_int32_t,
@@ -506,6 +507,26 @@ print_announce(struct peer_config *p, co
printf("%s\tannounce %s\n", c, aid2str(aid));
 }
 
+void print_as(struct filter_rule *r)
+{
+   switch(r->match.as.op) {
+   case OP_RANGE:
+printf("%s - %s ", log_as(r->match.as.as_min),
+   log_as(r->match.as.as_max));
+break;  
+case OP_XRANGE:
+printf("%s >< %s ", log_as(r->match.as.as_min),
+   log_as(r->match.as.as_max));
+break;
+case OP_NE:
+printf("!= %s ", log_as(r->match.as.as));
+break;
+default:
+printf("%s ", log_as(r->match.as.as));
+break;
+   }
+}
+
 void
 print_rule(struct peer *peer_l, struct filter_rule *r)
 {
@@ -577,15 +598,16 @@ print_rule(struct peer *peer_l, struct f
 
if (r->match.as.type) {
if (r->match.as.type == AS_ALL)
-   printf("AS %s ", log_as(r->match.as.as));
+   printf("AS ");
else if (r->match.as.type == AS_SOURCE)
-   printf("source-as %s ", log_as(r->match.as.as));
+   printf("source-as ");
else if (r->match.as.type == AS_TRANSIT)
-   printf("transit-as %s ", log_as(r->match.as.as));
+   printf("transit-as ");
else if (r->match.as.type == AS_PEER)
-   printf("peer-as %s ", log_as(r->match.as.as));
+   printf("peer-as ");
else
-   printf("unfluffy-as %s ", log_as(r->match.as.as));
+   printf("unfluffy-as ");
+   print_as(r);
}
 
if (r->match.aslen.type) {



Re: bgpd: print AS range

2016-06-05 Thread Denis Fondras
On Sun, Jun 05, 2016 at 10:28:05AM +0200, Sebastian Benoit wrote:
> hei,
> 
> thanks! i forgot that we print the config.
> 
> ok benno@, with whitespace fixed.
> 


Index: printconf.c
===
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
retrieving revision 1.96
diff -u -p -r1.96 printconf.c
--- printconf.c 21 Sep 2015 09:47:15 -  1.96
+++ printconf.c 5 Jun 2016 09:00:18 -
@@ -41,8 +41,9 @@ void   print_peer(struct peer_config *, 
 const char *print_auth_alg(u_int8_t);
 const char *print_enc_alg(u_int8_t);
 voidprint_announce(struct peer_config *, const char *);
+voidprint_as(struct filter_rule *);
 voidprint_rule(struct peer *, struct filter_rule *);
-const char *mrt_type(enum mrt_type);
+const char *mrt_type(enum mrt_type);
 voidprint_mrt(struct bgpd_config *, u_int32_t, u_int32_t,
const char *, const char *);
 voidprint_groups(struct bgpd_config *, struct peer *);
@@ -506,6 +507,26 @@ print_announce(struct peer_config *p, co
printf("%s\tannounce %s\n", c, aid2str(aid));
 }
 
+void print_as(struct filter_rule *r)
+{
+   switch(r->match.as.op) {
+   case OP_RANGE:
+   printf("%s - ", log_as(r->match.as.as_min));
+   printf("%s ", log_as(r->match.as.as_max));
+   break;  
+   case OP_XRANGE:
+   printf("%s >< ", log_as(r->match.as.as_min));
+   printf("%s ", log_as(r->match.as.as_max));
+   break;
+   case OP_NE:
+   printf("!= %s ", log_as(r->match.as.as));
+   break;
+   default:
+   printf("%s ", log_as(r->match.as.as));
+   break;
+   }
+}
+
 void
 print_rule(struct peer *peer_l, struct filter_rule *r)
 {
@@ -577,15 +598,16 @@ print_rule(struct peer *peer_l, struct f
 
if (r->match.as.type) {
if (r->match.as.type == AS_ALL)
-   printf("AS %s ", log_as(r->match.as.as));
+   printf("AS ");
else if (r->match.as.type == AS_SOURCE)
-   printf("source-as %s ", log_as(r->match.as.as));
+   printf("source-as ");
else if (r->match.as.type == AS_TRANSIT)
-   printf("transit-as %s ", log_as(r->match.as.as));
+   printf("transit-as ");
else if (r->match.as.type == AS_PEER)
-   printf("peer-as %s ", log_as(r->match.as.as));
+   printf("peer-as ");
else
-   printf("unfluffy-as %s ", log_as(r->match.as.as));
+   printf("unfluffy-as ");
+   print_as(r);
}
 
if (r->match.aslen.type) {



Re: bgpd: print AS range

2016-06-05 Thread Denis Fondras
> This didn't quite work, as log_as will override itself when used twice
> in the same printf.
> 

I should not have sent this late at night...


Index: printconf.c
===
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
retrieving revision 1.96
diff -u -p -r1.96 printconf.c
--- printconf.c 21 Sep 2015 09:47:15 -  1.96
+++ printconf.c 5 Jun 2016 08:00:59 -
@@ -41,8 +41,9 @@ void   print_peer(struct peer_config *, 
 const char *print_auth_alg(u_int8_t);
 const char *print_enc_alg(u_int8_t);
 voidprint_announce(struct peer_config *, const char *);
+voidprint_as(struct filter_rule *);
 voidprint_rule(struct peer *, struct filter_rule *);
-const char *mrt_type(enum mrt_type);
+const char *mrt_type(enum mrt_type);
 voidprint_mrt(struct bgpd_config *, u_int32_t, u_int32_t,
const char *, const char *);
 voidprint_groups(struct bgpd_config *, struct peer *);
@@ -506,6 +507,26 @@ print_announce(struct peer_config *p, co
printf("%s\tannounce %s\n", c, aid2str(aid));
 }
 
+void print_as(struct filter_rule *r)
+{
+   switch(r->match.as.op) {
+   case OP_RANGE:
+printf("%s - ", log_as(r->match.as.as_min));
+   printf("%s ", log_as(r->match.as.as_max));
+   break;  
+   case OP_XRANGE:
+   printf("%s >< ", log_as(r->match.as.as_min));
+   printf("%s ", log_as(r->match.as.as_max));
+   break;
+   case OP_NE:
+   printf("!= %s ", log_as(r->match.as.as));
+   break;
+   default:
+   printf("%s ", log_as(r->match.as.as));
+   break;
+   }
+}
+
 void
 print_rule(struct peer *peer_l, struct filter_rule *r)
 {
@@ -577,15 +598,16 @@ print_rule(struct peer *peer_l, struct f
 
if (r->match.as.type) {
if (r->match.as.type == AS_ALL)
-   printf("AS %s ", log_as(r->match.as.as));
+   printf("AS ");
else if (r->match.as.type == AS_SOURCE)
-   printf("source-as %s ", log_as(r->match.as.as));
+   printf("source-as ");
else if (r->match.as.type == AS_TRANSIT)
-   printf("transit-as %s ", log_as(r->match.as.as));
+   printf("transit-as ");
else if (r->match.as.type == AS_PEER)
-   printf("peer-as %s ", log_as(r->match.as.as));
+   printf("peer-as ");
else
-   printf("unfluffy-as %s ", log_as(r->match.as.as));
+   printf("unfluffy-as ");
+   print_as(r);
}
 
if (r->match.aslen.type) {



Problem with svlan(4) and bge(4)

2016-01-10 Thread Denis Fondras
Hi,

Following http://article.gmane.org/gmane.os.openbsd.tech/47475, I have a similar
problem with svlan(4) and em(4) (Intel 80003ES2). The main difference with
bge(4) is that ping works with em(4) but not tcp/udp. (obviously my bge(4)
supports IFCAP_CSUM_IPv4 and not my em(4)).
Everything works fine with IPv6 as the TCO capabilities are not supported by
these chips.
Also everything is fine if I don't use svlan(4).

With TCO :

# ssh root@185.22.128.253
ssh: connect to host 185.22.128.253 port 22: Operation timed out


Comment lines 1851-1854 of if_em.c to disable TCO, make && make install and
reboot. (network/system/pf config are the same)

Without TCO :

# ssh root@185.22.128.253  
The authenticity of host '185.22.128.253 (185.22.128.253)' can't be established.
ECDSA key fingerprint is SHA256:Mm4f4qaEuFBUZRoNTOccKdVLPdkISXU2f8v6oz9itec.
Are you sure you want to continue connecting (yes/no)? 


dmesg :

OpenBSD 5.9-beta (GENERIC) #0: Sun Jan 10 14:41:37 CET 2016
r...@test3.lab.ledeuns.net:/usr/src/sys/arch/amd64/compile/GENERIC
RTC BIOS diagnostic error 3
real mem = 8566259712 (8169MB)
avail mem = 8302551040 (7917MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.5 @ 0x9fa32000 (69 entries)
bios0: vendor Intel Corporation version "S5000.86B.10.00.0094.101320081858" date
10/13/2008
bios0: Rackable Systems Inc. S5000PSL
acpi0 at bios0: rev 2
acpi0: sleep states S0 S1 S4 S5
acpi0: tables DSDT SLIC FACP APIC SPCR HPET MCFG SSDT SSDT SSDT HEST BERT ERST
EINJ
acpi0: wakeup devices SLPB(S5) PEX0(S5) PS2M(S1) PS2K(S1) UAR1(S5) UAR2(S5)
UHC1(S1) UHC2(S1) UHC3(S1) UHC4(S1) EHCI(S1) PCIX(S5) PCIO(S5) PCIP(S5) PCIQ(S5)
PCIF(S5) [...]
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Xeon(R) CPU L5420 @ 2.50GHz, 2494.09 MHz
cpu0:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,DCA,SSE4.1,XSAVE,NXE,LONG,LAHF,PERF,SENSOR
cpu0: 6MB 64b/line 16-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 332MHz
cpu0: mwait min=64, max=64, C-substates=0.2.2.2, IBE
cpu at mainbus0: not configured
cpu at mainbus0: not configured
cpu at mainbus0: not configured
cpu at mainbus0: not configured
cpu at mainbus0: not configured
cpu at mainbus0: not configured
cpu at mainbus0: not configured
ioapic0 at mainbus0: apid 8 pa 0xfec0, version 20, 24 pins
ioapic1 at mainbus0: apid 9 pa 0xfec8, version 20, 24 pins
acpihpet0 at acpi0: 14318179 Hz
acpimcfg0 at acpi0 addr 0xa000, bus 0-255
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus 12 (PC32)
acpiprt2 at acpi0: bus 11 (PEX0)
acpiprt3 at acpi0: bus -1 (PEX1)
acpiprt4 at acpi0: bus -1 (PEX2)
acpiprt5 at acpi0: bus -1 (PEX3)
acpiprt6 at acpi0: bus 1 (PCIE)
acpiprt7 at acpi0: bus 5 (PCIX)
acpiprt8 at acpi0: bus 2 (PCIW)
acpiprt9 at acpi0: bus 3 (PCIO)
acpiprt10 at acpi0: bus -1 (PCIP)
acpiprt11 at acpi0: bus 4 (PCIQ)
acpiprt12 at acpi0: bus 7 (PCIF)
acpiprt13 at acpi0: bus 8 (PCIG)
acpiprt14 at acpi0: bus 9 (PCIH)
acpicpu0 at acpi0: !C2(750@40 io@0x162), C1(1000@20 halt), PSS
acpibtn0 at acpi0: SLPB
acpibtn1 at acpi0: PWRB
ipmi at mainbus0 not configured
cpu0: Enhanced SpeedStep 2494 MHz: speeds: 2497, 1998 MHz
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel 5000P Host" rev 0xb1
ppb0 at pci0 dev 2 function 0 "Intel 5000 PCIE x8" rev 0xb1
pci1 at ppb0 bus 1
ppb1 at pci1 dev 0 function 0 "Intel 6321ESB PCIE" rev 0x01
pci2 at ppb1 bus 2
ppb2 at pci2 dev 0 function 0 "Intel 6321ESB PCIE" rev 0x01
pci3 at ppb2 bus 3
ppb3 at pci2 dev 2 function 0 "Intel 6321ESB PCIE" rev 0x01
pci4 at ppb3 bus 4
em0 at pci4 dev 0 function 0 "Intel 80003ES2" rev 0x01: msi, address
00:15:17:9a:dd:ec
em1 at pci4 dev 0 function 1 "Intel 80003ES2" rev 0x01: msi, address
00:15:17:9a:dd:ed
ppb4 at pci1 dev 0 function 3 "Intel 6321ESB PCIE-PCIX" rev 0x01
pci5 at ppb4 bus 5
ppb5 at pci0 dev 3 function 0 "Intel 5000 PCIE" rev 0xb1
pci6 at ppb5 bus 6
ppb6 at pci0 dev 4 function 0 "Intel 5000 PCIE x8" rev 0xb1: msi
pci7 at ppb6 bus 7
ppb7 at pci0 dev 5 function 0 "Intel 5000 PCIE" rev 0xb1
pci8 at ppb7 bus 8
ppb8 at pci0 dev 6 function 0 "Intel 5000 PCIE x8" rev 0xb1: msi
pci9 at ppb8 bus 9
ppb9 at pci0 dev 7 function 0 "Intel 5000 PCIE" rev 0xb1
pci10 at ppb9 bus 10
pchb1 at pci0 dev 16 function 0 "Intel 5000 Error Reporting" rev 0xb1
pchb2 at pci0 dev 16 function 1 "Intel 5000 Error Reporting" rev 0xb1
pchb3 at pci0 dev 16 function 2 "Intel 5000 Error Reporting" rev 0xb1
pchb4 at pci0 dev 17 function 0 "Intel 5000 Reserved" rev 0xb1
pchb5 at pci0 dev 19 function 0 "Intel 5000 Reserved" rev 0xb1
pchb6 at pci0 

Problem with svlan(4) and bge(4)

2016-01-10 Thread Denis Fondras
Hi,

I have a problem with svlan(4) and bge(4) (Broadcom BCM5721).

With TCO :

denis@jigai:~$ ssh root@10.20.30.210
root@10.20.30.210's password: 
Last login: Sun Jan 10 13:22:27 2016 from 192.168.10.10
OpenBSD 5.9-beta (GENERIC) #1: Sun Jan 10 13:25:07 CET 2016

Welcome to OpenBSD: The proactively secure Unix-like operating system.

Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code.  With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.

# ping 185.22.128.253 
PING 185.22.128.253 (185.22.128.253): 56 data bytes
--- 185.22.128.253 ping statistics ---
13 packets transmitted, 0 packets received, 100.0% packet loss


Comment lines 3022-3023 of if_bge.c to disable TCO, make && make install and
reboot.
(network/system/pf config are the same)

Without TCO :

$ ssh root@10.20.30.210
root@10.20.30.210's password: 
Last login: Sun Jan 10 13:27:43 2016 from 192.168.10.10
OpenBSD 5.9-beta (GENERIC) #2: Sun Jan 10 13:30:31 CET 2016

Welcome to OpenBSD: The proactively secure Unix-like operating system.

Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code.  With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.

# ping 185.22.128.253   
PING 185.22.128.253 (185.22.128.253): 56 data bytes
64 bytes from 185.22.128.253: icmp_seq=0 ttl=254 time=0.292 ms
64 bytes from 185.22.128.253: icmp_seq=1 ttl=254 time=0.215 ms
64 bytes from 185.22.128.253: icmp_seq=2 ttl=254 time=0.339 ms
64 bytes from 185.22.128.253: icmp_seq=3 ttl=254 time=0.312 ms
--- 185.22.128.253 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.215/0.289/0.339/0.046 ms


dmesg :

OpenBSD 5.9-beta (GENERIC) #2: Sun Jan 10 13:30:31 CET 2016
r...@test.lab.ledeuns.net:/usr/src/sys/arch/amd64/compile/GENERIC
real mem = 8571977728 (8174MB)
avail mem = 8308101120 (7923MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.33 @ 0xbfeea000 (36 entries)
bios0: vendor IBM version "IBM BIOS Version 1.45-[PAE145AUS-1.45]-" date
01/23/2009
bios0: IBM IBM eServer 306m -[8849PAU]-
acpi0 at bios0: rev 0
acpi0: sleep states S0 S1 S4 S5
acpi0: tables DSDT FACP SPCR MCFG APIC BOOT SSDT
acpi0: wakeup devices PEG_(S4) EXP1(S4) EXP5(S4) EXP6(S4) PCIB(S5) COM1(S4)
COM2(S4) KBC0(S1) MSE0(S1) AC97(S1) USB1(S1) USB2(S1) USB3(S1) USB4(S1) EUSB(S1)
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimcfg0 at acpi0 addr 0xe000, bus 0-9
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Pentium(R) 4 CPU 3.00GHz, 2992.86 MHz
cpu0:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,DTES64,MWAIT,DS-CPL,CNXT-ID,CX16,xTPR,NXE,LONG,LAHF,PERF
cpu0: 1MB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 199MHz
cpu0: mwait min=64, max=64
cpu at mainbus0: not configured
ioapic0 at mainbus0: apid 2 pa 0xfec0, version 20, 24 pins
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus 1 (PEG_)
acpiprt2 at acpi0: bus 3 (PXHV)
acpiprt3 at acpi0: bus 4 (EXP5)
acpiprt4 at acpi0: bus 5 (EXP6)
acpiprt5 at acpi0: bus 10 (PCIB)
acpicpu0 at acpi0: C1(@1 halt!)
acpibtn0 at acpi0: PWRB
ipmi at mainbus0 not configured
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel E7230 Host" rev 0x81
ppb0 at pci0 dev 1 function 0 "Intel E7230 PCIE" rev 0x81: msi
pci1 at ppb0 bus 1
ppb1 at pci0 dev 28 function 0 "Intel 82801GB PCIE" rev 0x01: msi
pci2 at ppb1 bus 2
ppb2 at pci2 dev 0 function 0 "Intel 6702PXH PCIE-PCIX" rev 0x09
pci3 at ppb2 bus 3
"Intel IOxAPIC" rev 0x09 at pci2 dev 0 function 1 not configured
ppb3 at pci0 dev 28 function 4 "Intel 82801G PCIE" rev 0x01: msi
pci4 at ppb3 bus 4
bge0 at pci4 dev 0 function 0 "Broadcom BCM5721" rev 0x11, BCM5750 B1 (0x4101):
apic 2 int 16, address 00:14:5e:84:0b:06
brgphy0 at bge0 phy 1: BCM5750 10/100/1000baseT PHY, rev. 0
ppb4 at pci0 dev 28 function 5 "Intel 82801G PCIE" rev 0x01: msi
pci5 at ppb4 bus 5
bge1 at pci5 dev 0 function 0 "Broadcom BCM5721" rev 0x11, BCM5750 B1 (0x4101):
apic 2 int 17, address 00:14:5e:84:0b:07
brgphy1 at bge1 phy 1: BCM5750 10/100/1000baseT PHY, rev. 0
uhci0 at pci0 dev 29 function 0 "Intel 82801GB USB" rev 0x01: apic 2 int 23
uhci1 at pci0 dev 29 function 1 "Intel 82801GB USB" rev 0x01: apic 2 int 19
uhci2 at pci0 dev 29 function 2 "Intel 82801GB USB" rev 

Re: Problem with svlan(4) and bge(4)

2016-01-10 Thread Denis Fondras
On Sun, Jan 10, 2016 at 03:42:34PM +, Christian Weisgerber wrote:
> You don't actually describe your interface configuration.  I _guess_
> you are trying to terminate IP traffic directly on an svlan(4)
> interface.  That sounds very unusual.
> 

Sorry, the configuration is actually :
/etc/hostname.em1 :
up

/etc/hostname.svlan1003 :
vlandev em1
inet 100.67.233.1/30
up
!route add 185.22.128.252/30 100.67.233.2

Network diagram :
OpenBSD(vlanid:1003)  Switch  (vlanid:1003)router --- 
client(185.22.128.253)

> I can see why it might fail.  Since svlan(4) encapsulation is not
> covered by the hardware VLAN support, it changes the offsets to the
> IP/TCP headers, which is something the em(4) driver doesn't handle.
> 

Thank you for the insight.

Denis



Re: bgpd: fix adding a new interface and network inet connected

2016-03-22 Thread Denis Fondras
Peter,

Thank you for fixing this bug that has been responsible for much of my service
disruption over the months :)

Denis



[Patch/bgpd] Remove unused argument from community_ext_*

2016-03-27 Thread Denis Fondras
Hi,

I noticed that multiple functions from OpenBGPd declared an argument "u_int16_t
neighas" that is never used.
Here is a patch to remove it.

Denis

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.286
diff -u -p -r1.286 parse.y
--- parse.y 27 Oct 2015 18:19:33 -  1.286
+++ parse.y 27 Mar 2016 16:22:42 -
@@ -783,7 +783,7 @@ rdomainopts : RD STRING {
 * RD is almost encode like an ext-community,
 * but only almost so convert here.
 */
-   if (community_ext_conv(, 0, )) {
+   if (community_ext_conv(, )) {
yyerror("bad encoding of rd");
YYERROR;
}
Index: rde.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.345
diff -u -p -r1.345 rde.c
--- rde.c   22 Dec 2015 21:36:57 -  1.345
+++ rde.c   27 Mar 2016 16:22:43 -
@@ -2429,7 +2429,7 @@ rde_rdomain_import(struct rde_aspath *as
struct filter_set   *s;
 
TAILQ_FOREACH(s, >import, entry) {
-   if (community_ext_match(asp, >action.ext_community, 0))
+   if (community_ext_match(asp, >action.ext_community))
return (1);
}
return (0);
Index: rde.h
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.149
diff -u -p -r1.149 rde.h
--- rde.h   6 Nov 2015 16:23:26 -   1.149
+++ rde.h   27 Mar 2016 16:22:43 -
@@ -368,13 +368,12 @@ intcommunity_match(struct rde_aspath 
 int community_set(struct rde_aspath *, int, int);
 voidcommunity_delete(struct rde_aspath *, int, int);
 int community_ext_match(struct rde_aspath *,
-   struct filter_extcommunity *, u_int16_t);
+   struct filter_extcommunity *);
 int community_ext_set(struct rde_aspath *,
-   struct filter_extcommunity *, u_int16_t);
+   struct filter_extcommunity *);
 voidcommunity_ext_delete(struct rde_aspath *,
-   struct filter_extcommunity *, u_int16_t);
-int community_ext_conv(struct filter_extcommunity *, u_int16_t,
-   u_int64_t *);
+   struct filter_extcommunity *);
+int community_ext_conv(struct filter_extcommunity *, u_int64_t *);
 
 /* rde_decide.c */
 voidprefix_evaluate(struct prefix *, struct rib_entry *);
Index: rde_attr.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_attr.c,v
retrieving revision 1.95
diff -u -p -r1.95 rde_attr.c
--- rde_attr.c  24 Oct 2015 08:00:42 -  1.95
+++ rde_attr.c  27 Mar 2016 16:22:44 -
@@ -971,7 +971,7 @@ aspath_lenmatch(struct aspath *a, enum a
  * Functions handling communities and extended communities.
  */
 
-int community_ext_matchone(struct filter_extcommunity *, u_int16_t, u_int64_t);
+int community_ext_matchone(struct filter_extcommunity *, u_int64_t);
 
 int
 community_match(struct rde_aspath *asp, int as, int type)
@@ -1112,8 +1112,7 @@ community_delete(struct rde_aspath *asp,
 }
 
 int
-community_ext_match(struct rde_aspath *asp, struct filter_extcommunity *c,
-u_int16_t neighas)
+community_ext_match(struct rde_aspath *asp, struct filter_extcommunity *c)
 {
struct attr *attr;
u_int8_t*p;
@@ -1128,7 +1127,7 @@ community_ext_match(struct rde_aspath *a
p = attr->data;
for (len = attr->len / sizeof(ec); len > 0; len--) {
memcpy(, p, sizeof(ec));
-   if (community_ext_matchone(c, neighas, ec))
+   if (community_ext_matchone(c, ec))
return (1);
p += sizeof(ec);
}
@@ -1137,8 +1136,7 @@ community_ext_match(struct rde_aspath *a
 }
 
 int
-community_ext_set(struct rde_aspath *asp, struct filter_extcommunity *c,
-u_int16_t neighas)
+community_ext_set(struct rde_aspath *asp, struct filter_extcommunity *c)
 {
struct attr *attr;
u_int8_t*p = NULL;
@@ -1146,7 +1144,7 @@ community_ext_set(struct rde_aspath *asp
unsigned int i, ncommunities = 0;
u_int8_t f = ATTR_OPTIONAL|ATTR_TRANSITIVE;
 
-   if (community_ext_conv(c, neighas, ))
+   if (community_ext_conv(c, ))
return (0);
 
attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
@@ -1185,8 +1183,7 @@ community_ext_set(struct rde_aspath *asp
 }
 
 void
-community_ext_delete(struct rde_aspath *asp, struct filter_extcommunity *c,
-u_int16_t neighas)
+community_ext_delete(struct rde_aspath *asp, struct filter_extcommunity *c)
 {

OpenBGPd: expand rib list (updated for r1.295)

2017-01-20 Thread Denis Fondras
Hello,

Here is a patch to expand RIB names in rules. When playing with multi-RIBs, it
allows to simplify ruleset.

 Ex :
# cat /etc/bgpd.conf
[...]
peer_ribs = "{ m1, m2, m3 }"
deny rib m2 from any
allow rib $peer_ribs from any prefix { 2001:db8:1::/48, 2001:db8:2::/48 }

# bgpd -dnv
[...]
deny rib m2 from any 
allow rib m3 from any prefix 2001:db8:2::/48 
allow rib m3 from any prefix 2001:db8:1::/48 
allow rib m2 from any prefix 2001:db8:2::/48 
allow rib m2 from any prefix 2001:db8:1::/48 
allow rib m1 from any prefix 2001:db8:2::/48 
allow rib m1 from any prefix 2001:db8:1::/48 


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.295
diff -u -p -r1.295 parse.y
--- parse.y 18 Jan 2017 04:28:45 -  1.295
+++ parse.y 20 Jan 2017 20:15:20 -
@@ -91,6 +91,11 @@ static struct filter_rule*curpeer_filte
 static struct filter_rule  *curgroup_filter[2];
 static u_int32_tid;
 
+struct filter_rib_l {
+   struct filter_rib_l *next;
+   char name[PEER_DESCR_LEN];
+};
+
 struct filter_peers_l {
struct filter_peers_l   *next;
struct filter_peers  p;
@@ -128,8 +133,9 @@ struct rde_rib  *find_rib(char *);
 int get_id(struct peer *);
 int merge_prefixspec(struct filter_prefix_l *,
struct filter_prefixlen *);
-int expand_rule(struct filter_rule *, struct filter_peers_l *,
-   struct filter_match_l *, struct filter_set_head *);
+int expand_rule(struct filter_rule *, struct filter_rib_l *,
+   struct filter_peers_l *, struct filter_match_l *,
+   struct filter_set_head *);
 int str2key(char *, char *, size_t);
 int neighbor_consistent(struct peer *);
 int merge_filterset(struct filter_set_head *, struct filter_set *);
@@ -153,6 +159,7 @@ typedef struct {
char*string;
struct bgpd_addr addr;
u_int8_t u8;
+   struct filter_rib_l *filter_rib;
struct filter_peers_l   *filter_peers;
struct filter_match_lfilter_match;
struct filter_prefix_l  *filter_prefix;
@@ -203,10 +210,11 @@ typedef struct {
 %typeasnumber as4number as4number_any optnumber
 %typeespah family restart origincode nettype
 %typeyesno inout restricted
-%typestring filter_rib
+%typestring
 %type  address
 %typeprefix addrspec
 %typeaction quick direction delete
+%typefilter_rib_h filter_rib_l filter_rib
 %type  filter_peer filter_peer_l filter_peer_h
 %type  filter_match filter_elm filter_match_h
 %type filter_as filter_as_l filter_as_h
@@ -1469,9 +1477,10 @@ encspec  : /* nada */{
}
;
 
-filterrule : action quick filter_rib direction filter_peer_h 
filter_match_h filter_set
+filterrule : action quick filter_rib_h direction filter_peer_h 
filter_match_h filter_set
{
struct filter_rule   r;
+   struct filter_rib_l  *rb, *rbnext;
 
bzero(, sizeof(r));
r.action = $1;
@@ -1481,25 +1490,15 @@ filterrule  : action quick filter_rib dir
if (r.dir != DIR_IN) {
yyerror("rib only allowed on \"from\" "
"rules.");
-   free($3);
-   YYERROR;
-   }
-   if (!find_rib($3)) {
-   yyerror("rib \"%s\" does not exist.",
-   $3);
-   free($3);
-   YYERROR;
-   }
-   if (strlcpy(r.rib, $3, sizeof(r.rib)) >=
-   sizeof(r.rib)) {
-   yyerror("rib name \"%s\" too long: "
-   "max %zu", $3, sizeof(r.rib) - 1);
-   free($3);
+
+   for (rb = $3; rb != NULL; rb = rbnext) {
+   rbnext = rb->next;
+   free(rb);
+   }
YYERROR;
}
-   free($3);
}
-   if (expand_rule(, $5, &$6, $7) == 

Re: asr: support for RES_USE_DNSSEC

2017-02-25 Thread Denis Fondras
On Sat, Feb 25, 2017 at 07:24:48PM +0100, Jeremie Courreges-Anglas wrote:
> 
> > This flag is useful for software that wants to rely on the resolver to
> > perform DNSSEC validation.  Among the use cases there are DANE and SSHFP
> > records, and the obvious interfaces that I think are useful are
> > res_mkquery and getrrsetbyname.  The latter still doesn't support
> > DNSSEC, another diff will follow.
> 

Thank Jeremie for giving DNSSEC some love !



Re: bgpd: local-as

2016-09-27 Thread Denis Fondras
> I know cisco has a similar feature. Can someone of you check how it
> detects AS loops? If it does at all. I guess people expect it to work
> similar to other vendors.
> 

I expect it to work the OpenBSD way. That means it shouldn't bite me. Detect AS
loop is the way to go, whatever way  has decided to go.



OpenBGPd: expand rib list

2017-01-07 Thread Denis Fondras
Hello,

Here is a patch to expand RIB names in rules. When playing with multi-RIBs, it
allows to simplify ruleset.

 Ex :
# cat /etc/bgpd.conf
[...]
peer_ribs = "{ m1, m2, m3 }"
deny rib m2 from any
allow rib $peer_ribs from any prefix { 2001:db8:1::/48, 2001:db8:2::/48 }

# bgpd -dnv
[...]
deny rib m2 from any 
allow rib m3 from any prefix 2001:db8:2::/48 
allow rib m3 from any prefix 2001:db8:1::/48 
allow rib m2 from any prefix 2001:db8:2::/48 
allow rib m2 from any prefix 2001:db8:1::/48 
allow rib m1 from any prefix 2001:db8:2::/48 
allow rib m1 from any prefix 2001:db8:1::/48 


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.293
diff -u -p -r1.293 parse.y
--- parse.y 5 Jan 2017 13:53:09 -   1.293
+++ parse.y 7 Jan 2017 12:34:08 -
@@ -91,6 +91,11 @@ static struct filter_rule*curpeer_filte
 static struct filter_rule  *curgroup_filter[2];
 static u_int32_tid;
 
+struct filter_rib_l {
+   struct filter_rib_l *next;
+   char name[PEER_DESCR_LEN];
+};
+
 struct filter_peers_l {
struct filter_peers_l   *next;
struct filter_peers  p;
@@ -128,8 +133,9 @@ struct rde_rib  *find_rib(char *);
 int get_id(struct peer *);
 int merge_prefixspec(struct filter_prefix_l *,
struct filter_prefixlen *);
-int expand_rule(struct filter_rule *, struct filter_peers_l *,
-   struct filter_match_l *, struct filter_set_head *);
+int expand_rule(struct filter_rule *, struct filter_rib_l *,
+   struct filter_peers_l *, struct filter_match_l *,
+   struct filter_set_head *);
 int str2key(char *, char *, size_t);
 int neighbor_consistent(struct peer *);
 int merge_filterset(struct filter_set_head *, struct filter_set *);
@@ -153,6 +159,7 @@ typedef struct {
char*string;
struct bgpd_addr addr;
u_int8_t u8;
+   struct filter_rib_l *filter_rib;
struct filter_peers_l   *filter_peers;
struct filter_match_lfilter_match;
struct filter_prefix_l  *filter_prefix;
@@ -203,10 +210,11 @@ typedef struct {
 %typeasnumber as4number as4number_any optnumber
 %typeespah family restart origincode nettype
 %typeyesno inout restricted
-%typestring filter_rib
+%typestring
 %type  address
 %typeprefix addrspec
 %typeaction quick direction delete
+%typefilter_rib_h filter_rib_l filter_rib
 %type  filter_peer filter_peer_l filter_peer_h
 %type  filter_match filter_elm filter_match_h
 %type filter_as filter_as_l filter_as_h
@@ -1458,9 +1466,10 @@ encspec  : /* nada */{
}
;
 
-filterrule : action quick filter_rib direction filter_peer_h 
filter_match_h filter_set
+filterrule : action quick filter_rib_h direction filter_peer_h 
filter_match_h filter_set
{
struct filter_rule   r;
+   struct filter_rib_l  *rb, *rbnext;
 
bzero(, sizeof(r));
r.action = $1;
@@ -1470,25 +1479,15 @@ filterrule  : action quick filter_rib dir
if (r.dir != DIR_IN) {
yyerror("rib only allowed on \"from\" "
"rules.");
-   free($3);
-   YYERROR;
-   }
-   if (!find_rib($3)) {
-   yyerror("rib \"%s\" does not exist.",
-   $3);
-   free($3);
-   YYERROR;
-   }
-   if (strlcpy(r.rib, $3, sizeof(r.rib)) >=
-   sizeof(r.rib)) {
-   yyerror("rib name \"%s\" too long: "
-   "max %zu", $3, sizeof(r.rib) - 1);
-   free($3);
+
+   for (rb = $3; rb != NULL; rb = rbnext) {
+   rbnext = rb->next;
+   free(rb);
+   }
YYERROR;
}
-   free($3);
}
-   if (expand_rule(, $5, &$6, $7) == 

Re: ifconfig.8: Small improvement, typofix

2017-04-04 Thread Denis Fondras
> -If the master does not advertise within three times this interval, this host
> +If the master does not advertise this interval within three times, this host
> 

I think the old phrasing is easier to understand.



[patch/route] Automatically choose default route AF

2017-07-28 Thread Denis Fondras
Hello,

Here is a patch to route(8) to automatically choose the right address family
when adding a default route using the "default" keyword.

Index: route.8
===
RCS file: /cvs/src/sbin/route/route.8,v
retrieving revision 1.79
diff -u -p -r1.79 route.8
--- route.8 1 Jan 2017 01:08:11 -   1.79
+++ route.8 28 Jul 2017 13:41:24 -
@@ -317,7 +317,8 @@ data, in hexadecimal format
 In the absence of modifiers, an address is assumed to be IPv4,
 unless containing a
 .Sq :\&
-character, when it is treated as IPv6.
+character, when it is treated as IPv6. When using the "default" keyword,
+the address family used is that of the gateway.
 .Pp
 The optional modifier
 .Fl link
Index: route.c
===
RCS file: /cvs/src/sbin/route/route.c,v
retrieving revision 1.200
diff -u -p -r1.200 route.c
--- route.c 23 Mar 2017 13:28:25 -  1.200
+++ route.c 28 Jul 2017 13:41:24 -
@@ -72,7 +72,7 @@ union sockunion so_dst, so_gate, so_mask
 
 typedef union sockunion *sup;
 pid_t  pid;
-intrtm_addrs, s;
+intrtm_addrs, s, defroute = 0;
 intforcehost, forcenet, Fflag, nflag, af, qflag, tflag, Tflag;
 intiflag, verbose, aflen = sizeof(struct sockaddr_in);
 intlocking, lockrest, debugonly;
@@ -875,6 +875,10 @@ getaddr(int which, char *s, struct hoste
break;
case RTA_GATEWAY:
su = _gate;
+   if (defroute) {
+   so_dst.sa.sa_len = aflen;
+   so_dst.sa.sa_family = af;
+   }
break;
case RTA_NETMASK:
su = _mask;
@@ -901,6 +905,8 @@ getaddr(int which, char *s, struct hoste
break;
case RTA_NETMASK:
su->sa.sa_len = 0;
+   af = 0;
+   defroute = 1;
}
return (0);
}



Re: Is someone interested in resuming support for socppc?

2017-07-29 Thread Denis Fondras
On Sat, Jul 29, 2017 at 01:33:03PM +0300, Андрей Болконский wrote:
> https://www.openbsd.org/socppc.html
> 
> > The OpenBSD/socppc port was discontinued after the 5.8 release.
> Otherwise, will you approve removing support for socppc from src?

I am still using a RB600A.



Re: [patch/route] Allow short commands

2017-07-27 Thread Denis Fondras
Thank you for your comment.

> This will lead to usage and documentation issues (aside from your
> diff not including a manpage change):
>

You are right, I missed the manpage bits.

> With your diff, someone might write somewhere
> 
>  just type "route a default 192.0.2.1" to configure a default route.
> 
> Next we add a new keyword "abc"...
> 

I took bgpctl as an example. If there is an ambiguity, route(8) will complain.
As stated in the man "Commands may be abbreviated to the minimum unambiguous
prefix". I guess the shortcuts are to be used only interactively. Using the
longer keyword in a script or in hostname.if is not an issue.

Here is the manpage :

Index: route.8
===
RCS file: /cvs/src/sbin/route/route.8,v
retrieving revision 1.79
diff -u -p -r1.79 route.8
--- route.8 1 Jan 2017 01:08:11 -   1.79
+++ route.8 27 Jul 2017 17:44:46 -
@@ -97,7 +97,12 @@ instead of a real routing socket to test
 .Pp
 The
 .Nm
-utility provides the following simple commands:
+utility provides the following simple commands. Commands may be abbreviated
+to the minimum unambiguous prefix; for example,
+.Cm s
+for
+.Cm show.
+
 .Bl -tag -width Fl
 .It Xo
 .Nm route



Re: [patch/route] Allow short commands

2017-07-27 Thread Denis Fondras
> > +1 for a specific alias for "del" though.
> 
> I also worry about this.  However the addition of a few well-selected
> shortenings is OK.
> 

Here is a patch that adds the "del" shortcut.
I am not sure the usage() et man are changed the "right way" though.

Index: keywords.h
===
RCS file: /cvs/src/sbin/route/keywords.h,v
retrieving revision 1.33
diff -u -p -r1.33 keywords.h
--- keywords.h  4 Sep 2016 09:41:03 -   1.33
+++ keywords.h  27 Jul 2017 19:50:38 -
@@ -1,4 +1,4 @@
-/* $OpenBSD: keywords.h,v 1.33 2016/09/04 09:41:03 claudio Exp $ */
+/* $OpenBSD$ */
 
 /* WARNING!  This file was generated by keywords.sh  */
 
@@ -16,6 +16,7 @@ enum {
K_CHANGE,
K_CLONING,
K_CONNECTED,
+   K_DEL,
K_DELETE,
K_DST,
K_EXEC,
@@ -78,6 +79,7 @@ struct keytab keywords[] = {
{ "change", K_CHANGE },
{ "cloning",K_CLONING },
{ "connected",  K_CONNECTED },
+   { "del",K_DEL },
{ "delete", K_DELETE },
{ "dst",K_DST },
{ "exec",   K_EXEC },
Index: keywords.sh
===
RCS file: /cvs/src/sbin/route/keywords.sh,v
retrieving revision 1.31
diff -u -p -r1.31 keywords.sh
--- keywords.sh 4 Sep 2016 09:41:03 -   1.31
+++ keywords.sh 27 Jul 2017 19:50:38 -
@@ -17,6 +17,7 @@ bgp
 change
 cloning
 connected
+del
 delete
 dst
 exec
Index: route.8
===
RCS file: /cvs/src/sbin/route/route.8,v
retrieving revision 1.79
diff -u -p -r1.79 route.8
--- route.8 1 Jan 2017 01:08:11 -   1.79
+++ route.8 27 Jul 2017 19:50:38 -
@@ -211,6 +211,14 @@ have the syntax:
 .Nm route
 .Op Fl dnqtv
 .Op Fl T Ar tableid
+.Cm del
+.Op Ar modifiers
+.Ar destination gateway
+.Xc
+.It Xo
+.Nm route
+.Op Fl dnqtv
+.Op Fl T Ar tableid
 .Cm delete
 .Op Ar modifiers
 .Ar destination gateway
Index: route.c
===
RCS file: /cvs/src/sbin/route/route.c,v
retrieving revision 1.200
diff -u -p -r1.200 route.c
--- route.c 23 Mar 2017 13:28:25 -  1.200
+++ route.c 27 Jul 2017 19:50:38 -
@@ -134,7 +134,7 @@ usage(char *cp)
"usage: %s [-dnqtv] [-T tableid] command [[modifiers] args]\n",
__progname);
fprintf(stderr,
-   "commands: add, change, delete, exec, flush, get, monitor, show\n");
+   "commands: add, change, del, delete, exec, flush, get, monitor, 
show\n");
exit(1);
 }
 
@@ -252,6 +252,7 @@ main(int argc, char **argv)
/* FALLTHROUGH */
case K_CHANGE:
case K_ADD:
+   case K_DEL:
case K_DELETE:
rval = newroute(argc, argv);
break;



[patch/route] Allow short commands

2017-07-26 Thread Denis Fondras
Hi,

I use route(8) a lot and I thought being able to use shorter commands/keywords
could be nice. Like :

route a default 192.0.2.1
route del default

Regards,
Denis


Index: route.c
===
RCS file: /cvs/src/sbin/route/route.c,v
retrieving revision 1.200
diff -u -p -r1.200 route.c
--- route.c 23 Mar 2017 13:28:25 -  1.200
+++ route.c 26 Jul 2017 16:34:43 -
@@ -1864,7 +1864,10 @@ bprintf(FILE *fp, int b, char *s)
 int
 keycmp(const void *key, const void *kt)
 {
-   return (strcmp(key, ((struct keytab *)kt)->kt_cp));
+   size_t  wordlen = 0;
+
+   wordlen = strlen(key);
+   return (strncmp(key, ((struct keytab *)kt)->kt_cp, wordlen));
 }
 
 int



show ASN details in bgplg(8)

2017-07-19 Thread Denis Fondras
Hi,

I can be useful to display details about an ASN from the looking-glass.

rt-grav-01.liopen.net> show ip bgp detail as 199881

BGP routing table entry for 2a00:6060:8000::/48
199881
Nexthop 2001:7f8:81::19:9881:1 (via 2001:7f8:81::19:9881:1) from Auvergne 
Wireless IPv6 (185.22.131.1)
Origin IGP, metric 0, localpref 130, weight 0, external, valid, best
Last update: 03w0d23h ago
Ext. communities: soo 60983:1


Index: bgplg.h
===
RCS file: /cvs/src/usr.bin/bgplg/bgplg.h,v
retrieving revision 1.10
diff -u -p -r1.10 bgplg.h
--- bgplg.h 1 Jun 2013 18:47:55 -   1.10
+++ bgplg.h 19 Jul 2017 19:15:44 -
@@ -51,6 +51,8 @@ struct cmd {
{ BGPCTL, "show", "ip", "bgp", "summary", NULL } }, \
{ "show ip bgp detail", 1, 1, "prefix", \
{ BGPCTL, "show","ip", "bgp", "detail", NULL } },   \
+   { "show ip bgp detail as", 1, 1, "asnum",   \
+   { BGPCTL, "show","ip", "bgp", "detail", "as", NULL } }, \
{ "show ip bgp in", 1, 1, "prefix", \
{ BGPCTL, "show","ip", "bgp", "in", NULL } },   \
{ "show ip bgp out", 1, 1, "prefix",\



[patch/bgpd] Move comment in rde.c

2017-07-30 Thread Denis Fondras
Hi,

A comment is misplaced in rde.c.

Index: rde.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.368
diff -u -p -r1.368 rde.c
--- rde.c   29 May 2017 13:10:40 -  1.368
+++ rde.c   30 Jul 2017 19:49:06 -
@@ -213,11 +213,11 @@ rde_main(int debug, int verbose)
signal(SIGALRM, SIG_IGN);
signal(SIGUSR1, SIG_IGN);
 
-   /* initialize the RIB structures */
if ((ibuf_main = malloc(sizeof(struct imsgbuf))) == NULL)
fatal(NULL);
imsg_init(ibuf_main, 3);
 
+   /* initialize the RIB structures */
pt_init();
path_init(pathhashsize);
aspath_init(pathhashsize);



[patch/openbgpd] remove unused argument from community_ext_*

2017-05-22 Thread Denis Fondras
Hello,

Here is a patch to remove "u_int16_t neighas", an unused arguments from
community_ext_* functions.

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.298
diff -u -p -r1.298 parse.y
--- parse.y 22 Feb 2017 13:55:14 -  1.298
+++ parse.y 22 May 2017 18:52:27 -
@@ -848,7 +848,7 @@ rdomainopts : RD STRING {
 * RD is almost encode like an ext-community,
 * but only almost so convert here.
 */
-   if (community_ext_conv(, 0, )) {
+   if (community_ext_conv(, )) {
yyerror("bad encoding of rd");
YYERROR;
}
Index: rde.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.361
diff -u -p -r1.361 rde.c
--- rde.c   25 Jan 2017 03:21:55 -  1.361
+++ rde.c   22 May 2017 18:52:27 -
@@ -2455,7 +2455,7 @@ rde_rdomain_import(struct rde_aspath *as
struct filter_set   *s;
 
TAILQ_FOREACH(s, >import, entry) {
-   if (community_ext_match(asp, >action.ext_community, 0))
+   if (community_ext_match(asp, >action.ext_community))
return (1);
}
return (0);
Index: rde.h
===
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.160
diff -u -p -r1.160 rde.h
--- rde.h   25 Jan 2017 03:21:55 -  1.160
+++ rde.h   22 May 2017 18:52:27 -
@@ -379,12 +379,12 @@ intcommunity_large_set(struct rde_asp
 voidcommunity_large_delete(struct rde_aspath *, int64_t,
int64_t, int64_t);
 int community_ext_match(struct rde_aspath *,
-   struct filter_extcommunity *, u_int16_t);
+   struct filter_extcommunity *);
 int community_ext_set(struct rde_aspath *,
-   struct filter_extcommunity *, u_int16_t);
+   struct filter_extcommunity *);
 voidcommunity_ext_delete(struct rde_aspath *,
-   struct filter_extcommunity *, u_int16_t);
-int community_ext_conv(struct filter_extcommunity *, u_int16_t,
+   struct filter_extcommunity *);
+int community_ext_conv(struct filter_extcommunity *,
u_int64_t *);
 
 /* rde_decide.c */
Index: rde_attr.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_attr.c,v
retrieving revision 1.97
diff -u -p -r1.97 rde_attr.c
--- rde_attr.c  24 Jan 2017 04:22:42 -  1.97
+++ rde_attr.c  22 May 2017 18:52:27 -
@@ -974,7 +974,7 @@ aspath_lenmatch(struct aspath *a, enum a
  * Functions handling communities and extended communities.
  */
 
-int community_ext_matchone(struct filter_extcommunity *, u_int16_t, u_int64_t);
+int community_ext_matchone(struct filter_extcommunity *, u_int64_t);
 
 int
 community_match(struct rde_aspath *asp, int as, int type)
@@ -1115,8 +1115,7 @@ community_delete(struct rde_aspath *asp,
 }
 
 int
-community_ext_match(struct rde_aspath *asp, struct filter_extcommunity *c,
-u_int16_t neighas)
+community_ext_match(struct rde_aspath *asp, struct filter_extcommunity *c)
 {
struct attr *attr;
u_int8_t*p;
@@ -1131,7 +1130,7 @@ community_ext_match(struct rde_aspath *a
p = attr->data;
for (len = attr->len / sizeof(ec); len > 0; len--) {
memcpy(, p, sizeof(ec));
-   if (community_ext_matchone(c, neighas, ec))
+   if (community_ext_matchone(c, ec))
return (1);
p += sizeof(ec);
}
@@ -1140,8 +1139,7 @@ community_ext_match(struct rde_aspath *a
 }
 
 int
-community_ext_set(struct rde_aspath *asp, struct filter_extcommunity *c,
-u_int16_t neighas)
+community_ext_set(struct rde_aspath *asp, struct filter_extcommunity *c)
 {
struct attr *attr;
u_int8_t*p = NULL;
@@ -1149,7 +1147,7 @@ community_ext_set(struct rde_aspath *asp
unsigned int i, ncommunities = 0;
u_int8_t f = ATTR_OPTIONAL|ATTR_TRANSITIVE;
 
-   if (community_ext_conv(c, neighas, ))
+   if (community_ext_conv(c, ))
return (0);
 
attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
@@ -1188,8 +1186,7 @@ community_ext_set(struct rde_aspath *asp
 }
 
 void
-community_ext_delete(struct rde_aspath *asp, struct filter_extcommunity *c,
-u_int16_t neighas)
+community_ext_delete(struct rde_aspath *asp, struct filter_extcommunity *c)
 {
struct attr *attr;
u_int8_t*p, *n;
@@ -1197,7 +1194,7 @@ community_ext_delete(struct rde_aspath *
u_int16_tl, 

[patch/openbgpd] make man example works

2017-05-21 Thread Denis Fondras
Hi,

bgpd.conf manual has an example with :

good="{ 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"
bad="{ 224.0.0.0/4 prefixlen >= 4, 240.0.0.0/4 prefixlen >= 4 }"
ugly="{ 127.0.0.1/8, 169.254.0.0/16 }"
deny from any prefix { $good $bad $ugly } 

This syntax is not valid with current parse.y.

Here is a patch to make it valid.

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.298
diff -u -p -r1.298 parse.y
--- parse.y 22 Feb 2017 13:55:14 -  1.298
+++ parse.y 21 May 2017 17:29:11 -
@@ -217,6 +217,7 @@ typedef struct {
 %typefilter_set_opt
 %type   filter_set filter_set_l
 %type filter_prefix filter_prefix_l filter_prefix_h
+%type filter_prefix_m
 %typeunaryop equalityop binaryop filter_as_type
 %type   encspec
 %%
@@ -1615,8 +1616,22 @@ filter_prefix_h  : IPV4 prefixlenop  
 {
}
}
| PREFIX filter_prefix  { $$ = $2; }
-   | PREFIX '{' filter_prefix_l '}'{ $$ = $3; }
+   | PREFIX '{' filter_prefix_m '}'{ $$ = $3; }
;
+
+filter_prefix_m: filter_prefix_l
+   | '{' filter_prefix_l '}'   { $$ = $2; }
+   | '{' filter_prefix_l '}' filter_prefix_m
+   {
+   struct filter_prefix_l  *p;
+
+   /* merge, both can be lists */
+   for (p = $2; p != NULL && p->next != NULL; p = p->next)
+   ;   /* nothing */
+   if (p != NULL)
+   p->next = $4;
+   $$ = $2;
+   } 
 
 filter_prefix_l: filter_prefix { $$ = $1; }
| filter_prefix_l comma filter_prefix   {



[patch/bgpctl] Add support for extended communities

2017-06-03 Thread Denis Fondras
Hello,

Here is a patch to allow usage of extended communities with bgpctl :

bgpctl show ip bgp ext-community rt 10:10
bgpctl netw add 2001:db8:1::/64 ext soo 10:50

Denis

Index: bgpctl/bgpctl.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.195
diff -u -p -r1.195 bgpctl.c
--- bgpctl/bgpctl.c 31 May 2017 10:48:06 -  1.195
+++ bgpctl/bgpctl.c 3 Jun 2017 11:25:00 -
@@ -261,6 +261,11 @@ main(int argc, char *argv[])
sizeof(res->community));
type = IMSG_CTL_SHOW_RIB_COMMUNITY;
}
+   if (res->extcommunity.flags == EXT_COMMUNITY_FLAG_VALID) {
+   memcpy(, >extcommunity,
+   sizeof(res->extcommunity));
+   type = IMSG_CTL_SHOW_RIB_EXTCOMMUNITY;
+   }
if (res->large_community.as != COMMUNITY_UNSET &&
res->large_community.ld1 != COMMUNITY_UNSET &&
res->large_community.ld2 != COMMUNITY_UNSET) {
Index: bgpctl/parser.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
retrieving revision 1.77
diff -u -p -r1.77 parser.c
--- bgpctl/parser.c 14 Feb 2017 13:13:23 -  1.77
+++ bgpctl/parser.c 3 Jun 2017 11:25:00 -
@@ -47,6 +47,8 @@ enum token_type {
RIBNAME,
SHUTDOWN_COMMUNICATION,
COMMUNITY,
+   EXTCOMMUNITY,
+   EXTCOM_SUBTYPE,
LARGE_COMMUNITY,
LOCALPREF,
MED,
@@ -94,12 +96,16 @@ static const struct token t_show_mrt_as[
 static const struct token t_show_prefix[];
 static const struct token t_show_ip[];
 static const struct token t_show_community[];
+static const struct token t_show_extcommunity[];
+static const struct token t_show_ext_subtype[];
 static const struct token t_show_largecommunity[];
 static const struct token t_network[];
 static const struct token t_network_show[];
 static const struct token t_prefix[];
 static const struct token t_set[];
 static const struct token t_community[];
+static const struct token t_extcommunity[];
+static const struct token t_ext_subtype[];
 static const struct token t_largecommunity[];
 static const struct token t_localpref[];
 static const struct token t_med[];
@@ -166,6 +172,7 @@ static const struct token t_show_rib[] =
{ ASTYPE,   "peer-as",  AS_PEER,t_show_rib_as},
{ ASTYPE,   "empty-as", AS_EMPTY,   t_show_rib},
{ KEYWORD,  "community",NONE,   t_show_community},
+   { KEYWORD,  "ext-community", NONE,  t_show_extcommunity},
{ KEYWORD,  "large-community", NONE,t_show_largecommunity},
{ FLAG, "best", F_CTL_ACTIVE,   t_show_rib},
{ FLAG, "selected", F_CTL_ACTIVE,   t_show_rib},
@@ -288,6 +295,29 @@ static const struct token t_show_communi
{ ENDTOKEN, "", NONE,   NULL}
 };
 
+static const struct token t_show_extcommunity[] = {
+   { EXTCOM_SUBTYPE,   "bdc",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "defgw",NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "esi-lab",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "esi-rt",   NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "l2vid",NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "mac-mob",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "odi",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "ort",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "ori",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "ovs",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "rt",   NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "soo",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "srcas",NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "vrfri",NONE,   t_show_ext_subtype},
+   { ENDTOKEN, "", NONE,   NULL}
+};
+
+static const struct token t_show_ext_subtype[] = {
+   { EXTCOMMUNITY, "", NONE,   t_show_rib},
+   { ENDTOKEN, "", NONE,   NULL}
+};
+
 static const struct token t_show_largecommunity[] = {
{ LARGE_COMMUNITY,  "", NONE,   t_show_rib},
{ ENDTOKEN, "", NONE,   NULL}
@@ -317,6 +347,7 @@ static const struct token t_network_show
 static const struct token t_set[] = {
{ NOTOKEN,  "", NONE,   NULL},
{ KEYWORD,  "community",NONE,   t_community},
+   { KEYWORD,  "ext-community",NONE,   t_extcommunity},
{ KEYWORD,  "large-community",  NONE,   t_largecommunity},
 

[patch/bgpctl] Add support for extended communities (updated)

2017-06-03 Thread Denis Fondras
(forgot to add the manual bit in the previous patch)

Hello,

Here is a patch to allow usage of extended communities with bgpctl :

bgpctl show ip bgp ext-community rt 10:10
bgpctl netw add 2001:db8:1::/64 ext soo 10:50

Denis

Index: bgpctl/bgpctl.8
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.8,v
retrieving revision 1.77
diff -u -p -r1.77 bgpctl.8
--- bgpctl/bgpctl.8 29 May 2017 21:27:36 -  1.77
+++ bgpctl/bgpctl.8 3 Jun 2017 14:30:51 -
@@ -326,6 +326,9 @@ anywhere in the AS path.
 .It Cm community Ar community
 Show all entries with community
 .Ar community .
+.It Cm ext-community Ar ext-community
+Show all entries with extended-community
+.Ar ext-community .
 .It Cm large-community Ar large-community
 Show all entries with large-community
 .Ar large-community .
Index: bgpctl/bgpctl.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.195
diff -u -p -r1.195 bgpctl.c
--- bgpctl/bgpctl.c 31 May 2017 10:48:06 -  1.195
+++ bgpctl/bgpctl.c 3 Jun 2017 14:30:51 -
@@ -261,6 +261,11 @@ main(int argc, char *argv[])
sizeof(res->community));
type = IMSG_CTL_SHOW_RIB_COMMUNITY;
}
+   if (res->extcommunity.flags == EXT_COMMUNITY_FLAG_VALID) {
+   memcpy(, >extcommunity,
+   sizeof(res->extcommunity));
+   type = IMSG_CTL_SHOW_RIB_EXTCOMMUNITY;
+   }
if (res->large_community.as != COMMUNITY_UNSET &&
res->large_community.ld1 != COMMUNITY_UNSET &&
res->large_community.ld2 != COMMUNITY_UNSET) {
Index: bgpctl/parser.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
retrieving revision 1.77
diff -u -p -r1.77 parser.c
--- bgpctl/parser.c 14 Feb 2017 13:13:23 -  1.77
+++ bgpctl/parser.c 3 Jun 2017 14:30:51 -
@@ -47,6 +47,8 @@ enum token_type {
RIBNAME,
SHUTDOWN_COMMUNICATION,
COMMUNITY,
+   EXTCOMMUNITY,
+   EXTCOM_SUBTYPE,
LARGE_COMMUNITY,
LOCALPREF,
MED,
@@ -94,12 +96,16 @@ static const struct token t_show_mrt_as[
 static const struct token t_show_prefix[];
 static const struct token t_show_ip[];
 static const struct token t_show_community[];
+static const struct token t_show_extcommunity[];
+static const struct token t_show_ext_subtype[];
 static const struct token t_show_largecommunity[];
 static const struct token t_network[];
 static const struct token t_network_show[];
 static const struct token t_prefix[];
 static const struct token t_set[];
 static const struct token t_community[];
+static const struct token t_extcommunity[];
+static const struct token t_ext_subtype[];
 static const struct token t_largecommunity[];
 static const struct token t_localpref[];
 static const struct token t_med[];
@@ -166,6 +172,7 @@ static const struct token t_show_rib[] =
{ ASTYPE,   "peer-as",  AS_PEER,t_show_rib_as},
{ ASTYPE,   "empty-as", AS_EMPTY,   t_show_rib},
{ KEYWORD,  "community",NONE,   t_show_community},
+   { KEYWORD,  "ext-community", NONE,  t_show_extcommunity},
{ KEYWORD,  "large-community", NONE,t_show_largecommunity},
{ FLAG, "best", F_CTL_ACTIVE,   t_show_rib},
{ FLAG, "selected", F_CTL_ACTIVE,   t_show_rib},
@@ -288,6 +295,29 @@ static const struct token t_show_communi
{ ENDTOKEN, "", NONE,   NULL}
 };
 
+static const struct token t_show_extcommunity[] = {
+   { EXTCOM_SUBTYPE,   "bdc",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "defgw",NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "esi-lab",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "esi-rt",   NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "l2vid",NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "mac-mob",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "odi",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "ort",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "ori",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "ovs",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "rt",   NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "soo",  NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "srcas",NONE,   t_show_ext_subtype},
+   { EXTCOM_SUBTYPE,   "vrfri",NONE,   t_show_ext_subtype},
+   { ENDTOKEN, "", NONE,   NULL}
+};
+
+static const struct token 

Re: rework bgpd ext community and support origin validation state

2017-05-31 Thread Denis Fondras
Hi,

A typo slipped into Claudio's patch. While at it, fix the same typo elsewhere.

Denis


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.308
diff -u -p -r1.308 parse.y
--- parse.y 31 May 2017 10:44:00 -  1.308
+++ parse.y 31 May 2017 19:07:05 -
@@ -3218,7 +3218,7 @@ parseextcommunity(struct filter_extcommu
return (-1);
}
if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX) {
-   yyerror("Bad ext-community value to big");
+   yyerror("Bad ext-community value too big");
return (-1);
}
c->data.ext_opaq = ullval;
@@ -3504,7 +3504,7 @@ merge_prefixspec(struct filter_prefix_l 
case OP_LE:
case OP_GT:
if (pl->len_min > max_len) {
-   yyerror("prefixlen %d to big for AF, limit %d",
+   yyerror("prefixlen %d too big for AF, limit %d",
pl->len_min, max_len);
return (-1);
}
@@ -3516,7 +3516,7 @@ merge_prefixspec(struct filter_prefix_l 
break;
case OP_LT:
if (pl->len_min > max_len - 1) {
-   yyerror("prefixlen %d to big for AF, limit %d",
+   yyerror("prefixlen %d too big for AF, limit %d",
pl->len_min, max_len - 1);
return (-1);
}



Re: man page update for bgpctl

2017-09-21 Thread Denis Fondras
On Thu, Sep 21, 2017 at 01:07:26PM +0100, Tom Smyth wrote:
> Hello
> minor Grammar Correction on manual page for bgpctl
> 
> - line144
> Take the BGP session to the specified neighbor up.
> +line144
> Bring the BGP session to the specified neighbor up.

Thank you. I created a proper patch.
Take a look at https://www.openbsd.org/anoncvs.html to create an applicable
patch.

Index: bgpctl.8
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.8,v
retrieving revision 1.77
diff -u -p -r1.77 bgpctl.8
--- bgpctl.829 May 2017 21:27:36 -  1.77
+++ bgpctl.821 Sep 2017 13:17:54 -
@@ -141,7 +141,7 @@ all, even if it announced the route refr
 .Ar peer
 may be the neighbor's address or description.
 .It Cm neighbor Ar peer Cm up
-Take the BGP session to the specified neighbor up.
+Bring the BGP session to the specified neighbor up.
 .Ar peer
 may be the neighbor's address or description.
 .It Cm network add Ar prefix Op Ar arguments



[patch] exiting bgplgsh with ^D

2017-10-04 Thread Denis Fondras
Hi,

Here is a patch to make ^D (CTRL-D) escape from bgplgsh instead of displaying
help.

Denis

Index: bgplgsh.c
===
RCS file: /cvs/src/usr.bin/bgplg/bgplgsh.c,v
retrieving revision 1.8
diff -u -p -r1.8 bgplgsh.c
--- bgplgsh.c   9 Dec 2015 17:52:24 -   1.8
+++ bgplgsh.c   4 Oct 2017 13:12:02 -
@@ -229,8 +229,8 @@ main(void)
 
if ((line = readline(prompt)) == NULL) {
printf("\n");
-   lg_help(cmds, NULL);
-   continue;
+   quit = 1;
+   goto next;
}
if (!lg_strip(line))
goto next;



[patch bgpd] Remove unused argument

2017-10-03 Thread Denis Fondras
Hi,

The "struct peer" input of merge_config() is never used.
Here is a patch to remove it.

Denis

Index: config.c
===
RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
retrieving revision 1.67
diff -u -p -r1.67 config.c
--- config.c29 May 2017 09:56:33 -  1.67
+++ config.c3 Oct 2017 18:48:50 -
@@ -133,8 +133,7 @@ free_config(struct bgpd_config *conf)
 }
 
 int
-merge_config(struct bgpd_config *xconf, struct bgpd_config *conf,
-struct peer *peer_l)
+merge_config(struct bgpd_config *xconf, struct bgpd_config *conf)
 {
struct listen_addr  *nla, *ola, *next;
struct network  *n;
Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.315
diff -u -p -r1.315 parse.y
--- parse.y 21 Aug 2017 14:41:22 -  1.315
+++ parse.y 3 Oct 2017 18:48:50 -
@@ -2878,7 +2878,7 @@ parse_config(char *filename, struct bgpd
merge_filter_lists(conf->filters, filter_l);
 
errors += mrt_mergeconfig(xconf->mrt, conf->mrt);
-   errors += merge_config(xconf, conf, peer_l);
+   errors += merge_config(xconf, conf);
*xpeers = peer_l;
 
for (p = peer_l_old; p != NULL; p = pnext) {
Index: session.h
===
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
retrieving revision 1.123
diff -u -p -r1.123 session.h
--- session.h   28 May 2017 12:21:36 -  1.123
+++ session.h   3 Oct 2017 18:48:50 -
@@ -244,8 +244,7 @@ int  carp_demote_get(char *);
 int carp_demote_set(char *, int);
 
 /* config.c */
-int merge_config(struct bgpd_config *, struct bgpd_config *,
-   struct peer *);
+int merge_config(struct bgpd_config *, struct bgpd_config *);
 voidprepare_listeners(struct bgpd_config *);
 int get_mpe_label(struct rdomain *);
 



Add RPKI-ROA support to OpenBGPd 2/2

2017-08-26 Thread Denis Fondras
Hi,

Following the previous email, here is a patch to bgpctl(8).

It adds two commands :
- show validator
- show rib roa-state [valid|invalid|not-found]

Here is the result of each command :

# bgpctl show validator 
id address:port pref v4 v6
0 [2a02:cdc5:9715:0:185:5:200:241]:8282 128 36655 5837 

# bgpctl show rib roa-state invalid
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, S = Stale
   v = ROA valid, i = ROA invalid, n = ROA not found
origin: i = IGP, e = EGP, ? = Incomplete

flags  destination  gateway  lpref   med aspath origin
i*>185.22.130.0/24  192.168.10.21   50 0 60983 i
i*>2001:7c8::/322a00:6060:1::10:21 50 0 60983 i

# bgpctl show rib detail roa-state not-found
BGP routing table entry for 2001:db8:b000::/48
60983
Nexthop 2a00:6060:1::10:21 (via 2a00:6060:1::10:21) from 2a00:6060:1::10:21 
(192.168.10.21)
Origin IGP, metric 0, localpref 100, weight 0, external, valid, best, 
roa-notfound
Last update: 00:00:38 ago


Index: bgpctl.8
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.8,v
retrieving revision 1.77
diff -u -p -r1.77 bgpctl.8
--- bgpctl.829 May 2017 21:27:36 -  1.77
+++ bgpctl.826 Aug 2017 19:20:00 -
@@ -353,6 +353,11 @@ Show only entries from the specified RIB
 Show all entries with
 .Ar as
 anywhere but rightmost.
+.It Xo
+.Ic Cm roa-state
+.Pq Ic valid Ns | Ns Ic invalid Ns | Ns Ic not-found
+.Xc
+Show only routes with specified RPKI-ROA status.
 .El
 .Pp
 Additionally, the following
@@ -418,6 +423,8 @@ Show a list of all neighbors, including 
 in a terse format.
 .It Cm show tables
 Show a list of all currently loaded fib routing tables.
+.It Cm show validator
+Show a list of all RPKI-ROA cache validators.
 .El
 .Sh FILES
 .Bl -tag -width "/var/run/bgpd.sockXXX" -compact
Index: bgpctl.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.199
diff -u -p -r1.199 bgpctl.c
--- bgpctl.c10 Aug 2017 14:22:59 -  1.199
+++ bgpctl.c26 Aug 2017 19:20:01 -
@@ -39,6 +39,7 @@
 #include "bgpd.h"
 #include "session.h"
 #include "rde.h"
+#include "roa.h"
 #include "parser.h"
 #include "irrfilter.h"
 #include "mrtparser.h"
@@ -69,11 +70,13 @@ int  show_fib_msg(struct imsg *);
 voidshow_nexthop_head(void);
 int show_nexthop_msg(struct imsg *);
 voidshow_interface_head(void);
+voidshow_validator_head(void);
 uint64_tift2ifm(uint8_t);
 const char *get_media_descr(uint64_t);
 const char *get_linkstate(uint8_t, int);
 const char *get_baudrate(u_int64_t, char *);
 int show_interface_msg(struct imsg *);
+int show_validator_msg(struct imsg *);
 voidshow_rib_summary_head(void);
 voidprint_prefix(struct bgpd_addr *, u_int8_t, u_int8_t);
 const char *print_origin(u_int8_t, int);
@@ -232,6 +235,10 @@ main(int argc, char *argv[])
imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, NULL, 0);
show_interface_head();
break;
+   case SHOW_VALIDATOR:
+   imsg_compose(ibuf, IMSG_CTL_SHOW_VALIDATOR, 0, 0, -1, NULL, 0);
+   show_validator_head();
+   break;
case SHOW_NEIGHBOR:
case SHOW_NEIGHBOR_TIMERS:
case SHOW_NEIGHBOR_TERSE:
@@ -460,6 +467,9 @@ main(int argc, char *argv[])
case SHOW_INTERFACE:
done = show_interface_msg();
break;
+   case SHOW_VALIDATOR:
+   done = show_validator_msg();
+   break;
case SHOW_NEIGHBOR:
done = show_neighbor_msg(, NV_DEFAULT);
break;
@@ -947,7 +957,7 @@ show_fib_head(void)
"* = valid, B = BGP, C = Connected, S = Static, D = Dynamic\n");
printf("   "
"N = BGP Nexthop reachable via this route R = redistributed\n");
-   printf("   r = reject route, b = blackhole route\n\n");
+   printf("   r = reject route, b = blackhole route\n");
printf("flags prio destination  gateway\n");
 }
 
@@ -1141,6 +1151,42 @@ show_interface_head(void)
"Link state");
 }
 
+void
+show_validator_head(void)
+{
+   printf("%s %s %s %s %s\n", "id", "address:port",
+   "pref", "v4", "v6");
+}
+
+int
+show_validator_msg(struct imsg *imsg)
+{
+   struct validator*v;
+
+   switch (imsg->hdr.type) {
+   case IMSG_CTL_SHOW_VALIDATOR:
+   v = imsg->data;
+   printf("%d ", v->id);
+   if (v->remote_addr.aid == AID_INET)
+   printf("%s:%d ", log_addr(>remote_addr), v->port);
+   else if 

Add RPKI-ROA support to OpenBGPd 1/2

2017-08-26 Thread Denis Fondras
Hi,

Here is a patch to add RPKI/ROA support to bgpd(8) (based on RFC6810).
(bgpctl(8) patch in the next mail)

Can someone have a look and tell me what is wrong and what must be and how to
improved ?

* What needs to be done (in no specific order) :
- Do some benchmark
- Improve error handling
- Add support for multiple validators and preference setting
- Add transports (TLS/TCP-MD5/SSH)
- Load cache from a file (job@'s request)

* How does it work :
The patch creates a new thread (ROA engine, roa.{c,h}) when bgpd(8) starts.
If no 'validator' directive is found in bgpd.conf(5), the ROA engine does
basically nothing.
If such a directive is found, ROA engine (ROAE) will connect to the RPKI/ROA 
cache
validator and get a list of validated prefix is everything is fine. ROAE will
inform RDE that it can send prefixes to be validated. Upon prefix reception,
ROAE will return a status (VALID, INVALID, NOT FOUND) to RDE which in turn will
update the RIB according to filter rules. If ROAE loses its validated prefix
list, it will tell RDE to reset prefix validation status to NOT FOUND.

* Here is a sample bgpd.conf(5) :
---
AS 65531
router-id 192.168.10.20

network 198.168.55.0/24

neighbor "192.168.10.21" {
remote-as 60983
}

neighbor "2a00:6060:1::10:21" {
remote-as 60983
}

validator 2a02:cdc5:9715:0:185:5:200:241 port 8282

allow from any
allow to any
match from any roa-state invalid set localpref 50
match from any roa-state valid set localpref 110
---

* Patch :

Index: Makefile
===
RCS file: /cvs/src/usr.sbin/bgpd/Makefile,v
retrieving revision 1.32
diff -u -p -r1.32 Makefile
--- Makefile21 Aug 2017 14:43:33 -  1.32
+++ Makefile26 Aug 2017 19:48:24 -
@@ -4,7 +4,8 @@ PROG=   bgpd
 SRCS=  bgpd.c session.c log.c logmsg.c parse.y config.c \
rde.c rde_rib.c rde_decide.c rde_prefix.c mrt.c kroute.c \
control.c pfkey.c rde_update.c rde_attr.c printconf.c \
-   rde_filter.c pftable.c name2id.c util.c carp.c timer.c
+   rde_filter.c pftable.c name2id.c util.c carp.c timer.c \
+   roa.c
 CFLAGS+= -Wall -I${.CURDIR}
 CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
 CFLAGS+= -Wmissing-declarations
Index: bgpd.c
===
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
retrieving revision 1.191
diff -u -p -r1.191 bgpd.c
--- bgpd.c  12 Aug 2017 16:31:09 -  1.191
+++ bgpd.c  26 Aug 2017 19:48:24 -
@@ -35,6 +35,7 @@
 
 #include "bgpd.h"
 #include "mrt.h"
+#include "roa.h"
 #include "session.h"
 #include "log.h"
 
@@ -43,10 +44,12 @@ __dead void usage(void);
 intmain(int, char *[]);
 pid_t  start_child(enum bgpd_process, char *, int, int, int);
 intsend_filterset(struct imsgbuf *, struct filter_set_head *);
-intreconfigure(char *, struct bgpd_config *, struct peer **);
+intreconfigure(char *, struct bgpd_config *, struct peer **,
+   struct validator **);
 intdispatch_imsg(struct imsgbuf *, int, struct bgpd_config *);
 intcontrol_setup(struct bgpd_config *);
-intimsg_send_sockets(struct imsgbuf *, struct imsgbuf *);
+intimsg_send_sockets(struct imsgbuf *, struct imsgbuf *,
+   struct imsgbuf *);
 
 int cflags;
 volatile sig_atomic_t   mrtdump;
@@ -56,6 +59,7 @@ pid_t  reconfpid;
 int reconfpending;
 struct imsgbuf *ibuf_se;
 struct imsgbuf *ibuf_rde;
+struct imsgbuf *ibuf_roa;
 struct rib_namesribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
 char   *cname;
 char   *rcname;
@@ -90,8 +94,9 @@ usage(void)
 
 #define PFD_PIPE_SESSION   0
 #define PFD_PIPE_ROUTE 1
-#define PFD_SOCK_ROUTE 2
-#define POLL_MAX   3
+#define PFD_PIPE_ROA   2
+#define PFD_SOCK_ROUTE 3
+#define POLL_MAX   4
 #define MAX_TIMEOUT3600
 
 int cmd_opts;
@@ -101,16 +106,18 @@ main(int argc, char *argv[])
 {
struct bgpd_config  *conf;
struct peer *peer_l, *p;
+   struct validator*validator_l, *v;
struct pollfdpfd[POLL_MAX];
-   pid_tio_pid = 0, rde_pid = 0, pid;
+   pid_tio_pid = 0, rde_pid = 0, roa_pid = 0, pid;
char*conffile;
char*saved_argv0;
int  debug = 0;
-   int  rflag = 0, sflag = 0;
+   int  rflag = 0, sflag = 0, aflag = 0;
int  rfd = -1;
int  ch, timeout, status;
int  pipe_m2s[2];
int  pipe_m2r[2];
+   int  pipe_m2a[2];
 
conffile = CONFFILE;
   

Re: [patch] exiting bgplgsh with ^D

2017-10-04 Thread Denis Fondras
On Wed, Oct 04, 2017 at 09:04:43PM +0200, Sebastian Benoit wrote:
> I also noticed that the help message does not tell you to use exit to quit
> ;)
> 

I noticed this too but as ^D is a well-known command to exit a shell, I wonder
if it is useful to add exit to the help message. Plus it is not relevant for
bgplg (they share the command list/help message).



Re: forbid config reloads in ospf6d

2017-11-05 Thread Denis Fondras
Ok (for what it's worth).

On Sun, Nov 05, 2017 at 03:50:42PM +0100, Jeremie Courreges-Anglas wrote:
> 
> ospf6d consistently fails when I ask it to reload its config, even
> though I have a very basic test setup:
> 
> area 0.0.0.0 {
> interface em0 { passive }
> interface vether0
> }
> 
> Fixing ospf6d doesn't seem trivial.  Having it fail and exit doesn't
> seem to be a sufficient incentive, so I propose to disable reloading
> until it is fixed.
> 
> Just a suggestion, objections (and oks) welcome.
> 
> 
> Index: ospf6ctl/ospf6ctl.c
> ===
> RCS file: /d/cvs/src/usr.sbin/ospf6ctl/ospf6ctl.c,v
> retrieving revision 1.46
> diff -u -p -r1.46 ospf6ctl.c
> --- ospf6ctl/ospf6ctl.c   12 Aug 2017 22:09:54 -  1.46
> +++ ospf6ctl/ospf6ctl.c   5 Nov 2017 14:37:40 -
> @@ -232,10 +232,14 @@ main(int argc, char *argv[])
>   done = 1;
>   break;
>   case RELOAD:
> +#ifdef notyet
>   imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
>   printf("reload request sent.\n");
>   done = 1;
>   break;
> +#else
> + errx(1, "reload not supported");
> +#endif
>   }
>  
>   while (ibuf->w.queued)
> Index: ospf6d/ospf6d.c
> ===
> RCS file: /d/cvs/src/usr.sbin/ospf6d/ospf6d.c,v
> retrieving revision 1.34
> diff -u -p -r1.34 ospf6d.c
> --- ospf6d/ospf6d.c   12 Aug 2017 16:27:50 -  1.34
> +++ ospf6d/ospf6d.c   5 Nov 2017 14:36:08 -
> @@ -561,6 +561,7 @@ ospf_redistribute(struct kroute *kr, u_i
>  int
>  ospf_reload(void)
>  {
> +#ifdef notyet
>   struct area *area;
>   struct ospfd_conf   *xconf;
>  
> @@ -586,6 +587,9 @@ ospf_reload(void)
>   /* update redistribute lists */
>   kr_reload();
>   return (0);
> +#else
> + return (-1);
> +#endif
>  }
>  
>  int
> 
> 
> -- 
> jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE
> 



Re: [patch] adds include statement in dhcpd.conf

2018-05-11 Thread Denis Fondras
Hi Julien,

I like the idea but implementation seems a bit naive.
Do you have a working example ?

While testing, I can notice a bug with line count (my latest hobby :D).

$ dhcpd -dn -c /etc/examples/dhcpd.conf
/etc/examples/dhcpd.conf line 21: 
filenameee 
^
/etc/examples/dhcpd.conf line 24: /etc/examples/dhcpd.conf line 21: 

^
fatal in dhcpd: Configuration file errors encountered

My test file :

* /etc/examples/dhcpd.conf :
option  domain-name "my.domain";
option  domain-name-servers 192.168.1.3, 192.168.1.5;

subnet 192.168.1.0 netmask 255.255.255.0 {
option routers 192.168.1.1;

range 192.168.1.32 192.168.1.127;

host static-client {
hardware ethernet 22:33:44:55:66:77;
fixed-address 192.168.1.200;
}

host pxe-client {
hardware ethernet 02:03:04:05:06:07;
filename "pxeboot";
next-server 192.168.1.1;
}
include "/usr/src/usr.sbin/dhcpd/host.conf";
}

#include "/usr/src/usr.sbin/dhcpd/subnet.conf";

* /usr/src/usr.sbin/dhcpd/host.conf :
host pxe-client2 {
hardware ethernet 01:03:04:05:06:07;
filenameee "pxeboot";
next-server 192.168.1.10;
}



dhcpd.conf isn't 24 lines long and the problem is in the included file
host.conf.

Thanks.
Denis


On Fri, May 11, 2018 at 02:00:11AM +0200, Julien Dhaille wrote:
> Hi,
> this diff implements the “include” statement, like other daemons.
> Also the config file can be split between different files (in my case, a big 
> list of client is generated from a script, and I don’t want to modify 
> dhcpd.conf).
> 
> Although, I am not even sure if this diff is decent and if it’s a good idea.
> Have a good day :)
> 
> 
> Index: conflex.c
> ===
> RCS file: /cvs/src/usr.sbin/dhcpd/conflex.c,v
> retrieving revision 1.19
> diff -u -p -u -p -r1.19 conflex.c
> --- conflex.c 24 Apr 2017 14:58:36 -  1.19
> +++ conflex.c 10 May 2018 23:30:56 -
> @@ -321,6 +321,7 @@ static const struct keywords {
>   { "hardware",   TOK_HARDWARE },
>   { "host",   TOK_HOST },
>   { "hostname",   TOK_HOSTNAME },
> + { "include",TOK_INCLUDE },
>   { "ipsec-tunnel",   TOK_IPSEC_TUNNEL },
>   { "lease",  TOK_LEASE },
>   { "max-lease-time", TOK_MAX_LEASE_TIME },
> Index: confpars.c
> ===
> RCS file: /cvs/src/usr.sbin/dhcpd/confpars.c,v
> retrieving revision 1.33
> diff -u -p -u -p -r1.33 confpars.c
> --- confpars.c24 Apr 2017 14:58:36 -  1.33
> +++ confpars.c10 May 2018 23:30:56 -
> @@ -329,6 +329,23 @@ parse_statement(FILE *cfile, struct grou
>   parse_warn("use-host-decl-names not allowed here.");
>   group->use_host_decl_names = parse_boolean(cfile);
>   break;
> +
> + case TOK_INCLUDE:
> + group->include = parse_string(cfile);
> + if ((cfile = fopen(group->include, "r")) == NULL)
> + fatal("Can't open %s", group->include);
> + do {
> + token = peek_token(, cfile);
> + if (token == EOF)
> + break;
> + declaration = parse_statement(cfile, _group,
> + ROOT_GROUP,
> + NULL,
> + declaration);
> + } while (1);
> + token = next_token(, cfile); /* Clear the peek buffer */
> + fclose(cfile);
> + break;
> 
>   case TOK_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE:
>   group->use_lease_addr_for_default_route =
> Index: dhcpd.conf.5
> ===
> RCS file: /cvs/src/usr.sbin/dhcpd/dhcpd.conf.5,v
> retrieving revision 1.23
> diff -u -p -u -p -r1.23 dhcpd.conf.5
> --- dhcpd.conf.5  1 Mar 2018 20:48:11 -   1.23
> +++ dhcpd.conf.5  10 May 2018 23:30:56 -
> @@ -873,6 +873,25 @@ into its response (DHCP ACK or NAK) per
>  In other words if the client sends the option it will receive it back.
>  By default, this flag is on
>  and client identifiers will be echoed back to the client.
> +.Pp
> +The
> +.Ic include
> +statement allows additional configuration files to be included:
> +.Pp
> +.D1 Ic include Qq Ar filename ;
> +.Pp
> +For example:
> +.Bd -literal -offset indent
> +include "/etc/dhcpd.conf.hosts";
> +include "/etc/dhcpd.conf.office1";
> +include "/etc/dhcpd.conf.office2";
> +.Ed
> +.Pp
> +You can split the client declarations into different files.
> +It could be use in order to keep
> +.Nm
> +small and easy to read, and if you want to generate clients declaration

Re: route: improve inet6_makenetandmask

2018-05-26 Thread Denis Fondras
On Sat, May 26, 2018 at 12:54:03PM +0200, Klemens Nanni wrote:
> inet6_makenetandmask() parses the provided prefix length `plen' twice:
> first from inside prefixlen() which sets the mask, then right again
> doing almost the same dance to find out which bits to zero in the
> provided address.
> 
> But once prefixlen() set so_mask, we can just use it to actually mask
> the address.
> 
> prefixlen() returns `(len == max)' where `max = 128' for `AF_INET6', so
> it's equivalent to the strcmp() call.
> 
> Regress tests pass on amd64, also no issue after manually adding,
> testing and removing routes on my machine.
> 
> Feedback? OK?
> 
> Index: route.c
> ===
> RCS file: /cvs/src/sbin/route/route.c,v
> retrieving revision 1.214
> diff -u -p -r1.214 route.c
> --- route.c   1 May 2018 18:14:10 -   1.214
> +++ route.c   26 May 2018 10:49:50 -
> @@ -786,21 +786,17 @@ inet_makenetandmask(u_int32_t net, struc
>   sin->sin_len = 1 + cp - (char *)sin;
>  }
>  
> -/*
> - * XXX the function may need more improvement...
> - */
>  int
>  inet6_makenetandmask(struct sockaddr_in6 *sin6, char *plen)
>  {
>   struct in6_addr in6;
> - const char *errstr;
> - int i, len, q, r;
> + int i;
>  
> - if (NULL==plen) {
> + if (!plen) {
>   if (IN6_IS_ADDR_UNSPECIFIED(>sin6_addr) &&
> - sin6->sin6_scope_id == 0) {
> + sin6->sin6_scope_id == 0)
>   plen = "0";
> - } else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) {
> + else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) {
>   /* aggregatable global unicast - RFC2374 */
>   memset(, 0, sizeof(in6));
>   if (!memcmp(>sin6_addr.s6_addr[8],

Not related to this diff but RFC2374 has been made obsolete by RFC3587 for some
years : "implementations should not make any assumptions about 2000::/3 being
special". I think we can simplify this "else if" :)

> @@ -809,27 +805,14 @@ inet6_makenetandmask(struct sockaddr_in6
>   }
>   }
>  
> - if (!plen || strcmp(plen, "128") == 0)
> + if (!plen || prefixlen(AF_INET6, plen))
>   return (1);
> - else {
> - rtm_addrs |= RTA_NETMASK;
> - prefixlen(AF_INET6, plen);
> -
> - len = strtonum(plen, 0, 128, );
> - if (errstr)
> - errx(1, "prefixlen %s is %s", plen, errstr);
> -
> - q = (128-len) >> 3;
> - r = (128-len) & 7;
> - i = 15;
> -
> - while (q-- > 0)
> - sin6->sin6_addr.s6_addr[i--] = 0;
> - if (r > 0)
> - sin6->sin6_addr.s6_addr[i] &= 0xff << r;
> + rtm_addrs |= RTA_NETMASK;

Can't we consider this done in prefixlen() ?

>  
> - return (0);
> - }
> + for (i = 0; i < 16; ++i)
> + sin6->sin6_addr.s6_addr[i] &= so_mask.sin6.sin6_addr.s6_addr[i];
> +
> + return (0);
>  }
>  
>  /*
> 



acme-client/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to acme-client.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/acme-client/parse.y,v
retrieving revision 1.21
diff -u -p -r1.21 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.21
+++ parse.y 27 May 2018 15:47:33 -
@@ -43,6 +43,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -55,8 +59,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 struct authority_c *conf_new_authority(struct acme_conf *, char *);
@@ -432,34 +437,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#defineSTART_EXPAND1
+#defineDONE_EXPAND 2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -469,8 +479,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -479,28 +489,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -508,14 +529,9 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-
/* skip to either EOF or the 

bgpd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to bgpd
Fixes an off-by-one line count when using include statements.

Ok ?


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.320
diff -u -p -r1.320 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.320
+++ parse.y 27 May 2018 13:14:27 -
@@ -53,6 +53,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -66,8 +70,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -2566,34 +2571,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -2603,8 +2613,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -2613,28 +2623,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -2642,14 +2663,9 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-
/* skip to either EOF or the first real EOL 

hostapd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to hostapd.
Fixes an off-by-one line count when using include statements.

Ok ?


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/hostapd/parse.y,v
retrieving revision 1.55
diff -u -p -r1.55 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.55
+++ parse.y 27 May 2018 16:16:52 -
@@ -62,6 +62,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -75,8 +79,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -190,8 +195,7 @@ include : INCLUDE STRING
{
struct file *nfile;
 
-   if ((nfile =
-   pushfile($2, 1)) == NULL) {
+   if ((nfile = pushfile($2, 1)) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -1336,34 +1340,39 @@ lookup(char *token)
return (p == NULL ? STRING : p->k_val);
 }
 
-#define MAXPUSHBACK128
+#defineSTART_EXPAND1
+#defineDONE_EXPAND 2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -1373,8 +1382,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -1383,28 +1392,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
-   }
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   

smtpd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to smtpd.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/smtpd/parse.y,v
retrieving revision 1.210
diff -u -p -r1.210 parse.y
--- parse.y 1 Jun 2018 20:31:33 -   1.210
+++ parse.y 2 Jun 2018 19:31:08 -
@@ -63,6 +63,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -73,8 +77,9 @@ intyyparse(void);
 int yylex(void);
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 int yyerror(const char *, ...)
 __attribute__((__format__ (printf, 1, 2)))
@@ -1663,34 +1668,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-unsigned char  *parsebuf;
-int parseindex;
-unsigned char   pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -1700,8 +1710,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -1710,28 +1720,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -1739,9 +1760,6 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-   pushback_index = 0;
-

eigrpd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to eigrpd.
Fixes an off-by-one line count when using include statements.

Ok ?


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/eigrpd/parse.y,v
retrieving revision 1.23
diff -u -p -r1.23 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.23
+++ parse.y 27 May 2018 16:12:49 -
@@ -45,6 +45,10 @@ struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 };
@@ -83,15 +87,14 @@ typedef struct {
int lineno;
 } YYSTYPE;
 
-#define MAXPUSHBACK128
-
 static int  yyerror(const char *, ...)
 __attribute__((__format__ (printf, 1, 2)))
 __attribute__((__nonnull__ (1)));
 static int  kw_cmp(const void *, const void *);
 static int  lookup(char *);
+static int  igetc(void);
 static int  lgetc(int);
-static int  lungetc(int);
+voidlungetc(int);
 static int  findeol(void);
 static int  yylex(void);
 static int  check_file_secrecy(int, const char *);
@@ -123,11 +126,6 @@ static struct config_defaults   asdefs;
 static struct config_defaults   ifacedefs;
 static struct config_defaults  *defs;
 
-static unsigned char   *parsebuf;
-static int  parseindex;
-static unsigned charpushback_buffer[MAXPUSHBACK];
-static int  pushback_index;
-
 %}
 
 %token ROUTERID AS FIBUPDATE RDOMAIN REDISTRIBUTE METRIC DFLTMETRIC
@@ -159,7 +157,8 @@ grammar : /* empty */
 include: INCLUDE STRING {
struct file *nfile;
 
-   if ((nfile = pushfile($2, 1)) == NULL) {
+   if ((nfile = pushfile($2,
+   !(global.cmd_opts & EIGRPD_OPT_NOACTION))) == NULL) 
{
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -653,27 +652,39 @@ lookup(char *s)
return (STRING);
 }
 
-static int
-lgetc(int quotec)
+#define START_EXPAND   1
+#define DONE_EXPAND2
+
+static int expanding;
+
+int
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+static int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -683,8 +694,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -693,28 +704,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == 

snmpd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to snmpd.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.47
diff -u -p -r1.47 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.47
+++ parse.y 27 May 2018 14:18:32 -
@@ -61,6 +61,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -74,8 +78,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -657,34 +662,38 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing quoted 
string");
if (file == topfile || popfile() == EOF)
return (EOF);
@@ -693,8 +702,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -711,28 +720,39 @@ lgetc(int quotec)
c = ' ';
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -740,14 +760,9 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-
/* skip to either EOF or the first real EOL */
while (1) {
- 

switchd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to switchd.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/switchd/parse.y,v
retrieving revision 1.6
diff -u -p -r1.6 parse.y
--- parse.y 28 Aug 2017 06:00:05 -  1.6
+++ parse.y 27 May 2018 13:28:54 -
@@ -29,6 +29,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -44,6 +45,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -56,8 +61,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 int host(const char *, struct sockaddr *, socklen_t);
 
@@ -294,34 +300,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -331,8 +342,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -349,28 +360,39 @@ lgetc(int quotec)
c = ' ';
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -378,14 +400,9 @@ findeol(void)
 {
int c;
 
-   parsebuf 

iked/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to iked.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/sbin/iked/parse.y,v
retrieving revision 1.71
diff -u -p -r1.71 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.71
+++ parse.y 27 May 2018 14:41:47 -
@@ -59,6 +59,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file;
@@ -77,8 +81,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -434,7 +439,7 @@ comma   : ','
 include: INCLUDE STRING{
struct file *nfile;
 
-   if ((nfile = pushfile($2, 0)) == NULL) {
+   if ((nfile = pushfile($2, 1)) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -1213,34 +1218,39 @@ lookup(char *s)
}
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-unsigned char  *parsebuf;
-int parseindex;
-unsigned char   pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (popfile() == EOF)
@@ -1250,8 +1260,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -1261,27 +1271,38 @@ lgetc(int quotec)
}
 
while (c == EOF) {
-   if (popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index 

httpd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to httpd.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.99
diff -u -p -r1.99 parse.y
--- parse.y 23 May 2018 19:11:48 -  1.99
+++ parse.y 2 Jun 2018 18:18:13 -
@@ -59,6 +59,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -72,8 +76,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -1288,34 +1293,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-unsigned char  *parsebuf;
-int parseindex;
-unsigned char   pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -1325,8 +1335,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -1335,28 +1345,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -1364,14 +1385,9 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-
/* skip to 

iscsictl/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to iscsictl.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/iscsictl/parse.y,v
retrieving revision 1.11
diff -u -p -r1.11 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.11
+++ parse.y 2 Jun 2018 19:05:26 -
@@ -50,6 +50,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -62,8 +66,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 voidclear_config(struct iscsi_config *);
@@ -393,34 +398,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -430,8 +440,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -448,20 +458,20 @@ lgetc(int quotec)
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -469,14 +479,9 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-
/* skip to either EOF or the first real EOL */
while (1) {
-   if (pushback_index)
-   c = pushback_buffer[--pushback_index];
-   else
-   c = lgetc(0);
+   c = lgetc(0);
if (c == '\n') {
file->lineno++;
break;
@@ -504,7 +509,7 @@ top:
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
-   if (c == '$' && parsebuf == NULL) {
+   if (c == '$' && !expanding) {
while (1) {
if ((c = lgetc(0)) == EOF)
return (0);
@@ -526,8 +531,13 @@ top:
yyerror("macro '%s' not defined", buf);
return (findeol());
}
-   parsebuf = val;
-   

vmd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to vmd.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/vmd/parse.y,v
retrieving revision 1.33
diff -u -p -r1.33 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.33
+++ parse.y 2 Jun 2018 20:23:16 -
@@ -55,6 +55,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -67,8 +71,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -684,34 +689,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -721,8 +731,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -739,28 +749,39 @@ lgetc(int quotec)
c = ' ';
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -768,14 +789,9 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-
/* skip to either EOF or the first real EOL */
while (1) 

ldpd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to ldpd.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/ldpd/parse.y,v
retrieving revision 1.62
diff -u -p -r1.62 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.62
+++ parse.y 2 Jun 2018 19:51:55 -
@@ -43,6 +43,10 @@ struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 };
@@ -76,15 +80,14 @@ typedef struct {
int lineno;
 } YYSTYPE;
 
-#define MAXPUSHBACK128
-
 static int  yyerror(const char *, ...)
 __attribute__((__format__ (printf, 1, 2)))
 __attribute__((__nonnull__ (1)));
 static int  kw_cmp(const void *, const void *);
 static int  lookup(char *);
+static int  igetc(void);
 static int  lgetc(int);
-static int  lungetc(int);
+voidlungetc(int);
 static int  findeol(void);
 static int  yylex(void);
 static int  check_file_secrecy(int, const char *);
@@ -127,11 +130,6 @@ static struct config_defaults   tnbrdefs;
 static struct config_defaults   pwdefs;
 static struct config_defaults  *defs;
 
-static unsigned char   *parsebuf;
-static int  parseindex;
-static unsigned charpushback_buffer[MAXPUSHBACK];
-static int  pushback_index;
-
 %}
 
 %token INTERFACE TNEIGHBOR ROUTERID FIBUPDATE RDOMAIN EXPNULL
@@ -168,7 +166,8 @@ grammar : /* empty */
 include: INCLUDE STRING{
struct file *nfile;
 
-   if ((nfile = pushfile($2, 1)) == NULL) {
+   if ((nfile = pushfile($2,
+   !(global.cmd_opts & LDPD_OPT_NOACTION))) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -876,27 +875,39 @@ lookup(char *s)
return (STRING);
 }
 
-static int
-lgetc(int quotec)
+#define START_EXPAND   1
+#define DONE_EXPAND2
+
+static int expanding;
+
+int
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+static int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -906,8 +917,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -916,28 +927,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == 

ospf6d/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to ospf6d.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v
retrieving revision 1.31
diff -u -p -r1.31 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.31
+++ parse.y 2 Jun 2018 20:18:24 -
@@ -50,6 +50,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -63,8 +67,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -146,7 +151,8 @@ grammar : /* empty */
 include: INCLUDE STRING{
struct file *nfile;
 
-   if ((nfile = pushfile($2, 1)) == NULL) {
+   if ((nfile = pushfile($2,
+   !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -591,34 +597,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -628,8 +639,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -638,28 +649,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+ 

ldapd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to ldapd.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/ldapd/parse.y,v
retrieving revision 1.28
diff -u -p -r1.28 parse.y
--- parse.y 18 May 2018 12:36:30 -  1.28
+++ parse.y 2 Jun 2018 19:48:01 -
@@ -52,6 +52,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -65,8 +69,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 struct listener *host_unix(const char *path);
@@ -477,34 +482,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#defineSTART_EXPAND1
+#defineDONE_EXPAND 2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -514,8 +524,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -524,28 +534,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -553,14 +574,9 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-
/* skip to either EOF or the first real EOL */
while (1) {

ypldap/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to ypldap.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/ypldap/parse.y,v
retrieving revision 1.24
diff -u -p -r1.24 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.24
+++ parse.y 27 May 2018 12:58:06 -
@@ -56,6 +56,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -69,8 +73,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -130,7 +135,7 @@ optnl   : '\n' optnl
 include: INCLUDE STRING{
struct file *nfile;
 
-   if ((nfile = pushfile($2, 0)) == NULL) {
+   if ((nfile = pushfile($2, 1)) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -491,34 +496,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -528,8 +538,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -538,28 +548,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   

relayd/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to relayd.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.223
diff -u -p -r1.223 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.223
+++ parse.y 2 Jun 2018 18:55:33 -
@@ -63,6 +63,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -74,8 +78,9 @@ intyylex(void);
 int yyerror(const char *, ...);
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -2327,34 +2332,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+#define START_EXPAND   1
+#define DONE_EXPAND2
+
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -2364,8 +2374,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -2374,28 +2384,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+   if (p == NULL)
+   err(1, "lungetc");
+   file->ungetbuf = p;
+   file->ungetsize *= 2;
}
-   if (pushback_index < MAXPUSHBACK-1)
-   return (pushback_buffer[pushback_index++] = c);
-   else
-   return (EOF);
+   file->ungetbuf[file->ungetpos++] = c;
 }
 
 int
@@ -2403,14 +2424,9 @@ findeol(void)
 {
int c;
 
-   parsebuf = NULL;
-
/* skip to either EOF or the first real EOL */
while (1) {
-

regress/rtable coredump

2018-06-22 Thread Denis Fondras
When trying to add multiple time the same prefix, ./fullfeed/fullfeed throws
'Segmentation fault (core dumped)'.

Here is a fix :

Index: util.c
===
RCS file: /cvs/src/regress/sys/net/rtable/util.c,v
retrieving revision 1.6
diff -u -p -r1.6 util.c
--- util.c  27 Jul 2017 13:34:30 -  1.6
+++ util.c  22 Jun 2018 18:12:09 -
@@ -110,7 +110,7 @@ route_insert(unsigned int rid, sa_family
rt_maskedcopy(dst, ndst, mask);
 
if ((error = rtable_insert(rid, ndst, mask, NULL, 0, rt)) != 0) {
-   inet_net_satop(af, rt_key(rt), plen, ip, sizeof(ip));
+   inet_net_satop(af, ndst, plen, ip, sizeof(ip));
errx(1, "can't add route: %s, %s\n", ip, strerror(error));
}
nrt = rtable_lookup(rid, dst, mask, NULL, RTP_ANY);



uipc_domain.c : use constant instead of value

2018-06-23 Thread Denis Fondras
Cosmetic change.

Index: uipc_domain.c
===
RCS file: /cvs/src/sys/kern/uipc_domain.c,v
retrieving revision 1.55
diff -u -p -r1.55 uipc_domain.c
--- uipc_domain.c   23 Nov 2017 13:45:46 -  1.55
+++ uipc_domain.c   23 Jun 2018 13:48:51 -
@@ -141,7 +141,7 @@ pffindproto(int family, int protocol, in
const struct protosw *pr;
const struct protosw *maybe = NULL;
 
-   if (family == 0)
+   if (family == PF_UNSPEC)
return (NULL);
 
dp = pffinddomain(family);
@@ -176,7 +176,7 @@ net_sysctl(int *name, u_int namelen, voi
return (EISDIR);/* overloaded */
family = name[0];
 
-   if (family == 0)
+   if (family == PF_UNSPEC)
return (0);
 #if NBPFILTER > 0
if (family == PF_BPF)



Fix a kernelpanic when playing with rdomain(4) and enc(4)

2018-06-24 Thread Denis Fondras
When removing enc(4) interface from rdomain, the kernel panics randomly
(memcpy() seems to copy outside of the mallocarray() boundaries) with something
like :

Data modified on freelist: word -35183699295756 of object 0x8059da80 
size 0x8 previous type free (invalid addr 0x7b44962aa448c22a)
kernel: protection fault trap, code=0
Stopped at  malloc+0x4d3:   movq0x8(%r14),%rbx

Here is a script that trigger the bug :

#!/bin/sh
ifconfig enc0 rdomain 42
ifconfig enc0 rdomain 42
ifconfig enc0 rdomain 42
ifconfig enc0 -rdomain
ifconfig enc0 rdomain 42
ifconfig enc0 rdomain 42
ifconfig enc0 -rdomain 
ifconfig enc0 -rdomain
ifconfig enc0 rdomain 42
ifconfig enc0 -rdomain
ifconfig enc0 -rdomain
ifconfig enc0 -rdomain
ifconfig enc0 -rdomain
ifconfig enc0 -rdomain
ifconfig enc0 rdomain 42
ifconfig enc0 rdomain 42
ls

Here is a fix :

Index: if_enc.c
===
RCS file: /cvs/src/sys/net/if_enc.c,v
retrieving revision 1.70
diff -u -p -r1.70 if_enc.c
--- if_enc.c16 Oct 2017 08:22:25 -  1.70
+++ if_enc.c24 Jun 2018 17:15:32 -
@@ -271,7 +271,7 @@ enc_setif(struct ifnet *ifp, u_int id)
if (id > RT_TABLEID_MAX)
return (EINVAL);
 
-   if (id == 0 || id > enc_max_id) {
+   if (enc_ifps == NULL || id > enc_max_id) {
if ((new = mallocarray(id + 1, sizeof(struct ifnet *),
M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
return (ENOBUFS);



[diff] deleting lo(4) with rdomain

2018-06-23 Thread Denis Fondras
Here is a diff to allow deletion of lo(4) created by rdomain.

Of course, lo(4) cannot be deleted while the rdomain is used on another
interface. rtable is still available after all the interfaces are out of the
rdomain though.

[denis@visigoth:~] doas ifconfig em0 rdomain 3
[denis@visigoth:~] ifconfig 
lo0: flags=8049 mtu 32768
index 4 priority 0 llprio 3
groups: lo
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
inet 127.0.0.1 netmask 0xff00
em0: flags=8843 rdomain 3 mtu 1500
lladdr 8c:16:45:57:e4:91
index 2 priority 0 llprio 3
media: Ethernet autoselect (none)
status: no carrier
lo3: flags=8008 rdomain 3 mtu 32768
index 7 priority 0 llprio 3
groups: lo
[denis@visigoth:~] doas ifconfig lo3 -rdomain
ifconfig: SIOCSIFRDOMAIN: Operation not permitted
[denis@visigoth:~] doas ifconfig em0 -rdomain
[denis@visigoth:~] doas ifconfig lo3 -rdomain
[denis@visigoth:~] ifconfig 
lo0: flags=8049 mtu 32768
index 4 priority 0 llprio 3
groups: lo
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
inet 127.0.0.1 netmask 0xff00
em0: flags=8843 mtu 1500
lladdr 8c:16:45:57:e4:91
index 2 priority 0 llprio 3
media: Ethernet autoselect (none)
status: no carrier
lo3: flags=8008 mtu 32768
index 7 priority 0 llprio 3
groups: lo
[denis@visigoth:~] doas ifconfig lo3 destroy
[denis@visigoth:~] ifconfig
lo0: flags=8049 mtu 32768
index 4 priority 0 llprio 3
groups: lo
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
inet 127.0.0.1 netmask 0xff00
em0: flags=8843 mtu 1500
lladdr 8c:16:45:57:e4:91
index 2 priority 0 llprio 3
media: Ethernet autoselect (none)
status: no carrier

Because the kernel panics when manipulating rdomain on enc(4), I added a check
to disallow that (the kernel panic is not linked to this change, it
preexisted).


Index: if.c
===
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.556
diff -u -p -r1.556 if.c
--- if.c21 Jun 2018 07:40:43 -  1.556
+++ if.c23 Jun 2018 19:41:05 -
@@ -1729,43 +1729,53 @@ if_setlladdr(struct ifnet *ifp, const ui
return (0);
 }
 
+struct ifnet *
+rdomain_isused(struct ifnet *ifp, int rdomain)
+{
+   struct ifnet *ifp_;
+
+   TAILQ_FOREACH(ifp_, , if_list) {
+   if (ifp_ == ifp)
+   continue;
+   if (ifp_->if_rdomain == rdomain)
+   return (ifp_);
+   }
+   return (NULL);
+}
+
 int
 if_setrdomain(struct ifnet *ifp, int rdomain)
 {
struct ifreq ifr;
int error, up = 0, s;
+   struct ifnet *loifp;
+   char loifname[IFNAMSIZ];
+   unsigned int unit = rdomain;
 
if (rdomain < 0 || rdomain > RT_TABLEID_MAX)
return (EINVAL);
 
+   if (strncmp(ifp->if_xname, "enc", 3) == 0)
+   return (EPERM);
+
/*
 * Create the routing table if it does not exist, including its
 * loopback interface with unit == rdomain.
 */
-   if (!rtable_exists(rdomain)) {
-   struct ifnet *loifp;
-   char loifname[IFNAMSIZ];
-   unsigned int unit = rdomain;
-
-   snprintf(loifname, sizeof(loifname), "lo%u", unit);
-   error = if_clone_create(loifname, 0);
-
-   if ((loifp = ifunit(loifname)) == NULL)
-   return (ENXIO);
-
-   /* Do not error out if creating the default lo(4) interface */
-   if (error && (ifp != loifp || error != EEXIST))
+   if (!rtable_exists(rdomain))
+   if ((error = rtable_add(rdomain)))
return (error);
 
-   if ((error = rtable_add(rdomain)) == 0)
-   rtable_l2set(rdomain, rdomain, loifp->if_index);
-   if (error) {
-   if_clone_destroy(loifname);
-   return (error);
-   }
+   snprintf(loifname, sizeof(loifname), "lo%u", unit);
+   error = if_clone_create(loifname, 0);
+   if (error && error != EEXIST)
+   return (error);
 
-   loifp->if_rdomain = rdomain;
-   }
+   if ((loifp = ifunit(loifname)) == NULL)
+   return (ENXIO);
+
+   rtable_l2set(rdomain, rdomain, loifp->if_index);
+   loifp->if_rdomain = rdomain;
 
/* make sure that the routing table is a real rdomain */
if (rdomain != rtable_l2(rdomain))
@@ -1773,7 +1783,8 @@ if_setrdomain(struct ifnet *ifp, int rdo
 
if (rdomain != ifp->if_rdomain) {
if ((ifp->if_flags & IFF_LOOPBACK) &&
-   (ifp->if_index == rtable_loindex(ifp->if_rdomain)))
+   (ifp->if_index == 

IPv6 over VPLS

2017-12-27 Thread Denis Fondras
Hi,

I am trying to make IPv6 over VPLS.
I updated ldpd(8) to install MPLS route for IPv6 nexthop. I can see the routes
but when pinging the destination I get "No route to host". Can someone give me a
pointer for the next step ?

Thank you in advance,
Denis

* Without the patch :

mpls1# route -n show 
Routing tables

Internet:
DestinationGatewayFlags   Refs  Use   Mtu  Prio Iface
[...]
172.16.0/24192.168.150.139UGT06 -32 vio0 

Internet6:
DestinationGatewayFlags   Refs  
Use   Mtu  Prio Iface
[...]
2001:db8::/64  fe80::fcd8:d9ff:fe57:bd48%vio0 UG 0  
  4 -32 vio0 
2001:db8:1::/642001:db8:1::1  UCn0  
  0 - 4 vether0
2001:db8:1::1  fe:e1:ba:d0:89:89  UHLl   0  
 76 - 1 vether0
2001:db8:fffe::/64 fe80::fcd8:d9ff:fe57:bd48%vio0 UG 1  
  6 -32 vio0 
2001:db8:::/64 2001:db8:::1   UCn1  
  2 - 4 vio0 
2001:db8:::/64 link#1 UC 0  
  0 -32 vio0 
2001:db8:::1   9e:21:8a:77:cd:cc  UHLl   0  
   1511 - 1 vio0 
2001:db8:::2   fe:d8:d9:57:bd:48  UHLc   0  
257 - 3 vio0 

MPLS:
In label  Out label Op GatewayFlags   Refs  Use   Mtu  Prio 
Interface
17- POP192.168.150.139UGT00 -32 
vio0 
1816SWAP   192.168.150.139UGT00 -32 
vio0 

mpls1# route get 2001:db8::/64
   route to: 2001:db8::
destination: 2001:db8::
   mask: :::::
gateway: fe80::fcd8:d9ff:fe57:bd48%vio0
  interface: vio0
 if address: fe80::9c21:8aff:fe77:cdcc%vio0
   priority: 32 (ospf)
  flags: 
 use   mtuexpire
   4 0 0 

mpls1# ping6 2001:db8::1
PING 2001:db8::1 (2001:db8::1): 56 data bytes
64 bytes from 2001:db8::1: icmp_seq=0 hlim=63 time=1.039 ms
64 bytes from 2001:db8::1: icmp_seq=1 hlim=63 time=1.037 ms
^C
--- 2001:db8::1 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 1.037/1.038/1.039/0.001 ms

* With the patch :

mpls1# route -n show   
Routing tables

Internet:
DestinationGatewayFlags   Refs  Use   Mtu  Prio Iface
[...]
172.16.0/24192.168.150.139UGT06 -32 vio0 

Internet6:
DestinationGatewayFlags   Refs  
Use   Mtu  Prio Iface
[...]
2001:db8::/64  fe80::fcd8:d9ff:fe57:bd48%vio0 UGT0  
  4 -32 vio0 
2001:db8:1::/642001:db8:1::1  UCn0  
  0 - 4 vether0
2001:db8:1::1  fe:e1:ba:d0:89:89  UHLl   0  
 76 - 1 vether0
2001:db8:fffe::/64 fe80::fcd8:d9ff:fe57:bd48%vio0 UG 2  
  7 -32 vio0 
2001:db8:::/64 2001:db8:::1   UCn1  
  2 - 4 vio0 
2001:db8:::/64 link#1 UC 0  
  0 -32 vio0 
2001:db8:::1   9e:21:8a:77:cd:cc  UHLl   0  
   1526 - 1 vio0 
2001:db8:::2   fe:d8:d9:57:bd:48  UHLc   0  
281 - 3 vio0 

MPLS:
In label  Out label Op GatewayFlags   Refs  Use   Mtu  Prio 
Interface
17- POP192.168.150.139UGT00 -32 
vio0 
1816SWAP   192.168.150.139UGT00 -32 
vio0 
1918SWAP   fe80::fcd8:d9ff:fe57:bd48%vio0 UGT00 
-32 vio0 
20- POPfe80::fcd8:d9ff:fe57:bd48%vio0 UGT00 
-32 vio0 
21- LOCAL  ::1%3  UGT00 32768 8 
lo0  
22- LOCAL  ::1%3  UGT00 32768 8 
lo0  
23- LOCAL  ::1%3  UGT00 32768 8 
lo0  
24- LOCAL  ::1%3  UGT00 32768 8 
lo0

mpls1# route get 2001:db8::/64 
   route to: 2001:db8::
destination: 2001:db8::
   mask: :::::
gateway: fe80::fcd8:d9ff:fe57:bd48%vio0
  interface: vio0
 if address: fe80::9c21:8aff:fe77:cdcc%vio0
 mpls label: PUSH 18
   priority: 32 (ospf)
  flags: 
 use   mtuexpire
   4 0 0 
sockaddrs: 

mpls1# ping6 2001:db8::1 
PING 2001:db8::1 (2001:db8::1): 56 data bytes
ping6: sendmsg: No route to host
ping: 

[patch] IPv6 over VPLS

2017-12-27 Thread Denis Fondras
Hi,

Here are 2 patches to enable IPv6 over VPLS.
One for ldpd(8) and one for the kernel.

Denis


Index: if_ethersubr.c
===
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.246
diff -u -p -r1.246 if_ethersubr.c
--- if_ethersubr.c  31 May 2017 05:59:09 -  1.246
+++ if_ethersubr.c  27 Dec 2017 19:10:02 -
@@ -248,8 +248,12 @@ ether_output(struct ifnet *ifp, struct m
memcpy(edst, LLADDR(satosdl(dst)),
sizeof(edst));
break;
+   case AF_INET6:
+   error = nd6_resolve(ifp, rt, m, dst, edst);
+   if (error)
+   return (error == EAGAIN ? 0 : error);
+   break;
case AF_INET:
-   case AF_MPLS:
error = arpresolve(ifp, rt, m, dst, edst);
if (error)
return (error == EAGAIN ? 0 : error);


Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/ldpd/kroute.c,v
retrieving revision 1.66
diff -u -p -r1.66 kroute.c
--- kroute.c24 Jul 2017 11:00:01 -  1.66
+++ kroute.c27 Dec 2017 12:48:59 -
@@ -259,7 +259,7 @@ kr_change(struct kroute *kr)
 
if (ldp_addrisset(kn->r.af, >r.nexthop) &&
kn->r.remote_label != NO_LABEL) {
-   if (send_rtmsg(kr_state.fd, RTM_CHANGE, >r, AF_INET) == -1)
+   if (send_rtmsg(kr_state.fd, RTM_CHANGE, >r, kn->r.af) == -1)
return (-1);
}
 
@@ -305,7 +305,7 @@ kr_delete(struct kroute *kr)
kn->r.remote_label = NO_LABEL;
 
if (update &&
-   send_rtmsg(kr_state.fd, RTM_CHANGE, >r, AF_INET) == -1)
+   send_rtmsg(kr_state.fd, RTM_CHANGE, >r, kn->r.af) == -1)
return (-1);
 
return (0);
@@ -346,7 +346,7 @@ kr_fib_couple(void)
if (ldp_addrisset(kn->r.af, >r.nexthop) &&
kn->r.remote_label != NO_LABEL) {
send_rtmsg(kr_state.fd, RTM_CHANGE,
-   >r, AF_INET);
+   >r, kn->r.af);
}
}
}
@@ -387,7 +387,7 @@ kr_fib_decouple(void)
rl = kn->r.remote_label;
kn->r.remote_label = NO_LABEL;
send_rtmsg(kr_state.fd, RTM_CHANGE,
-   >r, AF_INET);
+   >r, kn->r.af);
kn->r.remote_label = rl;
}
}
@@ -1311,6 +1311,145 @@ send_rtmsg_v4(int fd, int action, struct
 static int
 send_rtmsg_v6(int fd, int action, struct kroute *kr, int family)
 {
+   struct ioveciov[5];
+   struct rt_msghdrhdr;
+   struct sockaddr_mplslabel_in, label_out;
+   struct sockaddr_in6 dst, mask, nexthop;
+   int iovcnt = 0;
+
+   if (kr_state.fib_sync == 0)
+   return (0);
+
+   /*
+* Reserved labels (implicit and explicit NULL) should not be added
+* to the FIB.
+*/
+   if (family == AF_MPLS && kr->local_label < MPLS_LABEL_RESERVED_MAX)
+   return (0);
+
+   /* initialize header */
+   memset(, 0, sizeof(hdr));
+   hdr.rtm_version = RTM_VERSION;
+
+   hdr.rtm_type = action;
+   hdr.rtm_flags = RTF_UP;
+   hdr.rtm_fmask = RTF_MPLS;
+   hdr.rtm_seq = kr_state.rtseq++; /* overflow doesn't matter */
+   hdr.rtm_msglen = sizeof(hdr);
+   hdr.rtm_hdrlen = sizeof(struct rt_msghdr);
+   hdr.rtm_priority = kr->priority;
+   hdr.rtm_tableid = kr_state.rdomain; /* rtableid */
+   /* adjust iovec */
+   iov[iovcnt].iov_base = 
+   iov[iovcnt++].iov_len = sizeof(hdr);
+
+   if (family == AF_MPLS) {
+   memset(_in, 0, sizeof(label_in));
+   label_in.smpls_len = sizeof(label_in);
+   label_in.smpls_family = AF_MPLS;
+   label_in.smpls_label =
+   htonl(kr->local_label << MPLS_LABEL_OFFSET);
+   /* adjust header */
+   hdr.rtm_flags |= RTF_MPLS | RTF_MPATH;
+   hdr.rtm_addrs |= RTA_DST;
+   hdr.rtm_msglen += sizeof(label_in);
+   /* adjust iovec */
+   iov[iovcnt].iov_base = _in;
+   iov[iovcnt++].iov_len = sizeof(label_in);
+   } else {
+   memset(, 0, sizeof(dst));
+   dst.sin6_len = sizeof(dst);
+   dst.sin6_family = AF_INET6;
+   dst.sin6_addr = kr->prefix.v6;
+   /* adjust 

remove link from oce.4

2018-01-28 Thread Denis Fondras
Hi,

The link to Emulex website is not available anymore. Remove it.

Denis

Index: oce.4
===
RCS file: /cvs/src/share/man/man4/oce.4,v
retrieving revision 1.3
diff -u -p -r1.3 oce.4
--- oce.4   15 Aug 2012 18:10:06 -  1.3
+++ oce.4   28 Jan 2018 11:23:39 -
@@ -46,8 +46,6 @@ HP NC552SFP (SPF+/10GbaseSR)
 IBM System x 10GbE (SPF+/10GbaseSR)
 .El
 .Pp
-For a comprehensive list of devices please consult the Emulex website:
-.Lk http://www.emulex.com/products/10gbe-network-adapters-nic.html .
 .Sh SEE ALSO
 .Xr arp 4 ,
 .Xr ifmedia 4 ,



Re: ospfd: prevent additional ospfd from starting

2018-08-21 Thread Denis Fondras
On Tue, Aug 21, 2018 at 05:16:47PM +0200, Remi Locherer wrote:
> Hi tech,
> 
> recently we had a short outage in our network. A script started an additional
> ospfd instance because the -n flag for config test was missing.
> 
> What then happend was not nice:
> - The new ospfd unlinked the control socket of the first ospfd
> - The new ospfd removed all routes from the first ospfd
> - The new ospfd was not able to build up an adjacency and therefore could
>   not install the routes needed for a recovery.
> - Both ospfd instances were running but non-functional.
> 
> Of course the faulty script is fixed by now. ;-)
> 
> It would be nice if ospfd could prevent such a situation.
> 
> Below diff does these things:
> - Detect a running ospfd by first doing a connect on the control socket.
> - Do not delete the control socket on exit.
>   - This could delete the socket of another instance.
>   - Unlinking the socket on shutdown will be in the way once we add pledge
> to the main process. It was removed recently from various daemons.
> - Do not delete routes added by another process even if they have
>   prio RTP_OSPF. Without this the new ospfd will remove all the routes
>   of the first one.
> 
> A side effect of this is that alien OSPF routes are now only logged but
> not removed anymore. Should a crashed ospfd leave some routes behind the
> next ospfd does not clean them up anymore. The admin would need to check
> the logs and remove them manually with the route command.
> 
> Does this make sense?
> 

Manually removing routes does not :)



Re: bgpd, log updates and invalid path

2018-08-29 Thread Denis Fondras
On Wed, Aug 29, 2018 at 11:49:16AM +0200, Claudio Jeker wrote:
> Currently if a path is rejected because of parse errors there is only
> a generic error message logged but it is not clear which prefix caused it.
> Lets make this at least more obvious when 'log updates' is used.
> 
> OK?

OK denis@


> -- 
> :wq Claudio
> 
> Index: rde.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.414
> diff -u -p -r1.414 rde.c
> --- rde.c 9 Aug 2018 12:54:06 -   1.414
> +++ rde.c 29 Aug 2018 09:19:05 -
> @@ -1310,6 +1310,7 @@ rde_update_update(struct rde_peer *peer,
>   struct prefix   *p;
>   enum filter_actions  action;
>   u_int16_ti;
> + const char  *wmsg = "filtered, withdraw";
>  
>   peer->prefix_rcvd_update++;
>   /* add original path to the Adj-RIB-In */
> @@ -1324,6 +1325,9 @@ rde_update_update(struct rde_peer *peer,
>   return (-1);
>   }
>  
> + if (in->aspath.flags & F_ATTR_PARSE_ERR)
> + wmsg = "path invalid, withdraw";
> +
>   p = prefix_get([RIB_ADJ_IN].rib, peer, prefix, prefixlen, 0);
>   if (p == NULL)
>   fatalx("rde_update_update: no prefix in Adj-RIB-In");
> @@ -1344,7 +1348,7 @@ rde_update_update(struct rde_peer *peer,
>   prefixlen, 0);
>   } else if (prefix_remove([i].rib, peer, prefix, prefixlen,
>   0)) {
> - rde_update_log("filtered withdraw", i, peer,
> + rde_update_log(wmsg, i, peer,
>   NULL, prefix, prefixlen);
>   }
>  
> 



Re: bgpd: allow dumping of invalid paths via control socket

2018-08-29 Thread Denis Fondras
On Wed, Aug 29, 2018 at 01:07:33PM +0200, Claudio Jeker wrote:
> This is the bgpd diff that allows bgpctl to show invalid / error paths
> which act as an implicit withdraw.
> 
> While there also fix 'bgpctl show rib in nei foo' since until now that
> code actually printed the same as 'bgpctl show rib nei foo'.
> 
> The code is a bit shuffled to make the if statement in rde_dump_filter()
> simpler.
> 
> OK?

OK denis@


> -- 
> :wq Claudio
> 
> ? obj
> Index: bgpd.h
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> retrieving revision 1.330
> diff -u -p -r1.330 bgpd.h
> --- bgpd.h9 Aug 2018 21:12:33 -   1.330
> +++ bgpd.h29 Aug 2018 11:03:57 -
> @@ -87,6 +87,7 @@
>  #define  F_CTL_ACTIVE0x8000
>  #define  F_RTLABEL   0x1
>  #define  F_CTL_SSV   0x2 /* only used by bgpctl */
> +#define  F_CTL_INVALID   0x4 /* only used by bgpctl */
>  
>  /*
>   * Limit the number of messages queued in the session engine.
> @@ -612,6 +613,7 @@ struct ctl_neighbor {
>  #define  F_PREF_INTERNAL 0x04
>  #define  F_PREF_ANNOUNCE 0x08
>  #define  F_PREF_STALE0x10
> +#define  F_PREF_INVALID  0x20
>  
>  struct ctl_show_rib {
>   struct bgpd_addrtrue_nexthop;
> @@ -712,8 +714,8 @@ struct ctl_show_rib_request {
>   struct filter_extcommunity extcommunity;
>   struct filter_largecommunity large_community;
>   u_int32_t   peerid;
> + u_int32_t   flags;
>   pid_t   pid;
> - u_int16_t   flags;
>   enum imsg_type  type;
>   u_int8_tprefixlen;
>   u_int8_taid;
> Index: rde.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.414
> diff -u -p -r1.414 rde.c
> --- rde.c 9 Aug 2018 12:54:06 -   1.414
> +++ rde.c 29 Aug 2018 11:03:57 -
> @@ -2081,6 +2081,8 @@ rde_dump_rib_as(struct prefix *p, struct
>   rib.flags |= F_PREF_ELIGIBLE;
>   if (asp->flags & F_ATTR_LOOP)
>   rib.flags &= ~F_PREF_ELIGIBLE;
> + if (asp->flags & F_ATTR_PARSE_ERR)
> + rib.flags |= F_PREF_INVALID;
>   staletime = prefix_peer(p)->staletime[p->re->prefix->aid];
>   if (staletime && p->lastchange <= staletime)
>   rib.flags |= F_PREF_STALE;
> @@ -2142,11 +2144,24 @@ rde_dump_filter(struct prefix *p, struct
>   struct rde_peer *peer;
>   struct rde_aspath   *asp;
>  
> - if (req->flags & F_CTL_ADJ_IN ||
> - !(req->flags & (F_CTL_ADJ_IN|F_CTL_ADJ_OUT))) {
> + if (req->flags & F_CTL_ADJ_OUT) {
> + if (p->re->active != p)
> + /* only consider active prefix */
> + return;
> + if (req->peerid) {
> + if ((peer = peer_get(req->peerid)) != NULL)
> + rde_dump_filterout(peer, p, req);
> + return;
> + }
> + } else {
>   asp = prefix_aspath(p);
>   if (req->peerid && req->peerid != prefix_peer(p)->conf.id)
>   return;
> + if ((req->flags & F_CTL_ACTIVE) && p->re->active != p)
> + return;
> + if ((req->flags & F_CTL_INVALID) &&
> + (asp->flags & F_ATTR_PARSE_ERR) == 0)
> + return;
>   if (req->type == IMSG_CTL_SHOW_RIB_AS &&
>   !aspath_match(asp->aspath->data, asp->aspath->len,
>   >as, req->as.as))
> @@ -2162,18 +2177,7 @@ rde_dump_filter(struct prefix *p, struct
>   !community_large_match(asp, req->large_community.as,
>   req->large_community.ld1, req->large_community.ld2))
>   return;
> - if ((req->flags & F_CTL_ACTIVE) && p->re->active != p)
> - return;
>   rde_dump_rib_as(p, asp, req->pid, req->flags);
> - } else if (req->flags & F_CTL_ADJ_OUT) {
> - if (p->re->active != p)
> - /* only consider active prefix */
> - return;
> - if (req->peerid) {
> - if ((peer = peer_get(req->peerid)) != NULL)
> - rde_dump_filterout(peer, p, req);
> - return;
> - }
>   }
>  }
>  
> @@ -2223,7 +2227,9 @@ rde_dump_ctx_new(struct ctl_show_rib_req
>   sizeof(error));
>   return;
>   }
> - if ((rib = rib_find(req->rib)) == NULL) {
> + if (req->flags & (F_CTL_ADJ_IN | F_CTL_INVALID)) {
> + rib = [RIB_ADJ_IN].rib;
> + } else if ((rib = rib_find(req->rib)) == NULL) {
>   log_warnx("rde_dump_ctx_new: no such rib %s", req->rib);
>   error = CTL_RES_NOSUCHPEER;
> 

Re: bgpd: allow dumping of invalid paths via control socket

2018-08-29 Thread Denis Fondras
On Wed, Aug 29, 2018 at 01:10:41PM +0200, Claudio Jeker wrote:
> On Wed, Aug 29, 2018 at 01:07:33PM +0200, Claudio Jeker wrote:
> > This is the bgpd diff that allows bgpctl to show invalid / error paths
> > which act as an implicit withdraw.
> > 
> > While there also fix 'bgpctl show rib in nei foo' since until now that
> > code actually printed the same as 'bgpctl show rib nei foo'.
> > 
> > The code is a bit shuffled to make the if statement in rde_dump_filter()
> > simpler.
> > 
> 
> And here are the bgpctl bits for the same. With this you should be able to
> see invalid path with 'bgpctl show rib error'.
> Now I would have liked to use 'invalid' but the table driven parser does
> not allow that because it conflicts with 'in' (gnarf).
> Hope this is still OK.
> 

Perhaps we can do something like that. Calling something "invalid" everywhere in
the code but having to "error" on the CLI is not something I like. That being
said OK denis@ for your diff.

Index: parser.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
retrieving revision 1.82
diff -u -p -r1.82 parser.c
--- parser.c10 Jul 2018 13:03:06 -  1.82
+++ parser.c29 Aug 2018 16:24:15 -
@@ -179,6 +179,7 @@ static const struct token t_show_rib[] =
{ FLAG, "detail",   F_CTL_DETAIL,   t_show_rib},
{ FLAG, "ssv"   ,   F_CTL_SSV,  t_show_rib},
{ FLAG, "in",   F_CTL_ADJ_IN,   t_show_rib},
+   { FLAG, "invalid",  F_CTL_INVALID,  t_show_rib},
{ FLAG, "out",  F_CTL_ADJ_OUT,  t_show_rib},
{ KEYWORD,  "neighbor", NONE,   t_show_rib_neigh},
{ KEYWORD,  "table",NONE,   t_show_rib_rib},
@@ -556,6 +557,8 @@ match_token(int *argc, char **argv[], co
if (word != NULL && strncmp(word, table[i].keyword,
wordlen) == 0) {
match++;
+   if (match > 1)
+   match--;
t = [i];
res.flags |= t->value;
}


> This also removes a lie from the manual page. Softreconfig is on by
> default since a while.
> -- 
> :wq Claudio
> 
> Index: bgpctl.8
> ===
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.8,v
> retrieving revision 1.79
> diff -u -p -r1.79 bgpctl.8
> --- bgpctl.8  15 Oct 2017 20:44:21 -  1.79
> +++ bgpctl.8  29 Aug 2018 10:47:43 -
> @@ -363,6 +363,8 @@ are defined:
>  .It Cm best
>  Alias for
>  .Ic selected .
> +.It Cm error
> +Show only prefixes which are maked invalid and are treated as withdraw.
>  .It Cm selected
>  Show only selected routes.
>  .It Cm ssv
> @@ -376,9 +378,6 @@ Show more detailed output for matching r
>  Limit the output to the given address family.
>  .It Cm in
>  Show routes from the unfiltered Adj-RIB-In.
> -This is only possible if
> -.Em softreconfig in
> -is enabled for the neighbor.
>  The
>  .Cm neighbor
>  needs to be specified.
> Index: bgpctl.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
> retrieving revision 1.210
> diff -u -p -r1.210 bgpctl.c
> --- bgpctl.c  29 Jul 2018 13:02:01 -  1.210
> +++ bgpctl.c  29 Aug 2018 10:47:55 -
> @@ -1181,8 +1181,8 @@ show_interface_msg(struct imsg *imsg)
>  void
>  show_rib_summary_head(void)
>  {
> - printf("flags: * = Valid, > = Selected, I = via IBGP, A = Announced, "
> - "S = Stale\n");
> + printf("flags: * = Valid, > = Selected, I = via IBGP, A = Announced,\n"
> + "   S = Stale, E = Error\n");
>   printf("origin: i = IGP, e = EGP, ? = Incomplete\n\n");
>   printf("%-5s %-20s %-15s  %5s %5s %s\n", "flags", "destination",
>   "gateway", "lpref", "med", "aspath origin");
> @@ -1222,6 +1222,8 @@ print_flags(u_int8_t flags, int sum)
>   char*p = flagstr;
>  
>   if (sum) {
> + if (flags & F_PREF_INVALID)
> + *p++ = 'E';
>   if (flags & F_PREF_ANNOUNCE)
>   *p++ = 'A';
>   if (flags & F_PREF_INTERNAL)
> Index: parser.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
> retrieving revision 1.82
> diff -u -p -r1.82 parser.c
> --- parser.c  10 Jul 2018 13:03:06 -  1.82
> +++ parser.c  29 Aug 2018 10:51:33 -
> @@ -177,6 +177,7 @@ static const struct token t_show_rib[] =
>   { FLAG, "best", F_CTL_ACTIVE,   t_show_rib},
>   { FLAG, "selected", F_CTL_ACTIVE,   t_show_rib},
>   { FLAG, "detail",   F_CTL_DETAIL,   t_show_rib},
> + { FLAG, "error",F_CTL_INVALID,  t_show_rib},
>   { FLAG, "ssv"   ,   

bgpd, allow for bigger (prefixlist) macros

2018-09-04 Thread Denis Fondras
Hi,

While generating big prefixlists macros with bgpq3 (big like as2914:as-europe-v6
for example), OpenBGPd cannot load the config file (error "string too long").
This diff implements a dynamic buffer to overcome this limitation.

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.331
diff -u -p -r1.331 parse.y
--- parse.y 27 Aug 2018 19:32:37 -  1.331
+++ parse.y 4 Sep 2018 18:13:48 -
@@ -2746,13 +2746,22 @@ findeol(void)
return (ERROR);
 }
 
+#define READBUFFERSIZE 1024
+
 int
 yylex(void)
 {
-   u_char   buf[8096];
+   u_char  *buf = NULL;
u_char  *p, *val;
int  quotec, next, c;
int  token;
+   u_int32_t bufsize = READBUFFERSIZE;
+
+   buf = malloc(bufsize);
+   if (buf == NULL) {
+   yyerror("malloc failed");
+   return (findeol());
+   }
 
 top:
p = buf;
@@ -2765,12 +2774,19 @@ top:
; /* nothing */
if (c == '$' && !expanding) {
while (1) {
-   if ((c = lgetc(0)) == EOF)
+   if ((c = lgetc(0)) == EOF) {
+   free(buf);
return (0);
+   }
 
-   if (p + 1 >= buf + sizeof(buf) - 1) {
-   yyerror("string too long");
-   return (findeol());
+   if (p + 1 >= buf + bufsize - 1) {
+   bufsize += READBUFFERSIZE;
+   buf = realloc(buf, bufsize);
+   if (buf == NULL) {
+   yyerror("realloc failed");
+   return (findeol());
+   }
+   p = buf + bufsize - READBUFFERSIZE - 2;
}
if (isalnum(c) || c == '_') {
*p++ = c;
@@ -2783,6 +2799,7 @@ top:
val = symget(buf);
if (val == NULL) {
yyerror("macro '%s' not defined", buf);
+   free(buf);
return (findeol());
}
p = val + strlen(val) - 1;
@@ -2800,14 +2817,18 @@ top:
case '"':
quotec = c;
while (1) {
-   if ((c = lgetc(quotec)) == EOF)
+   if ((c = lgetc(quotec)) == EOF) {
+   free(buf);
return (0);
+   }
if (c == '\n') {
file->lineno++;
continue;
} else if (c == '\\') {
-   if ((next = lgetc(quotec)) == EOF)
+   if ((next = lgetc(quotec)) == EOF) {
+   free(buf);
return (0);
+   }
if (next == quotec || c == ' ' || c == '\t')
c = next;
else if (next == '\n') {
@@ -2820,36 +2841,52 @@ top:
break;
} else if (c == '\0') {
yyerror("syntax error");
+   free(buf);
return (findeol());
}
-   if (p + 1 >= buf + sizeof(buf) - 1) {
-   yyerror("string too long");
-   return (findeol());
+   if (p + 1 >= buf + bufsize - 1) {
+   bufsize += READBUFFERSIZE;
+   buf = realloc(buf, bufsize);
+   if (buf == NULL) {
+   yyerror("realloc failed");
+   return (findeol());
+   }
+   p = buf + bufsize - READBUFFERSIZE - 2;
}
*p++ = c;
}
yylval.v.string = strdup(buf);
-   if (yylval.v.string == NULL)
+   if (yylval.v.string == NULL) {
+   free(buf);
fatal("yylex: strdup");
+   }
return (STRING);
case '!':
next = lgetc(0);
-   if (next == '=')
+   if (next == '=') {
+   free(buf);
return (NE);
+   }
lungetc(next);
break;
case '<':
next = lgetc(0);
-   if (next == '=')
+   

Re: bgpd, streamline aspath matching

2018-09-04 Thread Denis Fondras
On Tue, Sep 04, 2018 at 01:56:12PM +0200, Claudio Jeker wrote:
> On Mon, Aug 27, 2018 at 12:11:43PM +0200, Claudio Jeker wrote:
> > This is in preparation for introducing as-sets (a fast lookup table for
> > when you want to make sure that your peering partner is realy only passing
> > you traffic he should).
> > 
> > To make as-set possible lets do some cleanup beforehands. This mainly
> > removes one element from the filter_as struct, uses as_min for unary
> > operations and changes the way we pass the and check the neighbor-as.
> > as_compare() and aspath_match() now take the neighbor-as as last argument
> > and will match against it if AS_FLAG_NEIGHBORAS is set. Simplifies the
> > rde_filter_match() a fair bit.
> > 
> > OK?
> 

OK denis@ if you patch bgpctl too.

> -- 
> :wq Claudio
>  
> 
> Index: bgpd.h
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> retrieving revision 1.330
> diff -u -p -r1.330 bgpd.h
> --- bgpd.h9 Aug 2018 21:12:33 -   1.330
> +++ bgpd.h27 Aug 2018 10:03:55 -
> @@ -647,7 +647,6 @@ enum aslen_spec {
>  };
>  
>  struct filter_as {
> - u_int32_t   as;
>   u_int16_t   flags;
>   enum as_spectype;
>   u_int8_top;
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
> retrieving revision 1.330
> diff -u -p -r1.330 parse.y
> --- parse.y   27 Aug 2018 09:49:00 -  1.330
> +++ parse.y   27 Aug 2018 10:03:56 -
> @@ -1902,7 +1902,7 @@ filter_as   : as4number_any {
>   if (($$ = calloc(1, sizeof(struct filter_as_l))) ==
>   NULL)
>   fatal(NULL);
> - $$->a.as = $1;
> + $$->a.as_min = $1;
>   $$->a.op = OP_EQ;
>   }
>   | NEIGHBORAS{
> @@ -1916,7 +1916,7 @@ filter_as   : as4number_any {
>   NULL)
>   fatal(NULL);
>   $$->a.op = $1;
> - $$->a.as = $2;
> + $$->a.as_min = $2;
>   }
>   | as4number_any binaryop as4number_any {
>   if (($$ = calloc(1, sizeof(struct filter_as_l))) ==
> Index: printconf.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
> retrieving revision 1.109
> diff -u -p -r1.109 printconf.c
> --- printconf.c   11 Jul 2018 14:08:46 -  1.109
> +++ printconf.c   27 Aug 2018 10:03:56 -
> @@ -619,10 +619,10 @@ void print_as(struct filter_rule *r)
>   printf("%s ", log_as(r->match.as.as_max));
>   break;
>   case OP_NE:
> - printf("!= %s ", log_as(r->match.as.as));
> + printf("!= %s ", log_as(r->match.as.as_min));
>   break;
>   default:
> - printf("%s ", log_as(r->match.as.as));
> + printf("%s ", log_as(r->match.as.as_min));
>   break;
>   }
>  }
> Index: rde.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.414
> diff -u -p -r1.414 rde.c
> --- rde.c 9 Aug 2018 12:54:06 -   1.414
> +++ rde.c 27 Aug 2018 10:03:57 -
> @@ -2149,7 +2149,7 @@ rde_dump_filter(struct prefix *p, struct
>   return;
>   if (req->type == IMSG_CTL_SHOW_RIB_AS &&
>   !aspath_match(asp->aspath->data, asp->aspath->len,
> - >as, req->as.as))
> + >as, 0))
>   return;
>   if (req->type == IMSG_CTL_SHOW_RIB_COMMUNITY &&
>   !community_match(asp, req->community.as,
> @@ -3769,5 +3769,4 @@ rde_mark_prefixsets_dirty(struct prefixs
>   }
>   }
>   }
> - return;
>  }
> Index: rde_filter.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
> retrieving revision 1.99
> diff -u -p -r1.99 rde_filter.c
> --- rde_filter.c  3 Aug 2018 16:31:22 -   1.99
> +++ rde_filter.c  27 Aug 2018 10:03:57 -
> @@ -340,7 +340,6 @@ int
>  rde_filter_match(struct filter_rule *f, struct rde_peer *peer,
>  struct filterstate *state, struct prefix *p)
>  {
> - u_int32_t   pas;
>   int cas, type;
>   int64_t las, ld1, ld2;
>   struct prefixset_item   *psi;
> @@ -349,20 +348,16 @@ rde_filter_match(struct filter_rule *f, 
>   if (state != NULL)
>   asp = >aspath;
>  
> - if (asp != NULL && f->match.as.type != AS_NONE) {
> - if (f->match.as.flags & AS_FLAG_NEIGHBORAS)
> - pas = peer->conf.remote_as;
> - else
> - pas = 

Re: bgpd diff

2018-09-04 Thread Denis Fondras
On Tue, Sep 04, 2018 at 12:56:52PM +0200, Claudio Jeker wrote:
> Yet another minor bgpd diff from a much bigger diff. This adds
> inet4applymask() similar to inet6applymask() and starts using it in a few
> places. This makes some of the INET vs INET6 cases more similar.
> 
> OK?

OK denis@

> -- 
> :wq Claudio
> 
> Index: bgpd.h
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> retrieving revision 1.331
> diff -u -p -r1.331 bgpd.h
> --- bgpd.h29 Aug 2018 19:47:47 -  1.331
> +++ bgpd.h3 Sep 2018 14:29:39 -
> @@ -1174,6 +1177,7 @@ int  nlri_get_vpn4(u_char *, u_int16_t,
>  int   prefix_compare(const struct bgpd_addr *,
>   const struct bgpd_addr *, int);
>  in_addr_t prefixlen2mask(u_int8_t);
> +void  inet4applymask(struct in_addr *, const struct in_addr *, int);
>  void  inet6applymask(struct in6_addr *, const struct in6_addr *,
>   int);
>  const char   *aid2str(u_int8_t);
> Index: rde_prefix.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde_prefix.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 rde_prefix.c
> --- rde_prefix.c  24 Jan 2017 04:22:42 -  1.33
> +++ rde_prefix.c  4 Sep 2018 10:15:42 -
> @@ -101,7 +101,6 @@ pt_fill(struct bgpd_addr *prefix, int pr
>   static struct pt_entry4 pte4;
>   static struct pt_entry6 pte6;
>   static struct pt_entry_vpn4 pte_vpn4;
> - in_addr_t   addr_hbo;
>  
>   switch (prefix->aid) {
>   case AID_INET:
> @@ -109,9 +108,7 @@ pt_fill(struct bgpd_addr *prefix, int pr
>   pte4.aid = prefix->aid;
>   if (prefixlen > 32)
>   fatalx("pt_fill: bad IPv4 prefixlen");
> - addr_hbo = ntohl(prefix->v4.s_addr);
> - pte4.prefix4.s_addr = htonl(addr_hbo &
> - prefixlen2mask(prefixlen));
> + inet4applymask(, >v4, prefixlen);
>   pte4.prefixlen = prefixlen;
>   return ((struct pt_entry *));
>   case AID_INET6:
> @@ -119,17 +116,16 @@ pt_fill(struct bgpd_addr *prefix, int pr
>   pte6.aid = prefix->aid;
>   if (prefixlen > 128)
>   fatalx("pt_get: bad IPv6 prefixlen");
> - pte6.prefixlen = prefixlen;
>   inet6applymask(, >v6, prefixlen);
> + pte6.prefixlen = prefixlen;
>   return ((struct pt_entry *));
>   case AID_VPN_IPv4:
>   bzero(_vpn4, sizeof(pte_vpn4));
>   pte_vpn4.aid = prefix->aid;
>   if (prefixlen > 32)
>   fatalx("pt_fill: bad IPv4 prefixlen");
> - addr_hbo = ntohl(prefix->vpn4.addr.s_addr);
> - pte_vpn4.prefix4.s_addr = htonl(addr_hbo &
> - prefixlen2mask(prefixlen));
> + inet4applymask(_vpn4.prefix4, >vpn4.addr,
> + prefixlen);
>   pte_vpn4.prefixlen = prefixlen;
>   pte_vpn4.rd = prefix->vpn4.rd;
>   pte_vpn4.labellen = prefix->vpn4.labellen;
> Index: session.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
> retrieving revision 1.365
> diff -u -p -r1.365 session.c
> --- session.c 11 Jul 2018 16:34:36 -  1.365
> +++ session.c 4 Sep 2018 10:07:34 -
> @@ -3150,19 +3150,20 @@ session_template_clone(struct peer *p, s
>  int
>  session_match_mask(struct peer *p, struct bgpd_addr *a)
>  {
> - in_addr_tv4mask;
> - struct in6_addr  masked;
> + struct in_addr   v4masked;
> + struct in6_addr  v6masked;
>  
>   switch (p->conf.remote_addr.aid) {
>   case AID_INET:
> - v4mask = htonl(prefixlen2mask(p->conf.remote_masklen));
> - if (p->conf.remote_addr.v4.s_addr == (a->v4.s_addr & v4mask))
> + inet4applymask(, >v4, p->conf.remote_masklen);
> + if (p->conf.remote_addr.v4.s_addr == v4masked.s_addr)
>   return (1);
>   return (0);
>   case AID_INET6:
> - inet6applymask(, >v6, p->conf.remote_masklen);
> + inet6applymask(, >v6, p->conf.remote_masklen);
>  
> - if (!memcmp(, >conf.remote_addr.v6, sizeof(masked)))
> + if (memcmp(, >conf.remote_addr.v6,
> + sizeof(v6masked)) == 0)
>   return (1);
>   return (0);
>   }
> Index: util.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/util.c,v
> retrieving revision 1.31
> diff -u -p -r1.31 util.c
> --- util.c29 Aug 2018 11:43:15 -  1.31
> +++ util.c30 Aug 2018 12:12:05 -
> @@ -732,6 +732,15 @@ prefixlen2mask(u_int8_t prefixlen)
>  }
>  
>  void
> +inet4applymask(struct in_addr *dest, const struct in_addr 

Re: Fix a kernelpanic when playing with rdomain(4) and enc(4)

2018-07-08 Thread Denis Fondras
OK denis@

On Sun, Jul 08, 2018 at 02:04:56PM +0200, Jeremie Courreges-Anglas wrote:
> On Sun, Jul 08 2018, Jeremie Courreges-Anglas  wrote:
> > On Sun, Jun 24 2018, Denis Fondras  wrote:
> >> When removing enc(4) interface from rdomain, the kernel panics randomly
> >> (memcpy() seems to copy outside of the mallocarray() boundaries) with 
> >> something
> >> like :
> >>
> >> Data modified on freelist: word -35183699295756 of object 
> >> 0x8059da80 size 0x8 previous type free (invalid addr 
> >> 0x7b44962aa448c22a)
> >> kernel: protection fault trap, code=0
> >> Stopped at  malloc+0x4d3:   movq0x8(%r14),%rbx
> >
> > [...]
> >
> >> Here is a fix :
> >>
> >> Index: if_enc.c
> >> ===
> >> RCS file: /cvs/src/sys/net/if_enc.c,v
> >> retrieving revision 1.70
> >> diff -u -p -r1.70 if_enc.c
> >> --- if_enc.c   16 Oct 2017 08:22:25 -  1.70
> >> +++ if_enc.c   24 Jun 2018 17:15:32 -
> >> @@ -271,7 +271,7 @@ enc_setif(struct ifnet *ifp, u_int id)
> >>if (id > RT_TABLEID_MAX)
> >>return (EINVAL);
> >>  
> >> -  if (id == 0 || id > enc_max_id) {
> >> +  if (enc_ifps == NULL || id > enc_max_id) {
> >>if ((new = mallocarray(id + 1, sizeof(struct ifnet *),
> >>M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
> >>return (ENOBUFS);
> >
> > This pattern is also used in enc_clone_create(), even if right now we
> > can't call this function twice for enc0 I think the code should be made
> > consistent.  ok?
> 
> Better send the correct diff, thanks Denis for the heads-up.
> 
> 
> Index: net/if_enc.c
> ===
> --- net/if_enc.c.orig
> +++ net/if_enc.c
> @@ -120,7 +120,7 @@ enc_clone_create(struct if_clone *ifc, i
>   return (error);
>   }
>  
> - if (unit == 0 || unit > enc_max_unit) {
> + if (enc_allifps == NULL || unit > enc_max_unit) {
>   if ((new = mallocarray(unit + 1, sizeof(struct ifnet *),
>   M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) {
>   NET_UNLOCK();
> 
> 
> -- 
> jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE
> 



Re: bgpd, don't allocate initial aspath for update parsing

2018-07-09 Thread Denis Fondras
On Mon, Jul 09, 2018 at 05:47:11PM +0200, Claudio Jeker wrote:
> Similar to the rde_filter code there is no need to path_get() the aspath
> used in rde_update_dispatch(). Also makes the code a bit easier since the
> cleanup can be done all the time.
> 

looks good, compiles fine, runs well, OK denis@

> Index: rde.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.386
> diff -u -p -r1.386 rde.c
> --- rde.c 9 Jul 2018 14:44:02 -   1.386
> +++ rde.c 9 Jul 2018 14:50:21 -
> @@ -938,10 +938,10 @@ rde_dispatch_imsg_parent(struct imsgbuf 
>  int
>  rde_update_dispatch(struct imsg *imsg)
>  {
> + struct rde_aspathasp;
>   struct bgpd_addr prefix;
>   struct mpattrmpa;
>   struct rde_peer *peer;
> - struct rde_aspath   *asp = NULL;
>   u_char  *p, *mpp = NULL;
>   int  error = -1, pos = 0;
>   u_int16_tafi, len, mplen;
> @@ -986,11 +986,11 @@ rde_update_dispatch(struct imsg *imsg)
>   imsg->hdr.len - IMSG_HEADER_SIZE - 4 - withdrawn_len - attrpath_len;
>   bzero(, sizeof(mpa));
>  
> + path_prep();
>   if (attrpath_len != 0) { /* 0 = no NLRI information in this message */
>   /* parse path attributes */
> - asp = path_get();
>   while (len > 0) {
> - if ((pos = rde_attr_parse(p, len, peer, asp,
> + if ((pos = rde_attr_parse(p, len, peer, ,
>   )) < 0)
>   goto done;
>   p += pos;
> @@ -998,19 +998,19 @@ rde_update_dispatch(struct imsg *imsg)
>   }
>  
>   /* check for missing but necessary attributes */
> - if ((subtype = rde_attr_missing(asp, peer->conf.ebgp,
> + if ((subtype = rde_attr_missing(, peer->conf.ebgp,
>   nlri_len))) {
>   rde_update_err(peer, ERR_UPDATE, ERR_UPD_MISSNG_WK_ATTR,
>   , sizeof(u_int8_t));
>   goto done;
>   }
>  
> - rde_as4byte_fixup(peer, asp);
> + rde_as4byte_fixup(peer, );
>  
>   /* enforce remote AS if requested */
> - if (asp->flags & F_ATTR_ASPATH &&
> + if (asp.flags & F_ATTR_ASPATH &&
>   peer->conf.enforce_as == ENFORCE_AS_ON) {
> - fas = aspath_neighbor(asp->aspath);
> + fas = aspath_neighbor(asp.aspath);
>   if (peer->conf.remote_as != fas) {
>   log_peer_warnx(>conf, "bad path, "
>   "starting with %s, "
> @@ -1021,7 +1021,7 @@ rde_update_dispatch(struct imsg *imsg)
>   }
>   }
>  
> - rde_reflector(peer, asp);
> + rde_reflector(peer, );
>   }
>  
>   p = imsg->data;
> @@ -1103,7 +1103,7 @@ rde_update_dispatch(struct imsg *imsg)
>   goto done;
>   }
>  
> - if ((asp->flags & ~F_ATTR_MP_UNREACH) == 0 && mplen == 0) {
> + if ((asp.flags & ~F_ATTR_MP_UNREACH) == 0 && mplen == 0) {
>   /* EoR marker */
>   peer_recv_eor(peer, aid);
>   }
> @@ -1166,7 +1166,7 @@ rde_update_dispatch(struct imsg *imsg)
>   break;
>   }
>  
> - if ((asp->flags & ~F_ATTR_MP_UNREACH) == 0) {
> + if ((asp.flags & ~F_ATTR_MP_UNREACH) == 0) {
>   error = 0;
>   goto done;
>   }
> @@ -1178,8 +1178,8 @@ rde_update_dispatch(struct imsg *imsg)
>   /* aspath needs to be loop free nota bene this is not a hard error */
>   if (peer->conf.ebgp &&
>   peer->conf.enforce_local_as == ENFORCE_AS_ON &&
> - !aspath_loopfree(asp->aspath, peer->conf.local_as))
> - asp->flags |= F_ATTR_LOOP;
> + !aspath_loopfree(asp.aspath, peer->conf.local_as))
> + asp.flags |= F_ATTR_LOOP;
>  
>   /* parse nlri prefix */
>   while (nlri_len > 0) {
> @@ -1208,7 +1208,7 @@ rde_update_dispatch(struct imsg *imsg)
>   goto done;
>   }
>  
> - if (rde_update_update(peer, asp, , prefixlen) == -1)
> + if (rde_update_update(peer, , , prefixlen) == -1)
>   goto done;
>  
>   }
> @@ -1244,11 +1244,11 @@ rde_update_dispatch(struct imsg *imsg)
>* this works because asp is not linked.
>* But first unlock the previously locked nexthop.
>*/
> - if (asp->nexthop) {
> - (void)nexthop_put(asp->nexthop);
> - asp->nexthop = NULL;
> + if (asp.nexthop) {
> + (void)nexthop_put(asp.nexthop);
> +

Re: bgpd: check max prefix just once

2018-07-09 Thread Denis Fondras
I am late for a comment because it has already been commited but...

> @@ -1373,6 +1339,14 @@ rde_update_update(struct rde_peer *peer,
>   if (path_update([RIB_ADJ_IN].rib, peer, asp, prefix, prefixlen, 0))
>   peer->prefix_cnt++;
>  
> + /* max prefix checker */
> + if (peer->conf.max_prefix && peer->prefix_cnt > peer->conf.max_prefix) {
> + log_peer_warnx(>conf, "prefix limit reached (>%u/%u)",

Is it useful to display peer->prefix_cnt here ? I think it will always be
peer->conf.max_prefix+1

> + peer->prefix_cnt, peer->conf.max_prefix);
> + rde_update_err(peer, ERR_CEASE, ERR_CEASE_MAX_PREFIX, NULL, 0);
> + return (-1);
> + }
> +
>   p = prefix_get([RIB_ADJ_IN].rib, peer, prefix, prefixlen, 0);
>   if (p == NULL)
>   fatalx("rde_update_update: no prefix in Adj-RIB-In");



Re: route: improve inet6_makenetandmask

2018-06-24 Thread Denis Fondras
On Sun, Jun 24, 2018 at 04:34:01PM +0200, Jeremie Courreges-Anglas wrote:
> 3. ... why should we stop assuming that the user really means to
>configure a route for a /64 if the host id part is all-zeroes?  Is
>this really part of what has been deprecated by RFC3587?
> 
> I can understand that having the same behavior (host address is no
> prefix length is specified) with v4 and v6 is desirable, but as benno
> pointed out, some people might be relying on the current default
> behavior.  That's not a strong objection, but I'd like to know what's
> the exact rationale behind this change.
> 
> An alternate way of fixing item 2 would be to keep the current behavior
> but extend it to any foo:bar:: address, not just to addresses within
> 2000::/3.
> 

With your diff you break the ULA address space where
  route add fc01:db8:: ::1
results in fc01:db8::/64 being inserted instead of the /128 :)


> 
> Index: route.c
> ===
> RCS file: /d/cvs/src/sbin/route/route.c,v
> retrieving revision 1.215
> diff -u -p -p -u -r1.215 route.c
> --- route.c   18 Jun 2018 09:17:06 -  1.215
> +++ route.c   24 Jun 2018 14:31:46 -
> @@ -792,7 +792,7 @@ inet_makenetandmask(u_int32_t net, struc
>  int
>  inet6_makenetandmask(struct sockaddr_in6 *sin6, char *plen)
>  {
> - struct in6_addr in6;
> + static const struct in6_addr zero_in6;
>   const char *errstr;
>   int i, len, q, r;
>  
> @@ -800,12 +800,9 @@ inet6_makenetandmask(struct sockaddr_in6
>   if (IN6_IS_ADDR_UNSPECIFIED(>sin6_addr) &&
>   sin6->sin6_scope_id == 0) {
>   plen = "0";
> - } else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) {
> - /* aggregatable global unicast - RFC2374 */
> - memset(, 0, sizeof(in6));
> - if (!memcmp(>sin6_addr.s6_addr[8],
> - _addr[8], 8))
> - plen = "64";
> + } else if (!memcmp(>sin6_addr.s6_addr[8],
> + _in6.s6_addr[8], 8)) {
> + plen = "64";
>   }
>   }
>  
> 
> -- 
> jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE
> 



sync ldapd host*() functions with ntpd

2018-10-22 Thread Denis Fondras
Make host_*() AF-agnostic like in ntpd/pfctl/relayd

host_dns() stays unchanged because of port setting. Perhaps we could handle it
like in relayd ? (additional function to set port with sockaddr_storage :
relay_socket_af())

Also fix lines longer than 80 chars.

Regress passes, tested with this :

listen on lo0 port 61636
listen on 192.168.70.10 port 6136
listen on 2001:db8:1::10 port 61639 secure
listen on "/tmp/ldapi"

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/ldapd/parse.y,v
retrieving revision 1.33
diff -u -p -r1.33 parse.y
--- parse.y 7 Sep 2018 07:35:31 -   1.33
+++ parse.y 22 Oct 2018 09:27:27 -
@@ -75,8 +75,7 @@ void   lungetc(int);
 int findeol(void);
 
 struct listener *host_unix(const char *path);
-struct listener*host_v4(const char *, in_port_t);
-struct listener*host_v6(const char *, in_port_t);
+struct listener*host_ip(const char *);
 int host_dns(const char *, const char *,
struct listenerlist *, int, in_port_t, u_int8_t);
 int host(const char *, const char *,
@@ -960,46 +959,24 @@ host_unix(const char *path)
 }
 
 struct listener *
-host_v4(const char *s, in_port_t port)
+host_ip(const char *s)
 {
-   struct in_addr   ina;
-   struct sockaddr_in  *sain;
-   struct listener *h;
-
-   memset(, 0, sizeof(ina));
-   if (inet_pton(AF_INET, s, ) != 1)
-   return (NULL);
-
-   if ((h = calloc(1, sizeof(*h))) == NULL)
-   fatal(NULL);
-   sain = (struct sockaddr_in *)>ss;
-   sain->sin_len = sizeof(struct sockaddr_in);
-   sain->sin_family = AF_INET;
-   sain->sin_addr.s_addr = ina.s_addr;
-   sain->sin_port = port;
-
-   return (h);
-}
-
-struct listener *
-host_v6(const char *s, in_port_t port)
-{
-   struct in6_addr  ina6;
-   struct sockaddr_in6 *sin6;
-   struct listener *h;
-
-   memset(, 0, sizeof(ina6));
-   if (inet_pton(AF_INET6, s, ) != 1)
-   return (NULL);
-
-   if ((h = calloc(1, sizeof(*h))) == NULL)
-   fatal(NULL);
-   sin6 = (struct sockaddr_in6 *)>ss;
-   sin6->sin6_len = sizeof(struct sockaddr_in6);
-   sin6->sin6_family = AF_INET6;
-   sin6->sin6_port = port;
-   memcpy(>sin6_addr, , sizeof(ina6));
+   struct addrinfo  hints, *res;
+   struct listener *h = NULL;
 
+   memset(, 0, sizeof(hints));
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+   hints.ai_flags = AI_NUMERICHOST;
+   if (getaddrinfo(s, "0", , ) == 0) {
+   if (res->ai_family == AF_INET ||
+   res->ai_family == AF_INET6) {
+   if ((h = calloc(1, sizeof(*h))) == NULL)
+   fatal(NULL);
+   memcpy(>ss, res->ai_addr, res->ai_addrlen);
+   }
+   freeaddrinfo(res);
+   }
return (h);
 }
 
@@ -1014,7 +991,7 @@ host_dns(const char *s, const char *cert
struct listener *h;
 
memset(, 0, sizeof(hints));
-   hints.ai_family = PF_UNSPEC;
+   hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
error = getaddrinfo(s, NULL, , );
if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
@@ -1038,7 +1015,8 @@ host_dns(const char *s, const char *cert
h->ssl = NULL;
h->ssl_cert_name[0] = '\0';
if (cert != NULL)
-   (void)strlcpy(h->ssl_cert_name, cert, 
sizeof(h->ssl_cert_name));
+   (void)strlcpy(h->ssl_cert_name, cert,
+   sizeof(h->ssl_cert_name));
 
if (res->ai_family == AF_INET) {
sain = (struct sockaddr_in *)>ss;
@@ -1069,32 +1047,36 @@ int
 host(const char *s, const char *cert, struct listenerlist *al,
 int max, in_port_t port, u_int8_t flags)
 {
-   struct listener *h;
-
-   /* Unix socket path? */
-   h = host_unix(s);
-
-   /* IPv4 address? */
-   if (h == NULL)
-   h = host_v4(s, port);
-
-   /* IPv6 address? */
-   if (h == NULL)
-   h = host_v6(s, port);
-
-   if (h != NULL) {
-   h->port = port;
-   h->flags |= flags;
-   h->ssl = NULL;
-   h->ssl_cert_name[0] = '\0';
-   if (cert != NULL)
-   strlcpy(h->ssl_cert_name, cert, 
sizeof(h->ssl_cert_name));
+   struct listener *h;
+   struct sockaddr_in  *sain;
+   struct sockaddr_in6 *sin6;
 
-   TAILQ_INSERT_HEAD(al, h, entry);
-   return (1);
-   }
+   if ((h = host_unix(s)) == NULL)
+   if ((h = host_ip(s)) == NULL)
+   return (host_dns(s, cert, al, max, port, 

Re: bgpd throttling for peers

2018-10-19 Thread Denis Fondras
On Fri, Oct 19, 2018 at 05:51:20PM +0200, Claudio Jeker wrote:
> On Wed, Oct 17, 2018 at 02:37:48PM +0200, Claudio Jeker wrote:
> > I noticed that the throttling for peers which was added some time ago is
> > incomplete. The following diff solved these issues.
> > 
> > In rde_update_queue_runner() only process peers which are currently not
> > throttled. Additionally only run the runners if not too many imsg are
> > pending in the RDE. Both these changes should help imporve responsiveness.
> > In the SE only set the throttled flag if the imsg sending was successful.
> > 
> > Does work fine on my systems with little or no effect on convergance time.
> > Please test on your systems and look for preformance changes.
> 
> Updated version after recent commit.
> 

OK denis@

> -- 
> :wq Claudio
> 
> Index: rde.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.437
> diff -u -p -r1.437 rde.c
> --- rde.c 18 Oct 2018 12:19:09 -  1.437
> +++ rde.c 19 Oct 2018 15:49:43 -
> @@ -334,15 +334,16 @@ rde_main(int debug, int verbose)
>   mctx = LIST_NEXT(mctx, entry);
>   }
>  
> - rde_update_queue_runner();
> - for (aid = AID_INET6; aid < AID_MAX; aid++)
> - rde_update6_queue_runner(aid);
> + if (ibuf_se && ibuf_se->w.queued < SESS_MSG_HIGH_MARK) {
> + rde_update_queue_runner();
> + for (aid = AID_INET6; aid < AID_MAX; aid++)
> + rde_update6_queue_runner(aid);
> + }
>   if (rde_dump_pending() &&
>   ibuf_se_ctl && ibuf_se_ctl->w.queued <= 10)
>   rde_dump_runner();
> - if (softreconfig) {
> + if (softreconfig)
>   rde_reload_runner();
> - }
>   }
>  
>   /* do not clean up on shutdown on production, it takes ages. */
> @@ -2664,6 +2665,8 @@ rde_update_queue_runner(void)
>   continue;
>   if (peer->state != PEER_UP)
>   continue;
> + if (peer->throttled)
> + continue;
>   eor = 0;
>   /* first withdraws */
>   wpos = 2; /* reserve space for the length field */
> @@ -2730,6 +2733,8 @@ rde_update6_queue_runner(u_int8_t aid)
>   continue;
>   if (peer->state != PEER_UP)
>   continue;
> + if (peer->throttled)
> + continue;
>   len = sizeof(queue_buf) - MSGSIZE_HEADER;
>   b = up_dump_mp_unreach(queue_buf, , peer, aid);
>  
> @@ -2753,6 +2758,8 @@ rde_update6_queue_runner(u_int8_t aid)
>   if (peer->conf.id == 0)
>   continue;
>   if (peer->state != PEER_UP)
> + continue;
> + if (peer->throttled)
>   continue;
>   len = sizeof(queue_buf) - MSGSIZE_HEADER;
>   r = up_dump_mp_reach(queue_buf, , peer, aid);
> Index: session.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
> retrieving revision 1.369
> diff -u -p -r1.369 session.c
> --- session.c 29 Sep 2018 07:58:06 -  1.369
> +++ session.c 17 Oct 2018 12:18:51 -
> @@ -1382,7 +1382,8 @@ session_sendmsg(struct bgp_msg *msg, str
>   if (!p->throttled && p->wbuf.queued > SESS_MSG_HIGH_MARK) {
>   if (imsg_rde(IMSG_XOFF, p->conf.id, NULL, 0) == -1)
>   log_peer_warn(>conf, "imsg_compose XOFF");
> - p->throttled = 1;
> + else
> + p->throttled = 1;
>   }
>  
>   free(msg);
> @@ -1773,7 +1774,8 @@ session_dispatch_msg(struct pollfd *pfd,
>   if (p->throttled && p->wbuf.queued < SESS_MSG_LOW_MARK) {
>   if (imsg_rde(IMSG_XON, p->conf.id, NULL, 0) == -1)
>   log_peer_warn(>conf, "imsg_compose XON");
> - p->throttled = 0;
> + else
> + p->throttled = 0;
>   }
>   if (!(pfd->revents & POLLIN))
>   return (1);
> 



Re: tcpdump: remove #ifdef INET6

2018-10-21 Thread Denis Fondras
On Sat, Sep 29, 2018 at 10:26:45PM +0200, Klemens Nanni wrote:
> The build is broken with `-U INET6' anyway and I see no reason to
> disable IPv6 support.
> 
> Removing these macro guards leaves NSD and Unbound as last remaining
> programs in base to have them.
> 
> This diff also fixes an empty redefine for IPPROTO_IPV6 in print-ip.c.
> 
> No object change on amd64 and sparc64 when built with clang.
> Using gcc results in changes on both platforms, but I'm still unsure how
> to handle this.  Testing gcc builds on my machines did not reveal any
> breakage or change in behaviour.
> 
> Feedback? Objections? OK?
> 

Tested on amd64 and octeon, no regress found.

OK denis@

> Index: Makefile
> ===
> RCS file: /cvs/src/usr.sbin/tcpdump/Makefile,v
> retrieving revision 1.63
> diff -u -p -r1.63 Makefile
> --- Makefile  3 Feb 2018 13:39:48 -   1.63
> +++ Makefile  29 Sep 2018 19:15:37 -
> @@ -28,7 +28,7 @@ CFLAGS+=-Wall -I${.CURDIR}/../../sbin/pf
>  # for pcap-int.h
>  CFLAGS+=-I${.CURDIR}/../../lib/libpcap
>  
> -CFLAGS+=-DCSLIP -DPPP -DHAVE_FDDI -DETHER_SERVICE -DHAVE_ETHER_NTOHOST 
> -DINET6
> +CFLAGS+=-DCSLIP -DPPP -DHAVE_FDDI -DETHER_SERVICE -DHAVE_ETHER_NTOHOST
>  
>  LDADD+=  -lpcap -ll -lcrypto
>  DPADD+=  ${LIBL} ${LIBPCAP} ${LIBCRYPTO}
> Index: addrtoname.c
> ===
> RCS file: /cvs/src/usr.sbin/tcpdump/addrtoname.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 addrtoname.c
> --- addrtoname.c  14 Dec 2016 19:12:16 -  1.37
> +++ addrtoname.c  29 Sep 2018 18:56:46 -
> @@ -34,10 +34,7 @@ struct rtentry;
>  
>  #include 
>  #include 
> -
> -#ifdef INET6
>  #include 
> -#endif
>  
>  #include 
>  
> @@ -78,7 +75,6 @@ struct hnamemem eprototable[HASHNAMESIZE
>  struct hnamemem dnaddrtable[HASHNAMESIZE];
>  struct hnamemem llcsaptable[HASHNAMESIZE];
>  
> -#ifdef INET6
>  struct h6namemem {
>   struct in6_addr addr;
>   char *name;
> @@ -86,7 +82,6 @@ struct h6namemem {
>  };
>  
>  struct h6namemem h6nametable[HASHNAMESIZE];
> -#endif /* INET6 */
>  
>  struct enamemem {
>   u_short e_addr0;
> @@ -234,7 +229,6 @@ getname(const u_char *ap)
>   return (p->name);
>  }
>  
> -#ifdef INET6
>  /*
>   * Return a name for the IP6 address pointed to by ap.  This address
>   * is assumed to be in network byte order.
> @@ -293,7 +287,6 @@ getname6(const u_char *ap)
>   p->name = savestr(cp);
>   return (p->name);
>  }
> -#endif /* INET6 */
>  
>  static char hex[] = "0123456789abcdef";
>  
> @@ -902,7 +895,6 @@ newhnamemem(void)
>   return (p);
>  }
>  
> -#ifdef INET6
>  /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
>  struct h6namemem *
>  newh6namemem(void)
> @@ -921,4 +913,3 @@ newh6namemem(void)
>   p = ptr++;
>   return (p);
>  }
> -#endif /* INET6 */
> Index: addrtoname.h
> ===
> RCS file: /cvs/src/usr.sbin/tcpdump/addrtoname.h,v
> retrieving revision 1.11
> diff -u -p -r1.11 addrtoname.h
> --- addrtoname.h  7 Oct 2007 16:41:05 -   1.11
> +++ addrtoname.h  29 Sep 2018 18:57:02 -
> @@ -39,18 +39,12 @@ extern char *tcpport_string(u_short);
>  extern char *udpport_string(u_short);
>  extern char *ipproto_string(u_int);
>  extern char *getname(const u_char *);
> -#ifdef INET6
>  extern char *getname6(const u_char *);
> -#endif
>  extern char *intoa(u_int32_t);
>  
>  extern void init_addrtoname(u_int32_t, u_int32_t);
>  extern struct hnamemem *newhnamemem(void);
> -#ifdef INET6
>  extern struct h6namemem *newh6namemem(void);
> -#endif
>  
>  #define ipaddr_string(p) getname((const u_char *)(p))
> -#ifdef INET6
>  #define ip6addr_string(p) getname6((const u_char *)(p))
> -#endif
> Index: interface.h
> ===
> RCS file: /cvs/src/usr.sbin/tcpdump/interface.h,v
> retrieving revision 1.78
> diff -u -p -r1.78 interface.h
> --- interface.h   6 Jul 2018 07:13:21 -   1.78
> +++ interface.h   29 Sep 2018 18:57:28 -
> @@ -287,7 +287,6 @@ extern void ofp_if_print(u_char *, const
>  extern void usbpcap_if_print(u_char *, const struct pcap_pkthdr *,
>  const u_char *);
>  
> -#ifdef INET6
>  extern void ip6_print(const u_char *, u_int);
>  extern void ip6_opt_print(const u_char *, int);
>  extern int hbhopt_print(const u_char *);
> @@ -298,7 +297,6 @@ extern void ripng_print(const u_char *, 
>  extern int rt6_print(const u_char *, const u_char *);
>  extern void ospf6_print(const u_char *, u_int);
>  extern void dhcp6_print(const u_char *, u_int, u_short, u_short);
> -#endif /*INET6*/
>  
>  extern uint32_t in_cksum_add(const void *, size_t, uint32_t);
>  extern uint16_t in_cksum_fini(uint32_t);
> Index: print-atm.c
> ===
> RCS file: /cvs/src/usr.sbin/tcpdump/print-atm.c,v

httpd: sync host*() with ntpd

2018-10-21 Thread Denis Fondras
(resend with more infos by request from kn@)

Sync changes to host_*() from ntpd to httpd.

The diff was tested on amd64 and octeon with :
- regress
- curl to fetch a webpage and "listen on :: port 34125"
- curl to fetch a webpage and "listen on 2001:db8::1 port 34126"
- curl to fetch a webpage and "listen on 192.168.70.1 port 34127"
- curl to fetch a webpage and "listen on 127.0.0.1 port 34128"
- upgrade of a bgplg server ("listen on cnmac0 port 80" with v6 and v4, my only
  production httpd)

All pass.


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.106
diff -u -p -r1.106 parse.y
--- parse.y 7 Sep 2018 07:35:30 -   1.106
+++ parse.y 21 Oct 2018 11:43:42 -
@@ -103,8 +103,7 @@ static struct server_config *srv_conf = 
 struct serverlist   servers;
 struct media_type   media;
 
-struct address *host_v4(const char *);
-struct address *host_v6(const char *);
+struct address *host_ip(const char *);
 int host_dns(const char *, struct addresslist *,
int, struct portrange *, const char *, int);
 int host_if(const char *, struct addresslist *,
@@ -1846,60 +1845,25 @@ symget(const char *nam)
 }
 
 struct address *
-host_v4(const char *s)
-{
-   struct in_addr   ina;
-   struct sockaddr_in  *sain;
-   struct address  *h;
-
-   memset(, 0, sizeof(ina));
-   if (inet_pton(AF_INET, s, ) != 1)
-   return (NULL);
-
-   if ((h = calloc(1, sizeof(*h))) == NULL)
-   fatal(__func__);
-   sain = (struct sockaddr_in *)>ss;
-   sain->sin_len = sizeof(struct sockaddr_in);
-   sain->sin_family = AF_INET;
-   sain->sin_addr.s_addr = ina.s_addr;
-   if (sain->sin_addr.s_addr == INADDR_ANY)
-   h->prefixlen = 0; /* 0.0.0.0 address */
-   else
-   h->prefixlen = -1; /* host address */
-   return (h);
-}
-
-struct address *
-host_v6(const char *s)
+host_ip(const char *s)
 {
struct addrinfo  hints, *res;
-   struct sockaddr_in6 *sa_in6;
struct address  *h = NULL;
 
memset(, 0, sizeof(hints));
-   hints.ai_family = AF_INET6;
-   hints.ai_socktype = SOCK_DGRAM; /* dummy */
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM; /*dummy*/
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(s, "0", , ) == 0) {
-   if ((h = calloc(1, sizeof(*h))) == NULL)
-   fatal(__func__);
-   sa_in6 = (struct sockaddr_in6 *)>ss;
-   sa_in6->sin6_len = sizeof(struct sockaddr_in6);
-   sa_in6->sin6_family = AF_INET6;
-   memcpy(_in6->sin6_addr,
-   &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
-   sizeof(sa_in6->sin6_addr));
-   sa_in6->sin6_scope_id =
-   ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
-   if (memcmp(_in6->sin6_addr, _any,
-   sizeof(sa_in6->sin6_addr)) == 0)
-   h->prefixlen = 0; /* any address */
-   else
-   h->prefixlen = -1; /* host address */
+   if (res->ai_family == AF_INET ||
+   res->ai_family == AF_INET6) {
+   if ((h = calloc(1, sizeof(*h))) == NULL)
+   fatal(NULL);
+   memcpy(>ss, res->ai_addr, res->ai_addrlen);
+   }
freeaddrinfo(res);
}
-
-   return (h);
+   return (h); 
 }
 
 int
@@ -1908,15 +1872,13 @@ host_dns(const char *s, struct addressli
 {
struct addrinfo  hints, *res0, *res;
int  error, cnt = 0;
-   struct sockaddr_in  *sain;
-   struct sockaddr_in6 *sin6;
struct address  *h;
 
if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)
return (cnt);
 
memset(, 0, sizeof(hints));
-   hints.ai_family = PF_UNSPEC;
+   hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
hints.ai_flags = AI_ADDRCONFIG;
error = getaddrinfo(s, NULL, , );
@@ -1951,17 +1913,7 @@ host_dns(const char *s, struct addressli
h->ss.ss_family = res->ai_family;
h->prefixlen = -1; /* host address */
 
-   if (res->ai_family == AF_INET) {
-   sain = (struct sockaddr_in *)>ss;
-   sain->sin_len = sizeof(struct sockaddr_in);
-   sain->sin_addr.s_addr = ((struct sockaddr_in *)
-   res->ai_addr)->sin_addr.s_addr;
-   } else {
-   sin6 = (struct sockaddr_in6 *)>ss;
-   sin6->sin6_len = sizeof(struct sockaddr_in6);
-   memcpy(>sin6_addr, &((struct 

httpd: sync host*() with ntpd

2018-10-21 Thread Denis Fondras
Sync changes to host_*() from ntpd to httpd.


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.106
diff -u -p -r1.106 parse.y
--- parse.y 7 Sep 2018 07:35:30 -   1.106
+++ parse.y 21 Oct 2018 11:43:42 -
@@ -103,8 +103,7 @@ static struct server_config *srv_conf = 
 struct serverlist   servers;
 struct media_type   media;
 
-struct address *host_v4(const char *);
-struct address *host_v6(const char *);
+struct address *host_ip(const char *);
 int host_dns(const char *, struct addresslist *,
int, struct portrange *, const char *, int);
 int host_if(const char *, struct addresslist *,
@@ -1846,60 +1845,25 @@ symget(const char *nam)
 }
 
 struct address *
-host_v4(const char *s)
-{
-   struct in_addr   ina;
-   struct sockaddr_in  *sain;
-   struct address  *h;
-
-   memset(, 0, sizeof(ina));
-   if (inet_pton(AF_INET, s, ) != 1)
-   return (NULL);
-
-   if ((h = calloc(1, sizeof(*h))) == NULL)
-   fatal(__func__);
-   sain = (struct sockaddr_in *)>ss;
-   sain->sin_len = sizeof(struct sockaddr_in);
-   sain->sin_family = AF_INET;
-   sain->sin_addr.s_addr = ina.s_addr;
-   if (sain->sin_addr.s_addr == INADDR_ANY)
-   h->prefixlen = 0; /* 0.0.0.0 address */
-   else
-   h->prefixlen = -1; /* host address */
-   return (h);
-}
-
-struct address *
-host_v6(const char *s)
+host_ip(const char *s)
 {
struct addrinfo  hints, *res;
-   struct sockaddr_in6 *sa_in6;
struct address  *h = NULL;
 
memset(, 0, sizeof(hints));
-   hints.ai_family = AF_INET6;
-   hints.ai_socktype = SOCK_DGRAM; /* dummy */
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM; /*dummy*/
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(s, "0", , ) == 0) {
-   if ((h = calloc(1, sizeof(*h))) == NULL)
-   fatal(__func__);
-   sa_in6 = (struct sockaddr_in6 *)>ss;
-   sa_in6->sin6_len = sizeof(struct sockaddr_in6);
-   sa_in6->sin6_family = AF_INET6;
-   memcpy(_in6->sin6_addr,
-   &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
-   sizeof(sa_in6->sin6_addr));
-   sa_in6->sin6_scope_id =
-   ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
-   if (memcmp(_in6->sin6_addr, _any,
-   sizeof(sa_in6->sin6_addr)) == 0)
-   h->prefixlen = 0; /* any address */
-   else
-   h->prefixlen = -1; /* host address */
+   if (res->ai_family == AF_INET ||
+   res->ai_family == AF_INET6) {
+   if ((h = calloc(1, sizeof(*h))) == NULL)
+   fatal(NULL);
+   memcpy(>ss, res->ai_addr, res->ai_addrlen);
+   }
freeaddrinfo(res);
}
-
-   return (h);
+   return (h); 
 }
 
 int
@@ -1908,15 +1872,13 @@ host_dns(const char *s, struct addressli
 {
struct addrinfo  hints, *res0, *res;
int  error, cnt = 0;
-   struct sockaddr_in  *sain;
-   struct sockaddr_in6 *sin6;
struct address  *h;
 
if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)
return (cnt);
 
memset(, 0, sizeof(hints));
-   hints.ai_family = PF_UNSPEC;
+   hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
hints.ai_flags = AI_ADDRCONFIG;
error = getaddrinfo(s, NULL, , );
@@ -1951,17 +1913,7 @@ host_dns(const char *s, struct addressli
h->ss.ss_family = res->ai_family;
h->prefixlen = -1; /* host address */
 
-   if (res->ai_family == AF_INET) {
-   sain = (struct sockaddr_in *)>ss;
-   sain->sin_len = sizeof(struct sockaddr_in);
-   sain->sin_addr.s_addr = ((struct sockaddr_in *)
-   res->ai_addr)->sin_addr.s_addr;
-   } else {
-   sin6 = (struct sockaddr_in6 *)>ss;
-   sin6->sin6_len = sizeof(struct sockaddr_in6);
-   memcpy(>sin6_addr, &((struct sockaddr_in6 *)
-   res->ai_addr)->sin6_addr, sizeof(struct in6_addr));
-   }
+   memcpy(>ss, res->ai_addr, res->ai_addrlen);
 
TAILQ_INSERT_HEAD(al, h, entry);
cnt++;
@@ -2049,34 +2001,49 @@ int
 host(const char *s, struct addresslist *al, int max,
 struct portrange *port, const char *ifname, int ipproto)
 {
-   struct address *h;
+   struct address  *h;
+   struct 

bgplg: add missing commands

2018-10-24 Thread Denis Fondras
This diff adds 2 missing commands :
- show ip bgp ovs
- show ip bgp ext-community

Index: bgplg.h
===
RCS file: /cvs/src/usr.bin/bgplg/bgplg.h,v
retrieving revision 1.15
diff -u -p -r1.15 bgplg.h
--- bgplg.h 24 Oct 2018 09:02:48 -  1.15
+++ bgplg.h 24 Oct 2018 10:44:56 -
@@ -51,6 +51,10 @@ struct cmd {
{ BGPCTL, "show","ip", "bgp", "community", NULL } },\
{ "show ip bgp detail community", 1, 1, "community",\
{ BGPCTL, "show","ip", "bgp", "detail", "community", NULL } },\
+   { "show ip bgp ext-community", 2, 2, "ext-community",   \
+   { BGPCTL, "show","ip", "bgp", "ext-community", NULL } },\
+   { "show ip bgp detail ext-community", 2, 2, "ext-community",\
+   { BGPCTL, "show","ip", "bgp", "detail", "ext-community", NULL } },\
{ "show ip bgp large-community", 1, 1, "large-community",\
{ BGPCTL, "show","ip", "bgp", "large-community", NULL } },  \
{ "show ip bgp detail large-community", 1, 1, 
"large-community",\
@@ -63,6 +67,8 @@ struct cmd {
{ BGPCTL, "show","ip", "bgp", "in", "neighbor", NULL } },   \
{ "show ip bgp out", 1, 1, "neighbor",  \
{ BGPCTL, "show","ip", "bgp", "out", "neighbor", NULL } },  \
+   { "show ip bgp ovs", 1, 1, "state", \
+   { BGPCTL, "show","ip", "bgp", "ovs", NULL } },  \
{ "show ip bgp memory", 0, 0, NULL, \
{ BGPCTL, "show", "ip", "bgp", "memory", NULL } },  \
{ "show neighbor", 0, 1, NULL,  \



bgplg: allow neighbors with space in name

2018-10-24 Thread Denis Fondras
I have peers with description containing spaces but bgplg won't accept that by
default.

I'd like some comments on that diff.
It is OK for bgplgsh (show ip bgp in "Peer 1" feels OK) but not for bgplg as I
have to quote the peer description in the input box (feels rather unnatural).

Index: bgplg.c
===
RCS file: /cvs/src/usr.bin/bgplg/bgplg.c,v
retrieving revision 1.19
diff -u -p -r1.19 bgplg.c
--- bgplg.c 5 Mar 2018 10:53:37 -   1.19
+++ bgplg.c 24 Oct 2018 14:32:22 -
@@ -112,7 +112,7 @@ lg_getenv(const char *name, int *lenp)
*lenp = len;
 
 #define allowed_in_string(_x)   \
-   (isalnum((unsigned char)_x) || strchr("-_.:/= ", _x))
+   (isalnum((unsigned char)_x) || strchr("\"-_.:/= ", _x))
 
for (i = 0; i < len; i++) {
if (ptr[i] == '&')
@@ -155,13 +155,18 @@ lg_arg2argv(char *arg, int *argc)
 {
char **argv, *ptr = arg;
size_t len;
-   u_int i, c = 1;
+   u_int i, c = 1, instr = 0;
 
len = strlen(arg);
 
/* Count elements */
for (i = 0; i < len; i++) {
-   if (isspace((unsigned char)arg[i])) {
+   if (arg[i] == '\"') {
+   instr++;
+   memmove([i], [i+1], (len-i)*sizeof(char));
+   len--;
+   }
+   if (isspace((unsigned char)arg[i]) && !(instr%2)) {
/* filter out additional options */
if (arg[i + 1] == '-') {
printf("invalid input\n");
Index: bgplgsh.c
===
RCS file: /cvs/src/usr.bin/bgplg/bgplgsh.c,v
retrieving revision 1.8
diff -u -p -r1.8 bgplgsh.c
--- bgplgsh.c   9 Dec 2015 17:52:24 -   1.8
+++ bgplgsh.c   24 Oct 2018 14:32:22 -
@@ -79,7 +79,7 @@ lg_arg2argv(char *arg, int *argc)
 {
char **argv, *ptr = arg;
size_t len;
-   u_int i, c = 1;
+   u_int i, c = 1, instr = 0;
 
if (lg_checkarg(arg) != 0)
return (NULL);
@@ -88,7 +88,12 @@ lg_arg2argv(char *arg, int *argc)
 
/* Count elements */
for (i = 0; i < len; i++) {
-   if (isspace((unsigned char)arg[i])) {
+   if (arg[i] == '\"') {
+   instr++;
+   memmove([i], [i+1], (len-i)*sizeof(char));
+   len--;
+   }
+   if (isspace((unsigned char)arg[i]) && !(instr%2)) {
/* filter out additional options */
if (arg[i + 1] == '-') {
printf("invalid input\n");



Re: bgpd, Adj-RIB-Out support

2018-10-31 Thread Denis Fondras
On Wed, Oct 31, 2018 at 04:24:49PM +0100, Claudio Jeker wrote:
> This diff introduces a real Adj-RIB-Out. It is the minimal change to
> introduce the new RIB. This removes the update_rib introduced before 6.4
> lock because that is now replaced with a real RIB.
> The code used by bgpctl show rib is now a fair amount easier since now one
> RIB runner can be used for all cases.
> path_update() is now returning if a prefix was not modified which is
> needed in the update path to suppress unneeded updates.
> The softreconfig out case becomes simpler because there is no more the
> need to run with both filters and check results.
> Last the shutdown code of the RDE had to be adjusted a bit to still work
> with the Adj-RIB-Out.
> 
> This may cause memory consumption to go up but my testing has shown that
> the result is actually not significant. Needs the commits from earlier
> today to apply.

On my Route Server, it is quite a big change (in percentage).
* Before :
RDE memory statistics
 11561 IPv4 unicast network entries using 452K of memory
   131 IPv6 unicast network entries using 7.2K of memory
 23370 rib entries using 1.4M of memory
 23517 prefix entries using 1.8M of memory
  4894 BGP path attribute entries using 344K of memory
   and holding 23517 references
  1720 BGP AS-PATH attribute entries using 76.4K of memory
   and holding 4894 references
  1061 BGP attributes entries using 41.4K of memory
   and holding 10565 references
  1060 BGP attributes using 25.6K of memory
101809 as-set elements in 58041 tables using 2.1M of memory
114429 prefix-set elments using 4.7M of memory
RIB using 4.1M of memory
Sets using 6.9M of memory

RDE hash statistics
path hash: size 131072, 4894 entires
min 0 max 3 avg/std-dev = 0.037/0.000
aspath hash: size 131072, 1720 entires
min 0 max 2 avg/std-dev = 0.013/0.000
attr hash: size 16384, 1061 entires
min 0 max 2 avg/std-dev = 0.065/0.000

* After:
RDE memory statistics
 11560 IPv4 unicast network entries using 452K of memory
   145 IPv6 unicast network entries using 7.9K of memory
 34991 rib entries using 2.1M of memory
 69844 prefix entries using 5.3M of memory
  4929 BGP path attribute entries using 347K of memory
   and holding 69844 references
  1727 BGP AS-PATH attribute entries using 76.6K of memory
   and holding 4929 references
  1066 BGP attributes entries using 41.6K of memory
   and holding 10643 references
  1065 BGP attributes using 25.6K of memory
101809 as-set elements in 58041 tables using 2.1M of memory
114429 prefix-set elments using 4.7M of memory
RIB using 8.4M of memory
Sets using 6.9M of memory

RDE hash statistics
path hash: size 131072, 4929 entires
min 0 max 3 avg/std-dev = 0.038/0.000
aspath hash: size 131072, 1727 entires
min 0 max 2 avg/std-dev = 0.013/0.000
attr hash: size 16384, 1066 entires
min 0 max 2 avg/std-dev = 0.065/0.000

I need to test it on a router with a fullview.

Comments below.

> -- 
> :wq Claudio
> 
> Index: rde.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.444
> diff -u -p -r1.444 rde.c
> --- rde.c 31 Oct 2018 14:50:07 -  1.444
> +++ rde.c 31 Oct 2018 15:09:39 -
> @@ -1395,7 +1395,7 @@ rde_update_update(struct rde_peer *peer,
>  
>   /* add original path to the Adj-RIB-In */
>   if (path_update([RIB_ADJ_IN].rib, peer, in, prefix, prefixlen,
> - vstate))
> + vstate) == 1)
>   peer->prefix_cnt++;
>  
>   /* max prefix checker */
> @@ -2124,16 +2124,17 @@ rde_reflector(struct rde_peer *peer, str
>   * control specific functions
>   */
>  static void
> -rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp,
> -struct nexthop *nexthop, pid_t pid, int flags)
> +rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, pid_t pid, int 
> flags)
>  {
>   struct ctl_show_rib  rib;
>   struct ibuf *wbuf;
>   struct attr *a;
> + struct nexthop  *nexthop;
>   void*bp;
>   time_t   staletime;
>   u_int8_t l;
>  
> + nexthop = prefix_nexthop(p);
>   bzero(, sizeof(rib));
>   rib.lastchange = p->lastchange;
>   rib.local_pref = asp->lpref;
> @@ -2208,70 +2209,37 @@ rde_dump_rib_as(struct prefix *p, struct
>  }
>  
>  static void
> -rde_dump_filterout(struct rde_peer *peer, struct prefix *p,
> -struct ctl_show_rib_request *req)
> -{
> - struct filterstate   state;
> - enum filter_actions  a;
> -
> - if (up_test_update(peer, p) != 1)
> - return;
> -
> - rde_filterstate_prep(, prefix_aspath(p), prefix_nexthop(p),
> - prefix_nhflags(p));
> - a = 

Re: bgpd, Adj-RIB-Out support

2018-11-01 Thread Denis Fondras
On Wed, Oct 31, 2018 at 10:02:05PM -0400, David Higgs wrote:
> On Wed, Oct 31, 2018 at 6:58 PM Sebastian Benoit  wrote:
> 
> 
> 
> On a phone, saw some typos and such, sorry no diff.
> 
> [benoit@border2:~]$ cat before
> > RDE memory statistics
> > 715727 IPv4 unicast network entries using 27.3M of memory
> >  58953 IPv6 unicast network entries using 3.1M of memory
> >1549171 rib entries using 94.6M of memory
> >2897130 prefix entries using 265M of memory
> > 562423 BGP path attribute entries using 60.1M of memory
> > 149579 BGP AS-PATH attribute entries using 6.1M of memory,
> >and holding 562423 references
> >  37007 BGP attributes entries using 1.4M of memory
> >and holding 880668 references
> 
> 
> Inconsistent comma usage above
> 

This one was fixed in a recent commit. It seems benno@ has not updated bgpctl :)


> 
> >  37006 BGP attributes using 912K of memory
> >  61964 as-set elements in 58064 tables using 950K of memory
> > 103150 prefix-set elments using 4.3M of memory
> 
> 
> elments => elements
> 
> RIB using 459M of memory
> > Sets using 5.2M of memory
> >
> > RDE hash statistics
> > path hash: size 131072, 562423 entires
> > min 0 max 20 avg/std-dev = 4.291/2.364
> > aspath hash: size 131072, 149579 entires
> > min 0 max 8 avg/std-dev = 1.141/0.835
> > attr hash: size 16384, 37007 entires
> > min 0 max 10 avg/std-dev = 2.259/1.378
> >
> 
> entires => entries
> 

Thanks for spotting.

> —david

Index: bgpctl.c
===
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.222
diff -u -p -r1.222 bgpctl.c
--- bgpctl.c31 Oct 2018 14:58:59 -  1.222
+++ bgpctl.c1 Nov 2018 08:17:21 -
@@ -1880,7 +1880,7 @@ show_rib_memory_msg(struct imsg *imsg)
printf("%10lld as-set elements in %lld tables using "
"%s of memory\n", stats.aset_nmemb, stats.aset_cnt,
fmt_mem(stats.aset_size));
-   printf("%10lld prefix-set elments using %s of memory\n",
+   printf("%10lld prefix-set elements using %s of memory\n",
stats.pset_cnt, fmt_mem(stats.pset_size));
printf("RIB using %s of memory\n", fmt_mem(pts +
stats.prefix_cnt * sizeof(struct prefix) +
@@ -1894,7 +1894,7 @@ show_rib_memory_msg(struct imsg *imsg)
break;
case IMSG_CTL_SHOW_RIB_HASH:
memcpy(, imsg->data, sizeof(hash));
-   printf("\t%s: size %lld, %lld entires\n", hash.name, hash.num,
+   printf("\t%s: size %lld, %lld entries\n", hash.name, hash.num,
hash.sum);
avg = (double)hash.sum / (double)hash.num;
dev = sqrt(fmax(0, hash.sumq / hash.num - avg * avg));



Re: bgpd, remove some no longer needed linked lists

2018-10-31 Thread Denis Fondras
On Mon, Oct 29, 2018 at 11:08:12AM +0100, Claudio Jeker wrote:
> On Mon, Oct 29, 2018 at 10:58:36AM +0100, Claudio Jeker wrote:
> > With the last commit the rde_aspath no longer needs to have a list of
> > prefixes and also the peer no longer need to have a list of aspaths.
> > This diff removes both and replaces the list of prefixes with a refcount.
> > The big benefit of this is that struct rde_aspath can now be shared
> > between sessions and ribs. This is an important set for Adj-RIB-Out
> > support.
> > 
> 
> And here is the bgpctl diff to print out the number of references hold on
> the rde_aspath structs.
> 

OK denis@

> -- 
> :wq Claudio
> 
> Index: bgpctl.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
> retrieving revision 1.220
> diff -u -p -r1.220 bgpctl.c
> --- bgpctl.c  26 Oct 2018 16:54:53 -  1.220
> +++ bgpctl.c  29 Oct 2018 09:43:34 -
> @@ -1864,6 +1864,8 @@ show_rib_memory_msg(struct imsg *imsg)
>   printf("%10lld BGP path attribute entries using %s of memory\n",
>   (long long)stats.path_cnt, fmt_mem(stats.path_cnt *
>   sizeof(struct rde_aspath)));
> + printf("\t   and holding %lld references\n",
> + (long long)stats.path_refs);
>   printf("%10lld BGP AS-PATH attribute entries using "
>   "%s of memory,\n\t   and holding %lld references\n",
>   (long long)stats.aspath_cnt, fmt_mem(stats.aspath_size),
> 



Re: bgpd, use correct size for ASPATH_HEADER_SIZE

2018-10-25 Thread Denis Fondras
On Thu, Oct 25, 2018 at 10:57:58AM +0200, Claudio Jeker wrote:
> Currently struct aspath is defined with a placeholder for the dynamic data
> part.
> struct aspath {
> LIST_ENTRY(aspath)  entry;
> int refcnt; /* reference count */
> u_int16_t   len;/* total length of aspath in octets */
> u_int16_t   ascnt;  /* number of AS hops in data */
> u_char  data[1]; /* placeholder for actual data */
> };
> 
> The size of the struct - this placeholder was calculated as
> ASPATH_HEADER_SIZE using (sizeof(struct aspath) - sizeof(u_char)).
> Now that does not consider any padding bytes added. Instead this should
> use offsetof(struct aspath, data) so that the malloc does not allocate too
> much memory.
> 

OK denis@

> -- 
> :wq Claudio
> 
> Index: rde.h
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
> retrieving revision 1.198
> diff -u -p -r1.198 rde.h
> --- rde.h 24 Oct 2018 08:26:37 -  1.198
> +++ rde.h 25 Oct 2018 08:48:38 -
> @@ -23,6 +23,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "bgpd.h"
>  #include "log.h"
> @@ -125,7 +126,7 @@ struct rde_peer {
>  #define AS_SEQUENCE  2
>  #define AS_CONFED_SEQUENCE   3
>  #define AS_CONFED_SET4
> -#define ASPATH_HEADER_SIZE   (sizeof(struct aspath) - sizeof(u_char))
> +#define ASPATH_HEADER_SIZE   (offsetof(struct aspath, data))
>  
>  struct aspath {
>   LIST_ENTRY(aspath)  entry;
> 



Re: bgplg: allow neighbors with space in name

2018-10-25 Thread Denis Fondras
On Thu, Oct 25, 2018 at 02:04:10PM +0100, Stuart Henderson wrote:
> On 2018/10/24 17:38, Denis Fondras wrote:
> > I have peers with description containing spaces but bgplg won't accept that 
> > by
> > default.
> > 
> > I'd like some comments on that diff.
> > It is OK for bgplgsh (show ip bgp in "Peer 1" feels OK) but not for bgplg 
> > as I
> > have to quote the peer description in the input box (feels rather 
> > unnatural).
> 
> it feels like allowing " in allowed characters for the CGI is starting
> to open a can of worms..
> 
> personally I think I'd change the descriptions to avoid spaces.
> 

Thanks to everyone who respond.
Dropping the idea and changing my peer description :)



bgplg: fix crash (error 500)

2018-10-25 Thread Denis Fondras
Just make sure arg is not NULL in lg_getarg() before accessing. It happens when
input contains an invalid character.

Unrelated but while at it, abort earlier in lg_arg2argv() if there is no
argument available.

Index: bgplg.c
===
RCS file: /cvs/src/usr.bin/bgplg/bgplg.c,v
retrieving revision 1.19
diff -u -p -r1.19 bgplg.c
--- bgplg.c 5 Mar 2018 10:53:37 -   1.19
+++ bgplg.c 25 Oct 2018 18:18:55 -
@@ -134,6 +134,9 @@ lg_getarg(const char *name, char *arg, i
size_t namelen, ptrlen;
int i;
 
+   if (arg == NULL)
+   return (NULL);
+
namelen = strlen(name);
 
for (i = 0; i < len; i++) {
@@ -171,6 +174,9 @@ lg_arg2argv(char *arg, int *argc)
c++;
}
}
+
+   if (arg[0] == '\0')
+   return (NULL);
 
/* Generate array */
if ((argv = calloc(c + 1, sizeof(char *))) == NULL) {



Re: bgpd: replace some more walkers with rib_dump

2018-10-25 Thread Denis Fondras
On Thu, Oct 25, 2018 at 08:51:30AM +0200, Claudio Jeker wrote:
> Next step on my quest to make the RIB code better.
> This changes the following things:
> - network_flush is now using rib_dump_new to walk the Adj-RIB-In and
>   remove all dynamically added announcements
> - peer_flush got generalized and is now used also in peer_down.
>   It also uses a rib_dump_new call to walk the Adj-RIB-In and remove
>   all prefixes from a peer but this is done synchronous for now.
> - peer_flush is now working correctly for AID_UNSPEC.
> - Change the rib_valid check to continue instead of break out of the loop.
>   The rib table can have holes so the loop needs to continue.
> 
> This removes the last three places that use the peer -> path -> prefix
> tailqs so the next step is to remove these and make rde_aspath just an
> object that is referenced by prefixes. After that adding a proper
> Adj-RIB-Out should be possible.
> 

Question below.
Running on prod too :)

> Index: rde_rib.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
> retrieving revision 1.180
> diff -u -p -r1.180 rde_rib.c
> --- rde_rib.c 24 Oct 2018 08:26:37 -  1.180
> +++ rde_rib.c 24 Oct 2018 08:44:54 -
> @@ -339,8 +339,8 @@ rib_restart(struct rib_context *ctx)
>  static void
>  rib_dump_r(struct rib_context *ctx)
>  {
> + struct rib_entry*re, *next;
>   struct rib  *rib;
> - struct rib_entry*re;
>   unsigned int i;
>  
>   rib = rib_byid(ctx->ctx_rib_id);
> @@ -352,7 +352,8 @@ rib_dump_r(struct rib_context *ctx)
>   else
>   re = rib_restart(ctx);
>  
> - for (i = 0; re != NULL; re = RB_NEXT(rib_tree, unused, re)) {
> + for (i = 0; re != NULL; re = next) {
> + next = RB_NEXT(rib_tree, unused, re);

Why not RB_FOREACH_SAFE ?

>   if (re->rib_id != ctx->ctx_rib_id)
>   fatalx("%s: Unexpected RIB %u != %u.", __func__,
>   re->rib_id, ctx->ctx_rib_id);
> @@ -435,6 +436,10 @@ rib_dump_new(u_int16_t id, u_int8_t aid,
>  
>   LIST_INSERT_HEAD(_dumps, ctx, entry);
>  
> + /* requested a sync traversal */
> + if (count == 0)
> + rib_dump_r(ctx);
> +
>   return 0;
>  }
>  
> @@ -664,65 +669,6 @@ path_lookup(struct rde_aspath *aspath, s
>   return (NULL);
>  }
>  
> -void
> -path_remove(struct rde_aspath *asp)
> -{
> - struct prefix   *p, *np;
> -
> - for (p = TAILQ_FIRST(>prefixes); p != NULL; p = np) {
> - np = TAILQ_NEXT(p, path_l);
> - if (asp->pftableid) {
> - struct bgpd_addr addr;
> -
> - pt_getaddr(p->re->prefix, );
> - /* Commit is done in peer_down() */
> - rde_send_pftable(prefix_aspath(p)->pftableid, ,
> - p->re->prefix->prefixlen, 1);
> - }
> - prefix_destroy(p);
> - }
> -}
> -
> -/* remove all stale routes or if staletime is 0 remove all routes for
> -   a specified AID. */
> -u_int32_t
> -path_remove_stale(struct rde_aspath *asp, u_int8_t aid, time_t staletime)
> -{
> - struct prefix   *p, *np;
> - u_int32_trprefixes;
> -
> - rprefixes=0;
> - /*
> -  * This is called when a session flapped and during that time
> -  * the pending updates for that peer are getting reset.
> -  */
> - for (p = TAILQ_FIRST(>prefixes); p != NULL; p = np) {
> - np = TAILQ_NEXT(p, path_l);
> - if (p->re->prefix->aid != aid)
> - continue;
> -
> - if (staletime && p->lastchange > staletime)
> - continue;
> -
> - if (asp->pftableid) {
> - struct bgpd_addr addr;
> -
> - pt_getaddr(p->re->prefix, );
> - /* Commit is done in peer_flush() */
> - rde_send_pftable(prefix_aspath(p)->pftableid, ,
> - p->re->prefix->prefixlen, 1);
> - }
> -
> - /* only count Adj-RIB-In */
> - if (re_rib(p->re) == [RIB_ADJ_IN].rib)
> - rprefixes++;
> -
> - prefix_destroy(p);
> - }
> - return (rprefixes);
> -}
> -
> -
>  /*
>   * This function can only called when all prefix have been removed first.
>   * Normally this happens directly out of the prefix removal functions.
> @@ -1144,29 +1090,6 @@ prefix_destroy(struct prefix *p)
>  
>   if (path_empty(asp))
>   path_destroy(asp);
> -}
> -
> -/*
> - * helper function to clean up the dynamically added networks
> - */
> -void
> -prefix_network_clean(struct rde_peer *peer)
> -{
> - struct rde_aspath   *asp, *xasp;
> - struct prefix   *p, *xp;
> -
> - for (asp = TAILQ_FIRST(>path_h); asp != NULL; asp = xasp) {
> - xasp = TAILQ_NEXT(asp, peer_l);
> - if ((asp->flags & 

bgplg: keep all args on submit

2018-10-27 Thread Denis Fondras
When submitting a command in bgplg(8), argument is not kept in its entirety
(split on space) which can be annoying ie. when querying extended community.

Fix this by printing request before splitting.

Index: bgplg.c
===
RCS file: /cvs/src/usr.bin/bgplg/bgplg.c,v
retrieving revision 1.19
diff -u -p -r1.19 bgplg.c
--- bgplg.c 5 Mar 2018 10:53:37 -   1.19
+++ bgplg.c 27 Oct 2018 15:52:34 -
@@ -245,7 +245,7 @@ lg_incl(const char *file)
 int
 main(void)
 {
-   char *query, *myname, *self, *cmd = NULL, *req;
+   char *query, *myname, *self, *cmd = NULL, *req = NULL;
char **argv = NULL;
int ret = 1, argc = 0, query_length = 0;
struct stat st;
@@ -282,8 +282,11 @@ main(void)
printf("fatal error: invalid request\n");
goto err;
}
-   if ((query = lg_getenv("QUERY_STRING", _length)) != NULL)
+   if ((query = lg_getenv("QUERY_STRING", _length)) != NULL) {
cmd = lg_getarg("cmd=", query, query_length);
+   req = lg_getarg("req=", query, query_length);
+   }
+   
printf(
"\n"
"\n"
@@ -302,11 +305,6 @@ main(void)
cmds[i].name, cmds[i].name);
}
 
-   if ((req = lg_getarg("req=", query, query_length)) != NULL) {
-   /* Could be NULL */
-   argv = lg_arg2argv(req, );
-   }
-
printf("\n"
"\n"
"\n"
@@ -343,6 +341,10 @@ main(void)
printf("invalid command: %s\n", cmd);
goto err;
}
+
+   if (req != NULL)
+   argv = lg_arg2argv(req, );
+
if (argc > cmdp->maxargs) {
printf("superfluous argument(s): %s %s\n",
cmd, cmdp->args ? cmdp->args : "");



Re: bgpd, Adj-RIB-Out support

2018-11-03 Thread Denis Fondras
On Wed, Oct 31, 2018 at 09:02:16PM +0100, Denis Fondras wrote:
> On Wed, Oct 31, 2018 at 04:24:49PM +0100, Claudio Jeker wrote:
> > This diff introduces a real Adj-RIB-Out. It is the minimal change to
> > introduce the new RIB. This removes the update_rib introduced before 6.4
> > lock because that is now replaced with a real RIB.
> > The code used by bgpctl show rib is now a fair amount easier since now one
> > RIB runner can be used for all cases.
> > path_update() is now returning if a prefix was not modified which is
> > needed in the update path to suppress unneeded updates.
> > The softreconfig out case becomes simpler because there is no more the
> > need to run with both filters and check results.
> > Last the shutdown code of the RDE had to be adjusted a bit to still work
> > with the Adj-RIB-Out.
> > 
> > This may cause memory consumption to go up but my testing has shown that
> > the result is actually not significant. Needs the commits from earlier
> > today to apply.
> 

[zip]

> I need to test it on a router with a fullview.
> 

OK denis@

> Comments below.
> 
> > -- 
> > :wq Claudio
> > 
> > Index: rde.c
> > ===
> > RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> > retrieving revision 1.444
> > diff -u -p -r1.444 rde.c
> > --- rde.c   31 Oct 2018 14:50:07 -  1.444
> > +++ rde.c   31 Oct 2018 15:09:39 -
> > @@ -1395,7 +1395,7 @@ rde_update_update(struct rde_peer *peer,
> >  
> > /* add original path to the Adj-RIB-In */
> > if (path_update([RIB_ADJ_IN].rib, peer, in, prefix, prefixlen,
> > -   vstate))
> > +   vstate) == 1)
> > peer->prefix_cnt++;
> >  
> > /* max prefix checker */
> > @@ -2124,16 +2124,17 @@ rde_reflector(struct rde_peer *peer, str
> >   * control specific functions
> >   */
> >  static void
> > -rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp,
> > -struct nexthop *nexthop, pid_t pid, int flags)
> > +rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, pid_t pid, int 
> > flags)
> >  {
> > struct ctl_show_rib  rib;
> > struct ibuf *wbuf;
> > struct attr *a;
> > +   struct nexthop  *nexthop;
> > void*bp;
> > time_t   staletime;
> > u_int8_t l;
> >  
> > +   nexthop = prefix_nexthop(p);
> > bzero(, sizeof(rib));
> > rib.lastchange = p->lastchange;
> > rib.local_pref = asp->lpref;
> > @@ -2208,70 +2209,37 @@ rde_dump_rib_as(struct prefix *p, struct
> >  }
> >  
> >  static void
> > -rde_dump_filterout(struct rde_peer *peer, struct prefix *p,
> > -struct ctl_show_rib_request *req)
> > -{
> > -   struct filterstate   state;
> > -   enum filter_actions  a;
> > -
> > -   if (up_test_update(peer, p) != 1)
> > -   return;
> > -
> > -   rde_filterstate_prep(, prefix_aspath(p), prefix_nexthop(p),
> > -   prefix_nhflags(p));
> > -   a = rde_filter(out_rules, peer, p, );
> > -
> > -   if (a == ACTION_ALLOW)
> > -   rde_dump_rib_as(p, , state.nexthop, req->pid,
> > -   req->flags);
> > -
> > -   rde_filterstate_clean();
> > -}
> > -
> > -static void
> >  rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req)
> >  {
> > -   struct rde_peer *peer;
> > struct rde_aspath   *asp;
> >  
> > -   if (req->flags & F_CTL_ADJ_OUT) {
> > -   if (p->re->active != p)
> > -   /* only consider active prefix */
> > -   return;
> > -   if (req->peerid) {
> > -   if ((peer = peer_get(req->peerid)) != NULL)
> > -   rde_dump_filterout(peer, p, req);
> > -   return;
> > -   }
> > -   } else {
> > -   asp = prefix_aspath(p);
> > -   if (req->peerid && req->peerid != prefix_peer(p)->conf.id)
> > -   return;
> > -   if ((req->flags & F_CTL_ACTIVE) && p->re->active != p)
> > -   return;
> > -   if ((req->flags & F_CTL_INVALID) &&
> > -   (asp->flags & F_ATTR_PARSE_ERR) == 0)
> > -   return;
> > -   if (req->type == IMSG_CTL_SHOW_RIB_AS &

bgplg: fix show ip bgp out/in

2018-10-24 Thread Denis Fondras
This may have been broken for quite some time...

Fix usage message for "show ip bgp in/out" and add missing "neighbor" argument.

Index: bgplg.h
===
RCS file: /cvs/src/usr.bin/bgplg/bgplg.h,v
retrieving revision 1.14
diff -u -p -r1.14 bgplg.h
--- bgplg.h 2 Feb 2018 13:46:17 -   1.14
+++ bgplg.h 24 Oct 2018 06:20:37 -
@@ -59,10 +59,10 @@ struct cmd {
{ BGPCTL, "show","ip", "bgp", "detail", NULL } },   \
{ "show ip bgp detail as", 1, 1, "asnum",   \
{ BGPCTL, "show","ip", "bgp", "detail", "as", NULL } }, \
-   { "show ip bgp in", 1, 1, "prefix", \
-   { BGPCTL, "show","ip", "bgp", "in", NULL } },   \
-   { "show ip bgp out", 1, 1, "prefix",\
-   { BGPCTL, "show","ip", "bgp", "out", NULL } },  \
+   { "show ip bgp in", 1, 1, "neighbor",   \
+   { BGPCTL, "show","ip", "bgp", "in", "neighbor", NULL } },   \
+   { "show ip bgp out", 1, 1, "neighbor",  \
+   { BGPCTL, "show","ip", "bgp", "out", "neighbor", NULL } },  \
{ "show ip bgp memory", 0, 0, NULL, \
{ BGPCTL, "show", "ip", "bgp", "memory", NULL } },  \
{ "show neighbor", 0, 1, NULL,  \



  1   2   3   4   >