From 35f25a251b8b34dae11b39db45a47e79de898145 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Wed, 13 Sep 2023 10:24:35 -0300
Subject: [PATCH 01/10] parser: fix coverity issues found in snapshot 70858

This commit add fixes for issues found in coverity's snapshot 70858.
  - CID 323127:  Performance inefficiencies  (COPY_INSTEAD_OF_MOVE)
  - CID 323125:  Uninitialized members  (UNINIT_CTOR)

I'm also removing Novell, Inc. from the copyright notice added by a
copy-paste error, and an unused variable left over from debugging.

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
---
 parser/bignum.h       | 6 ++----
 parser/parser_regex.c | 4 ++--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/parser/bignum.h b/parser/bignum.h
index 757da4964..e472de844 100644
--- a/parser/bignum.h
+++ b/parser/bignum.h
@@ -12,8 +12,7 @@
  *   GNU General Public License for more details.
  *
  *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, contact Novell, Inc. or Canonical
- *   Ltd.
+ *   along with this program; if not, contact Canonical Ltd.
  */
 
 #ifndef __AA_BIGNUM_H
@@ -29,10 +28,9 @@ class bignum
 {
 public:
 	std::vector<uint8_t> data;
-	uint64_t sad = 543;
 	uint8_t base;
 	bool negative = false;
-	bignum () {}
+	bignum () : base(0) {}
 
 	bignum (unsigned long val) {
 		if (val == 0)
diff --git a/parser/parser_regex.c b/parser/parser_regex.c
index 7d1847692..ef5c2c1f4 100644
--- a/parser/parser_regex.c
+++ b/parser/parser_regex.c
@@ -882,7 +882,7 @@ static std::string generate_regex_range(bignum start, bignum end)
 	std::ostringstream result;
 	std::vector<std::pair<bignum, bignum>> regex_range;
 	int j;
-	regex_range = regex_range_generator(start, end);
+	regex_range = regex_range_generator(std::move(start), std::move(end));
 	for (auto &i: regex_range) {
 		bignum sstart = i.first;
 		bignum send = i.second;
@@ -942,7 +942,7 @@ int convert_range(std::string& buffer, bignum start, bignum end)
 	pattern_t ptype;
 	int pos;
 
-	std::string regex_range = generate_regex_range(start, end);
+	std::string regex_range = generate_regex_range(std::move(start), std::move(end));
 
 	if (!regex_range.empty()) {
 		ptype = convert_aaregex_to_pcre(regex_range.c_str(), 0, glob_default, buffer, &pos);
-- 
GitLab


From 746f76d3e1ec5f71139a28300b6abb1d4b3919a9 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Mon, 8 Jan 2024 16:09:13 -0300
Subject: [PATCH 02/10] parser: add ability to specify permission in network
 rules

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
---
 parser/af_unix.cc    |  2 +-
 parser/all_rule.cc   |  2 +-
 parser/network.cc    | 33 ++++++++++++++++++++++++++++++---
 parser/network.h     |  6 +++---
 parser/parser_lex.l  | 12 ++++++------
 parser/parser_yacc.y | 27 +++++++++++++++++++--------
 6 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/parser/af_unix.cc b/parser/af_unix.cc
index 742cd5241..b1fc38c14 100644
--- a/parser/af_unix.cc
+++ b/parser/af_unix.cc
@@ -202,7 +202,7 @@ void unix_rule::downgrade_rule(Profile &prof) {
 		if (audit == AUDIT_FORCE)
 			prof.net.audit[AF_UNIX] |= mask;
 		const char *error;
-		network_rule *netv8 = new network_rule(AF_UNIX, sock_type_n);
+		network_rule *netv8 = new network_rule(perms, AF_UNIX, sock_type_n);
 		if(!netv8->add_prefix({audit, rule_mode, owner}, error))
 			yyerror(error);
 		prof.rule_ents.push_back(netv8);
diff --git a/parser/all_rule.cc b/parser/all_rule.cc
index 0f20c6359..89129d92f 100644
--- a/parser/all_rule.cc
+++ b/parser/all_rule.cc
@@ -83,7 +83,7 @@ void all_rule::add_implied_rules(Profile &prof)
 	(void) rule->add_prefix(*prefix);
 	prof.rule_ents.push_back(rule);
 
-	rule = new network_rule(NULL);
+	rule = new network_rule(0, NULL);
 	(void) rule->add_prefix(*prefix);
 	prof.rule_ents.push_back(rule);
 	
diff --git a/parser/network.cc b/parser/network.cc
index aa0a44174..f71a0463f 100644
--- a/parser/network.cc
+++ b/parser/network.cc
@@ -322,7 +322,7 @@ void network_rule::set_netperm(unsigned int family, unsigned int type)
 		network_perms[family] |= 1 << type;
 }
 
-network_rule::network_rule(struct cond_entry *conds):
+network_rule::network_rule(perms_t perms_p, struct cond_entry *conds):
 	dedup_perms_rule_t(AA_CLASS_NETV8)
 {
 	size_t family_index;
@@ -333,9 +333,18 @@ network_rule::network_rule(struct cond_entry *conds):
 
 	move_conditionals(conds);
 	free_cond_list(conds);
+
+	if (perms_p) {
+		perms = perms_p;
+		if (perms & ~AA_VALID_NET_PERMS)
+			yyerror("perms contains invalid permissions for network rules\n");
+		/* can conds change permission availability? */
+	} else {
+		perms = AA_VALID_NET_PERMS;
+	}
 }
 
-network_rule::network_rule(const char *family, const char *type,
+network_rule::network_rule(perms_t perms_p, const char *family, const char *type,
 			   const char *protocol, struct cond_entry *conds):
 	dedup_perms_rule_t(AA_CLASS_NETV8)
 {
@@ -357,13 +366,31 @@ network_rule::network_rule(const char *family, const char *type,
 
 	move_conditionals(conds);
 	free_cond_list(conds);
+
+	if (perms_p) {
+		perms = perms_p;
+		if (perms & ~AA_VALID_NET_PERMS)
+			yyerror("perms contains invalid permissions for network rules\n");
+		/* can conds change permission availability? */
+	} else {
+		perms = AA_VALID_NET_PERMS;
+	}
 }
 
-network_rule::network_rule(unsigned int family, unsigned int type):
+network_rule::network_rule(perms_t perms_p, unsigned int family, unsigned int type):
 	dedup_perms_rule_t(AA_CLASS_NETV8)
 {
 	network_map[family].push_back({ family, type, 0xFFFFFFFF });
 	set_netperm(family, type);
+
+	if (perms_p) {
+		perms = perms_p;
+		if (perms & ~AA_VALID_NET_PERMS)
+			yyerror("perms contains invalid permissions for network rules\n");
+		/* can conds change permission availability? */
+	} else {
+		perms = AA_VALID_NET_PERMS;
+	}
 }
 
 ostream &network_rule::dump(ostream &os)
diff --git a/parser/network.h b/parser/network.h
index e0557750a..473444400 100644
--- a/parser/network.h
+++ b/parser/network.h
@@ -114,10 +114,10 @@ public:
 	 * static elements to maintain compatibility with
 	 * AA_CLASS_NET */
 	network_rule(): dedup_perms_rule_t(AA_CLASS_NETV8) { }
-	network_rule(struct cond_entry *conds);
-	network_rule(const char *family, const char *type,
+	network_rule(perms_t perms_p, struct cond_entry *conds);
+	network_rule(perms_t perms_p, const char *family, const char *type,
 		     const char *protocol, struct cond_entry *conds);
-	network_rule(unsigned int family, unsigned int type);
+	network_rule(perms_t perms_p, unsigned int family, unsigned int type);
 	virtual ~network_rule()
 	{
 		if (allow) {
diff --git a/parser/parser_lex.l b/parser/parser_lex.l
index de7141d33..aa09c367c 100644
--- a/parser/parser_lex.l
+++ b/parser/parser_lex.l
@@ -558,7 +558,7 @@ GT		>
 	{LT_EQUAL}	{ RETURN_TOKEN(TOK_LE); }
 }
 
-<UNIX_MODE>{
+<UNIX_MODE,NETWORK_MODE>{
 	listen	{ RETURN_TOKEN(TOK_LISTEN); }
 	accept	{ RETURN_TOKEN(TOK_ACCEPT); }
 	connect	{ RETURN_TOKEN(TOK_CONNECT); }
@@ -567,7 +567,7 @@ GT		>
 	shutdown	{ RETURN_TOKEN(TOK_SHUTDOWN); }
 }
 
-<UNIX_MODE,USERNS_MODE,MQUEUE_MODE>{
+<UNIX_MODE,USERNS_MODE,MQUEUE_MODE,NETWORK_MODE>{
 	create	{ RETURN_TOKEN(TOK_CREATE); }
 }
 
@@ -576,12 +576,12 @@ GT		>
 	delete		{ RETURN_TOKEN(TOK_DELETE); }
 }
 
-<UNIX_MODE,MQUEUE_MODE>{
+<UNIX_MODE,MQUEUE_MODE,NETWORK_MODE>{
 	getattr	{ RETURN_TOKEN(TOK_GETATTR); }
 	setattr	{ RETURN_TOKEN(TOK_SETATTR); }
 }
 
-<DBUS_MODE,UNIX_MODE>{
+<DBUS_MODE,UNIX_MODE,NETWORK_MODE>{
 	bind		{ RETURN_TOKEN(TOK_BIND); }
 }
 
@@ -589,7 +589,7 @@ GT		>
 	eavesdrop	{ RETURN_TOKEN(TOK_EAVESDROP); }
 }
 
-<DBUS_MODE,SIGNAL_MODE,UNIX_MODE>{
+<DBUS_MODE,SIGNAL_MODE,UNIX_MODE,NETWORK_MODE>{
 	send		{ RETURN_TOKEN(TOK_SEND); }
 	receive		{ RETURN_TOKEN(TOK_RECEIVE); }
 }
@@ -600,7 +600,7 @@ GT		>
 	tracedby	{ RETURN_TOKEN(TOK_TRACEDBY); }
 }
 
-<DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_MODE>{
+<DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_MODE,NETWORK_MODE>{
 	read		{ RETURN_TOKEN(TOK_READ); }
 	write		{ RETURN_TOKEN(TOK_WRITE); }
 	{OPEN_PAREN}	{
diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y
index f16195927..417adee6e 100644
--- a/parser/parser_yacc.y
+++ b/parser/parser_yacc.y
@@ -1083,24 +1083,35 @@ link_rule: TOK_LINK opt_subset_flag id_or_var TOK_ARROW id_or_var TOK_END_OF_RUL
 		$$ = entry;
 	};
 
-network_rule: TOK_NETWORK opt_conds TOK_END_OF_RULE
+network_rule: TOK_NETWORK opt_net_perm opt_cond_list TOK_END_OF_RULE
 	{
-		network_rule *entry = new network_rule($2);
+		network_rule *entry;
+
+		entry = new network_rule($2, $3.list);
 		$$ = entry;
 	}
 
-network_rule: TOK_NETWORK TOK_ID opt_conds TOK_END_OF_RULE
+network_rule: TOK_NETWORK opt_net_perm TOK_ID opt_cond_list TOK_END_OF_RULE
 	{
-		network_rule *entry = new network_rule($2, NULL, NULL, $3);
-		free($2);
+		network_rule *entry;
+
+		entry = new network_rule($2, $3, NULL, NULL, $4.list);
+		free($3);
 		$$ = entry;
 	}
 
-network_rule: TOK_NETWORK TOK_ID TOK_ID opt_conds TOK_END_OF_RULE
+network_rule: TOK_NETWORK opt_net_perm TOK_ID TOK_ID opt_cond_list TOK_END_OF_RULE
 	{
-		network_rule *entry = new network_rule($2, $3, NULL, $4);
-		free($2);
+		network_rule *entry;
+
+		if ($5.name) {
+			if (strcmp($5.name, "peer") != 0)
+				yyerror(_("network rule: invalid conditional group %s=()"), $5.name);
+			free($5.name);
+		}
+		entry = new network_rule($2, $3, $4, NULL, $5.list);
 		free($3);
+		free($4);
 		$$ = entry;
 	}
 
-- 
GitLab


From ddefe11a409005ee25ee52d954cc2ac674756349 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Tue, 22 Aug 2023 18:12:29 -0300
Subject: [PATCH 03/10] parser: add fine grained conditionals to network rule

Options available are ip= and port= inside the peer group or outside,
representing local addresses and ports:

network peer=(ip=127.0.0.1 port=8080),
network ip=::1 port=8080 peer=(ip=::2 port=8081),

The 'ip' option supports both IPv4 and IPv6. Examples would be
ip=192.168.0.4, or ip=::578d

The 'port' option accepts a 16-bit unsigned integer. An example would
be port=1234

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
---
 parser/all_rule.cc   |   2 +-
 parser/network.cc    | 214 +++++++++++++++++++++++++++++++++++++++----
 parser/network.h     |  49 +++++++++-
 parser/parser_yacc.y |  30 ++++--
 4 files changed, 264 insertions(+), 31 deletions(-)

diff --git a/parser/all_rule.cc b/parser/all_rule.cc
index 89129d92f..34159349e 100644
--- a/parser/all_rule.cc
+++ b/parser/all_rule.cc
@@ -83,7 +83,7 @@ void all_rule::add_implied_rules(Profile &prof)
 	(void) rule->add_prefix(*prefix);
 	prof.rule_ents.push_back(rule);
 
-	rule = new network_rule(0, NULL);
+	rule = new network_rule(0, (struct cond_entry *)NULL, (struct cond_entry *)NULL);
 	(void) rule->add_prefix(*prefix);
 	prof.rule_ents.push_back(rule);
 	
diff --git a/parser/network.cc b/parser/network.cc
index f71a0463f..88040c938 100644
--- a/parser/network.cc
+++ b/parser/network.cc
@@ -20,6 +20,7 @@
 #include <string>
 #include <sstream>
 #include <map>
+#include <arpa/inet.h>
 
 #include "lib.h"
 #include "parser.h"
@@ -298,7 +299,59 @@ const struct network_tuple *net_find_mapping(const struct network_tuple *map,
 	return NULL;
 }
 
-void network_rule::move_conditionals(struct cond_entry *conds)
+bool parse_ipv4_address(const char *input, struct ip_address *result)
+{
+	struct in_addr addr;
+	if (inet_pton(AF_INET, input, &addr) == 1) {
+		result->family = AF_INET;
+		result->address.address_v4 = addr.s_addr;
+		return true;
+	}
+	return false;
+}
+
+bool parse_ipv6_address(const char *input, struct ip_address *result)
+{
+	struct in6_addr addr;
+	if (inet_pton(AF_INET6, input, &addr) == 1) {
+		result->family = AF_INET6;
+		memcpy(result->address.address_v6, addr.s6_addr, 16);
+		return true;
+	}
+	return false;
+}
+
+bool parse_ip(const char *ip, struct ip_address *result)
+{
+	return parse_ipv6_address(ip, result) ||
+		parse_ipv4_address(ip, result);
+}
+
+bool parse_port_number(const char *port_entry, uint16_t *port) {
+	char *eptr;
+	unsigned long port_tmp = strtoul(port_entry, &eptr, 10);
+
+	if (port_tmp >= 0 && port_entry != eptr &&
+	    *eptr == '\0' && port_tmp <= UINT16_MAX) {
+		*port = port_tmp;
+		return true;
+	}
+	return false;
+}
+
+bool network_rule::parse_port(ip_conds &entry)
+{
+	entry.is_port = true;
+	return parse_port_number(entry.sport, &entry.port);
+}
+
+bool network_rule::parse_address(ip_conds &entry)
+{
+	entry.is_ip = true;
+	return parse_ip(entry.sip, &entry.ip);
+}
+
+void network_rule::move_conditionals(struct cond_entry *conds, ip_conds &ip_cond)
 {
 	struct cond_entry *cond_ent;
 
@@ -306,10 +359,18 @@ void network_rule::move_conditionals(struct cond_entry *conds)
 		/* for now disallow keyword 'in' (list) */
 		if (!cond_ent->eq)
 			yyerror("keyword \"in\" is not allowed in network rules\n");
-
-		/* no valid conditionals atm */
-		yyerror("invalid network rule conditional \"%s\"\n",
-			cond_ent->name);
+		if (strcmp(cond_ent->name, "ip") == 0) {
+			move_conditional_value("network", &ip_cond.sip, cond_ent);
+			if (!parse_address(ip_cond))
+				yyerror("network invalid ip='%s'\n", ip_cond.sip);
+		} else if (strcmp(cond_ent->name, "port") == 0) {
+			move_conditional_value("network", &ip_cond.sport, cond_ent);
+			if (!parse_port(ip_cond))
+				yyerror("network invalid port='%s'\n", ip_cond.sport);
+		} else {
+			yyerror("invalid network rule conditional \"%s\"\n",
+				cond_ent->name);
+		}
 	}
 }
 
@@ -322,7 +383,8 @@ void network_rule::set_netperm(unsigned int family, unsigned int type)
 		network_perms[family] |= 1 << type;
 }
 
-network_rule::network_rule(perms_t perms_p, struct cond_entry *conds):
+network_rule::network_rule(perms_t perms_p, struct cond_entry *conds,
+			   struct cond_entry *peer_conds):
 	dedup_perms_rule_t(AA_CLASS_NETV8)
 {
 	size_t family_index;
@@ -331,21 +393,25 @@ network_rule::network_rule(perms_t perms_p, struct cond_entry *conds):
 		set_netperm(family_index, 0xFFFFFFFF);
 	}
 
-	move_conditionals(conds);
+	move_conditionals(conds, local);
+	move_conditionals(peer_conds, peer);
 	free_cond_list(conds);
+	free_cond_list(peer_conds);
 
 	if (perms_p) {
 		perms = perms_p;
 		if (perms & ~AA_VALID_NET_PERMS)
 			yyerror("perms contains invalid permissions for network rules\n");
-		/* can conds change permission availability? */
+		else if ((perms & ~AA_PEER_NET_PERMS) && has_peer_conds())
+			yyerror("network 'create', 'shutdown', 'setattr', 'getattr', 'bind', 'listen', 'setopt', and/or 'getopt' accesses cannot be used with peer socket conditionals\n");
 	} else {
 		perms = AA_VALID_NET_PERMS;
 	}
 }
 
 network_rule::network_rule(perms_t perms_p, const char *family, const char *type,
-			   const char *protocol, struct cond_entry *conds):
+			   const char *protocol, struct cond_entry *conds,
+			   struct cond_entry *peer_conds):
 	dedup_perms_rule_t(AA_CLASS_NETV8)
 {
 	const struct network_tuple *mapping = NULL;
@@ -364,14 +430,17 @@ network_rule::network_rule(perms_t perms_p, const char *family, const char *type
 	if (network_map.empty())
 		yyerror(_("Invalid network entry."));
 
-	move_conditionals(conds);
+	move_conditionals(conds, local);
+	move_conditionals(peer_conds, peer);
 	free_cond_list(conds);
+	free_cond_list(peer_conds);
 
 	if (perms_p) {
 		perms = perms_p;
 		if (perms & ~AA_VALID_NET_PERMS)
 			yyerror("perms contains invalid permissions for network rules\n");
-		/* can conds change permission availability? */
+		else if ((perms & ~AA_PEER_NET_PERMS) && has_peer_conds())
+			yyerror("network 'create', 'shutdown', 'setattr', 'getattr', 'bind', 'listen', 'setopt', and/or 'getopt' accesses cannot be used with peer socket conditionals\n");
 	} else {
 		perms = AA_VALID_NET_PERMS;
 	}
@@ -387,7 +456,8 @@ network_rule::network_rule(perms_t perms_p, unsigned int family, unsigned int ty
 		perms = perms_p;
 		if (perms & ~AA_VALID_NET_PERMS)
 			yyerror("perms contains invalid permissions for network rules\n");
-		/* can conds change permission availability? */
+		else if ((perms & ~AA_PEER_NET_PERMS) && has_peer_conds())
+			yyerror("network 'create', 'shutdown', 'setattr', 'getattr', 'bind', 'listen', 'setopt', and/or 'getopt' accesses cannot be used with peer socket conditionals\n");
 	} else {
 		perms = AA_VALID_NET_PERMS;
 	}
@@ -455,6 +525,79 @@ void network_rule::warn_once(const char *name)
 	rule_t::warn_once(name, "network rules not enforced");
 }
 
+std::string gen_ip_cond(const struct ip_address ip)
+{
+	std::ostringstream oss;
+	int i;
+	if (ip.family == AF_INET) {
+		/* add a byte containing the size of the following ip */
+		oss << "\\x04";
+
+		u8 *byte = (u8 *) &ip.address.address_v4; /* in network byte order */
+		for (i = 0; i < 4; i++)
+			oss << "\\x" << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned int>(byte[i]);
+	} else {
+		/* add a byte containing the size of the following ip */
+		oss << "\\x10";
+		for (i = 0; i < 16; ++i)
+			oss << "\\x" << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned int>(ip.address.address_v6[i]);
+	}
+	return oss.str();
+}
+
+std::string gen_port_cond(uint16_t port)
+{
+	std::ostringstream oss;
+	if (port > 0) {
+		oss << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ((port & 0xff00) >> 8);
+		oss << "\\x" << std::setfill('0') << std::setw(2) << std::hex << (port & 0xff);
+	} else {
+		oss << "..";
+	}
+	return oss.str();
+}
+
+void network_rule::gen_ip_conds(std::ostringstream &oss, ip_conds entry, bool is_peer, bool is_cmd)
+{
+	/* encode protocol */
+	if (!is_cmd) {
+		if (entry.is_ip) {
+			oss << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ((entry.ip.family & 0xff00) >> 8);
+			oss << "\\x" << std::setfill('0') << std::setw(2) << std::hex << (entry.ip.family & 0xff);
+		} else {
+			oss << "..";
+		}
+	}
+
+	if (entry.is_port) {
+		/* encode port type (privileged - 1, remote - 2, unprivileged - 0) */
+		if (!is_peer && perms & AA_NET_BIND && entry.port < IPPORT_RESERVED)
+			oss << "\\x01";
+		else if (is_peer)
+			oss << "\\x02";
+		else
+			oss << "\\x00";
+
+		oss << gen_port_cond(entry.port);
+	} else {
+		/* port type + port number */
+		if (!is_cmd)
+			oss << ".";
+		oss << "..";
+	}
+
+	if (entry.is_ip) {
+		oss << gen_ip_cond(entry.ip);
+	} else {
+		/* encode 0 to indicate there's no ip (ip size) */
+		oss << "\\x00";
+	}
+
+	oss << "\\-x01"; /* oob separator */
+	oss << default_match_pattern; /* label - not used for now */
+	oss << "\\x00"; /* null transition */
+}
+
 bool network_rule::gen_net_rule(Profile &prof, u16 family, unsigned int type_mask) {
 	std::ostringstream buffer;
 	std::string buf;
@@ -468,13 +611,50 @@ bool network_rule::gen_net_rule(Profile &prof, u16 family, unsigned int type_mas
 		buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ((type_mask & 0xff00) >> 8);
 		buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << (type_mask & 0xff);
 	}
-	buf = buffer.str();
 
-	if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(AA_VALID_NET_PERMS),
-					 dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(AA_VALID_NET_PERMS) : 0,
-					 parseopts))
-		return false;
+	if (perms & AA_PEER_NET_PERMS) {
+		gen_ip_conds(buffer, peer, true, false);
+
+		buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << CMD_ADDR;
 
+		gen_ip_conds(buffer, local, false, true);
+
+		buf = buffer.str();
+		if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms),
+						 dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms) : 0,
+						 parseopts))
+			return false;
+	}
+	if ((perms & AA_NET_LISTEN) || (perms & AA_NET_OPT)) {
+		gen_ip_conds(buffer, local, false, false);
+
+		if (perms & AA_NET_LISTEN) {
+			std::ostringstream cmd_buffer;
+			cmd_buffer << buffer.str();
+			cmd_buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << CMD_LISTEN;
+			/* length of queue allowed - not used for now */
+			cmd_buffer << "..";
+			buf = cmd_buffer.str();
+			if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms),
+							 dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms) : 0,
+							 parseopts))
+				return false;
+		}
+		if (perms & AA_NET_OPT) {
+			std::ostringstream cmd_buffer;
+			cmd_buffer << buffer.str();
+			cmd_buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << CMD_OPT;
+			/* level - not used for now */
+			cmd_buffer << "..";
+			/* socket mapping - not used for now */
+			cmd_buffer << "..";
+			buf = cmd_buffer.str();
+			if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms),
+							 dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms) : 0,
+							 parseopts))
+				return false;
+		}
+	}
 	return true;
 }
 
