svn commit: r193897 - projects/mesh11s/sbin/ifconfig

Bruce Evans brde at optusnet.com.au
Thu Jun 11 02:24:48 UTC 2009


On Wed, 10 Jun 2009, Rui Paulo wrote:

> Log:
>  Work around the fact that ether_ntoa() uses a static buffer.

ether_ntoa() and inet_ntoa() use static buffers, so they are hard to
use in non-preemptive UP kernels and almost impossible to use in
preemtive UP and SMP kernels.  I don't see how the problem can be
worked around.  They shouldn't exist.  inet_ntoa_r() has existed for
a long time and ether_ntoa_r() has existed for a not so long time.

> Modified: projects/mesh11s/sbin/ifconfig/ifieee80211.c
> ==============================================================================
> --- projects/mesh11s/sbin/ifconfig/ifieee80211.c	Wed Jun 10 10:47:31 2009	(r193896)
> +++ projects/mesh11s/sbin/ifconfig/ifieee80211.c	Wed Jun 10 10:51:38 2009	(r193897)
> @@ -3916,9 +3916,9 @@ list_hwmp(int s)
> 		, "PREQID");
>
> 	for (i = 0; i < ireq.i_len / sizeof(*routes); i++) {
> -		printf("%s %s %4u   %4d   %6d %4d %6d\n",
> -			ether_ntoa((const struct ether_addr *)
> -			    routes[i].fi_dest),
> +		printf("%s ", ether_ntoa((const struct ether_addr *)
> +		    routes[i].fi_dest));
> +		printf("%s %4u   %4d   %6d %4d %6d\n",
> 			ether_ntoa((const struct ether_addr *)
> 			    routes[i].fi_nexthop),
> 			routes[i].fi_nhops, routes[i].fi_metric,

This still has nice races (unlikely to be hit, but confusing if they happen)
except for non-preemptive UP kernels.

Until all callers are fixed, ether_ntoa() and inet_ntoa() should use the
hack of an array of static buffers.  An array of size 2 permits 2 calls
per printf under UP, etc.  A larger array with atomic accesses for the
index should work well enough even for the SMP case in practice.

/sys sources on Mar 30 has the following lines matching ntoa:

% ./kern/kern_jail.c:			db_printf("%6s  %s\n", "", inet_ntoa(ia));
% ./boot/common/dev_net.c:	printf("net_open: client addr: %s\n", inet_ntoa(myip));
% ./boot/common/dev_net.c:		printf("net_open: subnet mask: %s\n", intoa(netmask));
% ./boot/common/dev_net.c:		printf("net_open: net gateway: %s\n", inet_ntoa(gateip));
% ./boot/common/dev_net.c:		printf("net_open: server addr: %s\n", inet_ntoa(rootip));
% ./boot/common/dev_net.c:	setenv("boot.netif.ip", inet_ntoa(myip), 1);
% ./boot/common/dev_net.c:	setenv("boot.netif.netmask", intoa(netmask), 1);
% ./boot/common/dev_net.c:	setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
% ./boot/common/dev_net.c:	setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
% ./boot/i386/libi386/pxe.c:		printf("pxe_open: server addr: %s\n", inet_ntoa(rootip));
% ./boot/i386/libi386/pxe.c:		printf("pxe_open: gateway ip:  %s\n", inet_ntoa(gateip));
% ./boot/i386/libi386/pxe.c:		setenv("boot.netif.ip", inet_ntoa(myip), 1);
% ./boot/i386/libi386/pxe.c:		setenv("boot.netif.netmask", intoa(netmask), 1);
% ./boot/i386/libi386/pxe.c:		setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
% ./boot/i386/libi386/pxe.c:		setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
% ./netinet/libalias/alias_proxy.c:	    inet_ntoa(GetProxyAddress(lnk)), (u_int) ntohs(GetProxyPort(lnk)));
% ./netinet/libalias/alias_nbt.c:	printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
% ./netinet/libalias/alias_nbt.c:	printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
% ./netinet/libalias/alias_nbt.c:	printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
% ./netinet/libalias/alias_nbt.c:	printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount);
% ./netinet/libalias/alias_nbt.c:		printf("<%s>", inet_ntoa(nb->addr));
% ./netinet/libalias/alias_nbt.c:	printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
% ./netinet/libalias/alias_nbt.c:	printf("->%s]", inet_ntoa(nbtarg->newaddr));
% ./netinet/libalias/alias_nbt.c:		printf("..%s", inet_ntoa(a->addr));
% ./netinet/libalias/alias_sctp.c:		inet_ntoa(ip->ip_dst),ntohs(sctp_hdr->dest_port), 
% ./netinet/libalias/alias_sctp.c:	    s, sp, assoc->exp, inet_ntoa(assoc->l_addr), ntohl(assoc->l_vtag),
% ./netinet/libalias/alias_sctp.c:		SctpAliasLog("\t\tga=%s\n",inet_ntoa(G_Addr->g_addr));
% ./netinet/ip_gre.c:void gre_inet_ntoa(struct in_addr in);	/* XXX */
% ./netinet/in.c:		    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
% ./netinet/in.h:char	*inet_ntoa(struct in_addr); /* in libkern */
% ./netinet/in.h:char	*inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */
% ./netinet/tcp_subr.c:		    (ip->ip_v == IPVERSION) ? inet_ntoa(dst.sin.sin_addr) :
% ./netinet/tcp_subr.c:		inet_ntoa_r(inc->inc_faddr, sp);
% ./netinet/tcp_subr.c:		inet_ntoa_r(inc->inc_laddr, sp);
% ./netinet/tcp_subr.c:		inet_ntoa_r(ip->ip_src, sp);
% ./netinet/tcp_subr.c:		inet_ntoa_r(ip->ip_dst, sp);
% ./netinet/in_pcb.c:		inet_ntoa_r(inc->inc_laddr, laddr_str);
% ./netinet/in_pcb.c:		inet_ntoa_r(inc->inc_faddr, faddr_str);
% ./netinet/in_mcast.c:			    __func__, ifma, inm, inet_ntoa(*group));
% ./netinet/in_mcast.c:		    inet_ntoa(ia), ims);
% ./netinet/in_mcast.c:		    __func__, n, inet_ntoa(ia));
% ./netinet/in_mcast.c:		    __func__, n, inet_ntoa(ia));
% ./netinet/in_mcast.c:		    __func__, n, inet_ntoa(ia));
% ./netinet/in_mcast.c:		    __func__, n, inet_ntoa(ia));
% ./netinet/in_mcast.c:	    inet_ntoa(*gina), ifp, ifp->if_xname);
% ./netinet/in_mcast.c:	    inm, inet_ntoa(inm->inm_addr),
% ./netinet/in_mcast.c:	    ("%s: %s not in 224.0.0.0/24", __func__, inet_ntoa(*ap)));
% ./netinet/in_mcast.c:		    __func__, inet_ntoa(mreqs.imr_interface), ifp);
% ./netinet/in_mcast.c:		    inet_ntoa(ssa->sin.sin_addr), doblock ? "" : "not ");
% ./netinet/in_mcast.c:		    __func__, inet_ntoa(mreqs.imr_interface), ifp);
% ./netinet/in_mcast.c:		    __func__, inet_ntoa(mreqs.imr_interface), ifp);
% ./netinet/in_mcast.c:			    inet_ntoa(ssa->sin.sin_addr), "not ");
% ./netinet/in_mcast.c:		    inet_ntoa(addr));
% ./netinet/in_mcast.c:		    __func__, inet_ntoa(group));
% ./netinet/in_mcast.c:			    inet_ntoa(ina));
% ./netinet/in_mcast.c:	    inet_ntoa(inm->inm_addr),
% ./netinet/tcp_hostcache.c:			    hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) :
% ./netinet/ip_mroute.c:	(int)vifcp->vifc_vifi, inet_ntoa(vifcp->vifc_lcl_addr),
% ./netinet/ip_mroute.c:	    __func__, inet_ntoa(mfccp->mfcc_origin),
% ./netinet/ip_mroute.c:		    __func__, inet_ntoa(mfccp->mfcc_origin),
% ./netinet/ip_mroute.c:	inet_ntoa(origin), (u_long)ntohl(mcastgrp.s_addr));
% ./netinet/ip_mroute.c:	inet_ntoa(ip->ip_src), (u_long)ntohl(ip->ip_dst.s_addr), ifp);
% ./netinet/ip_mroute.c:	    inet_ntoa(ip->ip_src), (u_long)ntohl(ip->ip_dst.s_addr));
% ./netinet/ip_mroute.c:	    __func__, datalen, inet_ntoa(ip->ip_src));
% ./netinet/ip_mroute.c:	    __func__, inet_ntoa(encap_ip->ip_src), ntohs(encap_ip->ip_len));
% ./netinet/ip_mroute.c:		inet_ntoa(encap_ip->ip_dst));
% ./netinet/ip_icmp.c:		strcpy(buf, inet_ntoa(ip->ip_src));
% ./netinet/ip_icmp.c:		       buf, inet_ntoa(ip->ip_dst), icmplen);
% ./netinet/ip_icmp.c:			strcpy(buf, inet_ntoa(icp->icmp_ip.ip_dst));
% ./netinet/ip_icmp.c:			       buf, inet_ntoa(icp->icmp_gwaddr));
% ./netinet/ip_icmp.c:		strcpy(buf, inet_ntoa(ip->ip_dst));
% ./netinet/ip_icmp.c:		       buf, inet_ntoa(ip->ip_src));
% ./netinet/ip_options.c:					strcpy(buf, inet_ntoa(ip->ip_dst));
% ./netinet/ip_options.c:					    inet_ntoa(ip->ip_src), buf);
% ./netinet/if_ether.c:			    inet_ntoa(SIN(dst)->sin_addr));
% ./netinet/if_ether.c:		    inet_ntoa(SIN(dst)->sin_addr));
% ./netinet/if_ether.c:		    inet_ntoa(isaddr));
% ./netinet/if_ether.c:		   inet_ntoa(isaddr), ifp->if_xname);
% ./netinet/if_ether.c:				    inet_ntoa(isaddr),
% ./netinet/if_ether.c:				    inet_ntoa(isaddr), ifp->if_xname);
% ./netinet/if_ether.c:				    inet_ntoa(isaddr),
% ./netinet/if_ether.c:			    inet_ntoa(isaddr), ifp->if_xname,
% ./netinet/if_ether.c:		       inet_ntoa(itaddr));
% ./netinet/if_ether.c:		    inet_ntoa(itaddr));
% ./netinet/ip_fw2.c:				inet_ntoa(dummyaddr));
% ./netinet/ip_fw2.c:			inet_ntoa_r(ip->ip_src, src);
% ./netinet/ip_fw2.c:			inet_ntoa_r(ip->ip_dst, dst);
% ./netinet/ip_fw2.c:						inet_ntoa_r(da, src);
% ./netinet/ip_fw2.c:						inet_ntoa_r(da, dst);
% ./netinet/udp_usrreq.c:			strcpy(buf, inet_ntoa(ip->ip_dst));
% ./netinet/udp_usrreq.c:			    buf, ntohs(uh->uh_dport), inet_ntoa(ip->ip_src),
% ./netinet/igmp.c:inet_ntoa_haddr(in_addr_t haddr)
% ./netinet/igmp.c:	return (inet_ntoa(ia));
% ./netinet/igmp.c:			    inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
% ./netinet/igmp.c:	    inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname, timer);
% ./netinet/igmp.c:		     inet_ntoa(igmpv3->igmp_group), ifp, ifp->if_xname);
% ./netinet/igmp.c:	     inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
% ./netinet/igmp.c:			    inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
% ./netinet/igmp.c:			    inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
% ./netinet/igmp.c:	     inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
% ./netinet/igmp.c:			    inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
% ./netinet/igmp.c:			    inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
% ./netinet/igmp.c:	    __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp,
% ./netinet/igmp.c:		    inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
% ./netinet/igmp.c:	    __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp,
% ./netinet/igmp.c:		    inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
% ./netinet/igmp.c:	    __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp,
% ./netinet/igmp.c:			    inet_ntoa(inm->inm_addr),
% ./netinet/igmp.c:		    inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
% ./netinet/igmp.c:		    __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
% ./netinet/igmp.c:		    __func__, inet_ntoa(inm->inm_addr),
% ./netinet/igmp.c:	    igmp_rec_type_to_str(type), inet_ntoa(inm->inm_addr),
% ./netinet/igmp.c:			    inet_ntoa_haddr(ims->ims_haddr));
% ./netinet/igmp.c:			    inet_ntoa_haddr(ims->ims_haddr));
% ./netinet/igmp.c:				    __func__, inet_ntoa_haddr(ims->ims_haddr));
% ./netipx/ipx.h:char		*ipx_ntoa(struct ipx_addr);
% ./nfs4client/nfs4_vfsops.c:	ipsrc = inet_ntoa(IA_SIN(ifatoia(ro.ro_rt->rt_ifa))->sin_addr);
% ./nfsserver/nfs_syscalls.c:				    inet_ntoa(sin->sin_addr), port);
% ./nfsserver/nfs_srvkrpc.c:			    inet_ntoa(sin->sin_addr), port);
% ./dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c:			inet_ntoa(local->sin_addr),
% ./dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c:			inet_ntoa(remote->sin_addr));
% ./dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c:		inet_ntoa(remote->sin_addr), ntohs(remote->sin_port));
% ./dev/isp/ispvar.h:	uint64_t		isp_intoasync;		/* other async */
% ./dev/isp/isp_freebsd.c:		sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
% ./dev/isp/isp_freebsd.c:		isp->isp_intoasync = 0;
% ./dev/isp/isp.c:		isp->isp_intoasync++;
% ./net/ethernet.h:char 	*ether_ntoa(const struct ether_addr *);
% ./net/ethernet.h:char 	*ether_ntoa_r(const struct ether_addr *, char *);
% ./net/if_dl.h:char	*link_ntoa(const struct sockaddr_dl *);
% ./net/if_gre.c:	    inet_ntoa(((struct sockaddr_in *)&ro->ro_dst)->sin_addr));
% ./net/if_gre.c:	    inet_ntoa(((struct sockaddr_in *)(ro->ro_rt->rt_gateway))->sin_addr));
% ./libkern/inet_ntoa.c:__FBSDID("$FreeBSD: head/sys/libkern/inet_ntoa.c 139815 2005-01-07 00:24:33Z imp $");
% ./libkern/inet_ntoa.c:inet_ntoa(struct in_addr ina)
% ./libkern/inet_ntoa.c:inet_ntoa_r(struct in_addr ina, char *buf)
% ./contrib/pf/net/pf_osfp.c:		strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname));
% ./cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c:			 * just the IPv4 string is returned for inet_ntoa6.
% ./netipsec/ipsec.c:inet_ntoa4(struct in_addr ina)
% ./netipsec/ipsec.c:		return (inet_ntoa4(sa->sin.sin_addr));
% ./netipsec/ipsec_input.c:			    inet_ntoa4(ipn.ip_src),
% ./netipsec/ipsec_input.c:			    inet_ntoa4(ipn.ip_src),
% ./sys/eui64.h:int	eui64_ntoa(const struct eui64 *, char *, size_t);

In 141 lines, the _r variants are only used 10 times.  Neither of the
ether_ntoa*() variants were used, so ether_ntoa() should be easy to remove.

Bruce


More information about the svn-src-projects mailing list