Line data Source code
1 : /*
2 : * Affinity map function.
3 : *
4 : * Copyright 2022 Hiroki Shirokura, LINE Corporation
5 : * Copyright 2022 Masakazu Asama
6 : * Copyright 2022 6WIND S.A.
7 : *
8 : * This file is part of Free Range Routing (FRR).
9 : *
10 : * FRR is free software; you can redistribute it and/or modify it
11 : * under the terms of the GNU General Public License as published by the
12 : * Free Software Foundation; either version 2, or (at your option) any
13 : * later version.
14 : *
15 : * FRR is distributed in the hope that it will be useful, but
16 : * WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 : * General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU General Public License along
21 : * with this program; see the file COPYING; if not, write to the Free Software
22 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 : */
24 :
25 : #include <zebra.h>
26 :
27 : #include "linklist.h"
28 : #include "memory.h"
29 : #include "command.h"
30 : #include "vector.h"
31 : #include "prefix.h"
32 : #include "vty.h"
33 : #include "affinitymap.h"
34 : #include "command.h"
35 : #include "log.h"
36 : #include "hash.h"
37 : #include "libfrr.h"
38 : #include "lib_errors.h"
39 : #include "table.h"
40 : #include "json.h"
41 : #include "jhash.h"
42 :
43 12 : DEFINE_MTYPE_STATIC(LIB, AFFINITY_MAP, "Affinity map");
44 12 : DEFINE_MTYPE(LIB, AFFINITY_MAP_NAME, "Affinity map name");
45 12 : DEFINE_MTYPE_STATIC(LIB, AFFINITY_MAP_INDEX, "Affinity map index");
46 :
47 : DEFINE_QOBJ_TYPE(affinity_maps);
48 : DEFINE_QOBJ_TYPE(affinity_map);
49 :
50 : struct affinity_maps affinity_map_master = {NULL, NULL, NULL, NULL};
51 :
52 0 : static void affinity_map_free(struct affinity_map *map)
53 : {
54 0 : XFREE(MTYPE_AFFINITY_MAP, map);
55 0 : }
56 :
57 0 : void affinity_map_set(const char *name, int pos)
58 : {
59 0 : struct listnode *node;
60 0 : struct affinity_map *map;
61 :
62 0 : if (!affinity_map_master.maps)
63 0 : affinity_map_master.maps = list_new();
64 :
65 0 : for (ALL_LIST_ELEMENTS_RO(affinity_map_master.maps, node, map)) {
66 0 : if (strncmp(name, map->name, AFFINITY_NAME_SIZE) != 0)
67 0 : continue;
68 0 : map->bit_position = pos;
69 0 : return;
70 : }
71 :
72 0 : map = XCALLOC(MTYPE_AFFINITY_MAP, sizeof(*map));
73 0 : map->bit_position = pos;
74 0 : snprintf(map->name, sizeof(map->name), "%s", name);
75 0 : listnode_add(affinity_map_master.maps, map);
76 : }
77 :
78 0 : void affinity_map_unset(const char *name)
79 : {
80 0 : struct listnode *node, *nnode;
81 0 : struct affinity_map *map;
82 :
83 0 : if (!affinity_map_master.maps)
84 : return;
85 :
86 0 : for (ALL_LIST_ELEMENTS(affinity_map_master.maps, node, nnode, map)) {
87 0 : if (strncmp(name, map->name, AFFINITY_NAME_SIZE) != 0)
88 0 : continue;
89 0 : listnode_delete(affinity_map_master.maps, map);
90 0 : affinity_map_free(map);
91 0 : return;
92 : }
93 : }
94 :
95 0 : struct affinity_map *affinity_map_get(const char *name)
96 : {
97 0 : struct listnode *node;
98 0 : struct affinity_map *map;
99 :
100 0 : if (!affinity_map_master.maps)
101 : return NULL;
102 :
103 0 : for (ALL_LIST_ELEMENTS_RO(affinity_map_master.maps, node, map))
104 0 : if (strncmp(name, map->name, AFFINITY_NAME_SIZE) == 0)
105 0 : return map;
106 : return NULL;
107 : }
108 :
109 :
110 0 : char *affinity_map_name_get(int pos)
111 : {
112 0 : struct listnode *node;
113 0 : struct affinity_map *map;
114 :
115 0 : if (!affinity_map_master.maps)
116 : return NULL;
117 :
118 0 : for (ALL_LIST_ELEMENTS_RO(affinity_map_master.maps, node, map))
119 0 : if (map->bit_position == pos)
120 0 : return map->name;
121 : return NULL;
122 : }
123 :
124 0 : bool affinity_map_check_use_hook(const char *affmap_name)
125 : {
126 0 : if (affinity_map_master.check_use_hook)
127 0 : return (*affinity_map_master.check_use_hook)(affmap_name);
128 : return false;
129 : }
130 :
131 0 : bool affinity_map_check_update_hook(const char *affmap_name, uint16_t new_pos)
132 : {
133 0 : if (affinity_map_master.check_update_hook)
134 0 : return (*affinity_map_master.check_update_hook)(affmap_name,
135 : new_pos);
136 : return true;
137 : }
138 :
139 0 : void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos)
140 : {
141 0 : struct affinity_map *map;
142 :
143 0 : if (!affinity_map_master.update_hook)
144 : return;
145 :
146 0 : map = affinity_map_get(affmap_name);
147 :
148 0 : if (!map)
149 : /* Affinity-map creation */
150 : return;
151 :
152 0 : (*affinity_map_master.update_hook)(affmap_name, map->bit_position,
153 : new_pos);
154 : }
155 :
156 :
157 2 : void affinity_map_set_check_use_hook(bool (*func)(const char *affmap_name))
158 : {
159 2 : affinity_map_master.check_use_hook = func;
160 2 : }
161 :
162 2 : void affinity_map_set_check_update_hook(bool (*func)(const char *affmap_name,
163 : uint16_t new_pos))
164 : {
165 2 : affinity_map_master.check_update_hook = func;
166 2 : }
167 :
168 2 : void affinity_map_set_update_hook(void (*func)(const char *affmap_name,
169 : uint16_t old_pos,
170 : uint16_t new_pos))
171 : {
172 2 : affinity_map_master.update_hook = func;
173 2 : }
|