From owner-svn-soc-all@freebsd.org Sun May 27 16:28:16 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7166EF79A49 for ; Sun, 27 May 2018 16:28:16 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 0024F859DA for ; Sun, 27 May 2018 16:28:16 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id 2284111A59 for ; Sun, 27 May 2018 16:28:15 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w4RGSEsh085245 for ; Sun, 27 May 2018 16:28:14 GMT (envelope-from aniketp@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w4RGSBxP085170 for svn-soc-all@FreeBSD.org; Sun, 27 May 2018 16:28:11 GMT (envelope-from aniketp@FreeBSD.org) Date: Sun, 27 May 2018 16:28:11 GMT Message-Id: <201805271628.w4RGSBxP085170@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to aniketp@FreeBSD.org using -f From: aniketp@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337255 - soc2018/aniketp/head/tests/sys/audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 May 2018 16:28:16 -0000 Author: aniketp Date: Sun May 27 16:28:08 2018 New Revision: 337255 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337255 Log: Initialize test-program for Inter-Process-Communication syscalls Added: soc2018/aniketp/head/tests/sys/audit/inter-process.c Modified: soc2018/aniketp/head/tests/sys/audit/Makefile soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c Modified: soc2018/aniketp/head/tests/sys/audit/Makefile ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/Makefile Sat May 26 23:14:07 2018 (r337254) +++ soc2018/aniketp/head/tests/sys/audit/Makefile Sun May 27 16:28:08 2018 (r337255) @@ -12,6 +12,7 @@ ATF_TESTS_C+= exec ATF_TESTS_C+= ioctl ATF_TESTS_C+= network +ATF_TESTS_C+= inter-process SRCS.file-create+= file-create.c SRCS.file-create+= utils.c @@ -33,6 +34,8 @@ SRCS.ioctl+= utils.c SRCS.network+= network.c SRCS.network+= utils.c +SRCS.inter-process+= inter-process.c +SRCS.inter-process+= utils.c TEST_METADATA.file-create+= timeout="30" TEST_METADATA.file-create+= required_user="root" @@ -54,6 +57,8 @@ TEST_METADATA.ioctl+= required_user="root" TEST_METADATA.network+= timeout="30" TEST_METADATA.network+= required_user="root" +TEST_METADATA.inter-process+= timeout="30" +TEST_METADATA.inter-process+= required_user="root" WARNS?= 6 Modified: soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c Sat May 26 23:14:07 2018 (r337254) +++ soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c Sun May 27 16:28:08 2018 (r337255) @@ -372,57 +372,6 @@ } -ATF_TC_WITH_CLEANUP(getfh_success); -ATF_TC_HEAD(getfh_success, tc) -{ - atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " - "getfh(2) call"); -} - -ATF_TC_BODY(getfh_success, tc) -{ - atf_tc_expect_fail("getfh(2) is audited as nfs_getfh(2) in 'ad'" - "audit class in success mode"); - - /* File needs to exist to get a file-handle */ - ATF_REQUIRE(open(path, O_CREAT, mode) != -1); - const char *regex = "getfh.*return,success"; - FILE *pipefd = setup(fds, "fa"); - ATF_REQUIRE_EQ(0, getfh(path, &fht)); - check_audit(fds, regex, pipefd); -} - -ATF_TC_CLEANUP(getfh_success, tc) -{ - cleanup(); -} - - -ATF_TC_WITH_CLEANUP(getfh_failure); -ATF_TC_HEAD(getfh_failure, tc) -{ - atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " - "getfh(2) call"); -} - -ATF_TC_BODY(getfh_failure, tc) -{ - atf_tc_expect_fail("getfh(2) is audited as nfs_getfh(2) in 'ad'" - "audit class in failure mode"); - - const char *regex = "getfh.*return,failure"; - FILE *pipefd = setup(fds, "fa"); - /* Failure reason: file does not exist */ - ATF_REQUIRE_EQ(0, lgetfh(errpath, &fht)); - check_audit(fds, regex, pipefd); -} - -ATF_TC_CLEANUP(getfh_failure, tc) -{ - cleanup(); -} - - ATF_TC_WITH_CLEANUP(lgetfh_success); ATF_TC_HEAD(lgetfh_success, tc) { @@ -2001,9 +1950,6 @@ ATF_TP_ADD_TC(tp, getfsstat_success); ATF_TP_ADD_TC(tp, getfsstat_failure); - - ATF_TP_ADD_TC(tp, getfh_success); - ATF_TP_ADD_TC(tp, getfh_failure); ATF_TP_ADD_TC(tp, lgetfh_success); ATF_TP_ADD_TC(tp, lgetfh_failure); Added: soc2018/aniketp/head/tests/sys/audit/inter-process.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2018/aniketp/head/tests/sys/audit/inter-process.c Sun May 27 16:28:08 2018 (r337255) @@ -0,0 +1,257 @@ +/*- + * Copyright 2018 Aniket Pandey + * All rights reserved. + * + * 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 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * 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 + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#include + +#include "utils.h" + +struct msgstr { + long int mtype; + char mtext[128]; +}; +typedef struct msgstr msgstr_t; + +static struct pollfd fds[1]; +static struct msqid_ds msgbuff; +static int msqid; +static char ipcregex[60]; +static ssize_t msgsize; + + +ATF_TC_WITH_CLEANUP(msgget_success); +ATF_TC_HEAD(msgget_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "msgget(2) call"); +} + +ATF_TC_BODY(msgget_success, tc) +{ + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE((msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR)) != -1); + /* Check the presence of message queue ID in audit record */ + snprintf(ipcregex, 60, "msgget.*return,success,%d", msqid); + check_audit(fds, ipcregex, pipefd); +} + +ATF_TC_CLEANUP(msgget_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgget_failure); +ATF_TC_HEAD(msgget_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "msgget(2) call"); +} + +ATF_TC_BODY(msgget_failure, tc) +{ + const char *regex = "msgget.*return,failure : No such file or directory"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, msgget((key_t)(-1), 0)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(msgget_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgctl_success); +ATF_TC_HEAD(msgctl_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "msgctl(2) call"); +} + +ATF_TC_BODY(msgctl_success, tc) +{ + msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_STAT, &msgbuff)); + /* Check the presence of message queue ID in audit record */ + snprintf(ipcregex, 60, "msgctl.*IPC_STAT.*%d.*return,success", msqid); + check_audit(fds, ipcregex, pipefd); +} + +ATF_TC_CLEANUP(msgctl_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgctl_failure); +ATF_TC_HEAD(msgctl_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "msgctl(2) call"); +} + +ATF_TC_BODY(msgctl_failure, tc) +{ + const char *regex = "msgctl.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, msgctl(-1, IPC_STAT, &msgbuff)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(msgctl_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgsnd_success); +ATF_TC_HEAD(msgsnd_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "msgsnd(2) call"); +} + +ATF_TC_BODY(msgsnd_success, tc) +{ + msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR); + msgsize = sizeof(msgstr_t) - sizeof(long int); + + /* Initialize a msgstr_t structure to store message */ + msgstr_t msg1 = {1, "sample message"}; + /* Check the presence of message queue ID in audit record */ + snprintf(ipcregex, 60, "msgsnd.*Message IPC.*%d.*return,success", msqid); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, msgsnd(msqid, &msg1, msgsize, IPC_NOWAIT)); + check_audit(fds, ipcregex, pipefd); +} + +ATF_TC_CLEANUP(msgsnd_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgsnd_failure); +ATF_TC_HEAD(msgsnd_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "msgsnd(2) call"); +} + +ATF_TC_BODY(msgsnd_failure, tc) +{ + const char *regex = "msgsnd.*Message IPC.*return,failure : Bad address"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, msgsnd(-1, NULL, 0, IPC_NOWAIT)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(msgsnd_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgrcv_success); +ATF_TC_HEAD(msgrcv_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "msgrcv(2) call"); +} + +ATF_TC_BODY(msgrcv_success, tc) +{ + ssize_t recv_bytes; + msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR); + msgsize = sizeof(msgstr_t) - sizeof(long int); + + /* Initialize two msgstr_t structures to store respective messages */ + msgstr_t msg1 = {1, "sample message"}; + msgstr_t msg2; + + /* Send a message to the queue with ID = msqid */ + ATF_REQUIRE_EQ(0, msgsnd(msqid, &msg1, msgsize, IPC_NOWAIT)); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE((recv_bytes = msgrcv(msqid, &msg2, \ + msgsize, 0, MSG_NOERROR | IPC_NOWAIT)) != -1); + /* Check the presence of queue ID and returned bytes in audit record */ + snprintf(ipcregex, 60, \ + "msgrcv.*Message IPC,*%d.*return,success,%zd", msqid, recv_bytes); + check_audit(fds, ipcregex, pipefd); +} + +ATF_TC_CLEANUP(msgrcv_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgrcv_failure); +ATF_TC_HEAD(msgrcv_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "msgrcv(2) call"); +} + +ATF_TC_BODY(msgrcv_failure, tc) +{ + const char *regex = "msgrcv.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, msgrcv(-1, NULL, 0, 0, MSG_NOERROR | IPC_NOWAIT)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(msgrcv_failure, tc) +{ + cleanup(); +} + + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, msgget_success); + ATF_TP_ADD_TC(tp, msgget_failure); + ATF_TP_ADD_TC(tp, msgctl_success); + ATF_TP_ADD_TC(tp, msgctl_failure); + ATF_TP_ADD_TC(tp, msgsnd_success); + ATF_TP_ADD_TC(tp, msgsnd_failure); + ATF_TP_ADD_TC(tp, msgrcv_success); + ATF_TP_ADD_TC(tp, msgrcv_failure); + + return (atf_no_error()); +} + From owner-svn-soc-all@freebsd.org Mon May 28 14:21:05 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 917EDEFA307 for ; Mon, 28 May 2018 14:21:05 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 0AA9D7178E for ; Mon, 28 May 2018 14:21:05 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id 5C3101D13B for ; Mon, 28 May 2018 14:21:04 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w4SEL4db034739 for ; Mon, 28 May 2018 14:21:04 GMT (envelope-from aniketp@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w4SEL1D2034609 for svn-soc-all@FreeBSD.org; Mon, 28 May 2018 14:21:01 GMT (envelope-from aniketp@FreeBSD.org) Date: Mon, 28 May 2018 14:21:01 GMT Message-Id: <201805281421.w4SEL1D2034609@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to aniketp@FreeBSD.org using -f From: aniketp@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337256 - soc2018/aniketp/head/tests/sys/audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 May 2018 14:21:05 -0000 Author: aniketp Date: Mon May 28 14:21:00 2018 New Revision: 337256 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337256 Log: Add tests for syscalls for semaphores, shared memory and message queues Modified: soc2018/aniketp/head/tests/sys/audit/Makefile soc2018/aniketp/head/tests/sys/audit/file-attribute-modify.c soc2018/aniketp/head/tests/sys/audit/inter-process.c Modified: soc2018/aniketp/head/tests/sys/audit/Makefile ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/Makefile Sun May 27 16:28:08 2018 (r337255) +++ soc2018/aniketp/head/tests/sys/audit/Makefile Mon May 28 14:21:00 2018 (r337256) @@ -37,28 +37,8 @@ SRCS.inter-process+= inter-process.c SRCS.inter-process+= utils.c -TEST_METADATA.file-create+= timeout="30" -TEST_METADATA.file-create+= required_user="root" -TEST_METADATA.file-delete+= timeout="30" -TEST_METADATA.file-delete+= required_user="root" -TEST_METADATA.file-read+= timeout="30" -TEST_METADATA.file-read+= required_user="root" -TEST_METADATA.file-write+= timeout="30" -TEST_METADATA.file-write+= required_user="root" -TEST_METADATA.file-close+= timeout="30" -TEST_METADATA.file-close+= required_user="root" -TEST_METADATA.file-attribute-access+= timeout="30" -TEST_METADATA.file-attribute-access+= required_user="root" -TEST_METADATA.file-attribute-modify+= timeout="30" -TEST_METADATA.file-attribute-modify+= required_user="root" -TEST_METADATA.exec+= timeout="30" -TEST_METADATA.exec+= required_user="root" -TEST_METADATA.ioctl+= timeout="30" -TEST_METADATA.ioctl+= required_user="root" -TEST_METADATA.network+= timeout="30" -TEST_METADATA.network+= required_user="root" -TEST_METADATA.inter-process+= timeout="30" -TEST_METADATA.inter-process+= required_user="root" +TEST_METADATA+= timeout="30" +TEST_METADATA+= required_user="root" WARNS?= 6 Modified: soc2018/aniketp/head/tests/sys/audit/file-attribute-modify.c ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/file-attribute-modify.c Sun May 27 16:28:08 2018 (r337255) +++ soc2018/aniketp/head/tests/sys/audit/file-attribute-modify.c Mon May 28 14:21:00 2018 (r337256) @@ -701,7 +701,9 @@ ATF_TC_BODY(chflagsat_success, tc) { - atf_tc_expect_fail("chflagsat(2) does not get audited"); + /* BSM conversion requested for unknown event 43209 */ + atf_tc_expect_fail("chflagsat(2) does not get audited in success mode"); + /* File needs to exist to call chflagsat(2) */ ATF_REQUIRE(open(path, O_CREAT, mode) != -1); FILE *pipefd = setup(fds, "fm"); @@ -724,7 +726,9 @@ ATF_TC_BODY(chflagsat_failure, tc) { - atf_tc_expect_fail("chflagsat(2) does not get audited"); + /* BSM conversion requested for unknown event 43209 */ + atf_tc_expect_fail("chflagsat(2) does not get audited in failure mode"); + FILE *pipefd = setup(fds, "fm"); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, chflagsat(AT_FDCWD, errpath, SF_IMMUTABLE, 0)); Modified: soc2018/aniketp/head/tests/sys/audit/inter-process.c ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/inter-process.c Sun May 27 16:28:08 2018 (r337255) +++ soc2018/aniketp/head/tests/sys/audit/inter-process.c Mon May 28 14:21:00 2018 (r337256) @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include @@ -36,15 +38,24 @@ #include "utils.h" struct msgstr { - long int mtype; - char mtext[128]; + long int mtype; + char mtext[128]; }; typedef struct msgstr msgstr_t; +static union semun { + int val; + struct semid_ds *buf; + unsigned short *array; +} arg; + static struct pollfd fds[1]; static struct msqid_ds msgbuff; -static int msqid; +static struct shmid_ds shmbuff; +static struct semid_ds sembuff; +static int msqid, shmid, semid; static char ipcregex[60]; +static unsigned short semvals[40]; static ssize_t msgsize; @@ -62,6 +73,9 @@ /* Check the presence of message queue ID in audit record */ snprintf(ipcregex, 60, "msgget.*return,success,%d", msqid); check_audit(fds, ipcregex, pipefd); + + /* Destroy the message queue with ID = msqid */ + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL)); } ATF_TC_CLEANUP(msgget_success, tc) @@ -91,51 +105,6 @@ } -ATF_TC_WITH_CLEANUP(msgctl_success); -ATF_TC_HEAD(msgctl_success, tc) -{ - atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " - "msgctl(2) call"); -} - -ATF_TC_BODY(msgctl_success, tc) -{ - msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR); - - FILE *pipefd = setup(fds, "ip"); - ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_STAT, &msgbuff)); - /* Check the presence of message queue ID in audit record */ - snprintf(ipcregex, 60, "msgctl.*IPC_STAT.*%d.*return,success", msqid); - check_audit(fds, ipcregex, pipefd); -} - -ATF_TC_CLEANUP(msgctl_success, tc) -{ - cleanup(); -} - - -ATF_TC_WITH_CLEANUP(msgctl_failure); -ATF_TC_HEAD(msgctl_failure, tc) -{ - atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " - "msgctl(2) call"); -} - -ATF_TC_BODY(msgctl_failure, tc) -{ - const char *regex = "msgctl.*return,failure : Invalid argument"; - FILE *pipefd = setup(fds, "ip"); - ATF_REQUIRE_EQ(-1, msgctl(-1, IPC_STAT, &msgbuff)); - check_audit(fds, regex, pipefd); -} - -ATF_TC_CLEANUP(msgctl_failure, tc) -{ - cleanup(); -} - - ATF_TC_WITH_CLEANUP(msgsnd_success); ATF_TC_HEAD(msgsnd_success, tc) { @@ -156,6 +125,9 @@ FILE *pipefd = setup(fds, "ip"); ATF_REQUIRE_EQ(0, msgsnd(msqid, &msg1, msgsize, IPC_NOWAIT)); check_audit(fds, ipcregex, pipefd); + + /* Destroy the message queue with ID = msqid */ + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL)); } ATF_TC_CLEANUP(msgsnd_success, tc) @@ -212,6 +184,9 @@ snprintf(ipcregex, 60, \ "msgrcv.*Message IPC,*%d.*return,success,%zd", msqid, recv_bytes); check_audit(fds, ipcregex, pipefd); + + /* Destroy the message queue with ID = msqid */ + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL)); } ATF_TC_CLEANUP(msgrcv_success, tc) @@ -241,16 +216,1166 @@ } -ATF_TP_ADD_TCS(tp) +ATF_TC_WITH_CLEANUP(msgctl_rmid_success); +ATF_TC_HEAD(msgctl_rmid_success, tc) { - ATF_TP_ADD_TC(tp, msgget_success); - ATF_TP_ADD_TC(tp, msgget_failure); - ATF_TP_ADD_TC(tp, msgctl_success); - ATF_TP_ADD_TC(tp, msgctl_failure); - ATF_TP_ADD_TC(tp, msgsnd_success); - ATF_TP_ADD_TC(tp, msgsnd_failure); - ATF_TP_ADD_TC(tp, msgrcv_success); - ATF_TP_ADD_TC(tp, msgrcv_failure); + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "msgctl(2) call for IPC_RMID command"); +} + +ATF_TC_BODY(msgctl_rmid_success, tc) +{ + msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL)); + /* Check the presence of queue ID and IPC_RMID in audit record */ + snprintf(ipcregex, 60, "msgctl.*IPC_RMID.*%d.*return,success", msqid); + check_audit(fds, ipcregex, pipefd); +} + +ATF_TC_CLEANUP(msgctl_rmid_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgctl_rmid_failure); +ATF_TC_HEAD(msgctl_rmid_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "msgctl(2) call for IPC_RMID command"); +} + +ATF_TC_BODY(msgctl_rmid_failure, tc) +{ + const char *regex = "msgctl.*IPC_RMID.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, msgctl(-1, IPC_RMID, NULL)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(msgctl_rmid_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgctl_stat_success); +ATF_TC_HEAD(msgctl_stat_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "msgctl(2) call for IPC_STAT command"); +} + +ATF_TC_BODY(msgctl_stat_success, tc) +{ + msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_STAT, &msgbuff)); + /* Check the presence of queue ID and IPC_STAT in audit record */ + snprintf(ipcregex, 60, "msgctl.*IPC_STAT.*%d.*return,success", msqid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the message queue with ID = msqid */ + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(msgctl_stat_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgctl_stat_failure); +ATF_TC_HEAD(msgctl_stat_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "msgctl(2) call for IPC_STAT command"); +} + +ATF_TC_BODY(msgctl_stat_failure, tc) +{ + const char *regex = "msgctl.*IPC_STAT.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, msgctl(-1, IPC_STAT, &msgbuff)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(msgctl_stat_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgctl_set_success); +ATF_TC_HEAD(msgctl_set_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "msgctl(2) call for IPC_SET command"); +} + +ATF_TC_BODY(msgctl_set_success, tc) +{ + msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR); + /* Fill up the msgbuff structure to be used with IPC_SET */ + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_STAT, &msgbuff)); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_SET, &msgbuff)); + /* Check the presence of message queue ID in audit record */ + snprintf(ipcregex, 60, "msgctl.*IPC_SET.*%d.*return,success", msqid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the message queue with ID = msqid */ + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(msgctl_set_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgctl_set_failure); +ATF_TC_HEAD(msgctl_set_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "msgctl(2) call for IPC_SET command"); +} + +ATF_TC_BODY(msgctl_set_failure, tc) +{ + const char *regex = "msgctl.*IPC_SET.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, msgctl(-1, IPC_SET, &msgbuff)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(msgctl_set_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(msgctl_illegal_command); +ATF_TC_HEAD(msgctl_illegal_command, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "msgctl(2) call for illegal cmd value"); +} + +ATF_TC_BODY(msgctl_illegal_command, tc) +{ + msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR); + + const char *regex = "msgctl.*illegal command.*failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, msgctl(msqid, -1, &msgbuff)); + check_audit(fds, regex, pipefd); + + /* Destroy the message queue with ID = msqid */ + ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(msgctl_illegal_command, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmget_success); +ATF_TC_HEAD(shmget_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "shmget(2) call"); +} + +ATF_TC_BODY(shmget_success, tc) +{ + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE((shmid = shmget(IPC_PRIVATE, 10, IPC_CREAT | S_IRUSR)) != -1); + /* Check the presence of message queue ID in audit record */ + snprintf(ipcregex, 60, "shmget.*return,success,%d", shmid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the shared memory with ID = shmid */ + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(shmget_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmget_failure); +ATF_TC_HEAD(shmget_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shmget(2) call"); +} + +ATF_TC_BODY(shmget_failure, tc) +{ + const char *regex = "shmget.*return,failure : No such file or directory"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, shmget((key_t)(-1), 0, 0)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shmget_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmat_success); +ATF_TC_HEAD(shmat_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "shmat(2) call"); +} + +ATF_TC_BODY(shmat_success, tc) +{ + void *addr; + shmid = shmget(IPC_PRIVATE, 10, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE((int)(addr = shmat(shmid, NULL, 0)) != -1); + /* Check the presence of shared memory ID and process address in record */ + snprintf(ipcregex, 60, "shmat.*Shared Memory " + "IPC.*%d.*return,success,%d", shmid, (int)addr); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the shared memory with ID = shmid */ + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(shmat_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmat_failure); +ATF_TC_HEAD(shmat_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shmat(2) call"); +} + +ATF_TC_BODY(shmat_failure, tc) +{ + const char *regex = "shmat.*Shared Memory IPC.*return,failure"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, (int)shmat(-1, NULL, 0)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shmat_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmdt_success); +ATF_TC_HEAD(shmdt_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "shmdt(2) call"); +} + +ATF_TC_BODY(shmdt_success, tc) +{ + void *addr; + const char *regex = "shmdt.*return,success"; + shmid = shmget(IPC_PRIVATE, 10, IPC_CREAT | S_IRUSR); + + /* Attach the shared memory to calling process's address space */ + ATF_REQUIRE((int)(addr = shmat(shmid, NULL, 0)) != -1); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, shmdt(addr)); + check_audit(fds, regex, pipefd); + + /* Destroy the shared memory with ID = shmid */ + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(shmdt_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmdt_failure); +ATF_TC_HEAD(shmdt_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shmdt(2) call"); +} + +ATF_TC_BODY(shmdt_failure, tc) +{ + const char *regex = "shmdt.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, shmdt(NULL)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shmdt_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmctl_rmid_success); +ATF_TC_HEAD(shmctl_rmid_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "shmctl(2) call for IPC_RMID command"); +} + +ATF_TC_BODY(shmctl_rmid_success, tc) +{ + shmid = shmget(IPC_PRIVATE, 10, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL)); + /* Check the presence of shmid and IPC_RMID in audit record */ + snprintf(ipcregex, 60, "shmctl.*IPC_RMID.*%d.*return,success", shmid); + check_audit(fds, ipcregex, pipefd); +} + +ATF_TC_CLEANUP(shmctl_rmid_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmctl_rmid_failure); +ATF_TC_HEAD(shmctl_rmid_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shmctl(2) call for IPC_RMID command"); +} + +ATF_TC_BODY(shmctl_rmid_failure, tc) +{ + const char *regex = "shmctl.*IPC_RMID.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, shmctl(-1, IPC_RMID, NULL)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shmctl_rmid_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmctl_stat_success); +ATF_TC_HEAD(shmctl_stat_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "shmctl(2) call for IPC_STAT command"); +} + +ATF_TC_BODY(shmctl_stat_success, tc) +{ + shmid = shmget(IPC_PRIVATE, 10, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_STAT, &shmbuff)); + /* Check the presence of shared memory ID and IPC_STAT in audit record */ + snprintf(ipcregex, 60, "shmctl.*IPC_STAT.*%d.*return,success", shmid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the shared memory with ID = shmid */ + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(shmctl_stat_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmctl_stat_failure); +ATF_TC_HEAD(shmctl_stat_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shmctl(2) call for IPC_STAT command"); +} + +ATF_TC_BODY(shmctl_stat_failure, tc) +{ + const char *regex = "shmctl.*IPC_STAT.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, shmctl(-1, IPC_STAT, &shmbuff)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shmctl_stat_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmctl_set_success); +ATF_TC_HEAD(shmctl_set_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "shmctl(2) call for IPC_SET command"); +} + +ATF_TC_BODY(shmctl_set_success, tc) +{ + shmid = shmget(IPC_PRIVATE, 10, IPC_CREAT | S_IRUSR); + /* Fill up the shmbuff structure to be used with IPC_SET */ + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_STAT, &shmbuff)); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_SET, &shmbuff)); + /* Check the presence of shared memory ID in audit record */ + snprintf(ipcregex, 60, "shmctl.*IPC_SET.*%d.*return,success", msqid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the shared memory with ID = shmid */ + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(shmctl_set_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmctl_set_failure); +ATF_TC_HEAD(shmctl_set_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shmctl(2) call for IPC_SET command"); +} + +ATF_TC_BODY(shmctl_set_failure, tc) +{ + const char *regex = "shmctl.*IPC_SET.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, shmctl(-1, IPC_SET, &shmbuff)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shmctl_set_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shmctl_illegal_command); +ATF_TC_HEAD(shmctl_illegal_command, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shmctl(2) call for illegal cmd value"); +} + +ATF_TC_BODY(shmctl_illegal_command, tc) +{ + shmid = shmget(IPC_PRIVATE, 10, IPC_CREAT | S_IRUSR); + + const char *regex = "shmctl.*illegal command.*failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, shmctl(shmid, -1, &shmbuff)); + check_audit(fds, regex, pipefd); + + /* Destroy the shared memory with ID = shmid */ + ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL)); +} + +ATF_TC_CLEANUP(shmctl_illegal_command, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semget_success); +ATF_TC_HEAD(semget_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "semget(2) call"); +} + +ATF_TC_BODY(semget_success, tc) +{ + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE((semid = semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1); + /* Check the presence of semaphore set ID in audit record */ + snprintf(ipcregex, 60, "semget.*return,success,%d", semid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the semaphore set with ID = semid */ + ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID)); +} + +ATF_TC_CLEANUP(semget_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semget_failure); +ATF_TC_HEAD(semget_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "semget(2) call"); +} + +ATF_TC_BODY(semget_failure, tc) +{ + const char *regex = "semget.*return,failure : No such file or directory"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, semget((key_t)(-1), 0, 0)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(semget_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semop_success); +ATF_TC_HEAD(semop_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "semop(2) call"); +} + +ATF_TC_BODY(semop_success, tc) +{ + semid = semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR); + + /* Initialize a sembuf structure to operate on semaphore set */ + struct sembuf sop[1] = {{0, 1, 0}}; + /* Check the presence of semaphore set ID in audit record */ + snprintf(ipcregex, 60, "semop.*Semaphore IPC.*%d.*return,success", semid); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, semop(semid, sop, 1)); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the semaphore set with ID = semid */ + ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID)); +} + +ATF_TC_CLEANUP(semop_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semop_failure); +ATF_TC_HEAD(semop_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "semop(2) call"); +} + +ATF_TC_BODY(semop_failure, tc) +{ + const char *regex = "semop.*0xffff.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, semop(-1, NULL, 0)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(semop_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_getval_success); +ATF_TC_HEAD(semctl_getval_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "semctl(2) call for GETVAL command"); +} + +ATF_TC_BODY(semctl_getval_success, tc) +{ + semid = semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, semctl(semid, 0, GETVAL, arg)); + /* Check the presence of semaphore ID and GETVAL in audit record */ + snprintf(ipcregex, 60, "semctl.*GETVAL.*%d.*return,success", semid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the semaphore set with ID = semid */ + ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID)); +} + +ATF_TC_CLEANUP(semctl_getval_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_getval_failure); +ATF_TC_HEAD(semctl_getval_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "semctl(2) call for GETVAL command"); +} + +ATF_TC_BODY(semctl_getval_failure, tc) +{ + const char *regex = "semctl.*GETVAL.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, semctl(-1, 0, GETVAL, arg)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(semctl_getval_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_setval_success); +ATF_TC_HEAD(semctl_setval_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "semctl(2) call for SETVAL command"); +} + +ATF_TC_BODY(semctl_setval_success, tc) +{ + semid = semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR | S_IWUSR); + arg.val = 1; + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, semctl(semid, 0, SETVAL, arg)); + /* Check the presence of semaphore ID and SETVAL in audit record */ + snprintf(ipcregex, 60, "semctl.*SETVAL.*%d.*return,success", semid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the semaphore set with ID = semid */ + ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID)); +} + +ATF_TC_CLEANUP(semctl_setval_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_setval_failure); +ATF_TC_HEAD(semctl_setval_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "semctl(2) call for SETVAL command"); +} + +ATF_TC_BODY(semctl_setval_failure, tc) +{ + const char *regex = "semctl.*SETVAL.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, semctl(-1, 0, SETVAL, arg)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(semctl_setval_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_getpid_success); +ATF_TC_HEAD(semctl_getpid_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "semctl(2) call for GETPID command"); +} + +ATF_TC_BODY(semctl_getpid_success, tc) +{ + semid = semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, semctl(semid, 0, GETPID, arg)); + /* Check the presence of semaphore ID and GETVAL in audit record */ + snprintf(ipcregex, 60, "semctl.*GETPID.*%d.*return,success", semid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the semaphore set with ID = semid */ + ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID)); +} + +ATF_TC_CLEANUP(semctl_getpid_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_getpid_failure); +ATF_TC_HEAD(semctl_getpid_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "semctl(2) call for GETPID command"); +} + +ATF_TC_BODY(semctl_getpid_failure, tc) +{ + const char *regex = "semctl.*GETPID.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, semctl(-1, 0, GETPID, arg)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(semctl_getpid_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_getncnt_success); +ATF_TC_HEAD(semctl_getncnt_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "semctl(2) call for GETNCNT command"); +} + +ATF_TC_BODY(semctl_getncnt_success, tc) +{ + semid = semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, semctl(semid, 0, GETNCNT, arg)); + /* Check the presence of semaphore ID and GETNCNT in audit record */ + snprintf(ipcregex, 60, "semctl.*GETNCNT.*%d.*return,success", semid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the semaphore set with ID = semid */ + ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID)); +} + +ATF_TC_CLEANUP(semctl_getncnt_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_getncnt_failure); +ATF_TC_HEAD(semctl_getncnt_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "semctl(2) call for GETNCNT command"); +} + +ATF_TC_BODY(semctl_getncnt_failure, tc) +{ + const char *regex = "semctl.*GETNCNT.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, semctl(-1, 0, GETNCNT, arg)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(semctl_getncnt_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_getzcnt_success); +ATF_TC_HEAD(semctl_getzcnt_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "semctl(2) call for GETZCNT command"); +} + +ATF_TC_BODY(semctl_getzcnt_success, tc) +{ + semid = semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR); + + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, semctl(semid, 0, GETZCNT, arg)); + /* Check the presence of semaphore ID and GETZCNT in audit record */ + snprintf(ipcregex, 60, "semctl.*GETZCNT.*%d.*return,success", semid); + check_audit(fds, ipcregex, pipefd); + + /* Destroy the semaphore set with ID = semid */ + ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID)); +} + +ATF_TC_CLEANUP(semctl_getzcnt_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(semctl_getzcnt_failure); +ATF_TC_HEAD(semctl_getzcnt_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "semctl(2) call for GETZCNT command"); +} + *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-soc-all@freebsd.org Mon May 28 19:59:57 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 24DBAF7E8D3 for ; Mon, 28 May 2018 19:59:57 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id B44B48059A for ; Mon, 28 May 2018 19:59:56 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id 02E8920975 for ; Mon, 28 May 2018 19:59:56 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w4SJxte0083459 for ; Mon, 28 May 2018 19:59:55 GMT (envelope-from aniketp@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w4SJxtp2083449 for svn-soc-all@FreeBSD.org; Mon, 28 May 2018 19:59:55 GMT (envelope-from aniketp@FreeBSD.org) Date: Mon, 28 May 2018 19:59:55 GMT Message-Id: <201805281959.w4SJxtp2083449@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to aniketp@FreeBSD.org using -f From: aniketp@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337257 - soc2018/aniketp/head/tests/sys/audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 May 2018 19:59:57 -0000 Author: aniketp Date: Mon May 28 19:59:53 2018 New Revision: 337257 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337257 Log: Finish tests fort all auditable IPC system calls Modified: soc2018/aniketp/head/tests/sys/audit/inter-process.c Modified: soc2018/aniketp/head/tests/sys/audit/inter-process.c ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/inter-process.c Mon May 28 14:21:00 2018 (r337256) +++ soc2018/aniketp/head/tests/sys/audit/inter-process.c Mon May 28 19:59:53 2018 (r337257) @@ -28,35 +28,42 @@ #include #include +#include #include #include #include #include #include +#include +#include +#include +#include #include "utils.h" struct msgstr { - long int mtype; - char mtext[128]; + long int mtype; + char mtext[128]; }; typedef struct msgstr msgstr_t; static union semun { - int val; - struct semid_ds *buf; - unsigned short *array; + int val; + struct semid_ds *buf; + unsigned short *array; } arg; +static int msqid, shmid, semid; +static ssize_t msgsize; +static mode_t mode = 0600; static struct pollfd fds[1]; static struct msqid_ds msgbuff; static struct shmid_ds shmbuff; static struct semid_ds sembuff; -static int msqid, shmid, semid; static char ipcregex[60]; +static char path[20] = "/fileforaudit"; static unsigned short semvals[40]; -static ssize_t msgsize; ATF_TC_WITH_CLEANUP(msgget_success); @@ -445,6 +452,7 @@ FILE *pipefd = setup(fds, "ip"); ATF_REQUIRE((int)(addr = shmat(shmid, NULL, 0)) != -1); + /* Check the presence of shared memory ID and process address in record */ snprintf(ipcregex, 60, "shmat.*Shared Memory " "IPC.*%d.*return,success,%d", shmid, (int)addr); @@ -1318,6 +1326,193 @@ } +ATF_TC_WITH_CLEANUP(shm_open_success); +ATF_TC_HEAD(shm_open_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "shm_open(2) call"); +} + +ATF_TC_BODY(shm_open_success, tc) +{ + /* Build an absolute path to a file in the test-case directory */ + char dirpath[50]; + ATF_REQUIRE(getcwd(dirpath, sizeof(dirpath)) != NULL); + ATF_REQUIRE(strncat(dirpath, path, sizeof(dirpath) - 1) != NULL); + + const char *regex = "shm_open.*fileforaudit.*return,success"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE(shm_open(dirpath, O_CREAT | O_TRUNC | O_RDWR, 0600) != -1); + check_audit(fds, regex, pipefd); + ATF_REQUIRE_EQ(0, shm_unlink(dirpath)); +} + +ATF_TC_CLEANUP(shm_open_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shm_open_failure); +ATF_TC_HEAD(shm_open_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shm_open(2) call"); +} + +ATF_TC_BODY(shm_open_failure, tc) +{ + const char *regex = "shm_open.*fileforaudit.*return,failure"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, shm_open(path, O_TRUNC | O_RDWR, 0600)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shm_open_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shm_unlink_success); +ATF_TC_HEAD(shm_unlink_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "shm_unlink(2) call"); +} + +ATF_TC_BODY(shm_unlink_success, tc) +{ + /* Build an absolute path to a file in the test-case directory */ + char dirpath[50]; + ATF_REQUIRE(getcwd(dirpath, sizeof(dirpath)) != NULL); + ATF_REQUIRE(strncat(dirpath, path, sizeof(dirpath) - 1) != NULL); + ATF_REQUIRE(shm_open(dirpath, O_CREAT | O_TRUNC | O_RDWR, 0600) != -1); + + const char *regex = "shm_unlink.*fileforaudit.*return,success"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, shm_unlink(dirpath)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shm_unlink_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(shm_unlink_failure); +ATF_TC_HEAD(shm_unlink_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "shm_unlink(2) call"); +} + +ATF_TC_BODY(shm_unlink_failure, tc) +{ + const char *regex = "shm_unlink.*fileforaudit.*return,failure"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, shm_unlink(path)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(shm_unlink_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(pipe_success); +ATF_TC_HEAD(pipe_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "pipe(2) call"); +} + +ATF_TC_BODY(pipe_success, tc) +{ + int filedesc[2]; + ATF_REQUIRE((filedesc[0] = open(path, O_CREAT, mode)) != -1); + ATF_REQUIRE((filedesc[1] = open(path, O_CREAT, mode)) != -1); + + pid_t pid = getpid(); + snprintf(ipcregex, 60, "pipe.*%d.*return,success", pid); + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(0, pipe(filedesc)); + check_audit(fds, ipcregex, pipefd); +} + +ATF_TC_CLEANUP(pipe_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(pipe_failure); +ATF_TC_HEAD(pipe_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "pipe(2) call"); +} + +ATF_TC_BODY(pipe_failure, tc) +{ + const char *regex = "pipe.*return,failure : Bad address"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, pipe((int *)-1)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(pipe_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(posix_openpt_success); +ATF_TC_HEAD(posix_openpt_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "posix_openpt(2) call"); +} + +ATF_TC_BODY(posix_openpt_success, tc) +{ + int filedesc; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE((filedesc = posix_openpt(O_RDWR)) != -1); + /* Check for the presence of filedesc in the audit record */ + snprintf(ipcregex, 60, "posix_openpt.*return,success,%d", filedesc); + check_audit(fds, ipcregex, pipefd); +} + +ATF_TC_CLEANUP(posix_openpt_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(posix_openpt_failure); +ATF_TC_HEAD(posix_openpt_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "posix_openpt(2) call"); +} + +ATF_TC_BODY(posix_openpt_failure, tc) +{ + const char *regex = "posix_openpt.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, "ip"); + ATF_REQUIRE_EQ(-1, posix_openpt(-1)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(posix_openpt_failure, tc) +{ + cleanup(); +} + + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, msgget_success); @@ -1377,6 +1572,16 @@ ATF_TP_ADD_TC(tp, semctl_rmid_failure); ATF_TP_ADD_TC(tp, semctl_illegal_command); + ATF_TP_ADD_TC(tp, shm_open_success); + ATF_TP_ADD_TC(tp, shm_open_failure); + ATF_TP_ADD_TC(tp, shm_unlink_success); + ATF_TP_ADD_TC(tp, shm_unlink_failure); + + ATF_TP_ADD_TC(tp, pipe_success); + ATF_TP_ADD_TC(tp, pipe_failure); + ATF_TP_ADD_TC(tp, posix_openpt_success); + ATF_TP_ADD_TC(tp, posix_openpt_failure); + return (atf_no_error()); } From owner-svn-soc-all@freebsd.org Mon May 28 20:05:55 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6263FF7F359 for ; Mon, 28 May 2018 20:05:55 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id A663081043 for ; Mon, 28 May 2018 20:05:54 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id D083520B01 for ; Mon, 28 May 2018 20:05:53 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w4SK5rSC018712 for ; Mon, 28 May 2018 20:05:53 GMT (envelope-from sduo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w4SK5qVE018660 for svn-soc-all@FreeBSD.org; Mon, 28 May 2018 20:05:52 GMT (envelope-from sduo@FreeBSD.org) Date: Mon, 28 May 2018 20:05:52 GMT Message-Id: <201805282005.w4SK5qVE018660@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to sduo@FreeBSD.org using -f From: sduo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337258 - in soc2018/sduo/head/sys: dev/vale_vlan modules/vale_vlan net MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 May 2018 20:05:55 -0000 Author: sduo Date: Mon May 28 20:05:50 2018 New Revision: 337258 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337258 Log: VLAN can now be created, and modified, through system calls. sys/net/vale_vlan_user.h contains the data structures passed between user and kernel space. Added: soc2018/sduo/head/sys/net/vale_vlan_user.h Modified: soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan_freebsd.c soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan_kern.h soc2018/sduo/head/sys/modules/vale_vlan/Makefile Modified: soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c ============================================================================== --- soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c Mon May 28 19:59:53 2018 (r337257) +++ soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c Mon May 28 20:05:50 2018 (r337258) @@ -146,8 +146,6 @@ -#define MAX_VLAN_ID 4096 - struct vlan_lookup_data { uint32_t trunk_port; uint16_t port_to_vlan[NM_BDG_MAXPORTS]; @@ -156,6 +154,95 @@ +/* must be called with GLOBAL_LOCK */ +static void +initialize_lookup_data(struct vlan_lookup_data *l_data) +{ + int i; + + l_data->trunk_port = NM_BDG_NOPORT; + for (i = 0; i < NM_BDG_MAXPORTS; ++i) { + l_data->port_to_vlan[i] = 0x000; + } + for (i = 0; i < MAX_VLAN_ID; ++i) { + l_data->vlan_to_port[i] = NM_BDG_NOPORT; + } +} + + + +struct port_elem { + struct port port_desc; + vv_list_entry(port_elem) list; +}; + + + +/* for each vlan conf there is only one 'modified bridge', + * therefore we can store a lookup data structure directly inside + * the struct which describes the configuration + */ +struct vale_vlan_conf { + struct vlan_lookup_data l_data; + char conf_name[NETMAP_REQ_IFNAMSIZ]; + void *vlan_bdg_auth_tokens[MAX_VLAN_ID]; + void *mod_bdg_auth_token; + uint32_t number_of_ports[MAX_VLAN_ID]; + vv_list_declare(list_head, port_elem) port_list; +}; + + + +/* there is one 'vlan_id bridge' with a specific vlan_id per configuration, + * therefore we only need the configuration name and vlan_id to create + * a unique bridge name + */ +static inline void +get_vlan_bdg_name(char *bridge_name, size_t len, const char *conf_name, + uint16_t vlan_id) +{ + + snprintf(bridge_name, len, "valeV%d%s:", vlan_id, conf_name); +} + + + +static inline void +get_ap_name(char *port_name, size_t len, const char *conf_name, + uint16_t vlan_id) +{ + + snprintf(port_name, len, "%sAP%d", conf_name, vlan_id); +} + + + +/* there is one 'modified bridge' per configuration, therefore we + * only need the configuration name to create a unique bridge name + */ +static inline void +get_modified_bdg_name(char *bridge_name, size_t len, const char *conf_name) +{ + + snprintf(bridge_name, len, "valeV%sTP:", conf_name); +} + + + +static void +initialize_conf(struct vale_vlan_conf *conf) +{ + + initialize_lookup_data(&(conf->l_data)); + conf->conf_name[0] = '\0'; + bzero(conf->vlan_bdg_auth_tokens, sizeof(conf->vlan_bdg_auth_tokens)); + conf->mod_bdg_auth_token = NULL; + bzero(conf->number_of_ports, sizeof(conf->number_of_ports)); + vv_list_head_init(&conf->port_list); +} + + + static uint32_t vlan_lookup(struct nm_bdg_fwd *ft, uint8_t *dst_ring, struct netmap_vp_adapter *vpna, void *lookup_data) @@ -200,19 +287,240 @@ -/* must be called with GLOBAL_LOCK */ -static void -initialize_lookup_data(struct vlan_lookup_data *l_data) +static inline int +modify_bdg(struct vale_vlan_conf *conf, const char *bdg_name) +{ + + D("Trying to modify bdg '%s' for conf '%s'", bdg_name, conf->conf_name); + return netmap_bdg_regops(bdg_name, &vlan_ops, &conf->l_data, + conf->mod_bdg_auth_token); +} + + + +static inline int +reset_bdg(struct vale_vlan_conf *conf, const char *bdg_name) +{ + + D("Trying to reset bdg '%s' for conf '%s'", bdg_name, conf->conf_name); + return netmap_bdg_regops(bdg_name, NULL, NULL, + conf->mod_bdg_auth_token); +} + + + +#define MAX_VLAN_CONFS 4 +/* used to access currently active vlan confs */ +static uint16_t vlan_conf_index[MAX_VLAN_CONFS]; +static struct vale_vlan_conf vlan_confs[MAX_VLAN_CONFS]; +static uint16_t active_vlan_conf = 0; + + + +/* Fails if conf alredy exists or we're out of space */ +static int +vale_vlan_create_conf(const char *conf_name, uint16_t *conf_index) { + uint16_t free_conf = MAX_VLAN_CONFS; + char modified_bdg_name[IF_NAMESIZE]; + struct vale_vlan_conf *conf = NULL; + void *auth_token = NULL; + int ret = 0; int i; - l_data->trunk_port = NM_BDG_NOPORT; - for (i = 0; i < NM_BDG_MAXPORTS; ++i) { - l_data->port_to_vlan[i] = 0x000; + if (active_vlan_conf == MAX_VLAN_CONFS) { + nm_prinf("vale_vlan: maximum number of" + "configurations reached\n"); + return ENOMEM; + } + + for (i = 0; i < MAX_VLAN_CONFS; ++i) { + if (strcmp(vlan_confs[i].conf_name, conf_name) == 0) { + nm_prinf("vale_vlan: a configuration named" + "'%s' alredy exists\n", conf_name); + return EEXIST; + } else if (vlan_confs[i].conf_name[0] == '\0') { + /* a free slot is represented by an empty conf_name */ + free_conf = i; + } + } + + /* create bridge in exclusive mode */ + get_modified_bdg_name(modified_bdg_name, sizeof(modified_bdg_name), + conf_name); + auth_token = netmap_bdg_create(modified_bdg_name, &ret); + if (auth_token == NULL || ret != 0) { + D("Error %d during bridge '%s' creation", + ret, modified_bdg_name); + return ret; + } + + vlan_conf_index[active_vlan_conf++] = free_conf; + conf = &vlan_confs[free_conf]; + initialize_conf(conf); + strncpy(conf->conf_name, conf_name, sizeof(conf->conf_name)); + conf->mod_bdg_auth_token = auth_token; + *conf_index = free_conf; + + ret = modify_bdg(conf, modified_bdg_name); + if (ret) { + int ret2; + D("Error %d during bridge '%s' regops()", + ret, modified_bdg_name); + ret2 = netmap_bdg_destroy(modified_bdg_name, + conf->mod_bdg_auth_token); + if (ret2) { + /* cannot happen */ + D("Error %d during bridge '%s' destroy(), " + "this should never happen", + ret2, modified_bdg_name); + } + initialize_conf(conf); + --active_vlan_conf; + return ret; + } + vv_try_module_get(); + + nm_prinf("vale_vlan: successfully created " + "configuration '%s'\n", conf_name); + return 0; +} + + + +/* Fails if the conf doesn't exist + * + * must be called with GLOBAL_LOCK + */ +static int +vale_vlan_select_conf(const char *conf_name, uint16_t *conf_index) +{ + int i; + + for (i = 0; i < active_vlan_conf; ++i) { + int index = vlan_conf_index[i]; + if (strcmp(vlan_confs[index].conf_name, conf_name) == 0) { + *conf_index = index; + nm_prinf("vale_vlan: successfully selected " + "configuration '%s'\n", conf_name); + return 0; + } + } + + nm_prinf("vale_vlan: a configuration named '%s' doesn't exist\n", + conf_name); + return ENXIO; +} + + + +/* Fails if the conf doesn't exist or the modified bridge isn't empty + * + * must be called with GLOBAL_LOCK + */ +static int +vale_vlan_delete_conf(const char *conf_name) +{ + uint16_t conf_index = MAX_VLAN_CONFS; + char modified_bdg_name[IF_NAMESIZE]; + struct vale_vlan_conf *conf = NULL; + uint16_t i; + int ret; + + for (i = 0; i < active_vlan_conf; ++i) { + int index = vlan_conf_index[i]; + if (strcmp(vlan_confs[index].conf_name, conf_name) == 0) { + conf = &vlan_confs[index]; + conf_index = i; + break; + } + } + + if (!conf || i == active_vlan_conf) { + /* conf doesn't exist */ + return ENXIO; } + + /* redundant check */ for (i = 0; i < MAX_VLAN_ID; ++i) { - l_data->vlan_to_port[i] = NM_BDG_NOPORT; + if (conf->number_of_ports[i] != 0) { + D("conf->number_of_ports[%d] = %d", + i, conf->number_of_ports[i]); + return EBUSY; + } + } + + get_modified_bdg_name(modified_bdg_name, sizeof(modified_bdg_name), + conf_name); + ret = netmap_bdg_destroy(modified_bdg_name, + conf->mod_bdg_auth_token); + if (ret) { + /* cannot happen (?) */ + D("Error %d during bridge '%s' destroy(), SHOULD NOT HAPPEN", + ret, modified_bdg_name); + return ret; } + + conf->conf_name[0] = '\0'; /* marks conf slot as free */ + vlan_conf_index[conf_index] = vlan_conf_index[--active_vlan_conf]; + vv_module_put(); + return 0; +} + + +/* returns 0 if conf_index isn't a possible index or if + * the conf entry isn't in use + * + * must be called with GLOBAL_LOCK + */ +static int +does_conf_exist(int conf_index) +{ + + if (conf_index < 0 || conf_index >= MAX_VLAN_CONFS) { + return 0; + } + return vlan_confs[conf_index].conf_name[0] != '\0'; +} + + + +#define NM_API_VERSION 12 + + + +static void * +modify_trunk_port(void *private_data, void *callback_data, int *error) +{ + struct vlan_lookup_data *l_data = private_data; + uint32_t *new_trunk_port = callback_data; + + l_data->trunk_port = *new_trunk_port; + *error = 0; + return l_data; +} + + + +struct mod_access_port { + uint32_t old_port_index; + uint32_t new_port_index; + uint16_t old_vlan_id; + uint16_t new_vlan_id; +}; + + + +static void * +modify_access_port(void *private_data, void *callback_data, int *error) +{ + struct vlan_lookup_data *l_data = private_data; + struct mod_access_port *mod = callback_data; + + l_data->port_to_vlan[mod->old_port_index] = mod->new_vlan_id; + l_data->vlan_to_port[mod->old_vlan_id] = mod->new_port_index; + *error = 0; + return l_data; } @@ -227,7 +535,7 @@ D("Trying to create port '%s'", name); bzero(&hdr, sizeof(hdr)); - hdr.nr_version = NETMAP_API; + hdr.nr_version = NM_API_VERSION; hdr.nr_reqtype = NETMAP_REQ_VALE_NEWIF; strncpy(hdr.nr_name, name, sizeof(hdr.nr_name)); @@ -264,6 +572,54 @@ static int +attach_port_list(struct vale_vlan_conf *conf, const char *bdg_name, + const char *port_name, uint8_t port_type, uint16_t vlan_id) +{ + struct port_elem *p_elem = NULL; + + p_elem = vv_malloc(sizeof(struct port_elem)); + if (!p_elem) { + return EFAULT; + } + + vv_list_elem_init(p_elem, list); + p_elem->port_desc.vlan_id = vlan_id; + p_elem->port_desc.port_type = port_type; + snprintf(p_elem->port_desc.bdg_name, + sizeof(p_elem->port_desc.bdg_name), "%s", bdg_name); + snprintf(p_elem->port_desc.port_name, + sizeof(p_elem->port_desc.port_name), "%s", port_name); + vv_list_insert_head(&conf->port_list, p_elem, list); + return 0; +} + + + +static int +detach_port_list(struct vale_vlan_conf *conf, const char *port_name) +{ + struct port_elem *cursor = NULL; + struct port_elem *next = NULL; + + vv_list_foreach_safe(cursor, &conf->port_list, list, next) { + if (strcmp(cursor->port_desc.port_name, port_name) == 0) { + vv_list_remove(cursor, list); + vv_free(cursor); + return 0; + } + } + + return ENXIO; +} + + + +static int detach_trunk_port(struct vale_vlan_conf *, const char *, uint16_t); +static int detach_vlan_port(struct vale_vlan_conf *, const char *, uint16_t); + + + +static int attach_port(const char *bdg_name, const char *port_name, void *auth_token, uint32_t *port_index) { @@ -276,7 +632,7 @@ nmr_att.reg.nr_mode = NR_REG_ALL_NIC; bzero(&hdr, sizeof(hdr)); - hdr.nr_version = NETMAP_API; + hdr.nr_version = NM_API_VERSION; hdr.nr_reqtype = NETMAP_REQ_VALE_ATTACH; hdr.nr_body = (uint64_t)&nmr_att; snprintf(hdr.nr_name, sizeof(hdr.nr_name), "%s%s", bdg_name, port_name); @@ -286,9 +642,7 @@ vv_try_module_get(); } - if (port_index != NULL) { - *port_index = nmr_att.port_index; - } + *port_index = nmr_att.port_index; return ret; } @@ -306,7 +660,7 @@ bzero(&nmr_det, sizeof(nmr_det)); bzero(&hdr, sizeof(hdr)); - hdr.nr_version = NETMAP_API; + hdr.nr_version = NM_API_VERSION; hdr.nr_reqtype = NETMAP_REQ_VALE_DETACH; hdr.nr_body = (uint64_t)&nmr_det; snprintf(hdr.nr_name, sizeof(hdr.nr_name), "%s%s", bdg_name, port_name); @@ -315,214 +669,707 @@ if (ret == 0) { vv_module_put(); } - if (port_index != NULL) { - *port_index = nmr_det.port_index; + *port_index = nmr_det.port_index; + return ret; +} + + + +static int +attach_vlan_port(struct vale_vlan_conf *conf, const char *port_name, + uint16_t vlan_id) +{ + void *vlan_bdg_auth_token = conf->vlan_bdg_auth_tokens[vlan_id]; + uint32_t port_index = NM_BDG_NOPORT; + char modified_bdg_name[IF_NAMESIZE]; + char vlan_bdg_name[IF_NAMESIZE]; + struct mod_access_port mod_ap; + char ap_name[IF_NAMESIZE]; + int ret = 0; + + D("Trying to attach port '%s' with vlan id: %d to conf '%s'", + port_name, vlan_id, conf->conf_name); + if (vlan_id == 0x000 || vlan_id == 0xFFF) { + return EINVAL; + } + get_modified_bdg_name(modified_bdg_name, sizeof(modified_bdg_name), + conf->conf_name); + get_vlan_bdg_name(vlan_bdg_name, sizeof(vlan_bdg_name), conf->conf_name, + vlan_id); + + if (conf->number_of_ports[vlan_id] == 0) { + /* we need to create a bridge in exclusive mode */ + vlan_bdg_auth_token = netmap_bdg_create(vlan_bdg_name, &ret); + if (vlan_bdg_auth_token == NULL || ret != 0) { + return ret; + } + + conf->vlan_bdg_auth_tokens[vlan_id] = vlan_bdg_auth_token; + } + + ret = attach_port(vlan_bdg_name, port_name, vlan_bdg_auth_token, + &port_index); + if (ret) { + goto l_destroy_vlan_bdg; + } + + if (++conf->number_of_ports[vlan_id] != 1) { + /* an access port has alredy been created and attached to the + * modified bridge + */ + return ret; + } + + /* we need to create an access port and attach it + * to the modified bridge + */ + get_ap_name(ap_name, sizeof(ap_name), conf->conf_name, vlan_id); + ret = create_vale_port(ap_name); + if (ret) { + goto l_detach_vlan_port; + } + + ret = attach_port(vlan_bdg_name, ap_name, vlan_bdg_auth_token, + &port_index); + if (ret) { + goto l_destroy_access_port; + } + + ret = attach_port(modified_bdg_name, ap_name, + conf->mod_bdg_auth_token, &port_index); + if (ret) { + goto l_detach_access_port_vlan_bdg; + } + + /* this can fail only if bdg_name doesn't exist or hasn't been modified + * by us, and in either case we would have alredy failed one of our + * previous call + */ + mod_ap.old_port_index = mod_ap.new_port_index = port_index; + mod_ap.old_vlan_id = mod_ap.new_vlan_id = vlan_id; + nm_bdg_update_private_data(modified_bdg_name, modify_access_port, + &mod_ap, conf->mod_bdg_auth_token); + + return ret; + +l_detach_access_port_vlan_bdg: + /* cannot fail */ + detach_port(vlan_bdg_name, ap_name, vlan_bdg_auth_token, &port_index); + +l_destroy_access_port: + /* cannot fail */ + destroy_vale_port(ap_name); + +l_detach_vlan_port: + /* cannot fail */ + detach_port(vlan_bdg_name, port_name, vlan_bdg_auth_token, &port_index); + --conf->number_of_ports[vlan_id]; + +l_destroy_vlan_bdg: + if (conf->number_of_ports[vlan_id] == 0) { + /* we need to destroy the vlan bridge only when we fail + * something after creating it + */ + conf->vlan_bdg_auth_tokens[vlan_id] = NULL; + /* cannot fail */ + netmap_bdg_destroy(vlan_bdg_name, vlan_bdg_auth_token); + } + + return ret; +} + + + +static int +attach_trunk_port(struct vale_vlan_conf *conf, const char *port_name, + uint16_t vlan_id) +{ + uint32_t port_index = NM_BDG_NOPORT; + char mod_bdg_name[IF_NAMESIZE]; + int ret = 0; + + if (vlan_id != 0xFFF || conf->l_data.trunk_port != NM_BDG_NOPORT) { + return EINVAL; } + + get_modified_bdg_name(mod_bdg_name, sizeof(mod_bdg_name), + conf->conf_name); + ret = attach_port(mod_bdg_name, port_name, conf->mod_bdg_auth_token, + &port_index); + if (ret) { + return ret; + } + + /* this can't fail because we have the bridge in exclusive mode */ + nm_bdg_update_private_data(mod_bdg_name, modify_trunk_port, + &port_index, conf->mod_bdg_auth_token); return ret; } -#define VALE_V1A "valev1A:" -#define VALE_V1B "valev1B:" -#define VALE_V2A "valev2A:" -#define VALE_V2B "valev2B:" -#define VALE_V500B "valev500B:" -#define VALE_MODA "valemodA:" -#define VALE_MODB "valemodB:" -void *token_v1_A; -void *token_v1_B; -void *token_v2_A; -void *token_v2_B; -void *token_v500_B; -void *token_A; -void *token_B; -struct vlan_lookup_data data_A; -struct vlan_lookup_data data_B; +static int +action_attach(struct vale_vlan_conf *conf, const char *port_name, + uint8_t port_type, uint16_t vlan_id) +{ + char bdg_name[IF_NAMESIZE]; + int ret = 0; + switch (port_type){ + case TRUNK_PORT: + ret = attach_trunk_port(conf, port_name, vlan_id); + if (ret) { + return ret; + } + get_modified_bdg_name(bdg_name, sizeof(bdg_name), + conf->conf_name); + break; + case VLAN_PORT: + ret = attach_vlan_port(conf, port_name, vlan_id); + if (ret) { + return ret; + } + get_vlan_bdg_name(bdg_name, sizeof(bdg_name), conf->conf_name, + vlan_id); + break; -static void -create_ports(void) + default: + return EINVAL; + } + + + ret = attach_port_list(conf, bdg_name, port_name, port_type, vlan_id); + if (ret) { + switch (port_type){ + case TRUNK_PORT: + /* cannot fail */ + detach_trunk_port(conf, port_name, vlan_id); + break; + + case VLAN_PORT: + /* cannot fail */ + detach_vlan_port(conf, port_name, vlan_id); + break; + } + } + + return ret; +} + + + +static int +action_create_and_attach(struct vale_vlan_conf *conf, const char *port_name, + uint8_t port_type, uint16_t vlan_id) { + int ret = 0; + + ret = create_vale_port(port_name); + if (ret) { + return ret; + } + + ret = action_attach(conf, port_name, port_type, vlan_id); + if (ret) { + /* cannot fail */ + destroy_vale_port(port_name); + } - create_vale_port("v1"); - create_vale_port("v2"); - create_vale_port("v3"); - create_vale_port("v4"); - create_vale_port("v5"); - create_vale_port("v6"); - create_vale_port("vtp"); - create_vale_port("ap1A"); - create_vale_port("ap1B"); - create_vale_port("ap2A"); - create_vale_port("ap2B"); - create_vale_port("ap500B"); + return ret; } -static void -create_bridges(void) +static int +detach_trunk_port(struct vale_vlan_conf *conf, const char *port_name, + uint16_t vlan_id) { - int ret; + uint32_t port_index = NM_BDG_NOPORT; + char bdg_name[IF_NAMESIZE]; + int ret = 0; + + if (vlan_id != 0xFFF) { + return EINVAL; + } - token_A = netmap_bdg_create(VALE_MODA, &ret); - token_B = netmap_bdg_create(VALE_MODB, &ret); - token_v1_A = netmap_bdg_create(VALE_V1A, &ret); - token_v1_B = netmap_bdg_create(VALE_V1B, &ret); - token_v2_A = netmap_bdg_create(VALE_V2A, &ret); - token_v2_B = netmap_bdg_create(VALE_V2B, &ret); - token_v500_B = netmap_bdg_create(VALE_V500B, &ret); + get_modified_bdg_name(bdg_name, sizeof(bdg_name), conf->conf_name); + ret = detach_port(bdg_name, port_name, conf->mod_bdg_auth_token, + &port_index); + if (ret) { + return ret; + } + + port_index = NM_BDG_NOPORT; + /* this can't fail because we have the bridge in exlusive mode */ + nm_bdg_update_private_data(bdg_name, modify_trunk_port, + &port_index, conf->mod_bdg_auth_token); + return ret; } -static void -connect_ports(void) +static int +detach_vlan_port(struct vale_vlan_conf *conf, const char *port_name, + uint16_t vlan_id) { + struct mod_access_port mod_access_port; + uint32_t port_index = NM_BDG_NOPORT; + void *vlan_bdg_auth_token = NULL; + char modified_bdg_name[IF_NAMESIZE]; + char vlan_bdg_name[IF_NAMESIZE]; + char ap_name[IF_NAMESIZE]; + int ret = 0; + + if (vlan_id == 0x000 || vlan_id == 0xFFF) { + return EINVAL; + } + get_vlan_bdg_name(vlan_bdg_name, sizeof(vlan_bdg_name), conf->conf_name, + vlan_id); + get_modified_bdg_name(modified_bdg_name, sizeof(modified_bdg_name), + conf->conf_name); + get_ap_name(ap_name, sizeof(ap_name), conf->conf_name, vlan_id); + vlan_bdg_auth_token = conf->vlan_bdg_auth_tokens[vlan_id]; + + ret = detach_port(vlan_bdg_name, port_name, vlan_bdg_auth_token, + &port_index); + if (ret) { + return ret; + } + + if (--conf->number_of_ports[vlan_id] != 0) { + /* there are still other vlan port on this vlan bridge */ + return ret; + } + + /* we have just detached the last vlan port on this bridge, we need + * to remove (and destroy) the access port and the bridge as well + */ + ret = detach_port(modified_bdg_name, ap_name, + conf->mod_bdg_auth_token, &port_index); + if (ret) { + goto l_attach_vlan_port; + } + + ret = detach_port(vlan_bdg_name, ap_name, vlan_bdg_auth_token, + &port_index); + if (ret) { + goto l_attach_access_port_mod_bdg; + } + + ret = destroy_vale_port(ap_name); + if (ret) { + goto l_attach_access_port_vlan_bdg; + } + + ret = netmap_bdg_destroy(vlan_bdg_name, vlan_bdg_auth_token); + if (ret) { + /* cannot happen (?) */ + goto l_create_access_port; + } - attach_port(VALE_V1A, "v1", token_v1_A, NULL); - attach_port(VALE_V1A, "v2", token_v1_A, NULL); - attach_port(VALE_V1A, "ap1A", token_v1_A, NULL); + mod_access_port.old_port_index = port_index; + mod_access_port.new_port_index = NM_BDG_NOPORT; + mod_access_port.old_vlan_id = vlan_id; + mod_access_port.new_vlan_id = 0x000; + /* this can't fail because we have the bridge in exlusive mode */ + nm_bdg_update_private_data(modified_bdg_name, modify_access_port, + &mod_access_port, conf->mod_bdg_auth_token); - attach_port(VALE_V2A, "v3", token_v2_A, NULL); - attach_port(VALE_V2A, "v3", token_v2_A, NULL); - attach_port(VALE_V2A, "ap2A", token_v2_A, NULL); - attach_port(VALE_V1B, "v4", token_v1_B, NULL); - attach_port(VALE_V1B, "ap1B", token_v1_B, NULL); + return ret; - attach_port(VALE_V2B, "v5", token_v2_B, NULL); - attach_port(VALE_V2B, "ap2B", token_v2_B, NULL); +l_create_access_port: + create_vale_port(ap_name); /* cannot fail */ - attach_port(VALE_V500B, "v6", token_v500_B, NULL); - attach_port(VALE_V500B, "ap500B", token_v500_B, NULL); +l_attach_access_port_vlan_bdg: + /* cannot fail */ + attach_port(vlan_bdg_name, ap_name, vlan_bdg_auth_token, &port_index); + +l_attach_access_port_mod_bdg: + /* cannot fail */ + attach_port(modified_bdg_name, ap_name, conf->mod_bdg_auth_token, + &port_index); + +l_attach_vlan_port: + /* cannot fail */ + attach_port(vlan_bdg_name, port_name, vlan_bdg_auth_token, &port_index); + ++conf->number_of_ports[vlan_id]; - attach_port(VALE_MODA, "ap1A", token_A, NULL); - attach_port(VALE_MODA, "ap2A", token_A, NULL); - attach_port(VALE_MODA, "vtp", token_A, NULL); + return ret; - attach_port(VALE_MODB, "ap1B", token_B, NULL); - attach_port(VALE_MODB, "ap2B", token_B, NULL); - attach_port(VALE_MODB, "ap500B", token_B, NULL); - attach_port(VALE_MODB, "vtp", token_B, NULL); } -static void -delete_ports(void) +static int +search_vlan_id_of(struct vale_vlan_conf *conf, const char *port_name, + uint16_t *vlan_id) { + struct port_elem *p_elem = NULL; - destroy_vale_port("v1"); - destroy_vale_port("v2"); - destroy_vale_port("v3"); - destroy_vale_port("v4"); - destroy_vale_port("v5"); - destroy_vale_port("v6"); - destroy_vale_port("vtp"); - destroy_vale_port("ap1A"); - destroy_vale_port("ap1B"); - destroy_vale_port("ap2A"); - destroy_vale_port("ap2B"); - destroy_vale_port("ap500B"); + vv_list_foreach(p_elem, &conf->port_list, list) { + if (strcmp(p_elem->port_desc.port_name, port_name) == 0) { + *vlan_id = p_elem->port_desc.vlan_id; + return 0; + } + } + return ENXIO; } -static void -delete_bridges(void) +static int +search_trunk_port_of(struct vale_vlan_conf *conf, char *trunk_port_name) { + struct port_elem *p_elem = NULL; - netmap_bdg_destroy(VALE_MODA, &token_A); - netmap_bdg_destroy(VALE_MODB, &token_B); - netmap_bdg_destroy(VALE_V1A, &token_v1_A); - netmap_bdg_destroy(VALE_V1B, &token_v1_B); - netmap_bdg_destroy(VALE_V2A, &token_v2_A); - netmap_bdg_destroy(VALE_V2B, &token_v2_B); - netmap_bdg_destroy(VALE_V500B, &token_v500_B); + vv_list_foreach(p_elem, &conf->port_list, list) { + if (p_elem->port_desc.port_type == TRUNK_PORT) { + snprintf(trunk_port_name, IF_NAMESIZE, "%s", + p_elem->port_desc.port_name); + return 0; + } + } + return ENXIO; } -static void -detach_ports(void) +static int +action_detach(struct vale_vlan_conf *conf, char *port_name, uint8_t port_type, + uint16_t vlan_id) { + int ret = 0; + + switch (port_type) { + case TRUNK_PORT: + if (port_name[0] == '\0') { + ret = search_trunk_port_of(conf, port_name); + if (ret) { + return ret; + } + } + ret = detach_trunk_port(conf, port_name, vlan_id); + if (ret) { + return ret; + } + break; + case VLAN_PORT: + if (vlan_id == 0xFFF) { + ret = search_vlan_id_of(conf, port_name, &vlan_id); + if (ret) { + return ret; + } + } - detach_port(VALE_MODB, "vtp", token_B, NULL); - detach_port(VALE_MODB, "ap500B", token_B, NULL); - detach_port(VALE_MODB, "ap2B", token_B, NULL); - detach_port(VALE_MODB, "ap1B", token_B, NULL); + ret = detach_vlan_port(conf, port_name, vlan_id); + if (ret) { + return ret; + } + break; + default: + return EINVAL; + } - detach_port(VALE_MODA, "vtp", token_A, NULL); - detach_port(VALE_MODA, "ap2A", token_A, NULL); - detach_port(VALE_MODA, "ap1A", token_A, NULL); + ret = detach_port_list(conf, port_name); + if (ret) { + switch (port_type){ + case TRUNK_PORT: + ret = attach_trunk_port(conf, port_name, vlan_id); + break; + + case VLAN_PORT: + ret = attach_vlan_port(conf, port_name, vlan_id); + break; + } + } + return ret; +} - detach_port(VALE_V500B, "ap500B", token_v500_B, NULL); - detach_port(VALE_V500B, "v6", token_v500_B, NULL); - detach_port(VALE_V2B, "ap2B", token_v2_B, NULL); - detach_port(VALE_V2B, "v5", token_v2_B, NULL); - detach_port(VALE_V1B, "ap1B", token_v1_B, NULL); - detach_port(VALE_V1B, "v4", token_v1_B, NULL); +static int +action_detach_and_destroy(struct vale_vlan_conf *conf, char *port_name, + uint8_t port_type, uint16_t vlan_id) +{ + int ret = 0; - detach_port(VALE_V2A, "ap2A", token_v2_A, NULL); - detach_port(VALE_V2A, "v3", token_v2_A, NULL); - detach_port(VALE_V2A, "v3", token_v2_A, NULL); + ret = action_detach(conf, port_name, port_type, vlan_id); + if (ret) { + return ret; + } - detach_port(VALE_V1A, "ap1A", token_v1_A, NULL); - detach_port(VALE_V1A, "v2", token_v1_A, NULL); - detach_port(VALE_V1A, "v1", token_v1_A, NULL); + ret = destroy_vale_port(port_name); + if (ret) { + /* cannot fail */ + action_attach(conf, port_name, port_type, vlan_id); + } + return ret; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***