gnetworkmonitornetlink: handle default route via device
authorDan Winship <danw@gnome.org>
Tue, 4 Jun 2013 20:29:55 +0000 (17:29 -0300)
committerDan Winship <danw@gnome.org>
Fri, 12 Jul 2013 15:59:50 +0000 (11:59 -0400)
If the default route is via a device rather than a particular IP
address, then neither RTA_DST nor RTA_GATEWAY will be present in the
RTM_NEWROUTE message, and so GNetworkMonitorNetlink would ignore it,
and then think there was no default route. (This could happen with
certain kinds of VPNs, if they were set to route all traffic through
the VPN.)

Fix this by recognizing routes that specify RTA_OIF ("output
interface") instead of RTA_GATEWAY.

https://bugzilla.gnome.org/show_bug.cgi?id=701609

gio/gnetworkmonitornetlink.c

index 89836919af5e2217a9971bd387ec8e633e20533f..4f7d089aa553aaf128e7f920deb173c33ff7ac21 100644 (file)
@@ -218,8 +218,7 @@ static void
 add_network (GNetworkMonitorNetlink *nl,
              GSocketFamily           family,
              gint                    dest_len,
-             guint8                 *dest,
-             guint8                 *gateway)
+             guint8                 *dest)
 {
   GInetAddress *dest_addr;
   GInetAddressMask *network;
@@ -245,8 +244,7 @@ static void
 remove_network (GNetworkMonitorNetlink *nl,
                 GSocketFamily           family,
                 gint                    dest_len,
-                guint8                 *dest,
-                guint8                 *gateway)
+                guint8                 *dest)
 {
   GInetAddress *dest_addr;
   GInetAddressMask *network;
@@ -305,7 +303,7 @@ read_netlink_messages (GSocket      *socket,
   struct rtmsg *rtmsg;
   struct rtattr *attr;
   gsize attrlen;
-  guint8 *dest, *gateway;
+  guint8 *dest, *gateway, *oif;
   gboolean retval = TRUE;
 
   iv.buffer = NULL;
@@ -367,22 +365,24 @@ read_netlink_messages (GSocket      *socket,
 
           attrlen = NLMSG_PAYLOAD (msg, sizeof (struct rtmsg));
           attr = RTM_RTA (rtmsg);
-          dest = gateway = NULL;
+          dest = gateway = oif = NULL;
           while (RTA_OK (attr, attrlen))
             {
               if (attr->rta_type == RTA_DST)
                 dest = RTA_DATA (attr);
               else if (attr->rta_type == RTA_GATEWAY)
                 gateway = RTA_DATA (attr);
+              else if (attr->rta_type == RTA_OIF)
+                oif = RTA_DATA (attr);
               attr = RTA_NEXT (attr, attrlen);
             }
 
-          if (dest || gateway)
+          if (dest || gateway || oif)
             {
               if (msg->nlmsg_type == RTM_NEWROUTE)
-                add_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest, gateway);
+                add_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest);
               else
-                remove_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest, gateway);
+                remove_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest);
               queue_request_dump (nl);
             }
           break;