]> git.meshlink.io Git - catta/commitdiff
* Some minor cleanups in netlink code
authorLennart Poettering <lennart@poettering.net>
Sat, 15 Oct 2005 01:30:46 +0000 (01:30 +0000)
committerLennart Poettering <lennart@poettering.net>
Sat, 15 Oct 2005 01:30:46 +0000 (01:30 +0000)
* add some comments to iface-linux.c, to ease porting for sebest

git-svn-id: file:///home/lennart/svn/public/avahi/trunk@762 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

avahi-core/iface-linux.c
avahi-core/netlink.c

index 5e16d6abd355fa1ccff4c94c74c097f022bd0c0b..64bb0aec69001a529ea660dfd29f9a1007cb3d5a 100644 (file)
@@ -69,7 +69,18 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
         if (ifinfomsg->ifi_family != AF_UNSPEC)
             return;
 
+        /* Check whether there already is an AvahiHwInterface object
+         * for this link, so that we can update its data. Note that
+         * Netlink sends us an RTM_NEWLINK not only when a new
+         * interface appears, but when it changes, too */
+
         if (!(hw = avahi_interface_monitor_get_hw_interface(m, ifinfomsg->ifi_index)))
+            
+            /* No object found, so let's create a new
+             * one. avahi_hw_interface_new() will call
+             * avahi_interface_new() internally twice for IPv4 and
+             * IPv6, so there is no need for us to do that
+             * ourselves */
             if (!(hw = avahi_hw_interface_new(m, (AvahiIfIndex) ifinfomsg->ifi_index)))
                 return; /* OOM */
 
@@ -80,31 +91,36 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
             !(ifinfomsg->ifi_flags & IFF_LOOPBACK) &&
             (ifinfomsg->ifi_flags & IFF_MULTICAST) &&
             !(ifinfomsg->ifi_flags & IFF_POINTOPOINT);
-            
 
+        /* Handle interface attributes */
         l = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg));
         a = IFLA_RTA(ifinfomsg);
 
         while (RTA_OK(a, l)) {
             switch(a->rta_type) {
                 case IFLA_IFNAME:
+
+                    /* Fill in interface name */
                     avahi_free(hw->name);
                     hw->name = avahi_strndup(RTA_DATA(a), RTA_PAYLOAD(a));
                     break;
 
                 case IFLA_MTU:
+
+                    /* Fill in MTU */
                     assert(RTA_PAYLOAD(a) == sizeof(unsigned int));
                     hw->mtu = *((unsigned int*) RTA_DATA(a));
                     break;
 
-                case IFLA_ADDRESS: {
+                case IFLA_ADDRESS:
+
+                    /* Fill in hardware (MAC) address */
                     hw->mac_address_size = RTA_PAYLOAD(a);
                     if (hw->mac_address_size > AVAHI_MAX_MAC_ADDRESS)
                         hw->mac_address_size = AVAHI_MAX_MAC_ADDRESS;
                     
                     memcpy(hw->mac_address, RTA_DATA(a), hw->mac_address_size);
                     break;
-                }
                     
                 default:
                     ;
@@ -113,7 +129,14 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
             a = RTA_NEXT(a, l);
         }
 
+        /* Check whether this interface is now "relevant" for us. If
+         * it is Avahi will start to announce its records on this
+         * interface and send out queries for subscribed records on
+         * it */
         avahi_hw_interface_check_relevant(hw);
+
+        /* Update any associated RRs of this interface. (i.e. the
+         * _workstation._tcp record containing the MAC address) */
         avahi_hw_interface_update_rrs(hw, 0);
         
     } else if (n->nlmsg_type == RTM_DELLINK) {
@@ -122,10 +145,12 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
 
         if (ifinfomsg->ifi_family != AF_UNSPEC)
             return;
-        
+
+        /* Get a reference to our AvahiHwInterface object of this interface */
         if (!(hw = avahi_interface_monitor_get_hw_interface(m, (AvahiIfIndex) ifinfomsg->ifi_index)))
             return;
 
+        /* Free our object */
         avahi_hw_interface_free(hw, 0);
         
     } else if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
