@@ -56,6 +56,13 @@ static void GetAddrStr(const in_common_addr* aAddr, uint8_t aFamily,
5656 _retval.Assign (addr);
5757}
5858
59+ static void GetNeighborKey (const in_common_addr* aAddr, uint8_t aFamily,
60+ uint32_t aIfIndex, nsACString& _retval) {
61+ GetAddrStr (aAddr, aFamily, _retval);
62+ _retval.Append (" ," );
63+ _retval.AppendInt (aIfIndex);
64+ }
65+
5966class NetlinkAddress {
6067 public:
6168 NetlinkAddress () {}
@@ -129,6 +136,7 @@ class NetlinkNeighbor {
129136 NetlinkNeighbor () : mHasMAC (false ) {}
130137
131138 uint8_t Family () const { return mNeigh .ndm_family ; }
139+ uint32_t GetIndex () const { return mNeigh .ndm_ifindex ; }
132140 const in_common_addr* GetAddrPtr () const { return &mAddr ; }
133141 const uint8_t * GetMACPtr () const { return mMAC ; }
134142 bool HasMAC () const { return mHasMAC ; };
@@ -246,7 +254,8 @@ class NetlinkRoute {
246254 : mHasGWAddr (false ),
247255 mHasPrefSrcAddr (false ),
248256 mHasDstAddr(false ),
249- mHasOif(false ) {}
257+ mHasOif(false ),
258+ mHasPrio(false ) {}
250259
251260 bool IsUnicast () const { return mRtm .rtm_type == RTN_UNICAST ; }
252261 bool IsDefault () const { return mRtm .rtm_dst_len == 0 ; }
@@ -270,6 +279,9 @@ class NetlinkRoute {
270279 if (mHasOif != aOther->mHasOif || mOif != aOther->mOif ) {
271280 return false ;
272281 }
282+ if (mHasPrio != aOther->mHasPrio || mPrio != aOther->mPrio ) {
283+ return false ;
284+ }
273285 if ((mHasGWAddr != aOther->mHasGWAddr ) ||
274286 (mHasGWAddr && memcmp (&mGWAddr , &(aOther->mGWAddr ), addrSize))) {
275287 return false ;
@@ -356,6 +368,10 @@ class NetlinkRoute {
356368 _retval.Append (" oif=" );
357369 _retval.AppendInt (mOif );
358370 }
371+ if (mHasPrio ) {
372+ _retval.Append (" prio=" );
373+ _retval.AppendInt (mPrio );
374+ }
359375 }
360376#endif
361377
@@ -390,6 +406,9 @@ class NetlinkRoute {
390406 } else if (attr->rta_type == RTA_OIF ) {
391407 mOif = *(uint32_t *)RTA_DATA (attr);
392408 mHasOif = true ;
409+ } else if (attr->rta_type == RTA_PRIORITY ) {
410+ mPrio = *(uint32_t *)RTA_DATA (attr);
411+ mHasPrio = true ;
393412 }
394413 }
395414
@@ -402,12 +421,14 @@ class NetlinkRoute {
402421 bool mHasPrefSrcAddr : 1 ;
403422 bool mHasDstAddr : 1 ;
404423 bool mHasOif : 1 ;
424+ bool mHasPrio : 1 ;
405425
406426 in_common_addr mGWAddr ;
407427 in_common_addr mDstAddr ;
408428 in_common_addr mPrefSrcAddr ;
409429
410430 uint32_t mOif ;
431+ uint32_t mPrio ;
411432 struct rtmsg mRtm ;
412433};
413434
@@ -536,7 +557,7 @@ NetlinkService::NetlinkService()
536557 mInitialScanFinished(false ),
537558 mDoRouteCheckIPv4(false ),
538559 mDoRouteCheckIPv6(false ),
539- mMsgId(1 ),
560+ mMsgId(0 ),
540561 mLinkUp(true ),
541562 mRecalculateNetworkId(false ) {
542563 mPid = getpid ();
@@ -610,11 +631,13 @@ void NetlinkService::OnNetlinkMessage(int aNetlinkSocket) {
610631 switch (nlh->nlmsg_type ) {
611632 case NLMSG_DONE : /* Message signalling end of dump for responses to
612633 request containing NLM_F_DUMP flag */
634+ LOG ((" received NLMSG_DONE" ));
613635 if (isResponse) {
614636 RemovePendingMsg ();
615637 }
616638 break ;
617639 case NLMSG_ERROR :
640+ LOG ((" received NLMSG_ERROR" ));
618641 if (isResponse) {
619642 if (mOutgoingMessages [0 ]->MsgType () == NetlinkMsg::kRtMsg ) {
620643 OnRouteCheckResult (nullptr );
@@ -659,7 +682,9 @@ void NetlinkService::OnNetlinkMessage(int aNetlinkSocket) {
659682}
660683
661684void NetlinkService::OnLinkMessage (struct nlmsghdr * aNlh) {
662- LOG ((" NetlinkService::OnLinkMessage" ));
685+ LOG ((" NetlinkService::OnLinkMessage [type=%s]" ,
686+ aNlh->nlmsg_type == RTM_NEWLINK ? " new" : " del" ));
687+
663688 nsAutoPtr<NetlinkLink> link (new NetlinkLink ());
664689 if (!link->Init (aNlh)) {
665690 return ;
@@ -737,7 +762,9 @@ void NetlinkService::CheckLinks() {
737762}
738763
739764void NetlinkService::OnAddrMessage (struct nlmsghdr * aNlh) {
740- LOG ((" NetlinkService::OnAddrMessage" ));
765+ LOG ((" NetlinkService::OnAddrMessage [type=%s]" ,
766+ aNlh->nlmsg_type == RTM_NEWADDR ? " new" : " del" ));
767+
741768 nsAutoPtr<NetlinkAddress> address (new NetlinkAddress ());
742769 if (!address->Init (aNlh)) {
743770 return ;
@@ -779,7 +806,9 @@ void NetlinkService::OnAddrMessage(struct nlmsghdr* aNlh) {
779806}
780807
781808void NetlinkService::OnRouteMessage (struct nlmsghdr * aNlh) {
782- LOG ((" NetlinkService::OnRouteMessage" ));
809+ LOG ((" NetlinkService::OnRouteMessage [type=%s]" ,
810+ aNlh->nlmsg_type == RTM_NEWROUTE ? " new" : " del" ));
811+
783812 nsAutoPtr<NetlinkRoute> route (new NetlinkRoute ());
784813 if (!route->Init (aNlh)) {
785814 return ;
@@ -806,9 +835,9 @@ void NetlinkService::OnRouteMessage(struct nlmsghdr* aNlh) {
806835 if (!route->IsDefault ()) {
807836 // Store only default routes
808837#ifdef NL_DEBUG_LOG
809- LOG ((" Not storing non-unicast route: %s" , routeDbgStr.get ()));
838+ LOG ((" Not a default route: %s" , routeDbgStr.get ()));
810839#else
811- LOG ((" Not storing non-unicast route" ));
840+ LOG ((" Not a default route" ));
812841#endif
813842 return ;
814843 }
@@ -845,14 +874,17 @@ void NetlinkService::OnRouteMessage(struct nlmsghdr* aNlh) {
845874}
846875
847876void NetlinkService::OnNeighborMessage (struct nlmsghdr * aNlh) {
848- LOG ((" NetlinkService::OnNeighborMessage" ));
877+ LOG ((" NetlinkService::OnNeighborMessage [type=%s]" ,
878+ aNlh->nlmsg_type == RTM_NEWNEIGH ? " new" : " del" ));
879+
849880 nsAutoPtr<NetlinkNeighbor> neigh (new NetlinkNeighbor ());
850881 if (!neigh->Init (aNlh)) {
851882 return ;
852883 }
853884
854- nsAutoCString addrStr;
855- GetAddrStr (neigh->GetAddrPtr (), neigh->Family (), addrStr);
885+ nsAutoCString neighKey;
886+ GetNeighborKey (neigh->GetAddrPtr (), neigh->Family (), neigh->GetIndex (),
887+ neighKey);
856888
857889 nsTArray<nsAutoPtr<NetlinkRoute> >* routesPtr;
858890 nsAutoPtr<NetlinkRoute>* routeCheckResultPtr;
@@ -867,7 +899,7 @@ void NetlinkService::OnNeighborMessage(struct nlmsghdr* aNlh) {
867899 if (aNlh->nlmsg_type == RTM_NEWNEIGH ) {
868900 if (!mRecalculateNetworkId && neigh->HasMAC ()) {
869901 NetlinkNeighbor* oldNeigh = nullptr ;
870- mNeighbors .Get (addrStr , &oldNeigh);
902+ mNeighbors .Get (neighKey , &oldNeigh);
871903
872904 if (!oldNeigh || !oldNeigh->HasMAC ()) {
873905 // The MAC address was added, if it's a host from some of the saved
@@ -890,14 +922,14 @@ void NetlinkService::OnNeighborMessage(struct nlmsghdr* aNlh) {
890922 neigh->GetAsString (neighDbgStr);
891923 LOG ((" Adding neighbor: %s" , neighDbgStr.get ()));
892924#else
893- LOG ((" Adding neighbor %s" , addrStr .get ()));
925+ LOG ((" Adding neighbor %s" , neighKey .get ()));
894926#endif
895- mNeighbors .Put (addrStr , neigh.forget ());
927+ mNeighbors .Put (neighKey , neigh.forget ());
896928 } else {
897929#ifdef NL_DEBUG_LOG
898- LOG ((" Removing neighbor %s" , addrStr .get ()));
930+ LOG ((" Removing neighbor %s" , neighKey .get ()));
899931#endif
900- mNeighbors .Remove (addrStr );
932+ mNeighbors .Remove (neighKey );
901933 }
902934}
903935
@@ -937,7 +969,7 @@ void NetlinkService::OnRouteCheckResult(struct nlmsghdr* aNlh) {
937969 LOG ((" Storing result for the check" ));
938970#endif
939971 } else {
940- LOG ((" Clearing result for the checkd " ));
972+ LOG ((" Clearing result for the check " ));
941973 }
942974
943975 (*routeCheckResultPtr) = route.forget ();
@@ -954,6 +986,9 @@ void NetlinkService::EnqueueRtMsg(uint8_t aFamily, void* aAddress) {
954986}
955987
956988void NetlinkService::RemovePendingMsg () {
989+ LOG ((" NetlinkService::RemovePendingMsg [seqId=%u]" ,
990+ mOutgoingMessages [0 ]->SeqId ()));
991+
957992 MOZ_ASSERT (mOutgoingMessages [0 ]->IsPending ());
958993
959994 DebugOnly<bool > isRtMessage =
@@ -1219,33 +1254,42 @@ bool NetlinkService::CalculateIDForFamily(uint8_t aFamily, SHA1Sum* aSHA1) {
12191254 (*routesPtr)[i]->GetAsString (routeDbgStr);
12201255 LOG ((" Checking default route: %s" , routeDbgStr.get ()));
12211256#endif
1222- nsAutoCString addrStr;
1257+ if (!(*routesPtr)[i]->HasOif ()) {
1258+ LOG ((" There is no output interface in default route." ));
1259+ continue ;
1260+ }
1261+
1262+ nsAutoCString neighKey;
12231263 const in_common_addr* addrPtr = (*routesPtr)[i]->GetGWAddrPtr ();
12241264 if (!addrPtr) {
12251265 LOG ((" There is no GW address in default route." ));
12261266 continue ;
12271267 }
12281268
1229- GetAddrStr (addrPtr, (*routesPtr)[i]->Family (), addrStr);
1269+ GetNeighborKey (addrPtr, (*routesPtr)[i]->Family (), (*routesPtr)[i]->Oif (),
1270+ neighKey);
1271+
12301272 NetlinkNeighbor* neigh = nullptr ;
1231- if (!mNeighbors .Get (addrStr , &neigh)) {
1232- LOG ((" Neighbor %s not found in hashtable." , addrStr .get ()));
1273+ if (!mNeighbors .Get (neighKey , &neigh)) {
1274+ LOG ((" Neighbor %s not found in hashtable." , neighKey .get ()));
12331275 continue ;
12341276 }
12351277
12361278 if (!neigh->HasMAC ()) {
12371279 // We don't know MAC address
1238- LOG ((" We have no MAC for neighbor %s." , addrStr .get ()));
1280+ LOG ((" We have no MAC for neighbor %s." , neighKey .get ()));
12391281 continue ;
12401282 }
12411283
1242- if (gwNeighbors.IndexOf (neigh) != gwNeighbors.NoIndex ) {
1284+ if (gwNeighbors.IndexOf (neigh, 0 , NeighborComparator ()) !=
1285+ nsTArray<NetlinkNeighbor*>::NoIndex) {
12431286 // avoid host duplicities
1244- LOG ((" Neighbor %s is already selected for hashing." , addrStr.get ()));
1287+ LOG ((" MAC of neighbor %s is already selected for hashing." ,
1288+ neighKey.get ()));
12451289 continue ;
12461290 }
12471291
1248- LOG ((" Neighbor %s will be used for network ID." , addrStr .get ()));
1292+ LOG ((" MAC of neighbor %s will be used for network ID." , neighKey .get ()));
12491293 gwNeighbors.AppendElement (neigh);
12501294 }
12511295
@@ -1311,24 +1355,25 @@ bool NetlinkService::CalculateIDForFamily(uint8_t aFamily, SHA1Sum* aSHA1) {
13111355
13121356 // Check whether we know next hop for mRouteCheckIPv4/6 host
13131357 const in_common_addr* addrPtr = (*routeCheckResultPtr)->GetGWAddrPtr ();
1314- if (addrPtr) {
1358+ if (addrPtr && (*routeCheckResultPtr)-> HasOif () ) {
13151359 // If we know MAC address of the next hop for mRouteCheckIPv4/6 host, hash
13161360 // it even if it's MAC of some of the default routes we've checked above.
13171361 // This ensures that if we have 2 different default routes and next hop for
13181362 // mRouteCheckIPv4/6 changes from one default route to the other, we'll
13191363 // detect it as a network change.
1320- nsAutoCString addrStr;
1321- GetAddrStr (addrPtr, (*routeCheckResultPtr)->Family (), addrStr);
1322- LOG ((" Next hop for the checked host is %s." , addrStr.get ()));
1364+ nsAutoCString neighKey;
1365+ GetNeighborKey (addrPtr, (*routeCheckResultPtr)->Family (),
1366+ (*routeCheckResultPtr)->Oif (), neighKey);
1367+ LOG ((" Next hop for the checked host is %s." , neighKey.get ()));
13231368
13241369 NetlinkNeighbor* neigh = nullptr ;
1325- if (!mNeighbors .Get (addrStr , &neigh)) {
1326- LOG ((" Neighbor %s not found in hashtable." , addrStr .get ()));
1370+ if (!mNeighbors .Get (neighKey , &neigh)) {
1371+ LOG ((" Neighbor %s not found in hashtable." , neighKey .get ()));
13271372 return retval;
13281373 }
13291374
13301375 if (!neigh->HasMAC ()) {
1331- LOG ((" We have no MAC for neighbor %s." , addrStr .get ()));
1376+ LOG ((" We have no MAC for neighbor %s." , neighKey .get ()));
13321377 return retval;
13331378 }
13341379
@@ -1337,7 +1382,7 @@ bool NetlinkService::CalculateIDForFamily(uint8_t aFamily, SHA1Sum* aSHA1) {
13371382 neigh->GetAsString (neighDbgStr);
13381383 LOG ((" Hashing MAC address of neighbor: %s" , neighDbgStr.get ()));
13391384#else
1340- LOG ((" Hashing MAC address of neighbor %s" , addrStr .get ()));
1385+ LOG ((" Hashing MAC address of neighbor %s" , neighKey .get ()));
13411386#endif
13421387 aSHA1->update (neigh->GetMACPtr (), ETH_ALEN );
13431388 retval = true ;
@@ -1445,6 +1490,8 @@ bool NetlinkService::CalculateIDForFamily(uint8_t aFamily, SHA1Sum* aSHA1) {
14451490
14461491// Figure out the "network identification".
14471492void NetlinkService::CalculateNetworkID () {
1493+ LOG ((" NetlinkService::CalculateNetworkID" ));
1494+
14481495 MOZ_ASSERT (!NS_IsMainThread(), " Must not be called on the main thread" );
14491496 MOZ_ASSERT (mRecalculateNetworkId );
14501497
0 commit comments