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: