diff --git a/Makefile b/Makefile
index a573a0e..203b2de 100644
--- a/Makefile
+++ b/Makefile
@@ -35,8 +35,8 @@ endif
 
 all: $(TARGETS)
 
-netcfg-static: netcfg-static.o static.o ethtool-lite.o
-netcfg: netcfg.o dhcp.o static.o ethtool-lite.o wpa.o wpa_ctrl.o rdnssd.o autoconfig.o
+netcfg-static: netcfg-static.o static.o ethtool-lite.o vlan.o
+netcfg: netcfg.o dhcp.o static.o ethtool-lite.o wpa.o wpa_ctrl.o rdnssd.o autoconfig.o vlan.o
 
 ethtool-lite: ethtool-lite-test.o
 	$(CC) -o $@ $<
diff --git a/debian/changelog b/debian/changelog
index 06d4557..1e48d08 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-netcfg (1.93) unstable; urgency=low
+netcfg (1.93+vlan) unstable; urgency=low
 
   [ Philipp Kern ]
   * Check the return code of the waitpid calls found in various cleanup
diff --git a/debian/netcfg-common.templates b/debian/netcfg-common.templates
index c579a16..3ac3a7f 100644
--- a/debian/netcfg-common.templates
+++ b/debian/netcfg-common.templates
@@ -26,6 +26,37 @@ _Description: Domain name:
  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:
diff --git a/netcfg.c b/netcfg.c
index d74f68f..98fffa3 100644
--- a/netcfg.c
+++ b/netcfg.c
@@ -215,6 +206,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 91c9d22..da44c02 100644
--- a/netcfg.h
+++ b/netcfg.h
@@ -268,4 +268,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..fce3a7b
--- /dev/null
+++ b/vlan.c
@@ -0,0 +1,73 @@
+#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);
+
+    vlancmd = malloc(256);
+    if(! vlancmd){
+        free(vlaniface);
+        goto error;
+    }
+    
+    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 d269301..1a58a2d 100644
--- a/write_interface.c
+++ b/write_interface.c
@@ -43,6 +43,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)
 {
 	/*
@@ -270,7 +285,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);
