diff options
85 files changed, 1217 insertions, 686 deletions
diff --git a/bgpd/IMPLEMENTATION.txt b/bgpd/IMPLEMENTATION.txt index fff360ab96..0f06359686 100644 --- a/bgpd/IMPLEMENTATION.txt +++ b/bgpd/IMPLEMENTATION.txt @@ -131,7 +131,6 @@ bgpd.h struct peer_group struct bgp_notify: (in-core representation of wire format?) struct bgp_nexthop: (v4 and v6 addresses, *ifp) - struct bgp_rd: router distinguisher: 8 octects struct bgp_filter: distribute, prefix, aslist, route_maps struct peer: neighbor structure (very rich/complex) struct bgp_nlri: reference to wire format diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 0ffbe174ed..b2f34dd968 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -274,8 +274,7 @@ static void community_list_entry_add(struct community_list *list, /* Delete community-list entry from the list. */ static void community_list_entry_delete(struct community_list *list, - struct community_entry *entry, - int style) + struct community_entry *entry) { if (entry->next) entry->next->prev = entry->prev; @@ -882,7 +881,7 @@ int community_list_unset(struct community_list_handler *ch, const char *name, if (!entry) return COMMUNITY_LIST_ERR_CANT_FIND_LIST; - community_list_entry_delete(list, entry, style); + community_list_entry_delete(list, entry); route_map_notify_dependencies(name, RMAP_EVENT_CLIST_DELETED); return 0; @@ -1040,7 +1039,7 @@ int lcommunity_list_unset(struct community_list_handler *ch, const char *name, if (!entry) return COMMUNITY_LIST_ERR_CANT_FIND_LIST; - community_list_entry_delete(list, entry, style); + community_list_entry_delete(list, entry); return 0; } @@ -1057,8 +1056,6 @@ int extcommunity_list_set(struct community_list_handler *ch, const char *name, if (str == NULL) return COMMUNITY_LIST_ERR_MALFORMED_VAL; - entry = NULL; - /* Get community list. */ list = community_list_get(ch, name, EXTCOMMUNITY_LIST_MASTER); @@ -1149,7 +1146,7 @@ int extcommunity_list_unset(struct community_list_handler *ch, const char *name, if (!entry) return COMMUNITY_LIST_ERR_CANT_FIND_LIST; - community_list_entry_delete(list, entry, style); + community_list_entry_delete(list, entry); route_map_notify_dependencies(name, RMAP_EVENT_ECLIST_DELETED); return 0; diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 8c5356c998..2c372124d2 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -65,7 +65,6 @@ void ecommunity_free(struct ecommunity **ecom) if ((*ecom)->str) XFREE(MTYPE_ECOMMUNITY_STR, (*ecom)->str); XFREE(MTYPE_ECOMMUNITY, *ecom); - ecom = NULL; } static void ecommunity_hash_free(struct ecommunity *ecom) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index e2cf094cc1..a026df59a0 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -4639,7 +4639,6 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, int addpath_encoded; int psize = 0; uint8_t rtype; - uint8_t rlen; struct prefix p; /* Start processing the NLRI - there may be multiple in the MP_REACH */ @@ -4673,7 +4672,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, return -1; rtype = *pnt++; - psize = rlen = *pnt++; + psize = *pnt++; /* When packet overflow occur return immediately. */ if (pnt + psize > lim) diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index 9b998d4497..2d336fa6d8 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -91,7 +91,6 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, afi_t afi; safi_t safi; int psize = 0; - uint8_t rlen; struct prefix p; int ret; void *temp; @@ -121,7 +120,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, if (pnt + 1 > lim) return -1; - psize = rlen = *pnt++; + psize = *pnt++; /* When packet overflow occur return immediately. */ if (pnt + psize > lim) { diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index ceca644de2..8a051b7ff0 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -57,7 +57,7 @@ int bgp_parse_fec_update(void) memset(&p, 0, sizeof(struct prefix)); p.family = stream_getw(s); p.prefixlen = stream_getc(s); - stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); + stream_get(p.u.val, s, PSIZE(p.prefixlen)); label = stream_getl(s); /* hack for the bgp instance & SAFI = have to send/receive it */ diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c index 33f4d139b8..3e160bc56e 100644 --- a/bgpd/bgp_lcommunity.c +++ b/bgpd/bgp_lcommunity.c @@ -50,7 +50,6 @@ void lcommunity_free(struct lcommunity **lcom) if ((*lcom)->str) XFREE(MTYPE_LCOMMUNITY_STR, (*lcom)->str); XFREE(MTYPE_LCOMMUNITY, *lcom); - lcom = NULL; } static void lcommunity_hash_free(struct lcommunity *lcom) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 3a854be534..f72104dd33 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -220,7 +220,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8; /* exclude label & RD */ - memcpy(&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES, + memcpy(p.u.val, pnt + VPN_PREFIXLEN_MIN_BYTES, psize - VPN_PREFIXLEN_MIN_BYTES); if (attr) { @@ -490,7 +490,7 @@ leak_update( * (only one hop back to ultimate parent for vrf-vpn-vrf scheme). * Using a loop here supports more complex intra-bgp import-export * schemes that could be implemented in the future. - * + * */ for (bi_ultimate = source_bi; bi_ultimate->extra && bi_ultimate->extra->parent; @@ -1356,8 +1356,7 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */ struct bgp_node *prn; safi_t safi = SAFI_MPLS_VPN; - if (!bgp_vpn) - return; + assert(bgp_vpn); /* * Walk vpn table @@ -2253,3 +2252,66 @@ vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey) } return VRF_UNKNOWN; } + +/* + * The purpose of this function is to process leaks that were deferred + * from earlier per-vrf configuration due to not-yet-existing default + * vrf, in other words, configuration such as: + * + * router bgp MMM vrf FOO + * address-family ipv4 unicast + * rd vpn export 1:1 + * exit-address-family + * + * router bgp NNN + * ... + * + * This function gets called when the default instance ("router bgp NNN") + * is created. + */ +void vpn_leak_postchange_all(void) +{ + struct listnode *next; + struct bgp *bgp; + struct bgp *bgp_default = bgp_get_default(); + + assert(bgp_default); + + /* First, do any exporting from VRFs to the single VPN RIB */ + for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) { + + if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF) + continue; + + vpn_leak_postchange( + BGP_VPN_POLICY_DIR_TOVPN, + AFI_IP, + bgp_default, + bgp); + + vpn_leak_postchange( + BGP_VPN_POLICY_DIR_TOVPN, + AFI_IP6, + bgp_default, + bgp); + } + + /* Now, do any importing to VRFs from the single VPN RIB */ + for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) { + + if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF) + continue; + + vpn_leak_postchange( + BGP_VPN_POLICY_DIR_FROMVPN, + AFI_IP, + bgp_default, + bgp); + + vpn_leak_postchange( + BGP_VPN_POLICY_DIR_FROMVPN, + AFI_IP6, + bgp_default, + bgp); + } +} diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 384108dc0c..b0add40da9 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -182,6 +182,10 @@ static inline void vpn_leak_prechange(vpn_policy_direction_t direction, afi_t afi, struct bgp *bgp_vpn, struct bgp *bgp_vrf) { + /* Detect when default bgp instance is not (yet) defined by config */ + if (!bgp_vpn) + return; + if ((direction == BGP_VPN_POLICY_DIR_FROMVPN) && vpn_leak_from_vpn_active(bgp_vrf, afi, NULL)) { @@ -198,6 +202,10 @@ static inline void vpn_leak_postchange(vpn_policy_direction_t direction, afi_t afi, struct bgp *bgp_vpn, struct bgp *bgp_vrf) { + /* Detect when default bgp instance is not (yet) defined by config */ + if (!bgp_vpn) + return; + if (direction == BGP_VPN_POLICY_DIR_FROMVPN) vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi); if (direction == BGP_VPN_POLICY_DIR_TOVPN) { @@ -216,4 +224,6 @@ 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); + #endif /* _QUAGGA_BGP_MPLSVPN_H */ diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 32011d210b..76bfa73fee 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -447,8 +447,6 @@ int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; - rn2 = NULL; - bgp = SUBGRP_INST(subgrp); rn1 = bgp_node_match(bgp->connected_table[AFI_IP], &np); if (!rn1) diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h index c92fd9b0a7..42ebe97f2e 100644 --- a/bgpd/bgp_open.h +++ b/bgpd/bgp_open.h @@ -34,21 +34,12 @@ struct capability_mp_data { uint8_t safi; /* iana_safi_t */ }; -struct capability_as4 { - uint32_t as4; -}; - struct graceful_restart_af { afi_t afi; safi_t safi; uint8_t flag; }; -struct capability_gr { - uint16_t restart_flag_time; - struct graceful_restart_af gr[]; -}; - /* Capability Code */ #define CAPABILITY_CODE_MP 1 /* Multiprotocol Extensions */ #define CAPABILITY_CODE_REFRESH 2 /* Route Refresh Capability */ diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index 45ec21631c..b5ddfd4b21 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -348,7 +348,7 @@ static bool bgp_pbr_extract_enumerate(struct bgp_pbr_match_val list[], void *valmask, uint8_t type_entry) { bool ret; - uint8_t unary_operator_val = unary_operator; + uint8_t unary_operator_val; bool double_check = false; if ((unary_operator & OPERATOR_UNARY_OR) && diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h index 307a34e34f..e853784afd 100644 --- a/bgpd/bgp_pbr.h +++ b/bgpd/bgp_pbr.h @@ -57,17 +57,13 @@ struct bgp_pbr_match_val { uint16_t value; uint8_t compare_operator; uint8_t unary_operator; -} bgp_pbr_value_t; +}; #define FRAGMENT_DONT 1 #define FRAGMENT_IS 2 #define FRAGMENT_FIRST 4 #define FRAGMENT_LAST 8 -struct bgp_pbr_fragment_val { - uint8_t bitmask; -}; - struct bgp_pbr_entry_action { /* used to store enum bgp_pbr_action_enum enumerate */ uint8_t action; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 60d1b5f313..795bd15613 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2673,14 +2673,12 @@ static void bgp_rib_withdraw(struct bgp_node *rn, struct bgp_info *ri, struct peer *peer, afi_t afi, safi_t safi, struct prefix_rd *prd) { - int status = BGP_DAMP_NONE; - /* apply dampening, if result is suppressed, we'll be retaining * the bgp_info in the RIB for historical reference. */ if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) && peer->sort == BGP_PEER_EBGP) - if ((status = bgp_damp_withdraw(ri, rn, afi, safi, 0)) + if ((bgp_damp_withdraw(ri, rn, afi, safi, 0)) == BGP_DAMP_SUPPRESSED) { bgp_aggregate_decrement(peer->bgp, &rn->p, ri, afi, safi); @@ -4238,7 +4236,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, } /* Fetch prefix from NLRI packet. */ - memcpy(&p.u.prefix, pnt, psize); + memcpy(p.u.val, pnt, psize); /* Check address. */ if (afi == AFI_IP && safi == SAFI_UNICAST) { diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index db182eef98..774c484784 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -47,6 +47,7 @@ #include "bgpd/bgp_attr.h" #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_route.h" +#include "lib/thread.h" #include "rtrlib/rtrlib.h" #include "rtrlib/rtr_mgr.h" #include "rtrlib/lib/ip.h" @@ -128,16 +129,22 @@ static void route_match_free(void *rule); static route_map_result_t route_match(void *rule, struct prefix *prefix, route_map_object_t type, void *object); static void *route_match_compile(const char *arg); +static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi, + safi_t safi); static struct rtr_mgr_config *rtr_config; static struct list *cache_list; static int rtr_is_running; +static int rtr_is_stopping; +static int rtr_is_starting; static int rpki_debug; static unsigned int polling_period; static unsigned int expire_interval; static unsigned int retry_interval; static unsigned int timeout; static unsigned int initial_synchronisation_timeout; +static int rpki_sync_socket_rtr; +static int rpki_sync_socket_bgpd; static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1}; static struct route_map_rule_cmd route_match_rpki_cmd = { @@ -185,6 +192,14 @@ static void free_tr_socket(struct cache *cache) static int rpki_validate_prefix(struct peer *peer, struct attr *attr, struct prefix *prefix); +static void ipv6_addr_to_network_byte_order(const uint32_t *src, uint32_t *dest) +{ + int i; + + for (i = 0; i < 4; i++) + dest[i] = htonl(src[i]); +} + static void ipv6_addr_to_host_byte_order(const uint32_t *src, uint32_t *dest) { int i; @@ -303,10 +318,159 @@ inline int is_running(void) return rtr_is_running; } +static struct prefix *pfx_record_to_prefix(struct pfx_record *record) +{ + struct prefix *prefix = prefix_new(); + + prefix->prefixlen = record->min_len; + + if (record->prefix.ver == LRTR_IPV4) { + prefix->family = AF_INET; + prefix->u.prefix4.s_addr = htonl(record->prefix.u.addr4.addr); + } else { + prefix->family = AF_INET6; + ipv6_addr_to_network_byte_order(record->prefix.u.addr6.addr, + prefix->u.prefix6.s6_addr32); + } + + return prefix; +} + +static int bgpd_sync_callback(struct thread *thread) +{ + struct bgp *bgp; + struct listnode *node; + struct prefix *prefix; + struct pfx_record rec; + + thread_add_read(bm->master, bgpd_sync_callback, NULL, + rpki_sync_socket_bgpd, NULL); + int retval = + read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record)); + if (retval != sizeof(struct pfx_record)) { + RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd"); + return retval; + } + prefix = pfx_record_to_prefix(&rec); + + afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; + + for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { + safi_t safi; + + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (!bgp->rib[afi][safi]) + continue; + + struct list *matches = list_new(); + + matches->del = (void (*)(void *))bgp_unlock_node; + + bgp_table_range_lookup(bgp->rib[afi][safi], prefix, + rec.max_len, matches); + + + struct bgp_node *bgp_node; + + for (ALL_LIST_ELEMENTS_RO(matches, node, bgp_node)) + revalidate_bgp_node(bgp_node, afi, safi); + + list_delete_and_null(&matches); + } + } + + prefix_free(prefix); + return 0; +} + +static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi, + safi_t safi) +{ + struct bgp_adj_in *ain; + + for (ain = bgp_node->adj_in; ain; ain = ain->next) { + int ret; + struct bgp_info *bgp_info = bgp_node->info; + mpls_label_t *label = NULL; + uint32_t num_labels = 0; + + if (bgp_info && bgp_info->extra) { + label = bgp_info->extra->label; + num_labels = bgp_info->extra->num_labels; + } + ret = bgp_update(ain->peer, &bgp_node->p, 0, ain->attr, afi, + safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, + label, num_labels, 1, NULL); + + if (ret < 0) { + bgp_unlock_node(bgp_node); + return; + } + } +} + +static void revalidate_all_routes(void) +{ + struct bgp *bgp; + struct listnode *node; + struct bgp_node *bgp_node; + + for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { + for (size_t i = 0; i < 2; i++) { + safi_t safi; + afi_t afi = (i == 0) ? AFI_IP : AFI_IP6; + + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (!bgp->rib[afi][safi]) + continue; + + for (bgp_node = + bgp_table_top(bgp->rib[afi][safi]); + bgp_node; + bgp_node = bgp_route_next(bgp_node)) { + if (bgp_node->info != NULL) { + revalidate_bgp_node(bgp_node, + afi, safi); + } + } + } + } + } +} + +static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)), + const struct pfx_record rec, + const bool added __attribute__((unused))) +{ + if (rtr_is_stopping || rtr_is_starting) + return; + + int retval = + write(rpki_sync_socket_rtr, &rec, sizeof(struct pfx_record)); + if (retval != sizeof(struct pfx_record)) + RPKI_DEBUG("Could not write to rpki_sync_socket_rtr"); +} + +static void rpki_init_sync_socket(void) +{ + int fds[2]; + + RPKI_DEBUG("initializing sync socket"); + if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, fds) != 0) { + RPKI_DEBUG("Could not open rpki sync socket"); + return; + } + rpki_sync_socket_rtr = fds[0]; + rpki_sync_socket_bgpd = fds[1]; + thread_add_read(bm->master, bgpd_sync_callback, NULL, + rpki_sync_socket_bgpd, NULL); +} + static int bgp_rpki_init(struct thread_master *master) { rpki_debug = 0; rtr_is_running = 0; + rtr_is_stopping = 0; cache_list = list_new(); cache_list->del = (void (*)(void *)) & free_cache; @@ -318,6 +482,7 @@ static int bgp_rpki_init(struct thread_master *master) initial_synchronisation_timeout = INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT; install_cli_commands(); + rpki_init_sync_socket(); return 0; } @@ -326,6 +491,9 @@ static int bgp_rpki_fini(void) stop(); list_delete_and_null(&cache_list); + close(rpki_sync_socket_rtr); + close(rpki_sync_socket_bgpd); + return 0; } @@ -344,6 +512,9 @@ static int start(void) unsigned int waiting_time = 0; int ret; + rtr_is_stopping = 0; + rtr_is_starting = 1; + if (list_isempty(cache_list)) { RPKI_DEBUG( "No caches were found in config. Prefix validation is off."); @@ -353,9 +524,10 @@ static int start(void) int groups_len = listcount(cache_list); struct rtr_mgr_group *groups = get_groups(); + RPKI_DEBUG("Polling period: %d", polling_period); ret = rtr_mgr_init(&rtr_config, groups, groups_len, polling_period, - expire_interval, retry_interval, NULL, NULL, NULL, - NULL); + expire_interval, retry_interval, + rpki_update_cb_sync_rtr, NULL, NULL, NULL); if (ret == RTR_ERROR) { RPKI_DEBUG("Init rtr_mgr failed."); return ERROR; @@ -378,9 +550,13 @@ static int start(void) } if (rtr_mgr_conf_in_sync(rtr_config)) { RPKI_DEBUG("Got synchronisation with at least one RPKI cache!"); + RPKI_DEBUG("Forcing revalidation."); + rtr_is_starting = 0; + revalidate_all_routes(); } else { RPKI_DEBUG( "Timeout expired! Proceeding without RPKI validation data."); + rtr_is_starting = 0; } XFREE(MTYPE_BGP_RPKI_CACHE_GROUP, groups); @@ -390,6 +566,7 @@ static int start(void) static void stop(void) { + rtr_is_stopping = 1; if (rtr_is_running) { rtr_mgr_stop(rtr_config); rtr_mgr_free(rtr_config); @@ -864,7 +1041,7 @@ DEFPY (rpki_cache, "Preference of the cache server\n" "Preference value\n") { - int return_value = SUCCESS; + int return_value; // use ssh connection if (ssh_uname) { @@ -873,6 +1050,7 @@ DEFPY (rpki_cache, add_ssh_cache(cache, sshport, ssh_uname, ssh_privkey, ssh_pubkey, server_pubkey, preference); #else + return_value = SUCCESS; vty_out(vty, "ssh sockets are not supported. " "Please recompile rtrlib and frr with ssh support. " diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c index 613b924d0d..94e2d83cfe 100644 --- a/bgpd/bgp_table.c +++ b/bgpd/bgp_table.c @@ -114,3 +114,65 @@ struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t afi, safi_t safi) return rt; } + +static struct bgp_node * +bgp_route_next_until_maxlen(struct bgp_node *node, const struct bgp_node *limit, + const uint8_t maxlen) +{ + if (node->l_left && node->p.prefixlen < maxlen + && node->l_left->p.prefixlen <= maxlen) { + return bgp_node_from_rnode(node->l_left); + } + if (node->l_right && node->p.prefixlen < maxlen + && node->l_right->p.prefixlen <= maxlen) { + return bgp_node_from_rnode(node->l_right); + } + + while (node->parent && node != limit) { + if (bgp_node_from_rnode(node->parent->l_left) == node + && node->parent->l_right) { + return bgp_node_from_rnode(node->parent->l_right); + } + node = bgp_node_from_rnode(node->parent); + } + return NULL; +} + +void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p, + uint8_t maxlen, struct list *matches) +{ + struct bgp_node *node = bgp_node_from_rnode(table->route_table->top); + struct bgp_node *matched = NULL; + + if (node == NULL) + return; + + while (node && node->p.prefixlen <= p->prefixlen + && prefix_match(&node->p, p)) { + if (node->info && node->p.prefixlen == p->prefixlen) { + matched = node; + break; + } + node = bgp_node_from_rnode(node->link[prefix_bit( + &p->u.prefix, node->p.prefixlen)]); + } + + if ((matched == NULL && node->p.prefixlen > maxlen) || !node->parent) + return; + else if (matched == NULL) + matched = node = bgp_node_from_rnode(node->parent); + + if (matched->info) { + bgp_lock_node(matched); + listnode_add(matches, matched); + } + + while ((node = bgp_route_next_until_maxlen(node, matched, maxlen))) { + if (prefix_match(p, &node->p)) { + if (node->info) { + bgp_lock_node(node); + listnode_add(matches, node); + } + } + } +} diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h index 388c247227..60c2cbd4a4 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h @@ -24,6 +24,7 @@ #include "mpls.h" #include "table.h" #include "queue.h" +#include "linklist.h" struct bgp_table { /* table belongs to this instance */ @@ -309,4 +310,7 @@ static inline uint64_t bgp_table_version(struct bgp_table *table) return table->version; } +void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p, + uint8_t maxlen, struct list *matches); + #endif /* _QUAGGA_BGP_TABLE_H */ diff --git a/bgpd/bgp_vnc_types.h b/bgpd/bgp_vnc_types.h index 70f5646e94..f4202ff75e 100644 --- a/bgpd/bgp_vnc_types.h +++ b/bgpd/bgp_vnc_types.h @@ -25,16 +25,5 @@ typedef enum { BGP_VNC_SUBTLV_TYPE_RFPOPTION = 2, /* deprecated */ } bgp_vnc_subtlv_types; -/* - * VNC Attribute subtlvs - */ -struct bgp_vnc_subtlv_lifetime { - uint32_t lifetime; -}; - -struct bgp_vnc_subtlv_unaddr { - struct prefix un_address; /* IPv4 or IPv6; pfx length ignored */ -}; - #endif /* ENABLE_BGP_VNC */ #endif /* _QUAGGA_BGP_VNC_TYPES_H */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 86f3f97c49..e9d9a846af 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -928,6 +928,14 @@ DEFUN_NOSH (router_bgp, return CMD_WARNING_CONFIG_FAILED; } + /* + * If we just instantiated the default instance, complete + * any pending VRF-VPN leaking that was configured via + * earlier "router bgp X vrf FOO" blocks. + */ + if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) + vpn_leak_postchange_all(); + /* Pending: handle when user tries to change a view to vrf n vv. */ } @@ -3372,8 +3380,6 @@ DEFUN (neighbor_set_peer_group, struct peer *peer; struct peer_group *group; - peer = NULL; - ret = str2sockunion(argv[idx_peer]->arg, &su); if (ret < 0) { peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index df3f9ddd6f..714f6791c1 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1190,7 +1190,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, mpls_label_t label; int nh_othervrf = 0; char buf_prefix[PREFIX_STRLEN]; /* filled in if we are debugging */ - bool is_evpn = false; + bool is_evpn; int nh_updated; /* Don't try to install if we're not connected to Zebra or Zebra doesn't diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index d21c074ccc..e5b269eb70 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -888,129 +888,6 @@ static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi, } } -/* Reset all address family specific configuration. */ -static void peer_af_flag_reset(struct peer *peer, afi_t afi, safi_t safi) -{ - int i; - struct bgp_filter *filter; - char orf_name[BUFSIZ]; - - filter = &peer->filter[afi][safi]; - - /* Clear neighbor filter and route-map */ - for (i = FILTER_IN; i < FILTER_MAX; i++) { - if (filter->dlist[i].name) { - XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[i].name); - filter->dlist[i].name = NULL; - } - if (filter->plist[i].name) { - XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[i].name); - filter->plist[i].name = NULL; - } - if (filter->aslist[i].name) { - XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[i].name); - filter->aslist[i].name = NULL; - } - } - for (i = RMAP_IN; i < RMAP_MAX; i++) { - if (filter->map[i].name) { - XFREE(MTYPE_BGP_FILTER_NAME, filter->map[i].name); - filter->map[i].name = NULL; - } - } - - /* Clear unsuppress map. */ - if (filter->usmap.name) - XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name); - filter->usmap.name = NULL; - filter->usmap.map = NULL; - - /* Clear neighbor's all address family flags. */ - peer->af_flags[afi][safi] = 0; - - /* Clear neighbor's all address family sflags. */ - peer->af_sflags[afi][safi] = 0; - - /* Clear neighbor's all address family capabilities. */ - peer->af_cap[afi][safi] = 0; - - /* Clear ORF info */ - peer->orf_plist[afi][safi] = NULL; - sprintf(orf_name, "%s.%d.%d", peer->host, afi, safi); - prefix_bgp_orf_remove_all(afi, orf_name); - - /* Set default neighbor send-community. */ - if (!bgp_option_check(BGP_OPT_CONFIG_CISCO)) { - SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY); - SET_FLAG(peer->af_flags[afi][safi], - PEER_FLAG_SEND_EXT_COMMUNITY); - SET_FLAG(peer->af_flags[afi][safi], - PEER_FLAG_SEND_LARGE_COMMUNITY); - - SET_FLAG(peer->af_flags_invert[afi][safi], - PEER_FLAG_SEND_COMMUNITY); - SET_FLAG(peer->af_flags_invert[afi][safi], - PEER_FLAG_SEND_EXT_COMMUNITY); - SET_FLAG(peer->af_flags_invert[afi][safi], - PEER_FLAG_SEND_LARGE_COMMUNITY); - } - - /* Clear neighbor default_originate_rmap */ - if (peer->default_rmap[afi][safi].name) - XFREE(MTYPE_ROUTE_MAP_NAME, peer->default_rmap[afi][safi].name); - peer->default_rmap[afi][safi].name = NULL; - peer->default_rmap[afi][safi].map = NULL; - - /* Clear neighbor maximum-prefix */ - peer->pmax[afi][safi] = 0; - peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT; -} - -/* peer global config reset */ -static void peer_global_config_reset(struct peer *peer) -{ - int saved_flags = 0; - - peer->change_local_as = 0; - peer->ttl = (peer_sort(peer) == BGP_PEER_IBGP ? MAXTTL : 1); - if (peer->update_source) { - sockunion_free(peer->update_source); - peer->update_source = NULL; - } - if (peer->update_if) { - XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if); - peer->update_if = NULL; - } - - if (peer_sort(peer) == BGP_PEER_IBGP) - peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; - else - peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; - - /* These are per-peer specific flags and so we must preserve them */ - saved_flags |= CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY); - saved_flags |= CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN); - peer->flags = 0; - SET_FLAG(peer->flags, saved_flags); - - peer->holdtime = 0; - peer->keepalive = 0; - peer->connect = 0; - peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; - - /* Reset some other configs back to defaults. */ - peer->v_start = BGP_INIT_START_TIMER; - peer->password = NULL; - peer->local_id = peer->bgp->router_id; - peer->v_holdtime = peer->bgp->default_holdtime; - peer->v_keepalive = peer->bgp->default_keepalive; - - bfd_info_free(&(peer->bfd_info)); - - /* Set back the CONFIG_NODE flag. */ - SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE); -} - /* Check peer's AS number and determines if this peer is IBGP or EBGP */ static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer) { @@ -2821,61 +2698,6 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, return 0; } -int peer_group_unbind(struct bgp *bgp, struct peer *peer, - struct peer_group *group) -{ - struct peer *other; - afi_t afi; - safi_t safi; - - if (group != peer->group) - return BGP_ERR_PEER_GROUP_MISMATCH; - - FOREACH_AFI_SAFI (afi, safi) { - if (peer->afc[afi][safi]) { - peer->afc[afi][safi] = 0; - peer_af_flag_reset(peer, afi, safi); - - if (peer_af_delete(peer, afi, safi) != 0) { - zlog_err( - "couldn't delete af structure for peer %s", - peer->host); - } - } - } - - assert(listnode_lookup(group->peer, peer)); - peer_unlock(peer); /* peer group list reference */ - listnode_delete(group->peer, peer); - peer->group = NULL; - other = peer->doppelganger; - - if (group->conf->as) { - peer_delete(peer); - if (other && other->status != Deleted) { - if (other->group) { - peer_unlock(other); - listnode_delete(group->peer, other); - } - other->group = NULL; - peer_delete(other); - } - return 0; - } - - bgp_bfd_deregister_peer(peer); - peer_global_config_reset(peer); - - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) { - peer->last_reset = PEER_DOWN_RMAP_UNBIND; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else - bgp_session_reset(peer); - - return 0; -} - static int bgp_startup_timer_expire(struct thread *thread) { struct bgp *bgp; @@ -3825,9 +3647,6 @@ struct peer_flag_action { /* Action when the flag is changed. */ enum peer_change_type type; - - /* Peer down cause */ - uint8_t peer_down; }; static const struct peer_flag_action peer_flag_action_list[] = { @@ -7649,10 +7468,6 @@ int bgp_config_write(struct vty *vty) vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n", bgp->default_subgroup_pkt_queue_max); - /* BGP default autoshutdown neighbors */ - if (bgp->autoshutdown) - vty_out(vty, " bgp default shutdown\n"); - /* BGP client-to-client reflection. */ if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT)) vty_out(vty, " no bgp client-to-client reflection\n"); @@ -7806,6 +7621,16 @@ int bgp_config_write(struct vty *vty) /* listen range and limit for dynamic BGP neighbors */ bgp_config_write_listen(vty, bgp); + /* + * BGP default autoshutdown neighbors + * + * This must be placed after any peer and peer-group + * configuration, to avoid setting all peers to shutdown after + * a daemon restart, which is undesired behavior. (see #2286) + */ + if (bgp->autoshutdown) + vty_out(vty, " bgp default shutdown\n"); + /* No auto-summary */ if (bgp_option_check(BGP_OPT_CONFIG_CISCO)) vty_out(vty, " no auto-summary\n"); @@ -7914,8 +7739,6 @@ static void bgp_if_finish(struct bgp *bgp) } } -extern void bgp_snmp_init(void); - static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token) { struct vrf *vrf = NULL; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 1fbc0a0db9..06eb86da95 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -590,13 +590,7 @@ struct bgp_nexthop { #define BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE 1 -/* BGP router distinguisher value. */ -#define BGP_RD_SIZE 8 - -struct bgp_rd { - uint8_t val[BGP_RD_SIZE]; -}; - +/* Route map direction */ #define RMAP_IN 0 #define RMAP_OUT 1 #define RMAP_MAX 2 @@ -1590,7 +1584,6 @@ extern int peer_afc_set(struct peer *, afi_t, safi_t, int); extern int peer_group_bind(struct bgp *, union sockunion *, struct peer *, struct peer_group *, as_t *); -extern int peer_group_unbind(struct bgp *, struct peer *, struct peer_group *); extern int peer_flag_set(struct peer *, uint32_t); extern int peer_flag_unset(struct peer *, uint32_t); diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 04531433ac..a1f1169a7a 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -3197,8 +3197,8 @@ DEFUN (debug_rfapi_register_vn_un_l2o, memset(optary, 0, sizeof(optary)); optary[opt_next].v.l2addr.logical_net_id = strtoul(argv[14]->arg, NULL, 10); - if ((rc = rfapiStr2EthAddr(argv[12]->arg, - &optary[opt_next].v.l2addr.macaddr))) { + if (rfapiStr2EthAddr(argv[12]->arg, + &optary[opt_next].v.l2addr.macaddr)) { vty_out(vty, "Bad mac address \"%s\"\n", argv[12]->arg); return CMD_WARNING_CONFIG_FAILED; } diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index c71f59563f..60534fece0 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -2099,7 +2099,6 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, nhp->vn_options = NULL; XFREE(MTYPE_RFAPI_NEXTHOP, nhp); - nhp = NULL; } } diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index ae31c3fe9e..d4dd34d1dd 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -402,7 +402,6 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi) { - struct rfapi_cfg *hc; struct route_node *rn; struct bgp_info *ri; @@ -411,7 +410,7 @@ static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi) if (!bgp) return; - if (!(hc = bgp->rfapi_cfg)) + if (!(bgp->rfapi_cfg)) return; if (!VNC_EXPORT_BGP_CE_ENABLED(bgp->rfapi_cfg)) { diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 7182e952b5..156572b57f 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -557,7 +557,6 @@ static void vnc_import_bgp_add_route_mode_resolve_nve( struct bgp_info *info) /* unicast info */ { afi_t afi = family2afi(prefix->family); - struct rfapi_cfg *hc = NULL; struct prefix pfx_unicast_nexthop = {0}; /* happy valgrind */ @@ -607,7 +606,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve( return; } - if (!(hc = bgp->rfapi_cfg)) { + if (!(bgp->rfapi_cfg)) { vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", __func__); return; @@ -698,7 +697,7 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, struct peer *peer = info->peer; struct attr *attr = info->attr; struct attr hattr; - struct rfapi_cfg *hc = NULL; + struct rfapi_cfg *hc = bgp->rfapi_cfg; struct attr *iattr = NULL; struct rfapi_ip_addr vnaddr; @@ -723,7 +722,7 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, return; } - if (!(hc = bgp->rfapi_cfg)) { + if (!hc) { vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", __func__); return; @@ -886,7 +885,6 @@ vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix, struct peer *peer = info->peer; struct attr *attr = info->attr; struct attr hattr; - struct rfapi_cfg *hc = NULL; struct attr *iattr = NULL; struct rfapi_ip_addr vnaddr; @@ -911,7 +909,7 @@ vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix, return; } - if (!(hc = bgp->rfapi_cfg)) { + if (!(bgp->rfapi_cfg)) { vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", __func__); return; diff --git a/doc/Makefile.am b/doc/Makefile.am index 1f27e4a8e7..62cb3c2edb 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -183,6 +183,7 @@ EXTRA_DIST = frr-sphinx.mk \ developer/ldpd-basic-test-setup.md \ developer/library.rst \ developer/Makefile.in \ + developer/maintainer-release-build.rst \ developer/memtypes.rst \ developer/modules.rst \ developer/next-hop-tracking.rst \ diff --git a/doc/developer/maintainer-release-build.rst b/doc/developer/maintainer-release-build.rst new file mode 100644 index 0000000000..907bd14ee6 --- /dev/null +++ b/doc/developer/maintainer-release-build.rst @@ -0,0 +1,89 @@ +Release Build Procedure for FRR maintainers +========================================================= + +1. Rename branch (if needed) + +.. code-block:: shell + + git clone git@github.com:FRRouting/frr.git + cd frr + git checkout dev/5.0 + git push origin :refs/heads/dev/5.0 + git push origin dev/5.0:refs/heads/stable/5.0 + +2. Checkout the new stable branch: + +.. code-block:: shell + + git checkout stable/5.0 + +3. Update Changelog for RedHat Package: + + Edit :file:`redhat/frr.spec.in` and look for the ``%changelog`` section: + + - Change last (top of list) entry from ``%{version}`` to previous fixed + version number, i.e.:: + + * Tue Nov 7 2017 Martin Winter <mwinter@opensourcerouting.org> - %{version} + + to:: + + * Tue Nov 7 2017 Martin Winter <mwinter@opensourcerouting.org> - 3.0.2 + + - Add new entry to the top of the list with ``%{version}`` tag and changelog + for version. + Make sure to watch the format, i.e. the day is always 2 characters, with + the 1st character being a space if the day is one digit. + +4. Update Changelog for Debian Packages: + + Edit :file:`debianpkg/changelog.in`: + + - Change last (top of list) entry from ``@VERSION@`` to previous fixed + version number, i.e.:: + + frr (@VERSION@) RELEASED; urgency=medium + + to:: + + frr (3.0.2) RELEASED; urgency=medium + + - Add a new entry to the top of the list with a ``@VERSION@`` tag and + changelog for version. + +5. Change main version number: + + - Edit :file:`configure.ac` and change version in the ``AC_INIT`` command + - Create a new entry with the version as ``%{version}`` tag + +6. Test building at least a Red Hat and Ubuntu package (or create a PR to have + the CI system test them) + +7. Commit the changes, adding the changelog to the commit message + +8. Create a git tag for the version: + + .. code-block:: shell + + git tag -a frr-5.0 -m "FRRouting Release 5.0" + +9. Push the commit and tag(s) and watch for errors on CI: + + .. code-block:: shell + + git push + git push --tags + +10. Kick off the Release build plan on the CI system for the correct release + +11. Send a Release Announcement with changes to + ``announce@lists.frrouting.org`` + +12. Kick off the Snapcraft build plan for the correct release + +13. After CI plans succeed, release on GitHub by going to + https://github.com/FRRouting/frr/releases and selecting "Draft a new + release". + +14. Deploy Snapcraft release (after CI system finishes the tests for snapcraft + testplan) diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index b29769da49..cd03d2733d 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -300,6 +300,37 @@ Documentation should be written in reStructuredText. Sphinx extensions may be utilized but pure ReST is preferred where possible. See :ref:`documentation`. +Code Reviews +============ + +Code quality is paramount for any large program. Consequently we require +reviews of all submitted patches by at least one person other than the +submitter before the patch is merged. + +Because of the nature of the software, FRR's maintainer list (i.e. those with +commit permissions) tends to contain employees / members of various +organizations. In order to prevent conflicts of interest, we use an honor +system in which submissions from an individual representing one company should +be merged by someone unaffiliated with that company. + +Guidelines for code review +"""""""""""""""""""""""""" + +- As a rule of thumb, the depth of the review should be proportional to the + scope and / or impact of the patch. + +- Anyone may review a patch. + +- When using GitHub reviews, marking "Approve" on a code review indicates + willingness to merge the PR. + +- For individuals with merge rights, marking "Changes requested" is equivalent + to a NAK. + +- For a PR you marked with "Changes requested", please respond to updates in a + timely manner to avoid impeding the flow of development. + + Coding Practices & Style ======================== diff --git a/doc/user/rpki.rst b/doc/user/rpki.rst index 93a8e4396a..c35928db07 100644 --- a/doc/user/rpki.rst +++ b/doc/user/rpki.rst @@ -44,6 +44,9 @@ In a nutshell, the current implementation provides the following features - Route maps can be configured to match a specific RPKI validation state. This allows the creation of local policies, which handle BGP routes based on the outcome of the Prefix Origin Validation. +- Updates from the RPKI cache servers are directly applied and path selection + is updated accordingly. (Soft reconfiguration **must** be enabled for this + to work). .. _enabling-rpki: diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 180d2d7efd..08606c2128 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -521,6 +521,94 @@ entered within the VRF context the static routes are created in the VRF. show ip table vrf r1-cust1 table 43 +.. _zebra-mpls: + +MPLS Commands +============= + +You can configure static mpls entries in zebra. Basically, handling MPLS +consists of popping, swapping or pushing labels to IP packets. + +MPLS Acronyms +------------- + +:abbr:`LSR (Labeled Switch Router)` + Networking devices handling labels used to forward traffic between and through + them. + +:abbr:`LER (Labeled Edge Router)` + A Labeled edge router is located at the edge of an MPLS network, generally + between an IP network and an MPLS network. + +MPLS Push Action +---------------- + +The push action is generally used for LER devices, which want to encapsulate +all traffic for a wished destination into an MPLS label. This action is stored +in routing entry, and can be configured like a route: + +.. index:: [no] ip route NETWORK MASK GATEWAY|INTERFACE label LABEL +.. clicmd:: [no] ip route NETWORK MASK GATEWAY|INTERFACE label LABEL + + NETWORK ans MASK stand for the IP prefix entry to be added as static + route entry. + GATEWAY is the gateway IP address to reach, in order to reach the prefix. + INTERFACE is the interface behind which the prefix is located. + LABEL is the MPLS label to use to reach the prefix abovementioned. + + You can check that the static entry is stored in the zebra RIB database, by + looking at the presence of the entry. + + :: + + zebra(configure)# ip route 1.1.1.1/32 10.0.1.1 label 777 + zebra# show ip route + Codes: K - kernel route, C - connected, S - static, R - RIP, + O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, + T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, + F - PBR, + > - selected route, * - FIB route + + S>* 1.1.1.1/32 [1/0] via 10.0.1.1, r2-eth0, label 777, 00:39:42 + +MPLS Swap and Pop Action +------------------------ + +The swap action is generally used for LSR devices, which swap a packet with a +label, with an other label. The Pop action is used on LER devices, at the +termination of the MPLS traffic; this is used to remove MPLS header. + +.. index:: [no] mpls lsp INCOMING_LABEL GATEWAY OUTGOING_LABEL|explicit-null|implicit-null +.. clicmd:: [no] mpls lsp INCOMING_LABEL GATEWAY OUTGOING_LABEL|explicit-null|implicit-null + + INCOMING_LABEL and OUTGOING_LABEL are MPLS labels with values ranging from 16 + to 1048575. + GATEWAY is the gateway IP address where to send MPLS packet. + The outgoing label can either be a value or have an explicit-null label header. This + specific header can be read by IP devices. The incoming label can also be removed; in + that case the implicit-null keyword is used, and the outgoing packet emitted is an IP + packet without MPLS header. + +You can check that the MPLS actions are stored in the zebra MPLS table, by looking at the +presence of the entry. + +.. index:: show mpls table +.. clicmd:: show mpls table + +:: + + zebra(configure)# mpls lsp 18 10.125.0.2 implicit-null + zebra(configure)# mpls lsp 19 10.125.0.2 20 + zebra(configure)# mpls lsp 21 10.125.0.2 explicit-null + zebra# show mpls table + Inbound Outbound + Label Type Nexthop Label + -------- ------- --------------- -------- + 18 Static 10.125.0.2 implicit-null + 19 Static 10.125.0.2 20 + 21 Static 10.125.0.2 IPv4 Explicit Null + + .. _multicast-rib-commands: Multicast RIB Commands diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h index ed0a5407b2..9113505581 100644 --- a/ldpd/ldpd.h +++ b/ldpd/ldpd.h @@ -691,7 +691,8 @@ void embedscope(struct sockaddr_in6 *); void recoverscope(struct sockaddr_in6 *); void addscope(struct sockaddr_in6 *, uint32_t); void clearscope(struct in6_addr *); -struct sockaddr *addr2sa(int af, union ldpd_addr *, uint16_t); +void addr2sa(int af, const union ldpd_addr *, uint16_t, + union sockunion *su); void sa2addr(struct sockaddr *, int *, union ldpd_addr *, in_port_t *); socklen_t sockaddr_len(struct sockaddr *); diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index 1c3f650dff..78a6131ca4 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -584,8 +584,8 @@ nbr_connect_cb(struct thread *thread) int nbr_establish_connection(struct nbr *nbr) { - struct sockaddr_storage local_sa; - struct sockaddr_storage remote_sa; + union sockunion local_su; + union sockunion remote_su; struct adj *adj; struct nbr_params *nbrp; #ifdef __OpenBSD__ @@ -619,16 +619,14 @@ nbr_establish_connection(struct nbr *nbr) #endif } - memcpy(&local_sa, addr2sa(nbr->af, &nbr->laddr, 0), sizeof(local_sa)); - memcpy(&remote_sa, addr2sa(nbr->af, &nbr->raddr, LDP_PORT), - sizeof(local_sa)); + addr2sa(nbr->af, &nbr->laddr, 0, &local_su); + addr2sa(nbr->af, &nbr->raddr, LDP_PORT, &remote_su); if (nbr->af == AF_INET6 && nbr->raddr_scope) - addscope((struct sockaddr_in6 *)&remote_sa, nbr->raddr_scope); + addscope(&remote_su.sin6, nbr->raddr_scope); - if (bind(nbr->fd, (struct sockaddr *)&local_sa, - sockaddr_len((struct sockaddr *)&local_sa)) == -1) { + if (bind(nbr->fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) { log_warn("%s: error while binding socket to %s", __func__, - log_sockaddr((struct sockaddr *)&local_sa)); + log_sockaddr(&local_su.sa)); close(nbr->fd); return (-1); } @@ -646,15 +644,15 @@ nbr_establish_connection(struct nbr *nbr) send_hello(adj->source.type, adj->source.link.ia, adj->source.target); - if (connect(nbr->fd, (struct sockaddr *)&remote_sa, - sockaddr_len((struct sockaddr *)&remote_sa)) == -1) { + if (connect(nbr->fd, &remote_su.sa, sockaddr_len(&remote_su.sa)) + == -1) { if (errno == EINPROGRESS) { thread_add_write(master, nbr_connect_cb, nbr, nbr->fd, &nbr->ev_connect); return (0); } log_warn("%s: error while connecting to %s", __func__, - log_sockaddr((struct sockaddr *)&remote_sa)); + log_sockaddr(&remote_su.sa)); close(nbr->fd); return (-1); } diff --git a/ldpd/packet.c b/ldpd/packet.c index b0f9c5eb14..8ca90841de 100644 --- a/ldpd/packet.c +++ b/ldpd/packet.c @@ -70,7 +70,7 @@ int send_packet(int fd, int af, union ldpd_addr *dst, struct iface_af *ia, void *pkt, size_t len) { - struct sockaddr *sa; + union sockunion su; switch (af) { case AF_INET: @@ -97,10 +97,10 @@ send_packet(int fd, int af, union ldpd_addr *dst, struct iface_af *ia, fatalx("send_packet: unknown af"); } - sa = addr2sa(af, dst, LDP_PORT); - if (sendto(fd, pkt, len, 0, sa, sockaddr_len(sa)) == -1) { + addr2sa(af, dst, LDP_PORT, &su); + if (sendto(fd, pkt, len, 0, &su.sa, sockaddr_len(&su.sa)) == -1) { log_warn("%s: error sending packet to %s", __func__, - log_sockaddr(sa)); + log_sockaddr(&su.sa)); return (-1); } diff --git a/ldpd/pfkey.c b/ldpd/pfkey.c index a1a79dabfd..906737217c 100644 --- a/ldpd/pfkey.c +++ b/ldpd/pfkey.c @@ -64,17 +64,17 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, ssize_t n; int len = 0; int iov_cnt; - struct sockaddr_storage ssrc, sdst, smask, dmask; - struct sockaddr *saptr; + struct sockaddr_storage smask, dmask; + union sockunion su_src, su_dst; if (!pid) pid = getpid(); /* we need clean sockaddr... no ports set */ - memset(&ssrc, 0, sizeof(ssrc)); memset(&smask, 0, sizeof(smask)); - if ((saptr = addr2sa(af, src, 0))) - memcpy(&ssrc, saptr, sizeof(ssrc)); + + addr2sa(af, src, 0, &su_src); + switch (af) { case AF_INET: memset(&((struct sockaddr_in *)&smask)->sin_addr, 0xff, 32/8); @@ -86,13 +86,13 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, default: return (-1); } - smask.ss_family = ssrc.ss_family; - smask.ss_len = ssrc.ss_len; + smask.ss_family = su_src.sa.sa_family; + smask.ss_len = sockaddr_len(&su_src.sa); - memset(&sdst, 0, sizeof(sdst)); memset(&dmask, 0, sizeof(dmask)); - if ((saptr = addr2sa(af, dst, 0))) - memcpy(&sdst, saptr, sizeof(sdst)); + + addr2sa(af, dst, 0, &su_dst); + switch (af) { case AF_INET: memset(&((struct sockaddr_in *)&dmask)->sin_addr, 0xff, 32/8); @@ -104,8 +104,8 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, default: return (-1); } - dmask.ss_family = sdst.ss_family; - dmask.ss_len = sdst.ss_len; + dmask.ss_family = su_dst.sa.sa_family; + dmask.ss_len = sockaddr_len(&su_dst.sa); memset(&smsg, 0, sizeof(smsg)); smsg.sadb_msg_version = PF_KEY_V2; @@ -138,11 +138,13 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, memset(&sa_src, 0, sizeof(sa_src)); sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; - sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8; + sa_src.sadb_address_len = + (sizeof(sa_src) + ROUNDUP(sockaddr_len(&su_src.sa))) / 8; memset(&sa_dst, 0, sizeof(sa_dst)); sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST; - sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; + sa_dst.sadb_address_len = + (sizeof(sa_dst) + ROUNDUP(sockaddr_len(&su_dst.sa))) / 8; sa.sadb_sa_auth = aalg; sa.sadb_sa_encrypt = SADB_X_EALG_AES; /* XXX */ @@ -195,8 +197,8 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, iov[iov_cnt].iov_base = &sa_dst; iov[iov_cnt].iov_len = sizeof(sa_dst); iov_cnt++; - iov[iov_cnt].iov_base = &sdst; - iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len); + iov[iov_cnt].iov_base = &su_dst; + iov[iov_cnt].iov_len = ROUNDUP(sockaddr_len(&su_dst.sa)); smsg.sadb_msg_len += sa_dst.sadb_address_len; iov_cnt++; @@ -204,8 +206,8 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, iov[iov_cnt].iov_base = &sa_src; iov[iov_cnt].iov_len = sizeof(sa_src); iov_cnt++; - iov[iov_cnt].iov_base = &ssrc; - iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len); + iov[iov_cnt].iov_base = &su_src; + iov[iov_cnt].iov_len = ROUNDUP(sockaddr_len(&su_src.sa)); smsg.sadb_msg_len += sa_src.sadb_address_len; iov_cnt++; diff --git a/ldpd/socket.c b/ldpd/socket.c index eaea9973a0..aefa3461a8 100644 --- a/ldpd/socket.c +++ b/ldpd/socket.c @@ -37,7 +37,7 @@ ldp_create_socket(int af, enum socket_type type) { int fd, domain, proto; union ldpd_addr addr; - struct sockaddr_storage local_sa; + union sockunion local_su; #ifdef __OpenBSD__ int opt; #endif @@ -70,14 +70,12 @@ ldp_create_socket(int af, enum socket_type type) case LDP_SOCKET_DISC: /* listen on all addresses */ memset(&addr, 0, sizeof(addr)); - memcpy(&local_sa, addr2sa(af, &addr, LDP_PORT), - sizeof(local_sa)); + addr2sa(af, &addr, LDP_PORT, &local_su); break; case LDP_SOCKET_EDISC: case LDP_SOCKET_SESSION: addr = (ldp_af_conf_get(ldpd_conf, af))->trans_addr; - memcpy(&local_sa, addr2sa(af, &addr, LDP_PORT), - sizeof(local_sa)); + addr2sa(af, &addr, LDP_PORT, &local_su); /* ignore any possible error */ sock_set_bindany(fd, 1); break; @@ -90,8 +88,7 @@ ldp_create_socket(int af, enum socket_type type) close(fd); return (-1); } - if (bind(fd, (struct sockaddr *)&local_sa, - sockaddr_len((struct sockaddr *)&local_sa)) == -1) { + if (bind(fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) { save_errno = errno; if (ldpd_privs.change(ZPRIVS_LOWER)) log_warn("%s: could not lower privs", __func__); @@ -307,7 +304,7 @@ sock_set_md5sig(int fd, int af, union ldpd_addr *addr, const char *password) if (fd == -1) return (0); #if HAVE_DECL_TCP_MD5SIG - memcpy(&su, addr2sa(af, addr, 0), sizeof(su)); + addr2sa(af, addr, 0, &su); if (ldpe_privs.change(ZPRIVS_RAISE)) { log_warn("%s: could not raise privs", __func__); diff --git a/ldpd/util.c b/ldpd/util.c index e735263f5f..12f9cb0ccf 100644 --- a/ldpd/util.c +++ b/ldpd/util.c @@ -305,14 +305,13 @@ clearscope(struct in6_addr *in6) } } -struct sockaddr * -addr2sa(int af, union ldpd_addr *addr, uint16_t port) +void +addr2sa(int af, const union ldpd_addr *addr, uint16_t port, union sockunion *su) { - static struct sockaddr_storage ss; - struct sockaddr_in *sa_in = (struct sockaddr_in *)&ss; - struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)&ss; + struct sockaddr_in *sa_in = &su->sin; + struct sockaddr_in6 *sa_in6 = &su->sin6; - memset(&ss, 0, sizeof(ss)); + memset(su, 0, sizeof(*su)); switch (af) { case AF_INET: sa_in->sin_family = AF_INET; @@ -333,8 +332,6 @@ addr2sa(int af, union ldpd_addr *addr, uint16_t port) default: fatalx("addr2sa: unknown af"); } - - return ((struct sockaddr *)&ss); } void diff --git a/lib/hash.c b/lib/hash.c index 37f6cdcc8f..ee5401b236 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -241,21 +241,15 @@ void hash_iterate(struct hash *hash, void (*func)(struct hash_backet *, void *), unsigned int i; struct hash_backet *hb; struct hash_backet *hbnext; - uint32_t count = 0; - for (i = 0; i < hash->size; i++) { + for (i = 0; i < hash->size; i++) for (hb = hash->index[i]; hb; hb = hbnext) { /* get pointer to next hash backet here, in case (*func) * decides to delete hb by calling hash_release */ hbnext = hb->next; (*func)(hb, arg); - count++; - } - if (count == hash->count) - return; - } } void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *), @@ -265,7 +259,6 @@ void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *), struct hash_backet *hb; struct hash_backet *hbnext; int ret = HASHWALK_CONTINUE; - uint32_t count = 0; for (i = 0; i < hash->size; i++) { for (hb = hash->index[i]; hb; hb = hbnext) { @@ -276,10 +269,7 @@ void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *), ret = (*func)(hb, arg); if (ret == HASHWALK_ABORT) return; - count++; } - if (count == hash->count) - return; } } diff --git a/lib/hash.h b/lib/hash.h index c7e670b723..12c214e469 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -232,7 +232,9 @@ extern void *hash_release(struct hash *hash, void *data); * Iterate over the elements in a hash table. * * It is safe to delete items passed to the iteration function from the hash - * table during iteration. + * table during iteration. Please note that adding entries to the hash + * during the walk will cause undefined behavior in that some new entries + * will be walked and some will not. So do not do this. * * hash * hash table to operate on @@ -250,7 +252,9 @@ extern void hash_iterate(struct hash *hash, * Iterate over the elements in a hash table, stopping on condition. * * It is safe to delete items passed to the iteration function from the hash - * table during iteration. + * table during iteration. Please note that adding entries to the hash + * during the walk will cause undefined behavior in that some new entries + * will be walked and some will not. So do not do this. * * hash * hash table to operate on diff --git a/lib/netns_linux.c b/lib/netns_linux.c index a3fae8f39f..a80b51fa00 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -435,10 +435,13 @@ char *ns_netns_pathname(struct vty *vty, const char *name) if (!result) { if (vty) - vty_out(vty, "Invalid pathname: %s\n", + vty_out(vty, "Invalid pathname for %s: %s\n", + pathname, safe_strerror(errno)); else - zlog_warn("Invalid pathname: %s", safe_strerror(errno)); + zlog_warn("Invalid pathname for %s: %s", + pathname, + safe_strerror(errno)); return NULL; } check_base = basename(pathname); diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h index a44f4e3542..473ecb34fc 100644 --- a/lib/nexthop_group.h +++ b/lib/nexthop_group.h @@ -56,6 +56,11 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh, (nhop); \ (nhop) = nexthop_next(nhop) +#define ALL_NEXTHOPS_PTR(head, nhop) \ + (nhop) = ((head)->nexthop); \ + (nhop); \ + (nhop) = nexthop_next(nhop) + struct nexthop_hold { char *nhvrf_name; diff --git a/lib/srcdest_table.c b/lib/srcdest_table.c index a70574cff2..32f8e8ca5b 100644 --- a/lib/srcdest_table.c +++ b/lib/srcdest_table.c @@ -127,7 +127,7 @@ route_table_delegate_t _srcdest_srcnode_delegate = { /* NB: read comments in code for refcounting before using! */ static struct route_node *srcdest_srcnode_get(struct route_node *rn, - struct prefix_ipv6 *src_p) + const struct prefix_ipv6 *src_p) { struct srcdest_rnode *srn; @@ -158,11 +158,12 @@ static struct route_node *srcdest_srcnode_get(struct route_node *rn, route_unlock_node(rn); } - return route_node_get(srn->src_table, (struct prefix *)src_p); + return route_node_get(srn->src_table, (const struct prefix *)src_p); } -static struct route_node *srcdest_srcnode_lookup(struct route_node *rn, - struct prefix_ipv6 *src_p) +static struct route_node *srcdest_srcnode_lookup( + struct route_node *rn, + const struct prefix_ipv6 *src_p) { struct srcdest_rnode *srn; @@ -180,7 +181,7 @@ static struct route_node *srcdest_srcnode_lookup(struct route_node *rn, if (!srn->src_table) return NULL; - return route_node_lookup(srn->src_table, (struct prefix *)src_p); + return route_node_lookup(srn->src_table, (const struct prefix *)src_p); } /* ----- exported functions ----- */ @@ -233,25 +234,25 @@ struct route_node *srcdest_route_next(struct route_node *rn) } struct route_node *srcdest_rnode_get(struct route_table *table, - union prefixptr dst_pu, - struct prefix_ipv6 *src_p) + union prefixconstptr dst_pu, + const struct prefix_ipv6 *src_p) { - struct prefix_ipv6 *dst_p = dst_pu.p6; + const struct prefix_ipv6 *dst_p = dst_pu.p6; struct route_node *rn; - rn = route_node_get(table, (struct prefix *)dst_p); + rn = route_node_get(table, (const struct prefix *)dst_p); return srcdest_srcnode_get(rn, src_p); } struct route_node *srcdest_rnode_lookup(struct route_table *table, - union prefixptr dst_pu, - struct prefix_ipv6 *src_p) + union prefixconstptr dst_pu, + const struct prefix_ipv6 *src_p) { - struct prefix_ipv6 *dst_p = dst_pu.p6; + const struct prefix_ipv6 *dst_p = dst_pu.p6; struct route_node *rn; struct route_node *srn; - rn = route_node_lookup_maynull(table, (struct prefix *)dst_p); + rn = route_node_lookup_maynull(table, (const struct prefix *)dst_p); srn = srcdest_srcnode_lookup(rn, src_p); if (rn != NULL && rn == srn && !rn->info) { @@ -263,8 +264,8 @@ struct route_node *srcdest_rnode_lookup(struct route_table *table, return srn; } -void srcdest_rnode_prefixes(struct route_node *rn, struct prefix **p, - struct prefix **src_p) +void srcdest_rnode_prefixes(struct route_node *rn, const struct prefix **p, + const struct prefix **src_p) { if (rnode_is_srcnode(rn)) { struct route_node *dst_rn = rn->table->info; @@ -282,7 +283,7 @@ void srcdest_rnode_prefixes(struct route_node *rn, struct prefix **p, const char *srcdest_rnode2str(struct route_node *rn, char *str, int size) { - struct prefix *dst_p, *src_p; + const struct prefix *dst_p, *src_p; char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN]; srcdest_rnode_prefixes(rn, &dst_p, &src_p); diff --git a/lib/srcdest_table.h b/lib/srcdest_table.h index 669068a79b..5f97f02bac 100644 --- a/lib/srcdest_table.h +++ b/lib/srcdest_table.h @@ -56,13 +56,14 @@ extern route_table_delegate_t _srcdest_srcnode_delegate; extern struct route_table *srcdest_table_init(void); extern struct route_node *srcdest_rnode_get(struct route_table *table, - union prefixptr dst_pu, - struct prefix_ipv6 *src_p); + union prefixconstptr dst_pu, + const struct prefix_ipv6 *src_p); extern struct route_node *srcdest_rnode_lookup(struct route_table *table, - union prefixptr dst_pu, - struct prefix_ipv6 *src_p); -extern void srcdest_rnode_prefixes(struct route_node *rn, struct prefix **p, - struct prefix **src_p); + union prefixconstptr dst_pu, + const struct prefix_ipv6 *src_p); +extern void srcdest_rnode_prefixes(struct route_node *rn, + const struct prefix **p, + const struct prefix **src_p); extern const char *srcdest_rnode2str(struct route_node *rn, char *str, int size); extern struct route_node *srcdest_route_next(struct route_node *rn); diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index c799a4b30f..d84fd26ac4 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -543,7 +543,7 @@ static int ospf_ase_route_match_same(struct route_table *rt, struct ospf_route *newor) { struct route_node *rn; - struct ospf_route * or ; + struct ospf_route *or; struct ospf_path *op; struct ospf_path *newop; struct listnode *n1; @@ -559,6 +559,9 @@ static int ospf_ase_route_match_same(struct route_table *rt, route_unlock_node(rn); or = rn->info; + + assert(or); + if (or->path_type != newor->path_type) return 0; @@ -577,6 +580,8 @@ static int ospf_ase_route_match_same(struct route_table *rt, return 0; } + assert(or->paths); + if (or->paths->count != newor->paths->count) return 0; diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index ec654b9e29..fb9770d09a 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2336,27 +2336,6 @@ DEFUN (no_ospf_timers_lsa_min_arrival, return CMD_SUCCESS; } -#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180708 -CPP_NOTICE("ospf: `timers lsa arrival (0-1000)` deprecated 2017/07/08") -#endif -ALIAS_HIDDEN(ospf_timers_lsa_min_arrival, ospf_timers_lsa_arrival_cmd, - "timers lsa arrival (0-1000)", - "adjust routing timers\n" - "throttling link state advertisement delays\n" - "ospf minimum arrival interval delay\n" - "delay (msec) between accepted lsas\n"); - -#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180708 -CPP_NOTICE("ospf: `no timers lsa arrival (0-1000)` deprecated 2017/07/08") -#endif -ALIAS_HIDDEN(no_ospf_timers_lsa_min_arrival, no_ospf_timers_lsa_arrival_cmd, - "no timers lsa arrival (0-1000)", NO_STR - "adjust routing timers\n" - "throttling link state advertisement delays\n" - "ospf minimum arrival interval delay\n" - "delay (msec) between accepted lsas\n"); - - DEFUN (ospf_neighbor, ospf_neighbor_cmd, "neighbor A.B.C.D [priority (0-255) [poll-interval (1-65535)]]", @@ -10661,8 +10640,6 @@ void ospf_vty_init(void) install_element(OSPF_NODE, &no_ospf_timers_min_ls_interval_cmd); install_element(OSPF_NODE, &ospf_timers_lsa_min_arrival_cmd); install_element(OSPF_NODE, &no_ospf_timers_lsa_min_arrival_cmd); - install_element(OSPF_NODE, &ospf_timers_lsa_arrival_cmd); - install_element(OSPF_NODE, &no_ospf_timers_lsa_arrival_cmd); /* refresh timer commands */ install_element(OSPF_NODE, &ospf_refresh_timer_cmd); diff --git a/pimd/mtracebis_netlink.c b/pimd/mtracebis_netlink.c index a66da87e1b..b4bf6bada3 100644 --- a/pimd/mtracebis_netlink.c +++ b/pimd/mtracebis_netlink.c @@ -489,7 +489,6 @@ int rtnl_listen(struct rtnl_handle *rtnl, rtnl_filter_t handler, void *jarg) int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler, void *jarg) { - int status; struct sockaddr_nl nladdr; char buf[8192]; struct nlmsghdr *h = (void *)buf; @@ -500,37 +499,43 @@ int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler, void *jarg) nladdr.nl_groups = 0; while (1) { - int err, len; - int l; + int err; + size_t l, rl, arl; - status = fread(&buf, 1, sizeof(*h), rtnl); + rl = sizeof(*h); + arl = fread(&buf, 1, rl, rtnl); - if (status < 0) { - if (errno == EINTR) - continue; - perror("rtnl_from_file: fread"); + if (arl != rl) { + if (arl == 0) + return 0; + + if (ferror(rtnl)) + fprintf(stderr, "%s: header read failed\n", + __func__); + else + fprintf(stderr, "%s: truncated header\n", + __func__); return -1; } - if (status == 0) - return 0; - len = h->nlmsg_len; - l = len - sizeof(*h); + l = h->nlmsg_len > rl ? h->nlmsg_len - rl : 0; - if (l < 0 || len > (int)sizeof(buf)) { - fprintf(stderr, "!!!malformed message: len=%d @%lu\n", - len, ftell(rtnl)); + if (l == 0 || (l + (size_t)NLMSG_HDRLEN) > sizeof(buf)) { + fprintf(stderr, "%s: malformed message: len=%zu @%lu\n", + __func__, (size_t)h->nlmsg_len, ftell(rtnl)); return -1; } - status = fread(NLMSG_DATA(h), 1, NLMSG_ALIGN(l), rtnl); + rl = NLMSG_ALIGN(l); + arl = fread(NLMSG_DATA(h), 1, rl, rtnl); - if (status < 0) { - perror("rtnl_from_file: fread"); - return -1; - } - if (status < l) { - fprintf(stderr, "rtnl-from_file: truncated message\n"); + if (arl != rl) { + if (ferror(rtnl)) + fprintf(stderr, "%s: msg read failed\n", + __func__); + else + fprintf(stderr, "%s: truncated message\n", + __func__); return -1; } diff --git a/pimd/pim_br.c b/pimd/pim_br.c index f297b0591d..6184ea12c4 100644 --- a/pimd/pim_br.c +++ b/pimd/pim_br.c @@ -64,10 +64,6 @@ void pim_br_set_pmbr(struct prefix_sg *sg, struct in_addr br) if (!pim_br) { pim_br = XCALLOC(MTYPE_PIM_BR, sizeof(*pim_br)); - if (!pim_br) { - zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_br)); - return; - } pim_br->sg = *sg; @@ -100,9 +96,4 @@ void pim_br_clear_pmbr(struct prefix_sg *sg) void pim_br_init(void) { pim_br_list = list_new(); - if (!pim_br_list) { - zlog_err("%s: Failure to create pim_br_list", - __PRETTY_FUNCTION__); - return; - } } diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 123c47568c..ae2daf40aa 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2038,7 +2038,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty, } else { vty_out(vty, "%-9d %-15s %-15s %-7s ", c_oil->installed, src_str, grp_str, - ifp_in->name); + in_ifname); } for (oif_vif_index = 0; oif_vif_index < MAXVIFS; diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 5c4d99ad4d..e075ff5ac2 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -75,36 +75,6 @@ void pim_if_terminate(struct pim_instance *pim) return; } -static void *if_list_clean(struct pim_interface *pim_ifp) -{ - struct pim_ifchannel *ch; - - if (pim_ifp->igmp_join_list) - list_delete_and_null(&pim_ifp->igmp_join_list); - - if (pim_ifp->igmp_socket_list) - list_delete_and_null(&pim_ifp->igmp_socket_list); - - if (pim_ifp->pim_neighbor_list) - list_delete_and_null(&pim_ifp->pim_neighbor_list); - - if (pim_ifp->upstream_switch_list) - list_delete_and_null(&pim_ifp->upstream_switch_list); - - if (pim_ifp->sec_addr_list) - list_delete_and_null(&pim_ifp->sec_addr_list); - - while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) { - ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb); - - pim_ifchannel_delete(ch); - } - - XFREE(MTYPE_PIM_INTERFACE, pim_ifp); - - return 0; -} - static void pim_sec_addr_free(struct pim_secondary_addr *sec_addr) { XFREE(MTYPE_PIM_SEC_ADDR, sec_addr); @@ -145,10 +115,6 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim) zassert(!ifp->info); pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp)); - if (!pim_ifp) { - zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_ifp)); - return 0; - } pim_ifp->options = 0; pim_ifp->pim = pim_get_pim_instance(ifp->vrf_id); @@ -186,38 +152,18 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim) /* list of struct igmp_sock */ pim_ifp->igmp_socket_list = list_new(); - if (!pim_ifp->igmp_socket_list) { - zlog_err("%s: failure: igmp_socket_list=list_new()", - __PRETTY_FUNCTION__); - return if_list_clean(pim_ifp); - } pim_ifp->igmp_socket_list->del = (void (*)(void *))igmp_sock_free; /* list of struct pim_neighbor */ pim_ifp->pim_neighbor_list = list_new(); - if (!pim_ifp->pim_neighbor_list) { - zlog_err("%s: failure: pim_neighbor_list=list_new()", - __PRETTY_FUNCTION__); - return if_list_clean(pim_ifp); - } pim_ifp->pim_neighbor_list->del = (void (*)(void *))pim_neighbor_free; pim_ifp->upstream_switch_list = list_new(); - if (!pim_ifp->upstream_switch_list) { - zlog_err("%s: failure: upstream_switch_list=list_new()", - __PRETTY_FUNCTION__); - return if_list_clean(pim_ifp); - } pim_ifp->upstream_switch_list->del = (void (*)(void *))pim_jp_agg_group_list_free; pim_ifp->upstream_switch_list->cmp = pim_jp_agg_group_list_cmp; pim_ifp->sec_addr_list = list_new(); - if (!pim_ifp->sec_addr_list) { - zlog_err("%s: failure: secondary addresslist", - __PRETTY_FUNCTION__); - return if_list_clean(pim_ifp); - } pim_ifp->sec_addr_list->del = (void (*)(void *))pim_sec_addr_free; pim_ifp->sec_addr_list->cmp = (int (*)(void *, void *))pim_sec_addr_comp; @@ -404,8 +350,6 @@ static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct prefix *addr) } sec_addr = XCALLOC(MTYPE_PIM_SEC_ADDR, sizeof(*sec_addr)); - if (!sec_addr) - return changed; changed = 1; sec_addr->addr = *addr; @@ -1286,20 +1230,6 @@ static struct igmp_join *igmp_join_new(struct interface *ifp, } ij = XCALLOC(MTYPE_PIM_IGMP_JOIN, sizeof(*ij)); - if (!ij) { - char group_str[INET_ADDRSTRLEN]; - char source_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<grp?>", group_addr, group_str, - sizeof(group_str)); - pim_inet4_dump("<src?>", source_addr, source_str, - sizeof(source_str)); - zlog_err( - "%s: XCALLOC(%zu) failure for IGMP group %s source %s on interface %s", - __PRETTY_FUNCTION__, sizeof(*ij), group_str, source_str, - ifp->name); - close(join_fd); - return 0; - } ij->sock_fd = join_fd; ij->group_addr = group_addr; @@ -1325,9 +1255,6 @@ ferr_r pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr, if (!pim_ifp->igmp_join_list) { pim_ifp->igmp_join_list = list_new(); - if (!pim_ifp->igmp_join_list) { - return ferr_cfg_invalid("Insufficient memory"); - } pim_ifp->igmp_join_list->del = (void (*)(void *))igmp_join_free; } diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 5e6b0f10cf..e82a7589b7 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -520,12 +520,6 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, pim_ifp = ifp->info; ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch)); - if (!ch) { - zlog_warn( - "%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s", - __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name); - return NULL; - } ch->flags = 0; if ((source_flags & PIM_ENCODE_RPT_BIT) diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index c980f5fcba..42bdd80ce2 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -860,18 +860,8 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr, } igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp)); - if (!igmp) { - zlog_warn("%s %s: XCALLOC() failure", __FILE__, - __PRETTY_FUNCTION__); - return 0; - } igmp->igmp_group_list = list_new(); - if (!igmp->igmp_group_list) { - zlog_err("%s %s: failure: igmp_group_list = list_new()", - __FILE__, __PRETTY_FUNCTION__); - return 0; - } igmp->igmp_group_list->del = (void (*)(void *))igmp_group_free; snprintf(hash_name, 64, "IGMP %s hash", ifp->name); @@ -1130,19 +1120,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp, */ group = XCALLOC(MTYPE_PIM_IGMP_GROUP, sizeof(*group)); - if (!group) { - zlog_warn("%s %s: XCALLOC() failure", __FILE__, - __PRETTY_FUNCTION__); - return NULL; /* error, not found, could not create */ - } group->group_source_list = list_new(); - if (!group->group_source_list) { - zlog_warn("%s %s: list_new() failure", __FILE__, - __PRETTY_FUNCTION__); - XFREE(MTYPE_PIM_IGMP_GROUP, group); /* discard group */ - return NULL; /* error, not found, could not initialize */ - } group->group_source_list->del = (void (*)(void *))igmp_source_free; group->t_group_timer = NULL; diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 5ccad39b33..b32d71cc0d 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -457,11 +457,6 @@ struct igmp_source *source_new(struct igmp_group *group, } src = XCALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src)); - if (!src) { - zlog_warn("%s %s: XCALLOC() failure", __FILE__, - __PRETTY_FUNCTION__); - return 0; /* error, not found, could not create */ - } src->t_source_timer = NULL; src->source_group = group; /* back pointer */ diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index cb70ee7904..5121dc94ca 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -69,8 +69,6 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) char hash_name[64]; pim = XCALLOC(MTYPE_PIM_PIM_INSTANCE, sizeof(struct pim_instance)); - if (!pim) - return NULL; pim_if_init(pim); @@ -102,12 +100,6 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) } pim->static_routes = list_new(); - if (!pim->static_routes) { - zlog_err("%s %s: failure: static_routes=list_new()", __FILE__, - __PRETTY_FUNCTION__); - pim_instance_terminate(pim); - return NULL; - } pim->static_routes->del = (void (*)(void *))pim_static_route_free; pim->send_v6_secondary = 1; diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c index e87dfbca95..c5f5b9c5e0 100644 --- a/pimd/pim_jp_agg.c +++ b/pimd/pim_jp_agg.c @@ -329,7 +329,6 @@ void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf, if (first) { groups = list_new(); - jag.sources = list_new(); listnode_add(groups, &jag); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index c7e1a18d28..dd30678405 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -158,7 +158,7 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp, * the Interface type is SSM we don't need to * do anything here */ - if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp) + if (!rpg || (pim_rpf_addr_is_inaddr_none(rpg)) || (!(PIM_I_am_DR(pim_ifp)))) { if (PIM_DEBUG_MROUTE_DETAIL) zlog_debug( diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index e798d70a51..951e743494 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -240,11 +240,6 @@ static struct pim_msdp_sa *pim_msdp_sa_new(struct pim_instance *pim, struct pim_msdp_sa *sa; sa = XCALLOC(MTYPE_PIM_MSDP_SA, sizeof(*sa)); - if (!sa) { - zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__, - sizeof(*sa)); - return NULL; - } sa->pim = pim; sa->sg = *sg; @@ -1069,11 +1064,6 @@ static enum pim_msdp_err pim_msdp_peer_new(struct pim_instance *pim, pim_msdp_enable(pim); mp = XCALLOC(MTYPE_PIM_MSDP_PEER, sizeof(*mp)); - if (!mp) { - zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__, - sizeof(*mp)); - return PIM_MSDP_ERR_OOM; - } mp->pim = pim; mp->peer = peer_addr; @@ -1277,11 +1267,6 @@ static struct pim_msdp_mg *pim_msdp_mg_new(const char *mesh_group_name) struct pim_msdp_mg *mg; mg = XCALLOC(MTYPE_PIM_MSDP_MG, sizeof(*mg)); - if (!mg) { - zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__, - sizeof(*mg)); - return NULL; - } mg->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name); mg->mbr_list = list_new(); @@ -1395,13 +1380,6 @@ enum pim_msdp_err pim_msdp_mg_mbr_add(struct pim_instance *pim, } mbr = XCALLOC(MTYPE_PIM_MSDP_MG_MBR, sizeof(*mbr)); - if (!mbr) { - zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__, - sizeof(*mbr)); - /* if there are no references to the mg free it */ - pim_msdp_mg_free(pim, mg); - return PIM_MSDP_ERR_OOM; - } mbr->mbr_ip = mbr_ip; listnode_add_sort(mg->mbr_list, mbr); diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 20a942b4fd..2730f5e7aa 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -305,11 +305,6 @@ pim_neighbor_new(struct interface *ifp, struct in_addr source_addr, zassert(pim_ifp); neigh = XCALLOC(MTYPE_PIM_NEIGHBOR, sizeof(*neigh)); - if (!neigh) { - zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__, - sizeof(*neigh)); - return 0; - } neigh->creation = pim_time_monotonic_sec(); neigh->source_addr = source_addr; diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index fa6486a83e..ac49373da0 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -92,10 +92,6 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim, pnc = XCALLOC(MTYPE_PIM_NEXTHOP_CACHE, sizeof(struct pim_nexthop_cache)); - if (!pnc) { - zlog_err("%s: NHT PIM XCALLOC failure ", __PRETTY_FUNCTION__); - return NULL; - } pnc->rpf.rpf_addr.family = rpf_addr->rpf_addr.family; pnc->rpf.rpf_addr.prefixlen = rpf_addr->rpf_addr.prefixlen; pnc->rpf.rpf_addr.u.prefix4.s_addr = @@ -140,14 +136,6 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr, pnc = pim_nexthop_cache_find(pim, &rpf); if (!pnc) { pnc = pim_nexthop_cache_add(pim, &rpf); - if (!pnc) { - char rpf_str[PREFIX_STRLEN]; - pim_addr_dump("<nht-pnc?>", addr, rpf_str, - sizeof(rpf_str)); - zlog_warn("%s: pnc node allocation failed. addr %s ", - __PRETTY_FUNCTION__, rpf_str); - return 0; - } pim_sendmsg_zebra_rnh(pim, zclient, pnc, ZEBRA_NEXTHOP_REGISTER); if (PIM_DEBUG_PIM_NHT) { @@ -168,7 +156,7 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr, if (up != NULL) hash_get(pnc->upstream_hash, up, hash_alloc_intern); - if (pnc && CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) { + if (CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) { memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache)); return 1; } diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index d49484f869..f0f336fb73 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -107,11 +107,6 @@ void pim_oil_init(struct pim_instance *pim) pim_oil_equal, hash_name); pim->channel_oil_list = list_new(); - if (!pim->channel_oil_list) { - zlog_err("%s %s: failure: channel_oil_list=list_new()", - __FILE__, __PRETTY_FUNCTION__); - return; - } pim->channel_oil_list->del = (void (*)(void *))pim_channel_oil_free; pim->channel_oil_list->cmp = (int (*)(void *, void *))pim_channel_oil_compare; @@ -182,10 +177,6 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, } c_oil = XCALLOC(MTYPE_PIM_CHANNEL_OIL, sizeof(*c_oil)); - if (!c_oil) { - zlog_err("PIM XCALLOC(%zu) failure", sizeof(*c_oil)); - return NULL; - } c_oil->oil.mfcc_mcastgrp = sg->grp; c_oil->oil.mfcc_origin = sg->src; diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index a8cf58cd36..7e053d2aa0 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -115,13 +115,6 @@ void pim_rp_init(struct pim_instance *pim) rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info)); - if (!rp_info) { - zlog_err("Unable to alloc rp_info"); - route_table_finish(pim->rp_table); - list_delete_and_null(&pim->rp_list); - return; - } - if (!str2prefix("224.0.0.0/4", &rp_info->group)) { zlog_err("Unable to convert 224.0.0.0/4 to prefix"); list_delete_and_null(&pim->rp_list); @@ -365,8 +358,6 @@ int pim_rp_new(struct pim_instance *pim, const char *rp, struct route_node *rn; rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info)); - if (!rp_info) - return PIM_MALLOC_FAIL; if (group_range == NULL) result = str2prefix("224.0.0.0/4", &rp_info->group); @@ -534,12 +525,6 @@ int pim_rp_new(struct pim_instance *pim, const char *rp, listnode_add_sort(pim->rp_list, rp_info); rn = route_node_get(pim->rp_table, &rp_info->group); - if (!rn) { - char buf[PREFIX_STRLEN]; - zlog_err("Failure to get route node for pim->rp_table: %s", - prefix2str(&rp_info->group, buf, sizeof(buf))); - return PIM_MALLOC_FAIL; - } rn->info = rp_info; if (PIM_DEBUG_TRACE) { diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index 8e7da0f121..bdf303d5c5 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -348,12 +348,6 @@ static struct ssmpingd_sock *ssmpingd_new(struct pim_instance *pim, if (!pim->ssmpingd_list) { pim->ssmpingd_list = list_new(); - if (!pim->ssmpingd_list) { - zlog_err( - "%s %s: failure: qpim_ssmpingd_list=list_new()", - __FILE__, __PRETTY_FUNCTION__); - return 0; - } pim->ssmpingd_list->del = (void (*)(void *))ssmpingd_free; } @@ -369,15 +363,6 @@ static struct ssmpingd_sock *ssmpingd_new(struct pim_instance *pim, } ss = XCALLOC(MTYPE_PIM_SSMPINGD, sizeof(*ss)); - if (!ss) { - char source_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<src?>", source_addr, source_str, - sizeof(source_str)); - zlog_err("%s: XCALLOC(%zu) failure for ssmpingd source %s", - __PRETTY_FUNCTION__, sizeof(*ss), source_str); - close(sock_fd); - return 0; - } ss->pim = pim; ss->sock_fd = sock_fd; diff --git a/pimd/pim_static.c b/pimd/pim_static.c index 3d44a01c78..9569b7dcac 100644 --- a/pimd/pim_static.c +++ b/pimd/pim_static.c @@ -39,14 +39,7 @@ void pim_static_route_free(struct static_route *s_route) static struct static_route *static_route_alloc() { - struct static_route *s_route; - - s_route = XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(*s_route)); - if (!s_route) { - zlog_err("PIM XCALLOC(%zu) failure", sizeof(*s_route)); - return 0; - } - return s_route; + return XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(struct static_route)); } static struct static_route *static_route_new(unsigned int iif, unsigned int oif, @@ -55,9 +48,6 @@ static struct static_route *static_route_new(unsigned int iif, unsigned int oif, { struct static_route *s_route; s_route = static_route_alloc(); - if (!s_route) { - return 0; - } s_route->group = group; s_route->source = source; diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c index eddec3c29e..80bda336df 100644 --- a/pimd/pim_tlv.c +++ b/pimd/pim_tlv.c @@ -757,12 +757,6 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, */ if (!*hello_option_addr_list) { *hello_option_addr_list = list_new(); - if (!*hello_option_addr_list) { - zlog_err( - "%s %s: failure: hello_option_addr_list=list_new()", - __FILE__, __PRETTY_FUNCTION__); - return -2; - } (*hello_option_addr_list)->del = (void (*)(void *))prefix_free; } diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 9329d72ce0..e3488b6a66 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -603,11 +603,6 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, struct pim_upstream *up; up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up)); - if (!up) { - zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__, - sizeof(*up)); - return NULL; - } up->sg = *sg; pim_str_sg_set(sg, up->sg_str); diff --git a/tests/Makefile.am b/tests/Makefile.am index 32d2db768a..a7dec67348 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -21,7 +21,8 @@ TESTS_BGPD = \ bgpd/test_peer_attr \ bgpd/test_ecommunity \ bgpd/test_mp_attr \ - bgpd/test_mpath + bgpd/test_mpath \ + bgpd/test_bgp_table else TESTS_BGPD = endif @@ -143,6 +144,7 @@ bgpd_test_peer_attr_SOURCES = bgpd/test_peer_attr.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 +bgpd_test_bgp_table_SOURCES = bgpd/test_bgp_table.c isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv.c nodist_isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv_tests.h BUILT_SOURCES=isisd/test_fuzz_isis_tlv_tests.h @@ -186,6 +188,7 @@ bgpd_test_peer_attr_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) +bgpd_test_bgp_table_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) diff --git a/tests/bgpd/test_bgp_table b/tests/bgpd/test_bgp_table new file mode 100755 index 0000000000..05a7e8947b --- /dev/null +++ b/tests/bgpd/test_bgp_table @@ -0,0 +1,228 @@ +#! /bin/sh + +# bgpd/test_bgp_table - temporary wrapper script for .libs/test_bgp_table +# Generated by libtool (GNU libtool) 2.4.6.40-6ca5-dirty +# +# The bgpd/test_bgp_table program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command="(cd /home/marcel/src/haw/frr-1/tests; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/home/marcel/.cargo/bin:/home/marcel/dotfiles/bin:/home/marcel/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl; export PATH; gcc -std=gnu11 -g3 -O0 -fno-omit-frame-pointer -funwind-tables -Wall -Wextra -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wbad-function-cast -Wwrite-strings -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -pthread -rdynamic -o \$progdir/\$file bgpd/test_bgp_table.o ../bgpd/libbgp.a ../bgpd/rfp-example/librfp/librfp.a ../lib/.libs/libfrr.so -lcap -ldl -lm -lcrypt -ljson-c -lrt -pthread -Wl,-rpath -Wl,/home/marcel/src/haw/frr-1/lib/.libs -Wl,-rpath -Wl,/usr/local/lib)" + +# This environment variable determines our operation mode. +if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then + # install mode needs the following variables: + generated_by_libtool_version='2.4.6.40-6ca5-dirty' + notinst_deplibs=' ../lib/libfrr.la' +else + # When we are sourced in execute mode, $file and $ECHO are already set. + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + file="$0" + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + ECHO="printf %s\\n" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string --lt- +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's ../libtool value, followed by no. +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=$0 + shift + for lt_opt + do + case "$lt_opt" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=`$ECHO "X$lt_script_arg0" | sed -e 's/^X//' -e 's%/[^/]*$%%'` + test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=. + lt_dump_F=`$ECHO "X$lt_script_arg0" | sed -e 's/^X//' -e 's%^.*/%%'` + cat "$lt_dump_D/$lt_dump_F" + exit 0 + ;; + --lt-*) + $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n "$lt_option_debug"; then + echo "test_bgp_table:bgpd/test_bgp_table:$LINENO: libtool wrapper (GNU libtool) 2.4.6.40-6ca5-dirty" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + $ECHO "test_bgp_table:bgpd/test_bgp_table:$LINENO: newargv[$lt_dump_args_N]: $lt_arg" + lt_dump_args_N=`expr $lt_dump_args_N + 1` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ + + if test -n "$lt_option_debug"; then + $ECHO "test_bgp_table:bgpd/test_bgp_table:$LINENO: newargv[0]: $progdir/$program" 1>&2 + func_lt_dump_args ${1+"$@"} 1>&2 + fi + exec "$progdir/$program" ${1+"$@"} + + $ECHO "$0: cannot exec $program $*" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from $@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case " $* " in + *\ --lt-*) + for lt_wr_arg + do + case $lt_wr_arg in + --lt-*) ;; + *) set x "$@" "$lt_wr_arg"; shift;; + esac + shift + done ;; + esac + func_exec_program_core ${1+"$@"} +} + + # Parse options + func_parse_lt_options "$0" ${1+"$@"} + + # Find the directory that this script lives in. + thisdir=`$ECHO "$file" | sed 's%/[^/]*$%%'` + test "x$thisdir" = "x$file" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=`ls -ld "$file" | sed -n 's/.*-> //p'` + while test -n "$file"; do + destdir=`$ECHO "$file" | sed 's%/[^/]*$%%'` + + # If there was a directory component, then change thisdir. + if test "x$destdir" != "x$file"; then + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; + *) thisdir="$thisdir/$destdir" ;; + esac + fi + + file=`$ECHO "$file" | sed 's%^.*/%%'` + file=`ls -ld "$thisdir/$file" | sed -n 's/.*-> //p'` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no + if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then + # special case for '.' + if test "$thisdir" = "."; then + thisdir=`pwd` + fi + # remove .libs from thisdir + case "$thisdir" in + *[\\/].libs ) thisdir=`$ECHO "$thisdir" | sed 's%[\\/][^\\/]*$%%'` ;; + .libs ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=`cd "$thisdir" && pwd` + test -n "$absdir" && thisdir="$absdir" + + program=lt-'test_bgp_table' + progdir="$thisdir/.libs" + + if test ! -f "$progdir/$program" || + { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | sed 1q`; \ + test "X$file" != "X$progdir/$program"; }; then + + file="$$-$program" + + if test ! -d "$progdir"; then + mkdir "$progdir" + else + rm -f "$progdir/$file" + fi + + # relink executable if necessary + if test -n "$relink_command"; then + if relink_command_output=`eval $relink_command 2>&1`; then : + else + $ECHO "$relink_command_output" >&2 + rm -f "$progdir/$file" + exit 1 + fi + fi + + mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null || + { rm -f "$progdir/$program"; + mv -f "$progdir/$file" "$progdir/$program"; } + rm -f "$progdir/$file" + fi + + if test -f "$progdir/$program"; then + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + # Run the actual program with our arguments. + func_exec_program ${1+"$@"} + fi + else + # The program doesn't exist. + $ECHO "$0: error: '$progdir/$program' does not exist" 1>&2 + $ECHO "This script is just a wrapper for $program." 1>&2 + $ECHO "See the libtool documentation for more information." 1>&2 + exit 1 + fi +fi diff --git a/tests/bgpd/test_bgp_table.c b/tests/bgpd/test_bgp_table.c new file mode 100644 index 0000000000..01ce7480d7 --- /dev/null +++ b/tests/bgpd/test_bgp_table.c @@ -0,0 +1,192 @@ +/* + * BGP Routing table range lookup test + * Copyright (C) 2012 OSR. + * Copyright (C) 2018 Marcel Röthke (marcel.roethke@haw-hamburg.de), for HAW + * Hamburg + * + * This file is part of FRRouting + * + * 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 + */ + +#include <zebra.h> + +#include "prefix.h" +#include "table.h" +#include "bgpd/bgp_table.h" +#include "linklist.h" + +/* + * test_node_t + * + * Information that is kept for each node in the radix tree. + */ +struct test_node_t { + + /* + * Human readable representation of the string. Allocated using + * malloc()/dup(). + */ + char *prefix_str; +}; + +/* + * add_node + * + * Add the given prefix (passed in as a string) to the given table. + */ +static void add_node(struct bgp_table *table, const char *prefix_str) +{ + struct prefix_ipv4 p; + struct test_node_t *node; + struct bgp_node *rn; + + assert(prefix_str); + + if (str2prefix_ipv4(prefix_str, &p) <= 0) + assert(0); + + rn = bgp_node_get(table, (struct prefix *)&p); + if (rn->info) { + assert(0); + return; + } + + node = malloc(sizeof(struct test_node_t)); + assert(node); + node->prefix_str = strdup(prefix_str); + assert(node->prefix_str); + rn->info = node; +} + +static void print_range_result(struct list *list) +{ + + struct listnode *listnode; + struct bgp_node *bnode; + + for (ALL_LIST_ELEMENTS_RO(list, listnode, bnode)) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str(&bnode->p, buf, PREFIX2STR_BUFFER); + printf("%s\n", buf); + } +} + +static void check_lookup_result(struct list *list, va_list arglist) +{ + char *prefix_str; + unsigned int prefix_count = 0; + + printf("Searching results\n"); + while ((prefix_str = va_arg(arglist, char *))) { + struct listnode *listnode; + struct bgp_node *bnode; + struct prefix p; + bool found = false; + + prefix_count++; + printf("Searching for %s\n", prefix_str); + + if (str2prefix(prefix_str, &p) <= 0) + assert(0); + + for (ALL_LIST_ELEMENTS_RO(list, listnode, bnode)) { + if (prefix_same(&bnode->p, &p)) + found = true; + } + + assert(found); + } + + printf("Checking for unexpected result items\n"); + printf("Expecting %d found %d\n", prefix_count, listcount(list)); + assert(prefix_count == listcount(list)); +} + +static void do_test(struct bgp_table *table, const char *prefix, uint8_t maxlen, + ...) +{ + va_list arglist; + struct list *list = list_new(); + struct prefix p; + + list->del = (void (*)(void *))bgp_unlock_node; + + va_start(arglist, maxlen); + printf("\nDoing lookup for %s-%d\n", prefix, maxlen); + if (str2prefix(prefix, &p) <= 0) + assert(0); + bgp_table_range_lookup(table, &p, maxlen, list); + print_range_result(list); + + check_lookup_result(list, arglist); + + list_delete_and_null(&list); + + va_end(arglist); + + printf("Checks successfull\n"); +} + +/* + * test_range_lookup + */ +static void test_range_lookup(void) +{ + struct bgp_table *table = bgp_table_init(NULL, AFI_IP, SAFI_UNICAST); + + printf("Testing bgp_table_range_lookup\n"); + + printf("Setup bgp_table"); + const char *prefixes[] = {"1.16.0.0/16", "1.16.128.0/18", + "1.16.192.0/18", "1.16.64.0/19", + "1.16.160.0/19", "1.16.32.0/20", + "1.16.32.0/21", "16.0.0.0/16"}; + + int num_prefixes = sizeof(prefixes) / sizeof(prefixes[0]); + + for (int i = 0; i < num_prefixes; i++) + add_node(table, prefixes[i]); + + do_test(table, "1.16.0.0/17", 20, "1.16.64.0/19", "1.16.32.0/20", NULL); + do_test(table, "1.16.128.0/17", 20, "1.16.128.0/18", "1.16.192.0/18", + "1.16.160.0/19", NULL); + + do_test(table, "1.16.128.0/17", 20, "1.16.128.0/18", "1.16.192.0/18", + "1.16.160.0/19", NULL); + + do_test(table, "1.16.0.0/16", 18, "1.16.0.0/16", "1.16.128.0/18", + "1.16.192.0/18", NULL); + + do_test(table, "1.16.0.0/16", 21, "1.16.0.0/16", "1.16.128.0/18", + "1.16.192.0/18", "1.16.64.0/19", "1.16.160.0/19", + "1.16.32.0/20", "1.16.32.0/21", NULL); + + do_test(table, "1.17.0.0/16", 20, NULL); + + do_test(table, "128.0.0.0/8", 16, NULL); + + do_test(table, "16.0.0.0/8", 16, "16.0.0.0/16", NULL); + + do_test(table, "0.0.0.0/3", 21, "1.16.0.0/16", "1.16.128.0/18", + "1.16.192.0/18", "1.16.64.0/19", "1.16.160.0/19", + "1.16.32.0/20", "1.16.32.0/21", "16.0.0.0/16", NULL); +} + +int main(void) +{ + test_range_lookup(); +} diff --git a/tests/bgpd/test_bgp_table.py b/tests/bgpd/test_bgp_table.py new file mode 100644 index 0000000000..4423530fe0 --- /dev/null +++ b/tests/bgpd/test_bgp_table.py @@ -0,0 +1,7 @@ +import frrtest + +class TestTable(frrtest.TestMultiOut): + program = './test_bgp_table' + +for i in range(6): + TestTable.onesimple('Checks successfull') diff --git a/zebra/connected.c b/zebra/connected.c index a9a4dfe08f..8869d34fd6 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -564,7 +564,7 @@ void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address, if (broad) { memset(&d, 0, sizeof(struct prefix)); d.family = AF_INET6; - IPV6_ADDR_COPY(&d.u.prefix, broad); + IPV6_ADDR_COPY(&d.u.prefix6, broad); d.prefixlen = prefixlen; ifc = connected_check_ptp(ifp, &p, &d); } else diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index d9c6631845..062fa9299c 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -390,8 +390,8 @@ void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, } } -int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, void *data, - unsigned int alen) +int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, + const void *data, unsigned int alen) { int len; struct rtattr *rta; @@ -415,8 +415,8 @@ int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, void *data, return 0; } -int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type, void *data, - unsigned int alen) +int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type, + const void *data, unsigned int alen) { unsigned int len; struct rtattr *subrta; diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index 3b4048ff69..80bb876e0b 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -29,9 +29,9 @@ extern void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len); extern int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, - void *data, unsigned int alen); + const void *data, unsigned int alen); extern int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type, - void *data, unsigned int alen); + const void *data, unsigned int alen); extern int addattr16(struct nlmsghdr *n, unsigned int maxlen, int type, uint16_t data); extern int addattr32(struct nlmsghdr *n, unsigned int maxlen, int type, diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 1fee675cbf..69c0ebb7ec 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -113,7 +113,7 @@ static void zebra_redistribute(struct zserv *client, int type, for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) RNODE_FOREACH_RE (rn, newre) { - struct prefix *dst_p, *src_p; + const struct prefix *dst_p, *src_p; char buf[PREFIX_STRLEN]; srcdest_rnode_prefixes(rn, &dst_p, &src_p); @@ -147,7 +147,7 @@ static void zebra_redistribute(struct zserv *client, int type, /* Either advertise a route for redistribution to registered clients or */ /* withdraw redistribution if add cannot be done for client */ -void redistribute_update(struct prefix *p, struct prefix *src_p, +void redistribute_update(const struct prefix *p, const struct prefix *src_p, struct route_entry *re, struct route_entry *prev_re) { struct listnode *node, *nnode; @@ -216,7 +216,7 @@ void redistribute_update(struct prefix *p, struct prefix *src_p, } } -void redistribute_delete(struct prefix *p, struct prefix *src_p, +void redistribute_delete(const struct prefix *p, const struct prefix *src_p, struct route_entry *re) { struct listnode *node, *nnode; diff --git a/zebra/redistribute.h b/zebra/redistribute.h index 9b4820acd4..a0fbd13cf9 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -36,9 +36,11 @@ extern void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS); extern void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS); /* ----------------- */ -extern void redistribute_update(struct prefix *, struct prefix *, +extern void redistribute_update(const struct prefix *p, + const struct prefix *src_p, struct route_entry *, struct route_entry *); -extern void redistribute_delete(struct prefix *, struct prefix *, +extern void redistribute_delete(const struct prefix *p, + const struct prefix *src_p, struct route_entry *); extern void zebra_interface_up_update(struct interface *); diff --git a/zebra/rib.h b/zebra/rib.h index 209f085ed1..6509cdaba7 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -289,7 +289,7 @@ extern int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate, extern int is_zebra_valid_kernel_table(uint32_t table_id); extern int is_zebra_main_routing_table(uint32_t table_id); -extern int zebra_check_addr(struct prefix *p); +extern int zebra_check_addr(const struct prefix *p); extern void rib_addnode(struct route_node *rn, struct route_entry *re, int process); diff --git a/zebra/rt.h b/zebra/rt.h index ad1fe9a1f5..57e62e4f6e 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -67,8 +67,8 @@ enum dp_req_result { * a re-add. */ extern enum dp_req_result kernel_route_rib(struct route_node *rn, - struct prefix *p, - struct prefix *src_p, + const struct prefix *p, + const struct prefix *src_p, struct route_entry *old, struct route_entry *new); @@ -77,7 +77,8 @@ extern enum dp_req_result kernel_route_rib(struct route_node *rn, * so let's separate it out and allow the result to * be passed back up. */ -extern void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p, +extern void kernel_route_rib_pass_fail(struct route_node *rn, + const struct prefix *p, struct route_entry *re, enum dp_results res); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 9033491549..06211d5a43 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1287,8 +1287,8 @@ _netlink_mpls_build_multipath(const char *routedesc, zebra_nhlfe_t *nhlfe, * @param zvrf: The vrf we are in * @param tableid: The table we are working on */ -static void _netlink_route_debug(int cmd, struct prefix *p, - int family, struct zebra_vrf *zvrf, +static void _netlink_route_debug(int cmd, const struct prefix *p, + int family, vrf_id_t vrfid, uint32_t tableid) { if (IS_ZEBRA_DEBUG_KERNEL) { @@ -1297,7 +1297,7 @@ static void _netlink_route_debug(int cmd, struct prefix *p, "netlink_route_multipath(): %s %s vrf %u(%u)", nl_msg_type_to_str(cmd), prefix2str(p, buf, sizeof(buf)), - zvrf_id(zvrf), tableid); + vrfid, tableid); } } @@ -1340,8 +1340,9 @@ static int netlink_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla, /* Routing table change via netlink interface. */ /* Update flag indicates whether this is a "replace" or not. */ -static int netlink_route_multipath(int cmd, struct prefix *p, - struct prefix *src_p, struct route_entry *re, +static int netlink_route_multipath(int cmd, const struct prefix *p, + const struct prefix *src_p, + struct route_entry *re, int update) { int bytelen; @@ -1416,7 +1417,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p, addattr32(&req.n, sizeof req, RTA_TABLE, re->table); } - _netlink_route_debug(cmd, p, family, zvrf, re->table); + _netlink_route_debug(cmd, p, family, zvrf_id(zvrf), re->table); /* * If we are not updating the route and we have received @@ -1699,8 +1700,8 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in) } enum dp_req_result kernel_route_rib(struct route_node *rn, - struct prefix *p, - struct prefix *src_p, + const struct prefix *p, + const struct prefix *src_p, struct route_entry *old, struct route_entry *new) { diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 441f518e91..cba0376300 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -386,8 +386,8 @@ static int kernel_rtm(int cmd, struct prefix *p, struct route_entry *re) } enum dp_req_result kernel_route_rib(struct route_node *rn, - struct prefix *p, - struct prefix *src_p, + const struct prefix *p, + const struct prefix *src_p, struct route_entry *old, struct route_entry *new) { diff --git a/zebra/rtadv.c b/zebra/rtadv.c index dc918b1a9b..49ffcdd490 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -518,7 +518,7 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len, /* Create entry for neighbor if not known. */ p.family = AF_INET6; - IPV6_ADDR_COPY(&p.u.prefix, &addr->sin6_addr); + IPV6_ADDR_COPY(&p.u.prefix6, &addr->sin6_addr); p.prefixlen = IPV6_MAX_PREFIXLEN; if (!nbr_connected_check(ifp, &p)) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 6e0d86d668..dcccb3e321 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -448,7 +448,7 @@ void nbr_connected_add_ipv6(struct interface *ifp, struct in6_addr *address) struct prefix p; p.family = AF_INET6; - IPV6_ADDR_COPY(&p.u.prefix, address); + IPV6_ADDR_COPY(&p.u.prefix6, address); p.prefixlen = IPV6_MAX_PREFIXLEN; ifc = listnode_head(ifp->nbr_connected); @@ -473,7 +473,7 @@ void nbr_connected_delete_ipv6(struct interface *ifp, struct in6_addr *address) struct prefix p; p.family = AF_INET6; - IPV6_ADDR_COPY(&p.u.prefix, address); + IPV6_ADDR_COPY(&p.u.prefix6, address); p.prefixlen = IPV6_MAX_PREFIXLEN; ifc = nbr_connected_check(ifp, &p); @@ -514,8 +514,9 @@ int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp) return zserv_send_message(client, s); } -int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, - struct prefix *src_p, struct route_entry *re) +int zsend_redistribute_route(int cmd, struct zserv *client, + const struct prefix *p, + const struct prefix *src_p, struct route_entry *re) { struct zapi_route api; struct zapi_nexthop *api_nh; @@ -677,22 +678,28 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client, return zserv_send_message(client, s); } -int zsend_route_notify_owner(struct route_entry *re, struct prefix *p, - enum zapi_route_notify_owner note) +/* + * Common utility send route notification, called from a path using a + * route_entry and from a path using a dataplane context. + */ +static int route_notify_internal(const struct prefix *p, int type, + uint16_t instance, vrf_id_t vrf_id, + uint32_t table_id, + enum zapi_route_notify_owner note) { struct zserv *client; struct stream *s; uint8_t blen; - client = zserv_find_client(re->type, re->instance); + client = zserv_find_client(type, instance); if (!client || !client->notify_owner) { if (IS_ZEBRA_DEBUG_PACKET) { char buff[PREFIX_STRLEN]; zlog_debug( "Not Notifying Owner: %u about prefix %s(%u) %d vrf: %u", - re->type, prefix2str(p, buff, sizeof(buff)), - re->table, note, re->vrf_id); + type, prefix2str(p, buff, sizeof(buff)), + table_id, note, vrf_id); } return 0; } @@ -701,14 +708,14 @@ int zsend_route_notify_owner(struct route_entry *re, struct prefix *p, char buff[PREFIX_STRLEN]; zlog_debug("Notifying Owner: %u about prefix %s(%u) %d vrf: %u", - re->type, prefix2str(p, buff, sizeof(buff)), - re->table, note, re->vrf_id); + type, prefix2str(p, buff, sizeof(buff)), + table_id, note, vrf_id); } s = stream_new(ZEBRA_MAX_PACKET_SIZ); stream_reset(s); - zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, re->vrf_id); + zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id); stream_put(s, ¬e, sizeof(note)); @@ -718,13 +725,20 @@ int zsend_route_notify_owner(struct route_entry *re, struct prefix *p, stream_putc(s, p->prefixlen); stream_put(s, &p->u.prefix, blen); - stream_putl(s, re->table); + stream_putl(s, table_id); stream_putw_at(s, 0, stream_get_endp(s)); return zserv_send_message(client, s); } +int zsend_route_notify_owner(struct route_entry *re, const struct prefix *p, + enum zapi_route_notify_owner note) +{ + return (route_notify_internal(p, re->type, re->instance, re->vrf_id, + re->table, note)); +} + void zsend_rule_notify_owner(struct zebra_pbr_rule *rule, enum zapi_rule_notify_owner note) { diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index f27897580a..8289e33c6a 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -56,7 +56,8 @@ extern void nbr_connected_delete_ipv6(struct interface *ifp, extern int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp); extern int zsend_redistribute_route(int cmd, struct zserv *zclient, - struct prefix *p, struct prefix *src_p, + const struct prefix *p, + const struct prefix *src_p, struct route_entry *re); extern int zsend_router_id_update(struct zserv *zclient, struct prefix *p, vrf_id_t vrf_id); @@ -65,7 +66,8 @@ extern int zsend_interface_vrf_update(struct zserv *zclient, extern int zsend_interface_link_params(struct zserv *zclient, struct interface *ifp); extern int zsend_pw_update(struct zserv *client, struct zebra_pw *pw); -extern int zsend_route_notify_owner(struct route_entry *re, struct prefix *p, +extern int zsend_route_notify_owner(struct route_entry *re, + const struct prefix *p, enum zapi_route_notify_owner note); extern void zsend_rule_notify_owner(struct zebra_pbr_rule *rule, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 8935956b25..9bf6bfa22f 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -156,7 +156,7 @@ int is_zebra_main_routing_table(uint32_t table_id) return 0; } -int zebra_check_addr(struct prefix *p) +int zebra_check_addr(const struct prefix *p) { if (p->family == AF_INET) { uint32_t addr; @@ -325,7 +325,7 @@ struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re, return nexthop; } -static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop, +static void nexthop_set_resolved(afi_t afi, const struct nexthop *newhop, struct nexthop *nexthop) { struct nexthop *resolved_hop; @@ -843,7 +843,7 @@ static unsigned nexthop_active_check(struct route_node *rn, route_map_result_t ret = RMAP_MATCH; int family; char buf[SRCDEST2STR_BUFFER]; - struct prefix *p, *src_p; + const struct prefix *p, *src_p; srcdest_rnode_prefixes(rn, &p, &src_p); if (rn->p.family == AF_INET) @@ -1012,7 +1012,7 @@ int zebra_rib_labeled_unicast(struct route_entry *re) return 1; } -void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p, +void kernel_route_rib_pass_fail(struct route_node *rn, const struct prefix *p, struct route_entry *re, enum dp_results res) { @@ -1085,7 +1085,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re, { struct nexthop *nexthop; rib_table_info_t *info = srcdest_rnode_table_info(rn); - struct prefix *p, *src_p; + const struct prefix *p, *src_p; struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id); srcdest_rnode_prefixes(rn, &p, &src_p); @@ -1143,7 +1143,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) { struct nexthop *nexthop; rib_table_info_t *info = srcdest_rnode_table_info(rn); - struct prefix *p, *src_p; + const struct prefix *p, *src_p; struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id); srcdest_rnode_prefixes(rn, &p, &src_p); @@ -1194,7 +1194,8 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re) } if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) { - struct prefix *p, *src_p; + const struct prefix *p, *src_p; + srcdest_rnode_prefixes(rn, &p, &src_p); redistribute_delete(p, src_p, re); @@ -1536,7 +1537,8 @@ static void rib_process(struct route_node *rn) char buf[SRCDEST2STR_BUFFER]; rib_dest_t *dest; struct zebra_vrf *zvrf = NULL; - struct prefix *p, *src_p; + const struct prefix *p, *src_p; + srcdest_rnode_prefixes(rn, &p, &src_p); vrf_id_t vrf_id = VRF_UNKNOWN; diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index ce51f54a65..bf6718164f 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1337,7 +1337,8 @@ void zebra_route_map_write_delay_timer(struct vty *vty) } route_map_result_t zebra_route_map_check(int family, int rib_type, - uint8_t instance, struct prefix *p, + uint8_t instance, + const struct prefix *p, struct nexthop *nexthop, vrf_id_t vrf_id, route_tag_t tag) { @@ -1358,7 +1359,8 @@ route_map_result_t zebra_route_map_check(int family, int rib_type, rmap = route_map_lookup_by_name( proto_rm[family][ZEBRA_ROUTE_MAX]); if (rmap) { - ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); + ret = route_map_apply(rmap, (struct prefix *)p, + RMAP_ZEBRA, &nh_obj); } return (ret); diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index 20d425a2bc..688c8b7203 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -40,7 +40,7 @@ zebra_import_table_route_map_check(int family, int rib_type, uint8_t instance, const char *rmap_name); extern route_map_result_t zebra_route_map_check(int family, int rib_type, uint8_t instance, - struct prefix *p, struct nexthop *nexthop, + const struct prefix *p, struct nexthop *nexthop, vrf_id_t vrf_id, route_tag_t tag); extern route_map_result_t zebra_nht_route_map_check(int family, int client_proto, struct prefix *p, diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 67b2954f35..76346f6b66 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -37,8 +37,9 @@ #include "zebra/zebra_memory.h" /* Install static route into rib. */ -void static_install_route(afi_t afi, safi_t safi, struct prefix *p, - struct prefix_ipv6 *src_p, struct static_route *si) +void static_install_route(afi_t afi, safi_t safi, const struct prefix *p, + const struct prefix_ipv6 *src_p, + struct static_route *si) { struct route_entry *re; struct route_node *rn; @@ -292,8 +293,9 @@ static int static_nexthop_same(struct nexthop *nexthop, struct static_route *si) } /* Uninstall static route from RIB. */ -void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p, - struct prefix_ipv6 *src_p, struct static_route *si) +void static_uninstall_route(afi_t afi, safi_t safi, const struct prefix *p, + const struct prefix_ipv6 *src_p, + struct static_route *si) { struct route_node *rn; struct route_entry *re; @@ -610,7 +612,7 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi, struct route_table *stable; struct route_node *rn; struct static_route *si; - struct prefix *p, *src_pp; + const struct prefix *p, *src_pp; struct prefix_ipv6 *src_p; struct vrf *vrf; diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h index 7dc47d6190..0be434fff2 100644 --- a/zebra/zebra_static.h +++ b/zebra/zebra_static.h @@ -82,11 +82,12 @@ struct static_route { uint32_t table_id; }; -extern void static_install_route(afi_t afi, safi_t safi, struct prefix *p, - struct prefix_ipv6 *src_p, +extern void static_install_route(afi_t afi, safi_t safi, const struct prefix *p, + const struct prefix_ipv6 *src_p, struct static_route *si); -extern void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p, - struct prefix_ipv6 *src_p, +extern void static_uninstall_route(afi_t afi, safi_t safi, + const struct prefix *p, + const struct prefix_ipv6 *src_p, struct static_route *si); extern int static_add_route(afi_t, safi_t safi, uint8_t type, struct prefix *p, |
