back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_community_alias.c (source / functions) Hit Total Coverage
Test: test_bgp_minimum_holdtime.py::TestBGPMinimumHoldtime Lines: 14 100 14.0 %
Date: 2023-02-24 18:37:25 Functions: 3 22 13.6 %

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

Generated by: LCOV version v1.16-topotato