Re: Fwd: worm.c removing unused variables

2015-08-20 Thread Ted Unangst
Rafael Zalamena wrote:
> On Mon, Aug 17, 2015 at 01:00:26PM -0300, Vinicios Barros wrote:
> > Hello all,
> > 
> > I would like to suggest these changes to remove unused variables
> > and a respectively unnecessary call of the gettimeofday, also removes
> > a casting in the malloc, that seems to be unnecessary.
> > 
> 
> I improved your diff a little bit to clean up more things.
>  * Kill some unused includes;
>  * Call poll() with time parameter direcly instead of doing some
>mathematical operations;
>  * Kill commented fflush() code;
> 
> I'll leave the malloc() bit to another diff, since it might be better and
> safer to replace it with a calloc().
> 
> Btw your diff wouldn't apply because your mail client fucked the spaces up.
> 
> any oks?

ok



Re: Fwd: worm.c removing unused variables

2015-08-20 Thread Rafael Zalamena
On Mon, Aug 17, 2015 at 01:00:26PM -0300, Vinicios Barros wrote:
> Hello all,
> 
> I would like to suggest these changes to remove unused variables
> and a respectively unnecessary call of the gettimeofday, also removes
> a casting in the malloc, that seems to be unnecessary.
> 

I improved your diff a little bit to clean up more things.
 * Kill some unused includes;
 * Call poll() with time parameter direcly instead of doing some
   mathematical operations;
 * Kill commented fflush() code;

I'll leave the malloc() bit to another diff, since it might be better and
safer to replace it with a calloc().

Btw your diff wouldn't apply because your mail client fucked the spaces up.

any oks?

Index: worm.c
===
RCS file: /cvs/src/games/worm/worm.c,v
retrieving revision 1.28
diff -u -p -r1.28 worm.c
--- worm.c  9 Mar 2015 19:52:02 -   1.28
+++ worm.c  21 Aug 2015 02:08:18 -
@@ -34,14 +34,10 @@
  * UCSC
  */
 
-#include 
-#include 
 #include 
 #include 
 #include 
 #include 
-#include 
-#include 
 #include 
 #include 
 
@@ -88,8 +84,6 @@ int
 main(int argc, char **argv)
 {
int retval;
-   struct timeval t, tod;
-   struct timezone tz;
struct pollfd pfd[1];
const char *errstr;
 
@@ -158,14 +152,9 @@ main(int argc, char **argv)
}
else
{
-   /* fflush(stdout); */
-   /* Delay could be a command line option */
-   t.tv_sec = 1;
-   t.tv_usec = 0;
-   (void)gettimeofday(&tod, &tz);
pfd[0].fd = STDIN_FILENO;
pfd[0].events = POLLIN;
-   retval = poll(pfd, 1, t.tv_sec * 1000 + t.tv_usec / 
1000);
+   retval = poll(pfd, 1, 1000);
if (retval > 0)
process(getch());
else



Re: RTM_DELETE and route refcount

2015-08-20 Thread Martin Pieuchot
On 20/08/15(Thu) 18:20, Mike Belopuhov wrote:
> Makes you wonder why the heck it wasn't done in the first place,
> doesn't it?

If you look at the original CSRG source tree, you'll see how/why
this happened :)

When karels@ changed rtrequest() to turn it into a frontend for the
radix tree in r7.8 of net/route.c RTM_DELETE was not returning a rt.
At this point "rt_refcnt" was not that used. 

All this nightmare really started with the introduction of cloning
routes.  Until today you can see the mess in rtalloc(9) to increment
the cloned vs cloning route depending on what happened.  This was
r7.13 of net/route.c and in this commit a call to rtrequest(RTM_DELETE)
would first rtfree(9) the route given in argument *then* try to remove
it from the routing table.

Later in r7.23 rtrequest(RTM_DELETE) stopped to free the given route and
rtinit() (what's today rt_ifa_del(9)) started to rtfree(9) the route
itself always before removing it from the tree.

Obviously this couldn't work and in r7.29 sklower@ made rtrequest()
return the route in the RTM_DELETE case to be able to free it.  At this
point rt_refcnt was *not* incremented prior to rfree(9) a route.  Note
that  a valid route in the tree without external reference has a count
of 0.  So in order to actually free the route the following pattern has
been copy/pasted from rtrequest():

   if (rt->rt_refcnt <= 0)
rtfree(rt);

Finally in r7.31  this idiom has been changed to:

if (rt->rt_refcnt <= 0) {  
rt->rt_refcnt++;
rtfree(rt);
}

I guess as an "easy fix" because the panic() in rtfree(9) triggered when
rtalloc(9) returned a cloning route instead of a cloned one without
incrementing it's reference counter.

Then this pattern has been copy/pasted everywhere, like most of the good
and not so good stuff we find in this tree.

All of that happened between 1988 and 1992, because of a bug in the
reference count of RTF_CLONING routes, obviously we weren't their to
do peer review ;)

