diff options
170 files changed, 2841 insertions, 2962 deletions
diff --git a/Makefile.am b/Makefile.am index 166ac29d1c..851cefc85c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,6 +40,12 @@ shvar-%: var-%: @echo "$($*)" >&$(VARFD) +if ONLY_CLIPPY +.DEFAULT_GOAL := clippy-only +endif +clippy-only: Makefile lib/clippy config.h +.PHONY: clippy-only + # overwriting these vars breaks cross-compilation. let's be helpful and warn. # # note: "#AUTODERP# " will be removed from Makefile by configure. These are @@ -20,6 +20,7 @@ FRR currently supports the following protocols: * Babel * PBR * OpenFabric +* VRRP * EIGRP (alpha) * NHRP (alpha) diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index b84bc39cd8..0eeb9b2bbb 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -39,9 +39,10 @@ THE SOFTWARE. #include "neighbour.h" #include "route.h" #include "xroute.h" -#include "babel_memory.h" #include "babel_errors.h" +DEFINE_MTYPE_STATIC(BABELD, BABEL_IF, "Babel Interface") + #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0) static int babel_enable_if_lookup (const char *ifname); diff --git a/babeld/babel_memory.c b/babeld/babel_memory.c deleted file mode 100644 index a10b7791e7..0000000000 --- a/babeld/babel_memory.c +++ /dev/null @@ -1,30 +0,0 @@ -/* babeld memory type definitions - * - * Copyright (C) 2017 Donald Sharp - * - * 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. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "babel_memory.h" - -DEFINE_MGROUP(BABELD, "babeld") -DEFINE_MTYPE(BABELD, BABEL, "Babel Structure") -DEFINE_MTYPE(BABELD, BABEL_IF, "Babel Interface") diff --git a/babeld/babel_memory.h b/babeld/babel_memory.h deleted file mode 100644 index 4283498891..0000000000 --- a/babeld/babel_memory.h +++ /dev/null @@ -1,32 +0,0 @@ -/* babel memory type declarations - * - * Copyright (C) 2017 Donald Sharp - * - * 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. - */ - -#ifndef _FRR_BABEL_MEMORY_H -#define _FRR_BABEL_MEMORY_H - -#include "memory.h" - -DECLARE_MGROUP(BABELD) -DECLARE_MTYPE(BABEL) -DECLARE_MTYPE(BABEL_IF) - -#endif /* _FRR_BABELD_MEMORY_H */ diff --git a/babeld/babeld.c b/babeld/babeld.c index 39451b435a..6ad004a4a4 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -43,9 +43,11 @@ THE SOFTWARE. #include "resend.h" #include "babel_filter.h" #include "babel_zebra.h" -#include "babel_memory.h" #include "babel_errors.h" +DEFINE_MGROUP(BABELD, "babeld") +DEFINE_MTYPE_STATIC(BABELD, BABEL, "Babel Structure") + static int babel_init_routing_process(struct thread *thread); static void babel_get_myid(void); static void babel_initial_noise(void); diff --git a/babeld/subdir.am b/babeld/subdir.am index 7081c730aa..dd46675f22 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -17,7 +17,6 @@ babeld_libbabel_a_SOURCES = \ babeld/babel_errors.c \ babeld/babel_filter.c \ babeld/babel_interface.c \ - babeld/babel_memory.c \ babeld/babel_zebra.c \ babeld/babeld.c \ babeld/kernel.c \ @@ -36,7 +35,6 @@ noinst_HEADERS += \ babeld/babel_filter.h \ babeld/babel_interface.h \ babeld/babel_main.h \ - babeld/babel_memory.h \ babeld/babel_zebra.h \ babeld/babeld.h \ babeld/kernel.h \ diff --git a/babeld/util.h b/babeld/util.h index 7b836c2e4c..00a025ff93 100644 --- a/babeld/util.h +++ b/babeld/util.h @@ -27,6 +27,9 @@ THE SOFTWARE. #include "babeld.h" #include "babel_main.h" #include "log.h" +#include "memory.h" + +DECLARE_MGROUP(BABELD) #if defined(i386) || defined(__mc68020__) || defined(__x86_64__) #define DO_NTOHS(_d, _s) do{ _d = ntohs(*(const unsigned short*)(_s)); }while(0) diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 4354431820..08a70abc1e 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -31,7 +31,10 @@ #include "bfd.h" -DEFINE_QOBJ_TYPE(bfd_session); +DEFINE_MTYPE_STATIC(BFDD, BFDD_CONFIG, "long-lived configuration memory") +DEFINE_MTYPE_STATIC(BFDD, BFDD_SESSION_OBSERVER, "Session observer") +DEFINE_MTYPE_STATIC(BFDD, BFDD_VRF, "BFD VRF") +DEFINE_QOBJ_TYPE(bfd_session) /* * Prototypes @@ -1552,41 +1555,41 @@ static int bfd_vrf_enable(struct vrf *vrf) } else bvrf = vrf->info; log_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id); - - /* create sockets if needed */ - if (!bvrf->bg_shop) - bvrf->bg_shop = bp_udp_shop(vrf->vrf_id); - if (!bvrf->bg_mhop) - bvrf->bg_mhop = bp_udp_mhop(vrf->vrf_id); - if (!bvrf->bg_shop6) - bvrf->bg_shop6 = bp_udp6_shop(vrf->vrf_id); - if (!bvrf->bg_mhop6) - bvrf->bg_mhop6 = bp_udp6_mhop(vrf->vrf_id); - if (!bvrf->bg_echo) - bvrf->bg_echo = bp_echo_socket(vrf->vrf_id); - if (!bvrf->bg_echov6) - bvrf->bg_echov6 = bp_echov6_socket(vrf->vrf_id); - - /* Add descriptors to the event loop. */ - if (!bvrf->bg_ev[0]) - thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop, - &bvrf->bg_ev[0]); - if (!bvrf->bg_ev[1]) - thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop, - &bvrf->bg_ev[1]); - if (!bvrf->bg_ev[2]) - thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6, - &bvrf->bg_ev[2]); - if (!bvrf->bg_ev[3]) - thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6, - &bvrf->bg_ev[3]); - if (!bvrf->bg_ev[4]) - thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo, - &bvrf->bg_ev[4]); - if (!bvrf->bg_ev[5]) - thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6, - &bvrf->bg_ev[5]); - + if (vrf->vrf_id == VRF_DEFAULT || + vrf_get_backend() == VRF_BACKEND_NETNS) { + if (!bvrf->bg_shop) + bvrf->bg_shop = bp_udp_shop(vrf->vrf_id); + if (!bvrf->bg_mhop) + bvrf->bg_mhop = bp_udp_mhop(vrf->vrf_id); + if (!bvrf->bg_shop6) + bvrf->bg_shop6 = bp_udp6_shop(vrf->vrf_id); + if (!bvrf->bg_mhop6) + bvrf->bg_mhop6 = bp_udp6_mhop(vrf->vrf_id); + if (!bvrf->bg_echo) + bvrf->bg_echo = bp_echo_socket(vrf->vrf_id); + if (!bvrf->bg_echov6) + bvrf->bg_echov6 = bp_echov6_socket(vrf->vrf_id); + + /* Add descriptors to the event loop. */ + if (!bvrf->bg_ev[0]) + thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop, + &bvrf->bg_ev[0]); + if (!bvrf->bg_ev[1]) + thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop, + &bvrf->bg_ev[1]); + if (!bvrf->bg_ev[2]) + thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6, + &bvrf->bg_ev[2]); + if (!bvrf->bg_ev[3]) + thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6, + &bvrf->bg_ev[3]); + if (!bvrf->bg_ev[4]) + thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo, + &bvrf->bg_ev[4]); + if (!bvrf->bg_ev[5]) + thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6, + &bvrf->bg_ev[5]); + } if (vrf->vrf_id != VRF_DEFAULT) { bfdd_zclient_register(vrf->vrf_id); bfdd_sessions_enable_vrf(vrf); diff --git a/bfdd/bfd.h b/bfdd/bfd.h index 213e905bf0..ec31c8cbc6 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -41,14 +41,9 @@ #define BFDD_JSON_CONV_OPTIONS (0) #endif -DECLARE_MGROUP(BFDD); -DECLARE_MTYPE(BFDD_TMP); -DECLARE_MTYPE(BFDD_CONFIG); -DECLARE_MTYPE(BFDD_LABEL); -DECLARE_MTYPE(BFDD_CONTROL); -DECLARE_MTYPE(BFDD_SESSION_OBSERVER); -DECLARE_MTYPE(BFDD_NOTIFICATION); -DECLARE_MTYPE(BFDD_VRF); +DECLARE_MGROUP(BFDD) +DECLARE_MTYPE(BFDD_CONTROL) +DECLARE_MTYPE(BFDD_NOTIFICATION) struct bfd_timers { uint32_t desired_min_tx; @@ -259,9 +254,9 @@ struct bfd_session { uint64_t refcount; /* number of pointers referencing this. */ /* VTY context data. */ - QOBJ_FIELDS; + QOBJ_FIELDS }; -DECLARE_QOBJ_TYPE(bfd_session); +DECLARE_QOBJ_TYPE(bfd_session) struct peer_label { TAILQ_ENTRY(peer_label) pl_entry; diff --git a/bfdd/bfdd.c b/bfdd/bfdd.c index 06e01abcfa..6c277c98f5 100644 --- a/bfdd/bfdd.c +++ b/bfdd/bfdd.c @@ -29,14 +29,9 @@ /* * FRR related code. */ -DEFINE_MGROUP(BFDD, "Bidirectional Forwarding Detection Daemon"); -DEFINE_MTYPE(BFDD, BFDD_TMP, "short-lived temporary memory"); -DEFINE_MTYPE(BFDD, BFDD_CONFIG, "long-lived configuration memory"); -DEFINE_MTYPE(BFDD, BFDD_LABEL, "long-lived label memory"); -DEFINE_MTYPE(BFDD, BFDD_CONTROL, "long-lived control socket memory"); -DEFINE_MTYPE(BFDD, BFDD_SESSION_OBSERVER, "Session observer"); -DEFINE_MTYPE(BFDD, BFDD_NOTIFICATION, "short-lived control notification data"); -DEFINE_MTYPE(BFDD, BFDD_VRF, "BFD VRF"); +DEFINE_MGROUP(BFDD, "Bidirectional Forwarding Detection Daemon") +DEFINE_MTYPE(BFDD, BFDD_CONTROL, "long-lived control socket memory") +DEFINE_MTYPE(BFDD, BFDD_NOTIFICATION, "short-lived control notification data") /* Master of threads. */ struct thread_master *master; diff --git a/bfdd/config.c b/bfdd/config.c index 74e7d63d0c..0c0bac0aaa 100644 --- a/bfdd/config.c +++ b/bfdd/config.c @@ -30,6 +30,8 @@ #include "bfd.h" +DEFINE_MTYPE_STATIC(BFDD, BFDD_LABEL, "long-lived label memory") + /* * Definitions */ diff --git a/bgpd/bgp_addpath.c b/bgpd/bgp_addpath.c index 63373cb9a7..0ca4b613ee 100644 --- a/bgpd/bgp_addpath.c +++ b/bgpd/bgp_addpath.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "bgp_addpath.h" #include "bgp_route.h" diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 5a4105b400..d46623c9d2 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1664,8 +1664,9 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, */ if (bgp_debug_update(peer, NULL, NULL, 0)) zlog_debug( - "%s: MP_REACH received AFI %u or SAFI %u is unrecognized", - peer->host, pkt_afi, pkt_safi); + "%s: MP_REACH received AFI %s or SAFI %s is unrecognized", + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); return BGP_ATTR_PARSE_ERROR; } @@ -1849,8 +1850,9 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args, */ if (bgp_debug_update(peer, NULL, NULL, 0)) zlog_debug( - "%s: MP_UNREACH received AFI %u or SAFI %u is unrecognized", - peer->host, pkt_afi, pkt_safi); + "%s: MP_UNREACH received AFI %s or SAFI %s is unrecognized", + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); return BGP_ATTR_PARSE_ERROR; } diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index b9a5784799..ce617fe6b5 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -695,6 +695,32 @@ int lcommunity_list_match(struct lcommunity *lcom, struct community_list *list) return 0; } + +/* Perform exact matching. In case of expanded large-community-list, do + * same thing as lcommunity_list_match(). + */ +int lcommunity_list_exact_match(struct lcommunity *lcom, + struct community_list *list) +{ + struct community_entry *entry; + + for (entry = list->head; entry; entry = entry->next) { + if (entry->any) + return entry->direct == COMMUNITY_PERMIT ? 1 : 0; + + if (entry->style == LARGE_COMMUNITY_LIST_STANDARD) { + if (lcommunity_cmp(lcom, entry->u.com)) + return entry->direct == COMMUNITY_PERMIT ? 1 + : 0; + } else if (entry->style == LARGE_COMMUNITY_LIST_EXPANDED) { + if (lcommunity_regexp_match(lcom, entry->reg)) + return entry->direct == COMMUNITY_PERMIT ? 1 + : 0; + } + } + return 0; +} + int ecommunity_list_match(struct ecommunity *ecom, struct community_list *list) { struct community_entry *entry; diff --git a/bgpd/bgp_clist.h b/bgpd/bgp_clist.h index 75a31611ba..87b29ac3be 100644 --- a/bgpd/bgp_clist.h +++ b/bgpd/bgp_clist.h @@ -165,6 +165,8 @@ extern int ecommunity_list_match(struct ecommunity *, struct community_list *); extern int lcommunity_list_match(struct lcommunity *, struct community_list *); extern int community_list_exact_match(struct community *, struct community_list *); +extern int lcommunity_list_exact_match(struct lcommunity *lcom, + struct community_list *list); extern struct community *community_list_match_delete(struct community *, struct community_list *); extern struct lcommunity * diff --git a/bgpd/bgp_errors.c b/bgpd/bgp_errors.c index 6e181697d6..d9aba87e35 100644 --- a/bgpd/bgp_errors.c +++ b/bgpd/bgp_errors.c @@ -427,12 +427,6 @@ static struct log_ref ferr_bgp_err[] = { .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" }, { - .code = EC_BGP_MULTI_INSTANCE, - .title = "BGP config multi-instance issue", - .description = "BGP configuration attempting multiple instances without enabling the feature", - .suggestion = "Correct the configuration so that bgp multiple-instance is enabled if desired" - }, - { .code = EC_BGP_EVPN_AS_MISMATCH, .title = "BGP AS configuration issue", .description = "BGP configuration attempted for a different AS than currently configured", diff --git a/bgpd/bgp_errors.h b/bgpd/bgp_errors.h index 39d043ff13..35c5cc3998 100644 --- a/bgpd/bgp_errors.h +++ b/bgpd/bgp_errors.h @@ -67,7 +67,6 @@ enum bgp_log_refs { EC_BGP_EVPN_ROUTE_INVALID, EC_BGP_EVPN_ROUTE_CREATE, EC_BGP_ES_CREATE, - EC_BGP_MULTI_INSTANCE, EC_BGP_EVPN_AS_MISMATCH, EC_BGP_EVPN_INSTANCE_MISMATCH, EC_BGP_FLOWSPEC_PACKET, diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c4b2a606c5..94022ec1be 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -5533,10 +5533,6 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, vrf_id == VRF_DEFAULT ? BGP_INSTANCE_TYPE_DEFAULT : BGP_INSTANCE_TYPE_VRF); switch (ret) { - case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET: - flog_err(EC_BGP_MULTI_INSTANCE, - "'bgp multiple-instance' not present\n"); - return -1; case BGP_ERR_AS_MISMATCH: flog_err(EC_BGP_EVPN_AS_MISMATCH, "BGP is already running; AS is %u\n", as); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 67b0079c37..ca6edffab0 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -1060,6 +1060,9 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, json_object_int_add(json_prefix_info, "prefixLen", rm->p.prefixlen); + + if (rd_header) + json_nroute = json_object_new_object(); } for (pi = bgp_node_get_bgp_path_info(rm); pi; @@ -1132,8 +1135,6 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, else if (type == RD_TYPE_IP) decode_rd_ip(pnt + 2, &rd_ip); if (use_json) { - json_nroute = - json_object_new_object(); if (type == RD_TYPE_AS || type == RD_TYPE_AS4) sprintf(rd_str, "%u:%d", @@ -1184,6 +1185,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, SAFI_EVPN, json_array); output_count++; } + rd_header = 0; if (use_json) { json_object_object_add(json_prefix_info, "paths", json_array); diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index f19453fecb..61c7b4080c 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -29,6 +29,7 @@ #include "bgpd/bgp_memory.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_packet.h" +#include "bgpd/bgp_rd.h" #include "bgpd/bgp_debug.h" #include "bgpd/bgp_evpn_private.h" @@ -133,11 +134,11 @@ static struct bgp_self_mac *bgp_mac_find_interface_name(const char *ifname) } static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, - struct bgp_table *table) + struct bgp_table *table, + struct ethaddr *macaddr) { struct bgp_node *prn, *rn; struct bgp_path_info *pi; - uint32_t count = 0; for (prn = bgp_table_top(table); prn; prn = bgp_route_next(prn)) { struct bgp_table *sub = prn->info; @@ -146,12 +147,21 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, continue; for (rn = bgp_table_top(sub); rn; rn = bgp_route_next(rn)) { + bool rn_affected; + struct prefix_evpn *pevpn = (struct prefix_evpn *)&rn->p; struct prefix_rd prd; uint32_t num_labels = 0; mpls_label_t *label_pnt = NULL; struct bgp_route_evpn evpn; - count++; + if (pevpn->family == AF_EVPN && + pevpn->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE && + memcmp(&rn->p.u.prefix_evpn.macip_addr.mac, + macaddr, ETH_ALEN) == 0) + rn_affected = true; + else + rn_affected = false; + for (pi = rn->info; pi; pi = pi->next) { if (pi->peer == peer) break; @@ -160,6 +170,14 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, if (!pi) continue; + /* + * If the mac address is not the same then + * we don't care and since we are looking + */ + if ((memcmp(&pi->attr->rmac, macaddr, ETH_ALEN) != 0) && + !rn_affected) + continue; + if (pi->extra) num_labels = pi->extra->num_labels; if (num_labels) @@ -169,6 +187,23 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, prd.prefixlen = 64; memcpy(&prd.val, &prn->p.u.val, 8); + if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) { + if (bgp_debug_update(peer, &rn->p, NULL, 1)) { + char pfx_buf[BGP_PRD_PATH_STRLEN]; + + bgp_debug_rdpfxpath2str( + AFI_L2VPN, SAFI_EVPN, &prd, + &rn->p, label_pnt, num_labels, + pi->addpath_rx_id ? 1 : 0, + pi->addpath_rx_id, pfx_buf, + sizeof(pfx_buf)); + zlog_debug( + "%s skip update of %s marked as removed", + peer->host, pfx_buf); + } + continue; + } + memcpy(&evpn, &pi->attr->evpn_overlay, sizeof(evpn)); int32_t ret = bgp_update(peer, &rn->p, pi->addpath_rx_id, @@ -184,7 +219,7 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, } } -static void bgp_mac_rescan_evpn_table(struct bgp *bgp) +static void bgp_mac_rescan_evpn_table(struct bgp *bgp, struct ethaddr *macaddr) { struct listnode *node; struct peer *peer; @@ -214,12 +249,12 @@ static void bgp_mac_rescan_evpn_table(struct bgp *bgp) if (bgp_debug_update(peer, NULL, NULL, 1)) zlog_debug("Processing EVPN MAC interface change on peer %s", peer->host); - bgp_process_mac_rescan_table(bgp, peer, table); + bgp_process_mac_rescan_table(bgp, peer, table, macaddr); } } } -static void bgp_mac_rescan_all_evpn_tables(void) +static void bgp_mac_rescan_all_evpn_tables(struct ethaddr *macaddr) { struct listnode *node; struct bgp *bgp; @@ -228,11 +263,12 @@ static void bgp_mac_rescan_all_evpn_tables(void) struct bgp_table *table = bgp->rib[AFI_L2VPN][SAFI_EVPN]; if (table) - bgp_mac_rescan_evpn_table(bgp); + bgp_mac_rescan_evpn_table(bgp, macaddr); } } -static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname) +static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname, + struct ethaddr *macaddr) { struct listnode *node = NULL; char *name; @@ -252,7 +288,7 @@ static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname) list_delete(&bsm->ifp_list); XFREE(MTYPE_BSM, bsm); - bgp_mac_rescan_all_evpn_tables(); + bgp_mac_rescan_all_evpn_tables(macaddr); } } @@ -276,22 +312,26 @@ void bgp_mac_add_mac_entry(struct interface *ifp) listnode_add(bsm->ifp_list, ifname); if (old_bsm) - bgp_mac_remove_ifp_internal(old_bsm, ifname); + bgp_mac_remove_ifp_internal(old_bsm, ifname, + &old_bsm->macaddr); } else { /* * If old mac address is the same as the new, * then there is nothing to do here */ - if (old_bsm == bsm) + if (old_bsm == bsm) { + XFREE(MTYPE_BSM_STRING, ifname); return; + } if (old_bsm) - bgp_mac_remove_ifp_internal(old_bsm, ifp->name); + bgp_mac_remove_ifp_internal(old_bsm, ifp->name, + &old_bsm->macaddr); listnode_add(bsm->ifp_list, ifname); } - bgp_mac_rescan_all_evpn_tables(); + bgp_mac_rescan_all_evpn_tables(&bsm->macaddr); } void bgp_mac_del_mac_entry(struct interface *ifp) @@ -308,7 +348,7 @@ void bgp_mac_del_mac_entry(struct interface *ifp) * Write code to allow old mac address to no-longer * win if we happen to have received it from a peer. */ - bgp_mac_remove_ifp_internal(bsm, ifp->name); + bgp_mac_remove_ifp_internal(bsm, ifp->name, &bsm->macaddr); } /* This API checks MAC address against any of local diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 6eddd0e1e3..355bc93320 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1488,7 +1488,8 @@ static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name) /* This API is used during router-id change, reflect VPNs * auto RD and RT values and readvertise routes to VPN table. */ -void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw) +void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw, + bool is_config) { afi_t afi; int debug; @@ -1536,6 +1537,20 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw) } } else { + /* + * Router-id changes that are not explicit config + * changes should not replace configured RD/RT. + */ + if (!is_config) { + if (CHECK_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_RD_SET)) { + if (debug) + zlog_debug("%s: auto router-id change skipped", + __func__); + goto postchange; + } + } + /* New router-id derive auto RD and RT and export * to VPN */ @@ -1565,6 +1580,8 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw) = ecommunity_dup(ecom); } + +postchange: /* Update routes to VPN */ vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 1526a8111e..2a6c0e1708 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -264,6 +264,7 @@ extern void vpn_policy_routemap_event(const char *rmap_name); extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey); extern void vpn_leak_postchange_all(void); -extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw); +extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw, + bool is_config); #endif /* _QUAGGA_BGP_MPLSVPN_H */ diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 7af5827d00..64529f6ef3 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -264,8 +264,9 @@ static int bgp_capability_mp(struct peer *peer, struct capability_header *hdr) bgp_capability_mp_data(s, &mpc); if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s OPEN has MP_EXT CAP for afi/safi: %u/%u", - peer->host, mpc.afi, mpc.safi); + zlog_debug("%s OPEN has MP_EXT CAP for afi/safi: %s/%s", + peer->host, iana_afi2str(mpc.afi), + iana_safi2str(mpc.safi)); /* Convert AFI, SAFI to internal values, check. */ if (bgp_map_afi_safi_iana2int(mpc.afi, mpc.safi, &afi, &safi)) @@ -325,8 +326,8 @@ static int bgp_capability_orf_entry(struct peer *peer, pkt_safi = mpc.safi; if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s ORF Cap entry for afi/safi: %u/%u", peer->host, - mpc.afi, mpc.safi); + zlog_debug("%s ORF Cap entry for afi/safi: %s/%s", peer->host, + iana_afi2str(mpc.afi), iana_safi2str(mpc.safi)); /* Convert AFI, SAFI to internal values, check. */ if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) { @@ -407,11 +408,11 @@ static int bgp_capability_orf_entry(struct peer *peer, if (bgp_debug_neighbor_events(peer)) zlog_debug( "%s OPEN has %s ORF capability" - " as %s for afi/safi: %d/%d", + " as %s for afi/safi: %s/%s", peer->host, lookup_msg(orf_type_str, type, NULL), - lookup_msg(orf_mode_str, mode, NULL), pkt_afi, - pkt_safi); + lookup_msg(orf_mode_str, mode, NULL), + iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); if (hdr->code == CAPABILITY_CODE_ORF) { sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV; @@ -487,15 +488,17 @@ static int bgp_capability_restart(struct peer *peer, if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Addr-family %d/%d(afi/safi) not supported." + "%s Addr-family %s/%s(afi/safi) not supported." " Ignore the Graceful Restart capability for this AFI/SAFI", - peer->host, pkt_afi, pkt_safi); + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); } else if (!peer->afc[afi][safi]) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Addr-family %d/%d(afi/safi) not enabled." + "%s Addr-family %s/%s(afi/safi) not enabled." " Ignore the Graceful Restart capability", - peer->host, pkt_afi, pkt_safi); + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); } else { if (bgp_debug_neighbor_events(peer)) zlog_debug( @@ -564,8 +567,9 @@ static int bgp_capability_addpath(struct peer *peer, if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s", - peer->host, pkt_afi, pkt_safi, + "%s OPEN has AddPath CAP for afi/safi: %s/%s%s%s", + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi), (send_receive & BGP_ADDPATH_RX) ? ", receive" : "", (send_receive & BGP_ADDPATH_TX) ? ", transmit" @@ -575,16 +579,18 @@ static int bgp_capability_addpath(struct peer *peer, if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Addr-family %d/%d(afi/safi) not supported." + "%s Addr-family %s/%s(afi/safi) not supported." " Ignore the Addpath Attribute for this AFI/SAFI", - peer->host, pkt_afi, pkt_safi); + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); continue; } else if (!peer->afc[afi][safi]) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Addr-family %d/%d(afi/safi) not enabled." + "%s Addr-family %s/%s(afi/safi) not enabled." " Ignore the AddPath capability for this AFI/SAFI", - peer->host, pkt_afi, pkt_safi); + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); continue; } @@ -624,16 +630,18 @@ static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Received with afi/safi/next-hop afi: %u/%u/%u", - peer->host, pkt_afi, pkt_safi, pkt_nh_afi); + "%s Received with afi/safi/next-hop afi: %s/%s/%u", + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi), pkt_nh_afi); /* Convert AFI, SAFI to internal values, check. */ if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Addr-family %d/%d(afi/safi) not supported." + "%s Addr-family %s/%s(afi/safi) not supported." " Ignore the ENHE Attribute for this AFI/SAFI", - peer->host, pkt_afi, pkt_safi); + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); continue; } @@ -652,9 +660,10 @@ static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr) || safi == SAFI_LABELED_UNICAST)) { flog_warn( EC_BGP_CAPABILITY_INVALID_DATA, - "%s Unexpected afi/safi/next-hop afi: %u/%u/%u " + "%s Unexpected afi/safi/next-hop afi: %s/%s/%u " "in Extended Next-hop capability, ignoring", - peer->host, pkt_afi, pkt_safi, pkt_nh_afi); + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi), pkt_nh_afi); continue; } diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 655a4745cb..5654fe5329 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -822,12 +822,13 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, stream_putc(s, ORF_COMMON_PART_REMOVE_ALL); if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d", + "%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s", peer->host, orf_type, (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"), - pkt_afi, pkt_safi); + iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); } else { SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND); @@ -838,12 +839,13 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, ORF_COMMON_PART_DENY); if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d", + "%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s", peer->host, orf_type, (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"), - pkt_afi, pkt_safi); + iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); } /* Total ORF Entry Len. */ @@ -856,8 +858,9 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, if (bgp_debug_neighbor_events(peer)) { if (!orf_refresh) - zlog_debug("%s sending REFRESH_REQ for afi/safi: %d/%d", - peer->host, pkt_afi, pkt_safi); + zlog_debug("%s sending REFRESH_REQ for afi/safi: %s/%s", + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); } /* Add packet to the peer. */ @@ -901,11 +904,11 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d", + "%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s", peer->host, action == CAPABILITY_ACTION_SET ? "Advertising" : "Removing", - pkt_afi, pkt_safi); + iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } /* Set packet size. */ @@ -1045,7 +1048,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) uint16_t holdtime; uint16_t send_holdtime; as_t remote_as; - as_t as4 = 0; + as_t as4 = 0, as4_be; struct in_addr remote_id; int mp_capability; uint8_t notify_data_remote_as[2]; @@ -1088,9 +1091,11 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) * that we do not know which peer is connecting to us now. */ as4 = peek_for_as4_capability(peer, optlen); - memcpy(notify_data_remote_as4, &as4, 4); } + as4_be = htonl(as4); + memcpy(notify_data_remote_as4, &as4_be, 4); + /* Just in case we have a silly peer who sends AS4 capability set to 0 */ if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) && !as4) { @@ -1788,14 +1793,16 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) pkt_safi = stream_getc(s); if (bgp_debug_update(peer, NULL, NULL, 0)) - zlog_debug("%s rcvd REFRESH_REQ for afi/safi: %d/%d", - peer->host, pkt_afi, pkt_safi); + zlog_debug("%s rcvd REFRESH_REQ for afi/safi: %s/%s", + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); /* Convert AFI, SAFI to internal values and check. */ if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) { zlog_info( - "%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored", - peer->host, pkt_afi, pkt_safi); + "%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored", + peer->host, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); return BGP_PACKET_NOOP; } @@ -2090,8 +2097,10 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, if (bgp_debug_neighbor_events(peer)) zlog_debug( "%s Dynamic Capability MP_EXT afi/safi invalid " - "(%u/%u)", - peer->host, pkt_afi, pkt_safi); + "(%s/%s)", + peer->host, + iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); continue; } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index db3bb2f63c..b90097a4f2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -22,6 +22,7 @@ #include <zebra.h> #include <math.h> +#include "printfrr.h" #include "prefix.h" #include "linklist.h" #include "memory.h" @@ -5787,6 +5788,13 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p, unsigned long match = 0; uint8_t atomic_aggregate = 0; + /* If the bgp instance is being deleted or self peer is deleted + * then do not create aggregate route + */ + if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS) || + (bgp->peer_self == NULL)) + return; + /* ORIGIN attribute: If at least one route among routes that are aggregated has ORIGIN with the value INCOMPLETE, then the aggregated route must have the ORIGIN attribute with the value @@ -6524,28 +6532,38 @@ DEFUN (no_aggregate_address_mask, DEFUN (ipv6_aggregate_address, ipv6_aggregate_address_cmd, - "aggregate-address X:X::X:X/M [summary-only]", + "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>]", "Configure BGP aggregate entries\n" "Aggregate prefix\n" - "Filter more specific routes from updates\n") + "Generate AS set path information\n" + "Filter more specific routes from updates\n" + "Filter more specific routes from updates\n" + "Generate AS set path information\n") { int idx = 0; argv_find(argv, argc, "X:X::X:X/M", &idx); char *prefix = argv[idx]->arg; + int as_set = + argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0; + + idx = 0; int sum_only = argv_find(argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0; return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only, - 0); + as_set); } DEFUN (no_ipv6_aggregate_address, no_ipv6_aggregate_address_cmd, - "no aggregate-address X:X::X:X/M [summary-only]", + "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>]", NO_STR "Configure BGP aggregate entries\n" "Aggregate prefix\n" - "Filter more specific routes from updates\n") + "Generate AS set path information\n" + "Filter more specific routes from updates\n" + "Filter more specific routes from updates\n" + "Generate AS set path information\n") { int idx = 0; argv_find(argv, argc, "X:X::X:X/M", &idx); @@ -7569,8 +7587,6 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p, && BGP_ATTR_NEXTHOP_AFI_IP6(attr)) || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { char buf_a[512]; - char buf_b[512]; - char buf_c[BUFSIZ]; if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) { if (json) @@ -7588,27 +7604,15 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p, buf_a, sizeof(buf_a))); } else if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { - if (json) { - inet_ntop(AF_INET6, - &attr->mp_nexthop_global, - buf_a, sizeof(buf_a)); - inet_ntop(AF_INET6, - &attr->mp_nexthop_local, - buf_b, sizeof(buf_b)); - sprintf(buf_c, "%s(%s)", buf_a, buf_b); + snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)", + &attr->mp_nexthop_global, + &attr->mp_nexthop_local); + if (json) json_object_string_add( json_out, - "mpNexthopGlobalLocal", buf_c); - } else - vty_out(vty, "%s(%s)", - inet_ntop( - AF_INET6, - &attr->mp_nexthop_global, - buf_a, sizeof(buf_a)), - inet_ntop( - AF_INET6, - &attr->mp_nexthop_local, - buf_b, sizeof(buf_b))); + "mpNexthopGlobalLocal", buf_a); + else + vty_out(vty, "%s", buf_a); } } } @@ -9163,6 +9167,15 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, lcom)) continue; } + + if (type == bgp_show_type_lcommunity_exact) { + struct lcommunity *lcom = output_arg; + + if (!pi->attr->lcommunity + || !lcommunity_cmp(pi->attr->lcommunity, + lcom)) + continue; + } if (type == bgp_show_type_lcommunity_list) { struct community_list *list = output_arg; @@ -9170,6 +9183,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, list)) continue; } + if (type + == bgp_show_type_lcommunity_list_exact) { + struct community_list *list = output_arg; + + if (!lcommunity_list_exact_match( + pi->attr->lcommunity, list)) + continue; + } if (type == bgp_show_type_lcommunity_all) { if (!pi->attr->lcommunity) continue; @@ -9793,8 +9814,8 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str, } static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, - struct cmd_token **argv, afi_t afi, safi_t safi, - bool uj) + struct cmd_token **argv, bool exact, afi_t afi, + safi_t safi, bool uj) { struct lcommunity *lcom; struct buffer *b; @@ -9825,13 +9846,15 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, return CMD_WARNING; } - return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom, - uj); + return bgp_show(vty, bgp, afi, safi, + (exact ? bgp_show_type_lcommunity_exact + : bgp_show_type_lcommunity), + lcom, uj); } static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp, - const char *lcom, afi_t afi, safi_t safi, - bool uj) + const char *lcom, bool exact, afi_t afi, + safi_t safi, bool uj) { struct community_list *list; @@ -9843,13 +9866,15 @@ static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp, return CMD_WARNING; } - return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_list, + return bgp_show(vty, bgp, afi, safi, + (exact ? bgp_show_type_lcommunity_list_exact + : bgp_show_type_lcommunity_list), list, uj); } DEFUN (show_ip_bgp_large_community_list, show_ip_bgp_large_community_list_cmd, - "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [exact-match] [json]", SHOW_STR IP_STR BGP_STR @@ -9859,12 +9884,14 @@ DEFUN (show_ip_bgp_large_community_list, "Display routes matching the large-community-list\n" "large-community-list number\n" "large-community-list name\n" + "Exact match of the large-communities\n" JSON_STR) { char *vrf = NULL; afi_t afi = AFI_IP6; safi_t safi = SAFI_UNICAST; int idx = 0; + bool exact_match = 0; if (argv_find(argv, argc, "ip", &idx)) afi = AFI_IP; @@ -9888,12 +9915,18 @@ DEFUN (show_ip_bgp_large_community_list, } argv_find(argv, argc, "large-community-list", &idx); - return bgp_show_lcommunity_list(vty, bgp, argv[idx + 1]->arg, afi, safi, - uj); + + const char *clist_number_or_name = argv[++idx]->arg; + + if (++idx < argc && strmatch(argv[idx]->text, "exact-match")) + exact_match = 1; + + return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name, + exact_match, afi, safi, uj); } DEFUN (show_ip_bgp_large_community, show_ip_bgp_large_community_cmd, - "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [AA:BB:CC] [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]", SHOW_STR IP_STR BGP_STR @@ -9902,12 +9935,14 @@ DEFUN (show_ip_bgp_large_community, BGP_SAFI_WITH_LABEL_HELP_STR "Display routes matching the large-communities\n" "List of large-community numbers\n" + "Exact match of the large-communities\n" JSON_STR) { char *vrf = NULL; afi_t afi = AFI_IP6; safi_t safi = SAFI_UNICAST; int idx = 0; + bool exact_match = 0; if (argv_find(argv, argc, "ip", &idx)) afi = AFI_IP; @@ -9930,9 +9965,12 @@ DEFUN (show_ip_bgp_large_community, return CMD_WARNING; } - if (argv_find(argv, argc, "AA:BB:CC", &idx)) - return bgp_show_lcommunity(vty, bgp, argc, argv, afi, safi, uj); - else + if (argv_find(argv, argc, "AA:BB:CC", &idx)) { + if (argv_find(argv, argc, "exact-match", &idx)) + exact_match = 1; + return bgp_show_lcommunity(vty, bgp, argc, argv, + exact_match, afi, safi, uj); + } else return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_all, NULL, uj); } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index f715084450..0f2363dc6f 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -45,7 +45,9 @@ enum bgp_show_type { bgp_show_type_community_list_exact, bgp_show_type_lcommunity_all, bgp_show_type_lcommunity, + bgp_show_type_lcommunity_exact, bgp_show_type_lcommunity_list, + bgp_show_type_lcommunity_list_exact, bgp_show_type_flap_statistics, bgp_show_type_flap_neighbor, bgp_show_type_dampend_paths, diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 28a763ed5e..a212523b19 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1173,8 +1173,17 @@ static route_map_result_t route_match_lcommunity(void *rule, if (!list) return RMAP_NOMATCH; - if (lcommunity_list_match(path->attr->lcommunity, list)) - return RMAP_MATCH; + if (rcom->exact) { + if (lcommunity_list_exact_match( + path->attr->lcommunity, + list)) + return RMAP_MATCH; + } else { + if (lcommunity_list_match( + path->attr->lcommunity, + list)) + return RMAP_MATCH; + } } return RMAP_NOMATCH; } @@ -1193,6 +1202,7 @@ static void *route_match_lcommunity_compile(const char *arg) len = p - arg; rcom->name = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1); memcpy(rcom->name, arg, len); + rcom->exact = 1; } else { rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); rcom->exact = 0; @@ -3796,26 +3806,45 @@ DEFUN (no_match_community, DEFUN (match_lcommunity, match_lcommunity_cmd, - "match large-community <(1-99)|(100-500)|WORD>", + "match large-community <(1-99)|(100-500)|WORD> [exact-match]", MATCH_STR "Match BGP large community list\n" "Large Community-list number (standard)\n" "Large Community-list number (expanded)\n" - "Large Community-list name\n") + "Large Community-list name\n" + "Do exact matching of communities\n") { - return bgp_route_match_add(vty, "large-community", argv[2]->arg, + int idx_lcomm_list = 2; + int ret; + char *argstr; + + if (argc == 4) { + argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, + strlen(argv[idx_lcomm_list]->arg) + + strlen("exact-match") + 2); + + sprintf(argstr, "%s exact-match", argv[idx_lcomm_list]->arg); + } else + argstr = argv[idx_lcomm_list]->arg; + + ret = bgp_route_match_add(vty, "large-community", argstr, RMAP_EVENT_LLIST_ADDED); + if (argstr != argv[idx_lcomm_list]->arg) + XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr); + + return ret; } DEFUN (no_match_lcommunity, no_match_lcommunity_cmd, - "no match large-community [<(1-99)|(100-500)|WORD>]", + "no match large-community [<(1-99)|(100-500)|WORD> [exact-match]]", NO_STR MATCH_STR "Match BGP large community list\n" "Large Community-list number (standard)\n" "Large Community-list number (expanded)\n" - "Large Community-list name\n") + "Large Community-list name\n" + "Do exact matching of communities\n") { return bgp_route_match_delete(vty, "large-community", NULL, RMAP_EVENT_LLIST_DELETED); diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index d0be2471af..82df1905ba 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -885,6 +885,9 @@ static void update_subgroup_add_peer(struct update_subgroup *subgrp, bpacket_add_peer(pkt, paf); bpacket_queue_sanity_check(SUBGRP_PKTQ(subgrp)); + if (BGP_DEBUG(update_groups, UPDATE_GROUPS)) + zlog_debug("peer %s added to subgroup s%" PRIu64, + paf->peer->host, subgrp->id); } /* @@ -910,6 +913,10 @@ static void update_subgroup_remove_peer_internal(struct update_subgroup *subgrp, paf->subgroup = NULL; subgrp->peer_count--; + if (BGP_DEBUG(update_groups, UPDATE_GROUPS)) + zlog_debug("peer %s deleted from subgroup s%" + PRIu64 "peer cnt %d", + paf->peer->host, subgrp->id, subgrp->peer_count); SUBGRP_INCR_STAT(subgrp, prune_events); } @@ -1826,9 +1833,9 @@ void peer_af_announce_route(struct peer_af *paf, int combine) */ if (!combine || !all_pending) { update_subgroup_split_peer(paf, NULL); - if (!paf->subgroup) - return; + subgrp = paf->subgroup; + assert(subgrp && subgrp->update_group); if (bgp_debug_update(paf->peer, NULL, subgrp->update_group, 0)) zlog_debug("u%" PRIu64 ":s%" PRIu64 " %s announcing routes", diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 43d0d93520..22e9469a73 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -979,10 +979,6 @@ DEFUN_NOSH (router_bgp, ret = bgp_get(&bgp, &as, name, inst_type); switch (ret) { - case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET: - vty_out(vty, - "Please specify 'bgp multiple-instance' first\n"); - return CMD_WARNING_CONFIG_FAILED; case BGP_ERR_AS_MISMATCH: vty_out(vty, "BGP is already running; AS is %u\n", as); return CMD_WARNING_CONFIG_FAILED; @@ -2577,7 +2573,7 @@ static struct peer_group *listen_range_exists(struct bgp *bgp, DEFUN (bgp_listen_range, bgp_listen_range_cmd, - "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group WORD", + "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME", "BGP specific commands\n" "Configure BGP dynamic neighbors listen range\n" "Configure BGP dynamic neighbors listen range\n" @@ -2595,7 +2591,7 @@ DEFUN (bgp_listen_range, argv_find(argv, argc, "A.B.C.D/M", &idx); argv_find(argv, argc, "X:X::X:X/M", &idx); char *prefix = argv[idx]->arg; - argv_find(argv, argc, "WORD", &idx); + argv_find(argv, argc, "PGNAME", &idx); char *peergroup = argv[idx]->arg; /* Convert IP prefix string to struct prefix. */ @@ -2647,7 +2643,7 @@ DEFUN (bgp_listen_range, DEFUN (no_bgp_listen_range, no_bgp_listen_range_cmd, - "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group WORD", + "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME", NO_STR "BGP specific commands\n" "Unconfigure BGP dynamic neighbors listen range\n" @@ -2947,7 +2943,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if, DEFUN (neighbor_interface_config, neighbor_interface_config_cmd, - "neighbor WORD interface [peer-group WORD]", + "neighbor WORD interface [peer-group PGNAME]", NEIGHBOR_STR "Interface name or neighbor tag\n" "Enable BGP on interface\n" @@ -2968,7 +2964,7 @@ DEFUN (neighbor_interface_config, DEFUN (neighbor_interface_config_v6only, neighbor_interface_config_v6only_cmd, - "neighbor WORD interface v6only [peer-group WORD]", + "neighbor WORD interface v6only [peer-group PGNAME]", NEIGHBOR_STR "Interface name or neighbor tag\n" "Enable BGP on interface\n" @@ -3113,7 +3109,7 @@ DEFUN (no_neighbor, DEFUN (no_neighbor_interface_config, no_neighbor_interface_config_cmd, - "no neighbor WORD interface [v6only] [peer-group WORD] [remote-as <(1-4294967295)|internal|external>]", + "no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external>]", NO_STR NEIGHBOR_STR "Interface name\n" @@ -3428,7 +3424,7 @@ ALIAS_HIDDEN(no_neighbor_activate, no_neighbor_activate_hidden_cmd, DEFUN (neighbor_set_peer_group, neighbor_set_peer_group_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD", + "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Member of the peer-group\n" @@ -3486,14 +3482,14 @@ DEFUN (neighbor_set_peer_group, } ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD", + "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Member of the peer-group\n" "Peer-group name\n") DEFUN (no_neighbor_set_peer_group, no_neighbor_set_peer_group_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD", + "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 @@ -3523,7 +3519,7 @@ DEFUN (no_neighbor_set_peer_group, } ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD", + "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Member of the peer-group\n" "Peer-group name\n") @@ -7216,7 +7212,7 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name, /* one clear bgp command to rule them all */ DEFUN (clear_ip_bgp_all, clear_ip_bgp_all_cmd, - "clear [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|l2vpn> [<unicast|multicast|vpn|labeled-unicast|flowspec|evpn>]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<soft [<in|out>]|in [prefix-filter]|out>]", + "clear [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|l2vpn> [<unicast|multicast|vpn|labeled-unicast|flowspec|evpn>]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group PGNAME> [<soft [<in|out>]|in [prefix-filter]|out>]", CLEAR_STR IP_STR BGP_STR @@ -7269,7 +7265,7 @@ DEFUN (clear_ip_bgp_all, if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) argv_find_and_parse_safi(argv, argc, &idx, &safi); - /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> */ + /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group PGNAME> */ if (argv_find(argv, argc, "*", &idx)) { clr_sort = clear_all; } else if (argv_find(argv, argc, "A.B.C.D", &idx)) { @@ -7282,7 +7278,7 @@ DEFUN (clear_ip_bgp_all, clr_sort = clear_group; idx++; clr_arg = argv[idx]->arg; - } else if (argv_find(argv, argc, "WORD", &idx)) { + } else if (argv_find(argv, argc, "PGNAME", &idx)) { clr_sort = clear_peer; clr_arg = argv[idx]->arg; } else if (argv_find(argv, argc, "(1-4294967295)", &idx)) { @@ -7463,11 +7459,14 @@ DEFUN (show_bgp_vrfs, continue; count++; - if (!uj && count == 1) + if (!uj && count == 1) { vty_out(vty, - "%4s %-5s %-16s %9s %10s %-37s %-10s %-15s\n", + "%4s %-5s %-16s %9s %10s %-37s\n", "Type", "Id", "routerId", "#PeersVfg", - "#PeersEstb", "Name", "L3-VNI", "Rmac"); + "#PeersEstb", "Name"); + vty_out(vty, "%11s %-16s %-21s %-6s\n", " ", + "L3-VNI", "RouterMAC", "Interface"); + } peers_cfg = peers_estb = 0; if (uj) @@ -7508,16 +7507,24 @@ DEFUN (show_bgp_vrfs, json_object_string_add( json_vrf, "rmac", prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); + json_object_string_add(json_vrf, "interface", + ifindex2ifname(bgp->l3vni_svi_ifindex, + bgp->vrf_id)); json_object_object_add(json_vrfs, name, json_vrf); - } else + } else { vty_out(vty, - "%4s %-5d %-16s %9u %10u %-37s %-10u %-15s\n", + "%4s %-5d %-16s %-9u %-10u %-37s\n", type, bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id, inet_ntoa(bgp->router_id), peers_cfg, - peers_estb, name, bgp->l3vni, - prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); + peers_estb, name); + vty_out(vty,"%11s %-16u %-21s %-20s\n", " ", + bgp->l3vni, + prefix_mac2str(&bgp->rmac, buf, sizeof(buf)), + ifindex2ifname(bgp->l3vni_svi_ifindex, + bgp->vrf_id)); + } } if (uj) { @@ -7715,14 +7722,6 @@ DEFUN (show_bgp_memory, count * sizeof(struct peer_group))); /* Other */ - if ((count = mtype_stats_alloc(MTYPE_HASH))) - vty_out(vty, "%ld hash tables, using %s of memory\n", count, - mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(struct hash))); - if ((count = mtype_stats_alloc(MTYPE_HASH_BACKET))) - vty_out(vty, "%ld hash buckets, using %s of memory\n", count, - mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(struct hash_bucket))); if ((count = mtype_stats_alloc(MTYPE_BGP_REGEXP))) vty_out(vty, "%ld compiled regexes, using %s of memory\n", count, mtype_memstr(memstrbuf, sizeof(memstrbuf), diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 5e9fc57f59..c0f2dfca17 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -793,6 +793,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote, peer->bgp->vrf_id); } if (local->sa.sa_family == AF_INET6) { + memcpy(&nexthop->v6_global, &local->sin6.sin6_addr, IPV6_MAX_BYTELEN); if (IN6_IS_ADDR_LINKLOCAL(&local->sin6.sin6_addr)) { if (peer->conf_if || peer->ifname) ifp = if_lookup_by_name(peer->conf_if diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 02eda7a430..3ca209676f 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -234,8 +234,11 @@ static int bgp_config_check(struct bgp *bgp, int config) return CHECK_FLAG(bgp->config, config); } -/* Set BGP router identifier. */ -static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id) +/* Set BGP router identifier; distinguish between explicit config and other + * cases. + */ +static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id, + bool is_config) { struct peer *peer; struct listnode *node, *nnode; @@ -247,7 +250,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id) if (is_evpn_enabled()) bgp_evpn_handle_router_id_update(bgp, TRUE); - vpn_handle_router_id_update(bgp, TRUE); + vpn_handle_router_id_update(bgp, TRUE, is_config); IPV4_ADDR_COPY(&bgp->router_id, id); @@ -266,7 +269,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id) if (is_evpn_enabled()) bgp_evpn_handle_router_id_update(bgp, FALSE); - vpn_handle_router_id_update(bgp, FALSE); + vpn_handle_router_id_update(bgp, FALSE, is_config); return 0; } @@ -300,7 +303,7 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id) if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("RID change : vrf %u, RTR ID %s", bgp->vrf_id, inet_ntoa(*addr)); - bgp_router_id_set(bgp, addr); + bgp_router_id_set(bgp, addr, FALSE); } } } @@ -320,7 +323,7 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id) if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("RID change : vrf %u, RTR ID %s", bgp->vrf_id, inet_ntoa(*addr)); - bgp_router_id_set(bgp, addr); + bgp_router_id_set(bgp, addr, FALSE); } } @@ -331,7 +334,8 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id) int bgp_router_id_static_set(struct bgp *bgp, struct in_addr id) { bgp->router_id_static = id; - bgp_router_id_set(bgp, id.s_addr ? &id : &bgp->router_id_zebra); + bgp_router_id_set(bgp, id.s_addr ? &id : &bgp->router_id_zebra, + TRUE /* is config */); return 0; } @@ -3179,13 +3183,13 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, if (bgp->inst_type != inst_type) return BGP_ERR_INSTANCE_MISMATCH; *bgp_val = bgp; - return 0; + return BGP_SUCCESS; } bgp = bgp_create(as, name, inst_type); if (bgp_option_check(BGP_OPT_NO_ZEBRA) && name) bgp->vrf_id = vrf_generate_id(); - bgp_router_id_set(bgp, &bgp->router_id_zebra); + bgp_router_id_set(bgp, &bgp->router_id_zebra, TRUE); bgp_address_init(bgp); bgp_tip_hash_init(bgp); bgp_scan_init(bgp); @@ -3213,7 +3217,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, bgp_zebra_instance_register(bgp); } - return 0; + return BGP_SUCCESS; } /* @@ -3287,6 +3291,9 @@ int bgp_delete(struct bgp *bgp) THREAD_OFF(bgp->t_update_delay); THREAD_OFF(bgp->t_establish_wait); + /* Set flag indicating bgp instance delete in progress */ + bgp_flag_set(bgp, BGP_FLAG_DELETE_IN_PROGRESS); + if (BGP_DEBUG(zebra, ZEBRA)) { if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) zlog_debug("Deleting Default VRF"); @@ -6974,7 +6981,7 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, } /* For swpX peers we displayed the peer-group - * via 'neighbor swpX interface peer-group WORD' */ + * via 'neighbor swpX interface peer-group PGNAME' */ if (!if_pg_printed) vty_out(vty, " neighbor %s peer-group %s\n", addr, peer->group->name); diff --git a/bgpd/bgpd.conf.sample b/bgpd/bgpd.conf.sample index cb12a92522..1fb4f1600b 100644 --- a/bgpd/bgpd.conf.sample +++ b/bgpd/bgpd.conf.sample @@ -8,7 +8,6 @@ hostname bgpd password zebra !enable password please-set-at-here ! -!bgp multiple-instance ! router bgp 7675 ! bgp router-id 10.0.0.1 diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 518f1f6714..4bce73898f 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -28,6 +28,7 @@ #include "lib/json.h" #include "vrf.h" #include "vty.h" +#include "iana_afi.h" /* For union sockunion. */ #include "queue.h" @@ -361,6 +362,7 @@ struct bgp { #define BGP_FLAG_SHOW_HOSTNAME (1 << 19) #define BGP_FLAG_GR_PRESERVE_FWD (1 << 20) #define BGP_FLAG_GRACEFUL_SHUTDOWN (1 << 21) +#define BGP_FLAG_DELETE_IN_PROGRESS (1 << 22) /* BGP Per AF flags */ uint16_t af_flags[AFI_MAX][SAFI_MAX]; @@ -1451,12 +1453,10 @@ enum bgp_clear_type { #define BGP_ERR_INVALID_AS -3 #define BGP_ERR_INVALID_BGP -4 #define BGP_ERR_PEER_GROUP_MEMBER -5 -#define BGP_ERR_MULTIPLE_INSTANCE_USED -6 #define BGP_ERR_PEER_GROUP_NO_REMOTE_AS -7 #define BGP_ERR_PEER_GROUP_CANT_CHANGE -8 #define BGP_ERR_PEER_GROUP_MISMATCH -9 #define BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT -10 -#define BGP_ERR_MULTIPLE_INSTANCE_NOT_SET -11 #define BGP_ERR_AS_MISMATCH -12 #define BGP_ERR_PEER_FLAG_CONFLICT -13 #define BGP_ERR_PEER_GROUP_SHUTDOWN -14 diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 5525547454..e7905e5622 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -2929,7 +2929,7 @@ DEFUN (debug_rfapi_open, { struct rfapi_ip_addr vn; struct rfapi_ip_addr un; - uint32_t lifetime; + uint32_t lifetime = 0; int rc; rfapi_handle handle; diff --git a/configure.ac b/configure.ac index 77d5ee1555..9b57c2ec9b 100755 --- a/configure.ac +++ b/configure.ac @@ -25,9 +25,25 @@ dnl ----------------------------------- AC_CANONICAL_BUILD() AC_CANONICAL_HOST() -AS_IF([test "$host" != "$build"], [ +hosttools_clippy="false" +build_clippy="true" + +dnl case 1: external clippy +if test -n "$with_clippy" -a "$with_clippy" != "no" -a "$with_clippy" != "yes"; then + if test "$enable_clippy_only" == "yes"; then + AC_MSG_ERROR([--enable-clippy-only does not make sense with --with-clippy]) + fi + + CLIPPY="$with_clippy" + build_clippy="false" + if test ! -x "$with_clippy"; then + AC_MSG_ERROR([clippy tool ($with_clippy) is not executable]) + fi + +dnl case 2: cross-compiling internal clippy +elif test "$host" != "$build"; then if test "$srcdir" = "."; then - AC_MSG_ERROR([cross-compilation is only possible with builddir separate from srcdir. create a separate directory and run as .../path-to-frr/configure.]) + AC_MSG_ERROR([cross-compilation is only possible with builddir separate from srcdir or by building clippy separately and using the --with-clippy option. create a separate directory and run as .../path-to-frr/configure.]) fi test -d hosttools || mkdir hosttools abssrc="`cd \"${srcdir}\"; pwd`" @@ -37,23 +53,47 @@ AS_IF([test "$host" != "$build"], [ AC_MSG_NOTICE([... use HOST_CPPFLAGS / HOST_CFLAGS / HOST_LDFLAGS if neccessary]) AC_MSG_NOTICE([...]) - ( CPPFLAGS="$HOST_CPPFLAGS"; \ - CFLAGS="$HOST_CFLAGS"; \ - LDFLAGS="$HOST_LDFLAGS"; \ - cd hosttools; "${abssrc}/configure" "--host=$build" "--build=$build" "--enable-clippy-only" "--disable-nhrpd" "--disable-vtysh"; ) + ( + for var in $ac_precious_vars; do + dnl special cases + case "$var" in + YACC|YFLAGS) continue;; + PYTHON*) retain=true;; + *) retain=false; + esac + + eval "hostvar=\"\${HOST_$var}\"" + eval "targetvar=\"\${$var}\"" + if test -n "$hostvar"; then + eval "$var='$hostvar'" + _AS_ECHO_LOG([host $var='$hostvar']) + elif $retain; then + _AS_ECHO_LOG([host retain $var='$targetvar']) + else + eval "unset $var" + _AS_ECHO_LOG([host unset $var]) + fi + done + cd hosttools + "${abssrc}/configure" "--host=$build" "--build=$build" "--enable-clippy-only" "--disable-nhrpd" "--disable-vtysh" + ) || exit 1 AC_MSG_NOTICE([...]) AC_MSG_NOTICE([... cross-compilation: finished self-configuring for build platform tools]) AC_MSG_NOTICE([...]) build_clippy="false" - HOSTTOOLS="hosttools/" -], [ - build_clippy="true" - HOSTTOOLS="" -]) -AC_SUBST([HOSTTOOLS]) + hosttools_clippy="true" + CLIPPY="hosttools/lib/clippy" + +dnl case 3: normal build internal clippy +else + CLIPPY="lib/clippy\$(EXEEXT)" +fi +AC_SUBST([CLIPPY]) AM_CONDITIONAL([BUILD_CLIPPY], [$build_clippy]) +AM_CONDITIONAL([HOSTTOOLS_CLIPPY], [$hosttools_clippy]) +AM_CONDITIONAL([ONLY_CLIPPY], [test "$enable_clippy_only" = "yes"]) # Disable portability warnings -- our automake code (in particular # common.am) uses some constructs specific to gmake. @@ -138,12 +178,11 @@ CXXFLAGS="$orig_cxxflags" AC_PROG_CC_C99 dnl NB: see C11 below -AC_PROG_EGREP PKG_PROG_PKG_CONFIG -dnl autoconf 2.59 appears not to support AC_PROG_SED -dnl AC_PROG_SED -AC_CHECK_PROG([SED],[sed],[sed],[/bin/false]) +dnl it's 2019, sed is sed. +SED=sed +AC_SUBST([SED]) dnl try and enable CFLAGS that are useful for FRR dnl - specifically, options to control warnings @@ -237,9 +276,7 @@ else fi if test "z$orig_cflags" = "z"; then AC_C_FLAG([-g]) - AC_C_FLAG([-Os], [ - AC_C_FLAG([-O2]) - ]) + AC_C_FLAG([-O2]) fi fi AM_CONDITIONAL([DEV_BUILD], [test "x$enable_dev_build" = "xyes"]) @@ -330,7 +367,6 @@ dnl Check programs dnl -------------- AC_PROG_INSTALL AC_PROG_LN_S -AC_PROG_MAKE_SET AC_CHECK_TOOL([AR], [ar]) dnl ------- @@ -371,14 +407,19 @@ AC_SUBST([ARFLAGS]) AC_SUBST([AR_FLAGS]) AC_MSG_CHECKING([whether $RANLIB supports D option]) -if $RANLIB -D conftest.a >/dev/null 2>/dev/null; then - AC_MSG_RESULT([yes]) - RANLIB="$RANLIB -D" +if $RANLIB -D conftest.a >conftest.err 2>&1; then + if grep -q -- '-D' conftest.err; then + AC_MSG_RESULT([no]) + else + AC_MSG_RESULT([yes]) + RANLIB="$RANLIB -D" + fi else AC_MSG_RESULT([no]) fi AC_SUBST([RANLIB]) +test -f conftest.err && rm conftest.err test -f conftest.a && rm conftest.a dnl ---------------------- @@ -400,6 +441,8 @@ AC_ARG_WITH([pkg-extra-version], AC_ARG_WITH([pkg-git-version], AS_HELP_STRING([--with-pkg-git-version], [add git information to MOTD and build version string]), [ test "x$withval" != "xno" && with_pkg_git_version="yes" ]) +AC_ARG_WITH([clippy], + AS_HELP_STRING([--with-clippy=PATH], [use external clippy helper program])) AC_ARG_WITH([vtysh_pager], AS_HELP_STRING([--with-vtysh-pager=PAGER], [control what pager is compiled in as default]), VTYSH_PAGER=$withval, VTYSH_PAGER="more") @@ -605,8 +648,6 @@ if test "${enable_shell_access}" = "yes"; then AC_DEFINE([HAVE_SHELL_ACCESS], [1], [Allow user to use ssh/telnet/bash, be aware this is considered insecure]) fi -AM_CONDITIONAL([FPM], [test "x$enable_fpm" = "xyes"]) - # # Python for clippy # @@ -637,31 +678,6 @@ FRR_PYTHON_MOD_EXEC([sphinx], [--version], [ AC_SUBST([PYSPHINX]) # -# Logic for protobuf support. -# -if test "$enable_protobuf" = "yes"; then - # Check for protoc & protoc-c - - # protoc is not required, it's only for a "be nice" helper target - AC_CHECK_PROGS([PROTOC], [protoc], [/bin/false]) - - AC_CHECK_PROGS([PROTOC_C], [protoc-c], [/bin/false]) - if test "$PROTOC_C" = "/bin/false"; then - AC_MSG_FAILURE([protobuf requested but protoc-c not found. Install protobuf-c.]) - fi - - PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c >= 0.14],, [ - AC_MSG_FAILURE([protobuf requested but libprotobuf-c not found. Install protobuf-c.]) - ]) - AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [], [ - AC_MSG_FAILURE([protobuf requested but protobuf-c.h not found. Install protobuf-c.]) - ]) - - AC_DEFINE([HAVE_PROTOBUF], [1], [protobuf]) -fi -AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$enable_protobuf" = "xyes"]) - -# # Logic for old vpn commands support. # if test "$enable_oldvpn_commands" = "yes"; then @@ -785,25 +801,11 @@ 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 ------------------------------------ -AC_C_CONST -AC_C_INLINE -AC_C_VOLATILE -AC_HEADER_STDC -dnl AC_TYPE_PID_T -AC_TYPE_UID_T -AC_TYPE_MODE_T -AC_TYPE_SIZE_T -AC_STRUCT_TM - dnl ------------------------- dnl Check other header files. dnl ------------------------- AC_CHECK_HEADERS([stropts.h sys/ksym.h \ - linux/version.h asm/types.h \ - sys/cdefs.h]) + linux/version.h asm/types.h]) ac_stdatomic_ok=false AC_DEFINE([FRR_AUTOCONF_ATOMIC], [1], [did autoconf checks for atomic funcs]) @@ -990,7 +992,7 @@ FRR_INCLUDES AC_CHECK_HEADERS([netinet/in_var.h \ net/if_dl.h net/netopt.h \ inet/nd.h netinet/ip_icmp.h \ - sys/sysctl.h sys/sockio.h kvm.h sys/conf.h], + sys/sysctl.h sys/sockio.h sys/conf.h], [], [], [FRR_INCLUDES]) AC_CHECK_HEADERS([ucontext.h], [], [], @@ -1110,7 +1112,48 @@ if test "${enable_realms}" = "yes"; then ;; esac fi -AM_CONDITIONAL([SUPPORT_REALMS], [test "${enable_realms}" = "yes"]) + +dnl ------------------------------- +dnl Endian-ness check +dnl ------------------------------- +AC_WORDS_BIGENDIAN + +dnl --------------- +dnl other functions +dnl --------------- +AC_CHECK_FUNCS([ \ + strlcat strlcpy \ + getgrouplist]) + +dnl ########################################################################## +dnl LARGE if block spans a lot of "configure"! +if test "${enable_clippy_only}" != "yes"; then +dnl ########################################################################## + +# +# Logic for protobuf support. +# +if test "$enable_protobuf" = "yes"; then + # Check for protoc & protoc-c + + # protoc is not required, it's only for a "be nice" helper target + AC_CHECK_PROGS([PROTOC], [protoc], [/bin/false]) + + AC_CHECK_PROGS([PROTOC_C], [protoc-c], [/bin/false]) + if test "$PROTOC_C" = "/bin/false"; then + AC_MSG_FAILURE([protobuf requested but protoc-c not found. Install protobuf-c.]) + fi + + PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c >= 0.14],, [ + AC_MSG_FAILURE([protobuf requested but libprotobuf-c not found. Install protobuf-c.]) + ]) + AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [], [ + AC_MSG_FAILURE([protobuf requested but protobuf-c.h not found. Install protobuf-c.]) + ]) + + AC_DEFINE([HAVE_PROTOBUF], [1], [protobuf]) +fi + dnl --------------------- dnl Integrated VTY option @@ -1159,7 +1202,6 @@ case "${enable_vtysh}" in ;; esac AC_SUBST([LIBREADLINE]) -AM_CONDITIONAL([VTYSH], test "x$VTYSH" = "xvtysh") dnl ---------- dnl PAM module @@ -1222,42 +1264,16 @@ fi AC_SUBST([LIBPAM]) dnl ------------------------------- -dnl Endian-ness check -dnl ------------------------------- -AC_WORDS_BIGENDIAN - -dnl ------------------------------- -dnl check the size in byte of the C -dnl ------------------------------- -dnl AC_CHECK_SIZEOF(char) -dnl AC_CHECK_SIZEOF(int) -dnl AC_CHECK_SIZEOF(short) -dnl AC_CHECK_SIZEOF(long) - -dnl ---------------------------- -dnl check existance of functions -dnl ---------------------------- -AC_FUNC_FNMATCH -AC_FUNC_FORK -AC_FUNC_MKTIME -AC_FUNC_STAT - -dnl ------------------------------- dnl bgpd needs pow() and hence libm dnl ------------------------------- TMPLIBS="$LIBS" -AC_CHECK_HEADER([math.h], - [AC_CHECK_LIB([m], [pow], - [LIBM="-lm" - LIBS="$LIBS $LIBM" - AC_CHECK_FUNCS(pow,[],[LIBM=""]) - ]) -]) -if test x"$LIBM" = x ; then +LIBS="" +AC_SEARCH_LIBS([pow], [m], [ + LIBM="$LIBS" +], [ AC_MSG_WARN([Unable to find working pow function - bgpd may not link]) -fi +]) LIBS="$TMPLIBS" - AC_SUBST([LIBM]) AC_CHECK_FUNCS([ppoll], [ @@ -1267,13 +1283,6 @@ AC_CHECK_FUNCS([pollts], [ AC_DEFINE([HAVE_POLLTS], [1], [have NetBSD pollts()]) ]) -dnl --------------- -dnl other functions -dnl --------------- -AC_CHECK_FUNCS([ \ - strlcat strlcpy \ - getgrouplist]) - AC_CHECK_HEADER([asm-generic/unistd.h], [AC_CHECK_DECL(__NR_setns, AC_DEFINE([HAVE_NETNS], [1], [Have netns]),, @@ -1418,6 +1427,28 @@ if test $ac_cv_have_decl_TCP_MD5SIG = no; then AC_CHECK_DECLS([TCP_MD5SIG], [], [], MD5_INCLUDES)]) fi +AC_SUBST([SOLARIS]) +AC_CHECK_LIB([crypt], [crypt], [], + [AC_CHECK_LIB([crypto], [DES_crypt])]) +AC_CHECK_LIB([resolv], [res_init]) + +dnl --------------------------- +dnl check system has PCRE regexp +dnl --------------------------- +if test "x$enable_pcreposix" = "xyes"; then + AC_CHECK_LIB([pcreposix], [regexec], [], [ + AC_MSG_ERROR([--enable-pcreposix given but unable to find libpcreposix]) + ]) +fi +AC_SUBST([HAVE_LIBPCREPOSIX]) + +dnl ########################################################################## +dnl test "${enable_clippy_only}" != "yes" +fi +dnl END OF LARGE if block +dnl ########################################################################## + + dnl ---------------------------------------------------------------------------- dnl figure out if domainname is available in the utsname struct (GNU extension). dnl ---------------------------------------------------------------------------- @@ -1450,18 +1481,6 @@ FRR_INCLUDES dnl -------------------- dnl Daemon disable check dnl -------------------- -AM_CONDITIONAL([ZEBRA], [test "${enable_zebra}" != "no"]) - -if test "${enable_bgpd}" = "no";then - BGPD="" -else - BGPD="bgpd" -fi -AM_CONDITIONAL([BGPD], [test "x$BGPD" = "xbgpd"]) - -AM_CONDITIONAL([RIPD], [test "${enable_ripd}" != "no"]) -AM_CONDITIONAL([OSPFD], [test "${enable_ospfd}" != "no"]) -AM_CONDITIONAL([LDPD], [test "${enable_ldpd}" != "no"]) AS_IF([test "${enable_ldpd}" != "no"], [ AC_DEFINE([HAVE_LDPD], [1], [ldpd]) @@ -1485,8 +1504,6 @@ else esac fi -AM_CONDITIONAL([BFDD], [test "x$BFDD" = "xbfdd"]) - if test "$ac_cv_lib_json_c_json_object_get" = no -a "x$BFDD" = "xbfdd"; then AC_MSG_ERROR(["you must use json-c library to use bfdd"]) fi @@ -1504,16 +1521,12 @@ case "$host_os" in fi ;; esac -AM_CONDITIONAL([NHRPD], [test "x$NHRPD" = "xnhrpd"]) - -AM_CONDITIONAL([EIGRPD], [test "${enable_eigrpd}" != "no"]) if test "${enable_watchfrr}" = "no";then WATCHFRR="" else WATCHFRR="watchfrr" fi -AM_CONDITIONAL([WATCHFRR], [test "x$WATCHFRR" = "xwatchfrr"]) OSPFCLIENT="" if test "${enable_ospfapi}" != "no";then @@ -1524,18 +1537,6 @@ if test "${enable_ospfapi}" != "no";then fi fi -AM_CONDITIONAL([OSPFCLIENT], [test "x$OSPFCLIENT" = "xospfclient"]) -AM_CONDITIONAL([RIPNGD], [test "${enable_ripngd}" != "no"]) -AM_CONDITIONAL([BABELD], [test "${enable_babeld}" != "no"]) -AM_CONDITIONAL([OSPF6D], [test "${enable_ospf6d}" != "no"]) -AM_CONDITIONAL([ISISD], [test "${enable_isisd}" != "no"]) -AM_CONDITIONAL([PIMD], [test "${enable_pimd}" != "no"]) -AM_CONDITIONAL([PBRD], [test "${enable_pbrd}" != "no"]) -AM_CONDITIONAL([SHARPD], [test "${enable_sharpd}" = "yes"]) -AM_CONDITIONAL([STATICD], [test "${enable_staticd}" != "no"]) -AM_CONDITIONAL([FABRICD], [test "${enable_fabricd}" != "no"]) -AM_CONDITIONAL([VRRPD], [test "${enable_vrrpd}" != "no"]) - if test "${enable_bgp_announce}" = "no";then AC_DEFINE([DISABLE_BGP_ANNOUNCE], [1], [Disable BGP installation to zebra]) else @@ -1545,22 +1546,11 @@ fi if test "${enable_bgp_vnc}" != "no";then AC_DEFINE([ENABLE_BGP_VNC], [1], [Enable BGP VNC support]) fi -AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno]) -AC_SUBST([SOLARIS]) -AC_CHECK_LIB([crypt], [crypt], [], - [AC_CHECK_LIB([crypto], [DES_crypt])]) -AC_CHECK_LIB([resolv], [res_init]) - -dnl --------------------------- -dnl check system has PCRE regexp -dnl --------------------------- -if test "x$enable_pcreposix" = "xyes"; then - AC_CHECK_LIB([pcreposix], [regexec], [], [ - AC_MSG_ERROR([--enable-pcreposix given but unable to find libpcreposix]) - ]) -fi -AC_SUBST([HAVE_LIBPCREPOSIX]) +dnl ########################################################################## +dnl LARGE if block +if test "${enable_clippy_only}" != "yes"; then +dnl ########################################################################## dnl ------------------ dnl check C-Ares library @@ -1612,7 +1602,6 @@ int main(void); AH_TEMPLATE([SNMP_AGENTX], [Use SNMP AgentX to interface with snmpd]) AC_DEFINE_UNQUOTED(AS_TR_CPP(SNMP_${SNMP_METHOD}),,[SNMP method to interface with snmpd]) fi -AM_CONDITIONAL([SNMP], [test "x${SNMP_METHOD}" != "x"]) AC_SUBST([SNMP_LIBS]) AC_SUBST([SNMP_CFLAGS]) @@ -1645,7 +1634,6 @@ if test "$enable_config_rollbacks" = "yes"; then AC_MSG_ERROR([--enable-config-rollbacks given but sqlite3 was not found on your system.]) ]) fi -AM_CONDITIONAL([SQLITE3], [$SQLITE3]) dnl --------------- dnl confd @@ -1661,7 +1649,6 @@ if test "$enable_confd" != "" -a "$enable_confd" != "no"; then AC_SUBST([CONFD_LIBS]) AC_DEFINE([HAVE_CONFD], [1], [Enable confd integration]) fi -AM_CONDITIONAL([CONFD], [test "x$enable_confd" != "x"]) dnl --------------- dnl sysrepo @@ -1674,7 +1661,6 @@ if test "$enable_sysrepo" = "yes"; then AC_MSG_ERROR([sysrepo was not found on your system.])] ) fi -AM_CONDITIONAL([SYSREPO], [test "x$enable_sysrepo" = "xyes"]) dnl --------------- dnl gRPC @@ -1693,12 +1679,42 @@ if test "$enable_grpc" = "yes"; then AC_MSG_ERROR([grpc/grpc++ were not found on your system.]) ]) fi -AM_CONDITIONAL([GRPC], [test "x$enable_grpc" = "xyes"]) -dnl --------------- -dnl math -dnl --------------- -AC_SEARCH_LIBS([sqrt], [m]) +dnl ------ +dnl ZeroMQ +dnl ------ +if test "x$enable_zeromq" != "xno"; then + PKG_CHECK_MODULES([ZEROMQ], [libzmq >= 4.0.0], [ + AC_DEFINE([HAVE_ZEROMQ], [1], [Enable ZeroMQ support]) + ZEROMQ=true + ], [ + if test "x$enable_zeromq" = "xyes"; then + AC_MSG_ERROR([configuration specifies --enable-zeromq but libzmq was not found]) + fi + ]) +fi + +dnl ------------------------------------ +dnl Enable RPKI and add librtr to libs +dnl ------------------------------------ +if test "${enable_rpki}" = "yes"; then + PKG_CHECK_MODULES([RTRLIB], [rtrlib >= 0.5.0], + [RPKI=true], + [RPKI=false + AC_MSG_ERROR([rtrlib was not found on your system or is too old.])] + ) +fi + +dnl ------------------------------------------ +dnl Check whether rtrlib was build with ssh support +dnl ------------------------------------------ +AC_MSG_CHECKING([whether the RTR Library is compiled with SSH]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]], + [[struct tr_ssh_config config;]])], + [AC_MSG_RESULT([yes]) + AC_DEFINE([FOUND_SSH], [1], [found_ssh])], + AC_MSG_RESULT([no]) +) dnl --------------- dnl dlopen & dlinfo @@ -1749,7 +1765,11 @@ if test "$frr_cv_rtld_di_linkmap" = yes; then AC_DEFINE([HAVE_DLINFO_LINKMAP], [1], [Have dlinfo RTLD_DI_LINKMAP]) fi -AM_CONDITIONAL([SNMP], [test "x$SNMP_METHOD" = "xagentx"]) +dnl ########################################################################## +dnl test "${enable_clippy_only}" != "yes" +fi +dnl END OF LARGE if block +dnl ########################################################################## dnl --------------------------- dnl sockaddr and netinet checks @@ -1759,7 +1779,7 @@ AC_CHECK_TYPES([ struct vifctl, struct mfcctl, struct sioc_sg_req, vifi_t, struct sioc_vif_req, struct igmpmsg, struct ifaliasreq, struct if6_aliasreq, struct in6_aliasreq, - struct nd_opt_adv_interval, struct rt_addrinfo, + struct nd_opt_adv_interval, struct nd_opt_homeagent_info, struct nd_opt_adv_interval, struct nd_opt_rdnss, struct nd_opt_dnssl], [], [], FRR_INCLUDES) @@ -1794,7 +1814,6 @@ no) ;; esac -AM_CONDITIONAL([IRDP], [$IRDP]) dnl ----------------------- dnl checking for IP_PKTINFO @@ -1901,7 +1920,7 @@ AC_MSG_CHECKING([version of bison]) frr_ac_bison_version="$(eval $YACC -V | grep bison | head -n 1)" frr_ac_bison_version="${frr_ac_bison_version##* }" frr_ac_bison_missing="false" -case "x${frr_ac_bison_version}" in +case "x${frr_ac_bison_version}x" in x2.7*) BISON_OPENBRACE='"' BISON_CLOSEBRACE='"' @@ -1918,11 +1937,17 @@ case "x${frr_ac_bison_version}" in AC_MSG_WARN([could not determine bison version. Please install GNU bison 2.7.x or newer.]) frr_ac_bison_missing="true" ;; - *) + x3.[012][^0-9]*) BISON_OPENBRACE='{' BISON_CLOSEBRACE='}' BISON_VERBOSE='-Dparse.error=verbose' - AC_MSG_RESULT([$frr_ac_bison_version - 3.0 or newer]) + AC_MSG_RESULT([$frr_ac_bison_version - 3.0 to 3.2]) + ;; + *) + BISON_OPENBRACE='{' + BISON_CLOSEBRACE='}' + BISON_VERBOSE='-Dparse.error=verbose -Wno-yacc' + AC_MSG_RESULT([$frr_ac_bison_version - 3.3 or newer]) ;; esac AC_SUBST([BISON_OPENBRACE]) @@ -2076,21 +2101,6 @@ size_t ac_x; ac_x = malloc_size(NULL); ]) ]) -dnl ------ -dnl ZeroMQ -dnl ------ -if test "x$enable_zeromq" != "xno"; then - PKG_CHECK_MODULES([ZEROMQ], [libzmq >= 4.0.0], [ - AC_DEFINE([HAVE_ZEROMQ], [1], [Enable ZeroMQ support]) - ZEROMQ=true - ], [ - if test "x$enable_zeromq" = "xyes"; then - AC_MSG_ERROR([configuration specifies --enable-zeromq but libzmq was not found]) - fi - ]) -fi -AM_CONDITIONAL([ZEROMQ], [test "x$ZEROMQ" = "xtrue"]) - dnl ---------- dnl configure date dnl ---------- @@ -2176,39 +2186,43 @@ AC_DEFINE_UNQUOTED([YANG_MODELS_PATH], ["$CFG_YANGMODELS"], [path to YANG data m AC_DEFINE_UNQUOTED([LIBYANG_PLUGINS_PATH], ["$CFG_LIBYANG_PLUGINS"], [path to libyang plugins]) AC_DEFINE_UNQUOTED([WATCHFRR_SH_PATH], ["${CFG_SBIN%/}/watchfrr.sh"], [path to watchfrr.sh]) -dnl ------------------------------------ -dnl Enable RPKI and add librtr to libs -dnl ------------------------------------ -if test "${enable_rpki}" = "yes"; then - PKG_CHECK_MODULES([RTRLIB], [rtrlib >= 0.5.0], - [RPKI=true], - [RPKI=false - AC_MSG_ERROR([rtrlib was not found on your system or is too old.])] - ) -fi +dnl various features +AM_CONDITIONAL([SUPPORT_REALMS], [test "${enable_realms}" = "yes"]) +AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno]) +dnl northbound +AM_CONDITIONAL([SQLITE3], [$SQLITE3]) +AM_CONDITIONAL([CONFD], [test "x$enable_confd" != "x"]) +AM_CONDITIONAL([SYSREPO], [test "x$enable_sysrepo" = "xyes"]) +AM_CONDITIONAL([GRPC], [test "x$enable_grpc" = "xyes"]) +AM_CONDITIONAL([ZEROMQ], [test "x$ZEROMQ" = "xtrue"]) +dnl plugins AM_CONDITIONAL([RPKI], [test "x$RPKI" = "xtrue"]) - -dnl ------------------------------------------ -dnl Check whether rtrlib was build with ssh support -dnl ------------------------------------------ -AC_MSG_CHECKING([whether the RTR Library is compiled with SSH]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]], - [[struct tr_ssh_config config;]])], - [AC_MSG_RESULT([yes]) - AC_DEFINE([FOUND_SSH], [1], [found_ssh])], - AC_MSG_RESULT([no]) -) - -dnl --------------------------- -dnl Check htonl works correctly -dnl --------------------------- -AC_MSG_CHECKING([for working htonl]) -AC_CACHE_VAL(ac_cv_htonl_works, - [AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES],[htonl (0);])], - [ac_cv_htonl_works=yes], [ac_cv_htonl_works=no]) - ] -) -AC_MSG_RESULT([$ac_cv_htonl_works]) +AM_CONDITIONAL([SNMP], [test "x$SNMP_METHOD" = "xagentx"]) +AM_CONDITIONAL([IRDP], [$IRDP]) +AM_CONDITIONAL([FPM], [test "x$enable_fpm" = "xyes"]) +AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$enable_protobuf" = "xyes"]) +dnl daemons +AM_CONDITIONAL([VTYSH], [test "x$VTYSH" = "xvtysh"]) +AM_CONDITIONAL([ZEBRA], [test "${enable_zebra}" != "no"]) +AM_CONDITIONAL([BGPD], [test "x${enable_bgpd}" != "no"]) +AM_CONDITIONAL([RIPD], [test "${enable_ripd}" != "no"]) +AM_CONDITIONAL([OSPFD], [test "${enable_ospfd}" != "no"]) +AM_CONDITIONAL([LDPD], [test "${enable_ldpd}" != "no"]) +AM_CONDITIONAL([BFDD], [test "x$BFDD" = "xbfdd"]) +AM_CONDITIONAL([NHRPD], [test "x$NHRPD" = "xnhrpd"]) +AM_CONDITIONAL([EIGRPD], [test "${enable_eigrpd}" != "no"]) +AM_CONDITIONAL([WATCHFRR], [test "x$WATCHFRR" = "xwatchfrr"]) +AM_CONDITIONAL([OSPFCLIENT], [test "x$OSPFCLIENT" = "xospfclient"]) +AM_CONDITIONAL([RIPNGD], [test "${enable_ripngd}" != "no"]) +AM_CONDITIONAL([BABELD], [test "${enable_babeld}" != "no"]) +AM_CONDITIONAL([OSPF6D], [test "${enable_ospf6d}" != "no"]) +AM_CONDITIONAL([ISISD], [test "${enable_isisd}" != "no"]) +AM_CONDITIONAL([PIMD], [test "${enable_pimd}" != "no"]) +AM_CONDITIONAL([PBRD], [test "${enable_pbrd}" != "no"]) +AM_CONDITIONAL([SHARPD], [test "${enable_sharpd}" = "yes"]) +AM_CONDITIONAL([STATICD], [test "${enable_staticd}" != "no"]) +AM_CONDITIONAL([FABRICD], [test "${enable_fabricd}" != "no"]) +AM_CONDITIONAL([VRRPD], [test "${enable_vrrpd}" != "no"]) AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile]) diff --git a/doc/developer/building-frr-for-fedora.rst b/doc/developer/building-frr-for-fedora.rst index d11da2d647..0bfd43e93c 100644 --- a/doc/developer/building-frr-for-fedora.rst +++ b/doc/developer/building-frr-for-fedora.rst @@ -14,7 +14,7 @@ Installing Dependencies sudo dnf install git autoconf automake libtool make \ readline-devel texinfo net-snmp-devel groff pkgconfig json-c-devel \ pam-devel python3-pytest bison flex c-ares-devel python3-devel \ - python3-sphinx perl-core patch + python3-sphinx perl-core patch systemd-devel .. include:: building-libyang.rst @@ -98,6 +98,18 @@ And load the kernel modules on the running system: sudo modprobe mpls-router mpls-iptunnel + +.. note:: + Fedora ships with the ``firewalld`` service enabled. You may run into some + issues with the iptables rules it installs by default. If you wish to just + stop the service and clear `ALL` rules do these commands: + + .. code-block:: console + + sudo systemctl disable firewalld.service + sudo systemctl stop firewalld.service + sudo iptables -F + Install service files ^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/developer/memtypes.rst b/doc/developer/memtypes.rst index 153131bab9..13f6b43bbf 100644 --- a/doc/developer/memtypes.rst +++ b/doc/developer/memtypes.rst @@ -42,6 +42,16 @@ Example: Definition ---------- +.. c:type:: struct memtype + + This is the (internal) type used for MTYPE definitions. The macros below + should be used to create these, but in some cases it is useful to pass a + ``struct memtype *`` pointer to some helper function. + + The ``MTYPE_name`` created by the macros is declared as an array, i.e. + a function taking a ``struct memtype *`` argument can be called with an + ``MTYPE_name`` argument (as opposed to ``&MTYPE_name``.) + .. c:macro:: DECLARE_MGROUP(name) This macro forward-declares a memory group and should be placed in a diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 768f22c873..f2b1328075 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -267,29 +267,6 @@ An example configuration with multiple autonomous systems might look like this: 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` @@ -688,6 +665,11 @@ Networks Route Aggregation ----------------- +.. _bgp-route-aggregation-ipv4: + +Route Aggregation-IPv4 Address Family +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. index:: aggregate-address A.B.C.D/M .. clicmd:: aggregate-address A.B.C.D/M @@ -707,6 +689,62 @@ Route Aggregation .. index:: no aggregate-address A.B.C.D/M .. clicmd:: no aggregate-address A.B.C.D/M + + This command removes an aggregate address. + + + This configuration example setup the aggregate-address under + ipv4 address-family. + + .. code-block:: frr + + router bgp 1 + address-family ipv4 unicast + aggregate-address 10.0.0.0/8 + aggregate-address 20.0.0.0/8 as-set + aggregate-address 40.0.0.0/8 summary-only + exit-address-family + + +.. _bgp-route-aggregation-ipv6: + +Route Aggregation-IPv6 Address Family +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: aggregate-address X:X::X:X/M +.. clicmd:: aggregate-address X:X::X:X/M + + This command specifies an aggregate address. + +.. index:: aggregate-address X:X::X:X/M as-set +.. clicmd:: aggregate-address X:X::X:X/M as-set + + This command specifies an aggregate address. Resulting routes include + AS set. + +.. index:: aggregate-address X:X::X:X/M summary-only +.. clicmd:: aggregate-address X:X::X:X/M summary-only + + This command specifies an aggregate address. Aggregated routes will + not be announce. + +.. index:: no aggregate-address X:X::X:X/M +.. clicmd:: no aggregate-address X:X::X:X/M + + This command removes an aggregate address. + + + This configuration example setup the aggregate-address under + ipv4 address-family. + + .. code-block:: frr + + router bgp 1 + address-family ipv6 unicast + aggregate-address 10::0/64 + aggregate-address 20::0/64 as-set + aggregate-address 40::0/64 summary-only + exit-address-family .. _bgp-redistribute-to-bgp: @@ -826,8 +864,8 @@ Defining Peers peers ASN is the same as mine as specified under the :clicmd:`router bgp ASN` command the connection will be denied. -.. index:: [no] bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group WORD -.. clicmd:: [no] bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group WORD +.. index:: [no] bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME +.. clicmd:: [no] bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME Accept connections from any peers in the specified prefix. Configuration from the specified peer-group is used to configure these peers. @@ -1050,8 +1088,8 @@ and will share updates. This command defines a new peer group. -.. index:: neighbor PEER peer-group WORD -.. clicmd:: neighbor PEER peer-group WORD +.. index:: neighbor PEER peer-group PGNAME +.. clicmd:: neighbor PEER peer-group PGNAME This command bind specific peer to peer group WORD. @@ -1736,13 +1774,15 @@ Two types of large community lists are supported, namely `standard` and Large Communities in Route Map """""""""""""""""""""""""""""" -.. index:: match large-community LINE -.. clicmd:: match large-community LINE +.. index:: match large-community LINE [exact-match] +.. clicmd:: match large-community LINE [exact-match] Where `line` can be a simple string to match, or a regular expression. It is very important to note that this match occurs on the entire large-community string as a whole, where each large-community is ordered - from lowest to highest. + from lowest to highest. When `exact-match` keyword is specified, match + happen only when BGP updates have completely same large communities value + specified in the large community list. .. index:: set large-community LARGE-COMMUNITY .. clicmd:: set large-community LARGE-COMMUNITY @@ -2235,8 +2275,49 @@ attribute. match the specified community list. When `exact-match` is specified, it displays only routes that have an exact match. +.. _bgp-display-routes-by-lcommunity: + +Displaying Routes by Large Community Attribute +---------------------------------------------- + +The following commands allow displaying routes based on their +large community attribute. + +.. index:: show [ip] bgp <ipv4|ipv6> large-community +.. clicmd:: show [ip] bgp <ipv4|ipv6> large-community + +.. index:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY +.. clicmd:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY + +.. index:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY exact-match +.. clicmd:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY exact-match + +.. index:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY json +.. clicmd:: show [ip] bgp <ipv4|ipv6> large-community LARGE-COMMUNITY json + + These commands display BGP routes which have the large community attribute. + attribute. When ``LARGE-COMMUNITY`` is specified, BGP routes that match that + large community are displayed. When `exact-match` is specified, it display + only routes that have an exact match. When `json` is specified, it display + routes in json format. + +.. index:: show [ip] bgp <ipv4|ipv6> large-community-list WORD +.. clicmd:: show [ip] bgp <ipv4|ipv6> large-community-list WORD + +.. index:: show [ip] bgp <ipv4|ipv6> large-community-list WORD exact-match +.. clicmd:: show [ip] bgp <ipv4|ipv6> large-community-list WORD exact-match + +.. index:: show [ip] bgp <ipv4|ipv6> large-community-list WORD json +.. clicmd:: show [ip] bgp <ipv4|ipv6> large-community-list WORD json + + These commands display BGP routes for the address family specified that + match the specified large community list. When `exact-match` is specified, + it displays only routes that have an exact match. When `json` is specified, + it display routes in json format. + .. _bgp-display-routes-by-as-path: + Displaying Routes by AS Path ---------------------------- @@ -2302,7 +2383,6 @@ different filter for a peer. .. code-block:: frr - bgp multiple-instance ! router bgp 1 view 1 neighbor 10.0.0.1 remote-as 2 diff --git a/doc/user/filter.rst b/doc/user/filter.rst index 9d7361443d..8c86d06087 100644 --- a/doc/user/filter.rst +++ b/doc/user/filter.rst @@ -165,14 +165,8 @@ Showing ip prefix-list Clear counter of ip prefix-list ------------------------------- -.. index:: clear ip prefix-list -.. clicmd:: clear ip prefix-list +.. index:: clear ip prefix-list [NAME [A.B.C.D/M]] +.. clicmd:: clear ip prefix-list [NAME [A.B.C.D/M]] Clears the counters of all IP prefix lists. Clear IP Prefix List can be used - with a specified name and prefix. - -.. index:: clear ip prefix-list NAME -.. clicmd:: clear ip prefix-list NAME - -.. index:: clear ip prefix-list NAME A.B.C.D/M -.. clicmd:: clear ip prefix-list NAME A.B.C.D/M + with a specified NAME or NAME and prefix. diff --git a/doc/user/installation.rst b/doc/user/installation.rst index 6438c11413..64949fc8ea 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -465,7 +465,8 @@ Additional kernel modules are also needed to support MPLS forwarding. mpls_router mpls_iptunnel - The following is an example to enable MPLS forwarding in the kernel: + The following is an example to enable MPLS forwarding in the + kernel, typically by editing :file:`/etc/sysctl.conf`: .. code-block:: shell diff --git a/doc/user/routeserver.rst b/doc/user/routeserver.rst index e677a3030d..474a68db25 100644 --- a/doc/user/routeserver.rst +++ b/doc/user/routeserver.rst @@ -369,8 +369,6 @@ the policies for client RA): hostname RS password ix ! - bgp multiple-instance - ! router bgp 65000 view RS no bgp default ipv4-unicast neighbor 2001:0DB8::A remote-as 65001 diff --git a/doc/user/setup.rst b/doc/user/setup.rst index 2cdd3a7c7f..6d61a970d2 100644 --- a/doc/user/setup.rst +++ b/doc/user/setup.rst @@ -134,6 +134,7 @@ add the following entries to :file:`/etc/services`. eigprd 2613/tcp # EIGRPd vty bfdd 2617/tcp # bfdd vty fabricd 2618/tcp # fabricd vty + vrrpd 2619/tcp # vrrpd vty If you use a FreeBSD newer than 2.2.8, the above entries are already added to @@ -142,7 +143,7 @@ number when starting the daemon, these entries may not be needed. You may need to make changes to the config files in |INSTALL_PREFIX_ETC|. -systemd +Systemd ------- Although not installed when installing from source, FRR provides a service file for use with ``systemd``. It is located in :file:`tools/frr.service` in the Git @@ -153,3 +154,70 @@ location. A good place is usually ``/etc/systemd/system/``. After issuing a ``systemctl daemon-reload``, you should be able to start the FRR service via ``systemctl start frr``. If this fails, or no daemons are started. check the ``journalctl`` logs for an indication of what went wrong. + +Operations +---------- + +This section covers a few common operational tasks and how to perform them. + +Restarting +^^^^^^^^^^ + +Restarting kills all running FRR daemons and starts them again. Any unsaved +configuration will be lost. + +.. code-block:: console + + service frr restart + +.. note:: + + Alternatively, you can invoke the init script directly:: + + /etc/init.d/frr restart + + Or, if using systemd:: + + systemctl restart frr + +Reloading +^^^^^^^^^ + +Reloading applies the differential between on-disk configuration and the +current effective configuration of running FRR processes. This includes +starting daemons that were previously stopped and any changes made to +individual or unified daemon configuration files. + +.. code-block:: console + + service frr reload + +.. note:: + + Alternatively, you can invoke the init script directly:: + + /etc/init.d/frr reload + + Or, if using systemd:: + + systemctl reload frr + +Starting a new daemon +^^^^^^^^^^^^^^^^^^^^^ + +Suppose *bgpd* and *zebra* are running, and you wish to start *pimd*. In +``/etc/frr/daemons`` make the following change: + +.. code-block:: diff + + - pimd=no + + pimd=yes + +Then perform a reload. + +Currently there is no way to stop or restart an individual daemon. This is +because FRR's monitoring program cannot currently distinguish between a crashed +/ killed daemon versus one that has been intentionally stopped or restarted. +The closest that can be achieved is to remove all configuration for the daemon, +and set its line in ``/etc/frr/daemons`` to ``=no``. Once this is done, the +daemon will be stopped the next time FRR is restarted. diff --git a/doc/user/vnc.rst b/doc/user/vnc.rst index d0934fe6fa..cb9c74ceea 100644 --- a/doc/user/vnc.rst +++ b/doc/user/vnc.rst @@ -468,8 +468,8 @@ redistributed to VNC as bgp-direct-to-nve-groups routes. These routes are NOT announced via BGP, but they are made available for local RFP lookup in response to queries from NVEs. -A non-main/default BGP instance is configured using the `bgp multiple-instance` -and `router bgp AS view NAME` commands as described elsewhere in this document. +A non-main/default BGP instance is configured using the +`router bgp AS view NAME` command as described elsewhere in this document. In order for a route in the unicast BGP RIB to be made available to a querying NVE, there must already be, available to that NVE, an (interior) VNC route diff --git a/docker/debian/Dockerfile b/docker/debian/Dockerfile index 4f192ec33e..6ffdd0ccb3 100644 --- a/docker/debian/Dockerfile +++ b/docker/debian/Dockerfile @@ -1,10 +1,13 @@ -FROM debian:stretch +FROM debian:buster MAINTAINER Rob Gil (rob@rem5.com) +ENV DEBIAN_FRONTEND noninteractive +ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn RUN apt-get update RUN apt-get install -y libpcre3-dev apt-transport-https ca-certificates curl wget logrotate \ - libc-ares2 libjson-c3 vim systemd procps -RUN curl -sLO https://ci1.netdef.org/artifact/LIBYANG-YANGRELEASE/shared/build-1/Debian-9-x86_64-Packages/libyang_0.16.46_amd64.deb && dpkg -i libyang_0.16.46_amd64.deb -RUN curl -sLO https://github.com/FRRouting/frr/releases/download/frr-6.0.2/frr_6.0.2-0.deb9u1_amd64.deb && dpkg -i frr_6.0.2-0.deb9u1_amd64.deb -ADD daemons /etc/frr/daemons + libc-ares2 libjson-c3 vim systemd procps libreadline7 gnupg2 lsb-release apt-utils +RUN curl -s https://deb.frrouting.org/frr/keys.asc | apt-key add - +RUN echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) frr-stable | tee -a /etc/apt/sources.list.d/frr.list +RUN apt-get update +RUN apt-get install -y frr frr-pythontools ADD docker-start /usr/sbin/docker-start ENTRYPOINT ["/usr/sbin/docker-start"] diff --git a/docker/debian/README.md b/docker/debian/README.md index b10d696a78..3c1209bc97 100644 --- a/docker/debian/README.md +++ b/docker/debian/README.md @@ -1,14 +1,17 @@ -# Debian9 Docker -This is a binary docker container build of debian9. +# Debian 10 Docker + +This is a binary docker container build of Debian 10 (buster) with FRR. # Build + ``` -docker build --rm -t frr:6.0.2 . +docker build -t frr-debian:latest . ``` # Running + ``` -docker run -itd --privileged --name frr frr:latest +docker run -itd --privileged --name frr frr-debian:latest ``` vtysh diff --git a/docker/debian/daemons b/docker/debian/daemons deleted file mode 100644 index ed4d98e1f8..0000000000 --- a/docker/debian/daemons +++ /dev/null @@ -1,65 +0,0 @@ -# This file tells the frr package which daemons to start. -# -# Sample configurations for these daemons can be found in -# /usr/share/doc/frr/examples/. -# -# ATTENTION: -# -# When activation a daemon at the first time, a config file, even if it is -# empty, has to be present *and* be owned by the user and group "frr", else -# the daemon will not be started by /etc/init.d/frr. The permissions should -# be u=rw,g=r,o=. -# When using "vtysh" such a config file is also needed. It should be owned by -# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too. -# -# The watchfrr and zebra daemons are always started. -# -bgpd=yes -ospfd=no -ospf6d=no -ripd=no -ripngd=no -isisd=no -pimd=no -ldpd=no -nhrpd=no -eigrpd=no -babeld=no -sharpd=no -pbrd=no -bfdd=no -fabricd=no - -# -# If this option is set the /etc/init.d/frr script automatically loads -# the config via "vtysh -b" when the servers are started. -# Check /etc/pam.d/frr if you intend to use "vtysh"! -# -vtysh_enable=yes -zebra_options=" -A 127.0.0.1 -s 90000000" -bgpd_options=" -A 127.0.0.1" -ospfd_options=" -A 127.0.0.1" -ospf6d_options=" -A ::1" -ripd_options=" -A 127.0.0.1" -ripngd_options=" -A ::1" -isisd_options=" -A 127.0.0.1" -pimd_options=" -A 127.0.0.1" -ldpd_options=" -A 127.0.0.1" -nhrpd_options=" -A 127.0.0.1" -eigrpd_options=" -A 127.0.0.1" -babeld_options=" -A 127.0.0.1" -sharpd_options=" -A 127.0.0.1" -pbrd_options=" -A 127.0.0.1" -staticd_options="-A 127.0.0.1" -bfdd_options=" -A 127.0.0.1" -fabricd_options="-A 127.0.0.1" - -# The list of daemons to watch is automatically generated by the init script. -watchfrr_options="-r '/usr/lib/frr/watchfrr.sh restart %s' -s '/usr/lib/frr/watchfrr.sh start %s' -k '/usr/lib/frr/watchfrr.sh stop %s'" - -# for debugging purposes, you can specify a "wrap" command to start instead -# of starting the daemon directly, e.g. to use valgrind on ospfd: -# ospfd_wrap="/usr/bin/valgrind" -# or you can use "all_wrap" for all daemons, e.g. to use perf record: -# all_wrap="/usr/bin/perf record --call-graph -" -# the normal daemon command is added to this at the end. diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index bedaf15c47..4efb91e4a0 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -1114,6 +1114,7 @@ static struct TLV_IPv4_Internal_type *eigrp_IPv4_InternalTLV_new(void) struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *s) { struct TLV_IPv4_Internal_type *tlv; + uint32_t destination_tmp; tlv = eigrp_IPv4_InternalTLV_new(); @@ -1133,31 +1134,16 @@ struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *s) tlv->prefix_length = stream_getc(s); - if (tlv->prefix_length <= 8) { - tlv->destination_part[0] = stream_getc(s); - tlv->destination.s_addr = (tlv->destination_part[0]); - } else if (tlv->prefix_length > 8 && tlv->prefix_length <= 16) { - tlv->destination_part[0] = stream_getc(s); - tlv->destination_part[1] = stream_getc(s); - tlv->destination.s_addr = ((tlv->destination_part[1] << 8) - + tlv->destination_part[0]); - } else if (tlv->prefix_length > 16 && tlv->prefix_length <= 24) { - tlv->destination_part[0] = stream_getc(s); - tlv->destination_part[1] = stream_getc(s); - tlv->destination_part[2] = stream_getc(s); - tlv->destination.s_addr = ((tlv->destination_part[2] << 16) - + (tlv->destination_part[1] << 8) - + tlv->destination_part[0]); - } else if (tlv->prefix_length > 24 && tlv->prefix_length <= 32) { - tlv->destination_part[0] = stream_getc(s); - tlv->destination_part[1] = stream_getc(s); - tlv->destination_part[2] = stream_getc(s); - tlv->destination_part[3] = stream_getc(s); - tlv->destination.s_addr = ((tlv->destination_part[3] << 24) - + (tlv->destination_part[2] << 16) - + (tlv->destination_part[1] << 8) - + tlv->destination_part[0]); - } + destination_tmp = stream_getc(s) << 24; + if (tlv->prefix_length > 8) + destination_tmp |= stream_getc(s) << 16; + if (tlv->prefix_length > 16) + destination_tmp |= stream_getc(s) << 8; + if (tlv->prefix_length > 24) + destination_tmp |= stream_getc(s); + + tlv->destination.s_addr = htonl(destination_tmp); + return tlv; } @@ -1234,15 +1220,13 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s, stream_putc(s, pe->destination->prefixlen); - stream_putc(s, pe->destination->u.prefix4.s_addr & 0xFF); + stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 24) & 0xFF); if (pe->destination->prefixlen > 8) - stream_putc(s, (pe->destination->u.prefix4.s_addr >> 8) & 0xFF); + stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 16) & 0xFF); if (pe->destination->prefixlen > 16) - stream_putc(s, - (pe->destination->u.prefix4.s_addr >> 16) & 0xFF); + stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 8) & 0xFF); if (pe->destination->prefixlen > 24) - stream_putc(s, - (pe->destination->u.prefix4.s_addr >> 24) & 0xFF); + stream_putc(s, ntohl(pe->destination->u.prefix4.s_addr) & 0xFF); return length; } diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index a78e5a53cf..1b9186f011 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -409,7 +409,6 @@ struct TLV_IPv4_Internal_type { uint8_t prefix_length; - unsigned char destination_part[4]; struct in_addr destination; } __attribute__((packed)); diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c index 0a42adea37..d4c38efaf3 100644 --- a/isisd/isis_misc.c +++ b/isisd/isis_misc.c @@ -23,6 +23,7 @@ #include <zebra.h> +#include "printfrr.h" #include "stream.h" #include "vty.h" #include "hash.h" @@ -511,42 +512,14 @@ void zlog_dump_data(void *data, int len) return; } -static char *qasprintf(const char *format, va_list ap) -{ - va_list aq; - va_copy(aq, ap); - - int size = 0; - char *p = NULL; - - size = vsnprintf(p, size, format, ap); - - if (size < 0) { - va_end(aq); - return NULL; - } - - size++; - p = XMALLOC(MTYPE_TMP, size); - - size = vsnprintf(p, size, format, aq); - va_end(aq); - - if (size < 0) { - XFREE(MTYPE_TMP, p); - return NULL; - } - - return p; -} - void log_multiline(int priority, const char *prefix, const char *format, ...) { + char shortbuf[256]; va_list ap; char *p; va_start(ap, format); - p = qasprintf(format, ap); + p = asnprintfrr(MTYPE_TMP, shortbuf, sizeof(shortbuf), format, ap); va_end(ap); if (!p) @@ -558,16 +531,18 @@ void log_multiline(int priority, const char *prefix, const char *format, ...) zlog(priority, "%s%s", prefix, line); } - XFREE(MTYPE_TMP, p); + if (p != shortbuf) + XFREE(MTYPE_TMP, p); } void vty_multiline(struct vty *vty, const char *prefix, const char *format, ...) { + char shortbuf[256]; va_list ap; char *p; va_start(ap, format); - p = qasprintf(format, ap); + p = asnprintfrr(MTYPE_TMP, shortbuf, sizeof(shortbuf), format, ap); va_end(ap); if (!p) @@ -579,7 +554,8 @@ void vty_multiline(struct vty *vty, const char *prefix, const char *format, ...) vty_out(vty, "%s%s\n", prefix, line); } - XFREE(MTYPE_TMP, p); + if (p != shortbuf) + XFREE(MTYPE_TMP, p); } void vty_out_timestr(struct vty *vty, time_t uptime) diff --git a/isisd/isis_misc.h b/isisd/isis_misc.h index c551fde7d1..fbfabaf24f 100644 --- a/isisd/isis_misc.h +++ b/isisd/isis_misc.h @@ -79,9 +79,9 @@ enum { ISIS_UI_LEVEL_BRIEF, #include "lib/log.h" void log_multiline(int priority, const char *prefix, const char *format, ...) - PRINTF_ATTRIBUTE(3, 4); + PRINTFRR(3, 4); struct vty; void vty_multiline(struct vty *vty, const char *prefix, const char *format, ...) - PRINTF_ATTRIBUTE(3, 4); + PRINTFRR(3, 4); void vty_out_timestr(struct vty *vty, time_t uptime); #endif diff --git a/isisd/isis_northbound.c b/isisd/isis_northbound.c index d5cdec154b..ffc6ee0464 100644 --- a/isisd/isis_northbound.c +++ b/isisd/isis_northbound.c @@ -2741,478 +2741,680 @@ const struct frr_yang_module_info frr_isisd_info = { .nodes = { { .xpath = "/frr-isisd:isis/instance", - .cbs.create = isis_instance_create, - .cbs.destroy = isis_instance_destroy, - .cbs.cli_show = cli_show_router_isis, + .cbs = { + .cli_show = cli_show_router_isis, + .create = isis_instance_create, + .destroy = isis_instance_destroy, + }, .priority = NB_DFLT_PRIORITY - 1, }, { .xpath = "/frr-isisd:isis/instance/is-type", - .cbs.modify = isis_instance_is_type_modify, - .cbs.cli_show = cli_show_isis_is_type, + .cbs = { + .cli_show = cli_show_isis_is_type, + .modify = isis_instance_is_type_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/area-address", - .cbs.create = isis_instance_area_address_create, - .cbs.destroy = isis_instance_area_address_destroy, - .cbs.cli_show = cli_show_isis_area_address, + .cbs = { + .cli_show = cli_show_isis_area_address, + .create = isis_instance_area_address_create, + .destroy = isis_instance_area_address_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/dynamic-hostname", - .cbs.modify = isis_instance_dynamic_hostname_modify, - .cbs.cli_show = cli_show_isis_dynamic_hostname, + .cbs = { + .cli_show = cli_show_isis_dynamic_hostname, + .modify = isis_instance_dynamic_hostname_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/attached", - .cbs.modify = isis_instance_attached_modify, - .cbs.cli_show = cli_show_isis_attached, + .cbs = { + .cli_show = cli_show_isis_attached, + .modify = isis_instance_attached_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/overload", - .cbs.modify = isis_instance_overload_modify, - .cbs.cli_show = cli_show_isis_overload, + .cbs = { + .cli_show = cli_show_isis_overload, + .modify = isis_instance_overload_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/metric-style", - .cbs.modify = isis_instance_metric_style_modify, - .cbs.cli_show = cli_show_isis_metric_style, + .cbs = { + .cli_show = cli_show_isis_metric_style, + .modify = isis_instance_metric_style_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/purge-originator", - .cbs.modify = isis_instance_purge_originator_modify, - .cbs.cli_show = cli_show_isis_purge_origin, + .cbs = { + .cli_show = cli_show_isis_purge_origin, + .modify = isis_instance_purge_originator_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/mtu", - .cbs.modify = isis_instance_lsp_mtu_modify, - .cbs.cli_show = cli_show_isis_lsp_mtu, + .cbs = { + .cli_show = cli_show_isis_lsp_mtu, + .modify = isis_instance_lsp_mtu_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval", - .cbs.cli_show = cli_show_isis_lsp_ref_interval, + .cbs = { + .cli_show = cli_show_isis_lsp_ref_interval, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval/level-1", - .cbs.modify = isis_instance_lsp_refresh_interval_level_1_modify, + .cbs = { + .modify = isis_instance_lsp_refresh_interval_level_1_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval/level-2", - .cbs.modify = isis_instance_lsp_refresh_interval_level_2_modify, + .cbs = { + .modify = isis_instance_lsp_refresh_interval_level_2_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime", - .cbs.cli_show = cli_show_isis_lsp_max_lifetime, + .cbs = { + .cli_show = cli_show_isis_lsp_max_lifetime, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-1", - .cbs.modify = isis_instance_lsp_maximum_lifetime_level_1_modify, + .cbs = { + .modify = isis_instance_lsp_maximum_lifetime_level_1_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-2", - .cbs.modify = isis_instance_lsp_maximum_lifetime_level_2_modify, + .cbs = { + .modify = isis_instance_lsp_maximum_lifetime_level_2_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/generation-interval", - .cbs.cli_show = cli_show_isis_lsp_gen_interval, + .cbs = { + .cli_show = cli_show_isis_lsp_gen_interval, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/generation-interval/level-1", - .cbs.modify = isis_instance_lsp_generation_interval_level_1_modify, + .cbs = { + .modify = isis_instance_lsp_generation_interval_level_1_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/lsp/generation-interval/level-2", - .cbs.modify = isis_instance_lsp_generation_interval_level_2_modify, + .cbs = { + .modify = isis_instance_lsp_generation_interval_level_2_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay", - .cbs.create = isis_instance_spf_ietf_backoff_delay_create, - .cbs.destroy = isis_instance_spf_ietf_backoff_delay_destroy, - .cbs.apply_finish = ietf_backoff_delay_apply_finish, - .cbs.cli_show = cli_show_isis_spf_ietf_backoff, + .cbs = { + .apply_finish = ietf_backoff_delay_apply_finish, + .cli_show = cli_show_isis_spf_ietf_backoff, + .create = isis_instance_spf_ietf_backoff_delay_create, + .destroy = isis_instance_spf_ietf_backoff_delay_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay", - .cbs.modify = isis_instance_spf_ietf_backoff_delay_init_delay_modify, + .cbs = { + .modify = isis_instance_spf_ietf_backoff_delay_init_delay_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay", - .cbs.modify = isis_instance_spf_ietf_backoff_delay_short_delay_modify, + .cbs = { + .modify = isis_instance_spf_ietf_backoff_delay_short_delay_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay", - .cbs.modify = isis_instance_spf_ietf_backoff_delay_long_delay_modify, + .cbs = { + .modify = isis_instance_spf_ietf_backoff_delay_long_delay_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down", - .cbs.modify = isis_instance_spf_ietf_backoff_delay_hold_down_modify, + .cbs = { + .modify = isis_instance_spf_ietf_backoff_delay_hold_down_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn", - .cbs.modify = isis_instance_spf_ietf_backoff_delay_time_to_learn_modify, + .cbs = { + .modify = isis_instance_spf_ietf_backoff_delay_time_to_learn_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/minimum-interval", - .cbs.cli_show = cli_show_isis_spf_min_interval, + .cbs = { + .cli_show = cli_show_isis_spf_min_interval, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/minimum-interval/level-1", - .cbs.modify = isis_instance_spf_minimum_interval_level_1_modify, + .cbs = { + .modify = isis_instance_spf_minimum_interval_level_1_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/spf/minimum-interval/level-2", - .cbs.modify = isis_instance_spf_minimum_interval_level_2_modify, + .cbs = { + .modify = isis_instance_spf_minimum_interval_level_2_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/area-password", - .cbs.create = isis_instance_area_password_create, - .cbs.destroy = isis_instance_area_password_destroy, - .cbs.apply_finish = area_password_apply_finish, - .cbs.cli_show = cli_show_isis_area_pwd, + .cbs = { + .apply_finish = area_password_apply_finish, + .cli_show = cli_show_isis_area_pwd, + .create = isis_instance_area_password_create, + .destroy = isis_instance_area_password_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/area-password/password", - .cbs.modify = isis_instance_area_password_password_modify, + .cbs = { + .modify = isis_instance_area_password_password_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/area-password/password-type", - .cbs.modify = isis_instance_area_password_password_type_modify, + .cbs = { + .modify = isis_instance_area_password_password_type_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/area-password/authenticate-snp", - .cbs.modify = isis_instance_area_password_authenticate_snp_modify, + .cbs = { + .modify = isis_instance_area_password_authenticate_snp_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/domain-password", - .cbs.create = isis_instance_domain_password_create, - .cbs.destroy = isis_instance_domain_password_destroy, - .cbs.apply_finish = domain_password_apply_finish, - .cbs.cli_show = cli_show_isis_domain_pwd, + .cbs = { + .apply_finish = domain_password_apply_finish, + .cli_show = cli_show_isis_domain_pwd, + .create = isis_instance_domain_password_create, + .destroy = isis_instance_domain_password_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/domain-password/password", - .cbs.modify = isis_instance_domain_password_password_modify, + .cbs = { + .modify = isis_instance_domain_password_password_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/domain-password/password-type", - .cbs.modify = isis_instance_domain_password_password_type_modify, + .cbs = { + .modify = isis_instance_domain_password_password_type_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/domain-password/authenticate-snp", - .cbs.modify = isis_instance_domain_password_authenticate_snp_modify, + .cbs = { + .modify = isis_instance_domain_password_authenticate_snp_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4", - .cbs.create = isis_instance_default_information_originate_ipv4_create, - .cbs.destroy = isis_instance_default_information_originate_ipv4_destroy, - .cbs.apply_finish = default_info_origin_ipv4_apply_finish, - .cbs.cli_show = cli_show_isis_def_origin_ipv4, + .cbs = { + .apply_finish = default_info_origin_ipv4_apply_finish, + .cli_show = cli_show_isis_def_origin_ipv4, + .create = isis_instance_default_information_originate_ipv4_create, + .destroy = isis_instance_default_information_originate_ipv4_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/always", - .cbs.modify = isis_instance_default_information_originate_ipv4_always_modify, + .cbs = { + .modify = isis_instance_default_information_originate_ipv4_always_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/route-map", - .cbs.modify = isis_instance_default_information_originate_ipv4_route_map_modify, - .cbs.destroy = isis_instance_default_information_originate_ipv4_route_map_destroy, + .cbs = { + .destroy = isis_instance_default_information_originate_ipv4_route_map_destroy, + .modify = isis_instance_default_information_originate_ipv4_route_map_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/metric", - .cbs.modify = isis_instance_default_information_originate_ipv4_metric_modify, + .cbs = { + .modify = isis_instance_default_information_originate_ipv4_metric_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6", - .cbs.create = isis_instance_default_information_originate_ipv6_create, - .cbs.destroy = isis_instance_default_information_originate_ipv6_destroy, - .cbs.apply_finish = default_info_origin_ipv6_apply_finish, - .cbs.cli_show = cli_show_isis_def_origin_ipv6, + .cbs = { + .apply_finish = default_info_origin_ipv6_apply_finish, + .cli_show = cli_show_isis_def_origin_ipv6, + .create = isis_instance_default_information_originate_ipv6_create, + .destroy = isis_instance_default_information_originate_ipv6_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/always", - .cbs.modify = isis_instance_default_information_originate_ipv6_always_modify, + .cbs = { + .modify = isis_instance_default_information_originate_ipv6_always_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/route-map", - .cbs.modify = isis_instance_default_information_originate_ipv6_route_map_modify, - .cbs.destroy = isis_instance_default_information_originate_ipv6_route_map_destroy, + .cbs = { + .destroy = isis_instance_default_information_originate_ipv6_route_map_destroy, + .modify = isis_instance_default_information_originate_ipv6_route_map_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/metric", - .cbs.modify = isis_instance_default_information_originate_ipv6_metric_modify, + .cbs = { + .modify = isis_instance_default_information_originate_ipv6_metric_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/redistribute/ipv4", - .cbs.create = isis_instance_redistribute_ipv4_create, - .cbs.destroy = isis_instance_redistribute_ipv4_destroy, - .cbs.apply_finish = redistribute_ipv4_apply_finish, - .cbs.cli_show = cli_show_isis_redistribute_ipv4, + .cbs = { + .apply_finish = redistribute_ipv4_apply_finish, + .cli_show = cli_show_isis_redistribute_ipv4, + .create = isis_instance_redistribute_ipv4_create, + .destroy = isis_instance_redistribute_ipv4_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/route-map", - .cbs.modify = isis_instance_redistribute_ipv4_route_map_modify, - .cbs.destroy = isis_instance_redistribute_ipv4_route_map_destroy, + .cbs = { + .destroy = isis_instance_redistribute_ipv4_route_map_destroy, + .modify = isis_instance_redistribute_ipv4_route_map_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/metric", - .cbs.modify = isis_instance_redistribute_ipv4_metric_modify, + .cbs = { + .modify = isis_instance_redistribute_ipv4_metric_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/redistribute/ipv6", - .cbs.create = isis_instance_redistribute_ipv6_create, - .cbs.destroy = isis_instance_redistribute_ipv6_destroy, - .cbs.apply_finish = redistribute_ipv6_apply_finish, - .cbs.cli_show = cli_show_isis_redistribute_ipv6, + .cbs = { + .apply_finish = redistribute_ipv6_apply_finish, + .cli_show = cli_show_isis_redistribute_ipv6, + .create = isis_instance_redistribute_ipv6_create, + .destroy = isis_instance_redistribute_ipv6_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/route-map", - .cbs.modify = isis_instance_redistribute_ipv6_route_map_modify, - .cbs.destroy = isis_instance_redistribute_ipv6_route_map_destroy, + .cbs = { + .destroy = isis_instance_redistribute_ipv6_route_map_destroy, + .modify = isis_instance_redistribute_ipv6_route_map_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/metric", - .cbs.modify = isis_instance_redistribute_ipv6_metric_modify, + .cbs = { + .modify = isis_instance_redistribute_ipv6_metric_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast", - .cbs.create = isis_instance_multi_topology_ipv4_multicast_create, - .cbs.destroy = isis_instance_multi_topology_ipv4_multicast_destroy, - .cbs.cli_show = cli_show_isis_mt_ipv4_multicast, + .cbs = { + .cli_show = cli_show_isis_mt_ipv4_multicast, + .create = isis_instance_multi_topology_ipv4_multicast_create, + .destroy = isis_instance_multi_topology_ipv4_multicast_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload", - .cbs.modify = isis_instance_multi_topology_ipv4_multicast_overload_modify, + .cbs = { + .modify = isis_instance_multi_topology_ipv4_multicast_overload_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management", - .cbs.create = isis_instance_multi_topology_ipv4_management_create, - .cbs.destroy = isis_instance_multi_topology_ipv4_management_destroy, - .cbs.cli_show = cli_show_isis_mt_ipv4_mgmt, + .cbs = { + .cli_show = cli_show_isis_mt_ipv4_mgmt, + .create = isis_instance_multi_topology_ipv4_management_create, + .destroy = isis_instance_multi_topology_ipv4_management_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management/overload", - .cbs.modify = isis_instance_multi_topology_ipv4_management_overload_modify, + .cbs = { + .modify = isis_instance_multi_topology_ipv4_management_overload_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast", - .cbs.create = isis_instance_multi_topology_ipv6_unicast_create, - .cbs.destroy = isis_instance_multi_topology_ipv6_unicast_destroy, - .cbs.cli_show = cli_show_isis_mt_ipv6_unicast, + .cbs = { + .cli_show = cli_show_isis_mt_ipv6_unicast, + .create = isis_instance_multi_topology_ipv6_unicast_create, + .destroy = isis_instance_multi_topology_ipv6_unicast_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload", - .cbs.modify = isis_instance_multi_topology_ipv6_unicast_overload_modify, + .cbs = { + .modify = isis_instance_multi_topology_ipv6_unicast_overload_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast", - .cbs.create = isis_instance_multi_topology_ipv6_multicast_create, - .cbs.destroy = isis_instance_multi_topology_ipv6_multicast_destroy, - .cbs.cli_show = cli_show_isis_mt_ipv6_multicast, + .cbs = { + .cli_show = cli_show_isis_mt_ipv6_multicast, + .create = isis_instance_multi_topology_ipv6_multicast_create, + .destroy = isis_instance_multi_topology_ipv6_multicast_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload", - .cbs.modify = isis_instance_multi_topology_ipv6_multicast_overload_modify, + .cbs = { + .modify = isis_instance_multi_topology_ipv6_multicast_overload_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management", - .cbs.create = isis_instance_multi_topology_ipv6_management_create, - .cbs.destroy = isis_instance_multi_topology_ipv6_management_destroy, - .cbs.cli_show = cli_show_isis_mt_ipv6_mgmt, + .cbs = { + .cli_show = cli_show_isis_mt_ipv6_mgmt, + .create = isis_instance_multi_topology_ipv6_management_create, + .destroy = isis_instance_multi_topology_ipv6_management_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management/overload", - .cbs.modify = isis_instance_multi_topology_ipv6_management_overload_modify, + .cbs = { + .modify = isis_instance_multi_topology_ipv6_management_overload_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc", - .cbs.create = isis_instance_multi_topology_ipv6_dstsrc_create, - .cbs.destroy = isis_instance_multi_topology_ipv6_dstsrc_destroy, - .cbs.cli_show = cli_show_isis_mt_ipv6_dstsrc, + .cbs = { + .cli_show = cli_show_isis_mt_ipv6_dstsrc, + .create = isis_instance_multi_topology_ipv6_dstsrc_create, + .destroy = isis_instance_multi_topology_ipv6_dstsrc_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload", - .cbs.modify = isis_instance_multi_topology_ipv6_dstsrc_overload_modify, + .cbs = { + .modify = isis_instance_multi_topology_ipv6_dstsrc_overload_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/log-adjacency-changes", - .cbs.modify = isis_instance_log_adjacency_changes_modify, - .cbs.cli_show = cli_show_isis_log_adjacency, + .cbs = { + .cli_show = cli_show_isis_log_adjacency, + .modify = isis_instance_log_adjacency_changes_modify, + }, }, { .xpath = "/frr-isisd:isis/instance/mpls-te", - .cbs.create = isis_instance_mpls_te_create, - .cbs.destroy = isis_instance_mpls_te_destroy, - .cbs.cli_show = cli_show_isis_mpls_te, + .cbs = { + .cli_show = cli_show_isis_mpls_te, + .create = isis_instance_mpls_te_create, + .destroy = isis_instance_mpls_te_destroy, + }, }, { .xpath = "/frr-isisd:isis/instance/mpls-te/router-address", - .cbs.modify = isis_instance_mpls_te_router_address_modify, - .cbs.destroy = isis_instance_mpls_te_router_address_destroy, - .cbs.cli_show = cli_show_isis_mpls_te_router_addr, + .cbs = { + .cli_show = cli_show_isis_mpls_te_router_addr, + .destroy = isis_instance_mpls_te_router_address_destroy, + .modify = isis_instance_mpls_te_router_address_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis", - .cbs.create = lib_interface_isis_create, - .cbs.destroy = lib_interface_isis_destroy, + .cbs = { + .create = lib_interface_isis_create, + .destroy = lib_interface_isis_destroy, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/area-tag", - .cbs.modify = lib_interface_isis_area_tag_modify, + .cbs = { + .modify = lib_interface_isis_area_tag_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/circuit-type", - .cbs.modify = lib_interface_isis_circuit_type_modify, - .cbs.cli_show = cli_show_ip_isis_circ_type, + .cbs = { + .cli_show = cli_show_ip_isis_circ_type, + .modify = lib_interface_isis_circuit_type_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv4-routing", - .cbs.modify = lib_interface_isis_ipv4_routing_modify, - .cbs.cli_show = cli_show_ip_isis_ipv4, + .cbs = { + .cli_show = cli_show_ip_isis_ipv4, + .modify = lib_interface_isis_ipv4_routing_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv6-routing", - .cbs.modify = lib_interface_isis_ipv6_routing_modify, - .cbs.cli_show = cli_show_ip_isis_ipv6, + .cbs = { + .cli_show = cli_show_ip_isis_ipv6, + .modify = lib_interface_isis_ipv6_routing_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval", - .cbs.cli_show = cli_show_ip_isis_csnp_interval, + .cbs = { + .cli_show = cli_show_ip_isis_csnp_interval, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1", - .cbs.modify = lib_interface_isis_csnp_interval_level_1_modify, + .cbs = { + .modify = lib_interface_isis_csnp_interval_level_1_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2", - .cbs.modify = lib_interface_isis_csnp_interval_level_2_modify, + .cbs = { + .modify = lib_interface_isis_csnp_interval_level_2_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval", - .cbs.cli_show = cli_show_ip_isis_psnp_interval, + .cbs = { + .cli_show = cli_show_ip_isis_psnp_interval, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1", - .cbs.modify = lib_interface_isis_psnp_interval_level_1_modify, + .cbs = { + .modify = lib_interface_isis_psnp_interval_level_1_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2", - .cbs.modify = lib_interface_isis_psnp_interval_level_2_modify, + .cbs = { + .modify = lib_interface_isis_psnp_interval_level_2_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/padding", - .cbs.modify = lib_interface_isis_hello_padding_modify, - .cbs.cli_show = cli_show_ip_isis_hello_padding, + .cbs = { + .cli_show = cli_show_ip_isis_hello_padding, + .modify = lib_interface_isis_hello_padding_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval", - .cbs.cli_show = cli_show_ip_isis_hello_interval, + .cbs = { + .cli_show = cli_show_ip_isis_hello_interval, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1", - .cbs.modify = lib_interface_isis_hello_interval_level_1_modify, + .cbs = { + .modify = lib_interface_isis_hello_interval_level_1_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2", - .cbs.modify = lib_interface_isis_hello_interval_level_2_modify, + .cbs = { + .modify = lib_interface_isis_hello_interval_level_2_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier", - .cbs.cli_show = cli_show_ip_isis_hello_multi, + .cbs = { + .cli_show = cli_show_ip_isis_hello_multi, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1", - .cbs.modify = lib_interface_isis_hello_multiplier_level_1_modify, + .cbs = { + .modify = lib_interface_isis_hello_multiplier_level_1_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2", - .cbs.modify = lib_interface_isis_hello_multiplier_level_2_modify, + .cbs = { + .modify = lib_interface_isis_hello_multiplier_level_2_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric", - .cbs.cli_show = cli_show_ip_isis_metric, + .cbs = { + .cli_show = cli_show_ip_isis_metric, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-1", - .cbs.modify = lib_interface_isis_metric_level_1_modify, + .cbs = { + .modify = lib_interface_isis_metric_level_1_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2", - .cbs.modify = lib_interface_isis_metric_level_2_modify, + .cbs = { + .modify = lib_interface_isis_metric_level_2_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority", - .cbs.cli_show = cli_show_ip_isis_priority, + .cbs = { + .cli_show = cli_show_ip_isis_priority, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-1", - .cbs.modify = lib_interface_isis_priority_level_1_modify, + .cbs = { + .modify = lib_interface_isis_priority_level_1_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-2", - .cbs.modify = lib_interface_isis_priority_level_2_modify, + .cbs = { + .modify = lib_interface_isis_priority_level_2_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/network-type", - .cbs.modify = lib_interface_isis_network_type_modify, - .cbs.cli_show = cli_show_ip_isis_network_type, + .cbs = { + .cli_show = cli_show_ip_isis_network_type, + .modify = lib_interface_isis_network_type_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/passive", - .cbs.modify = lib_interface_isis_passive_modify, - .cbs.cli_show = cli_show_ip_isis_passive, + .cbs = { + .cli_show = cli_show_ip_isis_passive, + .modify = lib_interface_isis_passive_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password", - .cbs.create = lib_interface_isis_password_create, - .cbs.destroy = lib_interface_isis_password_destroy, - .cbs.cli_show = cli_show_ip_isis_password, + .cbs = { + .cli_show = cli_show_ip_isis_password, + .create = lib_interface_isis_password_create, + .destroy = lib_interface_isis_password_destroy, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password/password", - .cbs.modify = lib_interface_isis_password_password_modify, + .cbs = { + .modify = lib_interface_isis_password_password_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password/password-type", - .cbs.modify = lib_interface_isis_password_password_type_modify, + .cbs = { + .modify = lib_interface_isis_password_password_type_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake", - .cbs.modify = lib_interface_isis_disable_three_way_handshake_modify, - .cbs.cli_show = cli_show_ip_isis_threeway_shake, + .cbs = { + .cli_show = cli_show_ip_isis_threeway_shake, + .modify = lib_interface_isis_disable_three_way_handshake_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast", - .cbs.modify = lib_interface_isis_multi_topology_ipv4_unicast_modify, - .cbs.cli_show = cli_show_ip_isis_mt_ipv4_unicast, + .cbs = { + .cli_show = cli_show_ip_isis_mt_ipv4_unicast, + .modify = lib_interface_isis_multi_topology_ipv4_unicast_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast", - .cbs.modify = lib_interface_isis_multi_topology_ipv4_multicast_modify, - .cbs.cli_show = cli_show_ip_isis_mt_ipv4_multicast, + .cbs = { + .cli_show = cli_show_ip_isis_mt_ipv4_multicast, + .modify = lib_interface_isis_multi_topology_ipv4_multicast_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management", - .cbs.modify = lib_interface_isis_multi_topology_ipv4_management_modify, - .cbs.cli_show = cli_show_ip_isis_mt_ipv4_mgmt, + .cbs = { + .cli_show = cli_show_ip_isis_mt_ipv4_mgmt, + .modify = lib_interface_isis_multi_topology_ipv4_management_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast", - .cbs.modify = lib_interface_isis_multi_topology_ipv6_unicast_modify, - .cbs.cli_show = cli_show_ip_isis_mt_ipv6_unicast, + .cbs = { + .cli_show = cli_show_ip_isis_mt_ipv6_unicast, + .modify = lib_interface_isis_multi_topology_ipv6_unicast_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast", - .cbs.modify = lib_interface_isis_multi_topology_ipv6_multicast_modify, - .cbs.cli_show = cli_show_ip_isis_mt_ipv6_multicast, + .cbs = { + .cli_show = cli_show_ip_isis_mt_ipv6_multicast, + .modify = lib_interface_isis_multi_topology_ipv6_multicast_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management", - .cbs.modify = lib_interface_isis_multi_topology_ipv6_management_modify, - .cbs.cli_show = cli_show_ip_isis_mt_ipv6_mgmt, + .cbs = { + .cli_show = cli_show_ip_isis_mt_ipv6_mgmt, + .modify = lib_interface_isis_multi_topology_ipv6_management_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc", - .cbs.modify = lib_interface_isis_multi_topology_ipv6_dstsrc_modify, - .cbs.cli_show = cli_show_ip_isis_mt_ipv6_dstsrc, + .cbs = { + .cli_show = cli_show_ip_isis_mt_ipv6_dstsrc, + .modify = lib_interface_isis_multi_topology_ipv6_dstsrc_modify, + }, }, { .xpath = NULL, diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 5aaa2ec325..9fccb085dd 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -447,7 +447,7 @@ ldpd_shutdown(void) if (errno == EINTR) continue; /* No more processes were found. */ - if (errno != ECHILD) + if (errno == ECHILD) break; /* Unhandled errno condition. */ diff --git a/ldpd/packet.c b/ldpd/packet.c index 8ca90841de..dfab30eeb3 100644 --- a/ldpd/packet.c +++ b/ldpd/packet.c @@ -618,12 +618,17 @@ session_read(struct thread *thread) len -= msg_size; } free(buf); + buf = NULL; if (len != 0) { session_shutdown(nbr, S_BAD_PDU_LEN, 0, 0); return (0); } } + /* shouldn't happen, session_get_pdu should be > 0 if buf was + * allocated - but let's get rid of the SA warning. + */ + free(buf); return (0); } diff --git a/lib/clippy.c b/lib/clippy.c index 44dcc02eb8..cd8067f5eb 100644 --- a/lib/clippy.c +++ b/lib/clippy.c @@ -85,8 +85,6 @@ int main(int argc, char **argv) if (PyRun_AnyFile(fp, pyfile)) { if (PyErr_Occurred()) PyErr_Print(); - else - printf("unknown python failure (?)\n"); return 1; } Py_Finalize(); diff --git a/lib/command.c b/lib/command.c index e5e0623163..f257c7d0f9 100644 --- a/lib/command.c +++ b/lib/command.c @@ -48,7 +48,7 @@ #include "lib_errors.h" #include "northbound_cli.h" -DEFINE_MTYPE(LIB, HOST, "Host config") +DEFINE_MTYPE_STATIC(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, COMPLETION, "Completion item") #define item(x) \ @@ -84,6 +84,7 @@ const char *node_names[] = { "vrf debug", // VRF_DEBUG_NODE, "northbound debug", // NORTHBOUND_DEBUG_NODE, "vnc debug", // DEBUG_VNC_NODE, + "route-map debug", /* RMAP_DEBUG_NODE */ "aaa", // AAA_NODE, "keychain", // KEYCHAIN_NODE, "keychain key", // KEYCHAIN_KEY_NODE, @@ -1053,9 +1054,16 @@ static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter, if (matched_element->daemon) ret = CMD_SUCCESS_DAEMON; else { - /* Clear enqueued configuration changes. */ - vty->num_cfg_changes = 0; - memset(&vty->cfg_changes, 0, sizeof(vty->cfg_changes)); + if (vty->config) { + /* Clear array of enqueued configuration changes. */ + vty->num_cfg_changes = 0; + memset(&vty->cfg_changes, 0, sizeof(vty->cfg_changes)); + + /* Regenerate candidate configuration. */ + if (frr_get_cli_mode() == FRR_CLI_CLASSIC) + nb_config_replace(vty->candidate_config, + running_config, true); + } ret = matched_element->func(matched_element, vty, argc, argv); } diff --git a/lib/command.h b/lib/command.h index d6c41e0824..fd8b56d62e 100644 --- a/lib/command.h +++ b/lib/command.h @@ -34,7 +34,6 @@ extern "C" { #endif -DECLARE_MTYPE(HOST) DECLARE_MTYPE(COMPLETION) /* @@ -94,6 +93,7 @@ enum node_type { VRF_DEBUG_NODE, /* Vrf Debug node. */ NORTHBOUND_DEBUG_NODE, /* Northbound Debug node. */ DEBUG_VNC_NODE, /* Debug VNC node. */ + RMAP_DEBUG_NODE, /* Route-map debug node */ AAA_NODE, /* AAA node. */ KEYCHAIN_NODE, /* Key-chain node. */ KEYCHAIN_KEY_NODE, /* Key-chain key node. */ diff --git a/lib/command_py.c b/lib/command_py.c index 58b7982665..4ec116df33 100644 --- a/lib/command_py.c +++ b/lib/command_py.c @@ -22,6 +22,12 @@ * memory leak or SEGV for things that haven't been well-tested. */ +/* This file is "exempt" from having +#include "config.h" + * as the first include statement because Python.h also does environment + * setup & these trample over each other. + */ + #include <Python.h> #include "structmember.h" #include <string.h> @@ -321,6 +327,7 @@ static struct PyModuleDef pymoddef_clippy = { } while (0) #endif +#pragma GCC diagnostic ignored "-Wstrict-aliasing" PyMODINIT_FUNC command_py_init(void) { PyObject *pymod; diff --git a/lib/compiler.h b/lib/compiler.h index 9ce91e3361..7c7f4ce294 100644 --- a/lib/compiler.h +++ b/lib/compiler.h @@ -173,6 +173,11 @@ extern "C" { #endif #endif +#ifdef container_of +#undef container_of +#endif + +#if !(defined(__cplusplus) || defined(test__cplusplus)) /* this variant of container_of() retains 'const' on pointers without needing * to be told to do so. The following will all work without warning: * @@ -191,9 +196,6 @@ extern "C" { * struct cont *x = container_of(cp, const struct cont, member); * struct cont *x = container_of(p, const struct cont, member); */ -#ifdef container_of -#undef container_of -#endif #define container_of(ptr, type, member) \ (__builtin_choose_expr( \ __builtin_types_compatible_p(typeof(&((type *)0)->member), \ @@ -209,6 +211,15 @@ extern "C" { offsetof(type, member)); \ }) \ )) +#else +/* current C++ compilers don't have the builtins used above; so this version + * of the macro doesn't do the const check. */ +#define container_of(ptr, type, member) \ + ({ \ + const typeof(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); \ + }) +#endif #define container_of_null(ptr, type, member) \ ({ \ @@ -218,6 +229,68 @@ extern "C" { #define array_size(ar) (sizeof(ar) / sizeof(ar[0])) +/* sigh. this is so ugly, it overflows and wraps to being nice again. + * + * printfrr() supports "%Ld" for <int64_t>, whatever that is typedef'd to. + * However, gcc & clang think that "%Ld" is <long long>, which doesn't quite + * match up since int64_t is <long> on a lot of 64-bit systems. + * + * If we have _FRR_ATTRIBUTE_PRINTFRR, we loaded a compiler plugin that + * replaces the whole format checking bits with a custom version that + * understands "%Ld" (along with "%pI4" and co.), so we don't need to do + * anything. + * + * If we don't have that attribute... we still want -Wformat to work. So, + * this is the "f*ck it" approach and we just redefine int64_t to always be + * <long long>. This should work until such a time that <long long> is + * something else (e.g. 128-bit integer)... let's just guard against that + * with the _Static_assert below and work with the world we have right now, + * where <long long> is always 64-bit. + */ + +/* these need to be included before any of the following, so we can + * "overwrite" things. + */ +#include <stdint.h> +#include <inttypes.h> + +#ifdef _FRR_ATTRIBUTE_PRINTFRR +#define PRINTFRR(a, b) __attribute__((printfrr(a, b))) + +#else /* !_FRR_ATTRIBUTE_PRINTFRR */ +#define PRINTFRR(a, b) __attribute__((format(printf, a, b))) + +/* these should be typedefs, but might also be #define */ +#ifdef uint64_t +#undef uint64_t +#endif +#ifdef int64_t +#undef int64_t +#endif + +/* can't overwrite the typedef, but we can replace int64_t with _int64_t */ +typedef unsigned long long _uint64_t; +#define uint64_t _uint64_t +typedef signed long long _int64_t; +#define int64_t _int64_t + +/* if this breaks, 128-bit machines may have entered reality (or <long long> + * is something weird) + */ +#if __STDC_VERSION__ >= 201112L +_Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8, + "nobody expects the spanish intquisition"); +#endif + +/* since we redefined int64_t, we also need to redefine PRI*64 */ +#undef PRIu64 +#undef PRId64 +#undef PRIx64 +#define PRIu64 "llu" +#define PRId64 "lld" +#define PRIx64 "llx" +#endif /* !_FRR_ATTRIBUTE_PRINTFRR */ + #ifdef __cplusplus } #endif diff --git a/lib/defun_lex.l b/lib/defun_lex.l index 6c0805a4fa..19b06f51b8 100644 --- a/lib/defun_lex.l +++ b/lib/defun_lex.l @@ -163,7 +163,7 @@ static int yylex_clr(char **retbuf) return rv; } -static PyObject *get_args(void) +static PyObject *get_args(const char *filename, int lineno) { PyObject *pyObj = PyList_New(0); PyObject *pyArg = NULL; @@ -190,6 +190,13 @@ static PyObject *get_args(void) free(tval); continue; } + if (token == PREPROC) { + free(tval); + Py_DECREF(pyObj); + return PyErr_Format(PyExc_ValueError, + "%s:%d: cannot process CPP directive within argument list", + filename, lineno); + } if (token == SPECIAL) { if (depth == 1 && (tval[0] == ',' || tval[0] == ')')) { if (pyArg) @@ -244,7 +251,12 @@ PyObject *clippy_parse(PyObject *self, PyObject *args) case DEFUNNY: case INSTALL: case AUXILIARY: - pyArgs = get_args(); + pyArgs = get_args(filename, lineno); + if (!pyArgs) { + free(tval); + Py_DECREF(pyCont); + return NULL; + } pyItem = PyDict_New(); PyDict_SetItemString(pyItem, "type", PyUnicode_FromString(tval)); PyDict_SetItemString(pyItem, "args", pyArgs); @@ -260,6 +272,7 @@ PyObject *clippy_parse(PyObject *self, PyObject *args) pyItem = PyDict_New(); PyDict_SetItemString(pyItem, "type", PyUnicode_FromString("PREPROC")); PyDict_SetItemString(pyItem, "line", PyUnicode_FromString(tval)); + lineno--; break; } if (pyItem) { diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index 2a18e5cfc6..e588571c01 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -28,8 +28,8 @@ #include "memory.h" #include "linklist.h" -DEFINE_MTYPE(LIB, FRR_PTHREAD, "FRR POSIX Thread"); -DEFINE_MTYPE(LIB, PTHREAD_PRIM, "POSIX synchronization primitives"); +DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread") +DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives") /* default frr_pthread start/stop routine prototypes */ static void *fpt_run(void *arg); diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h index 9bc7b94033..3afe7ba966 100644 --- a/lib/frr_pthread.h +++ b/lib/frr_pthread.h @@ -29,9 +29,6 @@ extern "C" { #endif -DECLARE_MTYPE(FRR_PTHREAD); -DECLARE_MTYPE(PTHREAD_PRIM); - #define OS_THREAD_NAMELEN 16 struct frr_pthread; diff --git a/lib/frrlua.c b/lib/frrlua.c index b7d8eea6e8..26610556dc 100644 --- a/lib/frrlua.c +++ b/lib/frrlua.c @@ -20,7 +20,6 @@ * 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> diff --git a/lib/hash.c b/lib/hash.c index fad7de5138..9d9d39702e 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -29,8 +29,8 @@ #include "command.h" #include "libfrr.h" -DEFINE_MTYPE(LIB, HASH, "Hash") -DEFINE_MTYPE(LIB, HASH_BACKET, "Hash Bucket") +DEFINE_MTYPE_STATIC(LIB, HASH, "Hash") +DEFINE_MTYPE_STATIC(LIB, HASH_BACKET, "Hash Bucket") DEFINE_MTYPE_STATIC(LIB, HASH_INDEX, "Hash Index") static pthread_mutex_t _hashes_mtx = PTHREAD_MUTEX_INITIALIZER; diff --git a/lib/hash.h b/lib/hash.h index c56a98d50c..7b3372d433 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -28,9 +28,6 @@ extern "C" { #endif -DECLARE_MTYPE(HASH) -DECLARE_MTYPE(HASH_BACKET) - /* Default hash table size. */ #define HASH_INITIAL_SIZE 256 /* Expansion threshold */ diff --git a/lib/iana_afi.h b/lib/iana_afi.h new file mode 100644 index 0000000000..ac03f73193 --- /dev/null +++ b/lib/iana_afi.h @@ -0,0 +1,133 @@ +/* + * iana_afi and safi definitions. + * Copyright (C) 2018-2019 Cumulus Networks, Inc. + * Donald Sharp + * + * This program 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 of the License, or (at your option) + * any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __IANA_AFI_H__ + +#include <prefix.h> + +/* + * The above AFI and SAFI definitions are for internal use. The protocol + * definitions (IANA values) as for example used in BGP protocol packets + * are defined below and these will get mapped to/from the internal values + * in the appropriate places. + * The rationale is that the protocol (IANA) values may be sparse and are + * not optimal for use in data-structure sizing. + * Note: Only useful (i.e., supported) values are defined below. + */ +typedef enum { + IANA_AFI_RESERVED = 0, + IANA_AFI_IPV4 = 1, + IANA_AFI_IPV6 = 2, + IANA_AFI_L2VPN = 25, +} iana_afi_t; + +typedef enum { + IANA_SAFI_RESERVED = 0, + IANA_SAFI_UNICAST = 1, + IANA_SAFI_MULTICAST = 2, + IANA_SAFI_LABELED_UNICAST = 4, + IANA_SAFI_ENCAP = 7, + IANA_SAFI_EVPN = 70, + IANA_SAFI_MPLS_VPN = 128, + IANA_SAFI_FLOWSPEC = 133 +} iana_safi_t; + +static inline afi_t afi_iana2int(iana_afi_t afi) +{ + switch (afi) { + case IANA_AFI_IPV4: + return AFI_IP; + case IANA_AFI_IPV6: + return AFI_IP6; + case IANA_AFI_L2VPN: + return AFI_L2VPN; + default: + return AFI_MAX; + } +} + +static inline iana_afi_t afi_int2iana(afi_t afi) +{ + switch (afi) { + case AFI_IP: + return IANA_AFI_IPV4; + case AFI_IP6: + return IANA_AFI_IPV6; + case AFI_L2VPN: + return IANA_AFI_L2VPN; + default: + return IANA_AFI_RESERVED; + } +} + +static inline const char *iana_afi2str(iana_afi_t afi) +{ + return afi2str(afi_iana2int(afi)); +} + +static inline safi_t safi_iana2int(iana_safi_t safi) +{ + switch (safi) { + case IANA_SAFI_UNICAST: + return SAFI_UNICAST; + case IANA_SAFI_MULTICAST: + return SAFI_MULTICAST; + case IANA_SAFI_MPLS_VPN: + return SAFI_MPLS_VPN; + case IANA_SAFI_ENCAP: + return SAFI_ENCAP; + case IANA_SAFI_EVPN: + return SAFI_EVPN; + case IANA_SAFI_LABELED_UNICAST: + return SAFI_LABELED_UNICAST; + case IANA_SAFI_FLOWSPEC: + return SAFI_FLOWSPEC; + default: + return SAFI_MAX; + } +} + +static inline iana_safi_t safi_int2iana(safi_t safi) +{ + switch (safi) { + case SAFI_UNICAST: + return IANA_SAFI_UNICAST; + case SAFI_MULTICAST: + return IANA_SAFI_MULTICAST; + case SAFI_MPLS_VPN: + return IANA_SAFI_MPLS_VPN; + case SAFI_ENCAP: + return IANA_SAFI_ENCAP; + case SAFI_EVPN: + return IANA_SAFI_EVPN; + case SAFI_LABELED_UNICAST: + return IANA_SAFI_LABELED_UNICAST; + case SAFI_FLOWSPEC: + return IANA_SAFI_FLOWSPEC; + default: + return IANA_SAFI_RESERVED; + } +} + +static inline const char *iana_safi2str(iana_safi_t safi) +{ + return safi2str(safi_iana2int(safi)); +} + +#endif diff --git a/lib/id_alloc.c b/lib/id_alloc.c index 222ba651b4..7c7f2c4689 100644 --- a/lib/id_alloc.c +++ b/lib/id_alloc.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "id_alloc.h" #include "log.h" @@ -39,7 +39,7 @@ #include "lib/if_clippy.c" #endif -DEFINE_MTYPE(LIB, IF, "Interface") +DEFINE_MTYPE_STATIC(LIB, IF, "Interface") DEFINE_MTYPE_STATIC(LIB, CONNECTED, "Connected") DEFINE_MTYPE_STATIC(LIB, NBR_CONNECTED, "Neighbor Connected") DEFINE_MTYPE(LIB, CONNECTED_LABEL, "Connected interface label") @@ -1422,15 +1422,19 @@ const struct frr_yang_module_info frr_interface_info = { .nodes = { { .xpath = "/frr-interface:lib/interface", - .cbs.create = lib_interface_create, - .cbs.destroy = lib_interface_destroy, - .cbs.cli_show = cli_show_interface, + .cbs = { + .create = lib_interface_create, + .destroy = lib_interface_destroy, + .cli_show = cli_show_interface, + }, }, { .xpath = "/frr-interface:lib/interface/description", - .cbs.modify = lib_interface_description_modify, - .cbs.destroy = lib_interface_description_destroy, - .cbs.cli_show = cli_show_interface_desc, + .cbs = { + .modify = lib_interface_description_modify, + .destroy = lib_interface_description_destroy, + .cli_show = cli_show_interface_desc, + }, }, { .xpath = NULL, @@ -31,7 +31,6 @@ extern "C" { #endif -DECLARE_MTYPE(IF) DECLARE_MTYPE(CONNECTED_LABEL) /* Interface link-layer type, if known. Derived from: diff --git a/lib/lib_errors.c b/lib/lib_errors.c index b6c764d873..e0559f332d 100644 --- a/lib/lib_errors.c +++ b/lib/lib_errors.c @@ -51,6 +51,12 @@ static struct log_ref ferr_lib_warn[] = { .suggestion = "Gather log data and open an Issue", }, { + .code = EC_LIB_NO_THREAD, + .title = "The Event subsystem has detected an internal FD problem", + .description = "The Event subsystem has detected a file descriptor read/write event without an associated handling function. This is a bug, please collect log data and open an issue.", + .suggestion = "Gather log data and open an Issue", + }, + { .code = EC_LIB_RMAP_RECURSION_LIMIT, .title = "Reached the Route-Map Recursion Limit", .description = "The Route-Map subsystem has detected a route-map depth of RMAP_RECURSION_LIMIT and has stopped processing", diff --git a/lib/lib_errors.h b/lib/lib_errors.h index 39b39fb065..996a16ba95 100644 --- a/lib/lib_errors.h +++ b/lib/lib_errors.h @@ -45,6 +45,7 @@ enum lib_log_refs { EC_LIB_STREAM, EC_LIB_LINUX_NS, EC_LIB_SLOW_THREAD, + EC_LIB_NO_THREAD, EC_LIB_RMAP_RECURSION_LIMIT, EC_LIB_BACKUP_CONFIG, EC_LIB_VRF_LENGTH, @@ -81,20 +81,13 @@ extern void openzlog(const char *progname, const char *protoname, /* Close zlog function. */ extern void closezlog(void); -/* GCC have printf type attribute check. */ -#ifdef __GNUC__ -#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) -#else -#define PRINTF_ATTRIBUTE(a,b) -#endif /* __GNUC__ */ - /* Handy zlog functions. */ -extern void zlog_err(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); -extern void zlog_warn(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); -extern void zlog_info(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); -extern void zlog_notice(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); -extern void zlog_debug(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); -extern void zlog(int priority, const char *format, ...) PRINTF_ATTRIBUTE(2, 3); +extern void zlog_err(const char *format, ...) PRINTFRR(1, 2); +extern void zlog_warn(const char *format, ...) PRINTFRR(1, 2); +extern void zlog_info(const char *format, ...) PRINTFRR(1, 2); +extern void zlog_notice(const char *format, ...) PRINTFRR(1, 2); +extern void zlog_debug(const char *format, ...) PRINTFRR(1, 2); +extern void zlog(int priority, const char *format, ...) PRINTFRR(2, 3); /* For logs which have error codes associated with them */ #define flog_err(ferr_id, format, ...) \ diff --git a/lib/memory.h b/lib/memory.h index 0002ea3349..14cd76f2f5 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -102,9 +102,14 @@ struct memgroup { } +/* the array is a trick to make the "MTYPE_FOO" name work as a pointer without + * putting a & in front of it, so we can do "XMALLOC(MTYPE_FOO, ...)" instead + * of "XMALLOC(&MTYPE_FOO, ...)". + */ #define DECLARE_MTYPE(name) \ extern struct memtype _mt_##name; \ - static struct memtype *const MTYPE_##name = &_mt_##name; + extern struct memtype MTYPE_##name[1]; \ + /* end */ #define DEFINE_MTYPE_ATTR(group, mname, attr, desc) \ attr struct memtype _mt_##mname \ @@ -130,12 +135,21 @@ struct memgroup { if (_mt_##mname.next) \ _mt_##mname.next->ref = _mt_##mname.ref; \ *_mt_##mname.ref = _mt_##mname.next; \ - } - -#define DEFINE_MTYPE(group, name, desc) DEFINE_MTYPE_ATTR(group, name, , desc) + } \ + /* end */ + +/* can't quite get gcc to emit the alias correctly, so asm-alias it is :/ */ +#define DEFINE_MTYPE(group, name, desc) \ + DEFINE_MTYPE_ATTR(group, name, , desc) \ + __asm__(".equiv MTYPE_" #name ", _mt_" #name "\n\t" \ + ".global MTYPE_" #name "\n"); \ + /* end */ +/* and this one's borked on clang, it drops static on aliases :/, so... asm */ #define DEFINE_MTYPE_STATIC(group, name, desc) \ DEFINE_MTYPE_ATTR(group, name, static, desc) \ - static struct memtype *const MTYPE_##name = &_mt_##name; + extern struct memtype MTYPE_##name[1]; \ + __asm__(".equiv MTYPE_" #name ", _mt_" #name "\n"); \ + /* end */ DECLARE_MGROUP(LIB) DECLARE_MTYPE(TMP) diff --git a/lib/ntop.c b/lib/ntop.c index d47a0b697a..066e10e3e4 100644 --- a/lib/ntop.c +++ b/lib/ntop.c @@ -81,7 +81,7 @@ static inline void puthex(uint16_t word, char **posx) const char *frr_inet_ntop(int af, const void * restrict src, char * restrict dst, socklen_t size) - __attribute__((flatten)) DSO_SELF OPTIMIZE; + __attribute__((flatten)) OPTIMIZE; const char *frr_inet_ntop(int af, const void * restrict src, char * restrict dst, socklen_t size) @@ -170,5 +170,5 @@ inet4: * as frr_inet_ntop (to avoid confusion while debugging) */ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) - __attribute__((alias ("frr_inet_ntop"))) DSO_SELF; + __attribute__((alias ("frr_inet_ntop"))); #endif diff --git a/lib/plist.c b/lib/plist.c index 54ea742c66..1ba8982499 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -750,6 +750,7 @@ enum prefix_list_type prefix_list_apply_which_prefix( if (pbest == NULL) return PREFIX_DENY; + pbest->hitcnt++; return pbest->type; } diff --git a/lib/prefix.c b/lib/prefix.c index 134d9cf908..7abeebcd09 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1329,13 +1329,29 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size) { const struct prefix *p = pu.p; char buf[PREFIX2STR_BUFFER]; + int byte, tmp, a, b; + bool z = false; + size_t l; switch (p->family) { case AF_INET: case AF_INET6: - snprintf(str, size, "%s/%d", inet_ntop(p->family, &p->u.prefix, - buf, PREFIX2STR_BUFFER), - p->prefixlen); + inet_ntop(p->family, &p->u.prefix, buf, sizeof(buf)); + l = strlen(buf); + buf[l++] = '/'; + byte = p->prefixlen; + if ((tmp = p->prefixlen - 100) >= 0) { + buf[l++] = '1'; + z = true; + byte = tmp; + } + b = byte % 10; + a = byte / 10; + if (a || z) + buf[l++] = '0' + a; + buf[l++] = '0' + b; + buf[l] = '\0'; + strlcpy(str, buf, size); break; case AF_ETHERNET: @@ -1349,11 +1365,11 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size) break; case AF_FLOWSPEC: - sprintf(str, "FS prefix"); + strlcpy(str, "FS prefix", size); break; default: - sprintf(str, "UNK prefix"); + strlcpy(str, "UNK prefix", size); break; } diff --git a/lib/routemap.c b/lib/routemap.c index 9336154b1a..47cc2e294a 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -688,7 +688,7 @@ static unsigned int route_map_dep_hash_make_key(const void *p); static void route_map_clear_all_references(char *rmap_name); static void route_map_rule_delete(struct route_map_rule_list *, struct route_map_rule *); -static int rmap_debug = 0; +static bool rmap_debug; static void route_map_index_delete(struct route_map_index *, int); @@ -739,6 +739,9 @@ static struct route_map *route_map_add(const char *name) (*route_map_master.add_hook)(name); route_map_notify_dependencies(name, RMAP_EVENT_CALL_ADDED); } + + if (rmap_debug) + zlog_debug("Add route-map %s", name); return map; } @@ -757,6 +760,9 @@ static void route_map_free_map(struct route_map *map) while ((index = map->head) != NULL) route_map_index_delete(index, 0); + if (rmap_debug) + zlog_debug("Deleting route-map %s", map->name); + list = &route_map_master; QOBJ_UNREG(map); @@ -921,6 +927,24 @@ static const char *route_map_type_str(enum route_map_type type) return ""; } +static const char *route_map_result_str(route_map_result_t res) +{ + switch (res) { + case RMAP_MATCH: + return "match"; + case RMAP_DENYMATCH: + return "deny"; + case RMAP_NOMATCH: + return "no match"; + case RMAP_ERROR: + return "error"; + case RMAP_OKAY: + return "okay"; + } + + return "invalid"; +} + static int route_map_empty(struct route_map *map) { if (map->head == NULL && map->tail == NULL) @@ -1066,6 +1090,10 @@ static void route_map_index_delete(struct route_map_index *index, int notify) QOBJ_UNREG(index); + if (rmap_debug) + zlog_debug("Deleting route-map %s sequence %d", + index->map->name, index->pref); + /* Free route match. */ while ((rule = index->match_list.head) != NULL) route_map_rule_delete(&index->match_list, rule); @@ -1152,6 +1180,11 @@ route_map_index_add(struct route_map *map, enum route_map_type type, int pref) (*route_map_master.event_hook)(map->name); route_map_notify_dependencies(map->name, RMAP_EVENT_CALL_ADDED); } + + if (rmap_debug) + zlog_debug("Route-map %s add sequence %d, type: %s", + map->name, pref, route_map_type_str(type)); + return index; } @@ -1612,6 +1645,7 @@ route_map_result_t route_map_apply(struct route_map *map, int ret = 0; struct route_map_index *index; struct route_map_rule *set; + char buf[PREFIX_STRLEN]; if (recursion > RMAP_RECURSION_LIMIT) { flog_warn( @@ -1622,8 +1656,10 @@ route_map_result_t route_map_apply(struct route_map *map, return RMAP_DENYMATCH; } - if (map == NULL) - return RMAP_DENYMATCH; + if (map == NULL) { + ret = RMAP_DENYMATCH; + goto route_map_apply_end; + } map->applied++; for (index = map->head; index; index = index->next) { @@ -1632,6 +1668,13 @@ route_map_result_t route_map_apply(struct route_map *map, ret = route_map_apply_match(&index->match_list, prefix, type, object); + if (rmap_debug) { + zlog_debug("Route-map: %s, sequence: %d, prefix: %s, result: %s", + map->name, index->pref, + prefix2str(prefix, buf, sizeof(buf)), + route_map_result_str(ret)); + } + /* Now we apply the matrix from above */ if (ret == RMAP_NOMATCH) /* 'cont' from matrix - continue to next route-map @@ -1666,12 +1709,12 @@ route_map_result_t route_map_apply(struct route_map *map, /* If nextrm returned 'deny', finish. */ if (ret == RMAP_DENYMATCH) - return ret; + goto route_map_apply_end; } switch (index->exitpolicy) { case RMAP_EXIT: - return ret; + goto route_map_apply_end; case RMAP_NEXT: continue; case RMAP_GOTO: { @@ -1686,19 +1729,30 @@ route_map_result_t route_map_apply(struct route_map *map, } if (next == NULL) { /* No clauses match! */ - return ret; + goto route_map_apply_end; } } } } else if (index->type == RMAP_DENY) /* 'deny' */ { - return RMAP_DENYMATCH; + ret = RMAP_DENYMATCH; + goto route_map_apply_end; } } } /* Finally route-map does not match at all. */ - return RMAP_DENYMATCH; + ret = RMAP_DENYMATCH; + +route_map_apply_end: + if (rmap_debug) { + zlog_debug("Route-map: %s, prefix: %s, result: %s", + (map ? map->name : "null"), + prefix2str(prefix, buf, sizeof(buf)), + route_map_result_str(ret)); + } + + return (ret); } void route_map_add_hook(void (*func)(const char *)) @@ -1835,8 +1889,8 @@ static int route_map_dep_update(struct hash *dephash, const char *dep_name, case RMAP_EVENT_CALL_ADDED: case RMAP_EVENT_FILTER_ADDED: if (rmap_debug) - zlog_debug("%s: Adding dependency for %s in %s", - __FUNCTION__, dep_name, rmap_name); + zlog_debug("Adding dependency for filter %s in route-map %s", + dep_name, rmap_name); dep = (struct route_map_dep *)hash_get( dephash, dname, route_map_dep_hash_alloc); if (!dep) { @@ -1864,8 +1918,8 @@ static int route_map_dep_update(struct hash *dephash, const char *dep_name, case RMAP_EVENT_CALL_DELETED: case RMAP_EVENT_FILTER_DELETED: if (rmap_debug) - zlog_debug("%s: Deleting dependency for %s in %s", - __FUNCTION__, dep_name, rmap_name); + zlog_debug("Deleting dependency for filter %s in route-map %s", + dep_name, rmap_name); dep = (struct route_map_dep *)hash_get(dephash, dname, NULL); if (!dep) { goto out; @@ -1979,8 +2033,7 @@ static void route_map_process_dependency(struct hash_bucket *bucket, void *data) rmap_name = dep_data->rname; if (rmap_debug) - zlog_debug("%s: Notifying %s of dependency", - __FUNCTION__, rmap_name); + zlog_debug("Notifying %s of dependency", rmap_name); if (route_map_master.event_hook) (*route_map_master.event_hook)(rmap_name); } @@ -2027,6 +2080,8 @@ void route_map_notify_dependencies(const char *affected_name, if (!dep->this_hash) dep->this_hash = upd8_hash; + if (rmap_debug) + zlog_debug("Filter %s updated", dep->dep_name); hash_iterate(dep->dep_rmap_hash, route_map_process_dependency, (void *)event); } @@ -3006,6 +3061,30 @@ DEFUN (no_rmap_description, return CMD_SUCCESS; } +DEFUN (debug_rmap, + debug_rmap_cmd, + "debug route-map", + DEBUG_STR + "Debug option set for route-maps\n") +{ + rmap_debug = true; + return CMD_SUCCESS; +} + +DEFUN (no_debug_rmap, + no_debug_rmap_cmd, + "no debug route-map", + NO_STR + DEBUG_STR + "Debug option set for route-maps\n") +{ + rmap_debug = false; + return CMD_SUCCESS; +} + +/* Debug node. */ +static struct cmd_node rmap_debug_node = {RMAP_DEBUG_NODE, "", 1}; + /* Configuration write function. */ static int route_map_config_write(struct vty *vty) { @@ -3051,6 +3130,18 @@ static int route_map_config_write(struct vty *vty) return write; } +static int rmap_config_write_debug(struct vty *vty) +{ + int write = 0; + + if (rmap_debug) { + vty_out(vty, "debug route-map\n"); + write++; + } + + return write; +} + /* Route map node structure. */ static struct cmd_node rmap_node = {RMAP_NODE, "%s(config-route-map)# ", 1}; @@ -3164,15 +3255,22 @@ void route_map_init(void) cmd_variable_handler_register(rmap_var_handlers); + rmap_debug = false; + /* Install route map top node. */ install_node(&rmap_node, route_map_config_write); + install_node(&rmap_debug_node, rmap_config_write_debug); + /* Install route map commands. */ install_default(RMAP_NODE); install_element(CONFIG_NODE, &route_map_cmd); install_element(CONFIG_NODE, &no_route_map_cmd); install_element(CONFIG_NODE, &no_route_map_all_cmd); + install_element(CONFIG_NODE, &debug_rmap_cmd); + install_element(CONFIG_NODE, &no_debug_rmap_cmd); + /* Install the on-match stuff */ install_element(RMAP_NODE, &route_map_cmd); install_element(RMAP_NODE, &rmap_onmatch_next_cmd); @@ -3196,6 +3294,9 @@ void route_map_init(void) install_element(ENABLE_NODE, &rmap_show_name_cmd); install_element(ENABLE_NODE, &rmap_show_unused_cmd); + install_element(ENABLE_NODE, &debug_rmap_cmd); + install_element(ENABLE_NODE, &no_debug_rmap_cmd); + install_element(RMAP_NODE, &match_interface_cmd); install_element(RMAP_NODE, &no_match_interface_cmd); diff --git a/lib/sbuf.c b/lib/sbuf.c index 03a2be3e09..c04af153b1 100644 --- a/lib/sbuf.c +++ b/lib/sbuf.c @@ -22,6 +22,7 @@ */ #include <zebra.h> +#include "printfrr.h" #include "sbuf.h" #include "memory.h" @@ -68,7 +69,7 @@ void sbuf_push(struct sbuf *buf, int indent, const char *format, ...) written1 = indent; va_start(args, format); - written2 = vsnprintf(NULL, 0, format, args); + written2 = vsnprintfrr(NULL, 0, format, args); va_end(args); new_size = buf->size; @@ -92,8 +93,8 @@ void sbuf_push(struct sbuf *buf, int indent, const char *format, ...) buf->pos = buf->size; va_start(args, format); - written = vsnprintf(buf->buf + buf->pos, buf->size - buf->pos, format, - args); + written = vsnprintfrr(buf->buf + buf->pos, buf->size - buf->pos, + format, args); va_end(args); if (written >= 0) diff --git a/lib/sbuf.h b/lib/sbuf.h index b1518a3aa8..9f0311006d 100644 --- a/lib/sbuf.h +++ b/lib/sbuf.h @@ -78,7 +78,7 @@ const char *sbuf_buf(struct sbuf *buf); void sbuf_free(struct sbuf *buf); #include "lib/log.h" void sbuf_push(struct sbuf *buf, int indent, const char *format, ...) - PRINTF_ATTRIBUTE(3, 4); + PRINTFRR(3, 4); #ifdef __cplusplus } diff --git a/lib/subdir.am b/lib/subdir.am index 4e6adced74..8b6cbe2aeb 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -3,7 +3,7 @@ # lib_LTLIBRARIES += lib/libfrr.la lib_libfrr_la_LDFLAGS = -version-info 0:0:0 -Xlinker -e_libfrr_version -lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) +lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(LIBM) lib_libfrr_la_SOURCES = \ lib/agg_table.c \ @@ -165,6 +165,7 @@ pkginclude_HEADERS += \ lib/graph.h \ lib/hash.h \ lib/hook.h \ + lib/iana_afi.h \ lib/id_alloc.h \ lib/if.h \ lib/if_rmap.h \ @@ -340,8 +341,10 @@ noinst_PROGRAMS += \ if BUILD_CLIPPY noinst_PROGRAMS += lib/clippy else -$(HOSTTOOLS)lib/clippy: - @$(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/route_types.h lib/clippy +if HOSTTOOLS_CLIPPY +$(CLIPPY): + @$(MAKE) -C $(top_builddir)/hosttools lib/route_types.h lib/clippy +endif endif lib_grammar_sandbox_SOURCES = \ @@ -372,13 +375,11 @@ am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY)) am__v_CLIPPY_0 = @echo " CLIPPY " $@; am__v_CLIPPY_1 = -CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py +CLIPPY_DEPS = $(CLIPPY) $(top_srcdir)/python/clidef.py SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h .pb.cc .grpc.pb.cc .c_clippy.c: - @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || \ - $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; } - $(AM_V_CLIPPY) $(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $< + $(AM_V_CLIPPY) $(CLIPPY) $(top_srcdir)/python/clidef.py -o $@ $< ## automake's "ylwrap" is a great piece of GNU software... not. .l.c: diff --git a/lib/table.c b/lib/table.c index 728615c776..1a89a95f4f 100644 --- a/lib/table.c +++ b/lib/table.c @@ -28,7 +28,7 @@ #include "memory.h" #include "sockunion.h" -DEFINE_MTYPE(LIB, ROUTE_TABLE, "Route table") +DEFINE_MTYPE_STATIC(LIB, ROUTE_TABLE, "Route table") DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node") static void route_table_free(struct route_table *); diff --git a/lib/table.h b/lib/table.h index eefd992546..57b65ac4ba 100644 --- a/lib/table.h +++ b/lib/table.h @@ -31,7 +31,6 @@ extern "C" { #endif -DECLARE_MTYPE(ROUTE_TABLE) DECLARE_MTYPE(ROUTE_NODE) /* diff --git a/lib/termtable.c b/lib/termtable.c index 01468b8203..b59c1118f8 100644 --- a/lib/termtable.c +++ b/lib/termtable.c @@ -20,6 +20,7 @@ #include <zebra.h> #include <stdio.h> +#include "printfrr.h" #include "memory.h" #include "termtable.h" @@ -134,6 +135,7 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i, { assert(i >= -1 && i < tt->nrows); + char shortbuf[256]; char *res, *orig, *section; struct ttable_cell *row; int col = 0; @@ -158,9 +160,7 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i, /* CALLOC a block of cells */ row = XCALLOC(MTYPE_TTABLE, tt->ncols * sizeof(struct ttable_cell)); - res = NULL; - vasprintf(&res, format, ap); - + res = vasnprintfrr(MTYPE_TMP, shortbuf, sizeof(shortbuf), format, ap); orig = res; while (res && col < tt->ncols) { @@ -170,7 +170,8 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i, col++; } - free(orig); + if (orig != shortbuf) + XFREE(MTYPE_TMP, orig); /* insert row */ if (i == -1 || i == tt->nrows) diff --git a/lib/termtable.h b/lib/termtable.h index 491010a856..4f7c595ce2 100644 --- a/lib/termtable.h +++ b/lib/termtable.h @@ -137,8 +137,7 @@ void ttable_cell_del(struct ttable_cell *cell); * columns were specified */ struct ttable_cell *ttable_insert_row(struct ttable *tt, unsigned int row, - const char *format, ...) - PRINTF_ATTRIBUTE(3, 4); + const char *format, ...) PRINTFRR(3, 4); /** * Inserts a new row at the end of the table. * @@ -164,7 +163,7 @@ struct ttable_cell *ttable_insert_row(struct ttable *tt, unsigned int row, * columns were specified */ struct ttable_cell *ttable_add_row(struct ttable *tt, const char *format, ...) - PRINTF_ATTRIBUTE(2, 3); + PRINTFRR(2, 3); /** * Removes a row from the table. diff --git a/lib/thread.c b/lib/thread.c index 7489be5c2d..fc2de09df0 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -307,6 +307,7 @@ static void show_thread_poll_helper(struct vty *vty, struct thread_master *m) { const char *name = m->name ? m->name : "main"; char underline[strlen(name) + 1]; + struct thread *thread; uint32_t i; memset(underline, '-', sizeof(underline)); @@ -316,11 +317,31 @@ static void show_thread_poll_helper(struct vty *vty, struct thread_master *m) vty_out(vty, "----------------------%s\n", underline); vty_out(vty, "Count: %u/%d\n", (uint32_t)m->handler.pfdcount, m->fd_limit); - for (i = 0; i < m->handler.pfdcount; i++) - vty_out(vty, "\t%6d fd:%6d events:%2d revents:%2d\n", i, - m->handler.pfds[i].fd, - m->handler.pfds[i].events, + for (i = 0; i < m->handler.pfdcount; i++) { + vty_out(vty, "\t%6d fd:%6d events:%2d revents:%2d\t\t", i, + m->handler.pfds[i].fd, m->handler.pfds[i].events, m->handler.pfds[i].revents); + + if (m->handler.pfds[i].events & POLLIN) { + thread = m->read[m->handler.pfds[i].fd]; + + if (!thread) + vty_out(vty, "ERROR "); + else + vty_out(vty, "%s ", thread->funcname); + } else + vty_out(vty, " "); + + if (m->handler.pfds[i].events & POLLOUT) { + thread = m->write[m->handler.pfds[i].fd]; + + if (!thread) + vty_out(vty, "ERROR\n"); + else + vty_out(vty, "%s\n", thread->funcname); + } else + vty_out(vty, "\n"); + } } DEFUN (show_thread_poll, @@ -756,6 +777,7 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m, debugargdef) { struct thread *thread = NULL; + struct thread **thread_array; assert(fd >= 0 && fd < m->fd_limit); pthread_mutex_lock(&m->mtx); @@ -770,11 +792,25 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m, /* default to a new pollfd */ nfds_t queuepos = m->handler.pfdcount; + if (dir == THREAD_READ) + thread_array = m->read; + else + thread_array = m->write; + /* if we already have a pollfd for our file descriptor, find and * use it */ for (nfds_t i = 0; i < m->handler.pfdcount; i++) if (m->handler.pfds[i].fd == fd) { queuepos = i; + +#ifdef DEV_BUILD + /* + * What happens if we have a thread already + * created for this event? + */ + if (thread_array[fd]) + assert(!"Thread already scheduled for file descriptor"); +#endif break; } @@ -794,10 +830,7 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m, pthread_mutex_lock(&thread->mtx); { thread->u.fd = fd; - if (dir == THREAD_READ) - m->read[thread->u.fd] = thread; - else - m->write[thread->u.fd] = thread; + thread_array[thread->u.fd] = thread; } pthread_mutex_unlock(&thread->mtx); @@ -1238,12 +1271,31 @@ static struct thread *thread_run(struct thread_master *m, struct thread *thread, } static int thread_process_io_helper(struct thread_master *m, - struct thread *thread, short state, int pos) + struct thread *thread, short state, + short actual_state, int pos) { struct thread **thread_array; - if (!thread) + /* + * poll() clears the .events field, but the pollfd array we + * pass to poll() is a copy of the one used to schedule threads. + * We need to synchronize state between the two here by applying + * the same changes poll() made on the copy of the "real" pollfd + * array. + * + * This cleans up a possible infinite loop where we refuse + * to respond to a poll event but poll is insistent that + * we should. + */ + m->handler.pfds[pos].events &= ~(state); + + if (!thread) { + if ((actual_state & (POLLHUP|POLLIN)) != POLLHUP) + flog_err(EC_LIB_NO_THREAD, + "Attempting to process an I/O event but for fd: %d(%d) no thread to handle this!\n", + m->handler.pfds[pos].fd, actual_state); return 0; + } if (thread->type == THREAD_READ) thread_array = m->read; @@ -1253,9 +1305,7 @@ static int thread_process_io_helper(struct thread_master *m, thread_array[thread->u.fd] = NULL; thread_list_add_tail(&m->ready, thread); thread->type = THREAD_READY; - /* if another pthread scheduled this file descriptor for the event we're - * responding to, no problem; we're getting to it now */ - thread->master->handler.pfds[pos].events &= ~(state); + return 1; } @@ -1291,12 +1341,13 @@ static void thread_process_io(struct thread_master *m, unsigned int num) * there's no need to update it. Similarily, barring deletion, * the fd * should still be a valid index into the master's pfds. */ - if (pfds[i].revents & (POLLIN | POLLHUP)) + if (pfds[i].revents & (POLLIN | POLLHUP)) { thread_process_io_helper(m, m->read[pfds[i].fd], POLLIN, - i); + pfds[i].revents, i); + } if (pfds[i].revents & POLLOUT) thread_process_io_helper(m, m->write[pfds[i].fd], - POLLOUT, i); + POLLOUT, pfds[i].revents, i); /* if one of our file descriptors is garbage, remove the same * from diff --git a/lib/typerb.c b/lib/typerb.c index d361e7651e..4c48d6434f 100644 --- a/lib/typerb.c +++ b/lib/typerb.c @@ -41,6 +41,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "typerb.h" #define RB_BLACK 0 diff --git a/lib/typesafe.c b/lib/typesafe.c index 47a6d0af48..f2ca67b7c6 100644 --- a/lib/typesafe.c +++ b/lib/typesafe.c @@ -14,6 +14,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <string.h> @@ -105,8 +105,8 @@ void vty_frame(struct vty *vty, const char *format, ...) va_list args; va_start(args, format); - vsnprintf(vty->frame + vty->frame_pos, - sizeof(vty->frame) - vty->frame_pos, format, args); + vsnprintfrr(vty->frame + vty->frame_pos, + sizeof(vty->frame) - vty->frame_pos, format, args); vty->frame_pos = strlen(vty->frame); va_end(args); } @@ -2289,6 +2289,7 @@ static void vty_read_file(struct nb_config *config, FILE *confp) vty->wfd = STDERR_FILENO; vty->type = VTY_FILE; vty->node = CONFIG_NODE; + vty->config = true; if (config) vty->candidate_config = config; else { @@ -302,8 +302,8 @@ extern struct vty *vty_stdio(void (*atclose)(int isexit)); * - vty_endframe() clears the buffer without printing it, and prints an * extra string if the buffer was empty before (for context-end markers) */ -extern int vty_out(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3); -extern void vty_frame(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3); +extern int vty_out(struct vty *, const char *, ...) PRINTFRR(2, 3); +extern void vty_frame(struct vty *, const char *, ...) PRINTFRR(2, 3); extern void vty_endframe(struct vty *, const char *); bool vty_set_include(struct vty *vty, const char *regexp); diff --git a/lib/yang.c b/lib/yang.c index 2f9a9aa5a3..674f3610d6 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -27,8 +27,8 @@ #include <libyang/user_types.h> -DEFINE_MTYPE(LIB, YANG_MODULE, "YANG module") -DEFINE_MTYPE(LIB, YANG_DATA, "YANG data structure") +DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module") +DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure") /* libyang container. */ struct ly_ctx *ly_native_ctx; diff --git a/lib/yang.h b/lib/yang.h index 6f8c84ab64..322c74c76a 100644 --- a/lib/yang.h +++ b/lib/yang.h @@ -33,9 +33,6 @@ extern "C" { #endif -DECLARE_MTYPE(YANG_MODULE) -DECLARE_MTYPE(YANG_DATA) - /* Maximum XPath length. */ #define XPATH_MAXLEN 256 diff --git a/lib/zebra.h b/lib/zebra.h index 2f9ada09be..22239f8e60 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -244,13 +244,6 @@ size_t strlcpy(char *__restrict dest, const char *__restrict src, size_t destsize); #endif -/* GCC have printf type attribute check. */ -#ifdef __GNUC__ -#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) -#else -#define PRINTF_ATTRIBUTE(a,b) -#endif /* __GNUC__ */ - /* * RFC 3542 defines several macros for using struct cmsghdr. * Here, we define those that are not present @@ -373,35 +366,6 @@ typedef enum { SAFI_MAX = 8 } safi_t; -/* - * The above AFI and SAFI definitions are for internal use. The protocol - * definitions (IANA values) as for example used in BGP protocol packets - * are defined below and these will get mapped to/from the internal values - * in the appropriate places. - * The rationale is that the protocol (IANA) values may be sparse and are - * not optimal for use in data-structure sizing. - * Note: Only useful (i.e., supported) values are defined below. - */ -typedef enum { - IANA_AFI_RESERVED = 0, - IANA_AFI_IPV4 = 1, - IANA_AFI_IPV6 = 2, - IANA_AFI_L2VPN = 25, - IANA_AFI_IPMR = 128, - IANA_AFI_IP6MR = 129 -} iana_afi_t; - -typedef enum { - IANA_SAFI_RESERVED = 0, - IANA_SAFI_UNICAST = 1, - IANA_SAFI_MULTICAST = 2, - IANA_SAFI_LABELED_UNICAST = 4, - IANA_SAFI_ENCAP = 7, - IANA_SAFI_EVPN = 70, - IANA_SAFI_MPLS_VPN = 128, - IANA_SAFI_FLOWSPEC = 133 -} iana_safi_t; - /* Default Administrative Distance of each protocol. */ #define ZEBRA_KERNEL_DISTANCE_DEFAULT 0 #define ZEBRA_CONNECT_DISTANCE_DEFAULT 0 @@ -439,76 +403,4 @@ typedef uint32_t route_tag_t; #define ROUTE_TAG_MAX UINT32_MAX #define ROUTE_TAG_PRI PRIu32 -static inline afi_t afi_iana2int(iana_afi_t afi) -{ - switch (afi) { - case IANA_AFI_IPV4: - return AFI_IP; - case IANA_AFI_IPV6: - return AFI_IP6; - case IANA_AFI_L2VPN: - return AFI_L2VPN; - default: - return AFI_MAX; - } -} - -static inline iana_afi_t afi_int2iana(afi_t afi) -{ - switch (afi) { - case AFI_IP: - return IANA_AFI_IPV4; - case AFI_IP6: - return IANA_AFI_IPV6; - case AFI_L2VPN: - return IANA_AFI_L2VPN; - default: - return IANA_AFI_RESERVED; - } -} - -static inline safi_t safi_iana2int(iana_safi_t safi) -{ - switch (safi) { - case IANA_SAFI_UNICAST: - return SAFI_UNICAST; - case IANA_SAFI_MULTICAST: - return SAFI_MULTICAST; - case IANA_SAFI_MPLS_VPN: - return SAFI_MPLS_VPN; - case IANA_SAFI_ENCAP: - return SAFI_ENCAP; - case IANA_SAFI_EVPN: - return SAFI_EVPN; - case IANA_SAFI_LABELED_UNICAST: - return SAFI_LABELED_UNICAST; - case IANA_SAFI_FLOWSPEC: - return SAFI_FLOWSPEC; - default: - return SAFI_MAX; - } -} - -static inline iana_safi_t safi_int2iana(safi_t safi) -{ - switch (safi) { - case SAFI_UNICAST: - return IANA_SAFI_UNICAST; - case SAFI_MULTICAST: - return IANA_SAFI_MULTICAST; - case SAFI_MPLS_VPN: - return IANA_SAFI_MPLS_VPN; - case SAFI_ENCAP: - return IANA_SAFI_ENCAP; - case SAFI_EVPN: - return IANA_SAFI_EVPN; - case SAFI_LABELED_UNICAST: - return IANA_SAFI_LABELED_UNICAST; - case SAFI_FLOWSPEC: - return IANA_SAFI_FLOWSPEC; - default: - return IANA_SAFI_RESERVED; - } -} - #endif /* _ZEBRA_H */ diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index ab2d5ae584..bb7e97bf7b 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -210,6 +210,40 @@ 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 external_info *ei = object; + + if (type == RMAP_OSPF && prefix->family == AF_INET) { + ei = (struct external_info *)object; + if (!ei) + return RMAP_DENYMATCH; + + if (ei->nexthop.s_addr == INADDR_ANY && !ei->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 address IP_ACCESS_LIST' */ /* Match function should return 1 if match is success else return zero. */ @@ -566,6 +600,9 @@ void ospf_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_tag_hook(generic_match_add); route_map_no_match_tag_hook(generic_match_delete); @@ -579,6 +616,7 @@ void ospf_route_map_init(void) route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd); route_map_install_match(&route_match_ip_address_cmd); route_map_install_match(&route_match_ip_address_prefix_list_cmd); + route_map_install_match(&route_match_ip_next_hop_type_cmd); route_map_install_match(&route_match_interface_cmd); route_map_install_match(&route_match_tag_cmd); diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 296a05bdf1..f5fe51d547 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -879,6 +879,9 @@ static void ospf_spf_next(struct vertex *v, struct ospf *ospf, "Invalid LSA link type %d", type); continue; } + + /* step (d) below */ + distance = v->distance + ntohs(l->m[0].metric); } else { /* In case of V is Network-LSA. */ r = (struct in_addr *)p; @@ -892,6 +895,9 @@ static void ospf_spf_next(struct vertex *v, struct ospf *ospf, zlog_debug("found Router LSA %s", inet_ntoa(w_lsa->data->id)); } + + /* step (d) below */ + distance = v->distance; } /* (b cont.) If the LSA does not exist, or its LS age is equal @@ -929,11 +935,7 @@ static void ospf_spf_next(struct vertex *v, struct ospf *ospf, vertex V and the advertised cost of the link between vertices V and W. If D is: */ - /* calculate link cost D. */ - if (v->lsa->type == OSPF_ROUTER_LSA) - distance = v->distance + ntohs(l->m[0].metric); - else /* v is not a Router-LSA */ - distance = v->distance; + /* calculate link cost D -- moved above */ /* Is there already vertex W in candidate list? */ if (w_lsa->stat == LSA_SPF_NOT_EXPLORED) { diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index 4ba8d08fe3..266d3ffcf5 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -19,6 +19,11 @@ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, * MA 02110-1301 USA */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "if.h" #include "pimd.h" #include "pim_iface.h" diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 18e84fef23..c6617d9d21 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -8717,9 +8717,17 @@ DEFUN (no_ip_pim_ucast_bsm, #if HAVE_BFDD > 0 DEFUN_HIDDEN( + ip_pim_bfd_param, + ip_pim_bfd_param_cmd, + "ip pim bfd (2-255) (50-60000) (50-60000)", + IP_STR + PIM_STR + "Enables BFD support\n" + "Detect Multiplier\n" + "Required min receive interval\n" + "Desired min transmit interval\n") #else DEFUN( -#endif /* HAVE_BFDD */ ip_pim_bfd_param, ip_pim_bfd_param_cmd, "ip pim bfd (2-255) (50-60000) (50-60000)", @@ -8729,6 +8737,7 @@ DEFUN( "Detect Multiplier\n" "Required min receive interval\n" "Desired min transmit interval\n") +#endif /* HAVE_BFDD */ { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 9b242e9be5..3fb3da8f44 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -613,6 +613,10 @@ static int on_ifjoin_expiry_timer(struct thread *t) ch = THREAD_ARG(t); + if (PIM_DEBUG_TRACE) + zlog_debug("%s: ifchannel %s expiry timer", __PRETTY_FUNCTION__, + ch->sg_str); + ifjoin_to_noinfo(ch, true); /* ch may have been deleted */ diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index bc0460fa03..d9b940bba7 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -332,7 +332,8 @@ void igmp_source_free(struct igmp_source *source) static void source_channel_oil_detach(struct igmp_source *source) { if (source->source_channel_oil) { - pim_channel_oil_del(source->source_channel_oil); + pim_channel_oil_del(source->source_channel_oil, + __PRETTY_FUNCTION__); source->source_channel_oil = NULL; } } diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index ca05824347..2bdec12cd1 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -203,7 +203,8 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp, * and causing us to consider them. */ c_oil = pim_channel_oil_add(pim_ifp->pim, &sg, - pim_ifp->mroute_vif_index); + pim_ifp->mroute_vif_index, + __PRETTY_FUNCTION__); pim_mroute_add(c_oil, __PRETTY_FUNCTION__); return 0; @@ -523,7 +524,8 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, if (!up->channel_oil) up->channel_oil = pim_channel_oil_add( pim_ifp->pim, &sg, - pim_ifp->mroute_vif_index); + pim_ifp->mroute_vif_index, + __PRETTY_FUNCTION__); pim_upstream_inherited_olist(pim_ifp->pim, up); if (!up->channel_oil->installed) pim_mroute_add(up->channel_oil, @@ -548,7 +550,8 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, } pim_ifp = ifp->info; - oil = pim_channel_oil_add(pim_ifp->pim, &sg, pim_ifp->mroute_vif_index); + oil = pim_channel_oil_add(pim_ifp->pim, &sg, pim_ifp->mroute_vif_index, + __PRETTY_FUNCTION__); if (!oil->installed) pim_mroute_add(oil, __PRETTY_FUNCTION__); if (pim_if_connected_to_source(ifp, sg.src)) { diff --git a/pimd/pim_msg.h b/pimd/pim_msg.h index 5f50303967..b6e2cada1f 100644 --- a/pimd/pim_msg.h +++ b/pimd/pim_msg.h @@ -66,9 +66,19 @@ struct pim_encoded_ipv4_unicast { struct in_addr addr; } __attribute__((packed)); +/* + * Encoded Group format. RFC 4601 Sec 4.9.1 + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Addr Family | Encoding Type |B| Reserved |Z| Mask Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Group multicast Address + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+... + */ struct pim_encoded_group_ipv4 { - uint8_t ne; uint8_t family; + uint8_t ne; uint8_t bidir : 1; /* Bidir bit */ uint8_t reserved : 6; /* Reserved */ uint8_t sz : 1; /* scope zone bit */ @@ -76,9 +86,20 @@ struct pim_encoded_group_ipv4 { struct in_addr addr; } __attribute__((packed)); + +/* + * Encoded Source format. RFC 4601 Sec 4.9.1 + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Source Address + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... + */ struct pim_encoded_source_ipv4 { - uint8_t ne; uint8_t family; + uint8_t ne; uint8_t bits; uint8_t mask; struct in_addr addr; diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index 22045c2d33..d4fc03e20c 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -38,18 +38,22 @@ char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size) { char *out; + struct interface *ifp; struct prefix_sg sg; int i; sg.src = c_oil->oil.mfcc_origin; sg.grp = c_oil->oil.mfcc_mcastgrp; - snprintf(buf, size, "%s IIF: %d, OIFS: ", pim_str_sg_dump(&sg), - c_oil->oil.mfcc_parent); + ifp = pim_if_find_by_vif_index(c_oil->pim, c_oil->oil.mfcc_parent); + snprintf(buf, size, "%s IIF: %s, OIFS: ", pim_str_sg_dump(&sg), + ifp ? ifp->name : "(?)"); out = buf + strlen(buf); for (i = 0; i < MAXVIFS; i++) { if (c_oil->oil.mfcc_ttls[i] != 0) { - snprintf(out, buf + size - out, "%d ", i); + ifp = pim_if_find_by_vif_index(c_oil->pim, i); + snprintf(out, buf + size - out, "%s ", + ifp ? ifp->name : "(?)"); out += strlen(out); } } @@ -144,7 +148,7 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim, struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, struct prefix_sg *sg, - int input_vif_index) + int input_vif_index, const char *name) { struct channel_oil *c_oil; struct interface *ifp; @@ -153,18 +157,23 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, if (c_oil) { if (c_oil->oil.mfcc_parent != input_vif_index) { c_oil->oil_inherited_rescan = 1; - if (PIM_DEBUG_MROUTE) + if (PIM_DEBUG_MROUTE_DETAIL) zlog_debug( - "%s: Existing channel oil %s points to %d, modifying to point at %d", - __PRETTY_FUNCTION__, - pim_str_sg_dump(sg), + "%s: Existing channel oil %pSG4 points to %d, modifying to point at %d", + __PRETTY_FUNCTION__, sg, c_oil->oil.mfcc_parent, input_vif_index); } c_oil->oil.mfcc_parent = input_vif_index; ++c_oil->oil_ref_count; - c_oil->up = pim_upstream_find( - pim, sg); // channel might be present prior to upstream + /* channel might be present prior to upstream */ + c_oil->up = pim_upstream_find(pim, sg); + + if (PIM_DEBUG_MROUTE) + zlog_debug( + "%s(%s): Existing oil for %pSG4 Ref Count: %d (Post Increment)", + __PRETTY_FUNCTION__, name, sg, + c_oil->oil_ref_count); return c_oil; } @@ -173,9 +182,8 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, if (!ifp) { /* warning only */ zlog_warn( - "%s: (S,G)=%s could not find input interface for input_vif_index=%d", - __PRETTY_FUNCTION__, pim_str_sg_dump(sg), - input_vif_index); + "%s:%s (S,G)=%pSG4 could not find input interface for input_vif_index=%d", + __PRETTY_FUNCTION__, name, sg, input_vif_index); } } @@ -193,11 +201,23 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, listnode_add_sort(pim->channel_oil_list, c_oil); + if (PIM_DEBUG_MROUTE) + zlog_debug( + "%s(%s): New oil for %pSG4 vif_index: %d Ref Count: 1 (Post Increment)", + __PRETTY_FUNCTION__, name, sg, input_vif_index); return c_oil; } -void pim_channel_oil_del(struct channel_oil *c_oil) +void pim_channel_oil_del(struct channel_oil *c_oil, const char *name) { + if (PIM_DEBUG_MROUTE) { + struct prefix_sg sg = {.src = c_oil->oil.mfcc_mcastgrp, + .grp = c_oil->oil.mfcc_origin}; + + zlog_debug( + "%s(%s): Del oil for %pSG4, Ref Count: %d (Predecrement)", + __PRETTY_FUNCTION__, name, &sg, c_oil->oil_ref_count); + } --c_oil->oil_ref_count; if (c_oil->oil_ref_count < 1) { @@ -344,10 +364,12 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif, IGMP must be protected against adding looped MFC entries created by both source and receiver attached to the same interface. See TODO T22. + We shall allow igmp to create upstream when it is DR for the intf. + Assume RP reachable via non DR. */ - if (channel_oil->up && - PIM_UPSTREAM_FLAG_TEST_ALLOW_IIF_IN_OIL( - channel_oil->up->flags)) { + if ((channel_oil->up && + PIM_UPSTREAM_FLAG_TEST_ALLOW_IIF_IN_OIL(channel_oil->up->flags)) || + ((proto_mask == PIM_OIF_FLAG_PROTO_IGMP) && PIM_I_am_DR(pim_ifp))) { allow_iif_in_oil = true; } diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index d097da6b3e..485299196d 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -113,8 +113,8 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim, struct prefix_sg *sg); struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, struct prefix_sg *sg, - int input_vif_index); -void pim_channel_oil_del(struct channel_oil *c_oil); + int input_vif_index, const char *name); +void pim_channel_oil_del(struct channel_oil *c_oil, const char *name); int pim_channel_add_oif(struct channel_oil *c_oil, struct interface *oif, uint32_t proto_mask); diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 50c68c66bd..2e6c5c7803 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -146,7 +146,7 @@ static void upstream_channel_oil_detach(struct pim_upstream *up) but upstream would not keep reference of it */ up->channel_oil->up = NULL; - pim_channel_oil_del(up->channel_oil); + pim_channel_oil_del(up->channel_oil, __PRETTY_FUNCTION__); up->channel_oil = NULL; } } @@ -740,13 +740,15 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, pim_upstream_fill_static_iif(up, incoming); pim_ifp = up->rpf.source_nexthop.interface->info; assert(pim_ifp); - up->channel_oil = pim_channel_oil_add(pim, - &up->sg, pim_ifp->mroute_vif_index); + up->channel_oil = pim_channel_oil_add(pim, &up->sg, + pim_ifp->mroute_vif_index, + __PRETTY_FUNCTION__); } else if (up->upstream_addr.s_addr == INADDR_ANY) { /* Create a dummmy channel oil with incoming ineterface MAXVIFS, * since RP is not configured */ - up->channel_oil = pim_channel_oil_add(pim, &up->sg, MAXVIFS); + up->channel_oil = pim_channel_oil_add(pim, &up->sg, MAXVIFS, + __PRETTY_FUNCTION__); } else { rpf_result = pim_rpf_update(pim, up, NULL); @@ -759,14 +761,15 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, * MAXVIFS, since RP is not reachable */ up->channel_oil = pim_channel_oil_add( - pim, &up->sg, MAXVIFS); + pim, &up->sg, MAXVIFS, __PRETTY_FUNCTION__); } if (up->rpf.source_nexthop.interface) { pim_ifp = up->rpf.source_nexthop.interface->info; if (pim_ifp) - up->channel_oil = pim_channel_oil_add(pim, - &up->sg, pim_ifp->mroute_vif_index); + up->channel_oil = pim_channel_oil_add( + pim, &up->sg, pim_ifp->mroute_vif_index, + __PRETTY_FUNCTION__); } } @@ -1524,8 +1527,9 @@ int pim_upstream_inherited_olist_decide(struct pim_instance *pim, __PRETTY_FUNCTION__, up->sg_str); } if (pim_ifp && !up->channel_oil) - up->channel_oil = pim_channel_oil_add( - pim, &up->sg, pim_ifp->mroute_vif_index); + up->channel_oil = pim_channel_oil_add(pim, &up->sg, + pim_ifp->mroute_vif_index, + __PRETTY_FUNCTION__); FOR_ALL_INTERFACES (pim->vrf, ifp) { if (!ifp->info) diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 468cd56ee5..d1935195df 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -70,10 +70,6 @@ int pim_debug_config_write(struct vty *vty) vty_out(vty, "debug igmp trace\n"); ++writes; } - if (PIM_DEBUG_IGMP_TRACE_DETAIL) { - vty_out(vty, "debug igmp trace detail\n"); - ++writes; - } if (PIM_DEBUG_MROUTE) { vty_out(vty, "debug mroute\n"); diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 25ac307ac4..4cebc43a0a 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -974,8 +974,8 @@ void igmp_source_forward_start(struct pim_instance *pim, if (!pim_rp_set_upstream_addr(pim, &vif_source, source->source_addr, sg.grp)) { /*Create a dummy channel oil */ - source->source_channel_oil = - pim_channel_oil_add(pim, &sg, MAXVIFS); + source->source_channel_oil = pim_channel_oil_add( + pim, &sg, MAXVIFS, __PRETTY_FUNCTION__); if (!source->source_channel_oil) { if (PIM_DEBUG_IGMP_TRACE) { @@ -1035,7 +1035,9 @@ void igmp_source_forward_start(struct pim_instance *pim, source_str); } source->source_channel_oil = - pim_channel_oil_add(pim, &sg, MAXVIFS); + pim_channel_oil_add( + pim, &sg, MAXVIFS, + __PRETTY_FUNCTION__); } else { @@ -1043,10 +1045,12 @@ void igmp_source_forward_start(struct pim_instance *pim, * Protect IGMP against adding looped MFC * entries created by both source and receiver * attached to the same interface. See TODO - * T22. + * T22. Block only when the intf is non DR + * DR must create upstream. */ - if (input_iface_vif_index == - pim_oif->mroute_vif_index) { + if ((input_iface_vif_index == + pim_oif->mroute_vif_index) && + !(PIM_I_am_DR(pim_oif))) { /* ignore request for looped MFC entry */ if (PIM_DEBUG_IGMP_TRACE) { @@ -1065,8 +1069,9 @@ void igmp_source_forward_start(struct pim_instance *pim, } source->source_channel_oil = - pim_channel_oil_add(pim, &sg, - input_iface_vif_index); + pim_channel_oil_add( + pim, &sg, input_iface_vif_index, + __PRETTY_FUNCTION__); if (!source->source_channel_oil) { if (PIM_DEBUG_IGMP_TRACE) { zlog_debug( @@ -1241,13 +1246,14 @@ void pim_forward_start(struct pim_ifchannel *ch) __FILE__, __PRETTY_FUNCTION__, source_str); } - up->channel_oil = pim_channel_oil_add(pim, &up->sg, - MAXVIFS); + up->channel_oil = pim_channel_oil_add( + pim, &up->sg, MAXVIFS, __PRETTY_FUNCTION__); } else { - up->channel_oil = pim_channel_oil_add(pim, &up->sg, - input_iface_vif_index); + up->channel_oil = pim_channel_oil_add( + pim, &up->sg, input_iface_vif_index, + __PRETTY_FUNCTION__); if (!up->channel_oil) { if (PIM_DEBUG_PIM_TRACE) zlog_debug( @@ -1268,8 +1274,9 @@ void pim_forward_start(struct pim_ifchannel *ch) input_iface_vif_index, up->sg_str); } - up->channel_oil = pim_channel_oil_add(pim, &up->sg, - input_iface_vif_index); + up->channel_oil = + pim_channel_oil_add(pim, &up->sg, input_iface_vif_index, + __PRETTY_FUNCTION__); if (!up->channel_oil) { if (PIM_DEBUG_PIM_TRACE) zlog_debug( diff --git a/python/clidef.py b/python/clidef.py index f8d96115bd..85464a62d4 100644 --- a/python/clidef.py +++ b/python/clidef.py @@ -37,6 +37,7 @@ class RenderHandler(object): deref = '' drop_str = False canfail = True + canassert = False class StringHandler(RenderHandler): argtype = 'const char *' @@ -44,6 +45,7 @@ class StringHandler(RenderHandler): code = Template('$varname = (argv[_i]->type == WORD_TKN) ? argv[_i]->text : argv[_i]->arg;') drop_str = True canfail = False + canassert = True class LongHandler(RenderHandler): argtype = 'long' @@ -111,6 +113,7 @@ if (argv[_i]->text[0] == 'X') { _fail = !inet_aton(argv[_i]->arg, &s__$varname.sin.sin_addr); $varname = &s__$varname; }''') + canassert = True def mix_handlers(handlers): def combine(a, b): @@ -171,6 +174,7 @@ $argblocks return CMD_WARNING; #endif #endif +$argassert return ${fnname}_magic(self, vty, argc, argv$arglist); } @@ -182,16 +186,72 @@ argblock = Template(''' $code }''') -def process_file(fn, ofd, dumpfd, all_defun): +def get_always_args(token, always_args, args = [], stack = []): + if token in stack: + return + if token.type == 'END_TKN': + for arg in list(always_args): + if arg not in args: + always_args.remove(arg) + return + + stack = stack + [token] + if token.type in handlers and token.varname is not None: + args = args + [token.varname] + for nexttkn in token.next(): + get_always_args(nexttkn, always_args, args, stack) + +class Macros(dict): + def load(self, filename): + filedata = clippy.parse(filename) + for entry in filedata['data']: + if entry['type'] != 'PREPROC': + continue + ppdir = entry['line'].lstrip().split(None, 1) + if ppdir[0] != 'define' or len(ppdir) != 2: + continue + ppdef = ppdir[1].split(None, 1) + name = ppdef[0] + if '(' in name: + continue + val = ppdef[1] if len(ppdef) == 2 else '' + + val = val.strip(' \t\n\\') + if name in self: + sys.stderr.write('warning: macro %s redefined!\n' % (name)) + self[name] = val + +def process_file(fn, ofd, dumpfd, all_defun, macros): + errors = 0 filedata = clippy.parse(fn) for entry in filedata['data']: if entry['type'].startswith('DEFPY') or (all_defun and entry['type'].startswith('DEFUN')): + if len(entry['args'][0]) != 1: + sys.stderr.write('%s:%d: DEFPY function name not parseable (%r)\n' % (fn, entry['lineno'], entry['args'][0])) + errors += 1 + continue + cmddef = entry['args'][2] - cmddef = ''.join([i[1:-1] for i in cmddef]) + cmddefx = [] + for i in cmddef: + while i in macros: + i = macros[i] + if i.startswith('"') and i.endswith('"'): + cmddefx.append(i[1:-1]) + continue + + sys.stderr.write('%s:%d: DEFPY command string not parseable (%r)\n' % (fn, entry['lineno'], cmddef)) + errors += 1 + cmddefx = None + break + if cmddefx is None: + continue + cmddef = ''.join([i for i in cmddefx]) graph = clippy.Graph(cmddef) args = OrderedDict() + always_args = set() for token, depth in clippy.graph_iterate(graph): if token.type not in handlers: continue @@ -199,6 +259,9 @@ def process_file(fn, ofd, dumpfd, all_defun): continue arg = args.setdefault(token.varname, []) arg.append(handlers[token.type](token)) + always_args.add(token.varname) + + get_always_args(graph.first(), always_args) #print('-' * 76) #pprint(entry) @@ -210,30 +273,36 @@ def process_file(fn, ofd, dumpfd, all_defun): argdecls = [] arglist = [] argblocks = [] + argassert = [] doc = [] canfail = 0 - def do_add(handler, varname, attr = ''): + def do_add(handler, basename, varname, attr = ''): argdefs.append(',\\\n\t%s %s%s' % (handler.argtype, varname, attr)) argdecls.append('\t%s\n' % (handler.decl.substitute({'varname': varname}).replace('\n', '\n\t'))) arglist.append(', %s%s' % (handler.deref, varname)) + if basename in always_args and handler.canassert: + argassert.append('''\tif (!%s) { +\t\tvty_out(vty, "Internal CLI error [%%s]\\n", "%s"); +\t\treturn CMD_WARNING; +\t}\n''' % (varname, varname)) if attr == '': at = handler.argtype if not at.startswith('const '): at = '. . . ' + at - doc.append('\t%-26s %s' % (at, varname)) + doc.append('\t%-26s %s %s' % (at, 'alw' if basename in always_args else 'opt', varname)) for varname in args.keys(): handler = mix_handlers(args[varname]) #print(varname, handler) if handler is None: continue - do_add(handler, varname) + do_add(handler, varname, varname) code = handler.code.substitute({'varname': varname}).replace('\n', '\n\t\t\t') if handler.canfail: canfail = 1 strblock = '' if not handler.drop_str: - do_add(StringHandler(None), '%s_str' % (varname), ' __attribute__ ((unused))') + do_add(StringHandler(None), varname, '%s_str' % (varname), ' __attribute__ ((unused))') strblock = '\n\t\t\t%s_str = argv[_i]->arg;' % (varname) argblocks.append(argblock.substitute({'varname': varname, 'strblock': strblock, 'code': code})) @@ -249,8 +318,11 @@ def process_file(fn, ofd, dumpfd, all_defun): params['argblocks'] = ''.join(argblocks) params['canfail'] = canfail params['nonempty'] = len(argblocks) + params['argassert'] = ''.join(argassert) ofd.write(templ.substitute(params)) + return errors + if __name__ == '__main__': import argparse @@ -274,7 +346,15 @@ if __name__ == '__main__': if args.show: dumpfd = sys.stderr - process_file(args.cfile, ofd, dumpfd, args.all_defun) + macros = Macros() + macros.load('lib/route_types.h') + macros.load('lib/command.h') + # sigh :( + macros['PROTO_REDIST_STR'] = 'FRR_REDIST_STR_ISISD' + + errors = process_file(args.cfile, ofd, dumpfd, args.all_defun, macros) + if errors != 0: + sys.exit(1) if args.o is not None: clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__), sys.executable]) diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 634fee0b30..80561f350b 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -43,6 +43,8 @@ #include "ripd/rip_debug.h" #include "ripd/rip_interface.h" +DEFINE_MTYPE_STATIC(RIPD, RIP_INTERFACE, "RIP interface") +DEFINE_MTYPE(RIPD, RIP_INTERFACE_STRING, "RIP Interface String") DEFINE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc)) DEFINE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc)) diff --git a/ripd/rip_interface.h b/ripd/rip_interface.h index 6befda0e28..715daf2e50 100644 --- a/ripd/rip_interface.h +++ b/ripd/rip_interface.h @@ -20,8 +20,11 @@ #ifndef _QUAGGA_RIP_INTERFACE_H #define _QUAGGA_RIP_INTERFACE_H +#include "memory.h" #include "zclient.h" +DECLARE_MTYPE(RIP_INTERFACE_STRING) + extern int rip_interface_down(int, struct zclient *, zebra_size_t, vrf_id_t); extern int rip_interface_up(int, struct zclient *, zebra_size_t, vrf_id_t); extern int rip_interface_add(int, struct zclient *, zebra_size_t, vrf_id_t); diff --git a/ripd/rip_memory.c b/ripd/rip_memory.c deleted file mode 100644 index 7d703a86db..0000000000 --- a/ripd/rip_memory.c +++ /dev/null @@ -1,36 +0,0 @@ -/* ripd memory type definitions - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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 this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rip_memory.h" - -DEFINE_MGROUP(RIPD, "ripd") -DEFINE_MTYPE(RIPD, RIP, "RIP structure") -DEFINE_MTYPE(RIPD, RIP_VRF_NAME, "RIP VRF name") -DEFINE_MTYPE(RIPD, RIP_INFO, "RIP route info") -DEFINE_MTYPE(RIPD, RIP_INTERFACE, "RIP interface") -DEFINE_MTYPE(RIPD, RIP_INTERFACE_STRING, "RIP Interface String") -DEFINE_MTYPE(RIPD, RIP_PEER, "RIP peer") -DEFINE_MTYPE(RIPD, RIP_OFFSET_LIST, "RIP offset list") -DEFINE_MTYPE(RIPD, RIP_DISTANCE, "RIP distance") diff --git a/ripd/rip_memory.h b/ripd/rip_memory.h deleted file mode 100644 index 1f9d8f500f..0000000000 --- a/ripd/rip_memory.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ripd memory type declarations - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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 this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _QUAGGA_RIP_MEMORY_H -#define _QUAGGA_RIP_MEMORY_H - -#include "memory.h" - -DECLARE_MGROUP(RIPD) -DECLARE_MTYPE(RIP) -DECLARE_MTYPE(RIP_VRF_NAME) -DECLARE_MTYPE(RIP_INFO) -DECLARE_MTYPE(RIP_INTERFACE) -DECLARE_MTYPE(RIP_INTERFACE_STRING) -DECLARE_MTYPE(RIP_PEER) -DECLARE_MTYPE(RIP_OFFSET_LIST) -DECLARE_MTYPE(RIP_DISTANCE) - -#endif /* _QUAGGA_RIP_MEMORY_H */ diff --git a/ripd/rip_northbound.c b/ripd/rip_northbound.c index d4fde5519b..1238d0f0fc 100644 --- a/ripd/rip_northbound.c +++ b/ripd/rip_northbound.c @@ -33,6 +33,7 @@ #include "ripd/ripd.h" #include "ripd/rip_debug.h" #include "ripd/rip_cli.h" +#include "ripd/rip_interface.h" /* * XPath: /frr-ripd:ripd/instance @@ -103,12 +104,12 @@ static int ripd_instance_destroy(enum nb_event event, static const void *ripd_instance_get_next(const void *parent_list_entry, const void *list_entry) { - const struct rip *rip = list_entry; + struct rip *rip = (struct rip *)list_entry; if (list_entry == NULL) rip = RB_MIN(rip_instance_head, &rip_instances); else - rip = RB_NEXT(rip_instance_head, (struct rip *)rip); + rip = RB_NEXT(rip_instance_head, rip); return rip; } @@ -1483,241 +1484,337 @@ const struct frr_yang_module_info frr_ripd_info = { .nodes = { { .xpath = "/frr-ripd:ripd/instance", - .cbs.create = ripd_instance_create, - .cbs.destroy = ripd_instance_destroy, - .cbs.get_next = ripd_instance_get_next, - .cbs.get_keys = ripd_instance_get_keys, - .cbs.lookup_entry = ripd_instance_lookup_entry, - .cbs.cli_show = cli_show_router_rip, + .cbs = { + .cli_show = cli_show_router_rip, + .create = ripd_instance_create, + .destroy = ripd_instance_destroy, + .get_keys = ripd_instance_get_keys, + .get_next = ripd_instance_get_next, + .lookup_entry = ripd_instance_lookup_entry, + }, }, { .xpath = "/frr-ripd:ripd/instance/allow-ecmp", - .cbs.modify = ripd_instance_allow_ecmp_modify, - .cbs.cli_show = cli_show_rip_allow_ecmp, + .cbs = { + .cli_show = cli_show_rip_allow_ecmp, + .modify = ripd_instance_allow_ecmp_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/default-information-originate", - .cbs.modify = ripd_instance_default_information_originate_modify, - .cbs.cli_show = cli_show_rip_default_information_originate, + .cbs = { + .cli_show = cli_show_rip_default_information_originate, + .modify = ripd_instance_default_information_originate_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/default-metric", - .cbs.modify = ripd_instance_default_metric_modify, - .cbs.cli_show = cli_show_rip_default_metric, + .cbs = { + .cli_show = cli_show_rip_default_metric, + .modify = ripd_instance_default_metric_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/distance/default", - .cbs.modify = ripd_instance_distance_default_modify, - .cbs.cli_show = cli_show_rip_distance, + .cbs = { + .cli_show = cli_show_rip_distance, + .modify = ripd_instance_distance_default_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/distance/source", - .cbs.create = ripd_instance_distance_source_create, - .cbs.destroy = ripd_instance_distance_source_destroy, - .cbs.cli_show = cli_show_rip_distance_source, + .cbs = { + .cli_show = cli_show_rip_distance_source, + .create = ripd_instance_distance_source_create, + .destroy = ripd_instance_distance_source_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/distance/source/distance", - .cbs.modify = ripd_instance_distance_source_distance_modify, + .cbs = { + .modify = ripd_instance_distance_source_distance_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/distance/source/access-list", - .cbs.modify = ripd_instance_distance_source_access_list_modify, - .cbs.destroy = ripd_instance_distance_source_access_list_destroy, + .cbs = { + .destroy = ripd_instance_distance_source_access_list_destroy, + .modify = ripd_instance_distance_source_access_list_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/explicit-neighbor", - .cbs.create = ripd_instance_explicit_neighbor_create, - .cbs.destroy = ripd_instance_explicit_neighbor_destroy, - .cbs.cli_show = cli_show_rip_neighbor, + .cbs = { + .cli_show = cli_show_rip_neighbor, + .create = ripd_instance_explicit_neighbor_create, + .destroy = ripd_instance_explicit_neighbor_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/network", - .cbs.create = ripd_instance_network_create, - .cbs.destroy = ripd_instance_network_destroy, - .cbs.cli_show = cli_show_rip_network_prefix, + .cbs = { + .cli_show = cli_show_rip_network_prefix, + .create = ripd_instance_network_create, + .destroy = ripd_instance_network_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/interface", - .cbs.create = ripd_instance_interface_create, - .cbs.destroy = ripd_instance_interface_destroy, - .cbs.cli_show = cli_show_rip_network_interface, + .cbs = { + .cli_show = cli_show_rip_network_interface, + .create = ripd_instance_interface_create, + .destroy = ripd_instance_interface_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/offset-list", - .cbs.create = ripd_instance_offset_list_create, - .cbs.destroy = ripd_instance_offset_list_destroy, - .cbs.cli_show = cli_show_rip_offset_list, + .cbs = { + .cli_show = cli_show_rip_offset_list, + .create = ripd_instance_offset_list_create, + .destroy = ripd_instance_offset_list_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/offset-list/access-list", - .cbs.modify = ripd_instance_offset_list_access_list_modify, + .cbs = { + .modify = ripd_instance_offset_list_access_list_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/offset-list/metric", - .cbs.modify = ripd_instance_offset_list_metric_modify, + .cbs = { + .modify = ripd_instance_offset_list_metric_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/passive-default", - .cbs.modify = ripd_instance_passive_default_modify, - .cbs.cli_show = cli_show_rip_passive_default, + .cbs = { + .cli_show = cli_show_rip_passive_default, + .modify = ripd_instance_passive_default_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/passive-interface", - .cbs.create = ripd_instance_passive_interface_create, - .cbs.destroy = ripd_instance_passive_interface_destroy, - .cbs.cli_show = cli_show_rip_passive_interface, + .cbs = { + .cli_show = cli_show_rip_passive_interface, + .create = ripd_instance_passive_interface_create, + .destroy = ripd_instance_passive_interface_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/non-passive-interface", - .cbs.create = ripd_instance_non_passive_interface_create, - .cbs.destroy = ripd_instance_non_passive_interface_destroy, - .cbs.cli_show = cli_show_rip_non_passive_interface, + .cbs = { + .cli_show = cli_show_rip_non_passive_interface, + .create = ripd_instance_non_passive_interface_create, + .destroy = ripd_instance_non_passive_interface_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/redistribute", - .cbs.create = ripd_instance_redistribute_create, - .cbs.destroy = ripd_instance_redistribute_destroy, - .cbs.apply_finish = ripd_instance_redistribute_apply_finish, - .cbs.cli_show = cli_show_rip_redistribute, + .cbs = { + .apply_finish = ripd_instance_redistribute_apply_finish, + .cli_show = cli_show_rip_redistribute, + .create = ripd_instance_redistribute_create, + .destroy = ripd_instance_redistribute_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/redistribute/route-map", - .cbs.modify = ripd_instance_redistribute_route_map_modify, - .cbs.destroy = ripd_instance_redistribute_route_map_destroy, + .cbs = { + .destroy = ripd_instance_redistribute_route_map_destroy, + .modify = ripd_instance_redistribute_route_map_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/redistribute/metric", - .cbs.modify = ripd_instance_redistribute_metric_modify, - .cbs.destroy = ripd_instance_redistribute_metric_destroy, + .cbs = { + .destroy = ripd_instance_redistribute_metric_destroy, + .modify = ripd_instance_redistribute_metric_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/static-route", - .cbs.create = ripd_instance_static_route_create, - .cbs.destroy = ripd_instance_static_route_destroy, - .cbs.cli_show = cli_show_rip_route, + .cbs = { + .cli_show = cli_show_rip_route, + .create = ripd_instance_static_route_create, + .destroy = ripd_instance_static_route_destroy, + }, }, { .xpath = "/frr-ripd:ripd/instance/timers", - .cbs.apply_finish = ripd_instance_timers_apply_finish, - .cbs.cli_show = cli_show_rip_timers, + .cbs = { + .apply_finish = ripd_instance_timers_apply_finish, + .cli_show = cli_show_rip_timers, + }, }, { .xpath = "/frr-ripd:ripd/instance/timers/flush-interval", - .cbs.modify = ripd_instance_timers_flush_interval_modify, + .cbs = { + .modify = ripd_instance_timers_flush_interval_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/timers/holddown-interval", - .cbs.modify = ripd_instance_timers_holddown_interval_modify, + .cbs = { + .modify = ripd_instance_timers_holddown_interval_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/timers/update-interval", - .cbs.modify = ripd_instance_timers_update_interval_modify, + .cbs = { + .modify = ripd_instance_timers_update_interval_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/version", - .cbs.cli_show = cli_show_rip_version, + .cbs = { + .cli_show = cli_show_rip_version, + }, }, { .xpath = "/frr-ripd:ripd/instance/version/receive", - .cbs.modify = ripd_instance_version_receive_modify, + .cbs = { + .modify = ripd_instance_version_receive_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/version/send", - .cbs.modify = ripd_instance_version_send_modify, + .cbs = { + .modify = ripd_instance_version_send_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/split-horizon", - .cbs.modify = lib_interface_rip_split_horizon_modify, - .cbs.cli_show = cli_show_ip_rip_split_horizon, + .cbs = { + .cli_show = cli_show_ip_rip_split_horizon, + .modify = lib_interface_rip_split_horizon_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast", - .cbs.modify = lib_interface_rip_v2_broadcast_modify, - .cbs.cli_show = cli_show_ip_rip_v2_broadcast, + .cbs = { + .cli_show = cli_show_ip_rip_v2_broadcast, + .modify = lib_interface_rip_v2_broadcast_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-receive", - .cbs.modify = lib_interface_rip_version_receive_modify, - .cbs.cli_show = cli_show_ip_rip_receive_version, + .cbs = { + .cli_show = cli_show_ip_rip_receive_version, + .modify = lib_interface_rip_version_receive_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-send", - .cbs.modify = lib_interface_rip_version_send_modify, - .cbs.cli_show = cli_show_ip_rip_send_version, + .cbs = { + .cli_show = cli_show_ip_rip_send_version, + .modify = lib_interface_rip_version_send_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme", - .cbs.cli_show = cli_show_ip_rip_authentication_scheme, + .cbs = { + .cli_show = cli_show_ip_rip_authentication_scheme, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode", - .cbs.modify = lib_interface_rip_authentication_scheme_mode_modify, + .cbs = { + .modify = lib_interface_rip_authentication_scheme_mode_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length", - .cbs.modify = lib_interface_rip_authentication_scheme_md5_auth_length_modify, - .cbs.destroy = lib_interface_rip_authentication_scheme_md5_auth_length_destroy, + .cbs = { + .destroy = lib_interface_rip_authentication_scheme_md5_auth_length_destroy, + .modify = lib_interface_rip_authentication_scheme_md5_auth_length_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-password", - .cbs.modify = lib_interface_rip_authentication_password_modify, - .cbs.destroy = lib_interface_rip_authentication_password_destroy, - .cbs.cli_show = cli_show_ip_rip_authentication_string, + .cbs = { + .cli_show = cli_show_ip_rip_authentication_string, + .destroy = lib_interface_rip_authentication_password_destroy, + .modify = lib_interface_rip_authentication_password_modify, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain", - .cbs.modify = lib_interface_rip_authentication_key_chain_modify, - .cbs.destroy = lib_interface_rip_authentication_key_chain_destroy, - .cbs.cli_show = cli_show_ip_rip_authentication_key_chain, + .cbs = { + .cli_show = cli_show_ip_rip_authentication_key_chain, + .destroy = lib_interface_rip_authentication_key_chain_destroy, + .modify = lib_interface_rip_authentication_key_chain_modify, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor", - .cbs.get_next = ripd_instance_state_neighbors_neighbor_get_next, - .cbs.get_keys = ripd_instance_state_neighbors_neighbor_get_keys, - .cbs.lookup_entry = ripd_instance_state_neighbors_neighbor_lookup_entry, + .cbs = { + .get_keys = ripd_instance_state_neighbors_neighbor_get_keys, + .get_next = ripd_instance_state_neighbors_neighbor_get_next, + .lookup_entry = ripd_instance_state_neighbors_neighbor_lookup_entry, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor/address", - .cbs.get_elem = ripd_instance_state_neighbors_neighbor_address_get_elem, + .cbs = { + .get_elem = ripd_instance_state_neighbors_neighbor_address_get_elem, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor/last-update", - .cbs.get_elem = ripd_instance_state_neighbors_neighbor_last_update_get_elem, + .cbs = { + .get_elem = ripd_instance_state_neighbors_neighbor_last_update_get_elem, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd", - .cbs.get_elem = ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem, + .cbs = { + .get_elem = ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd", - .cbs.get_elem = ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem, + .cbs = { + .get_elem = ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/routes/route", - .cbs.get_next = ripd_instance_state_routes_route_get_next, - .cbs.get_keys = ripd_instance_state_routes_route_get_keys, - .cbs.lookup_entry = ripd_instance_state_routes_route_lookup_entry, + .cbs = { + .get_keys = ripd_instance_state_routes_route_get_keys, + .get_next = ripd_instance_state_routes_route_get_next, + .lookup_entry = ripd_instance_state_routes_route_lookup_entry, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/routes/route/prefix", - .cbs.get_elem = ripd_instance_state_routes_route_prefix_get_elem, + .cbs = { + .get_elem = ripd_instance_state_routes_route_prefix_get_elem, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/routes/route/next-hop", - .cbs.get_elem = ripd_instance_state_routes_route_next_hop_get_elem, + .cbs = { + .get_elem = ripd_instance_state_routes_route_next_hop_get_elem, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/routes/route/interface", - .cbs.get_elem = ripd_instance_state_routes_route_interface_get_elem, + .cbs = { + .get_elem = ripd_instance_state_routes_route_interface_get_elem, + }, }, { .xpath = "/frr-ripd:ripd/instance/state/routes/route/metric", - .cbs.get_elem = ripd_instance_state_routes_route_metric_get_elem, + .cbs = { + .get_elem = ripd_instance_state_routes_route_metric_get_elem, + }, }, { .xpath = "/frr-ripd:clear-rip-route", - .cbs.rpc = clear_rip_route_rpc, + .cbs = { + .rpc = clear_rip_route_rpc, + }, }, { .xpath = NULL, diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c index 8307a95d27..776f121d59 100644 --- a/ripd/rip_offset.c +++ b/ripd/rip_offset.c @@ -29,6 +29,8 @@ #include "ripd/ripd.h" +DEFINE_MTYPE_STATIC(RIPD, RIP_OFFSET_LIST, "RIP offset list") + #define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIP_OFFSET_LIST_IN].alist_name) #define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_IN].metric) diff --git a/ripd/rip_peer.c b/ripd/rip_peer.c index 08aa61257d..4ad7309c41 100644 --- a/ripd/rip_peer.c +++ b/ripd/rip_peer.c @@ -29,6 +29,8 @@ #include "ripd/ripd.h" +DEFINE_MTYPE_STATIC(RIPD, RIP_PEER, "RIP peer") + static struct rip_peer *rip_peer_new(void) { return XCALLOC(MTYPE_RIP_PEER, sizeof(struct rip_peer)); diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c index 3216b8f89f..85d83c61dc 100644 --- a/ripd/rip_routemap.c +++ b/ripd/rip_routemap.c @@ -231,6 +231,40 @@ static 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 rip_info *rinfo; + + if (type == RMAP_RIP && prefix->family == AF_INET) { + rinfo = (struct rip_info *)object; + if (!rinfo) + return RMAP_DENYMATCH; + + if (rinfo->nh.type == NEXTHOP_TYPE_BLACKHOLE) + 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 address IP_ACCESS_LIST' */ /* Match function should return 1 if match is success else return @@ -537,6 +571,9 @@ void rip_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_metric_hook(generic_match_add); route_map_no_match_metric_hook(generic_match_delete); @@ -556,6 +593,7 @@ void rip_route_map_init(void) route_map_install_match(&route_match_interface_cmd); route_map_install_match(&route_match_ip_next_hop_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_address_cmd); route_map_install_match(&route_match_ip_address_prefix_list_cmd); route_map_install_match(&route_match_tag_cmd); diff --git a/ripd/ripd.c b/ripd/ripd.c index 3a1ffd17a6..e0ff0430f8 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -51,6 +51,12 @@ /* UDP receive buffer size */ #define RIP_UDP_RCV_BUF 41600 +DEFINE_MGROUP(RIPD, "ripd") +DEFINE_MTYPE_STATIC(RIPD, RIP, "RIP structure") +DEFINE_MTYPE_STATIC(RIPD, RIP_VRF_NAME, "RIP VRF name") +DEFINE_MTYPE_STATIC(RIPD, RIP_INFO, "RIP route info") +DEFINE_MTYPE_STATIC(RIPD, RIP_DISTANCE, "RIP distance") + /* Prototypes. */ static void rip_output_process(struct connected *, struct sockaddr_in *, int, uint8_t); diff --git a/ripd/ripd.h b/ripd/ripd.h index 44f5932fb6..7f2c3fd068 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -24,7 +24,7 @@ #include "hook.h" #include "nexthop.h" #include "distribute.h" -#include "rip_memory.h" +#include "memory.h" /* RIP version number. */ #define RIPv1 1 @@ -97,6 +97,8 @@ #define RIP_INSTANCE "/frr-ripd:ripd/instance" #define RIP_IFACE "/frr-interface:lib/interface/frr-ripd:rip" +DECLARE_MGROUP(RIPD) + /* RIP structure. */ struct rip { RB_ENTRY(rip) entry; diff --git a/ripd/subdir.am b/ripd/subdir.am index 2a63cc5229..312c1db6af 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -23,7 +23,6 @@ ripd_librip_a_SOURCES = \ ripd/rip_debug.c \ ripd/rip_errors.c \ ripd/rip_interface.c \ - ripd/rip_memory.c \ ripd/rip_offset.c \ ripd/rip_northbound.c \ ripd/rip_peer.c \ @@ -40,7 +39,6 @@ noinst_HEADERS += \ ripd/rip_debug.h \ ripd/rip_errors.h \ ripd/rip_interface.h \ - ripd/rip_memory.h \ ripd/ripd.h \ # end diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index d83f4d2791..49ed13a2c2 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -49,6 +49,8 @@ #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP #endif +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_IF, "ripng interface") + /* Static utility function. */ static void ripng_enable_apply(struct interface *); static void ripng_passive_interface_apply(struct interface *); @@ -913,7 +915,7 @@ static struct ripng_interface *ri_new(void) { struct ripng_interface *ri; - ri = XCALLOC(MTYPE_IF, sizeof(struct ripng_interface)); + ri = XCALLOC(MTYPE_RIPNG_IF, sizeof(struct ripng_interface)); /* Set default split-horizon behavior. If the interface is Frame Relay or SMDS is enabled, the default value for split-horizon is @@ -950,7 +952,7 @@ static int ripng_if_new_hook(struct interface *ifp) /* Called when interface structure deleted. */ static int ripng_if_delete_hook(struct interface *ifp) { - XFREE(MTYPE_IF, ifp->info); + XFREE(MTYPE_RIPNG_IF, ifp->info); ifp->info = NULL; return 0; } diff --git a/ripngd/ripng_memory.c b/ripngd/ripng_memory.c deleted file mode 100644 index f459566bed..0000000000 --- a/ripngd/ripng_memory.c +++ /dev/null @@ -1,35 +0,0 @@ -/* ripngd memory type definitions - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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 this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "ripng_memory.h" - -DEFINE_MGROUP(RIPNGD, "ripngd") -DEFINE_MTYPE(RIPNGD, RIPNG, "RIPng structure") -DEFINE_MTYPE(RIPNGD, RIPNG_VRF_NAME, "RIPng VRF name") -DEFINE_MTYPE(RIPNGD, RIPNG_ROUTE, "RIPng route info") -DEFINE_MTYPE(RIPNGD, RIPNG_AGGREGATE, "RIPng aggregate") -DEFINE_MTYPE(RIPNGD, RIPNG_PEER, "RIPng peer") -DEFINE_MTYPE(RIPNGD, RIPNG_OFFSET_LIST, "RIPng offset lst") -DEFINE_MTYPE(RIPNGD, RIPNG_RTE_DATA, "RIPng rte data") diff --git a/ripngd/ripng_memory.h b/ripngd/ripng_memory.h deleted file mode 100644 index 3dfc57b3ff..0000000000 --- a/ripngd/ripng_memory.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ripngd memory type declarations - * - * Copyright (C) 2015 David Lamparter - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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 this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _QUAGGA_RIPNG_MEMORY_H -#define _QUAGGA_RIPNG_MEMORY_H - -#include "memory.h" - -DECLARE_MGROUP(RIPNGD) -DECLARE_MTYPE(RIPNG) -DECLARE_MTYPE(RIPNG_VRF_NAME) -DECLARE_MTYPE(RIPNG_ROUTE) -DECLARE_MTYPE(RIPNG_AGGREGATE) -DECLARE_MTYPE(RIPNG_PEER) -DECLARE_MTYPE(RIPNG_OFFSET_LIST) -DECLARE_MTYPE(RIPNG_RTE_DATA) - -#endif /* _QUAGGA_RIPNG_MEMORY_H */ diff --git a/ripngd/ripng_nexthop.c b/ripngd/ripng_nexthop.c index 882c2fbc8c..ba6e52fdda 100644 --- a/ripngd/ripng_nexthop.c +++ b/ripngd/ripng_nexthop.c @@ -39,6 +39,8 @@ #include "ripngd/ripng_debug.h" #include "ripngd/ripng_nexthop.h" +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_RTE_DATA, "RIPng rte data") + #define DEBUG 1 #define min(a, b) ((a) < (b) ? (a) : (b)) diff --git a/ripngd/ripng_northbound.c b/ripngd/ripng_northbound.c index f8ac4a5cd5..588f6db037 100644 --- a/ripngd/ripng_northbound.c +++ b/ripngd/ripng_northbound.c @@ -105,12 +105,12 @@ static int ripngd_instance_destroy(enum nb_event event, static const void *ripngd_instance_get_next(const void *parent_list_entry, const void *list_entry) { - const struct ripng *ripng = list_entry; + struct ripng *ripng = (struct ripng *)list_entry; if (list_entry == NULL) ripng = RB_MIN(ripng_instance_head, &ripng_instances); else - ripng = RB_NEXT(ripng_instance_head, (struct ripng *)ripng); + ripng = RB_NEXT(ripng_instance_head, ripng); return ripng; } @@ -1012,158 +1012,220 @@ const struct frr_yang_module_info frr_ripngd_info = { .nodes = { { .xpath = "/frr-ripngd:ripngd/instance", - .cbs.create = ripngd_instance_create, - .cbs.destroy = ripngd_instance_destroy, - .cbs.get_next = ripngd_instance_get_next, - .cbs.get_keys = ripngd_instance_get_keys, - .cbs.lookup_entry = ripngd_instance_lookup_entry, - .cbs.cli_show = cli_show_router_ripng, + .cbs = { + .cli_show = cli_show_router_ripng, + .create = ripngd_instance_create, + .destroy = ripngd_instance_destroy, + .get_keys = ripngd_instance_get_keys, + .get_next = ripngd_instance_get_next, + .lookup_entry = ripngd_instance_lookup_entry, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/allow-ecmp", - .cbs.modify = ripngd_instance_allow_ecmp_modify, - .cbs.cli_show = cli_show_ripng_allow_ecmp, + .cbs = { + .cli_show = cli_show_ripng_allow_ecmp, + .modify = ripngd_instance_allow_ecmp_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/default-information-originate", - .cbs.modify = ripngd_instance_default_information_originate_modify, - .cbs.cli_show = cli_show_ripng_default_information_originate, + .cbs = { + .cli_show = cli_show_ripng_default_information_originate, + .modify = ripngd_instance_default_information_originate_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/default-metric", - .cbs.modify = ripngd_instance_default_metric_modify, - .cbs.cli_show = cli_show_ripng_default_metric, + .cbs = { + .cli_show = cli_show_ripng_default_metric, + .modify = ripngd_instance_default_metric_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/network", - .cbs.create = ripngd_instance_network_create, - .cbs.destroy = ripngd_instance_network_destroy, - .cbs.cli_show = cli_show_ripng_network_prefix, + .cbs = { + .cli_show = cli_show_ripng_network_prefix, + .create = ripngd_instance_network_create, + .destroy = ripngd_instance_network_destroy, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/interface", - .cbs.create = ripngd_instance_interface_create, - .cbs.destroy = ripngd_instance_interface_destroy, - .cbs.cli_show = cli_show_ripng_network_interface, + .cbs = { + .cli_show = cli_show_ripng_network_interface, + .create = ripngd_instance_interface_create, + .destroy = ripngd_instance_interface_destroy, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/offset-list", - .cbs.create = ripngd_instance_offset_list_create, - .cbs.destroy = ripngd_instance_offset_list_destroy, - .cbs.cli_show = cli_show_ripng_offset_list, + .cbs = { + .cli_show = cli_show_ripng_offset_list, + .create = ripngd_instance_offset_list_create, + .destroy = ripngd_instance_offset_list_destroy, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/offset-list/access-list", - .cbs.modify = ripngd_instance_offset_list_access_list_modify, + .cbs = { + .modify = ripngd_instance_offset_list_access_list_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/offset-list/metric", - .cbs.modify = ripngd_instance_offset_list_metric_modify, + .cbs = { + .modify = ripngd_instance_offset_list_metric_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/passive-interface", - .cbs.create = ripngd_instance_passive_interface_create, - .cbs.destroy = ripngd_instance_passive_interface_destroy, - .cbs.cli_show = cli_show_ripng_passive_interface, + .cbs = { + .cli_show = cli_show_ripng_passive_interface, + .create = ripngd_instance_passive_interface_create, + .destroy = ripngd_instance_passive_interface_destroy, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/redistribute", - .cbs.create = ripngd_instance_redistribute_create, - .cbs.destroy = ripngd_instance_redistribute_destroy, - .cbs.apply_finish = ripngd_instance_redistribute_apply_finish, - .cbs.cli_show = cli_show_ripng_redistribute, + .cbs = { + .apply_finish = ripngd_instance_redistribute_apply_finish, + .cli_show = cli_show_ripng_redistribute, + .create = ripngd_instance_redistribute_create, + .destroy = ripngd_instance_redistribute_destroy, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/redistribute/route-map", - .cbs.modify = ripngd_instance_redistribute_route_map_modify, - .cbs.destroy = ripngd_instance_redistribute_route_map_destroy, + .cbs = { + .destroy = ripngd_instance_redistribute_route_map_destroy, + .modify = ripngd_instance_redistribute_route_map_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/redistribute/metric", - .cbs.modify = ripngd_instance_redistribute_metric_modify, - .cbs.destroy = ripngd_instance_redistribute_metric_destroy, + .cbs = { + .destroy = ripngd_instance_redistribute_metric_destroy, + .modify = ripngd_instance_redistribute_metric_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/static-route", - .cbs.create = ripngd_instance_static_route_create, - .cbs.destroy = ripngd_instance_static_route_destroy, - .cbs.cli_show = cli_show_ripng_route, + .cbs = { + .cli_show = cli_show_ripng_route, + .create = ripngd_instance_static_route_create, + .destroy = ripngd_instance_static_route_destroy, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/aggregate-address", - .cbs.create = ripngd_instance_aggregate_address_create, - .cbs.destroy = ripngd_instance_aggregate_address_destroy, - .cbs.cli_show = cli_show_ripng_aggregate_address, + .cbs = { + .cli_show = cli_show_ripng_aggregate_address, + .create = ripngd_instance_aggregate_address_create, + .destroy = ripngd_instance_aggregate_address_destroy, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/timers", - .cbs.apply_finish = ripngd_instance_timers_apply_finish, - .cbs.cli_show = cli_show_ripng_timers, + .cbs = { + .apply_finish = ripngd_instance_timers_apply_finish, + .cli_show = cli_show_ripng_timers, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/timers/flush-interval", - .cbs.modify = ripngd_instance_timers_flush_interval_modify, + .cbs = { + .modify = ripngd_instance_timers_flush_interval_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/timers/holddown-interval", - .cbs.modify = ripngd_instance_timers_holddown_interval_modify, + .cbs = { + .modify = ripngd_instance_timers_holddown_interval_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/timers/update-interval", - .cbs.modify = ripngd_instance_timers_update_interval_modify, + .cbs = { + .modify = ripngd_instance_timers_update_interval_modify, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor", - .cbs.get_next = ripngd_instance_state_neighbors_neighbor_get_next, - .cbs.get_keys = ripngd_instance_state_neighbors_neighbor_get_keys, - .cbs.lookup_entry = ripngd_instance_state_neighbors_neighbor_lookup_entry, + .cbs = { + .get_keys = ripngd_instance_state_neighbors_neighbor_get_keys, + .get_next = ripngd_instance_state_neighbors_neighbor_get_next, + .lookup_entry = ripngd_instance_state_neighbors_neighbor_lookup_entry, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/address", - .cbs.get_elem = ripngd_instance_state_neighbors_neighbor_address_get_elem, + .cbs = { + .get_elem = ripngd_instance_state_neighbors_neighbor_address_get_elem, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/last-update", - .cbs.get_elem = ripngd_instance_state_neighbors_neighbor_last_update_get_elem, + .cbs = { + .get_elem = ripngd_instance_state_neighbors_neighbor_last_update_get_elem, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-packets-rcvd", - .cbs.get_elem = ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem, + .cbs = { + .get_elem = ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-routes-rcvd", - .cbs.get_elem = ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem, + .cbs = { + .get_elem = ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/routes/route", - .cbs.get_next = ripngd_instance_state_routes_route_get_next, - .cbs.get_keys = ripngd_instance_state_routes_route_get_keys, - .cbs.lookup_entry = ripngd_instance_state_routes_route_lookup_entry, + .cbs = { + .get_keys = ripngd_instance_state_routes_route_get_keys, + .get_next = ripngd_instance_state_routes_route_get_next, + .lookup_entry = ripngd_instance_state_routes_route_lookup_entry, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/routes/route/prefix", - .cbs.get_elem = ripngd_instance_state_routes_route_prefix_get_elem, + .cbs = { + .get_elem = ripngd_instance_state_routes_route_prefix_get_elem, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/routes/route/next-hop", - .cbs.get_elem = ripngd_instance_state_routes_route_next_hop_get_elem, + .cbs = { + .get_elem = ripngd_instance_state_routes_route_next_hop_get_elem, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/routes/route/interface", - .cbs.get_elem = ripngd_instance_state_routes_route_interface_get_elem, + .cbs = { + .get_elem = ripngd_instance_state_routes_route_interface_get_elem, + }, }, { .xpath = "/frr-ripngd:ripngd/instance/state/routes/route/metric", - .cbs.get_elem = ripngd_instance_state_routes_route_metric_get_elem, + .cbs = { + .get_elem = ripngd_instance_state_routes_route_metric_get_elem, + }, }, { .xpath = "/frr-ripngd:clear-ripng-route", - .cbs.rpc = clear_ripng_route_rpc, + .cbs = { + .rpc = clear_ripng_route_rpc, + }, }, { .xpath = "/frr-interface:lib/interface/frr-ripngd:ripng/split-horizon", - .cbs.modify = lib_interface_ripng_split_horizon_modify, - .cbs.cli_show = cli_show_ipv6_ripng_split_horizon, + .cbs = { + .cli_show = cli_show_ipv6_ripng_split_horizon, + .modify = lib_interface_ripng_split_horizon_modify, + }, }, { .xpath = NULL, diff --git a/ripngd/ripng_offset.c b/ripngd/ripng_offset.c index fe95ccfc2b..0094c993ad 100644 --- a/ripngd/ripng_offset.c +++ b/ripngd/ripng_offset.c @@ -33,6 +33,8 @@ #include "ripngd/ripngd.h" +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_OFFSET_LIST, "RIPng offset lst") + #define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name) #define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].metric) diff --git a/ripngd/ripng_peer.c b/ripngd/ripng_peer.c index 5376007747..109524e212 100644 --- a/ripngd/ripng_peer.c +++ b/ripngd/ripng_peer.c @@ -34,6 +34,8 @@ #include "ripngd/ripngd.h" #include "ripngd/ripng_nexthop.h" +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_PEER, "RIPng peer") + static struct ripng_peer *ripng_peer_new(void) { return XCALLOC(MTYPE_RIPNG_PEER, sizeof(struct ripng_peer)); diff --git a/ripngd/ripng_route.c b/ripngd/ripng_route.c index 1bf1007fec..ed9d77a378 100644 --- a/ripngd/ripng_route.c +++ b/ripngd/ripng_route.c @@ -30,6 +30,8 @@ #include "ripngd/ripngd.h" #include "ripngd/ripng_route.h" +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_AGGREGATE, "RIPng aggregate") + static struct ripng_aggregate *ripng_aggregate_new(void) { struct ripng_aggregate *new; diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 71bc43049a..3314892e74 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -43,6 +43,11 @@ #include "ripngd/ripng_debug.h" #include "ripngd/ripng_nexthop.h" +DEFINE_MGROUP(RIPNGD, "ripngd") +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG, "RIPng structure") +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_VRF_NAME, "RIPng VRF name") +DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_ROUTE, "RIPng route info") + enum { ripng_all_route, ripng_changed_route, }; diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index a2686304fc..5a0d350a84 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -26,8 +26,7 @@ #include <vty.h> #include <distribute.h> #include <vector.h> - -#include "ripng_memory.h" +#include <memory.h> /* RIPng version and port number. */ #define RIPNG_V1 1 @@ -87,6 +86,8 @@ #define RIPNG_INSTANCE "/frr-ripngd:ripngd/instance" #define RIPNG_IFACE "/frr-interface:lib/interface/frr-ripngd:ripng" +DECLARE_MGROUP(RIPNGD) + /* RIPng structure. */ struct ripng { RB_ENTRY(ripng) entry; diff --git a/ripngd/subdir.am b/ripngd/subdir.am index ea0ccf1482..eac0d67313 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -17,7 +17,6 @@ ripngd_libripng_a_SOURCES = \ ripngd/ripng_cli.c \ ripngd/ripng_debug.c \ ripngd/ripng_interface.c \ - ripngd/ripng_memory.c \ ripngd/ripng_nexthop.c \ ripngd/ripng_offset.c \ ripngd/ripng_northbound.c \ @@ -34,7 +33,6 @@ ripngd/ripng_cli.$(OBJEXT): ripngd/ripng_cli_clippy.c noinst_HEADERS += \ ripngd/ripng_cli.h \ ripngd/ripng_debug.h \ - ripngd/ripng_memory.h \ ripngd/ripng_nexthop.h \ ripngd/ripng_route.h \ ripngd/ripngd.h \ diff --git a/tests/.gitignore b/tests/.gitignore index 4c6a51d475..6252cea823 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -31,6 +31,7 @@ /lib/test_memory /lib/test_nexthop_iter /lib/test_ntop +/lib/test_prefix2str /lib/test_printfrr /lib/test_privs /lib/test_ringbuf diff --git a/tests/Makefile.in b/tests/Makefile.in deleted file mode 100644 index 29d903e70a..0000000000 --- a/tests/Makefile.in +++ /dev/null @@ -1,1338 +0,0 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2017 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# -# Automake fragment intended to be shared by Makefile.am files in the -# tree. -# - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -check_PROGRAMS = lib/test_buffer$(EXEEXT) lib/test_checksum$(EXEEXT) \ - lib/test_heavy_thread$(EXEEXT) lib/test_heavy_wq$(EXEEXT) \ - lib/test_heavy$(EXEEXT) lib/test_memory$(EXEEXT) \ - lib/test_nexthop_iter$(EXEEXT) lib/test_privs$(EXEEXT) \ - lib/test_ringbuf$(EXEEXT) lib/test_srcdest_table$(EXEEXT) \ - lib/test_segv$(EXEEXT) lib/test_sig$(EXEEXT) \ - lib/test_stream$(EXEEXT) lib/test_table$(EXEEXT) \ - lib/test_timer_correctness$(EXEEXT) \ - lib/test_timer_performance$(EXEEXT) lib/test_ttable$(EXEEXT) \ - lib/cli/test_cli$(EXEEXT) lib/cli/test_commands$(EXEEXT) \ - $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ - $(am__EXEEXT_4) -@ZEROMQ_TRUE@am__append_1 = \ -@ZEROMQ_TRUE@ lib/test_zmq \ -@ZEROMQ_TRUE@ # end - -subdir = tests -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ - $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -@BGPD_TRUE@am__EXEEXT_1 = bgpd/test_aspath$(EXEEXT) \ -@BGPD_TRUE@ bgpd/test_capability$(EXEEXT) \ -@BGPD_TRUE@ bgpd/test_packet$(EXEEXT) \ -@BGPD_TRUE@ bgpd/test_ecommunity$(EXEEXT) \ -@BGPD_TRUE@ bgpd/test_mp_attr$(EXEEXT) bgpd/test_mpath$(EXEEXT) -@ISISD_TRUE@@SOLARIS_FALSE@am__EXEEXT_2 = \ -@ISISD_TRUE@@SOLARIS_FALSE@ isisd/test_fuzz_isis_tlv$(EXEEXT) \ -@ISISD_TRUE@@SOLARIS_FALSE@ isisd/test_isis_vertex_queue$(EXEEXT) -@OSPF6D_TRUE@am__EXEEXT_3 = ospf6d/test_lsdb$(EXEEXT) -@ZEROMQ_TRUE@am__EXEEXT_4 = lib/test_zmq$(EXEEXT) -am__dirstamp = $(am__leading_dot)dirstamp -am_bgpd_test_aspath_OBJECTS = bgpd/test_aspath.$(OBJEXT) -bgpd_test_aspath_OBJECTS = $(am_bgpd_test_aspath_OBJECTS) -@ENABLE_BGP_VNC_TRUE@am__DEPENDENCIES_1 = \ -@ENABLE_BGP_VNC_TRUE@ @top_builddir@/$(LIBRFP)/librfp.a -am__DEPENDENCIES_2 = ../lib/libfrr.la -am__DEPENDENCIES_3 = ../bgpd/libbgp.a $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_2) -bgpd_test_aspath_DEPENDENCIES = $(am__DEPENDENCIES_3) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -am_bgpd_test_capability_OBJECTS = bgpd/test_capability.$(OBJEXT) -bgpd_test_capability_OBJECTS = $(am_bgpd_test_capability_OBJECTS) -bgpd_test_capability_DEPENDENCIES = $(am__DEPENDENCIES_3) -am_bgpd_test_ecommunity_OBJECTS = bgpd/test_ecommunity.$(OBJEXT) -bgpd_test_ecommunity_OBJECTS = $(am_bgpd_test_ecommunity_OBJECTS) -bgpd_test_ecommunity_DEPENDENCIES = $(am__DEPENDENCIES_3) -am_bgpd_test_mp_attr_OBJECTS = bgpd/test_mp_attr.$(OBJEXT) -bgpd_test_mp_attr_OBJECTS = $(am_bgpd_test_mp_attr_OBJECTS) -bgpd_test_mp_attr_DEPENDENCIES = $(am__DEPENDENCIES_3) -am_bgpd_test_mpath_OBJECTS = bgpd/test_mpath.$(OBJEXT) -bgpd_test_mpath_OBJECTS = $(am_bgpd_test_mpath_OBJECTS) -bgpd_test_mpath_DEPENDENCIES = $(am__DEPENDENCIES_3) -am_bgpd_test_packet_OBJECTS = bgpd/test_packet.$(OBJEXT) -bgpd_test_packet_OBJECTS = $(am_bgpd_test_packet_OBJECTS) -bgpd_test_packet_DEPENDENCIES = $(am__DEPENDENCIES_3) -am_isisd_test_fuzz_isis_tlv_OBJECTS = \ - isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT) -isisd_test_fuzz_isis_tlv_OBJECTS = \ - $(am_isisd_test_fuzz_isis_tlv_OBJECTS) -am__DEPENDENCIES_4 = ../isisd/libisis.a $(am__DEPENDENCIES_2) -isisd_test_fuzz_isis_tlv_DEPENDENCIES = $(am__DEPENDENCIES_4) -am_isisd_test_isis_vertex_queue_OBJECTS = \ - isisd/test_isis_vertex_queue.$(OBJEXT) -isisd_test_isis_vertex_queue_OBJECTS = \ - $(am_isisd_test_isis_vertex_queue_OBJECTS) -isisd_test_isis_vertex_queue_DEPENDENCIES = $(am__DEPENDENCIES_4) -am_lib_cli_test_cli_OBJECTS = lib/cli/test_cli.$(OBJEXT) \ - lib/cli/common_cli.$(OBJEXT) -lib_cli_test_cli_OBJECTS = $(am_lib_cli_test_cli_OBJECTS) -lib_cli_test_cli_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_cli_test_commands_OBJECTS = \ - lib/cli/test_commands_defun.$(OBJEXT) \ - lib/cli/test_commands.$(OBJEXT) helpers/c/prng.$(OBJEXT) -lib_cli_test_commands_OBJECTS = $(am_lib_cli_test_commands_OBJECTS) -lib_cli_test_commands_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_buffer_OBJECTS = lib/test_buffer.$(OBJEXT) -lib_test_buffer_OBJECTS = $(am_lib_test_buffer_OBJECTS) -lib_test_buffer_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_checksum_OBJECTS = lib/test_checksum.$(OBJEXT) -lib_test_checksum_OBJECTS = $(am_lib_test_checksum_OBJECTS) -lib_test_checksum_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_heavy_OBJECTS = lib/test_heavy.$(OBJEXT) \ - helpers/c/main.$(OBJEXT) -lib_test_heavy_OBJECTS = $(am_lib_test_heavy_OBJECTS) -lib_test_heavy_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_heavy_thread_OBJECTS = lib/test_heavy_thread.$(OBJEXT) \ - helpers/c/main.$(OBJEXT) -lib_test_heavy_thread_OBJECTS = $(am_lib_test_heavy_thread_OBJECTS) -lib_test_heavy_thread_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_heavy_wq_OBJECTS = lib/test_heavy_wq.$(OBJEXT) \ - helpers/c/main.$(OBJEXT) -lib_test_heavy_wq_OBJECTS = $(am_lib_test_heavy_wq_OBJECTS) -lib_test_heavy_wq_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_memory_OBJECTS = lib/test_memory.$(OBJEXT) -lib_test_memory_OBJECTS = $(am_lib_test_memory_OBJECTS) -lib_test_memory_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_nexthop_iter_OBJECTS = lib/test_nexthop_iter.$(OBJEXT) \ - helpers/c/prng.$(OBJEXT) -lib_test_nexthop_iter_OBJECTS = $(am_lib_test_nexthop_iter_OBJECTS) -lib_test_nexthop_iter_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_privs_OBJECTS = lib/test_privs.$(OBJEXT) -lib_test_privs_OBJECTS = $(am_lib_test_privs_OBJECTS) -lib_test_privs_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_ringbuf_OBJECTS = lib/test_ringbuf.$(OBJEXT) -lib_test_ringbuf_OBJECTS = $(am_lib_test_ringbuf_OBJECTS) -lib_test_ringbuf_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_segv_OBJECTS = lib/test_segv.$(OBJEXT) -lib_test_segv_OBJECTS = $(am_lib_test_segv_OBJECTS) -lib_test_segv_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_sig_OBJECTS = lib/test_sig.$(OBJEXT) -lib_test_sig_OBJECTS = $(am_lib_test_sig_OBJECTS) -lib_test_sig_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_srcdest_table_OBJECTS = lib/test_srcdest_table.$(OBJEXT) \ - helpers/c/prng.$(OBJEXT) -lib_test_srcdest_table_OBJECTS = $(am_lib_test_srcdest_table_OBJECTS) -lib_test_srcdest_table_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_stream_OBJECTS = lib/test_stream.$(OBJEXT) -lib_test_stream_OBJECTS = $(am_lib_test_stream_OBJECTS) -lib_test_stream_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_table_OBJECTS = lib/test_table.$(OBJEXT) -lib_test_table_OBJECTS = $(am_lib_test_table_OBJECTS) -lib_test_table_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_timer_correctness_OBJECTS = \ - lib/test_timer_correctness.$(OBJEXT) helpers/c/prng.$(OBJEXT) -lib_test_timer_correctness_OBJECTS = \ - $(am_lib_test_timer_correctness_OBJECTS) -lib_test_timer_correctness_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_timer_performance_OBJECTS = \ - lib/test_timer_performance.$(OBJEXT) helpers/c/prng.$(OBJEXT) -lib_test_timer_performance_OBJECTS = \ - $(am_lib_test_timer_performance_OBJECTS) -lib_test_timer_performance_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_ttable_OBJECTS = lib/test_ttable.$(OBJEXT) -lib_test_ttable_OBJECTS = $(am_lib_test_ttable_OBJECTS) -lib_test_ttable_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_lib_test_zmq_OBJECTS = lib/lib_test_zmq-test_zmq.$(OBJEXT) -lib_test_zmq_OBJECTS = $(am_lib_test_zmq_OBJECTS) -am__DEPENDENCIES_5 = -lib_test_zmq_DEPENDENCIES = ../lib/libfrrzmq.la $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_5) -lib_test_zmq_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(lib_test_zmq_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am_ospf6d_test_lsdb_OBJECTS = ospf6d/test_lsdb.$(OBJEXT) \ - lib/cli/common_cli.$(OBJEXT) -ospf6d_test_lsdb_OBJECTS = $(am_ospf6d_test_lsdb_OBJECTS) -am__DEPENDENCIES_6 = ../ospf6d/libospf6.a $(am__DEPENDENCIES_2) -ospf6d_test_lsdb_DEPENDENCIES = $(am__DEPENDENCIES_6) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(bgpd_test_aspath_SOURCES) $(bgpd_test_capability_SOURCES) \ - $(bgpd_test_ecommunity_SOURCES) $(bgpd_test_mp_attr_SOURCES) \ - $(bgpd_test_mpath_SOURCES) $(bgpd_test_packet_SOURCES) \ - $(isisd_test_fuzz_isis_tlv_SOURCES) \ - $(isisd_test_isis_vertex_queue_SOURCES) \ - $(lib_cli_test_cli_SOURCES) $(lib_cli_test_commands_SOURCES) \ - $(lib_test_buffer_SOURCES) $(lib_test_checksum_SOURCES) \ - $(lib_test_heavy_SOURCES) $(lib_test_heavy_thread_SOURCES) \ - $(lib_test_heavy_wq_SOURCES) $(lib_test_memory_SOURCES) \ - $(lib_test_nexthop_iter_SOURCES) $(lib_test_privs_SOURCES) \ - $(lib_test_ringbuf_SOURCES) $(lib_test_segv_SOURCES) \ - $(lib_test_sig_SOURCES) $(lib_test_srcdest_table_SOURCES) \ - $(lib_test_stream_SOURCES) $(lib_test_table_SOURCES) \ - $(lib_test_timer_correctness_SOURCES) \ - $(lib_test_timer_performance_SOURCES) \ - $(lib_test_ttable_SOURCES) $(lib_test_zmq_SOURCES) \ - $(ospf6d_test_lsdb_SOURCES) -DIST_SOURCES = $(bgpd_test_aspath_SOURCES) \ - $(bgpd_test_capability_SOURCES) \ - $(bgpd_test_ecommunity_SOURCES) $(bgpd_test_mp_attr_SOURCES) \ - $(bgpd_test_mpath_SOURCES) $(bgpd_test_packet_SOURCES) \ - $(isisd_test_fuzz_isis_tlv_SOURCES) \ - $(isisd_test_isis_vertex_queue_SOURCES) \ - $(lib_cli_test_cli_SOURCES) $(lib_cli_test_commands_SOURCES) \ - $(lib_test_buffer_SOURCES) $(lib_test_checksum_SOURCES) \ - $(lib_test_heavy_SOURCES) $(lib_test_heavy_thread_SOURCES) \ - $(lib_test_heavy_wq_SOURCES) $(lib_test_memory_SOURCES) \ - $(lib_test_nexthop_iter_SOURCES) $(lib_test_privs_SOURCES) \ - $(lib_test_ringbuf_SOURCES) $(lib_test_segv_SOURCES) \ - $(lib_test_sig_SOURCES) $(lib_test_srcdest_table_SOURCES) \ - $(lib_test_stream_SOURCES) $(lib_test_table_SOURCES) \ - $(lib_test_timer_correctness_SOURCES) \ - $(lib_test_timer_performance_SOURCES) \ - $(lib_test_ttable_SOURCES) $(lib_test_zmq_SOURCES) \ - $(ospf6d_test_lsdb_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/../common.am $(srcdir)/Makefile.in \ - $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BGPD = @BGPD@ -BISON_CLOSEBRACE = @BISON_CLOSEBRACE@ -BISON_OPENBRACE = @BISON_OPENBRACE@ -BISON_VERBOSE = @BISON_VERBOSE@ -CARES_CFLAGS = @CARES_CFLAGS@ -CARES_LIBS = @CARES_LIBS@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFG_MODULE = @CFG_MODULE@ -CFG_SBIN = @CFG_SBIN@ -CFG_STATE = @CFG_STATE@ -CFG_SYSCONF = @CFG_SYSCONF@ -CFLAGS = @CFLAGS@ -CONFDATE = @CONFDATE@ -CONFIG_ARGS = @CONFIG_ARGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CURSES = @CURSES@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\" -DEPDIR = @DEPDIR@ -DFLT_NAME = @DFLT_NAME@ -DLLTOOL = @DLLTOOL@ -DOC = @DOC@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_LIBPCREPOSIX = @HAVE_LIBPCREPOSIX@ -HOSTTOOLS = @HOSTTOOLS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBCAP = @LIBCAP@ -LIBM = @LIBM@ -LIBOBJS = @LIBOBJS@ -LIBPAM = @LIBPAM@ -LIBREADLINE = @LIBREADLINE@ -LIBRFP = @LIBRFP@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NETSNMP_CONFIG = @NETSNMP_CONFIG@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_EXTRAVERSION = @PACKAGE_EXTRAVERSION@ -PACKAGE_FULLNAME = @PACKAGE_FULLNAME@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -PROTOBUF_C_CFLAGS = @PROTOBUF_C_CFLAGS@ -PROTOBUF_C_LIBS = @PROTOBUF_C_LIBS@ -PROTOC_C = @PROTOC_C@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -PYTHONCONFIG = @PYTHONCONFIG@ -PYTHON_CFLAGS = @PYTHON_CFLAGS@ -PYTHON_LIBS = @PYTHON_LIBS@ -RANLIB = @RANLIB@ -RFPINC = @RFPINC@ -RFPTEST = @RFPTEST@ -RTRLIB_CFLAGS = @RTRLIB_CFLAGS@ -RTRLIB_LIBS = @RTRLIB_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SNMP_CFLAGS = @SNMP_CFLAGS@ -SNMP_LIBS = @SNMP_LIBS@ -SOLARIS = @SOLARIS@ -STRIP = @STRIP@ -VERSION = @VERSION@ -VNC_RFP_PATH = @VNC_RFP_PATH@ -VTYSH = @VTYSH@ -WERROR = @WERROR@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -ZEROMQ_CFLAGS = @ZEROMQ_CFLAGS@ -ZEROMQ_LIBS = @ZEROMQ_LIBS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -ac_ct_PYTHONCONFIG = @ac_ct_PYTHONCONFIG@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -enable_group = @enable_group@ -enable_user = @enable_user@ -enable_vty_group = @enable_vty_group@ -exampledir = @exampledir@ -exec_prefix = @exec_prefix@ -frr_statedir = @frr_statedir@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -moduledir = @moduledir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgsrcrcdir = @pkgsrcrcdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AM_V_CLIPPY = $(am__v_CLIPPY_$(V)) -am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY)) -am__v_CLIPPY_0 = @echo " CLIPPY " $@; -am__v_CLIPPY_1 = -CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h - -# Uncomment to use an non-system version of libprotobuf-c. -# -# Q_PROTOBUF_C_CLIENT_INCLUDES = -I$(top_srcdir)/third-party/protobuf-c/src -# Q_PROTOBUF_C_CLIENT_LDOPTS = $(top_builddir)/third-party/protobuf-c/src/libprotobuf-c.la -@HAVE_PROTOBUF_TRUE@Q_PROTOBUF_C_CLIENT_INCLUDES = -@HAVE_PROTOBUF_TRUE@Q_PROTOBUF_C_CLIENT_LDOPTS = -lprotobuf-c -@HAVE_PROTOBUF_TRUE@Q_PROTOC = protoc -@HAVE_PROTOBUF_TRUE@Q_PROTOC_C = protoc-c -@HAVE_PROTOBUF_TRUE@AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V)) -@HAVE_PROTOBUF_TRUE@am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY)) -@HAVE_PROTOBUF_TRUE@am__v_PROTOC_C_0 = @echo " PROTOC_C" $@; -@HAVE_PROTOBUF_TRUE@am__v_PROTOC_C_1 = - -# -# Information about how to link to various libraries. -# -@HAVE_PROTOBUF_TRUE@Q_FRR_PB_CLIENT_LDOPTS = $(top_srcdir)/qpb/libfrr_pb.la $(Q_PROTOBUF_C_CLIENT_LDOPTS) -@HAVE_PROTOBUF_TRUE@Q_FPM_PB_CLIENT_LDOPTS = $(top_srcdir)/fpm/libfrrfpm_pb.la $(Q_FRR_PB_CLIENT_LDOPTS) -AUTOMAKE_OPTIONS = subdir-objects -AM_CPPFLAGS = \ - -I.. \ - -I$(top_srcdir) \ - -I$(top_srcdir)/lib \ - -I$(top_builddir)/lib \ - -I$(top_srcdir)/tests/helpers/c \ - -I$(top_builddir)/tests/helpers/c \ - -O - -@BGPD_FALSE@TESTS_BGPD = -@BGPD_TRUE@TESTS_BGPD = \ -@BGPD_TRUE@ bgpd/test_aspath \ -@BGPD_TRUE@ bgpd/test_capability \ -@BGPD_TRUE@ bgpd/test_packet \ -@BGPD_TRUE@ bgpd/test_ecommunity \ -@BGPD_TRUE@ bgpd/test_mp_attr \ -@BGPD_TRUE@ bgpd/test_mpath - -@ISISD_FALSE@TESTS_ISISD = -@ISISD_TRUE@@SOLARIS_FALSE@TESTS_ISISD = \ -@ISISD_TRUE@@SOLARIS_FALSE@ isisd/test_fuzz_isis_tlv \ -@ISISD_TRUE@@SOLARIS_FALSE@ isisd/test_isis_vertex_queue \ -@ISISD_TRUE@@SOLARIS_FALSE@ # end - -@ISISD_TRUE@@SOLARIS_TRUE@TESTS_ISISD = -@OSPF6D_FALSE@TESTS_OSPF6D = -@OSPF6D_TRUE@TESTS_OSPF6D = \ -@OSPF6D_TRUE@ ospf6d/test_lsdb \ -@OSPF6D_TRUE@ # end - -@ENABLE_BGP_VNC_FALSE@BGP_VNC_RFP_LIB = -@ENABLE_BGP_VNC_TRUE@BGP_VNC_RFP_LIB = @top_builddir@/$(LIBRFP)/librfp.a -noinst_HEADERS = \ - ./helpers/c/prng.h \ - ./helpers/c/tests.h \ - ./lib/cli/common_cli.h - -lib_test_buffer_SOURCES = lib/test_buffer.c -lib_test_checksum_SOURCES = lib/test_checksum.c -lib_test_heavy_thread_SOURCES = lib/test_heavy_thread.c helpers/c/main.c -lib_test_heavy_wq_SOURCES = lib/test_heavy_wq.c helpers/c/main.c -lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c -lib_test_memory_SOURCES = lib/test_memory.c -lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c -lib_test_privs_SOURCES = lib/test_privs.c -lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \ - helpers/c/prng.c - -lib_test_ringbuf_SOURCES = lib/test_ringbuf.c -lib_test_segv_SOURCES = lib/test_segv.c -lib_test_sig_SOURCES = lib/test_sig.c -lib_test_stream_SOURCES = lib/test_stream.c -lib_test_table_SOURCES = lib/test_table.c -lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \ - helpers/c/prng.c - -lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \ - helpers/c/prng.c - -lib_test_ttable_SOURCES = lib/test_ttable.c -lib_test_zmq_SOURCES = lib/test_zmq.c -lib_test_zmq_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS) -lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c -lib_cli_test_commands_SOURCES = lib/cli/test_commands_defun.c \ - lib/cli/test_commands.c \ - helpers/c/prng.c - -bgpd_test_aspath_SOURCES = bgpd/test_aspath.c -bgpd_test_capability_SOURCES = bgpd/test_capability.c -bgpd_test_packet_SOURCES = bgpd/test_packet.c -bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c -bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c -bgpd_test_mpath_SOURCES = bgpd/test_mpath.c -isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv.c -isisd_test_fuzz_isis_tlv_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/tests/isisd -isisd_test_isis_vertex_queue_SOURCES = isisd/test_isis_vertex_queue.c -ospf6d_test_lsdb_SOURCES = ospf6d/test_lsdb.c lib/cli/common_cli.c -ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@ -BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm -ISISD_TEST_LDADD = ../isisd/libisis.a $(ALL_TESTS_LDADD) -OSPF6_TEST_LDADD = ../ospf6d/libospf6.a $(ALL_TESTS_LDADD) -lib_test_buffer_LDADD = $(ALL_TESTS_LDADD) -lib_test_checksum_LDADD = $(ALL_TESTS_LDADD) -lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_memory_LDADD = $(ALL_TESTS_LDADD) -lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD) -lib_test_privs_LDADD = $(ALL_TESTS_LDADD) -lib_test_ringbuf_LDADD = $(ALL_TESTS_LDADD) -lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD) -lib_test_segv_LDADD = $(ALL_TESTS_LDADD) -lib_test_sig_LDADD = $(ALL_TESTS_LDADD) -lib_test_stream_LDADD = $(ALL_TESTS_LDADD) -lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD) -lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD) -lib_test_ttable_LDADD = $(ALL_TESTS_LDADD) -lib_test_zmq_LDADD = ../lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS) -lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD) -lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) -bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD) -bgpd_test_capability_LDADD = $(BGP_TEST_LDADD) -bgpd_test_packet_LDADD = $(BGP_TEST_LDADD) -bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD) -bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD) -bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD) -isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD) -isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD) -ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD) -EXTRA_DIST = \ - runtests.py \ - bgpd/test_aspath.py \ - bgpd/test_capability.py \ - bgpd/test_ecommunity.py \ - bgpd/test_mp_attr.py \ - bgpd/test_mpath.py \ - helpers/python/frrsix.py \ - helpers/python/frrtest.py \ - isisd/test_fuzz_isis_tlv.py \ - isisd/test_fuzz_isis_tlv_tests.h.gz \ - isisd/test_isis_vertex_queue.py \ - lib/cli/test_commands.in \ - lib/cli/test_commands.py \ - lib/cli/test_commands.refout \ - lib/cli/test_cli.in \ - lib/cli/test_cli.py \ - lib/cli/test_cli.refout \ - lib/test_nexthop_iter.py \ - lib/test_ringbuf.py \ - lib/test_srcdest_table.py \ - lib/test_stream.py \ - lib/test_stream.refout \ - lib/test_table.py \ - lib/test_timer_correctness.py \ - lib/test_ttable.py \ - lib/test_ttable.refout \ - ospf6d/test_lsdb.py \ - ospf6d/test_lsdb.in \ - ospf6d/test_lsdb.refout \ - # end - -all: all-am - -.SUFFIXES: -.SUFFIXES: _clippy.c .proto .pb-c.c .pb-c.h .pb.h .c .l .lo .o .obj .y -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/../common.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu tests/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; -$(srcdir)/../common.am $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -bgpd/$(am__dirstamp): - @$(MKDIR_P) bgpd - @: > bgpd/$(am__dirstamp) -bgpd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) bgpd/$(DEPDIR) - @: > bgpd/$(DEPDIR)/$(am__dirstamp) -bgpd/test_aspath.$(OBJEXT): bgpd/$(am__dirstamp) \ - bgpd/$(DEPDIR)/$(am__dirstamp) - -bgpd/test_aspath$(EXEEXT): $(bgpd_test_aspath_OBJECTS) $(bgpd_test_aspath_DEPENDENCIES) $(EXTRA_bgpd_test_aspath_DEPENDENCIES) bgpd/$(am__dirstamp) - @rm -f bgpd/test_aspath$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bgpd_test_aspath_OBJECTS) $(bgpd_test_aspath_LDADD) $(LIBS) -bgpd/test_capability.$(OBJEXT): bgpd/$(am__dirstamp) \ - bgpd/$(DEPDIR)/$(am__dirstamp) - -bgpd/test_capability$(EXEEXT): $(bgpd_test_capability_OBJECTS) $(bgpd_test_capability_DEPENDENCIES) $(EXTRA_bgpd_test_capability_DEPENDENCIES) bgpd/$(am__dirstamp) - @rm -f bgpd/test_capability$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bgpd_test_capability_OBJECTS) $(bgpd_test_capability_LDADD) $(LIBS) -bgpd/test_ecommunity.$(OBJEXT): bgpd/$(am__dirstamp) \ - bgpd/$(DEPDIR)/$(am__dirstamp) - -bgpd/test_ecommunity$(EXEEXT): $(bgpd_test_ecommunity_OBJECTS) $(bgpd_test_ecommunity_DEPENDENCIES) $(EXTRA_bgpd_test_ecommunity_DEPENDENCIES) bgpd/$(am__dirstamp) - @rm -f bgpd/test_ecommunity$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bgpd_test_ecommunity_OBJECTS) $(bgpd_test_ecommunity_LDADD) $(LIBS) -bgpd/test_mp_attr.$(OBJEXT): bgpd/$(am__dirstamp) \ - bgpd/$(DEPDIR)/$(am__dirstamp) - -bgpd/test_mp_attr$(EXEEXT): $(bgpd_test_mp_attr_OBJECTS) $(bgpd_test_mp_attr_DEPENDENCIES) $(EXTRA_bgpd_test_mp_attr_DEPENDENCIES) bgpd/$(am__dirstamp) - @rm -f bgpd/test_mp_attr$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bgpd_test_mp_attr_OBJECTS) $(bgpd_test_mp_attr_LDADD) $(LIBS) -bgpd/test_mpath.$(OBJEXT): bgpd/$(am__dirstamp) \ - bgpd/$(DEPDIR)/$(am__dirstamp) - -bgpd/test_mpath$(EXEEXT): $(bgpd_test_mpath_OBJECTS) $(bgpd_test_mpath_DEPENDENCIES) $(EXTRA_bgpd_test_mpath_DEPENDENCIES) bgpd/$(am__dirstamp) - @rm -f bgpd/test_mpath$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bgpd_test_mpath_OBJECTS) $(bgpd_test_mpath_LDADD) $(LIBS) -bgpd/test_packet.$(OBJEXT): bgpd/$(am__dirstamp) \ - bgpd/$(DEPDIR)/$(am__dirstamp) - -bgpd/test_packet$(EXEEXT): $(bgpd_test_packet_OBJECTS) $(bgpd_test_packet_DEPENDENCIES) $(EXTRA_bgpd_test_packet_DEPENDENCIES) bgpd/$(am__dirstamp) - @rm -f bgpd/test_packet$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bgpd_test_packet_OBJECTS) $(bgpd_test_packet_LDADD) $(LIBS) -isisd/$(am__dirstamp): - @$(MKDIR_P) isisd - @: > isisd/$(am__dirstamp) -isisd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) isisd/$(DEPDIR) - @: > isisd/$(DEPDIR)/$(am__dirstamp) -isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \ - isisd/$(am__dirstamp) isisd/$(DEPDIR)/$(am__dirstamp) - -isisd/test_fuzz_isis_tlv$(EXEEXT): $(isisd_test_fuzz_isis_tlv_OBJECTS) $(isisd_test_fuzz_isis_tlv_DEPENDENCIES) $(EXTRA_isisd_test_fuzz_isis_tlv_DEPENDENCIES) isisd/$(am__dirstamp) - @rm -f isisd/test_fuzz_isis_tlv$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(isisd_test_fuzz_isis_tlv_OBJECTS) $(isisd_test_fuzz_isis_tlv_LDADD) $(LIBS) -isisd/test_isis_vertex_queue.$(OBJEXT): isisd/$(am__dirstamp) \ - isisd/$(DEPDIR)/$(am__dirstamp) - -isisd/test_isis_vertex_queue$(EXEEXT): $(isisd_test_isis_vertex_queue_OBJECTS) $(isisd_test_isis_vertex_queue_DEPENDENCIES) $(EXTRA_isisd_test_isis_vertex_queue_DEPENDENCIES) isisd/$(am__dirstamp) - @rm -f isisd/test_isis_vertex_queue$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(isisd_test_isis_vertex_queue_OBJECTS) $(isisd_test_isis_vertex_queue_LDADD) $(LIBS) -lib/cli/$(am__dirstamp): - @$(MKDIR_P) lib/cli - @: > lib/cli/$(am__dirstamp) -lib/cli/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) lib/cli/$(DEPDIR) - @: > lib/cli/$(DEPDIR)/$(am__dirstamp) -lib/cli/test_cli.$(OBJEXT): lib/cli/$(am__dirstamp) \ - lib/cli/$(DEPDIR)/$(am__dirstamp) -lib/cli/common_cli.$(OBJEXT): lib/cli/$(am__dirstamp) \ - lib/cli/$(DEPDIR)/$(am__dirstamp) - -lib/cli/test_cli$(EXEEXT): $(lib_cli_test_cli_OBJECTS) $(lib_cli_test_cli_DEPENDENCIES) $(EXTRA_lib_cli_test_cli_DEPENDENCIES) lib/cli/$(am__dirstamp) - @rm -f lib/cli/test_cli$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_cli_test_cli_OBJECTS) $(lib_cli_test_cli_LDADD) $(LIBS) -lib/cli/test_commands_defun.$(OBJEXT): lib/cli/$(am__dirstamp) \ - lib/cli/$(DEPDIR)/$(am__dirstamp) -lib/cli/test_commands.$(OBJEXT): lib/cli/$(am__dirstamp) \ - lib/cli/$(DEPDIR)/$(am__dirstamp) -helpers/c/$(am__dirstamp): - @$(MKDIR_P) helpers/c - @: > helpers/c/$(am__dirstamp) -helpers/c/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) helpers/c/$(DEPDIR) - @: > helpers/c/$(DEPDIR)/$(am__dirstamp) -helpers/c/prng.$(OBJEXT): helpers/c/$(am__dirstamp) \ - helpers/c/$(DEPDIR)/$(am__dirstamp) - -lib/cli/test_commands$(EXEEXT): $(lib_cli_test_commands_OBJECTS) $(lib_cli_test_commands_DEPENDENCIES) $(EXTRA_lib_cli_test_commands_DEPENDENCIES) lib/cli/$(am__dirstamp) - @rm -f lib/cli/test_commands$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_cli_test_commands_OBJECTS) $(lib_cli_test_commands_LDADD) $(LIBS) -lib/$(am__dirstamp): - @$(MKDIR_P) lib - @: > lib/$(am__dirstamp) -lib/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) lib/$(DEPDIR) - @: > lib/$(DEPDIR)/$(am__dirstamp) -lib/test_buffer.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_buffer$(EXEEXT): $(lib_test_buffer_OBJECTS) $(lib_test_buffer_DEPENDENCIES) $(EXTRA_lib_test_buffer_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_buffer$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_buffer_OBJECTS) $(lib_test_buffer_LDADD) $(LIBS) -lib/test_checksum.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_checksum$(EXEEXT): $(lib_test_checksum_OBJECTS) $(lib_test_checksum_DEPENDENCIES) $(EXTRA_lib_test_checksum_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_checksum$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_checksum_OBJECTS) $(lib_test_checksum_LDADD) $(LIBS) -lib/test_heavy.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) -helpers/c/main.$(OBJEXT): helpers/c/$(am__dirstamp) \ - helpers/c/$(DEPDIR)/$(am__dirstamp) - -lib/test_heavy$(EXEEXT): $(lib_test_heavy_OBJECTS) $(lib_test_heavy_DEPENDENCIES) $(EXTRA_lib_test_heavy_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_heavy$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_heavy_OBJECTS) $(lib_test_heavy_LDADD) $(LIBS) -lib/test_heavy_thread.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_heavy_thread$(EXEEXT): $(lib_test_heavy_thread_OBJECTS) $(lib_test_heavy_thread_DEPENDENCIES) $(EXTRA_lib_test_heavy_thread_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_heavy_thread$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_heavy_thread_OBJECTS) $(lib_test_heavy_thread_LDADD) $(LIBS) -lib/test_heavy_wq.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_heavy_wq$(EXEEXT): $(lib_test_heavy_wq_OBJECTS) $(lib_test_heavy_wq_DEPENDENCIES) $(EXTRA_lib_test_heavy_wq_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_heavy_wq$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_heavy_wq_OBJECTS) $(lib_test_heavy_wq_LDADD) $(LIBS) -lib/test_memory.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_memory$(EXEEXT): $(lib_test_memory_OBJECTS) $(lib_test_memory_DEPENDENCIES) $(EXTRA_lib_test_memory_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_memory$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_memory_OBJECTS) $(lib_test_memory_LDADD) $(LIBS) -lib/test_nexthop_iter.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_nexthop_iter$(EXEEXT): $(lib_test_nexthop_iter_OBJECTS) $(lib_test_nexthop_iter_DEPENDENCIES) $(EXTRA_lib_test_nexthop_iter_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_nexthop_iter$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_nexthop_iter_OBJECTS) $(lib_test_nexthop_iter_LDADD) $(LIBS) -lib/test_privs.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_privs$(EXEEXT): $(lib_test_privs_OBJECTS) $(lib_test_privs_DEPENDENCIES) $(EXTRA_lib_test_privs_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_privs$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_privs_OBJECTS) $(lib_test_privs_LDADD) $(LIBS) -lib/test_ringbuf.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_ringbuf$(EXEEXT): $(lib_test_ringbuf_OBJECTS) $(lib_test_ringbuf_DEPENDENCIES) $(EXTRA_lib_test_ringbuf_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_ringbuf$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_ringbuf_OBJECTS) $(lib_test_ringbuf_LDADD) $(LIBS) -lib/test_segv.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_segv$(EXEEXT): $(lib_test_segv_OBJECTS) $(lib_test_segv_DEPENDENCIES) $(EXTRA_lib_test_segv_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_segv$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_segv_OBJECTS) $(lib_test_segv_LDADD) $(LIBS) -lib/test_sig.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_sig$(EXEEXT): $(lib_test_sig_OBJECTS) $(lib_test_sig_DEPENDENCIES) $(EXTRA_lib_test_sig_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_sig$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_sig_OBJECTS) $(lib_test_sig_LDADD) $(LIBS) -lib/test_srcdest_table.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_srcdest_table$(EXEEXT): $(lib_test_srcdest_table_OBJECTS) $(lib_test_srcdest_table_DEPENDENCIES) $(EXTRA_lib_test_srcdest_table_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_srcdest_table$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_srcdest_table_OBJECTS) $(lib_test_srcdest_table_LDADD) $(LIBS) -lib/test_stream.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_stream$(EXEEXT): $(lib_test_stream_OBJECTS) $(lib_test_stream_DEPENDENCIES) $(EXTRA_lib_test_stream_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_stream$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_stream_OBJECTS) $(lib_test_stream_LDADD) $(LIBS) -lib/test_table.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_table$(EXEEXT): $(lib_test_table_OBJECTS) $(lib_test_table_DEPENDENCIES) $(EXTRA_lib_test_table_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_table$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_table_OBJECTS) $(lib_test_table_LDADD) $(LIBS) -lib/test_timer_correctness.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_timer_correctness$(EXEEXT): $(lib_test_timer_correctness_OBJECTS) $(lib_test_timer_correctness_DEPENDENCIES) $(EXTRA_lib_test_timer_correctness_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_timer_correctness$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_timer_correctness_OBJECTS) $(lib_test_timer_correctness_LDADD) $(LIBS) -lib/test_timer_performance.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_timer_performance$(EXEEXT): $(lib_test_timer_performance_OBJECTS) $(lib_test_timer_performance_DEPENDENCIES) $(EXTRA_lib_test_timer_performance_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_timer_performance$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_timer_performance_OBJECTS) $(lib_test_timer_performance_LDADD) $(LIBS) -lib/test_ttable.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_ttable$(EXEEXT): $(lib_test_ttable_OBJECTS) $(lib_test_ttable_DEPENDENCIES) $(EXTRA_lib_test_ttable_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_ttable$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(lib_test_ttable_OBJECTS) $(lib_test_ttable_LDADD) $(LIBS) -lib/lib_test_zmq-test_zmq.$(OBJEXT): lib/$(am__dirstamp) \ - lib/$(DEPDIR)/$(am__dirstamp) - -lib/test_zmq$(EXEEXT): $(lib_test_zmq_OBJECTS) $(lib_test_zmq_DEPENDENCIES) $(EXTRA_lib_test_zmq_DEPENDENCIES) lib/$(am__dirstamp) - @rm -f lib/test_zmq$(EXEEXT) - $(AM_V_CCLD)$(lib_test_zmq_LINK) $(lib_test_zmq_OBJECTS) $(lib_test_zmq_LDADD) $(LIBS) -ospf6d/$(am__dirstamp): - @$(MKDIR_P) ospf6d - @: > ospf6d/$(am__dirstamp) -ospf6d/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) ospf6d/$(DEPDIR) - @: > ospf6d/$(DEPDIR)/$(am__dirstamp) -ospf6d/test_lsdb.$(OBJEXT): ospf6d/$(am__dirstamp) \ - ospf6d/$(DEPDIR)/$(am__dirstamp) - -ospf6d/test_lsdb$(EXEEXT): $(ospf6d_test_lsdb_OBJECTS) $(ospf6d_test_lsdb_DEPENDENCIES) $(EXTRA_ospf6d_test_lsdb_DEPENDENCIES) ospf6d/$(am__dirstamp) - @rm -f ospf6d/test_lsdb$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(ospf6d_test_lsdb_OBJECTS) $(ospf6d_test_lsdb_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f bgpd/*.$(OBJEXT) - -rm -f helpers/c/*.$(OBJEXT) - -rm -f isisd/*.$(OBJEXT) - -rm -f lib/*.$(OBJEXT) - -rm -f lib/cli/*.$(OBJEXT) - -rm -f ospf6d/*.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@bgpd/$(DEPDIR)/test_aspath.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@bgpd/$(DEPDIR)/test_capability.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@bgpd/$(DEPDIR)/test_ecommunity.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@bgpd/$(DEPDIR)/test_mp_attr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@bgpd/$(DEPDIR)/test_mpath.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@bgpd/$(DEPDIR)/test_packet.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@helpers/c/$(DEPDIR)/main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@helpers/c/$(DEPDIR)/prng.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@isisd/$(DEPDIR)/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@isisd/$(DEPDIR)/test_isis_vertex_queue.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/lib_test_zmq-test_zmq.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_buffer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_checksum.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_heavy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_heavy_thread.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_heavy_wq.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_memory.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_nexthop_iter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_privs.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_ringbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_segv.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_sig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_srcdest_table.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_stream.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_table.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_timer_correctness.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_timer_performance.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/test_ttable.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/cli/$(DEPDIR)/common_cli.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/cli/$(DEPDIR)/test_cli.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/cli/$(DEPDIR)/test_commands.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/cli/$(DEPDIR)/test_commands_defun.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ospf6d/$(DEPDIR)/test_lsdb.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.o: isisd/test_fuzz_isis_tlv.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isisd_test_fuzz_isis_tlv_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.o -MD -MP -MF isisd/$(DEPDIR)/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.Tpo -c -o isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.o `test -f 'isisd/test_fuzz_isis_tlv.c' || echo '$(srcdir)/'`isisd/test_fuzz_isis_tlv.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) isisd/$(DEPDIR)/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.Tpo isisd/$(DEPDIR)/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isisd/test_fuzz_isis_tlv.c' object='isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isisd_test_fuzz_isis_tlv_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.o `test -f 'isisd/test_fuzz_isis_tlv.c' || echo '$(srcdir)/'`isisd/test_fuzz_isis_tlv.c - -isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.obj: isisd/test_fuzz_isis_tlv.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isisd_test_fuzz_isis_tlv_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.obj -MD -MP -MF isisd/$(DEPDIR)/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.Tpo -c -o isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.obj `if test -f 'isisd/test_fuzz_isis_tlv.c'; then $(CYGPATH_W) 'isisd/test_fuzz_isis_tlv.c'; else $(CYGPATH_W) '$(srcdir)/isisd/test_fuzz_isis_tlv.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) isisd/$(DEPDIR)/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.Tpo isisd/$(DEPDIR)/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isisd/test_fuzz_isis_tlv.c' object='isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isisd_test_fuzz_isis_tlv_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.obj `if test -f 'isisd/test_fuzz_isis_tlv.c'; then $(CYGPATH_W) 'isisd/test_fuzz_isis_tlv.c'; else $(CYGPATH_W) '$(srcdir)/isisd/test_fuzz_isis_tlv.c'; fi` - -lib/lib_test_zmq-test_zmq.o: lib/test_zmq.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_test_zmq_CFLAGS) $(CFLAGS) -MT lib/lib_test_zmq-test_zmq.o -MD -MP -MF lib/$(DEPDIR)/lib_test_zmq-test_zmq.Tpo -c -o lib/lib_test_zmq-test_zmq.o `test -f 'lib/test_zmq.c' || echo '$(srcdir)/'`lib/test_zmq.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/lib_test_zmq-test_zmq.Tpo lib/$(DEPDIR)/lib_test_zmq-test_zmq.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/test_zmq.c' object='lib/lib_test_zmq-test_zmq.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_test_zmq_CFLAGS) $(CFLAGS) -c -o lib/lib_test_zmq-test_zmq.o `test -f 'lib/test_zmq.c' || echo '$(srcdir)/'`lib/test_zmq.c - -lib/lib_test_zmq-test_zmq.obj: lib/test_zmq.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_test_zmq_CFLAGS) $(CFLAGS) -MT lib/lib_test_zmq-test_zmq.obj -MD -MP -MF lib/$(DEPDIR)/lib_test_zmq-test_zmq.Tpo -c -o lib/lib_test_zmq-test_zmq.obj `if test -f 'lib/test_zmq.c'; then $(CYGPATH_W) 'lib/test_zmq.c'; else $(CYGPATH_W) '$(srcdir)/lib/test_zmq.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/lib_test_zmq-test_zmq.Tpo lib/$(DEPDIR)/lib_test_zmq-test_zmq.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/test_zmq.c' object='lib/lib_test_zmq-test_zmq.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_test_zmq_CFLAGS) $(CFLAGS) -c -o lib/lib_test_zmq-test_zmq.obj `if test -f 'lib/test_zmq.c'; then $(CYGPATH_W) 'lib/test_zmq.c'; else $(CYGPATH_W) '$(srcdir)/lib/test_zmq.c'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf bgpd/.libs bgpd/_libs - -rm -rf isisd/.libs isisd/_libs - -rm -rf lib/.libs lib/_libs - -rm -rf lib/cli/.libs lib/cli/_libs - -rm -rf ospf6d/.libs ospf6d/_libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) -check: check-am -all-am: Makefile $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f bgpd/$(DEPDIR)/$(am__dirstamp) - -rm -f bgpd/$(am__dirstamp) - -rm -f helpers/c/$(DEPDIR)/$(am__dirstamp) - -rm -f helpers/c/$(am__dirstamp) - -rm -f isisd/$(DEPDIR)/$(am__dirstamp) - -rm -f isisd/$(am__dirstamp) - -rm -f lib/$(DEPDIR)/$(am__dirstamp) - -rm -f lib/$(am__dirstamp) - -rm -f lib/cli/$(DEPDIR)/$(am__dirstamp) - -rm -f lib/cli/$(am__dirstamp) - -rm -f ospf6d/$(DEPDIR)/$(am__dirstamp) - -rm -f ospf6d/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ - mostlyclean-am - -distclean: distclean-am - -rm -rf bgpd/$(DEPDIR) helpers/c/$(DEPDIR) isisd/$(DEPDIR) lib/$(DEPDIR) lib/cli/$(DEPDIR) ospf6d/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf bgpd/$(DEPDIR) helpers/c/$(DEPDIR) isisd/$(DEPDIR) lib/$(DEPDIR) lib/cli/$(DEPDIR) ospf6d/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ - clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - -.c_clippy.c: - @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; } - $(AM_V_CLIPPY)$(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $< - -.l.c: - $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $< -.y.c: - $(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $< - -# Rules -@HAVE_PROTOBUF_TRUE@.proto.pb.h: -@HAVE_PROTOBUF_TRUE@ $(Q_PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^ - -@HAVE_PROTOBUF_TRUE@.proto.pb-c.c: -@HAVE_PROTOBUF_TRUE@ $(AM_V_PROTOC_C)$(Q_PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^ -@HAVE_PROTOBUF_TRUE@.pb-c.c.pb-c.h: -@HAVE_PROTOBUF_TRUE@ @/bin/true - -PYTHON ?= python - -lib/cli/test_cli.o: lib/cli/test_cli_clippy.c -ospf6d/test_lsdb.o: ospf6d/test_lsdb_clippy.c - -../vtysh/vtysh_cmd.c: - $(MAKE) -C ../vtysh vtysh_cmd.c - -lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c - sed \ - -e 's/"vtysh\.h"/"tests.h"/' \ - -e 's/vtysh_init_cmd/test_init_cmd/' \ - -e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \ - < ../vtysh/vtysh_cmd.c \ - > "$@" - -isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz - gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@" -isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \ - isisd/test_fuzz_isis_tlv_tests.h - -.PHONY: tests.xml -tests.xml: $(check_PROGRAMS) - $(PYTHON) $(srcdir)/runtests.py --junitxml=$@ -v $(srcdir) -check: tests.xml - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/tests/lib/cxxcompat.c b/tests/lib/cxxcompat.c index 48fa0ec8a9..6624de7386 100644 --- a/tests/lib/cxxcompat.c +++ b/tests/lib/cxxcompat.c @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#define test__cplusplus + #include "lib/zebra.h" #include "lib/agg_table.h" @@ -107,6 +109,17 @@ #include "lib/zassert.h" #include "lib/zclient.h" +PREDECL_RBTREE_UNIQ(footree) +struct foo { + int dummy; + struct footree_item item; +}; +static int foocmp(const struct foo *a, const struct foo *b) +{ + return memcmp(&a->dummy, &b->dummy, sizeof(a->dummy)); +} +DECLARE_RBTREE_UNIQ(footree, struct foo, item, foocmp) + int main(int argc, char **argv) { return 0; diff --git a/tests/lib/test_idalloc.c b/tests/lib/test_idalloc.c index 3053c1c074..ce1582b1ba 100644 --- a/tests/lib/test_idalloc.c +++ b/tests/lib/test_idalloc.c @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "id_alloc.h" #include <inttypes.h> diff --git a/tests/lib/test_prefix2str.c b/tests/lib/test_prefix2str.c new file mode 100644 index 0000000000..cbfc20a797 --- /dev/null +++ b/tests/lib/test_prefix2str.c @@ -0,0 +1,80 @@ +/* + * prefix2str() unit test + * Copyright (C) 2019 David Lamparter + * Portions: + * Copyright (C) 2019 Cumulus Networks, Inc + * Quentin Young + * + * This program 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 of the License, or (at your option) + * any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> + +#include "lib/prefix.h" + +#include "tests/helpers/c/prng.h" + +int main(int argc, char **argv) +{ + size_t i, j, k, l; + struct in6_addr i6; + char buf1[64], buf2[64], ntopbuf[64]; + struct prng *prng; + struct prefix p = {}; + + prng = prng_new(0); + /* IPv4 */ + p.family = AF_INET; + for (i = 0; i < 1000; i++) { + p.u.prefix = prng_rand(prng); + p.prefixlen = prng_rand(prng) >> 26; + snprintf(buf1, sizeof(buf1), "%s/%d", + inet_ntop(AF_INET, &p.u.prefix4, ntopbuf, + sizeof(ntopbuf)), + p.prefixlen); + prefix2str(&p, buf2, sizeof(buf2)); + assert(!strcmp(buf1, buf2)); + fprintf(stdout, "%s\n", buf1); + } + + /* IPv6 */ + p.family = AF_INET6; + for (i = 0; i < 10000; i++) { + uint16_t *i6w = (uint16_t *)&i6; + for (j = 0; j < 8; j++) + i6w[j] = prng_rand(prng); + + /* clear some words */ + l = prng_rand(prng) & 7; + for (j = 0; j < l; j++) { + uint32_t num = __builtin_ctz(prng_rand(prng)); + uint32_t where = prng_rand(prng) & 7; + + for (k = where; k < where + num && k < 8; k++) + i6w[k] = 0; + } + + p.prefixlen = prng_rand(prng) >> 24; + memcpy(&p.u.prefix, &i6, sizeof(i6)); + snprintf(buf1, sizeof(buf1), "%s/%d", + inet_ntop(AF_INET6, &p.u.prefix6, ntopbuf, + sizeof(ntopbuf)), + p.prefixlen); + prefix2str(&p, buf2, sizeof(buf2)); + assert(!strcmp(buf1, buf2)); + fprintf(stdout, "%s\n", buf1); + } + + return 0; +} diff --git a/tests/lib/test_prefix2str.py b/tests/lib/test_prefix2str.py new file mode 100644 index 0000000000..6e26d1b409 --- /dev/null +++ b/tests/lib/test_prefix2str.py @@ -0,0 +1,6 @@ +import frrtest + +class TestPrefix2str(frrtest.TestMultiOut): + program = './test_prefix2str' + +TestPrefix2str.exit_cleanly() diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c index c8ef150b07..24de3fa88d 100644 --- a/tests/lib/test_printfrr.c +++ b/tests/lib/test_printfrr.c @@ -27,6 +27,7 @@ static int errors; +static void printcmp(const char *fmt, ...) PRINTFRR(1, 2); static void printcmp(const char *fmt, ...) { va_list ap; @@ -58,6 +59,7 @@ static void printcmp(const char *fmt, ...) errors++; } +static void printchk(const char *ref, const char *fmt, ...) PRINTFRR(2, 3); static void printchk(const char *ref, const char *fmt, ...) { va_list ap; diff --git a/tests/lib/test_seqlock.c b/tests/lib/test_seqlock.c index 6b2b9ed8a5..9cc6f80702 100644 --- a/tests/lib/test_seqlock.c +++ b/tests/lib/test_seqlock.c @@ -18,6 +18,10 @@ * Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include <stdint.h> #include <inttypes.h> diff --git a/tests/subdir.am b/tests/subdir.am index 41f1a4873b..270c0811b4 100644 --- a/tests/subdir.am +++ b/tests/subdir.am @@ -55,6 +55,7 @@ check_PROGRAMS = \ tests/lib/test_memory \ tests/lib/test_nexthop_iter \ tests/lib/test_ntop \ + tests/lib/test_prefix2str \ tests/lib/test_printfrr \ tests/lib/test_privs \ tests/lib/test_ringbuf \ @@ -236,6 +237,10 @@ tests_lib_test_ntop_CFLAGS = $(TESTS_CFLAGS) tests_lib_test_ntop_CPPFLAGS = $(TESTS_CPPFLAGS) tests_lib_test_ntop_LDADD = # none tests_lib_test_ntop_SOURCES = tests/lib/test_ntop.c tests/helpers/c/prng.c +tests_lib_test_prefix2str_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_prefix2str_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_prefix2str_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_prefix2str_SOURCES = tests/lib/test_prefix2str.c tests/helpers/c/prng.c tests_lib_test_printfrr_CFLAGS = $(TESTS_CFLAGS) tests_lib_test_printfrr_CPPFLAGS = $(TESTS_CPPFLAGS) tests_lib_test_printfrr_LDADD = $(ALL_TESTS_LDADD) @@ -328,6 +333,7 @@ EXTRA_DIST += \ tests/lib/test_atomlist.py \ tests/lib/test_nexthop_iter.py \ tests/lib/test_ntop.py \ + tests/lib/test_prefix2str.py \ tests/lib/test_printfrr.py \ tests/lib/test_ringbuf.py \ tests/lib/test_srcdest_table.py \ diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py index ce542413ba..02fba97316 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py @@ -149,7 +149,9 @@ def ltemplatePreRouterStartHook(): krel = platform.release() tgen = get_topogen() logger.info('pre router-start hook, kernel=' + krel) - if topotest.version_cmp(krel, '4.15') == 0: + + if topotest.version_cmp(krel, '4.15') >= 0 and \ + topotest.version_cmp(krel, '4.18') <= 0: l3mdev_accept = 1 else: l3mdev_accept = 0 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py index 897fc48436..c17bf1168c 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py @@ -6,7 +6,7 @@ if ret != False and found != None: luCommand('ce3', 'vtysh -c "show bgp sum"', '.', 'pass', 'See %s sharp routes' % num) if num > 0: - wait = num/500 + wait = 2*num/500 luCommand('ce1', 'vtysh -c "sharp remove routes 10.0.0.0 {}"'.format(num),'.','none','Removing {} routes'.format(num)) luCommand('ce2', 'vtysh -c "sharp remove routes 10.0.0.0 {}"'.format(num),'.','none','Removing {} routes'.format(num)) rtrs = ['ce1', 'ce2', 'ce3'] diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py index 3b3aac5fbe..7f114d10df 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py @@ -10,7 +10,7 @@ if c > 0: d = r - c * 256 - 1 else: d = r -wait = num/1000 +wait = 2*num/1000 mem = {} rtrs = ['ce1', 'ce2', 'ce3', 'r1', 'r2', 'r3', 'r4'] for rtr in rtrs: diff --git a/tests/topotests/bgp_multiview_topo1/README.md b/tests/topotests/bgp_multiview_topo1/README.md index b9982d4900..c5e615d252 100644 --- a/tests/topotests/bgp_multiview_topo1/README.md +++ b/tests/topotests/bgp_multiview_topo1/README.md @@ -55,8 +55,6 @@ Simplified `R1` config: ip address 172.16.1.254/24 no link-detect ! - bgp multiple-instance - ! router bgp 100 view 1 bgp router-id 172.30.1.1 network 172.20.0.0/28 route-map local1 diff --git a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf index 0c24942f43..71397a9942 100644 --- a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf +++ b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf @@ -11,8 +11,6 @@ log file bgpd.log !debug bgp filters !debug bgp zebra ! -bgp multiple-instance -! router bgp 100 view 1 bgp router-id 172.30.1.1 network 172.20.0.0/28 route-map local1 diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index 2acb04fb0e..86993665ce 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -38,6 +38,11 @@ import time from lib.topolog import logger +if sys.version_info[0] > 2: + import configparser +else: + import ConfigParser as configparser + from mininet.topo import Topo from mininet.net import Mininet from mininet.node import Node, OVSSwitch, Host @@ -624,6 +629,20 @@ class Router(Node): super(Router, self).__init__(name, **params) self.logdir = params.get('logdir') + # Backward compatibility: + # Load configuration defaults like topogen. + self.config_defaults = configparser.ConfigParser({ + 'verbosity': 'info', + 'frrdir': '/usr/lib/frr', + 'quaggadir': '/usr/lib/quagga', + 'routertype': 'frr', + 'memleak_path': None, + }) + self.config_defaults.read( + os.path.join(os.path.dirname(os.path.realpath(__file__)), + '../pytest.ini') + ) + # If this topology is using old API and doesn't have logdir # specified, then attempt to generate an unique logdir. if self.logdir is None: @@ -652,7 +671,7 @@ class Router(Node): "Configure FRR binaries" self.daemondir = params.get('frrdir') if self.daemondir is None: - self.daemondir = '/usr/lib/frr' + self.daemondir = self.config_defaults.get('topogen', 'frrdir') zebra_path = os.path.join(self.daemondir, 'zebra') if not os.path.isfile(zebra_path): @@ -662,7 +681,7 @@ class Router(Node): "Configure Quagga binaries" self.daemondir = params.get('quaggadir') if self.daemondir is None: - self.daemondir = '/usr/lib/quagga' + self.daemondir = self.config_defaults.get('topogen', 'quaggadir') zebra_path = os.path.join(self.daemondir, 'zebra') if not os.path.isfile(zebra_path): @@ -676,7 +695,10 @@ class Router(Node): # User did not specify the daemons directory, try to autodetect it. self.daemondir = params.get('daemondir') if self.daemondir is None: - self.routertype = params.get('routertype', 'frr') + self.routertype = params.get('routertype', + self.config_defaults.get( + 'topogen', + 'routertype')) if self.routertype == 'quagga': self._config_quagga(**params) else: @@ -688,7 +710,7 @@ class Router(Node): raise Exception('No zebra binary found in {}'.format(zpath)) # Allow user to specify routertype when the path was specified. if params.get('routertype') is not None: - self.routertype = self.params.get('routertype') + self.routertype = params.get('routertype') self.cmd('ulimit -c unlimited') # Set ownership of config files diff --git a/tools/frr.vim b/tools/frr.vim new file mode 100644 index 0000000000..86aa0c0e3f --- /dev/null +++ b/tools/frr.vim @@ -0,0 +1,36 @@ +" settings & syntax hilighting for FRR codebase +" 2019 by David Lamparter, placed in public domain + +let c_gnu=1 + +function! CStyleFRR() + syn clear cFormat + syn match cFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbiuoxXDOUfFeEgGcCsSn]\|[pd]\([A-Z][A-Z0-9]*[a-z]*\|\)\|\[\^\=.[^]]*\]\)" contained + syn match cFormat display "%%" contained + + syn keyword cIterator frr_each frr_each_safe frr_each_from + syn keyword cMacroOp offsetof container_of container_of_null array_size + + syn keyword cStorageClass atomic + syn keyword cFormatConst PRId64 PRIu64 PRIx64 + syn keyword cFormatConst PRId32 PRIu32 PRIx32 + syn keyword cFormatConst PRId16 PRIu16 PRIx16 + syn keyword cFormatConst PRId8 PRIu8 PRIx8 + + " you can unlink these by just giving them their own hilighting / color + hi link cFormatConst cFormat + hi link cIterator cRepeat + hi link cMacroOp cOperator + + " indentation + setlocal cindent + setlocal cinoptions=:0,(0,u4,w1,W8 + setlocal shiftwidth=8 + setlocal softtabstop=0 + setlocal textwidth=0 + setlocal fo=croql + setlocal noet +endfunction + +" auto-apply the above based on path rules +"autocmd BufRead,BufNewFile /home/.../frr/*.[ch] call CStyleFRR() diff --git a/vrrpd/subdir.am b/vrrpd/subdir.am index a328f969d6..57eec108cb 100644 --- a/vrrpd/subdir.am +++ b/vrrpd/subdir.am @@ -14,7 +14,6 @@ vrrpd_libvrrp_a_SOURCES = \ vrrpd/vrrp.c \ vrrpd/vrrp_arp.c \ vrrpd/vrrp_debug.c \ - vrrpd/vrrp_memory.c \ vrrpd/vrrp_ndisc.c \ vrrpd/vrrp_packet.c \ vrrpd/vrrp_vty.c \ @@ -25,7 +24,6 @@ noinst_HEADERS += \ vrrpd/vrrp.h \ vrrpd/vrrp_arp.h \ vrrpd/vrrp_debug.h \ - vrrpd/vrrp_memory.h \ vrrpd/vrrp_ndisc.h \ vrrpd/vrrp_packet.h \ vrrpd/vrrp_vty.h \ diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index 3d535cbfba..5213b27d32 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -34,13 +34,15 @@ #include "vrrp.h" #include "vrrp_arp.h" #include "vrrp_debug.h" -#include "vrrp_memory.h" #include "vrrp_ndisc.h" #include "vrrp_packet.h" #include "vrrp_zebra.h" #define VRRP_LOGPFX "[CORE] " +DEFINE_MTYPE_STATIC(VRRPD, VRRP_IP, "VRRP IP address") +DEFINE_MTYPE_STATIC(VRRPD, VRRP_RTR, "VRRP Router") + /* statics */ struct hash *vrrp_vrouters_hash; bool vrrp_autoconfig_is_on; @@ -768,7 +770,7 @@ static void vrrp_send_advertisement(struct vrrp_router *r) ssize_t sent = sendto(r->sock_tx, pkt, (size_t)pktsz, 0, &dest.sa, sockunion_sizeof(&dest)); - XFREE(MTYPE_VRRP_PKT, pkt); + vrrp_pkt_free(pkt); if (sent < 0) { zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM diff --git a/vrrpd/vrrp.h b/vrrpd/vrrp.h index fd4901fe22..5d355d04b5 100644 --- a/vrrpd/vrrp.h +++ b/vrrpd/vrrp.h @@ -23,6 +23,7 @@ #include <zebra.h> #include <netinet/ip.h> +#include "lib/memory.h" #include "lib/hash.h" #include "lib/hook.h" #include "lib/if.h" @@ -54,6 +55,8 @@ /* User compatibility constant */ #define CS2MS 10 +DECLARE_MGROUP(VRRPD) + /* Configured defaults */ struct vrrp_defaults { uint8_t priority; diff --git a/vrrpd/vrrp_main.c b/vrrpd/vrrp_main.c index 46a92d936a..6c6a06064d 100644 --- a/vrrpd/vrrp_main.c +++ b/vrrpd/vrrp_main.c @@ -39,6 +39,8 @@ #include "vrrp_vty.h" #include "vrrp_zebra.h" +DEFINE_MGROUP(VRRPD, "vrrpd") + char backup_config_file[256]; zebra_capabilities_t _caps_p[] = { diff --git a/vrrpd/vrrp_memory.c b/vrrpd/vrrp_memory.c deleted file mode 100644 index 30eef523cd..0000000000 --- a/vrrpd/vrrp_memory.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * VRRP memory types. - * Copyright (C) 2018-2019 Cumulus Networks, Inc. - * Quentin Young - * - * This program 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 of the License, or (at your option) - * any later version. - * - * This program 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 this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include <zebra.h> - -#include "lib/memory.h" - -#include "vrrp_memory.h" - -DEFINE_MGROUP(VRRPD, "vrrpd"); -DEFINE_MTYPE(VRRPD, VRRP_IP, "VRRP IP address"); -DEFINE_MTYPE(VRRPD, VRRP_PKT, "VRRP packet"); -DEFINE_MTYPE(VRRPD, VRRP_RTR, "VRRP Router"); diff --git a/vrrpd/vrrp_memory.h b/vrrpd/vrrp_memory.h deleted file mode 100644 index c3025d1acb..0000000000 --- a/vrrpd/vrrp_memory.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * VRRP memory types. - * Copyright (C) 2018-2019 Cumulus Networks, Inc. - * Quentin Young - * - * This program 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 of the License, or (at your option) - * any later version. - * - * This program 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 this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __VRRP_MEMORY_H__ -#define __VRRP_MEMORY_H__ - -#include <zebra.h> - -#include "lib/memory.h" - -DECLARE_MGROUP(VRRPD); -DECLARE_MTYPE(VRRP_IP); -DECLARE_MTYPE(VRRP_PKT); -DECLARE_MTYPE(VRRP_RTR); - -#endif /* __VRRP_MEMORY_H__ */ diff --git a/vrrpd/vrrp_packet.c b/vrrpd/vrrp_packet.c index c3f2afba4c..c6b7ac1a7f 100644 --- a/vrrpd/vrrp_packet.c +++ b/vrrpd/vrrp_packet.c @@ -28,9 +28,10 @@ #include "vrrp.h" #include "vrrp_debug.h" -#include "vrrp_memory.h" #include "vrrp_packet.h" +DEFINE_MTYPE_STATIC(VRRPD, VRRP_PKT, "VRRP packet") + /* clang-format off */ const char *vrrp_packet_names[16] = { [0] = "Unknown", @@ -151,6 +152,11 @@ ssize_t vrrp_pkt_adver_build(struct vrrp_pkt **pkt, struct ipaddr *src, return pktsize; } +void vrrp_pkt_free(struct vrrp_pkt *pkt) +{ + XFREE(MTYPE_VRRP_PKT, pkt); +} + size_t vrrp_pkt_adver_dump(char *buf, size_t buflen, struct vrrp_pkt *pkt) { if (buflen < 1) diff --git a/vrrpd/vrrp_packet.h b/vrrpd/vrrp_packet.h index 475e4780d5..c2ce22f008 100644 --- a/vrrpd/vrrp_packet.h +++ b/vrrpd/vrrp_packet.h @@ -135,6 +135,9 @@ ssize_t vrrp_pkt_adver_build(struct vrrp_pkt **pkt, struct ipaddr *src, uint16_t max_adver_int, uint8_t numip, struct ipaddr **ips); +/* free memory allocated by vrrp_pkt_adver_build's pkt arg */ +void vrrp_pkt_free(struct vrrp_pkt *pkt); + /* * Dumps a VRRP ADVERTISEMENT packet to a string. * diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index 48d81b0258..2dc3d3f8a3 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -29,7 +29,6 @@ #include "vrrp.h" #include "vrrp_debug.h" -#include "vrrp_memory.h" #include "vrrp_vty.h" #ifndef VTYSH_EXTRACT_PL #include "vrrpd/vrrp_vty_clippy.c" diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 9c2de0f62b..b8957c2b00 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -373,6 +373,10 @@ void vtysh_config_parse_line(void *arg, const char *line) strlen("debug northbound")) == 0) config = config_get(NORTHBOUND_DEBUG_NODE, line); + else if (strncmp(line, "debug route-map", + strlen("debug route-map")) + == 0) + config = config_get(RMAP_DEBUG_NODE, line); else if (strncmp(line, "debug", strlen("debug")) == 0) config = config_get(DEBUG_NODE, line); else if (strncmp(line, "password", strlen("password")) == 0 @@ -418,7 +422,8 @@ void vtysh_config_parse_line(void *arg, const char *line) || (I) == ACCESS_IPV6_NODE || (I) == ACCESS_MAC_NODE \ || (I) == PREFIX_IPV6_NODE || (I) == FORWARDING_NODE \ || (I) == DEBUG_NODE || (I) == AAA_NODE || (I) == VRF_DEBUG_NODE \ - || (I) == NORTHBOUND_DEBUG_NODE || (I) == MPLS_NODE) + || (I) == NORTHBOUND_DEBUG_NODE || (I) == RMAP_DEBUG_NODE \ + || (I) == MPLS_NODE) /* Display configuration to file pointer. */ void vtysh_config_dump(void) diff --git a/zebra/interface.c b/zebra/interface.c index 13582008a7..719cf05db1 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1517,7 +1517,6 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) #endif /* HAVE_PROC_NET_DEV */ #ifdef HAVE_NET_RT_IFLIST -#if defined(__bsdi__) || defined(__NetBSD__) /* Statistics print out using sysctl (). */ vty_out(vty, " input packets %llu, bytes %llu, dropped %llu," @@ -1542,25 +1541,6 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) vty_out(vty, " collisions %llu\n", (unsigned long long)ifp->stats.ifi_collisions); -#else - /* Statistics print out using sysctl (). */ - vty_out(vty, - " input packets %lu, bytes %lu, dropped %lu," - " multicast packets %lu\n", - ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes, - ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts); - - vty_out(vty, " input errors %lu\n", ifp->stats.ifi_ierrors); - - vty_out(vty, - " output packets %lu, bytes %lu, multicast packets %lu\n", - ifp->stats.ifi_opackets, ifp->stats.ifi_obytes, - ifp->stats.ifi_omcasts); - - vty_out(vty, " output errors %lu\n", ifp->stats.ifi_oerrors); - - vty_out(vty, " collisions %lu\n", ifp->stats.ifi_collisions); -#endif /* __bsdi__ || __NetBSD__ */ #endif /* HAVE_NET_RT_IFLIST */ } @@ -1613,12 +1593,13 @@ DEFPY(show_interface, show_interface_cmd, /* Show all interfaces to vty. */ -DEFUN (show_interface_vrf_all, +DEFPY (show_interface_vrf_all, show_interface_vrf_all_cmd, - "show interface vrf all", + "show interface vrf all [brief$brief]", SHOW_STR "Interface status and configuration\n" - VRF_ALL_CMD_HELP_STR) + VRF_ALL_CMD_HELP_STR + "Interface status and configuration summary\n") { struct vrf *vrf; struct interface *ifp; @@ -1626,9 +1607,14 @@ DEFUN (show_interface_vrf_all, interface_update_stats(); /* All interface print. */ - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) - FOR_ALL_INTERFACES (vrf, ifp) - if_dump_vty(vty, ifp); + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + if (brief) { + ifs_dump_brief_vty(vty, vrf); + } else { + FOR_ALL_INTERFACES (vrf, ifp) + if_dump_vty(vty, ifp); + } + } return CMD_SUCCESS; } diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 387a3531bd..2c306434a3 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -23,6 +23,7 @@ #if defined(HANDLE_NETLINK_FUZZING) #include <stdio.h> #include <string.h> +#include "libfrr.h" #endif /* HANDLE_NETLINK_FUZZING */ #ifdef HAVE_NETLINK @@ -128,8 +129,18 @@ static const struct message family_str[] = {{AF_INET, "ipv4"}, {RTNL_FAMILY_IP6MR, "ipv6MR"}, {0}}; -static const struct message rttype_str[] = {{RTN_UNICAST, "unicast"}, +static const struct message rttype_str[] = {{RTN_UNSPEC, "none"}, + {RTN_UNICAST, "unicast"}, + {RTN_LOCAL, "local"}, + {RTN_BROADCAST, "broadcast"}, + {RTN_ANYCAST, "anycast"}, {RTN_MULTICAST, "multicast"}, + {RTN_BLACKHOLE, "blackhole"}, + {RTN_UNREACHABLE, "unreachable"}, + {RTN_PROHIBIT, "prohibited"}, + {RTN_THROW, "throw"}, + {RTN_NAT, "nat"}, + {RTN_XRESOLVE, "resolver"}, {0}}; extern struct thread_master *master; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 92c78a4cbb..d594accf4d 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -330,6 +330,10 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, bh_type = BLACKHOLE_ADMINPROHIB; break; default: + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("Route rtm_type: %s(%d) intentionally ignoring", + nl_rttype_to_str(rtm->rtm_type), + rtm->rtm_type); return 0; } @@ -2413,8 +2417,13 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) } /* if kernel marks our rfc5549 neighbor entry invalid, re-install it */ - if (h->nlmsg_type == RTM_NEWNEIGH && !(ndm->ndm_state & NUD_VALID)) - netlink_handle_5549(ndm, zif, ifp, &ip); + if (h->nlmsg_type == RTM_NEWNEIGH && !(ndm->ndm_state & NUD_VALID)) { + if (!(ndm->ndm_state & NUD_FAILED)) + netlink_handle_5549(ndm, zif, ifp, &ip); + else + zlog_info("Neighbor Entry for %s has entered a failed state, not reinstalling", + ifp->name); + } /* The neighbor is present on an SVI. From this, we locate the * underlying diff --git a/zebra/rtadv.c b/zebra/rtadv.c index e181b495b8..5841c44b03 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -50,6 +50,8 @@ extern struct zebra_privs_t zserv_privs; #if defined(HAVE_RTADV) +DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix") + #ifdef OPEN_BSD #include <netinet/icmp6.h> #endif diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 1707d3a68b..f93562b31b 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "lib/libfrr.h" #include "lib/debug.h" #include "lib/frratomic.h" @@ -32,8 +36,8 @@ #include "zebra/debug.h" /* Memory type for context blocks */ -DEFINE_MTYPE(ZEBRA, DP_CTX, "Zebra DPlane Ctx") -DEFINE_MTYPE(ZEBRA, DP_PROV, "Zebra DPlane Provider") +DEFINE_MTYPE_STATIC(ZEBRA, DP_CTX, "Zebra DPlane Ctx") +DEFINE_MTYPE_STATIC(ZEBRA, DP_PROV, "Zebra DPlane Provider") #ifndef AOK # define AOK 0 diff --git a/zebra/zebra_memory.c b/zebra/zebra_memory.c index ee041b1c3d..a9c2c5fe58 100644 --- a/zebra/zebra_memory.c +++ b/zebra/zebra_memory.c @@ -26,11 +26,5 @@ #include "zebra_memory.h" DEFINE_MGROUP(ZEBRA, "zebra") -DEFINE_MTYPE(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix") -DEFINE_MTYPE(ZEBRA, ZEBRA_VRF, "ZEBRA VRF") DEFINE_MTYPE(ZEBRA, RE, "Route Entry") -DEFINE_MTYPE(ZEBRA, RIB_QUEUE, "RIB process work queue") -DEFINE_MTYPE(ZEBRA, STATIC_ROUTE, "Static route") DEFINE_MTYPE(ZEBRA, RIB_DEST, "RIB destination") -DEFINE_MTYPE(ZEBRA, RIB_TABLE_INFO, "RIB table info") -DEFINE_MTYPE(ZEBRA, RNH, "Nexthop tracking object") diff --git a/zebra/zebra_memory.h b/zebra/zebra_memory.h index 667c73b227..e15f972493 100644 --- a/zebra/zebra_memory.h +++ b/zebra/zebra_memory.h @@ -29,17 +29,9 @@ extern "C" { #endif DECLARE_MGROUP(ZEBRA) -DECLARE_MTYPE(RTADV_PREFIX) DECLARE_MTYPE(ZEBRA_NS) -DECLARE_MTYPE(ZEBRA_VRF) DECLARE_MTYPE(RE) -DECLARE_MTYPE(RIB_QUEUE) -DECLARE_MTYPE(STATIC_ROUTE) DECLARE_MTYPE(RIB_DEST) -DECLARE_MTYPE(RIB_TABLE_INFO) -DECLARE_MTYPE(RNH) -DECLARE_MTYPE(DP_CTX) -DECLARE_MTYPE(DP_PROV) #ifdef __cplusplus } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index cc614abac5..555bec9593 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -744,9 +744,10 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) if (IS_ZEBRA_DEBUG_NHT_DETAILED) { char buf[PREFIX_STRLEN]; - zlog_debug("%s: %s Being examined for Nexthop Tracking", + zlog_debug("%s: %s Being examined for Nexthop Tracking Count: %zd", __PRETTY_FUNCTION__, - srcdest_rnode2str(rn, buf, sizeof(buf))); + srcdest_rnode2str(rn, buf, sizeof(buf)), + dest ? rnh_list_count(&dest->nht) : 0); } if (!dest) { rn = rn->parent; @@ -760,7 +761,7 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) * nht resolution and as such we need to call the * nexthop tracking evaluation code */ - frr_each (rnh_list, &dest->nht, rnh) { + frr_each_safe(rnh_list, &dest->nht, rnh) { struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id); struct prefix *p = &rnh->node->p; @@ -769,11 +770,12 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) char buf1[PREFIX_STRLEN]; char buf2[PREFIX_STRLEN]; - zlog_debug("%u:%s has Nexthop(%s) depending on it, evaluating %u:%u", + zlog_debug("%u:%s has Nexthop(%s) Type: %s depending on it, evaluating %u:%u", zvrf->vrf->vrf_id, srcdest_rnode2str(rn, buf1, sizeof(buf1)), prefix2str(p, buf2, sizeof(buf2)), + rnh_type2str(rnh->type), seq, rnh->seqno); } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 1024f3a052..5f397eb8c2 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -50,6 +50,8 @@ #include "zebra/zebra_memory.h" #include "zebra/zebra_errors.h" +DEFINE_MTYPE_STATIC(ZEBRA, RNH, "Nexthop tracking object") + static void free_state(vrf_id_t vrf_id, struct route_entry *re, struct route_node *rn); static void copy_state(struct rnh *rnh, struct route_entry *re, @@ -160,14 +162,15 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type, if (IS_ZEBRA_DEBUG_NHT) { prefix2str(p, buf, sizeof(buf)); - zlog_debug("%u: Add RNH %s type %d", vrfid, buf, type); + zlog_debug("%u: Add RNH %s type %s", vrfid, buf, + rnh_type2str(type)); } table = get_rnh_table(vrfid, afi, type); if (!table) { prefix2str(p, buf, sizeof(buf)); flog_warn(EC_ZEBRA_RNH_NO_TABLE, - "%u: Add RNH %s type %d - table not found", vrfid, - buf, type); + "%u: Add RNH %s type %s - table not found", vrfid, + buf, rnh_type2str(type)); exists = false; return NULL; } @@ -271,8 +274,8 @@ static void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type) if (IS_ZEBRA_DEBUG_NHT) { char buf[PREFIX2STR_BUFFER]; - zlog_debug("%u: Del RNH %s type %d", rnh->vrf_id, - rnh_str(rnh, buf, sizeof(buf)), type); + zlog_debug("%u: Del RNH %s type %s", rnh->vrf_id, + rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type)); } zebra_free_rnh(rnh); @@ -293,9 +296,9 @@ void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, { if (IS_ZEBRA_DEBUG_NHT) { char buf[PREFIX2STR_BUFFER]; - zlog_debug("%u: Client %s registers for RNH %s type %d", vrf_id, + zlog_debug("%u: Client %s registers for RNH %s type %s", vrf_id, zebra_route_string(client->proto), - rnh_str(rnh, buf, sizeof(buf)), type); + rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type)); } if (!listnode_lookup(rnh->client_list, client)) listnode_add(rnh->client_list, client); @@ -312,9 +315,9 @@ void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client, { if (IS_ZEBRA_DEBUG_NHT) { char buf[PREFIX2STR_BUFFER]; - zlog_debug("Client %s unregisters for RNH %s type %d", + zlog_debug("Client %s unregisters for RNH %s type %s", zebra_route_string(client->proto), - rnh_str(rnh, buf, sizeof(buf)), type); + rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type)); } listnode_delete(rnh->client_list, client); zebra_delete_rnh(rnh, type); @@ -803,8 +806,8 @@ static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi, if (IS_ZEBRA_DEBUG_NHT) { prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); - zlog_debug("%u:%s: Evaluate RNH, type %d %s", zvrf->vrf->vrf_id, - bufn, type, force ? "(force)" : ""); + zlog_debug("%u:%s: Evaluate RNH, type %s %s", zvrf->vrf->vrf_id, + bufn, rnh_type2str(type), force ? "(force)" : ""); } rnh = nrn->info; @@ -1156,9 +1159,9 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, struct rnh *rnh; if (IS_ZEBRA_DEBUG_NHT) - zlog_debug("%u: Client %s RNH cleanup for family %s type %d", + zlog_debug("%u: Client %s RNH cleanup for family %s type %s", vrf_id, zebra_route_string(client->proto), - afi2str(afi), type); + afi2str(afi), rnh_type2str(type)); ntable = get_rnh_table(vrf_id, afi, type); if (!ntable) { diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 95a3941181..c7d2c0d298 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -43,6 +43,18 @@ static inline int rnh_resolve_via_default(int family) return 0; } +static inline const char *rnh_type2str(rnh_type_t type) +{ + switch (type) { + case RNH_NEXTHOP_TYPE: + return "Nexthop"; + case RNH_IMPORT_CHECK_TYPE: + return "Import"; + } + + return "ERROR"; +} + extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type, bool *exists); extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index dbfe695a00..2f7d50541e 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1254,6 +1254,40 @@ static struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = { route_match_address_prefix_list_compile, route_match_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 nh_rmap_obj *nh_data; + + if (type == RMAP_ZEBRA && prefix->family == AF_INET6) { + nh_data = (struct nh_rmap_obj *)object; + if (!nh_data) + return RMAP_DENYMATCH; + + if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) + return RMAP_MATCH; + } + return RMAP_NOMATCH; +} + +static void *route_match_ipv6_next_hop_type_compile(const char *arg) +{ + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); +} + +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}; + /* `match ip address prefix-len PREFIXLEN' */ static route_map_result_t @@ -1345,6 +1379,40 @@ static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd = { route_match_address_prefix_len_free /* reuse */ }; +/* `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 nh_rmap_obj *nh_data; + + if (type == RMAP_ZEBRA && prefix->family == AF_INET) { + nh_data = (struct nh_rmap_obj *)object; + if (!nh_data) + return RMAP_DENYMATCH; + + if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) + 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 source-protocol PROTOCOL' */ static route_map_result_t route_match_source_protocol(void *rule, @@ -1927,6 +1995,9 @@ void zebra_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_tag_hook(generic_match_add); route_map_no_match_tag_hook(generic_match_delete); @@ -1936,6 +2007,9 @@ void zebra_route_map_init(void) 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_install_match(&route_match_tag_cmd); route_map_install_match(&route_match_interface_cmd); route_map_install_match(&route_match_ip_next_hop_cmd); @@ -1947,6 +2021,8 @@ void zebra_route_map_init(void) route_map_install_match(&route_match_ip_address_prefix_len_cmd); route_map_install_match(&route_match_ipv6_address_prefix_len_cmd); route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd); + route_map_install_match(&route_match_ip_next_hop_type_cmd); + route_map_install_match(&route_match_ipv6_next_hop_type_cmd); route_map_install_match(&route_match_source_protocol_cmd); route_map_install_match(&route_match_source_instance_cmd); diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index 4352d688a1..1e9f9e4ec7 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -32,6 +32,8 @@ #include "zebra_nhg.h" #include "debug.h" +DEFINE_MTYPE_STATIC(ZEBRA, RIB_TABLE_INFO, "RIB table info") + struct zebra_router zrouter = { .multipath_num = MULTIPATH_NUM, .ipv4_multicast_mode = MCAST_NO_CONFIG, diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index fdf0cbc693..fcc94a7be9 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -48,7 +48,8 @@ static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi, static void zebra_rnhtable_node_cleanup(struct route_table *table, struct route_node *node); -DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table"); +DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_VRF, "ZEBRA VRF") +DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table") /* VRF information update. */ static void zebra_vrf_add_update(struct zebra_vrf *zvrf) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 257fb168d2..1f8eec9cad 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2172,7 +2172,7 @@ DEFPY (show_evpn_mac_vni_all_dad, DEFPY (show_evpn_mac_vni_dad, show_evpn_mac_vni_dad_cmd, - "show evpn mac vni " CMD_VNI_RANGE " duplicate" "[json]", + "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]", SHOW_STR "EVPN\n" "MAC addresses\n" @@ -2182,10 +2182,8 @@ DEFPY (show_evpn_mac_vni_dad, JSON_STR) { struct zebra_vrf *zvrf; - vni_t vni; bool uj = use_json(argc, argv); - vni = strtoul(argv[4]->arg, NULL, 10); zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj); @@ -2195,7 +2193,7 @@ DEFPY (show_evpn_mac_vni_dad, DEFPY (show_evpn_neigh_vni_dad, show_evpn_neigh_vni_dad_cmd, - "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate" "[json]", + "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]", SHOW_STR "EVPN\n" "ARP and ND cache\n" @@ -2205,10 +2203,8 @@ DEFPY (show_evpn_neigh_vni_dad, JSON_STR) { struct zebra_vrf *zvrf; - vni_t vni; bool uj = use_json(argc, argv); - vni = strtoul(argv[4]->arg, NULL, 10); zvrf = zebra_vrf_get_evpn(); zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj); return CMD_SUCCESS; @@ -2387,7 +2383,7 @@ DEFUN (show_pbr_iptable, DEFPY (clear_evpn_dup_addr, clear_evpn_dup_addr_cmd, - "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE"$vni_val [mac M:A:C$mac_val | ip <A.B.C.D|X:X::X:X>]>", + "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE"$vni [mac M:A:C$mac_val | ip <A.B.C.D|X:X::X:X>]>", CLEAR_STR "EVPN\n" "Duplicate address \n" @@ -2401,15 +2397,12 @@ DEFPY (clear_evpn_dup_addr, "IPv6 address\n") { struct zebra_vrf *zvrf; - vni_t vni = 0; struct ipaddr host_ip = {.ipa_type = IPADDR_NONE }; struct ethaddr mac_addr; int ret = CMD_SUCCESS; zvrf = zebra_vrf_get_evpn(); - if (vni_val) { - vni = strtoul(vni_val, NULL, 10); - + if (vni_str) { if (mac_val) { prefix_str2mac(mac_val, &mac_addr); ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf, diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 077c1ff8f0..abd076bc82 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1386,7 +1386,9 @@ static void zvni_print_mac_hash(struct hash_bucket *bucket, void *ctxt) vty_out(vty, " %-5u", vid); else json_object_int_add(json_mac, "vlan", vid); - } + } else /* No vid? fill out the space */ + vty_out(vty, " %-5s", ""); + vty_out(vty, " %u/%u", mac->loc_seq, mac->rem_seq); if (json_mac_hdr == NULL) { vty_out(vty, "\n"); } else { @@ -1418,11 +1420,13 @@ static void zvni_print_mac_hash(struct hash_bucket *bucket, void *ctxt) if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) && (wctx->count == 0)) { vty_out(vty, "\nVNI %u\n\n", wctx->zvni->vni); - vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", - "Type", "Intf/Remote VTEP", "VLAN"); + vty_out(vty, "%-17s %-6s %-21s %-5s %s\n", + "MAC", "Type", "Intf/Remote VTEP", + "VLAN", "Seq #'s"); } - vty_out(vty, "%-17s %-6s %-21s\n", buf1, "remote", - inet_ntoa(mac->fwd_info.r_vtep_ip)); + vty_out(vty, "%-17s %-6s %-21s %-5s %u/%u\n", buf1, + "remote", inet_ntoa(mac->fwd_info.r_vtep_ip), + "", mac->loc_seq, mac->rem_seq); } else { json_object_string_add(json_mac, "type", "remote"); json_object_string_add(json_mac, "remoteVtep", @@ -1536,8 +1540,8 @@ static void zvni_print_mac_hash_all_vni(struct hash_bucket *bucket, void *ctxt) if (json == NULL) { vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n", zvni->vni, num_macs); - vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type", - "Intf/Remote VTEP", "VLAN"); + vty_out(vty, "%-17s %-6s %-21s %-5s %s\n", "MAC", + "Type", "Intf/Remote VTEP", "VLAN", "Seq #'s"); } else json_object_int_add(json_vni, "numMacs", num_macs); } diff --git a/zebra/zserv.c b/zebra/zserv.c index 49fb302ba8..cb9ca6578b 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1067,10 +1067,8 @@ DEFUN (show_zebra_client_summary, void zserv_read_file(char *input) { int fd; - struct thread t; fd = open(input, O_RDONLY | O_NONBLOCK); - t.u.fd = fd; zserv_client_create(fd); } |
