ifplugd
Denys Vlasenko
vda.linux at googlemail.com
Sun Apr 26 01:16:12 UTC 2009
On Sunday 19 April 2009 02:04, Maksym Kryzhanovskyy wrote:
> 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
More information about the busybox
mailing list