diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-07-30 20:32:34 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-07-30 20:32:34 +0200 |
commit | 664fc8eb9dae45273e2d34eb80c1b0bad093542e (patch) | |
tree | 31f8cd448bb165ed32a6abb8011a2a7d48940be5 /plugins/ethernet.c | |
parent | 426271d6f854493529c28632152dec25a6142a1d (diff) | |
download | connman-664fc8eb9dae45273e2d34eb80c1b0bad093542e.tar.gz connman-664fc8eb9dae45273e2d34eb80c1b0bad093542e.tar.bz2 connman-664fc8eb9dae45273e2d34eb80c1b0bad093542e.zip |
Bring Ethernet device up and down if needed
Diffstat (limited to 'plugins/ethernet.c')
-rw-r--r-- | plugins/ethernet.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/plugins/ethernet.c b/plugins/ethernet.c index 21ca7fcb..b9089409 100644 --- a/plugins/ethernet.c +++ b/plugins/ethernet.c @@ -25,6 +25,7 @@ #include <unistd.h> #include <string.h> +#include <sys/ioctl.h> #include <sys/socket.h> #include <linux/if.h> #include <linux/netlink.h> @@ -219,6 +220,92 @@ static int rtnl_request(void) (struct sockaddr *) &addr, sizeof(addr)); } +static int iface_up(struct connman_element *element) +{ + struct ifreq ifr; + int sk, err; + + DBG("element %p", element); + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return -errno; + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = element->netdev.index; + + if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { + err = -errno; + goto done; + } + + if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) { + err = -errno; + goto done; + } + + if (ifr.ifr_flags & IFF_UP) { + err = -EALREADY; + goto done; + } + + ifr.ifr_flags |= IFF_UP; + + if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) { + err = -errno; + goto done; + } + + err = 0; + +done: + close(sk); + + return err; +} + +static int iface_down(struct connman_element *element) +{ + struct ifreq ifr; + int sk, err; + + DBG("element %p", element); + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return -errno; + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = element->netdev.index; + + if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { + err = -errno; + goto done; + } + + if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) { + err = -errno; + goto done; + } + + if (!(ifr.ifr_flags & IFF_UP)) { + err = -EALREADY; + goto done; + } + + ifr.ifr_flags &= ~IFF_UP; + + if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) + err = -errno; + else + err = 0; + +done: + close(sk); + + return err; +} + static int ethernet_probe(struct connman_element *element) { DBG("element %p name %s", element, element->name); @@ -227,6 +314,8 @@ static int ethernet_probe(struct connman_element *element) ethernet_list = g_slist_append(ethernet_list, element); g_static_mutex_unlock(ðernet_mutex); + iface_up(element); + rtnl_request(); return 0; @@ -236,6 +325,8 @@ static void ethernet_remove(struct connman_element *element) { DBG("element %p name %s", element, element->name); + iface_down(element); + remove_elements(element); g_static_mutex_lock(ðernet_mutex); |