From: Artem Bityutskiy Date: Thu, 20 Sep 2012 11:53:51 +0000 (+0300) Subject: wifi: Fix tethering with kernel 3.5 X-Git-Tag: 1.8~83 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0102a3fb69c0e4ba5504f9ae4fe7d94998813373;p=platform%2Fupstream%2Fconnman.git wifi: Fix tethering with kernel 3.5 Wifi tethering works with kernel 3.4, but not with 3.5. Bisecting showed that the following kernel patch causes the breakage: "3edaf3e mac80211: manage AP netdev carrier state". Running connman with debugging enabled showed that in case of 3.4 we have the following sequence of RTM_NEWLINK events from the kernel: 1. IFF_UP not set, ifi_change=1 2. IFF_UP,IFF_LOWER_UP, ifi_change=1 which makes connman do the following: connmand[210]: plugins/wifi.c:wifi_newlink() index 4 flags 4098 change 1 connmand[210]: plugins/wifi.c:wifi_newlink() interface down connmand[210]: plugins/wifi.c:wifi_newlink() index 4 flags 69635 change 1 connmand[210]: plugins/wifi.c:wifi_newlink() interface up connmand[210]: plugins/wifi.c:wifi_newlink() carrier on connmand[210]: plugins/wifi.c:handle_tethering() index 4 bridge tether However, in 3.5 we have the following sequents of events from the kernel: 1. IFF_UP, ifi_change=1 2. IFF_UP,IFF_LOWER_UP, ifi_change=0 which makes connman do the following: connmand[493]: plugins/wifi.c:wifi_newlink() index 4 flags 4099 change 1 connmand[493]: plugins/wifi.c:wifi_newlink() interface up connmand[493]: plugins/wifi.c:wifi_newlink() index 4 flags 69635 change 0 The root-cause for it is that connman handles the "ifi_change" flag incorrectly. Connman interprets it as "if non-zero, there was some change", which is wrong. According to RFC 3549, it is "reserved for future use. Must be set to 0xFFFFFFFF". Thus, just remove that check, which makes tethering work. --- diff --git a/plugins/wifi.c b/plugins/wifi.c index f5690b54..2d81f806 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -142,9 +142,6 @@ static void wifi_newlink(unsigned flags, unsigned change, void *user_data) DBG("index %d flags %d change %d", wifi->index, flags, change); - if (!change) - return; - if ((wifi->flags & IFF_UP) != (flags & IFF_UP)) { if (flags & IFF_UP) DBG("interface up");