From a76b638a370cd0cdd087ec780e6b1f8d18bac66d Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Sun, 29 May 2016 20:25:41 +0200 Subject: 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. --- src/irmd/CMakeLists.txt | 1 + src/irmd/main.c | 116 +++++++++++++++++++++--------------------------- src/irmd/utils.c | 70 +++++++++++++++++++++++++++++ src/irmd/utils.h | 27 +++++++++++ 4 files changed, 149 insertions(+), 65 deletions(-) create mode 100644 src/irmd/utils.c create mode 100644 src/irmd/utils.h (limited to 'src/irmd') 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 #include +#include "utils.h" + #include #include #include @@ -47,9 +49,6 @@ #include #include -/* 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 + * + * 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); -- cgit v1.2.3