[PATCH] osmo-ggsn[master]: sgsnemu: Add '--tun-device' option to specify TUN device name

Harald Welte gerrit-no-reply at lists.osmocom.org
Tue Oct 10 01:46:14 UTC 2017


Review at  https://gerrit.osmocom.org/4190

sgsnemu: Add '--tun-device' option to specify TUN device name

This way, multiple sgsnemu instances can be runnig in parallel, each
of them creating a different tun device for their respective PDP context

Change-Id: Id12fbadf924a60db255b6d51b9f647aa51dd2e16
---
M sgsnemu/cmdline.c
M sgsnemu/cmdline.ggo
M sgsnemu/cmdline.h
M sgsnemu/sgsnemu.c
4 files changed, 90 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-ggsn refs/changes/90/4190/1

diff --git a/sgsnemu/cmdline.c b/sgsnemu/cmdline.c
index 60c0a25..441322b 100644
--- a/sgsnemu/cmdline.c
+++ b/sgsnemu/cmdline.c
@@ -70,6 +70,7 @@
 	"      --defaultroute            Create default route  (default=off)",
 	"      --ipup=STRING             Script to run after link-up",
 	"      --ipdown=STRING           Script to run after link-down",
+	"      --tun-device=STRING       Name of the local network interface",
 	"      --pinghost=STRING         Ping remote host",
 	"      --pingrate=INT            Number of ping req per second  (default=`1')",
 	"      --pingsize=INT            Number of ping data bytes  (default=`56')",
@@ -94,6 +95,9 @@
 			struct cmdline_parser_params *params,
 			const char *additional_error);
 
+static int
+cmdline_parser_required2(struct gengetopt_args_info *args_info,
+			 const char *prog_name, const char *additional_error);
 struct line_list {
 	char *string_arg;
 	struct line_list *next;
@@ -156,6 +160,7 @@
 	args_info->defaultroute_given = 0;
 	args_info->ipup_given = 0;
 	args_info->ipdown_given = 0;
+	args_info->tun_device_given = 0;
 	args_info->pinghost_given = 0;
 	args_info->pingrate_given = 0;
 	args_info->pingsize_given = 0;
@@ -233,6 +238,8 @@
 	args_info->ipup_orig = NULL;
 	args_info->ipdown_arg = NULL;
 	args_info->ipdown_orig = NULL;
+	args_info->tun_device_arg = NULL;
+	args_info->tun_device_orig = NULL;
 	args_info->pinghost_arg = NULL;
 	args_info->pinghost_orig = NULL;
 	args_info->pingrate_arg = 1;
@@ -288,13 +295,14 @@
 	args_info->defaultroute_help = gengetopt_args_info_help[33];
 	args_info->ipup_help = gengetopt_args_info_help[34];
 	args_info->ipdown_help = gengetopt_args_info_help[35];
-	args_info->pinghost_help = gengetopt_args_info_help[36];
-	args_info->pingrate_help = gengetopt_args_info_help[37];
-	args_info->pingsize_help = gengetopt_args_info_help[38];
-	args_info->pingcount_help = gengetopt_args_info_help[39];
-	args_info->pingquiet_help = gengetopt_args_info_help[40];
-	args_info->no_tx_gpdu_seq_help = gengetopt_args_info_help[41];
-	args_info->pdp_type_help = gengetopt_args_info_help[42];
+	args_info->tun_device_help = gengetopt_args_info_help[36];
+	args_info->pinghost_help = gengetopt_args_info_help[37];
+	args_info->pingrate_help = gengetopt_args_info_help[38];
+	args_info->pingsize_help = gengetopt_args_info_help[39];
+	args_info->pingcount_help = gengetopt_args_info_help[40];
+	args_info->pingquiet_help = gengetopt_args_info_help[41];
+	args_info->no_tx_gpdu_seq_help = gengetopt_args_info_help[42];
+	args_info->pdp_type_help = gengetopt_args_info_help[43];
 
 }
 
@@ -419,6 +427,8 @@
 	free_string_field(&(args_info->ipup_orig));
 	free_string_field(&(args_info->ipdown_arg));
 	free_string_field(&(args_info->ipdown_orig));
+	free_string_field(&(args_info->tun_device_arg));
+	free_string_field(&(args_info->tun_device_orig));
 	free_string_field(&(args_info->pinghost_arg));
 	free_string_field(&(args_info->pinghost_orig));
 	free_string_field(&(args_info->pingrate_orig));
@@ -529,6 +539,9 @@
 		write_into_file(outfile, "ipup", args_info->ipup_orig, 0);
 	if (args_info->ipdown_given)
 		write_into_file(outfile, "ipdown", args_info->ipdown_orig, 0);
+	if (args_info->tun_device_given)
+		write_into_file(outfile, "tun-device",
+				args_info->tun_device_orig, 0);
 	if (args_info->pinghost_given)
 		write_into_file(outfile, "pinghost", args_info->pinghost_orig,
 				0);
@@ -640,9 +653,37 @@
 cmdline_parser_required(struct gengetopt_args_info *args_info,
 			const char *prog_name)
 {
-	FIX_UNUSED(args_info);
-	FIX_UNUSED(prog_name);
-	return EXIT_SUCCESS;
+	int result = EXIT_SUCCESS;
+
+	if (cmdline_parser_required2(args_info, prog_name, 0) > 0)
+		result = EXIT_FAILURE;
+
+	if (result == EXIT_FAILURE) {
+		cmdline_parser_free(args_info);
+		exit(EXIT_FAILURE);
+	}
+
+	return result;
+}
+
+int
+cmdline_parser_required2(struct gengetopt_args_info *args_info,
+			 const char *prog_name, const char *additional_error)
+{
+	int error_occurred = 0;
+	FIX_UNUSED(additional_error);
+
+	/* checks for required options */
+
+	/* checks for dependences among options */
+	if (args_info->tun_device_given && !args_info->createif_given) {
+		fprintf(stderr,
+			"%s: '--tun-device' option depends on option 'createif'%s\n",
+			prog_name, (additional_error ? additional_error : ""));
+		error_occurred = 1;
+	}
+
+	return error_occurred;
 }
 
 static char *package_name = 0;
@@ -837,6 +878,7 @@
 			{"defaultroute", 0, NULL, 0},
 			{"ipup", 1, NULL, 0},
 			{"ipdown", 1, NULL, 0},
+			{"tun-device", 1, NULL, 0},
 			{"pinghost", 1, NULL, 0},
 			{"pingrate", 1, NULL, 0},
 			{"pingsize", 1, NULL, 0},
@@ -1355,6 +1397,22 @@
 					goto failure;
 
 			}
+			/* Name of the local network interface.  */
+			else if (strcmp
+				 (long_options[option_index].name,
+				  "tun-device") == 0) {
+
+				if (update_arg
+				    ((void *)&(args_info->tun_device_arg),
+				     &(args_info->tun_device_orig),
+				     &(args_info->tun_device_given),
+				     &(local_args_info.tun_device_given),
+				     optarg, 0, 0, ARG_STRING, check_ambiguity,
+				     override, 0, 0, "tun-device", '-',
+				     additional_error))
+					goto failure;
+
+			}
 			/* Ping remote host.  */
 			else if (strcmp
 				 (long_options[option_index].name,
@@ -1460,6 +1518,12 @@
 		}		/* switch */
 	}			/* while */
 
+	if (check_required) {
+		error_occurred +=
+		    cmdline_parser_required2(args_info, argv[0],
+					     additional_error);
+	}
+
 	cmdline_parser_release(&local_args_info);
 
 	if (error_occurred)
diff --git a/sgsnemu/cmdline.ggo b/sgsnemu/cmdline.ggo
index d8b3c26..7592eb5 100644
--- a/sgsnemu/cmdline.ggo
+++ b/sgsnemu/cmdline.ggo
@@ -54,6 +54,7 @@
 option  "defaultroute" - "Create default route"           flag   off
 option  "ipup"         - "Script to run after link-up"    string no
 option  "ipdown"       - "Script to run after link-down"  string no
