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

Bug#433568: [PATCH 1/3] Add vlan support.



---
 Makefile                       |  2 +-
 debian/changelog               |  3 ++
 debian/netcfg-common.templates | 34 +++++++++++++++++++--
 netcfg.c                       |  5 ++++
 netcfg.h                       |  2 ++
 vlan.c                         | 67 ++++++++++++++++++++++++++++++++++++++++++
 write_interface.c              | 20 ++++++++++++-
 7 files changed, 129 insertions(+), 4 deletions(-)
 create mode 100644 vlan.c

diff --git a/Makefile b/Makefile
index a15d476..03343c9 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ TARGETS		?= netcfg-static netcfg
 
 LDOPTS		= -ldebconfclient -ldebian-installer
 CFLAGS		= -W -Wall -Werror -DNDEBUG -DNETCFG_VERSION="\"$(NETCFG_VERSION)\"" -I.
-COMMON_OBJS	= netcfg-common.o wireless.o write_interface.o ipv6.o
+COMMON_OBJS	= netcfg-common.o wireless.o write_interface.o ipv6.o vlan.o
 NETCFG_O   	= netcfg.o dhcp.o static.o ethtool-lite.o wpa.o wpa_ctrl.o rdnssd.o autoconfig.o
 NETCFG_STATIC_O	= netcfg-static.o static.o ethtool-lite.o
 
diff --git a/debian/changelog b/debian/changelog
index 0930928..2a5e4e6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,9 @@ netcfg (1.138) UNRELEASED; urgency=medium
   * static: trim user-specified values for IP and other addresses
   * Closes: #818611, LP: #1541955
 
+  [ YunQiang Su ]
+  * Add vlan support. Closes: #433568
+
   [ Dimitri John Ledkov ]
   * dhcp.c: check return result of two more fgets calls
   * nm-conf.c: check return result of fscanf
diff --git a/debian/netcfg-common.templates b/debian/netcfg-common.templates
index 2b77936..0dc3446 100644
--- a/debian/netcfg-common.templates
+++ b/debian/netcfg-common.templates
@@ -22,10 +22,41 @@ Type: string
 # :sl1:
 _Description: Domain name:
  The domain name is the part of your Internet address to the right of your
- host name.  It is often something that ends in .com, .net, .edu, or .org. 
+ host name.  It is often something that ends in .com, .net, .edu, or .org.
  If you are setting up a home network, you can make something up, but make
  sure you use the same domain name on all your computers.
 
+Template: netcfg/use_vlan
+Type: boolean
+Default: false
+# :sl6:
+_Description: Are you configuring on an IEEE 802.1Q VLAN trunk port?
+ Virtual LAN (VLAN) is a concept of partitioning a physical network to create
+ distinct broadcast domains. Packets can be marked for different IDs by
+ tagging, so that a single interconnect (trunk) may be used to transport
+ data for various VLANs.
+ .
+ If your network interface is directly attached to a VLAN trunk port,
+ specifying a VLAN ID may be necessary to get a working connection.
+
+Template: netcfg/vlan_id
+Type: string
+# :sl6:
+_Description: VLAN ID (1-4094):
+ VLAN IDs are divided into a normal range and an extended range:
+ .
+ Normal range IDs are 1-1005. 1 is the default native VLAN,
+ and 1002-1005 are reserved for Token Ring and FDDI VLANs.
+ Extended range IDs are 1006-4094, which are designed for service
+ providers and have fewer options.
+
+Template: netcfg/vlan_cmderror
+Type: error
+# :sl6:
+_Description: Error setting VLAN
+ The command used to set VLAN during installation got an error,
+ please go back and try again.
+
 Template: netcfg/get_nameservers
 Type: string
 # :sl1:
@@ -371,4 +402,3 @@ _Choices: ${essid_list} Enter ESSID manually
 # :sl1:
 _Description: Wireless network:
  Select the wireless network to use during the installation process.
-
diff --git a/netcfg.c b/netcfg.c
index 195681b..df0bc04 100644
--- a/netcfg.c
+++ b/netcfg.c
@@ -222,6 +222,11 @@ int main(int argc, char *argv[])
                 else
                     state = GET_METHOD;
             }
+
+            if(netcfg_set_vlan(&interface, client) == GO_BACK){
+                state = BACKUP;
+            }
+
             break;
         case GET_HOSTNAME_ONLY:
             if(netcfg_get_hostname(client, "netcfg/get_hostname", hostname, 0))
diff --git a/netcfg.h b/netcfg.h
index 00a2cea..4dfbdee 100644
--- a/netcfg.h
+++ b/netcfg.h
@@ -270,4 +270,6 @@ extern void cleanup_dhcpv6_client(void);
 extern int start_dhcpv6_client(struct debconfclient *client, const struct netcfg_interface *interface);
 extern int netcfg_autoconfig(struct debconfclient *client, struct netcfg_interface *interface);
 
