Hi Denis,

i want to thank for the ifplugd code review! I think I'm one step further with 
the busybox's philosophy.

I have written up a short summary explaining the code differences between 
implementations. Also can we remove some dead/redundant code from the 
'check_existence_through_netlink' function? For example:

//linux/netlink.h
//#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
//   (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
//   (nlh)->nlmsg_len <= (len))
if (!NLMSG_OK(mhdr, bytes)
  || bytes < sizeof(struct nlmsghdr) || bytes < mhdr->nlmsg_len // as NLMSG_OK 
is declared, with short-cut evaluation its never be performed
) {
        ...
}

Attached is a patch.
--
max


> > Hi Denis,
> > 
> > attached is a patch for ifplugd.
> 
> +     int iface_disabled;
> 
> This flag is "negative". 1 means no and 0 means yes.
> Which is hard to read. I am renaming it to iface_enabled.
> Hmmm... or rather iface_exists, that's closer to what
> it actually means.
> 
> 
> static int ifplugd_is_iface_available(void)
> {
>         struct ifreq ifrequest;
> 
>         ifplugd_set_ifreq_to_ifname(&ifrequest);
> 
>         if (ifplugd_ioctl(SIOCGIFINDEX, &ifrequest) < 0
>          && errno != ENODEV
>         ) {
>                 bb_perror_msg("SIOCGIFINDEX failed");
>                 return -1;
>         }
> 
>         return ifrequest.ifr_ifindex < 0;
> }
> 
> (1) Is it really possible to have ifr_ifindex < 0?
>     What does that mean?
> (2) If ioctl fails, won't you use uninitialized data
>     in ifrequest.ifr_ifindex?
> 
> 
> +static int ifplugd_netlink_work(void)
> +{
> ...
> +     char ifname[IFNAMSIZ+1] = { 0 };
> ...
> +     while (1) {
> +             bytes = recv(netlink_fd, &replybuf, sizeof(replybuf), 
> MSG_DONTWAIT);
> +             if (bytes < 0) {
> ...
> +             }
> +
> +             mhdr = (struct nlmsghdr*)replybuf;
> +             while (bytes > 0) {
> ...
> +                     if (mhdr->nlmsg_type == RTM_NEWLINK || mhdr->nlmsg_type 
> == RTM_DELLINK) {
> ...
> +                             while (RTA_OK(attr, attr_len)) {
> +                                     if(attr->rta_type == IFLA_IFNAME) {
> +                                             int len = RTA_PAYLOAD(attr);
> +                                             if (len > IFNAMSIZ)
> +                                                     len = IFNAMSIZ;
> +                                             strncpy(ifname, RTA_DATA(attr), 
> len);
> +                                     }
> +                                     attr = RTA_NEXT(attr, attr_len);
> +                             }
> +
> +                             if (ifname[0] && strcmp(G.iface, ifname) == 0) {
> +                                     return !(mhdr->nlmsg_type == 
> RTM_NEWLINK);
> +                             }
> +                     }
> ...
> +     }
> 
> (1) Why do you fill entire ifname with zeroes? ifname[0] = 0 is enough.
> (2) You can get ifname for one message but use nlmsg_type from another,
>     because you clear ifname in the wrong place. Need to do it
>     after if (mhdr->nlmsg_type == RTM_NEWLINK || mhdr->nlmsg_type ==
> RTM_DELLINK)
> 
> 
>         logmode |= LOGMODE_NONE;
> 
>         iface_status = ifplugd_interface_detect_beat_ethtool();
>         if (iface_status != IFSTATUS_ERR) {
>                 logmode &= ~LOGMODE_NONE;
> 
> LOGMODE_NONE is constant 0.
> 
> 
> +static int ifplugd_interface_detect_beat_wlan(void)
> +{
> +     struct iwreq iwrequest;
> +     uint8_t mac[ETH_ALEN];
> +
> +     if (!(option_mask32 & FLAG_NO_AUTO))
> +             ifplugd_interface_up();
> 
> You repeat ifplugd_interface_up() code in every
> ifplugd_interface_detect_beat_XXX
> function. 5 copies. You can do it just once in ifplugd_detect_beat().
> 
> 
>         getopt32(argv, OPTION_STR,
>                 &G.iface, &G.run, &G.poll_time, &G.delay_up,
>                 &G.delay_down, &G.api_mode, &G.extra_arg);
> 
> G.delay_up/down are time_t's, here you assume they have the same
> sizeof as ints. Bad idea.
> 
> 
> +             if (poll(netlink_pollfd, (option_mask32 & FLAG_MONITOR) ? 1 : 0,
> +               G.poll_time*1000)
> +             ) {
> 
> Only negative returns from poll are errors. You test for != 0.
> 
> 
> ifplugd_netlink_work reports 1 ("interface exists") even if netlink
> data does not say whether it exists or not.
> 
> 
> I edited the applet a lot and committed it to svn.
> 
> Can you test current svn?
> 
> Please write up a summary what version of ifplugd it is based on,
> what features are implemented compatibly and what is dropped
> or changed?
> 
> One questionable point of the design is netlink usage:
> 
> We have 1 second timeout by default to poll the link status,
> it is short enough so that there are no real benefits in
> using netlink to get "instantaneous" interface creation/deletion
> notifications. We can check for interface existence by just
> doing some fast ioctl using its name.
> 
> Netlink code then can be just dropped (1k or more?).
> --
> vda
> 
> 
diff --git a/networking/ifplugd.c b/networking/ifplugd.c
index 3739108..38a0324 100644
--- a/networking/ifplugd.c
+++ b/networking/ifplugd.c
@@ -1,6 +1,6 @@
 /* vi: set sw=4 ts=4: */
 /*
- * ifplugd for busybox
+ * ifplugd for busybox, based on ifplugd 0.28 (written by Lennart Poettering).
  *
  * Copyright (C) 2009 Maksym Kryzhanovskyy <[email protected]>
  *
@@ -22,7 +22,11 @@
 #include <linux/wireless.h>
 
 /*
-TODO: describe compat status here.
+From initial port to busybox, removed most of the redundancy by
+converting implementation of a polymorphic interface to the strict
+functional style. The main role is run a script when link state
+changed, other activities like audio signal or detailed reports
+are on the script itself.
 
 One questionable point of the design is netlink usage:
 
diff --git a/networking/ifplugd.c b/networking/ifplugd.c
index 3739108..f398cca 100644
--- a/networking/ifplugd.c
+++ b/networking/ifplugd.c
@@ -1,6 +1,6 @@
 /* vi: set sw=4 ts=4: */
 /*
- * ifplugd for busybox
+ * ifplugd for busybox, based on ifplugd 0.28 (written by Lennart Poettering).
  *
  * Copyright (C) 2009 Maksym Kryzhanovskyy <[email protected]>
  *
@@ -22,7 +22,11 @@
 #include <linux/wireless.h>
 
 /*
-TODO: describe compat status here.
+From initial port to busybox, removed most of the redundancy by
+converting implementation of a polymorphic interface to the strict
+functional style. The main role is run a script when link state
+changed, other activities like audio signal or detailed reports
+are on the script itself.
 
 One questionable point of the design is netlink usage:
 
@@ -500,38 +504,30 @@ static NOINLINE int check_existence_through_netlink(void)
 
 		mhdr = (struct nlmsghdr*)replybuf;
 		while (bytes > 0) {
-			if (!NLMSG_OK(mhdr, bytes)
-			 || bytes < sizeof(struct nlmsghdr)
-			 || bytes < mhdr->nlmsg_len
-			) {
+			if (!NLMSG_OK(mhdr, bytes)) {
 				bb_error_msg("netlink packet too small or truncated");
 				return -1;
 			}
 
 			if (mhdr->nlmsg_type == RTM_NEWLINK || mhdr->nlmsg_type == RTM_DELLINK) {
 				struct rtattr *attr;
-				struct ifinfomsg *imsg;
 				int attr_len;
 
-				imsg = NLMSG_DATA(mhdr);
-
 				if (mhdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) {
 					bb_error_msg("netlink packet too small or truncated");
 					return -1;
 				}
 
-				attr = (struct rtattr*)((char*)imsg + NLMSG_ALIGN(sizeof(struct ifinfomsg)));
-				attr_len = NLMSG_PAYLOAD(mhdr, sizeof(struct ifinfomsg));
+				attr = IFLA_RTA(NLMSG_DATA(mhdr));
+				attr_len = IFLA_PAYLOAD(mhdr);
 
 				while (RTA_OK(attr, attr_len)) {
 					if (attr->rta_type == IFLA_IFNAME) {
-						char ifname[IFNAMSIZ + 1];
 						int len = RTA_PAYLOAD(attr);
-
 						if (len > IFNAMSIZ)
 							len = IFNAMSIZ;
-						memcpy(ifname, RTA_DATA(attr), len);
-						if (strcmp(G.iface, ifname) == 0) {
+
+						if (strncmp(G.iface, RTA_DATA(attr), len) == 0) {
 							G.iface_exists = (mhdr->nlmsg_type == RTM_NEWLINK);
 						}
 					}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to