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 (strncmp(ca1
->community
, ca2
->community
,
44 sizeof(struct community_alias
))
48 static unsigned int bgp_ca_alias_hash_key(const void *p
)
50 const struct community_alias
*ca
= p
;
52 return jhash(ca
->alias
, sizeof(ca
->alias
), 0);
55 static bool bgp_ca_alias_hash_cmp(const void *p1
, const void *p2
)
57 const struct community_alias
*ca1
= p1
;
58 const struct community_alias
*ca2
= p2
;
60 return (strncmp(ca1
->alias
, ca2
->alias
, sizeof(struct community_alias
))
64 static void *bgp_community_alias_alloc(void *p
)
66 const struct community_alias
*ca
= p
;
67 struct communtiy_alias
*new;
69 new = XCALLOC(MTYPE_COMMUNITY_ALIAS
, sizeof(struct community_alias
));
70 memcpy(new, ca
, sizeof(struct community_alias
));
75 void bgp_community_alias_init(void)
77 bgp_ca_community_hash
= hash_create(bgp_ca_community_hash_key
,
78 bgp_ca_community_hash_cmp
,
79 "BGP community alias (community)");
81 hash_create(bgp_ca_alias_hash_key
, bgp_ca_alias_hash_cmp
,
82 "BGP community alias (alias)");
85 void bgp_community_alias_finish(void)
87 hash_free(bgp_ca_community_hash
);
88 hash_free(bgp_ca_alias_hash
);
91 static void bgp_community_alias_show_iterator(struct hash_bucket
*hb
,
94 struct community_alias
*ca
= hb
->data
;
96 vty_out(vty
, "bgp community alias %s %s\n", ca
->community
, ca
->alias
);
99 int bgp_community_alias_write(struct vty
*vty
)
101 hash_iterate(bgp_ca_community_hash
,
102 (void (*)(struct hash_bucket
*,
103 void *))bgp_community_alias_show_iterator
,
108 void bgp_ca_community_insert(struct community_alias
*ca
)
110 hash_get(bgp_ca_community_hash
, ca
, bgp_community_alias_alloc
);
113 void bgp_ca_alias_insert(struct community_alias
*ca
)
115 hash_get(bgp_ca_alias_hash
, ca
, bgp_community_alias_alloc
);
118 void bgp_ca_community_delete(struct community_alias
*ca
)
120 struct community_alias
*data
= hash_release(bgp_ca_community_hash
, ca
);
122 XFREE(MTYPE_COMMUNITY_ALIAS
, data
);
125 void bgp_ca_alias_delete(struct community_alias
*ca
)
127 struct community_alias
*data
= hash_release(bgp_ca_alias_hash
, ca
);
129 XFREE(MTYPE_COMMUNITY_ALIAS
, data
);
132 struct community_alias
*bgp_ca_community_lookup(struct community_alias
*ca
)
134 return hash_lookup(bgp_ca_community_hash
, ca
);
137 struct community_alias
*bgp_ca_alias_lookup(struct community_alias
*ca
)
139 return hash_lookup(bgp_ca_alias_hash
, ca
);
142 const char *bgp_community2alias(char *community
)
144 struct community_alias ca
;
145 struct community_alias
*find
;
147 memset(&ca
, 0, sizeof(ca
));
148 strlcpy(ca
.community
, community
, sizeof(ca
.community
));
150 find
= bgp_ca_community_lookup(&ca
);
157 const char *bgp_alias2community(char *alias
)
159 struct community_alias ca
;
160 struct community_alias
*find
;
162 memset(&ca
, 0, sizeof(ca
));
163 strlcpy(ca
.alias
, alias
, sizeof(ca
.alias
));
165 find
= bgp_ca_alias_lookup(&ca
);
167 return find
->community
;
172 /* Communities structs have `->str` which is used
173 * for vty outputs and extended BGP community lists
175 * This is a helper to convert already aliased version
176 * of communities into numerical-only format.
178 char *bgp_alias2community_str(const char *str
)
184 frrstr_split(str
, " ", &aliases
, &num
);
185 const char *communities
[num
];
187 for (i
= 0; i
< num
; i
++)
188 communities
[i
] = bgp_alias2community(aliases
[i
]);
190 comstr
= frrstr_join(communities
, num
, " ");
192 for (i
= 0; i
< num
; i
++)
193 XFREE(MTYPE_TMP
, aliases
[i
]);
194 XFREE(MTYPE_TMP
, aliases
);
199 static int bgp_community_alias_vector_walker(struct hash_bucket
*bucket
,
202 vector
*comps
= data
;
203 struct community_alias
*alias
= bucket
->data
;
205 vector_set(*comps
, XSTRDUP(MTYPE_COMPLETION
, alias
->alias
));
210 static void bgp_community_alias_cmd_completion(vector comps
,
211 struct cmd_token
*token
)
213 hash_walk(bgp_ca_alias_hash
, bgp_community_alias_vector_walker
, &comps
);
216 static const struct cmd_variable_handler community_alias_handlers
[] = {
217 {.varname
= "alias_name",
218 .completions
= bgp_community_alias_cmd_completion
},
219 {.tokenname
= "ALIAS_NAME",
220 .completions
= bgp_community_alias_cmd_completion
},
221 {.completions
= NULL
}};
223 void bgp_community_alias_command_completion_setup(void)
225 cmd_variable_handler_register(community_alias_handlers
);