mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 21:37:08 +00:00

* (general) extern and static'ification of functions in code and header. Cleanup any definitions with unspecified arguments. Add casts for callback assignments where the callback is defined, typically, as passing void *, but the function being assigned has some other pointer type defined as its argument, as gcc complains about casts from void * to X* via function arguments. Fix some old K&R style function argument definitions. Add noreturn gcc attribute to some functions, as appropriate. Add unused gcc attribute to some functions (eg ones meant to help while debugging) Add guard defines to headers which were missing them. * command.c: (install_node) add const qualifier, still doesnt shut up the warning though, because of the double pointer. (cmp_node) ditto * keychain.c: (key_str2time) Add GET_LONG_RANGE() macro, derived fromn vty.h ones to fix some of the (long) < 0 warnings. * thread.c: (various) use thread_empty (cpu_record_hash_key) should cast to uintptr_t, a stdint.h type * vty.h: Add VTY_GET_IPV4_ADDRESS and VTY_GET_IPV4_PREFIX so they removed from ospfd/ospf_vty.h * zebra.h: Move definition of ZEBRA_PORT to here, to remove dependence of lib on zebra/zserv.h
336 lines
7.4 KiB
C
336 lines
7.4 KiB
C
/* route-map for interface.
|
||
* Copyright (C) 1999 Kunihiro Ishiguro
|
||
*
|
||
* This file is part of GNU Zebra.
|
||
*
|
||
* GNU Zebra 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, or (at your option) any
|
||
* later version.
|
||
*
|
||
* GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the Free
|
||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||
* 02111-1307, USA.
|
||
*/
|
||
|
||
#include <zebra.h>
|
||
|
||
#include "hash.h"
|
||
#include "command.h"
|
||
#include "memory.h"
|
||
#include "if.h"
|
||
#include "if_rmap.h"
|
||
|
||
struct hash *ifrmaphash;
|
||
|
||
/* Hook functions. */
|
||
static void (*if_rmap_add_hook) (struct if_rmap *) = NULL;
|
||
static void (*if_rmap_delete_hook) (struct if_rmap *) = NULL;
|
||
|
||
static struct if_rmap *
|
||
if_rmap_new (void)
|
||
{
|
||
struct if_rmap *new;
|
||
|
||
new = XCALLOC (MTYPE_IF_RMAP, sizeof (struct if_rmap));
|
||
|
||
return new;
|
||
}
|
||
|
||
static void
|
||
if_rmap_free (struct if_rmap *if_rmap)
|
||
{
|
||
if (if_rmap->ifname)
|
||
free (if_rmap->ifname);
|
||
|
||
if (if_rmap->routemap[IF_RMAP_IN])
|
||
free (if_rmap->routemap[IF_RMAP_IN]);
|
||
if (if_rmap->routemap[IF_RMAP_OUT])
|
||
free (if_rmap->routemap[IF_RMAP_OUT]);
|
||
|
||
XFREE (MTYPE_IF_RMAP, if_rmap);
|
||
}
|
||
|
||
struct if_rmap *
|
||
if_rmap_lookup (const char *ifname)
|
||
{
|
||
struct if_rmap key;
|
||
struct if_rmap *if_rmap;
|
||
|
||
/* temporary copy */
|
||
key.ifname = (char *)ifname;
|
||
|
||
if_rmap = hash_lookup (ifrmaphash, &key);
|
||
|
||
return if_rmap;
|
||
}
|
||
|
||
void
|
||
if_rmap_hook_add (void (*func) (struct if_rmap *))
|
||
{
|
||
if_rmap_add_hook = func;
|
||
}
|
||
|
||
void
|
||
if_rmap_hook_delete (void (*func) (struct if_rmap *))
|
||
{
|
||
if_rmap_delete_hook = func;
|
||
}
|
||
|
||
static void *
|
||
if_rmap_hash_alloc (void *arg)
|
||
{
|
||
struct if_rmap *ifarg = arg;
|
||
struct if_rmap *if_rmap;
|
||
|
||
if_rmap = if_rmap_new ();
|
||
if_rmap->ifname = strdup (ifarg->ifname);
|
||
|
||
return if_rmap;
|
||
}
|
||
|
||
static struct if_rmap *
|
||
if_rmap_get (const char *ifname)
|
||
{
|
||
struct if_rmap key;
|
||
|
||
/* temporary copy */
|
||
key.ifname = (char *)ifname;
|
||
|
||
return (struct if_rmap *) hash_get (ifrmaphash, &key, if_rmap_hash_alloc);
|
||
}
|
||
|
||
static unsigned int
|
||
if_rmap_hash_make (void *data)
|
||
{
|
||
struct if_rmap *if_rmap = data;
|
||
unsigned int i, key;
|
||
|
||
key = 0;
|
||
for (i = 0; i < strlen (if_rmap->ifname); i++)
|
||
key += if_rmap->ifname[i];
|
||
|
||
return key;
|
||
}
|
||
|
||
static int
|
||
if_rmap_hash_cmp (void *arg1, void* arg2)
|
||
{
|
||
struct if_rmap *if_rmap1 = arg1;
|
||
struct if_rmap *if_rmap2 = arg2;
|
||
if (strcmp (if_rmap1->ifname, if_rmap2->ifname) == 0)
|
||
return 1;
|
||
return 0;
|
||
}
|
||
|
||
static struct if_rmap *
|
||
if_rmap_set (const char *ifname, enum if_rmap_type type,
|
||
const char *routemap_name)
|
||
{
|
||
struct if_rmap *if_rmap;
|
||
|
||
if_rmap = if_rmap_get (ifname);
|
||
|
||
if (type == IF_RMAP_IN)
|
||
{
|
||
if (if_rmap->routemap[IF_RMAP_IN])
|
||
free (if_rmap->routemap[IF_RMAP_IN]);
|
||
if_rmap->routemap[IF_RMAP_IN] = strdup (routemap_name);
|
||
}
|
||
if (type == IF_RMAP_OUT)
|
||
{
|
||
if (if_rmap->routemap[IF_RMAP_OUT])
|
||
free (if_rmap->routemap[IF_RMAP_OUT]);
|
||
if_rmap->routemap[IF_RMAP_OUT] = strdup (routemap_name);
|
||
}
|
||
|
||
if (if_rmap_add_hook)
|
||
(*if_rmap_add_hook) (if_rmap);
|
||
|
||
return if_rmap;
|
||
}
|
||
|
||
static int
|
||
if_rmap_unset (const char *ifname, enum if_rmap_type type,
|
||
const char *routemap_name)
|
||
{
|
||
struct if_rmap *if_rmap;
|
||
|
||
if_rmap = if_rmap_lookup (ifname);
|
||
if (!if_rmap)
|
||
return 0;
|
||
|
||
if (type == IF_RMAP_IN)
|
||
{
|
||
if (!if_rmap->routemap[IF_RMAP_IN])
|
||
return 0;
|
||
if (strcmp (if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0)
|
||
return 0;
|
||
|
||
free (if_rmap->routemap[IF_RMAP_IN]);
|
||
if_rmap->routemap[IF_RMAP_IN] = NULL;
|
||
}
|
||
|
||
if (type == IF_RMAP_OUT)
|
||
{
|
||
if (!if_rmap->routemap[IF_RMAP_OUT])
|
||
return 0;
|
||
if (strcmp (if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0)
|
||
return 0;
|
||
|
||
free (if_rmap->routemap[IF_RMAP_OUT]);
|
||
if_rmap->routemap[IF_RMAP_OUT] = NULL;
|
||
}
|
||
|
||
if (if_rmap_delete_hook)
|
||
(*if_rmap_delete_hook) (if_rmap);
|
||
|
||
if (if_rmap->routemap[IF_RMAP_IN] == NULL &&
|
||
if_rmap->routemap[IF_RMAP_OUT] == NULL)
|
||
{
|
||
hash_release (ifrmaphash, if_rmap);
|
||
if_rmap_free (if_rmap);
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
DEFUN (if_rmap,
|
||
if_rmap_cmd,
|
||
"route-map RMAP_NAME (in|out) IFNAME",
|
||
"Route map set\n"
|
||
"Route map name\n"
|
||
"Route map set for input filtering\n"
|
||
"Route map set for output filtering\n"
|
||
"Route map interface name\n")
|
||
{
|
||
enum if_rmap_type type;
|
||
struct if_rmap *if_rmap;
|
||
|
||
if (strncmp (argv[1], "i", 1) == 0)
|
||
type = IF_RMAP_IN;
|
||
else if (strncmp (argv[1], "o", 1) == 0)
|
||
type = IF_RMAP_OUT;
|
||
else
|
||
{
|
||
vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
|
||
return CMD_WARNING;
|
||
}
|
||
|
||
if_rmap = if_rmap_set (argv[2], type, argv[0]);
|
||
|
||
return CMD_SUCCESS;
|
||
}
|
||
|
||
ALIAS (if_rmap,
|
||
if_ipv6_rmap_cmd,
|
||
"route-map RMAP_NAME (in|out) IFNAME",
|
||
"Route map set\n"
|
||
"Route map name\n"
|
||
"Route map set for input filtering\n"
|
||
"Route map set for output filtering\n"
|
||
"Route map interface name\n")
|
||
|
||
DEFUN (no_if_rmap,
|
||
no_if_rmap_cmd,
|
||
"no route-map ROUTEMAP_NAME (in|out) IFNAME",
|
||
NO_STR
|
||
"Route map unset\n"
|
||
"Route map name\n"
|
||
"Route map for input filtering\n"
|
||
"Route map for output filtering\n"
|
||
"Route map interface name\n")
|
||
{
|
||
int ret;
|
||
enum if_rmap_type type;
|
||
|
||
if (strncmp (argv[1], "i", 1) == 0)
|
||
type = IF_RMAP_IN;
|
||
else if (strncmp (argv[1], "o", 1) == 0)
|
||
type = IF_RMAP_OUT;
|
||
else
|
||
{
|
||
vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
|
||
return CMD_WARNING;
|
||
}
|
||
|
||
ret = if_rmap_unset (argv[2], type, argv[0]);
|
||
if (! ret)
|
||
{
|
||
vty_out (vty, "route-map doesn't exist%s", VTY_NEWLINE);
|
||
return CMD_WARNING;
|
||
}
|
||
return CMD_SUCCESS;
|
||
}
|
||
|
||
ALIAS (no_if_rmap,
|
||
no_if_ipv6_rmap_cmd,
|
||
"no route-map ROUTEMAP_NAME (in|out) IFNAME",
|
||
NO_STR
|
||
"Route map unset\n"
|
||
"Route map name\n"
|
||
"Route map for input filtering\n"
|
||
"Route map for output filtering\n"
|
||
"Route map interface name\n")
|
||
|
||
/* Configuration write function. */
|
||
int
|
||
config_write_if_rmap (struct vty *vty)
|
||
{
|
||
unsigned int i;
|
||
struct hash_backet *mp;
|
||
int write = 0;
|
||
|
||
for (i = 0; i < ifrmaphash->size; i++)
|
||
for (mp = ifrmaphash->index[i]; mp; mp = mp->next)
|
||
{
|
||
struct if_rmap *if_rmap;
|
||
|
||
if_rmap = mp->data;
|
||
|
||
if (if_rmap->routemap[IF_RMAP_IN])
|
||
{
|
||
vty_out (vty, " route-map %s in %s%s",
|
||
if_rmap->routemap[IF_RMAP_IN],
|
||
if_rmap->ifname,
|
||
VTY_NEWLINE);
|
||
write++;
|
||
}
|
||
|
||
if (if_rmap->routemap[IF_RMAP_OUT])
|
||
{
|
||
vty_out (vty, " route-map %s out %s%s",
|
||
if_rmap->routemap[IF_RMAP_OUT],
|
||
if_rmap->ifname,
|
||
VTY_NEWLINE);
|
||
write++;
|
||
}
|
||
}
|
||
return write;
|
||
}
|
||
|
||
void
|
||
if_rmap_reset ()
|
||
{
|
||
hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free);
|
||
}
|
||
|
||
void
|
||
if_rmap_init (int node)
|
||
{
|
||
ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp);
|
||
if (node == RIPNG_NODE) {
|
||
install_element (RIPNG_NODE, &if_ipv6_rmap_cmd);
|
||
install_element (RIPNG_NODE, &no_if_ipv6_rmap_cmd);
|
||
} else if (node == RIP_NODE) {
|
||
install_element (RIP_NODE, &if_rmap_cmd);
|
||
install_element (RIP_NODE, &no_if_rmap_cmd);
|
||
}
|
||
}
|