@@ -137,12 +162,17 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
         AvahiAddress raddr;
         int raddr_valid = 0;
 
+        /* We are only interested in IPv4 and IPv6 */
         if (ifaddrmsg->ifa_family != AF_INET && ifaddrmsg->ifa_family != AF_INET6)
             return;
 
+        /* Try to get a reference to our AvahiInterface object for the
+         * interface this address is assigned to. If ther is no object
+         * for this interface, we ignore this address. */
         if (!(i = avahi_interface_monitor_get_interface(m, (AvahiIfIndex) ifaddrmsg->ifa_index, avahi_af_to_proto(ifaddrmsg->ifa_family))))
             return;
 
+        /* Fill in address family for our new address */
         raddr.proto = avahi_af_to_proto(ifaddrmsg->ifa_family);
 
         l = NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg));
@@ -152,6 +182,8 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
 
             switch(a->rta_type) {
                 case IFA_ADDRESS:
+                    /* Fill in address data */
+                    
                     if ((raddr.proto == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) ||
                         (raddr.proto == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4))
                         return;
@@ -167,55 +199,91 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
             
             a = RTA_NEXT(a, l);
         }
-        
+
+        /* If there was no adress attached to this message, let's quit. */
         if (!raddr_valid)
             return;
 
         if (n->nlmsg_type == RTM_NEWADDR) {
             AvahiInterfaceAddress *addr;
-            
+
+            /* This address is new or has been modified, so let's get an object for it */
             if (!(addr = avahi_interface_monitor_get_address(m, i, &raddr)))
+
+                /* Mmm, no object existing yet, so let's create a new one */
                 if (!(addr = avahi_interface_address_new(m, i, &raddr, ifaddrmsg->ifa_prefixlen)))
                     return; /* OOM */
-            
+
+            /* Update the scope field for the address */
             addr->global_scope = ifaddrmsg->ifa_scope == RT_SCOPE_UNIVERSE || ifaddrmsg->ifa_scope == RT_SCOPE_SITE;
         } else {
             AvahiInterfaceAddress *addr;
-            
+            assert(n->nlmsg_type == RTM_DELADDR);
+
+            /* Try to get a reference to our AvahiInterfaceAddress object for this address */
             if (!(addr = avahi_interface_monitor_get_address(m, i, &raddr)))
                 return;
 
+            /* And free it */
             avahi_interface_address_free(addr);
         }
 
+        /* Avahi only considers interfaces with at least one address
+         * attached relevant. Since we migh have added or removed an
+         * address, let's have it check again whether the interface is
+         * now relevant */
         avahi_interface_check_relevant(i);
+
+        /* Update any associated RRs, like A or AAAA for our new/removed address */
         avahi_interface_update_rrs(i, 0);
         
     } else if (n->nlmsg_type == NLMSG_DONE) {
+
+        /* This wild dump request ended, so let's see what we do next */
         
         if (m->osdep.list == LIST_IFACE) {
+
+            /* Mmmm, interfaces have been wild dumped already, so
+             * let's go on with wild dumping the addresses */
             
             if (netlink_list_items(m->osdep.netlink, RTM_GETADDR, &m->osdep.query_addr_seq) < 0) {
                 avahi_log_warn("NETLINK: Failed to list addrs: %s", strerror(errno));
                 m->osdep.list = LIST_DONE;
             } else
+
+                /* Update state information */
                 m->osdep.list = LIST_ADDR;
 
         } else
-            /* We're through */
+            /* We're done. Tell avahi_interface_monitor_sync() to finish. */
             m->osdep.list = LIST_DONE;
 
         if (m->osdep.list == LIST_DONE) {
+
+            /* Only after this boolean variable has been set, Avahi
+             * will start to announce or browse on all interfaces. It
+             * is originaly set to 0, which means that relevancy
+             * checks and RR updates are disabled during the wild
+             * dumps. */
             m->list_complete = 1;
+
+            /* So let's check if any interfaces are relevant now */
             avahi_interface_monitor_check_relevant(m);
+
+            /* And update all RRs attached to any interface */
             avahi_interface_monitor_update_rrs(m, 0);
+
+            /* Tell the user that the wild dump is complete */
             avahi_log_info("Network interface enumeration completed.");
         }
         
     } else if (n->nlmsg_type == NLMSG_ERROR &&
                (n->nlmsg_seq == m->osdep.query_link_seq || n->nlmsg_seq == m->osdep.query_addr_seq)) {
         struct nlmsgerr *e = NLMSG_DATA (n);
-                    
+
+        /* Some kind of error happened. Let's just tell the user and
+         * ignore it otherwise */
+        
         if (e->error)
             avahi_log_warn("NETLINK: Failed to browse: %s", strerror(-e->error));
     }
