aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-01-08 12:27:57 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-01-08 12:28:47 +0100
commitf422a722bb7c0b39a086255380c87eb4ba7af45b (patch)
treed05655f447a76ae037ae2bf8a9a6a8079f4c6b31
parent9037787eaee5efb58fd46f326397193b16b161dd (diff)
downloadbusybox-w32-f422a722bb7c0b39a086255380c87eb4ba7af45b.tar.gz
busybox-w32-f422a722bb7c0b39a086255380c87eb4ba7af45b.tar.bz2
busybox-w32-f422a722bb7c0b39a086255380c87eb4ba7af45b.zip
ifplugd: restore auto-ifup unless -a; make iff method less iffy :D
function old new delta up_iface - 112 +112 network_ioctl 13 38 +25 detect_link_iff 58 71 +13 detect_link 143 152 +9 ifplugd_main 1107 1109 +2 detect_link_wlan 131 125 -6 detect_link_ethtool 71 65 -6 detect_link_priv 88 80 -8 detect_link_mii 88 80 -8 maybe_up_new_iface 144 27 -117 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 4/5 up/down: 161/-145) Total: 16 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/ifplugd.c72
1 files changed, 34 insertions, 38 deletions
diff --git a/networking/ifplugd.c b/networking/ifplugd.c
index 458553013..ac6607c91 100644
--- a/networking/ifplugd.c
+++ b/networking/ifplugd.c
@@ -210,9 +210,12 @@ static int run_script(const char *action)
210#endif 210#endif
211} 211}
212 212
213static int network_ioctl(int request, void* data) 213static int network_ioctl(int request, void* data, const char *errmsg)
214{ 214{
215 return ioctl(ioctl_fd, request, data); 215 int r = ioctl(ioctl_fd, request, data);
216 if (r < 0 && errmsg)
217 bb_perror_msg(errmsg);
218 return r;
216} 219}
217 220
218static void set_ifreq_to_ifname(struct ifreq *ifreq) 221static void set_ifreq_to_ifname(struct ifreq *ifreq)
@@ -236,8 +239,7 @@ static void up_iface(void)
236 return; 239 return;
237 240
238 set_ifreq_to_ifname(&ifrequest); 241 set_ifreq_to_ifname(&ifrequest);
239 if (network_ioctl(SIOCGIFFLAGS, &ifrequest) < 0) { 242 if (network_ioctl(SIOCGIFFLAGS, &ifrequest, "can't get interface flags") < 0) {
240 bb_perror_msg("can't %cet interface flags", 'g');
241 G.iface_exists = 0; 243 G.iface_exists = 0;
242 return; 244 return;
243 } 245 }
@@ -246,24 +248,19 @@ static void up_iface(void)
246 ifrequest.ifr_flags |= IFF_UP; 248 ifrequest.ifr_flags |= IFF_UP;
247 /* Let user know we mess up with interface */ 249 /* Let user know we mess up with interface */
248 bb_error_msg("upping interface"); 250 bb_error_msg("upping interface");
249 if (network_ioctl(SIOCSIFFLAGS, &ifrequest) < 0) 251 if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "can't set interface flags") < 0)
250 bb_perror_msg_and_die("can't %cet interface flags", 's'); 252 xfunc_die();
251 } 253 }
252 254
253#if 0 /* why do we mess with IP addr? It's not our business */ 255#if 0 /* why do we mess with IP addr? It's not our business */
254 if (network_ioctl(SIOCGIFADDR, &ifrequest) < 0) { 256 if (network_ioctl(SIOCGIFADDR, &ifrequest, "can't get interface address") < 0) {
255 bb_error_msg("can't get interface address");
256 } else if (ifrequest.ifr_addr.sa_family != AF_INET) { 257 } else if (ifrequest.ifr_addr.sa_family != AF_INET) {
257 bb_perror_msg("the interface is not IP-based"); 258 bb_perror_msg("the interface is not IP-based");
258 } else { 259 } else {
259 ((struct sockaddr_in*)(&ifrequest.ifr_addr))->sin_addr.s_addr = INADDR_ANY; 260 ((struct sockaddr_in*)(&ifrequest.ifr_addr))->sin_addr.s_addr = INADDR_ANY;
260 if (network_ioctl(SIOCSIFADDR, &ifrequest) < 0) 261 network_ioctl(SIOCSIFADDR, &ifrequest, "can't set interface address");
261 bb_perror_msg("can't set interface address");
262 }
263 if (network_ioctl(SIOCGIFFLAGS, &ifrequest) < 0) {
264 bb_perror_msg("can't get interface flags");
265 return;
266 } 262 }
263 network_ioctl(SIOCGIFFLAGS, &ifrequest, "can't get interface flags");
267#endif 264#endif
268} 265}
269 266
@@ -279,13 +276,13 @@ static void maybe_up_new_iface(void)
279 set_ifreq_to_ifname(&ifrequest); 276 set_ifreq_to_ifname(&ifrequest);
280 driver_info.cmd = ETHTOOL_GDRVINFO; 277 driver_info.cmd = ETHTOOL_GDRVINFO;
281 ifrequest.ifr_data = &driver_info; 278 ifrequest.ifr_data = &driver_info;
282 if (network_ioctl(SIOCETHTOOL, &ifrequest) == 0) { 279 if (network_ioctl(SIOCETHTOOL, &ifrequest, NULL) == 0) {
283 char buf[sizeof("/xx:xx:xx:xx:xx:xx")]; 280 char buf[sizeof("/xx:xx:xx:xx:xx:xx")];
284 281
285 /* Get MAC */ 282 /* Get MAC */
286 buf[0] = '\0'; 283 buf[0] = '\0';
287 set_ifreq_to_ifname(&ifrequest); 284 set_ifreq_to_ifname(&ifrequest);
288 if (network_ioctl(SIOCGIFHWADDR, &ifrequest) == 0) { 285 if (network_ioctl(SIOCGIFHWADDR, &ifrequest, NULL) == 0) {
289 sprintf(buf, "/%02X:%02X:%02X:%02X:%02X:%02X", 286 sprintf(buf, "/%02X:%02X:%02X:%02X:%02X:%02X",
290 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[0]), 287 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[0]),
291 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[1]), 288 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[1]),
@@ -310,15 +307,13 @@ static smallint detect_link_mii(void)
310 307
311 set_ifreq_to_ifname(&ifreq); 308 set_ifreq_to_ifname(&ifreq);
312 309
313 if (network_ioctl(SIOCGMIIPHY, &ifreq) < 0) { 310 if (network_ioctl(SIOCGMIIPHY, &ifreq, "SIOCGMIIPHY failed") < 0) {
314 bb_perror_msg("SIOCGMIIPHY failed");
315 return IFSTATUS_ERR; 311 return IFSTATUS_ERR;
316 } 312 }
317 313
318 mii->reg_num = 1; 314 mii->reg_num = 1;
319 315
320 if (network_ioctl(SIOCGMIIREG, &ifreq) < 0) { 316 if (network_ioctl(SIOCGMIIREG, &ifreq, "SIOCGMIIREG failed") < 0) {
321 bb_perror_msg("SIOCGMIIREG failed");
322 return IFSTATUS_ERR; 317 return IFSTATUS_ERR;
323 } 318 }
324 319
@@ -332,15 +327,13 @@ static smallint detect_link_priv(void)
332 327
333 set_ifreq_to_ifname(&ifreq); 328 set_ifreq_to_ifname(&ifreq);
334 329
335 if (network_ioctl(SIOCDEVPRIVATE, &ifreq) < 0) { 330 if (network_ioctl(SIOCDEVPRIVATE, &ifreq, "SIOCDEVPRIVATE failed") < 0) {
336 bb_perror_msg("SIOCDEVPRIVATE failed");
337 return IFSTATUS_ERR; 331 return IFSTATUS_ERR;
338 } 332 }
339 333
340 mii->reg_num = 1; 334 mii->reg_num = 1;
341 335
342 if (network_ioctl(SIOCDEVPRIVATE+1, &ifreq) < 0) { 336 if (network_ioctl(SIOCDEVPRIVATE+1, &ifreq, "SIOCDEVPRIVATE+1 failed") < 0) {
343 bb_perror_msg("SIOCDEVPRIVATE+1 failed");
344 return IFSTATUS_ERR; 337 return IFSTATUS_ERR;
345 } 338 }
346 339
@@ -357,8 +350,7 @@ static smallint detect_link_ethtool(void)
357 edata.cmd = ETHTOOL_GLINK; 350 edata.cmd = ETHTOOL_GLINK;
358 ifreq.ifr_data = (void*) &edata; 351 ifreq.ifr_data = (void*) &edata;
359 352
360 if (network_ioctl(SIOCETHTOOL, &ifreq) < 0) { 353 if (network_ioctl(SIOCETHTOOL, &ifreq, "ETHTOOL_GLINK failed") < 0) {
361 bb_perror_msg("ETHTOOL_GLINK failed");
362 return IFSTATUS_ERR; 354 return IFSTATUS_ERR;
363 } 355 }
364 356
@@ -371,11 +363,19 @@ static smallint detect_link_iff(void)
371 363
372 set_ifreq_to_ifname(&ifreq); 364 set_ifreq_to_ifname(&ifreq);
373 365
374 if (network_ioctl(SIOCGIFFLAGS, &ifreq) < 0) { 366 if (network_ioctl(SIOCGIFFLAGS, &ifreq, "SIOCGIFFLAGS failed") < 0) {
375 bb_perror_msg("SIOCGIFFLAGS failed");
376 return IFSTATUS_ERR; 367 return IFSTATUS_ERR;
377 } 368 }
378 369
370 /* If IFF_UP is not set (interface is down), IFF_RUNNING is never set
371 * regardless of link status. Simply continue to report last status -
372 * no point in reporting spurious link downs if interface is disabled
373 * by admin. When/if it will be brought up,
374 * we'll report real link status.
375 */
376 if (!(ifreq.ifr_flags & IFF_UP) && G.iface_last_status != IFSTATUS_ERR)
377 return G.iface_last_status;
378
379 return (ifreq.ifr_flags & IFF_RUNNING) ? IFSTATUS_UP : IFSTATUS_DOWN; 379 return (ifreq.ifr_flags & IFF_RUNNING) ? IFSTATUS_UP : IFSTATUS_DOWN;
380} 380}
381 381
@@ -387,8 +387,7 @@ static smallint detect_link_wlan(void)
387 memset(&iwrequest, 0, sizeof(struct iwreq)); 387 memset(&iwrequest, 0, sizeof(struct iwreq));
388 strncpy_IFNAMSIZ(iwrequest.ifr_ifrn.ifrn_name, G.iface); 388 strncpy_IFNAMSIZ(iwrequest.ifr_ifrn.ifrn_name, G.iface);
389 389
390 if (network_ioctl(SIOCGIWAP, &iwrequest) < 0) { 390 if (network_ioctl(SIOCGIWAP, &iwrequest, "SIOCGIWAP failed") < 0) {
391 bb_perror_msg("SIOCGIWAP failed");
392 return IFSTATUS_ERR; 391 return IFSTATUS_ERR;
393 } 392 }
394 393
@@ -469,15 +468,12 @@ static smallint detect_link(void)
469 if (!G.iface_exists) 468 if (!G.iface_exists)
470 return (option_mask32 & FLAG_MONITOR) ? IFSTATUS_DOWN : IFSTATUS_ERR; 469 return (option_mask32 & FLAG_MONITOR) ? IFSTATUS_DOWN : IFSTATUS_ERR;
471 470
472#if 0 471 /* Some drivers can't detect link status when the interface is down.
473/* Why? This behavior makes it hard to temporary down the iface. 472 * I imagine detect_link_iff() is the most vulnerable.
474 * It makes a bit more sense to do only in maybe_up_new_iface. 473 * That's why -a "noauto" in an option, not a hardwired behavior.
475 * OTOH, maybe detect_link_wlan needs this. Then it should be done 474 */
476 * _only_ there.
477 */
478 if (!(option_mask32 & FLAG_NO_AUTO)) 475 if (!(option_mask32 & FLAG_NO_AUTO))
479 up_iface(); 476 up_iface();
480#endif
481 477
482 status = G.detect_link_func(); 478 status = G.detect_link_func();
483 if (status == IFSTATUS_ERR) { 479 if (status == IFSTATUS_ERR) {
@@ -692,7 +688,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
692 if (opts & FLAG_MONITOR) { 688 if (opts & FLAG_MONITOR) {
693 struct ifreq ifrequest; 689 struct ifreq ifrequest;
694 set_ifreq_to_ifname(&ifrequest); 690 set_ifreq_to_ifname(&ifrequest);
695 G.iface_exists = (network_ioctl(SIOCGIFINDEX, &ifrequest) == 0); 691 G.iface_exists = (network_ioctl(SIOCGIFINDEX, &ifrequest, NULL) == 0);
696 } 692 }
697 693
698 if (G.iface_exists) 694 if (G.iface_exists)