]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_community_alias.c
Merge pull request #9374 from mjstapp/fix_nhg_add_leak
[mirror_frr.git] / bgpd / bgp_community_alias.c
CommitLineData
ed0e57e3
DA
1/* BGP community, large-community aliasing.
2 *
3 * Copyright (C) 2021 Donatas Abraitis <donatas.abraitis@gmail.com>
4 *
5 * This file is part of FRRouting (FRR).
6 *
7 * FRR is free software; you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation; either version 2, or (at your option) any later version.
10 *
11 * FRR is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "memory.h"
22#include "lib/jhash.h"
f4dd8296 23#include "frrstr.h"
ed0e57e3
DA
24
25#include "bgpd/bgpd.h"
26#include "bgpd/bgp_community_alias.h"
27
28static struct hash *bgp_ca_alias_hash;
29static struct hash *bgp_ca_community_hash;
30
31static unsigned int bgp_ca_community_hash_key(const void *p)
32{
33 const struct community_alias *ca = p;
34
35 return jhash(ca->community, sizeof(ca->community), 0);
36}
37
38static bool bgp_ca_community_hash_cmp(const void *p1, const void *p2)
39{
40 const struct community_alias *ca1 = p1;
41 const struct community_alias *ca2 = p2;
42
43 return (strncmp(ca1->community, ca2->community,
44 sizeof(struct community_alias))
45 == 0);
46}
47
48static unsigned int bgp_ca_alias_hash_key(const void *p)
49{
50 const struct community_alias *ca = p;
51
52 return jhash(ca->alias, sizeof(ca->alias), 0);
53}
54
55static bool bgp_ca_alias_hash_cmp(const void *p1, const void *p2)
56{
57 const struct community_alias *ca1 = p1;
58 const struct community_alias *ca2 = p2;
59
60 return (strncmp(ca1->alias, ca2->alias, sizeof(struct community_alias))
61 == 0);
62}
63
64static void *bgp_community_alias_alloc(void *p)
65{
66 const struct community_alias *ca = p;
67 struct communtiy_alias *new;
68
69 new = XCALLOC(MTYPE_COMMUNITY_ALIAS, sizeof(struct community_alias));
70 memcpy(new, ca, sizeof(struct community_alias));
71
72 return new;
73}
74
75void bgp_community_alias_init(void)
76{
77 bgp_ca_community_hash = hash_create(bgp_ca_community_hash_key,
78 bgp_ca_community_hash_cmp,
79 "BGP community alias (community)");
80 bgp_ca_alias_hash =
81 hash_create(bgp_ca_alias_hash_key, bgp_ca_alias_hash_cmp,
82 "BGP community alias (alias)");
83}
84
85void bgp_community_alias_finish(void)
86{
87 hash_free(bgp_ca_community_hash);
88 hash_free(bgp_ca_alias_hash);
89}
90
91static void bgp_community_alias_show_iterator(struct hash_bucket *hb,
92 struct vty *vty)
93{
94 struct community_alias *ca = hb->data;
95
96 vty_out(vty, "bgp community alias %s %s\n", ca->community, ca->alias);
97}
98
99int bgp_community_alias_write(struct vty *vty)
100{
101 hash_iterate(bgp_ca_community_hash,
102 (void (*)(struct hash_bucket *,
103 void *))bgp_community_alias_show_iterator,
104 vty);
105 return 1;
106}
107
108void bgp_ca_community_insert(struct community_alias *ca)
109{
110 hash_get(bgp_ca_community_hash, ca, bgp_community_alias_alloc);
111}
112
113void bgp_ca_alias_insert(struct community_alias *ca)
114{
115 hash_get(bgp_ca_alias_hash, ca, bgp_community_alias_alloc);
116}
117
118void bgp_ca_community_delete(struct community_alias *ca)
119{
120 struct community_alias *data = hash_release(bgp_ca_community_hash, ca);
121
122 XFREE(MTYPE_COMMUNITY_ALIAS, data);
123}
124
125void bgp_ca_alias_delete(struct community_alias *ca)
126{
127 struct community_alias *data = hash_release(bgp_ca_alias_hash, ca);
128
129 XFREE(MTYPE_COMMUNITY_ALIAS, data);
130}
131
132struct community_alias *bgp_ca_community_lookup(struct community_alias *ca)
133{
134 return hash_lookup(bgp_ca_community_hash, ca);
135}
136
137struct community_alias *bgp_ca_alias_lookup(struct community_alias *ca)
138{
139 return hash_lookup(bgp_ca_alias_hash, ca);
140}
141
142const char *bgp_community2alias(char *community)
143{
144 struct community_alias ca;
145 struct community_alias *find;
146
147 memset(&ca, 0, sizeof(ca));
148 strlcpy(ca.community, community, sizeof(ca.community));
149
150 find = bgp_ca_community_lookup(&ca);
151 if (find)
152 return find->alias;
153
154 return community;
155}
b4ad2fae 156
f4dd8296
DA
157const char *bgp_alias2community(char *alias)
158{
159 struct community_alias ca;
160 struct community_alias *find;
161
162 memset(&ca, 0, sizeof(ca));
163 strlcpy(ca.alias, alias, sizeof(ca.alias));
164
165 find = bgp_ca_alias_lookup(&ca);
166 if (find)
167 return find->community;
168
169 return alias;
170}
171
172/* Communities structs have `->str` which is used
173 * for vty outputs and extended BGP community lists
174 * with regexp.
175 * This is a helper to convert already aliased version
176 * of communities into numerical-only format.
177 */
178const char *bgp_alias2community_str(const char *str)
179{
180 char **aliases;
181 int num;
182
183 frrstr_split(str, " ", &aliases, &num);
184 const char *communities[num + 1];
185
186 for (int i = 0; i < num; i++) {
187 communities[i] =
188 XSTRDUP(MTYPE_TMP, bgp_alias2community(aliases[i]));
189 XFREE(MTYPE_TMP, aliases[i]);
190 }
191 XFREE(MTYPE_TMP, aliases);
192
193 return frrstr_join(communities, num, " ");
194}
195
b4ad2fae
DS
196static int bgp_community_alias_vector_walker(struct hash_bucket *bucket,
197 void *data)
198{
199 vector *comps = data;
200 struct community_alias *alias = bucket->data;
201
202 vector_set(*comps, XSTRDUP(MTYPE_COMPLETION, alias->alias));
203
204 return 1;
205}
206
207static void bgp_community_alias_cmd_completion(vector comps,
208 struct cmd_token *token)
209{
210 hash_walk(bgp_ca_alias_hash, bgp_community_alias_vector_walker, &comps);
211}
212
213static const struct cmd_variable_handler community_alias_handlers[] = {
214 {.varname = "alias_name",
215 .completions = bgp_community_alias_cmd_completion},
216 {.tokenname = "ALIAS_NAME",
217 .completions = bgp_community_alias_cmd_completion},
218 {.completions = NULL}};
219
220void bgp_community_alias_command_completion_setup(void)
221{
222 cmd_variable_handler_register(community_alias_handlers);
223}