[patch] ng_iface(4) and ports/net/mpd4 allow renaming of interfaces.

Ermal Luçi ermal.luci at gmail.com
Wed Apr 16 19:08:35 UTC 2008


Hello,

the patches inlined give the ng_iface(4) and the mpd4 port the ability
to rename its interfaces.
IE if you create a new pppoe connection instead of the line

new -i ng0 pppoe pppoe
you can enter
new -i pppoe0 pppoe pppoe

so when mpd starts it will create an ngX interface with a ngX: hook
after that it will rename ngX to pppoe0 and the corresponding hook to pppoe0:

The ng_iface(4) patch adds a new message NGM_IFACE_SET_IFNAME:
usable through ngctl msg $path: setifname $name

it is just a copy of the ioctl in if.c SIFNAME without the routing
adevertising cause mostly you will do renaming before bringing the
interface up. Alghotu you are not allowed to rename it after the
interface is up.

I wonder if it can be polished and integrated in future versions of FreeBSD?!
If it is needed to patch even mpd5 i will do even that.

Regards,
Ermal



--- src/ngfunc.c.orig	2008-04-16 13:29:08.000000000 -0400
+++ src/ngfunc.c	2008-04-16 13:29:16.000000000 -0400
@@ -249,6 +249,7 @@
       struct ng_mesg	reply;
   }			u;
   char		path[NG_PATHLEN + 1];
+#if 0
   char		*eptr;
   int		ifnum;

@@ -258,9 +259,10 @@
   ifnum = (int)strtoul(ifname + strlen(NG_IFACE_IFACE_NAME), &eptr, 10);
   if (ifnum < 0 || *eptr != '\0')
     return(-1);
+#endif

   /* See if interface exists */
-  snprintf(path, sizeof(path), "%s%d:", NG_IFACE_IFACE_NAME, ifnum);
+  snprintf(path, sizeof(path), "%s:", ifname);
   if (NgSendMsg(b->csock, path, NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0)
     return(0);
   if (NgRecvMsg(b->csock, &u.reply, sizeof(u), NULL) < 0) {
@@ -270,7 +272,7 @@

   /* It exists */
   if (buf != NULL)
-    snprintf(buf, max, "%s%d", NG_IFACE_IFACE_NAME, ifnum);
+    snprintf(buf, max, "%s", ifname);
   return(1);
 }

@@ -294,30 +296,10 @@
   struct nodeinfo	*const ni = (struct nodeinfo *)(void *)u.reply.data;
   struct ngm_rmhook	rm;
   struct ngm_mkpeer	mp;
+  struct ngm_name	nm;
+  char path[NG_PATHLEN + 1];
   int			rtn = 0;

-  /* If ifname is not null, create interfaces until it gets created */
-  if (ifname != NULL) {
-    int count;
-
-    for (count = 0; count < MAX_IFACE_CREATE; count++) {
-      switch (NgFuncIfaceExists(b, ifname, buf, max)) {
-      case 1:				/* ok now it exists */
-	return(0);
-      case 0:				/* nope, create another one */
-	NgFuncCreateIface(b, NULL, NULL, 0);
-	break;
-      case -1:				/* something weird happened */
-	return(-1);
-      default:
-	assert(0);
-      }
-    }
-    Log(LG_ERR, ("[%s] created %d interfaces, that's too many!",
-      b->name, count));
-    return(-1);
-  }
-
   /* Create iface node (as a temporary peer of the socket node) */
   snprintf(mp.type, sizeof(mp.type), "%s", NG_IFACE_NODE_TYPE);
   snprintf(mp.ourhook, sizeof(mp.ourhook), "%s", TEMPHOOK);
@@ -328,7 +310,6 @@
       b->name, NG_IFACE_NODE_TYPE, ".", mp.ourhook, strerror(errno)));
     return(-1);
   }
-
   /* Get the new node's name */
   if (NgSendMsg(b->csock, TEMPHOOK,
       NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0) {
@@ -342,6 +323,28 @@
     rtn = -1;
     goto done;
   }
+
+if (ifname != NULL) {
+  /* Set the new node's name */
+  bzero(path, sizeof(path));
+  snprintf(path, sizeof(path), "%s:", ni->name);
+snprintf(nm.name, sizeof(nm.name), "%s", ifname);
+  if (NgSendMsg(b->csock, path,
+      NGM_IFACE_COOKIE, NGM_IFACE_SET_IFNAME, nm.name, sizeof(nm.name)) < 0) {
+    Log(LG_ERR, ("[%s] %s: %s", b->name, "NGM_NODEINFO", strerror(errno)));
+    rtn = -1;
+    goto done;
+  }
+
+  /* Set the new node's name */
+  if (NgSendMsg(b->csock, path,
+      NGM_GENERIC_COOKIE, NGM_NAME, &nm, sizeof(nm)) < 0) {
+    Log(LG_ERR, ("[%s] %s: %s", b->name, "NGM_NODEINFO", strerror(errno)));
+    rtn = -1;
+    goto done;
+  }
+  snprintf(buf, max, "%s", ifname);
+} else
   snprintf(buf, max, "%s", ni->name);

 done:
@@ -355,7 +358,7 @@
   }

   /* Done */
