X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Frtnl.c;h=40ede4f4efaf6e979cf4ce087f937bfe914b3d9d;hb=bf0e619ef451bde3568c1af509ccb12cbda2ff93;hp=c9e84daba4582831a9f3f987b7184420faf977e2;hpb=f89b473dfd8e916314b534b3397442f8c869c783;p=platform%2Fupstream%2Fconnman.git diff --git a/src/rtnl.c b/src/rtnl.c index c9e84da..40ede4f 100644 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -46,6 +46,12 @@ #define ARPHDR_PHONET_PIPE (821) #endif +#if defined TIZEN_EXT +#ifndef ARPHDR_RMNET +#define ARPHDR_RMNET (530) +#endif +#endif + #define print(arg...) do { if (0) connman_info(arg); } while (0) //#define print(arg...) connman_info(arg) @@ -94,6 +100,7 @@ static bool ether_blacklisted(const char *name) return false; } +#if !defined TIZEN_EXT static bool wext_interface(char *ifname) { struct iwreq wrq; @@ -115,6 +122,30 @@ static bool wext_interface(char *ifname) return true; } +#endif + +#if defined TIZEN_EXT +static bool __connman_rtnl_is_cellular_device(const char *name) +{ + char **pattern; + char **cellular_interfaces; + + cellular_interfaces = + connman_setting_get_string_list( + "NetworkCellularInterfaceList"); + if (!cellular_interfaces) + return false; + + for (pattern = cellular_interfaces; *pattern; pattern++) { + if (g_str_has_prefix(name, *pattern)) { + DBG("Cellular interface: %s", name); + return true; + } + } + + return false; +} +#endif static void read_uevent(struct interface_data *interface) { @@ -124,6 +155,15 @@ static void read_uevent(struct interface_data *interface) name = connman_inet_ifname(interface->index); +#if defined TIZEN_EXT + if (__connman_rtnl_is_cellular_device(name)) { + interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR; + interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR; + g_free(name); + return; + } +#endif + if (ether_blacklisted(name)) { interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN; @@ -191,6 +231,8 @@ static void read_uevent(struct interface_data *interface) if (found_devtype) goto out; +#if !defined TIZEN_EXT + /* TIZEN does not use old wext interface */ /* We haven't got a DEVTYPE, let's check if it's a wireless device */ if (wext_interface(name)) { interface->service_type = CONNMAN_SERVICE_TYPE_WIFI; @@ -198,6 +240,7 @@ static void read_uevent(struct interface_data *interface) connman_error("%s runs an unsupported 802.11 driver", name); } +#endif out: g_free(name); @@ -423,6 +466,28 @@ static void process_newlink(unsigned short type, int index, unsigned flags, if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats)) return; +#if defined TIZEN_EXT_WIFI_MESH + /* Do not accept Wi-Fi Mesh interface */ + if (g_strrstr(ifname, "mesh") != NULL) { + DBG("Newlink event for Wi-Fi Mesh interface ignored"); + return; + } + + /* Do not accept Wi-Fi WLAN1 interface "dedicated for softAP */ + if (!g_strcmp0(ifname, "wlan1")) { + DBG("Newlink event for Wi-Fi WLAN1 interface ignored"); + return; + } +#endif + +#if defined TIZEN_EXT + /* Do not accept Wi-Fi P2P interface */ + if (g_strrstr(ifname, "p2p") != NULL) { + DBG("Newlink event for Wi-Fi P2P interface ignored"); + return; + } +#endif + snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x", address.ether_addr_octet[0], address.ether_addr_octet[1], @@ -445,12 +510,25 @@ static void process_newlink(unsigned short type, int index, unsigned flags, return; } +#ifdef TIZEN_EXT + if (TIZEN_TV_EXT && g_strcmp0(ident, "eeeeeeeeeeee") == 0) { + DBG("Newlink event with Dummy MAC. Ignored!"); + return; + } +#endif + switch (type) { case ARPHRD_ETHER: case ARPHRD_LOOPBACK: case ARPHDR_PHONET_PIPE: case ARPHRD_PPP: case ARPHRD_NONE: +#if defined TIZEN_EXT +/* + * Description: ARPHDR_RMNET for QC modem using QMI + */ + case ARPHDR_RMNET: +#endif __connman_ipconfig_newlink(index, type, flags, str, mtu, &stats); break; @@ -475,6 +553,25 @@ static void process_newlink(unsigned short type, int index, unsigned flags, if (type == ARPHRD_ETHER) read_uevent(interface); +#if defined TIZEN_EXT + if (type == ARPHRD_PPP || type == ARPHDR_RMNET) + read_uevent(interface); + + } else if (g_strcmp0(interface->ident, ident) != 0) { + /* If an original address is built-in physical device, + * it's hardly get an address at a initial creation + */ + __connman_technology_remove_interface(interface->service_type, + interface->index, interface->ident); + + g_free(interface->ident); + interface->ident = g_strdup(ident); + + __connman_technology_add_interface(interface->service_type, + interface->index, interface->ident); + + interface = NULL; +#endif } else if (type == ARPHRD_ETHER && interface->device_type == CONNMAN_DEVICE_TYPE_UNKNOWN) read_uevent(interface); else @@ -539,6 +636,13 @@ static void process_dellink(unsigned short type, int index, unsigned flags, case ARPHDR_PHONET_PIPE: case ARPHRD_PPP: case ARPHRD_NONE: +#if defined TIZEN_EXT + /* + * Description: SLP requires ARPHRD_PPP for PPP type device + * ARPHDR_RMNET for QC modem using QMI + */ + case ARPHDR_RMNET: +#endif __connman_ipconfig_dellink(index, &stats); break; } @@ -1234,6 +1338,37 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) if (index < 0) return; +#if defined TIZEN_EXT + struct connman_service *service; + enum connman_service_state state; + enum connman_dnsconfig_method ipv6_dns_method; + + service = __connman_service_lookup_from_index(index); + if (!service) { + DBG("Invalid service"); + return; + } + + DBG("service: %p index: %d\n", service, index); + + if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) { + state = __connman_service_ipconfig_get_state(service, CONNMAN_IPCONFIG_TYPE_IPV6); + if (state != CONNMAN_SERVICE_STATE_ASSOCIATION && + state != CONNMAN_SERVICE_STATE_CONFIGURATION && + state != CONNMAN_SERVICE_STATE_READY && + state != CONNMAN_SERVICE_STATE_ONLINE) { + DBG("Service state[%d] is not connecting/connected", state); + return; + } + } + + ipv6_dns_method = connman_service_get_ipv6_dns_method(service); + if (ipv6_dns_method != CONNMAN_DNSCONFIG_METHOD_DHCP) { + DBG("IPv6 DNS method is not Auto ignore RA!!! [DNS method: %d]", ipv6_dns_method); + return; + } +#endif + for (opt = (void *)&msg[1]; msglen > 0; msglen -= opt->nd_opt_len * 8, @@ -1244,7 +1379,12 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */ char buf[40]; +#if defined TIZEN_EXT + struct connman_service *service; + service = __connman_service_lookup_from_index(index); + DBG("service: %p\n",service); +#endif servers = rtnl_nd_opt_rdnss(opt, &lifetime, &nr_servers); for (i = 0; i < nr_servers; i++) { @@ -1252,6 +1392,14 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) sizeof(buf))) continue; +#if defined TIZEN_EXT + __connman_service_nameserver_remove(service, + buf, false, + CONNMAN_IPCONFIG_TYPE_IPV6); + __connman_service_nameserver_append(service, + buf, false, + CONNMAN_IPCONFIG_TYPE_IPV6); +#endif connman_resolver_append_lifetime(index, NULL, buf, lifetime); } @@ -1442,8 +1590,15 @@ static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data ssize_t status; int fd; +#if defined TIZEN_EXT + if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { + __connman_rtnl_init(GIO_SOCKET_RETRY_COUNT); + return FALSE; + } +#else /* TIZEN_EXT */ if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) return FALSE; +#endif /* TIZEN_EXT */ memset(buf, 0, sizeof(buf)); memset(&nladdr, 0, sizeof(nladdr)); @@ -1456,11 +1611,21 @@ static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data if (errno == EINTR || errno == EAGAIN) return TRUE; +#if defined TIZEN_EXT + __connman_rtnl_init(GIO_SOCKET_RETRY_COUNT); +#endif /* TIZEN_EXT */ return FALSE; } +#if defined TIZEN_EXT + if (status == 0) { + __connman_rtnl_init(GIO_SOCKET_RETRY_COUNT); + return FALSE; + } +#else /* TIZEN_EXT */ if (status == 0) return FALSE; +#endif /* TIZEN_EXT */ if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */ DBG("Received msg from %u, ignoring it", nladdr.nl_pid); @@ -1604,19 +1769,34 @@ int __connman_rtnl_request_update(void) return send_getlink(); } +#if defined TIZEN_EXT +int __connman_rtnl_init(int retry_count) +#else /* TIZEN_EXT */ int __connman_rtnl_init(void) +#endif /* TIZEN_EXT */ { struct sockaddr_nl addr; int sk; +#if defined TIZEN_EXT + if (retry_count < 0) + return -1; + + DBG("retry_count %d", retry_count); +#else /* TIZEN_EXT */ DBG(""); +#endif /* TIZEN_EXT */ interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_interface); sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE); if (sk < 0) +#if defined TIZEN_EXT + return __connman_rtnl_init(retry_count - 1); +#else /* TIZEN_EXT */ return -1; +#endif /* TIZEN_EXT */ memset(&addr, 0, sizeof(addr)); addr.nl_family = AF_NETLINK; @@ -1626,7 +1806,11 @@ int __connman_rtnl_init(void) if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { close(sk); +#if defined TIZEN_EXT + return __connman_rtnl_init(retry_count - 1); +#else /* TIZEN_EXT */ return -1; +#endif /* TIZEN_EXT */ } channel = g_io_channel_unix_new(sk);