1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP community, large-community aliasing.
4 * Copyright (C) 2021 Donatas Abraitis <donatas.abraitis@gmail.com>
10 #include "lib/jhash.h"
13 #include "bgpd/bgpd.h"
14 #include "bgpd/bgp_community_alias.h"
16 static struct hash
*bgp_ca_alias_hash
;
17 static struct hash
*bgp_ca_community_hash
;
19 static unsigned int bgp_ca_community_hash_key(const void *p
)
21 const struct community_alias
*ca
= p
;
23 return jhash(ca
->community
, sizeof(ca
->community
), 0);
26 static bool bgp_ca_community_hash_cmp(const void *p1
, const void *p2
)
28 const struct community_alias
*ca1
= p1
;
29 const struct community_alias
*ca2
= p2
;
31 return (strcmp(ca1
->community
, ca2
->community
) == 0);
34 static unsigned int bgp_ca_alias_hash_key(const void *p
)
36 const struct community_alias
*ca
= p
;
38 return jhash(ca
->alias
, sizeof(ca
->alias
), 0);
41 static bool bgp_ca_alias_hash_cmp(const void *p1
, const void *p2
)
43 const struct community_alias
*ca1
= p1
;
44 const struct community_alias
*ca2
= p2
;
46 return (strcmp(ca1
->alias
, ca2
->alias
) == 0);
49 static void *bgp_community_alias_alloc(void *p
)
51 const struct community_alias
*ca
= p
;
52 struct communtiy_alias
*new;
54 new = XCALLOC(MTYPE_COMMUNITY_ALIAS
, sizeof(struct community_alias
));
55 memcpy(new, ca
, sizeof(struct community_alias
));
60 void bgp_community_alias_init(void)
62 bgp_ca_community_hash
= hash_create(bgp_ca_community_hash_key
,
63 bgp_ca_community_hash_cmp
,
64 "BGP community alias (community)");
66 hash_create(bgp_ca_alias_hash_key
, bgp_ca_alias_hash_cmp
,
67 "BGP community alias (alias)");
70 static void bgp_ca_free(void *ca
)
72 XFREE(MTYPE_COMMUNITY_ALIAS
, ca
);
75 void bgp_community_alias_finish(void)
77 hash_clean(bgp_ca_community_hash
, bgp_ca_free
);
78 hash_free(bgp_ca_community_hash
);
79 hash_clean(bgp_ca_alias_hash
, bgp_ca_free
);
80 hash_free(bgp_ca_alias_hash
);
83 static void bgp_community_alias_show_iterator(struct hash_bucket
*hb
,
86 struct community_alias
*ca
= hb
->data
;
88 vty_out(vty
, "bgp community alias %s %s\n", ca
->community
, ca
->alias
);
91 int bgp_community_alias_write(struct vty
*vty
)
93 hash_iterate(bgp_ca_community_hash
,
94 (void (*)(struct hash_bucket
*,
95 void *))bgp_community_alias_show_iterator
,
100 void bgp_ca_community_insert(struct community_alias
*ca
)
102 (void)hash_get(bgp_ca_community_hash
, ca
, bgp_community_alias_alloc
);
105 void bgp_ca_alias_insert(struct community_alias
*ca
)
107 (void)hash_get(bgp_ca_alias_hash
, ca
, bgp_community_alias_alloc
);
110 void bgp_ca_community_delete(struct community_alias
*ca
)
112 struct community_alias
*data
= hash_release(bgp_ca_community_hash
, ca
);
114 XFREE(MTYPE_COMMUNITY_ALIAS
, data
);
117 void bgp_ca_alias_delete(struct community_alias
*ca
)
119 struct community_alias
*data
= hash_release(bgp_ca_alias_hash
, ca
);
121 XFREE(MTYPE_COMMUNITY_ALIAS
, data
);
124 struct community_alias
*bgp_ca_community_lookup(struct community_alias
*ca
)
126 return hash_lookup(bgp_ca_community_hash
, ca
);
129 struct community_alias
*bgp_ca_alias_lookup(struct community_alias
*ca
)
131 return hash_lookup(bgp_ca_alias_hash
, ca
);
134 const char *bgp_community2alias(char *community
)
136 struct community_alias ca
;
137 struct community_alias
*find
;
139 memset(&ca
, 0, sizeof(ca
));
140 strlcpy(ca
.community
, community
, sizeof(ca
.community
));
142 find
= bgp_ca_community_lookup(&ca
);
149 const char *bgp_alias2community(char *alias
)
151 struct community_alias ca
;
152 struct community_alias
*find
;
154 memset(&ca
, 0, sizeof(ca
));
155 strlcpy(ca
.alias
, alias
, sizeof(ca
.alias
));
157 find
= bgp_ca_alias_lookup(&ca
);
159 return find
->community
;
164 /* Communities structs have `->str` which is used
165 * for vty outputs and extended BGP community lists
167 * This is a helper to convert already aliased version
168 * of communities into numerical-only format.
170 char *bgp_alias2community_str(const char *str
)
176 frrstr_split(str
, " ", &aliases
, &num
);
177 const char *communities
[num
];
179 for (i
= 0; i
< num
; i
++)
180 communities
[i
] = bgp_alias2community(aliases
[i
]);
182 comstr
= frrstr_join(communities
, num
, " ");
184 for (i
= 0; i
< num
; i
++)
185 XFREE(MTYPE_TMP
, aliases
[i
]);
186 XFREE(MTYPE_TMP
, aliases
);
191 static int bgp_community_alias_vector_walker(struct hash_bucket
*bucket
,
194 vector
*comps
= data
;
195 struct community_alias
*alias
= bucket
->data
;
197 vector_set(*comps
, XSTRDUP(MTYPE_COMPLETION
, alias
->alias
));
202 static void bgp_community_alias_cmd_completion(vector comps
,
203 struct cmd_token
*token
)
205 hash_walk(bgp_ca_alias_hash
, bgp_community_alias_vector_walker
, &comps
);
208 static 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
}};
215 void bgp_community_alias_command_completion_setup(void)
217 cmd_variable_handler_register(community_alias_handlers
);