1 /* BGP community, large-community aliasing.
3 * Copyright (C) 2021 Donatas Abraitis <donatas.abraitis@gmail.com>
5 * This file is part of FRRouting (FRR).
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.
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
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
22 #include "lib/jhash.h"
25 #include "bgpd/bgpd.h"
26 #include "bgpd/bgp_community_alias.h"
28 static struct hash
*bgp_ca_alias_hash
;
29 static struct hash
*bgp_ca_community_hash
;
31 static unsigned int bgp_ca_community_hash_key(const void *p
)
33 const struct community_alias
*ca
= p
;
35 return jhash(ca
->community
, sizeof(ca
->community
), 0);
38 static bool bgp_ca_community_hash_cmp(const void *p1
, const void *p2
)
40 const struct community_alias
*ca1
= p1
;
41 const struct community_alias
*ca2
= p2
;
43 return (strcmp(ca1
->community
, ca2
->community
) == 0);
46 static unsigned int bgp_ca_alias_hash_key(const void *p
)
48 const struct community_alias
*ca
= p
;
50 return jhash(ca
->alias
, sizeof(ca
->alias
), 0);
53 static bool bgp_ca_alias_hash_cmp(const void *p1
, const void *p2
)
55 const struct community_alias
*ca1
= p1
;
56 const struct community_alias
*ca2
= p2
;
58 return (strcmp(ca1
->alias
, ca2
->alias
) == 0);
61 static void *bgp_community_alias_alloc(void *p
)
63 const struct community_alias
*ca
= p
;
64 struct communtiy_alias
*new;
66 new = XCALLOC(MTYPE_COMMUNITY_ALIAS
, sizeof(struct community_alias
));
67 memcpy(new, ca
, sizeof(struct community_alias
));
72 void bgp_community_alias_init(void)
74 bgp_ca_community_hash
= hash_create(bgp_ca_community_hash_key
,
75 bgp_ca_community_hash_cmp
,
76 "BGP community alias (community)");
78 hash_create(bgp_ca_alias_hash_key
, bgp_ca_alias_hash_cmp
,
79 "BGP community alias (alias)");
82 void bgp_community_alias_finish(void)
84 hash_free(bgp_ca_community_hash
);
85 hash_free(bgp_ca_alias_hash
);
88 static void bgp_community_alias_show_iterator(struct hash_bucket
*hb
,
91 struct community_alias
*ca
= hb
->data
;
93 vty_out(vty
, "bgp community alias %s %s\n", ca
->community
, ca
->alias
);
96 int bgp_community_alias_write(struct vty
*vty
)
98 hash_iterate(bgp_ca_community_hash
,
99 (void (*)(struct hash_bucket
*,
100 void *))bgp_community_alias_show_iterator
,
105 void bgp_ca_community_insert(struct community_alias
*ca
)
107 hash_get(bgp_ca_community_hash
, ca
, bgp_community_alias_alloc
);
110 void bgp_ca_alias_insert(struct community_alias
*ca
)
112 hash_get(bgp_ca_alias_hash
, ca
, bgp_community_alias_alloc
);
115 void bgp_ca_community_delete(struct community_alias
*ca
)
117 struct community_alias
*data
= hash_release(bgp_ca_community_hash
, ca
);
119 XFREE(MTYPE_COMMUNITY_ALIAS
, data
);
122 void bgp_ca_alias_delete(struct community_alias
*ca
)
124 struct community_alias
*data
= hash_release(bgp_ca_alias_hash
, ca
);
126 XFREE(MTYPE_COMMUNITY_ALIAS
, data
);
129 struct community_alias
*bgp_ca_community_lookup(struct community_alias
*ca
)
131 return hash_lookup(bgp_ca_community_hash
, ca
);
134 struct community_alias
*bgp_ca_alias_lookup(struct community_alias
*ca
)
136 return hash_lookup(bgp_ca_alias_hash
, ca
);
139 const char *bgp_community2alias(char *community
)
141 struct community_alias ca
;
142 struct community_alias
*find
;
144 memset(&ca
, 0, sizeof(ca
));
145 strlcpy(ca
.community
, community
, sizeof(ca
.community
));
147 find
= bgp_ca_community_lookup(&ca
);
154 const char *bgp_alias2community(char *alias
)
156 struct community_alias ca
;
157 struct community_alias
*find
;
159 memset(&ca
, 0, sizeof(ca
));
160 strlcpy(ca
.alias
, alias
, sizeof(ca
.alias
));
162 find
= bgp_ca_alias_lookup(&ca
);
164 return find
->community
;
169 /* Communities structs have `->str` which is used
170 * for vty outputs and extended BGP community lists
172 * This is a helper to convert already aliased version
173 * of communities into numerical-only format.
175 char *bgp_alias2community_str(const char *str
)
181 frrstr_split(str
, " ", &aliases
, &num
);
182 const char *communities
[num
];
184 for (i
= 0; i
< num
; i
++)
185 communities
[i
] = bgp_alias2community(aliases
[i
]);
187 comstr
= frrstr_join(communities
, num
, " ");
189 for (i
= 0; i
< num
; i
++)
190 XFREE(MTYPE_TMP
, aliases
[i
]);
191 XFREE(MTYPE_TMP
, aliases
);
196 static int bgp_community_alias_vector_walker(struct hash_bucket
*bucket
,
199 vector
*comps
= data
;
200 struct community_alias
*alias
= bucket
->data
;
202 vector_set(*comps
, XSTRDUP(MTYPE_COMPLETION
, alias
->alias
));
207 static void bgp_community_alias_cmd_completion(vector comps
,
208 struct cmd_token
*token
)
210 hash_walk(bgp_ca_alias_hash
, bgp_community_alias_vector_walker
, &comps
);
213 static 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
}};
220 void bgp_community_alias_command_completion_setup(void)
222 cmd_variable_handler_register(community_alias_handlers
);