/src/frr/lib/affinitymap.c
Line | Count | Source (jump to first uncovered line) |
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 | | DEFINE_MTYPE_STATIC(LIB, AFFINITY_MAP, "Affinity map"); |
44 | | DEFINE_MTYPE(LIB, AFFINITY_MAP_NAME, "Affinity map name"); |
45 | | 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 | | static void affinity_map_free(struct affinity_map *map) |
53 | 0 | { |
54 | 0 | XFREE(MTYPE_AFFINITY_MAP, map); |
55 | 0 | } |
56 | | |
57 | | void affinity_map_set(const char *name, int pos) |
58 | 0 | { |
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 | 0 | } |
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 | 0 | } |
77 | | |
78 | | void affinity_map_unset(const char *name) |
79 | 0 | { |
80 | 0 | struct listnode *node, *nnode; |
81 | 0 | struct affinity_map *map; |
82 | |
|
83 | 0 | if (!affinity_map_master.maps) |
84 | 0 | 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 | 0 | } |
93 | 0 | } |
94 | | |
95 | | struct affinity_map *affinity_map_get(const char *name) |
96 | 0 | { |
97 | 0 | struct listnode *node; |
98 | 0 | struct affinity_map *map; |
99 | |
|
100 | 0 | if (!affinity_map_master.maps) |
101 | 0 | 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 | 0 | return NULL; |
107 | 0 | } |
108 | | |
109 | | |
110 | | char *affinity_map_name_get(int pos) |
111 | 0 | { |
112 | 0 | struct listnode *node; |
113 | 0 | struct affinity_map *map; |
114 | |
|
115 | 0 | if (!affinity_map_master.maps) |
116 | 0 | 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 | 0 | return NULL; |
122 | 0 | } |
123 | | |
124 | | bool affinity_map_check_use_hook(const char *affmap_name) |
125 | 0 | { |
126 | 0 | if (affinity_map_master.check_use_hook) |
127 | 0 | return (*affinity_map_master.check_use_hook)(affmap_name); |
128 | 0 | return false; |
129 | 0 | } |
130 | | |
131 | | bool affinity_map_check_update_hook(const char *affmap_name, uint16_t new_pos) |
132 | 0 | { |
133 | 0 | if (affinity_map_master.check_update_hook) |
134 | 0 | return (*affinity_map_master.check_update_hook)(affmap_name, |
135 | 0 | new_pos); |
136 | 0 | return true; |
137 | 0 | } |
138 | | |
139 | | void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos) |
140 | 0 | { |
141 | 0 | struct affinity_map *map; |
142 | |
|
143 | 0 | if (!affinity_map_master.update_hook) |
144 | 0 | return; |
145 | | |
146 | 0 | map = affinity_map_get(affmap_name); |
147 | |
|
148 | 0 | if (!map) |
149 | | /* Affinity-map creation */ |
150 | 0 | return; |
151 | | |
152 | 0 | (*affinity_map_master.update_hook)(affmap_name, map->bit_position, |
153 | 0 | new_pos); |
154 | 0 | } |
155 | | |
156 | | |
157 | | void affinity_map_set_check_use_hook(bool (*func)(const char *affmap_name)) |
158 | 0 | { |
159 | 0 | affinity_map_master.check_use_hook = func; |
160 | 0 | } |
161 | | |
162 | | void affinity_map_set_check_update_hook(bool (*func)(const char *affmap_name, |
163 | | uint16_t new_pos)) |
164 | 0 | { |
165 | 0 | affinity_map_master.check_update_hook = func; |
166 | 0 | } |
167 | | |
168 | | void affinity_map_set_update_hook(void (*func)(const char *affmap_name, |
169 | | uint16_t old_pos, |
170 | | uint16_t new_pos)) |
171 | 0 | { |
172 | 0 | affinity_map_master.update_hook = func; |
173 | 0 | } |