That's why I appreciate as much review as possible in this area, I'm
sure we will have (or already do) similar issues.



Re: v6 autoconf, where have my connected routes gone?

2015-08-20 Thread Sebastian Reitenbach

On 08/19/15 17:51, Martin Pieuchot wrote:

On 18/08/15(Tue) 23:22, Martin Pieuchot wrote:

On 18/08/15(Tue) 14:00, Stuart Henderson wrote:

On 2015/08/18 14:27, Martin Pieuchot wrote:

On 18/08/15(Tue) 13:05, Stuart Henderson wrote:

I'm trying to add v6 to my second ISP connection on pppoe1, unlike my
first ISP, this one requires autoconf and dhcpv6-pd to pick up addresses
and have them routed. (They are referring to TR-187,
https://www.broadband-forum.org/technical/download/TR-187.pdf -
the "residential gateway" requirements are in section 6.1)

I haven't got as far as looking at dhcpv6-pd because when I enable
autoconf, as soon as it picks up the address I lose connected routes
to my local /64 subnets:


Which prefixes (ndp -p) and default routers (ndp -r) do you have before
and after the interface picks up the address?


Before: no default routers showing with ndp -r.

$ ndp -p | paste - - - | sed 's/vltime=infinity, pltime=infinity, expire=Never, 
//'
[...]
2001:4b10:1002:cc01::/64 if=vlan2   flags=LO ref=1No advertising router
... After:

$ ndp -r
[...]
2001:4b10:1002:cc01::/64 if=vlan2   flags=LD ref=1No advertising router


See how all your prefix suddenly became detached "D"?  That's a
limitation of pfxlist_onlink_check() which does not make a difference
between prefixes added to the global prefix list via an advertisement
or via manual configuration.

I'll see if it's possible to split the prefix lists in such way that
the RS/RA code only mess with its own states.


Diff below is just slightly tested and depends on the diff to
"Kill IN6_IFF_NODAD" but it shows where I'd like to go.

The idea is to use the global prefix list only for AUTOCONF'd addresses.

Since this list is only checked in nd6_is_addr_neighbor() I added a new
case for non-AUTOCONF'd addresses.  With it you should not longer see
the prefix of your manually configured interfaces in the "ndp -p" output
but it's ok since they should always be in your routing table.


That problem sthen@ describes here, sounds very similar to my home situation.
My router has IPv6 /48 HE tunnel, and on the wired network, i have /64 subnet
where all hosts have statically configured IPv6 addresses, incl. default route.
The router is also WLAN AP, where it has rtadvd running on the WLAN if,
and announcing a different /64 subnet.

Notebooks and other gear, that might have WLAN and network interfaces, when
connected to the wired network, and autoconf on the WLAN interface kicked in,
the IPv6 connection to the local /64 network were gone.

With the patch below, together with the other patch you mention above,
my problem is gone, network works as I expect it.

cheers,
Sebastian




diff --git sys/netinet6/in6.c sys/netinet6/in6.c
index 2f5d5a6..e9101dc 100644
--- sys/netinet6/in6.c
+++ sys/netinet6/in6.c
@@ -462,7 +462,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, 
struct ifnet *ifp)

case SIOCAIFADDR_IN6:
{
-   struct nd_prefix *pr;
int plen, error = 0;

/* reject read-only flags */
@@ -509,40 +508,19 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, 
struct ifnet *ifp)
if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
nd6_dad_start(&ia6->ia_ifa);

-
plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr, NULL);
if (plen == 128) {
dohooks(ifp->if_addrhooks, 0);
break;  /* we don't need to install a host route. */
}

