If you build route6d with -Wshadow, you'll notice lots of warnings like
this one:
/usr/src/usr.sbin/route6d/route6d.c: In function 'riprecv':
/usr/src/usr.sbin/route6d/route6d.c:970: warning: declaration of 'np' shadows a
global declaration
/usr/src/usr.sbin/route6d/route6d.c:629: warning: shadowed declaration is here
Such warnings are because functions ripsend() and ripflush() share two
global variables, "np" and "nrt". "np" is used to fill the ripbuf
buffer in ripsend(), "nrt" tells ripflush() how many route entries this
buffer contains. When it gets called, ripflush() resets "nrt" to 0 and
"np" to NULL.
I find this use of globals dirty. "ripbuf" is a global already, the
only thing rtflush() needs to know from ripsend() is how many routes
have been put in the buffer. We can use a parameter for this, and kill
those globals by resetting "np" in ripsend().
I find the code clearer with the following patch, is it just me? Tested
with 100+ routes, other side is quagga/ripngd.
Comments / ok?
Index: route6d.c
===================================================================
RCS file: /cvs/src/usr.sbin/route6d/route6d.c,v
retrieving revision 1.81
diff -u -p -r1.81 route6d.c
--- route6d.c 26 Oct 2015 00:37:44 -0000 1.81
+++ route6d.c 26 Oct 2015 14:22:29 -0000
@@ -220,7 +220,7 @@ void rtdump(int);
void rt_entry(struct rt_msghdr *, int);
void rtdexit(void);
void riprequest(struct ifc *, struct netinfo6 *, int, struct sockaddr_in6 *);
-void ripflush(struct ifc *, struct sockaddr_in6 *);
+void ripflush(struct ifc *, struct sockaddr_in6 *, int);
void sendrequest(struct ifc *);
int sin6mask2len(const struct sockaddr_in6 *);
int mask2len(const struct in6_addr *, int);
@@ -625,14 +625,11 @@ init(void)
/*
* ripflush flushes the rip datagram stored in the rip buffer
*/
-static int nrt;
-static struct netinfo6 *np;
-
void
-ripflush(struct ifc *ifcp, struct sockaddr_in6 *sin6)
+ripflush(struct ifc *ifcp, struct sockaddr_in6 *sin6, int nrt)
{
- int i;
- int error;
+ struct netinfo6 *np;
+ int error, i;
if (ifcp)
tracet(1, "Send(%s): info(%d) to %s.%d\n",
@@ -671,7 +668,6 @@ ripflush(struct ifc *ifcp, struct sockad
ifcp->ifc_name, inet6_n2p(&ifcp->ifc_ripsin.sin6_addr));
ifcp->ifc_flags &= ~IFF_UP; /* As if down for AF_INET6 */
}
- nrt = 0; np = ripbuf->rip6_nets;
}
/*
@@ -680,9 +676,11 @@ ripflush(struct ifc *ifcp, struct sockad
void
ripsend(struct ifc *ifcp, struct sockaddr_in6 *sin6, int flag)
{
- struct riprt *rrt;
- struct in6_addr *nh; /* next hop */
- int maxrte;
+ struct netinfo6 *np;
+ int nrt;
+ struct in6_addr *nh; /* next hop */
+ struct riprt *rrt;
+ int maxrte;
if (qflag)
return;
@@ -696,7 +694,9 @@ ripsend(struct ifc *ifcp, struct sockadd
sizeof(struct udphdr) -
sizeof(struct rip6) + sizeof(struct netinfo6)) /
sizeof(struct netinfo6);
- nrt = 0; np = ripbuf->rip6_nets; nh = NULL;
+ np = ripbuf->rip6_nets;
+ nrt = 0;
+ nh = NULL;
for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
if (rrt->rrt_rflags & RRTF_NOADVERTISE)
continue;
@@ -704,12 +704,14 @@ ripsend(struct ifc *ifcp, struct sockadd
*np = rrt->rrt_info;
np++; nrt++;
if (nrt == maxrte) {
- ripflush(NULL, sin6);
+ ripflush(NULL, sin6, nrt);
+ np = ripbuf->rip6_nets;
+ nrt = 0;
nh = NULL;
}
}
if (nrt) /* Send last packet */
- ripflush(NULL, sin6);
+ ripflush(NULL, sin6, nrt);
return;
}
@@ -733,7 +735,7 @@ ripsend(struct ifc *ifcp, struct sockadd
np = ripbuf->rip6_nets;
*np = rrt_info;
nrt = 1;
- ripflush(ifcp, sin6);
+ ripflush(ifcp, sin6, nrt);
return;
}
@@ -741,8 +743,9 @@ ripsend(struct ifc *ifcp, struct sockadd
sizeof(struct udphdr) -
sizeof(struct rip6) + sizeof(struct netinfo6)) /
sizeof(struct netinfo6);
-
- nrt = 0; np = ripbuf->rip6_nets; nh = NULL;
+ np = ripbuf->rip6_nets;
+ nrt = 0;
+ nh = NULL;
for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
if (rrt->rrt_rflags & RRTF_NOADVERTISE)
continue;
@@ -765,8 +768,11 @@ ripsend(struct ifc *ifcp, struct sockadd
!IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_gw) &&
(rrt->rrt_rflags & RRTF_NH_NOT_LLADDR) == 0) {
if (nh == NULL || !IN6_ARE_ADDR_EQUAL(nh,
&rrt->rrt_gw)) {
- if (nrt == maxrte - 2)
- ripflush(ifcp, sin6);
+ if (nrt == maxrte - 2) {
+ ripflush(ifcp, sin6, nrt);
+ np = ripbuf->rip6_nets;
+ nrt = 0;
+ }
np->rip6_dest = rrt->rrt_gw;
if (IN6_IS_ADDR_LINKLOCAL(&np->rip6_dest))
SET_IN6_LINKLOCAL_IFINDEX(np->rip6_dest, 0);
@@ -780,8 +786,11 @@ ripsend(struct ifc *ifcp, struct sockadd
!IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw) ||
rrt->rrt_rflags & RRTF_NH_NOT_LLADDR)) {
/* Reset nexthop */
- if (nrt == maxrte - 2)
- ripflush(ifcp, sin6);
+ if (nrt == maxrte - 2) {
+ ripflush(ifcp, sin6, nrt);
+ np = ripbuf->rip6_nets;
+ nrt = 0;
+ }
memset(np, 0, sizeof(struct netinfo6));
np->rip6_metric = NEXTHOP_METRIC;
nh = NULL;
@@ -792,12 +801,14 @@ ripsend(struct ifc *ifcp, struct sockadd
*np = rrt->rrt_info;
np++; nrt++;
if (nrt == maxrte) {
- ripflush(ifcp, sin6);
+ ripflush(ifcp, sin6, nrt);
+ np = ripbuf->rip6_nets;
+ nrt = 0;
nh = NULL;
}
}
if (nrt) /* Send last packet */
- ripflush(ifcp, sin6);
+ ripflush(ifcp, sin6, nrt);
}
/*
--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE