diff --git a/src/Makefile b/src/Makefile
index ad5e9250bd632193fe24a71a654619bf7ebf3b5c..3a533850f278185fd2f2851fdbce4fa4baa3fe99 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -32,7 +32,7 @@ ${PROG}: $(OBJS)
 	$(CP) ${PROG} ../${PROG}
 
 $(LIB): $(LIB_OBJS)
-	$(CC) $(PROG_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
+	$(CC) $(PROG_CFLAGS) $(PROG_LDFLAGS) -shared -o $@ $^
 	$(CP) ${LIB} ../${LIB}
 
 clean:
diff --git a/src/datamodel.c b/src/datamodel.c
index a8277bea4a3849862e341f640e5805cb6b203678..4043c64f972eab3b27a75db0b6df72d20ac36c76 100644
--- a/src/datamodel.c
+++ b/src/datamodel.c
@@ -10,6 +10,11 @@
 
 #include "datamodel.h"
 
+#define MAX_ENV_VAR_BUFF 1620
+#define MAX_ENV_VAR_NUM 5
+#define MAX_ENV_KEY_LEN 64
+#define MAX_ENV_VAL_LEN 256
+
 /* ********** DynamicObj ********** */
 DM_MAP_OBJ tDynamicObj[] = {
 /* parentobj, nextobject, parameter */
@@ -838,6 +843,8 @@ static operation_args softwaremodules_installdu_args = {
 		"Username",
 		"Password",
 		"ExecutionEnvRef",
+		"EnvVariable.{i}.Key",
+		"EnvVariable.{i}.Value",
 		NULL
 	}
 };
@@ -852,11 +859,46 @@ static int operate_SoftwareModules_InstallDU(char *refparam, struct dmctx *ctx,
 {
 	unsigned int eeid = 0;
 	json_object *res = NULL;
+	char env_var[MAX_ENV_VAR_BUFF] = {0};
+	int i;
 
 	char *url = dmjson_get_value((json_object *)value, 1, "URL");
 	if (url[0] == '\0')
 		return USP_FAULT_INVALID_ARGUMENT;
 
+	for (i = 0; i < MAX_ENV_VAR_NUM; i++) {
+		char buf[32] = {0};
+
+		snprintf(buf, sizeof(buf), "EnvVariable.%d.Key", i+1);
+		char *key = dmjson_get_value((json_object *)value, 1, buf);
+		if (DM_STRLEN(key) == 0) {
+			break;
+		}
+
+		snprintf(buf, sizeof(buf), "EnvVariable.%d.Value", i+1);
+		char *val = dmjson_get_value((json_object *)value, 1, buf);
+
+		if (DM_STRLEN(key) > MAX_ENV_KEY_LEN || DM_STRLEN(val) > MAX_ENV_VAL_LEN) {
+			TRACE("Key value length exceeded, max key len=%d and value len=%d", MAX_ENV_KEY_LEN, MAX_ENV_VAL_LEN);
+			bbfdm_set_fault_message(ctx, "Max supported key len=%d and value len=%d", MAX_ENV_KEY_LEN, MAX_ENV_VAL_LEN);
+			return USP_FAULT_INVALID_ARGUMENT;
+		}
+
+		if ((DM_STRLEN(env_var) == 0) && ((sizeof(env_var) - 1) >= (DM_STRLEN(key) + DM_STRLEN(val) + 1))) {
+			snprintf(env_var, sizeof(env_var), "%s=%s", key, val);
+		} else if ((sizeof(env_var) - DM_STRLEN(env_var) - 1) >= (DM_STRLEN(key) + DM_STRLEN(val) + 2)) {
+			char var[MAX_ENV_KEY_LEN + 2] = {0};
+
+			snprintf(var, sizeof(var), "%s=", key);
+
+			if (DM_STRSTR(env_var, var) == NULL) { // key should be unique
+				char *tmp = env_var + DM_STRLEN(env_var);
+				size_t size = sizeof(env_var) - DM_STRLEN(env_var);
+				snprintf(tmp, size, ",%s=%s", key, val);
+			}
+		}
+	}
+
 	char *uuid = dmjson_get_value((json_object *)value, 1, "UUID");
 	char *username = dmjson_get_value((json_object *)value, 1, "Username");
 	char *password = dmjson_get_value((json_object *)value, 1, "Password");
@@ -878,8 +920,9 @@ static int operate_SoftwareModules_InstallDU(char *refparam, struct dmctx *ctx,
 			{"uuid", uuid, String},
 			{"username", username, String},
 			{"password", password, String},
-			{"eeid", eeid_str, Integer}},
-			5,
+			{"eeid", eeid_str, Integer},
+			{"env_var", env_var, String}},
+			6,
 			&res);
 
 	char *status = dmjson_get_value(res, 1, "status");
diff --git a/src/swmod.c b/src/swmod.c
index 6a01fceecfa29651f9a161a5579b60e487619a3a..d1aef069f446daa6de4a3bc5c34fec69bf57f56b 100644
--- a/src/swmod.c
+++ b/src/swmod.c
@@ -48,6 +48,7 @@ enum {
 	DU_INSTALL_URL,
 	DU_INSTALL_USERNAME,
 	DU_INSTALL_PASSWORD,
+	DU_INSTALL_ENVVAR,
 	__DU_INSTALL_MAX
 };
 
@@ -139,6 +140,7 @@ static const struct blobmsg_policy du_install_policy[__DU_INSTALL_MAX] = {
 	[DU_INSTALL_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING },
 	[DU_INSTALL_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING },
 	[DU_INSTALL_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING },
+	[DU_INSTALL_ENVVAR] = { .name = "env_var", .type = BLOBMSG_TYPE_STRING },
 };
 
 static const struct blobmsg_policy du_update_policy[__DU_UPDATE_MAX] = {
@@ -441,6 +443,17 @@ static void swmod_perform_package_install(PkgInfo *pkg)
 	swmod_uci_set_value_by_section(s, "ee_name", pkg->env_name);
 	swmod_uci_set_value_by_section(s, "du_status", "Installing");
 
+	if (strlen(pkg->env_var) != 0) {
+		char *tok = NULL, *ptr = NULL;
+		char env_var_buff[MAX_ENV_VAR_BUFF] = {0};
+
+		snprintf(env_var_buff, sizeof(env_var_buff), "%s", pkg->env_var);
+
+		for (tok = strtok_r(env_var_buff, ",", &ptr); tok != NULL; tok = strtok_r(NULL, ",", &ptr)) {
+			swmod_uci_set_value_by_section_list(s, "env_var", tok);
+		}
+	}
+
 	char *duid = generate_duid(true, incr++);
 	swmod_uci_set_value_by_section(s, "duid", duid);
 	FREE(duid);
@@ -727,6 +740,9 @@ swmod_du_install(struct ubus_context *ctx, struct ubus_object *obj,
 	if (tb[DU_INSTALL_PASSWORD])
 		snprintf(pkg.psw, sizeof(pkg.psw), "%s", blobmsg_get_string(tb[DU_INSTALL_PASSWORD]));
 
+	if (tb[DU_INSTALL_ENVVAR])
+		snprintf(pkg.env_var, sizeof(pkg.env_var), "%s", blobmsg_get_string(tb[DU_INSTALL_ENVVAR]));
+
 	snprintf(pkg.env_name, sizeof(pkg.env_name), "%s", env->name);
 	pkg.operation = SWMOD_INSTALL;
 
diff --git a/src/swmod_common.h b/src/swmod_common.h
index 7908efb93b6cedbaf4f8793ab47f8f2712c98af4..e5fad84dc2848dc0aa25ddb4cea3cdc5441a8e4d 100644
--- a/src/swmod_common.h
+++ b/src/swmod_common.h
@@ -17,6 +17,7 @@
 #define PROC_PATH "/proc"
 #define DW_TMP_DIR_PATH "/tmp"
 #define DW_PKG_LOCAL_PATH DW_TMP_DIR_PATH"/dw_package.ipk"
+#define MAX_ENV_VAR_BUFF 1620
 
 enum swmod_du_opration_enum {
 	SWMOD_INSTALL,
@@ -27,6 +28,7 @@ enum swmod_du_opration_enum {
 
 typedef struct {
 	time_t start;
+	char env_var[MAX_ENV_VAR_BUFF];
 	char url[2049];
 	char uname[257];
 	char psw[257];