]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_community_alias.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / bgpd / bgp_community_alias.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
ed0e57e3
DA
2/* BGP community, large-community aliasing.
3 *
4 * Copyright (C) 2021 Donatas Abraitis <donatas.abraitis@gmail.com>
ed0e57e3
DA
5 */
6
5b4f4e62
DL
7#include "zebra.h"
8
ed0e57e3
DA
9#include "memory.h"
10#include "lib/jhash.h"
f4dd8296 11#include "frrstr.h"
ed0e57e3
DA
12
13#include "bgpd/bgpd.h"
14#include "bgpd/bgp_community_alias.h"
15
16static struct hash *bgp_ca_alias_hash;
17static struct hash *bgp_ca_community_hash;
18
19static unsigned int bgp_ca_community_hash_key(const void *p)
20{
21 const struct community_alias *ca = p;
22
23 return jhash(ca->community, sizeof(ca->community), 0);
24}
25
26static bool bgp_ca_community_hash_cmp(const void *p1, const void *p2)
27{
28 const struct community_alias *ca1 = p1;
29 const struct community_alias *ca2 = p2;
30
c975f1a5 31 return (strcmp(ca1->community, ca2->community) == 0);
ed0e57e3
DA
32}
33
34static unsigned int bgp_ca_alias_hash_key(const void *p)
35{
36 const struct community_alias *ca = p;
37
38 return jhash(ca->alias, sizeof(ca->alias), 0);
39}
40
41static bool bgp_ca_alias_hash_cmp(const void *p1, const void *p2)
42{
43 const struct community_alias *ca1 = p1;
44 const struct community_alias *ca2 = p2;
45
c975f1a5 46 return (strcmp(ca1->alias, ca2->alias) == 0);
ed0e57e3
DA
47}
48
49static void *bgp_community_alias_alloc(void *p)
50{
51 const struct community_alias *ca = p;
52 struct communtiy_alias *new;
53
54 new = XCALLOC(MTYPE_COMMUNITY_ALIAS, sizeof(struct community_alias));
55 memcpy(new, ca, sizeof(struct community_alias));
56
57 return new;
58}
59
60void bgp_community_alias_init(void)
61{
62 bgp_ca_community_hash = hash_create(bgp_ca_community_hash_key,
63 bgp_ca_community_hash_cmp,
64 "BGP community alias (community)");
65 bgp_ca_alias_hash =
66 hash_create(bgp_ca_alias_hash_key, bgp_ca_alias_hash_cmp,
67 "BGP community alias (alias)");
68}
69
176d7bea
DA
70static void bgp_ca_free(void *ca)
71{
72 XFREE(MTYPE_COMMUNITY_ALIAS, ca);
73}
74
ed0e57e3
DA
75void bgp_community_alias_finish(void)
76{
176d7bea 77 hash_clean(bgp_ca_community_hash, bgp_ca_free);
ed0e57e3 78 hash_free(bgp_ca_community_hash);
176d7bea 79 hash_clean(bgp_ca_alias_hash, bgp_ca_free);
ed0e57e3
DA
80 hash_free(bgp_ca_alias_hash);
81}
82
83static void bgp_community_alias_show_iterator(struct hash_bucket *hb,
84 struct vty *vty)
85{
86 struct community_alias *ca = hb->data;
87
88 vty_out(vty, "bgp community alias %s %s\n", ca->community, ca->alias);
89}
90
91int bgp_community_alias_write(struct vty *vty)
92{
93 hash_iterate(bgp_ca_community_hash,
94 (void (*)(struct hash_bucket *,
95 void *))bgp_community_alias_show_iterator,
96 vty);
97 return 1;
98}
99
100void bgp_ca_community_insert(struct community_alias *ca)
101{
8e3aae66 102 (void)hash_get(bgp_ca_community_hash, ca, bgp_community_alias_alloc);
ed0e57e3
DA
103}
104
105void bgp_ca_alias_insert(struct community_alias *ca)
106{
8e3aae66 107 (void)hash_get(bgp_ca_alias_hash, ca, bgp_community_alias_alloc);
ed0e57e3
DA
108}
109
110void bgp_ca_community_delete(struct community_alias *ca)
111{
112 struct community_alias *data = hash_release(bgp_ca_community_hash, ca);
113
114 XFREE(MTYPE_COMMUNITY_ALIAS, data);
115}
116
117void bgp_ca_alias_delete(struct community_alias *ca)
118{
119 struct community_alias *data = hash_release(bgp_ca_alias_hash, ca);
120
121 XFREE(MTYPE_COMMUNITY_ALIAS, data);
122}
123
124struct community_alias *bgp_ca_community_lookup(struct community_alias *ca)
125{
126 return hash_lookup(bgp_ca_community_hash, ca);
127}
128
129struct community_alias *bgp_ca_alias_lookup(struct community_alias *ca)
130{
131 return hash_lookup(bgp_ca_alias_hash, ca);
132}
133
134const char *bgp_community2alias(char *community)
135{
136 struct community_alias ca;
137 struct community_alias *find;
138
139 memset(&ca, 0, sizeof(ca));
140 strlcpy(ca.community, community, sizeof(ca.community));
141
142 find = bgp_ca_community_lookup(&ca);
143 if (find)
144 return find->alias;
145
146 return community;
147}
b4ad2fae 148
f4dd8296
DA
149const char *bgp_alias2community(char *alias)
150{
151 struct community_alias ca;
152 struct community_alias *find;
153
154 memset(&ca, 0, sizeof(ca));
155 strlcpy(ca.alias, alias, sizeof(ca.alias));
156
157 find = bgp_ca_alias_lookup(&ca);
158 if (find)
159 return find->community;
160
161 return alias;
162}
163
164/* Communities structs have `->str` which is used
165 * for vty outputs and extended BGP community lists
166 * with regexp.
167 * This is a helper to convert already aliased version
168 * of communities into numerical-only format.
169 */
15bc6a40 170char *bgp_alias2community_str(const char *str)
f4dd8296
DA
171{
172 char **aliases;
15bc6a40
IR
173 char *comstr;
174 int num, i;
f4dd8296
DA
175
176 frrstr_split(str, " ", &aliases, &num);
15bc6a40 177 const char *communities[num];
f4dd8296 178
15bc6a40
IR
179 for (i = 0; i < num; i++)
180 communities[i] = bgp_alias2community(aliases[i]);
181
182 comstr = frrstr_join(communities, num, " ");
183
184 for (i = 0; i < num; i++)
f4dd8296 185 XFREE(MTYPE_TMP, aliases[i]);
f4dd8296
DA
186 XFREE(MTYPE_TMP, aliases);
187
15bc6a40 188 return comstr;
f4dd8296
DA
189}
190
b4ad2fae
DS
191static int bgp_community_alias_vector_walker(struct hash_bucket *bucket,
192 void *data)
193{
194 vector *comps = data;
195 struct community_alias *alias = bucket->data;
196
197 vector_set(*comps, XSTRDUP(MTYPE_COMPLETION, alias->alias));
198
199 return 1;
200}
201
202static void bgp_community_alias_cmd_completion(vector comps,
203 struct cmd_token *token)
204{
205 hash_walk(bgp_ca_alias_hash, bgp_community_alias_vector_walker, &comps);
206}
207
208static const struct cmd_variable_handler community_alias_handlers[] = {
209 {.varname = "alias_name",
210 .completions = bgp_community_alias_cmd_completion},
211 {.tokenname = "ALIAS_NAME",
212 .completions = bgp_community_alias_cmd_completion},
213 {.completions = NULL}};
214
215void bgp_community_alias_command_completion_setup(void)
216{
217 cmd_variable_handler_register(community_alias_handlers);
218}