-   /*
-* then, make the prefix on-link on the interface.
-* XXX: we'd rather create the prefix before the address, but
-* we need at least one address to install the corresponding
-* interface route, so we configure the address first.
-*/
-   pr = nd6_prefix_add(ifp, &ifra->ifra_addr,
-   &ifra->ifra_prefixmask, &ifra->ifra_lifetime,
-   ((ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0));
-   if (pr == NULL) {
-   log(LOG_ERR, "cannot add prefix\n");
-   return (EINVAL); /* XXX panic here? */
-   }
-
-   /* relate the address to the prefix */
-   if (ia6->ia6_ndpr == NULL) {
-   ia6->ia6_ndpr = pr;
-   pr->ndpr_refcnt++;
+   error = rt_ifa_add(&ia6->ia_ifa,
+   RTF_UP|RTF_CLONING|RTF_CONNECTED, ia6->ia_ifa.ifa_addr);
+   if (error) {
+   in6_purgeaddr(&ia6->ia_ifa);
+   return (error);
}
-
s = splsoftnet();
-   /*
-* this might affect the status of autoconfigured addresses,
-* that is, this address might make other addresses detached.
-*/
-   pfxlist_onlink_check();
-
doho

Re: RTM_DELETE and route refcount

2015-08-20 Thread Mike Belopuhov
Makes you wonder why the heck it wasn't done in the first place, doesn't it?


Fix ndp -p unaligned access (kernel and userland)

2015-08-20 Thread Christian Weisgerber
Currently, ndp -p will trigger unaligned accesses in the kernel and
userland on architectures that require strict alignment for 64-bit
types (e.g. sparc64).

This is actually fallout from the time_t change.

The sysctl used to pass the prefix list uses a packed format:
  one struct in6_prefix, several struct sockaddr_in6,
  one struct in6_prefix, several struct sockaddr_in6,
  ...
This worked dandily when both structs had the same alignment
requirement (int32_t).  However, there's a time_t in in6_prefix
which pushed that struct's alignment to int64_t... boom!

The patches below are taken from NetBSD (Martin Husemann):
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netinet6/nd6.c.diff?r1=1.145&r2=1.146
http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.sbin/ndp/ndp.c.diff?r1=1.41&r2=1.42

Use simple byte pointer arithmetic and memcpy from/to aligned stack
variables to handle the "packed" binary format passed out to userland
when querying the prefix/router list.

OK?

Index: sys/netinet6/nd6.c
===
RCS file: /cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.143
diff -u -p -r1.143 nd6.c
--- sys/netinet6/nd6.c  16 Jul 2015 15:31:35 -  1.143
+++ sys/netinet6/nd6.c  20 Aug 2015 14:36:19 -
@@ -1877,45 +1877,43 @@ fill_prlist(void *oldp, size_t *oldlenp,
 {
int error = 0, s;
struct nd_prefix *pr;
-   struct in6_prefix *p = NULL;
-   struct in6_prefix *pe = NULL;
+   char *p = NULL, *ps = NULL;
+   char *pe = NULL;
size_t l;
 
s = splsoftnet();
 
if (oldp) {
-   p = (struct in6_prefix *)oldp;
-   pe = (struct in6_prefix *)((caddr_t)oldp + *oldlenp);
+   ps = p = (char *)oldp;
+   pe = (char *)oldp + *oldlenp;
}
l = 0;
 
LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
u_short advrtrs;
-   size_t advance;
-   struct sockaddr_in6 *sin6;
-   struct sockaddr_in6 *s6;
+   struct sockaddr_in6 sin6;
struct nd_pfxrouter *pfr;
+   struct in6_prefix pfx;
char addr[INET6_ADDRSTRLEN];
 
-   if (oldp && p + 1 <= pe)
-   {
-   bzero(p, sizeof(*p));
-   sin6 = (struct sockaddr_in6 *)(p + 1);
-
-   p->prefix = pr->ndpr_prefix;
-   if (in6_recoverscope(&p->prefix,
-   &p->prefix.sin6_addr, pr->ndpr_ifp) != 0)
+   if (oldp && p + sizeof(struct in6_prefix) <= pe) {
+   memset(&pfx, 0, sizeof(pfx));
+   ps = p;
+
+   pfx.prefix = pr->ndpr_prefix;
+   if (in6_recoverscope(&pfx.prefix,
+   &pfx.prefix.sin6_addr, pr->ndpr_ifp) != 0)
log(LOG_ERR,
"scope error in prefix list (%s)\n",
-   inet_ntop(AF_INET6, &p->prefix.sin6_addr,
+   inet_ntop(AF_INET6, &pfx.prefix.sin6_addr,
addr, sizeof(addr)));
-   p->raflags = pr->ndpr_raf;
-   p->prefixlen = pr->ndpr_plen;
-   p->vltime = pr->ndpr_vltime;
-   p->pltime = pr->ndpr_pltime;
-   p->if_index = pr->ndpr_ifp->if_index;
+   pfx.raflags = pr->ndpr_raf;
+   pfx.prefixlen = pr->ndpr_plen;
+   pfx.vltime = pr->ndpr_vltime;
+   pfx.pltime = pr->ndpr_pltime;
+   pfx.if_index = pr->ndpr_ifp->if_index;
if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME)
-   p->expire = 0;
+   pfx.expire = 0;
else {
time_t maxexpire;
 
@@ -1924,40 +1922,44 @@ fill_prlist(void *oldp, size_t *oldlenp,
((sizeof(maxexpire) * 8) - 1));
if (pr->ndpr_vltime <
maxexpire - pr->ndpr_lastupdate) {
-   p->expire = pr->ndpr_lastupdate +
+   pfx.expire = pr->ndpr_lastupdate +
pr->ndpr_vltime;
} else
-   p->expire = maxexpire;
+   pfx.expire = maxexpire;
}
-   p->refcnt = pr->ndpr_refcnt;
-   p->flags = pr->ndpr_stateflags;
-   p->origin = PR_ORIG_RA;
+   pfx.refcnt = pr->ndpr_refcnt;
+   pfx.flags = pr->ndpr_stateflags;
+   pfx.origin = PR_ORIG_RA

Re: libm: avoid left-shifting a negative integer

2015-08-20 Thread Mark Kettenis
> Date: Wed, 19 Aug 2015 21:25:35 +0200
> From: Christian Weisgerber 
> 
> I saw this drifting by on FreeBSD (from Dimitry Andric):
> 
>   In libm's exp2(3), avoid left-shifting a negative integer, which is
>   undefined.  Replace it with the intended value, in a defined way.
> 
> OK?  Don't bother?

ok kettenis@

> Index: src/s_exp2.c
> ===
> RCS file: /cvs/src/lib/libm/src/s_exp2.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 s_exp2.c
> --- src/s_exp2.c  3 Jul 2013 04:46:36 -   1.7
> +++ src/s_exp2.c  19 Aug 2015 19:10:38 -
> @@ -373,14 +373,14 @@ exp2(double x)
>   /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
>   t = tbl[i0];/* exp2t[i0] */
>   z -= tbl[i0 + 1];   /* eps[i0]   */
> - if (k >= -1021 << 20)
> + if (k >= -(1021 << 20))
>   INSERT_WORDS(twopk, 0x3ff0 + k, 0);
>   else
>   INSERT_WORDS(twopkp1000, 0x3ff0 + k + (1000 << 20), 0);
>   r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5;
>  
>   /* Scale by 2**(k>>20). */
> - if(k >= -1021 << 20) {
> + if(k >= -(1021 << 20)) {
>   if (k == 1024 << 20)
>   return (r * 2.0 * 0x1p1023);
>   return (r * twopk);
> -- 
> Christian "naddy" Weisgerber  na...@mips.inka.de
> 
> 



Re: ipip interrupt path and list iteration

2015-08-20 Thread Martin Pieuchot
On 19/08/15(Wed) 20:10, Alexander Bluhm wrote:
> On Wed, Aug 19, 2015 at 02:41:22PM +0200, Martin Pieuchot wrote:
> > > Diff below converts one of the few remaining iteration on the global
> > > list of interfaces (&ifnet).
> 
> >   /* Check for local address spoofing. */
> > - if (((ifp = if_get(m->m_pkthdr.ph_ifidx)) == NULL ||
> > - !(ifp->if_flags & IFF_LOOPBACK)) && ipip_allow != 2) {
> 
> If the packet was coming from a loopback interface it was always
> passed.  Your code always drops if it is coming from a local address.
> I think we need this check, see also the comment mentioning ph_ifidx
> above the function ipip_input().

Right, I'm still really interested in an explanation.  The comment you
mentioned talks about enc(4) which is not a IFF_LOOPBACK interface.  I
just hate these loopback hacks, we have so many of them always checking
for the IFF_LOOPBACK type and I'd rather see fewer if_get(9) usage in
the stack.

Anyway if somebody could comment on that;  I'm interested, but I left
it.

> > > + struct sockaddr_storage ss;
> > > + struct rtentry *rt;
> > > +
> > > + if (ipo) {
> > > + sin = (struct sockaddr_in *)&ss;
> > > + sin->sin_family = AF_INET;
> > > + sin->sin_len = sizeof(*sin);
> > > + sin->sin_addr = ipo->ip_src;
> > > +#ifdef INET6
> > > + } else if (ip6) {
> > > + sin6 = (struct sockaddr_in6 *)&ss;
> > > + sin6->sin6_family = AF_INET6;
> > > + sin6->sin6_len = sizeof(*sin6);
> > > + sin6->sin6_addr = ip6->ip6_src;
> > >  #endif /* INET6 */
> > > + }
> 
> Normaly you should memset(0) sin and sin6 because of the padding.
> At least in user land and with sobind() this is necessary.  Most
> of the kernel code does this.  But there are a few places where it
> is not done before rtalloc().  I think we should initialize it
> everywhere.  I can build a diff to make it consistent.

Thanks, here's an updated diff.

Index: netinet/ip_ipip.c
===
RCS file: /cvs/src/sys/netinet/ip_ipip.c,v
retrieving revision 1.64
diff -u -p -r1.64 ip_ipip.c
--- netinet/ip_ipip.c   14 Aug 2015 18:07:28 -  1.64
+++ netinet/ip_ipip.c   20 Aug 2015 11:42:26 -
@@ -146,10 +146,8 @@ ipip_input(struct mbuf *m, int iphlen, s
 {
struct sockaddr_in *sin;
struct ifnet *ifp;
-   struct ifaddr *ifa;
struct niqueue *ifq = NULL;
struct ip *ipo;
-   u_int rdomain;
 #ifdef INET6
struct sockaddr_in6 *sin6;
struct ip6_hdr *ip6;
@@ -297,43 +295,34 @@ ipip_input(struct mbuf *m, int iphlen, s
/* Check for local address spoofing. */
if (((ifp = if_get(m->m_pkthdr.ph_ifidx)) == NULL ||
!(ifp->if_flags & IFF_LOOPBACK)) && ipip_allow != 2) {
-   rdomain = rtable_l2(m->m_pkthdr.ph_rtableid);
-   TAILQ_FOREACH(ifp, &ifnet, if_list) {
-   if (ifp->if_rdomain != rdomain)
-   continue;
-   TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
-   if (ipo) {
-   if (ifa->ifa_addr->sa_family !=
-   AF_INET)
-   continue;
-
-   sin = satosin(ifa->ifa_addr); 
-   if (sin->sin_addr.s_addr ==
-   ipo->ip_src.s_addr) {
-   ipipstat.ipips_spoof++;
-   m_freem(m);
-   return;
-   }
-   }
-#ifdef INET6
-   if (ip6) {
-   if (ifa->ifa_addr->sa_family !=
-   AF_INET6)
-   continue;
-
-   sin6 = satosin6(ifa->ifa_addr);
-   if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
-   &ip6->ip6_src)) {
-   ipipstat.ipips_spoof++;
-   m_freem(m);
-   return;
-   }
+   struct sockaddr_storage ss;
+   struct rtentry *rt;
 
-   }
+   memset(&ss, 0, sizeof(ss));
+
+   if (ipo) {
+   sin = (struct sockaddr_in *)&ss;
+   sin->sin_family = AF_INET;
+   sin->sin_len = sizeof(*sin);
+   sin->sin_addr = ipo->ip_src;
+#ifdef INET6
+  

RTM_DELETE and route refcount

2015-08-20 Thread Martin Pieuchot
This is the next logical step after bluhm@'s retrequest1(9) unification.

The idea is to always return a route with an incremented reference count
when the ``rtp'' argument of rtrequest1(9) is non-NULL.  Apart from the
code simplification this will prevent ``rt'' to be freed by another CPU
between the return of rtrequest1(9) and the actual rtfree(9).

Ok?

Index: net/route.c
===
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.223
diff -u -p -r1.223 route.c
--- net/route.c 19 Aug 2015 13:27:38 -  1.223
+++ net/route.c 20 Aug 2015 11:25:54 -
@@ -570,12 +570,8 @@ rtdeletemsg(struct rtentry *rt, u_int ta
info.rti_flags = rt->rt_flags;
ifp = rt->rt_ifp;
error = rtrequest1(RTM_DELETE, &info, rt->rt_priority, &rt, tableid);
-
rt_missmsg(RTM_DELETE, &info, info.rti_flags, ifp, error, tableid);
-
-   /* Adjust the refcount */
-   if (error == 0 && rt->rt_refcnt <= 0) {
-   rt->rt_refcnt++;
+   if (error == 0) {
rtfree(rt);
}
return (error);
@@ -820,12 +816,11 @@ rtrequest1(int req, struct rt_addrinfo *
ifa->ifa_rtrequest(RTM_DELETE, rt);
rttrash++;
 
-   if (ret_nrt)
+   rt->rt_refcnt++;
+   if (ret_nrt != NULL)
*ret_nrt = rt;
-   else if (rt->rt_refcnt <= 0) {
-   rt->rt_refcnt++;
+   else
rtfree(rt);
-   }
break;
 
case RTM_RESOLVE:
@@ -1269,10 +1264,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags
rt_sendmsg(rt, RTM_DELETE, rtableid);
if (flags & RTF_LOCAL)
rt_sendaddrmsg(rt, RTM_DELADDR);
-   if (rt->rt_refcnt <= 0) {
-   rt->rt_refcnt++;
-   rtfree(rt);
-   }
+   rtfree(rt);
}
if (m != NULL)
m_free(m);
Index: net/rtsock.c
===
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.168
diff -u -p -r1.168 rtsock.c
--- net/rtsock.c19 Aug 2015 13:27:38 -  1.168
+++ net/rtsock.c20 Aug 2015 11:25:54 -
@@ -593,8 +593,7 @@ route_output(struct mbuf *m, ...)
error = EINVAL;
goto flush;
}
-   error = rtrequest1(rtm->rtm_type, &info, prio, &saved_nrt,
-   tableid);
+   error = rtrequest1(RTM_ADD, &info, prio, &saved_nrt, tableid);
if (error == 0) {
rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,
&saved_nrt->rt_rmx);
@@ -606,12 +605,9 @@ route_output(struct mbuf *m, ...)
}
break;
case RTM_DELETE:
-   error = rtrequest1(rtm->rtm_type, &info, prio, &saved_nrt,
-   tableid);
-   if (error == 0) {
-   (rt = saved_nrt)->rt_refcnt++;
+   error = rtrequest1(RTM_DELETE, &info, prio, &rt, tableid);
+   if (error == 0)
goto report;
-   }
break;
case RTM_GET:
case RTM_CHANGE:
Index: netinet6/nd6_rtr.c
===
RCS file: /cvs/src/sys/netinet6/nd6_rtr.c,v
retrieving revision 1.116
diff -u -p -r1.116 nd6_rtr.c
--- netinet6/nd6_rtr.c  19 Aug 2015 13:27:38 -  1.116
+++ netinet6/nd6_rtr.c  20 Aug 2015 11:25:54 -
@@ -732,14 +732,7 @@ defrouter_delreq(struct nd_defrouter *dr
dr->ifp->if_rdomain);
if (error == 0) {
rt_sendmsg(rt, RTM_DELETE, dr->ifp->if_rdomain);
-   if (rt->rt_refcnt <= 0) {
-   /*
-* XXX: borrowed from the RTM_DELETE case of
-* rtrequest1().
-*/
-   rt->rt_refcnt++;
-   rtfree(rt);
-   }
+   rtfree(rt);
}
 
dr->installed = 0;
@@ -1902,10 +1895,10 @@ nd6_prefix_offlink(struct nd_prefix *pr)
error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &rt,
ifp->if_rdomain);
if (error == 0) {
-   pr->ndpr_stateflags &= ~NDPRF_ONLINK;
-
-   /* report the route deletion to the routing socket. */
rt_sendmsg(rt, RTM_DELETE, ifp->if_rdomain);
+   rtfree(rt);
+
+   pr->ndpr_stateflags &= ~NDPRF_ONLINK;
 
/*
 * There might be the same prefix on another interface,
@@ -1945,12 +1938,6 @@ nd6_prefix_offlink(struct nd_prefix *pr)
opr->ndpr_ifp->if_xname, e));
}
}

Re: [patch] ctags -u

2015-08-20 Thread Sebastien Marie
On Wed, Aug 19, 2015 at 12:53:15PM -0600, Todd C. Miller wrote:
> On Wed, 19 Aug 2015 20:21:08 +0200, Sebastien Marie wrote:
> 
> Some minor comments inline.
> 

Thanks for the comments.

Here is a new version, which include your comments, and have the
following additional changes:
  - do preloading only if -v or -x are absents (same behaviour as
before)
  - manage '/' and '?' as possible search char (-F/-B forward/backward
search)
  - check for skipping the preloaded entry more early (instead of
parsing pattern and discard it after)
  - reflects logic change in ctags.1

One behaviour change remains: if your 'tags' file was previously
generated with '-F' and you update with '-B', the previous behaviour was
to mix /^xxx/ and ?^xxx?  in 'tags' file. Here, as the file is
completely regenerated (with preloaded old entries), all the updated
'tags' will be in ?^xxx? format (backward search).

Thanks.
-- 
Sebastien Marie

Index: ctags.1
===
RCS file: /cvs/src/usr.bin/ctags/ctags.1,v
retrieving revision 1.28
diff -u -p -r1.28 ctags.1
--- ctags.1 13 Mar 2015 19:58:41 -  1.28
+++ ctags.1 20 Aug 2015 10:36:40 -
@@ -89,12 +89,8 @@ The default behaviour is to place them i
 Update the specified files in the
 .Ar tags
 file, that is, all
-references to them are deleted, and the new values are appended to the
+references to them are regenerated, keeping only the others values in the
 file.
-(Beware: this option is implemented in a way which is rather
-slow; it is usually faster to simply rebuild the
-.Ar tags
-file.)
 .It Fl v
 An index of the form expected by vgrind
 is produced on the standard output.
Index: ctags.c
===
RCS file: /cvs/src/usr.bin/ctags/ctags.c,v
retrieving revision 1.15
diff -u -p -r1.15 ctags.c
--- ctags.c 8 Feb 2015 23:40:34 -   1.15
+++ ctags.c 20 Aug 2015 10:36:40 -
@@ -65,6 +65,7 @@ char  lbuf[LINE_MAX];
 
 void   init(void);
 void   find_entries(char *);
+void   preload_entries(char *, int, char *[]);
 
 int
 main(int argc, char *argv[])
@@ -75,7 +76,6 @@ main(int argc, char *argv[])
int exit_val;   /* exit value */
int step;   /* step through args */
int ch; /* getopts char */
-   char*cmd;
 
aflag = uflag = NO;
while ((ch = getopt(argc, argv, "BFadf:tuwvx")) != -1)
@@ -122,6 +122,8 @@ usage:  (void)fprintf(stderr,
}
 
init();
+   if (uflag && !vflag && !xflag)
+   preload_entries(outfile, argc, argv);
 
for (exit_val = step = 0; step < argc; ++step)
if (!(inf = fopen(argv[step], "r"))) {
@@ -138,30 +140,10 @@ usage:(void)fprintf(stderr,
if (xflag)
put_entries(head);
else {
-   if (uflag) {
-   for (step = 0; step < argc; step++) {
-   if (asprintf(&cmd,
-   "mv %s OTAGS; fgrep -v '\t%s\t' 
OTAGS >%s; rm OTAGS",
-   outfile, argv[step], outfile) == -1)
-   err(1, "out of space");
-   system(cmd);
-   free(cmd);
-   cmd = NULL;
-   }
-   aflag = 1;
-   }
if (!(outf = fopen(outfile, aflag ? "a" : "w")))
err(exit_val, "%s", outfile);
put_entries(head);
(void)fclose(outf);
-   if (uflag) {
-   if (asprintf(&cmd, "sort -o %s %s",
-   outfile, outfile) == -1)
-   err(1, "out of space");
-   system(cmd);
-   free(cmd);
-   cmd = NULL;
-   }
}
}
exit(exit_val);
@@ -252,4 +234,80 @@ find_entries(char *file)
}
}
 /* C */c_entries();
+}
+
+void
+preload_entries(char *tagsfile, int argc, char *argv[])
+{
+   FILE*fp;
+   char line[LINE_MAX];
+   char*entry = NULL;
+   char*file = NULL;
+   char*pattern = NULL;
+   char*eol;
+   int  i;
+
+   in_preload = YES;
+
+   if ((fp = fopen(tagsfile, "r")) == NULL)
+   err(1, "preload_entries: %s", tagsfile);
+
+   while (1) {
+next:
+   if (fgets(line, sizeof(line), fp) == NULL)
+   break;
+
+   if ((eol = strchr(line, '\n')) == NULL