ioctl SIOCSIFADDR multiple calls

Steven King sking at zetron.com
Wed Nov 15 01:06:38 UTC 2006


Hi All,

I have been trying to write an "ifconfig" like command for RTEMS, however I
have run into an issue when attempting to set the Interface address (using
ioctl SIOCSIFADDR) more than once in the same application.

The code im using looks like:

Void network_config() 
{
if (set_ip_using (sockfd, ifname,  SIOCSIFADDR, ip) < 0 )
{
	cout << "IP Failure" << endl;
	close (sockfd);
	return ;
}
}

static int set_ip_using(int sockfd, const char *name,  int c, in_addr ip)
	{
   	struct ifreq ifr;
    	struct sockaddr_in sin;
    	strncpy(ifr.ifr_name, name, IFNAMSIZ);
    	memset(&sin, 0, sizeof(struct sockaddr));
    	sin.sin_family = AF_INET;
    	sin.sin_addr = ip;
    	memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
    	return ioctl(sockfd, c, &ifr) ;
}

On the second and subsequent calls to network_config(), the ioctl returns
EEXIST (code = 17).  I have traced this down into the routing table
modifications. Route.c line 572.

The relevant (I think) code from route.c is shown below:
		/*
		 * This moved from below so that rnh->rnh_addaddr() can
		 * examine the ifa and ifp if it so desires.
		 */
		ifa->ifa_refcnt++;
		rt->rt_ifa = ifa;
		rt->rt_ifp = ifa->ifa_ifp;

		rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask,
					rnh, rt->rt_nodes);
		if (rn == 0) {
			struct rtentry *rt2;
			/*
			 * Uh-oh, we already have one of these in the tree.
			 * We do a special hack: if the route that's already
			 * there was generated by the protocol-cloning
			 * mechanism, then we just blow it away and retry
			 * the insertion of the new one.
			 */
			rt2 = rtalloc1(dst, 0, RTF_PRCLONING);
			if (rt2 && rt2->rt_parent) {
				rtrequest(RTM_DELETE, 
					  (struct sockaddr *)rt_key(rt2),
					  rt2->rt_gateway,
					  rt_mask(rt2), rt2->rt_flags, 0);
				RTFREE(rt2);
				rn = rnh->rnh_addaddr((caddr_t)ndst,
						      (caddr_t)netmask,
						      rnh, rt->rt_nodes);
			} else if (rt2) {
				RTFREE(rt2);
			}
		}

		if (rn == 0) {
			if (rt->rt_gwroute)
				rtfree(rt->rt_gwroute);
			if (rt->rt_ifa) {
				IFAFREE(rt->rt_ifa);
			}
			Free(rt_key(rt));
			Free(rt);
			printf ("%s:%d\r\n",__FILE__,__LINE__);
			senderr(EEXIST); // ****** HERE ********
		}
		rt->rt_parent = 0;

Am I doing something wrong? 
Is there an issue with setting the interface address in the same program
multiple times?

Note: The address does actually get changed and reports to ping commands.
Also the reported IP address is the address I set in the command.
I have tried SIOCDIFADDR but no change and it should not be needed anyhow.

Steven King
Firmware Design Engineer
Zetron - Australasia
Phone: +61 7 3856 4888 (Ext 220)
Fax: +61 7 3356 6877
Internet: www.zetron.com


  




More information about the users mailing list