This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / net / decnet / dn_dev.c
index aba8435..a21a326 100644 (file)
@@ -1291,6 +1291,59 @@ int unregister_dnaddr_notifier(struct notifier_block *nb)
        return notifier_chain_unregister(&dnaddr_chain, nb);
 }
 
+#ifdef CONFIG_DECNET_SIOCGIFCONF
+/*
+ * Now we support multiple addresses per interface.
+ * Since we don't want to break existing code, you have to enable
+ * it as a compile time option. Probably you should use the
+ * rtnetlink interface instead.
+ */
+int dnet_gifconf(struct net_device *dev, char __user *buf, int len)
+{
+       struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;
+       struct dn_ifaddr *ifa;
+       char buffer[DN_IFREQ_SIZE];
+       struct ifreq *ifr = (struct ifreq *)buffer;
+       struct sockaddr_dn *addr = (struct sockaddr_dn *)&ifr->ifr_addr;
+       int done = 0;
+
+       if ((dn_db == NULL) || ((ifa = dn_db->ifa_list) == NULL))
+               return 0;
+
+       for(; ifa; ifa = ifa->ifa_next) {
+               if (!buf) {
+                       done += sizeof(DN_IFREQ_SIZE);
+                       continue;
+               }
+               if (len < DN_IFREQ_SIZE)
+                       return done;
+               memset(buffer, 0, DN_IFREQ_SIZE);
+
+               if (ifa->ifa_label)
+                       strcpy(ifr->ifr_name, ifa->ifa_label);
+               else
+                       strcpy(ifr->ifr_name, dev->name);
+
+               addr->sdn_family = AF_DECnet;
+               addr->sdn_add.a_len = 2;
+               memcpy(addr->sdn_add.a_addr, &ifa->ifa_local,
+                       sizeof(dn_address));
+
+               if (copy_to_user(buf, buffer, DN_IFREQ_SIZE)) {
+                       done = -EFAULT;
+                       break;
+               }
+
+               buf  += DN_IFREQ_SIZE;
+               len  -= DN_IFREQ_SIZE;
+               done += DN_IFREQ_SIZE;
+       }
+
+       return done;
+}
+#endif /* CONFIG_DECNET_SIOCGIFCONF */
+
+
 #ifdef CONFIG_PROC_FS
 static inline struct net_device *dn_dev_get_next(struct seq_file *seq, struct net_device *dev)
 {
@@ -1431,7 +1484,8 @@ static struct rtnetlink_link dnet_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
 };
 
 static int __initdata addr[2];
-module_param_array(addr, int, NULL, 0444);
+static int __initdata num;
+module_param_array(addr, int, num, 0444);
 MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
 
 void __init dn_dev_init(void)
@@ -1449,6 +1503,9 @@ void __init dn_dev_init(void)
         decnet_address = dn_htons((addr[0] << 10) | addr[1]);
 
        dn_dev_devices_on();
+#ifdef CONFIG_DECNET_SIOCGIFCONF
+       register_gifconf(PF_DECnet, dnet_gifconf);
+#endif /* CONFIG_DECNET_SIOCGIFCONF */
 
        rtnetlink_links[PF_DECnet] = dnet_rtnetlink_table;
 
@@ -1467,6 +1524,10 @@ void __exit dn_dev_cleanup(void)
 {
        rtnetlink_links[PF_DECnet] = NULL;
 
+#ifdef CONFIG_DECNET_SIOCGIFCONF
+       unregister_gifconf(PF_DECnet);
+#endif /* CONFIG_DECNET_SIOCGIFCONF */
+
 #ifdef CONFIG_SYSCTL
        {
                int i;