diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fcea03516ec5c098ce4fc2f0dbfbfd3e037a7f10
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,13 @@
+include:
+ - project: 'iopsys/gitlab-ci-pipeline'
+ file: '/static-code-analysis.yml'
+ ref: '0.31'
+
+stages:
+ - static_code_analysis
+
+variables:
+ DEBUG: 'TRUE'
+ SOURCE_FOLDER: "./bbf_plugin"
+ CPPCHECK_OPTIONS: "--enable=all --error-exitcode=1 ."
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..59536805e59ad69447b519a36558f898cd6c354c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,19 @@
+CC=gcc
+
+PLUGIN = bbf_plugin
+
+
+PROG_CFLAGS = $(CFLAGS) -Wall -Werror -fstrict-aliasing
+PROG_LDFLAGS = $(LDFLAGS)
+PROG_LIBS += -luci -ljson-c -lblobmsg_json
+
+%.o: %.c
+ (CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
+
+.PHONY: all clean
+
+all:
+ $(MAKE) -C ./bbf_plugin
+
+clean:
+ rm -rf *.o *.so
diff --git a/bbf_plugin/Makefile b/bbf_plugin/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bcd8adb71bbeaffb36e2fb69c3ef23a800ae660e
--- /dev/null
+++ b/bbf_plugin/Makefile
@@ -0,0 +1,21 @@
+LIB_PORTTRIGGER := libporttrigger.so
+
+OBJS := nat_porttrigger.o
+
+LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fstrict-aliasing
+LIB_LDFLAGS = $(LDFLAGS)
+FPIC := -fPIC
+
+.PHONY: all
+
+%.o: %.c
+ $(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $<
+
+all: $(LIB_PORTTRIGGER)
+
+$(LIB_PORTTRIGGER): $(OBJS)
+ $(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
+
+clean:
+ rm -f *.o $(LIB_PORTTRIGGER)
+
diff --git a/bbf_plugin/nat_porttrigger.c b/bbf_plugin/nat_porttrigger.c
new file mode 100644
index 0000000000000000000000000000000000000000..de76eaed919db1f39965fd5db438aa7609a440fb
--- /dev/null
+++ b/bbf_plugin/nat_porttrigger.c
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2024 iopsys Software Solutions AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * Author: Amit Kumar <amit.kumar@iopsys.eu>
+ *
+ */
+
+#include "libbbfdm-api/dmcommon.h"
+
+/*************************************************************
+* ENTRY METHOD
+**************************************************************/
+
+/*#Device.NAT.PortTrigger.{i}.!UCI:port-trigger/port_trigger/dmmap_port_trigger*/
+static int browseNATPortTriggerInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
+{
+ int inst = 0;
+ struct uci_section *p = NULL;
+ struct dm_data data = {0};
+ char *name = NULL;
+ char *buf = NULL;
+
+ uci_foreach_sections("port-trigger", "port_trigger", p) {
+ dmuci_get_section_name(section_name(p),&name);
+ if (name) {
+ sscanf(name, "port_trigger_%d",&inst);
+ if (inst == 0) {
+ continue;
+ }
+ dmasprintf(&buf, "%d", inst);
+ data.config_section = p;
+ if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&data, buf) == DM_STOP)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int browseNATPortTriggerRuleInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
+{
+ struct uci_section *p = NULL;
+ struct dm_data data = {0};
+ int inst = 0;
+ int ptg_inst = 0;
+ char *name = NULL;
+ char *buf = NULL;
+ int parent_inst = 0;
+ parent_inst = atoi(prev_instance);
+
+ uci_foreach_sections("port-trigger", "rule", p) {
+ dmuci_get_section_name(section_name(p),&name);
+ if (name) {
+ sscanf(name, "port_trigger_%d_rule_%d",&ptg_inst,&inst);
+ if ((inst == 0) || (ptg_inst != parent_inst))
+ continue;
+ dmasprintf(&buf, "%d", inst);
+ data.config_section = p;
+ if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&data, buf) == DM_STOP)
+ break;
+ }
+ }
+ return 0;
+}
+
+/*************************************************************
+* ADD & DEL OBJ
+**************************************************************/
+static int addObjNATPortTrigger(char *refparam, struct dmctx *ctx, void *data, char **instance)
+{
+ struct uci_section *s = NULL;
+ char port_trigger_name[16] = {0};
+ char name[16] = {0};
+
+ snprintf(port_trigger_name, sizeof(port_trigger_name), "port_trigger_%s", *instance);
+ snprintf(name, sizeof(name), "trigger_%s", *instance);
+
+ dmuci_add_section("port-trigger", "port_trigger", &s);
+ dmuci_rename_section_by_section(s, port_trigger_name);
+ dmuci_set_value_by_section(s, "name", name);
+
+ return 0;
+}
+
+static int delObjNATPortTrigger(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
+{
+ struct uci_section *s = NULL, *stmp = NULL;
+ char *name;
+
+ switch (del_action) {
+ case DEL_INST:
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", &name);
+ uci_foreach_option_eq_safe("port-trigger", "rule", "port_trigger", name, stmp, s) {
+ dmuci_delete_by_section(s, NULL, NULL);
+ }
+
+ dmuci_delete_by_section(((struct dm_data *)data)->config_section, NULL, NULL);
+ break;
+ case DEL_ALL:
+ uci_foreach_sections_safe("port-trigger", "port_trigger", stmp, s) {
+
+ dmuci_delete_by_section(s, NULL, NULL);
+ }
+ uci_foreach_sections_safe("port-trigger", "rule", stmp, s) {
+
+ dmuci_delete_by_section(s, NULL, NULL);
+ }
+ break;
+ }
+ return 0;
+}
+
+static int addObjNATPortTriggerRule(char *refparam, struct dmctx *ctx, void *data, char **instance)
+{
+ struct uci_section *port_trigger = ((struct dm_data *)data)->config_section;
+ struct uci_section *s = NULL;
+ char s_name[50] = {0};
+ char *name = NULL;
+
+ snprintf(s_name, sizeof(s_name), "%s_rule_%s", section_name(port_trigger),*instance);
+
+ dmuci_add_section("port-trigger", "rule", &s);
+ dmuci_rename_section_by_section(s, s_name);
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", &name);
+ dmuci_set_value_by_section(s, "port_trigger", name);
+
+ return 0;
+}
+
+static int delObjNATPortTriggerRule(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
+{
+ struct uci_section *s = NULL, *stmp = NULL;
+ char *name;
+
+ switch (del_action) {
+ case DEL_INST:
+ dmuci_delete_by_section(((struct dm_data *)data)->config_section, NULL, NULL);
+ break;
+ case DEL_ALL:
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", &name);
+ uci_foreach_option_eq_safe("port-trigger", "rule", "port_trigger", name, stmp, s) {
+ dmuci_delete_by_section(s, NULL, NULL);
+ }
+ break;
+ }
+ return 0;
+}
+
+/*************************************************************
+* GET & SET PARAM
+**************************************************************/
+/*#Device.NAT.PortTriggerNumberOfEntries!UCI:port-trigger/port_trigger/*/
+static int get_NAT_PortTriggerNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ int cnt = get_number_of_entries(ctx, data, instance, browseNATPortTriggerInst);
+ dmasprintf(value, "%d", cnt);
+ return 0;
+}
+
+static int get_NATPortTrigger_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ dmuci_get_section_name(section_name(((struct dm_data *)data)->config_section),value);
+ return 0;
+}
+
+static int get_NATPortTrigger_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "enable", "0");
+ *value = (**value == 'n' || **value == '0' ) ? "0" : "1";
+ return 0;
+}
+
+static int set_NATPortTrigger_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ bool b;
+ time_t now = time(NULL);
+
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_boolean(ctx, value))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ string_to_bool(value, &b);
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "enable", b ? "1" : "0");
+
+ if (b == 1) {
+ char activation_date[32] = {0};
+
+ strftime(activation_date, sizeof(activation_date), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "activation_date", activation_date);
+ }
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ /*return the admin state of port trigger rule
+ * running status to be updated in later changes*/
+ *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "enable", "0");
+ *value = (**value == 'n' || **value == '0' ) ? "Disabled" : "Enabled";
+ return 0;
+}
+
+static int get_NATPortTrigger_Origin(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "origin", "Controller");
+ return 0;
+}
+
+static int set_NATPortTrigger_Origin(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ char *Origin[] = {"User", "System", "Controller", NULL};
+
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_string(ctx, value, -1, -1, Origin, NULL))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "origin", value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "description", value);
+ return 0;
+}
+
+static int set_NATPortTrigger_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_string(ctx, value, -1, 256, NULL, NULL))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "description", value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ char *interf = NULL;
+
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "src", &interf);
+
+ adm_entry_get_reference_param(ctx, "Device.IP.Interface.*.Name", interf, value);
+
+ return 0;
+}
+
+static int set_NATPortTrigger_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ char *allowed_objects[] = {"Device.IP.Interface.", NULL};
+ struct dm_reference reference = {0};
+
+ bbf_get_reference_args(value, &reference);
+
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_string(ctx, reference.path, -1, 256, NULL, NULL))
+ return FAULT_9007;
+
+ if (dm_validate_allowed_objects(ctx, &reference, allowed_objects))
+ return FAULT_9007;
+
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "src", reference.value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "port", "0");
+ return 0;
+}
+
+static int set_NATPortTrigger_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "port", value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_PortEndRange(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "port_end_range", "0");
+ return 0;
+}
+
+static int set_NATPortTrigger_PortEndRange(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ char *port;
+ uint16_t s_port, end_port;
+
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "port", &port);
+ s_port = DM_STRTOL(port);
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1))
+ return FAULT_9007;
+ end_port = DM_STRTOL(value);
+ if (s_port > end_port)
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "port_end_range", value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_AutoDisableDuration(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "auto_disable_duration", value);
+ return 0;
+}
+
+static int set_NATPortTrigger_AutoDisableDuration(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,NULL}}, 1))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "auto_disable_duration", value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_ActivationDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "activation_date", "0001-01-01T00:00:00Z");
+ return 0;
+}
+
+static int set_NATPortTrigger_ActivationDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ char activation_date[16] = {0};
+ struct tm tm;
+
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_dateTime(ctx, value))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ strptime(value, "%Y-%m-%dT%H:%M:%SZ", &tm);
+ snprintf(activation_date, sizeof(activation_date), "%lld", (long long)timegm(&tm));
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "activation_date", activation_date);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "protocol", value);
+ return 0;
+}
+
+static int set_NATPortTrigger_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_string(ctx, value, -1, -1, NATProtocol, NULL))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "protocol", value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTrigger_RuleNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ int cnt = get_number_of_entries(ctx, data, instance, browseNATPortTriggerRuleInst);
+ dmasprintf(value, "%d", cnt);
+ return 0;
+}
+
+static int get_NATPortTriggerRule_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ dmuci_get_section_name(section_name(((struct dm_data *)data)->config_section),value);
+ return 0;
+}
+
+static int get_NATPortTriggerRule_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "port", "0");
+ return 0;
+}
+
+static int set_NATPortTriggerRule_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "port", value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTriggerRule_PortEndRange(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "port_end_range", "0");
+ return 0;
+}
+
+static int set_NATPortTriggerRule_PortEndRange(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+
+ char *port;
+ uint16_t s_port, end_port;
+
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "port", &port);
+ s_port = DM_STRTOL(port);
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1))
+ return FAULT_9007;
+ end_port = DM_STRTOL(value);
+ if (s_port > end_port)
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "port_end_range", value);
+ break;
+ }
+ return 0;
+}
+
+static int get_NATPortTriggerRule_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "protocol", value);
+ return 0;
+}
+
+static int set_NATPortTriggerRule_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ switch (action) {
+ case VALUECHECK:
+ if (bbfdm_validate_string(ctx, value, -1, -1, NATProtocol, NULL))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "protocol", value);
+ break;
+ }
+ return 0;
+}
+
+/**********************************************************************************************************************************
+* OBJ & PARAM DEFINITION
+***********************************************************************************************************************************/
+
+DMLEAF tNATPortTriggerParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
+{"Alias", &DMREAD, DMT_STRING, get_NATPortTrigger_Alias, NULL, BBFDM_BOTH},
+{"Enable", &DMWRITE, DMT_BOOL, get_NATPortTrigger_Enable, set_NATPortTrigger_Enable, BBFDM_BOTH},
+{"Status", &DMREAD, DMT_STRING, get_NATPortTrigger_Status, NULL, BBFDM_BOTH},
+{"Origin", &DMWRITE, DMT_STRING, get_NATPortTrigger_Origin, set_NATPortTrigger_Origin, BBFDM_BOTH},
+{"Description", &DMWRITE, DMT_STRING, get_NATPortTrigger_Description, set_NATPortTrigger_Description, BBFDM_BOTH},
+{"Interface", &DMWRITE, DMT_STRING, get_NATPortTrigger_Interface, set_NATPortTrigger_Interface, BBFDM_BOTH, DM_FLAG_REFERENCE},
+{"Port", &DMWRITE, DMT_UNINT, get_NATPortTrigger_Port, set_NATPortTrigger_Port, BBFDM_BOTH},
+{"PortEndRange", &DMWRITE, DMT_UNINT, get_NATPortTrigger_PortEndRange, set_NATPortTrigger_PortEndRange, BBFDM_BOTH},
+{"AutoDisableDuration", &DMWRITE, DMT_UNINT, get_NATPortTrigger_AutoDisableDuration, set_NATPortTrigger_AutoDisableDuration, BBFDM_BOTH},
+{"ActivationDate", &DMWRITE, DMT_TIME, get_NATPortTrigger_ActivationDate, set_NATPortTrigger_ActivationDate, BBFDM_BOTH},
+{"Protocol", &DMWRITE, DMT_STRING, get_NATPortTrigger_Protocol, set_NATPortTrigger_Protocol, BBFDM_BOTH},
+{"RuleNumberOfEntries", &DMREAD, DMT_UNINT, get_NATPortTrigger_RuleNumberOfEntries, NULL, BBFDM_BOTH},
+{0}
+};
+
+/* *** Device.NAT.PortTrigger.{i}.Rule.{i}. *** */
+DMLEAF tNATPortTriggerRuleParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
+{"Alias", &DMREAD, DMT_STRING, get_NATPortTriggerRule_Alias, NULL, BBFDM_BOTH},
+{"Port", &DMWRITE, DMT_UNINT, get_NATPortTriggerRule_Port, set_NATPortTriggerRule_Port, BBFDM_BOTH},
+{"PortEndRange", &DMWRITE, DMT_UNINT, get_NATPortTriggerRule_PortEndRange, set_NATPortTriggerRule_PortEndRange, BBFDM_BOTH},
+{"Protocol", &DMWRITE, DMT_STRING, get_NATPortTriggerRule_Protocol, set_NATPortTriggerRule_Protocol, BBFDM_BOTH},
+{0}
+};
+
+DMLEAF tDeviceNATPortTriggerParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
+{"PortTriggerNumberOfEntries", &DMREAD, DMT_UNINT, get_NAT_PortTriggerNumberOfEntries, NULL, BBFDM_BOTH},
+{0}
+};
+
+/* *** Device.NAT.PortTrigger.{i}. *** */
+DMOBJ tNATPortTriggerObj[] = {
+/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys */
+{"Rule", &DMWRITE, addObjNATPortTriggerRule, delObjNATPortTriggerRule, NULL, browseNATPortTriggerRuleInst, NULL, NULL, NULL, tNATPortTriggerRuleParams, NULL, BBFDM_BOTH, NULL},
+{0}
+};
+
+/* *** Device.NAT. *** */
+DMOBJ tDeviceNATPortTriggerObj[] = {
+/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
+{"PortTrigger", &DMWRITE, addObjNATPortTrigger, delObjNATPortTrigger, NULL, browseNATPortTriggerInst, NULL, NULL, tNATPortTriggerObj, tNATPortTriggerParams, NULL, BBFDM_BOTH},
+{0}
+};
+
+/* *** Device.NAT.PortTrigger. *** */
+DM_MAP_OBJ tDynamicObj[] = {
+/* parentobj, nextobject, parameter */
+{"Device.NAT.", tDeviceNATPortTriggerObj, tDeviceNATPortTriggerParams},
+{0}
+};