diff options
author | Zhang zhengguang <zhengguang.zhang@intel.com> | 2014-07-17 10:37:39 +0800 |
---|---|---|
committer | Zhang zhengguang <zhengguang.zhang@intel.com> | 2014-07-17 10:37:39 +0800 |
commit | 1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7 (patch) | |
tree | 6e991827d28537f7f40f20786c2354fd04a9fdad /src/rtnl.c | |
parent | fbe905ab58ecc31fe64c410c5f580cadc30e7f04 (diff) | |
download | connman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.tar.gz connman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.tar.bz2 connman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.zip |
Imported Upstream version 1.24upstream/1.24
Diffstat (limited to 'src/rtnl.c')
-rw-r--r-- | src/rtnl.c | 180 |
1 files changed, 93 insertions, 87 deletions
@@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2007-2012 Intel Corporation. All rights reserved. + * Copyright (C) 2007-2013 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -65,7 +65,6 @@ static guint update_timeout = 0; struct interface_data { int index; - char *name; char *ident; enum connman_service_type service_type; enum connman_device_type device_type; @@ -78,53 +77,54 @@ static void free_interface(gpointer data) struct interface_data *interface = data; __connman_technology_remove_interface(interface->service_type, - interface->index, interface->name, interface->ident); + interface->index, interface->ident); g_free(interface->ident); - g_free(interface->name); g_free(interface); } -static connman_bool_t ether_blacklisted(const char *name) +static bool ether_blacklisted(const char *name) { - if (name == NULL) - return TRUE; + if (!name) + return true; - if (__connman_device_isfiltered(name) == TRUE) - return TRUE; + if (__connman_device_isfiltered(name)) + return true; - return FALSE; + return false; } -static connman_bool_t wext_interface(char *ifname) +static bool wext_interface(char *ifname) { struct iwreq wrq; int fd, err; fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (fd < 0) - return FALSE; + return false; memset(&wrq, 0, sizeof(wrq)); - strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + strncpy(wrq.ifr_name, ifname, sizeof(wrq.ifr_name) - 1); err = ioctl(fd, SIOCGIWNAME, &wrq); close(fd); if (err < 0) - return FALSE; + return false; - return TRUE; + return true; } static void read_uevent(struct interface_data *interface) { - char *filename, line[128]; - connman_bool_t found_devtype; + char *filename, *name, line[128]; + bool found_devtype; FILE *f; - if (ether_blacklisted(interface->name) == TRUE) { + name = connman_inet_ifname(interface->index); + + if (ether_blacklisted(name)) { interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN; } else { @@ -132,29 +132,31 @@ static void read_uevent(struct interface_data *interface) interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET; } - filename = g_strdup_printf("/sys/class/net/%s/uevent", - interface->name); + filename = g_strdup_printf("/sys/class/net/%s/uevent", name); f = fopen(filename, "re"); g_free(filename); - if (f == NULL) - return; + if (!f) { + interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; + interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN; + goto out; + } - found_devtype = FALSE; + found_devtype = false; while (fgets(line, sizeof(line), f)) { char *pos; pos = strchr(line, '\n'); - if (pos == NULL) + if (!pos) continue; pos[0] = '\0'; if (strncmp(line, "DEVTYPE=", 8) != 0) continue; - found_devtype = TRUE; + found_devtype = true; if (strcmp(line + 8, "wlan") == 0) { interface->service_type = CONNMAN_SERVICE_TYPE_WIFI; @@ -178,16 +180,18 @@ static void read_uevent(struct interface_data *interface) fclose(f); if (found_devtype) - return; + goto out; /* We haven't got a DEVTYPE, let's check if it's a wireless device */ - if (wext_interface(interface->name)) { + if (wext_interface(name)) { interface->service_type = CONNMAN_SERVICE_TYPE_WIFI; interface->device_type = CONNMAN_DEVICE_TYPE_WIFI; - connman_error("%s runs an unsupported 802.11 driver", - interface->name); + connman_error("%s runs an unsupported 802.11 driver", name); } + +out: + g_free(name); } enum connman_device_type __connman_rtnl_get_device_type(int index) @@ -196,7 +200,7 @@ enum connman_device_type __connman_rtnl_get_device_type(int index) interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index)); - if (interface == NULL) + if (!interface) return CONNMAN_DEVICE_TYPE_UNKNOWN; return interface->device_type; @@ -218,7 +222,7 @@ unsigned int connman_rtnl_add_newlink_watch(int index, struct watch_data *watch; watch = g_try_new0(struct watch_data, 1); - if (watch == NULL) + if (!watch) return 0; watch->id = ++watch_id; @@ -283,7 +287,7 @@ static void trigger_rtnl(int index, void *user_data) __connman_ipconfig_get_gateway_from_index(index, CONNMAN_IPCONFIG_TYPE_ALL); - if (gateway != NULL) + if (gateway) rtnl->newgateway(index, gateway); } } @@ -353,7 +357,7 @@ static const char *operstate2str(unsigned char operstate) return ""; } -static connman_bool_t extract_link(struct ifinfomsg *msg, int bytes, +static bool extract_link(struct ifinfomsg *msg, int bytes, struct ether_addr *address, const char **ifname, unsigned int *mtu, unsigned char *operstate, struct rtnl_link_stats *stats) @@ -364,41 +368,40 @@ static connman_bool_t extract_link(struct ifinfomsg *msg, int bytes, attr = RTA_NEXT(attr, bytes)) { switch (attr->rta_type) { case IFLA_ADDRESS: - if (address != NULL) + if (address) memcpy(address, RTA_DATA(attr), ETH_ALEN); break; case IFLA_IFNAME: - if (ifname != NULL) + if (ifname) *ifname = RTA_DATA(attr); break; case IFLA_MTU: - if (mtu != NULL) + if (mtu) *mtu = *((unsigned int *) RTA_DATA(attr)); break; case IFLA_STATS: - if (stats != NULL) + if (stats) memcpy(stats, RTA_DATA(attr), sizeof(struct rtnl_link_stats)); break; case IFLA_OPERSTATE: - if (operstate != NULL) + if (operstate) *operstate = *((unsigned char *) RTA_DATA(attr)); break; case IFLA_LINKMODE: break; case IFLA_WIRELESS: - return FALSE; + return false; } } - return TRUE; + return true; } static void process_newlink(unsigned short type, int index, unsigned flags, unsigned change, struct ifinfomsg *msg, int bytes) { struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }}; - struct ether_addr compare = {{ 0, 0, 0, 0, 0, 0 }}; struct rtnl_link_stats stats; unsigned char operstate = 0xff; struct interface_data *interface; @@ -408,8 +411,7 @@ static void process_newlink(unsigned short type, int index, unsigned flags, GSList *list; memset(&stats, 0, sizeof(stats)); - if (extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, - &stats) == FALSE) + if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats)) return; snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x", @@ -428,6 +430,12 @@ static void process_newlink(unsigned short type, int index, unsigned flags, address.ether_addr_octet[4], address.ether_addr_octet[5]); + if (flags & IFF_SLAVE) { + connman_info("%s {newlink} ignoring slave, index %d address %s", + ifname, index, str); + return; + } + switch (type) { case ARPHRD_ETHER: case ARPHRD_LOOPBACK: @@ -439,9 +447,8 @@ static void process_newlink(unsigned short type, int index, unsigned flags, break; } - if (memcmp(&address, &compare, ETH_ALEN) != 0) - connman_info("%s {newlink} index %d address %s mtu %u", - ifname, index, str, mtu); + connman_info("%s {newlink} index %d address %s mtu %u", + ifname, index, str, mtu); if (operstate != 0xff) connman_info("%s {newlink} index %d operstate %u <%s>", @@ -449,10 +456,9 @@ static void process_newlink(unsigned short type, int index, unsigned flags, operstate2str(operstate)); interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index)); - if (interface == NULL) { + if (!interface) { interface = g_new0(struct interface_data, 1); interface->index = index; - interface->name = g_strdup(ifname); interface->ident = g_strdup(ident); g_hash_table_insert(interface_list, @@ -476,9 +482,9 @@ static void process_newlink(unsigned short type, int index, unsigned flags, * __connman_technology_add_interface() expects the * technology to be there already. */ - if (interface != NULL) + if (interface) __connman_technology_add_interface(interface->service_type, - interface->index, interface->name, interface->ident); + interface->index, interface->ident); for (list = watch_list; list; list = list->next) { struct watch_data *watch = list->data; @@ -500,8 +506,7 @@ static void process_dellink(unsigned short type, int index, unsigned flags, GSList *list; memset(&stats, 0, sizeof(stats)); - if (extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, - &stats) == FALSE) + if (!extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats)) return; if (operstate != 0xff) @@ -519,6 +524,8 @@ static void process_dellink(unsigned short type, int index, unsigned flags, switch (type) { case ARPHRD_ETHER: case ARPHRD_LOOPBACK: + case ARPHDR_PHONET_PIPE: + case ARPHRD_PPP: case ARPHRD_NONE: __connman_ipconfig_dellink(index, &stats); break; @@ -539,19 +546,19 @@ static void extract_ipv4_addr(struct ifaddrmsg *msg, int bytes, attr = RTA_NEXT(attr, bytes)) { switch (attr->rta_type) { case IFA_ADDRESS: - if (address != NULL) + if (address) *address = *((struct in_addr *) RTA_DATA(attr)); break; case IFA_LOCAL: - if (local != NULL) + if (local) *local = *((struct in_addr *) RTA_DATA(attr)); break; case IFA_BROADCAST: - if (broadcast != NULL) + if (broadcast) *broadcast = *((struct in_addr *) RTA_DATA(attr)); break; case IFA_LABEL: - if (label != NULL) + if (label) *label = RTA_DATA(attr); break; } @@ -568,11 +575,11 @@ static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes, attr = RTA_NEXT(attr, bytes)) { switch (attr->rta_type) { case IFA_ADDRESS: - if (addr != NULL) + if (addr) *addr = *((struct in6_addr *) RTA_DATA(attr)); break; case IFA_LOCAL: - if (local != NULL) + if (local) *local = *((struct in6_addr *) RTA_DATA(attr)); break; } @@ -582,18 +589,17 @@ static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes, static void process_newaddr(unsigned char family, unsigned char prefixlen, int index, struct ifaddrmsg *msg, int bytes) { + struct in_addr ipv4_addr = { INADDR_ANY }; + struct in6_addr ipv6_address, ipv6_local; const char *label = NULL; void *src; char ip_string[INET6_ADDRSTRLEN]; if (family == AF_INET) { - struct in_addr ipv4_addr = { INADDR_ANY }; extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL); src = &ipv4_addr; } else if (family == AF_INET6) { - struct in6_addr ipv6_address, ipv6_local; - extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local); if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address)) return; @@ -603,7 +609,7 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen, return; } - if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL) + if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN)) return; __connman_ipconfig_newaddr(index, family, label, @@ -623,18 +629,16 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen, static void process_deladdr(unsigned char family, unsigned char prefixlen, int index, struct ifaddrmsg *msg, int bytes) { + struct in_addr ipv4_addr = { INADDR_ANY }; + struct in6_addr ipv6_address, ipv6_local; const char *label = NULL; void *src; char ip_string[INET6_ADDRSTRLEN]; if (family == AF_INET) { - struct in_addr ipv4_addr = { INADDR_ANY }; - extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL); src = &ipv4_addr; } else if (family == AF_INET6) { - struct in6_addr ipv6_address, ipv6_local; - extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local); if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address)) return; @@ -644,7 +648,7 @@ static void process_deladdr(unsigned char family, unsigned char prefixlen, return; } - if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL) + if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN)) return; __connman_ipconfig_deladdr(index, family, label, @@ -661,15 +665,15 @@ static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index, attr = RTA_NEXT(attr, bytes)) { switch (attr->rta_type) { case RTA_DST: - if (dst != NULL) + if (dst) *dst = *((struct in_addr *) RTA_DATA(attr)); break; case RTA_GATEWAY: - if (gateway != NULL) + if (gateway) *gateway = *((struct in_addr *) RTA_DATA(attr)); break; case RTA_OIF: - if (index != NULL) + if (index) *index = *((int *) RTA_DATA(attr)); break; } @@ -686,16 +690,16 @@ static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index, attr = RTA_NEXT(attr, bytes)) { switch (attr->rta_type) { case RTA_DST: - if (dst != NULL) + if (dst) *dst = *((struct in6_addr *) RTA_DATA(attr)); break; case RTA_GATEWAY: - if (gateway != NULL) + if (gateway) *gateway = *((struct in6_addr *) RTA_DATA(attr)); break; case RTA_OIF: - if (index != NULL) + if (index) *index = *((int *) RTA_DATA(attr)); break; } @@ -947,6 +951,9 @@ static void rtnl_newlink(struct nlmsghdr *hdr) rtnl_link(hdr); + if (hdr->nlmsg_type == IFLA_WIRELESS) + connman_warn_once("Obsolete WEXT WiFi driver detected"); + process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags, msg->ifi_change, msg, IFA_PAYLOAD(hdr)); } @@ -1074,20 +1081,20 @@ static void rtnl_route(struct nlmsghdr *hdr) } } -static connman_bool_t is_route_rtmsg(struct rtmsg *msg) +static bool is_route_rtmsg(struct rtmsg *msg) { if (msg->rtm_table != RT_TABLE_MAIN) - return FALSE; + return false; if (msg->rtm_protocol != RTPROT_BOOT && msg->rtm_protocol != RTPROT_KERNEL) - return FALSE; + return false; if (msg->rtm_type != RTN_UNICAST) - return FALSE; + return false; - return TRUE; + return true; } static void rtnl_newroute(struct nlmsghdr *hdr) @@ -1238,7 +1245,7 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) g_free(domains); domains = rtnl_nd_opt_dnssl(opt, &lifetime); - for (i = 0; domains != NULL && domains[i] != NULL; i++) + for (i = 0; domains && domains[i]; i++) connman_resolver_append_lifetime(index, domains[i], NULL, lifetime); } @@ -1344,13 +1351,13 @@ static int process_response(guint32 seq) DBG("seq %d", seq); req = find_request(seq); - if (req != NULL) { + if (req) { request_list = g_slist_remove(request_list, req); g_free(req); } req = g_slist_nth_data(request_list, 0); - if (req == NULL) + if (!req) return 0; return send_request(req); @@ -1413,8 +1420,7 @@ static void rtnl_message(void *buf, size_t len) } } -static gboolean netlink_event(GIOChannel *chan, - GIOCondition cond, gpointer data) +static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[4096]; struct sockaddr_nl nladdr; @@ -1459,7 +1465,7 @@ static int send_getlink(void) DBG(""); req = g_try_malloc0(RTNL_REQUEST_SIZE); - if (req == NULL) + if (!req) return -ENOMEM; req->hdr.nlmsg_len = RTNL_REQUEST_SIZE; @@ -1479,7 +1485,7 @@ static int send_getaddr(void) DBG(""); req = g_try_malloc0(RTNL_REQUEST_SIZE); - if (req == NULL) + if (!req) return -ENOMEM; req->hdr.nlmsg_len = RTNL_REQUEST_SIZE; @@ -1499,7 +1505,7 @@ static int send_getroute(void) DBG(""); req = g_try_malloc0(RTNL_REQUEST_SIZE); - if (req == NULL) + if (!req) return -ENOMEM; req->hdr.nlmsg_len = RTNL_REQUEST_SIZE; @@ -1570,7 +1576,7 @@ unsigned int __connman_rtnl_update_interval_remove(unsigned int interval) update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval)); - if (update_list != NULL) + if (update_list) min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0)); if (min > update_interval) |