-  return(rtn);
+  return (rtn);
 }

 /*




Index: ng_iface.c
===================================================================
RCS file: /home/ncvs/src/sys/netgraph/ng_iface.c,v
retrieving revision 1.47
diff -u -r1.47 ng_iface.c
--- ng_iface.c	2 Jun 2006 23:14:40 -0000	1.47
+++ ng_iface.c	16 Apr 2008 17:03:47 -0000
@@ -69,9 +69,11 @@
 #include <sys/socket.h>
 #include <sys/syslog.h>
 #include <sys/libkern.h>
+#include <sys/ctype.h>

 #include <net/if.h>
 #include <net/if_types.h>
+#include <net/if_dl.h>
 #include <net/bpf.h>
 #include <net/netisr.h>

@@ -163,6 +165,13 @@
 	},
 	{
 	  NGM_IFACE_COOKIE,
+	  NGM_IFACE_SET_IFNAME,
+	  "setifname",
+	  &ng_parse_string_type,
+	  NULL
+	},
+	{
+	  NGM_IFACE_COOKIE,
 	  NGM_IFACE_POINT2POINT,
 	  "point2point",
 	  NULL,
@@ -587,6 +596,10 @@
 	struct ng_mesg *resp = NULL;
 	int error = 0;
 	struct ng_mesg *msg;
+	char *new_name;
+	size_t namelen, onamelen;
+	struct sockaddr_dl *sdl = NULL;
+	struct ifaddr *ifa = NULL;

 	NGI_GET_MSG(item, msg);
 	switch (msg->header.typecookie) {
@@ -601,6 +614,49 @@
 			strlcpy(resp->data, ifp->if_xname, IFNAMSIZ);
 			break;

+		case NGM_IFACE_SET_IFNAME:
+
+		new_name = (char *)msg->data;
+                /* Announce the departure of the interface. */
+		//new_name[strlen(new_name)] = '\0';
+
+ 		/* Deny request if interface is UP */
+ 		if ((ifp->if_flags & IFF_UP) != 0) {
+ 		  error = EBUSY;
+ 		  break;
+			}
+
+                //rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
+                EVENTHANDLER_INVOKE(ifnet_departure_event, ifp);
+
+                strlcpy(ifp->if_xname, new_name, sizeof(ifp->if_xname));
+                ifa = ifp->if_addr;
+                IFA_LOCK(ifa);
+                sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+                namelen = strlen(new_name) + 1;
+                onamelen = sdl->sdl_nlen;
+                /*
+                 * Move the address if needed.  This is safe because we
+                 * allocate space for a name of length IFNAMSIZ when we
+                 * create this in if_attach().
+                 */
+                if (namelen != onamelen) {
+                        bcopy(sdl->sdl_data + onamelen,
+                            sdl->sdl_data + namelen, sdl->sdl_alen);
+                }
+                bcopy(new_name, sdl->sdl_data, namelen);
+                sdl->sdl_nlen = namelen;
+                sdl = (struct sockaddr_dl *)ifa->ifa_netmask;
+                bzero(sdl->sdl_data, onamelen);
+                while (namelen != 0)
+                        sdl->sdl_data[--namelen] = 0xff;
+                IFA_UNLOCK(ifa);
+
+                EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp);
+                /* Announce the return of the interface. */
+                //rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
+			break;
+		
 		case NGM_IFACE_POINT2POINT:
 		case NGM_IFACE_BROADCAST:
 		    {
Index: ng_iface.h
===================================================================
RCS file: /home/ncvs/src/sys/netgraph/ng_iface.h,v
retrieving revision 1.9
diff -u -r1.9 ng_iface.h
--- ng_iface.h	13 Feb 2005 16:36:41 -0000	1.9
+++ ng_iface.h	16 Apr 2008 17:03:48 -0000
@@ -70,6 +70,7 @@
 	NGM_IFACE_POINT2POINT,
 	NGM_IFACE_BROADCAST,
 	NGM_IFACE_GET_IFINDEX,
+	NGM_IFACE_SET_IFNAME,
 };

 #endif /* _NETGRAPH_NG_IFACE_H_ */


More information about the freebsd-net mailing list