+option  "tun-device"   - "Name of the local network interface" string dependon="createif" no
 
 option  "pinghost"     - "Ping remote host"               string no
 option  "pingrate"     - "Number of ping req per second"  int default="1" no
diff --git a/sgsnemu/cmdline.h b/sgsnemu/cmdline.h
index 1accfd0..9dc210e 100644
--- a/sgsnemu/cmdline.h
+++ b/sgsnemu/cmdline.h
@@ -236,6 +236,12 @@
 			/**< @brief Script to run after link-down original value given at command line.  */
 		const char *ipdown_help;
 			   /**< @brief Script to run after link-down help description.  */
+		char *tun_device_arg;
+				/**< @brief Name of the local network interface.  */
+		char *tun_device_orig;
+				/**< @brief Name of the local network interface original value given at command line.  */
+		const char *tun_device_help;
+			       /**< @brief Name of the local network interface help description.  */
 		char *pinghost_arg;
 			/**< @brief Ping remote host.  */
 		char *pinghost_orig;
@@ -347,6 +353,8 @@
 				/**< @brief Whether ipup was given.  */
 		unsigned int ipdown_given;
 				/**< @brief Whether ipdown was given.  */
+		unsigned int tun_device_given;
+					/**< @brief Whether tun-device was given.  */
 		unsigned int pinghost_given;
 				/**< @brief Whether pinghost was given.  */
 		unsigned int pingrate_given;
diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c
index fa295da..c83aebd 100644
--- a/sgsnemu/sgsnemu.c
+++ b/sgsnemu/sgsnemu.c
@@ -84,6 +84,7 @@
 struct {
 	int debug;		/* Print debug messages */
 	int createif;		/* Create local network interface */
+	char *tun_dev_name;
 	struct in_addr netaddr, destaddr, net;	/* Network interface  */
 	size_t prefixlen;
 	char *ipup, *ipdown;	/* Filename of scripts */
@@ -289,6 +290,8 @@
 		printf("contexts: %d\n", args_info.contexts_arg);
 		printf("timelimit: %d\n", args_info.timelimit_arg);
 		printf("createif: %d\n", args_info.createif_flag);
+		if (args_info.tun_device_arg)
+			printf("tun-device: %d\n", args_info.tun_device_arg);
 		if (args_info.ipup_arg)
 			printf("ipup: %s\n", args_info.ipup_arg);
 		if (args_info.ipdown_arg)
@@ -345,6 +348,8 @@
 			printf("contexts: %d\n", args_info.contexts_arg);
 			printf("timelimit: %d\n", args_info.timelimit_arg);
 			printf("createif: %d\n", args_info.createif_flag);
+			if (args_info.tun_device_arg)
+				printf("tun-device: %d\n", args_info.tun_device_arg);
 			if (args_info.ipup_arg)
 				printf("ipup: %s\n", args_info.ipup_arg);
 			if (args_info.ipdown_arg)
@@ -863,6 +868,7 @@
 
 	/* createif */
 	options.createif = args_info.createif_flag;
+	options.tun_dev_name = args_info.tun_device_arg;
 
 	/* net                                                          */
 	/* Store net as in_addr net and mask                            */
@@ -1525,7 +1531,7 @@
 	if (options.createif) {
 		printf("Setting up interface\n");
 		/* Create a tunnel interface */
-		if (tun_new((struct tun_t **)&tun, NULL)) {
+		if (tun_new((struct tun_t **)&tun, options.tun_dev_name)) {
 			SYS_ERR(DSGSN, LOGL_ERROR, 0,
 				"Failed to create tun");
 			exit(1);

-- 
To view, visit https://gerrit.osmocom.org/4190
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id12fbadf924a60db255b6d51b9f647aa51dd2e16
Gerrit-PatchSet: 1
Gerrit-Project: osmo-ggsn
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>


More information about the gerrit-log mailing list