@@ -224,15 +292,23 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat
 int avahi_interface_monitor_init_osdep(AvahiInterfaceMonitor *m) {
     assert(m);
 
+    /* Initialize our own data */
+    
     m->osdep.netlink = NULL;
     m->osdep.query_addr_seq = m->osdep.query_link_seq = 0;
-    
+
+    /* Create a netlink object for us. It abstracts some things and
+     * makes netlink easier to use. It will attach to the main loop
+     * for us and call netlink_callback() whenever an event
+     * happens. */
     if (!(m->osdep.netlink = avahi_netlink_new(m->server->poll_api, RTMGRP_LINK|RTMGRP_IPV4_IFADDR|RTMGRP_IPV6_IFADDR, netlink_callback, m)))
         goto fail;
 
+    /* Start the wild dump for the interfaces */
     if (netlink_list_items(m->osdep.netlink, RTM_GETLINK, &m->osdep.query_link_seq) < 0)
         goto fail;
 
+    /* Set the initial state. */
     m->osdep.list = LIST_IFACE;
 
     return 0;
@@ -258,9 +334,15 @@ void avahi_interface_monitor_free_osdep(AvahiInterfaceMonitor *m) {
 
 void avahi_interface_monitor_sync(AvahiInterfaceMonitor *m) {
     assert(m);
+
+    /* Let's handle netlink events until we are done with wild
+     * dumping */
     
     while (m->osdep.list != LIST_DONE) {
-        if (!avahi_netlink_work(m->osdep.netlink, 1))
+        if (!avahi_netlink_work(m->osdep.netlink, 1) == 0)
             break;
-    } 
+    }
+
+    /* At this point Avahi knows about all local interfaces and
+     * addresses in existance. */
 }
index ccb4d836ef8599c7a3f973648557e712c4ca71fe..d5d22951aac2e7b0db3fb00fe6b301f99bab3de6 100644 (file)
@@ -56,10 +56,10 @@ int avahi_netlink_work(AvahiNetlink *nl, int block) {
             if ((bytes = recv(nl->fd, nl->buffer, nl->buffer_length, block ? 0 : MSG_DONTWAIT)) < 0) {
 
                 if (errno == EAGAIN || errno == EINTR)
-                    return 1;
+                    return 0;
                 
                 avahi_log_error(__FILE__": recv() failed: %s", strerror(errno));
-                return 0;
+                return -1;
             }
 
             break;
@@ -71,7 +71,7 @@ int avahi_netlink_work(AvahiNetlink *nl, int block) {
             for (; bytes > 0; p = NLMSG_NEXT(p, bytes)) {
                 if (!NLMSG_OK(p, (size_t) bytes)) {
                     avahi_log_warn(__FILE__": packet truncated");
-                    return 0;
+                    return -1;
                 }
 
                 nl->callback(nl, p, nl->userdata);