--- 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