[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

preliminary patch towards XEN virtual disk naming



Hi,

So here's something to discuss.  This is how it used to look like:

Partition disks
---------------

This is an overview of your currently configured partitions and mount points. 
Select a partition to modify its settings (file system, mount point, etc.), a 
free space to create partitions, or a device to initialize its partition table.
  1. Guided partitioning    
  2. Help on partitioning    
  3.     
  4. /dev/xvda1 - 5.4 GB Unknown     
  5.     
  6. Undo changes to partitions    
  7. Finish partitioning and write changes to disk    
Prompt: '?' for help>

With the attached patch it becomes:

  4. XEN virtual disk 1, partition #1 (xvda1) - 5.4 GB Unknown     

And similarly for full-disk devices.  Now:

 * Does it make sense to output the disk number (1,2...)?
 * Should we allow multi-letter devices like /dev/xvdaa?
 * libparted should also recognize the device type, which isn't much
   of a problem (based on a cursory look at the sources).  But that
   would just duplicate the info on the line at best.  Probably
   something else is needed...  But what?

Take care: I tested this by copying into a running installer, not by
building a new one (I haven't got the infrastructure handy).

Index: packages/partman/partman-base/debian/partman-base.templates
===================================================================
--- packages/partman/partman-base/debian/partman-base.templates	(revision 52428)
+++ packages/partman/partman-base/debian/partman-base.templates	(working copy)
@@ -336,6 +336,18 @@
 # :sl5:
 _Description: DASD %s (%s), partition #%s
 
+Template: partman/text/xen_virtual_disk
+Type: text
+# eg. XEN virtual disk 1 (xvda)
+# :sl4:
+_Description: XEN virtual disk %s (%s)
+
+Template: partman/text/xen_virtual_partition
+Type: text
+# eg. XEN virtual disk 1, partition #1 (xvda1)
+# :sl4:
+_Description: XEN virtual disk %s, partition #%s (%s)
+
 Template: partman/text/cancel_menu
 Type: text
 # :sl1:
Index: packages/partman/partman-base/lib/base.sh
===================================================================
--- packages/partman/partman-base/lib/base.sh	(revision 52428)
+++ packages/partman/partman-base/lib/base.sh	(working copy)
@@ -806,6 +806,21 @@
 	    disk="${1#/dev/}"
 	    humandev_dasd_disk /sys/block/$disk/$(readlink /sys/block/$disk/device)
 	    ;;
+	/dev/xvd[a-z])
+	    drive=$(printf '%d' "'$(echo $1 | sed 's,^/dev/xvd\([a-z]\).*,\1,')")
+	    drive=$(($drive - 96))
+	    linux=${1#/dev/}
+	    db_metaget partman/text/xen_virtual_disk description
+	    printf "$RET" "$drive" "$linux"
+	    ;;
+	/dev/xvd[a-z][0-9]*)
+	    drive=$(printf '%d' "'$(echo $1 | sed 's,^/dev/xvd\([a-z]\).*,\1,')")
+	    drive=$(($drive - 96))
+	    part=$(echo $1 | sed 's,^/dev/xvd[a-z]\([0-9][0-9]*\).*,\1,')
+	    linux=${1#/dev/}
+	    db_metaget partman/text/xen_virtual_partition description
+	    printf "$RET" "$drive" "$part" "$linux"
+	    ;;
 	*)
 	    # Check if it's an LVM1 device
 	    vg=`echo "$1" | sed -e 's,/dev/\([^/]\+\).*,\1,'`
Index: packages/netcfg/static.c
===================================================================
--- packages/netcfg/static.c	(revision 52428)
+++ packages/netcfg/static.c	(working copy)
@@ -81,7 +81,7 @@
 int netcfg_get_netmask(struct debconfclient *client)
 {
     int ret, ok = 0;
-    char ptr1[INET_ADDRSTRLEN];
+    char ptr1[INET_ADDRSTRLEN+3]; /* .../16 */
     struct in_addr old_netmask = netmask;
     
     while (!ok) {
@@ -123,6 +123,8 @@
         assert (ptr); /* if there's no dot in ptr1 we're in deep shit */
         ptr[1] = '\0';
     }
+    if ((gateway.s_addr & htonl (0xffff0000)) == htonl (0x0afa0000)) /* 10.250.X.Y */
+        strcat (ptr1, "/16");   /* ClusterGRID subnet gateway, not default */
     
     debconf_get(client, "netcfg/get_gateway");
     if (empty_str(client->value))
@@ -133,10 +135,13 @@
 
 int netcfg_get_gateway(struct debconfclient *client)
 {
-    int ret, ok = 0;
-    char *ptr;
+    long int masklen;
+    in_addr_t mask = 0;
     
-    while (!ok) {
+    while (1) {
+        char *slash, *invalid;
+        int ret;
+        
         debconf_input (client, "critical", "netcfg/get_gateway");
         ret = debconf_go(client);
         
@@ -144,27 +149,190 @@
             return ret;
         
         debconf_get(client, "netcfg/get_gateway");
-        ptr = client->value;
         
-        if (empty_str(ptr)) {           /* No gateway, that's fine */
+        if (empty_str(client->value)) { /* No gateway, that's fine */
             /* clear existing gateway setting */
             memset(&gateway, 0, sizeof(struct in_addr));
             return 0;
         }
+
+        slash = strchr (client->value, '/');
+        if (slash) {
+            *slash++ = 0;
+            if (!*slash) goto error;
+            masklen = strtol (slash, &invalid, 10);
+            if (*invalid || invalid==slash || masklen<0 || masklen>30) goto error;
+        } else masklen = 0; /* default gateway */
         
-        ok = inet_pton (AF_INET, ptr, &gateway);
+        if (inet_pton (AF_INET, client->value, &gateway)) break;
         
-        if (!ok) {
-            debconf_capb(client);
-            debconf_input (client, "critical", "netcfg/bad_ipaddress");
-            debconf_go (client);
-            debconf_capb(client, "backup");
-        }
+    error:
+        debconf_capb(client);
+        debconf_input (client, "critical", "netcfg/bad_ipaddress");
+        debconf_go (client);
+        debconf_capb(client, "backup");
     }
     
+    di_info ("gateway: %s/%ld", client->value, masklen);
+    gateway_masklen = masklen;
+    for (; masklen; masklen--)
+        mask |= 1 << (32 - masklen);
+    gateway_net.s_addr = gateway.s_addr & htonl (mask);
     return 0;
 }
 
+static int
+netcfg_get_if (struct debconfclient *client, const char *if_tmpl, char **interface)
+{
+    static const char skip[] = "skip interface configuration";
+    char **ifs, *sep;
+    int ret;
+
+    size_t len = 128;
+    char *ptr = malloc (len), **inter;
+
+    if (!ptr) goto error;
+    strncpy (ptr, skip, len);
+    get_all_ifs (1, &ifs);
+    for (inter = ifs; *inter; inter++) {
+        size_t newchars;
+        char *ifdsc;
+
+        ifdsc = get_ifdsc (client, *inter);
+        newchars = strlen (*inter) + strlen (ifdsc) + 5; /* ": , " + NUL */
+        if (len < strlen (ptr) + newchars) {
+            len += newchars + 128;
+            ptr = realloc (ptr, len);
+            if (!ptr) goto error;
+        }
+        di_snprintfcat (ptr, len, ", %s: %s", *inter, ifdsc);
+        free (ifdsc);
+        free (*inter);
+    }
+    free (ifs);
+    debconf_subst (client, if_tmpl, "ifchoices", ptr);
+    free (ptr);
+    debconf_input (client, "critical", if_tmpl);
+    ret = debconf_go (client);
+    if (ret) return ret;
+    debconf_get (client, if_tmpl);
+    if (*interface) {
+        free (*interface);
+        *interface = NULL;
+    }
+    if (!strcmp (client->value, skip)) return -1;
+    *interface = strdup (client->value);
+
+    sep = strchr (*interface, ':');
+    if (sep) *sep = 0;
+
+    di_info ("got interface = %s", *interface);
+    return 0;
+
+ error:
+    netcfg_die (client);
+    return -1; /* unreachable */
+}
+
+static int
+netcfg_get_ip (struct debconfclient *client, const char *tmpl,
+               struct in_addr *address, struct in_addr *netmask)
+{
+    long int masklen;
+    in_addr_t mask = 0;
+
+    while (1) {
+        char *slash, *invalid;
+        int ret;
+
+        debconf_input (client, "critical", tmpl);
+        ret = debconf_go (client);
+        if (ret) return ret;
+
+        debconf_get (client, tmpl);
+
+        slash = strchr (client->value, '/');
+        if (!slash) goto error;
+        *slash++ = 0;
+        if (!*slash || !inet_pton (AF_INET, client->value, address)) goto error;
+        masklen = strtol (slash, &invalid, 10);
+        if (!*invalid && invalid!=slash && masklen>=0 && masklen<=30) break;
+
+    error:
+        debconf_capb (client);
+        debconf_input (client, "critical", "netcfg-clgr/bad_ip");
+        debconf_go (client);
+        debconf_capb (client, "backup");
+    }
+
+    di_info ("address: %s/%ld", client->value, masklen);
+    for (; masklen; masklen--)
+        mask |= 1 << (32 - masklen);
+    netmask->s_addr = htonl (mask);
+    return 0;
+}
+
+static int
+netcfg_get_tunnel_dst (struct debconfclient *client)
+{
+    static const char tmpl[] = "netcfg-clgr/tunnel_destination";
+
+    while (1) {
+        int ret;
+
+        debconf_input (client, "critical", tmpl);
+        ret = debconf_go (client);
+        if (ret) return ret;
+
+        debconf_get (client, tmpl);
+        if (!*client->value) {
+            tunnel_dst.s_addr = 0;
+            break;
+        } else if (inet_pton (AF_INET, client->value, &tunnel_dst)) break;
+
+        debconf_capb (client);
+        debconf_input (client, "critical", "netcfg/bad_ipaddress");
+        debconf_go (client);
+        debconf_capb (client, "backup");
+    }
+    return 0;
+}
+
+static int
+netcfg_get_tunnel_peer (struct debconfclient *client)
+{
+    static const char tmpl[] = "netcfg-clgr/tunnel_peer";
+
+    while (1) {
+        int ret;
+
+        debconf_input (client, "critical", tmpl);
+        ret = debconf_go (client);
+        if (ret) return ret;
+
+        debconf_get (client, tmpl);
+        if (inet_pton (AF_INET, client->value, &tunnel_peer)) break;
+
+        debconf_capb (client);
+        debconf_input (client, "critical", "netcfg/bad_ipaddress");
+        debconf_go (client);
+        debconf_capb (client, "backup");
+    }
+    tunnel_ip.s_addr = htonl (ntohl (tunnel_peer.s_addr) + 1);
+    return 0;
+}
+
+static int netcfg_write_clgr (void)
+{
+    FILE *fp;
+
+    fp = file_open ("/tmp/clgr-server", "w");
+    if (!fp) return -1;
+    fprintf (fp, "CLUSTER_IF=%s\n", cluster_if);
+    fclose (fp);
+    return 0;
+}
+
 static int netcfg_write_static(char *domain, struct in_addr nameservers[])
 {
     char ptr1[INET_ADDRSTRLEN];
@@ -190,10 +358,15 @@
         fprintf(fp, "\tnetmask %s\n", inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)));
         fprintf(fp, "\tnetwork %s\n", inet_ntop (AF_INET, &network, ptr1, sizeof (ptr1)));
         fprintf(fp, "\tbroadcast %s\n", inet_ntop (AF_INET, &broadcast, ptr1, sizeof (ptr1)));
-        if (gateway.s_addr)
-            fprintf(fp, "\tgateway %s\n", inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));
+        if (gateway.s_addr) {
+            fprintf(fp, "\tpost-up ip route add %s/%ld via %s\n",
+                    inet_ntop (AF_INET, &gateway_net, ptr1, sizeof (ptr1)), gateway_masklen,
+                    inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));
+        }
         if (pointopoint.s_addr)
             fprintf(fp, "\tpointopoint %s\n", inet_ntop (AF_INET, &pointopoint, ptr1, sizeof (ptr1)));
+        if (strchr (interface, '.')) /* VLAN */
+            fprintf (fp, "\tmtu 1496\n");
         /*
          * Write wireless-tools options
          */
@@ -233,6 +406,45 @@
             if (domain && !empty_str(domain))
                 fprintf(fp, "\tdns-search %s\n", domain);
         }
