diff options
156 files changed, 2293 insertions, 1136 deletions
diff --git a/Makefile.am b/Makefile.am index fb052a8dea..65aed79152 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,6 +12,7 @@ AM_CPPFLAGS = \ -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib AM_LDFLAGS = \ -export-dynamic \ + $(AC_LDFLAGS) \ $(SAN_FLAGS) \ # end DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE) @@ -154,6 +155,7 @@ EXTRA_DIST += \ aclocal.m4 \ README.md \ m4/README.txt \ + m4/libtool-whole-archive.patch \ \ python/clidef.py \ python/clippy/__init__.py \ diff --git a/bfdd/bfd.c b/bfdd/bfd.c index cf7c027db5..8d9de857f5 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -157,7 +157,8 @@ void ptm_bfd_echo_stop(struct bfd_session *bfd, int polling) void ptm_bfd_echo_start(struct bfd_session *bfd) { bfd->echo_detect_TO = (bfd->remote_detect_mult * bfd->echo_xmt_TO); - ptm_bfd_echo_xmt_TO(bfd); + if (bfd->echo_detect_TO > 0) + ptm_bfd_echo_xmt_TO(bfd); bfd->polling = 1; bfd->new_timers.desired_min_tx = bfd->up_min_tx; @@ -324,7 +325,8 @@ int bfd_echo_xmt_cb(struct thread *t) { struct bfd_session *bs = THREAD_ARG(t); - ptm_bfd_echo_xmt_TO(bs); + if (bs->echo_xmt_TO > 0) + ptm_bfd_echo_xmt_TO(bs); return 0; } diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index 8acb9438c5..1ba5ee826f 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -197,7 +197,8 @@ static int ptm_bfd_process_echo_pkt(int s) bfd->echo_detect_TO = bfd->remote_detect_mult * bfd->echo_xmt_TO; /* Update echo receive timeout. */ - bfd_echo_recvtimer_update(bfd); + if (bfd->echo_detect_TO > 0) + bfd_echo_recvtimer_update(bfd); return 0; } diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index 1c6d03195c..51dd9cb26d 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -886,14 +886,7 @@ static int bfd_configure_peer(struct bfd_peer_cfg *bpc, bool mhop, if (local) bpc->bpc_local = *local; - if (peer) { - bpc->bpc_peer = *peer; - } else { - /* Peer configuration is mandatory. */ - snprintf(ebuf, ebuflen, "no peer configured"); - return -1; - } - + bpc->bpc_peer = *peer; bpc->bpc_mhop = mhop; /* Handle interface specification configuration. */ diff --git a/bfdd/event.c b/bfdd/event.c index 63f64077eb..3f48921af9 100644 --- a/bfdd/event.c +++ b/bfdd/event.c @@ -39,6 +39,9 @@ void bfd_recvtimer_update(struct bfd_session *bs) { struct timeval tv = {.tv_sec = 0, .tv_usec = bs->detect_TO}; + /* Remove previous schedule if any. */ + bfd_recvtimer_delete(bs); + /* Don't add event if peer is deactivated. */ if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN)) return; @@ -48,9 +51,6 @@ void bfd_recvtimer_update(struct bfd_session *bs) log_debug("%s: sec = %ld, usec = %ld", __func__, tv.tv_sec, tv.tv_usec); #endif /* BFD_EVENT_DEBUG */ - /* Remove previous schedule if any. */ - bfd_recvtimer_delete(bs); - thread_add_timer_tv(master, bfd_recvtimer_cb, bs, &tv, &bs->recvtimer_ev); } @@ -59,6 +59,9 @@ void bfd_echo_recvtimer_update(struct bfd_session *bs) { struct timeval tv = {.tv_sec = 0, .tv_usec = bs->echo_detect_TO}; + /* Remove previous schedule if any. */ + bfd_echo_recvtimer_delete(bs); + /* Don't add event if peer is deactivated. */ if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN)) return; @@ -68,9 +71,6 @@ void bfd_echo_recvtimer_update(struct bfd_session *bs) log_debug("%s: sec = %ld, usec = %ld", __func__, tv.tv_sec, tv.tv_usec); #endif /* BFD_EVENT_DEBUG */ - /* Remove previous schedule if any. */ - bfd_echo_recvtimer_delete(bs); - thread_add_timer_tv(master, bfd_echo_recvtimer_cb, bs, &tv, &bs->echo_recvtimer_ev); } @@ -79,6 +79,9 @@ void bfd_xmttimer_update(struct bfd_session *bs, uint64_t jitter) { struct timeval tv = {.tv_sec = 0, .tv_usec = jitter}; + /* Remove previous schedule if any. */ + bfd_xmttimer_delete(bs); + /* Don't add event if peer is deactivated. */ if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN)) return; @@ -88,9 +91,6 @@ void bfd_xmttimer_update(struct bfd_session *bs, uint64_t jitter) log_debug("%s: sec = %ld, usec = %ld", __func__, tv.tv_sec, tv.tv_usec); #endif /* BFD_EVENT_DEBUG */ - /* Remove previous schedule if any. */ - bfd_xmttimer_delete(bs); - thread_add_timer_tv(master, bfd_xmt_cb, bs, &tv, &bs->xmttimer_ev); } @@ -98,6 +98,9 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter) { struct timeval tv = {.tv_sec = 0, .tv_usec = jitter}; + /* Remove previous schedule if any. */ + bfd_echo_xmttimer_delete(bs); + /* Don't add event if peer is deactivated. */ if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN)) return; @@ -107,9 +110,6 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter) log_debug("%s: sec = %ld, usec = %ld", __func__, tv.tv_sec, tv.tv_usec); #endif /* BFD_EVENT_DEBUG */ - /* Remove previous schedule if any. */ - bfd_echo_xmttimer_delete(bs); - thread_add_timer_tv(master, bfd_echo_xmt_cb, bs, &tv, &bs->echo_xmttimer_ev); } diff --git a/bgpd/bgp_errors.c b/bgpd/bgp_errors.c index bd42901c2d..7cebd0e484 100644 --- a/bgpd/bgp_errors.c +++ b/bgpd/bgp_errors.c @@ -463,6 +463,12 @@ static struct log_ref ferr_bgp_err[] = { .suggestion = "Gather log files from the router and open an issue, Restart FRR" }, { + .code = EC_BGP_DOPPELGANGER_CONFIG, + .title = "BGP has detected a configuration overwrite during peer collision resolution", + .description = "As part of BGP startup, the peer and ourselves can start connections to each other at the same time. During this process BGP received additional configuration, but it was only applied to one of the two nascent connections. Depending on the result of collision detection and resolution this configuration might be lost. To remedy this, after performing collision detection and resolution the peer session has been reset in order to apply the new configuration.", + .suggestion = "Gather data and open a Issue so that this developmental escape can be fixed, the peer should have been reset", + }, + { .code = END_FERR, } }; diff --git a/bgpd/bgp_errors.h b/bgpd/bgp_errors.h index 853f2da222..13bd318e27 100644 --- a/bgpd/bgp_errors.h +++ b/bgpd/bgp_errors.h @@ -99,6 +99,7 @@ enum bgp_log_refs { EC_BGP_CAPABILITY_VENDOR, EC_BGP_CAPABILITY_UNKNOWN, EC_BGP_INVALID_NEXTHOP_LENGTH, + EC_BGP_DOPPELGANGER_CONFIG, }; extern void bgp_error_init(void); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 41aceae9f7..c350015cc4 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -210,7 +210,7 @@ static void vrf_import_rt_free(struct vrf_irt_node *irt) } hash_release(bgp_def->vrf_import_rt_hash, irt); - list_delete_and_null(&irt->vrfs); + list_delete(&irt->vrfs); XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt); } @@ -313,7 +313,7 @@ static struct irt_node *import_rt_new(struct bgp *bgp, static void import_rt_free(struct bgp *bgp, struct irt_node *irt) { hash_release(bgp->import_rt_hash, irt); - list_delete_and_null(&irt->vnis); + list_delete(&irt->vnis); XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt); } @@ -2428,6 +2428,8 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, ri->uptime = bgp_clock(); } + bgp_aggregate_increment(bgp_vrf, &rn->p, ri, afi, safi); + /* Perform route selection and update zebra, if required. */ bgp_process(bgp_vrf, rn, afi, safi); @@ -2597,6 +2599,8 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, if (!ri) return 0; + bgp_aggregate_decrement(bgp_vrf, &rn->p, ri, afi, safi); + /* Mark entry for deletion */ bgp_info_delete(rn, ri); @@ -4984,8 +4988,8 @@ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) bgpevpn_unlink_from_l3vni(vpn); bgp_table_unlock(vpn->route_table); bgp_evpn_unmap_vni_from_its_rts(bgp, vpn); - list_delete_and_null(&vpn->import_rtl); - list_delete_and_null(&vpn->export_rtl); + list_delete(&vpn->import_rtl); + list_delete(&vpn->export_rtl); bf_release_index(bm->rd_idspace, vpn->rd_id); hash_release(bgp->vnihash, vpn); QOBJ_UNREG(vpn); @@ -5058,7 +5062,7 @@ struct evpnes *bgp_evpn_es_new(struct bgp *bgp, */ void bgp_evpn_es_free(struct bgp *bgp, struct evpnes *es) { - list_delete_and_null(&es->vtep_list); + list_delete(&es->vtep_list); bgp_table_unlock(es->route_table); bf_release_index(bm->rd_idspace, es->rd_id); hash_release(bgp->esihash, es); @@ -5627,9 +5631,9 @@ void bgp_evpn_cleanup(struct bgp *bgp) hash_free(bgp->esihash); bgp->esihash = NULL; - list_delete_and_null(&bgp->vrf_import_rtl); - list_delete_and_null(&bgp->vrf_export_rtl); - list_delete_and_null(&bgp->l2vnis); + list_delete(&bgp->vrf_import_rtl); + list_delete(&bgp->vrf_export_rtl); + list_delete(&bgp->l2vnis); } /* diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 6f907c3ab5..5a1e8edac4 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -4862,7 +4862,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi, for (ALL_LIST_ELEMENTS_RO(vnilist, ln, data)) write_vni_config(vty, data); - list_delete_and_null(&vnilist); + list_delete(&vnilist); } if (bgp->advertise_all_vni) diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c index c7977a9af4..1ccb8fb245 100644 --- a/bgpd/bgp_filter.c +++ b/bgpd/bgp_filter.c @@ -77,7 +77,7 @@ struct as_list { struct as_filter *tail; }; -/* ip as-path access-list 10 permit AS1. */ +/* as-path access-list 10 permit AS1. */ static struct as_list_master as_list_master = {{NULL, NULL}, {NULL, NULL}, @@ -401,9 +401,9 @@ static int config_bgp_aspath_validate(const char *regstr) return 0; } -DEFUN(ip_as_path, ip_as_path_cmd, - "ip as-path access-list WORD <deny|permit> LINE...", - IP_STR +DEFUN(as_path, bgp_as_path_cmd, + "bgp as-path access-list WORD <deny|permit> LINE...", + BGP_STR "BGP autonomous system path filter\n" "Specify an access list name\n" "Regular expression access list name\n" @@ -418,6 +418,13 @@ DEFUN(ip_as_path, ip_as_path_cmd, regex_t *regex; char *regstr; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command\n"); + vty_out(vty, "'bgp as-path access-list WORD <deny|permit> LINE'\n"); + zlog_warn("Deprecated option: 'ip as-path access-list WORD <deny|permit> LINE' being used"); + } + /* Retrieve access list name */ argv_find(argv, argc, "WORD", &idx); char *alname = argv[idx]->arg; @@ -459,9 +466,23 @@ DEFUN(ip_as_path, ip_as_path_cmd, return CMD_SUCCESS; } -DEFUN(no_ip_as_path, no_ip_as_path_cmd, - "no ip as-path access-list WORD <deny|permit> LINE...", - NO_STR IP_STR +#if CONFDATE > 20191005 +CPP_NOTICE("bgpd: remove deprecated 'ip as-path access-list WORD <deny|permit> LINE' command") +#endif +ALIAS(as_path, ip_as_path_cmd, + "ip as-path access-list WORD <deny|permit> LINE...", + IP_STR + "BGP autonomous system path filter\n" + "Specify an access list name\n" + "Regular expression access list name\n" + "Specify packets to reject\n" + "Specify packets to forward\n" + "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n") + +DEFUN(no_as_path, no_bgp_as_path_cmd, + "no bgp as-path access-list WORD <deny|permit> LINE...", + NO_STR + BGP_STR "BGP autonomous system path filter\n" "Specify an access list name\n" "Regular expression access list name\n" @@ -476,13 +497,19 @@ DEFUN(no_ip_as_path, no_ip_as_path_cmd, char *regstr; regex_t *regex; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command\n"); + vty_out(vty, "'no bgp as-path access-list WORD <deny|permit> LINE'\n"); + zlog_warn("Deprecated option: 'no ip as-path access-list WORD <deny|permit> LINE' being used"); + } char *aslistname = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL; /* Lookup AS list from AS path list. */ aslist = as_list_lookup(aslistname); if (aslist == NULL) { - vty_out(vty, "ip as-path access-list %s doesn't exist\n", + vty_out(vty, "bgp as-path access-list %s doesn't exist\n", aslistname); return CMD_WARNING_CONFIG_FAILED; } @@ -530,21 +557,39 @@ DEFUN(no_ip_as_path, no_ip_as_path_cmd, return CMD_SUCCESS; } -DEFUN (no_ip_as_path_all, - no_ip_as_path_all_cmd, - "no ip as-path access-list WORD", +ALIAS(no_as_path, no_ip_as_path_cmd, + "no ip as-path access-list WORD <deny|permit> LINE...", + NO_STR IP_STR + "BGP autonomous system path filter\n" + "Specify an access list name\n" + "Regular expression access list name\n" + "Specify packets to reject\n" + "Specify packets to forward\n" + "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n") + +DEFUN (no_as_path_all, + no_bgp_as_path_all_cmd, + "no bgp as-path access-list WORD", NO_STR - IP_STR + BGP_STR "BGP autonomous system path filter\n" "Specify an access list name\n" "Regular expression access list name\n") { int idx_word = 4; struct as_list *aslist; + int idx = 0; + + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command\n"); + vty_out(vty, "'no bgp as-path access-list WORD'\n"); + zlog_warn("Deprecated option: `no ip as-path access-list WORD` being used"); + } aslist = as_list_lookup(argv[idx_word]->arg); if (aslist == NULL) { - vty_out(vty, "ip as-path access-list %s doesn't exist\n", + vty_out(vty, "bgp as-path access-list %s doesn't exist\n", argv[idx_word]->arg); return CMD_WARNING_CONFIG_FAILED; } @@ -558,6 +603,15 @@ DEFUN (no_ip_as_path_all, return CMD_SUCCESS; } +ALIAS (no_as_path_all, + no_ip_as_path_all_cmd, + "no ip as-path access-list WORD", + NO_STR + IP_STR + "BGP autonomous system path filter\n" + "Specify an access list name\n" + "Regular expression access list name\n") + static void as_list_show(struct vty *vty, struct as_list *aslist) { struct as_filter *asfilter; @@ -598,17 +652,24 @@ static void as_list_show_all(struct vty *vty) } } -DEFUN (show_ip_as_path_access_list, - show_ip_as_path_access_list_cmd, - "show ip as-path-access-list WORD", +DEFUN (show_as_path_access_list, + show_bgp_as_path_access_list_cmd, + "show bgp as-path-access-list WORD", SHOW_STR - IP_STR + BGP_STR "List AS path access lists\n" "AS path access list name\n") { int idx_word = 3; struct as_list *aslist; + int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command\n"); + vty_out(vty, "'show bgp as-path-access-list WORD'\n"); + zlog_warn("Deprecated option: 'show ip as-path-access-list WORD' being used"); + } aslist = as_list_lookup(argv[idx_word]->arg); if (aslist) as_list_show(vty, aslist); @@ -616,17 +677,40 @@ DEFUN (show_ip_as_path_access_list, return CMD_SUCCESS; } -DEFUN (show_ip_as_path_access_list_all, - show_ip_as_path_access_list_all_cmd, - "show ip as-path-access-list", +ALIAS (show_as_path_access_list, + show_ip_as_path_access_list_cmd, + "show ip as-path-access-list WORD", SHOW_STR IP_STR + "List AS path access lists\n" + "AS path access list name\n") + +DEFUN (show_as_path_access_list_all, + show_bgp_as_path_access_list_all_cmd, + "show bgp as-path-access-list", + SHOW_STR + BGP_STR "List AS path access lists\n") { + int idx = 0; + + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command\n"); + vty_out(vty, "'show bgp as-path-access-list'\n"); + zlog_warn("Deprecated option: 'show ip as-path-access-list' being used"); + } as_list_show_all(vty); return CMD_SUCCESS; } +ALIAS (show_as_path_access_list_all, + show_ip_as_path_access_list_all_cmd, + "show ip as-path-access-list", + SHOW_STR + IP_STR + "List AS path access lists\n") + static int config_write_as_list(struct vty *vty) { struct as_list *aslist; @@ -636,7 +720,7 @@ static int config_write_as_list(struct vty *vty) for (aslist = as_list_master.num.head; aslist; aslist = aslist->next) for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) { - vty_out(vty, "ip as-path access-list %s %s %s\n", + vty_out(vty, "bgp as-path access-list %s %s %s\n", aslist->name, filter_type_str(asfilter->type), asfilter->reg_str); write++; @@ -645,7 +729,7 @@ static int config_write_as_list(struct vty *vty) for (aslist = as_list_master.str.head; aslist; aslist = aslist->next) for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) { - vty_out(vty, "ip as-path access-list %s %s %s\n", + vty_out(vty, "bgp as-path access-list %s %s %s\n", aslist->name, filter_type_str(asfilter->type), asfilter->reg_str); write++; @@ -660,11 +744,16 @@ void bgp_filter_init(void) { install_node(&as_list_node, config_write_as_list); + install_element(CONFIG_NODE, &bgp_as_path_cmd); install_element(CONFIG_NODE, &ip_as_path_cmd); + install_element(CONFIG_NODE, &no_bgp_as_path_cmd); install_element(CONFIG_NODE, &no_ip_as_path_cmd); + install_element(CONFIG_NODE, &no_bgp_as_path_all_cmd); install_element(CONFIG_NODE, &no_ip_as_path_all_cmd); + install_element(VIEW_NODE, &show_bgp_as_path_access_list_cmd); install_element(VIEW_NODE, &show_ip_as_path_access_list_cmd); + install_element(VIEW_NODE, &show_bgp_as_path_access_list_all_cmd); install_element(VIEW_NODE, &show_ip_as_path_access_list_all_cmd); } diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index faa88f9850..ceeecc7e19 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -357,7 +357,7 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p, if (list_began) vty_out(vty, ")"); vty_out(vty, "\n"); - list_delete_and_null(&list_bpm); + list_delete(&list_bpm); } else vty_out(vty, "\tnot installed in PBR\n"); } diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 384d2bca82..65b8b5bd2d 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -125,6 +125,20 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) return from_peer; + /* + * Let's check that we are not going to loose known configuration + * state based upon doppelganger rules. + */ + FOREACH_AFI_SAFI (afi, safi) { + if (from_peer->afc[afi][safi] != peer->afc[afi][safi]) { + flog_err( + EC_BGP_DOPPELGANGER_CONFIG, + "from_peer->afc[%d][%d] is not the same as what we are overwriting", + afi, safi); + return NULL; + } + } + if (bgp_debug_neighbor_events(peer)) zlog_debug("%s: peer transfer %p fd %d -> %p fd %d)", from_peer->host, from_peer, from_peer->fd, peer, diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c index 73d3dc67e8..181f864575 100644 --- a/bgpd/bgp_labelpool.c +++ b/bgpd/bgp_labelpool.c @@ -223,7 +223,7 @@ void bgp_lp_finish(void) skiplist_free(lp->inuse); lp->inuse = NULL; - list_delete_and_null(&lp->chunks); + list_delete(&lp->chunks); while ((lf = LABEL_FIFO_HEAD(lp->requests))) { diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 6643795f55..503c3f9f88 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -234,7 +234,7 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) bgp_zebra_destroy(); bf_free(bm->rd_idspace); - list_delete_and_null(&bm->bgp); + list_delete(&bm->bgp); memset(bm, 0, sizeof(*bm)); frr_fini(); diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 64453987d5..ce7f5b40f5 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -226,7 +226,7 @@ static void bgp_address_hash_free(void *data) { struct bgp_addr *addr = data; - list_delete_and_null(&addr->ifp_name_list); + list_delete(&addr->ifp_name_list); XFREE(MTYPE_BGP_ADDR, addr); } @@ -308,7 +308,7 @@ static void bgp_address_del(struct bgp *bgp, struct connected *ifc, if (addr->ifp_name_list->count == 0) { hash_release(bgp->address_hash, addr); - list_delete_and_null(&addr->ifp_name_list); + list_delete(&addr->ifp_name_list); XFREE(MTYPE_BGP_ADDR, addr); } } diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index dd1ffe9f3b..c94c707157 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -169,11 +169,6 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, if (make_prefix(afi, ri, &p) < 0) return 1; } else if (peer) { - /* Don't register link local NH */ - if (afi == AFI_IP6 - && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) - return 1; - if (!sockunion2hostprefix(&peer->su, &p)) { if (BGP_DEBUG(nht, NHT)) { zlog_debug( @@ -287,10 +282,6 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer) if (!peer) return; - /* We don't register link local address for NHT */ - if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) - return; - if (!sockunion2hostprefix(&peer->su, &p)) return; @@ -437,8 +428,9 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) * we receive from bgp. This is to allow us * to work with v4 routing over v6 nexthops */ - if (peer && - CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE) + if (peer && !peer->ifp + && CHECK_FLAG(peer->flags, + PEER_FLAG_CAPABILITY_ENHE) && nhr.prefix.family == AF_INET6) { struct interface *ifp; @@ -556,11 +548,6 @@ static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p) } break; case AFI_IP6: - /* We don't register link local NH */ - if (ri->attr->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL - || IN6_IS_ADDR_LINKLOCAL(&ri->attr->mp_nexthop_global)) - return -1; - p->family = AF_INET6; if (is_bgp_static) { diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index a04ed8eef5..1693147b89 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -215,7 +215,7 @@ static void bgp_info_extra_free(struct bgp_info_extra **extra) bgp_unlock(e->bgp_orig); if ((*extra)->bgp_fs_pbr) - list_delete_and_null(&((*extra)->bgp_fs_pbr)); + list_delete(&((*extra)->bgp_fs_pbr)); XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra); *extra = NULL; @@ -2775,30 +2775,40 @@ static bool overlay_index_equal(afi_t afi, struct bgp_info *info, { struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote; union gw_addr *info_gw_ip, *info_gw_ip_remote; - char temp[16]; + union { + struct eth_segment_id esi; + union gw_addr ip; + } temp; if (afi != AFI_L2VPN) return true; if (!info->attr) { - memset(&temp, 0, 16); - info_eth_s_id = (struct eth_segment_id *)&temp; - info_gw_ip = (union gw_addr *)&temp; + memset(&temp, 0, sizeof(temp)); + info_eth_s_id = &temp.esi; + info_gw_ip = &temp.ip; + if (eth_s_id == NULL && gw_ip == NULL) return true; } else { info_eth_s_id = &(info->attr->evpn_overlay.eth_s_id); info_gw_ip = &(info->attr->evpn_overlay.gw_ip); } - if (gw_ip == NULL) - info_gw_ip_remote = (union gw_addr *)&temp; - else + + if (gw_ip == NULL) { + memset(&temp, 0, sizeof(temp)); + info_gw_ip_remote = &temp.ip; + } else info_gw_ip_remote = gw_ip; - if (eth_s_id == NULL) - info_eth_s_id_remote = (struct eth_segment_id *)&temp; - else + + if (eth_s_id == NULL) { + memset(&temp, 0, sizeof(temp)); + info_eth_s_id_remote = &temp.esi; + } else info_eth_s_id_remote = eth_s_id; + if (!memcmp(info_gw_ip, info_gw_ip_remote, sizeof(union gw_addr))) return false; + return !memcmp(info_eth_s_id, info_eth_s_id_remote, sizeof(struct eth_segment_id)); } @@ -5478,6 +5488,9 @@ static int bgp_aggregate_info_same(struct bgp_info *ri, uint8_t origin, if (!community_cmp(ri->attr->community, comm)) return 0; + if (!CHECK_FLAG(ri->flags, BGP_INFO_VALID)) + return 0; + return 1; } @@ -8653,17 +8666,39 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, best = count; if (ri->extra && ri->extra->suppress) suppress = 1; - if (ri->attr->community != NULL) { - if (community_include(ri->attr->community, - COMMUNITY_NO_ADVERTISE)) - no_advertise = 1; - if (community_include(ri->attr->community, - COMMUNITY_NO_EXPORT)) - no_export = 1; - if (community_include(ri->attr->community, - COMMUNITY_LOCAL_AS)) - local_as = 1; - } + + if (ri->attr->community == NULL) + continue; + + no_advertise += community_include( + ri->attr->community, COMMUNITY_NO_ADVERTISE); + no_export += community_include(ri->attr->community, + COMMUNITY_NO_EXPORT); + local_as += community_include(ri->attr->community, + COMMUNITY_LOCAL_AS); + accept_own += community_include(ri->attr->community, + COMMUNITY_ACCEPT_OWN); + route_filter_translated_v4 += community_include( + ri->attr->community, + COMMUNITY_ROUTE_FILTER_TRANSLATED_v4); + route_filter_translated_v6 += community_include( + ri->attr->community, + COMMUNITY_ROUTE_FILTER_TRANSLATED_v6); + route_filter_v4 += community_include( + ri->attr->community, COMMUNITY_ROUTE_FILTER_v4); + route_filter_v6 += community_include( + ri->attr->community, COMMUNITY_ROUTE_FILTER_v6); + llgr_stale += community_include(ri->attr->community, + COMMUNITY_LLGR_STALE); + no_llgr += community_include(ri->attr->community, + COMMUNITY_NO_LLGR); + accept_own_nexthop += + community_include(ri->attr->community, + COMMUNITY_ACCEPT_OWN_NEXTHOP); + blackhole += community_include(ri->attr->community, + COMMUNITY_BLACKHOLE); + no_peer += community_include(ri->attr->community, + COMMUNITY_NO_PEER); } } @@ -9074,10 +9109,6 @@ DEFUN (show_ip_bgp, |prefix-list WORD\ |filter-list WORD\ |statistics\ - |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown\ - no-peer|blackhole|llgr-stale|no-llgr|accept-own|accept-own-nexthop\ - route-filter-v6|route-filter-v4|route-filter-translated-v6|\ - route-filter-translated-v4> [exact-match]\ |community-list <(1-500)|WORD> [exact-match]\ |A.B.C.D/M longer-prefixes\ |X:X::X:X/M longer-prefixes\ @@ -9097,23 +9128,6 @@ DEFUN (show_ip_bgp, "Display routes conforming to the filter-list\n" "Regular expression access list name\n" "BGP RIB advertisement statistics\n" - "Display routes matching the communities\n" - COMMUNITY_AANN_STR - "Do not send outside local AS (well-known community)\n" - "Do not advertise to any peer (well-known community)\n" - "Do not export to next AS (well-known community)\n" - "Graceful shutdown (well-known community)\n" - "Do not export to any peer (well-known community)\n" - "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n" - "Staled Long-lived Graceful Restart VPN route (well-known community)\n" - "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n" - "Should accept local VPN route if exported and imported into different VRF (well-known community)\n" - "Should accept VPN route with local nexthop (well-known community)\n" - "RT VPNv6 route filtering (well-known community)\n" - "RT VPNv4 route filtering (well-known community)\n" - "RT translated VPNv6 route filtering (well-known community)\n" - "RT translated VPNv4 route filtering (well-known community)\n" - "Exact match of the communities\n" "Display routes matching the community-list\n" "community-list number\n" "community-list name\n" @@ -9175,11 +9189,14 @@ DEFUN (show_ip_bgp, DEFUN (show_ip_bgp_json, show_ip_bgp_json_cmd, "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\ - [<\ - cidr-only\ - |dampening <flap-statistics|dampened-paths>\ - |community [<AA:NN|local-AS|no-advertise|no-export|graceful-shutdown>] [exact-match]\ - >] [json]", + [cidr-only\ + |dampening <flap-statistics|dampened-paths>\ + |community [AA:NN|local-AS|no-advertise|no-export\ + |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\ + |accept-own|accept-own-nexthop|route-filter-v6\ + |route-filter-v4|route-filter-translated-v6\ + |route-filter-translated-v4] [exact-match]\ + ] [json]", SHOW_STR IP_STR BGP_STR @@ -9196,6 +9213,16 @@ DEFUN (show_ip_bgp_json, "Do not advertise to any peer (well-known community)\n" "Do not export to next AS (well-known community)\n" "Graceful shutdown (well-known community)\n" + "Do not export to any peer (well-known community)\n" + "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n" + "Staled Long-lived Graceful Restart VPN route (well-known community)\n" + "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n" + "Should accept local VPN route if exported and imported into different VRF (well-known community)\n" + "Should accept VPN route with local nexthop (well-known community)\n" + "RT VPNv6 route filtering (well-known community)\n" + "RT VPNv4 route filtering (well-known community)\n" + "RT translated VPNv6 route filtering (well-known community)\n" + "RT translated VPNv4 route filtering (well-known community)\n" "Exact match of the communities\n" JSON_STR) { @@ -9204,7 +9231,6 @@ DEFUN (show_ip_bgp_json, enum bgp_show_type sh_type = bgp_show_type_normal; struct bgp *bgp = NULL; int idx = 0; - int idx_community_type = 0; int exact_match = 0; bool uj = use_json(argc, argv); @@ -9231,29 +9257,23 @@ DEFUN (show_ip_bgp_json, } if (argv_find(argv, argc, "community", &idx)) { + char *maybecomm = idx + 1 < argc ? argv[idx + 1]->text : NULL; + char *community = NULL; - /* show a specific community */ - if (argv_find(argv, argc, "local-AS", &idx_community_type) || - argv_find(argv, argc, "no-advertise", - &idx_community_type) || - argv_find(argv, argc, "no-export", - &idx_community_type) || - argv_find(argv, argc, "graceful-shutdown", - &idx_community_type) || - argv_find(argv, argc, "AA:NN", &idx_community_type)) { - if (argv_find(argv, argc, "exact-match", &idx)) - exact_match = 1; - - return (bgp_show_community(vty, bgp, - argv[idx_community_type]->arg, - exact_match, afi, safi, uj)); - } else { + if (maybecomm && !strmatch(maybecomm, "json") + && !strmatch(maybecomm, "exact-match")) + community = maybecomm; + + if (argv_find(argv, argc, "exact-match", &idx)) + exact_match = 1; - /* show all communities */ + if (community) + return bgp_show_community(vty, bgp, community, + exact_match, afi, safi, uj); + else return (bgp_show(vty, bgp, afi, safi, - bgp_show_type_community_all, NULL, - uj)); - } + bgp_show_type_community_all, NULL, + uj)); } return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 0b4355805c..0a3e4b3c89 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -28,6 +28,7 @@ #include "plist.h" #include "memory.h" #include "log.h" +#include "lua.h" #ifdef HAVE_LIBPCREPOSIX #include <pcreposix.h> #else @@ -330,6 +331,102 @@ struct route_map_rule_cmd route_match_peer_cmd = {"peer", route_match_peer, route_match_peer_compile, route_match_peer_free}; +#if defined(HAVE_LUA) +static route_map_result_t route_match_command(void *rule, + const struct prefix *prefix, + route_map_object_t type, + void *object) +{ + int status = RMAP_NOMATCH; + u_int32_t locpref = 0; + u_int32_t newlocpref = 0; + enum lua_rm_status lrm_status; + struct bgp_info *info = (struct bgp_info *)object; + lua_State *L = lua_initialize("/etc/frr/lua.scr"); + + if (L == NULL) + return status; + + /* + * Setup the prefix information to pass in + */ + lua_setup_prefix_table(L, prefix); + + zlog_debug("Set up prefix table"); + /* + * Setup the bgp_info information + */ + lua_newtable(L); + lua_pushinteger(L, info->attr->med); + lua_setfield(L, -2, "metric"); + lua_pushinteger(L, info->attr->nh_ifindex); + lua_setfield(L, -2, "ifindex"); + lua_pushstring(L, info->attr->aspath->str); + lua_setfield(L, -2, "aspath"); + lua_pushinteger(L, info->attr->local_pref); + lua_setfield(L, -2, "localpref"); + zlog_debug("%s %d", info->attr->aspath->str, info->attr->nh_ifindex); + lua_setglobal(L, "nexthop"); + + zlog_debug("Set up nexthop information"); + /* + * Run the rule + */ + lrm_status = lua_run_rm_rule(L, rule); + switch (lrm_status) { + case LUA_RM_FAILURE: + zlog_debug("RM_FAILURE"); + break; + case LUA_RM_NOMATCH: + zlog_debug("RM_NOMATCH"); + break; + case LUA_RM_MATCH_AND_CHANGE: + zlog_debug("MATCH AND CHANGE"); + lua_getglobal(L, "nexthop"); + info->attr->med = get_integer(L, "metric"); + /* + * This needs to be abstraced with the set function + */ + if (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) + locpref = info->attr->local_pref; + newlocpref = get_integer(L, "localpref"); + if (newlocpref != locpref) { + info->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); + info->attr->local_pref = newlocpref; + } + status = RMAP_MATCH; + break; + case LUA_RM_MATCH: + zlog_debug("MATCH ONLY"); + status = RMAP_MATCH; + break; + } + lua_close(L); + return status; +} + +static void *route_match_command_compile(const char *arg) +{ + char *command; + + command = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); + return command; +} + +static void +route_match_command_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +struct route_map_rule_cmd route_match_command_cmd = { + "command", + route_match_command, + route_match_command_compile, + route_match_command_free +}; +#endif + /* `match ip address IP_ACCESS_LIST' */ /* Match function should return 1 if match is success else return @@ -548,6 +645,45 @@ struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = { route_match_ip_next_hop_prefix_list_compile, route_match_ip_next_hop_prefix_list_free}; +/* `match ip next-hop type <blackhole>' */ + +static route_map_result_t +route_match_ip_next_hop_type(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct bgp_info *bgp_info; + + if (type == RMAP_BGP && prefix->family == AF_INET) { + bgp_info = (struct bgp_info *)object; + if (!bgp_info || !bgp_info->attr) + return RMAP_DENYMATCH; + + /* If nexthop interface's index can't be resolved and nexthop is + set to any address then mark it as type `blackhole`. + This logic works for matching kernel/static routes like: + `ip route add blackhole 10.0.0.1`. */ + if (bgp_info->attr->nexthop.s_addr == INADDR_ANY + && !bgp_info->attr->nh_ifindex) + return RMAP_MATCH; + } + return RMAP_NOMATCH; +} + +static void *route_match_ip_next_hop_type_compile(const char *arg) +{ + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); +} + +static void route_match_ip_next_hop_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +static struct route_map_rule_cmd route_match_ip_next_hop_type_cmd = { + "ip next-hop type", route_match_ip_next_hop_type, + route_match_ip_next_hop_type_compile, + route_match_ip_next_hop_type_free}; + /* `match ip route-source prefix-list PREFIX_LIST' */ static route_map_result_t @@ -2372,6 +2508,53 @@ struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = { route_match_ipv6_address_prefix_list_compile, route_match_ipv6_address_prefix_list_free}; +/* `match ipv6 next-hop type <TYPE>' */ + +static route_map_result_t +route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct bgp_info *bgp_info; + struct in6_addr *addr = rule; + + if (type == RMAP_BGP && prefix->family == AF_INET6) { + bgp_info = (struct bgp_info *)object; + if (!bgp_info || !bgp_info->attr) + return RMAP_DENYMATCH; + + if (IPV6_ADDR_SAME(&bgp_info->attr->mp_nexthop_global, addr) + && !bgp_info->attr->nh_ifindex) + return RMAP_MATCH; + } + return RMAP_NOMATCH; +} + +static void *route_match_ipv6_next_hop_type_compile(const char *arg) +{ + struct in6_addr *address; + int ret; + + address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in6_addr)); + + ret = inet_pton(AF_INET6, "::0", address); + if (!ret) { + XFREE(MTYPE_ROUTE_MAP_COMPILED, address); + return NULL; + } + + return address; +} + +static void route_match_ipv6_next_hop_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +struct route_map_rule_cmd route_match_ipv6_next_hop_type_cmd = { + "ipv6 next-hop type", route_match_ipv6_next_hop_type, + route_match_ipv6_next_hop_type_compile, + route_match_ipv6_next_hop_type_free}; + /* `set ipv6 nexthop global IP_ADDRESS' */ /* Set nexthop to object. ojbect must be pointer to struct attr. */ @@ -3356,6 +3539,30 @@ DEFUN (no_match_peer, RMAP_EVENT_MATCH_DELETED); } +#if defined(HAVE_LUA) +DEFUN (match_command, + match_command_cmd, + "match command WORD", + MATCH_STR + "Run a command to match\n" + "The command to run\n") +{ + return bgp_route_match_add(vty, "command", argv[2]->arg, + RMAP_EVENT_FILTER_ADDED); +} + +DEFUN (no_match_command, + no_match_command_cmd, + "no match command WORD", + NO_STR + MATCH_STR + "Run a command to match\n" + "The command to run\n") +{ + return bgp_route_match_delete(vty, "command", argv[3]->arg, + RMAP_EVENT_FILTER_DELETED); +} +#endif /* match probability */ DEFUN (match_probability, @@ -4645,12 +4852,18 @@ void bgp_route_map_init(void) route_map_match_ip_next_hop_prefix_list_hook(generic_match_add); route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete); + route_map_match_ip_next_hop_type_hook(generic_match_add); + route_map_no_match_ip_next_hop_type_hook(generic_match_delete); + route_map_match_ipv6_address_hook(generic_match_add); route_map_no_match_ipv6_address_hook(generic_match_delete); route_map_match_ipv6_address_prefix_list_hook(generic_match_add); route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete); + route_map_match_ipv6_next_hop_type_hook(generic_match_add); + route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete); + route_map_match_metric_hook(generic_match_add); route_map_no_match_metric_hook(generic_match_delete); @@ -4671,11 +4884,15 @@ void bgp_route_map_init(void) route_map_install_match(&route_match_peer_cmd); route_map_install_match(&route_match_local_pref_cmd); +#if defined(HAVE_LUA) + route_map_install_match(&route_match_command_cmd); +#endif route_map_install_match(&route_match_ip_address_cmd); route_map_install_match(&route_match_ip_next_hop_cmd); route_map_install_match(&route_match_ip_route_source_cmd); route_map_install_match(&route_match_ip_address_prefix_list_cmd); route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd); + route_map_install_match(&route_match_ip_next_hop_type_cmd); route_map_install_match(&route_match_ip_route_source_prefix_list_cmd); route_map_install_match(&route_match_aspath_cmd); route_map_install_match(&route_match_community_cmd); @@ -4791,6 +5008,7 @@ void bgp_route_map_init(void) route_map_install_match(&route_match_ipv6_address_cmd); route_map_install_match(&route_match_ipv6_next_hop_cmd); route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); + route_map_install_match(&route_match_ipv6_next_hop_type_cmd); route_map_install_set(&route_set_ipv6_nexthop_global_cmd); route_map_install_set(&route_set_ipv6_nexthop_prefer_global_cmd); route_map_install_set(&route_set_ipv6_nexthop_local_cmd); @@ -4804,6 +5022,10 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd); install_element(RMAP_NODE, &set_ipv6_nexthop_peer_cmd); install_element(RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd); +#if defined(HAVE_LUA) + install_element(RMAP_NODE, &match_command_cmd); + install_element(RMAP_NODE, &no_match_command_cmd); +#endif } void bgp_route_map_terminate(void) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 2e0bb1ae62..56566525a4 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -402,7 +402,7 @@ static int bgpd_sync_callback(struct thread *thread) revalidate_bgp_node(bgp_node, afi, safi); - list_delete_and_null(&matches); + list_delete(&matches); } } } @@ -539,7 +539,7 @@ static int bgp_rpki_init(struct thread_master *master) static int bgp_rpki_fini(void) { stop(); - list_delete_and_null(&cache_list); + list_delete(&cache_list); close(rpki_sync_socket_rtr); close(rpki_sync_socket_bgpd); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 58f23fd2f4..e705a714e9 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -13725,11 +13725,11 @@ static void community_list_perror(struct vty *vty, int ret) /* "community-list" keyword help string. */ #define COMMUNITY_LIST_STR "Add a community list entry\n" -/* ip community-list standard */ -DEFUN (ip_community_list_standard, - ip_community_list_standard_cmd, - "ip community-list <(1-99)|standard WORD> <deny|permit> AA:NN...", - IP_STR +/*community-list standard */ +DEFUN (community_list_standard, + bgp_community_list_standard_cmd, + "bgp community-list <(1-99)|standard WORD> <deny|permit> AA:NN...", + BGP_STR COMMUNITY_LIST_STR "Community list number (standard)\n" "Add an standard community-list entry\n" @@ -13743,6 +13743,14 @@ DEFUN (ip_community_list_standard, int style = COMMUNITY_LIST_STANDARD; int idx = 0; + + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'bgp community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> AA:NN'\n"); + zlog_warn("Deprecated option: 'ip community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> AA:NN' being used"); + } + argv_find(argv, argc, "(1-99)", &idx); argv_find(argv, argc, "WORD", &idx); cl_name_or_number = argv[idx]->arg; @@ -13765,10 +13773,12 @@ DEFUN (ip_community_list_standard, return CMD_SUCCESS; } -DEFUN (no_ip_community_list_standard_all, - no_ip_community_list_standard_all_cmd, - "no ip community-list <(1-99)|standard WORD> <deny|permit> AA:NN...", - NO_STR +#if CONFDATE > 20191005 +CPP_NOTICE("bgpd: remove deprecated 'ip community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> AA:NN' command") +#endif +ALIAS (community_list_standard, + ip_community_list_standard_cmd, + "ip community-list <(1-99)|standard WORD> <deny|permit> AA:NN...", IP_STR COMMUNITY_LIST_STR "Community list number (standard)\n" @@ -13777,12 +13787,33 @@ DEFUN (no_ip_community_list_standard_all, "Specify community to reject\n" "Specify community to accept\n" COMMUNITY_VAL_STR) + +DEFUN (no_community_list_standard_all, + no_bgp_community_list_standard_all_cmd, + "no bgp community-list <(1-99)|standard WORD> <deny|permit> AA:NN...", + NO_STR + BGP_STR + COMMUNITY_LIST_STR + "Community list number (standard)\n" + "Add an standard community-list entry\n" + "Community list name\n" + "Specify community to reject\n" + "Specify community to accept\n" + COMMUNITY_VAL_STR) { char *cl_name_or_number = NULL; int direct = 0; int style = COMMUNITY_LIST_STANDARD; int idx = 0; + + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'no bgp community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> AA:NN'\n"); + zlog_warn("Deprecated option: 'no ip community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> |AA:NN' being used"); + } + argv_find(argv, argc, "(1-99)", &idx); argv_find(argv, argc, "WORD", &idx); cl_name_or_number = argv[idx]->arg; @@ -13803,13 +13834,25 @@ DEFUN (no_ip_community_list_standard_all, return CMD_SUCCESS; } - -/* ip community-list expanded */ -DEFUN (ip_community_list_expanded_all, - ip_community_list_expanded_all_cmd, - "ip community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...", +ALIAS (no_community_list_standard_all, + no_ip_community_list_standard_all_cmd, + "no ip community-list <(1-99)|standard WORD> <deny|permit> AA:NN...", + NO_STR IP_STR COMMUNITY_LIST_STR + "Community list number (standard)\n" + "Add an standard community-list entry\n" + "Community list name\n" + "Specify community to reject\n" + "Specify community to accept\n" + COMMUNITY_VAL_STR) + +/*community-list expanded */ +DEFUN (community_list_expanded_all, + bgp_community_list_expanded_all_cmd, + "bgp community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...", + BGP_STR + COMMUNITY_LIST_STR "Community list number (expanded)\n" "Add an expanded community-list entry\n" "Community list name\n" @@ -13822,6 +13865,12 @@ DEFUN (ip_community_list_expanded_all, int style = COMMUNITY_LIST_EXPANDED; int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'bgp community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> AA:NN'\n"); + zlog_warn("Deprecated option: 'ip community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> AA:NN' being used"); + } argv_find(argv, argc, "(100-500)", &idx); argv_find(argv, argc, "WORD", &idx); cl_name_or_number = argv[idx]->arg; @@ -13844,10 +13893,9 @@ DEFUN (ip_community_list_expanded_all, return CMD_SUCCESS; } -DEFUN (no_ip_community_list_expanded_all, - no_ip_community_list_expanded_all_cmd, - "no ip community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...", - NO_STR +ALIAS (community_list_expanded_all, + ip_community_list_expanded_all_cmd, + "ip community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...", IP_STR COMMUNITY_LIST_STR "Community list number (expanded)\n" @@ -13856,12 +13904,31 @@ DEFUN (no_ip_community_list_expanded_all, "Specify community to reject\n" "Specify community to accept\n" COMMUNITY_VAL_STR) + +DEFUN (no_community_list_expanded_all, + no_bgp_community_list_expanded_all_cmd, + "no bgp community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...", + NO_STR + BGP_STR + COMMUNITY_LIST_STR + "Community list number (expanded)\n" + "Add an expanded community-list entry\n" + "Community list name\n" + "Specify community to reject\n" + "Specify community to accept\n" + COMMUNITY_VAL_STR) { char *cl_name_or_number = NULL; int direct = 0; int style = COMMUNITY_LIST_EXPANDED; int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'no community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> AA:NN'\n"); + zlog_warn("Deprecated option: 'no community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> AA:NN' being used"); + } argv_find(argv, argc, "(100-500)", &idx); argv_find(argv, argc, "WORD", &idx); cl_name_or_number = argv[idx]->arg; @@ -13883,6 +13950,19 @@ DEFUN (no_ip_community_list_expanded_all, return CMD_SUCCESS; } +ALIAS (no_community_list_expanded_all, + no_ip_community_list_expanded_all_cmd, + "no ip community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...", + NO_STR + IP_STR + COMMUNITY_LIST_STR + "Community list number (expanded)\n" + "Add an expanded community-list entry\n" + "Community list name\n" + "Specify community to reject\n" + "Specify community to accept\n" + COMMUNITY_VAL_STR) + /* Return configuration string of community-list entry. */ static const char *community_list_config_str(struct community_entry *entry) { @@ -13930,16 +14010,23 @@ static void community_list_show(struct vty *vty, struct community_list *list) } } -DEFUN (show_ip_community_list, - show_ip_community_list_cmd, - "show ip community-list", +DEFUN (show_community_list, + show_bgp_community_list_cmd, + "show bgp community-list", SHOW_STR - IP_STR + BGP_STR "List community-list\n") { struct community_list *list; struct community_list_master *cm; + int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'show bgp community-list <(1-500)|WORD>'\n"); + zlog_warn("Deprecated option: 'ip show community-list <(1-500)|WORD>' being used"); + } cm = community_list_master_lookup(bgp_clist, COMMUNITY_LIST_MASTER); if (!cm) return CMD_SUCCESS; @@ -13953,11 +14040,18 @@ DEFUN (show_ip_community_list, return CMD_SUCCESS; } -DEFUN (show_ip_community_list_arg, - show_ip_community_list_arg_cmd, - "show ip community-list <(1-500)|WORD>", +ALIAS (show_community_list, + show_ip_community_list_cmd, + "show ip community-list", SHOW_STR IP_STR + "List community-list\n") + +DEFUN (show_community_list_arg, + show_bgp_community_list_arg_cmd, + "show bgp community-list <(1-500)|WORD>", + SHOW_STR + BGP_STR "List community-list\n" "Community-list number\n" "Community-list name\n") @@ -13965,6 +14059,13 @@ DEFUN (show_ip_community_list_arg, int idx_comm_list = 3; struct community_list *list; + int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'show bgp community-list <(1-500)|WORD>'\n"); + zlog_warn("Deprecated option: 'ip show community-list <(1-500)|WORD>' being used"); + } list = community_list_lookup(bgp_clist, argv[idx_comm_list]->arg, COMMUNITY_LIST_MASTER); if (!list) { @@ -13977,6 +14078,15 @@ DEFUN (show_ip_community_list_arg, return CMD_SUCCESS; } +ALIAS (show_community_list_arg, + show_ip_community_list_arg_cmd, + "show ip community-list <(1-500)|WORD>", + SHOW_STR + IP_STR + "List community-list\n" + "Community-list number\n" + "Community-list name\n") + /* * Large Community code. */ @@ -13990,6 +14100,12 @@ static int lcommunity_list_set_vty(struct vty *vty, int argc, int idx = 0; char *cl_name; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'bgp large-community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:BB:CC>'\n"); + zlog_warn("Deprecated option: 'large-community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:BB:CC>' being used"); + } direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY; @@ -14035,6 +14151,12 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc, char *str = NULL; int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'no bgp large-community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:BB:CC>'\n"); + zlog_warn("Deprecated option: 'no ip large-community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:BB:CC>' being used"); + } argv_find(argv, argc, "permit", &idx); argv_find(argv, argc, "deny", &idx); @@ -14078,7 +14200,23 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc, #define LCOMMUNITY_LIST_STR "Add a large community list entry\n" #define LCOMMUNITY_VAL_STR "large community in 'aa:bb:cc' format\n" -DEFUN (ip_lcommunity_list_standard, +#if CONFDATE > 20191005 +CPP_NOTICE("bgpd: remove deprecated 'ip large-community-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:BB:CC>' command") +#endif +DEFUN (lcommunity_list_standard, + bgp_lcommunity_list_standard_cmd, + "bgp large-community-list (1-99) <deny|permit>", + BGP_STR + LCOMMUNITY_LIST_STR + "Large Community list number (standard)\n" + "Specify large community to reject\n" + "Specify large community to accept\n") +{ + return lcommunity_list_set_vty(vty, argc, argv, + LARGE_COMMUNITY_LIST_STANDARD, 0); +} + +ALIAS (lcommunity_list_standard, ip_lcommunity_list_standard_cmd, "ip large-community-list (1-99) <deny|permit>", IP_STR @@ -14086,12 +14224,22 @@ DEFUN (ip_lcommunity_list_standard, "Large Community list number (standard)\n" "Specify large community to reject\n" "Specify large community to accept\n") + +DEFUN (lcommunity_list_standard1, + bgp_lcommunity_list_standard1_cmd, + "bgp large-community-list (1-99) <deny|permit> AA:BB:CC...", + BGP_STR + LCOMMUNITY_LIST_STR + "Large Community list number (standard)\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + LCOMMUNITY_VAL_STR) { return lcommunity_list_set_vty(vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 0); } -DEFUN (ip_lcommunity_list_standard1, +ALIAS (lcommunity_list_standard1, ip_lcommunity_list_standard1_cmd, "ip large-community-list (1-99) <deny|permit> AA:BB:CC...", IP_STR @@ -14100,12 +14248,22 @@ DEFUN (ip_lcommunity_list_standard1, "Specify large community to reject\n" "Specify large community to accept\n" LCOMMUNITY_VAL_STR) + +DEFUN (lcommunity_list_expanded, + bgp_lcommunity_list_expanded_cmd, + "bgp large-community-list (100-500) <deny|permit> LINE...", + BGP_STR + LCOMMUNITY_LIST_STR + "Large Community list number (expanded)\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + "An ordered list as a regular-expression\n") { return lcommunity_list_set_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_STANDARD, 0); + LARGE_COMMUNITY_LIST_EXPANDED, 0); } -DEFUN (ip_lcommunity_list_expanded, +ALIAS (lcommunity_list_expanded, ip_lcommunity_list_expanded_cmd, "ip large-community-list (100-500) <deny|permit> LINE...", IP_STR @@ -14114,12 +14272,22 @@ DEFUN (ip_lcommunity_list_expanded, "Specify large community to reject\n" "Specify large community to accept\n" "An ordered list as a regular-expression\n") + +DEFUN (lcommunity_list_name_standard, + bgp_lcommunity_list_name_standard_cmd, + "bgp large-community-list standard WORD <deny|permit>", + BGP_STR + LCOMMUNITY_LIST_STR + "Specify standard large-community-list\n" + "Large Community list name\n" + "Specify large community to reject\n" + "Specify large community to accept\n") { return lcommunity_list_set_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_EXPANDED, 0); + LARGE_COMMUNITY_LIST_STANDARD, 1); } -DEFUN (ip_lcommunity_list_name_standard, +ALIAS (lcommunity_list_name_standard, ip_lcommunity_list_name_standard_cmd, "ip large-community-list standard WORD <deny|permit>", IP_STR @@ -14128,12 +14296,23 @@ DEFUN (ip_lcommunity_list_name_standard, "Large Community list name\n" "Specify large community to reject\n" "Specify large community to accept\n") + +DEFUN (lcommunity_list_name_standard1, + bgp_lcommunity_list_name_standard1_cmd, + "bgp large-community-list standard WORD <deny|permit> AA:BB:CC...", + BGP_STR + LCOMMUNITY_LIST_STR + "Specify standard large-community-list\n" + "Large Community list name\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + LCOMMUNITY_VAL_STR) { return lcommunity_list_set_vty(vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 1); } -DEFUN (ip_lcommunity_list_name_standard1, +ALIAS (lcommunity_list_name_standard1, ip_lcommunity_list_name_standard1_cmd, "ip large-community-list standard WORD <deny|permit> AA:BB:CC...", IP_STR @@ -14143,12 +14322,23 @@ DEFUN (ip_lcommunity_list_name_standard1, "Specify large community to reject\n" "Specify large community to accept\n" LCOMMUNITY_VAL_STR) + +DEFUN (lcommunity_list_name_expanded, + bgp_lcommunity_list_name_expanded_cmd, + "bgp large-community-list expanded WORD <deny|permit> LINE...", + BGP_STR + LCOMMUNITY_LIST_STR + "Specify expanded large-community-list\n" + "Large Community list name\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + "An ordered list as a regular-expression\n") { return lcommunity_list_set_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_STANDARD, 1); + LARGE_COMMUNITY_LIST_EXPANDED, 1); } -DEFUN (ip_lcommunity_list_name_expanded, +ALIAS (lcommunity_list_name_expanded, ip_lcommunity_list_name_expanded_cmd, "ip large-community-list expanded WORD <deny|permit> LINE...", IP_STR @@ -14158,12 +14348,22 @@ DEFUN (ip_lcommunity_list_name_expanded, "Specify large community to reject\n" "Specify large community to accept\n" "An ordered list as a regular-expression\n") + +DEFUN (no_lcommunity_list_standard_all, + no_bgp_lcommunity_list_standard_all_cmd, + "no bgp large-community-list <(1-99)|(100-500)|WORD>", + NO_STR + BGP_STR + LCOMMUNITY_LIST_STR + "Large Community list number (standard)\n" + "Large Community list number (expanded)\n" + "Large Community list name\n") { - return lcommunity_list_set_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_EXPANDED, 1); + return lcommunity_list_unset_vty(vty, argc, argv, + LARGE_COMMUNITY_LIST_STANDARD); } -DEFUN (no_ip_lcommunity_list_standard_all, +ALIAS (no_lcommunity_list_standard_all, no_ip_lcommunity_list_standard_all_cmd, "no ip large-community-list <(1-99)|(100-500)|WORD>", NO_STR @@ -14172,12 +14372,21 @@ DEFUN (no_ip_lcommunity_list_standard_all, "Large Community list number (standard)\n" "Large Community list number (expanded)\n" "Large Community list name\n") + +DEFUN (no_lcommunity_list_name_expanded_all, + no_bgp_lcommunity_list_name_expanded_all_cmd, + "no bgp large-community-list expanded WORD", + NO_STR + BGP_STR + LCOMMUNITY_LIST_STR + "Specify expanded large-community-list\n" + "Large Community list name\n") { return lcommunity_list_unset_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_STANDARD); + LARGE_COMMUNITY_LIST_EXPANDED); } -DEFUN (no_ip_lcommunity_list_name_expanded_all, +ALIAS (no_lcommunity_list_name_expanded_all, no_ip_lcommunity_list_name_expanded_all_cmd, "no ip large-community-list expanded WORD", NO_STR @@ -14185,12 +14394,23 @@ DEFUN (no_ip_lcommunity_list_name_expanded_all, LCOMMUNITY_LIST_STR "Specify expanded large-community-list\n" "Large Community list name\n") + +DEFUN (no_lcommunity_list_standard, + no_bgp_lcommunity_list_standard_cmd, + "no bgp large-community-list (1-99) <deny|permit> AA:AA:NN...", + NO_STR + BGP_STR + LCOMMUNITY_LIST_STR + "Large Community list number (standard)\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + LCOMMUNITY_VAL_STR) { return lcommunity_list_unset_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_EXPANDED); + LARGE_COMMUNITY_LIST_STANDARD); } -DEFUN (no_ip_lcommunity_list_standard, +ALIAS (no_lcommunity_list_standard, no_ip_lcommunity_list_standard_cmd, "no ip large-community-list (1-99) <deny|permit> AA:AA:NN...", NO_STR @@ -14200,12 +14420,23 @@ DEFUN (no_ip_lcommunity_list_standard, "Specify large community to reject\n" "Specify large community to accept\n" LCOMMUNITY_VAL_STR) + +DEFUN (no_lcommunity_list_expanded, + no_bgp_lcommunity_list_expanded_cmd, + "no bgp large-community-list (100-500) <deny|permit> LINE...", + NO_STR + BGP_STR + LCOMMUNITY_LIST_STR + "Large Community list number (expanded)\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + "An ordered list as a regular-expression\n") { return lcommunity_list_unset_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_STANDARD); + LARGE_COMMUNITY_LIST_EXPANDED); } -DEFUN (no_ip_lcommunity_list_expanded, +ALIAS (no_lcommunity_list_expanded, no_ip_lcommunity_list_expanded_cmd, "no ip large-community-list (100-500) <deny|permit> LINE...", NO_STR @@ -14215,12 +14446,24 @@ DEFUN (no_ip_lcommunity_list_expanded, "Specify large community to reject\n" "Specify large community to accept\n" "An ordered list as a regular-expression\n") + +DEFUN (no_lcommunity_list_name_standard, + no_bgp_lcommunity_list_name_standard_cmd, + "no bgp large-community-list standard WORD <deny|permit> AA:AA:NN...", + NO_STR + BGP_STR + LCOMMUNITY_LIST_STR + "Specify standard large-community-list\n" + "Large Community list name\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + LCOMMUNITY_VAL_STR) { return lcommunity_list_unset_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_EXPANDED); + LARGE_COMMUNITY_LIST_STANDARD); } -DEFUN (no_ip_lcommunity_list_name_standard, +ALIAS (no_lcommunity_list_name_standard, no_ip_lcommunity_list_name_standard_cmd, "no ip large-community-list standard WORD <deny|permit> AA:AA:NN...", NO_STR @@ -14231,12 +14474,24 @@ DEFUN (no_ip_lcommunity_list_name_standard, "Specify large community to reject\n" "Specify large community to accept\n" LCOMMUNITY_VAL_STR) + +DEFUN (no_lcommunity_list_name_expanded, + no_bgp_lcommunity_list_name_expanded_cmd, + "no bgp large-community-list expanded WORD <deny|permit> LINE...", + NO_STR + BGP_STR + LCOMMUNITY_LIST_STR + "Specify expanded large-community-list\n" + "Large community list name\n" + "Specify large community to reject\n" + "Specify large community to accept\n" + "An ordered list as a regular-expression\n") { return lcommunity_list_unset_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_STANDARD); + LARGE_COMMUNITY_LIST_EXPANDED); } -DEFUN (no_ip_lcommunity_list_name_expanded, +ALIAS (no_lcommunity_list_name_expanded, no_ip_lcommunity_list_name_expanded_cmd, "no ip large-community-list expanded WORD <deny|permit> LINE...", NO_STR @@ -14247,10 +14502,6 @@ DEFUN (no_ip_lcommunity_list_name_expanded, "Specify large community to reject\n" "Specify large community to accept\n" "An ordered list as a regular-expression\n") -{ - return lcommunity_list_unset_vty(vty, argc, argv, - LARGE_COMMUNITY_LIST_EXPANDED); -} static void lcommunity_list_show(struct vty *vty, struct community_list *list) { @@ -14282,15 +14533,23 @@ static void lcommunity_list_show(struct vty *vty, struct community_list *list) } } -DEFUN (show_ip_lcommunity_list, - show_ip_lcommunity_list_cmd, - "show ip large-community-list", +DEFUN (show_lcommunity_list, + show_bgp_lcommunity_list_cmd, + "show bgp large-community-list", SHOW_STR - IP_STR + BGP_STR "List large-community list\n") { struct community_list *list; struct community_list_master *cm; + int idx = 0; + + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'show bgp large-community-list <(1-500)|WORD>'\n"); + zlog_warn("Deprecated option: 'ip show large-community-list <(1-500)|WORD>' being used"); + } cm = community_list_master_lookup(bgp_clist, LARGE_COMMUNITY_LIST_MASTER); @@ -14306,16 +14565,31 @@ DEFUN (show_ip_lcommunity_list, return CMD_SUCCESS; } -DEFUN (show_ip_lcommunity_list_arg, - show_ip_lcommunity_list_arg_cmd, - "show ip large-community-list <(1-500)|WORD>", +ALIAS (show_lcommunity_list, + show_ip_lcommunity_list_cmd, + "show ip large-community-list", SHOW_STR IP_STR + "List large-community list\n") + +DEFUN (show_lcommunity_list_arg, + show_bgp_lcommunity_list_arg_cmd, + "show bgp large-community-list <(1-500)|WORD>", + SHOW_STR + BGP_STR "List large-community list\n" "large-community-list number\n" "large-community-list name\n") { struct community_list *list; + int idx = 0; + + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'show bgp large-community-list <(1-500)|WORD>'\n"); + zlog_warn("Deprecated option: 'ip show large-community-list <(1-500)|WORD>' being used"); + } list = community_list_lookup(bgp_clist, argv[3]->arg, LARGE_COMMUNITY_LIST_MASTER); @@ -14329,14 +14603,23 @@ DEFUN (show_ip_lcommunity_list_arg, return CMD_SUCCESS; } +ALIAS (show_lcommunity_list_arg, + show_ip_lcommunity_list_arg_cmd, + "show ip large-community-list <(1-500)|WORD>", + SHOW_STR + IP_STR + "List large-community list\n" + "large-community-list number\n" + "large-community-list name\n") + /* "extcommunity-list" keyword help string. */ #define EXTCOMMUNITY_LIST_STR "Add a extended community list entry\n" #define EXTCOMMUNITY_VAL_STR "Extended community attribute in 'rt aa:nn_or_IPaddr:nn' OR 'soo aa:nn_or_IPaddr:nn' format\n" -DEFUN (ip_extcommunity_list_standard, - ip_extcommunity_list_standard_cmd, - "ip extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...", - IP_STR +DEFUN (extcommunity_list_standard, + bgp_extcommunity_list_standard_cmd, + "bgp extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...", + BGP_STR EXTCOMMUNITY_LIST_STR "Extended Community list number (standard)\n" "Specify standard extcommunity-list\n" @@ -14350,6 +14633,12 @@ DEFUN (ip_extcommunity_list_standard, char *cl_number_or_name = NULL; int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'bgp extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>'\n"); + zlog_warn("Deprecated option: 'ip extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>' being used"); + } argv_find(argv, argc, "(1-99)", &idx); argv_find(argv, argc, "WORD", &idx); cl_number_or_name = argv[idx]->arg; @@ -14371,11 +14660,26 @@ DEFUN (ip_extcommunity_list_standard, return CMD_SUCCESS; } -DEFUN (ip_extcommunity_list_name_expanded, - ip_extcommunity_list_name_expanded_cmd, - "ip extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...", +#if CONFDATE > 20191005 +CPP_NOTICE("bgpd: remove deprecated 'ip extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>' command") +#endif +ALIAS (extcommunity_list_standard, + ip_extcommunity_list_standard_cmd, + "ip extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...", IP_STR EXTCOMMUNITY_LIST_STR + "Extended Community list number (standard)\n" + "Specify standard extcommunity-list\n" + "Community list name\n" + "Specify community to reject\n" + "Specify community to accept\n" + EXTCOMMUNITY_VAL_STR) + +DEFUN (extcommunity_list_name_expanded, + bgp_extcommunity_list_name_expanded_cmd, + "bgp extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...", + BGP_STR + EXTCOMMUNITY_LIST_STR "Extended Community list number (expanded)\n" "Specify expanded extcommunity-list\n" "Extended Community list name\n" @@ -14388,6 +14692,13 @@ DEFUN (ip_extcommunity_list_name_expanded, char *cl_number_or_name = NULL; int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>'\n"); + zlog_warn("Deprecated option: ‘ip extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>' being used"); + } + argv_find(argv, argc, "(100-500)", &idx); argv_find(argv, argc, "WORD", &idx); cl_number_or_name = argv[idx]->arg; @@ -14409,12 +14720,24 @@ DEFUN (ip_extcommunity_list_name_expanded, return CMD_SUCCESS; } -DEFUN (no_ip_extcommunity_list_standard_all, - no_ip_extcommunity_list_standard_all_cmd, - "no ip extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...", - NO_STR +ALIAS (extcommunity_list_name_expanded, + ip_extcommunity_list_name_expanded_cmd, + "ip extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...", IP_STR EXTCOMMUNITY_LIST_STR + "Extended Community list number (expanded)\n" + "Specify expanded extcommunity-list\n" + "Extended Community list name\n" + "Specify community to reject\n" + "Specify community to accept\n" + "An ordered list as a regular-expression\n") + +DEFUN (no_extcommunity_list_standard_all, + no_bgp_extcommunity_list_standard_all_cmd, + "no bgp extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...", + NO_STR + BGP_STR + EXTCOMMUNITY_LIST_STR "Extended Community list number (standard)\n" "Specify standard extcommunity-list\n" "Community list name\n" @@ -14427,6 +14750,12 @@ DEFUN (no_ip_extcommunity_list_standard_all, char *cl_number_or_name = NULL; int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'no bgp extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>'\n"); + zlog_warn("Deprecated option: ‘no ip extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>' being used"); + } argv_find(argv, argc, "(1-99)", &idx); argv_find(argv, argc, "WORD", &idx); cl_number_or_name = argv[idx]->arg; @@ -14448,12 +14777,25 @@ DEFUN (no_ip_extcommunity_list_standard_all, return CMD_SUCCESS; } -DEFUN (no_ip_extcommunity_list_expanded_all, - no_ip_extcommunity_list_expanded_all_cmd, - "no ip extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...", +ALIAS (no_extcommunity_list_standard_all, + no_ip_extcommunity_list_standard_all_cmd, + "no ip extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...", NO_STR IP_STR EXTCOMMUNITY_LIST_STR + "Extended Community list number (standard)\n" + "Specify standard extcommunity-list\n" + "Community list name\n" + "Specify community to reject\n" + "Specify community to accept\n" + EXTCOMMUNITY_VAL_STR) + +DEFUN (no_extcommunity_list_expanded_all, + no_bgp_extcommunity_list_expanded_all_cmd, + "no bgp extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...", + NO_STR + BGP_STR + EXTCOMMUNITY_LIST_STR "Extended Community list number (expanded)\n" "Specify expanded extcommunity-list\n" "Extended Community list name\n" @@ -14466,6 +14808,12 @@ DEFUN (no_ip_extcommunity_list_expanded_all, char *cl_number_or_name = NULL; int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'no bgp extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>'\n"); + zlog_warn("Deprecated option: ‘no ip extcommunity-list <(1-99)|(100-500)|standard|expanded> <deny|permit> <LINE|AA:NN>' being used"); + } argv_find(argv, argc, "(100-500)", &idx); argv_find(argv, argc, "WORD", &idx); cl_number_or_name = argv[idx]->arg; @@ -14487,6 +14835,19 @@ DEFUN (no_ip_extcommunity_list_expanded_all, return CMD_SUCCESS; } +ALIAS (no_extcommunity_list_expanded_all, + no_ip_extcommunity_list_expanded_all_cmd, + "no ip extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...", + NO_STR + IP_STR + EXTCOMMUNITY_LIST_STR + "Extended Community list number (expanded)\n" + "Specify expanded extcommunity-list\n" + "Extended Community list name\n" + "Specify community to reject\n" + "Specify community to accept\n" + "An ordered list as a regular-expression\n") + static void extcommunity_list_show(struct vty *vty, struct community_list *list) { struct community_entry *entry; @@ -14517,16 +14878,23 @@ static void extcommunity_list_show(struct vty *vty, struct community_list *list) } } -DEFUN (show_ip_extcommunity_list, - show_ip_extcommunity_list_cmd, - "show ip extcommunity-list", +DEFUN (show_extcommunity_list, + show_bgp_extcommunity_list_cmd, + "show bgp extcommunity-list", SHOW_STR - IP_STR + BGP_STR "List extended-community list\n") { struct community_list *list; struct community_list_master *cm; + int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'show bgp extcommunity-list <(1-500)|WORD>'\n"); + zlog_warn("Deprecated option: 'ip show extcommunity-list <(1-500)|WORD>' being used"); + } cm = community_list_master_lookup(bgp_clist, EXTCOMMUNITY_LIST_MASTER); if (!cm) return CMD_SUCCESS; @@ -14540,18 +14908,32 @@ DEFUN (show_ip_extcommunity_list, return CMD_SUCCESS; } -DEFUN (show_ip_extcommunity_list_arg, - show_ip_extcommunity_list_arg_cmd, - "show ip extcommunity-list <(1-500)|WORD>", +ALIAS (show_extcommunity_list, + show_ip_extcommunity_list_cmd, + "show ip extcommunity-list", SHOW_STR IP_STR + "List extended-community list\n") + +DEFUN (show_extcommunity_list_arg, + show_bgp_extcommunity_list_arg_cmd, + "show bgp extcommunity-list <(1-500)|WORD>", + SHOW_STR + BGP_STR "List extended-community list\n" "Extcommunity-list number\n" "Extcommunity-list name\n") { int idx_comm_list = 3; struct community_list *list; + int idx = 0; + if (argv_find(argv, argc, "ip", &idx)) { + vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); + vty_out(vty, "if you are using this please migrate to the below command.\n"); + vty_out(vty, "'show bgp extcommunity-list <(1-500)|WORD>'\n"); + zlog_warn("Deprecated option: 'ip show extcommunity-list <(1-500)|WORD>' being used"); + } list = community_list_lookup(bgp_clist, argv[idx_comm_list]->arg, EXTCOMMUNITY_LIST_MASTER); if (!list) { @@ -14564,6 +14946,15 @@ DEFUN (show_ip_extcommunity_list_arg, return CMD_SUCCESS; } +ALIAS (show_extcommunity_list_arg, + show_ip_extcommunity_list_arg_cmd, + "show ip extcommunity-list <(1-500)|WORD>", + SHOW_STR + IP_STR + "List extended-community list\n" + "Extcommunity-list number\n" + "Extcommunity-list name\n") + /* Display community-list and extcommunity-list configuration. */ static int community_list_config_write(struct vty *vty) { @@ -14577,14 +14968,14 @@ static int community_list_config_write(struct vty *vty) for (list = cm->num.head; list; list = list->next) for (entry = list->head; entry; entry = entry->next) { - vty_out(vty, "ip community-list %s %s %s\n", list->name, + vty_out(vty, "bgp community-list %s %s %s\n", list->name, community_direct_str(entry->direct), community_list_config_str(entry)); write++; } for (list = cm->str.head; list; list = list->next) for (entry = list->head; entry; entry = entry->next) { - vty_out(vty, "ip community-list %s %s %s %s\n", + vty_out(vty, "bgp community-list %s %s %s %s\n", entry->style == COMMUNITY_LIST_STANDARD ? "standard" : "expanded", @@ -14598,14 +14989,14 @@ static int community_list_config_write(struct vty *vty) for (list = cm->num.head; list; list = list->next) for (entry = list->head; entry; entry = entry->next) { - vty_out(vty, "ip extcommunity-list %s %s %s\n", + vty_out(vty, "bgp extcommunity-list %s %s %s\n", list->name, community_direct_str(entry->direct), community_list_config_str(entry)); write++; } for (list = cm->str.head; list; list = list->next) for (entry = list->head; entry; entry = entry->next) { - vty_out(vty, "ip extcommunity-list %s %s %s %s\n", + vty_out(vty, "bgp extcommunity-list %s %s %s %s\n", entry->style == EXTCOMMUNITY_LIST_STANDARD ? "standard" : "expanded", @@ -14621,14 +15012,14 @@ static int community_list_config_write(struct vty *vty) for (list = cm->num.head; list; list = list->next) for (entry = list->head; entry; entry = entry->next) { - vty_out(vty, "ip large-community-list %s %s %s\n", + vty_out(vty, "bgp large-community-list %s %s %s\n", list->name, community_direct_str(entry->direct), community_list_config_str(entry)); write++; } for (list = cm->str.head; list; list = list->next) for (entry = list->head; entry; entry = entry->next) { - vty_out(vty, "ip large-community-list %s %s %s %s\n", + vty_out(vty, "bgp large-community-list %s %s %s %s\n", entry->style == LARGE_COMMUNITY_LIST_STANDARD ? "standard" : "expanded", @@ -14649,6 +15040,12 @@ static void community_list_vty(void) install_node(&community_list_node, community_list_config_write); /* Community-list. */ + install_element(CONFIG_NODE, &bgp_community_list_standard_cmd); + install_element(CONFIG_NODE, &bgp_community_list_expanded_all_cmd); + install_element(CONFIG_NODE, &no_bgp_community_list_standard_all_cmd); + install_element(CONFIG_NODE, &no_bgp_community_list_expanded_all_cmd); + install_element(VIEW_NODE, &show_bgp_community_list_cmd); + install_element(VIEW_NODE, &show_bgp_community_list_arg_cmd); install_element(CONFIG_NODE, &ip_community_list_standard_cmd); install_element(CONFIG_NODE, &ip_community_list_expanded_all_cmd); install_element(CONFIG_NODE, &no_ip_community_list_standard_all_cmd); @@ -14657,6 +15054,12 @@ static void community_list_vty(void) install_element(VIEW_NODE, &show_ip_community_list_arg_cmd); /* Extcommunity-list. */ + install_element(CONFIG_NODE, &bgp_extcommunity_list_standard_cmd); + install_element(CONFIG_NODE, &bgp_extcommunity_list_name_expanded_cmd); + install_element(CONFIG_NODE, &no_bgp_extcommunity_list_standard_all_cmd); + install_element(CONFIG_NODE, &no_bgp_extcommunity_list_expanded_all_cmd); + install_element(VIEW_NODE, &show_bgp_extcommunity_list_cmd); + install_element(VIEW_NODE, &show_bgp_extcommunity_list_arg_cmd); install_element(CONFIG_NODE, &ip_extcommunity_list_standard_cmd); install_element(CONFIG_NODE, &ip_extcommunity_list_name_expanded_cmd); install_element(CONFIG_NODE, &no_ip_extcommunity_list_standard_all_cmd); @@ -14665,6 +15068,21 @@ static void community_list_vty(void) install_element(VIEW_NODE, &show_ip_extcommunity_list_arg_cmd); /* Large Community List */ + install_element(CONFIG_NODE, &bgp_lcommunity_list_standard_cmd); + install_element(CONFIG_NODE, &bgp_lcommunity_list_standard1_cmd); + install_element(CONFIG_NODE, &bgp_lcommunity_list_expanded_cmd); + install_element(CONFIG_NODE, &bgp_lcommunity_list_name_standard_cmd); + install_element(CONFIG_NODE, &bgp_lcommunity_list_name_standard1_cmd); + install_element(CONFIG_NODE, &bgp_lcommunity_list_name_expanded_cmd); + install_element(CONFIG_NODE, &no_bgp_lcommunity_list_standard_all_cmd); + install_element(CONFIG_NODE, + &no_bgp_lcommunity_list_name_expanded_all_cmd); + install_element(CONFIG_NODE, &no_bgp_lcommunity_list_standard_cmd); + install_element(CONFIG_NODE, &no_bgp_lcommunity_list_expanded_cmd); + install_element(CONFIG_NODE, &no_bgp_lcommunity_list_name_standard_cmd); + install_element(CONFIG_NODE, &no_bgp_lcommunity_list_name_expanded_cmd); + install_element(VIEW_NODE, &show_bgp_lcommunity_list_cmd); + install_element(VIEW_NODE, &show_bgp_lcommunity_list_arg_cmd); install_element(CONFIG_NODE, &ip_lcommunity_list_standard_cmd); install_element(CONFIG_NODE, &ip_lcommunity_list_standard1_cmd); install_element(CONFIG_NODE, &ip_lcommunity_list_expanded_cmd); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 3b762a362b..5a5c7c9861 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -229,8 +229,6 @@ static int bgp_interface_delete(int command, struct zclient *zclient, struct bgp *bgp; bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; s = zclient->ibuf; ifp = zebra_interface_state_read(s, vrf_id); @@ -240,7 +238,8 @@ static int bgp_interface_delete(int command, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name); - bgp_update_interface_nbrs(bgp, ifp, NULL); + if (bgp) + bgp_update_interface_nbrs(bgp, ifp, NULL); if_set_index(ifp, IFINDEX_INTERNAL); return 0; @@ -257,8 +256,6 @@ static int bgp_interface_up(int command, struct zclient *zclient, struct bgp *bgp; bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; s = zclient->ibuf; ifp = zebra_interface_state_read(s, vrf_id); @@ -269,6 +266,9 @@ static int bgp_interface_up(int command, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name); + if (!bgp) + return 0; + for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c)) bgp_connected_add(bgp, c); @@ -290,8 +290,6 @@ static int bgp_interface_down(int command, struct zclient *zclient, struct peer *peer; bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; s = zclient->ibuf; ifp = zebra_interface_state_read(s, vrf_id); @@ -301,6 +299,9 @@ static int bgp_interface_down(int command, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name); + if (!bgp) + return 0; + for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c)) bgp_connected_delete(bgp, c); @@ -342,8 +343,6 @@ static int bgp_interface_address_add(int command, struct zclient *zclient, struct bgp *bgp; bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id); @@ -357,6 +356,9 @@ static int bgp_interface_address_add(int command, struct zclient *zclient, ifc->ifp->name, buf); } + if (!bgp) + return 0; + if (if_is_operative(ifc->ifp)) { bgp_connected_add(bgp, ifc); @@ -379,8 +381,6 @@ static int bgp_interface_address_delete(int command, struct zclient *zclient, struct bgp *bgp; bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id); @@ -394,7 +394,7 @@ static int bgp_interface_address_delete(int command, struct zclient *zclient, ifc->ifp->name, buf); } - if (if_is_operative(ifc->ifp)) { + if (bgp && if_is_operative(ifc->ifp)) { bgp_connected_delete(bgp, ifc); } @@ -483,23 +483,23 @@ static int bgp_interface_vrf_update(int command, struct zclient *zclient, ifp->name, new_vrf_id); bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; - for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c)) - bgp_connected_delete(bgp, c); + if (bgp) { + for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c)) + bgp_connected_delete(bgp, c); - for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc)) - bgp_nbr_connected_delete(bgp, nc, 1); + for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc)) + bgp_nbr_connected_delete(bgp, nc, 1); - /* Fast external-failover */ - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) { - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if ((peer->ttl != 1) && (peer->gtsm_hops != 1)) - continue; + /* Fast external-failover */ + if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) { + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + if ((peer->ttl != 1) && (peer->gtsm_hops != 1)) + continue; - if (ifp == peer->nexthop.ifp) - BGP_EVENT_ADD(peer, BGP_Stop); + if (ifp == peer->nexthop.ifp) + BGP_EVENT_ADD(peer, BGP_Stop); + } } } @@ -1580,7 +1580,7 @@ static void bgp_redist_del(struct bgp *bgp, afi_t afi, uint8_t type, listnode_delete(bgp->redist[afi][type], red); XFREE(MTYPE_BGP_REDIST, red); if (!bgp->redist[afi][type]->count) - list_delete_and_null(&bgp->redist[afi][type]); + list_delete(&bgp->redist[afi][type]); } } @@ -2191,8 +2191,6 @@ static void bgp_encode_pbr_ipset_match(struct stream *s, stream_put(s, pbim->ipset_name, ZEBRA_IPSET_NAME_SIZE); - - } static void bgp_encode_pbr_ipset_entry_match(struct stream *s, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index e4dedc2420..0300485e91 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1802,6 +1802,7 @@ static void peer_group2peer_config_copy_af(struct peer_group *group, static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) { int active; + struct peer *other; if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { flog_err(EC_BGP_PEER_GROUP, "%s was called for peer-group %s", @@ -1852,6 +1853,23 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } + /* + * If we are turning on a AFI/SAFI locally and we've + * started bringing a peer up, we need to tell + * the other peer to restart because we might loose + * configuration here because when the doppelganger + * gets to a established state due to how + * we resolve we could just overwrite the afi/safi + * activation. + */ + other = peer->doppelganger; + if (other + && (other->status == OpenSent + || other->status == OpenConfirm)) { + other->last_reset = PEER_DOWN_AF_ACTIVATE; + bgp_notify_send(other, BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); + } } return 0; @@ -2426,14 +2444,14 @@ int peer_group_delete(struct peer_group *group) peer_delete(other); } } - list_delete_and_null(&group->peer); + list_delete(&group->peer); for (afi = AFI_IP; afi < AFI_MAX; afi++) { for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode, prefix)) { prefix_free(prefix); } - list_delete_and_null(&group->listen_range[afi]); + list_delete(&group->listen_range[afi]); } XFREE(MTYPE_PEER_GROUP_HOST, group->name); @@ -3221,8 +3239,8 @@ void bgp_free(struct bgp *bgp) QOBJ_UNREG(bgp); - list_delete_and_null(&bgp->group); - list_delete_and_null(&bgp->peer); + list_delete(&bgp->group); + list_delete(&bgp->peer); if (bgp->peerhash) { hash_free(bgp->peerhash); @@ -3264,9 +3282,9 @@ void bgp_free(struct bgp *bgp) vpn_policy_direction_t dir; if (bgp->vpn_policy[afi].import_vrf) - list_delete_and_null(&bgp->vpn_policy[afi].import_vrf); + list_delete(&bgp->vpn_policy[afi].import_vrf); if (bgp->vpn_policy[afi].export_vrf) - list_delete_and_null(&bgp->vpn_policy[afi].export_vrf); + list_delete(&bgp->vpn_policy[afi].export_vrf); dir = BGP_VPN_POLICY_DIR_FROMVPN; if (bgp->vpn_policy[afi].rtlist[dir]) @@ -7864,7 +7882,7 @@ void bgp_terminate(void) bgp_close(); if (bm->listen_sockets) - list_delete_and_null(&bm->listen_sockets); + list_delete(&bm->listen_sockets); for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index 15e3974248..cb45fc8da4 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -2290,7 +2290,7 @@ static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */ listnode_delete(rfg->nves, rfd); listnode_add(orphaned_nves, rfd); } - list_delete_and_null(&rfg->nves); + list_delete(&rfg->nves); } /* delete it */ @@ -2367,7 +2367,7 @@ static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */ if (vty) vty_out(vty, "\n"); } - list_delete_and_null(&orphaned_nves); + list_delete(&orphaned_nves); } } @@ -3395,7 +3395,7 @@ static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */ if (rfg->rt_export_list) ecommunity_free(&rfg->rt_export_list); if (rfg->labels) - list_delete_and_null(&rfg->labels); + list_delete(&rfg->labels); if (rfg->rfp_cfg) XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); listnode_delete(bgp->rfapi_cfg->l2_groups, rfg); @@ -3809,10 +3809,10 @@ void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h) bgp_rfapi_delete_named_nve_group(NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX); bgp_rfapi_delete_named_l2_group(NULL, bgp, NULL); if (h->l2_groups != NULL) - list_delete_and_null(&h->l2_groups); - list_delete_and_null(&h->nve_groups_sequential); - list_delete_and_null(&h->rfg_export_direct_bgp_l); - list_delete_and_null(&h->rfg_export_zebra_l); + list_delete(&h->l2_groups); + list_delete(&h->nve_groups_sequential); + list_delete(&h->rfg_export_direct_bgp_l); + list_delete(&h->rfg_export_zebra_l); if (h->default_rt_export_list) ecommunity_free(&h->default_rt_export_list); if (h->default_rt_import_list) diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 16dcbd4ee7..c7c2239db7 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -483,7 +483,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd, * Delete local_nexthops list */ if (bi->extra && bi->extra->vnc.export.local_nexthops) { - list_delete_and_null( + list_delete( &bi->extra->vnc.export.local_nexthops); } diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 008da30118..fa8c038d6f 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -508,7 +508,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) */ if (pn->info) { if (pn->info != (void *)1) { - list_delete_and_null( + list_delete( (struct list * *)(&pn->info)); } @@ -1433,7 +1433,7 @@ callback: } delete_list->del = (void (*)(void *))rfapi_info_free; - list_delete_and_null(&delete_list); + list_delete(&delete_list); } RFAPI_RIB_CHECK_COUNTS(0, 0); @@ -1448,7 +1448,7 @@ callback: agg_unlock_node(pn); } if (lPendCost) { - list_delete_and_null(&lPendCost); + list_delete(&lPendCost); pn->info = NULL; agg_unlock_node(pn); } @@ -1633,7 +1633,7 @@ void rfapiRibUpdatePendingNode( */ if (pn->info) { if (pn->info != (void *)1) { - list_delete_and_null((struct list **)(&pn->info)); + list_delete((struct list **)(&pn->info)); } pn->info = NULL; agg_unlock_node(pn); /* linklist or 1 deleted */ diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 1dc2d02f15..1af9479a6a 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -3268,7 +3268,7 @@ static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg *cda, } list_delete_all_node(adb_delete_list); } - list_delete_and_null(&adb_delete_list); + list_delete(&adb_delete_list); } diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index f830c3ed52..6fcae17a8a 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -1610,7 +1610,7 @@ void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi) if (nve_list) { vnc_direct_bgp_unexport_table( afi, it->imported_vpn[afi], nve_list); - list_delete_and_null(&nve_list); + list_delete(&nve_list); } } } diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 71a4485d39..8a286d1377 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -2404,7 +2404,7 @@ void vnc_import_bgp_exterior_add_route_interior( skiplist_delete(it->monitor_exterior_orphans, an_bi_exterior, NULL); } - list_delete_and_null(&list_adopted); + list_delete(&list_adopted); } } diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 1db1755368..fdd200ac37 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -596,7 +596,7 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp, nve_list_to_nh_array(rn->p.family, nves, &nexthop_count, &nh_ary, &nhp_ary); - list_delete_and_null(&nves); + list_delete(&nves); if (nexthop_count) vnc_zebra_route_msg(&rn->p, nexthop_count, nhp_ary, @@ -768,7 +768,7 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp, vnc_zlog_debug_verbose("%s: family: %d, nve count: %d", __func__, family, nexthop_count); - list_delete_and_null(&nves); + list_delete(&nves); if (nexthop_count) { /* diff --git a/configure.ac b/configure.ac index 32d5756a61..12100121d6 100755 --- a/configure.ac +++ b/configure.ac @@ -203,7 +203,15 @@ elif test "x${enable_dev_build}" = "xyes"; then AC_C_FLAG([-g3]) AC_C_FLAG([-O0]) fi + if test "x${enable_lua}" = "xyes"; then + AC_CHECK_LIB([lua], [lua_newstate], + [LIBS="$LIBS -llua"]) + AC_DEFINE(HAVE_LUA,,Lua enabled for development) + fi else + if test "x${enable_lua}" = "xyes"; then + AC_MSG_ERROR([Lua is not meant to be built/used outside of development at this time]) + fi if test "z$orig_cflags" = "z"; then AC_C_FLAG([-g]) AC_C_FLAG([-Os], [ @@ -302,7 +310,18 @@ AC_CHECK_TOOL(AR, ar) dnl ------- dnl libtool dnl ------- +AC_ARG_ENABLE(static-bin, + AS_HELP_STRING([--enable-static-bin], [link binaries statically])) LT_INIT +_LT_CONFIG_LIBTOOL([ + patch -N -i "${srcdir}/m4/libtool-whole-archive.patch" libtool >&AS_MESSAGE_LOG_FD || \ + AC_MSG_WARN([Could not patch libtool for static linking support. Loading modules into a statically linked daemon will fail.]) +]) +if test "$enable_static_bin" = "yes"; then + AC_LDFLAGS="-static" +fi +AC_SUBST(AC_LDFLAGS) +AM_CONDITIONAL([STATIC_BIN], [test "x$enable_static_bin" = "xyes"]) dnl ---------------------- dnl Packages configuration @@ -454,6 +473,9 @@ fi AC_ARG_ENABLE([dev_build], AS_HELP_STRING([--enable-dev-build], [build for development])) +AC_ARG_ENABLE([lua], + AS_HELP_STRING([--enable-lua], [Build Lua scripting])) + if test x"${enable_time_check}" != x"no" ; then if test x"${enable_time_check}" = x"yes" -o x"${enable_time_check}" = x ; then AC_DEFINE(CONSUMED_TIME_CHECK,5000000,Consumed Time Check) @@ -730,6 +752,20 @@ if test "x$with_pkg_git_version" = "xyes"; then fi AM_CONDITIONAL([GIT_VERSION], [test "x$with_pkg_git_version" = "xyes"]) +AC_CHECK_TOOL([OBJCOPY], [objcopy], [:]) +AC_CACHE_CHECK([for .interp value to use], [frr_cv_interp], [ + frr_cv_interp="" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main() { return 0; }]])], [ + if $OBJCOPY -j.interp -Obinary conftest conftest.interp; then + frr_cv_interp="`xargs -0 echo < conftest.interp`" + fi + test -f conftest.interp && rm conftest.interp + ]) +]) +if test -n "$frr_cv_interp"; then + AC_DEFINE_UNQUOTED(INTERP, ["$frr_cv_interp"], [.interp value]) +fi + dnl ------------------------------------ dnl Check C keywords and standard types dnl ------------------------------------ @@ -1126,6 +1162,7 @@ if test x"$LIBM" = x ; then AC_MSG_WARN([Unable to find working pow function - bgpd may not link]) fi LIBS="$TMPLIBS" + AC_SUBST(LIBM) AC_CHECK_FUNCS([ppoll], [ @@ -1926,6 +1963,7 @@ for I in 1 2 3 4 5 6 7 8 9 10; do eval vtysh_bin="\"$vtysh_bin\"" done AC_DEFINE_UNQUOTED(VTYSH_BIN_PATH, "$vtysh_bin",path to vtysh binary) +AC_SUBST(vtysh_bin) CFG_SYSCONF="$sysconfdir" CFG_SBIN="$sbindir" @@ -1992,6 +2030,7 @@ AC_CONFIG_FILES([ pkgsrc/eigrpd.sh]) AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl]) +AC_CONFIG_FILES([tools/frr],[chmod +x tools/frr]) AC_CONFIG_COMMANDS([lib/route_types.h], [ dst="${ac_abs_top_builddir}/lib/route_types.h" diff --git a/debianpkg/backports/ubuntu17.10/debian/control b/debianpkg/backports/ubuntu17.10/debian/control index 1bc3c4e4b5..ce73f9d1b0 100644 --- a/debianpkg/backports/ubuntu17.10/debian/control +++ b/debianpkg/backports/ubuntu17.10/debian/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: Nobody <nobody@frrouting.org> Uploaders: Nobody <nobody@frrouting.org> XSBC-Original-Maintainer: <maintainers@frrouting.org> -Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddr, libpython-dev +Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddress, libpython-dev Standards-Version: 3.9.6 Homepage: http://www.frrouting.org/ @@ -47,7 +47,7 @@ Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (documentation) Package: frr-pythontools Section: net Architecture: all -Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr +Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddress Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools) This package includes info files for frr, a free software which manages TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3, diff --git a/debianpkg/backports/ubuntu18.04/debian/control b/debianpkg/backports/ubuntu18.04/debian/control index 1e31ad6d51..3fccb46b7a 100644 --- a/debianpkg/backports/ubuntu18.04/debian/control +++ b/debianpkg/backports/ubuntu18.04/debian/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: Nobody <nobody@frrouting.org> Uploaders: Nobody <nobody@frrouting.org> XSBC-Original-Maintainer: <maintainers@frrouting.org> -Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddr, python-sphinx, libpython-dev +Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddress, python-sphinx, libpython-dev Standards-Version: 3.9.6 Homepage: http://www.frrouting.org/ @@ -47,7 +47,7 @@ Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (documentation) Package: frr-pythontools Section: net Architecture: all -Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr +Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddress Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools) This package includes info files for frr, a free software which manages TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3, diff --git a/doc/developer/building-frr-for-ubuntu1604.rst b/doc/developer/building-frr-for-ubuntu1604.rst index 69c4e44d98..1fa0ede201 100644 --- a/doc/developer/building-frr-for-ubuntu1604.rst +++ b/doc/developer/building-frr-for-ubuntu1604.rst @@ -16,8 +16,8 @@ Add packages: apt-get install \ git autoconf automake libtool make gawk libreadline-dev texinfo dejagnu \ pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \ - libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \ - install-info + libc-ares-dev python3-dev libsystemd-dev python-ipaddress \ + python3-sphinx install-info Get FRR, compile it and install it (from Git) --------------------------------------------- diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst index 50e90fc7ea..75b31a41f9 100644 --- a/doc/developer/building-frr-for-ubuntu1804.rst +++ b/doc/developer/building-frr-for-ubuntu1804.rst @@ -12,8 +12,8 @@ Required packages sudo apt-get install \ git autoconf automake libtool make gawk libreadline-dev texinfo \ pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \ - libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \ - install-info + libc-ares-dev python3-dev libsystemd-dev python-ipaddress \ + python3-sphinx install-info Optional packages ^^^^^^^^^^^^^^^^^ diff --git a/doc/developer/packaging-debian.rst b/doc/developer/packaging-debian.rst index 66339b6d1f..4ea784c0fc 100644 --- a/doc/developer/packaging-debian.rst +++ b/doc/developer/packaging-debian.rst @@ -130,6 +130,13 @@ If all worked correctly, then you should end up with the Debian packages under with the sources (``frr_*.orig.tar.gz``, ``frr_*.debian.tar.xz`` and ``frr_*.dsc``) +The build procedure can also be executed automatically using the ``tools/build-debian-package.sh`` +script. For example: + +.. code-block:: shell + + EXTRA_VERSION="-myversion" WANT_SNMP=1 WANT_CUMULUS_MODE=1 tools/build-debian-package.sh + .. _deb-backports: Debian Backports diff --git a/doc/subdir.am b/doc/subdir.am index 4170101655..7d3792bf2b 100644 --- a/doc/subdir.am +++ b/doc/subdir.am @@ -56,7 +56,7 @@ doc/%/_build/man/man.stamp: doc/%/_build/.doctrees/environment.pickle $(MKDIR_P) "$${subdoc}/_build/man"; touch $@.tmp; \ $(SPHINXBUILD) -a -q -b man -d "$${subdoc}/_build/.doctrees" \ $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/man" && \ - mv $@.tmp $@ \ + mv -f $@.tmp $@ \ ) # diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index d9d496f7fc..f10883b984 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -181,20 +181,6 @@ will establish the connection with unicast only capability. When there are no common capabilities, FRR sends Unsupported Capability error and then resets the connection. -.. _bgp-concepts-vrfs: - -VRFs: Virtual Routing and Forwarding ------------------------------------- - -*bgpd* supports :abbr:`L3VPN (Layer 3 Virtual Private Networks)` :abbr:`VRFs -(Virtual Routing and Forwarding tables)` for IPv4 :rfc:`4364` and IPv6 -:rfc:`4659`. L3VPN routes, and their associated VRF MPLS labels, can be -distributed to VPN SAFI neighbors in the *default*, i.e., non VRF, BGP -instance. VRF MPLS labels are reached using *core* MPLS labels which are -distributed using LDP or BGP labeled unicast. *bgpd* also supports inter-VRF -route leaking. General information on FRR's VRF support can be found in -:ref:`zebra-vrf`. - .. _bgp-router-configuration: BGP Router Configuration @@ -228,6 +214,126 @@ internal or external. not enabled *bgpd* can't get interface information so `router-id` is set to 0.0.0.0. So please set router-id by hand. + +.. _bgp-multiple-autonomous-systems: + +Multiple Autonomous Systems +--------------------------- + +FRR's BGP implementation is capable of running multiple autonomous systems at +once. Each configured AS corresponds to a :ref:`zebra-vrf`. In the past, to get +the same functionality the network administrator had to run a new *bgpd* +process; using VRFs allows multiple autonomous systems to be handled in a +single process. + +When using multiple autonomous systems, all router config blocks after the +first one must specify a VRF to be the target of BGP's route selection. This +VRF must be unique within respect to all other VRFs being used for the same +purpose, i.e. two different autonomous systems cannot use the same VRF. +However, the same AS can be used with different VRFs. + +.. note:: + + The separated nature of VRFs makes it possible to peer a single *bgpd* + process to itself, on one machine. Note that this can be done fully within + BGP without a corresponding VRF in the kernel or Zebra, which enables some + practical use cases such as :ref:`route reflectors <bgp-route-reflector>` + and route servers. + +Configuration of additional autonomous systems, or of a router that targets a +specific VRF, is accomplished with the following command: + +.. index:: router bgp ASN vrf VRFNAME +.. clicmd:: router bgp ASN vrf VRFNAME + + ``VRFNAME`` is matched against VRFs configured in the kernel. When ``vrf + VRFNAME`` is not specified, the BGP protocol process belongs to the default + VRF. + +An example configuration with multiple autonomous systems might look like this: + +.. code-block:: frr + + router bgp 1 + neighbor 10.0.0.1 remote-as 20 + neighbor 10.0.0.2 remote-as 30 + ! + router bgp 2 vrf blue + neighbor 10.0.0.3 remote-as 40 + neighbor 10.0.0.4 remote-as 50 + ! + router bgp 3 vrf red + neighbor 10.0.0.5 remote-as 60 + neighbor 10.0.0.6 remote-as 70 + ... + +In the past this feature done differently and the following commands were +required to enable the functionality. They are now deprecated. + +.. deprecated:: 5.0 + This command is deprecated and may be safely removed from the config. + +.. index:: bgp multiple-instance +.. clicmd:: bgp multiple-instance + + Enable BGP multiple instance feature. Because this is now the default + configuration this command will not be displayed in the running + configuration. + +.. deprecated:: 5.0 + This command is deprecated and may be safely removed from the config. + +.. index:: no bgp multiple-instance +.. clicmd:: no bgp multiple-instance + + In previous versions of FRR, this command disabled the BGP multiple instance + feature. This functionality is automatically turned on when BGP multiple + instances or views exist so this command no longer does anything. + +.. seealso:: :ref:`bgp-vrf-route-leaking` +.. seealso:: :ref:`zebra-vrf` + + +.. _bgp-views: + +Views +----- + +In addition to supporting multiple autonomous systems, FRR's BGP implementation +also supports *views*. + +BGP views are almost the same as normal BGP processes, except that routes +selected by BGP are not installed into the kernel routing table. Each BGP view +provides an independent set of routing information which is only distributed +via BGP. Multiple views can be supported, and BGP view information is always +independent from other routing protocols and Zebra/kernel routes. BGP views use +the core instance (i.e., default VRF) for communication with peers. + +.. index:: router bgp AS-NUMBER view NAME +.. clicmd:: router bgp AS-NUMBER view NAME + + Make a new BGP view. You can use an arbitrary word for the ``NAME``. Routes + selected by the view are not installed into the kernel routing table. + + With this command, you can setup Route Server like below. + + .. code-block:: frr + + ! + router bgp 1 view 1 + neighbor 10.0.0.1 remote-as 2 + neighbor 10.0.0.2 remote-as 3 + ! + router bgp 2 view 2 + neighbor 10.0.0.3 remote-as 4 + neighbor 10.0.0.4 remote-as 5 + +.. index:: show [ip] bgp view NAME +.. clicmd:: show [ip] bgp view NAME + + Display the routing table of BGP view ``NAME``. + + Route Selection --------------- @@ -1609,32 +1715,23 @@ Large Communities in Route Map overwriting other values. Multiple large-community values can be specified. -.. _bgp-vrfs: +.. _bgp-l3vpn-vrfs: -VRFs ----- +L3VPN VRFs +---------- -BGP supports multiple VRF instances with the following command: - -.. index:: router bgp ASN vrf VRFNAME -.. clicmd:: router bgp ASN vrf VRFNAME +*bgpd* supports :abbr:`L3VPN (Layer 3 Virtual Private Networks)` :abbr:`VRFs +(Virtual Routing and Forwarding)` for IPv4 :rfc:`4364` and IPv6 :rfc:`4659`. +L3VPN routes, and their associated VRF MPLS labels, can be distributed to VPN +SAFI neighbors in the *default*, i.e., non VRF, BGP instance. VRF MPLS labels +are reached using *core* MPLS labels which are distributed using LDP or BGP +labeled unicast. *bgpd* also supports inter-VRF route leaking. -``VRFNAME`` is matched against VRFs configured in the kernel. When -``vrf VRFNAME`` is not specified, the BGP protocol process belongs to the -default VRF. -With VRF, you can isolate networking information. Having BGP VRF allows you to -have several BGP instances on the same system process. This solution solves -scalabiliy issues where the network administrator had previously to run -separately several BGP processes on each namespace. Now, not only BGP VRF -solves this, but also this method applies to both kind of VRFs backend: default -VRF from Linux kernel or network namespaces. Also, having separate BGP -instances does not imply that the AS number has to be different. For internal -purposes, it is possible to do iBGP peering from two differents network -namespaces. +.. _bgp-vrf-route-leaking: VRF Route Leaking -^^^^^^^^^^^^^^^^^ +----------------- BGP routes may be leaked (i.e. copied) between a unicast VRF RIB and the VPN SAFI RIB of the default VRF for use in MPLS-based L3VPNs. Unicast routes may @@ -1648,7 +1745,7 @@ to a unicast VRF, whereas ``export`` refers to routes leaked from a unicast VRF to VPN. Required parameters -""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^ Routes exported from a unicast VRF to the VPN RIB must be augmented by two parameters: @@ -1682,7 +1779,7 @@ When using the shortcut syntax for vrf-to-vrf leaking, the RD and RT are auto-derived. General configuration -""""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^^ Configuration of route leaking between a unicast VRF RIB and the VPN SAFI RIB of the default VRF is accomplished via commands in the context of a VRF @@ -1781,86 +1878,6 @@ address-family: Disables automatic leaking from vrf VRFNAME to the current VRF using the VPN RIB as intermediary. -.. _bgp-instances-and-views: - -Instances and Views -------------------- - -A BGP *instance* is a normal BGP process. Routes selected by BGP are installed -into the kernel routing table. - -.. note:: - In previous versions of FRR, running multiple AS's from the same BGP process - was not supported; in order to run multiple AS's it was necessary to run - multiple BGP processes. This had to be explicitly configured with the - ``bgp multiple-instance`` command. Recent versions of FRR support multiple - BGP AS's within the same process by simply defining multiple - ``router bgp X`` blocks, so the ``multiple-instance`` command is now - unnecessary and deprecated. - -.. index:: router bgp AS-NUMBER -.. clicmd:: router bgp AS-NUMBER - - Make a new BGP instance. You can use an arbitrary word for the `name`. - - .. code-block:: frr - - router bgp 1 - neighbor 10.0.0.1 remote-as 2 - neighbor 10.0.0.2 remote-as 3 - ! - router bgp 2 - neighbor 10.0.0.3 remote-as 4 - neighbor 10.0.0.4 remote-as 5 - -.. deprecated:: 5.0 - This command does nothing and can be safely removed. - -.. index:: bgp multiple-instance -.. clicmd:: bgp multiple-instance - - Enable BGP multiple instance feature. Because this is now the default - configuration this command will not be displayed in the running - configuration. - -.. deprecated:: 5.0 - This command does nothing and can be safely removed. - -.. index:: no bgp multiple-instance -.. clicmd:: no bgp multiple-instance - - In previous versions of FRR, this command disabled the BGP multiple instance - feature. This functionality is automatically turned on when BGP multiple - instances or views exist so this command no longer does anything. - -BGP views are almost same as normal BGP processes, except that routes selected -by BGP are not installed into the kernel routing table. The view functionality -allows the exchange of BGP routing information only without affecting the -kernel routing tables. - -.. index:: router bgp AS-NUMBER view NAME -.. clicmd:: router bgp AS-NUMBER view NAME - - Make a new BGP view. You can use arbitrary word for the ``NAME``. Routes selected by the view are not installed into the kernel routing table. - view's route selection result does not go to the kernel routing table. - - With this command, you can setup Route Server like below. - - .. code-block:: frr - - ! - router bgp 1 view 1 - neighbor 10.0.0.1 remote-as 2 - neighbor 10.0.0.2 remote-as 3 - ! - router bgp 2 view 2 - neighbor 10.0.0.3 remote-as 4 - neighbor 10.0.0.4 remote-as 5 - -.. index:: show [ip] bgp view NAME -.. clicmd:: show [ip] bgp view NAME - - Display the routing table of BGP view ``NAME``. .. _bgp-cisco-compatibility: diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst index 57b4875e23..42a8250ae0 100644 --- a/doc/user/routemap.rst +++ b/doc/user/routemap.rst @@ -105,10 +105,10 @@ Route Map Match Command Matches the specified `access_list` -.. index:: match ip address PREFIX-LIST -.. clicmd:: match ip address PREFIX-LIST +.. index:: match ip address prefix-list PREFIX_LIST +.. clicmd:: match ip address prefix-list PREFIX_LIST - Matches the specified `prefix-list` + Matches the specified `PREFIX_LIST` .. index:: match ip address prefix-len 0-32 .. clicmd:: match ip address prefix-len 0-32 @@ -120,10 +120,10 @@ Route Map Match Command Matches the specified `access_list` -.. index:: match ipv6 address PREFIX-LIST -.. clicmd:: match ipv6 address PREFIX-LIST +.. index:: match ipv6 address prefix-list PREFIX_LIST +.. clicmd:: match ipv6 address prefix-list PREFIX_LIST - Matches the specified `prefix-list` + Matches the specified `PREFIX_LIST` .. index:: match ipv6 address prefix-len 0-128 .. clicmd:: match ipv6 address prefix-len 0-128 diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 651a9339d7..bbe2b88223 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -300,7 +300,7 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) tn->serno); if (successors) - list_delete_and_null(&successors); + list_delete(&successors); } void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index d291cab4c0..f955e6df0f 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -453,7 +453,7 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg) // neighbors left } - list_delete_and_null(&successors); + list_delete(&successors); return 1; } @@ -479,7 +479,7 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) // neighbors left } - list_delete_and_null(&successors); + list_delete(&successors); return 1; } @@ -530,7 +530,7 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) ne = listnode_head(successors); eigrp_send_reply(ne->adv_router, prefix); - list_delete_and_null(&successors); + list_delete(&successors); } prefix->state = EIGRP_FSM_STATE_PASSIVE; @@ -560,7 +560,7 @@ int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg) msg); - list_delete_and_null(&successors); + list_delete(&successors); return 1; } @@ -584,7 +584,7 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) ne = listnode_head(successors); eigrp_send_reply(ne->adv_router, prefix); - list_delete_and_null(&successors); + list_delete(&successors); } prefix->req_action |= EIGRP_FSM_NEED_UPDATE; listnode_add(eigrp->topology_changes_internalIPV4, prefix); @@ -620,7 +620,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) // neighbors left } - list_delete_and_null(&successors); + list_delete(&successors); return 1; } @@ -636,6 +636,6 @@ int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg) msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2; msg->prefix->distance = ne->distance; - list_delete_and_null(&successors); + list_delete(&successors); return 1; } diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 913db684c1..e450c7d999 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -109,7 +109,7 @@ int eigrp_if_delete_hook(struct interface *ifp) if (!ei) return 0; - list_delete_and_null(&ei->nbrs); + list_delete(&ei->nbrs); eigrp = ei->eigrp; listnode_delete(eigrp->eiflist, ei); @@ -351,7 +351,7 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) eigrp_if_down(ei); - list_delete_and_null(&ei->nbrs); + list_delete(&ei->nbrs); listnode_delete(ei->eigrp->eiflist, ei); } diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index dd4231fa00..84dcf5e2d5 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -235,11 +235,8 @@ void eigrp_send_query(struct eigrp_interface *ei) } } - if (!has_tlv) { - if (ep) - eigrp_packet_free(ep); + if (!has_tlv) return; - } if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) && ei->params.auth_keychain != NULL) diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 3520972731..0cb4e0e9f4 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -164,7 +164,7 @@ void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node, eigrp_zebra_route_add(node->destination, l); } - list_delete_and_null(&l); + list_delete(&l); } /* @@ -193,8 +193,8 @@ void eigrp_prefix_entry_delete(struct route_table *table, for (ALL_LIST_ELEMENTS(pe->entries, node, nnode, ne)) eigrp_nexthop_entry_delete(pe, ne); - list_delete_and_null(&pe->entries); - list_delete_and_null(&pe->rij); + list_delete(&pe->entries); + list_delete(&pe->rij); eigrp_zebra_route_delete(pe->destination); prefix_free(pe->destination); @@ -276,7 +276,7 @@ struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node) * If we have no successors return NULL */ if (!successors->count) { - list_delete_and_null(&successors); + list_delete(&successors); successors = NULL; } @@ -481,7 +481,7 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix) for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG; - list_delete_and_null(&successors); + list_delete(&successors); } else { eigrp_zebra_route_delete(prefix->destination); for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry)) diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index e0142f6b32..8db4903077 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -411,7 +411,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, eigrp_update_send_all(eigrp, ei); if (nbr_prefixes) - list_delete_and_null(&nbr_prefixes); + list_delete(&nbr_prefixes); } /*send EIGRP Update packet*/ diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index e9f81fc1c5..9bbecdf9e3 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -266,15 +266,15 @@ void eigrp_finish_final(struct eigrp *eigrp) THREAD_OFF(eigrp->t_read); close(eigrp->fd); - list_delete_and_null(&eigrp->eiflist); - list_delete_and_null(&eigrp->oi_write_q); + list_delete(&eigrp->eiflist); + list_delete(&eigrp->oi_write_q); eigrp_topology_free(eigrp->topology_table); eigrp_nbr_delete(eigrp->neighbor_self); - list_delete_and_null(&eigrp->topology_changes_externalIPV4); - list_delete_and_null(&eigrp->topology_changes_internalIPV4); + list_delete(&eigrp->topology_changes_externalIPV4); + list_delete(&eigrp->topology_changes_internalIPV4); listnode_delete(eigrp_om->eigrp, eigrp); diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index b43a3915ae..58c6dfa368 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -449,17 +449,17 @@ void isis_circuit_if_del(struct isis_circuit *circuit, struct interface *ifp) if (circuit->ip_addrs) { assert(listcount(circuit->ip_addrs) == 0); - list_delete_and_null(&circuit->ip_addrs); + list_delete(&circuit->ip_addrs); } if (circuit->ipv6_link) { assert(listcount(circuit->ipv6_link) == 0); - list_delete_and_null(&circuit->ipv6_link); + list_delete(&circuit->ipv6_link); } if (circuit->ipv6_non_link) { assert(listcount(circuit->ipv6_non_link) == 0); - list_delete_and_null(&circuit->ipv6_non_link); + list_delete(&circuit->ipv6_non_link); } circuit->circ_type = CIRCUIT_T_UNKNOWN; @@ -685,22 +685,22 @@ void isis_circuit_down(struct isis_circuit *circuit) if (circuit->circ_type == CIRCUIT_T_BROADCAST) { /* destroy neighbour lists */ if (circuit->u.bc.lan_neighs[0]) { - list_delete_and_null(&circuit->u.bc.lan_neighs[0]); + list_delete(&circuit->u.bc.lan_neighs[0]); circuit->u.bc.lan_neighs[0] = NULL; } if (circuit->u.bc.lan_neighs[1]) { - list_delete_and_null(&circuit->u.bc.lan_neighs[1]); + list_delete(&circuit->u.bc.lan_neighs[1]); circuit->u.bc.lan_neighs[1] = NULL; } /* destroy adjacency databases */ if (circuit->u.bc.adjdb[0]) { circuit->u.bc.adjdb[0]->del = isis_delete_adj; - list_delete_and_null(&circuit->u.bc.adjdb[0]); + list_delete(&circuit->u.bc.adjdb[0]); circuit->u.bc.adjdb[0] = NULL; } if (circuit->u.bc.adjdb[1]) { circuit->u.bc.adjdb[1]->del = isis_delete_adj; - list_delete_and_null(&circuit->u.bc.adjdb[1]); + list_delete(&circuit->u.bc.adjdb[1]); circuit->u.bc.adjdb[1] = NULL; } if (circuit->u.bc.is_dr[0]) { diff --git a/isisd/isis_dr.c b/isisd/isis_dr.c index 99506a243d..f71fe9555b 100644 --- a/isisd/isis_dr.c +++ b/isisd/isis_dr.c @@ -135,7 +135,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level) if (!adjdb) { zlog_warn("isis_dr_elect() adjdb == NULL"); - list_delete_and_null(&list); + list_delete(&list); return ISIS_WARNING; } isis_adj_build_up_list(adjdb, list); @@ -177,7 +177,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level) */ if (circuit->u.bc.is_dr[level - 1]) retval = isis_dr_resign(circuit, level); - list_delete_and_null(&list); + list_delete(&list); return retval; } @@ -217,7 +217,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level) if (circuit->u.bc.is_dr[level - 1]) retval = isis_dr_resign(circuit, level); } - list_delete_and_null(&list); + list_delete(&list); return retval; } diff --git a/isisd/isis_events.c b/isisd/isis_events.c index 342787af30..5dcc0a1324 100644 --- a/isisd/isis_events.c +++ b/isisd/isis_events.c @@ -134,7 +134,7 @@ static void circuit_resign_level(struct isis_circuit *circuit, int level) circuit->lsp_regenerate_pending[idx] = 0; circuit->u.bc.run_dr_elect[idx] = 0; if (circuit->u.bc.lan_neighs[idx] != NULL) - list_delete_and_null(&circuit->u.bc.lan_neighs[idx]); + list_delete(&circuit->u.bc.lan_neighs[idx]); } return; diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index b2c6f092ee..1258bec064 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -126,7 +126,7 @@ static void lsp_destroy(struct isis_lsp *lsp) lsp_clear_data(lsp); if (LSP_FRAGMENT(lsp->hdr.lsp_id) == 0 && lsp->lspu.frags) { - list_delete_and_null(&lsp->lspu.frags); + list_delete(&lsp->lspu.frags); lsp->lspu.frags = NULL; } @@ -1050,6 +1050,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) uint8_t subtlv_len; if (IS_MPLS_TE(isisMplsTE) + && circuit->interface && HAS_LINK_PARAMS( circuit->interface)) subtlv_len = add_te_subtlvs( @@ -1181,7 +1182,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) frag->tlvs = tlvs; } - list_delete_and_null(&fragments); + list_delete(&fragments); lsp_debug("ISIS (%s): LSP construction is complete. Serializing...", area->area_tag); return; @@ -1560,7 +1561,7 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit, LSP_PSEUDO_ID(ne_id)); } } - list_delete_and_null(&adj_list); + list_delete(&adj_list); return; } diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c index 2dfccf9830..e0227f4656 100644 --- a/isisd/isis_mt.c +++ b/isisd/isis_mt.c @@ -163,7 +163,7 @@ void area_mt_init(struct isis_area *area) void area_mt_finish(struct isis_area *area) { - list_delete_and_null(&area->mt_settings); + list_delete(&area->mt_settings); } struct isis_area_mt_setting *area_get_mt_setting(struct isis_area *area, @@ -286,7 +286,7 @@ void circuit_mt_init(struct isis_circuit *circuit) void circuit_mt_finish(struct isis_circuit *circuit) { - list_delete_and_null(&circuit->mt_settings); + list_delete(&circuit->mt_settings); } struct isis_circuit_mt_setting * diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 7843fb9b9d..99041b0e61 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -1356,7 +1356,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, } /* lets free it */ - list_delete_and_null(&lsp_list); + list_delete(&lsp_list); } if (fabricd_initial_sync_is_complete(circuit->area) && resync_needed) diff --git a/isisd/isis_route.c b/isisd/isis_route.c index b1225ae547..f9b4a2b146 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -253,13 +253,13 @@ static void isis_route_info_delete(struct isis_route_info *route_info) if (route_info->nexthops) { route_info->nexthops->del = (void (*)(void *))isis_nexthop_delete; - list_delete_and_null(&route_info->nexthops); + list_delete(&route_info->nexthops); } if (route_info->nexthops6) { route_info->nexthops6->del = (void (*)(void *))isis_nexthop6_delete; - list_delete_and_null(&route_info->nexthops6); + list_delete(&route_info->nexthops6); } XFREE(MTYPE_ISIS_ROUTE_INFO, route_info); diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 6a7528623c..1440a3becf 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -824,7 +824,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, adjdb = circuit->u.bc.adjdb[spftree->level - 1]; isis_adj_build_up_list(adjdb, adj_list); if (listcount(adj_list) == 0) { - list_delete_and_null(&adj_list); + list_delete(&adj_list); if (isis->debugs & DEBUG_SPF_EVENTS) zlog_debug( "ISIS-Spf: no L%d adjacencies on circuit %s", @@ -890,7 +890,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, "isis_spf_preload_tent unknow adj type"); } } - list_delete_and_null(&adj_list); + list_delete(&adj_list); /* * Add the pseudonode */ @@ -1068,7 +1068,8 @@ static void isis_spf_loop(struct isis_spftree *spftree, lsp = lsp_for_vertex(spftree, vertex); if (!lsp) { zlog_warn("ISIS-Spf: No LSP found for %s", - rawlspid_print(vertex->N.id)); /* FIXME */ + isis_format_id(vertex->N.id, + sizeof(vertex->N.id))); continue; } diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h index 453abfedd8..131fa37991 100644 --- a/isisd/isis_spf_private.h +++ b/isisd/isis_spf_private.h @@ -168,8 +168,8 @@ static void isis_vertex_queue_init(struct isis_vertex_queue *queue, __attribute__((__unused__)) static void isis_vertex_del(struct isis_vertex *vertex) { - list_delete_and_null(&vertex->Adj_N); - list_delete_and_null(&vertex->parents); + list_delete(&vertex->Adj_N); + list_delete(&vertex->parents); if (vertex->firsthops) { hash_clean(vertex->firsthops, NULL); hash_free(vertex->firsthops); @@ -212,7 +212,7 @@ static void isis_vertex_queue_free(struct isis_vertex_queue *queue) skiplist_free(queue->l.slist); queue->l.slist = NULL; } else - list_delete_and_null(&queue->l.list); + list_delete(&queue->l.list); } __attribute__((__unused__)) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 782462766a..fce3a0a113 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -2946,7 +2946,7 @@ struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size) struct listnode *node; for (ALL_LIST_ELEMENTS_RO(rv, node, fragment_tlvs)) isis_free_tlvs(fragment_tlvs); - list_delete_and_null(&rv); + list_delete(&rv); } stream_free(dummy_stream); diff --git a/isisd/isisd.c b/isisd/isisd.c index e3ff3b8d93..e5e43c4b7d 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -226,7 +226,7 @@ int isis_area_destroy(struct vty *vty, const char *area_tag) circuit->ipv6_router = 0; isis_csm_state_change(ISIS_DISABLE, circuit, area); } - list_delete_and_null(&area->circuit_list); + list_delete(&area->circuit_list); } if (area->lspdb[0] != NULL) { diff --git a/lib/command.c b/lib/command.c index e4e3d786ac..60c5f4e75b 100644 --- a/lib/command.c +++ b/lib/command.c @@ -695,7 +695,7 @@ static vector cmd_complete_command_real(vector vline, struct vty *vty, } vector comps = completions_to_vec(completions); - list_delete_and_null(&completions); + list_delete(&completions); // set status code appropriately switch (vector_active(comps)) { @@ -1020,7 +1020,7 @@ static int cmd_execute_command_real(vector vline, enum filter_type filter, // if matcher error, return corresponding CMD_ERR if (MATCHER_ERROR(status)) { if (argv_list) - list_delete_and_null(&argv_list); + list_delete(&argv_list); switch (status) { case MATCHER_INCOMPLETE: return CMD_ERR_INCOMPLETE; @@ -1049,7 +1049,7 @@ static int cmd_execute_command_real(vector vline, enum filter_type filter, ret = matched_element->func(matched_element, vty, argc, argv); // delete list and cmd_token's in it - list_delete_and_null(&argv_list); + list_delete(&argv_list); XFREE(MTYPE_TMP, argv); return ret; @@ -2949,6 +2949,6 @@ void cmd_terminate() if (host.config) XFREE(MTYPE_HOST, host.config); - list_delete_and_null(&varhandlers); + list_delete(&varhandlers); qobj_finish(); } diff --git a/lib/command_match.c b/lib/command_match.c index a1ae3ac6b9..8b34d1e3eb 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -334,7 +334,7 @@ static enum matcher_rv command_match_r(struct graph_node *start, vector vline, status = MATCHER_INCOMPLETE; // cleanup - list_delete_and_null(&next); + list_delete(&next); return status; } @@ -367,7 +367,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, unsigned int idx; for (idx = 0; idx < vector_active(vline) && next->count > 0; idx++) { - list_delete_and_null(¤t); + list_delete(¤t); current = next; next = list_new(); next->del = stack_del; @@ -458,8 +458,8 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, } } - list_delete_and_null(¤t); - list_delete_and_null(&next); + list_delete(¤t); + list_delete(&next); return mrv; } @@ -652,7 +652,7 @@ static void del_arglist(struct list *list) list_delete_node(list, tail); // delete the rest of the list as usual - list_delete_and_null(&list); + list_delete(&list); } /*---------- token level matching functions ----------*/ diff --git a/lib/ferr.c b/lib/ferr.c index afef196cec..bf89cc7f46 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -167,7 +167,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json) json_object_free(top); } - list_delete_and_null(&errlist); + list_delete(&errlist); } DEFUN_NOSH(show_error_code, diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index c1ce57e24e..a0223730b8 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -61,7 +61,7 @@ void frr_pthread_finish() { pthread_mutex_lock(&frr_pthread_list_mtx); { - list_delete_and_null(&frr_pthread_list); + list_delete(&frr_pthread_list); } pthread_mutex_unlock(&frr_pthread_list_mtx); } diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 0d6200b006..20d5879c67 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -140,7 +140,7 @@ DEFUN (grammar_test_complete, vty_out(vty, "%% No match\n"); // free resources - list_delete_and_null(&completions); + list_delete(&completions); cmd_free_strvec(command); XFREE(MTYPE_TMP, cmdstr); @@ -184,7 +184,7 @@ DEFUN (grammar_test_match, vty_out(vty, "func: %p\n", element->func); - list_delete_and_null(&argvv); + list_delete(&argvv); } else { assert(MATCHER_ERROR(result)); switch (result) { @@ -421,7 +421,7 @@ DEFUN (grammar_findambig, } prev = cur; } - list_delete_and_null(&commands); + list_delete(&commands); vty_out(vty, "\n"); } while (scan && scannode < LINK_PARAMS_NODE); diff --git a/lib/hash.c b/lib/hash.c index ee5401b236..114522a75a 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -318,7 +318,7 @@ void hash_free(struct hash *hash) if (_hashes) { listnode_delete(_hashes, hash); if (_hashes->count == 0) { - list_delete_and_null(&_hashes); + list_delete(&_hashes); } } } @@ -206,8 +206,8 @@ void if_delete(struct interface *ifp) if_delete_retain(ifp); - list_delete_and_null(&ifp->connected); - list_delete_and_null(&ifp->nbr_connected); + list_delete(&ifp->connected); + list_delete(&ifp->nbr_connected); if_link_params_free(ifp); diff --git a/lib/keychain.c b/lib/keychain.c index 494f6f6430..601b44a4f1 100644 --- a/lib/keychain.c +++ b/lib/keychain.c @@ -119,7 +119,7 @@ static void keychain_delete(struct keychain *keychain) if (keychain->name) XFREE(MTYPE_KEYCHAIN, keychain->name); - list_delete_and_null(&keychain->key); + list_delete(&keychain->key); listnode_delete(keychain_list, keychain); keychain_free(keychain); } diff --git a/lib/libfrr.c b/lib/libfrr.c index 2bce4766d3..35a6da577f 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -54,6 +54,7 @@ static char pidfile_default[512]; static char vtypath_default[256]; bool debug_memstats_at_exit = 0; +static bool nodetach_term, nodetach_daemon; static char comb_optstr[256]; static struct option comb_lo[64]; @@ -281,6 +282,8 @@ void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv) opt_extend(&os_zclient); if (!(di->flags & FRR_NO_TCPVTY)) opt_extend(&os_vty); + if (di->flags & FRR_DETACH_LATER) + nodetach_daemon = true; snprintf(config_default, sizeof(config_default), "%s/%s.conf", frr_sysconfdir, di->name); @@ -767,13 +770,16 @@ void frr_config_fork(void) { hook_call(frr_late_init, master); - /* Don't start execution if we are in dry-run mode */ - if (di->dryrun) { - frr_config_read_in(NULL); - exit(0); - } + if (!(di->flags & FRR_NO_CFG_PID_DRY)) { + /* Don't start execution if we are in dry-run mode */ + if (di->dryrun) { + frr_config_read_in(NULL); + exit(0); + } - thread_add_event(master, frr_config_read_in, NULL, 0, &di->read_in); + thread_add_event(master, frr_config_read_in, NULL, 0, + &di->read_in); + } if (di->daemon_mode || di->terminal) frr_daemonize(); @@ -783,7 +789,7 @@ void frr_config_fork(void) pid_output(di->pid_file); } -void frr_vty_serv(void) +static void frr_vty_serv(void) { /* allow explicit override of vty_path in the future * (not currently set anywhere) */ @@ -810,14 +816,22 @@ void frr_vty_serv(void) vty_serv_sock(di->vty_addr, di->vty_port, di->vty_path); } +static void frr_check_detach(void) +{ + if (nodetach_term || nodetach_daemon) + return; + + if (daemon_ctl_sock != -1) + close(daemon_ctl_sock); + daemon_ctl_sock = -1; +} + static void frr_terminal_close(int isexit) { int nullfd; - if (daemon_ctl_sock != -1) { - close(daemon_ctl_sock); - daemon_ctl_sock = -1; - } + nodetach_term = false; + frr_check_detach(); if (!di->daemon_mode || isexit) { printf("\n%s exiting\n", di->name); @@ -881,6 +895,12 @@ out: return 0; } +void frr_detach(void) +{ + nodetach_daemon = false; + frr_check_detach(); +} + void frr_run(struct thread_master *master) { char instanceinfo[64] = ""; @@ -895,6 +915,8 @@ void frr_run(struct thread_master *master) instanceinfo, di->vty_port, di->startinfo); if (di->terminal) { + nodetach_term = true; + vty_stdio(frr_terminal_close); if (daemon_ctl_sock != -1) { set_nonblocking(daemon_ctl_sock); @@ -914,9 +936,7 @@ void frr_run(struct thread_master *master) close(nullfd); } - if (daemon_ctl_sock != -1) - close(daemon_ctl_sock); - daemon_ctl_sock = -1; + frr_check_detach(); } /* end fixed stderr startup logging */ @@ -973,3 +993,25 @@ void frr_fini(void) fclose(fp); } } + +#ifdef INTERP +static const char interp[] + __attribute__((section(".interp"), used)) = INTERP; +#endif +/* + * executable entry point for libfrr.so + * + * note that libc initialization is skipped for this so the set of functions + * that can be called is rather limited + */ +extern void _libfrr_version(void) + __attribute__((visibility("hidden"), noreturn)); +void _libfrr_version(void) +{ + const char banner[] = + FRR_FULL_NAME " " FRR_VERSION ".\n" + FRR_COPYRIGHT GIT_INFO "\n" + "configured with:\n " FRR_CONFIG_ARGS "\n"; + write(1, banner, sizeof(banner) - 1); + _exit(0); +} diff --git a/lib/libfrr.h b/lib/libfrr.h index d255279906..db58ff92be 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -29,11 +29,21 @@ #include "module.h" #include "hook.h" +/* The following options disable specific command line options that + * are not applicable for a particular daemon. + */ #define FRR_NO_PRIVSEP (1 << 0) #define FRR_NO_TCPVTY (1 << 1) #define FRR_LIMITED_CLI (1 << 2) -#define FRR_NO_CFG_PID_DRY (1 << 3) +#define FRR_NO_CFG_PID_DRY (1 << 3) #define FRR_NO_ZCLIENT (1 << 4) +/* If FRR_DETACH_LATER is used, the daemon will keep its parent running + * until frr_detach() is called. Normally "somedaemon -d" returns once the + * main event loop is reached in the daemon; use this for extra startup bits. + * + * Does nothing if -d isn't used. + */ +#define FRR_DETACH_LATER (1 << 5) struct frr_daemon_info { unsigned flags; @@ -102,10 +112,8 @@ extern struct thread_master *frr_init(void); DECLARE_HOOK(frr_late_init, (struct thread_master * tm), (tm)) extern void frr_config_fork(void); -extern void frr_vty_serv(void); - -/* note: contains call to frr_vty_serv() */ extern void frr_run(struct thread_master *master); +extern void frr_detach(void); extern bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len, const char *path); diff --git a/lib/linklist.c b/lib/linklist.c index bee9d05a2c..3aa7cae8b7 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -240,7 +240,7 @@ void list_delete_all_node(struct list *list) list->count = 0; } -void list_delete_and_null(struct list **list) +void list_delete(struct list **list) { assert(*list); list_delete_all_node(*list); @@ -248,11 +248,6 @@ void list_delete_and_null(struct list **list) *list = NULL; } -void list_delete_original(struct list *list) -{ - list_delete_and_null(&list); -} - struct listnode *listnode_lookup(struct list *list, void *data) { struct listnode *node; diff --git a/lib/linklist.h b/lib/linklist.h index f5cd44efb0..0475391e9f 100644 --- a/lib/linklist.h +++ b/lib/linklist.h @@ -236,20 +236,6 @@ extern void list_sort(struct list *list, int (*cmp)(const void **, const void **)); /* - * The usage of list_delete is being transitioned to pass in - * the double pointer to remove use after free's. - * list_free usage is deprecated, it leads to memory leaks - * of the linklist nodes. Please use list_delete_and_null - * - * In Oct of 2018, rename list_delete_and_null to list_delete - * and remove list_delete_original and the list_delete #define - * Additionally remove list_free entirely - */ -#if CONFDATE > 20181001 -CPP_NOTICE("list_delete without double pointer is deprecated, please fixup") -#endif - -/* * Delete a list and NULL its pointer. * * If non-null, list->del is called with each data element. @@ -258,23 +244,7 @@ CPP_NOTICE("list_delete without double pointer is deprecated, please fixup") * pointer to list pointer; this will be set to NULL after the list has been * deleted */ -extern void list_delete_and_null(struct list **plist); - -/* - * Delete a list. - * - * If non-null, list->del is called with each data element. - * - * plist - * pointer to list pointer - */ -extern void list_delete_original(struct list *list); -#define list_delete(X) \ - list_delete_original((X)) \ - CPP_WARN("Please transition to using list_delete_and_null") -#define list_free(X) \ - list_delete_original((X)) \ - CPP_WARN("Please transition tousing list_delete_and_null") +extern void list_delete(struct list **plist); /* * Delete all nodes from a list without deleting the list itself. diff --git a/lib/lua.c b/lib/lua.c new file mode 100644 index 0000000000..3d701a9364 --- /dev/null +++ b/lib/lua.c @@ -0,0 +1,130 @@ +/* + * This file defines the lua interface into + * FRRouting. + * + * Copyright (C) 2016 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FreeRangeRouting (FRR). + * + * FRR is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later version. + * + * FRR is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with FRR; see the file COPYING. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <stdio.h> + +#include <zebra.h> + +#if defined(HAVE_LUA) +#include "prefix.h" +#include "lua.h" +#include "log.h" + +static int lua_zlog_debug(lua_State *L) +{ + int debug_lua = 1; + const char *string = lua_tostring(L, 1); + + if (debug_lua) + zlog_debug("%s", string); + + return 0; +} + +const char *get_string(lua_State *L, const char *key) +{ + const char *str; + + lua_pushstring(L, key); + lua_gettable(L, -2); + + str = (const char *)lua_tostring(L, -1); + lua_pop(L, 1); + + return str; +} + +int get_integer(lua_State *L, const char *key) +{ + int result; + + lua_pushstring(L, key); + lua_gettable(L, -2); + + result = lua_tointeger(L, -1); + lua_pop(L, 1); + + return result; +} + +static void *lua_alloc(void *ud, void *ptr, size_t osize, + size_t nsize) +{ + (void)ud; (void)osize; /* not used */ + if (nsize == 0) { + free(ptr); + return NULL; + } else + return realloc(ptr, nsize); +} + +lua_State *lua_initialize(const char *file) +{ + int status; + lua_State *L = lua_newstate(lua_alloc, NULL); + + zlog_debug("Newstate: %p", L); + luaL_openlibs(L); + zlog_debug("Opened lib"); + status = luaL_loadfile(L, file); + if (status) { + zlog_debug("Failure to open %s %d", file, status); + lua_close(L); + return NULL; + } + + lua_pcall(L, 0, LUA_MULTRET, 0); + zlog_debug("Setting global function"); + lua_pushcfunction(L, lua_zlog_debug); + lua_setglobal(L, "zlog_debug"); + + return L; +} + +void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix) +{ + char buffer[100]; + + lua_newtable(L); + lua_pushstring(L, prefix2str(prefix, buffer, 100)); + lua_setfield(L, -2, "route"); + lua_pushinteger(L, prefix->family); + lua_setfield(L, -2, "family"); + lua_setglobal(L, "prefix"); +} + +enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule) +{ + int status; + + lua_getglobal(L, rule); + status = lua_pcall(L, 0, 1, 0); + if (status) { + zlog_debug("Executing Failure with function: %s: %d", + rule, status); + return LUA_RM_FAILURE; + } + + status = lua_tonumber(L, -1); + return status; +} +#endif diff --git a/lib/lua.h b/lib/lua.h new file mode 100644 index 0000000000..8020a22711 --- /dev/null +++ b/lib/lua.h @@ -0,0 +1,79 @@ +/* + * This file defines the lua interface into + * FRRouting. + * + * Copyright (C) 2016 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FreeRangeRouting (FRR). + * + * FRR is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later version. + * + * FRR is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with FRR; see the file COPYING. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __LUA_H__ +#define __LUA_H__ + +#if defined(HAVE_LUA) + +#include <lua.h> +#include <lualib.h> +#include <lauxlib.h> + +/* + * These functions are helper functions that + * try to glom some of the lua_XXX functionality + * into what we actually need, instead of having + * to make multiple calls to set up what + * we want + */ +enum lua_rm_status { + /* + * Script function run failure. This will translate into a + * deny + */ + LUA_RM_FAILURE = 0, + /* + * No Match was found for the route map function + */ + LUA_RM_NOMATCH, + /* + * Match was found but no changes were made to the + * incoming data. + */ + LUA_RM_MATCH, + /* + * Match was found and data was modified, so + * figure out what changed + */ + LUA_RM_MATCH_AND_CHANGE, +}; + +/* + * Open up the lua.scr file and parse + * initial global values, if any. + */ +lua_State *lua_initialize(const char *file); + +void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix); + +enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule); + +/* + * Get particular string/integer information + * from a table. It is *assumed* that + * the table has already been selected + */ +const char *get_string(lua_State *L, const char *key); +int get_integer(lua_State *L, const char *key); +#endif +#endif diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 937b84bddd..23ea96f75c 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -246,7 +246,7 @@ static void nhgc_delete(struct nexthop_group_cmd *nhgc) RB_REMOVE(nhgc_entry_head, &nhgc_entries, nhgc); - list_delete_and_null(&nhgc->nhg_list); + list_delete(&nhgc->nhg_list); XFREE(MTYPE_TMP, nhgc); } diff --git a/lib/openbsd-tree.c b/lib/openbsd-tree.c index e8d13339b6..eadef9902b 100644 --- a/lib/openbsd-tree.c +++ b/lib/openbsd-tree.c @@ -345,7 +345,7 @@ rbe_remove(const struct rb_type *t, struct rbt_tree *rbt, struct rb_entry *rbe) else RBE_RIGHT(tmp) = rbe; - rbe_if_augment(t, parent); + rbe_if_augment(t, tmp); } else RBH_ROOT(rbt) = rbe; diff --git a/lib/routemap.c b/lib/routemap.c index bec6d389e5..bc45cd51d0 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -111,6 +111,20 @@ struct route_map_match_set_hooks { const char *arg, route_map_event_t type); + /* match ip next hop type */ + int (*match_ip_next_hop_type)(struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type); + + /* no match ip next hop type */ + int (*no_match_ip_next_hop_type)(struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type); + /* match ipv6 address */ int (*match_ipv6_address)(struct vty *vty, struct route_map_index *index, @@ -138,6 +152,19 @@ struct route_map_match_set_hooks { const char *arg, route_map_event_t type); + /* match ipv6 next-hop type */ + int (*match_ipv6_next_hop_type)(struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type); + + /* no match ipv6next-hop type */ + int (*no_match_ipv6_next_hop_type)(struct vty *vty, + struct route_map_index *index, + const char *command, const char *arg, + route_map_event_t type); + /* match metric */ int (*match_metric)(struct vty *vty, struct route_map_index *index, const char *command, const char *arg, @@ -275,6 +302,22 @@ void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)( rmap_match_set_hook.no_match_ip_next_hop_prefix_list = func; } +/* match ip next hop type */ +void route_map_match_ip_next_hop_type_hook(int (*func)( + struct vty *vty, struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type)) +{ + rmap_match_set_hook.match_ip_next_hop_type = func; +} + +/* no match ip next hop type */ +void route_map_no_match_ip_next_hop_type_hook(int (*func)( + struct vty *vty, struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type)) +{ + rmap_match_set_hook.no_match_ip_next_hop_type = func; +} + /* match ipv6 address */ void route_map_match_ipv6_address_hook(int (*func)( struct vty *vty, struct route_map_index *index, const char *command, @@ -308,6 +351,22 @@ void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)( rmap_match_set_hook.no_match_ipv6_address_prefix_list = func; } +/* match ipv6 next-hop type */ +void route_map_match_ipv6_next_hop_type_hook(int (*func)( + struct vty *vty, struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type)) +{ + rmap_match_set_hook.match_ipv6_next_hop_type = func; +} + +/* no match ipv6 next-hop type */ +void route_map_no_match_ipv6_next_hop_type_hook(int (*func)( + struct vty *vty, struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type)) +{ + rmap_match_set_hook.no_match_ipv6_next_hop_type = func; +} + /* match metric */ void route_map_match_metric_hook(int (*func)( struct vty *vty, struct route_map_index *index, const char *command, @@ -854,11 +913,13 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map) struct route_map_index *index; struct route_map_rule *rule; - vty_out(vty, "%s:\n", frr_protonameinst); + vty_out(vty, "route-map: %s Invoked: %" PRIu64 "\n", + map->name, map->applied); for (index = map->head; index; index = index->next) { - vty_out(vty, "route-map %s, %s, sequence %d\n", map->name, - route_map_type_str(index->type), index->pref); + vty_out(vty, " %s, sequence %d Invoked %" PRIu64 "\n", + route_map_type_str(index->type), index->pref, + index->applied); /* Description */ if (index->description) @@ -904,6 +965,8 @@ static int vty_show_route_map(struct vty *vty, const char *name) { struct route_map *map; + vty_out(vty, "%s:\n", frr_protonameinst); + if (name) { map = route_map_lookup_by_name(name); @@ -928,7 +991,7 @@ static int vty_show_route_map(struct vty *vty, const char *name) for (ALL_LIST_ELEMENTS_RO(maplist, ln, map)) vty_show_route_map_entry(vty, map); - list_delete_and_null(&maplist); + list_delete(&maplist); } return CMD_SUCCESS; } @@ -1457,8 +1520,10 @@ route_map_result_t route_map_apply(struct route_map *map, if (map == NULL) return RMAP_DENYMATCH; + map->applied++; for (index = map->head; index; index = index->next) { /* Apply this index. */ + index->applied++; ret = route_map_apply_match(&index->match_list, prefix, type, object); @@ -2028,6 +2093,45 @@ DEFUN (no_match_ip_next_hop_prefix_list, return CMD_SUCCESS; } +DEFUN(match_ip_next_hop_type, match_ip_next_hop_type_cmd, + "match ip next-hop type <blackhole>", + MATCH_STR IP_STR + "Match next-hop address of route\n" + "Match entries by type\n" + "Blackhole\n") +{ + int idx_word = 4; + VTY_DECLVAR_CONTEXT(route_map_index, index); + + if (rmap_match_set_hook.match_ip_next_hop_type) + return rmap_match_set_hook.match_ip_next_hop_type( + vty, index, "ip next-hop type", argv[idx_word]->arg, + RMAP_EVENT_MATCH_ADDED); + return CMD_SUCCESS; +} + +DEFUN(no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd, + "no match ip next-hop type [<blackhole>]", + NO_STR MATCH_STR IP_STR + "Match next-hop address of route\n" + "Match entries by type\n" + "Blackhole\n") +{ + int idx_word = 5; + VTY_DECLVAR_CONTEXT(route_map_index, index); + + if (rmap_match_set_hook.no_match_ip_next_hop) { + if (argc <= idx_word) + return rmap_match_set_hook.no_match_ip_next_hop( + vty, index, "ip next-hop type", NULL, + RMAP_EVENT_MATCH_DELETED); + return rmap_match_set_hook.no_match_ip_next_hop( + vty, index, "ip next-hop type", argv[idx_word]->arg, + RMAP_EVENT_MATCH_DELETED); + } + return CMD_SUCCESS; +} + DEFUN (match_ipv6_address, match_ipv6_address_cmd, @@ -2106,6 +2210,39 @@ DEFUN (no_match_ipv6_address_prefix_list, return CMD_SUCCESS; } +DEFUN(match_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd, + "match ipv6 next-hop type <blackhole>", + MATCH_STR IPV6_STR + "Match address of route\n" + "Match entries by type\n" + "Blackhole\n") +{ + int idx_word = 4; + VTY_DECLVAR_CONTEXT(route_map_index, index); + + if (rmap_match_set_hook.match_ipv6_next_hop_type) + return rmap_match_set_hook.match_ipv6_next_hop_type( + vty, index, "ipv6 next-hop type", argv[idx_word]->arg, + RMAP_EVENT_MATCH_ADDED); + return CMD_SUCCESS; +} + +DEFUN(no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd, + "no match ipv6 next-hop type [<blackhole>]", + NO_STR MATCH_STR IPV6_STR + "Match address of route\n" + "Match entries by type\n" + "Blackhole\n") +{ + int idx_word = 5; + VTY_DECLVAR_CONTEXT(route_map_index, index); + + if (rmap_match_set_hook.no_match_ipv6_next_hop_type) + return rmap_match_set_hook.no_match_ipv6_next_hop_type( + vty, index, "ipv6 next-hop type", argv[idx_word]->arg, + RMAP_EVENT_MATCH_DELETED); + return CMD_SUCCESS; +} DEFUN (match_metric, match_metric_cmd, @@ -2873,12 +3010,18 @@ void route_map_init(void) install_element(RMAP_NODE, &match_ip_next_hop_prefix_list_cmd); install_element(RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd); + install_element(RMAP_NODE, &match_ip_next_hop_type_cmd); + install_element(RMAP_NODE, &no_match_ip_next_hop_type_cmd); + install_element(RMAP_NODE, &match_ipv6_address_cmd); install_element(RMAP_NODE, &no_match_ipv6_address_cmd); install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd); install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd); + install_element(RMAP_NODE, &match_ipv6_next_hop_type_cmd); + install_element(RMAP_NODE, &no_match_ipv6_next_hop_type_cmd); + install_element(RMAP_NODE, &match_metric_cmd); install_element(RMAP_NODE, &no_match_metric_cmd); diff --git a/lib/routemap.h b/lib/routemap.h index a193e32536..481b8c4a9a 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -142,6 +142,9 @@ struct route_map_index { struct route_map_index *next; struct route_map_index *prev; + /* Keep track how many times we've try to apply */ + uint64_t applied; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(route_map_index) @@ -163,6 +166,9 @@ struct route_map { bool to_be_processed; /* True if modification isn't acted on yet */ bool deleted; /* If 1, then this node will be deleted */ + /* How many times have we applied this route-map */ + uint64_t applied; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(route_map) @@ -283,6 +289,14 @@ extern void route_map_match_ip_next_hop_prefix_list_hook(int (*func)( extern void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)( struct vty *vty, struct route_map_index *index, const char *command, const char *arg, route_map_event_t type)); +/* match ip next hop type */ +extern void route_map_match_ip_next_hop_type_hook(int (*func)( + struct vty *vty, struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type)); +/* no match ip next hop type */ +extern void route_map_no_match_ip_next_hop_type_hook(int (*func)( + struct vty *vty, struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type)); /* match ipv6 address */ extern void route_map_match_ipv6_address_hook(int (*func)( struct vty *vty, struct route_map_index *index, const char *command, @@ -299,6 +313,14 @@ extern void route_map_match_ipv6_address_prefix_list_hook(int (*func)( extern void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)( struct vty *vty, struct route_map_index *index, const char *command, const char *arg, route_map_event_t type)); +/* match ipv6 next-hop type */ +extern void route_map_match_ipv6_next_hop_type_hook(int (*func)( + struct vty *vty, struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type)); +/* no match ipv6 next-hop type */ +extern void route_map_no_match_ipv6_next_hop_type_hook(int (*func)( + struct vty *vty, struct route_map_index *index, const char *command, + const char *arg, route_map_event_t type)); /* match metric */ extern void route_map_match_metric_hook(int (*func)( struct vty *vty, struct route_map_index *index, const char *command, diff --git a/lib/subdir.am b/lib/subdir.am index 499bb94920..dd2731f74c 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -2,7 +2,7 @@ # libfrr # lib_LTLIBRARIES += lib/libfrr.la -lib_libfrr_la_LDFLAGS = -version-info 0:0:0 +lib_libfrr_la_LDFLAGS = -version-info 0:0:0 -Xlinker -e_libfrr_version lib_libfrr_la_LIBADD = @LIBCAP@ lib_libfrr_la_SOURCES = \ @@ -82,6 +82,7 @@ lib_libfrr_la_SOURCES = \ lib/workqueue.c \ lib/zclient.c \ lib/logicalrouter.c \ + lib/lua.c \ # end vtysh_scan += \ @@ -190,6 +191,7 @@ pkginclude_HEADERS += \ lib/zclient.h \ lib/zebra.h \ lib/logicalrouter.h \ + lib/lua.h \ lib/pbr.h \ # end @@ -205,6 +207,17 @@ noinst_HEADERS += \ lib/plist_int.h \ #end +# General note about module and module helper library (libfrrsnmp, libfrrzmq) +# linking: If we're linking libfrr statically into daemons, we *must* remove +# libfrr from modules because modules will always link it in dynamically and +# thus 2 copies of libfrr will be loaded... hilarity ensues. +# +# Not linking libfrr into modules should generally work fine because the +# executable refers to libfrr either way and the dynamic linker should make +# libfrr available to modules. If some OS platform has a dynamic linker that +# doesn't do that, libfrr needs to be readded to modules, but _only_ _if_ +# it's not linked into daemons statically. + # # SNMP support # @@ -214,7 +227,7 @@ endif lib_libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 lib_libfrrsnmp_la_LDFLAGS = -version-info 0:0:0 -lib_libfrrsnmp_la_LIBADD = lib/libfrr.la $(SNMP_LIBS) +lib_libfrrsnmp_la_LIBADD = $(SNMP_LIBS) lib_libfrrsnmp_la_SOURCES = \ lib/agentx.c \ lib/snmp.c \ @@ -230,7 +243,7 @@ endif lib_libfrrzmq_la_CFLAGS = $(WERROR) $(ZEROMQ_CFLAGS) lib_libfrrzmq_la_LDFLAGS = -version-info 0:0:0 -lib_libfrrzmq_la_LIBADD = lib/libfrr.la $(ZEROMQ_LIBS) +lib_libfrrzmq_la_LIBADD = $(ZEROMQ_LIBS) lib_libfrrzmq_la_SOURCES = \ lib/frr_zmq.c \ #end diff --git a/lib/thread.c b/lib/thread.c index 2c3db27c7b..267dcd1cfc 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -58,6 +58,7 @@ pthread_key_t thread_current; pthread_mutex_t masters_mtx = PTHREAD_MUTEX_INITIALIZER; static struct list *masters; +static void thread_free(struct thread_master *master, struct thread *thread); /* CLI start ---------------------------------------------------------------- */ static unsigned int cpu_record_hash_key(struct cpu_thread_history *a) @@ -538,6 +539,8 @@ static struct thread *thread_trim_head(struct thread_list *list) /* Move thread to unuse list. */ static void thread_add_unuse(struct thread_master *m, struct thread *thread) { + pthread_mutex_t mtxc = thread->mtx; + assert(m != NULL && thread != NULL); assert(thread->next == NULL); assert(thread->prev == NULL); @@ -546,10 +549,15 @@ static void thread_add_unuse(struct thread_master *m, struct thread *thread) memset(thread, 0, sizeof(struct thread)); thread->type = THREAD_UNUSED; - if (m->unuse.count < THREAD_UNUSED_DEPTH) + /* Restore the thread mutex context. */ + thread->mtx = mtxc; + + if (m->unuse.count < THREAD_UNUSED_DEPTH) { thread_list_add(&m->unuse, thread); - else - XFREE(MTYPE_THREAD, thread); + return; + } + + thread_free(m, thread); } /* Free all unused thread. */ @@ -560,9 +568,8 @@ static void thread_list_free(struct thread_master *m, struct thread_list *list) for (t = list->head; t; t = next) { next = t->next; - XFREE(MTYPE_THREAD, t); + thread_free(m, t); list->count--; - m->alloc--; } } @@ -576,8 +583,7 @@ static void thread_array_free(struct thread_master *m, t = thread_array[index]; if (t) { thread_array[index] = NULL; - XFREE(MTYPE_THREAD, t); - m->alloc--; + thread_free(m, t); } } XFREE(MTYPE_THREAD_POLL, thread_array); @@ -588,9 +594,8 @@ static void thread_queue_free(struct thread_master *m, struct pqueue *queue) int i; for (i = 0; i < queue->size; i++) - XFREE(MTYPE_THREAD, queue->array[i]); + thread_free(m, queue->array[i]); - m->alloc -= queue->size; pqueue_delete(queue); } @@ -608,8 +613,7 @@ void thread_master_free_unused(struct thread_master *m) { struct thread *t; while ((t = thread_trim_head(&m->unuse)) != NULL) { - pthread_mutex_destroy(&t->mtx); - XFREE(MTYPE_THREAD, t); + thread_free(m, t); } } pthread_mutex_unlock(&m->mtx); @@ -622,7 +626,7 @@ void thread_master_free(struct thread_master *m) { listnode_delete(masters, m); if (masters->count == 0) { - list_delete_and_null(&masters); + list_delete(&masters); } } pthread_mutex_unlock(&masters_mtx); @@ -637,7 +641,7 @@ void thread_master_free(struct thread_master *m) pthread_cond_destroy(&m->cancel_cond); close(m->io_pipe[0]); close(m->io_pipe[1]); - list_delete_and_null(&m->cancel_req); + list_delete(&m->cancel_req); m->cancel_req = NULL; hash_clean(m->cpu_record, cpu_record_hash_free); @@ -728,6 +732,17 @@ static struct thread *thread_get(struct thread_master *m, uint8_t type, return thread; } +static void thread_free(struct thread_master *master, struct thread *thread) +{ + /* Update statistics. */ + assert(master->alloc > 0); + master->alloc--; + + /* Free allocated resources. */ + pthread_mutex_destroy(&thread->mtx); + XFREE(MTYPE_THREAD, thread); +} + static int fd_poll(struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize, nfds_t count, const struct timeval *timer_wait) { @@ -1633,25 +1648,27 @@ void funcname_thread_execute(struct thread_master *m, int (*func)(struct thread *), void *arg, int val, debugargdef) { - struct cpu_thread_history tmp; - struct thread dummy; - - memset(&dummy, 0, sizeof(struct thread)); + struct thread *thread; - pthread_mutex_init(&dummy.mtx, NULL); - dummy.type = THREAD_EVENT; - dummy.add_type = THREAD_EXECUTE; - dummy.master = NULL; - dummy.arg = arg; - dummy.u.val = val; + /* Get or allocate new thread to execute. */ + pthread_mutex_lock(&m->mtx); + { + thread = thread_get(m, THREAD_EVENT, func, arg, debugargpass); - tmp.func = dummy.func = func; - tmp.funcname = dummy.funcname = funcname; - dummy.hist = hash_get(m->cpu_record, &tmp, - (void *(*)(void *))cpu_record_hash_alloc); + /* Set its event value. */ + pthread_mutex_lock(&thread->mtx); + { + thread->add_type = THREAD_EXECUTE; + thread->u.val = val; + thread->ref = &thread; + } + pthread_mutex_unlock(&thread->mtx); + } + pthread_mutex_unlock(&m->mtx); - dummy.schedfrom = schedfrom; - dummy.schedfrom_line = fromln; + /* Execute thread doing all accounting. */ + thread_call(thread); - thread_call(&dummy); + /* Give back or free thread. */ + thread_add_unuse(m, thread); } diff --git a/lib/wheel.c b/lib/wheel.c index 722b02424a..69d2fa48dc 100644 --- a/lib/wheel.c +++ b/lib/wheel.c @@ -115,7 +115,7 @@ void wheel_delete(struct timer_wheel *wheel) int i; for (i = 0; i < wheel->slots; i++) { - list_delete_and_null(&wheel->wheel_slot_lists[i]); + list_delete(&wheel->wheel_slot_lists[i]); } THREAD_OFF(wheel->timer); diff --git a/lib/zclient.c b/lib/zclient.c index e6626a178b..8b1069b827 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -133,7 +133,7 @@ void redist_del_instance(struct redist_proto *red, unsigned short instance) XFREE(MTYPE_REDIST_INST, id); if (!red->instances->count) { red->enabled = 0; - list_delete_and_null(&red->instances); + list_delete(&red->instances); } } diff --git a/lib/zebra.h b/lib/zebra.h index 4e0e408ea6..46721cc1ab 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -379,6 +379,12 @@ struct in_pktinfo { */ #define ZEBRA_HEADER_MARKER 254 +/* + * The compiler.h header is used for anyone using the CPP_NOTICE + * since this is universally needed, let's add it to zebra.h + */ +#include "compiler.h" + /* Zebra route's types are defined in route_types.h */ #include "route_types.h" diff --git a/m4/.gitignore b/m4/.gitignore index 357e65588d..2c04163659 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -1,4 +1,5 @@ *.m4 +!*.patch !ax_compare_version.m4 !ax_prog_perl_modules.m4 diff --git a/m4/libtool-whole-archive.patch b/m4/libtool-whole-archive.patch new file mode 100644 index 0000000000..7e2749c90a --- /dev/null +++ b/m4/libtool-whole-archive.patch @@ -0,0 +1,18 @@ +--- /usr/share/libtool/build-aux/ltmain.sh 2017-08-01 07:13:09.611041402 +0200 ++++ ltmain.sh 2018-08-31 17:32:15.381903718 +0200 +@@ -8439,8 +8439,13 @@ + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library +- compile_deplibs="$dir/$linklib $compile_deplibs" +- finalize_deplibs="$dir/$linklib $finalize_deplibs" ++ if test yes,yes = "$export_dynamic,$with_gnu_ld"; then ++ compile_deplibs="-Wl,--no-whole-archive $dir/$linklib -Wl,--whole-archive $compile_deplibs" ++ finalize_deplibs="-Wl,--no-whole-archive $dir/$linklib -Wl,--whole-archive $finalize_deplibs" ++ else ++ compile_deplibs="$dir/$linklib $compile_deplibs" ++ finalize_deplibs="$dir/$linklib $finalize_deplibs" ++ fi + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 586584c65c..1890e9bdc3 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -171,8 +171,9 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, /* AS External routes are never considered */ if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 || route->path.type == OSPF6_PATH_TYPE_EXTERNAL2) { - if (is_debug) - zlog_debug("Path type is external, skip"); +#if 0 + zlog_debug("Path type is external, skip"); +#endif return 0; } @@ -1004,6 +1005,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_ROUTER)) { /* To pass test suites */ + assert(router_lsa); if (!OSPF6_OPT_ISSET(router_lsa->options, OSPF6_OPT_R) || !OSPF6_OPT_ISSET(router_lsa->options, OSPF6_OPT_V6)) { if (is_debug) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 2cab69aac2..c848a16aa9 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -277,7 +277,7 @@ void ospf6_area_delete(struct ospf6_area *oa) for (ALL_LIST_ELEMENTS_RO(oa->if_list, n, oi)) oi->area = NULL; - list_delete_and_null(&oa->if_list); + list_delete(&oa->if_list); ospf6_lsdb_delete(oa->lsdb); ospf6_lsdb_delete(oa->lsdb_self); @@ -441,6 +441,7 @@ DEFUN (area_range, SET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); } else if (strmatch(argv[idx_type]->text, "advertise")) { UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + cost = range->path.u.cost_config; } else { cost = strtoul(argv[5]->arg, NULL, 10); UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 9777a01ae6..17a30188c7 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -241,7 +241,7 @@ void ospf6_interface_delete(struct ospf6_interface *oi) for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) ospf6_neighbor_delete(on); - list_delete_and_null(&oi->neighbor_list); + list_delete(&oi->neighbor_list); THREAD_OFF(oi->thread_send_hello); THREAD_OFF(oi->thread_send_lsupdate); diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index bba3c0db5e..79e1a44392 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -365,7 +365,7 @@ static int ospf6_path_cmp(struct ospf6_path *a, struct ospf6_path *b) void ospf6_path_free(struct ospf6_path *op) { if (op->nh_list) - list_delete_and_null(&op->nh_list); + list_delete(&op->nh_list); XFREE(MTYPE_OSPF6_PATH, op); } @@ -413,9 +413,9 @@ void ospf6_route_delete(struct ospf6_route *route) { if (route) { if (route->nh_list) - list_delete_and_null(&route->nh_list); + list_delete(&route->nh_list); if (route->paths) - list_delete_and_null(&route->paths); + list_delete(&route->paths); XFREE(MTYPE_OSPF6_ROUTE, route); } } diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index d9ddc1bb83..2d271c1dab 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -158,8 +158,8 @@ static struct ospf6_vertex *ospf6_vertex_create(struct ospf6_lsa *lsa) static void ospf6_vertex_delete(struct ospf6_vertex *v) { - list_delete_and_null(&v->nh_list); - list_delete_and_null(&v->child_list); + list_delete(&v->nh_list); + list_delete(&v->child_list); XFREE(MTYPE_OSPF6_VERTEX, v); } diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index ca1a65ff0b..901a35ccfa 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -202,7 +202,7 @@ void ospf6_delete(struct ospf6 *o) ospf6_area_delete(oa); - list_delete_and_null(&o->area_list); + list_delete(&o->area_list); ospf6_lsdb_delete(o->lsdb); ospf6_lsdb_delete(o->lsdb_self); diff --git a/ospfclient/subdir.am b/ospfclient/subdir.am index df7d85a1f5..d42c5b450e 100644 --- a/ospfclient/subdir.am +++ b/ospfclient/subdir.am @@ -23,9 +23,21 @@ endif ospfclient_ospfclient_LDADD = \ ospfclient/libfrrospfapiclient.la \ - lib/libfrr.la \ @LIBCAP@ \ # end + +if STATIC_BIN +# libfrr is linked in through libfrrospfapiclient. If we list it here too, +# it gets linked twice and we get a ton of symbol collisions. + +else # !STATIC_BIN +# For most systems we don't need this, except Debian, who patch their linker +# to disallow transitive references *while* *als* not patching their libtool +# to work appropriately. RedHat has the same linker behaviour, but things +# work as expected since they also patch libtool. +ospfclient_ospfclient_LDADD += lib/libfrr.la +endif + ospfclient_ospfclient_SOURCES = \ ospfclient/ospfclient.c \ # end diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 870037efc0..c8b8b611ef 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -196,6 +196,8 @@ int ospf_area_range_set(struct ospf *ospf, struct in_addr area_id, range = ospf_area_range_lookup(area, p); if (range != NULL) { + if (!CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)) + range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC; if ((CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE) && !CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)) || (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE) @@ -209,8 +211,10 @@ int ospf_area_range_set(struct ospf *ospf, struct in_addr area_id, if (CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)) SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE); - else + else { UNSET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE); + range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC; + } return 1; } diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 0f76527950..d0ee818722 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -182,7 +182,7 @@ void ospf_apiserver_term(void) /* Free client list itself */ if (apiserver_list) - list_delete_and_null(&apiserver_list); + list_delete(&apiserver_list); /* Free wildcard list */ /* XXX */ diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 0221d1e1b2..9492de544f 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -77,7 +77,7 @@ struct ospf_route *ospf_find_asbr_route(struct ospf *ospf, /* If none is found -- look through all. */ if (listcount(chosen) == 0) { - list_delete_and_null(&chosen); + list_delete(&chosen); chosen = rn->info; } @@ -98,7 +98,7 @@ struct ospf_route *ospf_find_asbr_route(struct ospf *ospf, } if (chosen != rn->info) - list_delete_and_null(&chosen); + list_delete(&chosen); return best; } @@ -775,7 +775,7 @@ void ospf_ase_external_lsas_finish(struct route_table *rt) if ((lst = rn->info) != NULL) { for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa)) ospf_lsa_unlock(&lsa); /* external_lsas lst */ - list_delete_and_null(&lst); + list_delete(&lst); } route_table_finish(rt); diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index d8742943c0..48d210d279 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -1799,7 +1799,7 @@ static int config_write_debug(struct vty *vty) } /* Initialize debug commands. */ -void debug_init() +void ospf_debug_init(void) { install_node(&debug_node, config_write_debug); diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index 99d7512f16..397f666f69 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -140,7 +140,7 @@ extern const char *ospf_timer_dump(struct thread *, char *, size_t); extern const char *ospf_timeval_dump(struct timeval *, char *, size_t); extern void ospf_ip_header_dump(struct ip *); extern void ospf_packet_dump(struct stream *); -extern void debug_init(void); +extern void ospf_debug_init(void); /* Appropriate buffer size to use with ospf_timer_dump and ospf_timeval_dump: */ #define OSPF_TIME_DUMP_SIZE 16 diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index 316019c159..df64fca883 100644 --- a/ospfd/ospf_ext.c +++ b/ospfd/ospf_ext.c @@ -185,7 +185,7 @@ void ospf_ext_term(void) ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA, OPAQUE_TYPE_EXTENDED_LINK_LSA); - list_delete_and_null(&OspfEXT.iflist); + list_delete(&OspfEXT.iflist); OspfEXT.scope = 0; OspfEXT.enabled = false; diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 8078455930..714c47b4e6 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -91,7 +91,7 @@ struct external_info *ospf_external_info_check(struct ospf *ospf, p.prefix = lsa->data->id; p.prefixlen = ip_masklen(al->mask); - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { int redist_on = 0; redist_on = diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 2ad36ae364..ddb25a20f6 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -341,10 +341,10 @@ void ospf_if_free(struct ospf_interface *oi) route_table_finish(oi->ls_upd_queue); /* Free any lists that should be freed */ - list_delete_and_null(&oi->nbr_nbma); + list_delete(&oi->nbr_nbma); - list_delete_and_null(&oi->ls_ack); - list_delete_and_null(&oi->ls_ack_direct.ls_ack); + list_delete(&oi->ls_ack); + list_delete(&oi->ls_ack_direct.ls_ack); if (IS_DEBUG_OSPF_EVENT) zlog_debug("%s: ospf interface %s vrf %s id %u deleted", @@ -545,7 +545,7 @@ static struct ospf_if_params *ospf_new_if_params(void) void ospf_del_if_params(struct ospf_if_params *oip) { - list_delete_and_null(&oip->auth_crypt); + list_delete(&oip->auth_crypt); bfd_info_free(&(oip->bfd_info)); XFREE(MTYPE_OSPF_IF_PARAMS, oip); } diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index 25ab9cbe0f..ad9b3efe6e 100644 --- a/ospfd/ospf_ism.c +++ b/ospfd/ospf_ism.c @@ -104,7 +104,7 @@ static struct ospf_neighbor *ospf_elect_dr(struct ospf_interface *oi, else DR(oi).s_addr = 0; - list_delete_and_null(&dr_list); + list_delete(&dr_list); return dr; } @@ -144,8 +144,8 @@ static struct ospf_neighbor *ospf_elect_bdr(struct ospf_interface *oi, else BDR(oi).s_addr = 0; - list_delete_and_null(&bdr_list); - list_delete_and_null(&no_dr_list); + list_delete(&bdr_list); + list_delete(&no_dr_list); return bdr; } @@ -232,7 +232,7 @@ static int ospf_dr_election(struct ospf_interface *oi) zlog_debug("DR-Election[2nd]: DR %s", inet_ntoa(DR(oi))); } - list_delete_and_null(&el_list); + list_delete(&el_list); /* if DR or BDR changes, cause AdjOK? neighbor event. */ if (!IPV4_ADDR_SAME(&old_dr, &DR(oi)) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index a752630a35..288ce43f79 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -1891,7 +1891,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, zlog_debug( "ospf_translated_nssa_refresh(): no Type-7 found for " "Type-5 LSA Id %s", - type5 ? inet_ntoa(type5->data->id) : "(null)"); + inet_ntoa(type5->data->id)); return NULL; } @@ -1901,7 +1901,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, zlog_debug( "ospf_translated_nssa_refresh(): No translated Type-5 " "found for Type-7 with Id %s", - type7 ? inet_ntoa(type7->data->id) : "(null)"); + inet_ntoa(type7->data->id)); return NULL; } @@ -1914,7 +1914,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, zlog_debug( "ospf_translated_nssa_refresh(): Could not translate " "Type-7 for %s to Type-5", - type7 ? inet_ntoa(type7->data->id) : "(null)"); + inet_ntoa(type7->data->id)); return NULL; } @@ -3633,7 +3633,7 @@ void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa) ospf->lsa_refresh_queue.qs[lsa->refresh_list]; listnode_delete(refresh_list, lsa); if (!listcount(refresh_list)) { - list_delete_and_null(&refresh_list); + list_delete(&refresh_list); ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL; } ospf_lsa_unlock(&lsa); /* lsa_refresh_queue */ @@ -3702,7 +3702,7 @@ int ospf_lsa_refresh_walker(struct thread *t) lsa->refresh_list = -1; listnode_add(lsa_to_refresh, lsa); } - list_delete_and_null(&refresh_list); + list_delete(&refresh_list); } } @@ -3718,7 +3718,7 @@ int ospf_lsa_refresh_walker(struct thread *t) &lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/ } - list_delete_and_null(&lsa_to_refresh); + list_delete(&lsa_to_refresh); if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) zlog_debug("LSA[Refresh]: ospf_lsa_refresh_walker(): end"); diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 9fb0e0ad13..20632f2840 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -187,7 +187,7 @@ int main(int argc, char **argv) master = om->master; /* Library inits. */ - debug_init(); + ospf_debug_init(); ospf_vrf_init(); access_list_init(); diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index e3c830d71b..7f96299768 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -136,7 +136,7 @@ void ospf_opaque_finish(void) int ospf_opaque_type9_lsa_init(struct ospf_interface *oi) { if (oi->opaque_lsa_self != NULL) - list_delete_and_null(&oi->opaque_lsa_self); + list_delete(&oi->opaque_lsa_self); oi->opaque_lsa_self = list_new(); oi->opaque_lsa_self->del = free_opaque_info_per_type; @@ -148,7 +148,7 @@ void ospf_opaque_type9_lsa_term(struct ospf_interface *oi) { OSPF_TIMER_OFF(oi->t_opaque_lsa_self); if (oi->opaque_lsa_self != NULL) - list_delete_and_null(&oi->opaque_lsa_self); + list_delete(&oi->opaque_lsa_self); oi->opaque_lsa_self = NULL; return; } @@ -156,7 +156,7 @@ void ospf_opaque_type9_lsa_term(struct ospf_interface *oi) int ospf_opaque_type10_lsa_init(struct ospf_area *area) { if (area->opaque_lsa_self != NULL) - list_delete_and_null(&area->opaque_lsa_self); + list_delete(&area->opaque_lsa_self); area->opaque_lsa_self = list_new(); area->opaque_lsa_self->del = free_opaque_info_per_type; @@ -177,14 +177,14 @@ void ospf_opaque_type10_lsa_term(struct ospf_area *area) OSPF_TIMER_OFF(area->t_opaque_lsa_self); if (area->opaque_lsa_self != NULL) - list_delete_and_null(&area->opaque_lsa_self); + list_delete(&area->opaque_lsa_self); return; } int ospf_opaque_type11_lsa_init(struct ospf *top) { if (top->opaque_lsa_self != NULL) - list_delete_and_null(&top->opaque_lsa_self); + list_delete(&top->opaque_lsa_self); top->opaque_lsa_self = list_new(); top->opaque_lsa_self->del = free_opaque_info_per_type; @@ -205,7 +205,7 @@ void ospf_opaque_type11_lsa_term(struct ospf *top) OSPF_TIMER_OFF(top->t_opaque_lsa_self); if (top->opaque_lsa_self != NULL) - list_delete_and_null(&top->opaque_lsa_self); + list_delete(&top->opaque_lsa_self); return; } @@ -314,16 +314,16 @@ static void ospf_opaque_funclist_term(void) struct list *funclist; funclist = ospf_opaque_wildcard_funclist; - list_delete_and_null(&funclist); + list_delete(&funclist); funclist = ospf_opaque_type9_funclist; - list_delete_and_null(&funclist); + list_delete(&funclist); funclist = ospf_opaque_type10_funclist; - list_delete_and_null(&funclist); + list_delete(&funclist); funclist = ospf_opaque_type11_funclist; - list_delete_and_null(&funclist); + list_delete(&funclist); return; } @@ -633,7 +633,7 @@ static void free_opaque_info_per_type(void *val) } OSPF_TIMER_OFF(oipt->t_opaque_lsa_self); - list_delete_and_null(&oipt->id_list); + list_delete(&oipt->id_list); XFREE(MTYPE_OPAQUE_INFO_PER_TYPE, oipt); return; } diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index c4c4d2f030..359d59cb58 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -525,7 +525,7 @@ int ospf_ls_upd_timer(struct thread *thread) if (listcount(update) > 0) ospf_ls_upd_send(nbr, update, OSPF_SEND_PACKET_DIRECT, 0); - list_delete_and_null(&update); + list_delete(&update); } /* Set LS Update retransmission timer. */ @@ -1620,7 +1620,7 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, /* Verify LSA type. */ if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA) { OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); - list_delete_and_null(&ls_upd); + list_delete(&ls_upd); return; } @@ -1629,7 +1629,7 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, adv_router); if (find == NULL) { OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); - list_delete_and_null(&ls_upd); + list_delete(&ls_upd); return; } @@ -1664,9 +1664,9 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT, 0); - list_delete_and_null(&ls_upd); + list_delete(&ls_upd); } else - list_delete_and_null(&ls_upd); + list_delete(&ls_upd); } /* Get the list of LSAs from Link State Update packet. @@ -1811,7 +1811,7 @@ static void ospf_upd_list_clean(struct list *lsas) for (ALL_LIST_ELEMENTS(lsas, node, nnode, lsa)) ospf_lsa_discard(lsa); - list_delete_and_null(&lsas); + list_delete(&lsas); } /* OSPF Link State Update message read -- RFC2328 Section 13. */ @@ -2215,7 +2215,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, #undef DISCARD_LSA assert(listcount(lsas) == 0); - list_delete_and_null(&lsas); + list_delete(&lsas); } /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */ @@ -3855,7 +3855,7 @@ void ospf_ls_upd_send_lsa(struct ospf_neighbor *nbr, struct ospf_lsa *lsa, else ospf_ls_upd_send(nbr, update, flag, 0); - list_delete_and_null(&update); + list_delete(&update); } /* Determine size for packet. Must be at least big enough to accomodate next @@ -4016,7 +4016,7 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread) /* list might not be empty. */ if (listcount(update) == 0) { - list_delete_and_null((struct list **)&rn->info); + list_delete((struct list **)&rn->info); route_unlock_node(rn); } else again = 1; diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index 22262c804f..3b0319b591 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -217,8 +217,8 @@ static int ospf_router_info_unregister() void ospf_router_info_term(void) { - list_delete_and_null(&OspfRI.pce_info.pce_domain); - list_delete_and_null(&OspfRI.pce_info.pce_neighbor); + list_delete(&OspfRI.pce_info.pce_domain); + list_delete(&OspfRI.pce_info.pce_neighbor); OspfRI.enabled = false; diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index b36f2f4652..7ee91b5b6c 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -54,7 +54,7 @@ struct ospf_route *ospf_route_new() void ospf_route_free(struct ospf_route * or) { if (or->paths) - list_delete_and_null(& or->paths); + list_delete(& or->paths); XFREE(MTYPE_OSPF_ROUTE, or); } @@ -905,7 +905,7 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs) zlog_debug("Pruning router node %s", inet_ntoa(rn->p.u.prefix4)); - list_delete_and_null(&paths); + list_delete(&paths); rn->info = NULL; route_unlock_node(rn); } diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 7896fb632a..9c223facd3 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -209,10 +209,10 @@ static void ospf_vertex_free(void *data) // assert (listcount (v->parents) == 0); if (v->children) - list_delete_and_null(&v->children); + list_delete(&v->children); if (v->parents) - list_delete_and_null(&v->parents); + list_delete(&v->parents); v->lsa = NULL; @@ -1086,7 +1086,7 @@ void ospf_rtrs_free(struct route_table *rtrs) for (ALL_LIST_ELEMENTS(or_list, node, nnode, or)) ospf_route_free(or); - list_delete_and_null(&or_list); + list_delete(&or_list); /* Unlock the node. */ rn->info = NULL; diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 33ec09b9f3..d793735003 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -165,10 +165,10 @@ static void sr_node_del(struct sr_node *srn) return; /* Clean Extended Link */ - list_delete_and_null(&srn->ext_link); + list_delete(&srn->ext_link); /* Clean Prefix List */ - list_delete_and_null(&srn->ext_prefix); + list_delete(&srn->ext_prefix); XFREE(MTYPE_OSPF_SR_PARAMS, srn); } @@ -283,7 +283,7 @@ static void ospf_sr_stop(void) /* * Remove all SR Nodes from the Hash table. Prefix and Link SID will - * be remove though list_delete_and_null() call. See sr_node_del() + * be remove though list_delete() call. See sr_node_del() */ hash_clean(OspfSR.neighbors, (void *)sr_node_del); } diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 12122e7646..f43038ab8d 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -169,7 +169,7 @@ static int ospf_mpls_te_unregister() void ospf_mpls_te_term(void) { - list_delete_and_null(&OspfMplsTE.iflist); + list_delete(&OspfMplsTE.iflist); ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA, OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index dd8ffa234d..652c47387a 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -750,6 +750,7 @@ DEFUN (ospf_area_range_not_advertise, ospf_area_range_set(ospf, area_id, &p, 0); ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), format); + ospf_area_range_substitute_unset(ospf, area_id, &p); return CMD_SUCCESS; } diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 4de68b15f2..ed19ae4f31 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -583,7 +583,7 @@ void ospf_external_del(struct ospf *ospf, uint8_t type, unsigned short instance) listnode_delete(ospf->external[type], ext); if (!ospf->external[type]->count) - list_delete_and_null(&ospf->external[type]); + list_delete(&ospf->external[type]); XFREE(MTYPE_OSPF_EXTERNAL, ext); } @@ -643,7 +643,7 @@ void ospf_redist_del(struct ospf *ospf, uint8_t type, unsigned short instance) if (red) { listnode_delete(ospf->redist[type], red); if (!ospf->redist[type]->count) { - list_delete_and_null(&ospf->redist[type]); + list_delete(&ospf->redist[type]); } ospf_routemap_unset(red); XFREE(MTYPE_OSPF_REDISTRIBUTE, red); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index d481e9e4c8..dc54f04c07 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -635,7 +635,7 @@ static void ospf_finish_final(struct ospf *ospf) for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data)) ospf_vl_delete(ospf, vl_data); - list_delete_and_null(&ospf->vlinks); + list_delete(&ospf->vlinks); /* Remove any ospf interface config params */ FOR_ALL_INTERFACES (vrf, ifp) { @@ -649,7 +649,7 @@ static void ospf_finish_final(struct ospf *ospf) /* Reset interface. */ for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) ospf_if_free(oi); - list_delete_and_null(&ospf->oiflist); + list_delete(&ospf->oiflist); /* De-Register VRF */ ospf_zebra_vrf_deregister(ospf); @@ -749,8 +749,8 @@ static void ospf_finish_final(struct ospf *ospf) ospf_ase_external_lsas_finish(ospf->external_lsas); } - list_delete_and_null(&ospf->areas); - list_delete_and_null(&ospf->oi_write_q); + list_delete(&ospf->areas); + list_delete(&ospf->oi_write_q); for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) { struct list *ext_list; @@ -866,7 +866,7 @@ static void ospf_area_free(struct ospf_area *area) ospf_lsa_unlock(&area->router_lsa_self); route_table_finish(area->ranges); - list_delete_and_null(&area->oiflist); + list_delete(&area->oiflist); if (EXPORT_NAME(area)) free(EXPORT_NAME(area)); @@ -1297,7 +1297,7 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi) if ((lst = (struct list *)rn->info)) { for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa)) ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */ - list_delete_and_null(&lst); + list_delete(&lst); rn->info = NULL; } diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c index b6c5bc432d..e482d321a4 100644 --- a/pimd/pim_hello.c +++ b/pimd/pim_hello.c @@ -127,7 +127,7 @@ static void tlv_trace_list(const char *label, const char *tlv_name, #define FREE_ADDR_LIST \ if (hello_option_addr_list) { \ - list_delete_and_null(&hello_option_addr_list); \ + list_delete(&hello_option_addr_list); \ } #define FREE_ADDR_LIST_THEN_RETURN(code) \ diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 249b24c0d7..1ad71823b8 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -201,10 +201,10 @@ void pim_if_delete(struct interface *ifp) pim_if_del_vif(ifp); - list_delete_and_null(&pim_ifp->igmp_socket_list); - list_delete_and_null(&pim_ifp->pim_neighbor_list); - list_delete_and_null(&pim_ifp->upstream_switch_list); - list_delete_and_null(&pim_ifp->sec_addr_list); + list_delete(&pim_ifp->igmp_socket_list); + list_delete(&pim_ifp->pim_neighbor_list); + list_delete(&pim_ifp->upstream_switch_list); + list_delete(&pim_ifp->sec_addr_list); if (pim_ifp->boundary_oil_plist) XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist); @@ -1349,7 +1349,7 @@ int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr, listnode_delete(pim_ifp->igmp_join_list, ij); igmp_join_free(ij); if (listcount(pim_ifp->igmp_join_list) < 1) { - list_delete_and_null(&pim_ifp->igmp_join_list); + list_delete(&pim_ifp->igmp_join_list); pim_ifp->igmp_join_list = 0; } diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index a3d6a2e658..129d569c87 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -162,7 +162,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch) pim_ifchannel_remove_children(ch); if (ch->sources) - list_delete_and_null(&ch->sources); + list_delete(&ch->sources); listnode_delete(ch->upstream->ifchannels, ch); diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 64537cfa84..8a2efd41ad 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -736,7 +736,7 @@ void igmp_startup_mode_on(struct igmp_sock *igmp) static void igmp_group_free(struct igmp_group *group) { - list_delete_and_null(&group->group_source_list); + list_delete(&group->group_source_list); XFREE(MTYPE_PIM_IGMP_GROUP, group); } @@ -788,7 +788,7 @@ void igmp_sock_free(struct igmp_sock *igmp) zassert(igmp->igmp_group_list); zassert(!listcount(igmp->igmp_group_list)); - list_delete_and_null(&igmp->igmp_group_list); + list_delete(&igmp->igmp_group_list); hash_free(igmp->igmp_group_hash); XFREE(MTYPE_PIM_IGMP_SOCKET, igmp); diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index c592a2c047..2550651464 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -42,7 +42,7 @@ static void pim_instance_terminate(struct pim_instance *pim) } if (pim->static_routes) - list_delete_and_null(&pim->static_routes); + list_delete(&pim->static_routes); pim_upstream_terminate(pim); diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c index c5f5b9c5e0..7726ffda57 100644 --- a/pimd/pim_jp_agg.c +++ b/pimd/pim_jp_agg.c @@ -32,7 +32,7 @@ void pim_jp_agg_group_list_free(struct pim_jp_agg_group *jag) { - list_delete_and_null(&jag->sources); + list_delete(&jag->sources); XFREE(MTYPE_PIM_JP_AGG_GROUP, jag); } @@ -108,7 +108,7 @@ void pim_jp_agg_clear_group(struct list *group) js->up = NULL; XFREE(MTYPE_PIM_JP_AGG_SOURCE, js); } - list_delete_and_null(&jag->sources); + list_delete(&jag->sources); listnode_delete(group, jag); XFREE(MTYPE_PIM_JP_AGG_GROUP, jag); } @@ -168,7 +168,7 @@ void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up) } if (jag->sources->count == 0) { - list_delete_and_null(&jag->sources); + list_delete(&jag->sources); listnode_delete(group, jag); XFREE(MTYPE_PIM_JP_AGG_GROUP, jag); } diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 5a75ed329c..9ef343a0c5 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -1260,7 +1260,7 @@ static void pim_msdp_mg_free(struct pim_instance *pim) XFREE(MTYPE_PIM_MSDP_MG_NAME, mg->mesh_group_name); if (mg->mbr_list) - list_delete_and_null(&mg->mbr_list); + list_delete(&mg->mbr_list); XFREE(MTYPE_PIM_MSDP_MG, pim->msdp.mg); } @@ -1610,7 +1610,7 @@ void pim_msdp_exit(struct pim_instance *pim) } if (pim->msdp.peer_list) { - list_delete_and_null(&pim->msdp.peer_list); + list_delete(&pim->msdp.peer_list); } if (pim->msdp.sa_hash) { @@ -1620,7 +1620,7 @@ void pim_msdp_exit(struct pim_instance *pim) } if (pim->msdp.sa_list) { - list_delete_and_null(&pim->msdp.sa_list); + list_delete(&pim->msdp.sa_list); } if (pim->msdp.work_obuf) diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index bff1e7ff13..f402629653 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -397,7 +397,7 @@ static void delete_prefix_list(struct pim_neighbor *neigh) } #endif - list_delete_and_null(&neigh->prefix_list); + list_delete(&neigh->prefix_list); } } @@ -407,7 +407,7 @@ void pim_neighbor_free(struct pim_neighbor *neigh) delete_prefix_list(neigh); - list_delete_and_null(&neigh->upstream_jp_agg); + list_delete(&neigh->upstream_jp_agg); THREAD_OFF(neigh->jp_timer); if (neigh->bfd_info) diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 0a64c8db3d..2d808639b5 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -196,7 +196,7 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr, pim_sendmsg_zebra_rnh(pim, zclient, pnc, ZEBRA_NEXTHOP_UNREGISTER); - list_delete_and_null(&pnc->rp_list); + list_delete(&pnc->rp_list); hash_free(pnc->upstream_hash); hash_release(pim->rpf_hash, pnc); diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index a0debc0c78..68f7dae128 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -116,7 +116,7 @@ void pim_oil_init(struct pim_instance *pim) void pim_oil_terminate(struct pim_instance *pim) { if (pim->channel_oil_list) - list_delete_and_null(&pim->channel_oil_list); + list_delete(&pim->channel_oil_list); if (pim->channel_oil_hash) hash_free(pim->channel_oil_hash); diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 51ca0945b9..6b76794b75 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -52,7 +52,7 @@ void pim_rp_list_hash_clean(void *data) { struct pim_nexthop_cache *pnc = (struct pim_nexthop_cache *)data; - list_delete_and_null(&pnc->rp_list); + list_delete(&pnc->rp_list); hash_clean(pnc->upstream_hash, NULL); hash_free(pnc->upstream_hash); @@ -115,7 +115,7 @@ void pim_rp_init(struct pim_instance *pim) if (!str2prefix("224.0.0.0/4", &rp_info->group)) { flog_err(EC_LIB_DEVELOPMENT, "Unable to convert 224.0.0.0/4 to prefix"); - list_delete_and_null(&pim->rp_list); + list_delete(&pim->rp_list); route_table_finish(pim->rp_table); XFREE(MTYPE_PIM_RP, rp_info); return; @@ -138,7 +138,7 @@ void pim_rp_init(struct pim_instance *pim) void pim_rp_free(struct pim_instance *pim) { if (pim->rp_list) - list_delete_and_null(&pim->rp_list); + list_delete(&pim->rp_list); } /* diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index a5082608b8..c3d958428c 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -52,7 +52,7 @@ void pim_ssmpingd_init(struct pim_instance *pim) void pim_ssmpingd_destroy(struct pim_instance *pim) { if (pim->ssmpingd_list) - list_delete_and_null(&pim->ssmpingd_list); + list_delete(&pim->ssmpingd_list); } static struct ssmpingd_sock *ssmpingd_find(struct pim_instance *pim, diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c index 70700dd508..d93a360448 100644 --- a/pimd/pim_tlv.c +++ b/pimd/pim_tlv.c @@ -657,7 +657,7 @@ int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags, #define FREE_ADDR_LIST(hello_option_addr_list) \ { \ if (hello_option_addr_list) { \ - list_delete_and_null(&hello_option_addr_list); \ + list_delete(&hello_option_addr_list); \ hello_option_addr_list = 0; \ } \ } diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 4adfde6775..cd6326f097 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -80,7 +80,7 @@ static void pim_upstream_remove_children(struct pim_instance *pim, if (child) child->parent = NULL; } - list_delete_and_null(&up->sources); + list_delete(&up->sources); } /* @@ -202,11 +202,11 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim, for (ALL_LIST_ELEMENTS(up->ifchannels, node, nnode, ch)) pim_ifchannel_delete(ch); - list_delete_and_null(&up->ifchannels); + list_delete(&up->ifchannels); pim_upstream_remove_children(pim, up); if (up->sources) - list_delete_and_null(&up->sources); + list_delete(&up->sources); if (up->parent && up->parent->sources) listnode_delete(up->parent->sources, up); @@ -683,9 +683,9 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, pim_upstream_remove_children(pim, up); if (up->sources) - list_delete_and_null(&up->sources); + list_delete(&up->sources); - list_delete_and_null(&up->ifchannels); + list_delete(&up->ifchannels); hash_release(pim->upstream_hash, up); XFREE(MTYPE_PIM_UPSTREAM, up); @@ -1542,7 +1542,7 @@ void pim_upstream_terminate(struct pim_instance *pim) pim_upstream_del(pim, up, __PRETTY_FUNCTION__); } - list_delete_and_null(&pim->upstream_list); + list_delete(&pim->upstream_list); } if (pim->upstream_hash) diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index bff0b40515..1395af5dfb 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -216,7 +216,7 @@ Contributed/3rd party tools which may be of use with frr. %package pythontools Summary: python tools for frr BuildRequires: python -Requires: python-ipaddr +Requires: python-ipaddress Group: System Environment/Daemons %description pythontools diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c index ab14c3176d..d2065a4bbb 100644 --- a/ripd/rip_offset.c +++ b/ripd/rip_offset.c @@ -363,7 +363,7 @@ void rip_offset_init() void rip_offset_clean() { - list_delete_and_null(&rip_offset_list_master); + list_delete(&rip_offset_list_master); rip_offset_list_master = list_new(); rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp; diff --git a/ripd/ripd.c b/ripd/ripd.c index 94c3d4bc9c..444a09914c 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -131,7 +131,7 @@ static int rip_garbage_collect(struct thread *t) /* Unlock route_node. */ listnode_delete(rp->info, rinfo); if (list_isempty((struct list *)rp->info)) { - list_delete_and_null((struct list **)&rp->info); + list_delete((struct list **)&rp->info); route_unlock_node(rp); } @@ -3832,7 +3832,7 @@ void rip_clean(void) RIP_TIMER_OFF(rinfo->t_garbage_collect); rip_info_free(rinfo); } - list_delete_and_null(&list); + list_delete(&list); rp->info = NULL; route_unlock_node(rp); } diff --git a/ripngd/ripng_nexthop.c b/ripngd/ripng_nexthop.c index 2e0841c5d4..74a132aa94 100644 --- a/ripngd/ripng_nexthop.c +++ b/ripngd/ripng_nexthop.c @@ -72,7 +72,7 @@ struct list *ripng_rte_new(void) void ripng_rte_free(struct list *ripng_rte_list) { - list_delete_and_null(&ripng_rte_list); + list_delete(&ripng_rte_list); } /* Delete RTE */ diff --git a/ripngd/ripng_offset.c b/ripngd/ripng_offset.c index f8d73250b4..32b81b5480 100644 --- a/ripngd/ripng_offset.c +++ b/ripngd/ripng_offset.c @@ -375,7 +375,7 @@ void ripng_offset_init(void) void ripng_offset_clean(void) { - list_delete_and_null(&ripng_offset_list_master); + list_delete(&ripng_offset_list_master); ripng_offset_list_master = list_new(); ripng_offset_list_master->cmp = diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index fbc06b0348..08dc3d8b4d 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -407,7 +407,7 @@ static int ripng_garbage_collect(struct thread *t) /* Unlock route_node. */ listnode_delete(rp->info, rinfo); if (list_isempty((struct list *)rp->info)) { - list_delete_and_null((struct list **)&rp->info); + list_delete((struct list **)&rp->info); agg_unlock_node(rp); } @@ -2144,7 +2144,7 @@ DEFUN (clear_ipv6_rip, } if (list_isempty(list)) { - list_delete_and_null(&list); + list_delete(&list); rp->info = NULL; agg_unlock_node(rp); } @@ -2826,7 +2826,7 @@ void ripng_clean() rinfo->t_garbage_collect); ripng_info_free(rinfo); } - list_delete_and_null(&list); + list_delete(&list); rp->info = NULL; agg_unlock_node(rp); } diff --git a/tests/bgpd/test_bgp_table.c b/tests/bgpd/test_bgp_table.c index a0382827b9..171b1aa22f 100644 --- a/tests/bgpd/test_bgp_table.c +++ b/tests/bgpd/test_bgp_table.c @@ -134,7 +134,7 @@ static void do_test(struct bgp_table *table, const char *prefix, check_lookup_result(list, arglist); - list_delete_and_null(&list); + list_delete(&list); va_end(arglist); diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c index e40fba2457..8e81119f5d 100644 --- a/tests/bgpd/test_peer_attr.c +++ b/tests/bgpd/test_peer_attr.c @@ -966,7 +966,7 @@ static void test_finish(struct test *test) test->vty = NULL; } if (test->log) - list_delete_and_null(&test->log); + list_delete(&test->log); if (test->desc) XFREE(MTYPE_TMP, test->desc); if (test->error) @@ -1423,7 +1423,7 @@ static void bgp_shutdown(void) bgp_zebra_destroy(); bf_free(bm->rd_idspace); - list_delete_and_null(&bm->bgp); + list_delete(&bm->bgp); memset(bm, 0, sizeof(*bm)); vty_terminate(); @@ -1502,7 +1502,7 @@ int main(void) XFREE(MTYPE_TMP, pa); } - list_delete_and_null(&pa_list); + list_delete(&pa_list); bgp_shutdown(); return 0; diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c index b75c1002d4..917ea66f13 100644 --- a/tests/isisd/test_fuzz_isis_tlv.c +++ b/tests/isisd/test_fuzz_isis_tlv.c @@ -176,7 +176,7 @@ static int test(FILE *input, FILE *output) sbuf_push(&fragment_format, 0, "%s", isis_format_tlvs(tlvs)); isis_free_tlvs(tlvs); } - list_delete_and_null(&fragments); + list_delete(&fragments); stream_free(s); char *fragment_content = sortlines((char *)sbuf_buf(&fragment_format)); diff --git a/tools/.gitignore b/tools/.gitignore index d400dfe8fa..a8d01d680e 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -1,2 +1,3 @@ +/frr /permutations /ssd diff --git a/tools/build-debian-package.sh b/tools/build-debian-package.sh new file mode 100755 index 0000000000..73231f0aec --- /dev/null +++ b/tools/build-debian-package.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# Written by Daniil Baturin, 2018 +# This file is public domain + +git diff-index --quiet HEAD || echo "Warning: git working directory is not clean!" + +# Set the defaults +if [ "$EXTRA_VERSION" = "" ]; then + EXTRA_VERSION="-MyDebPkgVersion" +fi + +if [ "$WANT_SNMP" = "" ]; then + WANT_SNMP=0 +fi + +if [ "$WANT_CUMULUS_MODE" = "" ]; then + WANT_CUMULUS_MODE=0 +fi + +echo "Preparing the build" +./bootstrap.sh +./configure --with-pkg-extra-version=$EXTRA_VERSION +make dist + +echo "Preparing Debian source package" +mv debianpkg debian +make -f debian/rules backports + +echo "Unpacking the source to frrpkg/" +mkdir frrpkg +cd frrpkg +tar xf ../frr_*.orig.tar.gz +cd frr* +. /etc/os-release +tar xf ../../frr_*${ID}${VERSION_ID}*.debian.tar.xz + +echo "Building the Debian package" +debuild --no-lintian --set-envvar=WANT_SNMP=$WANT_SNMP --set-envvar=WANT_CUMULUS_MODE=$WANT_CUMULUS_MODE -b -uc -us + diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 9d1af27d6c..3b41b57d68 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -28,6 +28,7 @@ This program text file """ +from __future__ import print_function, unicode_literals import argparse import copy import logging @@ -38,9 +39,22 @@ import string import subprocess import sys from collections import OrderedDict -from ipaddr import IPv6Address, IPNetwork +try: + from ipaddress import IPv6Address, ip_network +except ImportError: + from ipaddr import IPv6Address, IPNetwork from pprint import pformat +try: + dict.iteritems +except AttributeError: + # Python 3 + def iteritems(d): + return iter(d.items()) +else: + # Python 2 + def iteritems(d): + return d.iteritems() log = logging.getLogger(__name__) @@ -116,7 +130,7 @@ class Config(object): ve.output = e.output raise ve - for line in file_output.split('\n'): + for line in file_output.decode('utf-8').split('\n'): line = line.strip() # Compress duplicate whitespaces @@ -147,7 +161,7 @@ class Config(object): ve.output = e.output raise ve - for line in config_text.split('\n'): + for line in config_text.decode('utf-8').split('\n'): line = line.strip() if (line == 'Building configuration...' or @@ -171,8 +185,8 @@ class Config(object): Return the parsed context as strings for display, log etc. """ - for (_, ctx) in sorted(self.contexts.iteritems()): - print str(ctx) + '\n' + for (_, ctx) in sorted(iteritems(self.contexts)): + print(str(ctx) + '\n') def save_contexts(self, key, lines): """ @@ -195,11 +209,18 @@ class Config(object): addr = re_key_rt.group(2) if '/' in addr: try: - newaddr = IPNetwork(addr) - key[0] = '%s route %s/%s%s' % (re_key_rt.group(1), - newaddr.network, - newaddr.prefixlen, - re_key_rt.group(3)) + if 'ipaddress' not in sys.modules: + newaddr = IPNetwork(addr) + key[0] = '%s route %s/%s%s' % (re_key_rt.group(1), + newaddr.network, + newaddr.prefixlen, + re_key_rt.group(3)) + else: + newaddr = ip_network(addr, strict=False) + key[0] = '%s route %s/%s%s' % (re_key_rt.group(1), + str(newaddr.network_address), + newaddr.prefixlen, + re_key_rt.group(3)) except ValueError: pass @@ -211,8 +232,13 @@ class Config(object): addr = re_key_rt.group(4) if '/' in addr: try: - newaddr = '%s/%s' % (IPNetwork(addr).network, - IPNetwork(addr).prefixlen) + if 'ipaddress' not in sys.modules: + newaddr = '%s/%s' % (IPNetwork(addr).network, + IPNetwork(addr).prefixlen) + else: + network_addr = ip_network(addr, strict=False) + newaddr = '%s/%s' % (str(network_addr.network_address), + network_addr.prefixlen) except ValueError: newaddr = addr else: @@ -253,10 +279,16 @@ class Config(object): addr = addr + '/8' try: - newaddr = IPNetwork(addr) - line = 'network %s/%s %s' % (newaddr.network, - newaddr.prefixlen, - re_net.group(2)) + if 'ipaddress' not in sys.modules: + newaddr = IPNetwork(addr) + line = 'network %s/%s %s' % (newaddr.network, + newaddr.prefixlen, + re_net.group(2)) + else: + network_addr = ip_network(addr, strict=False) + line = 'network %s/%s %s' % (str(network_addr.network_address), + network_addr.prefixlen, + re_net.group(2)) newlines.append(line) except ValueError: # Really this should be an error. Whats a network @@ -598,8 +630,12 @@ def get_normalized_ipv6_line(line): norm_word = None if "/" in word: try: - v6word = IPNetwork(word) - norm_word = '%s/%s' % (v6word.network, v6word.prefixlen) + if 'ipaddress' not in sys.modules: + v6word = IPNetwork(word) + norm_word = '%s/%s' % (v6word.network, v6word.prefixlen) + else: + v6word = ip_network(word, strict=False) + norm_word = '%s/%s' % (str(v6word.network_address), v6word.prefixlen) except ValueError: pass if not norm_word: @@ -926,7 +962,7 @@ def compare_context_objects(newconf, running): # Find contexts that are in newconf but not in running # Find contexts that are in running but not in newconf - for (running_ctx_keys, running_ctx) in running.contexts.iteritems(): + for (running_ctx_keys, running_ctx) in iteritems(running.contexts): if running_ctx_keys not in newconf.contexts: @@ -977,7 +1013,7 @@ def compare_context_objects(newconf, running): # Find the lines within each context to add # Find the lines within each context to del - for (newconf_ctx_keys, newconf_ctx) in newconf.contexts.iteritems(): + for (newconf_ctx_keys, newconf_ctx) in iteritems(newconf.contexts): if newconf_ctx_keys in running.contexts: running_ctx = running.contexts[newconf_ctx_keys] @@ -990,7 +1026,7 @@ def compare_context_objects(newconf, running): if line not in newconf_ctx.dlines: lines_to_del.append((newconf_ctx_keys, line)) - for (newconf_ctx_keys, newconf_ctx) in newconf.contexts.iteritems(): + for (newconf_ctx_keys, newconf_ctx) in iteritems(newconf.contexts): if newconf_ctx_keys not in running.contexts: lines_to_add.append((newconf_ctx_keys, None)) @@ -1016,14 +1052,14 @@ def vtysh_config_available(): cmd = ['/usr/bin/vtysh', '-c', 'conf t'] output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip() - if 'VTY configuration is locked by other VTY' in output: - print output + if 'VTY configuration is locked by other VTY' in output.decode('utf-8'): + print(output) log.error("'%s' returned\n%s\n" % (' '.join(cmd), output)) return False except subprocess.CalledProcessError as e: msg = "vtysh could not connect with any frr daemons" - print msg + print(msg) log.error(msg) return False @@ -1070,13 +1106,13 @@ if __name__ == '__main__': # Verify the new config file is valid if not os.path.isfile(args.filename): msg = "Filename %s does not exist" % args.filename - print msg + print(msg) log.error(msg) sys.exit(1) if not os.path.getsize(args.filename): msg = "Filename %s is an empty file" % args.filename - print msg + print(msg) log.error(msg) sys.exit(1) @@ -1095,7 +1131,7 @@ if __name__ == '__main__': if not service_integrated_vtysh_config: msg = "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'" - print msg + print(msg) log.error(msg) sys.exit(1) @@ -1123,8 +1159,8 @@ if __name__ == '__main__': lines_to_configure = [] if lines_to_del: - print "\nLines To Delete" - print "===============" + print("\nLines To Delete") + print("===============") for (ctx_keys, line) in lines_to_del: @@ -1133,11 +1169,11 @@ if __name__ == '__main__': cmd = line_for_vtysh_file(ctx_keys, line, True) lines_to_configure.append(cmd) - print cmd + print(cmd) if lines_to_add: - print "\nLines To Add" - print "============" + print("\nLines To Add") + print("============") for (ctx_keys, line) in lines_to_add: @@ -1146,7 +1182,7 @@ if __name__ == '__main__': cmd = line_for_vtysh_file(ctx_keys, line, False) lines_to_configure.append(cmd) - print cmd + print(cmd) elif args.reload: diff --git a/tools/frr b/tools/frr.in index 9c8a8e9043..4ff080909d 100755 --- a/tools/frr +++ b/tools/frr.in @@ -14,23 +14,27 @@ # PATH=/bin:/usr/bin:/sbin:/usr/sbin -D_PATH=/usr/lib/frr -C_PATH=/etc/frr -V_PATH=/var/run/frr +D_PATH="@CFG_SBIN@" # /usr/lib/frr +C_PATH="@CFG_SYSCONF@" # /etc/frr +V_PATH="@CFG_STATE@" # /var/run/frr +VTYSH="@vtysh_bin@" # /usr/bin/vtysh +FRR_USER="@enable_user@" # frr +FRR_GROUP="@enable_group@" # frr +FRR_VTY_GROUP="@enable_vty_group@" # frrvty # Local Daemon selection may be done by using /etc/frr/daemons. # See /usr/share/doc/frr/README.Debian.gz for further information. # Keep zebra first and do not list watchfrr! DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd" MAX_INSTANCES=5 -RELOAD_SCRIPT=/usr/lib/frr/frr-reload.py +RELOAD_SCRIPT="$D_PATH/frr-reload.py" if [ -e /lib/lsb/init-functions ]; then . /lib/lsb/init-functions fi -if [ -f /usr/lib/frr/ssd ]; then - SSD=/usr/lib/frr/ssd +if [ -f $D_PATH/ssd ]; then + SSD=$D_PATH/ssd else SSD=`which start-stop-daemon` fi @@ -47,6 +51,12 @@ vtyfile() echo "$V_PATH/$1.vty" } +chownfrr() +{ + test -n "$FRR_USER" && chown "$FRR_USER" "$1" + test -n "$FRR_GROUP" && chgrp "$FRR_GROUP" "$1" +} + # Check if daemon is started by using the pidfile. started() { @@ -64,7 +74,7 @@ vtysh_b () { # Rember, that all variables have been incremented by 1 in convert_daemon_prios() if [ "$vtysh_enable" = 2 -a -f $C_PATH/frr.conf ]; then - /usr/bin/vtysh -b -n + $VTYSH -b -n fi } @@ -91,11 +101,11 @@ check_daemon() if [ -n "$2" ]; then if [ ! -r "$C_PATH/$1-$2.conf" ]; then touch "$C_PATH/$1-$2.conf" - chown frr:frr "$C_PATH/$1-$2.conf" + chownfrr "$C_PATH/$1-$2.conf" fi elif [ ! -r "$C_PATH/$1.conf" ]; then touch "$C_PATH/$1.conf" - chown frr:frr "$C_PATH/$1.conf" + chownfrr "$C_PATH/$1.conf" fi fi return 0 @@ -117,23 +127,13 @@ start() echo -n " $1" fi - if [ -e /var/run/frr/watchfrr.started ] ; then - rm /var/run/frr/watchfrr.started - fi - ${SSD} \ + ${SSD} \ --start \ --pidfile=`pidfile $1` \ --exec "$D_PATH/$1" \ -- \ "${watchfrr_options[@]}" - for i in `seq 1 10`; - do - if [ -e /var/run/frr/watchfrr.started ] ; then - break - else - sleep 1 - fi - done + elif [ -n "$2" ]; then echo -n " $1-$2" if ! check_daemon $1 $2 ; then @@ -523,7 +523,7 @@ convert_daemon_prios if [ ! -d $V_PATH ]; then echo "Creating $V_PATH" mkdir -p $V_PATH - chown frr:frr $V_PATH + chownfrr $V_PATH chmod 755 /$V_PATH fi @@ -604,7 +604,7 @@ case "$1" in NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}" [ ! -r $NEW_CONFIG_FILE ] && echo "Unable to read new configuration file $NEW_CONFIG_FILE" && exit 1 echo "Applying only incremental changes to running configuration from frr.conf" - "$RELOAD_SCRIPT" --reload /etc/frr/frr.conf + "$RELOAD_SCRIPT" --reload $C_PATH/frr.conf exit $? ;; diff --git a/tools/lua.scr b/tools/lua.scr new file mode 100644 index 0000000000..db6bf7d36b --- /dev/null +++ b/tools/lua.scr @@ -0,0 +1,29 @@ +-- Route map functionality +-- +-- There are no parameters passed in. +-- Currently we set two global tables +-- prefix +-- .family = The v4 or v6 family we are working in +-- .route = the A.B.C.D/X or Z:A:B::D/X string +-- nexthop +-- .metric = The metric we are going to use +-- .ifindex = The outgoing interface +-- .aspath = The aspath of the route +-- .localpref = The localpref value +-- +-- Valid Return Codes: +-- 0 - Some sort of processing failure +-- This turns into a implicit DENY +-- 1 - No match was found, turns into a DENY +-- 2 - Match found, turns into a PERMIT +-- 3 - Match found and data structures changed, turns into a PERMIT +-- and a reread of the prefix and nexthop tables +function mooey () + zlog_debug(string.format("Family: %d: %s %d ifindex: %d aspath: %s localpref: %d", + prefix.family, prefix.route, + nexthop.metric, nexthop.ifindex, nexthop.aspath, nexthop.localpref)) + + nexthop.metric = 33 + nexthop.localpref = 13 + return 3 +end diff --git a/tools/subdir.am b/tools/subdir.am index 602822e589..323d1222f9 100644 --- a/tools/subdir.am +++ b/tools/subdir.am @@ -26,4 +26,5 @@ EXTRA_DIST += \ tools/rrlookup.pl \ tools/zc.pl \ tools/zebra.el \ + tools/build-debian-package.sh \ # end diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 9f6e20f2be..7a7744f7c0 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -73,7 +73,7 @@ static int config_cmp(struct config *c1, struct config *c2) static void config_del(struct config *config) { - list_delete_and_null(&config->line); + list_delete(&config->line); if (config->name) XFREE(MTYPE_VTYSH_CONFIG_LINE, config->name); XFREE(MTYPE_VTYSH_CONFIG, config); @@ -271,18 +271,18 @@ void vtysh_config_parse_line(void *arg, const char *line) strlen("ipv6 prefix-list")) == 0) config = config_get(PREFIX_IPV6_NODE, line); - else if (strncmp(line, "ip as-path access-list", - strlen("ip as-path access-list")) + else if (strncmp(line, "bgp as-path access-list", + strlen("bgp as-path access-list")) == 0) config = config_get(AS_LIST_NODE, line); - else if (strncmp(line, "ip community-list", - strlen("ip community-list")) + else if (strncmp(line, "bgp community-list", + strlen("bgp community-list")) == 0 - || strncmp(line, "ip extcommunity-list", - strlen("ip extcommunity-list")) + || strncmp(line, "bgp extcommunity-list", + strlen("bgp extcommunity-list")) == 0 - || strncmp(line, "ip large-community-list", - strlen("ip large-community-list")) + || strncmp(line, "bgp large-community-list", + strlen("bgp large-community-list")) == 0) config = config_get(COMMUNITY_LIST_NODE, line); else if (strncmp(line, "ip route", strlen("ip route")) == 0) @@ -393,7 +393,7 @@ void vtysh_config_dump(void) for (i = 0; i < vector_active(configvec); i++) if ((master = vector_slot(configvec, i)) != NULL) { - list_delete_and_null(&master); + list_delete(&master); vector_slot(configvec, i) = NULL; } list_delete_all_node(config_top); diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index 9bbe04c338..e32bf3359b 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -55,9 +55,11 @@ #define PING_TOKEN "PING" +DEFINE_MGROUP(WATCHFRR, "watchfrr") +DEFINE_MTYPE_STATIC(WATCHFRR, WATCHFRR_DAEMON, "watchfrr daemon entry") + /* Needs to be global, referenced somewhere inside libfrr. */ struct thread_master *master; -static char pidfile_default[256]; static bool watch_only = false; @@ -230,7 +232,7 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n", name of the daemon should be substituted.\n\ --dry Do not start or restart anything, just log.\n\ -p, --pid-file Set process identifier file name\n\ - (default is %s).\n\ + (default is %s/watchfrr.pid).\n\ -b, --blank-string\n\ When the supplied argument string is found in any of the\n\ various shell command arguments (-r, -s, or -k), replace\n\ @@ -240,7 +242,7 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n", -h, --help Display this help and exit\n", frr_vtydir, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG, DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART, DEFAULT_PERIOD, - DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT, pidfile_default); + DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT, frr_vtydir); } static pid_t run_background(char *shell_cmd) @@ -609,12 +611,13 @@ static void daemon_send_ready(void) if (!sent && gs.numdown == 0) { FILE *fp; + zlog_notice("all daemons up, doing startup-complete notify"); + frr_detach(); + fp = fopen(DAEMON_VTY_DIR "/watchfrr.started", "w"); if (fp) fclose(fp); #if defined HAVE_SYSTEMD - zlog_notice( - "Watchfrr: Notifying Systemd we are up and running"); systemd_send_started(master, 0); #endif sent = 1; @@ -961,6 +964,53 @@ static char *translate_blanks(const char *cmd, const char *blankstr) return res; } +static void watchfrr_init(int argc, char **argv) +{ + const char *special = "zebra"; + int i; + struct daemon *dmn, **add = &gs.daemons; + char alldaemons[512] = "", *p = alldaemons; + + for (i = optind; i < argc; i++) { + dmn = XCALLOC(MTYPE_WATCHFRR_DAEMON, sizeof(*dmn)); + + dmn->name = dmn->restart.name = argv[i]; + dmn->state = DAEMON_INIT; + gs.numdaemons++; + gs.numdown++; + dmn->fd = -1; + dmn->t_wakeup = NULL; + thread_add_timer_msec(master, wakeup_init, dmn, + 100 + (random() % 900), + &dmn->t_wakeup); + dmn->restart.interval = gs.min_restart_interval; + *add = dmn; + add = &dmn->next; + + if (!strcmp(dmn->name, special)) + gs.special = dmn; + } + + if (!gs.daemons) { + fprintf(stderr, + "Must specify one or more daemons to monitor.\n\n"); + frr_help_exit(1); + } + if (!watch_only && !gs.special) { + fprintf(stderr, "\"%s\" daemon must be in daemon lists\n\n", + special); + frr_help_exit(1); + } + + for (dmn = gs.daemons; dmn; dmn = dmn->next) { + snprintf(p, alldaemons + sizeof(alldaemons) - p, "%s%s", + (p == alldaemons) ? "" : " ", dmn->name); + p += strlen(p); + } + zlog_notice("%s %s watching [%s]%s", progname, FRR_VERSION, alldaemons, + watch_only ? ", monitor mode" : ""); +} + struct zebra_privs_t watchfrr_privs = { #ifdef VTY_GROUP .vty_group = VTY_GROUP, @@ -984,7 +1034,8 @@ static struct quagga_signal_t watchfrr_signals[] = { FRR_DAEMON_INFO(watchfrr, WATCHFRR, .flags = FRR_NO_PRIVSEP | FRR_NO_TCPVTY | FRR_LIMITED_CLI - | FRR_NO_CFG_PID_DRY | FRR_NO_ZCLIENT, + | FRR_NO_CFG_PID_DRY | FRR_NO_ZCLIENT + | FRR_DETACH_LATER, .printhelp = printhelp, .copyright = "Copyright 2004 Andrew J. Schorr", @@ -999,13 +1050,8 @@ FRR_DAEMON_INFO(watchfrr, WATCHFRR, int main(int argc, char **argv) { int opt; - const char *pidfile = pidfile_default; - const char *special = "zebra"; const char *blankstr = NULL; - snprintf(pidfile_default, sizeof(pidfile_default), "%s/watchfrr.pid", - frr_vtydir); - frr_preinit(&watchfrr_di, argc, argv); progname = watchfrr_di.progname; @@ -1087,7 +1133,7 @@ int main(int argc, char **argv) gs.period = 1000 * period; } break; case 'p': - pidfile = optarg; + watchfrr_di.pid_file = optarg; break; case 'r': if (!valid_command(optarg)) { @@ -1167,98 +1213,18 @@ int main(int argc, char **argv) master = frr_init(); watchfrr_error_init(); + watchfrr_init(argc, argv); + watchfrr_vty_init(); + + frr_config_fork(); zlog_set_level(ZLOG_DEST_MONITOR, ZLOG_DISABLED); - if (watchfrr_di.daemon_mode) { + if (watchfrr_di.daemon_mode) zlog_set_level(ZLOG_DEST_SYSLOG, MIN(gs.loglevel, LOG_DEBUG)); - if (daemon(0, 0) < 0) { - fprintf(stderr, "Watchfrr daemon failed: %s", - strerror(errno)); - exit(1); - } - } else + else zlog_set_level(ZLOG_DEST_STDOUT, MIN(gs.loglevel, LOG_DEBUG)); - watchfrr_vty_init(); - - frr_vty_serv(); - - { - int i; - struct daemon *tail = NULL; - - for (i = optind; i < argc; i++) { - struct daemon *dmn; - - if (!(dmn = (struct daemon *)calloc(1, sizeof(*dmn)))) { - fprintf(stderr, "calloc(1,%u) failed: %s\n", - (unsigned int)sizeof(*dmn), - safe_strerror(errno)); - return 1; - } - dmn->name = dmn->restart.name = argv[i]; - dmn->state = DAEMON_INIT; - gs.numdaemons++; - gs.numdown++; - dmn->fd = -1; - dmn->t_wakeup = NULL; - thread_add_timer_msec(master, wakeup_init, dmn, - 100 + (random() % 900), - &dmn->t_wakeup); - dmn->restart.interval = gs.min_restart_interval; - if (tail) - tail->next = dmn; - else - gs.daemons = dmn; - tail = dmn; - - if (!strcmp(dmn->name, special)) - gs.special = dmn; - } - } - if (!gs.daemons) { - fputs("Must specify one or more daemons to monitor.\n", stderr); - frr_help_exit(1); - } - if (!watch_only && !gs.special) { - fprintf(stderr, "\"%s\" daemon must be in daemon list\n", - special); - frr_help_exit(1); - } - - /* Make sure we're not already running. */ - pid_output(pidfile); - - /* Announce which daemons are being monitored. */ - { - struct daemon *dmn; - size_t len = 0; - - for (dmn = gs.daemons; dmn; dmn = dmn->next) - len += strlen(dmn->name) + 1; - - { - char buf[len + 1]; - char *p = buf; - - for (dmn = gs.daemons; dmn; dmn = dmn->next) { - if (p != buf) - *p++ = ' '; - strcpy(p, dmn->name); - p += strlen(p); - } - zlog_notice("%s %s watching [%s]%s", progname, - FRR_VERSION, buf, - watch_only ? ", monitor mode" : ""); - } - } - - { - struct thread thread; - - while (thread_fetch(master, &thread)) - thread_call(&thread); - } + frr_run(master); systemd_send_stopping(); /* Not reached. */ diff --git a/watchfrr/watchfrr.h b/watchfrr/watchfrr.h index 1a1c19056f..ee16846a1d 100644 --- a/watchfrr/watchfrr.h +++ b/watchfrr/watchfrr.h @@ -21,6 +21,10 @@ #ifndef FRR_WATCHFRR_H #define FRR_WATCHFRR_H +#include "lib/memory.h" + +DECLARE_MGROUP(WATCHFRR) + extern void watchfrr_vty_init(void); extern pid_t integrated_write_pid; diff --git a/watchfrr/watchfrr_errors.c b/watchfrr/watchfrr_errors.c index c720b65099..0aa27ef661 100644 --- a/watchfrr/watchfrr_errors.c +++ b/watchfrr/watchfrr_errors.c @@ -32,6 +32,12 @@ static struct log_ref ferr_watchfrr_err[] = { .suggestion = "Ensure that FRR is still running and if not please open an Issue" }, { + .code = EC_WATCHFRR_UNEXPECTED_DAEMONS, + .title = "WATCHFRR wrong daemons to watch", + .description = "As part of WATCHFRR startup you must specify 1 or more daemons to monitor", + .suggestion = "Update your startup scripts to include zebra and any other daemon you would like to monitor", + }, + { .code = END_FERR, } }; diff --git a/watchfrr/watchfrr_errors.h b/watchfrr/watchfrr_errors.h index 93103b6551..9d5abde52b 100644 --- a/watchfrr/watchfrr_errors.h +++ b/watchfrr/watchfrr_errors.h @@ -25,6 +25,7 @@ enum watchfrr_log_refs { EC_WATCHFRR_CONNECTION = WATCHFRR_FERR_START, + EC_WATCHFRR_UNEXPECTED_DAEMONS, }; extern void watchfrr_error_init(void); diff --git a/zebra/interface.c b/zebra/interface.c index 96b244635d..afb08f7012 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -88,7 +88,7 @@ static void zebra_if_node_destroy(route_table_delegate_t *delegate, struct route_node *node) { if (node->info) - list_delete_and_null((struct list **)&node->info); + list_delete((struct list **)&node->info); route_node_destroy(delegate, table, node); } @@ -174,7 +174,7 @@ static int if_zebra_delete_hook(struct interface *ifp) struct rtadvconf *rtadv; rtadv = &zebra_if->rtadv; - list_delete_and_null(&rtadv->AdvPrefixList); + list_delete(&rtadv->AdvPrefixList); #endif /* HAVE_RTADV */ THREAD_OFF(zebra_if->speed_update); @@ -361,7 +361,7 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc) } /* Otherwise, free list and route node. */ - list_delete_and_null(&addr_list); + list_delete(&addr_list); rn->info = NULL; route_unlock_node(rn); @@ -673,7 +673,7 @@ static void if_delete_connected(struct interface *ifp) } /* Free chain list and respective route node. */ - list_delete_and_null(&addr_list); + list_delete(&addr_list); rn->info = NULL; route_unlock_node(rn); } else if (cp.family == AF_INET6) { diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 5fdaae4fe5..3e50550dd2 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -309,7 +309,7 @@ static void irdp_if_stop(struct interface *ifp) irdp_advert_off(ifp); - list_delete_and_null(&irdp->AdvPrefList); + list_delete(&irdp->AdvPrefList); irdp->flags = 0; } diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index c8ea8ae445..e6610f21be 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -1107,7 +1107,6 @@ void kernel_init(struct zebra_ns *zns) if (nl_rcvbufsize) netlink_recvbuf(&zns->netlink, nl_rcvbufsize); - assert(zns->netlink.sock >= 0); netlink_install_filter(zns->netlink.sock, zns->netlink_cmd.snl.nl_pid); zns->t_netlink = NULL; diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 2b0508099f..8afb1a0b79 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -482,6 +482,6 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, void label_manager_close() { - list_delete_and_null(&lbl_mgr.lc_list); + list_delete(&lbl_mgr.lc_list); stream_free(obuf); } diff --git a/zebra/main.c b/zebra/main.c index c46f8bb95d..148bcab7e4 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -170,7 +170,7 @@ static void sigint(void) prefix_list_reset(); route_map_finish(); - list_delete_and_null(&zebrad.client_list); + list_delete(&zebrad.client_list); work_queue_free_and_null(&zebrad.ribq); meta_queue_free(zebrad.mq); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 040de379e1..795ee2703a 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2200,7 +2200,7 @@ static int netlink_macfdb_update(struct interface *ifp, vlanid_t vid, struct interface *br_if; struct zebra_if *br_zif; char buf[ETHER_ADDR_STRLEN]; - int vid_present = 0, dst_present = 0; + int vid_present = 0; char vid_buf[20]; char dst_buf[30]; struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id); @@ -2234,7 +2234,6 @@ static int netlink_macfdb_update(struct interface *ifp, vlanid_t vid, req.ndm.ndm_ifindex = ifp->ifindex; dst_alen = 4; // TODO: hardcoded addattr_l(&req.n, sizeof(req), NDA_DST, &vtep_ip, dst_alen); - dst_present = 1; sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip)); br_zif = (struct zebra_if *)br_if->info; if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif) && vid > 0) { @@ -2250,8 +2249,7 @@ static int netlink_macfdb_update(struct interface *ifp, vlanid_t vid, nl_family_to_str(req.ndm.ndm_family), ifp->name, ifp->ifindex, vid_present ? vid_buf : "", sticky ? "sticky " : "", - prefix_mac2str(mac, buf, sizeof(buf)), - dst_present ? dst_buf : ""); + prefix_mac2str(mac, buf, sizeof(buf)), dst_buf); return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); diff --git a/zebra/table_manager.c b/zebra/table_manager.c index 91b45f3f07..7ed673a88f 100644 --- a/zebra/table_manager.c +++ b/zebra/table_manager.c @@ -237,5 +237,5 @@ void table_manager_disable(ns_id_t ns_id) { if (ns_id != NS_DEFAULT) return; - list_delete_and_null(&tbl_mgr.lc_list); + list_delete(&tbl_mgr.lc_list); } diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 0d1ccdc5aa..0ccd3242d5 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -572,7 +572,7 @@ static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p, */ static int fec_del(zebra_fec_t *fec) { - list_delete_and_null(&fec->client_list); + list_delete(&fec->client_list); fec->rn->info = NULL; route_unlock_node(fec->rn); XFREE(MTYPE_FEC, fec); @@ -2810,7 +2810,7 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, vty_out(vty, "\n"); } - list_delete_and_null(&lsp_list); + list_delete(&lsp_list); } /* @@ -2849,7 +2849,7 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) } } - list_delete_and_null(&slsp_list); + list_delete(&slsp_list); return (zvrf->slsp_table->count ? 1 : 0); } diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index 600d1d55c6..ea4b07a87d 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -220,46 +220,36 @@ ns_id_t zebra_ns_id_get(const char *netnspath) nlh = (struct nlmsghdr *)buf; /* message to analyse : NEWNSID response */ - len = ret; ret = 0; - do { - if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) { - return_nsid = extract_nsid(nlh, buf); - if (return_nsid != NS_UNKNOWN) - break; - } else { - if (nlh->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = - (struct nlmsgerr - *)((char *)nlh - + NETLINK_ALIGN(sizeof( - struct - nlmsghdr))); - - ret = -1; - if (err->error < 0) - errno = -err->error; - else - errno = err->error; - if (errno == 0) { - /* request NEWNSID was successfull - * return EEXIST error to get GETNSID - */ - errno = EEXIST; - } - } else { - /* other errors ignored - * attempt to get nsid + if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) { + return_nsid = extract_nsid(nlh, buf); + } else { + if (nlh->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = + (struct nlmsgerr + *)((char *)nlh + + NETLINK_ALIGN( + sizeof(struct nlmsghdr))); + + ret = -1; + if (err->error < 0) + errno = -err->error; + else + errno = err->error; + if (errno == 0) { + /* request NEWNSID was successfull + * return EEXIST error to get GETNSID */ - ret = -1; errno = EEXIST; - break; } + } else { + /* other errors ignored + * attempt to get nsid + */ + ret = -1; + errno = EEXIST; } - len = len - NETLINK_ALIGN(nlh->nlmsg_len); - nlh = (struct nlmsghdr *)((char *)nlh - + NETLINK_ALIGN(nlh->nlmsg_len)); - } while (len != 0 && return_nsid != NS_UNKNOWN && ret == 0); + } if (ret <= 0) { if (errno != EEXIST && ret != 0) { diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index a8f3493547..bdcf03a055 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2058,7 +2058,7 @@ void meta_queue_free(struct meta_queue *mq) unsigned i; for (i = 0; i < MQ_SIZE; i++) - list_delete_and_null(&mq->subq[i]); + list_delete(&mq->subq[i]); XFREE(MTYPE_WORK_QUEUE, mq); } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 30062a0728..622ed5ac05 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -171,8 +171,8 @@ struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type) void zebra_free_rnh(struct rnh *rnh) { rnh->flags |= ZEBRA_NHT_DELETED; - list_delete_and_null(&rnh->client_list); - list_delete_and_null(&rnh->zebra_pseudowire_list); + list_delete(&rnh->client_list); + list_delete(&rnh->zebra_pseudowire_list); free_state(rnh->vrf_id, rnh->state, rnh->node); XFREE(MTYPE_RNH, rnh); } diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index ea0bef3718..f8417503ef 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -2287,7 +2287,7 @@ static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac) { zebra_mac_t *tmp_mac; - list_delete_and_null(&mac->neigh_list); + list_delete(&mac->neigh_list); /* Free the VNI hash entry and allocated memory. */ tmp_mac = hash_release(zvni->mac_table, mac); @@ -3663,7 +3663,7 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni) assert(zns); /* free the list of l2vnis */ - list_delete_and_null(&zl3vni->l2vnis); + list_delete(&zl3vni->l2vnis); zl3vni->l2vnis = NULL; /* Free the rmac table */ @@ -4269,10 +4269,8 @@ static void process_remote_macip_add(vni_t vni, vni, prefix_mac2str(macaddr, buf, sizeof(buf)), - ipa_len ? " IP " : "", - ipa_len ? - ipaddr2str(ipaddr, - buf1, sizeof(buf1)) : "", + " IP ", + ipaddr2str(ipaddr, buf1, sizeof(buf1)), n_type, tmp_seq); return; diff --git a/zebra/zebra_vxlan_null.c b/zebra/zebra_vxlan_null.c deleted file mode 100644 index 00c849a3d0..0000000000 --- a/zebra/zebra_vxlan_null.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Zebra VxLAN (EVPN) - * Copyright (C) 2016, 2017 Cumulus Networks, Inc. - * - * This file is part of FRR. - * - * FRR is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * FRR is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FRR; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include <zebra.h> - -#include "if.h" -#include "zebra/debug.h" -#include "zebra/zserv.h" -#include "zebra/rib.h" -#include "zebra/zebra_vrf.h" -#include "zebra/zebra_l2.h" -#include "zebra/zebra_vxlan.h" - -void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni) -{ -} - -void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty, - struct zebra_vrf *zvrf, - struct in_addr vtep_ip) -{ -} - -void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, struct ethaddr *mac) -{ -} - -void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, struct in_addr vtep_ip) -{ -} - -void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni) -{ -} - -void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_print_specific_neigh_vni(struct vty *vty, - struct zebra_vrf *zvrf, vni_t vni, - struct ipaddr *ip) -{ -} - -void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, struct in_addr vtep_ip) -{ -} - -void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni) -{ -} - -void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_print_evpn(struct vty *vty, bool uj) -{ -} - -void zebra_vxlan_print_rmacs_l3vni(struct vty *, vni_t, uint8_t) -{ -} - -void zebra_vxlan_print_rmacs_all_l3vni(struct vty *, uint8_t) -{ -} - -void zebra_vxlan_print_nh_l3vni(struct vty *, vni_t, uint8_t) -{ -} - -void zebra_vxlan_print_nh_all_l3vni(struct vty *, uint8_t) -{ -} - -void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni) -{ -} - -int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) -{ - return 0; -} - -int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if) -{ - return 0; -} - -int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -int zebra_vxlan_local_mac_add_update(struct interface *ifp, - struct interface *br_if, - struct ethaddr *mac, vlanid_t vid, - uint8_t sticky) -{ - return 0; -} - -int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) -{ - return 0; -} - -int zebra_vxlan_check_readd_remote_mac(struct interface *ifp, - struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) -{ - return 0; -} - -int zebra_vxlan_check_del_local_mac(struct interface *ifp, - struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) -{ - return 0; -} - -int zebra_vxlan_if_up(struct interface *ifp) -{ - return 0; -} - -int zebra_vxlan_if_down(struct interface *ifp) -{ - return 0; -} - -int zebra_vxlan_if_add(struct interface *ifp) -{ - return 0; -} - -int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) -{ - return 0; -} - -int zebra_vxlan_if_del(struct interface *ifp) -{ - return 0; -} - -int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -void zebra_vxlan_init_tables(struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_close_tables(struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf) -{ -} |