diff --git a/parser/network.h b/parser/network.h
index 473444400..48f99b12a 100644
--- a/parser/network.h
+++ b/parser/network.h
@@ -75,6 +75,10 @@
 #define AA_PEER_NET_PERMS (AA_VALID_NET_PERMS & (~AA_LOCAL_NET_PERMS | \
 						 AA_NET_ACCEPT))
 
+#define CMD_ADDR	1
+#define CMD_LISTEN	2
+#define CMD_OPT		4
+
 struct network_tuple {
 	const char *family_name;
 	unsigned int family;
@@ -104,22 +108,58 @@ int net_find_type_val(const char *type);
 const char *net_find_type_name(int type);
 const char *net_find_af_name(unsigned int af);
 
+struct ip_address {
+	union {
+		uint8_t address_v6[16];
+		uint32_t address_v4;
+	} address;
+	uint16_t family;
+};
+
+class ip_conds {
+public:
+	char *sip = NULL;
+	char *sport = NULL;
+
+	bool is_ip = false;
+	bool is_port = false;
+
+	uint16_t port;
+	struct ip_address ip;
+
+	void free_conds() {
+		if (sip)
+			free(sip);
+		if (sport)
+			free(sport);
+	}
+};
+
 class network_rule: public dedup_perms_rule_t {
-	void move_conditionals(struct cond_entry *conds);
+	void move_conditionals(struct cond_entry *conds, ip_conds &ip_cond);
 public:
 	std::unordered_map<unsigned int, std::vector<struct aa_network_entry>> network_map;
 	std::unordered_map<unsigned int, perms_t> network_perms;
 
+	ip_conds peer;
+	ip_conds local;
+
+	bool has_local_conds(void) { return local.sip || local.sport; }
+	bool has_peer_conds(void) { return peer.sip || peer.sport; }
 	/* empty constructor used only for the profile to access
 	 * static elements to maintain compatibility with
 	 * AA_CLASS_NET */
 	network_rule(): dedup_perms_rule_t(AA_CLASS_NETV8) { }
-	network_rule(perms_t perms_p, struct cond_entry *conds);
+	network_rule(perms_t perms_p, struct cond_entry *conds,
+		     struct cond_entry *peer_conds);
 	network_rule(perms_t perms_p, const char *family, const char *type,
-		     const char *protocol, struct cond_entry *conds);
+		     const char *protocol, struct cond_entry *conds,
+		     struct cond_entry *peer_conds);
 	network_rule(perms_t perms_p, unsigned int family, unsigned int type);
 	virtual ~network_rule()
 	{
+		peer.free_conds();
+		local.free_conds();
 		if (allow) {
 			free(allow);
 			allow = NULL;
@@ -138,9 +178,12 @@ public:
 		}
 	};
 
+	void gen_ip_conds(std::ostringstream &oss, ip_conds entry, bool is_peer, bool is_cmd);
 	bool gen_net_rule(Profile &prof, u16 family, unsigned int type_mask);
 	void set_netperm(unsigned int family, unsigned int type);
 	void update_compat_net(void);
+	bool parse_address(ip_conds &entry);
+	bool parse_port(ip_conds &entry);
 
 	virtual bool valid_prefix(const prefixes &p, const char *&error) {
 		if (p.owner) {
diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y
index 417adee6e..b225fb5d0 100644
--- a/parser/parser_yacc.y
+++ b/parser/parser_yacc.y
@@ -1083,33 +1083,43 @@ link_rule: TOK_LINK opt_subset_flag id_or_var TOK_ARROW id_or_var TOK_END_OF_RUL
 		$$ = entry;
 	};
 
-network_rule: TOK_NETWORK opt_net_perm opt_cond_list TOK_END_OF_RULE
+network_rule: TOK_NETWORK opt_net_perm opt_conds opt_cond_list TOK_END_OF_RULE
 	{
 		network_rule *entry;
 
-		entry = new network_rule($2, $3.list);
+		if ($4.name) {
+			if (strcmp($4.name, "peer") != 0)
+				yyerror(_("network rule: invalid conditional group %s=()"), $4.name);
+			free($4.name);
+		}
+		entry = new network_rule($2, $3, $4.list);
 		$$ = entry;
 	}
 
-network_rule: TOK_NETWORK opt_net_perm TOK_ID opt_cond_list TOK_END_OF_RULE
+network_rule: TOK_NETWORK opt_net_perm TOK_ID opt_conds opt_cond_list TOK_END_OF_RULE
 	{
 		network_rule *entry;
 
-		entry = new network_rule($2, $3, NULL, NULL, $4.list);
+		if ($5.name) {
+			if (strcmp($5.name, "peer") != 0)
+				yyerror(_("network rule: invalid conditional group %s=()"), $5.name);
+			free($5.name);
+		}
+		entry = new network_rule($2, $3, NULL, NULL, $4, $5.list);
 		free($3);
 		$$ = entry;
 	}
 
-network_rule: TOK_NETWORK opt_net_perm TOK_ID TOK_ID opt_cond_list TOK_END_OF_RULE
+network_rule: TOK_NETWORK opt_net_perm TOK_ID TOK_ID opt_conds opt_cond_list TOK_END_OF_RULE
 	{
 		network_rule *entry;
 
-		if ($5.name) {
-			if (strcmp($5.name, "peer") != 0)
-				yyerror(_("network rule: invalid conditional group %s=()"), $5.name);
-			free($5.name);
+		if ($6.name) {
+			if (strcmp($6.name, "peer") != 0)
+				yyerror(_("network rule: invalid conditional group %s=()"), $6.name);
+			free($6.name);
 		}
-		entry = new network_rule($2, $3, $4, NULL, $5.list);
+		entry = new network_rule($2, $3, $4, NULL, $5, $6.list);
 		free($3);
 		free($4);
 		$$ = entry;
-- 
GitLab


From 7e25be7b0b82c6db51263cb66391c11bfa610a00 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Wed, 30 Aug 2023 14:06:22 -0300
Subject: [PATCH 04/10] parser: change network conditionals to allow unquoted
 ids

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
---
 parser/parser_lex.l | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/parser/parser_lex.l b/parser/parser_lex.l
index aa09c367c..22fd2b5a4 100644
--- a/parser/parser_lex.l
+++ b/parser/parser_lex.l
@@ -517,12 +517,6 @@ GT		>
 	}
 }
 
-<NETWORK_MODE>{
-	{IDS} {
-		yylval.id = strdup(yytext);
-		RETURN_TOKEN(TOK_ID);
-	}
-}
 
 <CHANGE_PROFILE_MODE>{
 	safe		{ RETURN_TOKEN(TOK_SAFE); }
@@ -621,7 +615,7 @@ GT		>
 	sqpoll { RETURN_TOKEN(TOK_SQPOLL); }
 }
 
-<MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_MODE,IOURING_MODE>{
+<MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_MODE,IOURING_MODE,NETWORK_MODE>{
 	({IDS_NOEQ}|{LABEL}|{QUOTED_ID}) {
 		yylval.id = processid(yytext, yyleng);
 		RETURN_TOKEN(TOK_ID);
-- 
GitLab


From 052dd987b3caada3945fcfaf140608cbf458dfc2 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Wed, 30 Aug 2023 14:50:33 -0300
Subject: [PATCH 05/10] parser: add network conditional parser tests

---
 parser/tst/simple_tests/network/network_bad_10.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_11.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_12.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_13.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_14.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_15.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_16.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_17.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_18.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_19.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_20.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_21.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_22.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_23.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_24.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_25.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_26.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_27.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_28.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_29.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_30.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_31.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_32.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_5.sd  |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_6.sd  |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_7.sd  |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_8.sd  |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_9.sd  |  8 ++++++++
 parser/tst/simple_tests/network/network_ok_10.sd  | 10 ++++++++++
 parser/tst/simple_tests/network/network_ok_11.sd  |  9 +++++++++
 parser/tst/simple_tests/network/network_ok_12.sd  |  9 +++++++++
 parser/tst/simple_tests/network/network_ok_13.sd  | 13 +++++++++++++
 parser/tst/simple_tests/network/network_ok_14.sd  | 10 ++++++++++
 parser/tst/simple_tests/network/network_ok_8.sd   |  8 ++++++++
 parser/tst/simple_tests/network/network_ok_9.sd   |  9 +++++++++
 utils/test/test-parser-simple-tests.py            | 14 ++++++++++++++
 36 files changed, 306 insertions(+)
 create mode 100644 parser/tst/simple_tests/network/network_bad_10.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_11.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_12.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_13.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_14.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_15.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_16.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_17.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_18.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_19.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_20.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_21.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_22.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_23.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_24.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_25.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_26.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_27.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_28.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_29.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_30.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_31.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_32.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_5.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_6.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_7.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_8.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_9.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_10.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_11.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_12.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_13.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_14.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_8.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_9.sd

diff --git a/parser/tst/simple_tests/network/network_bad_10.sd b/parser/tst/simple_tests/network/network_bad_10.sd
new file mode 100644
index 000000000..25de94b70
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_10.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=127.0.0.1 port=test),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_11.sd b/parser/tst/simple_tests/network/network_bad_11.sd
new file mode 100644
index 000000000..8fad9c9ab
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_11.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=127.0.0.1 port=65536),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_12.sd b/parser/tst/simple_tests/network/network_bad_12.sd
new file mode 100644
index 000000000..514d11545
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_12.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=[invalid] port=80),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_13.sd b/parser/tst/simple_tests/network/network_bad_13.sd
new file mode 100644
index 000000000..afa9ff7f6
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_13.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=::1 port=-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_14.sd b/parser/tst/simple_tests/network/network_bad_14.sd
new file mode 100644
index 000000000..686f6f752
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_14.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=::1 port=test),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_15.sd b/parser/tst/simple_tests/network/network_bad_15.sd
new file mode 100644
index 000000000..8cfcadac2
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_15.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=::1 port=65536),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_16.sd b/parser/tst/simple_tests/network/network_bad_16.sd
new file mode 100644
index 000000000..7406d710b
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_16.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(port=65536),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_17.sd b/parser/tst/simple_tests/network/network_bad_17.sd
new file mode 100644
index 000000000..c3bd5eb62
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_17.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(port=-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_18.sd b/parser/tst/simple_tests/network/network_bad_18.sd
new file mode 100644
index 000000000..50d2eba6b
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_18.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(port=test),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_19.sd b/parser/tst/simple_tests/network/network_bad_19.sd
new file mode 100644
index 000000000..d1ca755b9
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_19.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=192.168.0.39-192.168.0.4),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_20.sd b/parser/tst/simple_tests/network/network_bad_20.sd
new file mode 100644
index 000000000..cce022de2
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_20.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=192.168.0.39-invalid),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_21.sd b/parser/tst/simple_tests/network/network_bad_21.sd
new file mode 100644
index 000000000..626823d84
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_21.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=192.168.0.39-::58c2),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_22.sd b/parser/tst/simple_tests/network/network_bad_22.sd
new file mode 100644
index 000000000..a33dd6e58
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_22.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=2001:1884:d02e:2759:d30:f166:71c9:288f-192.168.0.39),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_23.sd b/parser/tst/simple_tests/network/network_bad_23.sd
new file mode 100644
index 000000000..0888bd90d
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_23.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=80-192.168.0.39),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_24.sd b/parser/tst/simple_tests/network/network_bad_24.sd
new file mode 100644
index 000000000..a934aefc5
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_24.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(port=80-65536),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_25.sd b/parser/tst/simple_tests/network/network_bad_25.sd
new file mode 100644
index 000000000..0be92c741
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_25.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(port=443-80),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_26.sd b/parser/tst/simple_tests/network/network_bad_26.sd
new file mode 100644
index 000000000..514762e59
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_26.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=invalid/80),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_27.sd b/parser/tst/simple_tests/network/network_bad_27.sd
new file mode 100644
index 000000000..7d268d098
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_27.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=192.168.0.1/-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_28.sd b/parser/tst/simple_tests/network/network_bad_28.sd
new file mode 100644
index 000000000..df1b72c09
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_28.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=192.168.0.1/invalid),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_29.sd b/parser/tst/simple_tests/network/network_bad_29.sd
new file mode 100644
index 000000000..bd73493ae
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_29.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=192.168.0.1/33),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_30.sd b/parser/tst/simple_tests/network/network_bad_30.sd
new file mode 100644
index 000000000..eadd6dcf8
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_30.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=2001:1884:d02e:2759:d30:f166:71c9:288f/-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_31.sd b/parser/tst/simple_tests/network/network_bad_31.sd
new file mode 100644
index 000000000..4ed5df7ee
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_31.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=2001:1884:d02e:2759:d30:f166:71c9:288f/invalid),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_32.sd b/parser/tst/simple_tests/network/network_bad_32.sd
new file mode 100644
index 000000000..b7034ea5f
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_32.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=2001:1884:d02e:2759:d30:f166:71c9:288f/129),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_5.sd b/parser/tst/simple_tests/network/network_bad_5.sd
new file mode 100644
index 000000000..b448c8a8c
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_5.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=10,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_6.sd b/parser/tst/simple_tests/network/network_bad_6.sd
new file mode 100644
index 000000000..6fc73d600
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_6.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=10.2,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_7.sd b/parser/tst/simple_tests/network/network_bad_7.sd
new file mode 100644
index 000000000..ff4a13826
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_7.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=test,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_8.sd b/parser/tst/simple_tests/network/network_bad_8.sd
new file mode 100644
index 000000000..f772cb25c
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_8.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_9.sd b/parser/tst/simple_tests/network/network_bad_9.sd
new file mode 100644
index 000000000..61f302a6f
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_9.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network peer=(ip=127.0.0.1 port=-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_10.sd b/parser/tst/simple_tests/network/network_ok_10.sd
new file mode 100644
index 000000000..709e58f23
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_10.sd
@@ -0,0 +1,10 @@
+#
+#=DESCRIPTION network ipv4 - port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network peer=(ip=127.0.0.1 port=8080),
+  network peer=(ip=127.0.0.1 port=0),
+  network peer=(ip=127.0.0.1 port=65535),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_11.sd b/parser/tst/simple_tests/network/network_ok_11.sd
new file mode 100644
index 000000000..b66d61a78
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_11.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv6 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network peer=(ip=2001:1254:f12e:2059:5f78:28f5:5cf5:9b73),
+  network peer=(ip=fe80::fc54:ff:fece:e21f),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_12.sd b/parser/tst/simple_tests/network/network_ok_12.sd
new file mode 100644
index 000000000..b7e2c4656
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_12.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv6 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network inet peer=(ip=fe80::fc54:ff:fece:e21f),
+  network inet tcp peer=(ip=fe80::fc54:ff:fece:e21f),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_13.sd b/parser/tst/simple_tests/network/network_ok_13.sd
new file mode 100644
index 000000000..e6a3e357a
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_13.sd
@@ -0,0 +1,13 @@
+#
+#=DESCRIPTION network ipv6 - port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network peer=(ip=::1 port=8080),
+  network peer=(ip=0000:0000:0000:0000:0000:0000:0000:0001 port=8080),
+  network peer=(ip=::1 port=0),
+  network peer=(ip=0000:0000:0000:0000:0000:0000:0000:0001 port=0),
+  network peer=(ip=::1 port=65535),
+  network peer=(ip=0000:0000:0000:0000:0000:0000:0000:0001 port=65535),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_14.sd b/parser/tst/simple_tests/network/network_ok_14.sd
new file mode 100644
index 000000000..8fcb3aa18
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_14.sd
@@ -0,0 +1,10 @@
+#
+#=DESCRIPTION network port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network peer=(port=0),
+  network peer=(port=65535),
+  network peer=(port=443),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_8.sd b/parser/tst/simple_tests/network/network_ok_8.sd
new file mode 100644
index 000000000..0a069536c
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_8.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION network ipv4 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network peer=(ip=10.0.2.1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_9.sd b/parser/tst/simple_tests/network/network_ok_9.sd
new file mode 100644
index 000000000..c13906737
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_9.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv4 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network inet peer=(ip=10.0.2.1),
+  network inet tcp peer=(ip=192.168.2.254),
+
+}
diff --git a/utils/test/test-parser-simple-tests.py b/utils/test/test-parser-simple-tests.py
index 234f9f482..0a65b8bed 100644
--- a/utils/test/test-parser-simple-tests.py
+++ b/utils/test/test-parser-simple-tests.py
@@ -447,6 +447,20 @@ syntax_failure = (
     'vars/vars_dbus_8.sd',  # Path doesn't start with / or variable: {/@{TLDS}/foo,/com/@{DOMAINS}}
     'vars/vars_simple_assignment_12.sd',  # Redefining existing variable @{BAR} ('\' not handled)
     'bare_include_tests/ok_2.sd',  # two #include<...> in one line
+
+    # fine grained net
+    'network/network_ok_8.sd',
+    'network/network_ok_9.sd',
+    'network/network_ok_10.sd',
+    'network/network_ok_11.sd',
+    'network/network_ok_12.sd',
+    'network/network_ok_13.sd',
+    'network/network_ok_14.sd',
+    'network/network_ok_15.sd',
+    'network/network_ok_16.sd',
+    'network/network_ok_17.sd',
+    'network/network_ok_18.sd',
+    'network/network_ok_19.sd',
 )
 
 
-- 
GitLab


From 79ee3eb180ab9d1ee90cad6a70baf448a164ff36 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Wed, 28 Feb 2024 21:24:39 -0300
Subject: [PATCH 06/10] parser: add parser tests for local conditional

---
 parser/tst/simple_tests/network/network_bad_33.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_34.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_35.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_36.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_37.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_38.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_39.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_40.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_41.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_42.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_43.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_44.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_45.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_46.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_47.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_48.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_49.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_50.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_51.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_52.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_53.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_54.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_55.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_56.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_57.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_58.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_59.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_60.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_61.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_62.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_63.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_64.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_65.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_66.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_67.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_68.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_69.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_70.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_71.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_72.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_73.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_74.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_75.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_76.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_77.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_78.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_79.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_80.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_81.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_bad_82.sd |  8 ++++++++
 parser/tst/simple_tests/network/network_ok_20.sd  | 10 ++++++++++
 parser/tst/simple_tests/network/network_ok_21.sd  | 10 ++++++++++
 parser/tst/simple_tests/network/network_ok_22.sd  |  9 +++++++++
 parser/tst/simple_tests/network/network_ok_23.sd  |  9 +++++++++
 parser/tst/simple_tests/network/network_ok_24.sd  |  9 +++++++++
 parser/tst/simple_tests/network/network_ok_25.sd  |  9 +++++++++
 parser/tst/simple_tests/network/network_ok_26.sd  | 13 +++++++++++++
 parser/tst/simple_tests/network/network_ok_27.sd  | 13 +++++++++++++
 parser/tst/simple_tests/network/network_ok_28.sd  | 10 ++++++++++
 parser/tst/simple_tests/network/network_ok_29.sd  | 10 ++++++++++
 parser/tst/simple_tests/network/network_ok_40.sd  |  8 ++++++++
 parser/tst/simple_tests/network/network_ok_41.sd  |  8 ++++++++
 parser/tst/simple_tests/network/network_ok_42.sd  |  9 +++++++++
 parser/tst/simple_tests/network/network_ok_43.sd  |  9 +++++++++
 64 files changed, 536 insertions(+)
 create mode 100644 parser/tst/simple_tests/network/network_bad_33.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_34.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_35.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_36.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_37.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_38.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_39.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_40.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_41.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_42.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_43.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_44.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_45.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_46.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_47.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_48.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_49.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_50.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_51.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_52.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_53.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_54.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_55.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_56.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_57.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_58.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_59.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_60.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_61.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_62.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_63.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_64.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_65.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_66.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_67.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_68.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_69.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_70.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_71.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_72.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_73.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_74.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_75.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_76.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_77.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_78.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_79.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_80.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_81.sd
 create mode 100644 parser/tst/simple_tests/network/network_bad_82.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_20.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_21.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_22.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_23.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_24.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_25.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_26.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_27.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_28.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_29.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_40.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_41.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_42.sd
 create mode 100644 parser/tst/simple_tests/network/network_ok_43.sd

diff --git a/parser/tst/simple_tests/network/network_bad_33.sd b/parser/tst/simple_tests/network/network_bad_33.sd
new file mode 100644
index 000000000..4864ca489
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_33.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=127.0.0.1 port=test,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_34.sd b/parser/tst/simple_tests/network/network_bad_34.sd
new file mode 100644
index 000000000..d9fe5196d
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_34.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=127.0.0.1 port=test peer=(ip=127.0.0.1 port=test),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_35.sd b/parser/tst/simple_tests/network/network_bad_35.sd
new file mode 100644
index 000000000..a668e997f
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_35.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=127.0.0.1 port=65536,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_36.sd b/parser/tst/simple_tests/network/network_bad_36.sd
new file mode 100644
index 000000000..762ee74ce
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_36.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=127.0.0.1 port=65536 peer=(ip=127.0.0.1 port=65536),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_37.sd b/parser/tst/simple_tests/network/network_bad_37.sd
new file mode 100644
index 000000000..0cb92ce60
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_37.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=[invalid] port=80,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_38.sd b/parser/tst/simple_tests/network/network_bad_38.sd
new file mode 100644
index 000000000..4f9d34a22
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_38.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=[invalid] port=80 peer=(ip=[invalid] port=80),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_39.sd b/parser/tst/simple_tests/network/network_bad_39.sd
new file mode 100644
index 000000000..d07d81690
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_39.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=::1 port=-1,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_40.sd b/parser/tst/simple_tests/network/network_bad_40.sd
new file mode 100644
index 000000000..f08dce0f1
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_40.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=::1 port=-1 peer=(ip=::1 port=-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_41.sd b/parser/tst/simple_tests/network/network_bad_41.sd
new file mode 100644
index 000000000..ad798c0be
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_41.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=::1 port=test,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_42.sd b/parser/tst/simple_tests/network/network_bad_42.sd
new file mode 100644
index 000000000..5d74142b9
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_42.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=::1 port=test peer=(ip=::1 port=test),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_43.sd b/parser/tst/simple_tests/network/network_bad_43.sd
new file mode 100644
index 000000000..25fd7f8a5
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_43.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=::1 port=65536,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_44.sd b/parser/tst/simple_tests/network/network_bad_44.sd
new file mode 100644
index 000000000..c0b00a507
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_44.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=::1 port=65536 peer=(ip=::1 port=65536),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_45.sd b/parser/tst/simple_tests/network/network_bad_45.sd
new file mode 100644
index 000000000..275c60a13
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_45.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=65536,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_46.sd b/parser/tst/simple_tests/network/network_bad_46.sd
new file mode 100644
index 000000000..a6ca1ac04
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_46.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=65536 peer=(port=65536),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_47.sd b/parser/tst/simple_tests/network/network_bad_47.sd
new file mode 100644
index 000000000..0c8298ce3
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_47.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=-1,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_48.sd b/parser/tst/simple_tests/network/network_bad_48.sd
new file mode 100644
index 000000000..2c2ee4b7e
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_48.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=-1 peer=(port=-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_49.sd b/parser/tst/simple_tests/network/network_bad_49.sd
new file mode 100644
index 000000000..c58740885
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_49.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=test,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_50.sd b/parser/tst/simple_tests/network/network_bad_50.sd
new file mode 100644
index 000000000..f4feb025d
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_50.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network port range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=test peer=(port=test),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_51.sd b/parser/tst/simple_tests/network/network_bad_51.sd
new file mode 100644
index 000000000..f8296feb0
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_51.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.39-192.168.0.4,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_52.sd b/parser/tst/simple_tests/network/network_bad_52.sd
new file mode 100644
index 000000000..5bb7369b1
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_52.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.39-192.168.0.4 peer=(ip=192.168.0.39-192.168.0.4),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_53.sd b/parser/tst/simple_tests/network/network_bad_53.sd
new file mode 100644
index 000000000..e34148767
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_53.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.39-invalid,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_54.sd b/parser/tst/simple_tests/network/network_bad_54.sd
new file mode 100644
index 000000000..41183ea6a
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_54.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.39-invalid peer=(ip=192.168.0.39-invalid),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_55.sd b/parser/tst/simple_tests/network/network_bad_55.sd
new file mode 100644
index 000000000..41875927d
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_55.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.39-::58c2,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_56.sd b/parser/tst/simple_tests/network/network_bad_56.sd
new file mode 100644
index 000000000..fb2b916c8
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_56.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.39-::58c2 peer=(ip=192.168.0.39-::58c2),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_57.sd b/parser/tst/simple_tests/network/network_bad_57.sd
new file mode 100644
index 000000000..4ac611bf3
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_57.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=2001:1884:d02e:2759:d30:f166:71c9:288f-192.168.0.39,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_58.sd b/parser/tst/simple_tests/network/network_bad_58.sd
new file mode 100644
index 000000000..1dbe1abd9
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_58.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=2001:1884:d02e:2759:d30:f166:71c9:288f-192.168.0.39 peer=(ip=2001:1884:d02e:2759:d30:f166:71c9:288f-192.168.0.39),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_59.sd b/parser/tst/simple_tests/network/network_bad_59.sd
new file mode 100644
index 000000000..69e5ad002
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_59.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=80-192.168.0.39,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_60.sd b/parser/tst/simple_tests/network/network_bad_60.sd
new file mode 100644
index 000000000..e3d23abd2
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_60.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=80-192.168.0.39 peer=(ip=80-192.168.0.39),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_61.sd b/parser/tst/simple_tests/network/network_bad_61.sd
new file mode 100644
index 000000000..43a413a71
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_61.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=80-65536,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_62.sd b/parser/tst/simple_tests/network/network_bad_62.sd
new file mode 100644
index 000000000..db2d9d68c
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_62.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=80-65536 peer=(port=80-65536),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_63.sd b/parser/tst/simple_tests/network/network_bad_63.sd
new file mode 100644
index 000000000..39c849e1b
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_63.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=443-80,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_64.sd b/parser/tst/simple_tests/network/network_bad_64.sd
new file mode 100644
index 000000000..247ef9ea2
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_64.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network range test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network port=443-80 peer=(port=443-80),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_65.sd b/parser/tst/simple_tests/network/network_bad_65.sd
new file mode 100644
index 000000000..b73a6afe5
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_65.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=invalid/80,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_66.sd b/parser/tst/simple_tests/network/network_bad_66.sd
new file mode 100644
index 000000000..f5ad51a20
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_66.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=invalid/80 peer=(ip=invalid/80),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_67.sd b/parser/tst/simple_tests/network/network_bad_67.sd
new file mode 100644
index 000000000..1f69dff1c
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_67.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.1/-1,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_68.sd b/parser/tst/simple_tests/network/network_bad_68.sd
new file mode 100644
index 000000000..788891cb2
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_68.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.1/-1 peer=(ip=192.168.0.1/-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_69.sd b/parser/tst/simple_tests/network/network_bad_69.sd
new file mode 100644
index 000000000..1b71b8533
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_69.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.1/invalid,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_70.sd b/parser/tst/simple_tests/network/network_bad_70.sd
new file mode 100644
index 000000000..8190fa21a
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_70.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.1/invalid peer=(ip=192.168.0.1/invalid),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_71.sd b/parser/tst/simple_tests/network/network_bad_71.sd
new file mode 100644
index 000000000..d8db428c7
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_71.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.1/33,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_72.sd b/parser/tst/simple_tests/network/network_bad_72.sd
new file mode 100644
index 000000000..687527e7a
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_72.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=192.168.0.1/33 peer=(ip=192.168.0.1/33),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_73.sd b/parser/tst/simple_tests/network/network_bad_73.sd
new file mode 100644
index 000000000..9750874b9
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_73.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=2001:1884:d02e:2759:d30:f166:71c9:288f/-1,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_74.sd b/parser/tst/simple_tests/network/network_bad_74.sd
new file mode 100644
index 000000000..ef31eb55a
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_74.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=2001:1884:d02e:2759:d30:f166:71c9:288f/-1 peer=(ip=2001:1884:d02e:2759:d30:f166:71c9:288f/-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_75.sd b/parser/tst/simple_tests/network/network_bad_75.sd
new file mode 100644
index 000000000..1a796b57e
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_75.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=2001:1884:d02e:2759:d30:f166:71c9:288f/invalid,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_76.sd b/parser/tst/simple_tests/network/network_bad_76.sd
new file mode 100644
index 000000000..d14e8a1e4
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_76.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=2001:1884:d02e:2759:d30:f166:71c9:288f/invalid peer=(ip=2001:1884:d02e:2759:d30:f166:71c9:288f/invalid),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_77.sd b/parser/tst/simple_tests/network/network_bad_77.sd
new file mode 100644
index 000000000..e708ee53d
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_77.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=2001:1884:d02e:2759:d30:f166:71c9:288f/129,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_78.sd b/parser/tst/simple_tests/network/network_bad_78.sd
new file mode 100644
index 000000000..d9a76c863
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_78.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network subnet test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=2001:1884:d02e:2759:d30:f166:71c9:288f/129 peer=(ip=2001:1884:d02e:2759:d30:f166:71c9:288f/129),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_79.sd b/parser/tst/simple_tests/network/network_bad_79.sd
new file mode 100644
index 000000000..36949d26b
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_79.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=-1,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_80.sd b/parser/tst/simple_tests/network/network_bad_80.sd
new file mode 100644
index 000000000..5b35fad8f
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_80.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=-1 peer=(ip=-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_81.sd b/parser/tst/simple_tests/network/network_bad_81.sd
new file mode 100644
index 000000000..0ec4b0b6c
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_81.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=127.0.0.1 port=-1,
+
+}
diff --git a/parser/tst/simple_tests/network/network_bad_82.sd b/parser/tst/simple_tests/network/network_bad_82.sd
new file mode 100644
index 000000000..41dbc9dde
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_bad_82.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION invalid network ip - port conditional test
+#=EXRESULT FAIL
+#
+/usr/bin/foo {
+  network ip=127.0.0.1 port=-1 peer=(ip=127.0.0.1 port=-1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_20.sd b/parser/tst/simple_tests/network/network_ok_20.sd
new file mode 100644
index 000000000..fe2620055
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_20.sd
@@ -0,0 +1,10 @@
+#
+#=DESCRIPTION network ipv4 - port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network ip=127.0.0.1 port=8080,
+  network ip=127.0.0.1 port=0,
+  network ip=127.0.0.1 port=65535,
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_21.sd b/parser/tst/simple_tests/network/network_ok_21.sd
new file mode 100644
index 000000000..3e81653e1
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_21.sd
@@ -0,0 +1,10 @@
+#
+#=DESCRIPTION network ipv4 - port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network ip=127.0.0.1 port=8080 peer=(ip=127.0.0.1 port=8080),
+  network ip=127.0.0.1 port=0 peer=(ip=127.0.0.1 port=0),
+  network ip=127.0.0.1 port=65535 peer=(ip=127.0.0.1 port=65535),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_22.sd b/parser/tst/simple_tests/network/network_ok_22.sd
new file mode 100644
index 000000000..c5ff3c59a
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_22.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv6 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network ip=2001:1254:f12e:2059:5f78:28f5:5cf5:9b73,
+  network ip=fe80::fc54:ff:fece:e21f,
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_23.sd b/parser/tst/simple_tests/network/network_ok_23.sd
new file mode 100644
index 000000000..bde609430
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_23.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv6 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network ip=2001:1254:f12e:2059:5f78:28f5:5cf5:9b73 peer=(ip=2001:1254:f12e:2059:5f78:28f5:5cf5:9b73),
+  network ip=fe80::fc54:ff:fece:e21f peer=(ip=fe80::fc54:ff:fece:e21f),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_24.sd b/parser/tst/simple_tests/network/network_ok_24.sd
new file mode 100644
index 000000000..1c5791700
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_24.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv6 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network inet ip=fe80::fc54:ff:fece:e21f,
+  network inet tcp ip=fe80::fc54:ff:fece:e21f,
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_25.sd b/parser/tst/simple_tests/network/network_ok_25.sd
new file mode 100644
index 000000000..d313dd7b3
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_25.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv6 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network inet ip=fe80::fc54:ff:fece:e21f peer=(ip=fe80::fc54:ff:fece:e21f),
+  network inet tcp ip=fe80::fc54:ff:fece:e21f peer=(ip=fe80::fc54:ff:fece:e21f),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_26.sd b/parser/tst/simple_tests/network/network_ok_26.sd
new file mode 100644
index 000000000..6698f590c
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_26.sd
@@ -0,0 +1,13 @@
+#
+#=DESCRIPTION network ipv6 - port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network ip=::1 port=8080,
+  network ip=0000:0000:0000:0000:0000:0000:0000:0001 port=8080,
+  network ip=::1 port=0,
+  network ip=0000:0000:0000:0000:0000:0000:0000:0001 port=0,
+  network ip=::1 port=65535,
+  network ip=0000:0000:0000:0000:0000:0000:0000:0001 port=65535,
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_27.sd b/parser/tst/simple_tests/network/network_ok_27.sd
new file mode 100644
index 000000000..7ccef0847
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_27.sd
@@ -0,0 +1,13 @@
+#
+#=DESCRIPTION network ipv6 - port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network ip=::1 port=8080 peer=(ip=::1 port=8080),
+  network ip=0000:0000:0000:0000:0000:0000:0000:0001 port=8080 peer=(ip=0000:0000:0000:0000:0000:0000:0000:0001 port=8080),
+  network ip=::1 port=0 peer=(ip=::1 port=0),
+  network ip=0000:0000:0000:0000:0000:0000:0000:0001 port=0 peer=(ip=0000:0000:0000:0000:0000:0000:0000:0001 port=0),
+  network ip=::1 port=65535 peer=(ip=::1 port=65535),
+  network ip=0000:0000:0000:0000:0000:0000:0000:0001 port=65535 peer=(ip=0000:0000:0000:0000:0000:0000:0000:0001 port=65535),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_28.sd b/parser/tst/simple_tests/network/network_ok_28.sd
new file mode 100644
index 000000000..dd3fc3dde
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_28.sd
@@ -0,0 +1,10 @@
+#
+#=DESCRIPTION network port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network port=0,
+  network port=65535,
+  network port=443,
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_29.sd b/parser/tst/simple_tests/network/network_ok_29.sd
new file mode 100644
index 000000000..07a965caf
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_29.sd
@@ -0,0 +1,10 @@
+#
+#=DESCRIPTION network port conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network port=0 peer=(port=0),
+  network port=65535 peer=(port=65535),
+  network port=443 peer=(port=443),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_40.sd b/parser/tst/simple_tests/network/network_ok_40.sd
new file mode 100644
index 000000000..7f904384e
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_40.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION network ipv4 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network ip=10.0.2.1,
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_41.sd b/parser/tst/simple_tests/network/network_ok_41.sd
new file mode 100644
index 000000000..adb3dbc03
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_41.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION network ipv4 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network ip=10.0.2.1 peer=(ip=10.0.2.1),
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_42.sd b/parser/tst/simple_tests/network/network_ok_42.sd
new file mode 100644
index 000000000..c877e1710
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_42.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv4 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network inet ip=10.0.2.1,
+  network inet tcp ip=192.168.2.254,
+
+}
diff --git a/parser/tst/simple_tests/network/network_ok_43.sd b/parser/tst/simple_tests/network/network_ok_43.sd
new file mode 100644
index 000000000..78dba8c10
--- /dev/null
+++ b/parser/tst/simple_tests/network/network_ok_43.sd
@@ -0,0 +1,9 @@
+#
+#=DESCRIPTION network ipv4 conditional test
+#=EXRESULT PASS
+#
+/usr/bin/foo {
+  network inet ip=10.0.2.1 peer=(ip=10.0.2.1),
+  network inet tcp ip=192.168.2.254 peer=(ip=192.168.2.254),
+
+}
-- 
GitLab


From 8a5e7227dbe4ef1ef4b4f89087b570325794e702 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Thu, 9 Nov 2023 15:12:49 +0200
Subject: [PATCH 07/10] parser: add parser tests for specified perms

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
---
 .../simple_tests/network/perms/bad_attr_1.sd  |  7 ++
 .../simple_tests/network/perms/bad_attr_2.sd  |  7 ++
 .../simple_tests/network/perms/bad_attr_3.sd  |  7 ++
 .../simple_tests/network/perms/bad_attr_4.sd  |  7 ++
 .../simple_tests/network/perms/bad_attr_5.sd  |  7 ++
 .../simple_tests/network/perms/bad_bind_1.sd  |  8 ++
 .../simple_tests/network/perms/bad_bind_2.sd  |  8 ++
 .../network/perms/bad_create_1.sd             |  7 ++
 .../network/perms/bad_create_2.sd             |  7 ++
 .../network/perms/bad_listen_1.sd             |  7 ++
 .../network/perms/bad_listen_2.sd             |  7 ++
 .../network/perms/bad_modifier_1.sd           |  7 ++
 .../network/perms/bad_modifier_2.sd           |  7 ++
 .../network/perms/bad_modifier_3.sd           |  7 ++
 .../simple_tests/network/perms/bad_opt_1.sd   |  7 ++
 .../simple_tests/network/perms/bad_opt_2.sd   |  7 ++
 .../simple_tests/network/perms/bad_opt_3.sd   |  7 ++
 .../simple_tests/network/perms/bad_opt_4.sd   |  7 ++
 .../simple_tests/network/perms/bad_opt_5.sd   |  7 ++
 .../network/perms/bad_outside_1.sd            |  5 ++
 .../simple_tests/network/perms/bad_peer_1.sd  |  8 ++
 .../simple_tests/network/perms/bad_peer_2.sd  |  8 ++
 .../network/perms/bad_shutdown_1.sd           |  7 ++
 .../network/perms/bad_shutdown_2.sd           |  7 ++
 .../network/perms/bad_shutdown_3.sd           |  7 ++
 .../simple_tests/network/perms/ok_accept_1.sd |  7 ++
 .../simple_tests/network/perms/ok_accept_2.sd |  7 ++
 .../simple_tests/network/perms/ok_attr_1.sd   |  7 ++
 .../simple_tests/network/perms/ok_attr_2.sd   |  7 ++
 .../simple_tests/network/perms/ok_attr_3.sd   |  7 ++
 .../simple_tests/network/perms/ok_attr_4.sd   |  7 ++
 .../simple_tests/network/perms/ok_attr_5.sd   |  7 ++
 .../simple_tests/network/perms/ok_attr_6.sd   |  7 ++
 .../simple_tests/network/perms/ok_attr_7.sd   |  7 ++
 .../simple_tests/network/perms/ok_attr_8.sd   |  7 ++
 .../simple_tests/network/perms/ok_bind_1.sd   |  7 ++
 .../simple_tests/network/perms/ok_bind_2.sd   |  7 ++
 .../network/perms/ok_connect_1.sd             |  7 ++
 .../network/perms/ok_connect_2.sd             |  7 ++
 .../simple_tests/network/perms/ok_create_1.sd |  7 ++
 .../simple_tests/network/perms/ok_create_2.sd |  7 ++
 .../simple_tests/network/perms/ok_create_3.sd |  7 ++
 .../simple_tests/network/perms/ok_create_4.sd |  7 ++
 .../simple_tests/network/perms/ok_listen_1.sd |  7 ++
 .../simple_tests/network/perms/ok_listen_2.sd |  7 ++
 .../simple_tests/network/perms/ok_listen_3.sd |  7 ++
 .../simple_tests/network/perms/ok_msg_1.sd    |  7 ++
 .../simple_tests/network/perms/ok_msg_10.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_11.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_12.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_13.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_14.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_15.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_16.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_17.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_18.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_19.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_2.sd    |  7 ++
 .../simple_tests/network/perms/ok_msg_20.sd   |  7 ++
 .../simple_tests/network/perms/ok_msg_3.sd    |  7 ++
 .../simple_tests/network/perms/ok_msg_4.sd    |  7 ++
 .../simple_tests/network/perms/ok_msg_5.sd    |  7 ++
 .../simple_tests/network/perms/ok_msg_6.sd    |  7 ++
 .../simple_tests/network/perms/ok_msg_7.sd    |  7 ++
 .../simple_tests/network/perms/ok_msg_8.sd    |  7 ++
 .../simple_tests/network/perms/ok_msg_9.sd    |  7 ++
 .../simple_tests/network/perms/ok_opt_1.sd    |  7 ++
 .../simple_tests/network/perms/ok_opt_2.sd    |  7 ++
 .../simple_tests/network/perms/ok_opt_3.sd    |  7 ++
 .../simple_tests/network/perms/ok_opt_4.sd    |  7 ++
 .../simple_tests/network/perms/ok_opt_5.sd    |  7 ++
 .../simple_tests/network/perms/ok_opt_6.sd    |  7 ++
 .../simple_tests/network/perms/ok_opt_7.sd    |  7 ++
 .../network/perms/ok_shutdown_1.sd            |  7 ++
 .../network/perms/ok_shutdown_2.sd            |  7 ++
 .../network/perms/ok_shutdown_3.sd            |  7 ++
 utils/test/test-parser-simple-tests.py        | 74 +++++++++++++++++++
 77 files changed, 608 insertions(+)
 create mode 100644 parser/tst/simple_tests/network/perms/bad_attr_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_attr_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_attr_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_attr_4.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_attr_5.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_bind_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_bind_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_create_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_create_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_listen_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_listen_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_modifier_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_modifier_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_modifier_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_opt_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_opt_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_opt_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_opt_4.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_opt_5.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_outside_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_peer_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_peer_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_shutdown_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_shutdown_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/bad_shutdown_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_accept_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_accept_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_attr_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_attr_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_attr_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_attr_4.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_attr_5.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_attr_6.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_attr_7.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_attr_8.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_bind_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_bind_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_connect_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_connect_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_create_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_create_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_create_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_create_4.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_listen_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_listen_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_listen_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_10.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_11.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_12.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_13.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_14.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_15.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_16.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_17.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_18.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_19.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_20.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_4.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_5.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_6.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_7.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_8.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_msg_9.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_opt_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_opt_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_opt_3.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_opt_4.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_opt_5.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_opt_6.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_opt_7.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_shutdown_1.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_shutdown_2.sd
 create mode 100644 parser/tst/simple_tests/network/perms/ok_shutdown_3.sd

diff --git a/parser/tst/simple_tests/network/perms/bad_attr_1.sd b/parser/tst/simple_tests/network/perms/bad_attr_1.sd
new file mode 100644
index 000000000..de891c643
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_attr_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getattr w/peer modifier
+#=EXRESULT FAIL
+
+profile a_profile {
+  network getattr peer=(ip=127.0.0.1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_attr_2.sd b/parser/tst/simple_tests/network/perms/bad_attr_2.sd
new file mode 100644
index 000000000..b7e1f4020
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_attr_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getattr acceptance test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network (getattr) peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_attr_3.sd b/parser/tst/simple_tests/network/perms/bad_attr_3.sd
new file mode 100644
index 000000000..5e2a08d21
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_attr_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setattr w/peer test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network setattr peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_attr_4.sd b/parser/tst/simple_tests/network/perms/bad_attr_4.sd
new file mode 100644
index 000000000..401c0f861
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_attr_4.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setattr w/peer ip test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network (setattr) peer=(ip=127.0.0.1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_attr_5.sd b/parser/tst/simple_tests/network/perms/bad_attr_5.sd
new file mode 100644
index 000000000..be3fc2a27
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_attr_5.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getattr w/peer modifier
+#=EXRESULT FAIL
+
+profile a_profile {
+  network getattr peer=(ip=::1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_bind_1.sd b/parser/tst/simple_tests/network/perms/bad_bind_1.sd
new file mode 100644
index 000000000..bfc3b78ff
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_bind_1.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION network bind with non-bind member modifier
+#=EXRESULT FAIL
+#
+
+profile foo {
+  network bind peer=(ip=127.0.0.1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_bind_2.sd b/parser/tst/simple_tests/network/perms/bad_bind_2.sd
new file mode 100644
index 000000000..07319f347
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_bind_2.sd
@@ -0,0 +1,8 @@
+#
+#=DESCRIPTION network bind with non-bind interface modifier
+#=EXRESULT FAIL
+#
+
+profile foo {
+  network bind peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_create_1.sd b/parser/tst/simple_tests/network/perms/bad_create_1.sd
new file mode 100644
index 000000000..c0b20053d
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_create_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network create w/peer acceptance test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network create peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_create_2.sd b/parser/tst/simple_tests/network/perms/bad_create_2.sd
new file mode 100644
index 000000000..9e31dd8bf
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_create_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network create acceptance test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network (create) peer=(ip=::1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_listen_1.sd b/parser/tst/simple_tests/network/perms/bad_listen_1.sd
new file mode 100644
index 000000000..6c9dad658
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_listen_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network listen w/peer test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network listen peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_listen_2.sd b/parser/tst/simple_tests/network/perms/bad_listen_2.sd
new file mode 100644
index 000000000..18b190683
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_listen_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network listen w/peer test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network (listen) peer=(ip=127.0.0.1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_modifier_1.sd b/parser/tst/simple_tests/network/perms/bad_modifier_1.sd
new file mode 100644
index 000000000..d6740344f
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_modifier_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION network entry with a bad modifier
+#=EXRESULT FAIL
+
+profile foo {
+  network send type=dgram modifier=foo,
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_modifier_2.sd b/parser/tst/simple_tests/network/perms/bad_modifier_2.sd
new file mode 100644
index 000000000..f2418454a
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_modifier_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION network entry with a repeated modifier
+#=EXRESULT FAIL
+
+profile foo {
+  network send ip=127.0.0.1 ip=::1,
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_modifier_3.sd b/parser/tst/simple_tests/network/perms/bad_modifier_3.sd
new file mode 100644
index 000000000..f6dd13b39
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_modifier_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION network entry with a bad 'in' keyword
+#=EXRESULT FAIL
+
+profile foo {
+  network send ip in (127.0.0.1, ::1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_opt_1.sd b/parser/tst/simple_tests/network/perms/bad_opt_1.sd
new file mode 100644
index 000000000..c04d26ebc
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_opt_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getopt w/peer ip test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network getopt peer=(ip=127.0.0.1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_opt_2.sd b/parser/tst/simple_tests/network/perms/bad_opt_2.sd
new file mode 100644
index 000000000..7f146ec8e
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_opt_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getopt w/peer label test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network (getopt) peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_opt_3.sd b/parser/tst/simple_tests/network/perms/bad_opt_3.sd
new file mode 100644
index 000000000..b73bbf8d6
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_opt_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setopt w/peer ip test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network setopt peer=(ip=::1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_opt_4.sd b/parser/tst/simple_tests/network/perms/bad_opt_4.sd
new file mode 100644
index 000000000..4eb629b4c
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_opt_4.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setopt w/peer label test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network (setopt) peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_opt_5.sd b/parser/tst/simple_tests/network/perms/bad_opt_5.sd
new file mode 100644
index 000000000..e8c4f1fd1
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_opt_5.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getopt w/peer ip test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network getopt peer=(ip=::1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_outside_1.sd b/parser/tst/simple_tests/network/perms/bad_outside_1.sd
new file mode 100644
index 000000000..25b247a58
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_outside_1.sd
@@ -0,0 +1,5 @@
+#
+#=DESCRIPTION network accept rule outside of a profile
+#=EXRESULT FAIL
+
+  network accept,
diff --git a/parser/tst/simple_tests/network/perms/bad_peer_1.sd b/parser/tst/simple_tests/network/perms/bad_peer_1.sd
new file mode 100644
index 000000000..98fde2dbb
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_peer_1.sd
@@ -0,0 +1,8 @@
+#
+#=Description network rule with bad 'peer'
+#=EXRESULT FAIL
+#
+
+profile foo {
+  network send peer(ip=wat),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_peer_2.sd b/parser/tst/simple_tests/network/perms/bad_peer_2.sd
new file mode 100644
index 000000000..4db6a8f67
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_peer_2.sd
@@ -0,0 +1,8 @@
+#
+#=Description network rule with bad 'peer'
+#=EXRESULT FAIL
+#
+
+profile foo {
+  network send peer(port=auto),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_shutdown_1.sd b/parser/tst/simple_tests/network/perms/bad_shutdown_1.sd
new file mode 100644
index 000000000..eeffe5a6a
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_shutdown_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network shutdown w/peer test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network shutdown peer=(ip=127.0.0.1),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_shutdown_2.sd b/parser/tst/simple_tests/network/perms/bad_shutdown_2.sd
new file mode 100644
index 000000000..4d3168bd3
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_shutdown_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network shutdown acceptance test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network (shutdown) peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/bad_shutdown_3.sd b/parser/tst/simple_tests/network/perms/bad_shutdown_3.sd
new file mode 100644
index 000000000..16886dfe0
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/bad_shutdown_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network shutdown w/peer test
+#=EXRESULT FAIL
+
+profile a_profile {
+  network shutdown peer=(ip=::1),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_accept_1.sd b/parser/tst/simple_tests/network/perms/ok_accept_1.sd
new file mode 100644
index 000000000..0978100a1
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_accept_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network accept acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network accept,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_accept_2.sd b/parser/tst/simple_tests/network/perms/ok_accept_2.sd
new file mode 100644
index 000000000..0a67e8c5d
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_accept_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network accept acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (accept),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_attr_1.sd b/parser/tst/simple_tests/network/perms/ok_attr_1.sd
new file mode 100644
index 000000000..388ee9eb6
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_attr_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getattr acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network getattr,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_attr_2.sd b/parser/tst/simple_tests/network/perms/ok_attr_2.sd
new file mode 100644
index 000000000..42b154ac2
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_attr_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getattr acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (getattr),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_attr_3.sd b/parser/tst/simple_tests/network/perms/ok_attr_3.sd
new file mode 100644
index 000000000..67c8a0029
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_attr_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setattr acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network setattr,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_attr_4.sd b/parser/tst/simple_tests/network/perms/ok_attr_4.sd
new file mode 100644
index 000000000..0146d8841
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_attr_4.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setattr acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (setattr),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_attr_5.sd b/parser/tst/simple_tests/network/perms/ok_attr_5.sd
new file mode 100644
index 000000000..c2740a3af
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_attr_5.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getattr w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network getattr ip=127.0.0.1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_attr_6.sd b/parser/tst/simple_tests/network/perms/ok_attr_6.sd
new file mode 100644
index 000000000..31d7d47e5
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_attr_6.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setattr w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network setattr ip=127.0.0.1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_attr_7.sd b/parser/tst/simple_tests/network/perms/ok_attr_7.sd
new file mode 100644
index 000000000..1c4aa8ce0
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_attr_7.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getattr w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network getattr ip=::1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_attr_8.sd b/parser/tst/simple_tests/network/perms/ok_attr_8.sd
new file mode 100644
index 000000000..9c30dea2b
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_attr_8.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setattr w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network setattr ip=::1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_bind_1.sd b/parser/tst/simple_tests/network/perms/ok_bind_1.sd
new file mode 100644
index 000000000..02f862136
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_bind_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network bind acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network bind,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_bind_2.sd b/parser/tst/simple_tests/network/perms/ok_bind_2.sd
new file mode 100644
index 000000000..c0a33f53f
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_bind_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network bind acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (bind),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_connect_1.sd b/parser/tst/simple_tests/network/perms/ok_connect_1.sd
new file mode 100644
index 000000000..ca30f0895
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_connect_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network connect acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network connect,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_connect_2.sd b/parser/tst/simple_tests/network/perms/ok_connect_2.sd
new file mode 100644
index 000000000..3045910af
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_connect_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network connect acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (connect),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_create_1.sd b/parser/tst/simple_tests/network/perms/ok_create_1.sd
new file mode 100644
index 000000000..b60d48163
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_create_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network create acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network create,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_create_2.sd b/parser/tst/simple_tests/network/perms/ok_create_2.sd
new file mode 100644
index 000000000..07868cc14
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_create_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network create acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (create),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_create_3.sd b/parser/tst/simple_tests/network/perms/ok_create_3.sd
new file mode 100644
index 000000000..da0ad75b3
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_create_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network create w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network create ip=127.0.0.1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_create_4.sd b/parser/tst/simple_tests/network/perms/ok_create_4.sd
new file mode 100644
index 000000000..7acbedde1
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_create_4.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network create w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network create ip=::1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_listen_1.sd b/parser/tst/simple_tests/network/perms/ok_listen_1.sd
new file mode 100644
index 000000000..5737faa65
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_listen_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network listen acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network listen,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_listen_2.sd b/parser/tst/simple_tests/network/perms/ok_listen_2.sd
new file mode 100644
index 000000000..efad4b665
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_listen_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network listen acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (listen),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_listen_3.sd b/parser/tst/simple_tests/network/perms/ok_listen_3.sd
new file mode 100644
index 000000000..00e0b090e
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_listen_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network listen w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network listen ip=127.0.0.1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_1.sd b/parser/tst/simple_tests/network/perms/ok_msg_1.sd
new file mode 100644
index 000000000..ab6a94296
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network send test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_10.sd b/parser/tst/simple_tests/network/perms/ok_msg_10.sd
new file mode 100644
index 000000000..3790b8dc6
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_10.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send) peer=(port=1234),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_11.sd b/parser/tst/simple_tests/network/perms/ok_msg_11.sd
new file mode 100644
index 000000000..40bb801a4
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_11.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network rule
+#=EXRESULT PASS
+
+profile a_profile {
+  network,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_12.sd b/parser/tst/simple_tests/network/perms/ok_msg_12.sd
new file mode 100644
index 000000000..0973abe1c
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_12.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network send test
+#=EXRESULT PASS
+
+profile a_profile {
+  network send,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_13.sd b/parser/tst/simple_tests/network/perms/ok_msg_13.sd
new file mode 100644
index 000000000..f154d6755
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_13.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network receive,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_14.sd b/parser/tst/simple_tests/network/perms/ok_msg_14.sd
new file mode 100644
index 000000000..cea023607
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_14.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network r,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_15.sd b/parser/tst/simple_tests/network/perms/ok_msg_15.sd
new file mode 100644
index 000000000..64e695323
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_15.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (r),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_16.sd b/parser/tst/simple_tests/network/perms/ok_msg_16.sd
new file mode 100644
index 000000000..ae5923a3a
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_16.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network w,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_17.sd b/parser/tst/simple_tests/network/perms/ok_msg_17.sd
new file mode 100644
index 000000000..63d906fbb
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_17.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (w),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_18.sd b/parser/tst/simple_tests/network/perms/ok_msg_18.sd
new file mode 100644
index 000000000..706614bac
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_18.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network rw,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_19.sd b/parser/tst/simple_tests/network/perms/ok_msg_19.sd
new file mode 100644
index 000000000..366f9049d
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_19.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (rw),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_2.sd b/parser/tst/simple_tests/network/perms/ok_msg_2.sd
new file mode 100644
index 000000000..13eb4bf59
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (receive),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_20.sd b/parser/tst/simple_tests/network/perms/ok_msg_20.sd
new file mode 100644
index 000000000..be4464a2b
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_20.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send) ip=127.0.0.1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_3.sd b/parser/tst/simple_tests/network/perms/ok_msg_3.sd
new file mode 100644
index 000000000..2d4950fd0
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (connect),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_4.sd b/parser/tst/simple_tests/network/perms/ok_msg_4.sd
new file mode 100644
index 000000000..da6857d90
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_4.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_5.sd b/parser/tst/simple_tests/network/perms/ok_msg_5.sd
new file mode 100644
index 000000000..f847821f4
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_5.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send, receive),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_6.sd b/parser/tst/simple_tests/network/perms/ok_msg_6.sd
new file mode 100644
index 000000000..54c96e267
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_6.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send, receive, connect),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_7.sd b/parser/tst/simple_tests/network/perms/ok_msg_7.sd
new file mode 100644
index 000000000..be4464a2b
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_7.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send) ip=127.0.0.1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_8.sd b/parser/tst/simple_tests/network/perms/ok_msg_8.sd
new file mode 100644
index 000000000..154e71180
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_8.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send) ip=::1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_msg_9.sd b/parser/tst/simple_tests/network/perms/ok_msg_9.sd
new file mode 100644
index 000000000..86b306a79
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_msg_9.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network msg test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (send) peer=(ip=::1),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_opt_1.sd b/parser/tst/simple_tests/network/perms/ok_opt_1.sd
new file mode 100644
index 000000000..680ece346
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_opt_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getopt acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network getopt,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_opt_2.sd b/parser/tst/simple_tests/network/perms/ok_opt_2.sd
new file mode 100644
index 000000000..3bff127b6
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_opt_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getopt acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (getopt),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_opt_3.sd b/parser/tst/simple_tests/network/perms/ok_opt_3.sd
new file mode 100644
index 000000000..dee88dcf7
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_opt_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setopt acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network setopt,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_opt_4.sd b/parser/tst/simple_tests/network/perms/ok_opt_4.sd
new file mode 100644
index 000000000..36add574e
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_opt_4.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setopt acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (setopt),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_opt_5.sd b/parser/tst/simple_tests/network/perms/ok_opt_5.sd
new file mode 100644
index 000000000..0f5821d5c
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_opt_5.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network getopt w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network getopt ip=127.0.0.1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_opt_6.sd b/parser/tst/simple_tests/network/perms/ok_opt_6.sd
new file mode 100644
index 000000000..f56dea6a9
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_opt_6.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setopt w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network setopt ip=127.0.0.1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_opt_7.sd b/parser/tst/simple_tests/network/perms/ok_opt_7.sd
new file mode 100644
index 000000000..abbd43d88
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_opt_7.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network setopt w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network setopt ip=::1,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_shutdown_1.sd b/parser/tst/simple_tests/network/perms/ok_shutdown_1.sd
new file mode 100644
index 000000000..826c1d683
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_shutdown_1.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network shutdown acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network shutdown,
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_shutdown_2.sd b/parser/tst/simple_tests/network/perms/ok_shutdown_2.sd
new file mode 100644
index 000000000..4901d3720
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_shutdown_2.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network shutdown acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network (shutdown),
+}
diff --git a/parser/tst/simple_tests/network/perms/ok_shutdown_3.sd b/parser/tst/simple_tests/network/perms/ok_shutdown_3.sd
new file mode 100644
index 000000000..987ff516d
--- /dev/null
+++ b/parser/tst/simple_tests/network/perms/ok_shutdown_3.sd
@@ -0,0 +1,7 @@
+#
+#=DESCRIPTION simple network shutdown w/ip acceptance test
+#=EXRESULT PASS
+
+profile a_profile {
+  network shutdown ip=127.0.0.1,
+}
diff --git a/utils/test/test-parser-simple-tests.py b/utils/test/test-parser-simple-tests.py
index 0a65b8bed..3eccf6075 100644
--- a/utils/test/test-parser-simple-tests.py
+++ b/utils/test/test-parser-simple-tests.py
@@ -461,6 +461,80 @@ syntax_failure = (
     'network/network_ok_17.sd',
     'network/network_ok_18.sd',
     'network/network_ok_19.sd',
+    'network/network_ok_20.sd',
+    'network/network_ok_21.sd',
+    'network/network_ok_22.sd',
+    'network/network_ok_23.sd',
+    'network/network_ok_24.sd',
+    'network/network_ok_25.sd',
+    'network/network_ok_26.sd',
+    'network/network_ok_27.sd',
+    'network/network_ok_28.sd',
+    'network/network_ok_29.sd',
+    'network/network_ok_30.sd',
+    'network/network_ok_31.sd',
+    'network/network_ok_32.sd',
+    'network/network_ok_33.sd',
+    'network/network_ok_34.sd',
+    'network/network_ok_35.sd',
+    'network/network_ok_36.sd',
+    'network/network_ok_37.sd',
+    'network/network_ok_38.sd',
+    'network/network_ok_39.sd',
+    'network/network_ok_40.sd',
+    'network/network_ok_41.sd',
+    'network/network_ok_42.sd',
+    'network/network_ok_43.sd',
+    'network/perms/ok_accept_1.sd',
+    'network/perms/ok_accept_2.sd',
+    'network/perms/ok_attr_1.sd',
+    'network/perms/ok_attr_2.sd',
+    'network/perms/ok_attr_3.sd',
+    'network/perms/ok_attr_4.sd',
+    'network/perms/ok_attr_5.sd',
+    'network/perms/ok_attr_6.sd',
+    'network/perms/ok_attr_7.sd',
+    'network/perms/ok_attr_8.sd',
+    'network/perms/ok_bind_1.sd',
+    'network/perms/ok_bind_2.sd',
+    'network/perms/ok_connect_1.sd',
+    'network/perms/ok_connect_2.sd',
+    'network/perms/ok_create_1.sd',
+    'network/perms/ok_create_2.sd',
+    'network/perms/ok_create_3.sd',
+    'network/perms/ok_create_4.sd',
+    'network/perms/ok_listen_1.sd',
+    'network/perms/ok_listen_2.sd',
+    'network/perms/ok_listen_3.sd',
+    'network/perms/ok_msg_1.sd',
+    'network/perms/ok_msg_2.sd',
+    'network/perms/ok_msg_3.sd',
+    'network/perms/ok_msg_4.sd',
+    'network/perms/ok_msg_5.sd',
+    'network/perms/ok_msg_6.sd',
+    'network/perms/ok_msg_7.sd',
+    'network/perms/ok_msg_8.sd',
+    'network/perms/ok_msg_9.sd',
+    'network/perms/ok_msg_10.sd',
+    'network/perms/ok_msg_12.sd',
+    'network/perms/ok_msg_13.sd',
+    'network/perms/ok_msg_14.sd',
+    'network/perms/ok_msg_15.sd',
+    'network/perms/ok_msg_16.sd',
+    'network/perms/ok_msg_17.sd',
+    'network/perms/ok_msg_18.sd',
+    'network/perms/ok_msg_19.sd',
+    'network/perms/ok_msg_20.sd',
+    'network/perms/ok_opt_1.sd',
+    'network/perms/ok_opt_2.sd',
+    'network/perms/ok_opt_3.sd',
+    'network/perms/ok_opt_4.sd',
+    'network/perms/ok_opt_5.sd',
+    'network/perms/ok_opt_6.sd',
+    'network/perms/ok_opt_7.sd',
+    'network/perms/ok_shutdown_1.sd',
+    'network/perms/ok_shutdown_2.sd',
+    'network/perms/ok_shutdown_3.sd',
 )
 
 
-- 
GitLab


From f6ad1cbe1e9947d59331cedba89a52212d6cc285 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Thu, 11 May 2023 12:07:21 -0300
Subject: [PATCH 08/10] tests: add multi string support in
 requires_parser_support

By not having quotes in $@, the string splits by the whitespace.
That prevents us from checking if the parser supports rules
that have spaces in them.

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
---
 tests/regression/apparmor/prologue.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/regression/apparmor/prologue.inc b/tests/regression/apparmor/prologue.inc
index 3bbea9b8e..d5b34b9e7 100755
--- a/tests/regression/apparmor/prologue.inc
+++ b/tests/regression/apparmor/prologue.inc
@@ -152,7 +152,7 @@ parser_supports()
 # $@: rules to test
 requires_parser_support()
 {
-	local res=$(parser_supports $@)
+	local res=$(parser_supports "$@")
 	if [ "$res" != "true" ] ; then
 		echo "$res. Skipping tests ..."
 		exit 0
-- 
GitLab


From dd0d145a19528c4dfe06aaa41594ac6f03245a62 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Mon, 8 Jan 2024 16:11:06 -0300
Subject: [PATCH 09/10] tests: add fine grained network regression tests

---
 .gitignore                                    |   2 +
 tests/regression/apparmor/Makefile            |   2 +
 tests/regression/apparmor/mkprofile.pl        |  12 +-
 tests/regression/apparmor/net_finegrained.h   |  60 +++
 tests/regression/apparmor/net_finegrained.sh  | 131 ++++++
 .../regression/apparmor/net_finegrained_rcv.c | 378 ++++++++++++++++++
 .../regression/apparmor/net_finegrained_snd.c | 263 ++++++++++++
 7 files changed, 845 insertions(+), 3 deletions(-)
 create mode 100644 tests/regression/apparmor/net_finegrained.h
 create mode 100644 tests/regression/apparmor/net_finegrained.sh
 create mode 100644 tests/regression/apparmor/net_finegrained_rcv.c
 create mode 100644 tests/regression/apparmor/net_finegrained_snd.c

diff --git a/.gitignore b/.gitignore
index 2bed5f57b..2c779f2ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -266,6 +266,8 @@ tests/regression/apparmor/mmap
 tests/regression/apparmor/mount
 tests/regression/apparmor/move_mount
 tests/regression/apparmor/named_pipe
+tests/regression/apparmor/net_finegrained_rcv
+tests/regression/apparmor/net_finegrained_snd
 tests/regression/apparmor/net_raw
 tests/regression/apparmor/open
 tests/regression/apparmor/openat
diff --git a/tests/regression/apparmor/Makefile b/tests/regression/apparmor/Makefile
index 7244a45a5..fde2958f8 100644
--- a/tests/regression/apparmor/Makefile
+++ b/tests/regression/apparmor/Makefile
@@ -111,6 +111,8 @@ SRC=access.c \
     mount.c \
     move_mount.c \
     named_pipe.c \
+    net_finegrained_rcv.c \
+    net_finegrained_snd.c \
     net_raw.c \
     open.c \
     openat.c \
diff --git a/tests/regression/apparmor/mkprofile.pl b/tests/regression/apparmor/mkprofile.pl
index f3ccba04b..271b46ede 100755
--- a/tests/regression/apparmor/mkprofile.pl
+++ b/tests/regression/apparmor/mkprofile.pl
@@ -164,8 +164,14 @@ sub gen_netdomain($@) {
 
 sub gen_network($@) {
   my ($rule, $qualifier) = @_;
-  my @rules = split (/:/, $rule);
-  push (@{$output_rules{$hat}}, "  ${qualifier}@rules,\n");
+  if ($rule =~ /^network:/) {
+    my @rules = split (/:/, $rule);
+    push (@{$output_rules{$hat}}, "  ${qualifier}@rules,\n");
+  } else {
+    # if using fine grained mediation, separator needs to be ; because of ipv6
+    my @rules = split (/;/, $rule);
+    push (@{$output_rules{$hat}}, "  ${qualifier}@rules,\n");
+  }
 }
 
 sub gen_unix($@) {
@@ -495,7 +501,7 @@ sub gen_from_args() {
     if ($rule =~ /^(tcp|udp)/) {
       # netdomain rules
       gen_netdomain($rule, $qualifier);
-    } elsif ($rule =~ /^network:/) {
+    } elsif ($rule =~ /^network(:|;)/) {
       gen_network($rule, $qualifier);
     } elsif ($rule =~ /^unix:/) {
       gen_unix($rule, $qualifier);
diff --git a/tests/regression/apparmor/net_finegrained.h b/tests/regression/apparmor/net_finegrained.h
new file mode 100644
index 000000000..414cfd59d
--- /dev/null
+++ b/tests/regression/apparmor/net_finegrained.h
@@ -0,0 +1,60 @@
+
+#include <arpa/inet.h>
+
+struct ip_address {
+	union {
+		uint8_t address_v6[16];
+		uint32_t address_v4;
+	} address;
+	uint16_t family;
+	uint16_t port;
+	uint8_t subnet_mask;
+};
+
+int parse_ipv4_address(const char *ip, const char *port, struct ip_address *result)
+{
+	struct in_addr addr;
+	if (inet_pton(AF_INET, ip, &addr) == 1) {
+		result->family = AF_INET;
+		result->address.address_v4 = addr.s_addr;
+		result->port = htons(atoi(port));
+		return 1;
+	}
+	return 0;
+}
+
+int parse_ipv6_address(const char *ip, const char *port, struct ip_address *result)
+{
+	struct in6_addr addr;
+	if (inet_pton(AF_INET6, ip, &addr) == 1) {
+		result->family = AF_INET6;
+		memcpy(result->address.address_v6, addr.s6_addr, 16);
+		result->port = htons(atoi(port));
+		return 1;
+	}
+	return 0;
+}
+
+int parse_ip(const char *ip, const char *port, struct ip_address *result)
+{
+	return parse_ipv6_address(ip, port, result) ||
+		parse_ipv4_address(ip, port, result);
+}
+
+struct sockaddr_in convert_to_sockaddr_in(struct ip_address result)
+{
+	struct sockaddr_in sockaddr;
+	sockaddr.sin_family = result.family;
+	sockaddr.sin_port = result.port;
+	sockaddr.sin_addr.s_addr = result.address.address_v4;
+	return sockaddr;
+}
+
+struct sockaddr_in6 convert_to_sockaddr_in6(struct ip_address result)
+{
+	struct sockaddr_in6 sockaddr;
+	sockaddr.sin6_family = result.family;
+	sockaddr.sin6_port = result.port;
+	memcpy(sockaddr.sin6_addr.s6_addr, result.address.address_v6, 16);
+	return sockaddr;
+}
diff --git a/tests/regression/apparmor/net_finegrained.sh b/tests/regression/apparmor/net_finegrained.sh
new file mode 100644
index 000000000..0ccf9528a
--- /dev/null
+++ b/tests/regression/apparmor/net_finegrained.sh
@@ -0,0 +1,131 @@
+#! /bin/bash
+#Copyright (C) 2022 Canonical, Ltd.
+#
+#This program is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public License as
+#published by the Free Software Foundation, version 2 of the
+#License.
+
+#=NAME posix_mq
+#=DESCRIPTION
+# This test verifies if mediation of posix message queues is working
+#=END
+
+pwd=`dirname $0`
+pwd=`cd $pwd ; /bin/pwd`
+
+bin=$pwd
+
+. $bin/prologue.inc
+
+#requires_kernel_features network_v8/finegrained
+requires_parser_support "network ip=::1,"
+
+settest net_finegrained_rcv
+
+sender="$bin/net_finegrained_snd"
+receiver="$bin/net_finegrained_rcv"
+
+# local ipv6 address generated according to https://www.rfc-editor.org/rfc/rfc4193.html
+#ipv6_subnet=fd74:1820:b03a:b361::/64
+bind_ipv6=fd74:1820:b03a:b361::cf32
+remote_ipv6=fd74:1820:b03a:b361::a0f9
+
+bind_ipv4=127.0.97.3
+remote_ipv4=127.187.243.54
+
+ip -6 addr add $bind_ipv6 dev lo || true
+ip -6 addr add $remote_ipv6 dev lo || true
+
+cleanup()
+{
+	ip -6 addr del $bind_ipv6 dev lo || true
+	ip -6 addr del $remote_ipv6 dev lo || true
+}
+
+do_onexit="cleanup"
+
+do_test()
+{
+	local desc="FINEGRAINED NETWORK ($1)"
+	shift
+	runchecktest "$desc" "$@"
+}
+
+
+do_tests()
+{
+	prefix="$1"
+	expect_rcv=$2
+	expect_snd=$3
+	bind_ip=$4
+	bind_port=$5
+	remote_ip=$6
+	remote_port=$7
+	protocol=$8
+	generate_profile=$9
+
+	settest net_finegrained_rcv
+	$generate_profile
+	do_test "$prefix - root" $expect_rcv --bind_ip $bind_ip --bind_port $bind_port --remote_ip $remote_ip --remote_port $remote_port --protocol $protocol --timeout 5 --sender $sender
+
+
+	settest -u "foo" net_finegrained_rcv
+	$generate_profile
+	do_test "$prefix - user" $expect_rcv --bind_ip $bind_ip --bind_port $bind_port --remote_ip $remote_ip --remote_port $remote_port --protocol $protocol --timeout 5 --sender $sender
+
+
+}
+
+bind_port=3456
+while lsof -i:$bind_port >/dev/null; do
+	let bind_port=$bind_port+1
+done
+
+let remote_port=$bind_port+1
+while lsof -i:$remote_port >/dev/null; do
+	let remote_port=$remote_port+1
+done
+
+generate_profile=""
+do_tests "ipv4 udp unconfined" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port udp "$generate_profile"
+do_tests "ipv4 tcp unconfined" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port tcp "$generate_profile"
+
+generate_profile="genprofile network $sender:px -- image=$sender network"
+do_tests "ipv4 udp no conds" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port udp "$generate_profile"
+
+generate_profile="genprofile network $sender:px -- image=$sender network"
+do_tests "ipv4 tcp no conds" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port tcp "$generate_profile"
+
+generate_profile="genprofile network;ip=$bind_ipv4;port=$bind_port;peer=(ip=$remote_ipv4,port=$remote_port) $sender:px -- image=$sender network;ip=$remote_ipv4;port=$remote_port;peer=(ip=$bind_ipv4,port=$bind_port)"
+do_tests "ipv4 udp generic perms" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port udp "$generate_profile"
+
+generate_profile="genprofile network;ip=$bind_ipv4;port=$bind_port;peer=(ip=$remote_ipv4,port=$remote_port) $sender:px -- image=$sender network;ip=$remote_ipv4;port=$remote_port;peer=(ip=$bind_ipv4,port=$bind_port)"
+do_tests "ipv4 tcp generic perms" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port tcp "$generate_profile"
+
+generate_profile="genprofile network;(connect,receive,send);ip=$bind_ipv4;port=$bind_port;peer=(ip=$remote_ipv4,port=$remote_port) $sender:px -- image=$sender network;ip=$remote_ipv4;port=$remote_port;peer=(ip=$bind_ipv4,port=$bind_port)"
+do_tests "ipv4 udp specific perms" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port udp "$generate_profile"
+
+generate_profile="genprofile network;(connect,receive,send);ip=$bind_ipv4;port=$bind_port;peer=(ip=$remote_ipv4,port=$remote_port) $sender:px -- image=$sender network;ip=$remote_ipv4;port=$remote_port;peer=(ip=$bind_ipv4,port=$bind_port)"
+do_tests "ipv4 tcp specific perms" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port tcp "$generate_profile"
+
+removeprofile
+# ipv6 tests
+
+generate_profile=""
+do_tests "ipv6 udp unconfined" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remote_port udp "$generate_profile"
+do_tests "ipv6 tcp unconfined" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remote_port tcp "$generate_profile"
+
+generate_profile="genprofile network $sender:px -- image=$sender network"
+do_tests "ipv6 udp no conds" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remote_port udp "$generate_profile"
+
+generate_profile="genprofile network $sender:px -- image=$sender network"
+do_tests "ipv6 tcp no conds" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remote_port tcp "$generate_profile"
+
+generate_profile="genprofile network;ip=$bind_ipv6;port=$bind_port;peer=(ip=$remote_ipv6,port=$remote_port) $sender:px -- image=$sender network;ip=$remote_ipv6;port=$remote_port;peer=(ip=$bind_ipv6,port=$bind_port)"
+do_tests "ipv6 udp generic perms" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remote_port udp "$generate_profile"
+
+generate_profile="genprofile network;ip=$bind_ipv6;port=$bind_port;peer=(ip=$remote_ipv6,port=$remote_port) $sender:px -- image=$sender network;ip=$remote_ipv6;port=$remote_port;peer=(ip=$bind_ipv6,port=$bind_port)"
+do_tests "ipv6 tcp generic perms" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remote_port tcp "$generate_profile"
+
+
diff --git a/tests/regression/apparmor/net_finegrained_rcv.c b/tests/regression/apparmor/net_finegrained_rcv.c
new file mode 100644
index 000000000..b426b85fc
--- /dev/null
+++ b/tests/regression/apparmor/net_finegrained_rcv.c
@@ -0,0 +1,378 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+#include <sys/stat.h>
+#include "net_finegrained.h"
+
+struct connection_info {
+	char *bind_ip;
+	char *bind_port;
+	char *remote_ip;
+	char *remote_port;
+	char *protocol;
+	int timeout;
+} net_info;
+
+
+int receive_udp()
+{
+
+	int sock;
+	char *buf;
+	struct sockaddr_in local;
+	struct sockaddr_in6 local6;
+	int ret = -1;
+	int select_return;
+
+	fd_set read_set, err_set;
+	struct timeval timeout;
+
+	buf = (char *) malloc(255);
+	memset(buf, '\0', 255);
+
+	struct ip_address bind_addr;
+	if (!parse_ip(net_info.bind_ip, net_info.bind_port, &bind_addr)) {
+		fprintf(stderr, "FAIL - could not parse bind ip address\n");
+		return -1;
+	}
+
+	if ((sock = socket(bind_addr.family, SOCK_DGRAM, 0)) < 0) {
+		perror("FAIL - Socket error: ");
+		return(-1);
+	}
+
+	const int enable = 1;
+	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0)
+		perror("FAIL - setsockopt(SO_REUSEADDR) failed");
+
+	if (bind_addr.family == AF_INET) {
+		local = convert_to_sockaddr_in(bind_addr);
+		if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0)
+		{
+			perror("FAIL - Bind error: ");
+			return(-1);
+		}
+	} else {
+		local6 = convert_to_sockaddr_in6(bind_addr);
+		if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0)
+		{
+			printf("errno %d\n", errno);
+			perror("FAIL - Bind error: ");
+			return(-1);
+		}
+	}
+
+	FD_ZERO(&read_set);
+	FD_SET(sock, &read_set);
+	FD_ZERO(&err_set);
+	FD_SET(sock, &err_set);
+	timeout.tv_sec = net_info.timeout;
+	timeout.tv_usec = 0;
+
+	select_return = select(sock + 1, &read_set, NULL, &err_set, &timeout);
+	if (select_return < 0)
+	{
+		perror("FAIL - Select error: ");
+		ret = -1;
+	}
+
+
+
+	if ((select_return > 0) && (FD_ISSET(sock, &read_set)) && (!FD_ISSET(sock, &err_set)))
+	{
+
+		if (recvfrom(sock, buf, 255, 0, (struct sockaddr *)0, (unsigned int *)0) >= 1)
+		{
+			//printf("MESSAGE: %s\n", buf);
+			ret = 0;
+		}
+		else
+		{
+			printf("FAIL - recvfrom failed\n");
+			ret = -1;
+		}
+	}
+	free(buf);
+	return(ret);
+
+}
+
+int receive_tcp()
+{
+	int sock, cli_sock;
+	char *buf;
+	struct sockaddr_in local;
+	struct sockaddr_in6 local6;
+	int ret = -1;
+	int select_return;
+
+	fd_set read_set, err_set;
+	struct timeval timeout;
+
+	buf = (char *) malloc(255);
+	memset(buf, '\0', 255);
+
+	struct ip_address bind_addr;
+	if (!parse_ip(net_info.bind_ip, net_info.bind_port, &bind_addr)) {
+		fprintf(stderr, "FAIL - could not parse bind ip address\n");
+		return -1;
+	}
+
+	if ((sock = socket(bind_addr.family, SOCK_STREAM, 0)) < 0)
+	{
+		perror("FAIL - Socket error:");
+		return(-1);
+	}
+
+	const int enable = 1;
+	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0)
+		perror("FAIL - setsockopt(SO_REUSEADDR) failed");
+
+	if (bind_addr.family == AF_INET) {
+		local = convert_to_sockaddr_in(bind_addr);
+		if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0)
+		{
+			perror("FAIL - Bind error: ");
+			return(-1);
+		}
+	} else {
+		local6 = convert_to_sockaddr_in6(bind_addr);
+		if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0)
+		{
+			perror("FAIL - Bind error: ");
+			return(-1);
+		}
+	}
+
+	if (listen(sock, 5) == -1)
+	{
+		perror("FAIL - Could not listen: ");
+		return(-1);
+	}
+
+	FD_ZERO(&read_set);
+	FD_SET(sock, &read_set);
+	FD_ZERO(&err_set);
+	FD_SET(sock, &err_set);
+	timeout.tv_sec = net_info.timeout;
+	timeout.tv_usec = 0;
+
+	select_return = select(sock + 1, &read_set, NULL, &err_set, &timeout);
+	if (select_return < 0)
+	{
+		perror("FAIL - Select failed: ");
+		ret = -1;
+	}
+
+	if ((select_return > 0) && (FD_ISSET(sock, &read_set)) && (!FD_ISSET(sock, &err_set)))
+	{
+		if ((cli_sock = accept(sock, NULL, NULL)) < 0)
+		{
+			perror("FAIL - Accept failed: ");
+			ret = -1;
+		}
+		else
+		{
+			if (recv(cli_sock, buf, 255, 0) >= 1)
+			{
+				//printf("MESSAGE: %s\n", buf);
+				ret = 0;
+			}
+			else
+			{
+				perror("FAIL - recv failure: ");
+				ret = -1;
+			}
+		}
+	}
+	else
+	{
+		perror("FAIL - There were select failures: ");
+		ret = -1;
+	}
+	free(buf);
+	return(ret);
+}
+
+int receive_icmp()
+{
+
+	int sock;
+	char *buf;
+	struct sockaddr_in local;
+	int ret = -1;
+	int select_return;
+
+	fd_set read_set, err_set;
+	struct timeval timeout;
+
+	buf = (char *) malloc(255);
+	memset(buf, '\0', 255);
+	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)) < 0)
+	{
+		perror("FAIL - Socket error: ");
+		return(-1);
+	}
+
+	const int enable = 1;
+	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0)
+		perror("FAIL - setsockopt(SO_REUSEADDR) failed");
+
+	local.sin_family  = AF_INET;
+	local.sin_port = htons(atoi(net_info.bind_port));
+	inet_aton(net_info.bind_ip, &local.sin_addr);
+
+	if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0)
+	{
+		perror("FAIL - Bind error: ");
+		return(-1);
+	}
+
+	FD_ZERO(&read_set);
+	FD_SET(sock, &read_set);
+	FD_ZERO(&err_set);
+	FD_SET(sock, &err_set);
+	timeout.tv_sec = net_info.timeout;
+	timeout.tv_usec = 0;
+
+	select_return = select(sock + 1, &read_set, NULL, &err_set, &timeout);
+	if (select_return < 0)
+	{
+		perror("FAIL - Select error: ");
+		ret = -1;
+	}
+
+
+
+	if ((select_return > 0) && (FD_ISSET(sock, &read_set)) && (!FD_ISSET(sock, &err_set)))
+	{
+
+		if (recvfrom(sock, buf, 255, 0, (struct sockaddr *)0, (unsigned int *)0) >= 1)
+		{
+			//printf("MESSAGE: %s\n", buf);
+			ret = 0;
+		}
+		else
+		{
+			printf("FAIL - recvfrom failed\n");
+			ret = -1;
+		}
+	}
+	free(buf);
+	return(ret);
+
+}
+
+static void usage(char *prog_name, char *msg)
+{
+	if (msg != NULL)
+		fprintf(stderr, "%s\n", msg);
+
+	fprintf(stderr, "Usage: %s [options]\n", prog_name);
+	fprintf(stderr, "Options are:\n");
+	fprintf(stderr, "--bind_ip     local ip address\n");
+	fprintf(stderr, "--bind_port   local port\n");
+	fprintf(stderr, "--remote_ip   remote ip address\n");
+	fprintf(stderr, "--remote_port remote port\n");
+	fprintf(stderr, "--protocol    protocol: udp or tcp\n");
+	fprintf(stderr, "--sender      path of the sender\n");
+	fprintf(stderr, "--timeout     timeout in seconds\n");
+	exit(EXIT_FAILURE);
+}
+
+
+int main(int argc, char *argv[])
+{
+	int opt = 0;
+	int pid, ret = -1;
+	char *sender;
+
+	static struct option long_options[] = {
+		{"bind_ip",     required_argument, 0,  'i' },
+		{"bind_port",   required_argument, 0,  'o' },
+		{"remote_ip",   required_argument, 0,  'r' },
+		{"remote_port", required_argument, 0,  'e' },
+		{"protocol",    required_argument, 0,  'p' },
+		{"timeout",     required_argument, 0,  't' },
+		{"sender",      required_argument, 0,  's' },
+		{0,           0,                 0,  0   }
+	};
+
+	while ((opt = getopt_long(argc, argv,"i:o:r:e:p:t:s:", long_options, 0)) != -1) {
+		switch (opt) {
+		case 'i':
+			net_info.bind_ip = optarg;
+			break;
+		case 'o':
+			net_info.bind_port = optarg;
+			break;
+		case 'r':
+			net_info.remote_ip = optarg;
+			break;
+		case 'e':
+			net_info.remote_port = optarg;
+			break;
+		case 'p':
+			net_info.protocol = optarg;
+			break;
+		case 't':
+			net_info.timeout = atoi(optarg);
+			break;
+		case 's':
+			sender = optarg;
+			break;
+		default:
+			usage(argv[0], "Unrecognized option\n");
+		}
+	}
+
+	/* exec the sender */
+	pid = fork();
+	if (pid == -1) {
+		perror("FAIL - could not fork");
+		exit(EXIT_FAILURE);
+	} else if (!pid) {
+		if (sender == NULL) {
+			usage(argv[0], "sender not specified");
+			exit(EXIT_FAILURE);
+			/* execution of the main thread continues
+			 * in case the sender will be manually executed
+			 */
+		}
+		/* invert remote x local ips to sender */
+		execl(sender, sender, net_info.remote_ip, net_info.remote_port,
+		      net_info.bind_ip, net_info.bind_port,
+		      net_info.protocol, NULL);
+		printf("FAIL %d - execlp %s --bind_ip %s --bind_port %s "
+		       "--remote_ip %s --remote_port %s --protocol %s - %m\n",
+		       getuid(), sender, net_info.bind_ip, net_info.bind_port,
+		       net_info.remote_ip, net_info.remote_port, net_info.protocol);
+		exit(EXIT_FAILURE);
+	}
+
+	if (strcmp(net_info.protocol, "udp") == 0)
+		ret = receive_udp(net_info);
+	else if (strcmp(net_info.protocol, "tcp") == 0)
+		ret = receive_tcp(net_info);
+	else if (strcmp(net_info.protocol, "icmp") == 0)
+		ret = receive_icmp(net_info);
+	else
+		printf("FAIL - Unknown protocol.\n");
+
+	if (ret == -1)
+	{
+		printf("FAIL - Receive message failed.\n");
+		exit(1);
+	}
+
+	printf("PASS\n");
+
+	return 0;
+}
diff --git a/tests/regression/apparmor/net_finegrained_snd.c b/tests/regression/apparmor/net_finegrained_snd.c
new file mode 100644
index 000000000..b208f2a55
--- /dev/null
+++ b/tests/regression/apparmor/net_finegrained_snd.c
@@ -0,0 +1,263 @@
+/* Multiple iteration sending test. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netinet/ip_icmp.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+#include "net_finegrained.h"
+
+struct connection_info {
+	char *bind_ip;
+	char *bind_port;
+	char *remote_ip;
+	char *remote_port;
+	char *protocol;
+} net_info;
+
+int send_udp(char *message)
+{
+	int sock;
+	struct sockaddr_in remote, local;
+	struct sockaddr_in6 remote6, local6;
+
+	struct ip_address bind_addr;
+	if (!parse_ip(net_info.bind_ip, net_info.bind_port, &bind_addr)) {
+		fprintf(stderr, "FAIL SND - could not parse bind ip address\n");
+		return -1;
+	}
+
+	struct ip_address remote_addr;
+	if (!parse_ip(net_info.remote_ip, net_info.remote_port, &remote_addr)) {
+		fprintf(stderr, "FAIL SND - could not parse remote ip address\n");
+		return -1;
+	}
+
+	if ((sock = socket(bind_addr.family, SOCK_DGRAM, 0)) < 0)
+	{
+		perror("FAIL SND - Could not open socket: ");
+		return(-1);
+	}
+
+	const int enable = 1;
+	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0)
+		perror("FAIL SND - setsockopt(SO_REUSEADDR) failed");
+
+
+	if (bind_addr.family == AF_INET) {
+		local = convert_to_sockaddr_in(bind_addr);
+		if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0)
+		{
+			perror("FAIL SND - Bind error: ");
+			return(-1);
+		}
+	} else {
+		local6 = convert_to_sockaddr_in6(bind_addr);
+		if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0)
+		{
+			perror("FAIL SND - Bind error: ");
+			return(-1);
+		}
+	}
+
+	if (remote_addr.family == AF_INET) {
+		remote = convert_to_sockaddr_in(remote_addr);
+		//printf("Sending \"%s\"\n", message);
+		if (sendto(sock, message, strlen(message), 0, (struct sockaddr *) &remote, sizeof(remote)) <= 0)
+		{
+			perror("FAIL SND - Send failed: ");
+			return(-1);
+		}
+	} else {
+		remote6 = convert_to_sockaddr_in6(remote_addr);
+		//printf("Sending \"%s\"\n", message);
+		if (sendto(sock, message, strlen(message), 0, (struct sockaddr *) &remote6, sizeof(remote6)) <= 0)
+		{
+			perror("FAIL SND - Send failed: ");
+			return(-1);
+		}
+	}
+
+
+	close(sock);
+	return(0);
+
+}
+
+int send_tcp(char *message)
+{
+	int sock;
+	struct sockaddr_in remote, local;
+	struct sockaddr_in6 remote6, local6;
+
+	struct ip_address bind_addr;
+	if (!parse_ip(net_info.bind_ip, net_info.bind_port, &bind_addr)) {
+		fprintf(stderr, "FAIL SND - could not parse bind ip address\n");
+		return -1;
+	}
+
+	struct ip_address remote_addr;
+	if (!parse_ip(net_info.remote_ip, net_info.remote_port, &remote_addr)) {
+		fprintf(stderr, "FAIL SND - could not parse remote ip address\n");
+		return -1;
+	}
+
+	if ((sock = socket(bind_addr.family, SOCK_STREAM, 0)) < 0)
+	{
+		perror("FAIL SND - Could not open socket: ");
+		return(-1);
+	}
+
+	const int enable = 1;
+	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0)
+		perror("FAIL SND - setsockopt(SO_REUSEADDR) failed");
+
+	if (bind_addr.family == AF_INET) {
+		local = convert_to_sockaddr_in(bind_addr);
+		if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0)
+		{
+			perror("FAIL SND - Bind error: ");
+			return(-1);
+		}
+	} else {
+		local6 = convert_to_sockaddr_in6(bind_addr);
+		if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0)
+		{
+			perror("FAIL SND - Bind error: ");
+			return(-1);
+		}
+	}
+
+	if (remote_addr.family == AF_INET) {
+		remote = convert_to_sockaddr_in(remote_addr);
+		//printf("Sending \"%s\"\n", message);
+		if (connect(sock, (struct sockaddr *) &remote, sizeof(remote)) < 0)
+		{
+			perror("FAIL SND - Could not connect: ");
+			return(-1);
+		}
+	} else {
+		remote6 = convert_to_sockaddr_in6(remote_addr);
+		//printf("Sending \"%s\"\n", message);
+		if (connect(sock, (struct sockaddr *) &remote6, sizeof(remote6)) < 0)
+		{
+			perror("FAIL SND - Could not connect: ");
+			return(-1);
+		}
+	}
+
+	//printf("Sending \"%s\"\n", message);
+	if (send(sock, message, strlen(message), 0) <= 0)
+	{
+		perror("FAIL SND - Send failed: ");
+		return(-1);
+	}
+	close(sock);
+	return(0);
+}
+
+int send_icmp(char *message)
+{
+	int sock;
+	struct sockaddr_in remote, local;
+	struct icmphdr icmp_hdr;
+	char packetdata[sizeof(icmp_hdr) + 4];
+
+
+	if ((sock = socket(AF_INET | AF_INET6, SOCK_DGRAM, IPPROTO_ICMP)) < 0)
+	{
+		perror("FAIL SND - Could not open socket: ");
+		return(-1);
+	}
+
+	const int enable = 1;
+	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0)
+		perror("FAIL SND - setsockopt(SO_REUSEADDR) failed");
+
+	remote.sin_family = AF_INET;
+	remote.sin_port = htons(atoi(net_info.remote_port));
+	inet_aton(net_info.remote_ip, &remote.sin_addr);
+
+	local.sin_family  = AF_INET;
+	local.sin_port = htons(atoi(net_info.bind_port));
+	inet_aton(net_info.bind_ip, &local.sin_addr);
+
+	// Initialize the ICMP header
+	memset(&icmp_hdr, 0, sizeof(icmp_hdr));
+	icmp_hdr.type = ICMP_ECHO;
+	icmp_hdr.un.echo.id = 1234;
+	icmp_hdr.un.echo.sequence = 1;
+
+	// Initialize the packet data (header and payload)
+	memcpy(packetdata, &icmp_hdr, sizeof(icmp_hdr));
+	memcpy(packetdata + sizeof(icmp_hdr), message, strlen(message));
+
+	if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0)
+	{
+		perror("FAIL SND - Could not bind: ");
+		return(-1);
+	}
+
+	//printf("Sending \"%s\"\n", message);
+
+	// Send the packet
+	if(sendto(sock, packetdata, sizeof(packetdata), 0, (struct sockaddr*) &remote, sizeof(remote)) < 0)
+	{
+		perror("FAIL SND - Send failed: ");
+		close(sock);
+		return(-1);
+	}
+
+	//printf("Sent \"%s\"\n", message);
+
+	/* if (send(sock, packetdata, strlen(packetdata), 0) <= 0) */
+	/* { */
+	/*         perror("FAIL SND - Send failed: "); */
+	/*	close(sock); */
+	/*         return(-1); */
+	/* } */
+	close(sock);
+	return(0);
+}
+
+int main(int argc, char *argv[])
+{
+	int send_ret;
+
+	if (argc < 6)
+	{
+		printf("Usage: %s bind_ip bind_port remote_ip remote_port proto\n", argv[0]);
+		exit(1);
+	}
+
+	net_info.bind_ip = argv[1];
+	net_info.bind_port = argv[2];
+	net_info.remote_ip = argv[3];
+	net_info.remote_port = argv[4];
+	net_info.protocol = argv[5];
+
+	send_ret = -1;
+	if (strcmp(net_info.protocol, "udp") == 0)
+		send_ret = send_udp("test");
+	else if (strcmp(net_info.protocol, "tcp") == 0)
+		send_ret = send_tcp("test");
+	else if (strcmp(net_info.protocol, "icmp") == 0)
+		send_ret = send_icmp("test");
+	else
+		printf("FAIL SND - Unknown protocol.\n");
+
+	if (send_ret == -1)
+	{
+		printf("FAIL SND - Send message failed.\n");
+		exit(1);
+	}
+
+	exit(0);
+}
-- 
GitLab


From 119e3f38f9ef3c3b51bfb2ef3f5525fbe90a0689 Mon Sep 17 00:00:00 2001
From: Georgia Garcia <georgia.garcia@canonical.com>
Date: Thu, 29 Feb 2024 17:30:38 -0300
Subject: [PATCH 10/10] parser: maintain compatibility for fine grained inet
 network mediation

A simple rule without conditionals need to be generated for when the
kernel does not support fine grained inet network mediation.

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
---
 parser/network.cc      | 9 +++++++++
 parser/parser.h        | 1 +
 parser/parser_common.c | 1 +
 parser/parser_main.c   | 3 +++
 4 files changed, 14 insertions(+)

diff --git a/parser/network.cc b/parser/network.cc
index 88040c938..0f14df756 100644
--- a/parser/network.cc
+++ b/parser/network.cc
@@ -612,6 +612,15 @@ bool network_rule::gen_net_rule(Profile &prof, u16 family, unsigned int type_mas
 		buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << (type_mask & 0xff);
 	}
 
+	if (!features_supports_inet) {
+		buf = buffer.str();
+		if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(AA_VALID_NET_PERMS),
+						 dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(AA_VALID_NET_PERMS) : 0,
+						 parseopts))
+			return false;
+		return true;
+	}
+
 	if (perms & AA_PEER_NET_PERMS) {
 		gen_ip_conds(buffer, peer, true, false);
 
diff --git a/parser/parser.h b/parser/parser.h
index b3c19eea3..1f9b1d501 100644
--- a/parser/parser.h
+++ b/parser/parser.h
@@ -341,6 +341,7 @@ extern int kernel_load;
 extern int kernel_supports_setload;
 extern int features_supports_network;
 extern int features_supports_networkv8;
+extern int features_supports_inet;
 extern int kernel_supports_policydb;
 extern int kernel_supports_diff_encode;
 extern int features_supports_mount;
diff --git a/parser/parser_common.c b/parser/parser_common.c
index ff245d057..5887a7a41 100644
--- a/parser/parser_common.c
+++ b/parser/parser_common.c
@@ -69,6 +69,7 @@ int kernel_load = 1;
 int kernel_supports_setload = 0;	/* kernel supports atomic set loads */
 int features_supports_network = 0;	/* kernel supports network rules */
 int features_supports_networkv8 = 0;	/* kernel supports 4.17 network rules */
+int features_supports_inet = 0; 	/* kernel supports inet network rules */
 int features_supports_unix = 0;		/* kernel supports unix socket rules */
 int kernel_supports_policydb = 0;	/* kernel supports new policydb */
 int features_supports_mount = 0;	/* kernel supports mount rules */
diff --git a/parser/parser_main.c b/parser/parser_main.c
index 936017c12..2f98b298a 100644
--- a/parser/parser_main.c
+++ b/parser/parser_main.c
@@ -919,6 +919,9 @@ void set_supported_features()
 	features_supports_networkv8 = features_intersect(kernel_features,
 							 policy_features,
 							 "network_v8");
+	features_supports_inet = features_intersect(kernel_features,
+						    policy_features,
+						    "network/af_inet");
 	features_supports_unix = features_intersect(kernel_features,
 						    policy_features,
 						    "network/af_unix");
-- 
GitLab