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.