summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
authorSander Vrijders <[email protected]>2016-05-29 20:25:41 +0200
committerSander Vrijders <[email protected]>2016-05-29 20:57:48 +0200
commita76b638a370cd0cdd087ec780e6b1f8d18bac66d (patch)
tree6eddda98b7c8b3f723e95d8b19505a512db1593d /src/irmd
parent81cdb27742f9ae93169b0b03d1a45090c4354f89 (diff)
downloadouroboros-a76b638a370cd0cdd087ec780e6b1f8d18bac66d.tar.gz
ouroboros-a76b638a370cd0cdd087ec780e6b1f8d18bac66d.zip
irmd: Add wildcarding of DIF names
This adds wildcarding of DIF names so that application developers can for instance specify home.* to specify all home DIFs.
Diffstat (limited to 'src/irmd')
-rw-r--r--src/irmd/CMakeLists.txt1
-rw-r--r--src/irmd/main.c116
-rw-r--r--src/irmd/utils.c70
-rw-r--r--src/irmd/utils.h27
4 files changed, 149 insertions, 65 deletions
diff --git a/src/irmd/CMakeLists.txt b/src/irmd/CMakeLists.txt
index b7e3cde4..75d65ba3 100644
--- a/src/irmd/CMakeLists.txt
+++ b/src/irmd/CMakeLists.txt
@@ -7,6 +7,7 @@ include_directories(${CMAKE_BINARY_DIR}/include)
set(SOURCE_FILES
# Add source files here
main.c
+ utils.c
)
add_executable (irmd ${SOURCE_FILES})
diff --git a/src/irmd/main.c b/src/irmd/main.c
index b84c3327..03f9a3c2 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -38,6 +38,8 @@
#include <ouroboros/qos.h>
#include <ouroboros/rw_lock.h>
+#include "utils.h"
+
#include <sys/socket.h>
#include <sys/un.h>
#include <signal.h>
@@ -47,9 +49,6 @@
#include <limits.h>
#include <pthread.h>
-/* FIXME: this smells like part of namespace management */
-#define ALL_DIFS "*"
-
#ifndef IRMD_MAX_FLOWS
#define IRMD_MAX_FLOWS 4096
#endif
@@ -229,7 +228,12 @@ static instance_name_t * get_ipcp_by_name(char * ap_name)
return NULL;
}
-static instance_name_t * get_ipcp_by_dif_name(char * dif_name)
+/*
+ * FIXME: this just returns the first IPCP that
+ * matches the requested DIF name for now
+ */
+static instance_name_t * get_ipcp_by_dst_name(char * dst_name,
+ char * dif_name)
{
struct list_head * pos = NULL;
@@ -240,22 +244,13 @@ static instance_name_t * get_ipcp_by_dif_name(char * dif_name)
if (e->dif_name == NULL)
continue;
- if (strcmp(dif_name, e->dif_name) == 0)
+ if (dif_name != NULL) {
+ if (wildcard_match(dif_name, e->dif_name) == 0) {
+ return e->api;
+ }
+ } else {
return e->api;
- }
-
- return NULL;
-}
-
-/* FIXME: this just returns the first IPCP for now */
-static instance_name_t * get_ipcp_by_dst_name(char * dst_name)
-{
- struct list_head * pos = NULL;
-
- list_for_each(pos, &instance->ipcps) {
- struct ipcp_entry * e =
- list_entry(pos, struct ipcp_entry, next);
- return e->api;
+ }
}
return NULL;
@@ -470,10 +465,10 @@ static int destroy_ipcp(instance_name_t * api)
struct ipcp_entry * tmp =
list_entry(pos, struct ipcp_entry, next);
- if (instance_name_cmp(api, tmp->api) == 0)
+ if (instance_name_cmp(api, tmp->api) == 0) {
list_del(&tmp->next);
-
- ipcp_entry_destroy(tmp);
+ ipcp_entry_destroy(tmp);
+ }
}
rw_lock_unlock(&instance->reg_lock);
@@ -649,7 +644,6 @@ static int ap_reg(char * ap_name,
struct reg_name_entry * rne = NULL;
instance_name_t * api = NULL;
- instance_name_t * ipcpi = NULL;
rw_lock_rdlock(&instance->state_lock);
rw_lock_wrlock(&instance->reg_lock);
@@ -689,31 +683,22 @@ static int ap_reg(char * ap_name,
* contains a single instance only
*/
- if (strcmp(difs[0], ALL_DIFS) == 0) {
- list_for_each(pos, &instance->ipcps) {
- struct ipcp_entry * e =
- list_entry(pos, struct ipcp_entry, next);
+ list_for_each(pos, &instance->ipcps) {
+ struct ipcp_entry * e =
+ list_entry(pos, struct ipcp_entry, next);
- if (ipcp_name_reg(e->api->id, ap_name)) {
- LOG_ERR("Could not register %s in DIF %s.",
- api->name, e->dif_name);
- } else {
- ++ret;
- }
- }
- } else {
- for (i = 0; i < len; ++i) {
- ipcpi = get_ipcp_by_dif_name(difs[i]);
- if (ipcpi == NULL) {
- LOG_ERR("%s: No such DIF.", difs[i]);
- continue;
- }
+ if (e->dif_name == NULL)
+ continue;
- if (ipcp_name_reg(ipcpi->id, api->name)) {
- LOG_ERR("Could not register %s in DIF %s.",
- api->name, difs[i]);
- } else {
- ++ret;
+ for (i = 0; i < len; ++i) {
+ if (wildcard_match(difs[i], e->dif_name) == 0) {
+ if (ipcp_name_reg(e->api->id, ap_name)) {
+ LOG_ERR("Could not register "
+ "%s in DIF %s.",
+ api->name, e->dif_name);
+ } else {
+ ++ret;
+ }
}
}
}
@@ -768,23 +753,21 @@ static int ap_unreg(char * ap_name,
return 0;
}
- if (strcmp(difs[0], ALL_DIFS) == 0) {
- list_for_each(pos, &instance->ipcps) {
- struct ipcp_entry * e =
- list_entry(pos, struct ipcp_entry, next);
+ list_for_each(pos, &instance->ipcps) {
+ struct ipcp_entry * e =
+ list_entry(pos, struct ipcp_entry, next);
+
+ if (e->dif_name == NULL)
+ continue;
- if (ipcp_name_unreg(e->api->id, rne->name)) {
- LOG_ERR("Could not unregister %s in DIF %s.",
- rne->name, e->dif_name);
- --ret;
- }
- }
- } else {
for (i = 0; i < len; ++i) {
- if (ipcp_name_unreg(ap_id, rne->name)) {
- LOG_ERR("Could not unregister %s in DIF %s.",
- rne->name, difs[i]);
- --ret;
+ if (wildcard_match(difs[i], e->dif_name) == 0) {
+ if (ipcp_name_unreg(e->api->id, rne->name)) {
+ LOG_ERR("Could not unregister "
+ "%s in DIF %s.",
+ rne->name, e->dif_name);
+ --ret;
+ }
}
}
}
@@ -942,6 +925,7 @@ static struct port_map_entry * flow_alloc(pid_t pid,
{
struct port_map_entry * pme;
instance_name_t * ipcp;
+ char * dif_name = NULL;
/* FIXME: Map qos_spec to qos_cube */
@@ -957,12 +941,14 @@ static struct port_map_entry * flow_alloc(pid_t pid,
rw_lock_rdlock(&instance->state_lock);
rw_lock_rdlock(&instance->reg_lock);
- ipcp = get_ipcp_by_dst_name(dst_name);
+ if (qos != NULL)
+ dif_name = qos->dif_name;
+ ipcp = get_ipcp_by_dst_name(dst_name, dif_name);
if (ipcp == NULL) {
rw_lock_unlock(&instance->reg_lock);
rw_lock_unlock(&instance->state_lock);
- LOG_DBG("unknown ipcp");
+ LOG_DBG("Unknown DIF name.");
return NULL;
}
@@ -970,7 +956,7 @@ static struct port_map_entry * flow_alloc(pid_t pid,
rw_lock_wrlock(&instance->flows_lock);
pme->port_id = bmp_allocate(instance->port_ids);
- pme->n_1_pid = get_ipcp_by_dst_name(dst_name)->id;
+ pme->n_1_pid = ipcp->id;
list_add(&pme->next, &instance->port_map);
@@ -1227,7 +1213,7 @@ static int flow_dealloc_ipcp(int port_id)
return 0;
}
-static void irm_destroy(struct irm * irm)
+static void irm_destroy(struct irm * irm)
{
struct list_head * h;
struct list_head * t;
diff --git a/src/irmd/utils.c b/src/irmd/utils.c
new file mode 100644
index 00000000..9cc1dd2f
--- /dev/null
+++ b/src/irmd/utils.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * wildcard_match is based on the fnmatch function from POSIX.2.
+ * Implementation based on that one from FreeBSD.
+ */
+
+int wildcard_match(const char * pattern, const char * string)
+{
+ char c;
+
+ /* For loop? Why not Zoidberg? */
+ for (;;) {
+ switch (c = *pattern++) {
+ case '\0':
+ return (*string == '\0' ? 0 : -1);
+ case '*':
+ c = *pattern;
+
+ if (c == '\0')
+ return 0;
+
+ /* General case, use recursion. */
+ while ((c = *string) != '\0') {
+ if (!wildcard_match(pattern, string))
+ return 0;
+ ++string;
+ }
+ return -1;
+ default:
+ if (c != *string)
+ return -1;
+ string++;
+ break;
+ }
+ }
+}
diff --git a/src/irmd/utils.h b/src/irmd/utils.h
new file mode 100644
index 00000000..aa8a38f1
--- /dev/null
+++ b/src/irmd/utils.h
@@ -0,0 +1,27 @@
+/*
+ * Ouroboros - Copyright (C) 2016
+ *
+ * Utils of the IPC Resource Manager
+ *
+ * Sander Vrijders <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Checks whether the string argument matches the pattern argument,
+ * which is a wildcard pattern.
+ */
+int wildcard_match(const char * pattern, const char * string);