Page MenuHomeFreeBSD

D20967.diff
No OneTemporary

D20967.diff

diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -815,6 +815,8 @@
mac
bsdextended
..
+ ipacl
+ ..
portacl
..
..
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -292,6 +292,7 @@
mac_bsdextended.4 \
mac_ddb.4 \
mac_ifoff.4 \
+ mac_ipacl.4 \
mac_lomac.4 \
mac_mls.4 \
mac_none.4 \
diff --git a/share/man/man4/mac.4 b/share/man/man4/mac.4
--- a/share/man/man4/mac.4
+++ b/share/man/man4/mac.4
@@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 10, 2023
+.Dd July 25, 2023
.Dt MAC 4
.Os
.Sh NAME
@@ -57,6 +57,7 @@
.It Xr mac_bsdextended 4 Ta "File system firewall" Ta no Ta any time
.It Xr mac_ddb 4 Ta "ddb(4) interface restrictions" Ta no Ta any time
.It Xr mac_ifoff 4 Ta "Interface silencing" Ta no Ta any time
+.It Xr mac_ipacl 4 Ta "IP Address access control" Ta no Ta any time
.It Xr mac_lomac 4 Ta "Low-Watermark MAC policy" Ta yes Ta boot only
.It Xr mac_mls 4 Ta "Confidentiality policy" Ta yes Ta boot only
.It Xr mac_ntpd 4 Ta "Non-root NTP Daemon policy" Ta no Ta any time
@@ -205,6 +206,7 @@
.Xr mac_bsdextended 4 ,
.Xr mac_ddb 4 ,
.Xr mac_ifoff 4 ,
+.Xr mac_ipacl 4 ,
.Xr mac_lomac 4 ,
.Xr mac_mls 4 ,
.Xr mac_none 4 ,
diff --git a/share/man/man4/mac_ipacl.4 b/share/man/man4/mac_ipacl.4
new file mode 100644
--- /dev/null
+++ b/share/man/man4/mac_ipacl.4
@@ -0,0 +1,166 @@
+.\" Copyright (c) 2019, 2023 Shivank Garg <shivank@FreeBSD.org>
+.\"
+.\" This code was developed as a Google Summer of Code 2019 project
+.\" under the guidance of Bjoern A. Zeeb.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 25, 2023
+.Dt MAC_IPACL 4
+.Os
+.Sh NAME
+.Nm mac_ipacl
+.Nd "IP Address access control policy"
+.Sh SYNOPSIS
+Add the following lines in your kernel configuration file to compile the
+IP address access control policy into your kernel:
+.Bd -ragged -offset indent
+.Cd "options MAC"
+.Cd "options MAC_IPACL"
+.Ed
+.Pp
+To load the mac_ipacl policy module at boot time, add the
+following line in your kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "options MAC"
+.Ed
+.Pp
+and in
+.Xr loader.conf 5 add:
+.Pp
+.Dl "mac_ipacl_load=""YES"""
+.Sh DESCRIPTION
+The
+.Nm
+policy allows the root of the host to use the
+.Xr sysctl 8
+interface to limit the
+.Xr VNET 9
+jail's ability to set IPv4 and IPv6 addresses.
+So, the host can
+define rules for jails and their interfaces about IP addresses
+with
+.Xr sysctl 8
+MIBs.
+.Pp
+Its default behavior is to deny all IP addresses for the jail if
+.Nm
+policy is enforced and allow/deny IP (or subnets) according to the
+.Va security.mac.ipacl.rules
+string specified with
+.Xr sysctl 8
+.Ss Runtime Configuration
+The following
+.Xr sysctl 8
+MIBs are used to control enforcement and behavior of this MAC Policy.
+.Bl -tag -width indent
+.It Va security.mac.ipacl.ipv4
+Enforce
+.Nm
+for IPv4 addresses.
+(Default: 1).
+.It Va security.mac.ipacl.ipv6
+Enforce
+.Nm
+for IPv6 addresses.
+(Default: 1).
+.It Va security.mac.ipacl.rules
+The IP address access control list is specified in the following format:
+.Pp
+.Sm off
+.D1 jid , allow , interface , addr_family , IP_addr / prefix Op @ jid , ...
+.Sm on
+.Bl -tag -width "interface"
+.It jid
+Describe the jail id of the jail for which the rule is written.
+.It allow
+1 for allow and 0 for deny.
+Decides action performed for the rule.
+.It interface
+Name of the interface the rule is enforced for.
+If the interface is left empty then it is a wildcard to enforce the
+rule for all interfaces.
+.It addr_family
+Address family of the IP_addr.
+The input to be given as AF_INET or AF_INET6
+string only.
+.It IP_addr
+IP address (or subnet) to be allowed/denied.
+Action depends on the prefix length.
+.It prefix
+Prefix length of the subnet to be enforced by the policy.
+-1 implies the policy is enforced for the individual IP address.
+For a non-negative value, a range of IP addresses (present in subnet)
+which is calculated as subnet = IP_addr & mask.
+.El
+.El
+.Sh EXAMPLES
+Behavior of the
+.Nm
+policy module for different inputs of sysctl variable:
+.Bl -tag -width "1."
+.It 1.
+Assign ipv4=1, ipv6=0 and rules="1,1,,AF_INET,169.254.123.123/-1"
+.Pp
+It allow only 169.254.123.123 IPv4 address for all interfaces (wildcard) of jail 1.
+It allows all IPv6 addresses since the policy is not enforced for IPv6.
+.It 2.
+Assign ipv4=1, ipv6=1 and rules="1,1,epair0b,AF_INET6,fe80::/32@1,0,epair0b,AF_INET6,fe80::abcd/-1"
+.Pp
+It denies all IPv4 addresses as the policy is enforced but no rules are specified
+about it.
+It allows all IPv6 addresses in subnet fe80::/32 except
+fe80::abcd for interface epair0b only.
+.It 3.
+Assign ipv4=1, ipv6=1, rules="2,1,,AF_INET6,fc00::/7@2,0,,AF_INET6,fc00::1111:2200/120@2,1,,AF_INET6,fc00::1111:2299/-1@1,1,,AF_INET,198.51.100.0/24"
+.Pp
+It allows IPv4 in subnet 198.51.100.0/24 for jail 2 and
+all interfaces.
+It allows IPv6 addresses in subnet fc00::/7 but
+denies subnet fc00::1111:2200/120, and allows individual IP
+fc00::1111:2299 from the denied subnet for all interfaces in jail 2.
+.El
+Please refer to mac/ipacl tests-framework for wide variety of examples on using
+the ipacl module.
+.Sh LIMITATIONS/PRECAUTIONS
+In the case where multiple rules are applicable to an IP address or
+a set of IP addresses, the rule that is defined later in the list
+determines the outcome, disregarding any previous rule for that IP
+address.
+.Sh FUTURE WORKS
+Rules are given with sysctl interface which gets very complex to give them
+all in command line.
+It has to be simplified with a better way to input those rules.
+.Sh SEE ALSO
+.Xr mac 4 ,
+.Xr mac 9
+.Sh AUTHORS
+The
+.Nm
+policy module was developed as a Google Summer of Code Project in 2019
+by
+.An -nosplit
+.An "Shivank Garg" Aq Mt shivank@FreeBSD.org
+under the guidance of
+.An "Bjoern A. Zeeb" Aq Mt bz@FreeBSD.org .
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1232,6 +1232,7 @@
options MAC_BSDEXTENDED
options MAC_DDB
options MAC_IFOFF
+options MAC_IPACL
options MAC_LOMAC
options MAC_MLS
options MAC_NONE
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -5147,6 +5147,7 @@
security/mac_bsdextended/ugidfw_system.c optional mac_bsdextended
security/mac_bsdextended/ugidfw_vnode.c optional mac_bsdextended
security/mac_ifoff/mac_ifoff.c optional mac_ifoff
+security/mac_ipacl/mac_ipacl.c optional mac_ipacl
security/mac_lomac/mac_lomac.c optional mac_lomac
security/mac_mls/mac_mls.c optional mac_mls
security/mac_none/mac_none.c optional mac_none
diff --git a/sys/conf/options b/sys/conf/options
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -158,6 +158,7 @@
MAC_BSDEXTENDED opt_dontuse.h
MAC_DDB opt_dontuse.h
MAC_IFOFF opt_dontuse.h
+MAC_IPACL opt_dontuse.h
MAC_LOMAC opt_dontuse.h
MAC_MLS opt_dontuse.h
MAC_NONE opt_dontuse.h
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -225,6 +225,7 @@
${_mac_bsdextended} \
${_mac_ddb} \
${_mac_ifoff} \
+ ${_mac_ipacl} \
${_mac_lomac} \
${_mac_mls} \
${_mac_none} \
@@ -581,6 +582,7 @@
_mac_ddb= mac_ddb
.endif
_mac_ifoff= mac_ifoff
+_mac_ipacl= mac_ipacl
_mac_lomac= mac_lomac
_mac_mls= mac_mls
_mac_none= mac_none
diff --git a/sys/modules/mac_ipacl/Makefile b/sys/modules/mac_ipacl/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/mac_ipacl/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/security/mac_ipacl
+
+KMOD= mac_ipacl
+SRCS= mac_ipacl.c
+SRCS+= opt_inet.h opt_inet6.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -77,6 +77,10 @@
#include <netinet/udp.h>
#include <netinet/udp_var.h>
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
+
static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct ucred *);
static int in_difaddr_ioctl(u_long, caddr_t, struct ifnet *, struct ucred *);
static int in_gifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct ucred *);
@@ -487,6 +491,13 @@
if (vhid != 0 && carp_attach_p == NULL)
return (EPROTONOSUPPORT);
+#ifdef MAC
+ /* Check if a MAC policy disallows setting the IPv4 address. */
+ error = mac_inet_check_add_addr(cred, &addr->sin_addr, ifp);
+ if (error != 0)
+ return (error);
+#endif
+
/*
* See whether address already exist.
*/
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -115,6 +115,10 @@
#include <netinet6/in6_fib.h>
#include <netinet6/in6_pcb.h>
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
+
/*
* struct in6_ifreq and struct ifreq must be type punnable for common members
* of ifr_ifru to allow accessors to be shared.
@@ -567,6 +571,12 @@
break;
case SIOCAIFADDR_IN6:
+#ifdef MAC
+ /* Check if a MAC policy disallows setting the IPv6 address. */
+ error = mac_inet6_check_add_addr(cred, &sa6->sin6_addr, ifp);
+ if (error != 0)
+ goto out;
+#endif
error = in6_addifaddr(ifp, ifra, ia);
ia = NULL;
break;
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h
--- a/sys/security/mac/mac_framework.h
+++ b/sys/security/mac/mac_framework.h
@@ -90,6 +90,9 @@
struct vnode;
struct vop_setlabel_args;
+struct in_addr;
+struct in6_addr;
+
#include <sys/acl.h> /* XXX acl_type_t */
#include <sys/types.h> /* accmode_t */
@@ -191,6 +194,12 @@
int mac_ifnet_ioctl_set(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifp);
+/* Check if the IP address is allowed for the interface. */
+int mac_inet_check_add_addr(struct ucred *cred,
+ const struct in_addr *ia, struct ifnet *ifp);
+int mac_inet6_check_add_addr(struct ucred *cred,
+ const struct in6_addr *ia6, struct ifnet *ifp);
+
int mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m);
int mac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp);
void mac_inpcb_create(struct socket *so, struct inpcb *inp);
diff --git a/sys/security/mac/mac_inet.c b/sys/security/mac/mac_inet.c
--- a/sys/security/mac/mac_inet.c
+++ b/sys/security/mac/mac_inet.c
@@ -108,6 +108,17 @@
return (0);
}
+/* Check with rules in module if the IPv4 address is allowed. */
+int
+mac_inet_check_add_addr(struct ucred *cred, const struct in_addr *ia,
+ struct ifnet *ifp)
+{
+ int error;
+
+ MAC_POLICY_CHECK(ip4_check_jail, cred, ia, ifp);
+ return (error);
+}
+
static struct label *
mac_ipq_label_alloc(int flag)
{
diff --git a/sys/security/mac/mac_inet6.c b/sys/security/mac/mac_inet6.c
--- a/sys/security/mac/mac_inet6.c
+++ b/sys/security/mac/mac_inet6.c
@@ -173,6 +173,17 @@
q6->ip6q_label);
}
+/* Check with rules in module if the IPv6 address is allowed. */
+int
+mac_inet6_check_add_addr(struct ucred *cred, const struct in6_addr *ia6,
+ struct ifnet *ifp)
+{
+ int error;
+
+ MAC_POLICY_CHECK(ip6_check_jail, cred, ia6, ifp);
+ return (error);
+}
+
void
mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m)
{
diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h
--- a/sys/security/mac/mac_policy.h
+++ b/sys/security/mac/mac_policy.h
@@ -104,6 +104,9 @@
struct vattr;
struct vnode;
+struct in_addr;
+struct in6_addr;
+
/*
* Policy module operations.
*/
@@ -248,6 +251,12 @@
typedef void (*mpo_ip6q_update_t)(struct mbuf *m, struct label *mlabel,
struct ip6q *q6, struct label *q6label);
+/* Policy ops checking IPv4 and IPv6 address for ipacl. */
+typedef int (*mpo_ip4_check_jail_t)(struct ucred *cred,
+ const struct in_addr *ia, struct ifnet *ifp);
+typedef int (*mpo_ip6_check_jail_t)(struct ucred *cred,
+ const struct in6_addr *ia6, struct ifnet *ifp);
+
typedef void (*mpo_ipq_create_t)(struct mbuf *m, struct label *mlabel,
struct ipq *q, struct label *qlabel);
typedef void (*mpo_ipq_destroy_label_t)(struct label *label);
@@ -762,6 +771,9 @@
mpo_inpcb_init_label_t mpo_inpcb_init_label;
mpo_inpcb_sosetlabel_t mpo_inpcb_sosetlabel;
+ mpo_ip4_check_jail_t mpo_ip4_check_jail;
+ mpo_ip6_check_jail_t mpo_ip6_check_jail;
+
mpo_ip6q_create_t mpo_ip6q_create;
mpo_ip6q_destroy_label_t mpo_ip6q_destroy_label;
mpo_ip6q_init_label_t mpo_ip6q_init_label;
diff --git a/sys/security/mac_ipacl/mac_ipacl.c b/sys/security/mac_ipacl/mac_ipacl.c
new file mode 100644
--- /dev/null
+++ b/sys/security/mac_ipacl/mac_ipacl.c
@@ -0,0 +1,453 @@
+/*-
+ * Copyright (c) 2003-2004 Networks Associates Technology, Inc.
+ * Copyright (c) 2006 SPARTA, Inc.
+ * Copyright (c) 2019, 2023 Shivank Garg <shivank@FreeBSD.org>
+ *
+ * This software was developed for the FreeBSD Project by Network
+ * Associates Laboratories, the Security Research Division of Network
+ * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
+ * as part of the DARPA CHATS research program.
+ *
+ * This software was enhanced by SPARTA ISSO under SPAWAR contract
+ * N66001-04-C-6019 ("SEFOS").
+ *
+ * This code was developed as a Google Summer of Code 2019 project
+ * under the guidance of Bjoern A. Zeeb.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * The IP address access control policy module - mac_ipacl allows the root of
+ * the host to limit the VNET jail's privileges of setting IPv4 and IPv6
+ * addresses via sysctl(8) interface. So, the host can define rules for jails
+ * and their interfaces about IP addresses.
+ * sysctl(8) is to be used to modify the rules string in following format-
+ * "jail_id,allow,interface,address_family,IP_addr/prefix_length[@jail_id,...]"
+ */
+
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/module.h>
+#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/mutex.h>
+#include <sys/priv.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/ucred.h>
+#include <sys/jail.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+
+#include <netinet/in.h>
+#include <netinet6/scope6_var.h>
+
+#include <security/mac/mac_policy.h>
+
+SYSCTL_DECL(_security_mac);
+
+static SYSCTL_NODE(_security_mac, OID_AUTO, ipacl, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+ "TrustedBSD mac_ipacl policy controls");
+
+#ifdef INET
+static int ipacl_ipv4 = 1;
+SYSCTL_INT(_security_mac_ipacl, OID_AUTO, ipv4, CTLFLAG_RWTUN,
+ &ipacl_ipv4, 0, "Enforce mac_ipacl for IPv4 addresses");
+#endif
+
+#ifdef INET6
+static int ipacl_ipv6 = 1;
+SYSCTL_INT(_security_mac_ipacl, OID_AUTO, ipv6, CTLFLAG_RWTUN,
+ &ipacl_ipv6, 0, "Enforce mac_ipacl for IPv6 addresses");
+#endif
+
+static MALLOC_DEFINE(M_IPACL, "ipacl_rule", "Rules for mac_ipacl");
+
+#define MAC_RULE_STRING_LEN 1024
+
+struct ipacl_addr {
+ union {
+#ifdef INET
+ struct in_addr ipv4;
+#endif
+#ifdef INET6
+ struct in6_addr ipv6;
+#endif
+ u_int8_t addr8[16];
+ u_int16_t addr16[8];
+ u_int32_t addr32[4];
+ } ipa; /* 128 bit address*/
+#ifdef INET
+#define v4 ipa.ipv4
+#endif
+#ifdef INET6
+#define v6 ipa.ipv6
+#endif
+#define addr8 ipa.addr8
+#define addr16 ipa.addr16
+#define addr32 ipa.addr32
+};
+
+struct ip_rule {
+ int jid;
+ bool allow;
+ bool subnet_apply; /* Apply rule on whole subnet. */
+ char if_name[IFNAMSIZ];
+ int af; /* Address family. */
+ struct ipacl_addr addr;
+ struct ipacl_addr mask;
+ TAILQ_ENTRY(ip_rule) r_entries;
+};
+
+static struct mtx rule_mtx;
+static TAILQ_HEAD(rulehead, ip_rule) rule_head;
+static char rule_string[MAC_RULE_STRING_LEN];
+
+static void
+destroy_rules(struct rulehead *head)
+{
+ struct ip_rule *rule;
+
+ while ((rule = TAILQ_FIRST(head)) != NULL) {
+ TAILQ_REMOVE(head, rule, r_entries);
+ free(rule, M_IPACL);
+ }
+}
+
+static void
+ipacl_init(struct mac_policy_conf *conf)
+{
+ mtx_init(&rule_mtx, "rule_mtx", NULL, MTX_DEF);
+ TAILQ_INIT(&rule_head);
+}
+
+static void
+ipacl_destroy(struct mac_policy_conf *conf)
+{
+ mtx_destroy(&rule_mtx);
+ destroy_rules(&rule_head);
+}
+
+/*
+ * Note: parsing routines are destructive on the passed string.
+ */
+static int
+parse_rule_element(char *element, struct ip_rule *rule)
+{
+ char *tok, *p;
+ int prefix;
+#ifdef INET6
+ int i;
+#endif
+
+ /* Should we support a jail wildcard? */
+ tok = strsep(&element, ",");
+ if (tok == NULL)
+ return (EINVAL);
+ rule->jid = strtol(tok, &p, 10);
+ if (*p != '\0')
+ return (EINVAL);
+ tok = strsep(&element, ",");
+ if (tok == NULL)
+ return (EINVAL);
+ rule->allow = strtol(tok, &p, 10);
+ if (*p != '\0')
+ return (EINVAL);
+ tok = strsep(&element, ",");
+ if (strlen(tok) + 1 > IFNAMSIZ)
+ return (EINVAL);
+ /* Empty interface name is wildcard to all interfaces. */
+ strlcpy(rule->if_name, tok, strlen(tok) + 1);
+ tok = strsep(&element, ",");
+ if (tok == NULL)
+ return (EINVAL);
+ rule->af = (strcmp(tok, "AF_INET") == 0) ? AF_INET :
+ (strcmp(tok, "AF_INET6") == 0) ? AF_INET6 : -1;
+ if (rule->af == -1)
+ return (EINVAL);
+ tok = strsep(&element, "/");
+ if (tok == NULL)
+ return (EINVAL);
+ if (inet_pton(rule->af, tok, rule->addr.addr32) != 1)
+ return (EINVAL);
+ tok = element;
+ if (tok == NULL)
+ return (EINVAL);
+ prefix = strtol(tok, &p, 10);
+ if (*p != '\0')
+ return (EINVAL);
+ /* Value -1 for prefix make policy applicable to individual IP only. */
+ if (prefix == -1)
+ rule->subnet_apply = false;
+ else {
+ rule->subnet_apply = true;
+ switch (rule->af) {
+#ifdef INET
+ case AF_INET:
+ if (prefix < 0 || prefix > 32)
+ return (EINVAL);
+
+ if (prefix == 0)
+ rule->mask.addr32[0] = htonl(0);
+ else
+ rule->mask.addr32[0] =
+ htonl(~((1 << (32 - prefix)) - 1));
+ rule->addr.addr32[0] &= rule->mask.addr32[0];
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (prefix < 0 || prefix > 128)
+ return (EINVAL);
+
+ for (i = 0; prefix > 0; prefix -= 8, i++)
+ rule->mask.addr8[i] = prefix >= 8 ? 0xFF :
+ (u_int8_t)((0xFFU << (8 - prefix)) & 0xFFU);
+ for (i = 0; i < 16; i++)
+ rule->addr.addr8[i] &= rule->mask.addr8[i];
+ break;
+#endif
+ }
+ }
+ return (0);
+}
+
+/*
+ * Format of Rule- jid,allow,interface_name,addr_family,ip_addr/subnet_mask
+ * Example: sysctl security.mac.ipacl.rules=1,1,epair0b,AF_INET,192.0.2.2/24
+ */
+static int
+parse_rules(char *string, struct rulehead *head)
+{
+ struct ip_rule *new;
+ char *element;
+ int error;
+
+ error = 0;
+ while ((element = strsep(&string, "@")) != NULL) {
+ if (strlen(element) == 0)
+ continue;
+
+ new = malloc(sizeof(*new), M_IPACL, M_ZERO | M_WAITOK);
+ error = parse_rule_element(element, new);
+ if (error != 0) {
+ free(new, M_IPACL);
+ goto out;
+ }
+ TAILQ_INSERT_TAIL(head, new, r_entries);
+ }
+out:
+ if (error != 0)
+ destroy_rules(head);
+ return (error);
+}
+
+static int
+sysctl_rules(SYSCTL_HANDLER_ARGS)
+{
+ char *string, *copy_string, *new_string;
+ struct rulehead head, save_head;
+ int error;
+
+ new_string = NULL;
+ if (req->newptr != NULL) {
+ new_string = malloc(MAC_RULE_STRING_LEN, M_IPACL,
+ M_WAITOK | M_ZERO);
+ mtx_lock(&rule_mtx);
+ strcpy(new_string, rule_string);
+ mtx_unlock(&rule_mtx);
+ string = new_string;
+ } else
+ string = rule_string;
+
+ error = sysctl_handle_string(oidp, string, MAC_RULE_STRING_LEN, req);
+ if (error)
+ goto out;
+
+ if (req->newptr != NULL) {
+ copy_string = strdup(string, M_IPACL);
+ TAILQ_INIT(&head);
+ error = parse_rules(copy_string, &head);
+ free(copy_string, M_IPACL);
+ if (error)
+ goto out;
+
+ TAILQ_INIT(&save_head);
+ mtx_lock(&rule_mtx);
+ TAILQ_CONCAT(&save_head, &rule_head, r_entries);
+ TAILQ_CONCAT(&rule_head, &head, r_entries);
+ strcpy(rule_string, string);
+ mtx_unlock(&rule_mtx);
+ destroy_rules(&save_head);
+ }
+out:
+ if (new_string != NULL)
+ free(new_string, M_IPACL);
+ return (error);
+}
+SYSCTL_PROC(_security_mac_ipacl, OID_AUTO, rules,
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+ 0, sysctl_rules, "A", "IP ACL Rules");
+
+static int
+rules_check(struct ucred *cred,
+ struct ipacl_addr *ip_addr, struct ifnet *ifp)
+{
+ struct ip_rule *rule;
+ int error;
+#ifdef INET6
+ int i;
+ bool same_subnet;
+#endif
+
+ error = EPERM;
+
+ mtx_lock(&rule_mtx);
+
+ /*
+ * In the case where multiple rules are applicable to an IP address or
+ * a set of IP addresses, the rule that is defined later in the list
+ * determines the outcome, disregarding any previous rule for that IP
+ * address.
+ * Walk the policy rules list in reverse order until rule applicable
+ * to the requested IP address is found.
+ */
+ TAILQ_FOREACH_REVERSE(rule, &rule_head, rulehead, r_entries) {
+ /* Skip if current rule applies to different jail. */
+ if (cred->cr_prison->pr_id != rule->jid)
+ continue;
+
+ if (strcmp(rule->if_name, "\0") &&
+ strcmp(rule->if_name, ifp->if_xname))
+ continue;
+
+ switch (rule->af) {
+#ifdef INET
+ case AF_INET:
+ if (rule->subnet_apply) {
+ if (rule->addr.v4.s_addr !=
+ (ip_addr->v4.s_addr & rule->mask.v4.s_addr))
+ continue;
+ } else
+ if (ip_addr->v4.s_addr != rule->addr.v4.s_addr)
+ continue;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (rule->subnet_apply) {
+ same_subnet = true;
+ for (i = 0; i < 16; i++)
+ if (rule->addr.v6.s6_addr[i] !=
+ (ip_addr->v6.s6_addr[i] &
+ rule->mask.v6.s6_addr[i])) {
+ same_subnet = false;
+ break;
+ }
+ if (!same_subnet)
+ continue;
+ } else
+ if (bcmp(&rule->addr, ip_addr,
+ sizeof(*ip_addr)))
+ continue;
+ break;
+#endif
+ }
+
+ if (rule->allow)
+ error = 0;
+ break;
+ }
+
+ mtx_unlock(&rule_mtx);
+
+ return (error);
+}
+
+/*
+ * Feature request: Can we make this sysctl policy apply to jails by default,
+ * but also allow it to be changed to apply to the base system?
+ */
+#ifdef INET
+static int
+ipacl_ip4_check_jail(struct ucred *cred,
+ const struct in_addr *ia, struct ifnet *ifp)
+{
+ struct ipacl_addr ip4_addr;
+
+ ip4_addr.v4 = *ia;
+
+ if (!jailed(cred))
+ return (0);
+
+ /* Checks with the policy only when it is enforced for ipv4. */
+ if (ipacl_ipv4)
+ return rules_check(cred, &ip4_addr, ifp);
+
+ return (0);
+}
+#endif
+
+#ifdef INET6
+static int
+ipacl_ip6_check_jail(struct ucred *cred,
+ const struct in6_addr *ia6, struct ifnet *ifp)
+{
+ struct ipacl_addr ip6_addr;
+
+ ip6_addr.v6 = *ia6; /* Make copy to not alter the original. */
+ in6_clearscope(&ip6_addr.v6); /* Clear the scope id. */
+
+ if (!jailed(cred))
+ return (0);
+
+ /* Checks with the policy when it is enforced for ipv6. */
+ if (ipacl_ipv6)
+ return rules_check(cred, &ip6_addr, ifp);
+
+ return (0);
+}
+#endif
+
+static struct mac_policy_ops ipacl_ops =
+{
+ .mpo_init = ipacl_init,
+ .mpo_destroy = ipacl_destroy,
+#ifdef INET
+ .mpo_ip4_check_jail = ipacl_ip4_check_jail,
+#endif
+#ifdef INET6
+ .mpo_ip6_check_jail = ipacl_ip6_check_jail,
+#endif
+};
+
+MAC_POLICY_SET(&ipacl_ops, mac_ipacl, "TrustedBSD MAC/ipacl",
+ MPC_LOADTIME_FLAG_UNLOADOK, NULL);
diff --git a/tests/sys/mac/Makefile b/tests/sys/mac/Makefile
--- a/tests/sys/mac/Makefile
+++ b/tests/sys/mac/Makefile
@@ -3,6 +3,7 @@
TESTSDIR= ${TESTSBASE}/sys/mac
TESTS_SUBDIRS+= bsdextended
+TESTS_SUBDIRS+= ipacl
TESTS_SUBDIRS+= portacl
.include <bsd.test.mk>
diff --git a/tests/sys/mac/ipacl/Makefile b/tests/sys/mac/ipacl/Makefile
new file mode 100644
--- /dev/null
+++ b/tests/sys/mac/ipacl/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/mac/ipacl
+
+ATF_TESTS_SH+= ipacl_test
+
+${PACKAGE}FILES+= utils.subr
+
+.include <bsd.test.mk>
diff --git a/tests/sys/mac/ipacl/ipacl_test.sh b/tests/sys/mac/ipacl/ipacl_test.sh
new file mode 100644
--- /dev/null
+++ b/tests/sys/mac/ipacl/ipacl_test.sh
@@ -0,0 +1,282 @@
+#-
+# Copyright (c) 2019, 2023 Shivank Garg <shivank@FreeBSD.org>
+#
+# This code was developed as a Google Summer of Code 2019 project
+# under the guidance of Bjoern A. Zeeb.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+. $(atf_get_srcdir)/utils.subr
+
+atf_test_case "ipacl_v4" "cleanup"
+
+ipacl_v4_head()
+{
+ atf_set descr 'basic test for ipacl on IPv4 addresses'
+ atf_set require.user root
+}
+
+ipacl_v4_body()
+{
+ ipacl_test_init
+
+ epairA=$(vnet_mkepair)
+ epairB=$(vnet_mkepair)
+ epairC=$(vnet_mkepair)
+
+ vnet_mkjail A ${epairA}b
+ vnet_mkjail B ${epairB}b ${epairC}b
+
+ jidA=$(jls -j A -s jid | grep -o -E '[0-9]+')
+ jidB=$(jls -j B -s jid | grep -o -E '[0-9]+')
+
+ # The ipacl policy module is not enforced for IPv4.
+ sysctl security.mac.ipacl.ipv4=0
+
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 192.0.2.2/24 up
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 203.0.113.254/24 up
+
+ # The ipacl policy module is enforced for IPv4 and prevent all
+ # jails from setting their IPv4 address.
+ sysctl security.mac.ipacl.ipv4=1
+ sysctl security.mac.ipacl.rules=
+
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 192.0.2.2/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 203.0.113.254/24 up
+
+ rule="${jidA},1,${epairA}b,AF_INET,192.0.2.42/-1@"
+ rule="${rule}${jidB},1,${epairB}b,AF_INET,198.51.100.12/-1@"
+ rule="${rule}${jidB},1,,AF_INET,203.0.113.1/24@"
+ rule="${rule}${jidB},0,,AF_INET,203.0.113.9/-1"
+ sysctl security.mac.ipacl.rules="${rule}"
+
+ # Verify if it allows jail to set only certain IPv4 address.
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 192.0.2.42/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 192.0.2.43/24 up
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b 198.51.100.12/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b 198.51.100.12/24 up
+
+ # Verify if the module allow jail to set any address in subnet.
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b 203.0.113.19/24 up
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b 203.0.113.241/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b 198.18.0.1/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b 203.0.113.9/24 up
+
+ # Check wildcard for interfaces.
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b 203.0.113.20/24 up
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b 203.0.113.242/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b 198.18.0.1/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b 203.0.113.9/24 up
+
+ rule="${jidA},1,,AF_INET,198.18.0.0/15@"
+ rule="${rule}${jidA},0,,AF_INET,198.18.23.0/24@"
+ rule="${rule}${jidA},1,,AF_INET,198.18.23.1/-1@"
+ rule="${rule}${jidA},1,,AF_INET,198.51.100.0/24@"
+ rule="${rule}${jidA},0,,AF_INET,198.51.100.100/-1"
+ sysctl security.mac.ipacl.rules="${rule}"
+
+ # Tests from Benchamarking and Documentation(TEST-NET-3).
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 198.18.0.1/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 198.18.23.2/24 up
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 198.18.23.1/22 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 198.18.23.3/24 up
+
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 198.51.100.001/24 up
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 198.51.100.254/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 198.51.100.100/24 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b 203.0.113.1/24 up
+
+ # Reset rules OID.
+ sysctl security.mac.ipacl.rules=
+}
+
+ipacl_v4_cleanup()
+{
+ ipacl_test_cleanup
+}
+
+atf_test_case "ipacl_v6" "cleanup"
+
+ipacl_v6_head()
+{
+ atf_set descr 'basic test for ipacl on IPv6 addresses'
+ atf_set require.user root
+}
+
+ipacl_v6_body()
+{
+ ipacl_test_init
+
+ epairA=$(vnet_mkepair)
+ epairB=$(vnet_mkepair)
+ epairC=$(vnet_mkepair)
+
+ vnet_mkjail A ${epairA}b
+ vnet_mkjail B ${epairB}b ${epairC}b
+
+ jidA=$(jls -j A -s jid | grep -o -E '[0-9]+')
+ jidB=$(jls -j B -s jid | grep -o -E '[0-9]+')
+
+ # The ipacl policy module is not enforced for IPv6.
+ sysctl security.mac.ipacl.ipv6=0
+
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 2001:2::abcd/48 up
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 2001:2::5ea:11/48 up
+
+ # The ipacl policy module is enforced for IPv6 and prevent all
+ # jails from setting their IPv6 address.
+ sysctl security.mac.ipacl.ipv6=1
+ sysctl security.mac.ipacl.rules=
+
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 2001:2::abcd/48 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 2001:2::5ea:11/48 up
+
+ rule="${jidA},1,${epairA}b,AF_INET6,2001:db8::1111/-1@"
+ rule="${rule}${jidB},1,${epairB}b,AF_INET6,2001:2::1234:1234/-1@"
+ rule="${rule}${jidB},1,,AF_INET6,fe80::/32@"
+ rule="${rule}${jidB},0,,AF_INET6,fe80::abcd/-1"
+ sysctl security.mac.ipacl.rules="${rule}"
+
+ # Verify if it allows jail to set only certain IPv6 address.
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 2001:db8::1111/64 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 2001:db8::1112/64 up
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b inet6 2001:2::1234:1234/48 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 2001:2::1234:1234/48 up
+
+ # Verify if the module allow jail set any address in subnet.
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b inet6 FE80::1101:1221/15 up
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b inet6 FE80::abab/15 up
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b inet6 FE80::1/64 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairB}b inet6 FE80::abcd/15 up
+
+ # Check wildcard for interfaces.
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b inet6 FE80::1101:1221/15 up
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b inet6 FE80::abab/32 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b inet6 FE81::1/64 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b inet6 FE80::abcd/32 up
+
+ rule="${jidB},1,,AF_INET6,2001:2::/48@"
+ rule="${rule}${jidB},1,,AF_INET6,2001:3::/32"
+ sysctl security.mac.ipacl.rules="${rule}"
+
+ # Tests when subnet is allowed.
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b inet6 2001:2:0001::1/64 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b inet6 2001:2:1000::1/32 up
+ atf_check -s exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b inet6 2001:3:0001::1/64 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec B ifconfig ${epairC}b inet6 2001:4::1/64 up
+
+ # More tests of ULA address space.
+ rule="${jidA},1,,AF_INET6,fc00::/7@"
+ rule="${rule}${jidA},0,,AF_INET6,fc00::1111:2200/120@"
+ rule="${rule}${jidA},1,,AF_INET6,fc00::1111:2299/-1@"
+ rule="${rule}${jidA},1,,AF_INET6,2001:db8::/32@"
+ rule="${rule}${jidA},0,,AF_INET6,2001:db8::abcd/-1"
+ sysctl security.mac.ipacl.rules="${rule}"
+
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 fc00::0000:1234/48 up
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 fc00::0000:1234/48 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 f800::2222:2200/48 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 f800::2222:22ff/48 up
+
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 fc00::1111:2111/64 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 fc00::1111:2211/64 up
+ atf_check -s not-exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 fc00::1111:22aa/48 up
+ atf_check -s exit:0 -e ignore \
+ jexec A ifconfig ${epairA}b inet6 fc00::1111:2299/48 up
+
+ # More tests from IPv6 documentation range.
+ atf_check -s exit:0 -e ignore jexec A ifconfig \
+ ${epairA}b inet6 2001:db8:abcd:bcde:cdef:def1:ef12:f123/32 up
+ atf_check -s exit:0 -e ignore jexec A ifconfig \
+ ${epairA}b inet6 2001:db8:1111:2222:3333:4444:5555:6666/32 up
+ atf_check -s not-exit:0 -e ignore jexec A ifconfig \
+ ${epairA}b inet6 2001:ab9:1111:2222:3333:4444:5555:6666/32 up
+ atf_check -s not-exit:0 -e ignore jexec A ifconfig \
+ ${epairA}b inet6 2001:db8::abcd/32 up
+
+ # Reset rules OID.
+ sysctl security.mac.ipacl.rules=
+}
+
+ipacl_v6_cleanup()
+{
+ ipacl_test_cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case "ipacl_v4"
+ atf_add_test_case "ipacl_v6"
+}
diff --git a/tests/sys/mac/ipacl/utils.subr b/tests/sys/mac/ipacl/utils.subr
new file mode 100644
--- /dev/null
+++ b/tests/sys/mac/ipacl/utils.subr
@@ -0,0 +1,18 @@
+# $FreeBSD$
+# Utility functions for mac_ipacl tests
+
+. $(atf_get_srcdir)/../../common/vnet.subr
+
+ipacl_test_init()
+{
+ vnet_init
+
+ if ! kldstat -q -m mac_ipacl; then
+ atf_skip "mac_ipacl is not loaded"
+ fi
+}
+
+ipacl_test_cleanup()
+{
+ vnet_cleanup
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 12, 2:50 AM (20 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15760290
Default Alt Text
D20967.diff (36 KB)

Event Timeline