+extern int netcfg_set_vlan(struct netcfg_interface *interface, struct debconfclient *client);
+
 #endif /* _NETCFG_H_ */
diff --git a/vlan.c b/vlan.c
new file mode 100644
index 0000000..ec2a19b
--- /dev/null
+++ b/vlan.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <cdebconf/debconfclient.h>
+#include <debian-installer.h>
+#include "netcfg.h"
+
+#define VLAN_SUCESSED 0
+#define VLAN_FAILED 1
+int netcfg_set_vlan(struct netcfg_interface *interface, struct debconfclient *client){
+    char *vlaniface = NULL, *vlanid = NULL, *vlancmd = NULL;
+    int vlaniface_len, vlancmd_len;
+
+/*kfreebsd or hurd has different cmd to set vlan*/
+#if defined(__linux__)
+    char vlancmd_template[] = "ip link add link %s name %s type vlan id %s";
+#elif defined(__FreeBSD_kernel__)
+    /*export 2 more to make it the same formt with Linux*/
+    char vlancmd_tmplate[] = "export NIC=%s; export VNIC=%s; export VLANID=%s;" 
+                             " ifconfig $VNIC create";
+#endif
+    int vlancmd_template_len = sizeof(vlancmd_template);
+
+    debconf_input(client, "medium", "netcfg/use_vlan");
+
+    if (debconf_go(client) == CMD_GOBACK)
+       return GO_BACK;
+    debconf_get(client, "netcfg/use_vlan");
+
+    if (!strcmp(client->value, "false")){
+       goto error;
+    }
+
+    debconf_input(client, "critical", "netcfg/vlan_id");
+    debconf_get(client, "netcfg/vlan_id");
+    vlanid = client -> value;
+
+    vlaniface_len = strlen(interface->name)+strlen(vlanid)+2;
+    vlaniface = malloc(vlaniface_len);
+    if(! vlaniface){
+       goto error;
+    }
+    snprintf(vlaniface, vlaniface_len, "%s.%s", interface->name, vlanid);
+    vlancmd_len = vlancmd_template_len + vlaniface_len*2 +1;
+    vlancmd = malloc(vlancmd_len);
+    if(! vlancmd){
+       goto error;
+    }
+    snprintf(vlancmd, vlancmd_len, vlancmd_template, interface->name, vlaniface, vlanid);
+    if(di_exec_shell_log(vlancmd)){
+       di_warning("^ Setting VLAN error: the command is \n%s", vlancmd);
+       debconf_capb(client); 
+       debconf_input(client, "critical", "netcfg/vlan_cmderror"); 
+       debconf_go(client); 
+       debconf_capb(client, "backup"); 
+       goto error;
+    }
+    if(interface->name){
+         free(interface->name);
+         interface->name = vlaniface;
+    }
+    free(vlancmd);
+    return VLAN_SUCESSED;
+
+error:
+    if(vlaniface) free(vlaniface);
+    if(vlancmd) free(vlancmd);
+    return VLAN_FAILED;
+}
diff --git a/write_interface.c b/write_interface.c
index 2ab1a34..be0d78b 100644
--- a/write_interface.c
+++ b/write_interface.c
@@ -44,6 +44,21 @@ static int nc_wi_loopback(const struct netcfg_interface *interface, FILE *fd)
 	return 1;
 }
 
+/* Write VLAN settings, such as: vlan_raw_device eth0
+*/
+static int nc_wi_vlan(const struct netcfg_interface *interface, FILE *fd)
+{
+    char *dup_name, *strip_name;
+    dup_name = strdup(interface->name);
+    strip_name = strsep(&dup_name, ".");
+    if(strip_name != NULL){
+        fprintf(fd, "\tvlan_raw_device %s\n", strip_name);
+	}
+    free(dup_name);
+	return 1;
+}
+
+
 static int nc_wi_wireless_options(const struct netcfg_interface *interface, FILE *fd)
 {
 	/*
@@ -271,7 +286,10 @@ int netcfg_write_interface(const struct netcfg_interface *interface)
 		di_debug("Writing static IPv6 stanza for %s", interface->name);
 		rv = nc_wi_static_ipv6(interface, fd);
 	}
-	
+	if (rv && strchr(interface->name, '.')){
+		di_debug("Writing VLAN: %s", interface->name);
+		rv = nc_wi_vlan(interface, fd);
+	}
 	if (rv && interface && is_wireless_iface(interface->name)) {
 		di_debug("Writing wireless options for %s", interface->name);
 		rv = nc_wi_wireless_options(interface, fd);
-- 
2.7.4


Reply to: