/* * (C) 2022 by sysmocom - s.f.m.c. GmbH * All Rights Reserved. * * Author: Neels Janosch Hofmeyr * * SPDX-License-Identifier: GPL-2.0+ * * 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, see . * */ #include #include #include #include #include /* Add a new netinst entry to the given list. * \param ctx talloc allocate new entry from ctx. * \param list append to this list. * \param name The Network Instance name as given in PFCP Network Instance IEs. * \param addr IP address string of local interface to associate with the Network Instance. * \param errmsg On error, an error description is returned in this out-argument. * \return new network_instance entry, or NULL on error. */ const struct network_instance *netinst_add(void *ctx, struct llist_head *list, const char *name, const char *addr, const char **errmsg) { struct network_instance *netinst; if (errmsg) *errmsg = NULL; if (!name || !*name) { if (errmsg) *errmsg = "Network Instance name must not be empty"; return NULL; } if (netinst_find(list, name)) { if (errmsg) *errmsg = "Network Instance entry with this name already exists"; return NULL; } netinst = talloc(ctx, struct network_instance); *netinst = (struct network_instance){ .name = talloc_strdup(netinst, name), }; if (osmo_sockaddr_str_from_str(&netinst->addr, addr, 0)) { if (errmsg) *errmsg = "Network Instance address is not a valid IP address string"; talloc_free(netinst); return NULL; } llist_add_tail(&netinst->entry, list); return netinst; } const struct network_instance *netinst_find(struct llist_head *list, const char *name) { const struct network_instance *netinst; if (!name) return NULL; llist_for_each_entry(netinst, list, entry) if (!strcmp(netinst->name, name)) return netinst; return NULL; } const struct network_instance *netinst_first(struct llist_head *list) { return llist_first_entry_or_null(list, struct network_instance, entry); } /* Clear the list of Network Instance entries, return the nr of entries that were removed. */ int netinst_clear(struct llist_head *list) { int count = 0; while (1) { struct network_instance *netinst = llist_first_entry_or_null(list, struct network_instance, entry); if (!netinst) break; llist_del(&netinst->entry); talloc_free(netinst); count++; } return count; } /* Write one or all netinst entries to the VTY output. * If name_or_null is NULL, print all entries. Else, print only the entry matching that name. * Return number of printed entries. */ int netinst_vty_write(struct vty *vty, struct llist_head *list, const char *indent, const char *name_or_null) { const struct network_instance *netinst; int count = 0; llist_for_each_entry(netinst, list, entry) { if (name_or_null && strcmp(netinst->name, name_or_null)) continue; vty_out(vty, "%sadd %s %s%s", indent, netinst->name, netinst->addr.ip, VTY_NEWLINE); count++; } return count; }