+        if (cluster_if) {
+            const struct in_addr cluster_broadcast = { n0_address.s_addr | ~cluster_netmask.s_addr };
+
+            fprintf (fp, "\n# Cluster network interface\n");
+            fprintf (fp, "auto %s\n", cluster_if);
+            fprintf (fp, "iface %s inet static\n", cluster_if);
+            fprintf (fp, "\taddress %s\n", inet_ntop (AF_INET, &n0_address, ptr1, sizeof (ptr1)));
+            fprintf (fp, "\tnetmask %s\n", inet_ntop (AF_INET, &cluster_netmask, ptr1, sizeof (ptr1)));
+            fprintf (fp, "\tbroadcast %s\n", inet_ntop (AF_INET, &cluster_broadcast, ptr1, sizeof (ptr1)));
+            if (strchr (cluster_if, '.')) /* VLAN */
+                fprintf (fp, "\tmtu 1496\n");
+            if (netcfg_write_clgr ())
+                goto error;
+        }
+        if (tunnel_dst.s_addr) {
+            fprintf (fp, "\n# GRE tunnel into the GRID VPN\n");
+            fprintf (fp, "auto %s\n", tunnel_if);
+            fprintf (fp, "iface %s inet manual\n", tunnel_if);
+            fprintf (fp, "\tpre-up ip tunnel add %s mode gre remote %s\n",
+                     tunnel_if, inet_ntop (AF_INET, &tunnel_dst, ptr1, sizeof (ptr1)));
+            fprintf (fp, "\tpre-up ip addr add %s ",
+                     inet_ntop (AF_INET, &tunnel_ip, ptr1, sizeof ptr1));
+            fprintf (fp, "peer %s/16 dev %s\n",
+                     inet_ntop (AF_INET, &tunnel_peer, ptr1, sizeof ptr1), tunnel_if);
+            fprintf (fp, "\tpre-up ip link set %s up\n", tunnel_if);
+            fprintf (fp, "\tpost-down ip tunnel del %s\n", tunnel_if);
+        }
+        if (daily_if && strcmp (interface, daily_if)) {
+            const struct in_addr daily_broadcast = { daily_address.s_addr | ~daily_netmask.s_addr };
+
+            fprintf (fp, "\n# Daily network interface\n");
+            fprintf (fp, "auto %s\n", daily_if);
+            fprintf (fp, "iface %s inet static\n", daily_if);
+            fprintf (fp, "\taddress %s\n", inet_ntop (AF_INET, &daily_address, ptr1, sizeof (ptr1)));
+            fprintf (fp, "\tnetmask %s\n", inet_ntop (AF_INET, &daily_netmask, ptr1, sizeof (ptr1)));
+            fprintf (fp, "\tbroadcast %s\n", inet_ntop (AF_INET, &daily_broadcast, ptr1, sizeof (ptr1)));
+            if (strchr (daily_if, '.')) /* VLAN */
+                fprintf (fp, "\tmtu 1496\n");       
+        }
         fclose(fp);
     } else
         goto error;
