diff options
| -rw-r--r-- | bgpd/bgp_clist.c | 1 | ||||
| -rw-r--r-- | bgpd/bgp_routemap.c | 11 | ||||
| -rw-r--r-- | ldpd/lde.c | 39 | ||||
| -rw-r--r-- | ldpd/lde.h | 1 | ||||
| -rw-r--r-- | ldpd/lde_lib.c | 3 | ||||
| -rw-r--r-- | lib/log.c | 4 | ||||
| -rw-r--r-- | tests/topotests/bgp_comm-list_delete/__init__.py | 0 | ||||
| -rw-r--r-- | tests/topotests/bgp_comm-list_delete/r1/bgpd.conf | 9 | ||||
| -rw-r--r-- | tests/topotests/bgp_comm-list_delete/r1/zebra.conf | 9 | ||||
| -rw-r--r-- | tests/topotests/bgp_comm-list_delete/r2/bgpd.conf | 11 | ||||
| -rw-r--r-- | tests/topotests/bgp_comm-list_delete/r2/zebra.conf | 6 | ||||
| -rw-r--r-- | tests/topotests/bgp_comm-list_delete/test_bgp_comm-list_delete.py | 105 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 2 |
13 files changed, 195 insertions, 6 deletions
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index ff2ea6f7cd..ad5553d9a0 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -823,6 +823,7 @@ struct community *community_list_match_delete(struct community *com, /* Delete all of the communities we flagged for deletion */ for (i = delete_index - 1; i >= 0; i--) { val = community_val_get(com, com_index_to_delete[i]); + val = htonl(val); community_del_val(com, &val); } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index dd3382a1e7..04043fdc8e 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -2174,12 +2174,19 @@ route_set_community_delete(void *rule, const struct prefix *prefix, static void *route_set_community_delete_compile(const char *arg) { struct rmap_community *rcom; + char **splits; + int num; - rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community)); + frrstr_split(arg, " ", &splits, &num); - rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); + rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community)); + rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, splits[0]); rcom->name_hash = bgp_clist_hash_key(rcom->name); + for (int i = 0; i < num; i++) + XFREE(MTYPE_TMP, splits[i]); + XFREE(MTYPE_TMP, splits); + return rcom; } diff --git a/ldpd/lde.c b/ldpd/lde.c index 0ddf4f07d9..ac680b47a9 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -1654,6 +1654,19 @@ lde_del_label_chunk(void *val) } static int +lde_release_label_chunk(uint32_t start, uint32_t end) +{ + int ret; + + ret = lm_release_label_chunk(zclient_sync, start, end); + if (ret < 0) { + log_warnx("Error releasing label chunk!"); + return (-1); + } + return (0); +} + +static int lde_get_label_chunk(void) { int ret; @@ -1709,6 +1722,32 @@ on_get_label_chunk_response(uint32_t start, uint32_t end) current_label_chunk = listtail(label_chunk_list); } +void +lde_free_label(uint32_t label) +{ + struct listnode *node; + struct label_chunk *label_chunk; + uint64_t pos; + + for (ALL_LIST_ELEMENTS_RO(label_chunk_list, node, label_chunk)) { + if (label <= label_chunk->end && label >= label_chunk->start) { + pos = 1ULL << (label - label_chunk->start); + label_chunk->used_mask &= ~pos; + /* if nobody is using this chunk and it's not current_label_chunk, then free it */ + if (!label_chunk->used_mask && (current_label_chunk != node)) { + if (lde_release_label_chunk(label_chunk->start, label_chunk->end) != 0) + log_warnx("%s: Error releasing label chunk!", __func__); + else { + listnode_delete(label_chunk_list, label_chunk); + lde_del_label_chunk(label_chunk); + } + } + break; + } + } + return; +} + static uint32_t lde_get_next_label(void) { diff --git a/ldpd/lde.h b/ldpd/lde.h index 94077d1631..0a7d0a58fe 100644 --- a/ldpd/lde.h +++ b/ldpd/lde.h @@ -147,6 +147,7 @@ void lde_imsg_compose_parent_sync(int, pid_t, void *, uint16_t); int lde_imsg_compose_ldpe(int, uint32_t, pid_t, void *, uint16_t); int lde_acl_check(char *, int, union ldpd_addr *, uint8_t); uint32_t lde_update_label(struct fec_node *); +void lde_free_label(uint32_t label); void lde_send_change_klabel(struct fec_node *, struct fec_nh *); void lde_send_delete_klabel(struct fec_node *, struct fec_nh *); void lde_fec2map(struct fec *, struct map *); diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index 28e455c7a5..0957a5455e 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -919,6 +919,9 @@ lde_gc_timer(struct thread *thread) !RB_EMPTY(lde_map_head, &fn->upstream)) continue; + if (fn->local_label != NO_LABEL) + lde_free_label(fn->local_label); + fec_remove(&ft, &fn->fec); free(fn); count++; @@ -387,10 +387,8 @@ void vzlog(int priority, const char *format, va_list args) /* If it doesn't match on a filter, do nothing with the debug log */ if ((priority == LOG_DEBUG) && zlog_filter_count - && vzlog_filter(zl, &tsctl, proto_str, priority, msg)) { - pthread_mutex_unlock(&loglock); + && vzlog_filter(zl, &tsctl, proto_str, priority, msg)) goto out; - } /* call external hook */ hook_call(zebra_ext_log, priority, format, args); diff --git a/tests/topotests/bgp_comm-list_delete/__init__.py b/tests/topotests/bgp_comm-list_delete/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_comm-list_delete/__init__.py diff --git a/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf b/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf new file mode 100644 index 0000000000..6e1273f464 --- /dev/null +++ b/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf @@ -0,0 +1,9 @@ +router bgp 65000 + neighbor 192.168.255.2 remote-as 65001 + address-family ipv4 unicast + redistribute connected route-map r2-out + exit-address-family +! +route-map r2-out permit 10 + set community 111:111 222:222 333:333 444:444 +! diff --git a/tests/topotests/bgp_comm-list_delete/r1/zebra.conf b/tests/topotests/bgp_comm-list_delete/r1/zebra.conf new file mode 100644 index 0000000000..0a283c06d5 --- /dev/null +++ b/tests/topotests/bgp_comm-list_delete/r1/zebra.conf @@ -0,0 +1,9 @@ +! +interface lo + ip address 172.16.255.254/32 +! +interface r1-eth0 + ip address 192.168.255.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf b/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf new file mode 100644 index 0000000000..3d354d56b1 --- /dev/null +++ b/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf @@ -0,0 +1,11 @@ +router bgp 65001 + neighbor 192.168.255.1 remote-as 65000 + address-family ipv4 + neighbor 192.168.255.1 route-map r1-in in + exit-address-family +! +bgp community-list standard r1 permit 333:333 +! +route-map r1-in permit 10 + set comm-list r1 delete +! diff --git a/tests/topotests/bgp_comm-list_delete/r2/zebra.conf b/tests/topotests/bgp_comm-list_delete/r2/zebra.conf new file mode 100644 index 0000000000..606c17bec9 --- /dev/null +++ b/tests/topotests/bgp_comm-list_delete/r2/zebra.conf @@ -0,0 +1,6 @@ +! +interface r2-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_comm-list_delete/test_bgp_comm-list_delete.py b/tests/topotests/bgp_comm-list_delete/test_bgp_comm-list_delete.py new file mode 100644 index 0000000000..de6c35ba8f --- /dev/null +++ b/tests/topotests/bgp_comm-list_delete/test_bgp_comm-list_delete.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +# +# bgp_comm-list_delete.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2019 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +bgp_comm-list_delete.py: + +Test if works the following commands: +route-map test permit 10 + set comm-list <arg> delete +""" + +import os +import sys +import json +import time +import pytest + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, '../')) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + +class TemplateTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + for routern in range(1, 3): + tgen.add_router('r{}'.format(routern)) + + switch = tgen.add_switch('s1') + switch.add_link(tgen.gears['r1']) + switch.add_link(tgen.gears['r2']) + +def setup_module(mod): + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.iteritems(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, + os.path.join(CWD, '{}/zebra.conf'.format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, + os.path.join(CWD, '{}/bgpd.conf'.format(rname)) + ) + + tgen.start_router() + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + +def test_bgp_maximum_prefix_invalid(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_converge(router): + while True: + output = json.loads(tgen.gears[router].vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + if output['192.168.255.1']['bgpState'] == 'Established': + if output['192.168.255.1']['addressFamilyInfo']['IPv4 Unicast']['acceptedPrefixCounter'] == 2: + return True + + def _bgp_comm_list_delete(router): + output = json.loads(tgen.gears[router].vtysh_cmd("show ip bgp 172.16.255.254/32 json")) + if '333:333' in output['paths'][0]['community']['list']: + return False + return True + + if _bgp_converge('r2'): + assert _bgp_comm_list_delete('r2') == True + +if __name__ == '__main__': + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index ca19971d64..f3721c478d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1774,7 +1774,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) /* Redistribute */ redistribute_update(dest_pfx, src_pfx, - re, NULL); + re, old_re); } /* |