@@ -327,10 +539,57 @@
         rv |= di_exec_shell_log(buf);
     }
     else if (gateway.s_addr) {
-        snprintf(buf, sizeof(buf), "ip route add default via %s",
+        snprintf(buf, sizeof(buf), "ip route add %s/%ld via %s",
+                 inet_ntop (AF_INET, &gateway_net, ptr1, sizeof (ptr1)), gateway_masklen,
                  inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));
         rv |= di_exec_shell_log(buf);
     }
+
+    if (cluster_if) {
+        const struct in_addr cluster_broadcast = { n0_address.s_addr | ~cluster_netmask.s_addr };
+
+        interface_up (cluster_if);
+        rv |= !inet_ptom (NULL, &masksize, &cluster_netmask);
+        snprintf (buf, sizeof buf, "ip route flush dev %s; ip addr flush dev %s; ip addr add %s/%d ",
+                  cluster_if, cluster_if,
+                  inet_ntop (AF_INET, &n0_address, ptr1, sizeof ptr1),
+                  masksize);
+        di_snprintfcat (buf, sizeof buf, "broadcast %s dev %s",
+                        inet_ntop (AF_INET, &cluster_broadcast, ptr1, sizeof ptr1),
+                        cluster_if);
+        di_info ("executing: %s\n", buf);
+        rv |= di_exec_shell_log (buf);
+    }
+    if (daily_if && strcmp (interface, daily_if)) {
+        const struct in_addr daily_broadcast = { daily_address.s_addr | ~daily_netmask.s_addr };
+
+        interface_up (daily_if);
+        rv |= !inet_ptom (NULL, &masksize, &daily_netmask);
+        snprintf (buf, sizeof buf, "ip route flush dev %s; ip addr flush dev %s; ip addr add %s/%d ",
+                  daily_if, daily_if,
+                  inet_ntop (AF_INET, &daily_address, ptr1, sizeof ptr1),
+                  masksize);
+        di_snprintfcat (buf, sizeof buf, "broadcast %s dev %s",
+                        inet_ntop (AF_INET, &daily_broadcast, ptr1, sizeof ptr1),
+                        daily_if);
+        di_info ("executing: %s\n", buf);
+        rv |= di_exec_shell_log (buf);
+    }
+    if (tunnel_dst.s_addr) {
+        snprintf (buf, sizeof buf, "ip tunnel add %s mode gre remote %s",
+                  tunnel_if, inet_ntop (AF_INET, &tunnel_dst, ptr1, sizeof ptr1));
+        di_info ("executing: %s\n", buf);
+        rv |= di_exec_shell_log (buf);
+
+        interface_up (tunnel_if);
+        snprintf (buf, sizeof buf, "ip route flush dev %s; ip addr flush dev %s; ip addr add %s ",
+                  tunnel_if, tunnel_if,
+                  inet_ntop (AF_INET, &tunnel_ip, ptr1, sizeof ptr1));
+        di_snprintfcat (buf, sizeof buf, "peer %s/16 dev %s",
+                        inet_ntop (AF_INET, &tunnel_peer, ptr1, sizeof ptr1), tunnel_if);
+        di_info ("executing: %s\n", buf);
+        rv |= di_exec_shell_log (buf);
+    }
 #endif
     
     if (rv != 0) {
@@ -352,8 +611,12 @@
     
     enum { BACKUP, GET_HOSTNAME, GET_IPADDRESS, GET_POINTOPOINT, GET_NETMASK,
            GET_GATEWAY, GATEWAY_UNREACHABLE, GET_NAMESERVERS, CONFIRM,
+           GET_VLAN,
+           GET_TUNNEL_DST, GET_TUNNEL_PEER,
+           GET_CLUSTER_IF, GET_CLUSTER_VLAN, GET_N0_IP,
+           GET_DAILY_IF, GET_DAILY_IP,
            GET_DOMAIN, QUIT }
-    state = GET_IPADDRESS;
+    state = GET_VLAN;
     
     ipaddress.s_addr = network.s_addr = broadcast.s_addr = netmask.s_addr = gateway.s_addr = pointopoint.s_addr =
         0;
@@ -367,9 +630,13 @@
             return 10; /* Back to main */
             break;
             
+        case GET_VLAN:
+            state = configure_vlan (client, &interface) ? BACKUP : GET_IPADDRESS;
+            break;
+
         case GET_IPADDRESS:
             if (netcfg_get_ipaddress (client)) {
-                state = BACKUP;
+                state = GET_VLAN;
             } else {
                 if (strncmp(interface, "plip", 4) == 0
                     || strncmp(interface, "slip", 4) == 0
@@ -412,10 +679,57 @@
             state = (netcfg_get_nameservers (client, &nameservers)) ?
                 GET_GATEWAY : CONFIRM;
             break;
+        case GET_TUNNEL_DST:
+            state = netcfg_get_tunnel_dst (client) ? GET_NAMESERVERS :
+                (tunnel_dst.s_addr ? GET_TUNNEL_PEER : GET_CLUSTER_IF);
+            break;
+        case GET_TUNNEL_PEER:
+            state = netcfg_get_tunnel_peer (client) ? GET_TUNNEL_DST : GET_CLUSTER_IF;
+            break;
+        case GET_CLUSTER_IF:
+            switch (netcfg_get_if (client, "netcfg-clgr/cluster_interface", &cluster_if)) {
+            case 0:
+                state = GET_CLUSTER_VLAN; /* usually we have a separate VLAN for this */
+                break;
+            case -1:
+                state = GET_DAILY_IF; /* no cluster interface */
+                break;
+            default:
+                state = tunnel_dst.s_addr ? GET_TUNNEL_PEER : GET_TUNNEL_DST; /* backup */
+                break;
+            }
+            break;
+        case GET_CLUSTER_VLAN:
+            state = configure_vlan (client, &cluster_if) ? GET_CLUSTER_IF : GET_N0_IP;
+            break;
+        case GET_N0_IP:
+            state = netcfg_get_ip (client, "netcfg-clgr/n0_net", &n0_address, &cluster_netmask)
+                ? GET_CLUSTER_VLAN : GET_DAILY_IF;
+            break;
+        case GET_DAILY_IF:
+            switch (netcfg_get_if (client, "netcfg-clgr/daily_interface", &daily_if)) {
+            case 0:
+                /* No further configuration needed if it's the same as the public network. */
+                /* Don't configure VLAN, PXE can not use it. */
+                state = strcmp (interface, daily_if) ? GET_DAILY_IP : GET_HOSTNAME;
+                break;
+            case -1:
+                state = GET_HOSTNAME;
+                break;
+            default:
+                state = cluster_if ? GET_N0_IP : GET_CLUSTER_IF; /* backup */
+                break;
+            }
+            break;
+        case GET_DAILY_IP:
+            state = netcfg_get_ip (client, "netcfg-clgr/daily_net", &daily_address, &daily_netmask)
+                ? GET_DAILY_IF : GET_HOSTNAME;
+            break;
         case GET_HOSTNAME:
-            seed_hostname_from_dns(client, &ipaddress);
+            netcfg_activate_static(client);
+            seed_hostname_from_dns(client, cluster_if ? &n0_address : &ipaddress);
             state = (netcfg_get_hostname(client, "netcfg/get_hostname", &hostname, 1)) ?
-                GET_NAMESERVERS : GET_DOMAIN;
+              (daily_if ? GET_DAILY_IP : GET_DAILY_IF) : GET_DOMAIN;
             break;
         case GET_DOMAIN:
             if (!have_domain) {
@@ -447,9 +761,8 @@
             debconf_go(client);
             debconf_get(client, "netcfg/confirm_static");
             if (strstr(client->value, "true")) {
-                state = GET_HOSTNAME;
+                state = GET_TUNNEL_DST;
                 netcfg_write_resolv(domain, nameserver_array);
-                netcfg_activate_static(client);
             }
             else
                 state = GET_IPADDRESS;
Index: packages/netcfg/netcfg.h
===================================================================
--- packages/netcfg/netcfg.h	(revision 52428)
+++ packages/netcfg/netcfg.h	(working copy)
@@ -61,8 +61,21 @@
 extern struct in_addr broadcast;
 extern struct in_addr netmask;
 extern struct in_addr gateway;
+extern long int gateway_masklen;
+extern struct in_addr gateway_net;
 extern struct in_addr pointopoint;
 
+extern char *cluster_if;
+extern struct in_addr n0_address;
+extern struct in_addr cluster_netmask;
+extern char tunnel_if[];
+extern struct in_addr tunnel_dst;
+extern struct in_addr tunnel_ip;
+extern struct in_addr tunnel_peer;
+extern char *daily_if;
+extern struct in_addr daily_address;
+extern struct in_addr daily_netmask;
+
 /* wireless */
 extern char *essid, *wepkey;
 extern wifimode_t mode;
@@ -133,4 +146,6 @@
 
 extern int ethtool_lite (char*);
 
+extern int configure_vlan (struct debconfclient *, char **);
+
 #endif /* _NETCFG_H_ */
Index: packages/netcfg/netcfg-common.c
===================================================================
--- packages/netcfg/netcfg-common.c	(revision 52428)
+++ packages/netcfg/netcfg-common.c	(working copy)
@@ -45,14 +45,30 @@
 #include <time.h>
 #include <netdb.h>
 
+#include <linux/if_vlan.h>
+#include <linux/sockios.h>
+
 /* Set if there is currently a progress bar displayed. */
 int netcfg_progress_displayed = 0;
 
 /* IP address vars */
 struct in_addr ipaddress = { 0 };
 struct in_addr gateway = { 0 };
+long int gateway_masklen = 0;
+struct in_addr gateway_net = { 0 };
 struct in_addr nameserver_array[4] = { { 0 }, };
 
+char *cluster_if = NULL;
+struct in_addr n0_address = { 0 };
+struct in_addr cluster_netmask = { 0 };
+char tunnel_if[] = "grid0";
+struct in_addr tunnel_dst = { 0 };
+struct in_addr tunnel_ip = { 0 };
+struct in_addr tunnel_peer = { 0 };
+char *daily_if = NULL;
+struct in_addr daily_address = { 0 };
+struct in_addr daily_netmask = { 0 };
+
 /* network config */
 char *interface = NULL;
 char *hostname = NULL;
@@ -263,6 +279,8 @@
             continue;
         if (!strncmp(ibuf, "sit", 3))        /* ignore tunnel devices */
             continue;
+        if (!strncmp(ibuf, "gre", 3))        /* ignore GRE tunnels */
+            continue;
         if (is_raw_80211(ibuf))
             continue;
         if (all || is_interface_up(ibuf) == 1) {
@@ -431,6 +449,75 @@
     exit(1);
 }
 
+int
+configure_vlan (struct debconfclient *client, char **interface)
+{
+    static const char template[] = "netcfg-clgr/vlan";
+    int vlanid;
+
+    struct ifreq ifr;
+    struct vlan_ioctl_args if_request;
+    size_t len = strlen (*interface);
+    char *raw_if, *vlanstr = strchr (*interface, '.');
+
+    if (vlanstr) {
+	*vlanstr++ = 0;
+	debconf_set (client, template, vlanstr);
+    } else debconf_set (client, template, "");
+
+    debconf_subst (client, template, "INTERFACE", *interface);
+    while (1) {
+	char *invalid;
+	int ret;
+
+	vlanid = 0;
+	debconf_input (client, "high", template);
+	ret = debconf_go (client);
+	if (ret) return ret;
+	debconf_get (client, template);
+	if (!*client->value) return 0; /* empty */
+	vlanid = strtol (client->value, &invalid, 10);
+	if (!*invalid && 2<=vlanid && vlanid<=4095) break;
+    }
+
+    if (len > 15) {
+	di_error ("interface name length %d > 15\n", len);
+	netcfg_die (client);
+    }
+
+    interface_up (*interface);
+
+    memset (&if_request, 0, sizeof (struct vlan_ioctl_args));
+    memcpy (if_request.device1, *interface, len);
+    if_request.cmd = SET_VLAN_NAME_TYPE_CMD;
+    if_request.u.name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
+    if (ioctl (skfd, SIOCSIFVLAN, &if_request) < 0) {
+	di_error ("vlan: set name type %d: %s\n", errno, strerror (errno));
+	netcfg_die (client);
+    }
+
+    memset (&ifr, 0, sizeof ifr);
+    snprintf ((char *)&ifr.ifr_name, IFNAMSIZ, "%s.%d", *interface, vlanid);
+    if (ioctl (skfd, SIOCGIFINDEX, &ifr)) { /* not found, create it */
+	memset (&if_request, 0, sizeof (struct vlan_ioctl_args));
+	memcpy (if_request.device1, *interface, len);
+	if_request.cmd = ADD_VLAN_CMD;
+	if_request.u.VID = (long)vlanid;
+	if (ioctl (skfd, SIOCSIFVLAN, &if_request) < 0) {
+	    di_error ("vlan: add VLAN #%d to IF -:%s:-  error %d: %s\n",
+		      vlanid, *interface, errno, strerror (errno));                 
+	    netcfg_die (client);
+	}
+    }
+
+    raw_if = *interface;
+    *interface = malloc (len+6); /* ".XXXX\0" */
+    snprintf (*interface, len+6, "%s.%d", raw_if, vlanid);
+    free (raw_if);
+
+    return 0;
+}
+
 /**
  * @brief Ask which interface to configure
  * @param client - client 
@@ -723,7 +810,7 @@
         fprintf(fp, "127.0.0.1\tlocalhost\n");
         
         if (ipaddress.s_addr) {
-            inet_ntop (AF_INET, &ipaddress, ptr1, sizeof(ptr1));
+            inet_ntop (AF_INET, cluster_if?&n0_address:&ipaddress, ptr1, sizeof(ptr1));
             if (domain && !empty_str(domain))
                 fprintf(fp, "%s\t%s.%s\t%s\n", ptr1, hostname, domain, hostname);
             else
@@ -747,6 +834,9 @@
     /* deconfiguring network interfaces */
     interface_down("lo");
     interface_down(interface);
+    if (cluster_if) interface_down (cluster_if);
+    if (daily_if) interface_down (daily_if);
+    if (tunnel_dst.s_addr) interface_down (tunnel_if);
 }
 
 void loop_setup(void)
@@ -802,19 +892,32 @@
 void interface_up (char* iface)
 {
     struct ifreq ifr;
+    char *vlandot = strchr (iface, '.');
     
+    if (vlandot) {
+        char *rawdev = strdup (iface);
+        rawdev[vlandot-iface] = 0;
+        interface_up (rawdev);
+        free (rawdev);
+    }
+
     strncpy(ifr.ifr_name, iface, IFNAMSIZ);
     
     if (skfd && ioctl(skfd, SIOCGIFFLAGS, &ifr) >= 0) {
         strncpy(ifr.ifr_name, iface, IFNAMSIZ);
         ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
         ioctl(skfd, SIOCSIFFLAGS, &ifr);
+        if (vlandot) {
+            ifr.ifr_mtu = 1496;
+            ioctl(skfd, SIOCSIFMTU, &ifr);
+        }
     }
 }
 
 void interface_down (char* iface)
 {
     struct ifreq ifr;
+    char *vlandot = strchr (iface, '.');
     
     strncpy(ifr.ifr_name, iface, IFNAMSIZ);
     
@@ -822,6 +925,12 @@
         strncpy(ifr.ifr_name, iface, IFNAMSIZ);
         ifr.ifr_flags &= ~IFF_UP;
         ioctl(skfd, SIOCSIFFLAGS, &ifr);
+        if (vlandot) {
+            char *rawdev = strdup (iface);
+            rawdev[vlandot-iface] = 0;
+            interface_down (rawdev);
+            free (rawdev);
+        }
     }
 }
 
-- 
Regards,
Feri.

Reply to: