diff --git a/bfdd/bfd.c b/bfdd/bfd.c index eb9c3003135f..e08d0160a3fb 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -1172,6 +1172,12 @@ void bfd_set_echo(struct bfd_session *bs, bool echo) if (bs->bdc == NULL) ptm_bfd_echo_stop(bs); } +<<<<<<< HEAD +======= + + if (bs->vrf && bs->vrf->info) + bfd_vrf_toggle_echo(bs->vrf->info); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } void bfd_set_shutdown(struct bfd_session *bs, bool shutdown) @@ -1800,6 +1806,72 @@ void bfd_profiles_remove(void) bfd_profile_free(bp); } +<<<<<<< HEAD +======= +struct __bfd_session_echo { + /* VRF peers must match */ + struct vrf *vrf; + /* Echo enabled or not */ + bool enabled; +}; + +static int __bfd_session_has_echo(struct hash_bucket *hb, void *arg) +{ + const struct bfd_session *session = hb->data; + struct __bfd_session_echo *has_echo = arg; + + if (session->vrf != has_echo->vrf) + return HASHWALK_CONTINUE; + if (!CHECK_FLAG(session->flags, BFD_SESS_FLAG_ECHO)) + return HASHWALK_CONTINUE; + + has_echo->enabled = true; + return HASHWALK_ABORT; +} + +void bfd_vrf_toggle_echo(struct bfd_vrf_global *bfd_vrf) +{ + struct __bfd_session_echo has_echo = { + .enabled = false, + .vrf = bfd_vrf->vrf, + }; + + /* Check for peers using echo */ + hash_walk(bfd_id_hash, __bfd_session_has_echo, &has_echo); + + /* + * No peers using echo, close all echo sockets. + */ + if (!has_echo.enabled) { + if (bfd_vrf->bg_echo != -1) { + event_cancel(&bfd_vrf->bg_ev[4]); + close(bfd_vrf->bg_echo); + bfd_vrf->bg_echo = -1; + } + + if (bfd_vrf->bg_echov6 != -1) { + event_cancel(&bfd_vrf->bg_ev[5]); + close(bfd_vrf->bg_echov6); + bfd_vrf->bg_echov6 = -1; + } + return; + } + + /* + * At least one peer using echo, open echo sockets. + */ + if (bfd_vrf->bg_echo == -1) + bfd_vrf->bg_echo = bp_echo_socket(bfd_vrf->vrf); + if (bfd_vrf->bg_echov6 == -1) + bfd_vrf->bg_echov6 = bp_echov6_socket(bfd_vrf->vrf); + + if (bfd_vrf->bg_ev[4] == NULL && bfd_vrf->bg_echo != -1) + event_add_read(master, bfd_recv_cb, bfd_vrf, bfd_vrf->bg_echo, &bfd_vrf->bg_ev[4]); + if (bfd_vrf->bg_ev[5] == NULL && bfd_vrf->bg_echov6 != -1) + event_add_read(master, bfd_recv_cb, bfd_vrf, bfd_vrf->bg_echov6, &bfd_vrf->bg_ev[5]); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Profile related hash functions. */ @@ -1842,9 +1914,29 @@ static void bfd_profile_detach(struct bfd_profile *bp) */ static int bfd_vrf_new(struct vrf *vrf) { +<<<<<<< HEAD if (bglobal.debug_zebra) zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id); +======= + struct bfd_vrf_global *bvrf; + + if (bglobal.debug_zebra) + zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id); + + bvrf = XCALLOC(MTYPE_BFDD_VRF, sizeof(struct bfd_vrf_global)); + bvrf->vrf = vrf; + vrf->info = bvrf; + + /* Invalidate all sockets */ + bvrf->bg_shop = -1; + bvrf->bg_mhop = -1; + bvrf->bg_shop6 = -1; + bvrf->bg_mhop6 = -1; + bvrf->bg_echo = -1; + bvrf->bg_echov6 = -1; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -1853,11 +1945,17 @@ static int bfd_vrf_delete(struct vrf *vrf) if (bglobal.debug_zebra) zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id); +<<<<<<< HEAD +======= + XFREE(MTYPE_BFDD_VRF, vrf->info); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } static int bfd_vrf_enable(struct vrf *vrf) { +<<<<<<< HEAD struct bfd_vrf_global *bvrf; /* a different name */ @@ -1877,10 +1975,14 @@ static int bfd_vrf_enable(struct vrf *vrf) } } else bvrf = vrf->info; +======= + struct bfd_vrf_global *bvrf = vrf->info; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (bglobal.debug_zebra) zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id); +<<<<<<< HEAD if (!bvrf->bg_shop) bvrf->bg_shop = bp_udp_shop(vrf); if (!bvrf->bg_mhop) @@ -1913,10 +2015,46 @@ static int bfd_vrf_enable(struct vrf *vrf) event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6, &bvrf->bg_ev[5]); +======= + /* Don't open sockets when using data plane */ + if (bglobal.bg_use_dplane) + goto skip_sockets; + + if (bvrf->bg_shop == -1) + bvrf->bg_shop = bp_udp_shop(vrf); + if (bvrf->bg_mhop == -1) + bvrf->bg_mhop = bp_udp_mhop(vrf); + if (bvrf->bg_shop6 == -1) + bvrf->bg_shop6 = bp_udp6_shop(vrf); + if (bvrf->bg_mhop6 == -1) + bvrf->bg_mhop6 = bp_udp6_mhop(vrf); + + if (bvrf->bg_ev[0] == NULL && bvrf->bg_shop != -1) + event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop, + &bvrf->bg_ev[0]); + if (bvrf->bg_ev[1] == NULL && bvrf->bg_mhop != -1) + event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop, + &bvrf->bg_ev[1]); + if (bvrf->bg_ev[2] == NULL && bvrf->bg_shop6 != -1) + event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6, + &bvrf->bg_ev[2]); + if (bvrf->bg_ev[3] == NULL && bvrf->bg_mhop6 != -1) + event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6, + &bvrf->bg_ev[3]); + + /* Toggle echo if VRF was disabled. */ + bfd_vrf_toggle_echo(bvrf); + +skip_sockets: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (vrf->vrf_id != VRF_DEFAULT) { bfdd_zclient_register(vrf->vrf_id); bfdd_sessions_enable_vrf(vrf); } +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -1948,6 +2086,7 @@ static int bfd_vrf_disable(struct vrf *vrf) socket_close(&bvrf->bg_echo); socket_close(&bvrf->bg_shop); socket_close(&bvrf->bg_mhop); +<<<<<<< HEAD if (bvrf->bg_shop6 != -1) socket_close(&bvrf->bg_shop6); if (bvrf->bg_mhop6 != -1) @@ -1959,6 +2098,11 @@ static int bfd_vrf_disable(struct vrf *vrf) /* free context */ XFREE(MTYPE_BFDD_VRF, bvrf); vrf->info = NULL; +======= + socket_close(&bvrf->bg_shop6); + socket_close(&bvrf->bg_mhop6); + socket_close(&bvrf->bg_echov6); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } diff --git a/bfdd/bfd.h b/bfdd/bfd.h index 2f83b245eb28..f9b70c7d09f4 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -610,6 +610,11 @@ void bfd_sessions_remove_manual(void); void bfd_profiles_remove(void); void bfd_rtt_init(struct bfd_session *bfd); +<<<<<<< HEAD +======= +extern void bfd_vrf_toggle_echo(struct bfd_vrf_global *bfd_vrf); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /** * Set the BFD session echo state. * diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c index 2e213a2237ea..aa88e1977465 100644 --- a/bfdd/bfdd_cli.c +++ b/bfdd/bfdd_cli.c @@ -338,7 +338,11 @@ void bfd_cli_show_minimum_ttl(struct vty *vty, const struct lyd_node *dnode, DEFPY_YANG( bfd_peer_mult, bfd_peer_mult_cmd, +<<<<<<< HEAD "[no] detect-multiplier ![(2-255)$multiplier]", +======= + "[no] detect-multiplier ![(1-255)$multiplier]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer detection multiplier\n" "Configure peer detection multiplier value\n") @@ -357,7 +361,11 @@ void bfd_cli_show_mult(struct vty *vty, const struct lyd_node *dnode, DEFPY_YANG( bfd_peer_rx, bfd_peer_rx_cmd, +<<<<<<< HEAD "[no] receive-interval ![(10-60000)$interval]", +======= + "[no] receive-interval ![(10-4294967)$interval]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer receive interval\n" "Configure peer receive interval value in milliseconds\n") @@ -381,7 +389,11 @@ void bfd_cli_show_rx(struct vty *vty, const struct lyd_node *dnode, DEFPY_YANG( bfd_peer_tx, bfd_peer_tx_cmd, +<<<<<<< HEAD "[no] transmit-interval ![(10-60000)$interval]", +======= + "[no] transmit-interval ![(10-4294967)$interval]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer transmit interval\n" "Configure peer transmit interval value in milliseconds\n") @@ -439,7 +451,11 @@ void bfd_cli_show_echo(struct vty *vty, const struct lyd_node *dnode, DEFPY_YANG( bfd_peer_echo_interval, bfd_peer_echo_interval_cmd, +<<<<<<< HEAD "[no] echo-interval ![(10-60000)$interval]", +======= + "[no] echo-interval ![(10-4294967)$interval]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer echo intervals\n" "Configure peer echo rx/tx intervals value in milliseconds\n") @@ -462,7 +478,11 @@ DEFPY_YANG( DEFPY_YANG( bfd_peer_echo_transmit_interval, bfd_peer_echo_transmit_interval_cmd, +<<<<<<< HEAD "[no] echo transmit-interval ![(10-60000)$interval]", +======= + "[no] echo transmit-interval ![(10-4294967)$interval]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer echo intervals\n" "Configure desired transmit interval\n" @@ -492,7 +512,11 @@ void bfd_cli_show_desired_echo_transmission_interval( DEFPY_YANG( bfd_peer_echo_receive_interval, bfd_peer_echo_receive_interval_cmd, +<<<<<<< HEAD "[no] echo receive-interval ![]", +======= + "[no] echo receive-interval ![]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer echo intervals\n" "Configure required receive interval\n" @@ -577,19 +601,31 @@ void bfd_cli_show_profile(struct vty *vty, const struct lyd_node *dnode, } ALIAS_YANG(bfd_peer_mult, bfd_profile_mult_cmd, +<<<<<<< HEAD "[no] detect-multiplier ![(2-255)$multiplier]", +======= + "[no] detect-multiplier ![(1-255)$multiplier]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer detection multiplier\n" "Configure peer detection multiplier value\n") ALIAS_YANG(bfd_peer_tx, bfd_profile_tx_cmd, +<<<<<<< HEAD "[no] transmit-interval ![(10-60000)$interval]", +======= + "[no] transmit-interval ![(10-4294967)$interval]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer transmit interval\n" "Configure peer transmit interval value in milliseconds\n") ALIAS_YANG(bfd_peer_rx, bfd_profile_rx_cmd, +<<<<<<< HEAD "[no] receive-interval ![(10-60000)$interval]", +======= + "[no] receive-interval ![(10-4294967)$interval]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer receive interval\n" "Configure peer receive interval value in milliseconds\n") @@ -621,14 +657,22 @@ ALIAS_YANG(bfd_peer_echo, bfd_profile_echo_cmd, "Configure echo mode\n") ALIAS_YANG(bfd_peer_echo_interval, bfd_profile_echo_interval_cmd, +<<<<<<< HEAD "[no] echo-interval ![(10-60000)$interval]", +======= + "[no] echo-interval ![(10-4294967)$interval]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer echo interval\n" "Configure peer echo interval value in milliseconds\n") ALIAS_YANG( bfd_peer_echo_transmit_interval, bfd_profile_echo_transmit_interval_cmd, +<<<<<<< HEAD "[no] echo transmit-interval ![(10-60000)$interval]", +======= + "[no] echo transmit-interval ![(10-4294967)$interval]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer echo intervals\n" "Configure desired transmit interval\n" @@ -636,7 +680,11 @@ ALIAS_YANG( ALIAS_YANG( bfd_peer_echo_receive_interval, bfd_profile_echo_receive_interval_cmd, +<<<<<<< HEAD "[no] echo receive-interval ![]", +======= + "[no] echo receive-interval ![]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Configure peer echo intervals\n" "Configure required receive interval\n" diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 4c1615a5c625..89c83dc0a00f 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -297,6 +297,11 @@ static struct aspath *aspath_new(enum asnotation_mode asnotation) as = XCALLOC(MTYPE_AS_PATH, sizeof(struct aspath)); as->asnotation = asnotation; +<<<<<<< HEAD +======= + as->count = 0; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return as; } @@ -400,6 +405,14 @@ unsigned int aspath_count_confeds(struct aspath *aspath) unsigned int aspath_count_hops(const struct aspath *aspath) { +<<<<<<< HEAD +======= + return aspath->count; +} + +static unsigned int aspath_count_hops_internal(const struct aspath *aspath) +{ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int count = 0; struct assegment *seg = aspath->segments; @@ -708,6 +721,10 @@ struct aspath *aspath_dup(struct aspath *aspath) else new->str[0] = '\0'; +<<<<<<< HEAD +======= + new->count = aspath->count; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return new; } @@ -729,6 +746,10 @@ static void *aspath_hash_alloc(void *arg) new->str_len = aspath->str_len; new->json = aspath->json; new->asnotation = aspath->asnotation; +<<<<<<< HEAD +======= + new->count = aspath->count; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return new; } @@ -856,6 +877,11 @@ struct aspath *aspath_parse(struct stream *s, size_t length, int use32bit, if (assegments_parse(s, length, &as.segments, use32bit) < 0) return NULL; +<<<<<<< HEAD +======= + as.count = aspath_count_hops_internal(&as); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* If already same aspath exist then return it. */ find = hash_get(ashash, &as, aspath_hash_alloc); @@ -1032,7 +1058,11 @@ static struct assegment *aspath_aggregate_as_set_add(struct aspath *aspath, asset->as[asset->length - 1] = as; } +<<<<<<< HEAD +======= + aspath->count = aspath_count_hops_internal(aspath); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return asset; } @@ -1113,6 +1143,11 @@ struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2) assegment_normalise(aspath->segments); aspath_str_update(aspath, false); +<<<<<<< HEAD +======= + aspath->count = aspath_count_hops_internal(aspath); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return aspath; } @@ -1268,6 +1303,10 @@ struct aspath *aspath_replace_regex_asn(struct aspath *aspath, } aspath_str_update(new, false); +<<<<<<< HEAD +======= + new->count = aspath_count_hops_internal(new); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return new; } @@ -1293,6 +1332,11 @@ struct aspath *aspath_replace_specific_asn(struct aspath *aspath, } aspath_str_update(new, false); +<<<<<<< HEAD +======= + new->count = aspath_count_hops_internal(new); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return new; } @@ -1315,6 +1359,11 @@ struct aspath *aspath_replace_all_asn(struct aspath *aspath, as_t our_asn) } aspath_str_update(new, false); +<<<<<<< HEAD +======= + new->count = aspath_count_hops_internal(new); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return new; } @@ -1341,6 +1390,11 @@ struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn, } aspath_str_update(new, false); +<<<<<<< HEAD +======= + new->count = aspath_count_hops_internal(new); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return new; } @@ -1413,6 +1467,10 @@ struct aspath *aspath_remove_private_asns(struct aspath *aspath, as_t peer_asn) if (!aspath->refcnt) aspath_free(aspath); aspath_str_update(new, false); +<<<<<<< HEAD +======= + new->count = aspath_count_hops_internal(new); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return new; } @@ -1469,6 +1527,10 @@ static struct aspath *aspath_merge(struct aspath *as1, struct aspath *as2) last->next = as2->segments; as2->segments = new; aspath_str_update(as2, false); +<<<<<<< HEAD +======= + as2->count = aspath_count_hops_internal(as2); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return as2; } @@ -1486,6 +1548,10 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2) if (as2->segments == NULL) { as2->segments = assegment_dup_all(as1->segments); aspath_str_update(as2, false); +<<<<<<< HEAD +======= + as2->count = aspath_count_hops_internal(as2); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return as2; } @@ -1506,6 +1572,10 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2) if (!as2->segments) { as2->segments = assegment_dup_all(as1->segments); aspath_str_update(as2, false); +<<<<<<< HEAD +======= + as2->count = aspath_count_hops_internal(as2); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return as2; } @@ -1551,6 +1621,10 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2) * the inbetween AS_SEQUENCE of seg2 in the process */ aspath_str_update(as2, false); +<<<<<<< HEAD +======= + as2->count = aspath_count_hops_internal(as2); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return as2; } else { /* AS_SET merge code is needed at here. */ @@ -1662,6 +1736,10 @@ struct aspath *aspath_filter_exclude(struct aspath *source, lastseg = newseg; } aspath_str_update(newpath, false); +<<<<<<< HEAD +======= + newpath->count = aspath_count_hops_internal(newpath); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* We are happy returning even an empty AS_PATH, because the * administrator * might expect this very behaviour. There's a mean to avoid this, if @@ -1680,6 +1758,10 @@ struct aspath *aspath_filter_exclude_all(struct aspath *source) newpath = aspath_new(source->asnotation); aspath_str_update(newpath, false); +<<<<<<< HEAD +======= + newpath->count = aspath_count_hops_internal(newpath); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* We are happy returning even an empty AS_PATH, because the * administrator * might expect this very behaviour. There's a mean to avoid this, if @@ -1767,6 +1849,10 @@ struct aspath *aspath_filter_exclude_acl(struct aspath *source, aspath_str_update(source, false); +<<<<<<< HEAD +======= + source->count = aspath_count_hops_internal(source); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* We are happy returning even an empty AS_PATH, because the * administrator * might expect this very behaviour. There's a mean to avoid this, if @@ -1805,6 +1891,10 @@ static struct aspath *aspath_add_asns(struct aspath *aspath, as_t asno, } aspath_str_update(aspath, false); +<<<<<<< HEAD +======= + aspath->count = aspath_count_hops_internal(aspath); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return aspath; } @@ -1896,6 +1986,10 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath, if (!hops) { newpath = aspath_dup(as4path); aspath_str_update(newpath, false); +<<<<<<< HEAD +======= + /* dup sets the count properly */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return newpath; } @@ -1957,6 +2051,10 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath, aspath_free(newpath); mergedpath->segments = assegment_normalise(mergedpath->segments); aspath_str_update(mergedpath, false); +<<<<<<< HEAD +======= + mergedpath->count = aspath_count_hops_internal(mergedpath); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (BGP_DEBUG(as4, AS4)) zlog_debug("[AS4] result of synthesizing is %s", @@ -2027,8 +2125,15 @@ struct aspath *aspath_delete_confed_seq(struct aspath *aspath) seg = next; } +<<<<<<< HEAD if (removed_confed_segment) aspath_str_update(aspath, false); +======= + if (removed_confed_segment) { + aspath_str_update(aspath, false); + aspath->count = aspath_count_hops_internal(aspath); + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return aspath; } diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h index f7e57fd66dda..17db3261f527 100644 --- a/bgpd/bgp_aspath.h +++ b/bgpd/bgp_aspath.h @@ -59,6 +59,10 @@ struct aspath { and AS path regular expression match. */ char *str; unsigned short str_len; +<<<<<<< HEAD +======= + uint32_t count; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* AS notation used by string expression of AS path */ enum asnotation_mode asnotation; diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 1a2fa8318e34..2fe11fd4b24e 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -697,6 +697,7 @@ static uint32_t srv6_l3vpn_hash_key_make(const void *p) uint32_t key = 0; key = jhash(&l3vpn->sid, 16, key); +<<<<<<< HEAD key = jhash_1word(l3vpn->sid_flags, key); key = jhash_1word(l3vpn->endpoint_behavior, key); key = jhash_1word(l3vpn->loc_block_len, key); @@ -705,6 +706,11 @@ static uint32_t srv6_l3vpn_hash_key_make(const void *p) key = jhash_1word(l3vpn->arg_len, key); key = jhash_1word(l3vpn->transposition_len, key); key = jhash_1word(l3vpn->transposition_offset, key); +======= + key = jhash_3words(l3vpn->sid_flags, l3vpn->endpoint_behavior, l3vpn->loc_block_len, key); + key = jhash_3words(l3vpn->loc_node_len, l3vpn->func_len, l3vpn->arg_len, key); + key = jhash_2words(l3vpn->transposition_len, l3vpn->transposition_offset, key); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return key; } @@ -863,6 +869,7 @@ unsigned int attrhash_key_make(const void *p) if (vnc_subtlvs) MIX(encap_hash_key_make(vnc_subtlvs)); #endif +<<<<<<< HEAD MIX(attr->mp_nexthop_len); key = jhash(attr->mp_nexthop_global.s6_addr, IPV6_MAX_BYTELEN, key); key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key); @@ -872,6 +879,13 @@ unsigned int attrhash_key_make(const void *p) MIX(attr->bh_type); MIX(attr->otc); MIX(bgp_attr_get_aigp_metric(attr)); +======= + MIX3(attr->mp_nexthop_len, attr->rmap_table_id, attr->nh_type); + key = jhash(attr->mp_nexthop_global.s6_addr, IPV6_MAX_BYTELEN, key); + key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key); + MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance); + MIX3(attr->bh_type, attr->otc, bgp_attr_get_aigp_metric(attr)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return key; } @@ -976,8 +990,16 @@ static void attr_show_all_iterator(struct hash_bucket *bucket, struct vty *vty) "\n", attr->flag, attr->distance, attr->med, attr->local_pref, attr->origin, attr->weight, attr->label, sid, attr->aigp_metric); +<<<<<<< HEAD vty_out(vty, "\taspath: %s Community: %s Large Community: %s\n", aspath_print(attr->aspath), +======= + vty_out(vty, + "\tnh_ifindex: %u nh_flags: %u distance: %u nexthop_global: %pI6 nexthop_local: %pI6 nexthop_local_ifindex: %u\n", + attr->nh_ifindex, attr->nh_flags, attr->distance, &attr->mp_nexthop_global, + &attr->mp_nexthop_local, attr->nh_lla_ifindex); + vty_out(vty, "\taspath: %s Community: %s Large Community: %s\n", aspath_print(attr->aspath), +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) community_str(attr->community, false, false), lcommunity_str(attr->lcommunity, false, false)); vty_out(vty, "\tExtended Community: %s Extended IPv6 Community: %s\n", @@ -1176,8 +1198,12 @@ struct attr *bgp_attr_aggregate_intern( SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)); /* MED */ +<<<<<<< HEAD attr.med = 0; SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)); +======= + bgp_attr_set_med(&attr, 0); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* AS path attribute. */ if (aspath) @@ -1932,9 +1958,13 @@ static enum bgp_attr_parse_ret bgp_attr_med(struct bgp_attr_parser_args *args) args->total); } +<<<<<<< HEAD attr->med = stream_getl(peer->curr); SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)); +======= + bgp_attr_set_med(attr, stream_getl(peer->curr)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return BGP_ATTR_PARSE_PROCEED; } @@ -4485,6 +4515,7 @@ static bool bgp_append_local_as(struct peer *peer, afi_t afi, safi_t safi) } static void bgp_packet_ecommunity_attribute(struct stream *s, struct peer *peer, +<<<<<<< HEAD struct ecommunity *ecomm, bool transparent, int attribute) { @@ -4545,6 +4576,24 @@ static void bgp_packet_ecommunity_attribute(struct stream *s, struct peer *peer, } } } +======= + struct ecommunity *ecomm, int attribute) +{ + if (!ecomm || !ecomm->size) + return; + + if (ecomm->size * ecomm->unit_size > 255) { + stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN); + stream_putc(s, attribute); + stream_putw(s, ecomm->size * ecomm->unit_size); + } else { + stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS); + stream_putc(s, attribute); + stream_putc(s, ecomm->size * ecomm->unit_size); + } + + stream_put(s, ecomm->val, ecomm->size * ecomm->unit_size); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Make attribute packet. */ @@ -4851,19 +4900,26 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, struct strea /* Extended IPv6/Communities attributes. */ if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) { +<<<<<<< HEAD bool transparent = CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) && from && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr); +<<<<<<< HEAD bgp_packet_ecommunity_attribute(s, peer, ecomm, transparent, BGP_ATTR_EXT_COMMUNITIES); +======= + bgp_packet_ecommunity_attribute(s, peer, ecomm, BGP_ATTR_EXT_COMMUNITIES); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (CHECK_FLAG(attr->flag, @@ -4872,7 +4928,10 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, struct strea bgp_attr_get_ipv6_ecommunity(attr); bgp_packet_ecommunity_attribute(s, peer, ecomm, +<<<<<<< HEAD transparent, +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) BGP_ATTR_IPV6_EXT_COMMUNITIES); } } diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 5633c2f89af8..91792ab4506a 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -515,7 +515,11 @@ static inline void bgp_attr_set_ecommunity(struct attr *attr, { attr->ecommunity = ecomm; +<<<<<<< HEAD if (ecomm) +======= + if (ecomm && ecomm->size) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)); else UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)); @@ -566,7 +570,11 @@ static inline void bgp_attr_set_ipv6_ecommunity(struct attr *attr, { attr->ipv6_ecommunity = ipv6_ecomm; +<<<<<<< HEAD if (ipv6_ecomm) +======= + if (ipv6_ecomm && ipv6_ecomm->size) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES)); else @@ -610,6 +618,15 @@ static inline uint64_t bgp_aigp_metric_total(struct bgp_path_info *bpi) return aigp; } +<<<<<<< HEAD +======= +static inline void bgp_attr_set_med(struct attr *attr, uint32_t med) +{ + attr->med = med; + SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static inline struct cluster_list *bgp_attr_get_cluster(const struct attr *attr) { return attr->cluster1; diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 14ff5f2e1151..51cbfde4a431 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -26,6 +26,10 @@ #include "bgpd/bgp_debug.h" #include "bgpd/bgp_vty.h" #include "bgpd/bgp_packet.h" +<<<<<<< HEAD +======= +#include "bgpd/bgp_network.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data"); @@ -53,6 +57,7 @@ static void bfd_session_status_update(struct bfd_session_params *bsp, peer->host); return; } +<<<<<<< HEAD peer->last_reset = PEER_DOWN_BFD_DOWN; /* rfc9384 */ @@ -61,6 +66,25 @@ static void bfd_session_status_update(struct bfd_session_params *bsp, BGP_NOTIFY_CEASE_BFD_DOWN); BGP_EVENT_ADD(peer->connection, BGP_Stop); +======= + + /* Once the BFD session is UP, and later BGP session is UP, + * BFD notices that peer->su_local changed, and BFD session goes down. + * We should trigger BGP session reset if BFD session is UP + * only when BGP session is UP already. + * Otherwise, we end up resetting BGP session when BFD session is UP, + * when the source address is changed, e.g. 0.0.0.0 -> 10.0.0.1. + */ + if (bss->last_event > peer->uptime) { + peer->last_reset = PEER_DOWN_BFD_DOWN; + /* rfc9384 */ + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_BFD_DOWN); + + BGP_EVENT_ADD(peer->connection, BGP_Stop); + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (bss->state == BSS_UP && bss->previous_state != BSS_UP && @@ -141,24 +165,61 @@ void bgp_peer_config_apply(struct peer *p, struct peer_group *pg) void bgp_peer_bfd_update_source(struct peer *p) { +<<<<<<< HEAD struct bfd_session_params *session = p->bfd_config->session; const union sockunion *source; +======= + struct bfd_session_params *session; + const union sockunion *source = NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bool changed = false; int family; union { struct in_addr v4; struct in6_addr v6; } src, dst; +<<<<<<< HEAD + +======= + struct interface *ifp; + union sockunion addr; + + if (!p->bfd_config) + return; + session = p->bfd_config->session; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Nothing to do for groups. */ if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)) return; /* Figure out the correct source to use. */ +<<<<<<< HEAD if (CHECK_FLAG(p->flags, PEER_FLAG_UPDATE_SOURCE) && p->update_source) source = p->update_source; else source = p->su_local; +======= + if (CHECK_FLAG(p->flags, PEER_FLAG_UPDATE_SOURCE)) { + if (p->update_source) { + source = p->update_source; + } else if (p->update_if) { + ifp = if_lookup_by_name(p->update_if, p->bgp->vrf_id); + if (ifp) { + sockunion_init(&addr); + if (bgp_update_address(ifp, &p->connection->su, &addr)) { + if (BGP_DEBUG(bfd, BFD_LIB)) + zlog_debug("%s: can't find the source address for interface %s", + __func__, p->update_if); + } + + source = &addr; + } + } + } else { + source = p->su_local; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Update peer's source/destination addresses. */ bfd_sess_addresses(session, &family, &src.v6, &dst.v6); diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 7b67d4b8241e..14ca51e3ac49 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -39,6 +39,11 @@ #include "bgpd/bgp_trace.h" #include "bgpd/bgp_network.h" #include "bgpd/bgp_label.h" +<<<<<<< HEAD +======= +#include "bgpd/bgp_open.h" +#include "bgpd/bgp_aspath.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static void bmp_close(struct bmp *bmp); static struct bmp_bgp *bmp_bgp_find(struct bgp *bgp); @@ -246,6 +251,36 @@ static void bmp_free(struct bmp *bmp) #define BMP_PEER_TYPE_LOCAL_INSTANCE 2 #define BMP_PEER_TYPE_LOC_RIB_INSTANCE 3 +<<<<<<< HEAD +======= +/* determine the peer type for per-peer headers from a vrf_id + * for non loc-rib peer type only + */ +static inline int bmp_get_peer_type_vrf(vrf_id_t vrf_id) +{ + switch (vrf_id) { + case VRF_DEFAULT: + return BMP_PEER_TYPE_GLOBAL_INSTANCE; + case VRF_UNKNOWN: + /* when the VRF is unknown consider it a local instance */ + return BMP_PEER_TYPE_LOCAL_INSTANCE; + default: + return BMP_PEER_TYPE_RD_INSTANCE; + } +} + +/* determine the peer type for per-peer headers from a struct peer + * provide a bgp->peer_self for loc-rib + */ +static inline int bmp_get_peer_type(struct peer *peer) +{ + if (peer->bgp->peer_self == peer) + return BMP_PEER_TYPE_LOC_RIB_INSTANCE; + + return bmp_get_peer_type_vrf(peer->bgp->vrf_id); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static inline int bmp_get_peer_distinguisher(struct bmp *bmp, afi_t afi, uint8_t peer_type, uint64_t *result_ref) @@ -370,6 +405,7 @@ static void bmp_put_info_tlv(struct stream *s, uint16_t type, stream_put(s, string, len); } +<<<<<<< HEAD static void __attribute__((unused)) bmp_put_vrftablename_info_tlv(struct stream *s, struct bmp *bmp) { @@ -381,6 +417,20 @@ bmp_put_vrftablename_info_tlv(struct stream *s, struct bmp *bmp) vrftablename = vrf ? vrf->name : NULL; } +======= +/* put the vrf table name of the bgp instance bmp is bound to in a tlv on the + * stream + */ +static void bmp_put_vrftablename_info_tlv(struct stream *s, struct bgp *bgp) +{ + const char *vrftablename = "global"; + +#define BMP_INFO_TYPE_VRFTABLENAME 3 + + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) + vrftablename = bgp->name; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (vrftablename != NULL) bmp_put_info_tlv(s, BMP_INFO_TYPE_VRFTABLENAME, vrftablename); } @@ -428,31 +478,66 @@ static void bmp_notify_put(struct stream *s, struct bgp_notify *nfy) + sizeof(marker)); } +<<<<<<< HEAD +======= +/* send peer up/down for peer based on down boolean value + * returns the message to send or NULL if the peer_distinguisher is not + * available + */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static struct stream *bmp_peerstate(struct peer *peer, bool down) { struct stream *s; size_t len; struct timeval uptime, uptime_real; +<<<<<<< HEAD +======= + uint8_t peer_type; + bool is_locrib = false; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) uptime.tv_sec = peer->uptime; uptime.tv_usec = 0; monotime_to_realtime(&uptime, &uptime_real); +<<<<<<< HEAD +======= + peer_type = bmp_get_peer_type(peer); + if (peer_type == BMP_PEER_TYPE_LOC_RIB_INSTANCE) + is_locrib = true; + else + /* TODO: remove this when other RD and local instances supported */ + peer_type = BMP_PEER_TYPE_GLOBAL_INSTANCE; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #define BGP_BMP_MAX_PACKET_SIZE 1024 #define BMP_PEERUP_INFO_TYPE_STRING 0 s = stream_new(BGP_MAX_PACKET_SIZE); +<<<<<<< HEAD if (peer_established(peer->connection) && !down) { +======= + if ((peer_established(peer->connection) || is_locrib) && !down) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct bmp_bgp_peer *bbpeer; bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_PEER_UP_NOTIFICATION); +<<<<<<< HEAD bmp_per_peer_hdr(s, peer->bgp, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, &uptime_real); /* Local Address (16 bytes) */ if (peer->su_local->sa.sa_family == AF_INET6) +======= + bmp_per_peer_hdr(s, peer->bgp, peer, 0, peer_type, 0, &uptime_real); + + /* Local Address (16 bytes) */ + if (is_locrib) + stream_put(s, 0, 16); + else if (peer->su_local->sa.sa_family == AF_INET6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) stream_put(s, &peer->su_local->sin6.sin6_addr, 16); else if (peer->su_local->sa.sa_family == AF_INET) { stream_putl(s, 0); @@ -462,15 +547,32 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down) } /* Local Port, Remote Port */ +<<<<<<< HEAD if (peer->su_local->sa.sa_family == AF_INET6) stream_putw(s, htons(peer->su_local->sin6.sin6_port)); else if (peer->su_local->sa.sa_family == AF_INET) stream_putw(s, htons(peer->su_local->sin.sin_port)); if (peer->su_remote->sa.sa_family == AF_INET6) +======= + if (!peer->su_local || is_locrib) + stream_putw(s, 0); + else if (peer->su_local->sa.sa_family == AF_INET6) + stream_putw(s, htons(peer->su_local->sin6.sin6_port)); + else if (peer->su_local->sa.sa_family == AF_INET) + stream_putw(s, htons(peer->su_local->sin.sin_port)); + + if (!peer->su_remote || is_locrib) + stream_putw(s, 0); + else if (peer->su_remote->sa.sa_family == AF_INET6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) stream_putw(s, htons(peer->su_remote->sin6.sin6_port)); else if (peer->su_remote->sa.sa_family == AF_INET) stream_putw(s, htons(peer->su_remote->sin.sin_port)); +<<<<<<< HEAD +======= + /* TODO craft message with fields & capabilities for loc-rib */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static const uint8_t dummy_open[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -510,6 +612,7 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down) type_pos = stream_get_endp(s); stream_putc(s, 0); /* placeholder for down reason */ +<<<<<<< HEAD switch (peer->last_reset) { case PEER_DOWN_NOTIFY_RECEIVED: type = BMP_PEERDOWN_REMOTE_NOTIFY; @@ -532,10 +635,45 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down) type = BMP_PEERDOWN_LOCAL_FSM; stream_putw(s, BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE); break; +======= + if (is_locrib) { + type = BMP_PEERDOWN_LOCAL_TLV; + } else { + switch (peer->last_reset) { + case PEER_DOWN_NOTIFY_RECEIVED: + type = BMP_PEERDOWN_REMOTE_NOTIFY; + bmp_notify_put(s, &peer->notify); + break; + case PEER_DOWN_CLOSE_SESSION: + type = BMP_PEERDOWN_REMOTE_CLOSE; + break; + case PEER_DOWN_WAITING_NHT: + type = BMP_PEERDOWN_LOCAL_FSM; + stream_putw(s, BGP_FSM_TcpConnectionFails); + break; + /* + * TODO: Map remaining PEER_DOWN_* reasons to RFC event + * codes. + * TODO: Implement BMP_PEERDOWN_LOCAL_NOTIFY. + * + * See RFC7854 ss. 4.9 + */ + default: + type = BMP_PEERDOWN_LOCAL_FSM; + stream_putw(s, BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE); + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } stream_putc_at(s, type_pos, type); } +<<<<<<< HEAD +======= + if (is_locrib) + bmp_put_vrftablename_info_tlv(s, peer->bgp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) len = stream_get_endp(s); stream_putl_at(s, BMP_LENGTH_POS, len); /* message length is set. */ return s; @@ -558,6 +696,28 @@ static int bmp_send_peerup(struct bmp *bmp) return 0; } +<<<<<<< HEAD +======= +static int bmp_send_peerup_vrf(struct bmp *bmp) +{ + struct bmp_bgp *bmpbgp = bmp->targets->bmpbgp; + struct stream *s; + + /* send unconditionally because state may has been set before the + * session was up. and in this case the peer up has not been sent. + */ + bmp_bgp_update_vrf_status(bmpbgp, vrf_state_unknown); + + s = bmp_peerstate(bmpbgp->bgp->peer_self, bmpbgp->vrf_state == vrf_state_down); + + pullwr_write_stream(bmp->pullwr, s); + stream_free(s); + + return 0; +} + +/* send a stream to all bmp sessions configured in a bgp instance */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* XXX: kludge - filling the pullwr's buffer */ static void bmp_send_all(struct bmp_bgp *bmpbgp, struct stream *s) { @@ -570,6 +730,19 @@ static void bmp_send_all(struct bmp_bgp *bmpbgp, struct stream *s) stream_free(s); } +<<<<<<< HEAD +======= +static void bmp_send_all_safe(struct bmp_bgp *bmpbgp, struct stream *s) +{ + if (!bmpbgp) { + stream_free(s); + return; + } + + bmp_send_all(bmpbgp, s); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Route Mirroring */ @@ -816,7 +989,11 @@ static int bmp_peer_status_changed(struct peer *peer) } } +<<<<<<< HEAD bmp_send_all(bmpbgp, bmp_peerstate(peer, false)); +======= + bmp_send_all_safe(bmpbgp, bmp_peerstate(peer, false)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -838,7 +1015,11 @@ static int bmp_peer_backward(struct peer *peer) bbpeer->open_rx_len = 0; } +<<<<<<< HEAD bmp_send_all(bmpbgp, bmp_peerstate(peer, true)); +======= + bmp_send_all_safe(bmpbgp, bmp_peerstate(peer, true)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -1475,6 +1656,10 @@ static void bmp_wrfill(struct bmp *bmp, struct pullwr *pullwr) { switch(bmp->state) { case BMP_PeerUp: +<<<<<<< HEAD +======= + bmp_send_peerup_vrf(bmp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bmp_send_peerup(bmp); bmp->state = BMP_Run; break; @@ -1838,6 +2023,10 @@ static struct bmp_bgp *bmp_bgp_get(struct bgp *bgp) bmpbgp = XCALLOC(MTYPE_BMP, sizeof(*bmpbgp)); bmpbgp->bgp = bgp; +<<<<<<< HEAD +======= + bmpbgp->vrf_state = vrf_state_unknown; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bmpbgp->mirror_qsizelimit = ~0UL; bmp_mirrorq_init(&bmpbgp->mirrorq); bmp_bgph_add(&bmp_bgph, bmpbgp); @@ -1872,6 +2061,84 @@ static int bmp_bgp_del(struct bgp *bgp) return 0; } +<<<<<<< HEAD +======= +static void bmp_bgp_peer_vrf(struct bmp_bgp_peer *bbpeer, struct bgp *bgp) +{ + struct peer *peer = bgp->peer_self; + uint16_t send_holdtime; + as_t local_as; + + if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) + send_holdtime = peer->holdtime; + else + send_holdtime = peer->bgp->default_holdtime; + + /* local-as Change */ + if (peer->change_local_as) + local_as = peer->change_local_as; + else + local_as = peer->local_as; + + struct stream *s = bgp_open_make(peer, send_holdtime, local_as); + size_t open_len = stream_get_endp(s); + + bbpeer->open_rx_len = open_len; + bbpeer->open_rx = XMALLOC(MTYPE_BMP_OPEN, open_len); + memcpy(bbpeer->open_rx, s->data, open_len); + + bbpeer->open_tx_len = open_len; + bbpeer->open_tx = bbpeer->open_rx; + + stream_free(s); +} + +/* update the vrf status of the bmpbgp struct for vrf peer up/down + * + * if force is unknown, use zebra vrf state + * + * returns true if state has changed + */ +bool bmp_bgp_update_vrf_status(struct bmp_bgp *bmpbgp, enum bmp_vrf_state force) +{ + enum bmp_vrf_state old_state; + struct bmp_bgp_peer *bbpeer; + struct peer *peer; + struct vrf *vrf; + struct bgp *bgp; + bool changed; + + if (!bmpbgp || !bmpbgp->bgp) + return false; + + bgp = bmpbgp->bgp; + old_state = bmpbgp->vrf_state; + + vrf = bgp_vrf_lookup_by_instance_type(bgp); + bmpbgp->vrf_state = force != vrf_state_unknown ? force + : vrf_is_enabled(vrf) ? vrf_state_up + : vrf_state_down; + + changed = old_state != bmpbgp->vrf_state; + if (changed) { + peer = bmpbgp->bgp->peer_self; + if (bmpbgp->vrf_state == vrf_state_up) { + bbpeer = bmp_bgp_peer_get(peer); + bmp_bgp_peer_vrf(bbpeer, bgp); + } else { + bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid); + if (bbpeer) { + XFREE(MTYPE_BMP_OPEN, bbpeer->open_rx); + bmp_peerh_del(&bmp_peerh, bbpeer); + XFREE(MTYPE_BMP_PEER, bbpeer); + } + } + } + + return changed; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static struct bmp_bgp_peer *bmp_bgp_peer_find(uint64_t peerid) { struct bmp_bgp_peer dummy = { .peerid = peerid }; @@ -2951,6 +3218,47 @@ static int bgp_bmp_early_fini(void) return 0; } +<<<<<<< HEAD +======= +/* called when a bgp instance goes up/down, implying that the underlying VRF + * has been created or deleted in zebra + */ +static int bmp_vrf_state_changed(struct bgp *bgp) +{ + struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp); + + if (!bmp_bgp_update_vrf_status(bmpbgp, vrf_state_unknown)) + return 1; + + bmp_send_all_safe(bmpbgp, + bmp_peerstate(bgp->peer_self, bmpbgp->vrf_state == vrf_state_down)); + + return 0; +} + +/* called when an interface goes up/down in a vrf, this may signal that the + * VRF changed state and is how bgp_snmp detects vrf state changes + */ +static int bmp_vrf_itf_state_changed(struct bgp *bgp, struct interface *itf) +{ + struct bmp_bgp *bmpbgp; + enum bmp_vrf_state new_state; + + /* if the update is not about the vrf device double-check + * the zebra status of the vrf + */ + if (!itf || !if_is_vrf(itf)) + return bmp_vrf_state_changed(bgp); + + bmpbgp = bmp_bgp_find(bgp); + new_state = if_is_up(itf) ? vrf_state_up : vrf_state_down; + if (bmp_bgp_update_vrf_status(bmpbgp, new_state)) + bmp_send_all(bmpbgp, bmp_peerstate(bgp->peer_self, new_state == vrf_state_down)); + + return 0; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static int bgp_bmp_module_init(void) { hook_register(bgp_packet_dump, bmp_mirror_packet); @@ -2963,6 +3271,11 @@ static int bgp_bmp_module_init(void) hook_register(frr_late_init, bgp_bmp_init); hook_register(bgp_route_update, bmp_route_update); hook_register(frr_early_fini, bgp_bmp_early_fini); +<<<<<<< HEAD +======= + hook_register(bgp_instance_state, bmp_vrf_state_changed); + hook_register(bgp_vrf_status_changed, bmp_vrf_itf_state_changed); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } diff --git a/bgpd/bgp_bmp.h b/bgpd/bgp_bmp.h index 33247c402504..aa539a7d4cd5 100644 --- a/bgpd/bgp_bmp.h +++ b/bgpd/bgp_bmp.h @@ -268,10 +268,25 @@ PREDECL_HASH(bmp_bgph); #define BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE 0x00 +<<<<<<< HEAD +======= +enum bmp_vrf_state { + vrf_state_down = -1, + vrf_state_unknown = 0, + vrf_state_up = 1, +}; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct bmp_bgp { struct bmp_bgph_item bbi; struct bgp *bgp; +<<<<<<< HEAD +======= + + enum bmp_vrf_state vrf_state; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct bmp_targets_head targets; struct bmp_mirrorq_head mirrorq; @@ -280,12 +295,26 @@ struct bmp_bgp { size_t mirror_qsizelimit; }; +<<<<<<< HEAD enum { BMP_PEERDOWN_LOCAL_NOTIFY = 1, BMP_PEERDOWN_LOCAL_FSM = 2, BMP_PEERDOWN_REMOTE_NOTIFY = 3, BMP_PEERDOWN_REMOTE_CLOSE = 4, BMP_PEERDOWN_ENDMONITOR = 5, +======= +extern bool bmp_bgp_update_vrf_status(struct bmp_bgp *bmpbgp, enum bmp_vrf_state force); + +enum { + /* RFC7854 - 10.8 */ + BMP_PEERDOWN_LOCAL_NOTIFY = 1, + BMP_PEERDOWN_LOCAL_FSM = 2, + BMP_PEERDOWN_REMOTE_NOTIFY = 3, + BMP_PEERDOWN_REMOTE_CLOSE = 4, + BMP_PEERDOWN_ENDMONITOR = 5, + /* RFC9069 - 8.4 */ + BMP_PEERDOWN_LOCAL_TLV = 6, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }; enum { diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 61ba527498ca..29d48458adf8 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -11,7 +11,10 @@ #include "queue.h" #include "filter.h" #include "stream.h" +<<<<<<< HEAD #include "jhash.h" +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "frrstr.h" #include "bgpd/bgpd.h" @@ -534,20 +537,44 @@ static bool community_regexp_match(struct community *com, regex_t *reg) const char *str; char *regstr; int rv; +<<<<<<< HEAD +======= + bool translate_alias = !!bgp_ca_alias_hash->count; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* When there is no communities attribute it is treated as empty string. */ if (com == NULL || com->size == 0) +<<<<<<< HEAD str = ""; else str = community_str(com, false, true); regstr = bgp_alias2community_str(str); +======= + return false; + + str = community_str(com, false, translate_alias); + + /* If at least one community alias is configured, then let's + * do the work, otherwise we don't need to spend time on splitting + * stuff and creating a new string. + */ + regstr = translate_alias ? bgp_alias2community_str(str) : (char *)str; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Regular expression match. */ rv = regexec(reg, regstr, 0, NULL, 0); +<<<<<<< HEAD XFREE(MTYPE_TMP, regstr); +======= + /* This is allocated by frrstr_join(), and needs to be freed + * only if it was created. + */ + if (translate_alias) + XFREE(MTYPE_TMP, regstr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return rv == 0; } @@ -608,20 +635,44 @@ static bool lcommunity_regexp_match(struct lcommunity *com, regex_t *reg) const char *str; char *regstr; int rv; +<<<<<<< HEAD +======= + bool translate_alias = !!bgp_ca_alias_hash->count; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* When there is no communities attribute it is treated as empty string. */ if (com == NULL || com->size == 0) +<<<<<<< HEAD str = ""; else str = lcommunity_str(com, false, true); regstr = bgp_alias2community_str(str); +======= + return false; + + str = lcommunity_str(com, false, translate_alias); + + /* If at least one community alias is configured, then let's + * do the work, otherwise we don't need to spend time on splitting + * stuff and creating a new string. + */ + regstr = translate_alias ? bgp_alias2community_str(str) : (char *)str; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Regular expression match. */ rv = regexec(reg, regstr, 0, NULL, 0); +<<<<<<< HEAD XFREE(MTYPE_TMP, regstr); +======= + /* This is allocated by frrstr_join(), and needs to be freed + * only if it was created. + */ + if (translate_alias) + XFREE(MTYPE_TMP, regstr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return rv == 0; } diff --git a/bgpd/bgp_community_alias.c b/bgpd/bgp_community_alias.c index 96dc1ec8f9aa..2126fd2258f2 100644 --- a/bgpd/bgp_community_alias.c +++ b/bgpd/bgp_community_alias.c @@ -13,7 +13,11 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_community_alias.h" +<<<<<<< HEAD static struct hash *bgp_ca_alias_hash; +======= +struct hash *bgp_ca_alias_hash; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static struct hash *bgp_ca_community_hash; static unsigned int bgp_ca_community_hash_key(const void *p) diff --git a/bgpd/bgp_community_alias.h b/bgpd/bgp_community_alias.h index cb7983e1a70c..09a2e1e19fa4 100644 --- a/bgpd/bgp_community_alias.h +++ b/bgpd/bgp_community_alias.h @@ -17,6 +17,10 @@ struct community_alias { char alias[BUFSIZ]; }; +<<<<<<< HEAD +======= +extern struct hash *bgp_ca_alias_hash; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern void bgp_community_alias_init(void); extern void bgp_community_alias_finish(void); extern struct community_alias *bgp_ca_alias_lookup(struct community_alias *ca); diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c index 2d96b444b6c5..a93d74ef6e4a 100644 --- a/bgpd/bgp_conditional_adv.c +++ b/bgpd/bgp_conditional_adv.c @@ -30,8 +30,13 @@ bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table, dummy_attr = *pi->attr; /* Fill temp path_info */ +<<<<<<< HEAD prep_for_rmap_apply(&path, &path_extra, dest, pi, pi->peer, &dummy_attr); +======= + prep_for_rmap_apply(&path, &path_extra, dest, pi, pi->peer, NULL, + &dummy_attr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) RESET_FLAG(dummy_attr.rmap_change_flags); @@ -99,8 +104,13 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, advmap_attr = *pi->attr; /* Fill temp path_info */ +<<<<<<< HEAD prep_for_rmap_apply(&path, &path_extra, dest, pi, pi->peer, &advmap_attr); +======= + prep_for_rmap_apply(&path, &path_extra, dest, pi, pi->peer, NULL, + &advmap_attr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) RESET_FLAG(advmap_attr.rmap_change_flags); diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 97c3e5740f6e..51a57c06fd8f 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -449,6 +449,13 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size) ", extcommunity %s", ecommunity_str(bgp_attr_get_ecommunity(attr))); +<<<<<<< HEAD +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES))) + snprintf(buf + strlen(buf), size - strlen(buf), ", ipv6-extcommunity %s", + ecommunity_str(bgp_attr_get_ipv6_ecommunity(attr))); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))) snprintf(buf + strlen(buf), size - strlen(buf), ", atomic-aggregate"); diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 547dcdf7f32a..d75be63ec40b 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -361,6 +361,7 @@ static void ecommunity_color_str(char *buf, size_t bufsz, uint8_t *ptr) { /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +<<<<<<< HEAD * | 0x03 | Sub-Type(0x0b) | Flags | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Color Value | @@ -371,6 +372,24 @@ static void ecommunity_color_str(char *buf, size_t bufsz, uint8_t *ptr) memcpy(&colorid, ptr + 3, 4); colorid = ntohl(colorid); snprintf(buf, bufsz, "Color:%d", colorid); +======= + * | 0x03 | Sub-Type(0x0b) | CO| Flags | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Color Value | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * https://datatracker.ietf.org/doc/rfc9256/, Section 8.8.1 + * The CO bits can have 4 different values: 00 01 10 11 + */ + uint32_t colorid; + uint8_t color_type; + /* get the color type */ + ptr++; + color_type = (*ptr) >> 6; + + memcpy(&colorid, ptr + 2, 4); + colorid = ntohl(colorid); + snprintf(buf, bufsz, "Color:%d%d:%d", (color_type & 0x2) >> 1, color_type & 0x1, colorid); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Initialize Extended Comminities related hash. */ @@ -531,7 +550,11 @@ static int ecommunity_encode_internal(uint8_t type, uint8_t sub_type, eval6->val[19] = val & 0xff; } else if (type == ECOMMUNITY_ENCODE_OPAQUE && sub_type == ECOMMUNITY_COLOR) { +<<<<<<< HEAD encode_color(val, eval); +======= + encode_color(val, as, eval); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else { encode_route_target_as4(as, val, eval, trans); } @@ -739,6 +762,16 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr, */ if (!asn_str2asn(buf, &as)) goto error; +<<<<<<< HEAD +======= + } else if (type == ECOMMUNITY_COLOR) { + /* If extcommunity is color, only support 00/01/10/11, max value is 3 */ + /* color value */ + as = strtoul(buf, &endptr, 2); + if (*endptr != '\0' || as > 3) + goto error; + val_color = 0; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else { /* Parsing A AS number in A:MN */ errno = 0; @@ -753,6 +786,11 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr, if (*endptr != '\0' || tmp_as > BGP_AS4_MAX || errno) goto error; +<<<<<<< HEAD +======= + if (*token == ecommunity_token_color && tmp_as > 3) + goto error; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) as = (as_t)tmp_as; } } else if (*p == '.') { @@ -791,6 +829,7 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr, /* Encode result into extended community for AS format or color. */ if (as > BGP_AS_MAX) ecomm_type = ECOMMUNITY_ENCODE_AS4; +<<<<<<< HEAD else if (as > 0) ecomm_type = ECOMMUNITY_ENCODE_AS; else if (val_color) { @@ -798,6 +837,17 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr, sub_type = ECOMMUNITY_COLOR; val = val_color; } +======= + else if (type == ECOMMUNITY_COLOR) { + ecomm_type = ECOMMUNITY_ENCODE_OPAQUE; + sub_type = ECOMMUNITY_COLOR; + if (val_color) { + val = val_color; + as = 1; + } + } else if (as > 0) + ecomm_type = ECOMMUNITY_ENCODE_AS; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (ecommunity_encode(ecomm_type, sub_type, 1, as, ip, val, eval)) goto error; @@ -1408,23 +1458,47 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) "FS:marking %u", *(pnt + 5)); } else unk_ecom = true; +<<<<<<< HEAD } else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS) { sub_type = *pnt++; if (sub_type == ECOMMUNITY_LINK_BANDWIDTH) +======= + } else if (CHECK_FLAG(type, ECOMMUNITY_FLAG_NON_TRANSITIVE) || + type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS) { + sub_type = *pnt++; + if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE) + ecommunity_origin_validation_state_str(encbuf, sizeof(encbuf), pnt); + else if (sub_type == ECOMMUNITY_LINK_BANDWIDTH) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ecommunity_lb_str(encbuf, sizeof(encbuf), pnt, ecom->disable_ieee_floating); else if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH) ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf), pnt, len); +<<<<<<< HEAD else unk_ecom = true; } else if (type == ECOMMUNITY_ENCODE_IP_NON_TRANS) { +======= + else if (sub_type == ECOMMUNITY_OPAQUE_SUBTYPE_COLOR) { + uint32_t color; + /* get the color type */ + uint8_t color_type = (*pnt) >> 6; + memcpy(&color, pnt + 2, 4); + color = ntohl(color); + snprintf(encbuf, sizeof(encbuf), "Color:%d%d:%u", + (color_type & 0x2) >> 1, color_type & 0x1, color); + } else + unk_ecom = true; + } else if (CHECK_FLAG(type, ECOMMUNITY_ENCODE_IP_NON_TRANS)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) sub_type = *pnt++; if (sub_type == ECOMMUNITY_NODE_TARGET) ecommunity_node_target_str( encbuf, sizeof(encbuf), pnt, format); else unk_ecom = true; +<<<<<<< HEAD } else if (type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS) { sub_type = *pnt++; if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE) @@ -1432,6 +1506,8 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) encbuf, sizeof(encbuf), pnt); else unk_ecom = true; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else { sub_type = *pnt++; unk_ecom = true; @@ -1443,6 +1519,10 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) sub_type); int r = strlcat(str_buf, encbuf, str_size); +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert(r < str_size); } @@ -1587,6 +1667,60 @@ bool ecommunity_strip(struct ecommunity *ecom, uint8_t type, return true; } +<<<<<<< HEAD +======= +static bool ecommunity_non_transitive(uint8_t type) +{ + return (CHECK_FLAG(type, ECOMMUNITY_FLAG_NON_TRANSITIVE) || + CHECK_FLAG(type, ECOMMUNITY_ENCODE_IP_NON_TRANS) || + type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS); +} + +/* Delete all non-transitive extended communities */ +bool ecommunity_strip_non_transitive(struct ecommunity *ecom) +{ + uint8_t *p, *q, *new; + uint32_t c, found = 0; + + if (!ecom || !ecom->val) + return false; + + /* Certain extended communities like the Route Target can be present + * multiple times, handle that. + */ + c = 0; + for (p = ecom->val; c < ecom->size; p += ecom->unit_size, c++) + if (ecommunity_non_transitive(*p)) + found++; + + if (!found) + return false; + + /* Handle the case where everything needs to be stripped. */ + if (found == ecom->size) { + XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val); + ecom->size = 0; + return true; + } + + /* Strip extended communities with non-transitive flag set */ + new = XMALLOC(MTYPE_ECOMMUNITY_VAL, (ecom->size - found) * ecom->unit_size); + q = new; + for (c = 0, p = ecom->val; c < ecom->size; c++, p += ecom->unit_size) { + if (!ecommunity_non_transitive(*p)) { + memcpy(q, p, ecom->unit_size); + q += ecom->unit_size; + } + } + + XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val); + ecom->val = new; + ecom->size -= found; + + return true; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Remove specified extended community value from extended community. * Returns 1 if value was present (and hence, removed), 0 otherwise. @@ -1883,9 +2017,13 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw) if (len < ecom->unit_size) return NULL; +<<<<<<< HEAD if ((type == ECOMMUNITY_ENCODE_AS || type == ECOMMUNITY_ENCODE_AS_NON_TRANS) && sub_type == ECOMMUNITY_LINK_BANDWIDTH) { +======= + if ((type == ECOMMUNITY_ENCODE_AS) && sub_type == ECOMMUNITY_LINK_BANDWIDTH) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) uint32_t bwval; pnt += 2; /* bandwidth is encoded as AS:val */ diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index 67c16aeb9e82..e156b9831d00 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -32,9 +32,13 @@ #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_3 0x82 /* Non-transitive extended community types. */ +<<<<<<< HEAD #define ECOMMUNITY_ENCODE_AS_NON_TRANS 0x40 #define ECOMMUNITY_ENCODE_IP_NON_TRANS 0x41 #define ECOMMUNITY_ENCODE_AS4_NON_TRANS 0x42 +======= +#define ECOMMUNITY_ENCODE_IP_NON_TRANS 0x41 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #define ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS 0x43 /* Low-order octet of the Extended Communities type field. */ @@ -87,6 +91,10 @@ /* Low-order octet of the Extended Communities type field for OPAQUE types */ #define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP 0x0c +<<<<<<< HEAD +======= +#define ECOMMUNITY_OPAQUE_SUBTYPE_COLOR 0x0b +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Extended communities attribute string format. */ #define ECOMMUNITY_FORMAT_ROUTE_MAP 0 @@ -330,6 +338,7 @@ static inline void encode_node_target(struct in_addr *node_id, /* * Encode BGP Color extended community +<<<<<<< HEAD * is's a transitive opaque Extended community (RFC 9012 4.3) * flag is set to 0 * RFC 9012 14.10: No values have currently been registered. @@ -345,11 +354,31 @@ static inline void encode_color(uint32_t color_id, struct ecommunity_val *eval) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Color Value | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +======= + * is's a transitive opaque Extended community (RFC 9256 8.8.1) + * flag is set to 0 + * + */ +static inline void encode_color(uint32_t color_id, uint32_t flags, struct ecommunity_val *eval) +{ + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 0x03 | Sub-Type(0x0b) |CO | Flags | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Color Value | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * https://datatracker.ietf.org/doc/rfc9256/, Section 8.8.1 + * The CO bits can have 4 different values: 00 01 10 11 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) */ memset(eval, 0, sizeof(*eval)); eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE; eval->val[1] = ECOMMUNITY_COLOR; +<<<<<<< HEAD eval->val[2] = 0x00; +======= + eval->val[2] = (flags << 6) & 0xff; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) eval->val[3] = 0x00; eval->val[4] = (color_id >> 24) & 0xff; eval->val[5] = (color_id >> 16) & 0xff; @@ -398,6 +427,10 @@ extern struct ecommunity *ecommunity_new(void); extern bool ecommunity_strip(struct ecommunity *ecom, uint8_t type, uint8_t subtype); extern struct ecommunity *ecommunity_new(void); +<<<<<<< HEAD +======= +extern bool ecommunity_strip_non_transitive(struct ecommunity *ecom); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern bool ecommunity_del_val(struct ecommunity *ecom, struct ecommunity_val *eval); struct bgp_pbr_entry_action; diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 134831900109..9d1d2657201e 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -5421,9 +5421,14 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi, tmp_attr = *pi->attr; /* Fill temp path_info */ +<<<<<<< HEAD prep_for_rmap_apply(&tmp_pi, &tmp_pie, dest, pi, pi->peer, &tmp_attr); +======= + prep_for_rmap_apply(&tmp_pi, &tmp_pie, dest, pi, pi->peer, + NULL, &tmp_attr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) RESET_FLAG(tmp_attr.rmap_change_flags); diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index e5692b6b4865..27c41966290a 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -178,6 +178,10 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) EVENT_OFF(going_away->t_delayopen); EVENT_OFF(going_away->t_connect_check_r); EVENT_OFF(going_away->t_connect_check_w); +<<<<<<< HEAD +======= + EVENT_OFF(going_away->t_stop_with_notify); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) EVENT_OFF(keeper->t_routeadv); EVENT_OFF(keeper->t_connect); EVENT_OFF(keeper->t_delayopen); @@ -264,7 +268,11 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) from_peer->addpath_paths_limit[afi][safi]; } +<<<<<<< HEAD if (bgp_getsockname(peer) < 0) { +======= + if (bgp_getsockname(keeper) < 0) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) flog_err(EC_LIB_SOCKET, "%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)", (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER) @@ -276,7 +284,11 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) return NULL; } if (going_away->status > Active) { +<<<<<<< HEAD if (bgp_getsockname(from_peer) < 0) { +======= + if (bgp_getsockname(going_away) < 0) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) flog_err(EC_LIB_SOCKET, "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)", @@ -324,8 +336,13 @@ void bgp_timer_set(struct peer_connection *connection) /* First entry point of peer's finite state machine. In Idle status start timer is on unless peer is shutdown or peer is inactive. All other timer must be turned off */ +<<<<<<< HEAD if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer) || peer->bgp->vrf_id == VRF_UNKNOWN) { +======= + if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(connection) || + peer->bgp->vrf_id == VRF_UNKNOWN) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) EVENT_OFF(connection->t_start); } else { BGP_TIMER_ON(connection->t_start, bgp_start_timer, @@ -1343,11 +1360,14 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) peer->nsf_af_count = 0; +<<<<<<< HEAD /* deregister peer */ if (peer->bfd_config && peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE) bfd_sess_uninstall(peer->bfd_config->session); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (peer_dynamic_neighbor_no_nsf(peer) && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) { if (bgp_debug_neighbor_events(peer)) @@ -1367,6 +1387,13 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) if (peer_established(connection)) { peer->dropped++; +<<<<<<< HEAD +======= + if (peer->bfd_config && (peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE || + peer->last_reset == PEER_DOWN_MULTIHOP_CHANGE)) + bfd_sess_uninstall(peer->bfd_config->session); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Notify BGP conditional advertisement process */ peer->advmap_table_change = true; @@ -1483,6 +1510,11 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) EVENT_OFF(connection->t_connect_check_r); EVENT_OFF(connection->t_connect_check_w); +<<<<<<< HEAD +======= + EVENT_OFF(connection->t_stop_with_notify); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Stop all timers. */ EVENT_OFF(connection->t_start); EVENT_OFF(connection->t_connect); @@ -1692,11 +1724,19 @@ bgp_connect_success(struct peer_connection *connection) return bgp_stop(connection); } +<<<<<<< HEAD if (bgp_getsockname(peer) < 0) { flog_err_sys(EC_LIB_SOCKET, "%s: bgp_getsockname(): failed for peer %s, fd %d", __func__, peer->host, connection->fd); bgp_notify_send(peer->connection, BGP_NOTIFY_FSM_ERR, +======= + if (bgp_getsockname(connection) < 0) { + flog_err_sys(EC_LIB_SOCKET, + "%s: bgp_getsockname(): failed for peer %s, fd %d", + __func__, peer->host, connection->fd); + bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_fsm_error_subcode(connection->status)); bgp_writes_on(connection); return BGP_FSM_FAILURE; @@ -1738,11 +1778,19 @@ bgp_connect_success_w_delayopen(struct peer_connection *connection) return bgp_stop(connection); } +<<<<<<< HEAD if (bgp_getsockname(peer) < 0) { flog_err_sys(EC_LIB_SOCKET, "%s: bgp_getsockname(): failed for peer %s, fd %d", __func__, peer->host, connection->fd); bgp_notify_send(peer->connection, BGP_NOTIFY_FSM_ERR, +======= + if (bgp_getsockname(connection) < 0) { + flog_err_sys(EC_LIB_SOCKET, + "%s: bgp_getsockname(): failed for peer %s, fd %d", + __func__, peer->host, connection->fd); + bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_fsm_error_subcode(connection->status)); bgp_writes_on(connection); return BGP_FSM_FAILURE; @@ -1805,12 +1853,23 @@ bgp_connect_fail(struct peer_connection *connection) /* after connect is called(), getpeername is able to return * port and address on non established streams */ +<<<<<<< HEAD static void bgp_connect_in_progress_update_connection(struct peer *peer) { bgp_updatesockname(peer); if (!peer->su_remote && !BGP_CONNECTION_SU_UNSPEC(peer->connection)) { /* if connect initiated, then dest port and dest addresses are well known */ peer->su_remote = sockunion_dup(&peer->connection->su); +======= +static void bgp_connect_in_progress_update_connection(struct peer_connection *connection) +{ + struct peer *peer = connection->peer; + + bgp_updatesockname(peer, connection); + if (!peer->su_remote && !BGP_CONNECTION_SU_UNSPEC(peer->connection)) { + /* if connect initiated, then dest port and dest addresses are well known */ + peer->su_remote = sockunion_dup(&connection->su); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (sockunion_family(peer->su_remote) == AF_INET) peer->su_remote->sin.sin_port = htons(peer->port); else if (sockunion_family(peer->su_remote) == AF_INET6) @@ -1824,7 +1883,11 @@ static void bgp_connect_in_progress_update_connection(struct peer *peer) static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection) { struct peer *peer = connection->peer; +<<<<<<< HEAD int status; +======= + enum connect_result status; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_peer_conf_if_to_su_update(connection); @@ -1914,7 +1977,11 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection) __func__, peer->connection->fd); return BGP_FSM_FAILURE; } +<<<<<<< HEAD bgp_connect_in_progress_update_connection(peer); +======= + bgp_connect_in_progress_update_connection(connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * - when the socket becomes ready, poll() will signify POLLOUT @@ -2743,10 +2810,14 @@ static void bgp_gr_update_mode_of_all_peers(struct bgp *bgp, peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset_safe(peer, &nnode); } else { group = peer->group; @@ -2766,10 +2837,14 @@ static void bgp_gr_update_mode_of_all_peers(struct bgp *bgp, member->last_reset = PEER_DOWN_CAPABILITY_CHANGE; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(member); } } @@ -2806,6 +2881,7 @@ int bgp_gr_update_all(struct bgp *bgp, enum global_gr_command global_gr_cmd) const char *print_peer_gr_mode(enum peer_mode pr_mode) { +<<<<<<< HEAD const char *peer_gr_mode = NULL; switch (pr_mode) { @@ -2827,10 +2903,27 @@ const char *print_peer_gr_mode(enum peer_mode pr_mode) } return peer_gr_mode; +======= + switch (pr_mode) { + case PEER_HELPER: + return "PEER_HELPER"; + case PEER_GR: + return "PEER_GR"; + case PEER_DISABLE: + return "PEER_DISABLE"; + case PEER_INVALID: + return "PEER_INVALID"; + case PEER_GLOBAL_INHERIT: + return "PEER_GLOBAL_INHERIT"; + } + + return NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd) { +<<<<<<< HEAD const char *peer_gr_cmd = NULL; switch (pr_gr_cmd) { @@ -2855,10 +2948,29 @@ const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd) } return peer_gr_cmd; +======= + switch (pr_gr_cmd) { + case PEER_GR_CMD: + return "PEER_GR_CMD"; + case NO_PEER_GR_CMD: + return "NO_PEER_GR_CMD"; + case PEER_DISABLE_CMD: + return "PEER_DISABLE_GR_CMD"; + case NO_PEER_DISABLE_CMD: + return "NO_PEER_DISABLE_GR_CMD"; + case PEER_HELPER_CMD: + return "PEER_HELPER_CMD"; + case NO_PEER_HELPER_CMD: + return "NO_PEER_HELPER_CMD"; + } + + return NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } const char *print_global_gr_mode(enum global_mode gl_mode) { +<<<<<<< HEAD const char *global_gr_mode = "???"; switch (gl_mode) { @@ -2877,10 +2989,25 @@ const char *print_global_gr_mode(enum global_mode gl_mode) } return global_gr_mode; +======= + switch (gl_mode) { + case GLOBAL_HELPER: + return "GLOBAL_HELPER"; + case GLOBAL_GR: + return "GLOBAL_GR"; + case GLOBAL_DISABLE: + return "GLOBAL_DISABLE"; + case GLOBAL_INVALID: + return "GLOBAL_INVALID"; + } + + return "???"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd) { +<<<<<<< HEAD const char *global_gr_cmd = NULL; switch (gl_gr_cmd) { @@ -2899,6 +3026,20 @@ const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd) } return global_gr_cmd; +======= + switch (gl_gr_cmd) { + case GLOBAL_GR_CMD: + return "GLOBAL_GR_CMD"; + case NO_GLOBAL_GR_CMD: + return "NO_GLOBAL_GR_CMD"; + case GLOBAL_DISABLE_CMD: + return "GLOBAL_DISABLE_CMD"; + case NO_GLOBAL_DISABLE_CMD: + return "NO_GLOBAL_DISABLE_CMD"; + } + + return NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } enum global_mode bgp_global_gr_mode_get(struct bgp *bgp) @@ -2998,10 +3139,14 @@ unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state, if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); } else { group = peer->group; @@ -3009,10 +3154,14 @@ unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state, member->last_reset = PEER_DOWN_CAPABILITY_CHANGE; bgp_peer_move_to_gr_mode(member, new_state); +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(member); } } @@ -3103,3 +3252,13 @@ void bgp_peer_gr_flags_update(struct peer *peer) } } } +<<<<<<< HEAD +======= + +void bgp_event_stop_with_notify(struct event *event) +{ + struct peer_connection *connection = EVENT_ARG(event); + + bgp_stop_with_notify(connection, BGP_NOTIFY_SEND_HOLD_ERR, 0); +} +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index 85c488962fc9..154e39ffc5d2 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -109,6 +109,10 @@ enum bgp_fsm_state_progress { extern void bgp_fsm_nht_update(struct peer_connection *connection, struct peer *peer, bool has_valid_nexthops); extern void bgp_event(struct event *event); +<<<<<<< HEAD +======= +extern void bgp_event_stop_with_notify(struct event *event); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern int bgp_event_update(struct peer_connection *connection, enum bgp_fsm_events event); extern enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection); diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index b07e69ac31bb..820b19da5fe6 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -512,7 +512,17 @@ static uint16_t bgp_read(struct peer_connection *connection, int *code_p) readsize = MIN(ibuf_work_space, sizeof(ibuf_scratch)); +<<<<<<< HEAD nbytes = read(connection->fd, ibuf_scratch, readsize); +======= +#ifdef __clang_analyzer__ + /* clang-SA doesn't want you to call read() while holding a mutex */ + (void)readsize; + nbytes = 0; +#else + nbytes = read(connection->fd, ibuf_scratch, readsize); +#endif +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* EAGAIN or EWOULDBLOCK; come back later */ if (nbytes < 0 && ERRNO_IO_RETRY(errno)) { diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index df45cf237e51..aacbd04a79ea 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1598,6 +1598,18 @@ vpn_leak_from_vrf_get_per_nexthop_label(afi_t afi, struct bgp_path_info *pi, return bgp_mplsvpn_get_vpn_label(&from_bgp->vpn_policy[afi]); } +<<<<<<< HEAD +======= + if (is_bgp_static_route && pi->nexthop->nexthop->type == NEXTHOP_TYPE_IFINDEX) { + /* "network" imported prefixes from vrf + * fallback to per-vrf label. + */ + + bgp_mplsvpn_path_nh_label_unlink(pi); + return bgp_mplsvpn_get_vpn_label(&from_bgp->vpn_policy[afi]); + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return _vpn_leak_from_vrf_get_per_nexthop_label(pi, to_bgp, from_bgp, afi); } diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index de57d91806e1..2bd5c65aa82c 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -504,7 +504,11 @@ static void bgp_accept(struct event *thread) bgp_fsm_change_status(connection1, Active); EVENT_OFF(connection1->t_start); +<<<<<<< HEAD if (peer_active(peer1)) { +======= + if (peer_active(peer1->connection)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (CHECK_FLAG(peer1->flags, PEER_FLAG_TIMER_DELAYOPEN)) BGP_EVENT_ADD(connection1, @@ -557,7 +561,11 @@ static void bgp_accept(struct event *thread) } /* Check that at least one AF is activated for the peer. */ +<<<<<<< HEAD if (!peer_active(peer1)) { +======= + if (!peer_active(connection1)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (bgp_debug_neighbor_events(peer1)) zlog_debug( "%s - incoming conn rejected - no AF activated for peer", @@ -658,7 +666,11 @@ static void bgp_accept(struct event *thread) bgp_event_update(connection1, TCP_connection_closed); } +<<<<<<< HEAD if (peer_active(peer)) { +======= + if (peer_active(peer->connection)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN)) BGP_EVENT_ADD(connection, TCP_connection_open_w_delay); else @@ -762,7 +774,11 @@ static int bgp_update_source(struct peer_connection *connection) } /* BGP try to connect to the peer. */ +<<<<<<< HEAD int bgp_connect(struct peer_connection *connection) +======= +enum connect_result bgp_connect(struct peer_connection *connection) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct peer *peer = connection->peer; @@ -773,7 +789,11 @@ int bgp_connect(struct peer_connection *connection) if (peer->conf_if && BGP_CONNECTION_SU_UNSPEC(connection)) { if (bgp_debug_neighbor_events(peer)) zlog_debug("Peer address not learnt: Returning from connect"); +<<<<<<< HEAD return 0; +======= + return connect_error; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } frr_with_privs(&bgpd_privs) { /* Make socket for the peer. */ @@ -787,7 +807,11 @@ int bgp_connect(struct peer_connection *connection) zlog_debug("%s: Failure to create socket for connection to %s, error received: %s(%d)", __func__, peer->host, safe_strerror(errno), errno); +<<<<<<< HEAD return -1; +======= + return connect_error; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } set_nonblocking(connection->fd); @@ -808,7 +832,11 @@ int bgp_connect(struct peer_connection *connection) __func__, peer->host, safe_strerror(errno), errno); +<<<<<<< HEAD return -1; +======= + return connect_error; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } sockopt_reuseaddr(connection->fd); @@ -844,7 +872,11 @@ int bgp_connect(struct peer_connection *connection) /* If the peer is passive mode, force to move to Active mode. */ if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) { BGP_EVENT_ADD(connection, TCP_connection_open_failed); +<<<<<<< HEAD return BGP_FSM_SUCCESS; +======= + return connect_error; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (peer->conf_if || peer->ifname) @@ -861,7 +893,11 @@ int bgp_connect(struct peer_connection *connection) htons(peer->port), ifindex); } +<<<<<<< HEAD void bgp_updatesockname(struct peer *peer) +======= +void bgp_updatesockname(struct peer *peer, struct peer_connection *connection) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { if (peer->su_local) { sockunion_free(peer->su_local); @@ -873,6 +909,7 @@ void bgp_updatesockname(struct peer *peer) peer->su_remote = NULL; } +<<<<<<< HEAD peer->su_local = sockunion_getsockname(peer->connection->fd); peer->su_remote = sockunion_getpeername(peer->connection->fd); } @@ -881,6 +918,18 @@ void bgp_updatesockname(struct peer *peer) int bgp_getsockname(struct peer *peer) { bgp_updatesockname(peer); +======= + peer->su_local = sockunion_getsockname(connection->fd); + peer->su_remote = sockunion_getpeername(connection->fd); +} + +/* After TCP connection is established. Get local address and port. */ +int bgp_getsockname(struct peer_connection *connection) +{ + struct peer *peer = connection->peer; + + bgp_updatesockname(peer, peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!bgp_zebra_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop, peer)) { diff --git a/bgpd/bgp_network.h b/bgpd/bgp_network.h index ceb6b6f002e3..780be4ded78d 100644 --- a/bgpd/bgp_network.h +++ b/bgpd/bgp_network.h @@ -21,9 +21,15 @@ extern int bgp_socket(struct bgp *bgp, unsigned short port, const char *address); extern void bgp_close_vrf_socket(struct bgp *bgp); extern void bgp_close(void); +<<<<<<< HEAD extern int bgp_connect(struct peer_connection *connection); extern int bgp_getsockname(struct peer *peer); extern void bgp_updatesockname(struct peer *peer); +======= +extern enum connect_result bgp_connect(struct peer_connection *connection); +extern int bgp_getsockname(struct peer_connection *connection); +extern void bgp_updatesockname(struct peer *peer, struct peer_connection *connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p, const char *password); diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index ba6d70710917..df05a99536dc 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -32,6 +32,10 @@ #include "bgpd/bgp_vty.h" #include "bgpd/bgp_rd.h" #include "bgpd/bgp_mplsvpn.h" +<<<<<<< HEAD +======= +#include "bgpd/bgp_bfd.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFINE_MTYPE_STATIC(BGPD, MARTIAN_STRING, "BGP Martian Addr Intf String"); @@ -409,6 +413,7 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc) bgp_dest_set_bgp_connected_ref_info(dest, bc); } +<<<<<<< HEAD for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { if (peer->conf_if && (strcmp(peer->conf_if, ifc->ifp->name) == 0) && @@ -420,6 +425,8 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc) BGP_EVENT_ADD(connection, BGP_Start); } } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else if (addr->family == AF_INET6) { apply_mask_ipv6((struct prefix_ipv6 *)&p); @@ -443,6 +450,25 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc) bgp_dest_set_bgp_connected_ref_info(dest, bc); } } +<<<<<<< HEAD +======= + + /* + * Iterate over all the peers and attempt to set the bfd session + * data and if it's a bgp unnumbered get her flowing if necessary + */ + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + bgp_peer_bfd_update_source(peer); + if (peer->conf_if && (strcmp(peer->conf_if, ifc->ifp->name) == 0) && + !peer_established(peer->connection) && + !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) { + connection = peer->connection; + if (peer_active(connection)) + BGP_EVENT_ADD(connection, BGP_Stop); + BGP_EVENT_ADD(connection, BGP_Start); + } + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } void bgp_connected_delete(struct bgp *bgp, struct connected *ifc) @@ -528,6 +554,7 @@ bool bgp_nexthop_self(struct bgp *bgp, afi_t afi, uint8_t type, tmp_addr.p.prefixlen = p->prefixlen; } else { /* Here we need to find out which nexthop to be used*/ +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) { tmp_addr.p.u.prefix4 = attr->nexthop; tmp_addr.p.prefixlen = IPV4_MAX_BITLEN; @@ -536,6 +563,14 @@ bool bgp_nexthop_self(struct bgp *bgp, afi_t afi, uint8_t type, == BGP_ATTR_NHLEN_IPV4) || (attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV4))) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))) { + tmp_addr.p.u.prefix4 = attr->nexthop; + tmp_addr.p.prefixlen = IPV4_MAX_BITLEN; + } else if ((attr->mp_nexthop_len) && + ((attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4) || + (attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV4))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tmp_addr.p.u.prefix4 = attr->mp_nexthop_global_in; tmp_addr.p.prefixlen = IPV4_MAX_BITLEN; @@ -564,11 +599,19 @@ bool bgp_nexthop_self(struct bgp *bgp, afi_t afi, uint8_t type, memset(&tmp_tip, 0, sizeof(tmp_tip)); tmp_tip.addr = attr->nexthop; +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) { tmp_tip.addr = attr->nexthop; } else if ((attr->mp_nexthop_len) && ((attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4) || (attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV4))) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))) { + tmp_tip.addr = attr->nexthop; + } else if ((attr->mp_nexthop_len) && + ((attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4) || + (attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV4))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tmp_tip.addr = attr->mp_nexthop_global_in; } @@ -1379,6 +1422,7 @@ char *bgp_nexthop_dump_bnc_change_flags(struct bgp_nexthop_cache *bnc, return buf; } +<<<<<<< HEAD snprintfrr(buf, len, "%s%s%s", CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED) ? "Changed " @@ -1389,6 +1433,11 @@ char *bgp_nexthop_dump_bnc_change_flags(struct bgp_nexthop_cache *bnc, CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CONNECTED_CHANGED) ? "Connected " : ""); +======= + snprintfrr(buf, len, "%s%s", + CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED) ? "Changed " : "", + CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED) ? "Metric " : ""); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return buf; } diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h index 5014eb8f3455..9fda23dfb4bb 100644 --- a/bgpd/bgp_nexthop.h +++ b/bgpd/bgp_nexthop.h @@ -45,11 +45,18 @@ struct bgp_nexthop_cache { */ bool is_evpn_gwip_nexthop; +<<<<<<< HEAD uint16_t change_flags; #define BGP_NEXTHOP_CHANGED (1 << 0) #define BGP_NEXTHOP_METRIC_CHANGED (1 << 1) #define BGP_NEXTHOP_CONNECTED_CHANGED (1 << 2) #define BGP_NEXTHOP_MACIP_CHANGED (1 << 3) +======= + uint8_t change_flags; +#define BGP_NEXTHOP_CHANGED (1 << 0) +#define BGP_NEXTHOP_METRIC_CHANGED (1 << 1) +#define BGP_NEXTHOP_MACIP_CHANGED (1 << 2) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct nexthop *nexthop; time_t last_update; diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 9b633b7139b2..d1d3fb118bba 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -1066,9 +1066,22 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) case AFI_IP6: p->family = AF_INET6; if (pi->attr->srv6_l3vpn) { +<<<<<<< HEAD IPV6_ADDR_COPY(&(p->u.prefix6), &(pi->attr->srv6_l3vpn->sid)); p->prefixlen = IPV6_MAX_BITLEN; +======= + p->prefixlen = IPV6_MAX_BITLEN; + if (pi->attr->srv6_l3vpn->transposition_len != 0 && + BGP_PATH_INFO_NUM_LABELS(pi)) { + IPV6_ADDR_COPY(&p->u.prefix6, &pi->attr->srv6_l3vpn->sid); + transpose_sid(&p->u.prefix6, + decode_label(&pi->extra->labels->label[0]), + pi->attr->srv6_l3vpn->transposition_offset, + pi->attr->srv6_l3vpn->transposition_len); + } else + IPV6_ADDR_COPY(&(p->u.prefix6), &(pi->attr->srv6_l3vpn->sid)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else if (is_bgp_static) { p->u.prefix6 = p_orig->u.prefix6; p->prefixlen = p_orig->prefixlen; diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 62be7ffbf733..de7156045a54 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -122,6 +122,7 @@ static void bgp_packet_add(struct peer_connection *connection, peer->last_sendq_ok = monotime(NULL); stream_fifo_push(connection->obuf, s); +<<<<<<< HEAD delta = monotime(NULL) - peer->last_sendq_ok; @@ -158,6 +159,40 @@ static void bgp_packet_add(struct peer_connection *connection, peer, holdtime); peer->last_sendq_warn = monotime(NULL); } +======= + } + + delta = monotime(NULL) - peer->last_sendq_ok; + + if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) + holdtime = atomic_load_explicit(&peer->holdtime, memory_order_relaxed); + else + holdtime = peer->bgp->default_holdtime; + + sendholdtime = holdtime * 2; + + /* Note that when we're here, we're adding some packet to the + * OutQ. That includes keepalives when there is nothing to + * do, so there's a guarantee we pass by here once in a while. + * + * That implies there is no need to go set up another separate + * timer that ticks down SendHoldTime, as we'll be here sooner + * or later anyway and will see the checks below failing. + */ + if (!holdtime) { + /* no holdtime, do nothing. */ + } else if (delta > sendholdtime) { + flog_err(EC_BGP_SENDQ_STUCK_PROPER, + "%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session", + peer, sendholdtime); + event_add_event(bm->master, bgp_event_stop_with_notify, connection, 0, + &connection->t_stop_with_notify); + } else if (delta > (intmax_t)holdtime && monotime(NULL) - peer->last_sendq_warn > 5) { + flog_warn(EC_BGP_SENDQ_STUCK_WARN, + "%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?", + peer, holdtime); + peer->last_sendq_warn = monotime(NULL); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -641,6 +676,7 @@ void bgp_keepalive_send(struct peer *peer) bgp_writes_on(peer->connection); } +<<<<<<< HEAD /* * Creates a BGP Open packet and appends it to the peer's output queue. * Sets capabilities as necessary. @@ -666,6 +702,13 @@ void bgp_open_send(struct peer_connection *connection) s = stream_new(BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE); +======= +struct stream *bgp_open_make(struct peer *peer, uint16_t send_holdtime, as_t local_as) +{ + struct stream *s = stream_new(BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE); + bool ext_opt_params = false; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Make open packet. */ bgp_packet_set_marker(s, BGP_MSG_OPEN); @@ -704,6 +747,36 @@ void bgp_open_send(struct peer_connection *connection) ext_opt_params ? " (Extended)" : "", BGP_VERSION_4, local_as, send_holdtime, &peer->local_id); +<<<<<<< HEAD +======= + return s; +} + +/* + * Creates a BGP Open packet and appends it to the peer's output queue. + * Sets capabilities as necessary. + */ +void bgp_open_send(struct peer_connection *connection) +{ + struct stream *s; + uint16_t send_holdtime; + as_t local_as; + struct peer *peer = connection->peer; + + if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) + send_holdtime = peer->holdtime; + else + send_holdtime = peer->bgp->default_holdtime; + + /* local-as Change */ + if (peer->change_local_as) + local_as = peer->change_local_as; + else + local_as = peer->local_as; + + s = bgp_open_make(peer, send_holdtime, local_as); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Dump packet if debug option is set. */ /* bgp_packet_dump (s); */ hook_call(bgp_packet_send, peer, BGP_MSG_OPEN, stream_get_endp(s), s); @@ -2051,7 +2124,11 @@ static int bgp_open_receive(struct peer_connection *connection, return BGP_Stop; /* Get sockname. */ +<<<<<<< HEAD if (bgp_getsockname(peer) < 0) { +======= + if (bgp_getsockname(connection) < 0) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) flog_err_sys(EC_LIB_SOCKET, "%s: bgp_getsockname() failed for peer: %s", __func__, peer->host); @@ -2311,7 +2388,11 @@ static int bgp_update_receive(struct peer_connection *connection, attr.label = MPLS_INVALID_LABEL; memset(&nlris, 0, sizeof(nlris)); memset(peer->rcvd_attr_str, 0, BUFSIZ); +<<<<<<< HEAD peer->rcvd_attr_printed = 0; +======= + peer->rcvd_attr_printed = false; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) s = peer->curr; end = stream_pnt(s) + size; @@ -2419,7 +2500,11 @@ static int bgp_update_receive(struct peer_connection *connection, BGP_DEBUG(update, UPDATE_DETAIL)) { zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer, peer->rcvd_attr_str); +<<<<<<< HEAD peer->rcvd_attr_printed = 1; +======= + peer->rcvd_attr_printed = true; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -2935,6 +3020,7 @@ static int bgp_route_refresh_receive(struct peer_connection *connection, if (bgp_debug_neighbor_events(peer)) { char buf[INET6_BUFSIZ]; +<<<<<<< HEAD zlog_debug( "%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s", peer, @@ -2964,6 +3050,33 @@ static int bgp_route_refresh_receive(struct peer_connection *connection, (common & ORF_COMMON_PART_REMOVE ? 0 : 1)); +======= + zlog_debug("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s", + peer, + (CHECK_FLAG(common, ORF_COMMON_PART_REMOVE) + ? "Remove" + : "Add"), + (CHECK_FLAG(common, ORF_COMMON_PART_DENY) + ? "deny" + : "permit"), + orfp.seq, + inet_ntop(orfp.p.family, &orfp.p.u.prefix, + buf, INET6_BUFSIZ), + orfp.p.prefixlen, orfp.ge, orfp.le, + ok ? "" : " MALFORMED"); + } + + if (ok) + ret = prefix_bgp_orf_set(name, afi, &orfp, + (CHECK_FLAG(common, + ORF_COMMON_PART_DENY) + ? 0 + : 1), + (CHECK_FLAG(common, + ORF_COMMON_PART_REMOVE) + ? 0 + : 1)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!ok || (ok && ret != CMD_SUCCESS)) { zlog_info( @@ -3190,6 +3303,7 @@ static void bgp_dynamic_capability_addpath(uint8_t *pnt, int action, if (bgp_debug_neighbor_events(peer)) zlog_debug("%s OPEN has %s capability for afi/safi: %s/%s%s%s", +<<<<<<< HEAD peer->host, lookup_msg(capcode_str, hdr->code, NULL), @@ -3201,6 +3315,13 @@ static void bgp_dynamic_capability_addpath(uint8_t *pnt, int action, (bac.flags & BGP_ADDPATH_TX) ? ", transmit" : ""); +======= + peer->host, lookup_msg(capcode_str, hdr->code, NULL), + iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), + CHECK_FLAG(bac.flags, BGP_ADDPATH_RX) ? ", receive" : "", + CHECK_FLAG(bac.flags, BGP_ADDPATH_TX) ? ", transmit" + : ""); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) { diff --git a/bgpd/bgp_packet.h b/bgpd/bgp_packet.h index b67acf205593..6eab9e217b95 100644 --- a/bgpd/bgp_packet.h +++ b/bgpd/bgp_packet.h @@ -43,6 +43,10 @@ DECLARE_HOOK(bgp_packet_send, /* Packet send and receive function prototypes. */ extern void bgp_keepalive_send(struct peer *peer); +<<<<<<< HEAD +======= +extern struct stream *bgp_open_make(struct peer *peer, uint16_t send_holdtime, as_t local_as); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern void bgp_open_send(struct peer_connection *connection); extern void bgp_notify_send(struct peer_connection *connection, uint8_t code, uint8_t sub_code); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 9cadf61c4da7..6ae33951f4d0 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -648,7 +648,11 @@ static bool use_bgp_med_value(struct attr *attr, struct bgp *bgp) missing-as-worst" is specified, treat it as the worst value. */ static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp) { +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return attr->med; else { if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST)) @@ -745,6 +749,11 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, struct bgp_path_info *bpi_ultimate; struct peer *peer_new, *peer_exist; +<<<<<<< HEAD +======= + bgp->bestpath_runs++; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) *paths_eq = 0; /* 0. Null check. */ @@ -996,9 +1005,15 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, /* 2. Local preference check. */ new_pref = exist_pref = bgp->default_local_pref; +<<<<<<< HEAD if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) new_pref = newattr->local_pref; if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) +======= + if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) + new_pref = newattr->local_pref; + if (CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) exist_pref = existattr->local_pref; if (new_pref > exist_pref) { @@ -1038,10 +1053,17 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, bool exist_accept_own = false; uint32_t accept_own = COMMUNITY_ACCEPT_OWN; +<<<<<<< HEAD if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) new_accept_own = community_include( bgp_attr_get_community(newattr), accept_own); if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) +======= + if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) + new_accept_own = community_include( + bgp_attr_get_community(newattr), accept_own); + if (CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) exist_accept_own = community_include( bgp_attr_get_community(existattr), accept_own); @@ -1130,9 +1152,15 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, /* 4. AS path length check. */ if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) { int exist_hops = aspath_count_hops(existattr->aspath); +<<<<<<< HEAD int exist_confeds = aspath_count_confeds(existattr->aspath); if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) { +======= + + if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) { + int exist_confeds = aspath_count_confeds(existattr->aspath); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int aspath_hops; aspath_hops = aspath_count_hops(newattr->aspath); @@ -1497,11 +1525,19 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, * be 0 and would always win over the other path. If originator id is * used for the comparison, it will decide which path is better. */ +<<<<<<< HEAD if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) new_id.s_addr = newattr->originator_id.s_addr; else new_id.s_addr = peer_new->remote_id.s_addr; if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) +======= + if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) + new_id.s_addr = newattr->originator_id.s_addr; + else + new_id.s_addr = peer_new->remote_id.s_addr; + if (CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) exist_id.s_addr = existattr->originator_id.s_addr; else exist_id.s_addr = peer_exist->remote_id.s_addr; @@ -1797,7 +1833,11 @@ static bool bgp_cluster_filter(struct peer *peer, struct attr *attr) struct cluster_list *cluster = bgp_attr_get_cluster(attr); if (cluster) { +<<<<<<< HEAD if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID) +======= + if (CHECK_FLAG(peer->bgp->config, BGP_CONFIG_CLUSTER_ID)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) cluster_id = peer->bgp->cluster_id; else cluster_id = peer->bgp->router_id; @@ -1810,7 +1850,11 @@ static bool bgp_cluster_filter(struct peer *peer, struct attr *attr) static bool bgp_otc_filter(struct peer *peer, struct attr *attr) { +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (peer->local_role == ROLE_PROVIDER || peer->local_role == ROLE_RS_SERVER) return true; @@ -1821,7 +1865,11 @@ static bool bgp_otc_filter(struct peer *peer, struct attr *attr) if (peer->local_role == ROLE_CUSTOMER || peer->local_role == ROLE_PEER || peer->local_role == ROLE_RS_CLIENT) { +<<<<<<< HEAD attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC); +======= + SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) attr->otc = peer->as; } return false; @@ -1829,7 +1877,11 @@ static bool bgp_otc_filter(struct peer *peer, struct attr *attr) static bool bgp_otc_egress(struct peer *peer, struct attr *attr) { +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (peer->local_role == ROLE_CUSTOMER || peer->local_role == ROLE_RS_CLIENT || peer->local_role == ROLE_PEER) @@ -1839,7 +1891,11 @@ static bool bgp_otc_egress(struct peer *peer, struct attr *attr) if (peer->local_role == ROLE_PROVIDER || peer->local_role == ROLE_PEER || peer->local_role == ROLE_RS_SERVER) { +<<<<<<< HEAD attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC); +======= + SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) attr->otc = peer->bgp->as; } return false; @@ -2096,7 +2152,11 @@ void bgp_attr_add_gshut_community(struct attr *attr) /* When we add the graceful-shutdown community we must also * lower the local-preference */ +<<<<<<< HEAD attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); +======= + SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) attr->local_pref = BGP_GSHUT_LOCAL_PREF; } @@ -2144,7 +2204,11 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct attr *piattr; route_map_result_t ret; int transparent; +<<<<<<< HEAD int reflect; +======= + int ibgp_to_ibgp; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) afi_t afi; safi_t safi; int samepeer_safe = 0; /* for synthetic mplsvpns routes */ @@ -2300,8 +2364,13 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, /* If the attribute has originator-id and it is same as remote peer's id. */ +<<<<<<< HEAD if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID) && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) { +======= + if (onlypeer && (CHECK_FLAG(piattr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) && + (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) zlog_debug( "%pBP [Update:SEND] %pFX originator-id is same as remote router-id", @@ -2324,6 +2393,30 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, } } +<<<<<<< HEAD +======= + /* RFC 8212 to prevent route leaks. + * This specification intends to improve this situation by requiring the + * explicit configuration of both BGP Import and Export Policies for any + * External BGP (EBGP) session such as customers, peers, or + * confederation boundaries for all enabled address families. Through + * codification of the aforementioned requirement, operators will + * benefit from consistent behavior across different BGP + * implementations. + */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY)) + if (!bgp_outbound_policy_exists(peer, filter)) { + if (monotime_since(&bgp->ebgprequirespolicywarning, NULL) > + FIFTEENMINUTE2USEC || + bgp->ebgprequirespolicywarning.tv_sec == 0) { + zlog_warn("%pBP [Update:SEND] %pFX EBGP outbound policy not properly setup, please configure in order for your peering to work correctly", + peer, p); + monotime(&bgp->ebgprequirespolicywarning); + } + return false; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Output filter check. */ if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) { if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) @@ -2353,6 +2446,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, } } +<<<<<<< HEAD /* Route-Reflect check. */ if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP) reflect = 1; @@ -2361,6 +2455,16 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, /* IBGP reflection check. */ if (reflect && !samepeer_safe) { +======= + /* iBGP to iBGP check. */ + if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP) + ibgp_to_ibgp = 1; + else + ibgp_to_ibgp = 0; + + /* IBGP reflection check. */ + if (ibgp_to_ibgp && !samepeer_safe) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* A route from a Client peer. */ if (CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)) { @@ -2398,16 +2502,26 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, RESET_FLAG(attr->rmap_change_flags); /* If local-preference is not set. */ +<<<<<<< HEAD if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) { attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); +======= + if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) && + (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) { + SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) attr->local_pref = bgp->default_local_pref; } /* If originator-id is not set and the route is to be reflected, set the originator id */ +<<<<<<< HEAD if (reflect && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) { +======= + if (ibgp_to_ibgp && (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id)); SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID); } @@ -2415,12 +2529,20 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, /* Remove MED if its an EBGP peer - will get overwritten by route-maps */ if (peer->sort == BGP_PEER_EBGP && peer->sub_sort != BGP_PEER_EBGP_OAD && +<<<<<<< HEAD attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) { if (from != bgp->peer_self && !transparent && !CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) attr->flag &= ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)); +======= + CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { + if (from != bgp->peer_self && !transparent + && !CHECK_FLAG(peer->af_flags[afi][safi], + PEER_FLAG_MED_UNCHANGED)) + UNSET_FLAG(attr->flag, (ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Since the nexthop attribute can vary per peer, it is not explicitly @@ -2440,7 +2562,11 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, * announced to an EBGP peer (and they have the same attributes barring * their nexthop). */ +<<<<<<< HEAD if (reflect) +======= + if (ibgp_to_ibgp) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED); #define NEXTHOP_IS_V6 \ @@ -2468,7 +2594,12 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, */ if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local)) global_and_ll = true; +<<<<<<< HEAD } else if (!reflect && !transparent && +======= + } else if (!ibgp_to_ibgp && !transparent && + !CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT) && +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local) && peer->shared_network && (from == bgp->peer_self || peer->sort == BGP_PEER_EBGP)) global_and_ll = true; @@ -2508,8 +2639,13 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct attr dummy_attr = *attr; /* Fill temp path_info */ +<<<<<<< HEAD prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest, pi, peer, &dummy_attr); +======= + prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest, pi, peer, NULL, + &dummy_attr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct route_map *amap = route_map_lookup_by_name(filter->advmap.aname); @@ -2533,9 +2669,19 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct bgp_path_info_extra dummy_rmap_path_extra = {0}; struct attr dummy_attr = {0}; +<<<<<<< HEAD /* Fill temp path_info */ prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest, pi, peer, attr); +======= + /* Fill temp path_info. + * Inject the peer structure of the source peer (from). + * This is useful for e.g. `match peer ...` in outgoing + * direction. + */ + prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest, pi, peer, from, attr); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * The route reflector is not allowed to modify the attributes * of the reflected IBGP routes unless explicitly allowed. @@ -2575,6 +2721,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, bgp_peer_remove_private_as(bgp, afi, safi, peer, attr); bgp_peer_as_override(bgp, afi, safi, peer, attr); +<<<<<<< HEAD /* RFC 8212 to prevent route leaks. * This specification intends to improve this situation by requiring the * explicit configuration of both BGP Import and Export Policies for any @@ -2596,6 +2743,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, return false; } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* draft-ietf-idr-deprecate-as-set-confed-set * Filter routes having AS_SET or AS_CONFED_SET in the path. * Eventually, This document (if approved) updates RFC 4271 @@ -2611,8 +2760,12 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, * one. If they match, do not announce, to prevent routing * loops. */ +<<<<<<< HEAD if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) && peer->soo[afi][safi]) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) && peer->soo[afi][safi]) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct ecommunity *ecomm_soo = peer->soo[afi][safi]; struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr); @@ -2639,7 +2792,11 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED || peer->sub_sort == BGP_PEER_EBGP_OAD) { +<<<<<<< HEAD attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); +======= + SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) attr->local_pref = BGP_GSHUT_LOCAL_PREF; } else { bgp_attr_add_gshut_community(attr); @@ -2690,9 +2847,14 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, PEER_FLAG_NEXTHOP_SELF) || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF)) { +<<<<<<< HEAD if (!reflect || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF)) { +======= + if (!ibgp_to_ibgp || + CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) subgroup_announce_reset_nhop( (peer_cap_enhe(peer, afi, safi) ? AF_INET6 @@ -2831,6 +2993,53 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, } } +<<<<<<< HEAD +======= + /* Extended communities can be transitive and non-transitive. + * If the extended community is non-transitive, strip it off, + * unless it's a locally originated route (static, aggregate, + * redistributed, etc.). + */ + if (from->sort == BGP_PEER_EBGP && peer->sort == BGP_PEER_EBGP && + pi->sub_type == BGP_ROUTE_NORMAL) { + struct ecommunity *new_ecomm; + struct ecommunity *old_ecomm; + + old_ecomm = bgp_attr_get_ecommunity(attr); + if (old_ecomm) { + new_ecomm = ecommunity_dup(old_ecomm); + if (ecommunity_strip_non_transitive(new_ecomm)) { + bgp_attr_set_ecommunity(attr, new_ecomm); + if (!old_ecomm->refcnt) + ecommunity_free(&old_ecomm); + if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) + zlog_debug("%pBP: %pFX stripped non-transitive extended communities", + peer, p); + } else { + ecommunity_free(&new_ecomm); + } + } + + /* Extended link-bandwidth communities are encoded as IPv6 + * address-specific extended communities. + */ + old_ecomm = bgp_attr_get_ipv6_ecommunity(attr); + if (old_ecomm) { + new_ecomm = ecommunity_dup(old_ecomm); + if (ecommunity_strip_non_transitive(new_ecomm)) { + bgp_attr_set_ipv6_ecommunity(attr, new_ecomm); + if (!old_ecomm->refcnt) + ecommunity_free(&old_ecomm); + if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) + zlog_debug("%pBP: %pFX stripped non-transitive ipv6 extended communities", + peer, p); + } else { + ecommunity_free(&new_ecomm); + } + } + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return true; } @@ -3153,6 +3362,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, struct bgp_path_info *end = bgp_dest_get_bgp_path_info(dest); +<<<<<<< HEAD for (; end && end->next != NULL; end = end->next) ; @@ -3162,6 +3372,25 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, bgp_dest_set_bgp_path_info(dest, first); first->prev = end; first->next = NULL; +======= + if (end && any_comparisons) { + for (; end && end->next != NULL; end = end->next) + ; + + if (end) + end->next = first; + else + bgp_dest_set_bgp_path_info(dest, first); + first->prev = end; + first->next = NULL; + } else { + bgp_dest_set_bgp_path_info(dest, first); + if (end) + end->prev = first; + first->next = end; + first->prev = NULL; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) dest->reason = first->reason; } else { @@ -3438,9 +3667,14 @@ static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi, dummy_attr = *new_select->attr; /* Fill temp path_info */ +<<<<<<< HEAD prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest, new_select, new_select->peer, &dummy_attr); +======= + prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest, new_select, + new_select->peer, NULL, &dummy_attr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) RESET_FLAG(dummy_attr.rmap_change_flags); @@ -3738,11 +3972,18 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, /* If there is a change of interest to peers, reannounce the * route. */ +<<<<<<< HEAD if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED) || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG) || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) { group_announce_route(bgp, afi, safi, dest, new_select); +======= + if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED) || + CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED) || + bgp_zebra_has_route_changed(old_select)) { + group_announce_route(bgp, afi, safi, dest, new_select); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* unicast routes must also be annouced to * labeled-unicast update-groups */ if (safi == SAFI_UNICAST) @@ -4068,8 +4309,15 @@ static void bgp_process_internal(struct bgp *bgp, struct bgp_dest *dest, } /* already scheduled for processing? */ +<<<<<<< HEAD if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) return; +======= + if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) { + bgp->node_already_on_queue++; + return; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to * the workqueue @@ -4078,6 +4326,10 @@ static void bgp_process_internal(struct bgp *bgp, struct bgp_dest *dest, if (BGP_DEBUG(update, UPDATE_OUT)) zlog_debug("BGP_NODE_SELECT_DEFER set for route %p", dest); +<<<<<<< HEAD +======= + bgp->node_deferred_on_queue++; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -4332,12 +4584,18 @@ void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi, bgp_process(peer->bgp, dest, pi, afi, safi); } +<<<<<<< HEAD static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi, struct peer *peer, afi_t afi, safi_t safi, struct prefix_rd *prd) { const struct prefix *p = bgp_dest_get_prefix(dest); +======= +static void bgp_rib_withdraw(const struct prefix *p, struct bgp_dest *dest, struct bgp_path_info *pi, + struct peer *peer, afi_t afi, safi_t safi, struct prefix_rd *prd) +{ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* apply dampening, if result is suppressed, we'll be retaining * the bgp_path_info in the RIB for historical reference. */ @@ -4523,7 +4781,11 @@ static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi, return false; /* The route in question carries the ACCEPT_OWN community */ +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct community *comm = bgp_attr_get_community(attr); if (community_include(comm, COMMUNITY_ACCEPT_OWN)) @@ -4561,6 +4823,63 @@ static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi, return false; } +<<<<<<< HEAD +======= +static inline void +bgp_update_nexthop_reachability_check(struct bgp *bgp, struct peer *peer, struct bgp_dest *dest, + const struct prefix *p, afi_t afi, safi_t safi, + struct bgp_path_info *pi, struct attr *attr_new, + const struct prefix *bgp_nht_param_prefix, bool accept_own) +{ + bool connected; + afi_t nh_afi; + + if (((afi == AFI_IP || afi == AFI_IP6) && + (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || + (safi == SAFI_MPLS_VPN && pi->sub_type != BGP_ROUTE_IMPORTED))) || + (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) { + if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP && + peer->ttl == BGP_DEFAULT_TTL && + !CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK) && + !CHECK_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) + connected = true; + else + connected = false; + + struct bgp *bgp_nexthop = bgp; + + if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig) + bgp_nexthop = pi->extra->vrfleak->bgp_orig; + + nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr); + + if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi, safi, pi, NULL, connected, + bgp_nht_param_prefix) || + CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) { + if (accept_own) + bgp_path_info_set_flag(dest, pi, BGP_PATH_ACCEPT_OWN); + + bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); + } else { + if (BGP_DEBUG(nht, NHT)) { + zlog_debug("%s(%pI4): NH unresolved for existing %pFX pi %p flags 0x%x", + __func__, (in_addr_t *)&attr_new->nexthop, p, pi, + pi->flags); + } + bgp_path_info_unset_flag(dest, pi, BGP_PATH_VALID); + } + } else { + /* case mpls-vpn routes with accept-own community + * (which have the BGP_ROUTE_IMPORTED subtype) + * case other afi/safi not supporting nexthop tracking + */ + if (accept_own) + bgp_path_info_set_flag(dest, pi, BGP_PATH_ACCEPT_OWN); + bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); + } +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, int sub_type, struct prefix_rd *prd, mpls_label_t *label, @@ -4568,7 +4887,10 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct bgp_route_evpn *evpn) { int ret; +<<<<<<< HEAD int aspath_loop_count = 0; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct bgp_dest *dest; struct bgp *bgp; struct attr new_attr = {}; @@ -4577,12 +4899,17 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct bgp_path_info *new = NULL; const char *reason; char pfx_buf[BGP_PRD_PATH_STRLEN]; +<<<<<<< HEAD int connected = 0; int do_loop_check = 1; afi_t nh_afi; bool force_evpn_import = false; safi_t orig_safi = safi; int allowas_in = 0; +======= + bool force_evpn_import = false; + safi_t orig_safi = safi; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct bgp_labels bgp_labels = {}; uint8_t i; @@ -4607,11 +4934,20 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp = peer->bgp; dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); +<<<<<<< HEAD if ((afi == AFI_L2VPN && safi == SAFI_EVPN) || bgp_is_valid_label(&label[0])) bgp_labels.num_labels = num_labels; for (i = 0; i < bgp_labels.num_labels; i++) bgp_labels.label[i] = label[i]; +======= + if (num_labels && + ((afi == AFI_L2VPN && safi == SAFI_EVPN) || bgp_is_valid_label(&label[0]))) { + bgp_labels.num_labels = num_labels; + for (i = 0; i < bgp_labels.num_labels; i++) + bgp_labels.label[i] = label[i]; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* When peer's soft reconfiguration enabled. Record input packet in Adj-RIBs-In. */ @@ -4624,6 +4960,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * will not be interned. In which case, it is ok to update the * attr->evpn_overlay, so that, this can be stored in adj_in. */ +<<<<<<< HEAD if ((afi == AFI_L2VPN) && evpn) bgp_attr_set_evpn_overlay(attr, evpn); else @@ -4635,6 +4972,17 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) allowas_in = peer->allowas_in[afi][safi]; +======= + if (evpn) { + if (afi == AFI_L2VPN) + bgp_attr_set_evpn_overlay(attr, evpn); + else + evpn_overlay_free(evpn); + } + bgp_adj_in_set(dest, peer, attr, addpath_id, &bgp_labels); + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Check previously received route. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (pi->peer == peer && pi->type == type @@ -4644,8 +4992,16 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* AS path local-as loop check. */ if (peer->change_local_as) { +<<<<<<< HEAD if (allowas_in) aspath_loop_count = allowas_in; +======= + int32_t aspath_loop_count = 0; + + /* Update permitted loop count */ + if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) + aspath_loop_count = peer->allowas_in[afi][safi]; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) else if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) aspath_loop_count = 1; @@ -4658,6 +5014,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } +<<<<<<< HEAD /* If the peer is configured for "allowas-in origin" and the last ASN in * the * as-path is our ASN then we do not need to call aspath_loop_check @@ -4666,6 +5023,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (aspath_get_last_as(attr->aspath) == bgp->as) do_loop_check = 0; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* When using bgp ipv4 labeled session, the local prefix is * received by a peer, and finds out that the proposed prefix * and its next-hop are the same. To avoid a route loop locally, @@ -4686,14 +5045,25 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, else bgp_nht_param_prefix = p; +<<<<<<< HEAD /* AS path loop check. */ if (do_loop_check) { +======= + /* + * If the peer is configured for "allowas-in origin" and the last ASN in + * the as-path is our ASN then we do not need to call aspath_loop_check + */ + if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN) || + (aspath_get_last_as(attr->aspath) != bgp->as)) { + /* AS path loop check. */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (aspath_loop_check(attr->aspath, bgp->as) > peer->allowas_in[afi][safi]) { peer->stat_pfx_aspath_loop++; reason = "as-path contains our own AS;"; goto filtered; } +<<<<<<< HEAD } /* If we're a CONFED we need to loop check the CONFED ID too */ @@ -4704,14 +5074,32 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, reason = "as-path contains our own confed AS;"; goto filtered; } +======= + + /* If we're a CONFED we need to loop check the CONFED ID too */ + if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) { + if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) > + peer->allowas_in[afi][safi]) { + peer->stat_pfx_aspath_loop++; + reason = "as-path contains our own confed AS;"; + goto filtered; + } + } + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Route reflector originator ID check. If ACCEPT_OWN mechanism is * enabled, then take care of that too. */ bool accept_own = false; +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID) && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) && + IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) accept_own = bgp_accept_own(peer, afi, safi, attr, p, &sub_type); if (!accept_own) { @@ -4728,6 +5116,31 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, goto filtered; } +<<<<<<< HEAD +======= + /* RFC 8212 to prevent route leaks. + * This specification intends to improve this situation by requiring the + * explicit configuration of both BGP Import and Export Policies for any + * External BGP (EBGP) session such as customers, peers, or + * confederation boundaries for all enabled address families. Through + * codification of the aforementioned requirement, operators will + * benefit from consistent behavior across different BGP + * implementations. + */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY)) + if (!bgp_inbound_policy_exists(peer, &peer->filter[afi][safi])) { + reason = "inbound policy missing"; + if (monotime_since(&bgp->ebgprequirespolicywarning, NULL) > + FIFTEENMINUTE2USEC || + bgp->ebgprequirespolicywarning.tv_sec == 0) { + zlog_warn("%pBP rcvd UPDATE EBGP inbound policy not properly setup, please configure in order for your peering to work correctly", + peer); + monotime(&bgp->ebgprequirespolicywarning); + } + goto filtered; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Apply incoming filter. */ if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) { peer->stat_pfx_filter++; @@ -4748,7 +5161,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* If the route has Node Target Extended Communities, check * if it's allowed to be installed locally. */ +<<<<<<< HEAD if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr); if (ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP, @@ -4760,6 +5177,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } +<<<<<<< HEAD /* RFC 8212 to prevent route leaks. * This specification intends to improve this situation by requiring the * explicit configuration of both BGP Import and Export Policies for any @@ -4783,6 +5201,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, goto filtered; } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* draft-ietf-idr-deprecate-as-set-confed-set * Filter routes having AS_SET or AS_CONFED_SET in the path. * Eventually, This document (if approved) updates RFC 4271 @@ -4803,10 +5223,19 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * attr->evpn_overlay with evpn directly. Instead memcpy * evpn to new_atr.evpn_overlay before it is interned. */ +<<<<<<< HEAD if (soft_reconfig && (afi == AFI_L2VPN) && evpn) bgp_attr_set_evpn_overlay(&new_attr, evpn); else evpn_overlay_free(evpn); +======= + if (soft_reconfig && evpn) { + if (afi == AFI_L2VPN) + bgp_attr_set_evpn_overlay(&new_attr, evpn); + else + evpn_overlay_free(evpn); + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Apply incoming route-map. * NB: new_attr may now contain newly allocated values from route-map @@ -4850,7 +5279,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (bgp_attr_get_community(&new_attr) && community_include(bgp_attr_get_community(&new_attr), COMMUNITY_GSHUT)) { +<<<<<<< HEAD new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); +======= + SET_FLAG(new_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) new_attr.local_pref = BGP_GSHUT_LOCAL_PREF; /* If graceful-shutdown is configured globally or @@ -4871,7 +5304,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, goto filtered; } +<<<<<<< HEAD if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) { +======= + if (safi == SAFI_EVPN && (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) peer->stat_pfx_nh_invalid++; reason = "self mac;"; bgp_attr_flush(&new_attr); @@ -4926,7 +5363,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (get_active_bdc_from_pi(pi, afi, safi) && peer->sort == BGP_PEER_EBGP && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) { +<<<<<<< HEAD if (bgp_debug_update(peer, p, NULL, 1)) { +======= + if (unlikely(bgp_debug_update(peer, p, NULL, 1))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, @@ -4944,13 +5385,21 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } else /* Duplicate - odd */ { +<<<<<<< HEAD if (bgp_debug_update(peer, p, NULL, 1)) { +======= + if (unlikely(bgp_debug_update(peer, p, NULL, 1))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!peer->rcvd_attr_printed) { zlog_debug( "%pBP rcvd UPDATE w/ attr: %s", peer, peer->rcvd_attr_str); +<<<<<<< HEAD peer->rcvd_attr_printed = 1; +======= + peer->rcvd_attr_printed = true; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } bgp_debug_rdpfxpath2str( @@ -4980,7 +5429,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Withdraw/Announce before we fully processed the withdraw */ if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) { +<<<<<<< HEAD if (bgp_debug_update(peer, p, NULL, 1)) { +======= + if (unlikely(bgp_debug_update(peer, p, NULL, 1))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, evpn, @@ -5008,7 +5461,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } /* Received Logging. */ +<<<<<<< HEAD if (bgp_debug_update(peer, p, NULL, 1)) { +======= + if (unlikely(bgp_debug_update(peer, p, NULL, 1))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, evpn, pfx_buf, @@ -5071,17 +5528,26 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, */ if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)) && !same_attr) { +<<<<<<< HEAD if ((pi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) && (attr_new->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { +======= + if (CHECK_FLAG(pi->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) && + CHECK_FLAG(attr_new->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int cmp; cmp = ecommunity_cmp( bgp_attr_get_ecommunity(pi->attr), bgp_attr_get_ecommunity(attr_new)); if (!cmp) { +<<<<<<< HEAD if (bgp_debug_update(peer, p, NULL, 1)) +======= + if (unlikely(bgp_debug_update(peer, p, NULL, 1))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug( "Change in EXT-COMM, existing %s new %s", ecommunity_str( @@ -5145,6 +5611,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } +<<<<<<< HEAD /* Nexthop reachability check - for unicast and * labeled-unicast.. */ if (((afi == AFI_IP || afi == AFI_IP6) && @@ -5201,6 +5668,13 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, BGP_PATH_ACCEPT_OWN); bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); } +======= + bgp_update_nexthop_reachability_check(bgp, peer, dest, p, afi, safi, pi, attr_new, + bgp_nht_param_prefix, accept_own); + /* Nexthop reachability check - for unicast and + * labeled-unicast.. */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #ifdef ENABLE_BGP_VNC if (safi == SAFI_MPLS_VPN) { @@ -5242,7 +5716,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * EVPN nexthop is decremented appropriately. */ else if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)) { +<<<<<<< HEAD if (BGP_DEBUG(nht, NHT)) +======= + if (unlikely(BGP_DEBUG(nht, NHT))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s unimport EVPN %pFX as pi %p is not VALID", __func__, p, pi); bgp_evpn_unimport_route(bgp, afi, safi, p, pi); @@ -5282,11 +5760,19 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } // End of implicit withdraw /* Received Logging. */ +<<<<<<< HEAD if (bgp_debug_update(peer, p, NULL, 1)) { if (!peer->rcvd_attr_printed) { zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer, peer->rcvd_attr_str); peer->rcvd_attr_printed = 1; +======= + if (unlikely(bgp_debug_update(peer, p, NULL, 1))) { + if (!peer->rcvd_attr_printed) { + zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer, + peer->rcvd_attr_str); + peer->rcvd_attr_printed = true; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, @@ -5302,6 +5788,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_path_info_extra_get(new); new->extra->labels = bgp_labels_intern(&bgp_labels); +<<<<<<< HEAD /* Nexthop reachability check. */ if (((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || @@ -5344,6 +5831,10 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_path_info_set_flag(dest, new, BGP_PATH_VALID); } +======= + bgp_update_nexthop_reachability_check(bgp, peer, dest, p, afi, safi, new, attr_new, + bgp_nht_param_prefix, accept_own); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* If maximum prefix count is configured and current prefix * count exeed it. */ @@ -5430,7 +5921,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (!peer->rcvd_attr_printed) { zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer, peer->rcvd_attr_str); +<<<<<<< HEAD peer->rcvd_attr_printed = 1; +======= + peer->rcvd_attr_printed = true; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, @@ -5539,7 +6034,11 @@ void bgp_withdraw(struct peer *peer, const struct prefix *p, break; /* Logging. */ +<<<<<<< HEAD if (bgp_debug_update(peer, p, NULL, 1)) { +======= + if (unlikely(bgp_debug_update(peer, p, NULL, 1))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, NULL, pfx_buf, sizeof(pfx_buf)); @@ -5549,11 +6048,16 @@ void bgp_withdraw(struct peer *peer, const struct prefix *p, /* Withdraw specified route from routing table. */ if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) { +<<<<<<< HEAD bgp_rib_withdraw(dest, pi, peer, afi, safi, prd); +======= + bgp_rib_withdraw(p, dest, pi, peer, afi, safi, prd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (SAFI_UNICAST == safi && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) { vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi); +<<<<<<< HEAD } if ((SAFI_MPLS_VPN == safi) && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) { @@ -5561,6 +6065,11 @@ void bgp_withdraw(struct peer *peer, const struct prefix *p, vpn_leak_to_vrf_withdraw(pi); } } else if (bgp_debug_update(peer, p, NULL, 1)) { +======= + } else if ((SAFI_MPLS_VPN == safi) && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) + vpn_leak_to_vrf_withdraw(pi); + } else if (unlikely(bgp_debug_update(peer, p, NULL, 1))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, NULL, pfx_buf, sizeof(pfx_buf)); @@ -6750,19 +7259,32 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP); attr.nexthop = bgp_static->igpnexthop; +<<<<<<< HEAD attr.med = bgp_static->igpmetric; attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +======= + + bgp_attr_set_med(&attr, bgp_static->igpmetric); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (afi == AFI_IP) attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; if (bgp_static->atomic) +<<<<<<< HEAD attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE); +======= + SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Store label index, if required. */ if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) { attr.label_index = bgp_static->label_index; +<<<<<<< HEAD attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID); +======= + SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (safi == SAFI_EVPN || safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) { @@ -8055,8 +8577,12 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, if (BGP_PATH_HOLDDOWN(pi)) continue; +<<<<<<< HEAD if (pi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) +======= + if (CHECK_FLAG(pi->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) atomic_aggregate = 1; if (pi->sub_type == BGP_ROUTE_AGGREGATE) @@ -9015,9 +9541,14 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, else UNSET_FLAG(attr.nh_flags, BGP_ATTR_NH_IF_OPERSTATE); +<<<<<<< HEAD attr.med = metric; attr.distance = distance; attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +======= + bgp_attr_set_med(&attr, metric); + attr.distance = distance; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) attr.tag = tag; afi = family2afi(p->family); @@ -9797,7 +10328,11 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } /* Local Pref */ +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) json_object_int_add(json_path, "locPrf", attr->local_pref); @@ -9838,7 +10373,11 @@ void route_vty_out(struct vty *vty, const struct prefix *p, esi_buf, sizeof(esi_buf))); } if (safi == SAFI_EVPN && +<<<<<<< HEAD attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) { +======= + CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) json_ext_community = json_object_new_object(); json_object_string_add( json_ext_community, "string", @@ -9892,8 +10431,12 @@ void route_vty_out(struct vty *vty, const struct prefix *p, vty_out(vty, "\n"); } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vty_out(vty, "%*s", 20, " "); vty_out(vty, "%s\n", bgp_attr_get_ecommunity(attr)->str); @@ -9975,7 +10518,11 @@ void route_vty_out_tmp(struct vty *vty, struct bgp *bgp, struct bgp_dest *dest, json_object_int_add(json_net, "metric", value); } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) json_object_int_add(json_net, "locPrf", attr->local_pref); @@ -10026,7 +10573,11 @@ void route_vty_out_tmp(struct vty *vty, struct bgp *bgp, struct bgp_dest *dest, else vty_out(vty, " "); +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vty_out(vty, "%7u", attr->local_pref); else vty_out(vty, " "); @@ -10938,7 +11489,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, &path->peer->connection->su); } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vty_out(vty, " (%pI4)", &attr->originator_id); else vty_out(vty, " (%pI4)", &path->peer->remote_id); @@ -11061,7 +11616,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, ", metric %u", value); } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) json_object_int_add(json_path, "locPrf", attr->local_pref); @@ -11069,7 +11628,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, ", localpref %u", attr->local_pref); } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) json_object_int_add(json_path, "aigpMetric", bgp_attr_get_aigp_metric(attr)); @@ -11169,7 +11732,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) json_object_boolean_true_add(json_path, "atomicAggregate"); @@ -11177,7 +11744,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, ", atomic-aggregate"); } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) json_object_int_add(json_path, "otc", attr->otc); else @@ -11241,7 +11812,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, "\n"); /* Line 4 display Community */ +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) { if (!bgp_attr_get_community(attr)->json) community_str(bgp_attr_get_community(attr), @@ -11257,7 +11832,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } /* Line 5 display Extended-community */ +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) { json_ext_community = json_object_new_object(); json_object_string_add( @@ -11271,7 +11850,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) { json_ext_ipv6_community = json_object_new_object(); json_object_string_add(json_ext_ipv6_community, "string", @@ -11287,7 +11870,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } /* Line 6 display Large community */ +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) { if (!bgp_attr_get_lcommunity(attr)->json) lcommunity_str(bgp_attr_get_lcommunity(attr), @@ -11303,11 +11890,19 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } /* Line 7 display Originator, Cluster-id */ +<<<<<<< HEAD if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { char buf[BUFSIZ] = {0}; if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) || + CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { + char buf[BUFSIZ] = {0}; + + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json_paths) json_object_string_addf(json_path, "originatorId", "%pI4", @@ -11317,7 +11912,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, &attr->originator_id); } +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct cluster_list *cluster = bgp_attr_get_cluster(attr); int i; @@ -11486,7 +12085,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, " Last update: %s", ctime_r(&tbuf, timebuf)); /* Line 10 display PMSI tunnel attribute, if present */ +<<<<<<< HEAD if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) { +======= + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) const char *str = lookup_msg(bgp_pmsi_tnltype_str, bgp_attr_get_pmsi_tnl_type(attr), PMSI_TNLTYPE_STR_DEFAULT); @@ -11783,8 +12386,13 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa dummy_attr = *pi->attr; +<<<<<<< HEAD prep_for_rmap_apply(&path, &extra, dest, pi, pi->peer, &dummy_attr); +======= + prep_for_rmap_apply(&path, &extra, dest, pi, pi->peer, NULL, + &dummy_attr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ret = route_map_apply(rmap, dest_p, &path); bgp_attr_flush(&dummy_attr); @@ -13037,6 +13645,12 @@ DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd, json = json_object_new_object(); json_object_object_add(json, get_afi_safi_str(afi, safi, true), json_afi_safi); +<<<<<<< HEAD +======= + json_object_int_add(json, "bgpBestPathCalls", bgp->bestpath_runs); + json_object_int_add(json, "bgpNodeOnQueue", bgp->node_already_on_queue); + json_object_int_add(json, "bgpNodeDeferredOnQueue", bgp->node_deferred_on_queue); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vty_json(vty, json); } return ret; @@ -14662,6 +15276,11 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, } for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) { +<<<<<<< HEAD +======= + struct bgp_path_info *bpi = NULL; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (type == bgp_show_adj_route_received || type == bgp_show_adj_route_filtered) { for (ain = dest->adj_in; ain; ain = ain->next) { @@ -14766,6 +15385,7 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, peer, rn_p, &attr, afi, safi, rmap_name); +<<<<<<< HEAD if (ret != RMAP_DENY) { if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) @@ -14818,6 +15438,54 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, (*filtered_count)++; } +======= + if (ret == RMAP_DENY) { + (*filtered_count)++; + bgp_attr_flush(&attr); + continue; + } + + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || + (safi == SAFI_EVPN)) { + if (use_json) + json_object_string_add(json_ar, "rd", + rd_str); + else if (show_rd && rd_str) { + vty_out(vty, "Route Distinguisher: %s\n", + rd_str); + show_rd = false; + } + } + if (detail) { + if (use_json) + json_net = json_object_new_object(); + bgp_show_path_info(NULL, dest, vty, bgp, afi, safi, + json_net, BGP_PATH_SHOW_ALL, + &display, RPKI_NOT_BEING_USED); + if (use_json) + json_object_object_addf(json_ar, json_net, + "%pFX", rn_p); + } else { + /* For JSON output use route_vty_out_tmp() instead + * of route_vty_out(). + * route_vty_out() is path-aware, while + * route_vty_out_tmp() prints only the best path. + * This is for backward compatibility. + */ + if (use_json) { + route_vty_out_tmp(vty, bgp, dest, rn_p, + &attr, safi, use_json, + json_ar, wide); + } else { + for (bpi = bgp_dest_get_bgp_path_info(dest); + bpi; bpi = bpi->next) + route_vty_out(vty, rn_p, bpi, 0, + safi, NULL, wide); + } + } + (*output_count)++; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_attr_flush(&attr); } } else if (type == bgp_show_adj_route_bestpath) { diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index d71bfd3ebc62..51857a84f647 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -284,6 +284,12 @@ struct bgp_path_info { /* Peer structure. */ struct peer *peer; +<<<<<<< HEAD +======= + /* From peer structure */ + struct peer *from; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Attribute structure. */ struct attr *attr; @@ -619,6 +625,7 @@ static inline bool is_pi_family_matching(struct bgp_path_info *pi, } static inline void prep_for_rmap_apply(struct bgp_path_info *dst_pi, +<<<<<<< HEAD struct bgp_path_info_extra *dst_pie, struct bgp_dest *dest, struct bgp_path_info *src_pi, @@ -626,6 +633,15 @@ static inline void prep_for_rmap_apply(struct bgp_path_info *dst_pi, { memset(dst_pi, 0, sizeof(struct bgp_path_info)); dst_pi->peer = peer; +======= + struct bgp_path_info_extra *dst_pie, struct bgp_dest *dest, + struct bgp_path_info *src_pi, struct peer *peer, + struct peer *from, struct attr *attr) +{ + memset(dst_pi, 0, sizeof(struct bgp_path_info)); + dst_pi->peer = peer; + dst_pi->from = from; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) dst_pi->attr = attr; dst_pi->net = dest; dst_pi->flags = src_pi->flags; diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 61586ea922f5..395545b60a54 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -125,6 +125,13 @@ o Local extensions #define RMAP_VALUE_ADD 1 #define RMAP_VALUE_SUB 2 +<<<<<<< HEAD +======= +#define RMAP_VALUE_TYPE_RTT 1 +#define RMAP_VALUE_TYPE_IGP 2 +#define RMAP_VALUE_TYPE_AIGP 3 + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct rmap_value { uint8_t action; uint8_t variable; @@ -140,6 +147,7 @@ static int route_value_match(struct rmap_value *rv, uint32_t value) } static uint32_t route_value_adjust(struct rmap_value *rv, uint32_t current, +<<<<<<< HEAD struct peer *peer) { uint32_t value; @@ -148,6 +156,23 @@ static uint32_t route_value_adjust(struct rmap_value *rv, uint32_t current, case 1: value = peer->rtt; break; +======= + struct bgp_path_info *bpi) +{ + uint32_t value; + struct peer *peer = bpi->peer; + + switch (rv->variable) { + case RMAP_VALUE_TYPE_RTT: + value = peer->rtt; + break; + case RMAP_VALUE_TYPE_IGP: + value = bpi->extra ? bpi->extra->igpmetric : 0; + break; + case RMAP_VALUE_TYPE_AIGP: + value = MIN(bpi->attr->aigp_metric, UINT32_MAX); + break; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) default: value = rv->value; break; @@ -187,11 +212,22 @@ static void *route_value_compile(const char *arg) larg = strtoul(arg, &endptr, 10); if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX) return NULL; +<<<<<<< HEAD } else { if (strcmp(arg, "rtt") == 0) var = 1; else return NULL; +======= + } else if (strmatch(arg, "rtt")) { + var = RMAP_VALUE_TYPE_RTT; + } else if (strmatch(arg, "igp")) { + var = RMAP_VALUE_TYPE_IGP; + } else if (strmatch(arg, "aigp")) { + var = RMAP_VALUE_TYPE_AIGP; + } else { + return NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } rv = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value)); @@ -333,6 +369,69 @@ static const struct route_map_rule_cmd route_match_peer_cmd = { route_match_peer_free }; +<<<<<<< HEAD +======= +static enum route_map_cmd_result_t route_match_src_peer(void *rule, const struct prefix *prefix, + void *object) +{ + struct bgp_match_peer_compiled *pc; + union sockunion *su; + struct peer_group *group; + struct peer *peer; + struct listnode *node, *nnode; + struct bgp_path_info *bpi; + + pc = rule; + su = &pc->su; + bpi = object; + peer = bpi->from; + + /* Fallback to destination (current) peer. This is mostly + * happens if `match src-peer ...` is used at incoming direction. + */ + if (!peer) + peer = bpi->peer; + + if (!peer) + return RMAP_NOMATCH; + + if (pc->interface) { + if (!peer->conf_if && !peer->group) + return RMAP_NOMATCH; + + if (peer->conf_if && strcmp(peer->conf_if, pc->interface) == 0) + return RMAP_MATCH; + + if (peer->group && strcmp(peer->group->name, pc->interface) == 0) + return RMAP_MATCH; + + return RMAP_NOMATCH; + } + + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + if (sockunion_same(su, &peer->connection->su)) + return RMAP_MATCH; + + return RMAP_NOMATCH; + } + + group = peer->group; + for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { + if (sockunion_same(su, &peer->connection->su)) + return RMAP_MATCH; + } + + return RMAP_NOMATCH; +} + +static const struct route_map_rule_cmd route_match_src_peer_cmd = { + "src-peer", + route_match_src_peer, + route_match_peer_compile, + route_match_peer_free +}; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #ifdef HAVE_SCRIPTING enum frrlua_rm_status { @@ -383,8 +482,12 @@ route_match_script(void *rule, const struct prefix *prefix, void *object) return RMAP_NOMATCH; } +<<<<<<< HEAD long long *action = frrscript_get_result(fs, routematch_function, "action", lua_tointegerp); +======= + int *action = frrscript_get_result(fs, routematch_function, "action", lua_tointegerp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int status = RMAP_NOMATCH; @@ -406,7 +509,11 @@ route_match_script(void *rule, const struct prefix *prefix, void *object) path->attr->med = newattr.med; +<<<<<<< HEAD if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) +======= + if (CHECK_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) locpref = path->attr->local_pref; if (locpref != newattr.local_pref) { SET_FLAG(path->attr->flag, @@ -639,15 +746,25 @@ route_match_prefix_list_flowspec(afi_t afi, struct prefix_list *plist, afi); if (ret < 0) return RMAP_NOMATCH; +<<<<<<< HEAD if (api.match_bitmask & PREFIX_DST_PRESENT || api.match_bitmask_iprule & PREFIX_DST_PRESENT) { +======= + if (CHECK_FLAG(api.match_bitmask, PREFIX_DST_PRESENT) || + CHECK_FLAG(api.match_bitmask_iprule, PREFIX_DST_PRESENT)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (family2afi((&api.dst_prefix)->family) != afi) return RMAP_NOMATCH; return prefix_list_apply(plist, &api.dst_prefix) == PREFIX_DENY ? RMAP_NOMATCH : RMAP_MATCH; +<<<<<<< HEAD } else if (api.match_bitmask & PREFIX_SRC_PRESENT || api.match_bitmask_iprule & PREFIX_SRC_PRESENT) { +======= + } else if (CHECK_FLAG(api.match_bitmask, PREFIX_SRC_PRESENT) || + CHECK_FLAG(api.match_bitmask_iprule, PREFIX_SRC_PRESENT)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (family2afi((&api.src_prefix)->family) != afi) return RMAP_NOMATCH; return (prefix_list_apply(plist, &api.src_prefix) == PREFIX_DENY @@ -1997,7 +2114,11 @@ route_set_ip_nexthop(void *rule, const struct prefix *prefix, void *object) sockunion_family(peer->su_remote) == AF_INET) { path->attr->nexthop.s_addr = sockunion2ip(peer->su_remote); +<<<<<<< HEAD path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); +======= + SET_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else if (CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT)) { /* The next hop value will be set as part of * packet rewrite. Set the flags here to indicate @@ -2010,7 +2131,11 @@ route_set_ip_nexthop(void *rule, const struct prefix *prefix, void *object) } } else { /* Set next hop value. */ +<<<<<<< HEAD path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); +======= + SET_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) path->attr->nexthop = *rins->address; SET_FLAG(path->attr->rmap_change_flags, BATTR_RMAP_IPV4_NHOP_CHANGED); @@ -2144,8 +2269,13 @@ route_set_local_pref(void *rule, const struct prefix *prefix, void *object) if (path->attr->local_pref) locpref = path->attr->local_pref; +<<<<<<< HEAD path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); path->attr->local_pref = route_value_adjust(rv, locpref, path->peer); +======= + SET_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)); + path->attr->local_pref = route_value_adjust(rv, locpref, path); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return RMAP_OKAY; } @@ -2172,7 +2302,11 @@ route_set_weight(void *rule, const struct prefix *prefix, void *object) path = object; /* Set weight value. */ +<<<<<<< HEAD path->attr->weight = route_value_adjust(rv, 0, path->peer); +======= + path->attr->weight = route_value_adjust(rv, 0, path); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return RMAP_OKAY; } @@ -2219,11 +2353,18 @@ route_set_metric(void *rule, const struct prefix *prefix, void *object) rv = rule; path = object; +<<<<<<< HEAD if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) med = path->attr->med; path->attr->med = route_value_adjust(rv, med, path->peer); path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +======= + if (CHECK_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) + med = path->attr->med; + + bgp_attr_set_med(path->attr, route_value_adjust(rv, med, path)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return RMAP_OKAY; } @@ -3420,7 +3561,11 @@ route_set_atomic_aggregate(void *rule, const struct prefix *pfx, void *object) struct bgp_path_info *path; path = object; +<<<<<<< HEAD path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE); +======= + SET_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return RMAP_OKAY; } @@ -3498,7 +3643,11 @@ route_set_aggregator_as(void *rule, const struct prefix *prefix, void *object) path->attr->aggregator_as = aggregator->as; path->attr->aggregator_addr = aggregator->address; +<<<<<<< HEAD path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR); +======= + SET_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return RMAP_OKAY; } @@ -3578,7 +3727,11 @@ route_set_label_index(void *rule, const struct prefix *prefix, void *object) label_index = rv->value; if (label_index) { path->attr->label_index = label_index; +<<<<<<< HEAD path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID); +======= + SET_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return RMAP_OKAY; @@ -4245,7 +4398,11 @@ route_set_originator_id(void *rule, const struct prefix *prefix, void *object) address = rule; path = object; +<<<<<<< HEAD path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID); +======= + SET_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) path->attr->originator_id = *address; return RMAP_OKAY; @@ -5270,6 +5427,55 @@ DEFUN_YANG (no_match_peer, return nb_cli_apply_changes(vty, NULL); } +<<<<<<< HEAD +======= +DEFPY_YANG (match_src_peer, + match_src_peer_cmd, + "match src-peer ", + MATCH_STR + "Match source peer address\n" + "IP address of peer\n" + "IPv6 address of peer\n" + "Interface name of peer or peer group name\n") +{ + const char *xpath = "./match-condition[condition='frr-bgp-route-map:src-peer']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address", xpath); + nb_cli_enqueue_change(vty, xpath_value, addrv4_str ? NB_OP_MODIFY : NB_OP_DESTROY, + addrv4_str); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-bgp-route-map:src-peer-ipv6-address", xpath); + nb_cli_enqueue_change(vty, xpath_value, addrv6_str ? NB_OP_MODIFY : NB_OP_DESTROY, + addrv6_str); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-bgp-route-map:src-peer-interface", xpath); + nb_cli_enqueue_change(vty, xpath_value, intf ? NB_OP_MODIFY : NB_OP_DESTROY, intf); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG (no_match_src_peer, + no_match_src_peer_cmd, + "no match src-peer []", + NO_STR + MATCH_STR + "Match peer address\n" + "IP address of peer\n" + "IPv6 address of peer\n" + "Interface name of peer\n") +{ + const char *xpath = "./match-condition[condition='frr-bgp-route-map:src-peer']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #ifdef HAVE_SCRIPTING DEFUN_YANG (match_script, match_script_cmd, @@ -7761,6 +7967,10 @@ void bgp_route_map_init(void) route_map_no_set_tag_hook(generic_set_delete); route_map_install_match(&route_match_peer_cmd); +<<<<<<< HEAD +======= + route_map_install_match(&route_match_src_peer_cmd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) route_map_install_match(&route_match_alias_cmd); route_map_install_match(&route_match_local_pref_cmd); #ifdef HAVE_SCRIPTING @@ -7828,6 +8038,11 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &match_peer_cmd); install_element(RMAP_NODE, &match_peer_local_cmd); +<<<<<<< HEAD +======= + install_element(RMAP_NODE, &match_src_peer_cmd); + install_element(RMAP_NODE, &no_match_src_peer_cmd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(RMAP_NODE, &no_match_peer_cmd); install_element(RMAP_NODE, &match_ip_route_source_cmd); install_element(RMAP_NODE, &no_match_ip_route_source_cmd); diff --git a/bgpd/bgp_routemap_nb.c b/bgpd/bgp_routemap_nb.c index 096502aaa904..294829901222 100644 --- a/bgpd/bgp_routemap_nb.c +++ b/bgpd/bgp_routemap_nb.c @@ -110,6 +110,30 @@ const struct frr_yang_module_info frr_bgp_route_map_info = { } }, { +<<<<<<< HEAD +======= + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address", + .cbs = { + .modify = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_modify, + .destroy = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-interface", + .cbs = { + .modify = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_modify, + .destroy = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-ipv6-address", + .cbs = { + .modify = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_modify, + .destroy = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_destroy, + } + }, + { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:list-name", .cbs = { .modify = lib_route_map_entry_match_condition_rmap_match_condition_list_name_modify, diff --git a/bgpd/bgp_routemap_nb.h b/bgpd/bgp_routemap_nb.h index d7f0cea30ea0..0e4a69146f89 100644 --- a/bgpd/bgp_routemap_nb.h +++ b/bgpd/bgp_routemap_nb.h @@ -46,6 +46,21 @@ int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_m int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_destroy(struct nb_cb_destroy_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_peer_local_modify(struct nb_cb_modify_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy(struct nb_cb_destroy_args *args); +<<<<<<< HEAD +======= +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_destroy( + struct nb_cb_destroy_args *args); +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_destroy( + struct nb_cb_destroy_args *args); +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_destroy( + struct nb_cb_destroy_args *args); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_modify(struct nb_cb_modify_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_destroy(struct nb_cb_destroy_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_extended_modify(struct nb_cb_modify_args *args); diff --git a/bgpd/bgp_routemap_nb_config.c b/bgpd/bgp_routemap_nb_config.c index 15c32eaa2856..c9a03042c7fb 100644 --- a/bgpd/bgp_routemap_nb_config.c +++ b/bgpd/bgp_routemap_nb_config.c @@ -809,6 +809,165 @@ lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy( } /* +<<<<<<< HEAD +======= + * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address + */ +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + const char *peer; + enum rmap_compile_rets ret; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + peer = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = bgp_route_match_delete; + rhc->rhc_rule = "src-peer"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + ret = bgp_route_match_add(rhc->rhc_rmi, "src-peer", peer, RMAP_EVENT_MATCH_ADDED, + args->errmsg, args->errmsg_len); + + if (ret != RMAP_COMPILE_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + } + + return NB_OK; +} + +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return lib_route_map_entry_match_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-interface + */ +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + const char *peer; + enum rmap_compile_rets ret; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + peer = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = bgp_route_match_delete; + rhc->rhc_rule = "src-peer"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + ret = bgp_route_match_add(rhc->rhc_rmi, "src-peer", peer, RMAP_EVENT_MATCH_ADDED, + args->errmsg, args->errmsg_len); + + if (ret != RMAP_COMPILE_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + } + + return NB_OK; +} + +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return lib_route_map_entry_match_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-ipv6-address + */ +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + const char *peer; + enum rmap_compile_rets ret; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + peer = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = bgp_route_match_delete; + rhc->rhc_rule = "src-peer"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + ret = bgp_route_match_add(rhc->rhc_rmi, "src-peer", peer, RMAP_EVENT_MATCH_ADDED, + args->errmsg, args->errmsg_len); + + if (ret != RMAP_COMPILE_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + } + + return NB_OK; +} + +int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return lib_route_map_entry_match_destroy(args); + } + + return NB_OK; +} + +/* +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:list-name */ int diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index 90c43b938ffd..fab872862234 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -455,6 +455,13 @@ static unsigned int updgrp_hash_key_make(const void *p) key = jhash_1word(jhash(soo_str, strlen(soo_str), SEED1), key); } +<<<<<<< HEAD +======= + if (afi == AFI_IP6 && + (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED))) + key = jhash(&peer->nexthop.v6_global, IPV6_MAX_BYTELEN, key); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * ANY NEW ITEMS THAT ARE ADDED TO THE key, ENSURE DEBUG * STATEMENT STAYS UP TO DATE @@ -521,6 +528,15 @@ static unsigned int updgrp_hash_key_make(const void *p) peer->soo[afi][safi] ? ecommunity_str(peer->soo[afi][safi]) : "(NONE)"); +<<<<<<< HEAD +======= + zlog_debug("%pBP Update Group Hash: IPv6 nexthop-local unchanged: %d IPv6 global %pI6", + peer, + afi == AFI_IP6 && (CHECK_FLAG(peer->af_flags[afi][safi], + PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)), + &peer->nexthop.v6_global); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%pBP Update Group Hash key: %u", peer, key); } return key; @@ -655,6 +671,15 @@ static bool updgrp_hash_cmp(const void *p1, const void *p2) !sockunion_same(&pe1->connection->su, &pe2->connection->su)) return false; +<<<<<<< HEAD +======= + if (afi == AFI_IP6 && + (CHECK_FLAG(flags1, PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) || + CHECK_FLAG(flags2, PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) && + !IPV6_ADDR_SAME(&pe1->nexthop.v6_global, &pe2->nexthop.v6_global)) + return false; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return true; } diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 250378af6845..5e0cab22a8cb 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -906,8 +906,13 @@ void subgroup_default_originate(struct update_subgroup *subgrp, bool withdraw) assert(attr.aspath); aspath = attr.aspath; +<<<<<<< HEAD attr.med = 0; attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +======= + + bgp_attr_set_med(&attr, 0); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) { /* IPv6 global nexthop must be included. */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f95769b3362c..ddf732a12cb0 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -161,9 +161,14 @@ static struct peer_group *listen_range_exists(struct bgp *bgp, static void bgp_show_global_graceful_restart_mode_vty(struct vty *vty, struct bgp *bgp); +<<<<<<< HEAD static int bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty, enum show_type type, const char *ip_str, +======= +static int bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty, struct bgp *bgp, + enum show_type type, const char *ip_str, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) afi_t afi, bool use_json); static enum node_type bgp_node_type(afi_t afi, safi_t safi) @@ -1473,6 +1478,12 @@ DEFUN_HIDDEN (no_bgp_local_mac, return CMD_SUCCESS; } +<<<<<<< HEAD +======= +#if CONFDATE > 20250514 +CPP_NOTICE("Remove no_synchronization_cmd, no_auto_summary_cmd commands") +#endif +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFUN (no_synchronization, no_synchronization_cmd, "no synchronization", @@ -2938,9 +2949,13 @@ DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { peer->last_reset = PEER_DOWN_AS_SETS_REJECT; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return CMD_SUCCESS; @@ -2963,9 +2978,13 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { peer->last_reset = PEER_DOWN_AS_SETS_REJECT; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return CMD_SUCCESS; @@ -4464,6 +4483,7 @@ DEFUN (bgp_network_import_check, return CMD_SUCCESS; } +<<<<<<< HEAD #if CONFDATE > 20241013 CPP_NOTICE("Drop `bgp network import-check exact` command") #endif @@ -4474,6 +4494,8 @@ ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd, "Check BGP network route exists in IGP\n" "Match route precisely\n") +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFUN (no_bgp_network_import_check, no_bgp_network_import_check_cmd, "no bgp network import-check", @@ -5108,10 +5130,14 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if, peer->last_reset = PEER_DOWN_V6ONLY_CHANGE; /* v6only flag changed. Reset bgp seesion */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); } @@ -5272,7 +5298,11 @@ DEFUN (no_neighbor, * interface. */ if (peer->ifp) bgp_zebra_terminate_radv(peer->bgp, peer); +<<<<<<< HEAD peer_notify_unconfig(peer); +======= + peer_notify_unconfig(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) peer_delete(peer); return CMD_SUCCESS; } @@ -5308,10 +5338,17 @@ DEFUN (no_neighbor, if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)) bgp_zebra_terminate_radv(peer->bgp, peer); +<<<<<<< HEAD peer_notify_unconfig(peer); peer_delete(peer); if (other && other->connection->status != Deleted) { peer_notify_unconfig(other); +======= + peer_notify_unconfig(peer->connection); + peer_delete(peer); + if (other && other->connection->status != Deleted) { + peer_notify_unconfig(other->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) peer_delete(other); } } @@ -5346,7 +5383,11 @@ DEFUN (no_neighbor_interface_config, /* Request zebra to terminate IPv6 RAs on this interface. */ if (peer->ifp) bgp_zebra_terminate_radv(peer->bgp, peer); +<<<<<<< HEAD peer_notify_unconfig(peer); +======= + peer_notify_unconfig(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) peer_delete(peer); } else { vty_out(vty, "%% Create the bgp interface first\n"); @@ -5754,7 +5795,11 @@ DEFUN (no_neighbor_set_peer_group, if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)) bgp_zebra_terminate_radv(peer->bgp, peer); +<<<<<<< HEAD peer_notify_unconfig(peer); +======= + peer_notify_unconfig(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ret = peer_delete(peer); return bgp_vty_return(vty, ret); @@ -16144,6 +16189,7 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, return CMD_SUCCESS; } +<<<<<<< HEAD static void bgp_show_neighbor_graceful_restart_vty(struct vty *vty, enum show_type type, const char *ip_str, @@ -16159,6 +16205,15 @@ static void bgp_show_neighbor_graceful_restart_vty(struct vty *vty, if (!bgp) return; +======= +static void bgp_show_neighbor_graceful_restart_vty(struct vty *vty, struct bgp *bgp, + enum show_type type, const char *ip_str, + afi_t afi, json_object *json) +{ + int ret; + union sockunion su; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!json) bgp_show_global_graceful_restart_mode_vty(vty, bgp); @@ -16313,6 +16368,7 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name, return CMD_SUCCESS; } +<<<<<<< HEAD /* "show [ip] bgp neighbors graceful-restart" commands. */ @@ -16355,6 +16411,43 @@ DEFUN (show_ip_bgp_neighbors_graceful_restart, return bgp_show_neighbor_graceful_restart_afi_all(vty, sh_type, sh_arg, afi, uj); +======= +/* "show [ip] bgp neighbors graceful-restart" commands. */ +DEFPY (show_ip_bgp_neighbors_graceful_restart, + show_ip_bgp_neighbors_graceful_restart_cmd, + "show bgp []$afi [ VIEWVRFNAME$vrf] neighbors [$neigh] graceful-restart [json]$json", + SHOW_STR + BGP_STR + IP_STR + IPV6_STR + BGP_INSTANCE_HELP_STR + NEIGHBOR_STR + "Neighbor to display information about\n" + "Neighbor to display information about\n" + "Neighbor on BGP configured interface\n" + GR_SHOW + JSON_STR) +{ + enum show_type sh_type = show_all; + afi_t afiz = AFI_IP; + bool uj = !!json; + struct bgp *bgp; + + if (afi) + afiz = bgp_vty_afi_from_str(afi); + + if (neigh) + sh_type = show_peer; + + bgp = vrf ? bgp_lookup_by_name(vrf) : bgp_get_default(); + + if (!bgp) { + vty_out(vty, "No such bgp instance %s", vrf ? vrf : ""); + return CMD_WARNING; + } + + return bgp_show_neighbor_graceful_restart_afi_all(vty, bgp, sh_type, neigh, afiz, uj); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* "show [ip] bgp neighbors" commands. */ @@ -16528,9 +16621,14 @@ static void bgp_show_global_graceful_restart_mode_vty(struct vty *vty, vty_out(vty, "\n"); } +<<<<<<< HEAD static int bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty, enum show_type type, const char *ip_str, +======= +static int bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty, struct bgp *bgp, + enum show_type type, const char *ip_str, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) afi_t afi, bool use_json) { json_object *json = NULL; @@ -16542,6 +16640,7 @@ static int bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty, afi = AFI_IP; while ((afi != AFI_L2VPN) && (afi < AFI_MAX)) { +<<<<<<< HEAD bgp_show_neighbor_graceful_restart_vty( vty, type, ip_str, afi, json); @@ -16550,6 +16649,13 @@ static int bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty, } else if (afi != AFI_MAX) { bgp_show_neighbor_graceful_restart_vty(vty, type, ip_str, afi, json); +======= + bgp_show_neighbor_graceful_restart_vty(vty, bgp, type, ip_str, afi, json); + afi++; + } + } else if (afi != AFI_MAX) { + bgp_show_neighbor_graceful_restart_vty(vty, bgp, type, ip_str, afi, json); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else { if (json) json_object_free(json); @@ -19138,9 +19244,13 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY_RPKI)) +<<<<<<< HEAD vty_out(vty, " no neighbor %s send-community extended rpki\n", addr); +======= + vty_out(vty, " neighbor %s send-community extended rpki\n", addr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Default information */ @@ -20451,6 +20561,12 @@ void bgp_vty_init(void) install_element(CONFIG_NODE, &no_bgp_graceful_restart_rib_stale_time_cmd); +<<<<<<< HEAD +======= +#if CONFDATE > 20250514 + CPP_NOTICE("Remove no_synchronization_cmd, no_auto_summary_cmd commands") +#endif +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Dummy commands (Currently not supported) */ install_element(BGP_NODE, &no_synchronization_cmd); install_element(BGP_NODE, &no_auto_summary_cmd); @@ -20692,7 +20808,10 @@ void bgp_vty_init(void) /* "bgp network import-check" commands. */ install_element(BGP_NODE, &bgp_network_import_check_cmd); +<<<<<<< HEAD install_element(BGP_NODE, &bgp_network_import_check_exact_cmd); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(BGP_NODE, &no_bgp_network_import_check_cmd); /* "bgp default local-preference" commands. */ diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 9053df3192e1..a13c0e1ebbd1 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -137,7 +137,11 @@ static void bgp_start_interface_nbrs(struct bgp *bgp, struct interface *ifp) for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { if (peer->conf_if && (strcmp(peer->conf_if, ifp->name) == 0) && !peer_established(peer->connection)) { +<<<<<<< HEAD if (peer_active(peer)) +======= + if (peer_active(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) BGP_EVENT_ADD(peer->connection, BGP_Stop); BGP_EVENT_ADD(peer->connection, BGP_Start); } @@ -744,6 +748,10 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote, int ret = 0; struct interface *ifp = NULL; bool v6_ll_avail = true; +<<<<<<< HEAD +======= + bool shared_network_original = peer->shared_network; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) memset(nexthop, 0, sizeof(struct bgp_nexthop)); @@ -838,9 +846,15 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote, if (!v6_ll_avail && !peer->conf_if) v6_ll_avail = true; if (if_lookup_by_ipv4(&remote->sin.sin_addr, peer->bgp->vrf_id)) +<<<<<<< HEAD peer->shared_network = 1; else peer->shared_network = 0; +======= + peer->shared_network = true; + else + peer->shared_network = false; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* IPv6 connection, fetch and store IPv4 local address if any. */ @@ -903,11 +917,22 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote, || if_lookup_by_ipv6(&remote->sin6.sin6_addr, remote->sin6.sin6_scope_id, peer->bgp->vrf_id)) +<<<<<<< HEAD peer->shared_network = 1; else peer->shared_network = 0; } +======= + peer->shared_network = true; + else + peer->shared_network = false; + } + + if (shared_network_original != peer->shared_network) + bgp_peer_bfd_update_source(peer); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* KAME stack specific treatment. */ #ifdef KAME if (IN6_IS_ADDR_LINKLOCAL(&nexthop->v6_global) @@ -1187,9 +1212,16 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp, ifindex = pi->peer->nexthop.ifp->ifindex; if (!ifindex) { +<<<<<<< HEAD if (pi->peer->conf_if) ifindex = pi->peer->ifp->ifindex; else if (pi->peer->ifname) +======= + if (pi->peer->conf_if) { + if (pi->peer->ifp) + ifindex = pi->peer->ifp->ifindex; + } else if (pi->peer->ifname) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ifindex = ifname2ifindex( pi->peer->ifname, pi->peer->bgp->vrf_id); @@ -3699,7 +3731,11 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS) // refresh functions for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func)) { tmp_prefi.family = AF_INET6; +<<<<<<< HEAD tmp_prefi.prefixlen = 128; +======= + tmp_prefi.prefixlen = IPV6_MAX_BITLEN; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tmp_prefi.prefix = func->sid; if (prefix_match((struct prefix *)&loc.prefix, (struct prefix *)&tmp_prefi)) { @@ -3717,7 +3753,11 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS) tovpn_sid = bgp_vrf->vpn_policy[AFI_IP].tovpn_sid; if (tovpn_sid) { tmp_prefi.family = AF_INET6; +<<<<<<< HEAD tmp_prefi.prefixlen = 128; +======= + tmp_prefi.prefixlen = IPV6_MAX_BITLEN; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tmp_prefi.prefix = *tovpn_sid; if (prefix_match((struct prefix *)&loc.prefix, (struct prefix *)&tmp_prefi)) @@ -3729,7 +3769,11 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS) tovpn_sid = bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid; if (tovpn_sid) { tmp_prefi.family = AF_INET6; +<<<<<<< HEAD tmp_prefi.prefixlen = 128; +======= + tmp_prefi.prefixlen = IPV6_MAX_BITLEN; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tmp_prefi.prefix = *tovpn_sid; if (prefix_match((struct prefix *)&loc.prefix, (struct prefix *)&tmp_prefi)) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index c452040f8ddc..5ee9511787c9 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -85,6 +85,10 @@ DEFINE_QOBJ_TYPE(bgp_master); DEFINE_QOBJ_TYPE(bgp); DEFINE_QOBJ_TYPE(peer); DEFINE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp)); +<<<<<<< HEAD +======= +DEFINE_HOOK(bgp_instance_state, (struct bgp *bgp), (bgp)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* BGP process wide configuration. */ static struct bgp_master bgp_master; @@ -308,9 +312,13 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id, peer->last_reset = PEER_DOWN_RID_CHANGE; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* EVPN uses router id in RD, update them */ @@ -446,8 +454,12 @@ void bm_wait_for_fib_set(bool set) peer->connection->status)) continue; +<<<<<<< HEAD bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } } @@ -506,8 +518,12 @@ void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set) if (!BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) continue; +<<<<<<< HEAD bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -531,9 +547,13 @@ void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id) peer->last_reset = PEER_DOWN_CLID_CHANGE; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -555,9 +575,13 @@ void bgp_cluster_id_unset(struct bgp *bgp) peer->last_reset = PEER_DOWN_CLID_CHANGE; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -636,6 +660,7 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str) if (already_confed) { if (ptype == BGP_PEER_EBGP) { peer->local_as = as; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) { peer->last_reset = @@ -644,6 +669,12 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str) BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else +======= + if (peer_notify_config_change(peer->connection)) + peer->last_reset = + PEER_DOWN_CONFED_ID_CHANGE; + else +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset_safe(peer, &nnode); } } else { @@ -654,6 +685,7 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str) /* Reset the local_as to be our EBGP one */ if (ptype == BGP_PEER_EBGP) peer->local_as = as; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) { peer->last_reset = @@ -662,6 +694,12 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str) BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else +======= + if (peer_notify_config_change(peer->connection)) + peer->last_reset = + PEER_DOWN_CONFED_ID_CHANGE; + else +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset_safe(peer, &nnode); } } @@ -683,12 +721,16 @@ void bgp_confederation_id_unset(struct bgp *bgp) if (peer_sort(peer) != BGP_PEER_IBGP) { peer->local_as = bgp->as; peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset_safe(peer, &nnode); } } @@ -735,6 +777,7 @@ void bgp_confederation_peers_add(struct bgp *bgp, as_t as, const char *as_str) if (peer->as == as) { peer->local_as = bgp->as; (void)peer_sort(peer); +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) { peer->last_reset = @@ -743,6 +786,12 @@ void bgp_confederation_peers_add(struct bgp *bgp, as_t as, const char *as_str) BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else +======= + if (peer_notify_config_change(peer->connection)) + peer->last_reset = + PEER_DOWN_CONFED_PEER_CHANGE; + else +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset_safe(peer, &nnode); } } @@ -792,6 +841,7 @@ void bgp_confederation_peers_remove(struct bgp *bgp, as_t as) if (peer->as == as) { peer->local_as = bgp->confed_id; (void)peer_sort(peer); +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) { peer->last_reset = @@ -800,6 +850,12 @@ void bgp_confederation_peers_remove(struct bgp *bgp, as_t as) BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else +======= + if (peer_notify_config_change(peer->connection)) + peer->last_reset = + PEER_DOWN_CONFED_PEER_CHANGE; + else +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset_safe(peer, &nnode); } } @@ -1568,19 +1624,27 @@ struct peer *peer_new(struct bgp *bgp) /* Set default flags. */ FOREACH_AFI_SAFI (afi, safi) { SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY); +<<<<<<< HEAD SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY); SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY_RPKI); +======= + SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY); SET_FLAG(peer->af_flags_invert[afi][safi], PEER_FLAG_SEND_COMMUNITY); +<<<<<<< HEAD SET_FLAG(peer->af_flags_invert[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY); SET_FLAG(peer->af_flags_invert[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY_RPKI); +======= + SET_FLAG(peer->af_flags_invert[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SET_FLAG(peer->af_flags_invert[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY); peer->addpath_type[afi][safi] = BGP_ADDPATH_NONE; @@ -2020,7 +2084,11 @@ struct peer *peer_create(union sockunion *su, const char *conf_if, bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct); } +<<<<<<< HEAD active = peer_active(peer); +======= + active = peer_active(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!active) { if (peer->connection->su.sa.sa_family == AF_UNSPEC) peer->last_reset = PEER_DOWN_NBR_ADDR; @@ -2053,7 +2121,11 @@ struct peer *peer_create(union sockunion *su, const char *conf_if, if (bgp->autoshutdown) peer_flag_set(peer, PEER_FLAG_SHUTDOWN); /* Set up peer's events and timers. */ +<<<<<<< HEAD else if (!active && peer_active(peer)) +======= + else if (!active && peer_active(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_timer_set(peer->connection); bgp_peer_gr_flags_update(peer); @@ -2104,10 +2176,14 @@ void peer_as_change(struct peer *peer, as_t as, enum peer_asn_type as_type, /* Stop peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); } origtype = peer_sort_lookup(peer); @@ -2448,13 +2524,21 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) if (peer_af_create(peer, afi, safi) == NULL) return 1; +<<<<<<< HEAD active = peer_active(peer); +======= + active = peer_active(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) peer->afc[afi][safi] = 1; if (peer->group) peer_group2peer_config_copy_af(peer->group, peer, afi, safi); +<<<<<<< HEAD if (!active && peer_active(peer)) { +======= + if (!active && peer_active(peer->connection)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_timer_set(peer->connection); } else { peer->last_reset = PEER_DOWN_AF_ACTIVATE; @@ -2471,6 +2555,7 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) false); } } else { +<<<<<<< HEAD bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -2480,6 +2565,13 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) peer->connection->status == OpenConfirm) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); + } + } + peer_notify_config_change(peer->connection); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * If we are turning on a AFI/SAFI locally and we've * started bringing a peer up, we need to tell @@ -2490,10 +2582,15 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) * activation. */ other = peer->doppelganger; +<<<<<<< HEAD if (other && (other->connection->status == OpenSent || other->connection->status == OpenConfirm)) bgp_notify_send(other->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + if (other) + peer_notify_config_change(other->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return 0; @@ -2600,6 +2697,7 @@ static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi, bgp_clear_route(peer, afi, safi); peer->pcount[afi][safi] = 0; } else { +<<<<<<< HEAD bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -2608,6 +2706,12 @@ static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi, bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } +======= + peer_notify_config_change(peer->connection); + } + } else + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return false; @@ -3081,11 +3185,28 @@ int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as, return 0; } +<<<<<<< HEAD void peer_notify_unconfig(struct peer *peer) { if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); +======= +bool peer_notify_config_change(struct peer_connection *connection) +{ + if (BGP_IS_VALID_STATE_FOR_NOTIF(connection->status)) { + bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); + return true; + } + + return false; +} + +void peer_notify_unconfig(struct peer_connection *connection) +{ + if (BGP_IS_VALID_STATE_FOR_NOTIF(connection->status)) + bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static void peer_notify_shutdown(struct peer *peer) @@ -3112,9 +3233,15 @@ void peer_group_notify_unconfig(struct peer_group *group) other = peer->doppelganger; if (other && other->connection->status != Deleted) { other->group = NULL; +<<<<<<< HEAD peer_notify_unconfig(other); } else peer_notify_unconfig(peer); +======= + peer_notify_unconfig(other->connection); + } else + peer_notify_unconfig(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -3361,10 +3488,14 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, peer->last_reset = PEER_DOWN_RMAP_BIND; +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); } @@ -3399,7 +3530,11 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, } /* Set up peer's events and timers. */ +<<<<<<< HEAD if (peer_active(peer)) +======= + if (peer_active(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_timer_set(peer->connection); } @@ -3939,6 +4074,12 @@ void bgp_instance_up(struct bgp *bgp) struct peer *peer; struct listnode *node, *next; +<<<<<<< HEAD +======= + /* notify BMP of instance state changed */ + hook_call(bgp_instance_state, bgp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_set_redist_vrf_bitmaps(bgp, true); /* Register with zebra. */ @@ -3967,6 +4108,12 @@ void bgp_instance_down(struct bgp *bgp) /* Cleanup evpn instance state */ bgp_evpn_instance_down(bgp); +<<<<<<< HEAD +======= + /* notify BMP of instance state changed */ + hook_call(bgp_instance_state, bgp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Stop timers. */ if (bgp->t_rmap_def_originate_eval) EVENT_OFF(bgp->t_rmap_def_originate_eval); @@ -4224,8 +4371,11 @@ int bgp_delete(struct bgp *bgp) if (bgp->process_queue) work_queue_free_and_null(&bgp->process_queue); +<<<<<<< HEAD event_master_free_unused(bm->master); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!IS_BGP_INSTANCE_HIDDEN(bgp)) bgp_unlock(bgp); /* initial reference */ else { @@ -4636,9 +4786,17 @@ bool bgp_path_attribute_treat_as_withdraw(struct peer *peer, char *buf, } /* If peer is configured at least one address family return 1. */ +<<<<<<< HEAD bool peer_active(struct peer *peer) { if (BGP_CONNECTION_SU_UNSPEC(peer->connection)) +======= +bool peer_active(struct peer_connection *connection) +{ + struct peer *peer = connection->peer; + + if (BGP_CONNECTION_SU_UNSPEC(connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return false; if (peer->bfd_config) { @@ -4727,8 +4885,12 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi, PEER_FLAG_CONFIG_NODE))) peer_delete(peer->doppelganger); +<<<<<<< HEAD bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else if (type == peer_change_reset_in) { if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_RCV)) bgp_route_refresh_send(peer, afi, safi, 0, 0, 0, @@ -4740,8 +4902,12 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi, PEER_FLAG_CONFIG_NODE))) peer_delete(peer->doppelganger); +<<<<<<< HEAD bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); +======= + peer_notify_config_change(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } else if (type == peer_change_reset_out) { paf = peer_af_find(peer, afi, safi); @@ -4940,10 +5106,14 @@ static void peer_flag_modify_action(struct peer *peer, uint64_t flag) peer->v_start = BGP_INIT_START_TIMER; BGP_EVENT_ADD(peer->connection, BGP_Stop); } +<<<<<<< HEAD } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else +======= + } else if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); } @@ -5394,7 +5564,11 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) { struct peer_group *group; struct listnode *node, *nnode; +<<<<<<< HEAD struct peer *peer1; +======= + struct peer *member; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (peer->sort == BGP_PEER_IBGP || peer->conf_if) return 0; @@ -5410,12 +5584,20 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) if (group->conf->gtsm_hops != BGP_GTSM_HOPS_DISABLED) return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; +<<<<<<< HEAD for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer1)) { if (peer1->sort == BGP_PEER_IBGP) continue; if (peer1->gtsm_hops != BGP_GTSM_HOPS_DISABLED) +======= + for (ALL_LIST_ELEMENTS(group->peer, node, nnode, member)) { + if (member->sort == BGP_PEER_IBGP) + continue; + + if (member->gtsm_hops != BGP_GTSM_HOPS_DISABLED) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; } } else { @@ -5428,12 +5610,16 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { if (peer->sort != BGP_PEER_IBGP) { +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); /* Reconfigure BFD peer with new TTL. */ @@ -5442,6 +5628,7 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) } } else { group = peer->group; +<<<<<<< HEAD for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { if (peer->sort == BGP_PEER_IBGP) continue; @@ -5459,6 +5646,20 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) /* Reconfigure BFD peer with new TTL. */ if (peer->bfd_config) bgp_peer_bfd_update_source(peer); +======= + for (ALL_LIST_ELEMENTS(group->peer, node, nnode, member)) { + if (member->sort == BGP_PEER_IBGP) + continue; + + member->ttl = group->conf->ttl; + + if (!peer_notify_config_change(member->connection)) + bgp_session_reset(member); + + /* Reconfigure BFD peer with new TTL. */ + if (member->bfd_config) + bgp_peer_bfd_update_source(member); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } return 0; @@ -5466,6 +5667,10 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) int peer_ebgp_multihop_unset(struct peer *peer) { +<<<<<<< HEAD +======= + struct peer *member; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct peer_group *group; struct listnode *node, *nnode; int ttl; @@ -5487,10 +5692,14 @@ int peer_ebgp_multihop_unset(struct peer *peer) peer->ttl = ttl; if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); /* Reconfigure BFD peer with new TTL. */ @@ -5498,6 +5707,7 @@ int peer_ebgp_multihop_unset(struct peer *peer) bgp_peer_bfd_update_source(peer); } else { group = peer->group; +<<<<<<< HEAD for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { if (peer->sort == BGP_PEER_IBGP) continue; @@ -5517,6 +5727,22 @@ int peer_ebgp_multihop_unset(struct peer *peer) /* Reconfigure BFD peer with new TTL. */ if (peer->bfd_config) bgp_peer_bfd_update_source(peer); +======= + for (ALL_LIST_ELEMENTS(group->peer, node, nnode, member)) { + if (member->sort == BGP_PEER_IBGP) + continue; + + member->ttl = BGP_DEFAULT_TTL; + + if (member->connection->fd >= 0) { + if (!peer_notify_config_change(member->connection)) + bgp_session_reset(member); + } + + /* Reconfigure BFD peer with new TTL. */ + if (member->bfd_config) + bgp_peer_bfd_update_source(member); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } return 0; @@ -5662,10 +5888,14 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); /* Apply new source configuration to BFD session. */ @@ -5700,10 +5930,14 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname) member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(member); /* Apply new source configuration to BFD session. */ @@ -5733,10 +5967,14 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); /* Apply new source configuration to BFD session. */ @@ -5770,10 +6008,14 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su) member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(member); /* Apply new source configuration to BFD session. */ @@ -5821,10 +6063,14 @@ void peer_update_source_unset(struct peer *peer) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); /* Apply new source configuration to BFD session. */ @@ -5857,10 +6103,14 @@ void peer_update_source_unset(struct peer *peer) member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(member); /* Apply new source configuration to BFD session. */ @@ -6374,7 +6624,11 @@ int peer_timers_connect_set(struct peer *peer, uint32_t connect) /* Skip peer-group mechanics for regular peers. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { if (!peer_established(peer->connection)) { +<<<<<<< HEAD if (peer_active(peer)) +======= + if (peer_active(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) BGP_EVENT_ADD(peer->connection, BGP_Stop); BGP_EVENT_ADD(peer->connection, BGP_Start); } @@ -6395,7 +6649,11 @@ int peer_timers_connect_set(struct peer *peer, uint32_t connect) member->v_connect = connect; if (!peer_established(member->connection)) { +<<<<<<< HEAD if (peer_active(member)) +======= + if (peer_active(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) BGP_EVENT_ADD(member->connection, BGP_Stop); BGP_EVENT_ADD(member->connection, BGP_Start); } @@ -6428,7 +6686,11 @@ int peer_timers_connect_unset(struct peer *peer) /* Skip peer-group mechanics for regular peers. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { if (!peer_established(peer->connection)) { +<<<<<<< HEAD if (peer_active(peer)) +======= + if (peer_active(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) BGP_EVENT_ADD(peer->connection, BGP_Stop); BGP_EVENT_ADD(peer->connection, BGP_Start); } @@ -6449,7 +6711,11 @@ int peer_timers_connect_unset(struct peer *peer) member->v_connect = peer->bgp->default_connect_retry; if (!peer_established(member->connection)) { +<<<<<<< HEAD if (peer_active(member)) +======= + if (peer_active(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) BGP_EVENT_ADD(member->connection, BGP_Stop); BGP_EVENT_ADD(member->connection, BGP_Start); } @@ -6890,10 +7156,14 @@ int peer_local_as_unset(struct peer *peer) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; /* Send notification or stop peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) BGP_EVENT_ADD(peer->connection, BGP_Stop); /* Skip peer-group mechanics for regular peers. */ @@ -6919,10 +7189,14 @@ int peer_local_as_unset(struct peer *peer) member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; /* Send notification or stop peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(member); } @@ -6951,10 +7225,14 @@ int peer_password_set(struct peer *peer, const char *password) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer->last_reset = PEER_DOWN_PASSWORD_CHANGE; /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); /* @@ -6989,10 +7267,14 @@ int peer_password_set(struct peer *peer, const char *password) member->last_reset = PEER_DOWN_PASSWORD_CHANGE; /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(member); /* Attempt to install password on socket. */ @@ -7035,10 +7317,14 @@ int peer_password_unset(struct peer *peer) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(peer->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(peer); /* Attempt to uninstall password on socket. */ @@ -7062,10 +7348,14 @@ int peer_password_unset(struct peer *peer) XFREE(MTYPE_PEER_PASSWORD, member->password); /* Send notification or reset peer depending on state. */ +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else +======= + if (!peer_notify_config_change(member->connection)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp_session_reset(member); /* Attempt to uninstall password on socket. */ @@ -8742,8 +9032,12 @@ static int peer_unshut_after_cfg(struct bgp *bgp) peer->host); peer->shut_during_cfg = false; +<<<<<<< HEAD if (peer_active(peer) && peer->connection->status != Established) { +======= + if (peer_active(peer->connection) && peer->connection->status != Established) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (peer->connection->status != Idle) BGP_EVENT_ADD(peer->connection, BGP_Stop); BGP_EVENT_ADD(peer->connection, BGP_Start); @@ -8846,11 +9140,15 @@ void bgp_terminate(void) peer); continue; } +<<<<<<< HEAD if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); +======= + peer_notify_unconfig(peer->connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 8aeb0eb43a5f..9f76cd4ab950 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -864,6 +864,13 @@ struct bgp { /* BGP route flap dampening configuration */ struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; +<<<<<<< HEAD +======= + uint64_t bestpath_runs; + uint64_t node_already_on_queue; + uint64_t node_deferred_on_queue; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) QOBJ_FIELDS; }; DECLARE_QOBJ_TYPE(bgp); @@ -883,6 +890,10 @@ DECLARE_HOOK(bgp_snmp_traps_config_write, (struct vty *vty), (vty)); DECLARE_HOOK(bgp_config_end, (struct bgp *bgp), (bgp)); DECLARE_HOOK(bgp_hook_vrf_update, (struct vrf *vrf, bool enabled), (vrf, enabled)); +<<<<<<< HEAD +======= +DECLARE_HOOK(bgp_instance_state, (struct bgp *bgp), (bgp)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Thread callback information */ struct afi_safi_info { @@ -1130,7 +1141,12 @@ enum bgp_fsm_rfc_codes { BGP_FSM_NotifMsg = 25, BGP_FSM_KeepAliveMsg = 26, BGP_FSM_UpdateMsg = 27, +<<<<<<< HEAD BGP_FSM_UpdateMsgErr = 28 +======= + BGP_FSM_UpdateMsgErr = 28, + BGP_FSM_SendHoldTimer_Expires = 29, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }; /* @@ -1225,6 +1241,11 @@ struct peer_connection { struct event *t_process_packet; struct event *t_process_packet_error; +<<<<<<< HEAD +======= + struct event *t_stop_with_notify; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) union sockunion su; #define BGP_CONNECTION_SU_UNSPEC(connection) \ (connection->su.sa.sa_family == AF_UNSPEC) @@ -1322,7 +1343,11 @@ struct peer { union sockunion *su_local; /* Sockunion of local address. */ union sockunion *su_remote; /* Sockunion of remote address. */ +<<<<<<< HEAD int shared_network; /* Is this peer shared same network. */ +======= + bool shared_network; /* Is this peer shared same network. */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct bgp_nexthop nexthop; /* Nexthop */ /* Roles in bgp session */ @@ -1762,8 +1787,20 @@ struct peer { /* Text description of last attribute rcvd */ char rcvd_attr_str[BUFSIZ]; +<<<<<<< HEAD /* Track if we printed the attribute in debugs */ int rcvd_attr_printed; +======= + /* + * Track if we printed the attribute in debugs + * + * These two rcvd_attr_str and rcvd_attr_printed are going to + * be fun in the long term when we want to break up parsing + * of data from the nlri in multiple pthreads or really + * if we ever change order of things this will just break + */ + bool rcvd_attr_printed; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Accepted prefix count */ uint32_t pcount[AFI_MAX][SAFI_MAX]; @@ -2280,7 +2317,11 @@ extern struct peer *peer_unlock_with_caller(const char *, struct peer *); extern enum bgp_peer_sort peer_sort(struct peer *peer); extern enum bgp_peer_sort peer_sort_lookup(struct peer *peer); +<<<<<<< HEAD extern bool peer_active(struct peer *); +======= +extern bool peer_active(struct peer_connection *connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern bool peer_active_nego(struct peer *); extern bool peer_afc_received(struct peer *peer); extern bool peer_afc_advertised(struct peer *peer); @@ -2370,7 +2411,12 @@ extern int peer_remote_as(struct bgp *bgp, union sockunion *su, extern int peer_group_remote_as(struct bgp *bgp, const char *peer_str, as_t *as, enum peer_asn_type as_type, const char *as_str); extern int peer_delete(struct peer *peer); +<<<<<<< HEAD extern void peer_notify_unconfig(struct peer *peer); +======= +extern void peer_notify_unconfig(struct peer_connection *connection); +extern bool peer_notify_config_change(struct peer_connection *connection); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern int peer_group_delete(struct peer_group *); extern int peer_group_remote_as_delete(struct peer_group *); extern int peer_group_listen_range_add(struct peer_group *, struct prefix *); diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index a452ebe48eb4..5fe4178aaefa 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -4403,6 +4403,10 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) { const char *s = ""; +<<<<<<< HEAD +======= + (void)s; /* clang-SA */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) switch (hc->redist_mode) { case VNC_REDIST_MODE_PLAIN: s = "plain"; diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 23e3eb482308..9618b9e863b7 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -667,10 +667,15 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); } +<<<<<<< HEAD if (med) { attr.med = *med; attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); } +======= + if (med) + bgp_attr_set_med(&attr, *med); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* override default weight assigned by bgp_attr_default_set() */ attr.weight = rfd->peer ? rfd->peer->weight[afi][safi] : 0; @@ -863,10 +868,15 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ red = bgp_redist_lookup(bgp, afi, type, 0); +<<<<<<< HEAD if (red && red->redist_metric_flag) { attr.med = red->redist_metric; attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); } +======= + if (red && red->redist_metric_flag) + bgp_attr_set_med(&attr, red->redist_metric); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 8f1f509bbbe6..34c5251dfe37 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -1257,6 +1257,11 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream, const char *agetype = ""; char *s; const char *type = ""; +<<<<<<< HEAD +======= + + (void)type; /* clang-SA */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (show_imported) { type = "Imported"; } else { diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index 4de2306609c9..5f111d22671b 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -96,6 +96,7 @@ static void encap_attr_export_ce(struct attr *new, struct attr *orig, * neighbor NEIGHBOR attribute-unchanged med */ if (!CHECK_FLAG(new->flag, BGP_ATTR_MULTI_EXIT_DISC)) { +<<<<<<< HEAD if (CHECK_FLAG(new->flag, BGP_ATTR_LOCAL_PREF)) { if (new->local_pref > 255) new->med = 0; @@ -105,6 +106,18 @@ static void encap_attr_export_ce(struct attr *new, struct attr *orig, new->med = 255; /* shouldn't happen */ } new->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +======= + uint32_t med = 255; + + if (CHECK_FLAG(new->flag, BGP_ATTR_LOCAL_PREF)) { + if (new->local_pref > 255) + med = 0; + else + med = 255 - new->local_pref; + } + + bgp_attr_set_med(new, med); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* @@ -642,6 +655,7 @@ encap_attr_export(struct attr *new, struct attr *orig, * neighbor NEIGHBOR attribute-unchanged med */ if (!CHECK_FLAG(new->flag, BGP_ATTR_MULTI_EXIT_DISC)) { +<<<<<<< HEAD if (CHECK_FLAG(new->flag, BGP_ATTR_LOCAL_PREF)) { if (new->local_pref > 255) new->med = 0; @@ -651,6 +665,18 @@ encap_attr_export(struct attr *new, struct attr *orig, new->med = 255; /* shouldn't happen */ } new->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +======= + uint32_t med = 255; + + if (CHECK_FLAG(new->flag, BGP_ATTR_LOCAL_PREF)) { + if (new->local_pref > 255) + med = 0; + else + med = 255 - new->local_pref; + } + + bgp_attr_set_med(new, med); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* diff --git a/configure.ac b/configure.ac index a177e5cd79fd..675e7c8ba549 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,11 @@ ## AC_PREREQ([2.69]) +<<<<<<< HEAD AC_INIT([frr], [10.2], [https://github.com/frrouting/frr/issues]) +======= +AC_INIT([frr], [10.3-dev], [https://github.com/frrouting/frr/issues]) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) PACKAGE_URL="https://frrouting.org/" AC_SUBST([PACKAGE_URL]) PACKAGE_FULLNAME="FRRouting" diff --git a/debian/changelog b/debian/changelog index 346e36926c46..c2eea1fb1885 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,14 +1,26 @@ +<<<<<<< HEAD frr (10.2-0) unstable; urgency=medium * New upstream release FRR 10.2 -- Jafar Al-Gharaibeh Tue, 12 Nov 2024 02:00:00 -0600 +======= +frr (10.3~dev-1) UNRELEASED; urgency=medium + + * FRR 10.3 Development + + -- Jafar Al-Gharaibeh Thu, 10 Oct 2024 02:00:00 -0600 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) frr (10.1-0) unstable; urgency=medium * New upstream release FRR 10.1 +<<<<<<< HEAD -- Jafar Al-Gharaibeh Tue, 26 Mar 2024 02:00:00 -0600 +======= + -- Jafar Al-Gharaibeh Fri, 26 Jul 2024 02:00:00 -0600 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) frr (10.0-0) unstable; urgency=medium diff --git a/debian/control b/debian/control index 4a02a36b71d1..c693e9a615c3 100644 --- a/debian/control +++ b/debian/control @@ -37,7 +37,12 @@ Build-Depends: bison, libgrpc-dev (>=1.16.1) , libgrpc++-dev (>=1.16.1) , protobuf-compiler (>=3.6.1) , +<<<<<<< HEAD protobuf-compiler-grpc (>=1.16.1) +======= + protobuf-compiler-grpc (>=1.16.1) , + libprotobuf-dev (>=3.6.1) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Standards-Version: 4.5.0.3 Homepage: https://www.frrouting.org/ Vcs-Browser: https://github.com/FRRouting/frr/tree/debian/master diff --git a/debian/rules b/debian/rules index ec8f92f755f6..d16df0686682 100755 --- a/debian/rules +++ b/debian/rules @@ -68,6 +68,10 @@ override_dh_auto_configure: --enable-ospfapi \ --enable-bgp-vnc \ --enable-multipath=256 \ +<<<<<<< HEAD +======= + --enable-pcre2posix \ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) \ --enable-user=frr \ --enable-group=frr \ diff --git a/doc/accords/frr-name-use b/doc/accords/frr-name-use new file mode 100644 index 000000000000..c2529e7a0cb6 --- /dev/null +++ b/doc/accords/frr-name-use @@ -0,0 +1,69 @@ +Usage of FRR names/logos +======================== + + +As FRRouting has become a popular open source suite of routing protocol +implementations, it has also become popular to use FRRouting as an environment +to prototype or test new features/protocols/etc. in. Such use is absolutely +welcome (and a freedom guaranteed by the GPL license). + +However, references to FRRouting in such context can be misunderstood both as +endorsements as well as promises of current or future availability. To contain +such misunderstandings, we would like to place the following limitations on the +use of the "FRRouting" name (or "FRR" where clear by context) as well as the +"chicken-head" logo (as they are ultimately "valuable trademarks"): + +- Advertisements, presentations, announcements, etc. of projects based on + FRRouting may only reference the 3 above-mentioned marks if the full source + code of said project is publicly available (under terms compatible with + FRRouting's licenses and without any access barriers) and locatable (either + by direct link or a reasonable search) on the internet. + +- References to code or features using the wording "in" FRRouting may only be + made for bits that are part of FRRouting's "master" or "stable" branches (or + history). This is specifically about the word "in". + +- use in previously created documents/publications/... is permitted + ("grandfathered"), so long as the use retains its context. Noone is + expected to scan their history and eliminate references. + + +The intent is as follows: + +- you are under no obligation to publish code just because it exists. The + above are only restrictions on the use of FRRouting trademarks. + +- The code itself being derivative of FRRouting (and therefore containing the + name/logo) is not considered use of the trademarks. You do not need to + eliminate the name from your private codebase. + +- pushing your code to github and/or opening a (maybe draft) PR trivially + fulfills the availability condition above, and we'd like to encourage this + as the "default". However, publishing on your own hosting services is also + acceptable. + +- please use phrasing like "available *for* FRRouting" or "we have implemented + XYZ *using* FRRouting", and refrain from "available *in* FRRouting" or "we + have implemented XYZ *in* FRRouting". In particular due to the world-wide + and multilingual nature of the FRRouting community, *in* carries too high a + risk for confusion - and conversely, reserving this term also allows clear + and meaningful signaling of some (your?) code in fact becoming part of + FRRouting. + +- while "advertisement" may create an impression of "sales call" or "vendor + presentation", this also applies to engineering processes such as IETF + standards development work. + + +These rules, while lawyer-y to some degree, are intended to convey FRRouting +community consensus and help clarify communication. We certainly hope we will +never need to pick them apart or even legally enforce them. However, in the +spirit of all legalese: + +This document is not to be construed as any grant of rights, guarantees, +agreement or other similar, even implicit. + + +P.S.: note that "Free Range Routing" is not a name we use, and neither should +you - there seem to be conflicting trademarks from completely unrelated +parties. diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst index d2308bea94ef..37d4f3fdf2b3 100644 --- a/doc/developer/topotests.rst +++ b/doc/developer/topotests.rst @@ -881,7 +881,11 @@ commands: .. code:: console make topotests-build +<<<<<<< HEAD TOPOTEST_PULL=0 make topotests +======= + make topotests +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. _topotests-guidelines: @@ -1323,6 +1327,11 @@ You can run scripts inside the node, or use vtysh's or feature. loc1 1 2001:db8:1:1::/64 Up loc2 2 2001:db8:2:2::/64 Up +<<<<<<< HEAD +======= +.. _writing-tests: + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Writing Tests """"""""""""" @@ -1393,6 +1402,7 @@ or using unified config (specifying which daemons to run is optional): Requirements: - Directory name for a new topotest must not contain hyphen (``-``) characters. +<<<<<<< HEAD To separate words, use underscores (``_``). For example, ``tests/topotests/bgp_new_example``. - Test code should always be declared inside functions that begin with the ``test_`` prefix. Functions beginning with different prefixes will not be run @@ -1408,6 +1418,24 @@ Requirements: - Always use IPv4 :rfc:`5737` (``192.0.2.0/24``, ``198.51.100.0/24``, ``203.0.113.0/24``) and IPv6 :rfc:`3849` (``2001:db8::/32``) ranges reserved for documentation. +======= + To separate words, use underscores (``_``). For example, ``tests/topotests/bgp_new_example``; +- Test code should always be declared inside functions that begin with the + ``test_`` prefix. Functions beginning with different prefixes will not be run + by pytest; +- Configuration files and long output commands should go into separated files + inside folders named after the equipment; +- Tests must be able to run without any interaction. To make sure your test + conforms with this, run it without the :option:`-s` parameter; +- Use `black `_ code formatter before creating + a pull request. This ensures we have a unified code style; +- Mark test modules with pytest markers depending on the daemons used during the + tests (see :ref:`topotests-markers`); +- Always use IPv4 :rfc:`5737` (``192.0.2.0/24``, ``198.51.100.0/24``, + ``203.0.113.0/24``) and IPv6 :rfc:`3849` (``2001:db8::/32``) ranges reserved + for documentation; +- Use unified config (``frr.conf``) for all new tests. See :ref:`writing-tests`. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Tips: diff --git a/doc/user/about.rst b/doc/user/about.rst index ba80a324d3bb..393deb9484e6 100644 --- a/doc/user/about.rst +++ b/doc/user/about.rst @@ -343,6 +343,11 @@ BGP :t:`Making Route Flap Damping Usable. C. Pelsser, R. Bush, K. Patel, P. Mohapatra, O. Maennel. May 2014.` - :rfc:`7300` :t:`Reservation of Last Autonomous System (AS) Numbers. J. Haas, J. Mitchell. July 2014.` +<<<<<<< HEAD +======= +- :rfc:`7311` + :t:`The Accumulated IGP Metric Attribute for BGP. P. Mohapatra, R. Fernando, E. Rosen, J. Uttaro. August 2014.` +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) - :rfc:`7313` :t:`Enhanced Route Refresh Capability for BGP-4. K. Patel, E. Chen, B. Venkatachalapathy. July 2014.` - :rfc:`7606` @@ -389,6 +394,11 @@ BGP :t:`A BGP Cease NOTIFICATION Subcode for Bidirectional Forwarding Detection (BFD). J. Haas. March 2023.` - :rfc:`9494` :t:`Long-Lived Graceful Restart for BGP. J. Uttaro, E. Chen, B. Decraene, J. Scudder. November 2023.` +<<<<<<< HEAD +======= +- :rfc:`9687` + :t:`Border Gateway Protocol 4 (BGP-4) Send Hold Timer. J. Snijders, B. Cartwright-Cox, Y. Qu. November 2024.` +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) OSPF ---- diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst index 4c142cfbbb06..12bb1a56c418 100644 --- a/doc/user/bfd.rst +++ b/doc/user/bfd.rst @@ -139,7 +139,11 @@ Peer / Profile Configuration BFD peers and profiles share the same BFD session configuration commands. +<<<<<<< HEAD .. clicmd:: detect-multiplier (2-255) +======= +.. clicmd:: detect-multiplier (1-255) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Configures the detection multiplier to determine packet loss. The remote transmission interval will be multiplied by this value to @@ -151,23 +155,39 @@ BFD peers and profiles share the same BFD session configuration commands. detect failures only after 900 milliseconds without receiving packets. +<<<<<<< HEAD .. clicmd:: receive-interval (10-60000) +======= +.. clicmd:: receive-interval (10-4294967) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Configures the minimum interval that this system is capable of receiving control packets. The default value is 300 milliseconds. +<<<<<<< HEAD .. clicmd:: transmit-interval (10-60000) +======= +.. clicmd:: transmit-interval (10-4294967) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) The minimum transmission interval (less jitter) that this system wants to use to send BFD control packets. Defaults to 300ms. +<<<<<<< HEAD .. clicmd:: echo receive-interval +======= +.. clicmd:: echo receive-interval +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Configures the minimum interval that this system is capable of receiving echo packets. Disabled means that this system doesn't want to receive echo packets. The default value is 50 milliseconds. +<<<<<<< HEAD .. clicmd:: echo transmit-interval (10-60000) +======= +.. clicmd:: echo transmit-interval (10-4294967) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) The minimum transmission interval (less jitter) that this system wants to use to send BFD echo packets. Defaults to 50ms. diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index adf5261fe0a2..6765438d38cd 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1169,6 +1169,17 @@ BGP GR Peer Mode Commands at the peer level. +<<<<<<< HEAD +======= +BGP GR Show Commands +^^^^^^^^^^^^^^^^^^^^ + +.. clicmd:: show bgp [] [ VRF] neighbors [] graceful-restart [json] + + This command will display information about the neighbors graceful-restart status + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Long-lived Graceful Restart --------------------------- @@ -1795,7 +1806,11 @@ Configuring Peers Send the extended RPKI communities to the peer. RPKI extended community can be send only to iBGP and eBGP-OAD peers. +<<<<<<< HEAD Default: enabled. +======= + Default: disabled. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: neighbor PEER weight WEIGHT @@ -1849,7 +1864,12 @@ Configuring Peers .. clicmd:: neighbor as-override +<<<<<<< HEAD Override AS number of the originating router with the local AS number. +======= + Override any AS number in the AS path that matches the neighbor's AS number + with the local AS number. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Usually this configuration is used in PEs (Provider Edge) to replace the incoming customer AS number so the connected CE (Customer Edge) @@ -2919,6 +2939,27 @@ BGP Extended Communities in Route Map This command sets colors values. +<<<<<<< HEAD +======= +:rfc:`9256`. + +``CO:COLOR`` + This is a format to define colors value. ``CO`` part is always 00 (default), + it can be used to support the requirements of Color-Only steering when using + a Null Endpoint in the SR-TE Policy as specified in Section 8.8 of [RFC9256]. + The below shows in detail what the different combinations of ``CO`` bits can + match on to for the purpose of determining what type of SR-TE Policy Tunnel + a BGP route can resolve over, and it also shows the order for resolving the + BGP route if there are different tunnels. + + - ``00`` Can match on a specific endpoint only which should be the nexthop + of the route(Default Setting). + - ``01`` Can match on a specific endpoint or a null endpoint. + - ``10`` Can match on a specific endpoint, null endpoint or any endpoint. + - ``11`` Reserved for future use and shuould not be used. + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: set extcommunity bandwidth <(1-25600) | cumulative | num-multipaths> [non-transitive] This command sets the BGP link-bandwidth extended community for the prefix diff --git a/doc/user/evpn.rst b/doc/user/evpn.rst index 7c4d9fe7d909..f26176c5e6fe 100644 --- a/doc/user/evpn.rst +++ b/doc/user/evpn.rst @@ -56,13 +56,21 @@ FRR learns about the system's Linux network interface configuration from the kernel via Netlink, however it does not manage network interfaces directly. The following sections will include examples of Linux interface configurations that are compatible with FRR's EVPN implementation. While there are multiple +<<<<<<< HEAD interface managers that can setup a proper kernel config (e.g. ifupdown2), +======= +interface managers that can set up a proper kernel config (e.g. ifupdown2), +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) these examples will use iproute2 to add/configure the interfaces. All of the examples will follow the same basic setup but use different, yet compatible, interface configurations. +<<<<<<< HEAD In this example we will setup the following: +======= +In this example we will set up the following: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * An IP-VRF named vrf1, associated with L3VNI 100 * An IP-VRF named vrf2, associated with L3VNI 200 @@ -78,7 +86,11 @@ In this example we will setup the following: Sample Configuration -------------------- This is a sample FRR configuration that implements the above EVPN environment. +<<<<<<< HEAD The first snippet will be the config in its entiretly, then each config element +======= +The first snippet will be the config in its entirety, then each config element +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) will be explained individually later in the document. The following snippet will result in a functional EVPN control plane if the @@ -484,7 +496,11 @@ VNI, The interface settings are the same for an L2VNI as they are for an L3VNI. Finally, to limit a traditional bridge's broadcast domain to traffic matching specific VLAN-IDs, ``vlan`` subinterfaces of a host/network port need to be +<<<<<<< HEAD setup. This example shows the creation of a VLAN subinterface of "eth0" +======= +set up. This example shows the creation of a VLAN subinterface of "eth0" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) matching VID 10 with the name "eth0.10". By enslaving "eth0.10" to "br10" (instead of "eth0") we ensure that only Ethernet frames ingressing "eth0" tagged with VID 10 will be associated with the "br10" broadcast domain. diff --git a/doc/user/filter.rst b/doc/user/filter.rst index c1146e50aa2b..e99dec36b25c 100644 --- a/doc/user/filter.rst +++ b/doc/user/filter.rst @@ -9,9 +9,13 @@ defined, it can be applied in any direction. IP Access List ============== +<<<<<<< HEAD .. clicmd:: access-list NAME [seq (1-4294967295)] permit IPV4-NETWORK .. clicmd:: access-list NAME [seq (1-4294967295)] deny IPV4-NETWORK +======= +.. clicmd:: access-list NAME [seq (1-4294967295)] +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) seq seq `number` can be set either automatically or manually. In the @@ -35,6 +39,32 @@ IP Access List access-list filter permit 10.0.0.0/8 access-list filter seq 13 permit 10.0.0.0/7 +<<<<<<< HEAD +======= +.. clicmd:: access-list NAME [seq (1-4294967295)] ip + + The extended access-list syntax enables filtering on both source and destination + IP addresses (or source and group, if used for multicast boundaries). The + source address is first in order in the command. + + If providing a mask, note that the access-lists use wildcard masks (inverse + matching logic of subnet masks). If specifying ``host``, only the single address + given will be matched. + + A basic example is as follows: + + .. code-block:: frr + + access-list filter seq 5 permit ip host 10.0.20.2 232.1.1.0 0.0.0.128 + access-list filter seq 10 deny ip 10.0.20.0 0.0.0.255 232.1.1.0 0.0.0.255 + access-list filter seq 15 permit ip any any + + .. note :: + + If an access-list is specified but no match is found, the default verdict + is deny. + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: show access-list [json] Display all IPv4 or IPv6 access lists. diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index b80adba7f046..60ea8f1a7216 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -200,6 +200,47 @@ To start OSPF process you have to specify the OSPF router. This command supersedes the *timers spf* command in previous FRR releases. +<<<<<<< HEAD +======= +.. clicmd:: timers throttle lsa all (0-5000) + + This command sets the minumum interval between originations of the + same LSA or the `minimum LSA refresh interval`. The time is specified + in milliseconds and the default is 5 seconds (5000 milliseconds) consistent + with the architectual constant MinLSInterval specified in Appendix D of + RFC 2328. When a self-originated LSA needs to be reoriginated, it may be + delayed for up to this interval. + + .. code-block:: frr + + router ospf + timers throttle lsa all 1000 + + + In this example, the `mininum LSA refresh interval` is set to 1000ms. This + command reduces the delay between successive originations of a self-originated + LSA from 5000 milliseconds to 1000 milliseconds. + +.. clicmd:: timers lsa min-arrival (0-5000) + + This command sets the minumum interval between receptions of instances of + the same LSA or the `minimum LSA arrival interval`. The time is specified in + milliseconds and the default is 1 second (1000 milliseconds) consistent with + the architectual constant MinLSArrival specified in Appendix D of RFC 2328. If a + newer instance of the same LSA is received in less than this interval, it is + ignored. + + .. code-block:: frr + + router ospf + timers lsa min-arrival 50 + + + In this example, the `minimum LSA arrival interval` is set to 50ms. This + command reduces the minimum interval required between instances of the same + LSA from 1000 milliseconds to 50 milliseconds. + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: max-metric router-lsa [on-startup (5-86400)|on-shutdown (5-100)] .. clicmd:: max-metric router-lsa administrative diff --git a/doc/user/pim.rst b/doc/user/pim.rst index 0fe53247b05e..80e3af605243 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -6,9 +6,15 @@ PIM PIM -- Protocol Independent Multicast +<<<<<<< HEAD *pimd* supports pim-sm as well as igmp v2 and v3. pim is vrf aware and can work within the context of vrf's in order to do S,G mrouting. Additionally PIM can be used in the EVPN underlay +======= +*pimd* supports PIM-SM as well as IGMP v2 and v3. PIM is +VRF aware and can work within the context of VRFs in order to +do S,G mrouting. Additionally, PIM can be used in the EVPN underlay +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) network for optimizing forwarding of overlay BUM traffic. .. note:: @@ -348,10 +354,53 @@ is in a vrf, enter the interface command with the vrf keyword at the end. .. clicmd:: ip multicast boundary oil WORD +<<<<<<< HEAD Set a pim multicast boundary, based upon the WORD prefix-list. If a pim join or IGMP report is received on this interface and the Group is denied by the prefix-list, PIM will ignore the join or report. +======= + Set a PIM multicast boundary, based upon the WORD prefix-list. If a PIM join + or IGMP report is received on this interface and the group is denied by the + prefix-list, PIM will ignore the join or report. + + .. code-block:: frr + + prefix-list multicast-acl seq 5 permit 232.1.1.1/32 + prefix-list multicast-acl seq 10 deny 232.1.1.0/24 + prefix-list multicast-acl seq 15 permit any + ! + interface r1-eth0 + ip pim + ip igmp + ip multicast boundary oil multicast-acl + exit + +.. clicmd:: ip multicast boundary ACCESS-LIST + + Set a PIM multicast boundary, based upon the ACCESS-LIST. If a PIM join + or IGMP report is received on this interface and the (S,G) tuple is denied by the + access-list, PIM will ignore the join or report. + + To filter on both source and group, the extended access-list syntax must be used. + + If both a prefix-list and access-list are configured for multicast boundaries, + the prefix-list will be evaluated first (and must have a terminating "permit any" + in order to also evaluate against the access-list). + + .. code-block:: frr + + access-list multicast-acl seq 5 permit ip host 10.0.20.2 host 232.1.1.1 + access-list multicast-acl seq 10 deny ip 10.0.20.0 0.0.0.255 232.1.1.0 0.0.0.255 + access-list multicast-acl seq 15 permit ip any any + ! + interface r1-eth0 + ip pim + ip igmp + ip multicast boundary pim-acl + exit + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: ip igmp last-member-query-count (1-255) Set the IGMP last member query count. The default value is 2. 'no' form of @@ -478,6 +527,13 @@ Commands available for MSDP To apply it immediately call `clear ip msdp peer A.B.C.D`. +<<<<<<< HEAD +======= +.. clicmd:: msdp shutdown + + Shutdown the MSDP sessions in this PIM instance. + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. _show-pim-information: diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst index e4e28d71ab1e..75da13701598 100644 --- a/doc/user/pimv6.rst +++ b/doc/user/pimv6.rst @@ -103,6 +103,42 @@ PIMv6 Router interface will be selected.By default, the highest loopback address is selected, which can also be configured via ``loopback``. +<<<<<<< HEAD +======= +.. clicmd:: embedded-rp + + Learn the RP via embedded RP address in multicast group. + + .. note:: + + The embedded RP address range is: FF70::/12 (with exception of FFF0::/12). + + Example: FF75:0130:2001:DB8:FFFF::100 + + - First byte is always 0xFF + - Second byte high nibble is always 7 (signifies RPT bits set) + - Second byte low nibble is address scope + - Third byte high nibble is zero (reserved) + - Third byte low nibble is the RP interface ID (RIID) + - Fourth byte is the RP prefix length (must be between 1 and 64) + - Fifth byte + RP prefix length is the RP address prefix + - Last four bytes are the group ID. + + The RP in the above multicast address sample is: + 2001:DB8:FFFF::1 + +.. clicmd:: embedded-rp group-list PREFIX_LIST_NAME + + Restrict the embedded RP prefix range using only the permitted groups + provided by the prefix-list. + + This is useful to restrict what RP addresses can be used. + +.. clicmd:: embedded-rp limit (1-4294967295) + + Restrict the maximum amount of embedded RPs to learn at same time. + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: spt-switchover infinity-and-beyond [prefix-list PLIST] On the last hop router if it is desired to not switch over to the SPT tree diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst index fbf7b8637e6a..7345b4a91a8e 100644 --- a/doc/user/routemap.rst +++ b/doc/user/routemap.rst @@ -101,9 +101,16 @@ cont .. clicmd:: clear route-map counter [WORD] +<<<<<<< HEAD Clear counters that are being stored about the route-map utilization so that subsuquent show commands will indicate since the last clear. If WORD is specified clear just that particular route-map's counters. +======= + Clear counters as well as cpu time spent that are being stored about + the route-map utilization so that subsequent show commands will indicate + since the last clear. If WORD is specified clear just that particular + route-map's counters. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. _route-map-command: @@ -190,6 +197,15 @@ Route Map Match Command do the exact matching of the communities, while ``any`` - can match any community specified in COMMUNITY_LIST. +<<<<<<< HEAD +======= +.. clicmd:: match src-peer [IPV4_ADDR|IPV6_ADDR|INTERFACE_NAME|PEER_GROUP_NAME] + + This is a BGP specific match command. Matches the source peer if the neighbor + was specified in this manner. Useful to announce the routes that was originated + by the source peer. + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: match peer IPV4_ADDR This is a BGP specific match command. Matches the peer ip address @@ -305,13 +321,18 @@ Route Map Set Command Set the route's weight. +<<<<<<< HEAD .. clicmd:: set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt> +======= +.. clicmd:: set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt|igp|aigp> +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Set the route metric. When used with BGP, set the BGP attribute MED to a specific value. Use `+`/`-` to add or subtract the specified value to/from the existing/MED. Use `rtt` to set the MED to the round trip time or `+rtt`/`-rtt` to add/subtract the round trip time to/from the MED. +<<<<<<< HEAD .. clicmd:: set min-metric <(0-4294967295)> Set the minimum meric for the route. @@ -319,6 +340,20 @@ Route Map Set Command .. clicmd:: set max-metric <(0-4294967295)> Set the maximum meric for the route. +======= + If ``igp`` is specified, then the actual value from the IGP protocol is used. + + If ``aigp`` is specified, then the actual value from the AIGP metric is used + (encoded as MED instead of AIGP attribute). + +.. clicmd:: set min-metric <(0-4294967295)> + + Set the minimum metric for the route. + +.. clicmd:: set max-metric <(0-4294967295)> + + Set the maximum metric for the route. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: set aigp-metric diff --git a/doc/user/vrrp.rst b/doc/user/vrrp.rst index d99fc23ef5be..f08bf497730b 100644 --- a/doc/user/vrrp.rst +++ b/doc/user/vrrp.rst @@ -519,6 +519,10 @@ Check: - Do you have unusual ``sysctls`` enabled that could affect the operation of multicast traffic? - Are you running in ESXi? See below. +<<<<<<< HEAD +======= +- Are you running in a linux VM with a bridged network? See below. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) My master router is not forwarding traffic @@ -552,6 +556,27 @@ feature instead, explained `here Issue reference: https://github.com/FRRouting/frr/issues/5386 +<<<<<<< HEAD +======= +My router is running in a linux VM with a bridged host network and VRRP has issues +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Issues can arise with VRRP (especially IPv6) when you have a VM running on top +of a linux host, where your physical network is in a bridge, and the VM +has an interface attached to the bridge. By default, the linux bridge will +snoop multicast traffic, and you will likely see sporadic VRRP advertisements failing +to be received. IPv6 traffic was be particularly affected. + +This was observed on a VM running on proxmox, and the solution was to disable +multicast snooping on the bridge: + +.. code-block:: console + + echo 0 > /sys/devices/virtual/net/vmbr0/bridge/multicast_snooping + +Issue reference: https://github.com/FRRouting/frr/issues/5386 + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) My router cannot interoperate with branded routers / L3 switches ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 06a19a61394b..14a6a24a4443 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -526,6 +526,7 @@ commands in relationship to VRF. Here is an extract of some of those commands: The network administrator can however decide to provision this command in configuration file to provide more clarity about the intended configuration. +<<<<<<< HEAD .. clicmd:: netns NAMESPACE This command is based on VRF configuration mode. This command is available @@ -536,6 +537,8 @@ commands in relationship to VRF. Here is an extract of some of those commands: decide to provision this command in configuration file to provide more clarity about the intended configuration. +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. clicmd:: show ip route vrf VRF The show command permits dumping the routing table associated to the VRF. If @@ -985,7 +988,11 @@ and this section also helps that case. :: router# configure terminal +<<<<<<< HEAD router(config)# segment-routinig +======= + router(config)# segment-routing +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) router(config-sr)# srv6 router(config-srv6)# locators router(config-srv6-locs)# locator loc1 @@ -1013,7 +1020,11 @@ and this section also helps that case. :: router# configure terminal +<<<<<<< HEAD router(config)# segment-routinig +======= + router(config)# segment-routing +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) router(config-sr)# srv6 router(config-srv6)# locators router(config-srv6-locators)# locator loc1 @@ -1042,7 +1053,11 @@ and this section also helps that case. :: router# configure terminal +<<<<<<< HEAD router(config)# segment-routinig +======= + router(config)# segment-routing +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) router(config-sr)# srv6 router(config-srv6)# locators router(config-srv6-locators)# locator loc1 @@ -1099,7 +1114,11 @@ and this section also helps that case. :: router# configure terminal +<<<<<<< HEAD router(config)# segment-routinig +======= + router(config)# segment-routing +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) router(config-sr)# srv6 router(config-srv6)# formats router(config-srv6-formats)# format usid-f3216 @@ -1287,6 +1306,28 @@ IPv6 example for OSPFv3. Set the delay before any route-maps are processed in zebra. The default time for this is 5 seconds. +<<<<<<< HEAD +======= + +.. _zebra-table-import: + +zebra Table Import +================== + +Zebra supports importing an alternate routing table into the main unicast RIB (URIB). +An imported table will continously sync all changes to the main URIB as routes are +added or deleted from the alternate table. +Zebra also supports importing into the main multicast RIB (MRIB) which can be used +to affect how multicast RPF lookups are performed as described in :ref: `_pim-multicast-rib`. + +.. clicmd:: ip import-table (1-252) [mrib] [distance (1-255)] [route-map RMAP_NAME] + + Import table, by given table id, into the main URIB (or MRIB). Optional distance can override + the default distance when importing routes from the alternate table. An optional route map + can be provided to filter routes that are imported into the main table. + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .. _zebra-fib-push-interface: zebra FIB push interface @@ -1864,6 +1905,13 @@ Debugging Nexthop and nexthop-group events. +<<<<<<< HEAD +======= +.. clicmd:: debug zebra srv6 + + Segment Routing for IPv6 dataplane debugging. + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Scripting ========= diff --git a/docker/ubuntu-ci/Dockerfile b/docker/ubuntu-ci/Dockerfile index 5c4649dc325c..2a3439af4a69 100644 --- a/docker/ubuntu-ci/Dockerfile +++ b/docker/ubuntu-ci/Dockerfile @@ -84,10 +84,18 @@ RUN apt update && apt upgrade -y && \ python3 -m pip install xmltodict && \ python3 -m pip install git+https://github.com/Exa-Networks/exabgp@0659057837cd6c6351579e9f0fa47e9fb7de7311 +<<<<<<< HEAD RUN groupadd -r -g 92 frr && \ groupadd -r -g 85 frrvty && \ adduser --system --ingroup frr --home /home/frr \ --gecos "FRR suite" --shell /bin/bash frr && \ +======= +ARG UID=1000 +RUN groupadd -r -g 92 frr && \ + groupadd -r -g 85 frrvty && \ + adduser --system --ingroup frr --home /home/frr \ + --gecos "FRR suite" -u $UID --shell /bin/bash frr && \ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) usermod -a -G frrvty frr && \ useradd -d /var/run/exabgp/ -s /bin/false exabgp && \ echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \ diff --git a/fpm/fpm.h b/fpm/fpm.h index 70c0df57157e..7c112c4e2e33 100644 --- a/fpm/fpm.h +++ b/fpm/fpm.h @@ -65,7 +65,11 @@ /* * Largest message that can be sent to or received from the FPM. */ +<<<<<<< HEAD #define FPM_MAX_MSG_LEN 4096 +======= +#define FPM_MAX_MSG_LEN MAX(MULTIPATH_NUM * 32, 4096) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #ifdef __SUNPRO_C #pragma pack(1) diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index fa1ce3007f8a..7dac4e489271 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -851,11 +851,19 @@ void isis_circuit_down(struct isis_circuit *circuit) isis_dr_resign(circuit, 1); circuit->u.bc.is_dr[0] = 0; } +<<<<<<< HEAD +======= + circuit->u.bc.run_dr_elect[0] = 0; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) memset(circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1); if (circuit->u.bc.is_dr[1]) { isis_dr_resign(circuit, 2); circuit->u.bc.is_dr[1] = 0; } +<<<<<<< HEAD +======= + circuit->u.bc.run_dr_elect[1] = 0; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1); memset(circuit->u.bc.snpa, 0, ETH_ALEN); diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index d588af314c11..69c5c3b6db9d 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -119,6 +119,13 @@ static void lsp_destroy(struct isis_lsp *lsp) lsp_clear_data(lsp); if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) { +<<<<<<< HEAD +======= + /* Only non-pseudo nodes and non-fragment LSPs can delete nodes. */ + if (!LSP_PSEUDO_ID(lsp->hdr.lsp_id)) + isis_dynhn_remove(lsp->area->isis, lsp->hdr.lsp_id); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (lsp->lspu.frags) { lsp_remove_frags(&lsp->area->lspdb[lsp->level - 1], lsp->lspu.frags); @@ -2209,10 +2216,13 @@ void lsp_tick(struct event *thread) &area->lspdb[level], next); +<<<<<<< HEAD if (!LSP_PSEUDO_ID(lsp->hdr.lsp_id)) isis_dynhn_remove(area->isis, lsp->hdr.lsp_id); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) lspdb_del(&area->lspdb[level], lsp); lsp_destroy(lsp); lsp = NULL; diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 23238d314a20..df847f434eef 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -231,7 +231,12 @@ static int process_p2p_hello(struct iih_info *iih) return ISIS_OK; } } +<<<<<<< HEAD if (!adj || adj->level != iih->calculated_type) { +======= + if (!adj || adj->level != iih->calculated_type || + !(iih->circuit->is_type & iih->circ_type)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!adj) { adj = isis_new_adj(iih->sys_id, NULL, iih->calculated_type, iih->circuit); diff --git a/isisd/isis_route.h b/isisd/isis_route.h index 4d49a5ae9cf5..1bffecb3f252 100644 --- a/isisd/isis_route.h +++ b/isisd/isis_route.h @@ -12,6 +12,10 @@ #ifndef _ZEBRA_ISIS_ROUTE_H #define _ZEBRA_ISIS_ROUTE_H +<<<<<<< HEAD +======= +#include "lib/table.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "lib/nexthop.h" struct isis_nexthop { diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 8fc0f144b203..bef10c1ed498 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -3258,6 +3258,10 @@ DEFUN(show_isis_route, show_isis_route_cmd, json_object *json = NULL, *json_vrf = NULL; uint8_t algorithm = SR_ALGORITHM_SPF; +<<<<<<< HEAD +======= + ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (argv_find(argv, argc, "level-1", &idx)) levels = ISIS_LEVEL1; else if (argv_find(argv, argc, "level-2", &idx)) @@ -3269,7 +3273,10 @@ DEFUN(show_isis_route, show_isis_route_cmd, vty_out(vty, "IS-IS Routing Process not enabled\n"); return CMD_SUCCESS; } +<<<<<<< HEAD ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (argv_find(argv, argc, "prefix-sid", &idx)) prefix_sid = true; @@ -3520,6 +3527,10 @@ DEFUN(show_isis_frr_summary, show_isis_frr_summary_cmd, bool all_vrf = false; int idx = 0; +<<<<<<< HEAD +======= + ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (argv_find(argv, argc, "level-1", &idx)) levels = ISIS_LEVEL1; else if (argv_find(argv, argc, "level-2", &idx)) @@ -3531,7 +3542,10 @@ DEFUN(show_isis_frr_summary, show_isis_frr_summary_cmd, vty_out(vty, "IS-IS Routing Process not enabled\n"); return CMD_SUCCESS; } +<<<<<<< HEAD ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (all_vrf) { for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index b5caf396c17c..48276dca73fc 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -7993,7 +7993,11 @@ struct isis_router_cap *isis_tlvs_init_router_capability(struct isis_tlvs *tlvs) tlvs->router_cap = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->router_cap)); /* init SR algo list content to the default value */ +<<<<<<< HEAD for (int i = 0; i < SR_ALGORITHM_COUNT; i++) +======= + for (int i = 1; i < SR_ALGORITHM_COUNT; i++) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tlvs->router_cap->algo[i] = SR_ALGORITHM_UNSET; return tlvs->router_cap; diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c index 0d25f6610934..83a2fa1f8524 100644 --- a/isisd/isis_vty_fabricd.c +++ b/isisd/isis_vty_fabricd.c @@ -218,6 +218,7 @@ DEFUN (ip_router_isis, if (!area) isis_area_create(area_tag, VRF_DEFAULT_NAME); +<<<<<<< HEAD if (!circuit) { circuit = isis_circuit_new(ifp, area_tag); @@ -229,6 +230,11 @@ DEFUN (ip_router_isis, } } +======= + if (!circuit) + circuit = isis_circuit_new(ifp, area_tag); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; if (af[2] != '\0') ipv6 = true; diff --git a/isisd/isisd.c b/isisd/isisd.c index 2863fd913f8f..23bb3a896eac 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -2366,35 +2366,59 @@ static void common_isis_summary_json(struct json_object *json, struct isis *isis) { int level; +<<<<<<< HEAD json_object *areas_json, *area_json, *tx_pdu_json, *rx_pdu_json, *levels_json, *level_json; +======= + json_object *vrf_json, *areas_json, *area_json, *tx_pdu_json, *rx_pdu_json, *levels_json, + *level_json; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct listnode *node, *node2; struct isis_area *area; time_t cur; char uptime[MONOTIME_STRLEN]; char stier[5]; +<<<<<<< HEAD json_object_string_add(json, "vrf", isis->name); json_object_int_add(json, "process-id", isis->process_id); if (isis->sysid_set) json_object_string_addf(json, "system-id", "%pSY", isis->sysid); +======= + vrf_json = json_object_new_object(); + json_object_string_add(vrf_json, "vrf", isis->name); + json_object_int_add(vrf_json, "process-id", isis->process_id); + if (isis->sysid_set) + json_object_string_addf(vrf_json, "system-id", "%pSY", isis->sysid); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) cur = time(NULL); cur -= isis->uptime; frrtime_to_interval(cur, uptime, sizeof(uptime)); +<<<<<<< HEAD json_object_string_add(json, "up-time", uptime); if (isis->area_list) json_object_int_add(json, "number-areas", isis->area_list->count); areas_json = json_object_new_array(); json_object_object_add(json, "areas", areas_json); +======= + json_object_string_add(vrf_json, "up-time", uptime); + if (isis->area_list) + json_object_int_add(vrf_json, "number-areas", isis->area_list->count); + areas_json = json_object_new_array(); + json_object_object_add(vrf_json, "areas", areas_json); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { area_json = json_object_new_object(); json_object_string_add(area_json, "area", area->area_tag ? area->area_tag : "null"); +<<<<<<< HEAD +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (fabricd) { uint8_t tier = fabricd_tier(area); snprintfrr(stier, sizeof(stier), "%s", &tier); @@ -2471,6 +2495,10 @@ static void common_isis_summary_json(struct json_object *json, } json_object_array_add(areas_json, area_json); } +<<<<<<< HEAD +======= + json_object_array_add(json, vrf_json); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static void common_isis_summary_vty(struct vty *vty, struct isis *isis) @@ -2573,6 +2601,7 @@ static void common_isis_summary_vty(struct vty *vty, struct isis *isis) } } +<<<<<<< HEAD static void common_isis_summary(struct vty *vty, struct json_object *json, struct isis *isis) { @@ -2580,6 +2609,29 @@ static void common_isis_summary(struct vty *vty, struct json_object *json, common_isis_summary_json(json, isis); } else { common_isis_summary_vty(vty, isis); +======= +static void common_isis_summary(struct vty *vty, struct json_object *json, const char *vrf_name, + bool all_vrf) +{ + struct listnode *node; + struct isis *isis; + + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { + if (json) + common_isis_summary_json(json, isis); + else + common_isis_summary_vty(vty, isis); + } + } else { + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) { + if (json) + common_isis_summary_json(json, isis); + else + common_isis_summary_vty(vty, isis); + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -2590,6 +2642,7 @@ DEFUN(show_isis_summary, show_isis_summary_cmd, "json output\n" "summary\n") { +<<<<<<< HEAD struct listnode *node; int idx_vrf = 0; struct isis *isis; @@ -2597,12 +2650,20 @@ DEFUN(show_isis_summary, show_isis_summary_cmd, bool all_vrf = false; bool uj = use_json(argc, argv); json_object *json = NULL; +======= + int idx_vrf = 0; + const char *vrf_name = VRF_DEFAULT_NAME; + bool all_vrf = false; + bool uj = use_json(argc, argv); + json_object *json = NULL, *vrfs_json = NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) if (!im) { vty_out(vty, PROTO_NAME " is not running\n"); return CMD_SUCCESS; } +<<<<<<< HEAD if (uj) json = json_object_new_object(); @@ -2615,6 +2676,15 @@ DEFUN(show_isis_summary, show_isis_summary_cmd, isis = isis_lookup_by_vrfname(vrf_name); if (isis != NULL) common_isis_summary(vty, json, isis); +======= + if (uj) { + json = json_object_new_object(); + vrfs_json = json_object_new_array(); + json_object_object_add(json, "vrfs", vrfs_json); + } + + common_isis_summary(vty, vrfs_json, vrf_name, all_vrf); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (uj) vty_json(vty, json); diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index 6e844c0aa18d..4aab9a507606 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -459,6 +459,11 @@ static void ldpe_dispatch_main(struct event *thread) tnbr_update_all(AF_UNSPEC); break; case IMSG_RECONF_CONF: +<<<<<<< HEAD +======= + if (nconf) + ldp_clear_config(nconf); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if ((nconf = malloc(sizeof(struct ldpd_conf))) == NULL) fatal(NULL); memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); diff --git a/lib/command.h b/lib/command.h index f369a35243f6..eaa6da0aa138 100644 --- a/lib/command.h +++ b/lib/command.h @@ -84,6 +84,10 @@ enum node_type { CONFIG_NODE, /* Config node. Default mode of config file. */ PREFIX_NODE, /* ip prefix-list node. */ PREFIX_IPV6_NODE, /* ipv6 prefix-list node. */ +<<<<<<< HEAD +======= + RMAP_NODE, /* Route map node. */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) LIB_DEBUG_NODE, /* frrlib debug node. */ DEBUG_NODE, /* Debug node. */ VRF_DEBUG_NODE, /* Vrf Debug node. */ @@ -136,7 +140,10 @@ enum node_type { AS_LIST_NODE, /* AS list node. */ COMMUNITY_LIST_NODE, /* Community list node. */ COMMUNITY_ALIAS_NODE, /* Community alias node. */ +<<<<<<< HEAD RMAP_NODE, /* Route map node. */ +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) PBRMAP_NODE, /* PBR map node. */ SMUX_NODE, /* SNMP configuration node. */ DUMP_NODE, /* Packet dump node. */ diff --git a/lib/csv.c b/lib/csv.c index fdd89a0c7a99..96d3d869ff3e 100644 --- a/lib/csv.c +++ b/lib/csv.c @@ -573,7 +573,11 @@ void csv_decode(csv_t *csv, char *inbuf) log_error("field str malloc failed\n"); return; } +<<<<<<< HEAD strncpy(rec->record, buf, pos - buf + 1); +======= + memcpy(rec->record, buf, MIN(pos - buf + 1, csv->buflen - 1)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } rec->rec_len = pos - buf + 1; /* decode record into fields */ diff --git a/lib/defun_lex.l b/lib/defun_lex.l index 3104e48063b5..2363c6df5ede 100644 --- a/lib/defun_lex.l +++ b/lib/defun_lex.l @@ -157,6 +157,12 @@ SPECIAL [(),] %% +<<<<<<< HEAD +======= +#else +extern int def_yylex(void); +extern int def_yylex_destroy(void); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #endif /* __clang_analyzer__ */ static int yylex_clr(char **retbuf) diff --git a/lib/event.c b/lib/event.c index d925d0d5f0fc..94a5a3983a35 100644 --- a/lib/event.c +++ b/lib/event.c @@ -669,6 +669,7 @@ static void thread_array_free(struct event_loop *m, struct event **thread_array) XFREE(MTYPE_EVENT_POLL, thread_array); } +<<<<<<< HEAD /* * event_master_free_unused * @@ -687,6 +688,8 @@ void event_master_free_unused(struct event_loop *m) } } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Stop thread scheduler. */ void event_master_free(struct event_loop *m) { @@ -793,7 +796,10 @@ static struct event *thread_get(struct event_loop *m, uint8_t type, thread = XCALLOC(MTYPE_THREAD, sizeof(struct event)); /* mutex only needs to be initialized at struct creation. */ pthread_mutex_init(&thread->mtx, NULL); +<<<<<<< HEAD m->alloc++; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } thread->type = type; @@ -832,10 +838,13 @@ static struct event *thread_get(struct event_loop *m, uint8_t type, static void thread_free(struct event_loop *master, struct event *thread) { +<<<<<<< HEAD /* Update statistics. */ assert(master->alloc > 0); master->alloc--; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Free allocated resources. */ pthread_mutex_destroy(&thread->mtx); XFREE(MTYPE_THREAD, thread); @@ -979,7 +988,11 @@ void _event_add_read_write(const struct xref_eventsched *xref, * if we already have a pollfd for our file descriptor, find and * use it */ +<<<<<<< HEAD for (nfds_t i = 0; i < m->handler.pfdcount; i++) +======= + for (nfds_t i = 0; i < m->handler.pfdcount; i++) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (m->handler.pfds[i].fd == fd) { queuepos = i; @@ -993,6 +1006,18 @@ void _event_add_read_write(const struct xref_eventsched *xref, #endif break; } +<<<<<<< HEAD +======= + /* + * We are setting the fd = -1 for the + * case when a read/write event is going + * away. if we find a -1 we can stuff it + * into that spot, so note it + */ + if (m->handler.pfds[i].fd == -1 && queuepos == m->handler.pfdcount) + queuepos = i; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* make sure we have room for this fd + pipe poker fd */ assert(queuepos + 1 < m->handler.pfdsize); @@ -1269,6 +1294,17 @@ static void cancel_arg_helper(struct event_loop *master, for (i = 0; i < master->handler.pfdcount;) { pfd = master->handler.pfds + i; +<<<<<<< HEAD +======= + /* + * Skip this spot, nothing here to see + */ + if (pfd->fd == -1) { + i++; + continue; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (pfd->events & POLLIN) t = master->read[pfd->fd]; else @@ -1590,6 +1626,15 @@ static int thread_process_io_helper(struct event_loop *m, struct event *thread, * we should. */ m->handler.pfds[pos].events &= ~(state); +<<<<<<< HEAD +======= + /* + * ppoll man page says that a fd of -1 causes the particular + * array item to be skipped. So let's skip it + */ + if (m->handler.pfds[pos].events == 0) + m->handler.pfds[pos].fd = -1; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!thread) { if ((actual_state & (POLLHUP|POLLIN)) != POLLHUP) diff --git a/lib/frrevent.h b/lib/frrevent.h index 94640a76b70f..387e5b987b6c 100644 --- a/lib/frrevent.h +++ b/lib/frrevent.h @@ -85,7 +85,10 @@ struct event_loop { int io_pipe[2]; int fd_limit; struct fd_handler handler; +<<<<<<< HEAD unsigned long alloc; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) long selectpoll_timeout; bool spin; bool handle_signals; @@ -227,7 +230,10 @@ static inline unsigned long timeval_elapsed(struct timeval a, struct timeval b) extern struct event_loop *event_master_create(const char *name); void event_master_set_name(struct event_loop *master, const char *name); extern void event_master_free(struct event_loop *m); +<<<<<<< HEAD extern void event_master_free_unused(struct event_loop *m); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern void _event_add_read_write(const struct xref_eventsched *xref, struct event_loop *master, diff --git a/lib/if.c b/lib/if.c index 8f15230f2334..7992f8f43b4d 100644 --- a/lib/if.c +++ b/lib/if.c @@ -1002,12 +1002,15 @@ void if_terminate(struct vrf *vrf) while (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) { ifp = RB_ROOT(if_name_head, &vrf->ifaces_by_name); +<<<<<<< HEAD if (ifp->node) { ifp->node->info = NULL; route_unlock_node(ifp->node); ifp->node = NULL; } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if_delete(&ifp); } } diff --git a/lib/if.h b/lib/if.h index 0dc56bd21098..9a29a95b7cb7 100644 --- a/lib/if.h +++ b/lib/if.h @@ -295,8 +295,11 @@ struct interface { struct if_data stats; #endif /* HAVE_NET_RT_IFLIST */ +<<<<<<< HEAD struct route_node *node; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; /* diff --git a/lib/libfrr.c b/lib/libfrr.c index 313fe99fd3ae..af0193699733 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -1239,10 +1239,13 @@ void frr_early_fini(void) void frr_fini(void) { +<<<<<<< HEAD FILE *fp; char filename[128]; int have_leftovers = 0; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) hook_call(frr_fini); vty_terminate(); @@ -1263,12 +1266,31 @@ void frr_fini(void) event_master_free(master); master = NULL; zlog_tls_buffer_fini(); +<<<<<<< HEAD zlog_fini(); +======= + + if (0) { + /* this is intentionally disabled. zlog remains running until + * exit(), so even the very last item done during shutdown can + * have its zlog() messages written out. + * + * Yes this causes memory leaks. They are explicitly marked + * with DEFINE_MGROUP_ACTIVEATEXIT, which is only used for + * log target memory allocations, and excluded from leak + * reporting at shutdown. This is strongly preferable over + * just discarding error messages at shutdown. + */ + zlog_fini(); + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* frrmod_init -> nothing needed / hooks */ rcu_shutdown(); frrmod_terminate(); +<<<<<<< HEAD /* also log memstats to stderr when stderr goes to a file*/ if (debug_memstats_at_exit || !isatty(STDERR_FILENO)) have_leftovers = log_memstats(stderr, di->name); @@ -1289,6 +1311,9 @@ void frr_fini(void) log_memstats(fp, di->name); fclose(fp); } +======= + log_memstats(di->name, debug_memstats_at_exit); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } struct json_object *frr_daemon_state_load(void) diff --git a/lib/libospf.h b/lib/libospf.h index 8a208beb3c33..6b10f8fbb020 100644 --- a/lib/libospf.h +++ b/lib/libospf.h @@ -27,8 +27,14 @@ extern "C" { #else #define OSPF_LS_REFRESH_TIME 1800 #endif +<<<<<<< HEAD #define OSPF_MIN_LS_INTERVAL 5000 /* msec */ #define OSPF_MIN_LS_ARRIVAL 1000 /* in milliseconds */ +======= +#define OSPF_MIN_LS_INTERVAL 5000 /* milliseconds */ +#define OSPF_MIN_LS_ARRIVAL 1000 /* milliseconds */ +#define OSPF_MIN_LS_ARRIVAL_MAX 5000 /* milliseconds */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #define OSPF_LSA_INITIAL_AGE 0 /* useful for debug */ #define OSPF_LSA_MAXAGE 3600 #define OSPF_CHECK_AGE 300 diff --git a/lib/log.c b/lib/log.c index 04b789b5da5d..aa29217a448e 100644 --- a/lib/log.c +++ b/lib/log.c @@ -306,7 +306,11 @@ void memory_oom(size_t size, const char *name) "out of memory: failed to allocate %zu bytes for %s object", size, name); zlog_backtrace(LOG_CRIT); +<<<<<<< HEAD log_memstats(stderr, "log"); +======= + log_memstats(zlog_progname, true); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) abort(); } diff --git a/lib/memory.c b/lib/memory.c index ac39516edd75..86b768dbf314 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -148,6 +148,7 @@ int qmem_walk(qmem_walk_fn *func, void *arg) } struct exit_dump_args { +<<<<<<< HEAD FILE *fp; const char *prefix; int error; @@ -178,5 +179,110 @@ int log_memstats(FILE *fp, const char *prefix) { struct exit_dump_args eda = {.fp = fp, .prefix = prefix, .error = 0}; qmem_walk(qmem_exit_walker, &eda); +======= + const char *daemon_name; + bool do_log; + bool do_file; + bool do_stderr; + int error; + FILE *fp; + struct memgroup *last_mg; +}; + +static void qmem_exit_fopen(struct exit_dump_args *eda) +{ + char filename[128]; + + if (eda->fp || !eda->do_file || !eda->daemon_name) + return; + + snprintf(filename, sizeof(filename), "/tmp/frr-memstats-%s-%llu-%llu", eda->daemon_name, + (unsigned long long)getpid(), (unsigned long long)time(NULL)); + eda->fp = fopen(filename, "w"); + + if (!eda->fp) { + zlog_err("failed to open memstats dump file %pSQq: %m", filename); + /* don't try opening file over and over again */ + eda->do_file = false; + } +} + +static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt) +{ + struct exit_dump_args *eda = arg; + const char *prefix = eda->daemon_name ?: "NONE"; + char size[32]; + + if (!mt) + /* iterator calls mg=X, mt=NULL first */ + return 0; + + if (!mt->n_alloc) + return 0; + + if (mt->size != SIZE_VAR) + snprintf(size, sizeof(size), "%10zu", mt->size); + else + snprintf(size, sizeof(size), "(variably sized)"); + + if (mg->active_at_exit) { + /* not an error - this memgroup has allocations remain active + * at exit. Only printed to zlog_debug. + */ + if (!eda->do_log) + return 0; + + if (eda->last_mg != mg) { + zlog_debug("showing active allocations in memory group %s (not an error)", + mg->name); + eda->last_mg = mg; + } + zlog_debug("memstats: %-30s: %6zu * %s", mt->name, mt->n_alloc, size); + return 0; + } + + eda->error++; + if (eda->do_file) + qmem_exit_fopen(eda); + + if (eda->last_mg != mg) { + if (eda->do_log) + zlog_warn("showing active allocations in memory group %s", mg->name); + if (eda->do_stderr) + fprintf(stderr, "%s: showing active allocations in memory group %s\n", + prefix, mg->name); + if (eda->fp) + fprintf(eda->fp, "%s: showing active allocations in memory group %s\n", + prefix, mg->name); + eda->last_mg = mg; + } + + if (eda->do_log) + zlog_warn("memstats: %-30s: %6zu * %s", mt->name, mt->n_alloc, size); + if (eda->do_stderr) + fprintf(stderr, "%s: memstats: %-30s: %6zu * %s\n", prefix, mt->name, mt->n_alloc, + size); + if (eda->fp) + fprintf(eda->fp, "%s: memstats: %-30s: %6zu * %s\n", prefix, mt->name, mt->n_alloc, + size); + return 0; +} + +int log_memstats(const char *daemon_name, bool enabled) +{ + struct exit_dump_args eda = { + .daemon_name = daemon_name, + .do_log = enabled, + .do_file = enabled, + .do_stderr = enabled || !isatty(STDERR_FILENO), + .error = 0, + }; + + qmem_walk(qmem_exit_walker, &eda); + if (eda.fp) + fclose(eda.fp); + if (eda.error && eda.do_log) + zlog_warn("exiting with %d leaked MTYPEs", eda.error); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return eda.error; } diff --git a/lib/memory.h b/lib/memory.h index 8e8c61da04d0..960186a2baa8 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -67,6 +67,11 @@ struct memgroup { * but MGROUP_* aren't. */ +<<<<<<< HEAD +======= +/* clang-format off */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #define DECLARE_MGROUP(name) extern struct memgroup _mg_##name #define _DEFINE_MGROUP(mname, desc, ...) \ struct memgroup _mg_##mname _DATA_SECTION("mgroups") = { \ @@ -75,6 +80,10 @@ struct memgroup { .next = NULL, \ .insert = NULL, \ .ref = NULL, \ +<<<<<<< HEAD +======= + __VA_ARGS__ \ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }; \ static void _mginit_##mname(void) __attribute__((_CONSTRUCTOR(1000))); \ static void _mginit_##mname(void) \ @@ -136,6 +145,11 @@ struct memgroup { DEFINE_MTYPE_ATTR(group, name, static, desc) \ /* end */ +<<<<<<< HEAD +======= +/* clang-format on */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DECLARE_MGROUP(LIB); DECLARE_MTYPE(TMP); DECLARE_MTYPE(TMP_TTABLE); @@ -176,8 +190,12 @@ static inline size_t mtype_stats_alloc(struct memtype *mt) * last value from qmem_walk_fn. */ typedef int qmem_walk_fn(void *arg, struct memgroup *mg, struct memtype *mt); extern int qmem_walk(qmem_walk_fn *func, void *arg); +<<<<<<< HEAD extern int log_memstats(FILE *fp, const char *); #define log_memstats_stderr(prefix) log_memstats(stderr, prefix) +======= +extern int log_memstats(const char *daemon_name, bool enabled); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern __attribute__((__noreturn__)) void memory_oom(size_t size, const char *name); diff --git a/lib/netns_linux.c b/lib/netns_linux.c index 8fa4bc6fe0f7..c10fcc9f6e2f 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -258,7 +258,11 @@ static void ns_disable_internal(struct ns *ns) if (ns_master.ns_disable_hook) (*ns_master.ns_disable_hook)(ns); +<<<<<<< HEAD if (have_netns()) +======= + if (have_netns() && ns->fd >= 0) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) close(ns->fd); ns->fd = -1; diff --git a/lib/nexthop.c b/lib/nexthop.c index 98b05295b996..9678177b53eb 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -581,6 +581,35 @@ void nexthop_del_labels(struct nexthop *nexthop) nexthop->nh_label_type = ZEBRA_LSP_NONE; } +<<<<<<< HEAD +======= +void nexthop_change_labels(struct nexthop *nexthop, struct mpls_label_stack *new_stack) +{ + struct mpls_label_stack *nh_label_tmp; + uint32_t i; + + /* Enforce limit on label stack size */ + if (new_stack->num_labels > MPLS_MAX_LABELS) + new_stack->num_labels = MPLS_MAX_LABELS; + + /* Resize the array to accommodate the new label stack */ + if (new_stack->num_labels > nexthop->nh_label->num_labels) { + nh_label_tmp = XREALLOC(MTYPE_NH_LABEL, nexthop->nh_label, + sizeof(struct mpls_label_stack) + + new_stack->num_labels * sizeof(mpls_label_t)); + if (nh_label_tmp) { + nexthop->nh_label = nh_label_tmp; + nexthop->nh_label->num_labels = new_stack->num_labels; + } else + new_stack->num_labels = nexthop->nh_label->num_labels; + } + + /* Copy the label stack into the array */ + for (i = 0; i < new_stack->num_labels; i++) + nexthop->nh_label->label[i] = new_stack->label[i]; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void nexthop_add_srv6_seg6local(struct nexthop *nexthop, uint32_t action, const struct seg6local_context *ctx) { diff --git a/lib/nexthop.h b/lib/nexthop.h index 02ea4d96f2df..5bb3e665eae4 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -154,6 +154,11 @@ void nexthops_free(struct nexthop *nexthop); void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t ltype, uint8_t num_labels, const mpls_label_t *labels); void nexthop_del_labels(struct nexthop *); +<<<<<<< HEAD +======= +void nexthop_change_labels(struct nexthop *nexthop, struct mpls_label_stack *new_stack); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void nexthop_add_srv6_seg6local(struct nexthop *nexthop, uint32_t action, const struct seg6local_context *ctx); void nexthop_del_srv6_seg6local(struct nexthop *nexthop); diff --git a/lib/ntop.c b/lib/ntop.c index 89b4d5ecdcab..23e9f4fce8b3 100644 --- a/lib/ntop.c +++ b/lib/ntop.c @@ -116,7 +116,22 @@ const char *frr_inet_ntop(int af, const void * restrict src, best = i - curlen; bestlen = curlen; } +<<<<<<< HEAD /* do we want ::ffff:A.B.C.D? */ +======= + if (best == 0 && bestlen == 5 && b[10] == 0xff && b[11] == 0xff) { + /* ::ffff:A.B.C.D */ + *o++ = ':'; + *o++ = ':'; + *o++ = 'f'; + *o++ = 'f'; + *o++ = 'f'; + *o++ = 'f'; + *o++ = ':'; + b += 12; + goto inet4; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (best == 0 && bestlen == 6) { *o++ = ':'; *o++ = ':'; diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c index ac800be0a5ef..a25aa39f1652 100644 --- a/lib/ptm_lib.c +++ b/lib/ptm_lib.c @@ -3,9 +3,13 @@ * Copyright (C) 2015 Cumulus Networks, Inc. */ +<<<<<<< HEAD #ifdef HAVE_CONFIG_H #include "config.h" #endif +======= +#include +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include #include @@ -308,6 +312,7 @@ static int _ptm_lib_read_ptm_socket(int fd, char *buf, int len) while (bytes_read != len) { rc = recv(fd, (void *)(buf + bytes_read), (len - bytes_read), MSG_DONTWAIT); +<<<<<<< HEAD if (rc <= 0) { if (errno && (errno != EAGAIN) && (errno != EWOULDBLOCK)) { @@ -324,6 +329,20 @@ static int _ptm_lib_read_ptm_socket(int fd, char *buf, int len) return (bytes_read); } break; +======= + if (rc < 0 && (errno != EAGAIN) && (errno != EWOULDBLOCK)) { + ERRLOG("fatal recv error(%s), closing connection, rc %d\n", strerror(errno), + rc); + return (rc); + } else if (rc <= 0) { + if (retries++ < 2) { + usleep(10000); + continue; + } + DLOG("max retries - recv error(%d - %s) bytes read %d (%d)\n", errno, + strerror(errno), bytes_read, len); + return (bytes_read); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else { bytes_read += rc; } @@ -454,7 +473,11 @@ ptm_lib_handle_t *ptm_lib_register(char *client_name, ptm_cmd_cb cmd_cb, hdl = calloc(1, sizeof(*hdl)); if (hdl) { +<<<<<<< HEAD strncpy(hdl->client_name, client_name, PTMLIB_MAXNAMELEN - 1); +======= + strlcpy(hdl->client_name, client_name, sizeof(hdl->client_name)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) hdl->cmd_cb = cmd_cb; hdl->notify_cb = notify_cb; hdl->response_cb = response_cb; diff --git a/lib/routemap.c b/lib/routemap.c index ea917ebd8c73..369b78e0091d 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -875,6 +875,31 @@ void route_map_walk_update_list(void (*route_map_update_fn)(char *name)) } } +<<<<<<< HEAD +======= +static const char *route_map_action_reason2str(enum route_map_action_reason reason) +{ + switch (reason) { + case route_map_action_none: + return "none"; + case route_map_action_map_null: + return "route-map is null"; + case route_map_action_no_index: + return "no index"; + case route_map_action_next_deny: + return "next statement is deny"; + case route_map_action_exit: + return "exit policy"; + case route_map_action_goto_null: + return "goto index is null"; + case route_map_action_index_deny: + return "deny index"; + } + + return "Invalid reason"; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Return route map's type string. */ static const char *route_map_type_str(enum route_map_type type) { @@ -941,11 +966,20 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map, json_object_boolean_add(json_rmap, "processedChange", map->to_be_processed); json_object_object_add(json_rmap, "rules", json_rules); +<<<<<<< HEAD } else { vty_out(vty, "route-map: %s Invoked: %" PRIu64 " Optimization: %s Processed Change: %s\n", map->name, map->applied - map->applied_clear, +======= + json_object_int_add(json_rmap, "cpuTimeMS", map->cputime / 1000); + } else { + vty_out(vty, + "route-map: %s Invoked: %" PRIu64 + " (%zu milliseconds total) Optimization: %s Processed Change: %s\n", + map->name, map->applied - map->applied_clear, map->cputime / 1000, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) map->optimization_disabled ? "disabled" : "enabled", map->to_be_processed ? "true" : "false"); } @@ -967,6 +1001,10 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map, json_object_int_add(json_rule, "invoked", index->applied - index->applied_clear); +<<<<<<< HEAD +======= + json_object_int_add(json_rule, "cpuTimeMS", index->cputime / 1000); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Description */ if (index->description) @@ -1018,9 +1056,16 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map, json_object_string_add(json_rule, "action", action); } else { +<<<<<<< HEAD vty_out(vty, " %s, sequence %d Invoked %" PRIu64 "\n", route_map_type_str(index->type), index->pref, index->applied - index->applied_clear); +======= + vty_out(vty, + " %s, sequence %d Invoked %" PRIu64 " (%zu milliseconds total)\n", + route_map_type_str(index->type), index->pref, + index->applied - index->applied_clear, index->cputime / 1000); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Description */ if (index->description) @@ -2548,6 +2593,13 @@ route_map_result_t route_map_apply_ext(struct route_map *map, struct route_map_index *index = NULL; struct route_map_rule *set = NULL; bool skip_match_clause = false; +<<<<<<< HEAD +======= + RUSAGE_T mbefore, mafter; + RUSAGE_T ibefore, iafter; + unsigned long cputime; + enum route_map_action_reason reason = route_map_action_none; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (recursion > RMAP_RECURSION_LIMIT) { if (map) @@ -2565,11 +2617,21 @@ route_map_result_t route_map_apply_ext(struct route_map *map, if (map) map->applied++; ret = RMAP_DENYMATCH; +<<<<<<< HEAD +======= + reason = route_map_action_map_null; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) goto route_map_apply_end; } map->applied++; +<<<<<<< HEAD +======= + GETRUSAGE(&mbefore); + ibefore = mbefore; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (prefix->family == AF_EVPN) { index = map->head; } else { @@ -2580,6 +2642,15 @@ route_map_result_t route_map_apply_ext(struct route_map *map, if (index) { index->applied++; +<<<<<<< HEAD +======= + + GETRUSAGE(&iafter); + event_consumed_time(&iafter, &ibefore, &cputime); + index->cputime += cputime; + ibefore = iafter; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))) zlog_debug( "Best match route-map: %s, sequence: %d for pfx: %pFX, result: %s", @@ -2599,6 +2670,10 @@ route_map_result_t route_map_apply_ext(struct route_map *map, ret = RMAP_PERMITMATCH; else ret = RMAP_DENYMATCH; +<<<<<<< HEAD +======= + reason = route_map_action_no_index; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) goto route_map_apply_end; } @@ -2686,12 +2761,23 @@ route_map_result_t route_map_apply_ext(struct route_map *map, } /* If nextrm returned 'deny', finish. */ +<<<<<<< HEAD if (ret == RMAP_DENYMATCH) goto route_map_apply_end; +======= + if (ret == RMAP_DENYMATCH) { + reason = route_map_action_next_deny; + goto route_map_apply_end; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } switch (index->exitpolicy) { case RMAP_EXIT: +<<<<<<< HEAD +======= + reason = route_map_action_exit; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) goto route_map_apply_end; case RMAP_NEXT: continue; @@ -2707,6 +2793,10 @@ route_map_result_t route_map_apply_ext(struct route_map *map, } if (next == NULL) { /* No clauses match! */ +<<<<<<< HEAD +======= + reason = route_map_action_goto_null; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) goto route_map_apply_end; } } @@ -2715,16 +2805,33 @@ route_map_result_t route_map_apply_ext(struct route_map *map, /* 'deny' */ { ret = RMAP_DENYMATCH; +<<<<<<< HEAD goto route_map_apply_end; } } +======= + reason = route_map_action_index_deny; + goto route_map_apply_end; + } + } + GETRUSAGE(&iafter); + event_consumed_time(&iafter, &ibefore, &cputime); + index->cputime += cputime; + ibefore = iafter; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } route_map_apply_end: if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP))) +<<<<<<< HEAD zlog_debug("Route-map: %s, prefix: %pFX, result: %s", (map ? map->name : "null"), prefix, route_map_result_str(ret)); +======= + zlog_debug("Route-map: %s, prefix: %pFX, result: %s, reason: %s", + (map ? map->name : "null"), prefix, route_map_result_str(ret), + route_map_action_reason2str(reason)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (pref) { if (index != NULL && ret == RMAP_PERMITMATCH) @@ -2733,6 +2840,16 @@ route_map_result_t route_map_apply_ext(struct route_map *map, *pref = 65536; } +<<<<<<< HEAD +======= + if (map) { + GETRUSAGE(&mbefore); + GETRUSAGE(&mafter); + event_consumed_time(&mafter, &mbefore, &cputime); + map->cputime += cputime; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return (ret); } @@ -3090,8 +3207,16 @@ static void clear_route_map_helper(struct route_map *map) struct route_map_index *index; map->applied_clear = map->applied; +<<<<<<< HEAD for (index = map->head; index; index = index->next) index->applied_clear = index->applied; +======= + map->cputime = 0; + for (index = map->head; index; index = index->next) { + index->applied_clear = index->applied; + index->cputime = 0; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } DEFPY (rmap_clear_counters, diff --git a/lib/routemap.h b/lib/routemap.h index dfb84ced5bae..86ada43f4c2f 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -29,6 +29,20 @@ extern uint32_t rmap_debug; /* Route map's type. */ enum route_map_type { RMAP_PERMIT, RMAP_DENY, RMAP_ANY }; +<<<<<<< HEAD +======= +/* Route-map's action reason */ +enum route_map_action_reason { + route_map_action_none, + route_map_action_map_null, + route_map_action_no_index, + route_map_action_next_deny, + route_map_action_exit, + route_map_action_goto_null, + route_map_action_index_deny, +}; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) typedef enum { RMAP_DENYMATCH, RMAP_PERMITMATCH @@ -176,6 +190,10 @@ struct route_map_index { /* Keep track how many times we've try to apply */ uint64_t applied; uint64_t applied_clear; +<<<<<<< HEAD +======= + size_t cputime; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* List of match/sets contexts. */ TAILQ_HEAD(, routemap_hook_context) rhclist; @@ -210,6 +228,10 @@ struct route_map { /* How many times have we applied this route-map */ uint64_t applied; uint64_t applied_clear; +<<<<<<< HEAD +======= + size_t cputime; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Counter to track active usage of this route-map */ uint16_t use_count; @@ -278,6 +300,10 @@ DECLARE_QOBJ_TYPE(route_map); #define IS_MATCH_SRC_VRF(C) \ (strmatch(C, "frr-bgp-route-map:source-vrf")) #define IS_MATCH_PEER(C) (strmatch(C, "frr-bgp-route-map:peer")) +<<<<<<< HEAD +======= +#define IS_MATCH_SRC_PEER(C) (strmatch(C, "frr-bgp-route-map:src-peer")) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #define IS_MATCH_AS_LIST(C) \ (strmatch(C, "frr-bgp-route-map:as-path-list")) #define IS_MATCH_MAC_LIST(C) \ diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index f64c3c2376a9..478d3cb15585 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -756,6 +756,21 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode, acl = "local"; vty_out(vty, " match peer %s\n", acl); +<<<<<<< HEAD +======= + } else if (IS_MATCH_SRC_PEER(condition)) { + acl = NULL; + ln = yang_dnode_get(dnode, + "./rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address"); + if (!ln) + ln = yang_dnode_get(dnode, + "./rmap-match-condition/frr-bgp-route-map:src-peer-ipv6-address"); + if (!ln) + ln = yang_dnode_get(dnode, + "./rmap-match-condition/frr-bgp-route-map:src-peer-interface"); + acl = yang_dnode_get_string(ln, NULL); + vty_out(vty, " match src-peer %s\n", acl); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else if (IS_MATCH_AS_LIST(condition)) { vty_out(vty, " match as-path %s\n", yang_dnode_get_string( @@ -922,13 +937,23 @@ DEFPY_YANG( DEFPY_YANG( set_metric, set_metric_cmd, +<<<<<<< HEAD "set metric <(-4294967295-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt>", +======= + "set metric <(-4294967295-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt|igp$igp|aigp$aigp>", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SET_STR "Metric value for destination routing protocol\n" "Metric value (use +/- for additions or subtractions)\n" "Assign round trip time\n" "Add round trip time\n" +<<<<<<< HEAD "Subtract round trip time\n") +======= + "Subtract round trip time\n" + "Metric value from IGP protocol\n" + "Metric value from AIGP (Accumulated IGP)\n") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { const char *xpath = "./set-action[action='frr-route-map:set-metric']"; char xpath_value[XPATH_MAXLEN]; @@ -939,6 +964,15 @@ DEFPY_YANG( snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-set-action/use-round-trip-time", xpath); snprintf(value, sizeof(value), "true"); +<<<<<<< HEAD +======= + } else if (igp) { + snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-set-action/use-igp", xpath); + snprintf(value, sizeof(value), "true"); + } else if (aigp) { + snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-set-action/use-aigp", xpath); + snprintf(value, sizeof(value), "true"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else if (artt) { snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-set-action/add-round-trip-time", xpath); @@ -1148,6 +1182,7 @@ void route_map_action_show(struct vty *vty, const struct lyd_node *dnode, if (yang_dnode_get(dnode, "./rmap-set-action/use-round-trip-time")) { vty_out(vty, " set metric rtt\n"); +<<<<<<< HEAD } else if (yang_dnode_get( dnode, "./rmap-set-action/add-round-trip-time")) { @@ -1165,6 +1200,21 @@ void route_map_action_show(struct vty *vty, const struct lyd_node *dnode, } else if (yang_dnode_get( dnode, "./rmap-set-action/subtract-metric")) { +======= + } else if (yang_dnode_get(dnode, "./rmap-set-action/use-igp")) { + vty_out(vty, " set metric igp\n"); + } else if (yang_dnode_get(dnode, "./rmap-set-action/use-aigp")) { + vty_out(vty, " set metric aigp\n"); + } else if (yang_dnode_get(dnode, "./rmap-set-action/add-round-trip-time")) { + vty_out(vty, " set metric +rtt\n"); + } else if (yang_dnode_get(dnode, "./rmap-set-action/subtract-round-trip-time")) { + vty_out(vty, " set metric -rtt\n"); + } else if (yang_dnode_get(dnode, "./rmap-set-action/add-metric")) { + vty_out(vty, " set metric +%s\n", + yang_dnode_get_string( + dnode, "./rmap-set-action/add-metric")); + } else if (yang_dnode_get(dnode, "./rmap-set-action/subtract-metric")) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vty_out(vty, " set metric -%s\n", yang_dnode_get_string( dnode, diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c index 1bba4dad47a6..fab9473eda1c 100644 --- a/lib/routemap_northbound.c +++ b/lib/routemap_northbound.c @@ -1214,6 +1214,37 @@ static int lib_route_map_entry_set_action_use_round_trip_time_destroy( } /* +<<<<<<< HEAD +======= + * XPath: /frr-route-map:lib/route-map/entry/set-action/use-igp + */ +static int lib_route_map_entry_set_action_use_igp_modify(struct nb_cb_modify_args *args) +{ + return set_action_modify(args->event, args->dnode, args->resource, "igp", args->errmsg, + args->errmsg_len); +} + +static int lib_route_map_entry_set_action_use_igp_destroy(struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_set_action_value_destroy(args); +} + +/* + * XPath: /frr-route-map:lib/route-map/entry/set-action/use-aigp + */ +static int lib_route_map_entry_set_action_use_aigp_modify(struct nb_cb_modify_args *args) +{ + return set_action_modify(args->event, args->dnode, args->resource, "aigp", args->errmsg, + args->errmsg_len); +} + +static int lib_route_map_entry_set_action_use_aigp_destroy(struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_set_action_value_destroy(args); +} + +/* +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * XPath: /frr-route-map:lib/route-map/entry/set-action/add-round-trip-time */ static int lib_route_map_entry_set_action_add_round_trip_time_modify( @@ -1517,6 +1548,23 @@ const struct frr_yang_module_info frr_route_map_info = { } }, { +<<<<<<< HEAD +======= + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/use-igp", + .cbs = { + .modify = lib_route_map_entry_set_action_use_igp_modify, + .destroy = lib_route_map_entry_set_action_use_igp_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/use-aigp", + .cbs = { + .modify = lib_route_map_entry_set_action_use_aigp_modify, + .destroy = lib_route_map_entry_set_action_use_aigp_destroy, + } + }, + { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/add-round-trip-time", .cbs = { .modify = lib_route_map_entry_set_action_add_round_trip_time_modify, diff --git a/lib/sigevent.c b/lib/sigevent.c index 3e69f280da2e..2fa0c1543e82 100644 --- a/lib/sigevent.c +++ b/lib/sigevent.c @@ -237,8 +237,23 @@ core_handler(int signo, siginfo_t *siginfo, void *context) zlog_signal(signo, "aborting...", siginfo, pc); +<<<<<<< HEAD /* dump memory stats on core */ log_memstats(stderr, "core_handler"); +======= + /* there used to be a log_memstats() call here, to dump MTYPE counters + * on a coredump. This is not possible since log_memstats is not + * AS-Safe, as it calls fopen(), fprintf(), and cousins. This can + * lead to a deadlock depending on where we crashed - very much not a + * good thing if the process just hangs there after a crash. + * + * The alarm(1) above tries to alleviate this, but that's really a + * last resort recovery. Stick with AS-safe calls here. + * + * If the fprintf() calls are removed from log_memstats(), this can be + * added back in, since writing to log with zlog_sigsafe() is AS-safe. + */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * This is a buffer flush because FRR is going down diff --git a/lib/sockunion.c b/lib/sockunion.c index c37ab1d6dd53..1ef553380c45 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -403,8 +403,12 @@ int sockunion_same(const union sockunion *su1, const union sockunion *su2) sizeof(struct in_addr)); break; case AF_INET6: +<<<<<<< HEAD ret = memcmp(&su1->sin6.sin6_addr, &su2->sin6.sin6_addr, sizeof(struct in6_addr)); +======= + ret = IPV6_ADDR_CMP(&su1->sin6.sin6_addr, &su2->sin6.sin6_addr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if ((ret == 0) && IN6_IS_ADDR_LINKLOCAL(&su1->sin6.sin6_addr)) { /* compare interface indices */ if (su1->sin6.sin6_scope_id && su2->sin6.sin6_scope_id) @@ -588,6 +592,7 @@ static void __attribute__((unused)) sockunion_print(const union sockunion *su) } } +<<<<<<< HEAD int in6addr_cmp(const struct in6_addr *addr1, const struct in6_addr *addr2) { unsigned int i; @@ -605,6 +610,8 @@ int in6addr_cmp(const struct in6_addr *addr1, const struct in6_addr *addr2) return 0; } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int sockunion_cmp(const union sockunion *su1, const union sockunion *su2) { if (su1->sa.sa_family > su2->sa.sa_family) @@ -621,7 +628,12 @@ int sockunion_cmp(const union sockunion *su1, const union sockunion *su2) return -1; } if (su1->sa.sa_family == AF_INET6) +<<<<<<< HEAD return in6addr_cmp(&su1->sin6.sin6_addr, &su2->sin6.sin6_addr); +======= + return IPV6_ADDR_CMP(&su1->sin6.sin6_addr, &su2->sin6.sin6_addr); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -727,8 +739,12 @@ int sockunion_is_null(const union sockunion *su) case AF_INET: return (su->sin.sin_addr.s_addr == 0); case AF_INET6: +<<<<<<< HEAD return !memcmp(su->sin6.sin6_addr.s6_addr, null_s6_addr, sizeof(null_s6_addr)); +======= + return !IPV6_ADDR_CMP(su->sin6.sin6_addr.s6_addr, null_s6_addr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) default: return 0; } diff --git a/lib/sockunion.h b/lib/sockunion.h index 146651225cdf..6a784aa7839a 100644 --- a/lib/sockunion.h +++ b/lib/sockunion.h @@ -93,7 +93,10 @@ enum connect_result { connect_error, connect_success, connect_in_progress }; /* Prototypes. */ extern int str2sockunion(const char *, union sockunion *); extern const char *sockunion2str(const union sockunion *, char *, size_t); +<<<<<<< HEAD int in6addr_cmp(const struct in6_addr *addr1, const struct in6_addr *addr2); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern int sockunion_cmp(const union sockunion *, const union sockunion *); extern int sockunion_same(const union sockunion *, const union sockunion *); extern unsigned int sockunion_hash(const union sockunion *); diff --git a/lib/table.c b/lib/table.c index 3bf93894ec0b..03cbbb0ac243 100644 --- a/lib/table.c +++ b/lib/table.c @@ -208,6 +208,7 @@ struct route_node *route_node_match(struct route_table *table, return NULL; } +<<<<<<< HEAD struct route_node *route_node_match_ipv4(struct route_table *table, const struct in_addr *addr) { @@ -234,6 +235,8 @@ struct route_node *route_node_match_ipv6(struct route_table *table, return route_node_match(table, &p); } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Lookup same prefix node. Return NULL when we can't find route. */ struct route_node *route_node_lookup(struct route_table *table, union prefixconstptr pu) diff --git a/lib/table.h b/lib/table.h index acfc87615429..c35046ecc7be 100644 --- a/lib/table.h +++ b/lib/table.h @@ -195,10 +195,13 @@ extern struct route_node *route_node_lookup_maynull(struct route_table *table, union prefixconstptr pu); extern struct route_node *route_node_match(struct route_table *table, union prefixconstptr pu); +<<<<<<< HEAD extern struct route_node *route_node_match_ipv4(struct route_table *table, const struct in_addr *addr); extern struct route_node *route_node_match_ipv6(struct route_table *table, const struct in6_addr *addr); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern unsigned long route_table_count(struct route_table *table); diff --git a/lib/wheel.c b/lib/wheel.c index 2520e81d4969..323efa7530fa 100644 --- a/lib/wheel.c +++ b/lib/wheel.c @@ -18,7 +18,11 @@ static int debug_timer_wheel = 0; static void wheel_timer_thread(struct event *t); +<<<<<<< HEAD static void wheel_timer_thread_helper(struct event *t) +======= +static void wheel_timer_thread(struct event *t) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct listnode *node, *nextnode; unsigned long long curr_slot; @@ -51,6 +55,7 @@ static void wheel_timer_thread_helper(struct event *t) wheel->nexttime * slots_to_skip, &wheel->timer); } +<<<<<<< HEAD static void wheel_timer_thread(struct event *t) { struct timer_wheel *wheel; @@ -60,6 +65,8 @@ static void wheel_timer_thread(struct event *t) event_execute(wheel->master, wheel_timer_thread_helper, wheel, 0, NULL); } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct timer_wheel *wheel_init(struct event_loop *master, int period, size_t slots, unsigned int (*slot_key)(const void *), @@ -70,7 +77,10 @@ struct timer_wheel *wheel_init(struct event_loop *master, int period, wheel = XCALLOC(MTYPE_TIMER_WHEEL, sizeof(struct timer_wheel)); +<<<<<<< HEAD wheel->name = XSTRDUP(MTYPE_TIMER_WHEEL, run_name); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) wheel->slot_key = slot_key; wheel->slot_run = slot_run; @@ -101,7 +111,10 @@ void wheel_delete(struct timer_wheel *wheel) EVENT_OFF(wheel->timer); XFREE(MTYPE_TIMER_WHEEL_LIST, wheel->wheel_slot_lists); +<<<<<<< HEAD XFREE(MTYPE_TIMER_WHEEL, wheel->name); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) XFREE(MTYPE_TIMER_WHEEL, wheel); } diff --git a/lib/wheel.h b/lib/wheel.h index 0d9ac1002072..aae46eefa28b 100644 --- a/lib/wheel.h +++ b/lib/wheel.h @@ -12,7 +12,10 @@ extern "C" { #endif struct timer_wheel { +<<<<<<< HEAD char *name; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct event_loop *master; int slots; long long curr_slot; diff --git a/lib/zclient.c b/lib/zclient.c index 0e832f0d8fe5..8c6db7eb9d35 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2374,7 +2374,11 @@ static bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match, STREAM_GETW(s, nhr->instance); STREAM_GETC(s, nhr->distance); STREAM_GETL(s, nhr->metric); +<<<<<<< HEAD STREAM_GETC(s, nhr->nexthop_num); +======= + STREAM_GETW(s, nhr->nexthop_num); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) for (i = 0; i < nhr->nexthop_num; i++) { if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, 0) != 0) @@ -4693,6 +4697,12 @@ void zclient_redistribute_default(int command, struct zclient *zclient, zebra_redistribute_default_send(command, zclient, afi, vrf_id); } +<<<<<<< HEAD +======= +#define ZCLIENT_QUICK_RECONNECT 1 +#define ZCLIENT_SLOW_RECONNECT 5 +#define ZCLIENT_SWITCH_TO_SLOW 30 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static void zclient_event(enum zclient_event event, struct zclient *zclient) { switch (event) { @@ -4702,11 +4712,21 @@ static void zclient_event(enum zclient_event event, struct zclient *zclient) break; case ZCLIENT_CONNECT: if (zclient_debug) +<<<<<<< HEAD zlog_debug( "zclient connect failures: %d schedule interval is now %d", zclient->fail, zclient->fail < 3 ? 10 : 60); event_add_timer(zclient->master, zclient_connect, zclient, zclient->fail < 3 ? 10 : 60, +======= + zlog_debug("zclient connect failures: %d schedule interval is now %d", + zclient->fail, + zclient->fail < ZCLIENT_SWITCH_TO_SLOW ? ZCLIENT_QUICK_RECONNECT + : ZCLIENT_SLOW_RECONNECT); + event_add_timer(zclient->master, zclient_connect, zclient, + zclient->fail < ZCLIENT_SWITCH_TO_SLOW ? ZCLIENT_QUICK_RECONNECT + : ZCLIENT_SLOW_RECONNECT, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) &zclient->t_connect); break; case ZCLIENT_READ: diff --git a/lib/zclient.h b/lib/zclient.h index 91c0c9ed6d3d..2adf53dbe27d 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -251,6 +251,7 @@ enum zebra_error_types { static inline const char *zebra_error_type2str(enum zebra_error_types type) { +<<<<<<< HEAD const char *ret = "UNKNOWN"; switch (type) { @@ -266,6 +267,18 @@ static inline const char *zebra_error_type2str(enum zebra_error_types type) } return ret; +======= + switch (type) { + case ZEBRA_UNKNOWN_ERROR: + return "ZEBRA_UNKNOWN_ERROR"; + case ZEBRA_NO_VRF: + return "ZEBRA_NO_VRF"; + case ZEBRA_INVALID_MSG_TYPE: + return "ZEBRA_INVALID_MSG_TYPE"; + } + + return "UNKNOWN"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } struct redist_proto { @@ -780,6 +793,7 @@ enum zclient_send_status { static inline const char * zapi_nhg_notify_owner2str(enum zapi_nhg_notify_owner note) { +<<<<<<< HEAD const char *ret = "UNKNOWN"; switch (note) { @@ -798,11 +812,26 @@ zapi_nhg_notify_owner2str(enum zapi_nhg_notify_owner note) } return ret; +======= + switch (note) { + case ZAPI_NHG_FAIL_INSTALL: + return "ZAPI_NHG_FAIL_INSTALL"; + case ZAPI_NHG_INSTALLED: + return "ZAPI_NHG_INSTALLED"; + case ZAPI_NHG_REMOVE_FAIL: + return "ZAPI_NHG_REMOVE_FAIL"; + case ZAPI_NHG_REMOVED: + return "ZAPI_NHG_REMOVED"; + } + + return "UNKNOWN"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static inline const char * zapi_rule_notify_owner2str(enum zapi_rule_notify_owner note) { +<<<<<<< HEAD const char *ret = "UNKNOWN"; switch (note) { @@ -821,10 +850,25 @@ zapi_rule_notify_owner2str(enum zapi_rule_notify_owner note) } return ret; +======= + switch (note) { + case ZAPI_RULE_FAIL_INSTALL: + return "ZAPI_RULE_FAIL_INSTALL"; + case ZAPI_RULE_INSTALLED: + return "ZAPI_RULE_INSTALLED"; + case ZAPI_RULE_FAIL_REMOVE: + return "ZAPI_RULE_FAIL_REMOVE"; + case ZAPI_RULE_REMOVED: + return "ZAPI_RULE_REMOVED"; + } + + return "UNKNOWN"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static inline const char *zapi_srv6_sid_notify2str(enum zapi_srv6_sid_notify note) { +<<<<<<< HEAD const char *ret = "UNKNOWN"; switch (note) { @@ -843,6 +887,20 @@ static inline const char *zapi_srv6_sid_notify2str(enum zapi_srv6_sid_notify not } return ret; +======= + switch (note) { + case ZAPI_SRV6_SID_FAIL_ALLOC: + return "ZAPI_SRV6_SID_FAIL_ALLOC"; + case ZAPI_SRV6_SID_ALLOCATED: + return "ZAPI_SRV6_SID_ALLOCATED"; + case ZAPI_SRV6_SID_FAIL_RELEASE: + return "ZAPI_SRV6_SID_FAIL_RELEASE"; + case ZAPI_SRV6_SID_RELEASED: + return "ZAPI_SRV6_SID_RELEASED"; + } + + return "UNKNOWN"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Zebra MAC types */ diff --git a/lib/zlog_5424_cli.c b/lib/zlog_5424_cli.c index 3003df542f58..001ae13f317c 100644 --- a/lib/zlog_5424_cli.c +++ b/lib/zlog_5424_cli.c @@ -674,6 +674,10 @@ static int log_5424_config_write(struct vty *vty) vty_out(vty, "log extended %s\n", cfg->name); +<<<<<<< HEAD +======= + (void)fmt_str; /* clang-SA */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) switch (cfg->cfg.fmt) { case ZLOG_FMT_5424: fmt_str = " format rfc5424"; diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index 199f4d75d4ec..93808510773f 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -933,6 +933,13 @@ static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx) if (ctx->afi != family2afi(sockunion_family(&c->remote_addr))) return; +<<<<<<< HEAD +======= + if (ctx->count && !ctx->json) + vty_out(ctx->vty, "\n"); + ctx->count++; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0])); if (c->cur.peer) sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1], @@ -985,8 +992,11 @@ static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx) if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC) vty_out(ctx->vty, "NBMA-NAT-OA-Address: %s\n", buf[2]); +<<<<<<< HEAD vty_out(ctx->vty, "\n\n"); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } DEFUN(show_ip_nhrp, show_ip_nhrp_cmd, @@ -1030,7 +1040,10 @@ DEFUN(show_ip_nhrp, show_ip_nhrp_cmd, else json_object_string_add(json_vrf, "status", "ok"); +<<<<<<< HEAD ctx.count++; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) FOR_ALL_INTERFACES (vrf, ifp) nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx); } diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index 324cd7abe88e..8e4cc6c7f5af 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -578,7 +578,11 @@ static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf, struct ospf6_prefix *prefix = nth_prefix(lsa->header, pos); struct in6_addr in6 = { 0 }; +<<<<<<< HEAD if (!lsa || !prefix || !buf || buflen < (1 + INET6_ADDRSTRLEN)) +======= + if (!prefix || !buf || buflen < (1 + INET6_ADDRSTRLEN)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NULL; /* position zero is used for the lladdr in the body of the LSA */ @@ -772,7 +776,11 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, char tbuf[16]; /* ensure buflen >= INET6_ADDRSTRLEN + '/128\0' */ +<<<<<<< HEAD if (!lsa || !prefix || !buf || buflen < (5 + INET6_ADDRSTRLEN)) +======= + if (!prefix || !buf || buflen < (5 + INET6_ADDRSTRLEN)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NULL; memcpy(&in6, OSPF6_PREFIX_BODY(prefix), diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index e04dad85539e..06913f241829 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -101,11 +101,26 @@ struct timeval msec2tv(int a) return ret; } +<<<<<<< HEAD int ospf_lsa_refresh_delay(struct ospf_lsa *lsa) +======= +int tv2msec(struct timeval tv) +{ + int msecs; + + msecs = tv.tv_sec * 1000; + msecs += (tv.tv_usec + 1000) / 1000; + + return msecs; +} + +int ospf_lsa_refresh_delay(struct ospf *ospf, struct ospf_lsa *lsa) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct timeval delta; int delay = 0; +<<<<<<< HEAD if (monotime_since(&lsa->tv_orig, &delta) < OSPF_MIN_LS_INTERVAL * 1000LL) { struct timeval minv = msec2tv(OSPF_MIN_LS_INTERVAL); @@ -121,6 +136,24 @@ int ospf_lsa_refresh_delay(struct ospf_lsa *lsa) delay); assert(delay > 0); +======= + if (monotime_since(&lsa->tv_orig, &delta) < ospf->min_ls_interval * 1000LL) { + struct timeval minv = msec2tv(ospf->min_ls_interval); + + timersub(&minv, &delta, &minv); + delay = tv2msec(minv); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type%d:%pI4]: Refresh timer delay %d milliseconds", + lsa->data->type, &lsa->data->id, delay); + + if (delay <= 0) { + zlog_warn("LSA[Type%d:%pI4]: Invalid refresh timer delay %d milliseconds Seq: 0x%x Age:%u", + lsa->data->type, &lsa->data->id, delay, + ntohl(lsa->data->ls_seqnum), ntohs(lsa->data->ls_age)); + delay = 0; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return delay; @@ -2608,8 +2641,12 @@ void ospf_external_lsa_refresh_default(struct ospf *ospf) } } +<<<<<<< HEAD void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type, unsigned short instance, int force) +======= +void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type, uint8_t instance, int force) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct route_node *rn; struct external_info *ei; @@ -3165,9 +3202,15 @@ int ospf_check_nbr_status(struct ospf *ospf) } +<<<<<<< HEAD void ospf_maxage_lsa_remover(struct event *thread) { struct ospf *ospf = EVENT_ARG(thread); +======= +void ospf_maxage_lsa_remover(struct event *event) +{ + struct ospf *ospf = EVENT_ARG(event); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct ospf_lsa *lsa, *old; struct route_node *rn; int reschedule = 0; @@ -3197,7 +3240,11 @@ void ospf_maxage_lsa_remover(struct event *thread) } /* TODO: maybe convert this function to a work-queue */ +<<<<<<< HEAD if (event_should_yield(thread)) { +======= + if (event_should_yield(event)) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) OSPF_TIMER_ON(ospf->t_maxage, ospf_maxage_lsa_remover, 0); route_unlock_node( @@ -3413,9 +3460,15 @@ static int ospf_lsa_maxage_walker_remover(struct ospf *ospf, } /* Periodical check of MaxAge LSA. */ +<<<<<<< HEAD void ospf_lsa_maxage_walker(struct event *thread) { struct ospf *ospf = EVENT_ARG(thread); +======= +void ospf_lsa_maxage_walker(struct event *event) +{ + struct ospf *ospf = EVENT_ARG(event); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct route_node *rn; struct ospf_lsa *lsa; struct ospf_area *area; @@ -4152,11 +4205,19 @@ void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa) } } +<<<<<<< HEAD void ospf_lsa_refresh_walker(struct event *t) { struct list *refresh_list; struct listnode *node, *nnode; struct ospf *ospf = EVENT_ARG(t); +======= +void ospf_lsa_refresh_walker(struct event *e) +{ + struct list *refresh_list; + struct listnode *node, *nnode; + struct ospf *ospf = EVENT_ARG(e); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct ospf_lsa *lsa; int i; struct list *lsa_to_refresh = list_new(); diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index d5ca0694ccb2..943f6c4d1b5c 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -225,6 +225,7 @@ enum lsid_status { LSID_AVAILABLE = 0, LSID_CHANGE, LSID_NOT_AVAILABLE }; /* Prototypes. */ /* XXX: Eek, time functions, similar are in lib/thread.c */ extern struct timeval int2tv(int); +<<<<<<< HEAD extern struct timeval msec2tv(int); extern int get_age(struct ospf_lsa *); @@ -238,10 +239,28 @@ extern void lsa_header_set(struct stream *, uint8_t, uint8_t, struct in_addr, struct in_addr); extern struct ospf_neighbor *ospf_nbr_lookup_ptop(struct ospf_interface *); extern int ospf_check_nbr_status(struct ospf *); +======= + +extern struct timeval msec2tv(int a); +extern int tv2msec(struct timeval tv); + +extern int get_age(struct ospf_lsa *lsa); +extern uint16_t ospf_lsa_checksum(struct lsa_header *lsah); +extern int ospf_lsa_checksum_valid(struct lsa_header *lsah); +extern int ospf_lsa_refresh_delay(struct ospf *ospf, struct ospf_lsa *lsa); + +extern const char *dump_lsa_key(struct ospf_lsa *lsa); +extern uint32_t lsa_seqnum_increment(struct ospf_lsa *lsa); +extern void lsa_header_set(struct stream *s, uint8_t options, uint8_t type, struct in_addr id, + struct in_addr router_id); +extern struct ospf_neighbor *ospf_nbr_lookup_ptop(struct ospf_interface *oi); +extern int ospf_check_nbr_status(struct ospf *ospf); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Prototype for LSA primitive. */ extern struct ospf_lsa *ospf_lsa_new(void); extern struct ospf_lsa *ospf_lsa_new_and_data(size_t size); +<<<<<<< HEAD extern struct ospf_lsa *ospf_lsa_dup(struct ospf_lsa *); extern void ospf_lsa_free(struct ospf_lsa *); extern struct ospf_lsa *ospf_lsa_lock(struct ospf_lsa *); @@ -251,10 +270,22 @@ extern int ospf_lsa_flush_schedule(struct ospf *, struct ospf_lsa *); extern struct lsa_header *ospf_lsa_data_new(size_t); extern struct lsa_header *ospf_lsa_data_dup(struct lsa_header *); extern void ospf_lsa_data_free(struct lsa_header *); +======= +extern struct ospf_lsa *ospf_lsa_dup(struct ospf_lsa *lsa); +extern void ospf_lsa_free(struct ospf_lsa *lsa); +extern struct ospf_lsa *ospf_lsa_lock(struct ospf_lsa *lsa); +extern void ospf_lsa_unlock(struct ospf_lsa **lsa); +extern void ospf_lsa_discard(struct ospf_lsa *lsa); +extern int ospf_lsa_flush_schedule(struct ospf *ospf, struct ospf_lsa *lsa); +extern struct lsa_header *ospf_lsa_data_new(size_t size); +extern struct lsa_header *ospf_lsa_data_dup(struct lsa_header *lsah); +extern void ospf_lsa_data_free(struct lsa_header *lsah); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Prototype for various LSAs */ extern void ospf_router_lsa_body_set(struct stream **s, struct ospf_area *area); extern uint8_t router_lsa_flags(struct ospf_area *area); +<<<<<<< HEAD extern int ospf_router_lsa_update(struct ospf *); extern int ospf_router_lsa_update_area(struct ospf_area *); @@ -278,12 +309,35 @@ extern struct in_addr ospf_get_ip_from_ifp(struct ospf_interface *); extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *, struct external_info *); +======= +extern int ospf_router_lsa_update(struct ospf *ospf); +extern int ospf_router_lsa_update_area(struct ospf_area *area); + +extern void ospf_network_lsa_update(struct ospf_interface *oi); + +extern struct ospf_lsa *ospf_summary_lsa_originate(struct prefix_ipv4 *p, uint32_t metric, + struct ospf_area *area); +extern struct ospf_lsa *ospf_summary_asbr_lsa_originate(struct prefix_ipv4 *p, uint32_t metric, + struct ospf_area *area); + +extern struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi, + struct ospf_lsa *lsa); + +extern void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p); +extern void ospf_external_lsa_flush(struct ospf *ospf, uint8_t type, struct prefix_ipv4 *p, + ifindex_t /* , struct in_addr nexthop */); + +extern struct in_addr ospf_get_ip_from_ifp(struct ospf_interface *oi); + +extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf, struct external_info *ei); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern struct ospf_lsa *ospf_nssa_lsa_originate(struct ospf_area *area, struct external_info *ei); extern struct ospf_lsa *ospf_nssa_lsa_refresh(struct ospf_area *area, struct ospf_lsa *lsa, struct external_info *ei); extern void ospf_external_lsa_rid_change(struct ospf *ospf); +<<<<<<< HEAD extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *, uint32_t, struct in_addr, struct in_addr); @@ -316,10 +370,39 @@ extern struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *, struct ospf_lsa *, struct external_info *, int, bool aggr); +======= +extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *area, uint32_t type, + struct in_addr id, struct in_addr adv_router); +extern struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *area, uint32_t type, + struct in_addr id); +extern struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area, struct lsa_header *lsah); +extern int ospf_lsa_more_recent(struct ospf_lsa *l1, struct ospf_lsa *l2); +extern int ospf_lsa_different(struct ospf_lsa *l1, struct ospf_lsa *l2, bool ignore_rcvd_flag); +extern void ospf_flush_self_originated_lsas_now(struct ospf *ospf); + +extern int ospf_lsa_is_self_originated(struct ospf *ospf, struct ospf_lsa *lsa); + +extern struct ospf_lsa *ospf_lsa_lookup_by_prefix(struct ospf_lsdb *lsdb, uint8_t type, + struct prefix_ipv4 *p, struct in_addr router_id); + +extern void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa); +extern uint32_t get_metric(uint8_t *metric); + +extern void ospf_lsa_maxage_walker(struct event *event); +extern struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa); + +extern void ospf_external_lsa_refresh_default(struct ospf *ospf); + +extern void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type, uint8_t instance, + int force); +extern struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa, + struct external_info *ei, int force, bool aggr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern enum lsid_status ospf_lsa_unique_id(struct ospf *ospf, struct ospf_lsdb *lsdb, uint8_t type, struct prefix_ipv4 *p, struct in_addr *addr); +<<<<<<< HEAD extern void ospf_schedule_lsa_flood_area(struct ospf_area *, struct ospf_lsa *); extern void ospf_schedule_lsa_flush_area(struct ospf_area *, struct ospf_lsa *); @@ -334,13 +417,32 @@ extern void ospf_discard_from_db(struct ospf *, struct ospf_lsdb *, extern int metric_type(struct ospf *, uint8_t, unsigned short); extern int metric_value(struct ospf *, uint8_t, unsigned short); +======= +extern void ospf_schedule_lsa_flood_area(struct ospf_area *area, struct ospf_lsa *lsa); +extern void ospf_schedule_lsa_flush_area(struct ospf_area *area, struct ospf_lsa *lsa); + +extern void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa); +extern void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa); +extern void ospf_lsa_refresh_walker(struct event *event); + +extern void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa); + +extern void ospf_discard_from_db(struct ospf *ospf, struct ospf_lsdb *lsdb, struct ospf_lsa *lsa); + +extern int metric_type(struct ospf *ospf, uint8_t src, unsigned short instance); +extern int metric_value(struct ospf *ospf, uint8_t src, unsigned short instance); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern char link_info_set(struct stream **s, struct in_addr id, struct in_addr data, uint8_t type, uint8_t tos, uint16_t cost); +<<<<<<< HEAD extern struct in_addr ospf_get_nssa_ip(struct ospf_area *); extern int ospf_translated_nssa_compare(struct ospf_lsa *, struct ospf_lsa *); +======= +extern struct in_addr ospf_get_nssa_ip(struct ospf_area *area); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, struct ospf_lsa *type7, struct ospf_lsa *type5); @@ -351,7 +453,11 @@ extern void ospf_check_and_gen_init_seq_lsa(struct ospf_interface *oi, struct ospf_lsa *lsa); extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id, int type); +<<<<<<< HEAD extern void ospf_maxage_lsa_remover(struct event *thread); +======= +extern void ospf_maxage_lsa_remover(struct event *event); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern bool ospf_check_dna_lsa(const struct ospf_lsa *lsa); extern void ospf_refresh_area_self_lsas(struct ospf_area *area); diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 5d2d65658f6e..d0806e6359f7 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -2051,7 +2051,11 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) struct opaque_info_per_type *oipt; struct opaque_info_per_id *oipi; struct ospf_lsa *lsa; +<<<<<<< HEAD struct ospf *top; +======= + struct ospf *ospf; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int delay; if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL @@ -2076,6 +2080,14 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) goto out; } +<<<<<<< HEAD +======= + if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL)) + ospf = lsa0->area->ospf; + else + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Delete this lsa from neighbor retransmit-list. */ switch (lsa->data->type) { case OSPF_OPAQUE_LINK_LSA: @@ -2083,10 +2095,14 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa); break; case OSPF_OPAQUE_AS_LSA: +<<<<<<< HEAD top = ospf_lookup_by_vrf_id(VRF_DEFAULT); if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL)) top = lsa0->area->ospf; ospf_ls_retransmit_delete_nbr_as(top, lsa); +======= + ospf_ls_retransmit_delete_nbr_as(ospf, lsa); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) break; default: flog_warn(EC_OSPF_LSA_UNEXPECTED, "%s: Unexpected LSA-type(%u)", @@ -2094,6 +2110,7 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) goto out; } +<<<<<<< HEAD delay = ospf_lsa_refresh_delay(lsa); if (IS_DEBUG_OSPF_EVENT) @@ -2105,6 +2122,16 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) OSPF_OPAQUE_TIMER_ON(oipi->t_opaque_lsa_self, ospf_opaque_lsa_refresh_timer, oipi, delay * 1000); +======= + delay = ospf_lsa_refresh_delay(ospf, lsa); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Schedule Type-%u Opaque-LSA to REFRESH in %d msec later: [opaque-type=%u, opaque-id=%x]", + lsa->data->type, delay, GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)), + GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr))); + + OSPF_OPAQUE_TIMER_ON(oipi->t_opaque_lsa_self, ospf_opaque_lsa_refresh_timer, oipi, delay); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) out: return; } diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 97dc5786795c..fe91fae72c85 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -1334,6 +1334,15 @@ static void update_out_nhlfe(struct hash_bucket *bucket, void *args) continue; for (ALL_LIST_ELEMENTS_RO(srp->route->paths, pnode, path)) { +<<<<<<< HEAD +======= + /* Compute NHFLE if path has not been initialized */ + if (!path->srni.nexthop) { + compute_prefix_nhlfe(srp); + continue; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Skip path that has not next SR-Node as nexthop */ if (path->srni.nexthop != srnext) continue; diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index ccc46424bc05..e098c7f6b52d 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -724,7 +724,11 @@ DEFUN (ospf_area_range_not_advertise, DEFUN (no_ospf_area_range, no_ospf_area_range_cmd, +<<<<<<< HEAD "no area range A.B.C.D/M []", +======= + "no area range A.B.C.D/M []", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "OSPF area parameters\n" "OSPF area ID in IP address format\n" @@ -754,6 +758,11 @@ DEFUN (no_ospf_area_range, ospf_area_range_unset(ospf, area, area->ranges, &p); +<<<<<<< HEAD +======= + ospf_area_check_free(ospf, area_id); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return CMD_SUCCESS; } @@ -787,6 +796,11 @@ DEFUN (no_ospf_area_range_substitute, ospf_area_range_substitute_unset(ospf, area, &p); +<<<<<<< HEAD +======= + ospf_area_check_free(ospf, area_id); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return CMD_SUCCESS; } @@ -1268,7 +1282,11 @@ DEFUN (ospf_area_vlink_intervals, DEFUN (no_ospf_area_vlink_intervals, no_ospf_area_vlink_intervals_cmd, +<<<<<<< HEAD "no area virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|retransmit-window (20-1000)|transmit-delay (1-65535)|dead-interval (1-65535)}", +======= + "no area virtual-link A.B.C.D {hello-interval [(1-65535)]|retransmit-interval [(1-65535)]|retransmit-window [(20-1000)]|transmit-delay [(1-65535)]|dead-interval [(1-65535)]}", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR VLINK_HELPSTR_IPADDR VLINK_HELPSTR_TIME_PARAM) @@ -1359,12 +1377,20 @@ DEFUN (ospf_area_shortcut, DEFUN (no_ospf_area_shortcut, no_ospf_area_shortcut_cmd, +<<<<<<< HEAD "no area shortcut ", +======= + "no area shortcut ", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "OSPF area parameters\n" "OSPF area ID in IP address format\n" "OSPF area ID as a decimal value\n" "Deconfigure the area's shortcutting mode\n" +<<<<<<< HEAD +======= + "Deconfigure default shortcutting through the area\n" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "Deconfigure enabled shortcutting through the area\n" "Deconfigure disabled shortcutting through the area\n") { @@ -1584,7 +1610,11 @@ DEFPY (no_ospf_area_nssa, "no area $area_str nssa\ [{\ \ +<<<<<<< HEAD |default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\ +======= + |default-information-originate [{metric [(0-16777214)]|metric-type [(1-2)]}]\ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) |no-summary\ |suppress-fa\ }]", @@ -1665,7 +1695,11 @@ DEFPY (ospf_area_nssa_range, DEFPY (no_ospf_area_nssa_range, no_ospf_area_nssa_range_cmd, +<<<<<<< HEAD "no area $area_str nssa range A.B.C.D/M$prefix []", +======= + "no area $area_str nssa range A.B.C.D/M$prefix []", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "OSPF area parameters\n" "OSPF area ID in IP address format\n" @@ -1744,7 +1778,11 @@ DEFUN (ospf_area_default_cost, DEFUN (no_ospf_area_default_cost, no_ospf_area_default_cost_cmd, +<<<<<<< HEAD "no area default-cost (0-16777215)", +======= + "no area default-cost [(0-16777215)]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "OSPF area parameters\n" "OSPF area ID in IP address format\n" @@ -2308,6 +2346,7 @@ static int ospf_timers_spf_set(struct vty *vty, unsigned int delay, return CMD_SUCCESS; } +<<<<<<< HEAD DEFUN (ospf_timers_min_ls_interval, ospf_timers_min_ls_interval_cmd, "timers throttle lsa all (0-5000)", @@ -2336,6 +2375,11 @@ DEFUN (ospf_timers_min_ls_interval, DEFUN (no_ospf_timers_min_ls_interval, no_ospf_timers_min_ls_interval_cmd, "no timers throttle lsa all [(0-5000)]", +======= +DEFPY (ospf_timers_min_ls_interval, + ospf_timers_min_ls_interval_cmd, + "[no] timers throttle lsa all ![(0-5000)]$lsa_refresh_interval", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Adjust routing timers\n" "Throttling adaptive timer\n" @@ -2344,7 +2388,15 @@ DEFUN (no_ospf_timers_min_ls_interval, "Delay (msec) between sending LSAs\n") { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); +<<<<<<< HEAD ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL; +======= + + if (no) + ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL; + else + ospf->min_ls_interval = strtoul(lsa_refresh_interval_str, NULL, 10); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return CMD_SUCCESS; } @@ -2393,6 +2445,7 @@ DEFUN (no_ospf_timers_throttle_spf, } +<<<<<<< HEAD DEFUN (ospf_timers_lsa_min_arrival, ospf_timers_lsa_min_arrival_cmd, "timers lsa min-arrival (0-600000)", @@ -2427,6 +2480,37 @@ DEFUN (no_ospf_timers_lsa_min_arrival, } ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; +======= +DEFPY (ospf_timers_lsa_min_arrival, + ospf_timers_lsa_min_arrival_cmd, + "[no] timers lsa min-arrival ![(0-5000)]$min_arrival", + NO_STR + "Adjust routing timers\n" + "OSPF LSA timers\n" + "Minimum delay in receiving new version of an LSA\n" + "Delay in milliseconds\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + if (no) + ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; + else + ospf->min_ls_arrival = strtoul(min_arrival_str, NULL, 10); + return CMD_SUCCESS; +} + +DEFPY_HIDDEN (ospf_timers_lsa_min_arrival_deprecated, + ospf_timers_lsa_min_arrival_deprecated_cmd, + "timers lsa min-arrival [(5001-60000)]$min_arrival", + "Adjust routing timers\n" + "OSPF LSA timers\n" + "Minimum delay in receiving new version of an LSA\n" + "Deprecated delay in milliseconds - delays in this range default to 5000 msec\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + vty_out(vty, "%% OSPF `timers lsa min-arrival` set to the maximum of %u milliseconds\n", + OSPF_MIN_LS_ARRIVAL_MAX); + ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL_MAX; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return CMD_SUCCESS; } @@ -2592,7 +2676,11 @@ ALIAS(ospf_write_multiplier, write_multiplier_cmd, "write-multiplier (1-100)", DEFUN (no_ospf_write_multiplier, no_ospf_write_multiplier_cmd, +<<<<<<< HEAD "no ospf write-multiplier (1-100)", +======= + "no ospf write-multiplier [(1-100)]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "OSPF specific commands\n" "Write multiplier\n" @@ -9564,7 +9652,11 @@ DEFUN (ospf_default_information_originate, DEFUN (no_ospf_default_information_originate, no_ospf_default_information_originate_cmd, +<<<<<<< HEAD "no default-information originate [{always|metric (0-16777214)|metric-type (1-2)|route-map RMAP_NAME}]", +======= + "no default-information originate [{always|metric [(0-16777214)]|metric-type [(1-2)]|route-map [RMAP_NAME]}]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Control distribution of default information\n" "Distribute a default route\n" @@ -9648,7 +9740,11 @@ DEFUN (ospf_distance, DEFUN (no_ospf_distance, no_ospf_distance_cmd, +<<<<<<< HEAD "no distance (1-255)", +======= + "no distance [(1-255)]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "Administrative distance\n" "OSPF Administrative distance\n") @@ -13717,9 +13813,14 @@ void ospf_vty_init(void) /* LSA timers commands */ install_element(OSPF_NODE, &ospf_timers_min_ls_interval_cmd); +<<<<<<< HEAD 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_min_arrival_cmd); + install_element(OSPF_NODE, &ospf_timers_lsa_min_arrival_deprecated_cmd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* refresh timer commands */ install_element(OSPF_NODE, &ospf_refresh_timer_cmd); diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index f1ebdb554c0b..e48b96be26f9 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -1217,6 +1217,55 @@ DEFPY_ATTR(no_ipv6_pim_rp_prefix_list, return ret; } +<<<<<<< HEAD +======= +DEFPY_YANG(pim6_embedded_rp, + pim6_embedded_rp_cmd, + "[no] embedded-rp", + NO_STR + PIM_EMBEDDED_RP) +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, sizeof(xpath), FRR_PIM_EMBEDDED_RP_XPATH); + nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(pim6_embedded_rp_group_list, + pim6_embedded_rp_group_list_cmd, + "[no] embedded-rp group-list ![WORD$prefix_list]", + NO_STR + PIM_EMBEDDED_RP + "Configure embedded RP permitted groups\n" + "Embedded RP permitted groups\n") +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, sizeof(xpath), FRR_PIM_EMBEDDED_RP_GROUP_LIST_XPATH); + nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_MODIFY, prefix_list); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(pim6_embedded_rp_limit, + pim6_embedded_rp_limit_cmd, + "[no] embedded-rp limit ![(1-4294967295)$limit]", + NO_STR + PIM_EMBEDDED_RP + "Limit the amount of embedded RPs to learn\n" + "Maximum amount of embedded RPs to learn\n") +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, sizeof(xpath), FRR_PIM_EMBEDDED_RP_MAXIMUM_RPS_XPATH); + nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_MODIFY, limit_str); + + return nb_cli_apply_changes(vty, NULL); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFPY (ipv6_pim_bsm, ipv6_pim_bsm_cmd, "ipv6 pim bsm", @@ -2788,6 +2837,14 @@ void pim_cmd_init(void) install_element(PIM6_NODE, &no_pim6_rp_cmd); install_element(PIM6_NODE, &pim6_rp_prefix_list_cmd); install_element(PIM6_NODE, &no_pim6_rp_prefix_list_cmd); +<<<<<<< HEAD +======= + + install_element(PIM6_NODE, &pim6_embedded_rp_cmd); + install_element(PIM6_NODE, &pim6_embedded_rp_group_list_cmd); + install_element(PIM6_NODE, &pim6_embedded_rp_limit_cmd); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(PIM6_NODE, &pim6_ssmpingd_cmd); install_element(PIM6_NODE, &no_pim6_ssmpingd_cmd); install_element(PIM6_NODE, &pim6_bsr_candidate_rp_cmd); diff --git a/pimd/pim6_cmd.h b/pimd/pim6_cmd.h index 201d8d6bcd34..4f3ad125de53 100644 --- a/pimd/pim6_cmd.h +++ b/pimd/pim6_cmd.h @@ -46,6 +46,10 @@ #define DEBUG_PIMV6_ZEBRA_STR "ZEBRA protocol activity\n" #define DEBUG_MROUTE6_STR "PIMv6 interaction with kernel MFC cache\n" #define DEBUG_PIMV6_BSM_STR "BSR message processing activity\n" +<<<<<<< HEAD +======= +#define PIM_EMBEDDED_RP "Embedded Rendezvous Point\n" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void pim_cmd_init(void); diff --git a/pimd/pim6_mld.c b/pimd/pim6_mld.c index a871837701a4..1b532da7e2c1 100644 --- a/pimd/pim6_mld.c +++ b/pimd/pim6_mld.c @@ -319,6 +319,12 @@ static void gm_expiry_calc(struct gm_query_timers *timers) static void gm_sg_free(struct gm_sg *sg) { +<<<<<<< HEAD +======= + if (pim_embedded_rp_is_embedded(&sg->sgaddr.grp)) + pim_embedded_rp_delete(sg->iface->pim, &sg->sgaddr.grp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* t_sg_expiry is handled before this is reached */ EVENT_OFF(sg->t_sg_query); gm_packet_sg_subs_fini(sg->subs_negative); @@ -415,6 +421,16 @@ static void gm_sg_update(struct gm_sg *sg, bool has_expired) new_join = gm_sg_state_want_join(desired); if (new_join && !sg->tib_joined) { +<<<<<<< HEAD +======= + pim_addr embedded_rp; + + if (sg->iface->pim->embedded_rp.enable && + pim_embedded_rp_extract(&sg->sgaddr.grp, &embedded_rp) && + !pim_embedded_rp_filter_match(sg->iface->pim, &sg->sgaddr.grp)) + pim_embedded_rp_new(sg->iface->pim, &sg->sgaddr.grp, &embedded_rp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* this will retry if join previously failed */ sg->tib_joined = tib_sg_gm_join(gm_ifp->pim, sg->sgaddr, gm_ifp->ifp, &sg->oil); @@ -434,6 +450,16 @@ static void gm_sg_update(struct gm_sg *sg, bool has_expired) } if (desired == GM_SG_NOINFO) { +<<<<<<< HEAD +======= + /* + * If oil is still present then get ride of it or we will leak + * this data structure. + */ + if (sg->oil) + pim_channel_oil_del(sg->oil, __func__); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* multiple paths can lead to the last state going away; * t_sg_expire can still be running if we're arriving from * another path. @@ -468,6 +494,11 @@ static void gm_sg_update(struct gm_sg *sg, bool has_expired) static void gm_packet_free(struct gm_packet_state *pkt) { +<<<<<<< HEAD +======= + assert(pkt->iface); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) gm_packet_expires_del(pkt->iface->expires, pkt); gm_packets_del(pkt->subscriber->packets, pkt); gm_subscriber_drop(&pkt->subscriber); diff --git a/pimd/pim_autorp.c b/pimd/pim_autorp.c index a07bd4ab3af7..5bfa1b928bd8 100644 --- a/pimd/pim_autorp.c +++ b/pimd/pim_autorp.c @@ -19,6 +19,10 @@ #include "lib/json.h" #include "pimd.h" +<<<<<<< HEAD +======= +#include "pim_util.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "pim_iface.h" #include "pim_rp.h" #include "pim_sock.h" @@ -26,43 +30,100 @@ #include "pim_autorp.h" DEFINE_MTYPE_STATIC(PIMD, PIM_AUTORP, "PIM AutoRP info"); +<<<<<<< HEAD DEFINE_MTYPE_STATIC(PIMD, PIM_AUTORP_RP, "PIM AutoRP advertised RP info"); DEFINE_MTYPE_STATIC(PIMD, PIM_AUTORP_CRP, "PIM AutoRP candidate RP info"); DEFINE_MTYPE_STATIC(PIMD, PIM_AUTORP_ANNOUNCE, "PIM AutoRP announcement packet"); +======= +DEFINE_MTYPE_STATIC(PIMD, PIM_AUTORP_RP, "PIM AutoRP discovered RP info"); +DEFINE_MTYPE_STATIC(PIMD, PIM_AUTORP_ANNOUNCE, "PIM AutoRP announcement packet"); +DEFINE_MTYPE_STATIC(PIMD, PIM_AUTORP_GRPPFIX, "PIM AutoRP group prefix list"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static const char *PIM_AUTORP_ANNOUNCEMENT_GRP = "224.0.1.39"; static const char *PIM_AUTORP_DISCOVERY_GRP = "224.0.1.40"; static const in_port_t PIM_AUTORP_PORT = 496; +<<<<<<< HEAD static int pim_autorp_rp_cmp(const struct pim_autorp_rp *l, const struct pim_autorp_rp *r) +======= +static int pim_autorp_rp_cmp(const struct pim_autorp_rp *l, const struct pim_autorp_rp *r) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { return pim_addr_cmp(l->addr, r->addr); } +<<<<<<< HEAD DECLARE_SORTLIST_UNIQ(pim_autorp_rp, struct pim_autorp_rp, list, pim_autorp_rp_cmp); static void pim_autorp_rp_free(struct pim_autorp_rp *rp) +======= +DECLARE_SORTLIST_UNIQ(pim_autorp_rp, struct pim_autorp_rp, item, pim_autorp_rp_cmp); + +static int pim_autorp_grppfix_cmp(const struct pim_autorp_grppfix *l, + const struct pim_autorp_grppfix *r) +{ + return prefix_cmp(&l->grp, &r->grp); +} + +DECLARE_SORTLIST_UNIQ(pim_autorp_grppfix, struct pim_autorp_grppfix, item, pim_autorp_grppfix_cmp); + +static void pim_autorp_grppfix_free(struct pim_autorp_grppfix_head *head) +{ + struct pim_autorp_grppfix *grp; + + while ((grp = pim_autorp_grppfix_pop(head))) + XFREE(MTYPE_PIM_AUTORP_GRPPFIX, grp); +} + +static void pim_autorp_rp_free(struct pim_autorp_rp *rp, bool installed) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { event_cancel(&rp->hold_timer); /* Clean up installed RP info */ +<<<<<<< HEAD if (pim_rp_del(rp->autorp->pim, rp->addr, rp->grp, (strlen(rp->grplist) ? rp->grplist : NULL), RP_SRC_AUTORP)) if (PIM_DEBUG_AUTORP) zlog_err("%s: Failed to delete RP %pI4", __func__, &rp->addr); +======= + if (installed) { + if (pim_rp_del(rp->autorp->pim, rp->addr, rp->grp, + (strlen(rp->grplist) ? rp->grplist : NULL), RP_SRC_AUTORP)) { + zlog_warn("%s: Failed to delete RP %pI4", __func__, &rp->addr); + } + + if (strlen(rp->grplist)) { + struct prefix_list *pl; + + pl = prefix_list_lookup(AFI_IP, rp->grplist); + if (pl) + prefix_list_delete(pl); + } + } + + pim_autorp_grppfix_free(&rp->grp_pfix_list); + pim_autorp_grppfix_fini(&rp->grp_pfix_list); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) XFREE(MTYPE_PIM_AUTORP_RP, rp); } +<<<<<<< HEAD static void pim_autorp_rplist_free(struct pim_autorp_rp_head *head) +======= +static void pim_autorp_rplist_free(struct pim_autorp_rp_head *head, bool installed) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct pim_autorp_rp *rp; while ((rp = pim_autorp_rp_pop(head))) +<<<<<<< HEAD pim_autorp_rp_free(rp); } @@ -72,15 +133,38 @@ static void pim_autorp_rplist_cfree(struct pim_autorp_rp_head *head) while ((rp = pim_autorp_rp_pop(head))) XFREE(MTYPE_PIM_AUTORP_CRP, rp); +======= + pim_autorp_rp_free(rp, installed); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static void pim_autorp_free(struct pim_autorp *autorp) { +<<<<<<< HEAD pim_autorp_rplist_free(&(autorp->discovery_rp_list)); pim_autorp_rp_fini(&(autorp->discovery_rp_list)); pim_autorp_rplist_cfree(&(autorp->candidate_rp_list)); pim_autorp_rp_fini(&(autorp->candidate_rp_list)); +======= + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Freeing PIM AutoRP", __func__); + + pim_autorp_rplist_free(&(autorp->discovery_rp_list), true); + pim_autorp_rp_fini(&(autorp->discovery_rp_list)); + + pim_autorp_rplist_free(&(autorp->candidate_rp_list), false); + pim_autorp_rp_fini(&(autorp->candidate_rp_list)); + + pim_autorp_rplist_free(&(autorp->mapping_rp_list), false); + pim_autorp_rp_fini(&(autorp->mapping_rp_list)); + + pim_autorp_rplist_free(&(autorp->advertised_rp_list), false); + pim_autorp_rp_fini(&(autorp->advertised_rp_list)); + + if (autorp->announce_pkt) + XFREE(MTYPE_PIM_AUTORP_ANNOUNCE, autorp->announce_pkt); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static bool pim_autorp_join_groups(struct interface *ifp) @@ -97,6 +181,7 @@ static bool pim_autorp_join_groups(struct interface *ifp) inet_pton(PIM_AF, PIM_AUTORP_DISCOVERY_GRP, &grp); if (pim_socket_join(autorp->sock, grp, pim_ifp->primary_address, ifp->ifindex, pim_ifp)) { +<<<<<<< HEAD zlog_err("Failed to join group %pI4 on interface %s", &grp, ifp->name); return false; @@ -117,6 +202,24 @@ static bool pim_autorp_join_groups(struct interface *ifp) if (PIM_DEBUG_AUTORP) zlog_debug("%s: Joined AutoRP groups on interface %s", __func__, ifp->name); +======= + zlog_warn("Failed to join group %pI4 on interface %s", &grp, ifp->name); + return false; + } + + zlog_info("%s: Joined AutoRP discovery group %pPA on interface %s", __func__, &grp, + ifp->name); + + inet_pton(PIM_AF, PIM_AUTORP_ANNOUNCEMENT_GRP, &grp); + if (pim_socket_join(pim->autorp->sock, grp, pim_ifp->primary_address, ifp->ifindex, + pim_ifp)) { + zlog_warn("Failed to join group %pI4 on interface %s", &grp, ifp->name); + return errno; + } + + zlog_info("%s: Joined AutoRP announcement group %pPA on interface %s", __func__, &grp, + ifp->name); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return true; } @@ -135,6 +238,7 @@ static bool pim_autorp_leave_groups(struct interface *ifp) inet_pton(PIM_AF, PIM_AUTORP_DISCOVERY_GRP, &grp); if (pim_socket_leave(autorp->sock, grp, pim_ifp->primary_address, ifp->ifindex, pim_ifp)) { +<<<<<<< HEAD zlog_err("Failed to leave group %pI4 on interface %s", &grp, ifp->name); return false; @@ -155,11 +259,32 @@ static bool pim_autorp_leave_groups(struct interface *ifp) if (PIM_DEBUG_AUTORP) zlog_debug("%s: Left AutoRP groups on interface %s", __func__, ifp->name); +======= + zlog_warn("Failed to leave group %pI4 on interface %s", &grp, ifp->name); + return false; + } + + zlog_info("%s: Left AutoRP discovery group %pPA on interface %s", __func__, &grp, ifp->name); + + inet_pton(PIM_AF, PIM_AUTORP_ANNOUNCEMENT_GRP, &grp); + if (pim_socket_leave(pim->autorp->sock, grp, pim_ifp->primary_address, ifp->ifindex, + pim_ifp)) { + zlog_warn("Failed to leave group %pI4 on interface %s", &grp, ifp->name); + return errno; + } + + zlog_info("%s: Left AutoRP announcement group %pPA on interface %s", __func__, &grp, + ifp->name); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return true; } +<<<<<<< HEAD static bool pim_autorp_setup(struct pim_autorp *autorp) +======= +static bool pim_autorp_setup(int fd) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { #if defined(HAVE_IP_PKTINFO) int data; @@ -170,18 +295,29 @@ static bool pim_autorp_setup(struct pim_autorp *autorp) .sin_addr = { .s_addr = INADDR_ANY }, .sin_port = htons(PIM_AUTORP_PORT) }; +<<<<<<< HEAD setsockopt_so_recvbuf(autorp->sock, 1024 * 1024 * 8); +======= + setsockopt_so_recvbuf(fd, 1024 * 1024 * 8); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #if defined(HAVE_IP_PKTINFO) /* Linux and Solaris IP_PKTINFO */ data = 1; +<<<<<<< HEAD if (setsockopt(autorp->sock, PIM_IPPROTO, IP_PKTINFO, &data, data_len)) { zlog_err("Could not set IP_PKTINFO on socket fd=%d: errno=%d: %s", autorp->sock, errno, safe_strerror(errno)); +======= + if (setsockopt(fd, PIM_IPPROTO, IP_PKTINFO, &data, data_len)) { + zlog_warn("%s: Could not set IP_PKTINFO on socket fd=%d: errno=%d: %s", __func__, + fd, errno, safe_strerror(errno)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return false; } #endif +<<<<<<< HEAD if (set_nonblocking(autorp->sock) < 0) { zlog_err("Could not set non blocking on socket fd=%d: errno=%d: %s", autorp->sock, errno, safe_strerror(errno)); @@ -199,6 +335,29 @@ static bool pim_autorp_setup(struct pim_autorp *autorp) zlog_err("Could not bind socket: %pSUp, fd=%d, errno=%d, %s", (union sockunion *)&autorp_addr, autorp->sock, errno, safe_strerror(errno)); +======= + if (set_nonblocking(fd) < 0) { + zlog_warn("%s: Could not set non blocking on socket fd=%d: errno=%d: %s", __func__, + fd, errno, safe_strerror(errno)); + return false; + } + + if (sockopt_reuseaddr(fd)) { + zlog_warn("%s: Could not set reuse addr on socket fd=%d: errno=%d: %s", __func__, + fd, errno, safe_strerror(errno)); + return false; + } + + if (setsockopt_ipv4_multicast_loop(fd, 1) < 0) { + zlog_warn("%s: Could not enable multicast loopback on socket fd=%d: errno=%d: %s", + __func__, fd, errno, safe_strerror(errno)); + return false; + } + + if (bind(fd, (const struct sockaddr *)&autorp_addr, sizeof(autorp_addr)) < 0) { + zlog_warn("%s: Could not bind socket: %pSUp, fd=%d, errno=%d, %s", __func__, + (union sockunion *)&autorp_addr, fd, errno, safe_strerror(errno)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return false; } @@ -208,6 +367,7 @@ static bool pim_autorp_setup(struct pim_autorp *autorp) return true; } +<<<<<<< HEAD static bool pim_autorp_announcement(struct pim_autorp *autorp, uint8_t rpcnt, uint16_t holdtime, char *buf, size_t buf_size) @@ -222,6 +382,150 @@ static bool pim_autorp_announcement(struct pim_autorp *autorp, uint8_t rpcnt, } static void autorp_rp_holdtime(struct event *evt) +======= +static void autorp_ma_rp_holdtime(struct event *evt) +{ + /* Mapping agent RP hold time expired, remove the RP */ + struct pim_autorp_rp *rp = EVENT_ARG(evt); + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP hold time expired, RP removed from mapping agent: addr=%pI4, grp=%pFX, grplist=%s", + __func__, &rp->addr, &rp->grp, + (strlen(rp->grplist) ? rp->grplist : "NONE")); + + pim_autorp_rp_del(&(rp->autorp->mapping_rp_list), rp); + pim_autorp_rp_free(rp, false); +} + +static bool autorp_recv_announcement(struct pim_autorp *autorp, uint8_t rpcnt, uint16_t holdtime, + char *buf, size_t buf_size) +{ + int i, j; + struct autorp_pkt_rp *rp; + struct autorp_pkt_grp *grp; + size_t offset = 0; + pim_addr rp_addr; + struct pim_autorp_rp *ma_rp; + struct pim_autorp_rp *trp; + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Processing AutoRP Announcement (rpcnt=%u, holdtime=%u)", __func__, + rpcnt, holdtime); + + for (i = 0; i < rpcnt; ++i) { + if ((buf_size - offset) < AUTORP_RPLEN) { + zlog_warn("%s: Failed to parse AutoRP Announcement RP, invalid buffer size (%u < %u)", + __func__, (uint32_t)(buf_size - offset), AUTORP_RPLEN); + return false; + } + + rp = (struct autorp_pkt_rp *)(buf + offset); + offset += AUTORP_RPLEN; + + rp_addr.s_addr = rp->addr; + + /* Ignore RP's limited to PIM version 1 or with an unknown version */ + if (rp->pimver == AUTORP_PIM_V1 || rp->pimver == AUTORP_PIM_VUNKNOWN) { + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Ignoring unsupported PIM version (%u) in AutoRP Announcement for RP %pI4", + __func__, rp->pimver, (in_addr_t *)&(rp->addr)); + /* Update the offset to skip past the groups advertised for this RP */ + offset += (AUTORP_GRPLEN * rp->grpcnt); + continue; + } + + if (rp->grpcnt == 0) { + /* No groups?? */ + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Announcement message has no groups for RP %pI4", + __func__, (in_addr_t *)&(rp->addr)); + continue; + } + + if ((buf_size - offset) < AUTORP_GRPLEN) { + zlog_warn("%s: Buffer underrun parsing groups for RP %pI4", __func__, + (in_addr_t *)&(rp->addr)); + return false; + } + + /* Store all announced RP's, calculate what to send in discovery when discovery is sent. */ + ma_rp = XCALLOC(MTYPE_PIM_AUTORP_RP, sizeof(struct pim_autorp_rp)); + memcpy(&(ma_rp->addr), &rp_addr, sizeof(pim_addr)); + trp = pim_autorp_rp_add(&(autorp->mapping_rp_list), ma_rp); + if (trp == NULL) { + /* RP was brand new, finish initializing */ + ma_rp->autorp = autorp; + ma_rp->holdtime = holdtime; + ma_rp->hold_timer = NULL; + ma_rp->grplist[0] = '\0'; + memset(&(ma_rp->grp), 0, sizeof(ma_rp->grp)); + pim_autorp_grppfix_init(&ma_rp->grp_pfix_list); + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: New candidate RP learned (%pPA)", __func__, + &rp_addr); + } else { + /* Returned an existing entry, free allocated RP */ + XFREE(MTYPE_PIM_AUTORP_RP, ma_rp); + ma_rp = trp; + /* Free the existing group prefix list, in case the advertised groups changed */ + pim_autorp_grppfix_free(&ma_rp->grp_pfix_list); + } + + /* Cancel any existing timer and restart it */ + event_cancel(&ma_rp->hold_timer); + if (holdtime > 0) + event_add_timer(router->master, autorp_ma_rp_holdtime, ma_rp, + ma_rp->holdtime, &(ma_rp->hold_timer)); + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Parsing %u group(s) for candidate RP %pPA", __func__, + rp->grpcnt, &rp_addr); + + for (j = 0; j < rp->grpcnt; ++j) { + /* grp is already pointing at the first group in the buffer */ + struct pim_autorp_grppfix *lgrp; + struct pim_autorp_grppfix *tgrp; + + if ((buf_size - offset) < AUTORP_GRPLEN) { + zlog_warn("%s: Failed parsing AutoRP announcement, RP(%pI4), invalid buffer size (%u < %u)", + __func__, &rp_addr, (uint32_t)(buf_size - offset), + AUTORP_GRPLEN); + return false; + } + + grp = (struct autorp_pkt_grp *)(buf + offset); + offset += AUTORP_GRPLEN; + + lgrp = XCALLOC(MTYPE_PIM_AUTORP_GRPPFIX, sizeof(struct pim_autorp_grppfix)); + lgrp->grp.family = AF_INET; + lgrp->grp.prefixlen = grp->masklen; + lgrp->grp.u.prefix4.s_addr = grp->addr; + lgrp->negative = grp->negprefix; + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: %s%pFX added to candidate RP %pPA", __func__, + (lgrp->negative ? "!" : ""), &lgrp->grp, &rp_addr); + + tgrp = pim_autorp_grppfix_add(&ma_rp->grp_pfix_list, lgrp); + if (tgrp != NULL) { + /* This should never happen but if there was an existing entry just free the + * allocated group prefix + */ + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: %pFX was duplicated in AutoRP announcement", + __func__, &lgrp->grp); + XFREE(MTYPE_PIM_AUTORP_GRPPFIX, lgrp); + } + } + } + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP processed announcement message", __func__); + return true; +} + +static void autorp_cand_rp_holdtime(struct event *evt) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { /* RP hold time expired, remove the RP */ struct pim_autorp_rp *rp = EVENT_ARG(evt); @@ -232,18 +536,27 @@ static void autorp_rp_holdtime(struct event *evt) (strlen(rp->grplist) ? rp->grplist : "NONE")); pim_autorp_rp_del(&(rp->autorp->discovery_rp_list), rp); +<<<<<<< HEAD pim_autorp_rp_free(rp); } static bool pim_autorp_add_rp(struct pim_autorp *autorp, pim_addr rpaddr, struct prefix grp, char *listname, uint16_t holdtime) +======= + pim_autorp_rp_free(rp, true); +} + +static bool pim_autorp_add_rp(struct pim_autorp *autorp, pim_addr rpaddr, struct prefix grp, + char *listname, uint16_t holdtime) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct pim_autorp_rp *rp; struct pim_autorp_rp *trp = NULL; int ret; ret = pim_rp_new(autorp->pim, rpaddr, grp, listname, RP_SRC_AUTORP); +<<<<<<< HEAD /* There may not be a path to the RP right now, but that doesn't mean it failed to add the RP */ if (ret != PIM_SUCCESS && ret != PIM_RP_NO_PATH) { zlog_err("%s: Failed to add new RP addr=%pI4, grp=%pFX, grplist=%s", @@ -268,11 +581,25 @@ static bool pim_autorp_add_rp(struct pim_autorp *autorp, pim_addr rpaddr, rp->holdtime = holdtime; rp->hold_timer = NULL; +======= + + /* There may not be a path to the RP right now, but that doesn't mean it failed to add the RP */ + if (ret != PIM_SUCCESS && ret != PIM_RP_NO_PATH) { + zlog_warn("%s: Failed to add active RP addr=%pI4, grp=%pFX, grplist=%s", __func__, + &rpaddr, &grp, (listname ? listname : "NONE")); + return false; + } + + rp = XCALLOC(MTYPE_PIM_AUTORP_RP, sizeof(*rp)); + rp->autorp = autorp; + memcpy(&(rp->addr), &rpaddr, sizeof(pim_addr)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) trp = pim_autorp_rp_add(&(autorp->discovery_rp_list), rp); if (trp == NULL) { /* RP was brand new */ trp = pim_autorp_rp_find(&(autorp->discovery_rp_list), (const struct pim_autorp_rp *)rp); +<<<<<<< HEAD } else { /* RP already existed */ XFREE(MTYPE_PIM_AUTORP_RP, rp); @@ -298,44 +625,378 @@ static bool pim_autorp_add_rp(struct pim_autorp *autorp, pim_addr rpaddr, } else { /* If hold time is zero, make sure there doesn't exist a hold timer for it already */ event_cancel(&trp->hold_timer); +======= + /* Make sure the timer is NULL so the cancel below doesn't mess up */ + trp->hold_timer = NULL; + zlog_info("%s: Added new AutoRP learned RP addr=%pI4, grp=%pFX, grplist=%s", + __func__, &rpaddr, &grp, (listname ? listname : "NONE")); + } else { + /* RP already existed, free the temp one */ + XFREE(MTYPE_PIM_AUTORP_RP, rp); + } + + /* Cancel any existing timer before restarting it */ + event_cancel(&trp->hold_timer); + trp->holdtime = holdtime; + prefix_copy(&(trp->grp), &grp); + if (listname) + snprintf(trp->grplist, sizeof(trp->grplist), "%s", listname); + else + trp->grplist[0] = '\0'; + + if (holdtime > 0) { + event_add_timer(router->master, autorp_cand_rp_holdtime, trp, holdtime, + &(trp->hold_timer)); + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Started %u second hold timer for RP %pI4", __func__, + holdtime, &trp->addr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return true; } +<<<<<<< HEAD static bool pim_autorp_discovery(struct pim_autorp *autorp, uint8_t rpcnt, uint16_t holdtime, char *buf, size_t buf_size) +======= +static size_t autorp_build_disc_rps(struct pim_autorp *autorp, uint8_t *buf, size_t buf_sz, + size_t *sz) +{ + /* Header has already been added, fill in starting with the address of RP1 + * buf_sz is the max size of the buf + * sz is the current size of the packet, update as buf is filled + * return the total number of RP's added + * + * + * We need to resolve the announced RP's following these rules: + * 1) Co-existence of longer and shorter group prefixes, from different RPs. E.g. when RP1 + * announces 224.2.*.*, and RP2 announces 224.2.2.*, both are accepted; + * 2) For announcements for identical group prefixes from two different RPs, the one from the + * RP with the higher IP address is accepted; + * 3) No duplicates are sent to the AUTORP-DISCOVERY address. E.g. if an RP announces both + * 224.2.2.* and 224.2.*.*, the former group-prefix is not sent and only 224.2.*.* is sent + * to the AUTORP-DISCOVERY address. + * + * + * The approach to resolution, first loop the stored RP's and extract the group prefixes, stored + * in a sorted list, sorted from least specific to most 0.0.0.0/0 -> 239.255.255.255/32. Each + * group prefix will then store the RP advertising that group prefix, this will resolve 2. + * The next step is to then loop the group prefix list and store them back into a list sorted by + * RP address, where the least specific group address will be stored, resolving 3. 1 is more + * about what is allowed, and in the example above the different prefixes will be unique in the + * list of group prefixes, and when they go back into RP's, they are also from different RP's + * and will therefore be sent. + */ + + struct pim_autorp_rp *rp; + struct pim_autorp_rp *trp; + struct pim_autorp_grppfix *grp; + struct pim_autorp_grppfix *grp2; + struct pim_autorp_grppfix *tgrp; + struct pim_autorp_grppfix_head grplist; + bool skip = false; + size_t rpcnt = 0; + size_t bsz = 0; + + /* Initialize the lists, grplist is temporary, disc rp list is stored long term for + * show output, so make sure it's empty + */ + pim_autorp_grppfix_init(&grplist); + pim_autorp_rplist_free(&autorp->advertised_rp_list, false); + + /* Loop the advertised RP's and their group prefixes and make a unique list of group prefixes, + * keeping just the highest IP RP for each group prefix + */ + frr_each (pim_autorp_rp, &autorp->mapping_rp_list, rp) { + frr_each (pim_autorp_grppfix, &rp->grp_pfix_list, grp) { + grp2 = XCALLOC(MTYPE_PIM_AUTORP_GRPPFIX, sizeof(struct pim_autorp_grppfix)); + prefix_copy(&grp2->grp, &grp->grp); + grp2->negative = grp->negative; + grp2->rp = rp->addr; + tgrp = pim_autorp_grppfix_add(&grplist, grp2); + if (tgrp != NULL) { + /* Returned an existing entry. Use the highest RP addr and free allocated object */ + if (IPV4_ADDR_CMP(&tgrp->rp, &grp2->rp)) + tgrp->rp = grp2->rp; + XFREE(MTYPE_PIM_AUTORP_GRPPFIX, grp2); + } + } + } + + /* Now loop the unique group prefixes and put it back into an RP list */ + frr_each (pim_autorp_grppfix, &grplist, grp) { + rp = XCALLOC(MTYPE_PIM_AUTORP_RP, sizeof(struct pim_autorp_rp)); + rp->addr = grp->rp; + trp = pim_autorp_rp_add(&autorp->advertised_rp_list, rp); + if (trp == NULL) { + /* RP was brand new, finish initializing */ + rp->autorp = NULL; + rp->holdtime = 0; + rp->hold_timer = NULL; + rp->grplist[0] = '\0'; + memset(&(rp->grp), 0, sizeof(rp->grp)); + pim_autorp_grppfix_init(&rp->grp_pfix_list); + } else { + /* Returned an existing entry, free allocated RP */ + XFREE(MTYPE_PIM_AUTORP_RP, rp); + rp = trp; + } + + /* Groups are in order from least specific to most, so go through the existing + * groups for this RP and see if the current group is within the prefix of one that + * is already in the list, if so, skip it, if not, add it + * If one is a positive match and the other is negative, then still include it. + */ + skip = false; + frr_each (pim_autorp_grppfix, &rp->grp_pfix_list, grp2) { + if (prefix_match(&grp2->grp, &grp->grp) && grp->negative == grp2->negative) { + skip = true; + break; + } + } + + if (skip) + continue; + + /* add the group to the RP's group list */ + grp2 = XCALLOC(MTYPE_PIM_AUTORP_GRPPFIX, sizeof(struct pim_autorp_grppfix)); + prefix_copy(&grp2->grp, &grp->grp); + grp2->negative = grp->negative; + tgrp = pim_autorp_grppfix_add(&rp->grp_pfix_list, grp2); + assert(tgrp == NULL); + } + + /* Done with temporary group prefix list, so free and finish */ + pim_autorp_grppfix_free(&grplist); + pim_autorp_grppfix_fini(&grplist); + + /* Now finally we can loop the disc rp list and build the packet */ + frr_each (pim_autorp_rp, &autorp->advertised_rp_list, rp) { + struct autorp_pkt_rp *brp; + struct autorp_pkt_grp *bgrp; + size_t rp_sz; + size_t grpcnt; + + grpcnt = pim_autorp_grppfix_count(&rp->grp_pfix_list); + rp_sz = sizeof(struct autorp_pkt_rp) + (grpcnt * sizeof(struct autorp_pkt_grp)); + if (buf_sz < *sz + rp_sz) { + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Failed to pack AutoRP discovery packet, buffer overrun, (%u < %u)", + __func__, (uint32_t)buf_sz, (uint32_t)(*sz + rp_sz)); + break; + } + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Add RP %pI4 (grpcnt=%u) to discovery message", __func__, + &rp->addr, (uint32_t)grpcnt); + + rpcnt++; + + brp = (struct autorp_pkt_rp *)(buf + bsz); + bsz += sizeof(struct autorp_pkt_rp); + + /* Since this is an in_addr, assume it's already the right byte order */ + brp->addr = rp->addr.s_addr; + brp->pimver = AUTORP_PIM_V2; + brp->reserved = 0; + brp->grpcnt = grpcnt; + + frr_each (pim_autorp_grppfix, &rp->grp_pfix_list, grp) { + bgrp = (struct autorp_pkt_grp *)(buf + bsz); + bsz += sizeof(struct autorp_pkt_grp); + + bgrp->addr = grp->grp.u.prefix4.s_addr; + bgrp->masklen = grp->grp.prefixlen; + bgrp->negprefix = grp->negative; + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Add group %s%pFX for RP %pI4 to discovery message", + __func__, (grp->negative ? "!" : ""), &grp->grp, + &rp->addr); + } + + /* Update the size with this RP now that it is packed */ + *sz += bsz; + } + + return rpcnt; +} + +static size_t autorp_build_disc_packet(struct pim_autorp *autorp, uint8_t *buf, size_t buf_sz) +{ + size_t sz = 0; + struct autorp_pkt_hdr *hdr; + + if (buf_sz >= AUTORP_HDRLEN) { + hdr = (struct autorp_pkt_hdr *)buf; + hdr->version = AUTORP_VERSION; + hdr->type = AUTORP_DISCOVERY_TYPE; + hdr->holdtime = htons(autorp->discovery_holdtime); + hdr->reserved = 0; + sz += AUTORP_HDRLEN; + hdr->rpcnt = autorp_build_disc_rps(autorp, buf + sizeof(struct autorp_pkt_hdr), + (buf_sz - AUTORP_HDRLEN), &sz); + if (hdr->rpcnt == 0) + sz = 0; + } + return sz; +} + +static void autorp_send_discovery(struct event *evt) +{ + struct pim_autorp *autorp = EVENT_ARG(evt); + struct sockaddr_in discGrp; + size_t disc_sz; + size_t buf_sz = 65535; + uint8_t buf[65535] = { 0 }; + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP sending discovery info", __func__); + + /* Mark true, even if nothing is sent */ + autorp->mapping_agent_active = true; + disc_sz = autorp_build_disc_packet(autorp, buf, buf_sz); + + if (disc_sz > 0) { + discGrp.sin_family = AF_INET; + discGrp.sin_port = htons(PIM_AUTORP_PORT); + inet_pton(PIM_AF, PIM_AUTORP_DISCOVERY_GRP, &discGrp.sin_addr); + + if (setsockopt(autorp->sock, IPPROTO_IP, IP_MULTICAST_TTL, + &(autorp->discovery_scope), sizeof(autorp->discovery_scope)) == 0) { + if (setsockopt(autorp->sock, IPPROTO_IP, IP_MULTICAST_IF, + &(autorp->mapping_agent_addrsel.run_addr), + sizeof(autorp->mapping_agent_addrsel.run_addr)) == 0) { + if (sendto(autorp->sock, buf, disc_sz, 0, + (struct sockaddr *)&discGrp, sizeof(discGrp)) > 0) { + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP discovery message sent", + __func__); + } else if (PIM_DEBUG_AUTORP) + zlog_warn("%s: Failed to send AutoRP discovery message, errno=%d, %s", + __func__, errno, safe_strerror(errno)); + } else if (PIM_DEBUG_AUTORP) + zlog_warn("%s: Failed to set Multicast Interface for sending AutoRP discovery message, errno=%d, %s", + __func__, errno, safe_strerror(errno)); + } else if (PIM_DEBUG_AUTORP) + zlog_warn("%s: Failed to set Multicast TTL for sending AutoRP discovery message, errno=%d, %s", + __func__, errno, safe_strerror(errno)); + } + + /* Start the new timer for the entire send discovery interval */ + event_add_timer(router->master, autorp_send_discovery, autorp, autorp->discovery_interval, + &(autorp->send_discovery_timer)); +} + +static void autorp_send_discovery_on(struct pim_autorp *autorp) +{ + int interval = 5; + + /* Send the first discovery shortly after being enabled. + * If the configured interval is less than 5 seconds, then just use that. + */ + if (interval > autorp->discovery_interval) + interval = autorp->discovery_interval; + + if (autorp->send_discovery_timer) + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP discovery sending enabled in %u seconds", __func__, + interval); + + event_add_timer(router->master, autorp_send_discovery, autorp, interval, + &(autorp->send_discovery_timer)); +} + +static void autorp_send_discovery_off(struct pim_autorp *autorp) +{ + if (autorp->send_discovery_timer) + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP discovery sending disabled", __func__); + event_cancel(&(autorp->send_discovery_timer)); +} + +static bool autorp_recv_discovery(struct pim_autorp *autorp, uint8_t rpcnt, uint16_t holdtime, + char *buf, size_t buf_size, pim_addr src) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { int i, j; struct autorp_pkt_rp *rp; struct autorp_pkt_grp *grp; size_t offset = 0; pim_addr rp_addr; +<<<<<<< HEAD struct prefix grppfix; +======= + struct prefix grppfix = {}; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) char plname[32]; struct prefix_list *pl; struct prefix_list_entry *ple; int64_t seq = 1; bool success = true; +<<<<<<< HEAD for (i = 0; i < rpcnt; ++i) { if ((buf_size - offset) < AUTORP_RPLEN) return false; +======= + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Received AutoRP discovery message (src=%pI4, rpcnt=%u, holdtime=%u)", + __func__, &src, rpcnt, holdtime); + + if (autorp->send_rp_discovery && + (pim_addr_cmp(autorp->mapping_agent_addrsel.run_addr, src) < 0)) { + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP send discovery suppressed -- Discovery received with higher IP address", + __func__); + + /* Cancel the existing send timer and restart for 3X the send discovery interval */ + event_cancel(&(autorp->send_discovery_timer)); + event_add_timer(router->master, autorp_send_discovery, autorp, + (autorp->discovery_interval * 3), &(autorp->send_discovery_timer)); + + /* Clear the last sent discovery RP's, since it is no longer valid */ + pim_autorp_rplist_free(&autorp->advertised_rp_list, false); + /* Unset flag indicating we are active */ + autorp->mapping_agent_active = false; + } + + for (i = 0; i < rpcnt; ++i) { + if ((buf_size - offset) < AUTORP_RPLEN) { + zlog_warn("%s: Failed to parse AutoRP discovery message, invalid buffer size (%u < %u)", + __func__, (uint32_t)(buf_size - offset), AUTORP_RPLEN); + return false; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) rp = (struct autorp_pkt_rp *)(buf + offset); offset += AUTORP_RPLEN; rp_addr.s_addr = rp->addr; +<<<<<<< HEAD /* Ignore RP's limited to PIM version 1 or with an unknown version */ if (rp->pimver == PIM_V1 || rp->pimver == PIM_VUNKNOWN) { zlog_warn("%s: Ignoring unsupported PIM version in AutoRP Discovery for RP %pI4", __func__, (in_addr_t *)&(rp->addr)); +======= + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Parsing RP %pI4 (grpcnt=%u)", __func__, + (in_addr_t *)&rp->addr, rp->grpcnt); + + /* Ignore RP's limited to PIM version 1 or with an unknown version */ + if (rp->pimver == AUTORP_PIM_V1 || rp->pimver == AUTORP_PIM_VUNKNOWN) { + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Ignoring unsupported PIM version in AutoRP Discovery for RP %pI4", + __func__, (in_addr_t *)&(rp->addr)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Update the offset to skip past the groups advertised for this RP */ offset += (AUTORP_GRPLEN * rp->grpcnt); continue; } +<<<<<<< HEAD if (rp->grpcnt == 0) { /* No groups?? */ @@ -369,14 +1030,82 @@ static bool pim_autorp_discovery(struct pim_autorp *autorp, uint8_t rpcnt, for (j = 0; j < rp->grpcnt; ++j) { /* grp is already pointing at the first group in the buffer */ +======= + if (rp->grpcnt == 0) { + /* No groups?? */ + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Discovery message has no groups for RP %pI4", + __func__, (in_addr_t *)&(rp->addr)); + continue; + } + + /* Make sure there is enough buffer to parse all the groups */ + if ((buf_size - offset) < (AUTORP_GRPLEN * rp->grpcnt)) { + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Buffer underrun parsing groups for RP %pI4 (%u < %u)", + __func__, (in_addr_t *)&(rp->addr), + (uint32_t)(buf_size - offset), + (uint32_t)(AUTORP_GRPLEN * rp->grpcnt)); + return false; + } + + /* Get the first group so we can check for a negative prefix */ + /* Don't add to offset yet to make the multiple group loop easier */ + grp = (struct autorp_pkt_grp *)(buf + offset); + + if (rp->grpcnt == 1 && grp->negprefix == 0) { + /* Only one group with positive prefix, we can use the standard RP API */ + offset += AUTORP_GRPLEN; + grppfix.family = AF_INET; + grppfix.prefixlen = grp->masklen; + grppfix.u.prefix4.s_addr = grp->addr; + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Parsing group %s%pFX for RP %pI4", __func__, + (grp->negprefix ? "!" : ""), &grppfix, + (in_addr_t *)&rp->addr); + + if (!pim_autorp_add_rp(autorp, rp_addr, grppfix, NULL, holdtime)) + success = false; + } else { + /* More than one grp, or the only group is a negative prefix. + * Need to make a prefix list for this RP + */ + snprintfrr(plname, sizeof(plname), "__AUTORP_%pI4__", &rp_addr); + pl = prefix_list_lookup(AFI_IP, plname); + + if (pl) { + /* Existing prefix list found, delete it first */ + /* TODO: Instead of deleting completely, maybe we can just clear it and re-add entries */ + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Found existing prefix list %s, replacing it", + __func__, plname); + prefix_list_delete(pl); + } + + /* Now get a new prefix list */ + pl = prefix_list_get(AFI_IP, 0, plname); + + for (j = 0; j < rp->grpcnt; ++j) { + /* This will just set grp to the same pointer on the first loop, but offset will + * be updated correctly while parsing + */ + grp = (struct autorp_pkt_grp *)(buf + offset); + offset += AUTORP_GRPLEN; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ple = prefix_list_entry_new(); ple->pl = pl; ple->seq = seq; seq += 5; memset(&ple->prefix, 0, sizeof(ple->prefix)); prefix_list_entry_update_start(ple); +<<<<<<< HEAD ple->type = (grp->negprefix ? PREFIX_DENY : PREFIX_PERMIT); +======= + ple->type = (grp->negprefix ? PREFIX_DENY : PREFIX_PERMIT); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ple->prefix.family = AF_INET; ple->prefix.prefixlen = grp->masklen; ple->prefix.u.prefix4.s_addr = grp->addr; @@ -385,6 +1114,7 @@ static bool pim_autorp_discovery(struct pim_autorp *autorp, uint8_t rpcnt, ple->le = 32; prefix_list_entry_update_finish(ple); +<<<<<<< HEAD if ((buf_size - offset) < AUTORP_GRPLEN) return false; @@ -394,10 +1124,20 @@ static bool pim_autorp_discovery(struct pim_autorp *autorp, uint8_t rpcnt, if (!pim_autorp_add_rp(autorp, rp_addr, grppfix, plname, holdtime)) +======= + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Parsing group %s%pFX for RP %pI4", __func__, + (grp->negprefix ? "!" : ""), &ple->prefix, + (in_addr_t *)&rp->addr); + } + + if (!pim_autorp_add_rp(autorp, rp_addr, grppfix, plname, holdtime)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) success = false; } } +<<<<<<< HEAD if (PIM_DEBUG_AUTORP) zlog_debug("%s: Processed AutoRP Discovery message", __func__); @@ -431,14 +1171,55 @@ static bool pim_autorp_msg(struct pim_autorp *autorp, char *buf, size_t buf_size zlog_debug("%s: Processed AutoRP packet", __func__); return true; +======= + return success; +} + +static bool autorp_recv_msg(struct pim_autorp *autorp, char *buf, size_t buf_size, pim_addr src) +{ + struct autorp_pkt_hdr *h; + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Received AutoRP message", __func__); + + if (buf_size < AUTORP_HDRLEN) { + zlog_warn("%s: Invalid AutoRP Header size (%u < %u)", __func__, (uint32_t)buf_size, + AUTORP_HDRLEN); + return false; + } + + h = (struct autorp_pkt_hdr *)buf; + + if (h->version != AUTORP_VERSION) { + zlog_warn("%s: Unsupported AutoRP version (%u != %u)", __func__, h->version, + AUTORP_VERSION); + return false; + } + + if (h->type == AUTORP_ANNOUNCEMENT_TYPE) + return autorp_recv_announcement(autorp, h->rpcnt, htons(h->holdtime), + buf + AUTORP_HDRLEN, buf_size - AUTORP_HDRLEN); + + if (h->type == AUTORP_DISCOVERY_TYPE) + return autorp_recv_discovery(autorp, h->rpcnt, htons(h->holdtime), + buf + AUTORP_HDRLEN, buf_size - AUTORP_HDRLEN, src); + + zlog_warn("%s: Unknown AutoRP message type (%u)", __func__, h->type); + + return false; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static void autorp_read(struct event *t); static void autorp_read_on(struct pim_autorp *autorp) { +<<<<<<< HEAD event_add_read(router->master, autorp_read, autorp, autorp->sock, &(autorp->read_event)); +======= + event_add_read(router->master, autorp_read, autorp, autorp->sock, &(autorp->read_event)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (PIM_DEBUG_AUTORP) zlog_debug("%s: AutoRP socket read enabled", __func__); } @@ -456,18 +1237,30 @@ static void autorp_read(struct event *evt) int fd = evt->u.fd; char buf[10000]; int rd; +<<<<<<< HEAD +======= + struct sockaddr_storage from; + socklen_t fromlen = sizeof(from); + pim_addr src; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (PIM_DEBUG_AUTORP) zlog_debug("%s: Reading from AutoRP socket", __func__); while (1) { +<<<<<<< HEAD rd = pim_socket_recvfromto(fd, (uint8_t *)buf, sizeof(buf), NULL, NULL, NULL, NULL, NULL); +======= + rd = pim_socket_recvfromto(fd, (uint8_t *)buf, sizeof(buf), &from, &fromlen, NULL, + NULL, NULL); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (rd <= 0) { if (errno == EINTR) continue; if (errno == EWOULDBLOCK || errno == EAGAIN) break; +<<<<<<< HEAD zlog_warn("%s: Failure reading rd=%d: fd=%d: errno=%d: %s", __func__, rd, fd, errno, safe_strerror(errno)); @@ -476,6 +1269,22 @@ static void autorp_read(struct event *evt) if (!pim_autorp_msg(autorp, buf, rd)) zlog_err("%s: Failure parsing AutoRP message", __func__); +======= + zlog_warn("%s: Failure reading rd=%d: fd=%d: errno=%d: %s", __func__, rd, + fd, errno, safe_strerror(errno)); + goto err; + } + + if (from.ss_family == AF_INET) + src.s_addr = ((struct sockaddr_in *)&from)->sin_addr.s_addr; + else { + zlog_warn("%s: AutoRP message is not IPV4", __func__); + goto err; + } + + if (!autorp_recv_msg(autorp, buf, rd, src)) + zlog_warn("%s: Failure parsing AutoRP message", __func__); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Keep reading until would block */ } @@ -493,6 +1302,7 @@ static bool pim_autorp_socket_enable(struct pim_autorp *autorp) frr_with_privs (&pimd_privs) { fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (fd < 0) { +<<<<<<< HEAD zlog_warn("Could not create autorp socket: errno=%d: %s", errno, safe_strerror(errno)); return false; @@ -504,12 +1314,30 @@ static bool pim_autorp_socket_enable(struct pim_autorp *autorp) fd, errno, safe_strerror(errno)); close(fd); autorp->sock = -1; +======= + zlog_warn("Could not create autorp socket: errno=%d: %s", errno, + safe_strerror(errno)); + return false; + } + + if (!pim_autorp_setup(fd)) { + zlog_warn("Could not setup autorp socket fd=%d: errno=%d: %s", fd, errno, + safe_strerror(errno)); + close(fd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return false; } } +<<<<<<< HEAD if (PIM_DEBUG_AUTORP) zlog_debug("%s: AutoRP socket enabled", __func__); +======= + autorp->sock = fd; + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP socket enabled (fd=%u)", __func__, fd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return true; } @@ -517,8 +1345,13 @@ static bool pim_autorp_socket_enable(struct pim_autorp *autorp) static bool pim_autorp_socket_disable(struct pim_autorp *autorp) { if (close(autorp->sock)) { +<<<<<<< HEAD zlog_warn("Failure closing autorp socket: fd=%d errno=%d: %s", autorp->sock, errno, safe_strerror(errno)); +======= + zlog_warn("Failure closing autorp socket: fd=%d errno=%d: %s", autorp->sock, errno, + safe_strerror(errno)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return false; } @@ -542,6 +1375,7 @@ static void autorp_send_announcement(struct event *evt) announceGrp.sin_port = htons(PIM_AUTORP_PORT); inet_pton(PIM_AF, PIM_AUTORP_ANNOUNCEMENT_GRP, &announceGrp.sin_addr); +<<<<<<< HEAD if (autorp->annouce_pkt_sz >= MIN_AUTORP_PKT_SZ) { if (setsockopt(autorp->sock, IPPROTO_IP, IP_MULTICAST_TTL, &(autorp->announce_scope), @@ -549,6 +1383,17 @@ static void autorp_send_announcement(struct event *evt) if (PIM_DEBUG_AUTORP) zlog_err("%s: Failed to set Multicast TTL for sending AutoRP announcement message, errno=%d, %s", __func__, errno, safe_strerror(errno)); +======= + if (autorp->announce_pkt_sz >= MIN_AUTORP_PKT_SZ) { + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Sending AutoRP announcement", __func__); + + if (setsockopt(autorp->sock, IPPROTO_IP, IP_MULTICAST_TTL, + &(autorp->announce_scope), sizeof(autorp->announce_scope)) < 0) { + zlog_warn("%s: Failed to set Multicast TTL for sending AutoRP announcement message, errno=%d, %s", + __func__, errno, safe_strerror(errno)); + return; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } FOR_ALL_INTERFACES (autorp->pim->vrf, ifp) { @@ -556,6 +1401,7 @@ static void autorp_send_announcement(struct event *evt) /* Only send on active interfaces with full pim enabled, non-passive * and have a primary address set. */ +<<<<<<< HEAD if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && pim_ifp && pim_ifp->pim_enable && !pim_ifp->pim_passive_enable && @@ -579,19 +1425,44 @@ static void autorp_send_announcement(struct event *evt) __func__, errno, safe_strerror(errno)); } +======= + if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && pim_ifp && + pim_ifp->pim_enable && !pim_ifp->pim_passive_enable && + !pim_addr_is_any(pim_ifp->primary_address)) { + if (setsockopt(autorp->sock, IPPROTO_IP, IP_MULTICAST_IF, + &(pim_ifp->primary_address), + sizeof(pim_ifp->primary_address)) < 0) { + zlog_warn("%s: Failed to set Multicast Interface for sending AutoRP announcement message, errno=%d, %s", + __func__, errno, safe_strerror(errno)); + continue; + } + + if (sendto(autorp->sock, autorp->announce_pkt, + autorp->announce_pkt_sz, 0, + (struct sockaddr *)&announceGrp, + sizeof(announceGrp)) <= 0) + zlog_warn("%s: Failed to send AutoRP announcement message, errno=%d, %s", + __func__, errno, safe_strerror(errno)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } } /* Start the new timer for the entire announce interval */ +<<<<<<< HEAD event_add_timer(router->master, autorp_send_announcement, autorp, autorp->announce_interval, &(autorp->announce_timer)); +======= + event_add_timer(router->master, autorp_send_announcement, autorp, autorp->announce_interval, + &(autorp->announce_timer)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static void autorp_announcement_on(struct pim_autorp *autorp) { int interval = 5; +<<<<<<< HEAD if (interval > autorp->announce_interval) { /* If the configured interval is less than 5 seconds, then just use that */ interval = autorp->announce_interval; @@ -600,13 +1471,34 @@ static void autorp_announcement_on(struct pim_autorp *autorp) interval, &(autorp->announce_timer)); if (PIM_DEBUG_AUTORP) zlog_debug("%s: AutoRP announcement sending enabled", __func__); +======= + /* Send the first announcement shortly after being enabled. + * If the configured interval is less than 5 seconds, then just use that. + */ + if (interval > autorp->announce_interval) + interval = autorp->announce_interval; + + if (autorp->announce_timer == NULL) + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP announcement sending enabled", __func__); + + event_add_timer(router->master, autorp_send_announcement, autorp, interval, + &(autorp->announce_timer)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static void autorp_announcement_off(struct pim_autorp *autorp) { +<<<<<<< HEAD event_cancel(&(autorp->announce_timer)); if (PIM_DEBUG_AUTORP) zlog_debug("%s: AutoRP announcement sending disabled", __func__); +======= + if (autorp->announce_timer != NULL) + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP announcement sending disabled", __func__); + event_cancel(&(autorp->announce_timer)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Pack the groups of the RP @@ -614,6 +1506,7 @@ static void autorp_announcement_off(struct pim_autorp *autorp) * buf - Pointer to the buffer where to start packing groups * returns - Total group count packed */ +<<<<<<< HEAD static uint8_t pim_autorp_new_announcement_rp_grps(struct pim_autorp_rp *rp, uint8_t *buf) { @@ -622,11 +1515,18 @@ static uint8_t pim_autorp_new_announcement_rp_grps(struct pim_autorp_rp *rp, struct autorp_pkt_grp *grpp = (struct autorp_pkt_grp *)buf; uint8_t cnt = 0; in_addr_t taddr; +======= +static uint8_t pim_autorp_new_announcement_rp_grps(struct pim_autorp_rp *rp, uint8_t *buf) +{ + struct autorp_pkt_grp *grpp = (struct autorp_pkt_grp *)buf; + uint8_t cnt = 0; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (is_default_prefix(&(rp->grp))) { /* No group so pack from the prefix list * The grplist should be set and the prefix list exist with at least one group address */ +<<<<<<< HEAD plist = prefix_list_lookup(AFI_IP, rp->grplist); for (ple = plist->head; ple; ple = ple->next) { taddr = ntohl(ple->prefix.u.prefix4.s_addr); @@ -642,6 +1542,24 @@ static uint8_t pim_autorp_new_announcement_rp_grps(struct pim_autorp_rp *rp, *)(buf + (sizeof(struct autorp_pkt_grp) * cnt)); +======= + struct prefix_list *plist; + struct prefix_list_entry *ple; + + plist = prefix_list_lookup(AFI_IP, rp->grplist); + for (ple = plist->head; ple; ple = ple->next) { + if (pim_addr_is_multicast(ple->prefix.u.prefix4) && + ple->prefix.prefixlen >= 4) { + grpp->addr = ple->prefix.u.prefix4.s_addr; + grpp->masklen = ple->prefix.prefixlen; + grpp->negprefix = (ple->type == PREFIX_PERMIT ? 0 : 1); + grpp->reserved = 0; + + ++cnt; + grpp = (struct autorp_pkt_grp *)(buf + + (sizeof(struct autorp_pkt_grp) * + cnt)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -661,13 +1579,18 @@ static uint8_t pim_autorp_new_announcement_rp_grps(struct pim_autorp_rp *rp, * buf - Pointer to the buffer where to start packing the RP * returns - Buffer pointer pointing to the start of the next RP */ +<<<<<<< HEAD static uint8_t *pim_autorp_new_announcement_rp(struct pim_autorp_rp *rp, uint8_t *buf) +======= +static uint8_t *pim_autorp_new_announcement_rp(struct pim_autorp_rp *rp, uint8_t *buf) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct autorp_pkt_rp *brp = (struct autorp_pkt_rp *)buf; /* Since this is an in_addr, assume it's already the right byte order */ brp->addr = rp->addr.s_addr; +<<<<<<< HEAD brp->pimver = PIM_V2; brp->reserved = 0; brp->grpcnt = @@ -675,6 +1598,12 @@ static uint8_t *pim_autorp_new_announcement_rp(struct pim_autorp_rp *rp, buf + sizeof(struct autorp_pkt_rp)); return buf + sizeof(struct autorp_pkt_rp) + (brp->grpcnt * sizeof(struct autorp_pkt_grp)); +======= + brp->pimver = AUTORP_PIM_V2; + brp->reserved = 0; + brp->grpcnt = pim_autorp_new_announcement_rp_grps(rp, buf + sizeof(struct autorp_pkt_rp)); + return buf + sizeof(struct autorp_pkt_rp) + (brp->grpcnt * sizeof(struct autorp_pkt_grp)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Pack the candidate RP's on the announcement packet @@ -683,13 +1612,18 @@ static uint8_t *pim_autorp_new_announcement_rp(struct pim_autorp_rp *rp, * bufsz - Output parameter to track size of packed bytes * returns - Total count of RP's packed */ +<<<<<<< HEAD static int pim_autorp_new_announcement_rps(struct pim_autorp *autorp, uint8_t *buf, uint16_t *bufsz) +======= +static int pim_autorp_new_announcement_rps(struct pim_autorp *autorp, uint8_t *buf, uint16_t *bufsz) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { int cnt = 0; struct pim_autorp_rp *rp; /* Keep the original buffer pointer to calculate final size after packing */ uint8_t *obuf = buf; +<<<<<<< HEAD struct prefix_list *plist; struct prefix_list_entry *ple; in_addr_t taddr; @@ -702,17 +1636,50 @@ static int pim_autorp_new_announcement_rps(struct pim_autorp *autorp, /* Group is net set, so list must be set, make sure the prefix list exists and has valid multicast groups */ if (is_default_prefix(&(rp->grp))) { +======= + + frr_each_safe (pim_autorp_rp, &(autorp->candidate_rp_list), rp) { + /* We must have an rp address and either group or list in order to pack this RP, + * so skip this one + */ + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: Evaluating AutoRP candidate %pI4, group range %pFX, group list %s", + __func__, &rp->addr, &rp->grp, rp->grplist); + + if (pim_addr_is_any(rp->addr) || + (is_default_prefix(&rp->grp) && strlen(rp->grplist) == 0)) + continue; + + /* Make sure that either group prefix is set, or that the prefix list exists and has at + * least one valid multicast prefix in it. Only multicast prefixes will be used. + */ + if (is_default_prefix(&rp->grp)) { + struct prefix_list *plist; + struct prefix_list_entry *ple; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) plist = prefix_list_lookup(AFI_IP, rp->grplist); if (plist == NULL) continue; plist = prefix_list_lookup(AFI_IP, rp->grplist); for (ple = plist->head; ple; ple = ple->next) { +<<<<<<< HEAD taddr = ntohl(ple->prefix.u.prefix4.s_addr); if ((taddr & 0xF0000000) == 0xE0000000) break; } /* If we went through the entire list without finding a multicast prefix, then skip this RP */ +======= + if (pim_addr_is_multicast(ple->prefix.u.prefix4) && + ple->prefix.prefixlen >= 4) + break; + } + + /* If we went through the entire list without finding a multicast prefix, + * then skip this RP + */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (ple == NULL) continue; } @@ -721,6 +1688,13 @@ static int pim_autorp_new_announcement_rps(struct pim_autorp *autorp, ++cnt; /* This will return the buffer pointer at the location to start packing the next RP */ buf = pim_autorp_new_announcement_rp(rp, buf); +<<<<<<< HEAD +======= + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP candidate %pI4 added to announcement", __func__, + &rp->addr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (cnt > 0) @@ -729,7 +1703,13 @@ static int pim_autorp_new_announcement_rps(struct pim_autorp *autorp, return cnt; } +<<<<<<< HEAD /* Build the new announcement packet. If there is a packet to send, restart the send timer with a short wait */ +======= +/* Build the new announcement packet. If there is a packet to send, restart the send timer + * with a short wait + */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static void pim_autorp_new_announcement(struct pim_instance *pim) { struct pim_autorp *autorp = pim->autorp; @@ -739,6 +1719,7 @@ static void pim_autorp_new_announcement(struct pim_instance *pim) /* First disable any existing send timer */ autorp_announcement_off(autorp); +<<<<<<< HEAD if (!autorp->annouce_pkt) { /* * First time building, allocate the space @@ -752,15 +1733,35 @@ static void pim_autorp_new_announcement(struct pim_instance *pim) holdtime = autorp->announce_holdtime; if (holdtime == DEFAULT_ANNOUNCE_HOLDTIME) +======= + /* + * First time building, allocate the space + * Allocate the max packet size of 65536 so we don't need to resize later. + * This should be ok since we are only allocating the memory once for a single packet + * (potentially per vrf) + */ + if (!autorp->announce_pkt) + autorp->announce_pkt = XCALLOC(MTYPE_PIM_AUTORP_ANNOUNCE, 65536); + + autorp->announce_pkt_sz = 0; + + holdtime = autorp->announce_holdtime; + if (holdtime == DEFAULT_AUTORP_ANNOUNCE_HOLDTIME) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) holdtime = autorp->announce_interval * 3; if (holdtime > UINT16_MAX) holdtime = UINT16_MAX; +<<<<<<< HEAD hdr = (struct autorp_pkt_hdr *)autorp->annouce_pkt; +======= + hdr = (struct autorp_pkt_hdr *)autorp->announce_pkt; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) hdr->version = AUTORP_VERSION; hdr->type = AUTORP_ANNOUNCEMENT_TYPE; hdr->holdtime = htons((uint16_t)holdtime); hdr->reserved = 0; +<<<<<<< HEAD hdr->rpcnt = pim_autorp_new_announcement_rps(autorp, autorp->annouce_pkt + @@ -775,34 +1776,88 @@ static void pim_autorp_new_announcement(struct pim_instance *pim) autorp_announcement_on(autorp); } +======= + hdr->rpcnt = pim_autorp_new_announcement_rps(autorp, + autorp->announce_pkt + + sizeof(struct autorp_pkt_hdr), + &(autorp->announce_pkt_sz)); + + /* Still need to add on the size of the header */ + autorp->announce_pkt_sz += sizeof(struct autorp_pkt_hdr); + + /* Only turn on the announcement timer if we have a packet to send */ + if (autorp->announce_pkt_sz >= MIN_AUTORP_PKT_SZ) + autorp_announcement_on(autorp); +} + +void pim_autorp_prefix_list_update(struct pim_instance *pim, struct prefix_list *plist) +{ + struct pim_autorp_rp *rp = NULL; + struct pim_autorp *autorp = NULL; + + autorp = pim->autorp; + if (autorp == NULL) + return; + + /* Search for a candidate RP using this prefix list */ + frr_each_safe (pim_autorp_rp, &(autorp->candidate_rp_list), rp) { + if (strmatch(rp->grplist, plist->name)) + break; + } + + /* If we broke out of the loop early because we found a match, then rebuild the announcement */ + if (rp != NULL) + pim_autorp_new_announcement(pim); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bool pim_autorp_rm_candidate_rp(struct pim_instance *pim, pim_addr rpaddr) { struct pim_autorp *autorp = pim->autorp; struct pim_autorp_rp *rp; struct pim_autorp_rp find = { .addr = rpaddr }; +<<<<<<< HEAD rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); +======= + rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!rp) return false; pim_autorp_rp_del(&(autorp->candidate_rp_list), rp); +<<<<<<< HEAD pim_autorp_rp_free(rp); +======= + pim_autorp_rp_free(rp, false); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_autorp_new_announcement(pim); return true; } +<<<<<<< HEAD void pim_autorp_add_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr, struct prefix group) +======= +void pim_autorp_add_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr, + struct prefix group) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct pim_autorp *autorp = pim->autorp; struct pim_autorp_rp *rp; struct pim_autorp_rp find = { .addr = rpaddr }; +<<<<<<< HEAD rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); if (!rp) { rp = XCALLOC(MTYPE_PIM_AUTORP_CRP, sizeof(*rp)); +======= + rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); + if (!rp) { + rp = XCALLOC(MTYPE_PIM_AUTORP_RP, sizeof(*rp)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) memset(rp, 0, sizeof(struct pim_autorp_rp)); rp->autorp = autorp; memcpy(&(rp->addr), &rpaddr, sizeof(pim_addr)); @@ -817,15 +1872,23 @@ void pim_autorp_add_candidate_rp_group(struct pim_instance *pim, pim_autorp_new_announcement(pim); } +<<<<<<< HEAD bool pim_autorp_rm_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr, struct prefix group) +======= +bool pim_autorp_rm_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr, struct prefix group) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct pim_autorp *autorp = pim->autorp; struct pim_autorp_rp *rp; struct pim_autorp_rp find = { .addr = rpaddr }; +<<<<<<< HEAD rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); +======= + rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!rp) return false; @@ -834,17 +1897,27 @@ bool pim_autorp_rm_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr, return true; } +<<<<<<< HEAD void pim_autorp_add_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist) +======= +void pim_autorp_add_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct pim_autorp *autorp = pim->autorp; struct pim_autorp_rp *rp; struct pim_autorp_rp find = { .addr = rpaddr }; +<<<<<<< HEAD rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); if (!rp) { rp = XCALLOC(MTYPE_PIM_AUTORP_CRP, sizeof(*rp)); +======= + rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); + if (!rp) { + rp = XCALLOC(MTYPE_PIM_AUTORP_RP, sizeof(*rp)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) memset(rp, 0, sizeof(struct pim_autorp_rp)); rp->autorp = autorp; memcpy(&(rp->addr), &rpaddr, sizeof(pim_addr)); @@ -859,15 +1932,23 @@ void pim_autorp_add_candidate_rp_plist(struct pim_instance *pim, pim_autorp_new_announcement(pim); } +<<<<<<< HEAD bool pim_autorp_rm_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist) +======= +bool pim_autorp_rm_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct pim_autorp *autorp = pim->autorp; struct pim_autorp_rp *rp; struct pim_autorp_rp find = { .addr = rpaddr }; +<<<<<<< HEAD rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); +======= + rp = pim_autorp_rp_find(&(autorp->candidate_rp_list), (const struct pim_autorp_rp *)&find); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!rp) return false; @@ -880,7 +1961,11 @@ void pim_autorp_announce_scope(struct pim_instance *pim, uint8_t scope) { struct pim_autorp *autorp = pim->autorp; +<<<<<<< HEAD scope = (scope == 0 ? DEFAULT_ANNOUNCE_SCOPE : scope); +======= + scope = (scope == 0 ? DEFAULT_AUTORP_ANNOUNCE_SCOPE : scope); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (autorp->announce_scope != scope) { autorp->announce_scope = scope; pim_autorp_new_announcement(pim); @@ -891,7 +1976,11 @@ void pim_autorp_announce_interval(struct pim_instance *pim, uint16_t interval) { struct pim_autorp *autorp = pim->autorp; +<<<<<<< HEAD interval = (interval == 0 ? DEFAULT_ANNOUNCE_INTERVAL : interval); +======= + interval = (interval == 0 ? DEFAULT_AUTORP_ANNOUNCE_INTERVAL : interval); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (autorp->announce_interval != interval) { autorp->announce_interval = interval; pim_autorp_new_announcement(pim); @@ -908,6 +1997,19 @@ void pim_autorp_announce_holdtime(struct pim_instance *pim, int32_t holdtime) } } +<<<<<<< HEAD +======= +void pim_autorp_send_discovery_apply(struct pim_autorp *autorp) +{ + if (!autorp->mapping_agent_addrsel.run || !autorp->send_rp_discovery) { + autorp_send_discovery_off(autorp); + return; + } + + autorp_send_discovery_on(autorp); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void pim_autorp_add_ifp(struct interface *ifp) { /* Add a new interface for autorp @@ -923,17 +2025,27 @@ void pim_autorp_add_ifp(struct interface *ifp) struct pim_interface *pim_ifp; pim_ifp = ifp->info; +<<<<<<< HEAD if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && pim_ifp && pim_ifp->pim_enable) { +======= + if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && pim_ifp && pim_ifp->pim_enable) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim = pim_ifp->pim; if (pim && pim->autorp && pim->autorp->do_discovery) { if (PIM_DEBUG_AUTORP) zlog_debug("%s: Adding interface %s to AutoRP, joining AutoRP groups", __func__, ifp->name); +<<<<<<< HEAD if (!pim_autorp_join_groups(ifp)) { zlog_err("Could not join AutoRP groups, errno=%d, %s", errno, safe_strerror(errno)); } +======= + if (!pim_autorp_join_groups(ifp)) + zlog_warn("Could not join AutoRP groups, errno=%d, %s", errno, + safe_strerror(errno)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } } @@ -954,10 +2066,16 @@ void pim_autorp_rm_ifp(struct interface *ifp) if (PIM_DEBUG_AUTORP) zlog_debug("%s: Removing interface %s from AutoRP, leaving AutoRP groups", __func__, ifp->name); +<<<<<<< HEAD if (!pim_autorp_leave_groups(ifp)) { zlog_err("Could not leave AutoRP groups, errno=%d, %s", errno, safe_strerror(errno)); } +======= + if (!pim_autorp_leave_groups(ifp)) + zlog_warn("Could not leave AutoRP groups, errno=%d, %s", errno, + safe_strerror(errno)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } } @@ -1008,16 +2126,37 @@ void pim_autorp_init(struct pim_instance *pim) autorp->read_event = NULL; autorp->announce_timer = NULL; autorp->do_discovery = false; +<<<<<<< HEAD pim_autorp_rp_init(&(autorp->discovery_rp_list)); pim_autorp_rp_init(&(autorp->candidate_rp_list)); autorp->announce_scope = DEFAULT_ANNOUNCE_SCOPE; autorp->announce_interval = DEFAULT_ANNOUNCE_INTERVAL; autorp->announce_holdtime = DEFAULT_ANNOUNCE_HOLDTIME; +======= + autorp->send_discovery_timer = NULL; + autorp->send_rp_discovery = false; + pim_autorp_rp_init(&(autorp->discovery_rp_list)); + pim_autorp_rp_init(&(autorp->candidate_rp_list)); + pim_autorp_rp_init(&(autorp->mapping_rp_list)); + pim_autorp_rp_init(&autorp->advertised_rp_list); + autorp->announce_scope = DEFAULT_AUTORP_ANNOUNCE_SCOPE; + autorp->announce_interval = DEFAULT_AUTORP_ANNOUNCE_INTERVAL; + autorp->announce_holdtime = DEFAULT_AUTORP_ANNOUNCE_HOLDTIME; + autorp->discovery_scope = DEFAULT_AUTORP_DISCOVERY_SCOPE; + autorp->discovery_interval = DEFAULT_AUTORP_DISCOVERY_INTERVAL; + autorp->discovery_holdtime = DEFAULT_AUTORP_DISCOVERY_HOLDTIME; + cand_addrsel_clear(&(autorp->mapping_agent_addrsel)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim->autorp = autorp; if (!pim_autorp_socket_enable(autorp)) { +<<<<<<< HEAD zlog_err("%s: AutoRP failed to initialize, feature will not work correctly", __func__); +======= + zlog_warn("%s: AutoRP failed to initialize, feature will not work correctly", + __func__); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -1033,6 +2172,7 @@ void pim_autorp_finish(struct pim_instance *pim) struct pim_autorp *autorp = pim->autorp; autorp_read_off(autorp); +<<<<<<< HEAD pim_autorp_free(autorp); if (pim_autorp_socket_disable(autorp)) { if (PIM_DEBUG_AUTORP) @@ -1041,16 +2181,29 @@ void pim_autorp_finish(struct pim_instance *pim) zlog_err("%s: AutoRP failed to finish", __func__); XFREE(MTYPE_PIM_AUTORP, pim->autorp); +======= + autorp_announcement_off(autorp); + autorp_send_discovery_off(autorp); + pim_autorp_free(autorp); + pim_autorp_socket_disable(autorp); + XFREE(MTYPE_PIM_AUTORP, pim->autorp); + + if (PIM_DEBUG_AUTORP) + zlog_debug("%s: AutoRP Finished", __func__); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } int pim_autorp_config_write(struct pim_instance *pim, struct vty *vty) { struct pim_autorp_rp *rp; struct pim_autorp *autorp = pim->autorp; +<<<<<<< HEAD char interval_str[16] = { 0 }; char scope_str[16] = { 0 }; char holdtime_str[32] = { 0 }; char grp_str[64] = { 0 }; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int writes = 0; if (!autorp->do_discovery) { @@ -1058,6 +2211,7 @@ int pim_autorp_config_write(struct pim_instance *pim, struct vty *vty) ++writes; } +<<<<<<< HEAD if (autorp->announce_interval != DEFAULT_ANNOUNCE_INTERVAL) { snprintf(interval_str, sizeof(interval_str), " interval %u", autorp->announce_interval); @@ -1076,6 +2230,19 @@ int pim_autorp_config_write(struct pim_instance *pim, struct vty *vty) if (strlen(interval_str) || strlen(scope_str) || strlen(holdtime_str)) { vty_out(vty, " autorp announce%s%s%s\n", interval_str, scope_str, holdtime_str); +======= + if (autorp->announce_interval != DEFAULT_AUTORP_ANNOUNCE_INTERVAL || + autorp->announce_scope != DEFAULT_AUTORP_ANNOUNCE_SCOPE || + autorp->announce_holdtime != DEFAULT_AUTORP_ANNOUNCE_HOLDTIME) { + vty_out(vty, " autorp announce"); + if (autorp->announce_interval != DEFAULT_AUTORP_ANNOUNCE_INTERVAL) + vty_out(vty, " interval %u", autorp->announce_interval); + if (autorp->announce_scope != DEFAULT_AUTORP_ANNOUNCE_SCOPE) + vty_out(vty, " scope %u", autorp->announce_scope); + if (autorp->announce_holdtime != DEFAULT_AUTORP_ANNOUNCE_HOLDTIME) + vty_out(vty, " holdtime %u", autorp->announce_holdtime); + vty_out(vty, "\n"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ++writes; } @@ -1085,6 +2252,7 @@ int pim_autorp_config_write(struct pim_instance *pim, struct vty *vty) (is_default_prefix(&(rp->grp)) && strlen(rp->grplist) == 0)) continue; +<<<<<<< HEAD /* Don't make sure the prefix list has multicast groups, user may not have created it yet */ if (!is_default_prefix(&(rp->grp))) @@ -1164,4 +2332,373 @@ void pim_autorp_show_autorp(struct vty *vty, struct pim_instance *pim, } ttable_del(tt); +======= + vty_out(vty, " autorp announce %pI4", &(rp->addr)); + if (!is_default_prefix(&(rp->grp))) + vty_out(vty, " %pFX", &(rp->grp)); + else + vty_out(vty, " group-list %s", rp->grplist); + vty_out(vty, "\n"); + ++writes; + } + + if (autorp->send_rp_discovery) { + if (autorp->mapping_agent_addrsel.cfg_enable) { + vty_out(vty, " autorp send-rp-discovery"); + switch (autorp->mapping_agent_addrsel.cfg_mode) { + case CAND_ADDR_LO: + break; + case CAND_ADDR_ANY: + vty_out(vty, " source any"); + break; + case CAND_ADDR_IFACE: + vty_out(vty, " source interface %s", + autorp->mapping_agent_addrsel.cfg_ifname); + break; + case CAND_ADDR_EXPLICIT: + vty_out(vty, " source address %pPA", + &autorp->mapping_agent_addrsel.cfg_addr); + break; + } + vty_out(vty, "\n"); + ++writes; + } + + if (autorp->discovery_interval != DEFAULT_AUTORP_DISCOVERY_INTERVAL || + autorp->discovery_scope != DEFAULT_AUTORP_DISCOVERY_SCOPE || + autorp->discovery_holdtime != DEFAULT_AUTORP_DISCOVERY_HOLDTIME) { + vty_out(vty, " autorp send-rp-discovery"); + if (autorp->discovery_interval != DEFAULT_AUTORP_DISCOVERY_INTERVAL) + vty_out(vty, " interval %u", autorp->discovery_interval); + if (autorp->discovery_scope != DEFAULT_AUTORP_DISCOVERY_SCOPE) + vty_out(vty, " scope %u", autorp->discovery_scope); + if (autorp->discovery_holdtime != DEFAULT_AUTORP_DISCOVERY_HOLDTIME) + vty_out(vty, " holdtime %u", autorp->discovery_holdtime); + vty_out(vty, "\n"); + ++writes; + } + } + + return writes; +} + +static void pim_autorp_show_autorp_json(struct pim_autorp *autorp, const char *component, + json_object *json, struct ttable *cand_table) +{ + struct pim_autorp_rp *rp; + + if (!component || strmatch(component, "discovery")) { + json_object *disc_obj; + + disc_obj = json_object_new_object(); + json_object_boolean_add(disc_obj, "enabled", autorp->do_discovery); + if (autorp->do_discovery) { + json_object *rplist_obj; + + rplist_obj = json_object_new_object(); + frr_each (pim_autorp_rp, &(autorp->discovery_rp_list), rp) { + json_object *rp_obj; + json_object *grp_arr; + + rp_obj = json_object_new_object(); + json_object_string_addf(rp_obj, "rpAddress", "%pI4", &rp->addr); + json_object_int_add(rp_obj, "holdtime", rp->holdtime); + grp_arr = json_object_new_array(); + + if (strlen(rp->grplist)) { + struct prefix_list *pl; + struct prefix_list_entry *ple; + + pl = prefix_list_lookup(AFI_IP, rp->grplist); + if (pl == NULL) + continue; + + for (ple = pl->head; ple != NULL; ple = ple->next) { + json_object *grp_obj; + + grp_obj = json_object_new_object(); + json_object_boolean_add(grp_obj, "negative", + ple->type == PREFIX_DENY); + json_object_string_addf(grp_obj, "prefix", "%pFX", + &ple->prefix); + json_object_array_add(grp_arr, grp_obj); + } + } else { + json_object *grp_obj; + + grp_obj = json_object_new_object(); + json_object_boolean_add(grp_obj, "negative", false); + json_object_string_addf(grp_obj, "prefix", "%pFX", &rp->grp); + json_object_array_add(grp_arr, grp_obj); + } + + json_object_object_add(rp_obj, "groupRanges", grp_arr); + json_object_object_addf(rplist_obj, rp_obj, "%pI4", &rp->addr); + } + json_object_object_add(disc_obj, "rpList", rplist_obj); + } + json_object_object_add(json, "discovery", disc_obj); + } + + if (!component || strmatch(component, "candidate")) { + json_object *announce_obj; + + announce_obj = json_object_new_object(); + json_object_boolean_add(announce_obj, "enabled", + pim_autorp_rp_count(&autorp->candidate_rp_list) > 0); + if (pim_autorp_rp_count(&autorp->candidate_rp_list) > 0) { + json_object_int_add(announce_obj, "scope", autorp->announce_scope); + json_object_int_add(announce_obj, "interval", autorp->announce_interval); + json_object_int_add(announce_obj, "holdtime", + (autorp->announce_holdtime == + DEFAULT_AUTORP_ANNOUNCE_HOLDTIME + ? (autorp->announce_interval * 3) + : autorp->announce_holdtime)); + json_object_object_add(announce_obj, "rpList", + ttable_json_with_json_text(cand_table, "sss", + "rpAddress|groupRange|prefixList")); + } + json_object_object_add(json, "announce", announce_obj); + } + + if (!component || strmatch(component, "mapping-agent")) { + json_object *adv_obj; + + adv_obj = json_object_new_object(); + json_object_boolean_add(adv_obj, "enabled", autorp->send_rp_discovery); + if (autorp->send_rp_discovery) { + json_object *rplist_obj; + + json_object_boolean_add(adv_obj, "active", autorp->mapping_agent_active); + json_object_int_add(adv_obj, "scope", autorp->discovery_scope); + json_object_int_add(adv_obj, "interval", autorp->discovery_interval); + json_object_int_add(adv_obj, "holdtime", autorp->discovery_holdtime); + switch (autorp->mapping_agent_addrsel.cfg_mode) { + case CAND_ADDR_LO: + json_object_string_add(adv_obj, "source", "loopback"); + break; + case CAND_ADDR_ANY: + json_object_string_add(adv_obj, "source", "any"); + break; + case CAND_ADDR_IFACE: + json_object_string_add(adv_obj, "source", "interface"); + json_object_string_add(adv_obj, "interface", + autorp->mapping_agent_addrsel.cfg_ifname); + break; + case CAND_ADDR_EXPLICIT: + json_object_string_add(adv_obj, "source", "address"); + break; + } + json_object_string_addf(adv_obj, "address", "%pPA", + &autorp->mapping_agent_addrsel.run_addr); + + rplist_obj = json_object_new_object(); + frr_each (pim_autorp_rp, &(autorp->advertised_rp_list), rp) { + json_object *rp_obj; + json_object *grp_arr; + struct pim_autorp_grppfix *grppfix; + + rp_obj = json_object_new_object(); + json_object_string_addf(rp_obj, "rpAddress", "%pI4", &rp->addr); + grp_arr = json_object_new_array(); + frr_each (pim_autorp_grppfix, &rp->grp_pfix_list, grppfix) { + json_object *grp_obj; + + grp_obj = json_object_new_object(); + json_object_boolean_add(grp_obj, "negative", + grppfix->negative); + json_object_string_addf(grp_obj, "prefix", "%pFX", + &grppfix->grp); + json_object_array_add(grp_arr, grp_obj); + } + json_object_object_add(rp_obj, "groupRanges", grp_arr); + json_object_object_addf(rplist_obj, rp_obj, "%pI4", &rp->addr); + } + json_object_object_add(adv_obj, "rpList", rplist_obj); + } + json_object_object_add(json, "mapping-agent", adv_obj); + } +} + +void pim_autorp_show_autorp(struct vty *vty, struct pim_instance *pim, const char *component, + json_object *json) +{ + struct pim_autorp *autorp = pim->autorp; + struct pim_autorp_rp *rp; + struct ttable *cand_table = NULL; + struct ttable *adv_table = NULL; + struct ttable *disc_table = NULL; + char *tmp; + + if (autorp == NULL) + return; + + /* We may use the candidate table in the json output, so prepare it first. */ + if (!component || strmatch(component, "candidate")) { + cand_table = ttable_new(&ttable_styles[TTSTYLE_BLANK]); + ttable_add_row(cand_table, "RP address|Group Range|Prefix-List"); + cand_table->style.cell.rpad = 2; + cand_table->style.corner = '+'; + ttable_restyle(cand_table); + + frr_each (pim_autorp_rp, &(autorp->candidate_rp_list), rp) { + if (strlen(rp->grplist)) + ttable_add_row(cand_table, "%pI4|%s|%s", &(rp->addr), "-", + rp->grplist); + else + ttable_add_row(cand_table, "%pI4|%pFX|%s", &(rp->addr), &(rp->grp), + "-"); + } + } + + if (json) { + pim_autorp_show_autorp_json(autorp, component, json, cand_table); + if (cand_table) + ttable_del(cand_table); + return; + } + + /* Prepare discovered RP's table. */ + if (!component || strmatch(component, "discovery")) { + disc_table = ttable_new(&ttable_styles[TTSTYLE_BLANK]); + ttable_add_row(disc_table, "RP address|Group Range"); + disc_table->style.cell.rpad = 2; + disc_table->style.corner = '+'; + ttable_restyle(disc_table); + + frr_each (pim_autorp_rp, &(autorp->discovery_rp_list), rp) { + if (strlen(rp->grplist)) { + struct prefix_list *pl; + struct prefix_list_entry *ple; + bool first = true; + + pl = prefix_list_lookup(AFI_IP, rp->grplist); + + if (pl == NULL) { + ttable_add_row(disc_table, + "%pI4|failed to find prefix list %s", + &(rp->addr), rp->grplist); + continue; + } + + for (ple = pl->head; ple != NULL; ple = ple->next) { + if (first) + ttable_add_row(disc_table, "%pI4|%s%pFX", + &(rp->addr), + (ple->type == PREFIX_DENY ? "!" + : " "), + &ple->prefix); + else + ttable_add_row(disc_table, "%s|%s%pFX", " ", + (ple->type == PREFIX_DENY ? "!" + : " "), + &ple->prefix); + first = false; + } + } else + ttable_add_row(disc_table, "%pI4| %pFX", &(rp->addr), &(rp->grp)); + } + } + + /* Prepare discovery RP's table (mapping-agent). */ + if (!component || strmatch(component, "mapping-agent")) { + adv_table = ttable_new(&ttable_styles[TTSTYLE_BLANK]); + ttable_add_row(adv_table, "RP address|Group Range"); + adv_table->style.cell.rpad = 2; + adv_table->style.corner = '+'; + ttable_restyle(adv_table); + + frr_each (pim_autorp_rp, &(autorp->advertised_rp_list), rp) { + struct pim_autorp_grppfix *grppfix; + bool first = true; + + frr_each (pim_autorp_grppfix, &rp->grp_pfix_list, grppfix) { + if (first) + ttable_add_row(adv_table, "%pI4|%s%pFX", &rp->addr, + grppfix->negative ? "!" : " ", &grppfix->grp); + else + ttable_add_row(adv_table, "%s|%s%pFX", " ", + grppfix->negative ? "!" : " ", &grppfix->grp); + first = false; + } + } + } + + if (!component || strmatch(component, "discovery")) { + vty_out(vty, "AutoRP Discovery is %sabled\n", (autorp->do_discovery ? "en" : "dis")); + if (autorp->do_discovery) { + tmp = ttable_dump(disc_table, "\n"); + vty_out(vty, "\n"); + vty_out(vty, "Discovered RP's (count=%u)\n", + (uint32_t)pim_autorp_rp_count(&autorp->discovery_rp_list)); + vty_out(vty, "%s\n", tmp); + XFREE(MTYPE_TMP_TTABLE, tmp); + } else + vty_out(vty, "\n"); + } + + if (!component || strmatch(component, "candidate")) { + vty_out(vty, "AutoRP Announcement is %sabled\n", + (pim_autorp_rp_count(&autorp->candidate_rp_list) > 0 ? "en" : "dis")); + if (pim_autorp_rp_count(&autorp->candidate_rp_list) > 0) { + tmp = ttable_dump(cand_table, "\n"); + vty_out(vty, " interval %us scope %u holdtime %us\n", + autorp->announce_interval, autorp->announce_scope, + (autorp->announce_holdtime == DEFAULT_AUTORP_ANNOUNCE_HOLDTIME + ? (autorp->announce_interval * 3) + : autorp->announce_holdtime)); + vty_out(vty, "\n"); + vty_out(vty, "Candidate RP's (count=%u)\n", + (uint32_t)pim_autorp_rp_count(&autorp->candidate_rp_list)); + vty_out(vty, "%s\n", tmp); + XFREE(MTYPE_TMP_TTABLE, tmp); + } else + vty_out(vty, "\n"); + } + + if (!component || strmatch(component, "mapping-agent")) { + vty_out(vty, "AutoRP Mapping-Agent is %sabled\n", + (autorp->send_rp_discovery ? "en" : "dis")); + if (autorp->send_rp_discovery) { + vty_out(vty, " interval %us scope %u holdtime %us\n", + autorp->discovery_interval, autorp->discovery_scope, + autorp->discovery_holdtime); + vty_out(vty, " source %pPA", &autorp->mapping_agent_addrsel.run_addr); + switch (autorp->mapping_agent_addrsel.cfg_mode) { + case CAND_ADDR_LO: + vty_out(vty, " (loopback)"); + break; + case CAND_ADDR_ANY: + vty_out(vty, " (any)"); + break; + case CAND_ADDR_IFACE: + vty_out(vty, " (interface %s)", + autorp->mapping_agent_addrsel.cfg_ifname); + break; + case CAND_ADDR_EXPLICIT: + vty_out(vty, " (explicit address)"); + break; + } + vty_out(vty, "\n"); + + if (autorp->mapping_agent_active) { + tmp = ttable_dump(adv_table, "\n"); + vty_out(vty, "\n"); + vty_out(vty, "Advertised RP's (count=%u)\n", + (uint32_t)pim_autorp_rp_count(&autorp->advertised_rp_list)); + vty_out(vty, "%s\n", tmp); + XFREE(MTYPE_TMP_TTABLE, tmp); + } else + vty_out(vty, " Mapping agent is inactive\n"); + } else + vty_out(vty, "\n"); + } + + if (cand_table) + ttable_del(cand_table); + if (adv_table) + ttable_del(adv_table); + if (disc_table) + ttable_del(disc_table); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } diff --git a/pimd/pim_autorp.h b/pimd/pim_autorp.h index a0b029d00ae6..96bb52f51836 100644 --- a/pimd/pim_autorp.h +++ b/pimd/pim_autorp.h @@ -14,6 +14,7 @@ #define AUTORP_VERSION 1 #define AUTORP_ANNOUNCEMENT_TYPE 1 #define AUTORP_DISCOVERY_TYPE 2 +<<<<<<< HEAD #define PIM_VUNKNOWN 0 #define PIM_V1 1 #define PIM_V2 2 @@ -24,6 +25,23 @@ #define DEFAULT_ANNOUNCE_HOLDTIME -1 PREDECL_SORTLIST_UNIQ(pim_autorp_rp); +======= +#define AUTORP_PIM_VUNKNOWN 0 +#define AUTORP_PIM_V1 1 +#define AUTORP_PIM_V2 2 +#define AUTORP_PIM_V1_2 3 + +#define DEFAULT_AUTORP_ANNOUNCE_INTERVAL 60 +#define DEFAULT_AUTORP_ANNOUNCE_SCOPE 31 +#define DEFAULT_AUTORP_ANNOUNCE_HOLDTIME -1 + +#define DEFAULT_AUTORP_DISCOVERY_INTERVAL 60 +#define DEFAULT_AUTORP_DISCOVERY_SCOPE 31 +#define DEFAULT_AUTORP_DISCOVERY_HOLDTIME 180 + +PREDECL_SORTLIST_UNIQ(pim_autorp_rp); +PREDECL_SORTLIST_UNIQ(pim_autorp_grppfix); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct autorp_pkt_grp { #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -79,7 +97,19 @@ struct pim_autorp_rp { struct event *hold_timer; struct prefix grp; char grplist[32]; +<<<<<<< HEAD struct pim_autorp_rp_item list; +======= + struct pim_autorp_grppfix_head grp_pfix_list; + struct pim_autorp_rp_item item; +}; + +struct pim_autorp_grppfix { + struct prefix grp; + struct in_addr rp; + bool negative; + struct pim_autorp_grppfix_item item; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }; struct pim_autorp { @@ -96,13 +126,26 @@ struct pim_autorp { struct event *announce_timer; /* Event for sending discovery packets*/ +<<<<<<< HEAD /* struct event *discovery_timer; */ +======= + struct event *send_discovery_timer; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Flag enabling reading discovery packets */ bool do_discovery; /* Flag enabling mapping agent (reading announcements and sending discovery)*/ +<<<<<<< HEAD /* bool do_mapping; */ +======= + bool send_rp_discovery; + + /* Flag indicating if we are sending discovery messages (true) or if a higher IP mapping + * agent preemptied our sending (false) + */ + bool mapping_agent_active; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* List of RP's in received discovery packets */ struct pim_autorp_rp_head discovery_rp_list; @@ -111,7 +154,16 @@ struct pim_autorp { struct pim_autorp_rp_head candidate_rp_list; /* List of announced RP's to send in discovery packets */ +<<<<<<< HEAD /* struct pim_autorp_rp_head mapping_rp_list; */ +======= + struct pim_autorp_rp_head mapping_rp_list; + + /* List of the last advertised RP's, via mapping agent discovery + * This is only filled if a discovery message was sent + */ + struct pim_autorp_rp_head advertised_rp_list; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Packet parameters for sending announcement packets */ uint8_t announce_scope; @@ -119,6 +171,7 @@ struct pim_autorp { int32_t announce_holdtime; /* Pre-built announcement packet, only changes when configured RP's or packet parameters change */ +<<<<<<< HEAD uint8_t *annouce_pkt; uint16_t annouce_pkt_sz; @@ -127,12 +180,23 @@ struct pim_autorp { * int discovery_interval; * int discovery_holdtime; */ +======= + uint8_t *announce_pkt; + uint16_t announce_pkt_sz; + + /* Packet parameters for sending discovery packets */ + uint8_t discovery_scope; + uint16_t discovery_interval; + uint16_t discovery_holdtime; + struct cand_addrsel mapping_agent_addrsel; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }; #define AUTORP_GRPLEN 6 #define AUTORP_RPLEN 6 #define AUTORP_HDRLEN 8 +<<<<<<< HEAD bool pim_autorp_rm_candidate_rp(struct pim_instance *pim, pim_addr rpaddr); void pim_autorp_add_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr, struct prefix group); @@ -145,6 +209,20 @@ bool pim_autorp_rm_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, void pim_autorp_announce_scope(struct pim_instance *pim, uint8_t scope); void pim_autorp_announce_interval(struct pim_instance *pim, uint16_t interval); void pim_autorp_announce_holdtime(struct pim_instance *pim, int32_t holdtime); +======= +void pim_autorp_prefix_list_update(struct pim_instance *pim, struct prefix_list *plist); +bool pim_autorp_rm_candidate_rp(struct pim_instance *pim, pim_addr rpaddr); +void pim_autorp_add_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr, + struct prefix group); +bool pim_autorp_rm_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr, + struct prefix group); +void pim_autorp_add_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist); +bool pim_autorp_rm_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist); +void pim_autorp_announce_scope(struct pim_instance *pim, uint8_t scope); +void pim_autorp_announce_interval(struct pim_instance *pim, uint16_t interval); +void pim_autorp_announce_holdtime(struct pim_instance *pim, int32_t holdtime); +void pim_autorp_send_discovery_apply(struct pim_autorp *autorp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void pim_autorp_add_ifp(struct interface *ifp); void pim_autorp_rm_ifp(struct interface *ifp); void pim_autorp_start_discovery(struct pim_instance *pim); @@ -152,7 +230,11 @@ void pim_autorp_stop_discovery(struct pim_instance *pim); void pim_autorp_init(struct pim_instance *pim); void pim_autorp_finish(struct pim_instance *pim); int pim_autorp_config_write(struct pim_instance *pim, struct vty *vty); +<<<<<<< HEAD void pim_autorp_show_autorp(struct vty *vty, struct pim_instance *pim, +======= +void pim_autorp_show_autorp(struct vty *vty, struct pim_instance *pim, const char *component, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) json_object *json); #endif diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index a44e4e08f3d5..1449f70d0324 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -1769,14 +1769,22 @@ static inline pim_addr if_highest_addr(pim_addr cur, struct interface *ifp) return cur; } +<<<<<<< HEAD static void cand_addrsel_clear(struct cand_addrsel *asel) +======= +void cand_addrsel_clear(struct cand_addrsel *asel) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { asel->run = false; asel->run_addr = PIMADDR_ANY; } /* returns whether address or active changed */ +<<<<<<< HEAD static bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf) +======= +bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { bool is_any = false, prev_run = asel->run; struct interface *ifp = NULL; diff --git a/pimd/pim_bsm.h b/pimd/pim_bsm.h index 1eacc1be5770..ad243e518db7 100644 --- a/pimd/pim_bsm.h +++ b/pimd/pim_bsm.h @@ -64,7 +64,11 @@ enum cand_addr { CAND_ADDR_EXPLICIT, }; +<<<<<<< HEAD /* used separately for Cand-RP and Cand-BSR */ +======= +/* used separately for Cand-RP, Cand-BSR, and AutoRP mapping agent */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct cand_addrsel { bool cfg_enable; enum cand_addr cfg_mode : 8; @@ -369,6 +373,12 @@ void pim_cand_rp_trigger(struct bsm_scope *scope); void pim_cand_rp_grp_add(struct bsm_scope *scope, const prefix_pim *p); void pim_cand_rp_grp_del(struct bsm_scope *scope, const prefix_pim *p); +<<<<<<< HEAD +======= +void cand_addrsel_clear(struct cand_addrsel *asel); +bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void pim_cand_addrs_changed(void); int pim_crp_process(struct interface *ifp, pim_sgaddr *src_dst, uint8_t *buf, diff --git a/pimd/pim_bsr_rpdb.c b/pimd/pim_bsr_rpdb.c index 3ec9f99cd198..a01a439bdc47 100644 --- a/pimd/pim_bsr_rpdb.c +++ b/pimd/pim_bsr_rpdb.c @@ -502,6 +502,12 @@ int pim_crp_process(struct interface *ifp, pim_sgaddr *src_dst, uint8_t *buf, buf += sizeof(*crp_hdr); remain -= sizeof(*crp_hdr); +<<<<<<< HEAD +======= + /* ignore trailing data */ + (void)buf; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) size_t ngroups = crp_hdr->prefix_cnt; if (remain < ngroups * sizeof(struct pim_encoded_group_ipv4)) { diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 934da2d53e67..149cc33a4e95 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2822,11 +2822,16 @@ DEFPY (show_ip_pim_rp_vrf_all, DEFPY (show_ip_pim_autorp, show_ip_pim_autorp_cmd, +<<<<<<< HEAD "show ip pim [vrf NAME] autorp [json$json]", +======= + "show ip pim [vrf ] autorp [discovery|candidate|mapping-agent]$component [json$json]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR +<<<<<<< HEAD "PIM AutoRP information\n" JSON_STR) { @@ -2839,10 +2844,22 @@ DEFPY (show_ip_pim_autorp, vty_out(vty, "%% Unable to find pim instance\n"); return CMD_WARNING; } +======= + "All VRF's\n" + "PIM AutoRP information\n" + "RP Discovery details\n" + "Candidate RP details\n" + "Mapping Agent details\n" + JSON_STR) +{ + json_object *json_parent = NULL; + struct vrf *v; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (json) json_parent = json_object_new_object(); +<<<<<<< HEAD pim_autorp_show_autorp(vty, v->info, json_parent); if (json) @@ -2881,6 +2898,33 @@ DEFPY (show_ip_pim_autorp_vrf_all, json_object_object_add(json_parent, vrf->name, json_vrf); } +======= + if (vrf && strmatch(vrf, "all")) { + json_object *json_vrf = NULL; + + RB_FOREACH (v, vrf_name_head, &vrfs_by_name) { + if (!v || !v->info) + continue; + + if (json) + json_vrf = json_object_new_object(); + else + vty_out(vty, "VRF: %s\n", v->name); + + pim_autorp_show_autorp(vty, v->info, component, json_vrf); + + if (json) + json_object_object_add(json_parent, v->name, json_vrf); + } + } else { + v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME); + if (!v || !v->info) { + if (!json) + vty_out(vty, "%% Unable to find pim instance\n"); + return CMD_WARNING; + } + pim_autorp_show_autorp(vty, v->info, component, json_parent); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (json) @@ -4609,13 +4653,26 @@ DEFPY (pim_autorp_announce_rp, "Prefix list\n" "List name\n") { +<<<<<<< HEAD return pim_process_autorp_candidate_rp_cmd(vty, no, rpaddr_str, (grp_str ? grp : NULL), plist); +======= + if (grp_str && (!pim_addr_is_multicast(grp->prefix) || grp->prefixlen < 4)) { + vty_out(vty, "%% group prefix %pFX is not a valid multicast range\n", grp); + return CMD_WARNING_CONFIG_FAILED; + } + + return pim_process_autorp_candidate_rp_cmd(vty, no, rpaddr_str, grp_str, plist); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } DEFPY (pim_autorp_announce_scope_int, pim_autorp_announce_scope_int_cmd, +<<<<<<< HEAD "[no] autorp announce ![{scope (1-255) | interval (1-65535) | holdtime (0-65535)}]", +======= + "[no] autorp announce {scope (1-255) | interval (1-65535) | holdtime (0-65535)}", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR "AutoRP\n" "AutoRP Candidate RP announcement\n" @@ -4626,11 +4683,52 @@ DEFPY (pim_autorp_announce_scope_int, "Announcement holdtime\n" "Time in seconds\n") { +<<<<<<< HEAD return pim_process_autorp_announce_scope_int_cmd(vty, no, scope_str, interval_str, holdtime_str); } +======= + return pim_process_autorp_announce_scope_int_cmd(vty, no, scope_str, interval_str, + holdtime_str); +} + +DEFPY (pim_autorp_send_rp_discovery, + pim_autorp_send_rp_discovery_cmd, + "[no] autorp send-rp-discovery [source
]", + NO_STR + "AutoRP\n" + "Enable AutoRP mapping agent\n" + "Specify AutoRP discovery source\n" + "Local address\n" + IP_ADDR_STR + "Local Interface (uses highest address)\n" + IFNAME_STR + "Highest loopback address (default)\n" + "Highest address of any interface\n") +{ + return pim_process_autorp_send_rp_discovery_cmd(vty, no, any, loopback, ifname, address_str); +} + +DEFPY (pim_autorp_send_rp_discovery_scope_int, + pim_autorp_send_rp_discovery_scope_int_cmd, + "[no] autorp send-rp-discovery {scope (0-255) | interval (1-65535) | holdtime (0-65535)}", + NO_STR + "AutoRP\n" + "Enable AutoRP mapping agent\n" + "Packet scope (TTL)\n" + "TTL value\n" + "Discovery TX interval\n" + "Time in seconds\n" + "Announcement holdtime\n" + "Time in seconds\n") +{ + return pim_process_autorp_send_rp_discovery_scope_int_cmd(vty, no, scope_str, interval_str, + holdtime_str); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFPY (pim_bsr_candidate_bsr, pim_bsr_candidate_bsr_cmd, "[no] bsr candidate-bsr [{priority (0-255)|source
}]", @@ -5850,6 +5948,24 @@ DEFUN(interface_no_ip_pim_boundary_oil, return pim_process_no_ip_pim_boundary_oil_cmd(vty); } +<<<<<<< HEAD +======= +DEFPY_YANG(interface_ip_pim_boundary_acl, + interface_ip_pim_boundary_acl_cmd, + "[no] ip multicast boundary ACCESSLIST4_NAME$name", + NO_STR + IP_STR + "Generic multicast configuration options\n" + "Define multicast boundary\n" + "Access-list to filter OIL with by source and group\n") +{ + nb_cli_enqueue_change(vty, "./multicast-boundary-acl", + (!!no ? NB_OP_DESTROY : NB_OP_MODIFY), name); + + return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFUN (interface_ip_mroute, interface_ip_mroute_cmd, "ip mroute INTERFACE A.B.C.D [A.B.C.D]", @@ -7539,6 +7655,27 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group, return ret; } +<<<<<<< HEAD +======= +DEFPY(msdp_shutdown, + msdp_shutdown_cmd, + "[no] msdp shutdown", + NO_STR + CFG_MSDP_STR + "Shutdown MSDP operation\n") +{ + char xpath_value[XPATH_MAXLEN]; + + snprintf(xpath_value, sizeof(xpath_value), "./msdp/shutdown"); + if (no) + nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg, struct json_object *json) { @@ -8267,6 +8404,40 @@ DEFUN (show_ip_msdp_sa_sg_vrf_all, return CMD_SUCCESS; } +<<<<<<< HEAD +======= +DEFPY(msdp_log_neighbor_changes, msdp_log_neighbor_changes_cmd, + "[no] msdp log neighbor-events", + NO_STR + MSDP_STR + "MSDP log messages\n" + "MSDP log neighbor event messages\n") +{ + char xpath_value[XPATH_MAXLEN + 32]; + + snprintf(xpath_value, sizeof(xpath_value), "%s/msdp/log-neighbor-events", VTY_CURR_XPATH); + nb_cli_enqueue_change(vty, xpath_value, no ? NB_OP_DESTROY : NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(msdp_log_sa_changes, msdp_log_sa_changes_cmd, + "[no] msdp log sa-events", + NO_STR + MSDP_STR + "MSDP log messages\n" + "MSDP log SA event messages\n") +{ + char xpath_value[XPATH_MAXLEN + 32]; + + snprintf(xpath_value, sizeof(xpath_value), "%s/msdp/log-sa-events", VTY_CURR_XPATH); + nb_cli_enqueue_change(vty, xpath_value, no ? NB_OP_DESTROY : NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct pim_sg_cache_walk_data { struct vty *vty; json_object *json; @@ -8855,6 +9026,11 @@ void pim_cmd_init(void) install_element(PIM_NODE, &pim_autorp_discovery_cmd); install_element(PIM_NODE, &pim_autorp_announce_rp_cmd); install_element(PIM_NODE, &pim_autorp_announce_scope_int_cmd); +<<<<<<< HEAD +======= + install_element(PIM_NODE, &pim_autorp_send_rp_discovery_cmd); + install_element(PIM_NODE, &pim_autorp_send_rp_discovery_scope_int_cmd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(PIM_NODE, &no_pim_ssm_prefix_list_cmd); install_element(PIM_NODE, &no_pim_ssm_prefix_list_name_cmd); install_element(PIM_NODE, &pim_ssm_prefix_list_cmd); @@ -8898,6 +9074,12 @@ void pim_cmd_init(void) install_element(PIM_NODE, &pim_msdp_mesh_group_source_cmd); install_element(PIM_NODE, &no_pim_msdp_mesh_group_source_cmd); install_element(PIM_NODE, &no_pim_msdp_mesh_group_cmd); +<<<<<<< HEAD +======= + install_element(PIM_NODE, &msdp_log_neighbor_changes_cmd); + install_element(PIM_NODE, &msdp_log_sa_changes_cmd); + install_element(PIM_NODE, &msdp_shutdown_cmd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(PIM_NODE, &pim_bsr_candidate_rp_cmd); install_element(PIM_NODE, &pim_bsr_candidate_rp_group_cmd); @@ -8943,6 +9125,10 @@ void pim_cmd_init(void) install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd); install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd); +<<<<<<< HEAD +======= + install_element(INTERFACE_NODE, &interface_ip_pim_boundary_acl_cmd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd); // Static mroutes NEB @@ -9010,7 +9196,10 @@ void pim_cmd_init(void) install_element(VIEW_NODE, &show_ip_pim_rp_cmd); install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd); install_element(VIEW_NODE, &show_ip_pim_autorp_cmd); +<<<<<<< HEAD install_element(VIEW_NODE, &show_ip_pim_autorp_vrf_all_cmd); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(VIEW_NODE, &show_ip_pim_bsr_cmd); install_element(VIEW_NODE, &show_ip_multicast_cmd); install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd); diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c index 02ddea8252d6..ed6f92205778 100644 --- a/pimd/pim_cmd_common.c +++ b/pimd/pim_cmd_common.c @@ -630,6 +630,7 @@ int pim_process_no_autorp_cmd(struct vty *vty) return nb_cli_apply_changes(vty, NULL); } +<<<<<<< HEAD int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str, const struct prefix_ipv4 *grp, @@ -763,6 +764,90 @@ int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no, } return nb_cli_apply_changes(vty, NULL); +======= +int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str, + const char *grp, const char *plist) +{ + if (no) { + if (grp || plist) { + /* If any single values are set, only destroy those */ + if (grp) + nb_cli_enqueue_change(vty, "./group", NB_OP_DESTROY, NULL); + if (plist) + nb_cli_enqueue_change(vty, "./prefix-list", NB_OP_DESTROY, NULL); + } else + /* No values set, remove the entire RP */ + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + if (grp) + nb_cli_enqueue_change(vty, "./group", NB_OP_MODIFY, grp); + if (plist) + nb_cli_enqueue_change(vty, "./prefix-list", NB_OP_MODIFY, plist); + } + + return nb_cli_apply_changes(vty, "%s/candidate-rp-list[rp-address='%s']", + FRR_PIM_AUTORP_XPATH, rpaddr_str); +} + +int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no, const char *scope, + const char *interval, const char *holdtime) +{ + /* At least one value is required, so set/delete anything defined */ + enum nb_operation op = (no ? NB_OP_DESTROY : NB_OP_MODIFY); + + if (scope) + nb_cli_enqueue_change(vty, "./announce-scope", op, scope); + if (interval) + nb_cli_enqueue_change(vty, "./announce-interval", op, interval); + if (holdtime) + nb_cli_enqueue_change(vty, "./announce-holdtime", op, holdtime); + + return nb_cli_apply_changes(vty, "%s", FRR_PIM_AUTORP_XPATH); +} + +int pim_process_autorp_send_rp_discovery_cmd(struct vty *vty, bool no, bool any, bool loopback, + const char *ifname, const char *addr) +{ + /* Just take any "no" version of this command as disable the mapping agent */ + nb_cli_enqueue_change(vty, "./send-rp-discovery", NB_OP_MODIFY, (no ? "false" : "true")); + if (no) { + nb_cli_enqueue_change(vty, "./if-any", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./interface", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./address", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./if-loopback", NB_OP_DESTROY, NULL); + } else { + /* Enabling mapping agent. Loopback is default, so any non-no for of the command will + * enable the mapping agent. + */ + if (any) + nb_cli_enqueue_change(vty, "./if-any", NB_OP_CREATE, NULL); + else if (ifname) + nb_cli_enqueue_change(vty, "./interface", NB_OP_MODIFY, ifname); + else if (addr) + nb_cli_enqueue_change(vty, "./address", NB_OP_MODIFY, addr); + else + nb_cli_enqueue_change(vty, "./if-loopback", NB_OP_CREATE, NULL); + } + + return nb_cli_apply_changes(vty, "%s/%s", FRR_PIM_AUTORP_XPATH, "mapping-agent"); +} + +int pim_process_autorp_send_rp_discovery_scope_int_cmd(struct vty *vty, bool no, const char *scope, + const char *interval, const char *holdtime) +{ + /* At least one value is required, so only set/delete the values specified */ + enum nb_operation op = (no ? NB_OP_DESTROY : NB_OP_MODIFY); + + if (scope) + nb_cli_enqueue_change(vty, "./discovery-scope", op, scope); + if (interval) + nb_cli_enqueue_change(vty, "./discovery-interval", op, interval); + if (holdtime) + nb_cli_enqueue_change(vty, "./discovery-holdtime", op, holdtime); + + return nb_cli_apply_changes(vty, "%s/%s", FRR_PIM_AUTORP_XPATH, "mapping-agent"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match) diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h index d7c97e31d45d..46a76e9cb612 100644 --- a/pimd/pim_cmd_common.h +++ b/pimd/pim_cmd_common.h @@ -37,6 +37,7 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str, const char *prefix_list); int pim_process_autorp_cmd(struct vty *vty); int pim_process_no_autorp_cmd(struct vty *vty); +<<<<<<< HEAD int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str, const struct prefix_ipv4 *grp, @@ -45,6 +46,16 @@ int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no, const char *scope, const char *interval, const char *holdtime); +======= +int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str, + const char *grp, const char *plist); +int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no, const char *scope, + const char *interval, const char *holdtime); +int pim_process_autorp_send_rp_discovery_cmd(struct vty *vty, bool no, bool any, bool loopback, + const char *ifname, const char *addr); +int pim_process_autorp_send_rp_discovery_scope_int_cmd(struct vty *vty, bool no, const char *scope, + const char *interval, const char *holdtime); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int pim_process_ip_pim_cmd(struct vty *vty); int pim_process_no_ip_pim_cmd(struct vty *vty); int pim_process_ip_pim_passive_cmd(struct vty *vty, bool enable); diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 19460aa445d6..8f0b41182b8c 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -38,6 +38,10 @@ #include "pim_igmp_join.h" #include "pim_vxlan.h" #include "pim_tib.h" +<<<<<<< HEAD +======= +#include "pim_util.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "pim6_mld.h" @@ -215,7 +219,10 @@ void pim_if_delete(struct interface *ifp) if (pim_ifp->bfd_config.profile) XFREE(MTYPE_TMP, pim_ifp->bfd_config.profile); +<<<<<<< HEAD XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) XFREE(MTYPE_PIM_INTERFACE, pim_ifp); ifp->info = NULL; @@ -1258,6 +1265,17 @@ static int gm_join_sock(const char *ifname, ifindex_t ifindex, { int join_fd; +<<<<<<< HEAD +======= + if (pim_is_group_filtered(pim_ifp, &group_addr, &source_addr)) { + if (PIM_DEBUG_GM_EVENTS) { + zlog_debug("%s: join failed for (S,G)=(%pPAs,%pPAs) due to multicast boundary filtering", + __func__, &source_addr, &group_addr); + } + return -1; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_ifp->igmp_ifstat_joins_sent++; join_fd = pim_socket_raw(IPPROTO_GM); diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index 95bac084d2bb..65b506dc5c5c 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -133,8 +133,15 @@ struct pim_interface { uint32_t pim_dr_priority; /* config */ int pim_dr_num_nondrpri_neighbors; /* neighbors without dr_pri */ +<<<<<<< HEAD /* boundary prefix-list */ char *boundary_oil_plist; +======= + /* boundary prefix-list (group) */ + struct prefix_list *boundary_oil_plist; + /* boundary access-list (source and group) */ + struct access_list *boundary_acl; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Turn on Active-Active for this interface */ bool activeactive; diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 8f9e41039ae6..bbfb46df0317 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -208,6 +208,15 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch) zlog_debug("%s: ifchannel entry %s(%s) is deleted ", __func__, ch->sg_str, ch->interface->name); +<<<<<<< HEAD +======= +#if PIM_IPV == 6 + /* Embedded RPs learned via PIM join/connected source are freed here */ + if (pim_embedded_rp_is_embedded(&ch->sg.grp)) + pim_embedded_rp_delete(pim_ifp->pim, &ch->sg.grp); +#endif /* PIM_IPV == 6 */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) XFREE(MTYPE_PIM_IFCHANNEL, ch); if (up) diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 1ba9bc45a20b..5c6a5dc1214f 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -666,7 +666,11 @@ static int igmp_v1_recv_report(struct gm_sock *igmp, struct in_addr from, memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr)); +<<<<<<< HEAD if (pim_is_group_filtered(ifp->info, &group_addr)) +======= + if (pim_is_group_filtered(ifp->info, &group_addr, NULL)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; /* non-existent group is created as INCLUDE {empty} */ diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c index 944dffdc3389..4a9b8b1974fd 100644 --- a/pimd/pim_igmpv2.c +++ b/pimd/pim_igmpv2.c @@ -134,6 +134,12 @@ int igmp_v2_recv_report(struct gm_sock *igmp, struct in_addr from, ifp->name, group_str); } +<<<<<<< HEAD +======= + if (pim_is_group_filtered(pim_ifp, &group_addr, NULL)) + return -1; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * RFC 4604 * section 2.2.1 diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 2c5ad4d44b1b..1c0d7e9465db 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -9,6 +9,11 @@ #include "memory.h" #include "if.h" #include "lib_errors.h" +<<<<<<< HEAD +======= +#include "plist.h" +#include "plist_int.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "pimd.h" #include "pim_instance.h" @@ -507,6 +512,11 @@ static void allow(struct gm_sock *igmp, struct in_addr from, struct in_addr *src_addr; src_addr = sources + i; +<<<<<<< HEAD +======= + if (pim_is_group_filtered(igmp->interface->info, &group_addr, src_addr)) + continue; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) source = igmp_get_source_by_addr(group, *src_addr, NULL); if (!source) @@ -646,7 +656,11 @@ void igmpv3_report_isex(struct gm_sock *igmp, struct in_addr from, on_trace(__func__, ifp, from, group_addr, num_sources, sources); +<<<<<<< HEAD if (pim_is_group_filtered(ifp->info, &group_addr)) +======= + if (pim_is_group_filtered(ifp->info, &group_addr, NULL)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; /* non-existent group is created as INCLUDE {empty} */ @@ -1809,12 +1823,23 @@ static bool igmp_pkt_grp_addr_ok(struct interface *ifp, const char *from_str, pim_ifp = ifp->info; /* determine filtering status for group */ +<<<<<<< HEAD if (pim_is_group_filtered(pim_ifp, &grp)) { if (PIM_DEBUG_GM_PACKETS) { zlog_debug( "Filtering IGMPv3 group record %pI4 from %s on %s per prefix-list %s", &grp.s_addr, from_str, ifp->name, pim_ifp->boundary_oil_plist); +======= + if (pim_is_group_filtered(pim_ifp, &grp, NULL)) { + if (PIM_DEBUG_GM_PACKETS) { + zlog_debug("Filtering IGMPv3 group record %pI4 from %s on %s per prefix-list %s or access-list %s", + &grp.s_addr, from_str, ifp->name, + (pim_ifp->boundary_oil_plist ? pim_ifp->boundary_oil_plist->name + : "(not found)"), + (pim_ifp->boundary_acl ? pim_ifp->boundary_acl->name + : "(not found)")); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return false; } @@ -1943,11 +1968,17 @@ int igmp_v3_recv_report(struct gm_sock *igmp, struct in_addr from, sizeof(struct in_addr)); if (PIM_DEBUG_GM_PACKETS) { +<<<<<<< HEAD zlog_debug( " Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%pI4", from_str, ifp->name, i, rec_type, rec_auxdatalen, rec_num_sources, &rec_group); +======= + zlog_debug(" Recv IGMP report v3 (type %d) from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%pI4", + rec_type, from_str, ifp->name, i, rec_type, rec_auxdatalen, + rec_num_sources, &rec_group); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Scan sources */ diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index f7c5ea3bcf34..695aae680957 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -26,6 +26,11 @@ static void pim_instance_terminate(struct pim_instance *pim) { +<<<<<<< HEAD +======= + pim->stopping = true; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_vxlan_exit(pim); if (pim->ssm_info) { @@ -270,3 +275,16 @@ void pim_vrf_terminate(void) vrf_terminate(); } +<<<<<<< HEAD +======= + +bool pim_msdp_log_neighbor_events(const struct pim_instance *pim) +{ + return (pim->log_flags & PIM_MSDP_LOG_NEIGHBOR_EVENTS); +} + +bool pim_msdp_log_sa_events(const struct pim_instance *pim) +{ + return (pim->log_flags & PIM_MSDP_LOG_SA_EVENTS); +} +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index f484d847b233..38c6f2d095b9 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -191,6 +191,34 @@ struct pim_instance { int64_t last_route_change_time; uint64_t gm_rx_drop_sys; +<<<<<<< HEAD +======= + + /** Log information flags. */ + uint32_t log_flags; +/** Log neighbor event messages. */ +#define PIM_MSDP_LOG_NEIGHBOR_EVENTS 0x01 +/** Log SA event messages. */ +#define PIM_MSDP_LOG_SA_EVENTS 0x02 + + bool stopping; + +#if PIM_IPV == 6 + struct { + /** Embedded RP enable state. */ + bool enable; + /** Embedded RP group prefix list. */ + char *group_list; + /** Maximum allowed number of embedded RPs at a time. */ + uint32_t maximum_rps; + + /** Embedded RP routing table */ + struct route_table *table; + /** Embedded RPs count */ + size_t rp_count; + } embedded_rp; +#endif /* PIM_IPV == 6 */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }; void pim_vrf_init(void); @@ -200,4 +228,10 @@ extern struct pim_router *router; struct pim_instance *pim_get_pim_instance(vrf_id_t vrf_id); +<<<<<<< HEAD +======= +extern bool pim_msdp_log_neighbor_events(const struct pim_instance *pim); +extern bool pim_msdp_log_sa_events(const struct pim_instance *pim); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #endif diff --git a/pimd/pim_join.c b/pimd/pim_join.c index bfdb0f06b410..debb40e9fc98 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -42,6 +42,12 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh, uint8_t source_flags) { struct pim_interface *pim_ifp = NULL; +<<<<<<< HEAD +======= +#if PIM_IPV == 6 + pim_addr embedded_rp; +#endif /* PIM_IPV == 6 */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (PIM_DEBUG_PIM_J_P) zlog_debug( @@ -53,6 +59,15 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh, pim_ifp = ifp->info; assert(pim_ifp); +<<<<<<< HEAD +======= +#if PIM_IPV == 6 + if (pim_ifp->pim->embedded_rp.enable && pim_embedded_rp_extract(&sg->grp, &embedded_rp) && + !pim_embedded_rp_filter_match(pim_ifp->pim, &sg->grp)) + pim_embedded_rp_new(pim_ifp->pim, &sg->grp, &embedded_rp); +#endif /* PIM_IPV == 6 */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ++pim_ifp->pim_ifstat_join_recv; /* @@ -236,7 +251,11 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, uint16_t msg_num_pruned_sources; int source; struct pim_ifchannel *starg_ch = NULL, *sg_ch = NULL; +<<<<<<< HEAD bool filtered = false; +======= + bool group_filtered = false; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) memset(&sg, 0, sizeof(sg)); addr_offset = pim_parse_addr_group(&sg, buf, pastend - buf); @@ -266,7 +285,11 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, &src_addr, ifp->name); /* boundary check */ +<<<<<<< HEAD filtered = pim_is_group_filtered(pim_ifp, &sg.grp); +======= + group_filtered = pim_is_group_filtered(pim_ifp, &sg.grp, NULL); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Scan joined sources */ for (source = 0; source < msg_num_joined_sources; ++source) { @@ -278,8 +301,13 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, buf += addr_offset; +<<<<<<< HEAD /* if we are filtering this group, skip the join */ if (filtered) +======= + /* if we are filtering this group or (S,G), skip the join */ + if (group_filtered || pim_is_group_filtered(pim_ifp, &sg.grp, &sg.src)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) continue; recv_join(ifp, neigh, msg_holdtime, msg_upstream_addr, @@ -303,10 +331,13 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, buf += addr_offset; +<<<<<<< HEAD /* if we are filtering this group, skip the prune */ if (filtered) continue; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) recv_prune(ifp, neigh, msg_holdtime, msg_upstream_addr, &sg, msg_source_flags); /* @@ -352,7 +383,11 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, } } } +<<<<<<< HEAD if (starg_ch && !filtered) +======= + if (starg_ch && !group_filtered) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_ifchannel_set_star_g_join_state(starg_ch, 1, 0); starg_ch = NULL; } /* scan groups */ diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index adc47e719d24..a62f3f2316d2 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -35,6 +35,10 @@ #include "pim_sock.h" #include "pim_vxlan.h" #include "pim_msg.h" +<<<<<<< HEAD +======= +#include "pim_util.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static void mroute_read_on(struct pim_instance *pim); static int pim_upstream_mroute_update(struct channel_oil *c_oil, @@ -182,6 +186,17 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) * so the kernel doesn't keep nagging us. */ struct pim_rpf *rpg; +<<<<<<< HEAD +======= +#if PIM_IPV == 6 + pim_addr embedded_rp; + + if (pim_ifp->pim->embedded_rp.enable && + pim_embedded_rp_extract(&sg.grp, &embedded_rp) && + !pim_embedded_rp_filter_match(pim_ifp->pim, &sg.grp)) + pim_embedded_rp_new(pim_ifp->pim, &sg.grp, &embedded_rp); +#endif /* PIM_IPV == 6 */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) rpg = RP(pim_ifp->pim, msg->msg_im_dst); if (!rpg) { @@ -263,7 +278,13 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg) *oil_incoming_vif(up->channel_oil) >= MAXVIFS) { pim_upstream_mroute_iif_update(up->channel_oil, __func__); } +<<<<<<< HEAD pim_register_join(up); +======= + + if (!pim_is_group_filtered(pim_ifp, &sg.grp, &sg.src)) + pim_register_join(up); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* if we have receiver, inherit from parent */ pim_upstream_inherited_olist_decide(pim_ifp->pim, up); @@ -624,7 +645,12 @@ int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, const char *buf, pim_upstream_keep_alive_timer_start( up, pim_ifp->pim->keep_alive_time); up->channel_oil->cc.pktcnt++; +<<<<<<< HEAD pim_register_join(up); +======= + if (!pim_is_group_filtered(pim_ifp, &sg.grp, &sg.src)) + pim_register_join(up); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_upstream_inherited_olist(pim_ifp->pim, up); if (!up->channel_oil->installed) pim_upstream_mroute_add(up->channel_oil, __func__); diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 215cc3c5029c..af7080001820 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -47,20 +47,28 @@ static int pim_msdp_mg_mbr_comp(const void *p1, const void *p2); static void pim_msdp_mg_mbr_free(struct pim_msdp_mg_mbr *mbr); /************************ SA cache management ******************************/ +<<<<<<< HEAD static void pim_msdp_sa_timer_expiry_log(struct pim_msdp_sa *sa, const char *timer_str) { zlog_debug("MSDP SA %s %s timer expired", sa->sg_str, timer_str); } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* RFC-3618:Sec-5.1 - global active source advertisement timer */ static void pim_msdp_sa_adv_timer_cb(struct event *t) { struct pim_instance *pim = EVENT_ARG(t); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA advertisement timer expired"); } +======= + if (pim_msdp_log_sa_events(pim)) + zlog_info("MSDP SA advertisement timer expired"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_msdp_sa_adv_timer_setup(pim, true /* start */); pim_msdp_pkt_sa_tx(pim); @@ -83,9 +91,14 @@ static void pim_msdp_sa_state_timer_cb(struct event *t) sa = EVENT_ARG(t); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_sa_timer_expiry_log(sa, "state"); } +======= + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP SA %s state timer expired", sa->sg_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_msdp_sa_deref(sa, PIM_MSDP_SAF_PEER); } @@ -120,9 +133,14 @@ static void pim_msdp_sa_upstream_del(struct pim_msdp_sa *sa) sa->flags &= ~PIM_MSDP_SAF_UP_DEL_IN_PROG; } +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s de-referenced SPT", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP SA %s de-referenced SPT", sa->sg_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static bool pim_msdp_sa_upstream_add_ok(struct pim_msdp_sa *sa, @@ -185,10 +203,15 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa, if (up && (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags))) { /* somehow we lost track of the upstream ptr? best log it */ sa->up = up; +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s SPT reference missing", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP SA %s SPT reference missing", sa->sg_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -204,6 +227,7 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa, /* should we also start the kat in parallel? we will need it * when the * SA ages out */ +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s referenced SPT", sa->sg_str); } @@ -212,6 +236,13 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa, zlog_debug("MSDP SA %s SPT reference failed", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP SA %s referenced SPT", sa->sg_str); + } else { + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP SA %s SPT reference failed", sa->sg_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -240,9 +271,14 @@ static struct pim_msdp_sa *pim_msdp_sa_new(struct pim_instance *pim, sa = hash_get(pim->msdp.sa_hash, sa, hash_alloc_intern); listnode_add_sort(pim->msdp.sa_list, sa); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s created", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(pim)) + zlog_info("MSDP SA %s created", sa->sg_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return sa; } @@ -282,9 +318,14 @@ static void pim_msdp_sa_del(struct pim_msdp_sa *sa) listnode_delete(sa->pim->msdp.sa_list, sa); hash_release(sa->pim->msdp.sa_hash, sa); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s deleted", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP SA %s deleted", sa->sg_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* free up any associated memory */ pim_msdp_sa_free(sa); @@ -333,10 +374,16 @@ static void pim_msdp_sa_deref(struct pim_msdp_sa *sa, if ((sa->flags & PIM_MSDP_SAF_LOCAL)) { if (flags & PIM_MSDP_SAF_LOCAL) { +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s local reference removed", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP SA %s local reference removed", sa->sg_str); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (sa->pim->msdp.local_cnt) --sa->pim->msdp.local_cnt; } @@ -346,10 +393,16 @@ static void pim_msdp_sa_deref(struct pim_msdp_sa *sa, if (flags & PIM_MSDP_SAF_PEER) { struct in_addr rp; +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s peer reference removed", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP SA %s peer reference removed", sa->sg_str); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_msdp_sa_state_timer_setup(sa, false /* start */); rp.s_addr = INADDR_ANY; pim_msdp_sa_peer_ip_set(sa, NULL /* mp */, rp); @@ -386,10 +439,15 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, if (mp) { if (!(sa->flags & PIM_MSDP_SAF_PEER)) { sa->flags |= PIM_MSDP_SAF_PEER; +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s added by peer", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(pim)) + zlog_info("MSDP SA %s added by peer", sa->sg_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } pim_msdp_sa_peer_ip_set(sa, mp, rp); /* start/re-start the state timer to prevent cache expiry */ @@ -403,10 +461,16 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) { sa->flags |= PIM_MSDP_SAF_LOCAL; ++sa->pim->msdp.local_cnt; +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP SA %s added locally", sa->sg_str); } +======= + if (pim_msdp_log_sa_events(pim)) + zlog_info("MSDP SA %s added locally", sa->sg_str); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* send an immediate SA update to peers */ pim_addr_to_prefix(&grp, sa->sg.grp); rp_info = pim_rp_find_match_group(pim, &grp); @@ -710,6 +774,12 @@ bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp) return true; } +<<<<<<< HEAD +======= + if (pim_msdp_log_sa_events(mp->pim)) + zlog_info("MSDP peer %pI4 RPF failure for %pI4", &mp->peer, &rp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return false; } @@ -744,7 +814,11 @@ static void pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp) char state_str[PIM_MSDP_STATE_STRLEN]; pim_msdp_state_dump(mp->state, state_str, sizeof(state_str)); +<<<<<<< HEAD zlog_debug("MSDP peer %s state chg to %s", mp->key_str, state_str); +======= + zlog_info("MSDP peer %s state changed to %s", mp->key_str, state_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* MSDP Connection State Machine actions (defined in RFC-3618:Sec-11.2) */ @@ -752,10 +826,20 @@ static void pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp) * a tcp connection will be made */ static void pim_msdp_peer_connect(struct pim_msdp_peer *mp) { +<<<<<<< HEAD mp->state = PIM_MSDP_CONNECTING; if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_state_chg_log(mp); } +======= + /* Stop here if we are shutdown. */ + if (mp->pim->msdp.shutdown) + return; + + mp->state = PIM_MSDP_CONNECTING; + if (pim_msdp_log_neighbor_events(mp->pim)) + pim_msdp_peer_state_chg_log(mp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_msdp_peer_cr_timer_setup(mp, true /* start */); } @@ -763,10 +847,20 @@ static void pim_msdp_peer_connect(struct pim_msdp_peer *mp) /* 11.2.A3: passive peer - just listen for connections */ static void pim_msdp_peer_listen(struct pim_msdp_peer *mp) { +<<<<<<< HEAD mp->state = PIM_MSDP_LISTEN; if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_state_chg_log(mp); } +======= + /* Stop here if we are shutdown. */ + if (mp->pim->msdp.shutdown) + return; + + mp->state = PIM_MSDP_LISTEN; + if (pim_msdp_log_neighbor_events(mp->pim)) + pim_msdp_peer_state_chg_log(mp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* this is interntionally asymmetric i.e. we set up listen-socket when * the @@ -790,9 +884,14 @@ void pim_msdp_peer_established(struct pim_msdp_peer *mp) mp->state = PIM_MSDP_ESTABLISHED; mp->uptime = pim_time_monotonic_sec(); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_state_chg_log(mp); } +======= + if (pim_msdp_log_neighbor_events(mp->pim)) + pim_msdp_peer_state_chg_log(mp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* stop retry timer on active peers */ pim_msdp_peer_cr_timer_setup(mp, false /* start */); @@ -816,9 +915,15 @@ void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state) ++mp->est_flaps; } mp->state = PIM_MSDP_INACTIVE; +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_state_chg_log(mp); } +======= + + if (pim_msdp_log_neighbor_events(mp->pim)) + pim_msdp_peer_state_chg_log(mp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (PIM_DEBUG_MSDP_INTERNAL) { @@ -851,10 +956,17 @@ void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state) /* RFC-3618:Sec-5.6 - stop the peer tcp connection and startover */ void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str) { +<<<<<<< HEAD if (PIM_DEBUG_EVENTS) { zlog_debug("MSDP peer %s tcp reset %s", mp->key_str, rc_str); snprintf(mp->last_reset, sizeof(mp->last_reset), "%s", rc_str); } +======= + if (pim_msdp_log_neighbor_events(mp->pim)) + zlog_info("MSDP peer %s tcp reset %s", mp->key_str, rc_str); + + snprintf(mp->last_reset, sizeof(mp->last_reset), "%s", rc_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* close the connection and transition to listening or connecting */ pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */); @@ -865,12 +977,15 @@ void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str) } } +<<<<<<< HEAD static void pim_msdp_peer_timer_expiry_log(struct pim_msdp_peer *mp, const char *timer_str) { zlog_debug("MSDP peer %s %s timer expired", mp->key_str, timer_str); } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* RFC-3618:Sec-5.4 - peer hold timer */ static void pim_msdp_peer_hold_timer_cb(struct event *t) { @@ -878,17 +993,28 @@ static void pim_msdp_peer_hold_timer_cb(struct event *t) mp = EVENT_ARG(t); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_timer_expiry_log(mp, "hold"); } +======= + if (pim_msdp_log_neighbor_events(mp->pim)) + zlog_info("MSDP peer %s hold timer expired", mp->key_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (mp->state != PIM_MSDP_ESTABLISHED) { return; } +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_state_chg_log(mp); } +======= + if (pim_msdp_log_neighbor_events(mp->pim)) + pim_msdp_peer_state_chg_log(mp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_msdp_peer_reset_tcp_conn(mp, "ht-expired"); } @@ -910,9 +1036,14 @@ static void pim_msdp_peer_ka_timer_cb(struct event *t) mp = EVENT_ARG(t); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_timer_expiry_log(mp, "ka"); } +======= + if (pim_msdp_log_neighbor_events(mp->pim)) + zlog_info("MSDP peer %s keep alive timer expired", mp->key_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_msdp_pkt_ka_tx(mp); pim_msdp_peer_ka_timer_setup(mp, true /* start */); @@ -970,9 +1101,14 @@ static void pim_msdp_peer_cr_timer_cb(struct event *t) mp = EVENT_ARG(t); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_timer_expiry_log(mp, "connect-retry"); } +======= + if (pim_msdp_log_neighbor_events(mp->pim)) + zlog_info("MSDP peer %s connection retry timer expired", mp->key_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (mp->state != PIM_MSDP_CONNECTING || PIM_MSDP_PEER_IS_LISTENER(mp)) { return; @@ -1012,6 +1148,7 @@ void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp) } } +<<<<<<< HEAD static void pim_msdp_addr2su(union sockunion *su, struct in_addr addr) { sockunion_init(su); @@ -1022,6 +1159,8 @@ static void pim_msdp_addr2su(union sockunion *su, struct in_addr addr) #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* 11.2.A1: create a new peer and transition state to listen or connecting */ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim, const struct in_addr *peer, @@ -1037,11 +1176,17 @@ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim, mp->pim = pim; mp->peer = *peer; pim_inet4_dump("", mp->peer, mp->key_str, sizeof(mp->key_str)); +<<<<<<< HEAD pim_msdp_addr2su(&mp->su_peer, mp->peer); mp->local = *local; /* XXX: originator_id setting needs to move to the mesh group */ pim->msdp.originator_id = *local; pim_msdp_addr2su(&mp->su_local, mp->local); +======= + mp->local = *local; + /* XXX: originator_id setting needs to move to the mesh group */ + pim->msdp.originator_id = *local; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (mesh_group_name) mp->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name); @@ -1063,8 +1208,13 @@ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim, mp = hash_get(pim->msdp.peer_hash, mp, hash_alloc_intern); listnode_add_sort(pim->msdp.peer_list, mp); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP peer %s created", mp->key_str); +======= + if (pim_msdp_log_neighbor_events(pim)) { + zlog_info("MSDP peer %s created", mp->key_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_msdp_peer_state_chg_log(mp); } @@ -1078,8 +1228,12 @@ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim, return mp; } +<<<<<<< HEAD struct pim_msdp_peer *pim_msdp_peer_find(struct pim_instance *pim, struct in_addr peer_addr) +======= +struct pim_msdp_peer *pim_msdp_peer_find(const struct pim_instance *pim, struct in_addr peer_addr) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct pim_msdp_peer lookup; @@ -1129,9 +1283,14 @@ void pim_msdp_peer_del(struct pim_msdp_peer **mp) listnode_delete((*mp)->pim->msdp.peer_list, *mp); hash_release((*mp)->pim->msdp.peer_hash, *mp); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP peer %s deleted", (*mp)->key_str); } +======= + if (pim_msdp_log_neighbor_events((*mp)->pim)) + zlog_info("MSDP peer %s deleted", (*mp)->key_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* free up any associated memory */ pim_msdp_peer_free(*mp); @@ -1206,10 +1365,15 @@ void pim_msdp_mg_free(struct pim_instance *pim, struct pim_msdp_mg **mgp) for (ALL_LIST_ELEMENTS((*mgp)->mbr_list, n, nn, mbr)) pim_msdp_mg_mbr_del((*mgp), mbr); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP mesh-group %s deleted", (*mgp)->mesh_group_name); } +======= + if (pim_msdp_log_neighbor_events(pim)) + zlog_info("MSDP mesh-group %s deleted", (*mgp)->mesh_group_name); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) XFREE(MTYPE_PIM_MSDP_MG_NAME, (*mgp)->mesh_group_name); @@ -1226,15 +1390,24 @@ struct pim_msdp_mg *pim_msdp_mg_new(struct pim_instance *pim, struct pim_msdp_mg *mg; mg = XCALLOC(MTYPE_PIM_MSDP_MG, sizeof(*mg)); +<<<<<<< HEAD +======= + mg->pim = pim; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) mg->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name); mg->mbr_list = list_new(); mg->mbr_list->del = (void (*)(void *))pim_msdp_mg_mbr_free; mg->mbr_list->cmp = (int (*)(void *, void *))pim_msdp_mg_mbr_comp; +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP mesh-group %s created", mg->mesh_group_name); } +======= + if (pim_msdp_log_neighbor_events(pim)) + zlog_info("MSDP mesh-group %s created", mg->mesh_group_name); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SLIST_INSERT_HEAD(&pim->msdp.mglist, mg, mg_entry); @@ -1268,12 +1441,19 @@ void pim_msdp_mg_mbr_del(struct pim_msdp_mg *mg, struct pim_msdp_mg_mbr *mbr) } listnode_delete(mg->mbr_list, mbr); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { char ip_str[INET_ADDRSTRLEN]; pim_inet4_dump("", mbr->mbr_ip, ip_str, sizeof(ip_str)); zlog_debug("MSDP mesh-group %s mbr %s deleted", mg->mesh_group_name, ip_str); } +======= + if (pim_msdp_log_neighbor_events(mg->pim)) + zlog_info("MSDP mesh-group %s neighbor %pI4 deleted", mg->mesh_group_name, + &mbr->mbr_ip); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pim_msdp_mg_mbr_free(mbr); if (mg->mbr_cnt) { --mg->mbr_cnt; @@ -1290,10 +1470,16 @@ static void pim_msdp_src_del(struct pim_msdp_mg *mg) if (mbr->mp) pim_msdp_peer_del(&mbr->mp); } +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) { zlog_debug("MSDP mesh-group %s src cleared", mg->mesh_group_name); } +======= + + if (pim_msdp_log_neighbor_events(mg->pim)) + zlog_info("MSDP mesh-group %s source cleared", mg->mesh_group_name); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /*********************** MSDP feature APIs *********************************/ @@ -1305,6 +1491,14 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty) char src_str[INET_ADDRSTRLEN]; int count = 0; +<<<<<<< HEAD +======= + if (pim_msdp_log_neighbor_events(pim)) + vty_out(vty, " msdp log neighbor-events\n"); + if (pim_msdp_log_sa_events(pim)) + vty_out(vty, " msdp log sa-events\n"); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (SLIST_EMPTY(&pim->msdp.mglist)) return count; @@ -1356,6 +1550,12 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim) written = true; } +<<<<<<< HEAD +======= + if (pim->msdp.shutdown) + vty_out(vty, " msdp shutdown\n"); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return written; } @@ -1439,9 +1639,14 @@ void pim_msdp_mg_src_add(struct pim_instance *pim, struct pim_msdp_mg *mg, /* No new address, disable everyone. */ if (ai->s_addr == INADDR_ANY) { +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) zlog_debug("MSDP mesh-group %s src unset", mg->mesh_group_name); +======= + if (pim_msdp_log_neighbor_events(pim)) + zlog_info("MSDP mesh-group %s source unset", mg->mesh_group_name); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -1450,9 +1655,14 @@ void pim_msdp_mg_src_add(struct pim_instance *pim, struct pim_msdp_mg *mg, mbr->mp = pim_msdp_peer_add(pim, &mbr->mbr_ip, &mg->src_ip, mg->mesh_group_name); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) zlog_debug("MSDP mesh-group %s src %pI4 set", mg->mesh_group_name, &mg->src_ip); +======= + if (pim_msdp_log_neighbor_events(pim)) + zlog_info("MSDP mesh-group %s source %pI4 set", mg->mesh_group_name, &mg->src_ip); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_add(struct pim_instance *pim, @@ -1470,11 +1680,59 @@ struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_add(struct pim_instance *pim, mbr->mp = pim_msdp_peer_add(pim, &mbr->mbr_ip, &mg->src_ip, mg->mesh_group_name); +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) zlog_debug("MSDP mesh-group %s mbr %pI4 created", mg->mesh_group_name, &mbr->mbr_ip); +======= + if (pim_msdp_log_neighbor_events(pim)) + zlog_info("MSDP mesh-group %s neighbor %pI4 created", mg->mesh_group_name, + &mbr->mbr_ip); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ++mg->mbr_cnt; return mbr; } +<<<<<<< HEAD +======= + +void pim_msdp_shutdown(struct pim_instance *pim, bool state) +{ + struct pim_msdp_peer *peer; + struct listnode *node; + + /* Same value nothing to do. */ + if (pim->msdp.shutdown == state) + return; + + if (state) { + pim->msdp.shutdown = true; + + for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, peer)) { + /* Stop the tcp connection and shutdown all timers */ + pim_msdp_peer_stop_tcp_conn(peer, true); + + /* Stop listening socket if any. */ + event_cancel(&peer->auth_listen_ev); + if (peer->auth_listen_sock != -1) + close(peer->auth_listen_sock); + + /* Disable and remove listener flag. */ + UNSET_FLAG(pim->msdp.flags, PIM_MSDPF_ENABLE | PIM_MSDPF_LISTENER); + } + } else { + pim->msdp.shutdown = false; + + for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, peer)) { + /* Start connection again. */ + if (PIM_MSDP_PEER_IS_LISTENER(peer)) + pim_msdp_peer_listen(peer); + else + pim_msdp_peer_connect(peer); + + SET_FLAG(pim->msdp.flags, PIM_MSDPF_ENABLE); + } + } +} +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h index f77b0e1a3afd..8ae31a555698 100644 --- a/pimd/pim_msdp.h +++ b/pimd/pim_msdp.h @@ -114,9 +114,12 @@ struct pim_msdp_peer { enum pim_msdp_peer_state state; enum pim_msdp_peer_flags flags; +<<<<<<< HEAD /* TCP socket info */ union sockunion su_local; union sockunion su_peer; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int fd; /* protocol timers */ @@ -168,6 +171,10 @@ struct pim_msdp_mg { struct in_addr src_ip; uint32_t mbr_cnt; struct list *mbr_list; +<<<<<<< HEAD +======= + struct pim_instance *pim; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /** Belongs to PIM instance list. */ SLIST_ENTRY(pim_msdp_mg) mg_entry; @@ -218,6 +225,12 @@ struct pim_msdp { uint32_t keep_alive; /** MSDP global connection retry period. */ uint32_t connection_retry; +<<<<<<< HEAD +======= + + /** MSDP operation state. */ + bool shutdown; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }; #define PIM_MSDP_PEER_READ_ON(mp) \ @@ -238,8 +251,12 @@ void pim_msdp_init(struct pim_instance *pim, struct event_loop *master); void pim_msdp_exit(struct pim_instance *pim); char *pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf, int buf_size); +<<<<<<< HEAD struct pim_msdp_peer *pim_msdp_peer_find(struct pim_instance *pim, struct in_addr peer_addr); +======= +struct pim_msdp_peer *pim_msdp_peer_find(const struct pim_instance *pim, struct in_addr peer_addr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void pim_msdp_peer_established(struct pim_msdp_peer *mp); void pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp); void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state); @@ -330,6 +347,17 @@ void pim_msdp_peer_change_source(struct pim_msdp_peer *mp, */ void pim_msdp_peer_restart(struct pim_msdp_peer *mp); +<<<<<<< HEAD +======= +/** + * Toggle MSDP functionality administrative state. + * + * \param pim PIM instance we want to shutdown. + * \param state shutdown state. + */ +void pim_msdp_shutdown(struct pim_instance *pim, bool state); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #else /* PIM_IPV == 6 */ static inline void pim_msdp_init(struct pim_instance *pim, struct event_loop *master) @@ -373,6 +401,13 @@ static inline bool pim_msdp_peer_config_write(struct vty *vty, { return false; } +<<<<<<< HEAD +======= + +static inline void pim_msdp_shutdown(struct pim_instance *pim, bool state) +{ +} +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #endif /* PIM_IPV == 6 */ #endif diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c index 27f4966a1cc3..f32b8eb0b90e 100644 --- a/pimd/pim_msdp_packet.c +++ b/pimd/pim_msdp_packet.c @@ -367,6 +367,7 @@ static void pim_msdp_pkt_sa_fill_one(struct pim_msdp_sa *sa) stream_put_ipv4(sa->pim->msdp.work_obuf, sa->sg.src.s_addr); } +<<<<<<< HEAD static bool msdp_cisco_match(const struct filter *filter, const struct in_addr *source, const struct in_addr *group) @@ -414,6 +415,8 @@ static enum filter_type msdp_access_list_apply(struct access_list *access, return FILTER_DENY; } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bool msdp_peer_sa_filter(const struct pim_msdp_peer *mp, const struct pim_msdp_sa *sa) { @@ -425,7 +428,11 @@ bool msdp_peer_sa_filter(const struct pim_msdp_peer *mp, /* Find access list and test it. */ acl = access_list_lookup(AFI_IP, mp->acl_out); +<<<<<<< HEAD if (msdp_access_list_apply(acl, &sa->sg.src, &sa->sg.grp) == FILTER_DENY) +======= + if (pim_access_list_apply(acl, &sa->sg.src, &sa->sg.grp) == FILTER_DENY) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return true; return false; @@ -487,9 +494,14 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, } if (msdp_peer_sa_filter(mp, sa)) { +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) zlog_debug("MSDP peer %pI4 filter SA out %s", &mp->peer, sa->sg_str); +======= + if (pim_msdp_log_sa_events(pim)) + zlog_info("MSDP peer %pI4 filter SA out %s", &mp->peer, sa->sg_str); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) continue; } @@ -551,9 +563,15 @@ void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa) pim_msdp_pkt_sa_fill_one(sa); for (ALL_LIST_ELEMENTS_RO(sa->pim->msdp.peer_list, node, mp)) { if (msdp_peer_sa_filter(mp, sa)) { +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) zlog_debug("MSDP peer %pI4 filter SA out %s", &mp->peer, sa->sg_str); +======= + if (pim_msdp_log_sa_events(sa->pim)) + zlog_info("MSDP peer %pI4 filter SA out %s", &mp->peer, sa->sg_str); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) continue; } @@ -583,9 +601,16 @@ void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp, /* Don't push it if filtered. */ if (msdp_peer_sa_filter(mp, &sa)) { +<<<<<<< HEAD if (PIM_DEBUG_MSDP_EVENTS) zlog_debug("MSDP peer %pI4 filter SA out (%pI4, %pI4)", &mp->peer, &sa.sg.src, &sa.sg.grp); +======= + if (pim_msdp_log_sa_events(mp->pim)) + zlog_info("MSDP peer %pI4 filter SA out (%pI4, %pI4)", &mp->peer, + &sa.sg.src, &sa.sg.grp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -641,11 +666,18 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) /* Filter incoming SA with configured access list. */ if (mp->acl_in) { acl = access_list_lookup(AFI_IP, mp->acl_in); +<<<<<<< HEAD if (msdp_access_list_apply(acl, &sg.src, &sg.grp) == FILTER_DENY) { if (PIM_DEBUG_MSDP_EVENTS) zlog_debug("MSDP peer %pI4 filter SA in (%pI4, %pI4)", &mp->peer, &sg.src, &sg.grp); +======= + if (pim_access_list_apply(acl, &sg.src, &sg.grp) == FILTER_DENY) { + if (pim_msdp_log_sa_events(mp->pim)) + zlog_info("MSDP peer %pI4 filter SA in (%pI4, %pI4)", &mp->peer, + &sg.src, &sg.grp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } } diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c index 2fb0bb87c789..67cd24739e25 100644 --- a/pimd/pim_msdp_socket.c +++ b/pimd/pim_msdp_socket.c @@ -49,6 +49,19 @@ static void pim_msdp_update_sock_send_buffer_size(int fd) } } +<<<<<<< HEAD +======= +static void pim_msdp_addr2su(union sockunion *su, struct in_addr addr) +{ + sockunion_init(su); + su->sin.sin_addr = addr; + su->sin.sin_family = AF_INET; +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + su->sin.sin_len = sizeof(struct sockaddr_in); +#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /** * Helper function to reduce code duplication. * @@ -64,7 +77,10 @@ static int _pim_msdp_sock_listen(const struct vrf *vrf, int rv; socklen_t socklen; struct sockaddr_in sin = {}; +<<<<<<< HEAD union sockunion su_peer = {}; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { @@ -117,7 +133,13 @@ static int _pim_msdp_sock_listen(const struct vrf *vrf, /* Set MD5 authentication. */ if (mp && mp->auth_key) { +<<<<<<< HEAD su_peer = mp->su_peer; +======= + union sockunion su_peer = {}; + + pim_msdp_addr2su(&su_peer, mp->peer); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) frr_with_privs (&pimd_privs) { sockopt_tcp_signature(sock, &su_peer, mp->auth_key); } @@ -349,6 +371,10 @@ int pim_msdp_sock_listen(struct pim_instance *pim) int pim_msdp_sock_connect(struct pim_msdp_peer *mp) { int rc; +<<<<<<< HEAD +======= + union sockunion su_peer = {}, su_local = {}; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (PIM_DEBUG_MSDP_INTERNAL) { zlog_debug("MSDP peer %s attempt connect%s", mp->key_str, @@ -366,8 +392,16 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) pim_msdp_peer_stop_tcp_conn(mp, false /* chg_state */); } +<<<<<<< HEAD /* Make socket for the peer. */ mp->fd = sockunion_socket(&mp->su_peer); +======= + pim_msdp_addr2su(&su_peer, mp->peer); + pim_msdp_addr2su(&su_local, mp->local); + + /* Make socket for the peer. */ + mp->fd = sockunion_socket(&su_peer); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (mp->fd < 0) { flog_err_sys(EC_LIB_SOCKET, "pim_msdp_socket socket failure: %s", @@ -402,7 +436,11 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) sockopt_reuseport(mp->fd); /* source bind */ +<<<<<<< HEAD rc = sockunion_bind(mp->fd, &mp->su_local, 0, &mp->su_local); +======= + rc = sockunion_bind(mp->fd, &su_local, 0, &su_local); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (rc < 0) { flog_err_sys(EC_LIB_SOCKET, "pim_msdp_socket connect bind failure: %s", @@ -421,12 +459,20 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) /* Set authentication (if configured). */ if (mp->auth_key) { frr_with_privs (&pimd_privs) { +<<<<<<< HEAD sockopt_tcp_signature(mp->fd, &mp->su_peer, mp->auth_key); +======= + sockopt_tcp_signature(mp->fd, &su_peer, mp->auth_key); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } /* Connect to the remote mp. */ +<<<<<<< HEAD return (sockunion_connect(mp->fd, &mp->su_peer, htons(PIM_MSDP_TCP_PORT), 0)); +======= + return (sockunion_connect(mp->fd, &su_peer, htons(PIM_MSDP_TCP_PORT), 0)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } diff --git a/pimd/pim_nb.c b/pimd/pim_nb.c index 66001d1463b9..5513f272436f 100644 --- a/pimd/pim_nb.c +++ b/pimd/pim_nb.c @@ -130,6 +130,27 @@ const struct frr_yang_module_info frr_pim_info = { } }, { +<<<<<<< HEAD +======= + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/log-neighbor-events", + .cbs = { + .modify = pim_msdp_log_neighbor_events_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/log-sa-events", + .cbs = { + .modify = pim_msdp_log_sa_events_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/shutdown", + .cbs = { + .modify = pim_msdp_shutdown_modify, + } + }, + { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups", .cbs = { .create = pim_msdp_mesh_group_create, @@ -335,6 +356,16 @@ const struct frr_yang_module_info frr_pim_info = { } }, { +<<<<<<< HEAD +======= + .xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-acl", + .cbs = { + .modify = lib_interface_pim_address_family_multicast_boundary_acl_modify, + .destroy = lib_interface_pim_address_family_multicast_boundary_acl_destroy, + } + }, + { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/mroute", .cbs = { .create = lib_interface_pim_address_family_mroute_create, @@ -380,6 +411,28 @@ const struct frr_yang_module_info frr_pim_rp_info = { } }, { +<<<<<<< HEAD +======= + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/embedded-rp/enable", + .cbs = { + .modify = pim_embedded_rp_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/embedded-rp/group-list", + .cbs = { + .modify = pim_embedded_rp_group_list_modify, + .destroy = pim_embedded_rp_group_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/embedded-rp/maximum-rps", + .cbs = { + .modify = pim_embedded_rp_maximum_rps_modify, + } + }, + { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/discovery-enabled", .cbs = { .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify, @@ -429,6 +482,61 @@ const struct frr_yang_module_info frr_pim_rp_info = { } }, { +<<<<<<< HEAD +======= + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/send-rp-discovery", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_send_rp_discovery_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-scope", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_scope_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-interval", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_interval_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-holdtime", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_holdtime_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/address", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify, + .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/interface", + .cbs = { + .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify, + .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/if-loopback", + .cbs = { + .create = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create, + .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/if-any", + .cbs = { + .create = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create, + .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy, + } + }, + { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) .xpath = NULL, }, } diff --git a/pimd/pim_nb.h b/pimd/pim_nb.h index befad4efe435..cc30730771a4 100644 --- a/pimd/pim_nb.h +++ b/pimd/pim_nb.h @@ -54,6 +54,12 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss int pim_msdp_hold_time_modify(struct nb_cb_modify_args *args); int pim_msdp_keep_alive_modify(struct nb_cb_modify_args *args); int pim_msdp_connection_retry_modify(struct nb_cb_modify_args *args); +<<<<<<< HEAD +======= +int pim_msdp_log_neighbor_events_modify(struct nb_cb_modify_args *args); +int pim_msdp_log_sa_events_modify(struct nb_cb_modify_args *args); +int pim_msdp_shutdown_modify(struct nb_cb_modify_args *args); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int pim_msdp_mesh_group_create(struct nb_cb_create_args *args); int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args *args); int pim_msdp_mesh_group_members_create(struct nb_cb_create_args *args); @@ -137,6 +143,11 @@ int lib_interface_pim_address_family_multicast_boundary_oil_modify( struct nb_cb_modify_args *args); int lib_interface_pim_address_family_multicast_boundary_oil_destroy( struct nb_cb_destroy_args *args); +<<<<<<< HEAD +======= +int lib_interface_pim_address_family_multicast_boundary_acl_modify(struct nb_cb_modify_args *args); +int lib_interface_pim_address_family_multicast_boundary_acl_destroy(struct nb_cb_destroy_args *args); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int lib_interface_pim_address_family_mroute_create( struct nb_cb_create_args *args); int lib_interface_pim_address_family_mroute_destroy( @@ -159,6 +170,13 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy( struct nb_cb_destroy_args *args); +<<<<<<< HEAD +======= +int pim_embedded_rp_enable_modify(struct nb_cb_modify_args *args); +int pim_embedded_rp_group_list_modify(struct nb_cb_modify_args *args); +int pim_embedded_rp_group_list_destroy(struct nb_cb_destroy_args *args); +int pim_embedded_rp_maximum_rps_modify(struct nb_cb_modify_args *args); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify( struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_destroy( @@ -187,6 +205,23 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy( struct nb_cb_destroy_args *args); +<<<<<<< HEAD +======= +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_send_rp_discovery_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_scope_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_interval_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_holdtime_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create( + struct nb_cb_create_args *args); +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify( + struct nb_cb_modify_args *args); +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy( + struct nb_cb_destroy_args *args); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* frr-cand-bsr */ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_candidate_bsr_create( @@ -286,6 +321,12 @@ int routing_control_plane_protocols_name_validate( "mroute[source-addr='%s'][group-addr='%s']" #define FRR_PIM_STATIC_RP_XPATH \ "frr-pim-rp:rp/static-rp/rp-list[rp-address='%s']" +<<<<<<< HEAD +======= +#define FRR_PIM_EMBEDDED_RP_XPATH "./frr-pim-rp:rp/embedded-rp/enable" +#define FRR_PIM_EMBEDDED_RP_GROUP_LIST_XPATH "./frr-pim-rp:rp/embedded-rp/group-list" +#define FRR_PIM_EMBEDDED_RP_MAXIMUM_RPS_XPATH "./frr-pim-rp:rp/embedded-rp/maximum-rps" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #define FRR_PIM_AUTORP_XPATH "./frr-pim-rp:rp/auto-rp" #define FRR_GMP_INTERFACE_XPATH \ "./frr-gmp:gmp/address-family[address-family='%s']" diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index ea8b56fee395..ceeb97d118f0 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -17,6 +17,10 @@ #include "pim_mlag.h" #include "pim_bfd.h" #include "pim_msdp_socket.h" +<<<<<<< HEAD +======= +#include "pimd/pim_rp.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "pim_static.h" #include "pim_ssm.h" #include "pim_ssmpingd.h" @@ -40,12 +44,30 @@ int funcname(struct argtype *args) \ } \ MACRO_REQUIRE_SEMICOLON() +<<<<<<< HEAD +======= +#define pim6_autorp_err(funcname, argtype) \ + int funcname(struct argtype *args) \ + { \ + snprintf(args->errmsg, args->errmsg_len, \ + "Trying to configure AutoRP in pim6d. " \ + "AutoRP does not exist for IPv6."); \ + return NB_ERR_VALIDATION; \ + } \ + MACRO_REQUIRE_SEMICOLON() + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #define yang_dnode_get_pimaddr yang_dnode_get_ipv6 #else /* PIM_IPV != 6 */ #define pim6_msdp_err(funcname, argtype) \ MACRO_REQUIRE_SEMICOLON() +<<<<<<< HEAD +======= +#define pim6_autorp_err(funcname, argtype) MACRO_REQUIRE_SEMICOLON() + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #define yang_dnode_get_pimaddr yang_dnode_get_ipv4 #endif /* PIM_IPV != 6 */ @@ -489,6 +511,29 @@ static void change_query_max_response_time(struct interface *ifp, #endif /* PIM_IPV == 4 */ } +<<<<<<< HEAD +======= +static void yang_addrsel(struct cand_addrsel *addrsel, const struct lyd_node *node) +{ + memset(addrsel->cfg_ifname, 0, sizeof(addrsel->cfg_ifname)); + addrsel->cfg_addr = PIMADDR_ANY; + + if (yang_dnode_exists(node, "if-any")) { + addrsel->cfg_mode = CAND_ADDR_ANY; + } else if (yang_dnode_exists(node, "address")) { + addrsel->cfg_mode = CAND_ADDR_EXPLICIT; + yang_dnode_get_pimaddr(&addrsel->cfg_addr, node, "address"); + } else if (yang_dnode_exists(node, "interface")) { + addrsel->cfg_mode = CAND_ADDR_IFACE; + strlcpy(addrsel->cfg_ifname, yang_dnode_get_string(node, "interface"), + sizeof(addrsel->cfg_ifname)); + } else if (yang_dnode_exists(node, "if-loopback")) { + addrsel->cfg_mode = CAND_ADDR_LO; + } + addrsel->cfg_enable = true; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int routing_control_plane_protocols_name_validate( struct nb_cb_create_args *args) { @@ -1063,10 +1108,103 @@ pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address pim6_msdp_err(pim_msdp_peer_authentication_type_modify, nb_cb_modify_args); pim6_msdp_err(pim_msdp_peer_authentication_key_modify, nb_cb_modify_args); pim6_msdp_err(pim_msdp_peer_authentication_key_destroy, nb_cb_destroy_args); +<<<<<<< HEAD +======= +pim6_msdp_err(pim_msdp_log_neighbor_events_modify, nb_cb_modify_args); +pim6_msdp_err(pim_msdp_log_sa_events_modify, nb_cb_modify_args); +pim6_msdp_err(pim_msdp_shutdown_modify, nb_cb_modify_args); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #if PIM_IPV != 6 /* * XPath: +<<<<<<< HEAD +======= + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/log-neighbor-events + */ +int pim_msdp_log_neighbor_events_modify(struct nb_cb_modify_args *args) +{ + struct pim_instance *pim; + struct vrf *vrf; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + /* NOTHING */ + break; + + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(pim->log_flags, PIM_MSDP_LOG_NEIGHBOR_EVENTS); + else + UNSET_FLAG(pim->log_flags, PIM_MSDP_LOG_NEIGHBOR_EVENTS); + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/log-sa-events + */ +int pim_msdp_log_sa_events_modify(struct nb_cb_modify_args *args) +{ + struct pim_instance *pim; + struct vrf *vrf; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + /* NOTHING */ + break; + + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(pim->log_flags, PIM_MSDP_LOG_SA_EVENTS); + else + UNSET_FLAG(pim->log_flags, PIM_MSDP_LOG_SA_EVENTS); + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/shutdown + */ +int pim_msdp_shutdown_modify(struct nb_cb_modify_args *args) +{ + struct pim_instance *pim; + struct vrf *vrf; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + /* NOTHING */ + break; + + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + pim_msdp_shutdown(pim, yang_dnode_get_bool(args->dnode, NULL)); + break; + } + + return NB_OK; +} + +/* + * XPath: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups */ int pim_msdp_mesh_group_create(struct nb_cb_create_args *args) @@ -2270,7 +2408,10 @@ int lib_interface_pim_address_family_multicast_boundary_oil_modify( { struct interface *ifp; struct pim_interface *pim_ifp; +<<<<<<< HEAD const char *plist; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) const struct lyd_node *if_dnode; switch (args->event) { @@ -2278,7 +2419,16 @@ int lib_interface_pim_address_family_multicast_boundary_oil_modify( if_dnode = yang_dnode_get_parent(args->dnode, "interface"); if (!is_pim_interface(if_dnode)) { snprintf(args->errmsg, args->errmsg_len, +<<<<<<< HEAD "Pim not enabled on this interface"); +======= + "%% Enable PIM and/or IGMP on this interface first"); + return NB_ERR_VALIDATION; + } + if (!prefix_list_lookup(AFI_IP, yang_dnode_get_string(args->dnode, NULL))) { + snprintf(args->errmsg, args->errmsg_len, + "%% Specified prefix-list not found"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_ERR_VALIDATION; } break; @@ -2288,6 +2438,7 @@ int lib_interface_pim_address_family_multicast_boundary_oil_modify( case NB_EV_APPLY: ifp = nb_running_get_entry(args->dnode, NULL, true); pim_ifp = ifp->info; +<<<<<<< HEAD plist = yang_dnode_get_string(args->dnode, NULL); if (pim_ifp->boundary_oil_plist) @@ -2295,6 +2446,10 @@ int lib_interface_pim_address_family_multicast_boundary_oil_modify( pim_ifp->boundary_oil_plist = XSTRDUP(MTYPE_PIM_INTERFACE, plist); +======= + pim_ifp->boundary_oil_plist = + prefix_list_lookup(AFI_IP, yang_dnode_get_string(args->dnode, NULL)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) break; } @@ -2324,8 +2479,77 @@ int lib_interface_pim_address_family_multicast_boundary_oil_destroy( case NB_EV_APPLY: ifp = nb_running_get_entry(args->dnode, NULL, true); pim_ifp = ifp->info; +<<<<<<< HEAD if (pim_ifp->boundary_oil_plist) XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist); +======= + pim_ifp->boundary_oil_plist = NULL; + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-acl + */ +int lib_interface_pim_address_family_multicast_boundary_acl_modify(struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct pim_interface *pim_ifp; + const struct lyd_node *if_dnode; + + switch (args->event) { + case NB_EV_VALIDATE: + if_dnode = yang_dnode_get_parent(args->dnode, "interface"); + if (!is_pim_interface(if_dnode)) { + snprintf(args->errmsg, args->errmsg_len, + "%% Enable PIM and/or IGMP on this interface first"); + return NB_ERR_VALIDATION; + } + if (!access_list_lookup(AFI_IP, yang_dnode_get_string(args->dnode, NULL))) { + snprintf(args->errmsg, args->errmsg_len, + "%% Specified access-list not found"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_ABORT: + case NB_EV_PREPARE: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + pim_ifp = ifp->info; + pim_ifp->boundary_acl = + access_list_lookup(AFI_IP, yang_dnode_get_string(args->dnode, NULL)); + break; + } + + return NB_OK; +} + +int lib_interface_pim_address_family_multicast_boundary_acl_destroy(struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct pim_interface *pim_ifp; + const struct lyd_node *if_dnode; + + switch (args->event) { + case NB_EV_VALIDATE: + if_dnode = yang_dnode_get_parent(args->dnode, "interface"); + if (!is_pim_interface(if_dnode)) { + snprintf(args->errmsg, args->errmsg_len, + "%% Enable PIM and/or IGMP on this interface first"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_ABORT: + case NB_EV_PREPARE: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + pim_ifp = ifp->info; + pim_ifp->boundary_acl = NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) break; } @@ -2685,12 +2909,192 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp } /* +<<<<<<< HEAD +======= + * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/embedded-rp/enable + */ +int pim_embedded_rp_enable_modify(struct nb_cb_modify_args *args) +{ +#if PIM_IPV == 6 + struct vrf *vrf; +#endif /* PIM_IPV == 6 */ + + switch (args->event) { + case NB_EV_APPLY: +#if PIM_IPV == 6 + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim_embedded_rp_enable(vrf->info, yang_dnode_get_bool(args->dnode, NULL)); + return NB_OK; +#else + snprintf(args->errmsg, args->errmsg_len, "embedded RP is IPv6 only"); + return NB_ERR; +#endif /* PIM_IPV == 6 */ + + case NB_EV_ABORT: + case NB_EV_PREPARE: + case NB_EV_VALIDATE: + default: + return NB_OK; + } +} + +/* + * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/embedded-rp/group-list + */ +int pim_embedded_rp_group_list_modify(struct nb_cb_modify_args *args) +{ +#if PIM_IPV == 6 + struct vrf *vrf; +#endif /* PIM_IPV == 6 */ + + switch (args->event) { + case NB_EV_APPLY: +#if PIM_IPV == 6 + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim_embedded_rp_set_group_list(vrf->info, yang_dnode_get_string(args->dnode, NULL)); + return NB_OK; +#else + snprintf(args->errmsg, args->errmsg_len, "embedded RP is IPv6 only"); + return NB_ERR; +#endif /* PIM_IPV == 6 */ + + case NB_EV_ABORT: + case NB_EV_PREPARE: + case NB_EV_VALIDATE: + default: + return NB_OK; + } +} + +int pim_embedded_rp_group_list_destroy(struct nb_cb_destroy_args *args) +{ +#if PIM_IPV == 6 + struct vrf *vrf; +#endif /* PIM_IPV == 6 */ + + switch (args->event) { + case NB_EV_APPLY: +#if PIM_IPV == 6 + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim_embedded_rp_set_group_list(vrf->info, NULL); + return NB_OK; +#else + snprintf(args->errmsg, args->errmsg_len, "embedded RP is IPv6 only"); + return NB_ERR; +#endif /* PIM_IPV == 6 */ + + case NB_EV_ABORT: + case NB_EV_PREPARE: + case NB_EV_VALIDATE: + default: + return NB_OK; + } +} + +/* + * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/embedded-rp/maximum-rps + */ +int pim_embedded_rp_maximum_rps_modify(struct nb_cb_modify_args *args) +{ +#if PIM_IPV == 6 + struct vrf *vrf; +#endif /* PIM_IPV == 6 */ + + switch (args->event) { + case NB_EV_APPLY: +#if PIM_IPV == 6 + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim_embedded_rp_set_maximum_rps(vrf->info, yang_dnode_get_uint32(args->dnode, NULL)); + return NB_OK; +#else + snprintf(args->errmsg, args->errmsg_len, "embedded RP is IPv6 only"); + return NB_ERR; +#endif /* PIM_IPV == 6 */ + + case NB_EV_ABORT: + case NB_EV_PREPARE: + case NB_EV_VALIDATE: + default: + return NB_OK; + } +} + +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_destroy, + nb_cb_destroy_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_destroy, + nb_cb_destroy_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_destroy, + nb_cb_destroy_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_destroy, + nb_cb_destroy_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_create, + nb_cb_create_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_destroy, + nb_cb_destroy_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_destroy, + nb_cb_destroy_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy, + nb_cb_destroy_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_send_rp_discovery_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_scope_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_interval_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_holdtime_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create, + nb_cb_create_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify, + nb_cb_modify_args); +pim6_autorp_err( + routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy, + nb_cb_destroy_args); + +#if PIM_IPV == 4 +/* +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/discovery-enabled */ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify( struct nb_cb_modify_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; bool enabled; @@ -2710,14 +3114,20 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp pim_autorp_stop_discovery(pim); break; } +<<<<<<< HEAD #endif +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_destroy( struct nb_cb_destroy_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; bool enabled; @@ -2736,7 +3146,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp pim_autorp_start_discovery(pim); break; } +<<<<<<< HEAD #endif +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } @@ -2747,7 +3160,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_modify( struct nb_cb_modify_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; uint8_t scope; @@ -2762,15 +3178,23 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp pim = vrf->info; scope = yang_dnode_get_uint8(args->dnode, NULL); pim_autorp_announce_scope(pim, scope); +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_destroy( struct nb_cb_destroy_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; @@ -2783,8 +3207,13 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp vrf = nb_running_get_entry(args->dnode, NULL, true); pim = vrf->info; pim_autorp_announce_scope(pim, 0); +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } @@ -2795,7 +3224,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_modify( struct nb_cb_modify_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; uint16_t interval; @@ -2810,15 +3242,23 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp pim = vrf->info; interval = yang_dnode_get_uint16(args->dnode, NULL); pim_autorp_announce_interval(pim, interval); +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_destroy( struct nb_cb_destroy_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; @@ -2831,8 +3271,13 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp vrf = nb_running_get_entry(args->dnode, NULL, true); pim = vrf->info; pim_autorp_announce_interval(pim, 0); +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } @@ -2843,7 +3288,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_modify( struct nb_cb_modify_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; uint16_t holdtime; @@ -2858,15 +3306,23 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp pim = vrf->info; holdtime = yang_dnode_get_uint16(args->dnode, NULL); pim_autorp_announce_holdtime(pim, holdtime); +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_destroy( struct nb_cb_destroy_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; @@ -2880,8 +3336,13 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp pim = vrf->info; /* 0 is a valid value, so -1 indicates deleting (go back to default) */ pim_autorp_announce_holdtime(pim, -1); +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } @@ -2892,7 +3353,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_create( struct nb_cb_create_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: @@ -2900,14 +3364,20 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp case NB_EV_APPLY: break; } +<<<<<<< HEAD #endif +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_destroy( struct nb_cb_destroy_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; pim_addr rp_addr; @@ -2925,7 +3395,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp return NB_ERR_INCONSISTENCY; break; } +<<<<<<< HEAD #endif +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } @@ -2936,7 +3409,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_modify( struct nb_cb_modify_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; struct prefix group; @@ -2954,15 +3430,23 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp yang_dnode_get_prefix(&group, args->dnode, NULL); apply_mask(&group); pim_autorp_add_candidate_rp_group(pim, rp_addr, group); +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_destroy( struct nb_cb_destroy_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; struct prefix group; @@ -2981,8 +3465,13 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp apply_mask(&group); if (!pim_autorp_rm_candidate_rp_group(pim, rp_addr, group)) return NB_ERR_INCONSISTENCY; +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } @@ -2993,7 +3482,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_modify( struct nb_cb_modify_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; pim_addr rp_addr; @@ -3010,15 +3502,23 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp plist = yang_dnode_get_string(args->dnode, NULL); yang_dnode_get_pimaddr(&rp_addr, args->dnode, "../rp-address"); pim_autorp_add_candidate_rp_plist(pim, rp_addr, plist); +<<<<<<< HEAD } #endif +======= + break; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy( struct nb_cb_destroy_args *args) { +<<<<<<< HEAD #if PIM_IPV == 4 +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf; struct pim_instance *pim; pim_addr rp_addr; @@ -3038,11 +3538,15 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp return NB_ERR_INCONSISTENCY; break; } +<<<<<<< HEAD #endif +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NB_OK; } +<<<<<<< HEAD static void yang_addrsel(struct cand_addrsel *addrsel, const struct lyd_node *node) { @@ -3064,6 +3568,210 @@ static void yang_addrsel(struct cand_addrsel *addrsel, } } +======= +/* + * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/send-rp-discovery + */ +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_send_rp_discovery_modify( + struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct pim_instance *pim; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (pim && pim->autorp) { + pim->autorp->send_rp_discovery = yang_dnode_get_bool(args->dnode, NULL); + pim_autorp_send_discovery_apply(pim->autorp); + } else + return NB_ERR_INCONSISTENCY; + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-scope + */ +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_scope_modify( + struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct pim_instance *pim; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (pim && pim->autorp) + pim->autorp->discovery_scope = yang_dnode_get_uint8(args->dnode, NULL); + else + return NB_ERR_INCONSISTENCY; + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-interval + */ +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_interval_modify( + struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct pim_instance *pim; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (pim && pim->autorp) + pim->autorp->discovery_interval = yang_dnode_get_uint16(args->dnode, NULL); + else + return NB_ERR_INCONSISTENCY; + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-holdtime + */ +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_holdtime_modify( + struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct pim_instance *pim; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (pim && pim->autorp) + pim->autorp->discovery_holdtime = yang_dnode_get_uint16(args->dnode, NULL); + else + return NB_ERR_INCONSISTENCY; + break; + } + + return NB_OK; +} + +static int pim_autorp_mapping_agent_addrsel(struct pim_autorp *autorp, + const struct lyd_node *mapping_agent_node, + struct vrf *vrf) +{ + yang_addrsel(&autorp->mapping_agent_addrsel, mapping_agent_node); + if (cand_addrsel_update(&autorp->mapping_agent_addrsel, vrf)) + pim_autorp_send_discovery_apply(autorp); + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/address + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/interface + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/if-loopback + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/if-any + */ +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create( + struct nb_cb_create_args *args) +{ + struct vrf *vrf; + struct pim_instance *pim; + const struct lyd_node *mapping_agent_node; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + mapping_agent_node = yang_dnode_get_parent(args->dnode, "mapping-agent"); + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (pim && pim->autorp) + return pim_autorp_mapping_agent_addrsel(pim->autorp, mapping_agent_node, + vrf); + else + return NB_ERR_INCONSISTENCY; + break; + } + return NB_OK; +} + +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify( + struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct pim_instance *pim; + const struct lyd_node *mapping_agent_node; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + mapping_agent_node = yang_dnode_get_parent(args->dnode, "mapping-agent"); + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (pim && pim->autorp) + return pim_autorp_mapping_agent_addrsel(pim->autorp, mapping_agent_node, + vrf); + else + return NB_ERR_INCONSISTENCY; + break; + } + return NB_OK; +} + +int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy( + struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + struct pim_instance *pim; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + if (pim && pim->autorp) + pim->autorp->mapping_agent_addrsel.cfg_enable = false; + else + return NB_ERR_INCONSISTENCY; + break; + } + + return NB_OK; +} +#endif /* PIM_IPV == 4 (for AutoRP)*/ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static int candidate_bsr_addrsel(struct bsm_scope *scope, const struct lyd_node *cand_bsr_node) { diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 0c47bc15823d..a13a99ef7c4e 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -115,10 +115,44 @@ void pim_rp_init(struct pim_instance *pim) zlog_debug("Allocated: %p for rp_info: %p(%pFX) Lock: %d", rn, rp_info, &rp_info->group, route_node_get_lock_count(rn)); +<<<<<<< HEAD +======= + +#if PIM_IPV == 6 + /* + * Embedded RP defaults + */ + pim->embedded_rp.enable = false; + pim->embedded_rp.group_list = NULL; + pim->embedded_rp.maximum_rps = PIM_EMBEDDED_RP_MAXIMUM; + + pim->embedded_rp.table = route_table_init(); +#endif /* PIM_IPV == 6 */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } void pim_rp_free(struct pim_instance *pim) { +<<<<<<< HEAD +======= +#if PIM_IPV == 6 + struct route_node *rn; + + pim_embedded_rp_set_group_list(pim, NULL); + + for (rn = route_top(pim->embedded_rp.table); rn; rn = route_next(rn)) { + if (rn->info == NULL) + continue; + + pim_embedded_rp_free(pim, rn->info); + rn->info = NULL; + } + + route_table_finish(pim->embedded_rp.table); + pim->embedded_rp.table = NULL; +#endif /* PIM_IPV == 6 */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (pim->rp_table) route_table_finish(pim->rp_table); pim->rp_table = NULL; @@ -216,6 +250,27 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, const struct prefix_list_entry *entry; struct route_node *rn; +<<<<<<< HEAD +======= +#if PIM_IPV == 6 + /* + * Embedded RP search. Always try to match against embedded RP first. + */ + rn = route_node_match(pim->embedded_rp.table, group); + if (rn != NULL) { + rp_info = rn->info ? rn->info : NULL; + + if (rp_info && PIM_DEBUG_PIM_TRACE_DETAIL) { + zlog_debug("Lookedup(%pFX): rn %p found:%pFX", group, rn, &rp_info->group); + } + + route_unlock_node(rn); + if (rp_info) + return rp_info; + } +#endif /* PIM_IPV == 6 */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bp = NULL; for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) { if (rp_info->plist) { @@ -330,9 +385,14 @@ static int pim_rp_check_interface_addrs(struct rp_info *rp_info, if (!pim_addr_cmp(pim_ifp->primary_address, rp_info->rp.rpf_addr)) return 1; +<<<<<<< HEAD if (!pim_ifp->sec_addr_list) { return 0; } +======= + if (!pim_ifp->sec_addr_list) + return 0; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) { sec_paddr = pim_addr_from_prefix(&sec_addr->addr); @@ -1203,6 +1263,13 @@ void pim_rp_show_information(struct pim_instance *pim, struct prefix *range, strlcpy(source, "BSR", sizeof(source)); else if (rp_info->rp_src == RP_SRC_AUTORP) strlcpy(source, "AutoRP", sizeof(source)); +<<<<<<< HEAD +======= +#if PIM_IPV == 6 + else if (rp_info->rp_src == RP_SRC_EMBEDDED_RP) + strlcpy(source, "Embedded-RP", sizeof(source)); +#endif /* PIM_IPV == 6 */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) else strlcpy(source, "None", sizeof(source)); if (json) { @@ -1329,3 +1396,215 @@ void pim_resolve_rp_nh(struct pim_instance *pim, struct pim_neighbor *nbr) } } } +<<<<<<< HEAD +======= + +#if PIM_IPV == 6 +DEFINE_MTYPE_STATIC(PIMD, PIM_EMBEDDED_RP_GROUP_LIST, "PIM embedded RP group list"); +DEFINE_MTYPE_STATIC(PIMD, PIM_EMBEDDED_RP_ENTRY, "PIM embedded RP configuration"); + +void pim_embedded_rp_enable(struct pim_instance *pim, bool enable) +{ + struct route_node *rn; + + pim->embedded_rp.enable = enable; + if (enable) + return; + + /* Remove all learned embedded RPs and reallocate data structure. */ + for (rn = route_top(pim->embedded_rp.table); rn; rn = route_next(rn)) { + pim_embedded_rp_free(pim, rn->info); + rn->info = NULL; + } + route_table_finish(pim->embedded_rp.table); + + pim->embedded_rp.table = route_table_init(); +} + +void pim_embedded_rp_set_group_list(struct pim_instance *pim, const char *group_list) +{ + if (pim->embedded_rp.group_list) + XFREE(MTYPE_PIM_EMBEDDED_RP_GROUP_LIST, pim->embedded_rp.group_list); + + if (group_list == NULL) + return; + + pim->embedded_rp.group_list = XSTRDUP(MTYPE_PIM_EMBEDDED_RP_GROUP_LIST, group_list); +} + +void pim_embedded_rp_set_maximum_rps(struct pim_instance *pim, uint32_t maximum) +{ + pim->embedded_rp.maximum_rps = maximum; +} + +bool pim_embedded_rp_filter_match(const struct pim_instance *pim, const pim_addr *group) +{ + struct prefix_list *list; + struct prefix group_prefix = { + .family = PIM_AF, + .prefixlen = PIM_MAX_BITLEN, + .u.prefix6 = *group, + }; + + list = prefix_list_lookup(PIM_AFI, pim->embedded_rp.group_list); + if (list == NULL) + return false; + + if (prefix_list_apply_ext(list, NULL, &group_prefix, true) == PREFIX_DENY) { + if (PIM_DEBUG_PIM_TRACE) + zlog_debug("filtering embedded-rp group %pPA", group); + return true; + } + + return false; +} + +bool pim_embedded_rp_is_embedded(const pim_addr *group) +{ + /* + * Embedded RP basic format: + * - First byte: 0xFF + * - Third nibble: 0x7 (binary 0111) + * - Fourth nibble: Scope + * - Fifth nibble: Reserved (zero) + * - Sixth nibble: RIID (RP interface ID) + * - Fourth byte: Prefix length (1..64) + * - Fifth byte and on: RP address prefix + * - Last four bytes: Multicast group ID + */ + if (group->s6_addr[0] != 0xFF) + return false; + /* Embedded RP flags must all be set. */ + if ((group->s6_addr[1] & 0xF0) != 0x70) + return false; + /* Reserved nibble */ + if ((group->s6_addr[2] & 0xF0) != 0x00) + return false; + /* RP Interface ID must not be zero */ + if ((group->s6_addr[2] & 0x0F) == 0x00) + return false; + /* Prefix length must be between 1 and 64. */ + if (group->s6_addr[3] == 0 || group->s6_addr[3] > 64) + return false; + + return true; +} + +bool pim_embedded_rp_extract(const pim_addr *group, pim_addr *rp) +{ + struct prefix prefix; + + if (!pim_embedded_rp_is_embedded(group)) + return false; + + /* Copy at most the prefix bytes length to RP prefix. */ + prefix = (struct prefix){ + .family = PIM_AF, + .prefixlen = group->s6_addr[3], + }; + memcpy(&prefix.u.prefix6, &group->s6_addr[4], + (prefix.prefixlen % 8) == 0 ? (prefix.prefixlen / 8) : (prefix.prefixlen / 8) + 1); + /* Zero unused address bits. */ + apply_mask(&prefix); + + /* Return assembled RP address. */ + *rp = prefix.u.prefix6; + rp->s6_addr[15] = group->s6_addr[2] & 0x0F; + return true; +} + +void pim_embedded_rp_new(struct pim_instance *pim, const pim_addr *group, const pim_addr *rp) +{ + struct route_node *rnode; + struct rp_info *rp_info; + struct prefix group_prefix = { + .family = PIM_AF, + .prefixlen = PIM_MAX_BITLEN, + .u.prefix6 = *group, + }; + + rnode = route_node_get(pim->embedded_rp.table, &group_prefix); + if (rnode->info != NULL) { + route_unlock_node(rnode); + return; + } + + if (pim->embedded_rp.rp_count >= pim->embedded_rp.maximum_rps) { + zlog_info("Embedded RP maximum (%u) has been reached. Disregarding new RP %pPA", + pim->embedded_rp.maximum_rps, rp); + route_unlock_node(rnode); + return; + } + + pim->embedded_rp.rp_count++; + + rnode->info = rp_info = XCALLOC(MTYPE_PIM_EMBEDDED_RP_ENTRY, sizeof(struct rp_info)); + rp_info->rp.rpf_addr = *rp; + prefix_copy(&rp_info->group, &group_prefix); + rp_info->rp_src = RP_SRC_EMBEDDED_RP; + listnode_add_sort(pim->rp_list, rp_info); + if (PIM_DEBUG_TRACE) + zlog_debug("add embedded RP %pPA for group %pPA", rp, group); + + /* + * PIM RP regular maintenance + */ + pim_zebra_update_all_interfaces(pim); + pim_rp_check_interfaces(pim, rp_info); + if (rp_info->i_am_rp && PIM_DEBUG_PIM_NHT_RP) + zlog_debug("new RP %pPA for %pFX is ourselves", &rp_info->rp.rpf_addr, + &rp_info->group); + + pim_rp_refresh_group_to_rp_mapping(pim); + if (PIM_DEBUG_PIM_NHT_RP) + zlog_debug("%s: NHT Register RP addr %pPA grp %pFX with Zebra", __func__, + &rp_info->rp.rpf_addr, &rp_info->group); + + pim_find_or_track_nexthop(pim, rp_info->rp.rpf_addr, NULL, rp_info, NULL); + if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, rp_info->rp.rpf_addr, + &rp_info->group, 1)) { + if (PIM_DEBUG_PIM_NHT_RP) + zlog_debug("%s: Embedded RP %pPA learned but no next hop", __func__, + &rp_info->rp.rpf_addr); + } +} + +void pim_embedded_rp_delete(struct pim_instance *pim, const pim_addr *group) +{ + struct route_node *rnode; + struct prefix group_prefix = { + .family = PIM_AF, + .prefixlen = PIM_MAX_BITLEN, + .u.prefix6 = *group, + }; + + /* Avoid NULL accesses during shutdown */ + if (pim->embedded_rp.table == NULL) + return; + + rnode = route_node_lookup(pim->embedded_rp.table, &group_prefix); + if (rnode == NULL) + return; + + pim_embedded_rp_free(pim, rnode->info); + rnode->info = NULL; + + /* Unlock twice to remove the node */ + route_unlock_node(rnode); + route_unlock_node(rnode); +} + +void pim_embedded_rp_free(struct pim_instance *pim, struct rp_info *rp_info) +{ + if (pim->embedded_rp.rp_count > 0) + pim->embedded_rp.rp_count--; + + if (PIM_DEBUG_TRACE) + zlog_debug("delete embedded RP %pPA", &rp_info->rp.rpf_addr); + + pim_delete_tracked_nexthop(pim, rp_info->rp.rpf_addr, NULL, rp_info); + listnode_delete(pim->rp_list, rp_info); + XFREE(MTYPE_PIM_EMBEDDED_RP_ENTRY, rp_info); +} +#endif /* PIM_IPV == 6 */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index 24832d0dbd60..99be25e1fcb3 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -16,7 +16,19 @@ struct pim_interface; +<<<<<<< HEAD enum rp_source { RP_SRC_NONE = 0, RP_SRC_STATIC, RP_SRC_BSR, RP_SRC_AUTORP }; +======= +enum rp_source { + RP_SRC_NONE = 0, + RP_SRC_STATIC, + RP_SRC_BSR, + RP_SRC_AUTORP, +#if PIM_IPV == 6 + RP_SRC_EMBEDDED_RP, +#endif /* PIM_IPV == 6*/ +}; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct rp_info { struct prefix group; @@ -26,6 +38,14 @@ struct rp_info { char *plist; }; +<<<<<<< HEAD +======= +#if PIM_IPV == 6 +/** Default maximum simultaneous embedded RPs at one time. */ +#define PIM_EMBEDDED_RP_MAXIMUM 25 +#endif /* PIM_IPV == 6 */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) void pim_rp_init(struct pim_instance *pim); void pim_rp_free(struct pim_instance *pim); @@ -69,4 +89,48 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, const struct prefix *group); void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up); void pim_rp_refresh_group_to_rp_mapping(struct pim_instance *pim); +<<<<<<< HEAD +======= + +#if PIM_IPV == 6 +/** Check if address has valid embedded RP value. */ +bool pim_embedded_rp_is_embedded(const pim_addr *group) __attribute__((nonnull(1))); + +/** Test address against embedded RP group list filter. */ +bool pim_embedded_rp_filter_match(const struct pim_instance *pim, const pim_addr *group) + __attribute__((nonnull(1, 2))); + +/** + * Extract embedded RP address from multicast group. + * + * Returns true if successful otherwise false. + */ +bool pim_embedded_rp_extract(const pim_addr *group, pim_addr *rp) __attribute__((nonnull(1, 2))); + +/** Allocate new embedded RP. */ +void pim_embedded_rp_new(struct pim_instance *pim, const pim_addr *group, const pim_addr *rp) + __attribute__((nonnull(1, 2, 3))); + +/** Remove and free allocated embedded RP. */ +void pim_embedded_rp_delete(struct pim_instance *pim, const pim_addr *group) + __attribute__((nonnull(1, 2))); + +/** Free memory allocated by embedded RP information. */ +extern void pim_embedded_rp_free(struct pim_instance *pim, struct rp_info *rp_info) + __attribute__((nonnull(1, 2))); + +/** Toggle embedded RP state. */ +extern void pim_embedded_rp_enable(struct pim_instance *pim, bool enable) + __attribute__((nonnull(1))); + +/** Configure embedded RP group prefix list. */ +extern void pim_embedded_rp_set_group_list(struct pim_instance *pim, const char *group_list) + __attribute__((nonnull(1))); + +/** Configure maximum number of embedded RPs to learn. */ +extern void pim_embedded_rp_set_maximum_rps(struct pim_instance *pim, uint32_t maximum) + __attribute__((nonnull(1))); +#endif /* PIM_IPV == 6 */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #endif diff --git a/pimd/pim_tib.c b/pimd/pim_tib.c index ac07154f86c1..dc7585589728 100644 --- a/pimd/pim_tib.c +++ b/pimd/pim_tib.c @@ -115,8 +115,18 @@ bool tib_sg_gm_join(struct pim_instance *pim, pim_sgaddr sg, return false; } +<<<<<<< HEAD if (!*oilp) *oilp = tib_sg_oil_setup(pim, sg, oif); +======= + if (!*oilp) { + *oilp = tib_sg_oil_setup(pim, sg, oif); +#if PIM_IPV == 6 + if (pim_embedded_rp_is_embedded(&sg.grp)) + (*oilp)->oil_ref_count--; +#endif /* PIM_IPV == 6 */ + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!*oilp) return false; @@ -176,7 +186,18 @@ void tib_sg_gm_prune(struct pim_instance *pim, pim_sgaddr sg, Making the call to pim_channel_del_oif and ignoring the return code fixes the issue without ill effect, similar to pim_forward_stop below. +<<<<<<< HEAD + */ +======= + + Also on shutdown when the PIM upstream is removed the channel removal + may have already happened, so just return here instead of trying to + access an invalid pointer. */ + if (pim->stopping) + return; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) result = pim_channel_del_oif(*oilp, oif, PIM_OIF_FLAG_PROTO_GM, __func__); if (result) { diff --git a/pimd/pim_util.c b/pimd/pim_util.c index 657e84ae50aa..0b5bbcdb3d05 100644 --- a/pimd/pim_util.c +++ b/pimd/pim_util.c @@ -9,7 +9,14 @@ #include "log.h" #include "prefix.h" #include "plist.h" +<<<<<<< HEAD +======= +#include "plist_int.h" + +#include "pimd.h" +#include "pim_instance.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "pim_util.h" /* @@ -126,20 +133,102 @@ int pim_is_group_224_4(struct in_addr group_addr) return prefix_match(&group_all, &group); } +<<<<<<< HEAD bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp) { struct prefix grp_pfx; struct prefix_list *pl; if (!pim_ifp->boundary_oil_plist) +======= +static bool pim_cisco_match(const struct filter *filter, const struct in_addr *source, + const struct in_addr *group) +{ + const struct filter_cisco *cfilter = &filter->u.cfilter; + uint32_t source_addr; + uint32_t group_addr; + + group_addr = group->s_addr & ~cfilter->mask_mask.s_addr; + + if (cfilter->extended) { + source_addr = source->s_addr & ~cfilter->addr_mask.s_addr; + if (group_addr == cfilter->mask.s_addr && source_addr == cfilter->addr.s_addr) + return true; + } else if (group_addr == cfilter->addr.s_addr) + return true; + + return false; +} + +enum filter_type pim_access_list_apply(struct access_list *access, const struct in_addr *source, + const struct in_addr *group) +{ + struct filter *filter; + struct prefix group_prefix = {}; + + if (access == NULL) + return FILTER_DENY; + + for (filter = access->head; filter; filter = filter->next) { + if (filter->cisco) { + if (pim_cisco_match(filter, source, group)) + return filter->type; + } + } + + group_prefix.family = AF_INET; + group_prefix.prefixlen = IPV4_MAX_BITLEN; + group_prefix.u.prefix4.s_addr = group->s_addr; + return access_list_apply(access, &group_prefix); +} + +bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp, pim_addr *src) +{ + bool is_filtered = false; +#if PIM_IPV == 4 + struct prefix grp_pfx = {}; + pim_addr any_src = PIMADDR_ANY; + + if (!pim_ifp->boundary_oil_plist && !pim_ifp->boundary_acl) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return false; pim_addr_to_prefix(&grp_pfx, *grp); +<<<<<<< HEAD pl = prefix_list_lookup(PIM_AFI, pim_ifp->boundary_oil_plist); return pl ? prefix_list_apply_ext(pl, NULL, &grp_pfx, true) == PREFIX_DENY : false; +======= + /* Filter if either group or (S,G) are denied */ + if (pim_ifp->boundary_oil_plist) { + is_filtered = prefix_list_apply_ext(pim_ifp->boundary_oil_plist, NULL, &grp_pfx, + true) == PREFIX_DENY; + if (is_filtered && PIM_DEBUG_EVENTS) { + zlog_debug("Filtering group %pI4 per prefix-list %s", grp, + pim_ifp->boundary_oil_plist->name); + } + } + if (!is_filtered && pim_ifp->boundary_acl) { + /* If src not provided, set to "any" (*)? */ + if (!src) + src = &any_src; + /* S,G filtering using extended access-list syntax */ + is_filtered = pim_access_list_apply(pim_ifp->boundary_acl, src, grp) == FILTER_DENY; + if (is_filtered && PIM_DEBUG_EVENTS) { + if (pim_addr_is_any(*src)) { + zlog_debug("Filtering (S,G)=(*, %pI4) per access-list %s", grp, + pim_ifp->boundary_acl->name); + } else { + zlog_debug("Filtering (S,G)=(%pI4, %pI4) per access-list %s", src, + grp, pim_ifp->boundary_acl->name); + } + } + } +#endif + return is_filtered; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } diff --git a/pimd/pim_util.h b/pimd/pim_util.h index c882fe4878a3..d2507e3afa63 100644 --- a/pimd/pim_util.h +++ b/pimd/pim_util.h @@ -10,6 +10,10 @@ #include #include +<<<<<<< HEAD +======= +#include "lib/filter.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "checksum.h" #include "pimd.h" @@ -22,7 +26,13 @@ void pim_pkt_dump(const char *label, const uint8_t *buf, int size); int pim_is_group_224_0_0_0_24(struct in_addr group_addr); int pim_is_group_224_4(struct in_addr group_addr); +<<<<<<< HEAD bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp); +======= +enum filter_type pim_access_list_apply(struct access_list *access, const struct in_addr *source, + const struct in_addr *group); +bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp, pim_addr *src); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int pim_get_all_mcast_group(struct prefix *prefix); bool pim_addr_is_multicast(pim_addr addr); #endif /* PIM_UTIL_H */ diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index bb620b7a7a57..7c67b40c9880 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -12,6 +12,11 @@ #include "vty.h" #include "vrf.h" #include "plist.h" +<<<<<<< HEAD +======= +#include "plist_int.h" +#include "filter.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #include "pimd.h" #include "pim_vty.h" @@ -186,6 +191,26 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) ++writes; } +<<<<<<< HEAD +======= +#if PIM_IPV == 6 + if (pim->embedded_rp.enable) { + vty_out(vty, " embedded-rp\n"); + writes++; + } + + if (pim->embedded_rp.maximum_rps != PIM_EMBEDDED_RP_MAXIMUM) { + vty_out(vty, " embedded-rp limit %u\n", pim->embedded_rp.maximum_rps); + writes++; + } + + if (pim->embedded_rp.group_list) { + vty_out(vty, " embedded-rp group-list %s\n", pim->embedded_rp.group_list); + writes++; + } +#endif /* PIM_IPV == 6 */ + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) writes += pim_rp_config_write(pim, vty); #if PIM_IPV == 4 writes += pim_autorp_config_write(pim, vty); @@ -475,7 +500,17 @@ int pim_config_write(struct vty *vty, int writes, struct interface *ifp, /* boundary */ if (pim_ifp->boundary_oil_plist) { vty_out(vty, " " PIM_AF_NAME " multicast boundary oil %s\n", +<<<<<<< HEAD pim_ifp->boundary_oil_plist); +======= + pim_ifp->boundary_oil_plist->name); + ++writes; + } + + if (pim_ifp->boundary_acl) { + vty_out(vty, " " PIM_AF_NAME " multicast boundary %s\n", + pim_ifp->boundary_acl->name); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ++writes; } diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index c19119fa4788..490bc0382458 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -193,7 +193,11 @@ static int zclient_read_nexthop(struct pim_instance *pim, distance = stream_getc(s); metric = stream_getl(s); +<<<<<<< HEAD nexthop_num = stream_getc(s); +======= + nexthop_num = stream_getw(s); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (nexthop_num < 1 || nexthop_num > router->multipath) { if (PIM_DEBUG_PIM_NHT_DETAIL) diff --git a/pimd/pimd.c b/pimd/pimd.c index 1a9ef0ce4118..0cae7fae8fec 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -36,6 +36,10 @@ #include "pim_zlookup.h" #include "pim_zebra.h" #include "pim_mlag.h" +<<<<<<< HEAD +======= +#include "pim_autorp.h" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #if MAXVIFS > 256 CPP_NOTICE("Work needs to be done to make this work properly via the pim mroute socket\n"); @@ -71,6 +75,12 @@ void pim_prefix_list_update(struct prefix_list *plist) pim_rp_prefix_list_update(pim, plist); pim_ssm_prefix_list_update(pim, plist); pim_upstream_spt_prefix_list_update(pim, plist); +<<<<<<< HEAD +======= +#if PIM_IPV == 4 + pim_autorp_prefix_list_update(pim, plist); +#endif +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } diff --git a/python/makefile.py b/python/makefile.py index 45f032296f3b..97fa40d002bd 100644 --- a/python/makefile.py +++ b/python/makefile.py @@ -52,7 +52,11 @@ "grep", "-l", "-P", +<<<<<<< HEAD "^#\s*include.*_clippy.c", +======= + r"^#\s*include.*_clippy.c", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "--", "**.c", ] diff --git a/python/xref2vtysh.py b/python/xref2vtysh.py index 0cfb11e72111..77b71667e763 100644 --- a/python/xref2vtysh.py +++ b/python/xref2vtysh.py @@ -450,9 +450,17 @@ def output_node_graph(cls, ofd, node, cmds, splitfile): graph_delete_node(node->cmdgraph, vector_slot(node->cmdgraph->nodes, 0)); vector_free(node->cmdgraph->nodes); node->cmdgraph->nodes = &gvec_{node}; +<<<<<<< HEAD {'}'} """ ) +======= +""" + ) + for cmdel in sorted(cmdels): + ofd.write(f"\tvector_set(node->cmd_vector, &{cmdel}_vtysh);\n") + ofd.write("}\n") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return [node] diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index 9286cb81d2c0..8c7a9e7cc599 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -189,6 +189,10 @@ BuildRequires: ncurses-devel BuildRequires: readline-devel BuildRequires: texinfo BuildRequires: libyang-devel >= 2.1.128 +<<<<<<< HEAD +======= +BuildRequires: pcre2-devel +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) %if 0%{?rhel} && 0%{?rhel} < 7 #python27-devel is available from ius community repo for RedHat/CentOS 6 BuildRequires: python27-devel @@ -448,7 +452,12 @@ Adds GRPC support to the individual FRR daemons. %else --disable-grpc \ %endif +<<<<<<< HEAD --enable-snmp +======= + --enable-snmp \ + --enable-pcre2posix \ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # end make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" @@ -834,6 +843,7 @@ sed -i 's/ -M rpki//' %{_sysconfdir}/frr/daemons %changelog +<<<<<<< HEAD * Tue Nov 12 2024 Jafar Al-Gharaibeh - %{version} * Tue Nov 12 2024 Jafar Al-Gharaibeh - 10.2 @@ -848,6 +858,12 @@ sed -i 's/ -M rpki//' %{_sysconfdir}/frr/daemons - Implement BGP-wide configuration for graceful restart [#16099] - Handle kernel routes appropriately (should fix recent NOPREFIXROUTE issue) [#16300] - Add `cisco-authentication` password support for NHRP [#16172] +======= +* Thu Oct 10 2024 Jafar Al-Gharaibeh - %{version} + +* Thu Oct 10 2024 Jafar Al-Gharaibeh - 10.3-dev +- FRR 10.3 Development +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * Fri Jul 26 2024 Jafar Al-Gharaibeh - 10.1 - Breaking changes diff --git a/ripd/ripd.c b/ripd/ripd.c index 8768819fe26c..4a799ece9be9 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1263,9 +1263,19 @@ static void rip_response_process(struct rip_packet *packet, int size, rip->vrf->vrf_id)) { struct route_node *rn; struct rip_info *rinfo; +<<<<<<< HEAD rn = route_node_match_ipv4(rip->table, &rte->nexthop); +======= + struct prefix p = { 0 }; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + p.u.prefix4 = rte->nexthop; + + rn = route_node_match(rip->table, &p); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (rn) { rinfo = rn->info; diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index c9211a152ffb..37d271b62253 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -213,7 +213,11 @@ DEFPY (install_routes, "The vrf we would like to install into if non-default\n" "The NAME of the vrf\n" "v4 Address to start /32 generation at\n" +<<<<<<< HEAD "v6 Address to start /32 generation at\n" +======= + "v6 Address to start /128 generation at\n" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "Nexthop to use(Can be an IPv4 or IPv6 address)\n" "V4 Nexthop address to use\n" "V6 Nexthop address to use\n" @@ -372,7 +376,11 @@ DEFPY (install_seg6_routes, "The vrf we would like to install into if non-default\n" "The NAME of the vrf\n" "v4 Address to start /32 generation at\n" +<<<<<<< HEAD "v6 Address to start /32 generation at\n" +======= + "v6 Address to start /128 generation at\n" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "Nexthop-seg6 to use\n" "V6 Nexthop address to use\n" "Encap mode\n" @@ -458,7 +466,11 @@ DEFPY (install_seg6local_routes, "Routes to install\n" "The vrf we would like to install into if non-default\n" "The NAME of the vrf\n" +<<<<<<< HEAD "v6 Address to start /32 generation at\n" +======= + "v6 Address to start /128 generation at\n" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "Nexthop-seg6local to use\n" "Output device to use\n" "SRv6 End function to use\n" @@ -503,7 +515,11 @@ DEFPY (install_seg6local_routes, sg.r.opaque[0] = '\0'; sg.r.inst = 0; sg.r.orig_prefix.family = AF_INET6; +<<<<<<< HEAD sg.r.orig_prefix.prefixlen = 128; +======= + sg.r.orig_prefix.prefixlen = IPV6_MAX_BITLEN; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) sg.r.orig_prefix.u.prefix6 = start6; if (!vrf_name) @@ -945,7 +961,11 @@ DEFPY (neigh_discover, prefix.u.prefix4 = dst4; } else { prefix.family = AF_INET6; +<<<<<<< HEAD prefix.prefixlen = 128; +======= + prefix.prefixlen = IPV6_MAX_BITLEN; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) prefix.u.prefix6 = dst6; } diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 420ed7903bbc..e4cb7c0d909b 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -43,7 +43,11 @@ struct static_nht_data { vrf_id_t nh_vrf_id; uint32_t refcount; +<<<<<<< HEAD uint8_t nh_num; +======= + uint16_t nh_num; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bool registered; }; diff --git a/tests/helpers/c/prng.c b/tests/helpers/c/prng.c index 612c43344308..fb57c42c9662 100644 --- a/tests/helpers/c/prng.c +++ b/tests/helpers/c/prng.c @@ -49,16 +49,28 @@ const char *prng_fuzz(struct prng *prng, const char *string, const char *charset, unsigned int operations) { static char buf[256]; +<<<<<<< HEAD unsigned int charset_len; +======= + size_t charset_len = strlen(charset); + size_t str_len = strlen(string); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) unsigned int i; unsigned int offset; unsigned int op; unsigned int character; +<<<<<<< HEAD assert(strlen(string) < sizeof(buf)); strncpy(buf, string, sizeof(buf)); charset_len = strlen(charset); +======= + assert(str_len < sizeof(buf)); + + memset(buf, 0, sizeof(buf)); + memcpy(buf, string, str_len); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) for (i = 0; i < operations; i++) { offset = prng_rand(prng) % strlen(buf); diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c index 627ccfee6fa3..ecc1c000a333 100644 --- a/tests/isisd/test_fuzz_isis_tlv.c +++ b/tests/isisd/test_fuzz_isis_tlv.c @@ -22,7 +22,11 @@ static bool atexit_registered; static void show_meminfo_at_exit(void) { +<<<<<<< HEAD log_memstats(stderr, "isis fuzztest"); +======= + log_memstats(NULL, true); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static int comp_line(const void *p1, const void *p2) @@ -43,7 +47,11 @@ static char *sortlines(char *in) } if (line_count == 1) { +<<<<<<< HEAD strncpy(rv, in, rv_len); +======= + memcpy(rv, in, rv_len); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return rv; } diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c index e5a8f7a51392..4bb4c29329b4 100644 --- a/tests/isisd/test_isis_spf.c +++ b/tests/isisd/test_isis_spf.c @@ -475,7 +475,11 @@ static void vty_do_exit(int isexit) yang_terminate(); event_master_free(master); +<<<<<<< HEAD log_memstats(stderr, "test-isis-spf"); +======= + log_memstats(NULL, true); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!isexit) exit(0); } diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c index 342a91cc79a7..075eef5499bb 100644 --- a/tests/lib/cli/common_cli.c +++ b/tests/lib/cli/common_cli.c @@ -43,7 +43,11 @@ static void vty_do_exit(int isexit) yang_terminate(); event_master_free(master); +<<<<<<< HEAD log_memstats(stderr, "testcli"); +======= + log_memstats(NULL, true); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!isexit) exit(0); } diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c index fdc9e53ca3ea..7b9f3483080a 100644 --- a/tests/lib/northbound/test_oper_data.c +++ b/tests/lib/northbound/test_oper_data.c @@ -427,7 +427,11 @@ static void vty_do_exit(int isexit) yang_terminate(); event_master_free(master); +<<<<<<< HEAD log_memstats(stderr, "test-nb-oper-data"); +======= + log_memstats(NULL, true); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!isexit) exit(0); } diff --git a/tests/lib/test_frrlua.c b/tests/lib/test_frrlua.c index 4aa8c8a8c396..99bba3ad0333 100644 --- a/tests/lib/test_frrlua.c +++ b/tests/lib/test_frrlua.c @@ -90,7 +90,11 @@ static void test_encode_decode(void) lua_pushin6addr(L, &in6addr_a); lua_decode_in6addr(L, -1, &in6addr_a); +<<<<<<< HEAD assert(in6addr_cmp(&in6addr_a, &in6addr_b) == 0); +======= + assert(memcmp(&in6addr_a, &in6addr_b, sizeof(struct in6_addr)) == 0); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert(lua_gettop(L) == 0); union sockunion su_a, su_b; diff --git a/tests/lib/test_frrscript.c b/tests/lib/test_frrscript.c index 9698aeaa6cb1..b9140c3c4087 100644 --- a/tests/lib/test_frrscript.c +++ b/tests/lib/test_frrscript.c @@ -49,15 +49,26 @@ int main(int argc, char **argv) long long *ansptr = frrscript_get_result(fs, "fact", "ans", lua_tolonglongp); assert(*ansptr == 120); +<<<<<<< HEAD +======= + XFREE(MTYPE_SCRIPT_RES, ansptr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* check consecutive call + get_result without re-loading */ n = 4; result = frrscript_call(fs, "fact", ("n", &n)); assert(result == 0); +<<<<<<< HEAD ansptr = frrscript_get_result(fs, "fact", "ans", lua_tointegerp); assert(*ansptr == 24); XFREE(MTYPE_SCRIPT_RES, ansptr); +======= + int *ansptr_c = frrscript_get_result(fs, "fact", "ans", lua_tointegerp); + + assert(*ansptr_c == 24); + XFREE(MTYPE_SCRIPT_RES, ansptr_c); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Negative testing */ @@ -70,9 +81,15 @@ int main(int argc, char **argv) assert(result == 1); /* Get result from a function that was not loaded */ +<<<<<<< HEAD long long *llptr = frrscript_get_result(fs, "does_not_exist", "c", lua_tointegerp); assert(llptr == NULL); +======= + int *intptr = frrscript_get_result(fs, "does_not_exist", "c", lua_tointegerp); + + assert(intptr == NULL); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Function returns void */ result = frrscript_call(fs, "bad_return1"); @@ -85,9 +102,15 @@ int main(int argc, char **argv) /* Get non-existent result from a function */ result = frrscript_call(fs, "bad_return3"); assert(result == 1); +<<<<<<< HEAD long long *cllptr = frrscript_get_result(fs, "bad_return3", "c", lua_tointegerp); assert(cllptr == NULL); +======= + intptr = frrscript_get_result(fs, "bad_return3", "c", lua_tointegerp); + assert(intptr == NULL); + XFREE(MTYPE_SCRIPT_RES, intptr); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Function throws exception */ result = frrscript_call(fs, "bad_return4"); diff --git a/tests/lib/test_typelist.c b/tests/lib/test_typelist.c index 070a30433573..cb9d8dc97dc3 100644 --- a/tests/lib/test_typelist.c +++ b/tests/lib/test_typelist.c @@ -156,6 +156,10 @@ int main(int argc, char **argv) test_ATOMSORT_UNIQ(); test_ATOMSORT_NONUNIQ(); +<<<<<<< HEAD log_memstats_stderr("test: "); +======= + log_memstats(NULL, true); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } diff --git a/tests/lib/test_zmq.c b/tests/lib/test_zmq.c index 2cd9d47cb4d4..94777377ca69 100644 --- a/tests/lib/test_zmq.c +++ b/tests/lib/test_zmq.c @@ -285,7 +285,11 @@ static void run_server(int syncfd) zmq_close(zmqsock); frrzmq_finish(); event_master_free(master); +<<<<<<< HEAD log_memstats_stderr("test"); +======= + log_memstats(NULL, true); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } int main(void) diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile index 1503e67d31dc..11f04e86415f 100644 --- a/tests/topotests/Dockerfile +++ b/tests/topotests/Dockerfile @@ -1,3 +1,4 @@ +<<<<<<< HEAD FROM ubuntu:18.04 RUN export DEBIAN_FRONTEND=noninteractive \ @@ -55,6 +56,103 @@ RUN export DEBIAN_FRONTEND=noninteractive \ && apt-get update \ && apt-get install -y libyang-dev \ && rm -rf /var/lib/apt/lists/* +======= +FROM ubuntu:22.04 + +ARG DEBIAN_FRONTEND=noninteractive +ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn + +RUN apt update -y && apt upgrade -y && \ + # Basic build requirements from documentation + apt-get install -y \ + autoconf \ + automake \ + bison \ + build-essential \ + flex \ + git \ + install-info \ + libc-ares-dev \ + libcap-dev \ + libelf-dev \ + libjson-c-dev \ + libpam0g-dev \ + libreadline-dev \ + libsnmp-dev \ + libsqlite3-dev \ + lsb-release \ + libtool \ + lcov \ + make \ + perl \ + pkg-config \ + python3-dev \ + python3-sphinx \ + screen \ + texinfo \ + tmux \ + && \ + # Protobuf build requirements + apt-get install -y \ + libprotobuf-c-dev \ + protobuf-c-compiler \ + && \ + # Libyang2 extra build requirements + apt-get install -y \ + cmake \ + libpcre2-dev \ + && \ + # GRPC extra build requirements + apt-get install -y \ + libgrpc-dev \ + libgrpc++-dev \ + protobuf-compiler-grpc \ + && \ + # Runtime/triage/testing requirements + apt-get install -y \ + rsync \ + curl \ + gdb \ + kmod \ + iproute2 \ + iputils-ping \ + liblua5.3-dev \ + libssl-dev \ + lua5.3 \ + net-tools \ + python3 \ + python3-pip \ + snmp \ + snmp-mibs-downloader \ + snmpd \ + sudo \ + time \ + tshark \ + valgrind \ + yodl \ + strace \ + tcpdump \ + && \ + download-mibs && \ + wget https://raw.githubusercontent.com/FRRouting/frr-mibs/main/iana/IANA-IPPM-METRICS-REGISTRY-MIB -O /usr/share/snmp/mibs/iana/IANA-IPPM-METRICS-REGISTRY-MIB && \ + wget https://raw.githubusercontent.com/FRRouting/frr-mibs/main/ietf/SNMPv2-PDU -O /usr/share/snmp/mibs/ietf/SNMPv2-PDU && \ + wget https://raw.githubusercontent.com/FRRouting/frr-mibs/main/ietf/IPATM-IPMC-MIB -O /usr/share/snmp/mibs/ietf/IPATM-IPMC-MIB && \ + python3 -m pip install wheel && \ + python3 -m pip install 'protobuf<4' grpcio grpcio-tools && \ + python3 -m pip install 'pytest>=6.2.4' 'pytest-xdist>=2.3.0' && \ + python3 -m pip install 'scapy>=2.4.5' && \ + python3 -m pip install xmltodict && \ + python3 -m pip install git+https://github.com/Exa-Networks/exabgp@0659057837cd6c6351579e9f0fa47e9fb7de7311 + +# Install FRR built packages +RUN mkdir -p /etc/apt/keyrings && \ + curl -s -o /etc/apt/keyrings/frrouting.gpg https://deb.frrouting.org/frr/keys.gpg && \ + echo deb '[signed-by=/etc/apt/keyrings/frrouting.gpg]' https://deb.frrouting.org/frr \ + $(lsb_release -s -c) "frr-stable" > /etc/apt/sources.list.d/frr.list && \ + apt-get update && apt-get install -y librtr-dev libyang2-dev libyang2-tools + +RUN apt install -y openvswitch-switch +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) RUN groupadd -r -g 92 frr \ && groupadd -r -g 85 frrvty \ diff --git a/tests/topotests/all_protocol_startup/r1/show_route_map.ref b/tests/topotests/all_protocol_startup/r1/show_route_map.ref index 612d0a729dfb..78d834d24159 100644 --- a/tests/topotests/all_protocol_startup/r1/show_route_map.ref +++ b/tests/topotests/all_protocol_startup/r1/show_route_map.ref @@ -1,6 +1,11 @@ ZEBRA: +<<<<<<< HEAD route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false deny, sequence 10 Invoked 0 +======= +route-map: LIES Invoked: 0 (X milliseconds total) Optimization: enabled Processed Change: false + deny, sequence 10 Invoked 0 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: interface notpresent Set clauses: @@ -8,8 +13,13 @@ route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false Action: Exit routemap RIP: +<<<<<<< HEAD route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false deny, sequence 10 Invoked 0 +======= +route-map: LIES Invoked: 0 (X milliseconds total) Optimization: enabled Processed Change: false + deny, sequence 10 Invoked 0 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: interface notpresent Set clauses: @@ -17,8 +27,13 @@ route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false Action: Exit routemap RIPNG: +<<<<<<< HEAD route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false deny, sequence 10 Invoked 0 +======= +route-map: LIES Invoked: 0 (X milliseconds total) Optimization: enabled Processed Change: false + deny, sequence 10 Invoked 0 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: interface notpresent Set clauses: @@ -26,8 +41,13 @@ route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false Action: Exit routemap OSPF: +<<<<<<< HEAD route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false deny, sequence 10 Invoked 0 +======= +route-map: LIES Invoked: 0 (X milliseconds total) Optimization: enabled Processed Change: false + deny, sequence 10 Invoked 0 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: interface notpresent Set clauses: @@ -35,8 +55,13 @@ route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false Action: Exit routemap OSPF6: +<<<<<<< HEAD route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false deny, sequence 10 Invoked 0 +======= +route-map: LIES Invoked: 0 (X milliseconds total) Optimization: enabled Processed Change: false + deny, sequence 10 Invoked 0 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: interface notpresent Set clauses: @@ -44,16 +69,26 @@ route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false Action: Exit routemap BGP: +<<<<<<< HEAD route-map: LIES Invoked: 0 Optimization: enabled Processed Change: false deny, sequence 10 Invoked 0 +======= +route-map: LIES Invoked: 0 (X milliseconds total) Optimization: enabled Processed Change: false + deny, sequence 10 Invoked 0 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: interface notpresent Set clauses: Call clause: Action: Exit routemap +<<<<<<< HEAD route-map: bgp-map Invoked: 0 Optimization: enabled Processed Change: false permit, sequence 10 Invoked 0 +======= +route-map: bgp-map Invoked: 0 (X milliseconds total) Optimization: enabled Processed Change: false + permit, sequence 10 Invoked 0 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: Set clauses: community 100:100 additive @@ -61,7 +96,11 @@ route-map: bgp-map Invoked: 0 Optimization: enabled Processed Change: false Call clause: Action: Exit routemap +<<<<<<< HEAD permit, sequence 20 Invoked 0 +======= + permit, sequence 20 Invoked 0 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: Set clauses: metric 10 diff --git a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py index 80bd2505a73d..5d24e55f50f3 100644 --- a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py +++ b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py @@ -20,6 +20,10 @@ import pytest import glob from time import sleep +<<<<<<< HEAD +======= +from lib.topolog import logger +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pytestmark = [ pytest.mark.babeld, @@ -37,6 +41,10 @@ from lib.common_config import ( required_linux_kernel_version, ) +<<<<<<< HEAD +======= +from lib.topolog import logger +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) import json import functools @@ -1422,6 +1430,10 @@ def test_route_map(): .cmd('vtysh -c "show route-map" 2> /dev/null') .rstrip() ) +<<<<<<< HEAD +======= + actual = re.sub(r"\([0-9].* milli", "(X milli", actual) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) diff = topotest.get_textdiff( @@ -1713,6 +1725,80 @@ def _show_func(): net["r1"].cmd('vtysh -c "conf" -c "no nexthop-group resilience"') +<<<<<<< HEAD +======= +def test_interface_stuff(): + global fatal_error + net = get_topogen().net + + # Skip if previous fatal error condition is raised + if fatal_error != "": + pytest.skip(fatal_error) + + print("\n\n** Verifying some interface code") + print("************************************\n") + + net["r1"].cmd('vtysh -c "conf" -c "interface r1-eth0" -c "multicast enable"') + + def _test_interface_multicast_on(): + output = json.loads(net["r1"].cmd('vtysh -c "show int r1-eth0 json"')) + expected = { + "r1-eth0": { + "flags": "", + "multicastConfig": "Enabled by CLI", + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_test_interface_multicast_on) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Multicast bit was not set on r1-eth0" + + net["r1"].cmd('vtysh -c "conf" -c "interface r1-eth0" -c "multicast disable"') + + def _test_interface_multicast_off(): + output = json.loads( + net["r1"].cmd('vtysh -c "show int r1-eth0 vrf default json"') + ) + expected = { + "r1-eth0": { + "flags": "", + "multicastConfig": "Disabled by CLI", + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_test_interface_multicast_off) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Multicast bit was not turned off on r1-eth0" + + net["r1"].cmd('vtysh -c "conf" -c "interface r1-eth0" -c "no multicast disable"') + + def _test_interface_multicast_disable(): + output = json.loads(net["r1"].cmd('vtysh -c "show int r1-eth0 json"')) + expected = { + "r1-eth0": { + "flags": "", + "multicastConfig": "Not specified by CLI", + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_test_interface_multicast_disable) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Multicast bit was set on r1-eth0" + + logger.info("Ensure that these commands are still nominally working") + rc, o, e = net["r1"].cmd_status('vtysh -c "show interface description vrf all"') + logger.info(o) + assert rc == 0 + + rc, o, e = net["r1"].cmd_status('vtysh -c "show interface description vrf default"') + logger.info(o) + assert rc == 0 + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_shutdown_check_stderr(): global fatal_error net = get_topogen().net diff --git a/tests/topotests/bfd_isis_topo1/rt1/step1/show_ipv6_route.ref b/tests/topotests/bfd_isis_topo1/rt1/step1/show_ipv6_route.ref index 68d3fe2c44e0..ca0fc76d6033 100644 --- a/tests/topotests/bfd_isis_topo1/rt1/step1/show_ipv6_route.ref +++ b/tests/topotests/bfd_isis_topo1/rt1/step1/show_ipv6_route.ref @@ -1,7 +1,13 @@ { +<<<<<<< HEAD "::ffff:202:202\/128":[ { "prefix":"::ffff:202:202\/128", +======= + "::ffff:2.2.2.2\/128":[ + { + "prefix":"::ffff:2.2.2.2\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -16,9 +22,15 @@ ] } ], +<<<<<<< HEAD "::ffff:303:303\/128":[ { "prefix":"::ffff:303:303\/128", +======= + "::ffff:3.3.3.3\/128":[ + { + "prefix":"::ffff:3.3.3.3\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -33,9 +45,15 @@ ] } ], +<<<<<<< HEAD "::ffff:404:404\/128":[ { "prefix":"::ffff:404:404\/128", +======= + "::ffff:4.4.4.4\/128":[ + { + "prefix":"::ffff:4.4.4.4\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -50,9 +68,15 @@ ] } ], +<<<<<<< HEAD "::ffff:505:505\/128":[ { "prefix":"::ffff:505:505\/128", +======= + "::ffff:5.5.5.5\/128":[ + { + "prefix":"::ffff:5.5.5.5\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, diff --git a/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_healthy.ref b/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_healthy.ref index 68d3fe2c44e0..ca0fc76d6033 100644 --- a/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_healthy.ref +++ b/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_healthy.ref @@ -1,7 +1,13 @@ { +<<<<<<< HEAD "::ffff:202:202\/128":[ { "prefix":"::ffff:202:202\/128", +======= + "::ffff:2.2.2.2\/128":[ + { + "prefix":"::ffff:2.2.2.2\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -16,9 +22,15 @@ ] } ], +<<<<<<< HEAD "::ffff:303:303\/128":[ { "prefix":"::ffff:303:303\/128", +======= + "::ffff:3.3.3.3\/128":[ + { + "prefix":"::ffff:3.3.3.3\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -33,9 +45,15 @@ ] } ], +<<<<<<< HEAD "::ffff:404:404\/128":[ { "prefix":"::ffff:404:404\/128", +======= + "::ffff:4.4.4.4\/128":[ + { + "prefix":"::ffff:4.4.4.4\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -50,9 +68,15 @@ ] } ], +<<<<<<< HEAD "::ffff:505:505\/128":[ { "prefix":"::ffff:505:505\/128", +======= + "::ffff:5.5.5.5\/128":[ + { + "prefix":"::ffff:5.5.5.5\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, diff --git a/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_rt2_down.ref b/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_rt2_down.ref index 200053c3e830..e857ebd24c4c 100644 --- a/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_rt2_down.ref +++ b/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_rt2_down.ref @@ -1,7 +1,13 @@ { +<<<<<<< HEAD "::ffff:202:202\/128":[ { "prefix":"::ffff:202:202\/128", +======= + "::ffff:2.2.2.2\/128":[ + { + "prefix":"::ffff:2.2.2.2\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -16,9 +22,15 @@ ] } ], +<<<<<<< HEAD "::ffff:303:303\/128":[ { "prefix":"::ffff:303:303\/128", +======= + "::ffff:3.3.3.3\/128":[ + { + "prefix":"::ffff:3.3.3.3\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -33,9 +45,15 @@ ] } ], +<<<<<<< HEAD "::ffff:404:404\/128":[ { "prefix":"::ffff:404:404\/128", +======= + "::ffff:4.4.4.4\/128":[ + { + "prefix":"::ffff:4.4.4.4\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -50,9 +68,15 @@ ] } ], +<<<<<<< HEAD "::ffff:505:505\/128":[ { "prefix":"::ffff:505:505\/128", +======= + "::ffff:5.5.5.5\/128":[ + { + "prefix":"::ffff:5.5.5.5\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, diff --git a/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_rt3_down.ref b/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_rt3_down.ref index 4297f163b568..9074a55ae5e8 100644 --- a/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_rt3_down.ref +++ b/tests/topotests/bfd_isis_topo1/rt1/step3/show_ipv6_route_rt3_down.ref @@ -1,7 +1,13 @@ { +<<<<<<< HEAD "::ffff:202:202\/128":[ { "prefix":"::ffff:202:202\/128", +======= + "::ffff:2.2.2.2\/128":[ + { + "prefix":"::ffff:2.2.2.2\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -16,9 +22,15 @@ ] } ], +<<<<<<< HEAD "::ffff:303:303\/128":[ { "prefix":"::ffff:303:303\/128", +======= + "::ffff:3.3.3.3\/128":[ + { + "prefix":"::ffff:3.3.3.3\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -33,9 +45,15 @@ ] } ], +<<<<<<< HEAD "::ffff:404:404\/128":[ { "prefix":"::ffff:404:404\/128", +======= + "::ffff:4.4.4.4\/128":[ + { + "prefix":"::ffff:4.4.4.4\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, @@ -50,9 +68,15 @@ ] } ], +<<<<<<< HEAD "::ffff:505:505\/128":[ { "prefix":"::ffff:505:505\/128", +======= + "::ffff:5.5.5.5\/128":[ + { + "prefix":"::ffff:5.5.5.5\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"isis", "selected":true, "destSelected":true, diff --git a/tests/topotests/bfd_isis_topo1/rt1/zebra.conf b/tests/topotests/bfd_isis_topo1/rt1/zebra.conf index 7e6f7881b4d5..8ba4587ac5e7 100644 --- a/tests/topotests/bfd_isis_topo1/rt1/zebra.conf +++ b/tests/topotests/bfd_isis_topo1/rt1/zebra.conf @@ -10,7 +10,11 @@ hostname rt1 ! interface lo ip address 1.1.1.1/32 +<<<<<<< HEAD ipv6 address ::ffff:0101:0101/128 +======= + ipv6 address ::ffff:1.1.1.1/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt2 ip address 10.0.1.1/24 diff --git a/tests/topotests/bfd_isis_topo1/rt2/zebra.conf b/tests/topotests/bfd_isis_topo1/rt2/zebra.conf index 5788e31f123a..08c861b53a99 100644 --- a/tests/topotests/bfd_isis_topo1/rt2/zebra.conf +++ b/tests/topotests/bfd_isis_topo1/rt2/zebra.conf @@ -7,7 +7,11 @@ hostname rt2 ! interface lo ip address 2.2.2.2/32 +<<<<<<< HEAD ipv6 address ::ffff:0202:0202/128 +======= + ipv6 address ::ffff:2.2.2.2/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt1 ip address 10.0.1.2/24 diff --git a/tests/topotests/bfd_isis_topo1/rt3/zebra.conf b/tests/topotests/bfd_isis_topo1/rt3/zebra.conf index 78eac2e15a60..1b6498b059bd 100644 --- a/tests/topotests/bfd_isis_topo1/rt3/zebra.conf +++ b/tests/topotests/bfd_isis_topo1/rt3/zebra.conf @@ -7,7 +7,11 @@ hostname rt3 ! interface lo ip address 3.3.3.3/32 +<<<<<<< HEAD ipv6 address ::ffff:0303:0303/128 +======= + ipv6 address ::ffff:3.3.3.3/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt1 ip address 10.0.2.2/24 diff --git a/tests/topotests/bfd_isis_topo1/rt4/zebra.conf b/tests/topotests/bfd_isis_topo1/rt4/zebra.conf index a6cb573ed878..7d5bdbac519e 100644 --- a/tests/topotests/bfd_isis_topo1/rt4/zebra.conf +++ b/tests/topotests/bfd_isis_topo1/rt4/zebra.conf @@ -7,7 +7,11 @@ hostname rt4 ! interface lo ip address 4.4.4.4/32 +<<<<<<< HEAD ipv6 address ::ffff:0404:0404/128 +======= + ipv6 address ::ffff:4.4.4.4/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt3 ip address 10.0.4.2/24 diff --git a/tests/topotests/bfd_isis_topo1/rt5/zebra.conf b/tests/topotests/bfd_isis_topo1/rt5/zebra.conf index 33473c91a3d1..ea23970109d7 100644 --- a/tests/topotests/bfd_isis_topo1/rt5/zebra.conf +++ b/tests/topotests/bfd_isis_topo1/rt5/zebra.conf @@ -7,7 +7,11 @@ hostname rt5 ! interface lo ip address 5.5.5.5/32 +<<<<<<< HEAD ipv6 address ::ffff:0505:0505/128 +======= + ipv6 address ::ffff:5.5.5.5/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt2 ip address 10.0.3.2/24 diff --git a/tests/topotests/bfd_ospf_topo1/rt1/step1/show_ipv6_route.ref b/tests/topotests/bfd_ospf_topo1/rt1/step1/show_ipv6_route.ref index 6465efb8b532..60e24166aa13 100644 --- a/tests/topotests/bfd_ospf_topo1/rt1/step1/show_ipv6_route.ref +++ b/tests/topotests/bfd_ospf_topo1/rt1/step1/show_ipv6_route.ref @@ -1,7 +1,13 @@ { +<<<<<<< HEAD "::ffff:202:202\/128":[ { "prefix":"::ffff:202:202\/128", +======= + "::ffff:2.2.2.2\/128":[ + { + "prefix":"::ffff:2.2.2.2\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -16,9 +22,15 @@ ] } ], +<<<<<<< HEAD "::ffff:303:303\/128":[ { "prefix":"::ffff:303:303\/128", +======= + "::ffff:3.3.3.3\/128":[ + { + "prefix":"::ffff:3.3.3.3\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -33,9 +45,15 @@ ] } ], +<<<<<<< HEAD "::ffff:404:404\/128":[ { "prefix":"::ffff:404:404\/128", +======= + "::ffff:4.4.4.4\/128":[ + { + "prefix":"::ffff:4.4.4.4\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -50,9 +68,15 @@ ] } ], +<<<<<<< HEAD "::ffff:505:505\/128":[ { "prefix":"::ffff:505:505\/128", +======= + "::ffff:5.5.5.5\/128":[ + { + "prefix":"::ffff:5.5.5.5\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, diff --git a/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_healthy.ref b/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_healthy.ref index 6465efb8b532..60e24166aa13 100644 --- a/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_healthy.ref +++ b/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_healthy.ref @@ -1,7 +1,13 @@ { +<<<<<<< HEAD "::ffff:202:202\/128":[ { "prefix":"::ffff:202:202\/128", +======= + "::ffff:2.2.2.2\/128":[ + { + "prefix":"::ffff:2.2.2.2\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -16,9 +22,15 @@ ] } ], +<<<<<<< HEAD "::ffff:303:303\/128":[ { "prefix":"::ffff:303:303\/128", +======= + "::ffff:3.3.3.3\/128":[ + { + "prefix":"::ffff:3.3.3.3\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -33,9 +45,15 @@ ] } ], +<<<<<<< HEAD "::ffff:404:404\/128":[ { "prefix":"::ffff:404:404\/128", +======= + "::ffff:4.4.4.4\/128":[ + { + "prefix":"::ffff:4.4.4.4\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -50,9 +68,15 @@ ] } ], +<<<<<<< HEAD "::ffff:505:505\/128":[ { "prefix":"::ffff:505:505\/128", +======= + "::ffff:5.5.5.5\/128":[ + { + "prefix":"::ffff:5.5.5.5\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, diff --git a/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_rt2_down.ref b/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_rt2_down.ref index cfb1ef1bb6c1..c7694faa3b89 100644 --- a/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_rt2_down.ref +++ b/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_rt2_down.ref @@ -1,7 +1,13 @@ { +<<<<<<< HEAD "::ffff:202:202\/128":[ { "prefix":"::ffff:202:202\/128", +======= + "::ffff:2.2.2.2\/128":[ + { + "prefix":"::ffff:2.2.2.2\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -16,9 +22,15 @@ ] } ], +<<<<<<< HEAD "::ffff:303:303\/128":[ { "prefix":"::ffff:303:303\/128", +======= + "::ffff:3.3.3.3\/128":[ + { + "prefix":"::ffff:3.3.3.3\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -33,9 +45,15 @@ ] } ], +<<<<<<< HEAD "::ffff:404:404\/128":[ { "prefix":"::ffff:404:404\/128", +======= + "::ffff:4.4.4.4\/128":[ + { + "prefix":"::ffff:4.4.4.4\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -50,9 +68,15 @@ ] } ], +<<<<<<< HEAD "::ffff:505:505\/128":[ { "prefix":"::ffff:505:505\/128", +======= + "::ffff:5.5.5.5\/128":[ + { + "prefix":"::ffff:5.5.5.5\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, diff --git a/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_rt3_down.ref b/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_rt3_down.ref index 58b44da5c21b..e576f0e86a92 100644 --- a/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_rt3_down.ref +++ b/tests/topotests/bfd_ospf_topo1/rt1/step3/show_ipv6_route_rt3_down.ref @@ -1,7 +1,13 @@ { +<<<<<<< HEAD "::ffff:202:202\/128":[ { "prefix":"::ffff:202:202\/128", +======= + "::ffff:2.2.2.2\/128":[ + { + "prefix":"::ffff:2.2.2.2\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -16,9 +22,15 @@ ] } ], +<<<<<<< HEAD "::ffff:303:303\/128":[ { "prefix":"::ffff:303:303\/128", +======= + "::ffff:3.3.3.3\/128":[ + { + "prefix":"::ffff:3.3.3.3\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -33,9 +45,15 @@ ] } ], +<<<<<<< HEAD "::ffff:404:404\/128":[ { "prefix":"::ffff:404:404\/128", +======= + "::ffff:4.4.4.4\/128":[ + { + "prefix":"::ffff:4.4.4.4\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, @@ -50,9 +68,15 @@ ] } ], +<<<<<<< HEAD "::ffff:505:505\/128":[ { "prefix":"::ffff:505:505\/128", +======= + "::ffff:5.5.5.5\/128":[ + { + "prefix":"::ffff:5.5.5.5\/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "protocol":"ospf6", "selected":true, "destSelected":true, diff --git a/tests/topotests/bfd_ospf_topo1/rt1/zebra.conf b/tests/topotests/bfd_ospf_topo1/rt1/zebra.conf index 7e6f7881b4d5..8ba4587ac5e7 100644 --- a/tests/topotests/bfd_ospf_topo1/rt1/zebra.conf +++ b/tests/topotests/bfd_ospf_topo1/rt1/zebra.conf @@ -10,7 +10,11 @@ hostname rt1 ! interface lo ip address 1.1.1.1/32 +<<<<<<< HEAD ipv6 address ::ffff:0101:0101/128 +======= + ipv6 address ::ffff:1.1.1.1/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt2 ip address 10.0.1.1/24 diff --git a/tests/topotests/bfd_ospf_topo1/rt2/zebra.conf b/tests/topotests/bfd_ospf_topo1/rt2/zebra.conf index 5788e31f123a..08c861b53a99 100644 --- a/tests/topotests/bfd_ospf_topo1/rt2/zebra.conf +++ b/tests/topotests/bfd_ospf_topo1/rt2/zebra.conf @@ -7,7 +7,11 @@ hostname rt2 ! interface lo ip address 2.2.2.2/32 +<<<<<<< HEAD ipv6 address ::ffff:0202:0202/128 +======= + ipv6 address ::ffff:2.2.2.2/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt1 ip address 10.0.1.2/24 diff --git a/tests/topotests/bfd_ospf_topo1/rt3/zebra.conf b/tests/topotests/bfd_ospf_topo1/rt3/zebra.conf index 78eac2e15a60..1b6498b059bd 100644 --- a/tests/topotests/bfd_ospf_topo1/rt3/zebra.conf +++ b/tests/topotests/bfd_ospf_topo1/rt3/zebra.conf @@ -7,7 +7,11 @@ hostname rt3 ! interface lo ip address 3.3.3.3/32 +<<<<<<< HEAD ipv6 address ::ffff:0303:0303/128 +======= + ipv6 address ::ffff:3.3.3.3/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt1 ip address 10.0.2.2/24 diff --git a/tests/topotests/bfd_ospf_topo1/rt4/zebra.conf b/tests/topotests/bfd_ospf_topo1/rt4/zebra.conf index a6cb573ed878..7d5bdbac519e 100644 --- a/tests/topotests/bfd_ospf_topo1/rt4/zebra.conf +++ b/tests/topotests/bfd_ospf_topo1/rt4/zebra.conf @@ -7,7 +7,11 @@ hostname rt4 ! interface lo ip address 4.4.4.4/32 +<<<<<<< HEAD ipv6 address ::ffff:0404:0404/128 +======= + ipv6 address ::ffff:4.4.4.4/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt3 ip address 10.0.4.2/24 diff --git a/tests/topotests/bfd_ospf_topo1/rt5/zebra.conf b/tests/topotests/bfd_ospf_topo1/rt5/zebra.conf index 33473c91a3d1..ea23970109d7 100644 --- a/tests/topotests/bfd_ospf_topo1/rt5/zebra.conf +++ b/tests/topotests/bfd_ospf_topo1/rt5/zebra.conf @@ -7,7 +7,11 @@ hostname rt5 ! interface lo ip address 5.5.5.5/32 +<<<<<<< HEAD ipv6 address ::ffff:0505:0505/128 +======= + ipv6 address ::ffff:5.5.5.5/128 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface eth-rt2 ip address 10.0.3.2/24 diff --git a/tests/topotests/bfd_profiles_topo1/r2/bgpd.conf b/tests/topotests/bfd_profiles_topo1/r2/bgpd.conf index 1aab1d1372e8..a31c56b51588 100644 --- a/tests/topotests/bfd_profiles_topo1/r2/bgpd.conf +++ b/tests/topotests/bfd_profiles_topo1/r2/bgpd.conf @@ -5,9 +5,17 @@ router bgp 100 no bgp ebgp-requires-policy neighbor 172.16.1.1 remote-as 100 neighbor 172.16.1.1 timers 3 10 +<<<<<<< HEAD neighbor 172.16.1.1 bfd profile fasttx neighbor 2001:db8:2::2 remote-as 200 neighbor 2001:db8:2::2 timers 3 10 +======= + neighbor 172.16.1.1 timers connect 1 + neighbor 172.16.1.1 bfd profile fasttx + neighbor 2001:db8:2::2 remote-as 200 + neighbor 2001:db8:2::2 timers 3 10 + neighbor 2001:db8:2::2 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) neighbor 2001:db8:2::2 ebgp-multihop 2 neighbor 2001:db8:2::2 bfd profile slowtx address-family ipv4 unicast diff --git a/tests/topotests/bfd_profiles_topo1/r3/bgpd.conf b/tests/topotests/bfd_profiles_topo1/r3/bgpd.conf index 65647b39e51d..af7d1e01e319 100644 --- a/tests/topotests/bfd_profiles_topo1/r3/bgpd.conf +++ b/tests/topotests/bfd_profiles_topo1/r3/bgpd.conf @@ -2,6 +2,10 @@ router bgp 100 bgp router-id 10.254.254.3 neighbor 172.16.1.2 remote-as 100 neighbor 172.16.1.2 timers 3 10 +<<<<<<< HEAD +======= + neighbor 172.16.1.2 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) neighbor 172.16.1.2 bfd profile DOES_NOT_EXIST address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bfd_profiles_topo1/r4/bgpd.conf b/tests/topotests/bfd_profiles_topo1/r4/bgpd.conf index 12d68270f8af..9d0b790b4998 100644 --- a/tests/topotests/bfd_profiles_topo1/r4/bgpd.conf +++ b/tests/topotests/bfd_profiles_topo1/r4/bgpd.conf @@ -5,6 +5,10 @@ router bgp 200 no bgp ebgp-requires-policy neighbor 2001:db8:1::2 remote-as 100 neighbor 2001:db8:1::2 timers 3 10 +<<<<<<< HEAD +======= + neighbor 2001:db8:1::2 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) neighbor 2001:db8:1::2 ebgp-multihop 2 neighbor 2001:db8:1::2 bfd profile DOES_NOT_EXIST address-family ipv4 unicast diff --git a/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf b/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf index c7cf4a527f9e..1267e6d1074c 100644 --- a/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf +++ b/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf @@ -19,8 +19,15 @@ router bgp 65000 no bgp ebgp-requires-policy neighbor 10.0.0.2 remote-as 65001 neighbor 10.0.0.2 timers 3 10 +<<<<<<< HEAD neighbor 10.0.1.2 remote-as internal neighbor 10.0.1.2 timers 3 10 +======= + neighbor 10.0.0.2 timers connect 1 + neighbor 10.0.1.2 remote-as internal + neighbor 10.0.1.2 timers 3 10 + neighbor 10.0.1.2 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv4 unicast redistribute connected aggregate-address 192.168.0.0/24 matching-MED-only diff --git a/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf b/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf index acacd8652657..9bbb97ad8a26 100644 --- a/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf +++ b/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf @@ -1,6 +1,10 @@ router bgp 65000 neighbor 10.0.1.1 remote-as internal neighbor 10.0.1.1 timers 3 10 +<<<<<<< HEAD +======= + neighbor 10.0.1.1 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv4 unicast redistribute connected exit-address-family diff --git a/tests/topotests/bgp_aggregator_zero/r1/bgpd.conf b/tests/topotests/bgp_aggregator_zero/r1/bgpd.conf index 002a5c78c0f7..e0d47802ad77 100644 --- a/tests/topotests/bgp_aggregator_zero/r1/bgpd.conf +++ b/tests/topotests/bgp_aggregator_zero/r1/bgpd.conf @@ -3,4 +3,8 @@ router bgp 65534 no bgp ebgp-requires-policy neighbor 10.0.0.2 remote-as external neighbor 10.0.0.2 timers 3 10 +<<<<<<< HEAD +======= + neighbor 10.0.0.2 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! diff --git a/tests/topotests/bgp_aigp/r1/bgpd.conf b/tests/topotests/bgp_aigp/r1/bgpd.conf index 74a0215bc476..bb8dac4ca57a 100644 --- a/tests/topotests/bgp_aigp/r1/bgpd.conf +++ b/tests/topotests/bgp_aigp/r1/bgpd.conf @@ -9,4 +9,24 @@ router bgp 65001 neighbor 10.0.0.3 timers 1 3 neighbor 10.0.0.3 timers connect 1 neighbor 10.0.0.3 update-source lo +<<<<<<< HEAD ! +======= + neighbor 192.168.18.8 remote-as external + neighbor 192.168.18.8 timers 1 3 + neighbor 192.168.18.8 timers connect 1 + address-family ipv4 + neighbor 192.168.18.8 route-map r8 out + exit-address-family +! +ip prefix-list p71 seq 5 permit 10.0.0.71/32 +ip prefix-list p72 seq 5 permit 10.0.0.72/32 +! +route-map r8 permit 10 + match ip address prefix-list p71 + set metric igp +route-map r8 permit 20 + match ip address prefix-list p72 + set metric aigp +exit +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/bgp_aigp/r1/zebra.conf b/tests/topotests/bgp_aigp/r1/zebra.conf index 0ed22d37be8b..74ab91cadf9e 100644 --- a/tests/topotests/bgp_aigp/r1/zebra.conf +++ b/tests/topotests/bgp_aigp/r1/zebra.conf @@ -8,3 +8,9 @@ interface r1-eth0 interface r1-eth1 ip address 192.168.13.1/24 ! +<<<<<<< HEAD +======= +interface r1-eth2 + ip address 192.168.18.1/24 +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/bgp_aigp/r8/bgpd.conf b/tests/topotests/bgp_aigp/r8/bgpd.conf new file mode 100644 index 000000000000..c50c3ce91a58 --- /dev/null +++ b/tests/topotests/bgp_aigp/r8/bgpd.conf @@ -0,0 +1,4 @@ +router bgp 65008 + no bgp ebgp-requires-policy + neighbor 192.168.18.1 remote-as external +! diff --git a/tests/topotests/bgp_aigp/r8/zebra.conf b/tests/topotests/bgp_aigp/r8/zebra.conf new file mode 100644 index 000000000000..f7545270b2c7 --- /dev/null +++ b/tests/topotests/bgp_aigp/r8/zebra.conf @@ -0,0 +1,4 @@ +! +interface r8-eth0 + ip address 192.168.18.8/24 +! diff --git a/tests/topotests/bgp_aigp/test_bgp_aigp.py b/tests/topotests/bgp_aigp/test_bgp_aigp.py index 194253736bd8..4e47782cce67 100644 --- a/tests/topotests/bgp_aigp/test_bgp_aigp.py +++ b/tests/topotests/bgp_aigp/test_bgp_aigp.py @@ -15,6 +15,13 @@ and 10 appropriately. r1 receives routes with aigp-metric TLV 81, 91 and 82, 92 respectively. +<<<<<<< HEAD +======= + +r1 advertises MED from IGP protocol (set metric igp) to r8. + +r1 advertises MED from AIGP (set metric aigp) to r8. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) """ import os @@ -34,7 +41,11 @@ def build_topo(tgen): +<<<<<<< HEAD for routern in range(1, 8): +======= + for routern in range(1, 9): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tgen.add_router("r{}".format(routern)) switch = tgen.add_switch("s1") @@ -65,6 +76,13 @@ def build_topo(tgen): switch.add_link(tgen.gears["r6"]) switch.add_link(tgen.gears["r7"]) +<<<<<<< HEAD +======= + switch = tgen.add_switch("s8") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r8"]) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) @@ -102,6 +120,10 @@ def test_bgp_aigp(): r3 = tgen.gears["r3"] r4 = tgen.gears["r4"] r5 = tgen.gears["r5"] +<<<<<<< HEAD +======= + r8 = tgen.gears["r8"] +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def _bgp_converge(): output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.0.0.71/32 json")) @@ -143,6 +165,21 @@ def _bgp_check_aigp_metric(router, prefix, aigp): expected = {"paths": [{"aigpMetric": aigp, "valid": True}]} return topotest.json_cmp(output, expected) +<<<<<<< HEAD +======= + def _bgp_check_received_med(): + output = json.loads( + r8.vtysh_cmd("show bgp ipv4 unicast 10.0.0.64/28 longer-prefixes json") + ) + expected = { + "routes": { + "10.0.0.71/32": [{"valid": True, "metric": 10}], + "10.0.0.72/32": [{"valid": True, "metric": 92}], + } + } + return topotest.json_cmp(output, expected) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def _bgp_check_aigp_metric_bestpath(): output = json.loads( r1.vtysh_cmd( @@ -257,6 +294,16 @@ def _bgp_check_aigp_metric_bestpath(): _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) assert result is None, "AIGP attribute is not considered in best-path selection" +<<<<<<< HEAD +======= + # r8, check if MED is set derived from `set metric igp`, and `set metric aigp` + test_func = functools.partial(_bgp_check_received_med) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert ( + result is None + ), "MED attribute values are not derived from `set metric [a]igp`" + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_as_override/test_bgp_as_override.py b/tests/topotests/bgp_as_override/test_bgp_as_override.py index dbbdf2c88f8e..26e8d006ea82 100644 --- a/tests/topotests/bgp_as_override/test_bgp_as_override.py +++ b/tests/topotests/bgp_as_override/test_bgp_as_override.py @@ -27,7 +27,11 @@ def build_topo(tgen): +<<<<<<< HEAD for routern in range(1, 7): +======= + for routern in range(1, 5): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tgen.add_router("r{}".format(routern)) switch = tgen.add_switch("s1") diff --git a/tests/topotests/bgp_aspath_zero/r1/bgpd.conf b/tests/topotests/bgp_aspath_zero/r1/bgpd.conf index 002a5c78c0f7..e0d47802ad77 100644 --- a/tests/topotests/bgp_aspath_zero/r1/bgpd.conf +++ b/tests/topotests/bgp_aspath_zero/r1/bgpd.conf @@ -3,4 +3,8 @@ router bgp 65534 no bgp ebgp-requires-policy neighbor 10.0.0.2 remote-as external neighbor 10.0.0.2 timers 3 10 +<<<<<<< HEAD +======= + neighbor 10.0.0.2 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! diff --git a/tests/topotests/bgp_bfd_session/__init__.py b/tests/topotests/bgp_bfd_session/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_bfd_session/r1/frr.conf b/tests/topotests/bgp_bfd_session/r1/frr.conf new file mode 100644 index 000000000000..a1560b09fa89 --- /dev/null +++ b/tests/topotests/bgp_bfd_session/r1/frr.conf @@ -0,0 +1,14 @@ +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +router bgp 65000 + neighbor 192.168.1.2 remote-as auto + neighbor 192.168.1.2 bfd + neighbor 192.168.1.2 ebgp-multihop 10 + neighbor 192.168.1.2 update-source 10.0.0.1 + neighbor 192.168.1.3 remote-as auto + neighbor 192.168.1.3 bfd + neighbor 192.168.1.3 ebgp-multihop 20 + neighbor 192.168.1.3 update-source r1-eth0 +exit diff --git a/tests/topotests/bgp_bfd_session/test_bgp_bfd_session.py b/tests/topotests/bgp_bfd_session/test_bgp_bfd_session.py new file mode 100644 index 000000000000..adf557af7b1b --- /dev/null +++ b/tests/topotests/bgp_bfd_session/test_bgp_bfd_session.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024 by +# Donatas Abraitis +# + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, get_topogen, TopoRouter +from lib.common_config import step + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + r1 = tgen.add_router("r1") + + switch = tgen.add_switch("s1") + switch.add_link(r1) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + for _, (rname, router) in enumerate(tgen.routers().items(), 1): + router.load_frr_config( + os.path.join(CWD, "{}/frr.conf".format(rname)), + [ + (TopoRouter.RD_ZEBRA, None), + (TopoRouter.RD_MGMTD, None), + (TopoRouter.RD_BFD, None), + (TopoRouter.RD_BGP, None), + ], + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_bfd_session(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + def _bfd_session(): + output = json.loads(r1.vtysh_cmd("show bfd peers json")) + expected = [ + { + "multihop": True, + "peer": "192.168.1.2", + "local": "10.0.0.1", + "vrf": "default", + "minimum-ttl": 246, + "status": "down", + "diagnostic": "ok", + "remote-diagnostic": "ok", + "type": "dynamic", + }, + { + "multihop": True, + "peer": "192.168.1.3", + "local": "10.0.0.1", + "vrf": "default", + "minimum-ttl": 236, + "status": "down", + "diagnostic": "ok", + "remote-diagnostic": "ok", + "type": "dynamic", + } + ] + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bfd_session) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't see BFD session created" + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_bmp/bgpbmp.py b/tests/topotests/bgp_bmp/bgpbmp.py new file mode 100644 index 000000000000..5e8b0d9be72d --- /dev/null +++ b/tests/topotests/bgp_bmp/bgpbmp.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: GPL-2.0-or-later + +# Copyright 2023, 6wind +import json +import os + +from lib import topotest +from lib.topogen import get_topogen +from lib.topolog import logger + +# remember the last sequence number of the logging messages +SEQ = 0 + + +def bmp_reset_seq(): + global SEQ + SEQ = 0 + + +def get_bmp_messages(bmp_collector, bmp_log_file): + """ + Read the BMP logging messages. + """ + messages = [] + text_output = bmp_collector.run(f"cat {bmp_log_file}") + + for m in text_output.splitlines(): + # some output in the bash can break the message decoding + try: + messages.append(json.loads(m)) + except Exception as e: + logger.warning(str(e) + " message: {}".format(str(m))) + continue + + if not messages: + logger.error("Bad BMP log format, check your BMP server") + + return messages + + +def bmp_update_seq(bmp_collector, bmp_log_file): + global SEQ + + messages = get_bmp_messages(bmp_collector, bmp_log_file) + + if len(messages): + SEQ = messages[-1]["seq"] + + +def bmp_update_expected_files( + bmp_actual, + expected_prefixes, + bmp_log_type, + policy, + step, + bmp_client, + bmp_log_folder, +): + tgen = get_topogen() + + with open( + f"{bmp_log_folder}/tmp/bmp-{bmp_log_type}-{policy}-step{step}.json", "w" + ) as json_file: + json.dump(bmp_actual, json_file, indent=4) + + out = bmp_client.vtysh_cmd("show bgp vrf vrf1 ipv4 json", isjson=True) + filtered_out = { + "routes": { + prefix: route_info + for prefix, route_info in out["routes"].items() + if prefix in expected_prefixes + } + } + if bmp_log_type == "withdraw": + for pfx in expected_prefixes: + if "::" in pfx: + continue + filtered_out["routes"][pfx] = None + + # ls {bmp_log_folder}/tmp/show*json | while read file; do egrep -v 'prefix|network|metric|ocPrf|version|weight|peerId|vrf|Version|valid|Reason|fe80' $file >$(basename $file); echo >> $(basename $file); done + with open( + f"{bmp_log_folder}/tmp/show-bgp-ipv4-{bmp_log_type}-step{step}.json", "w" + ) as json_file: + json.dump(filtered_out, json_file, indent=4) + + out = tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv6 json", isjson=True) + filtered_out = { + "routes": { + prefix: route_info + for prefix, route_info in out["routes"].items() + if prefix in expected_prefixes + } + } + if bmp_log_type == "withdraw": + for pfx in expected_prefixes: + if "::" not in pfx: + continue + filtered_out["routes"][pfx] = None + + with open( + f"{bmp_log_folder}/tmp/show-bgp-ipv6-{bmp_log_type}-step{step}.json", "w" + ) as json_file: + json.dump(filtered_out, json_file, indent=4) + + +def bmp_check_for_prefixes( + expected_prefixes, + bmp_log_type, + policy, + step, + bmp_collector, + bmp_log_folder, + bmp_client, + expected_json_path, + update_expected_json, + loc_rib, +): + """ + Check for the presence of the given prefixes in the BMP server logs with + the given message type and the set policy. + + """ + global SEQ + + bmp_log_file = f"{bmp_log_folder}/bmp.log" + # we care only about the new messages + messages = [ + m + for m in sorted( + get_bmp_messages(bmp_collector, bmp_log_file), key=lambda d: d["seq"] + ) + if m["seq"] > SEQ + ] + + # create empty initial files + # for step in $(seq 1); do + # for i in "update" "withdraw"; do + # for j in "pre-policy" "post-policy" "loc-rib"; do + # echo '{"null": {}}'> bmp-$i-$j-step$step.json + # done + # done + # done + + ref_file = f"{expected_json_path}/bmp-{bmp_log_type}-{policy}-step{step}.json" + expected = json.loads(open(ref_file).read()) + + # Build actual json from logs + actual = {} + for m in messages: + if ( + "bmp_log_type" in m.keys() + and "ip_prefix" in m.keys() + and m["ip_prefix"] in expected_prefixes + and m["bmp_log_type"] == bmp_log_type + and m["policy"] == policy + ): + policy_dict = actual.setdefault(m["policy"], {}) + bmp_log_type_dict = policy_dict.setdefault(m["bmp_log_type"], {}) + + # Add or update the ip_prefix dictionary with filtered key-value pairs + bmp_log_type_dict[m["ip_prefix"]] = { + k: v + for k, v in sorted(m.items()) + # filter out variable keys + if k not in ["timestamp", "seq", "nxhp_link-local"] + and ( + # When policy is loc-rib, the peer-distinguisher is 0:0 + # for the default VRF or the RD if any or the 0:. + # 0: is used to distinguished. RFC7854 says: "If the + # peer is a "Local Instance Peer", it is set to a unique, + # locally defined value." The value is not tested because it + # is variable. + k != "peer_distinguisher" + or policy != loc_rib + or v == "0:0" + or not v.startswith("0:") + ) + } + + # build expected JSON files + if ( + update_expected_json + and actual + and set(actual.get(policy, {}).get(bmp_log_type, {}).keys()) + == set(expected_prefixes) + ): + bmp_update_expected_files( + actual, + expected_prefixes, + bmp_log_type, + policy, + step, + bmp_client, + bmp_log_folder, + ) + + return topotest.json_cmp(actual, expected, exact=True) + + +def bmp_check_for_peer_message( + expected_peers, bmp_log_type, bmp_collector, bmp_log_file +): + """ + Check for the presence of a peer up message for the peer + """ + global SEQ + + # we care only about the new messages + messages = [ + m + for m in sorted( + get_bmp_messages(bmp_collector, bmp_log_file), key=lambda d: d["seq"] + ) + if m["seq"] > SEQ + ] + + # get the list of pairs (prefix, policy, seq) for the given message type + peers = [] + for m in messages: + if ( + "peer_ip" in m.keys() + and m["peer_ip"] != "0.0.0.0" + and m["bmp_log_type"] == bmp_log_type + ): + peers.append(m["peer_ip"]) + elif m["policy"] == "loc-rib" and m["bmp_log_type"] == bmp_log_type: + peers.append("0.0.0.0") + + # check for prefixes + for ep in expected_peers: + if ep not in peers: + msg = "The peer {} is not present in the {} log messages." + logger.debug(msg.format(ep, bmp_log_type)) + return False + + SEQ = messages[-1]["seq"] + return True diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step1.json new file mode 100644 index 000000000000..27f1fe6e27b6 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step1.json @@ -0,0 +1,34 @@ +{ + "loc-rib": { + "update": { + "172.31.0.15/32": { + "as_path": "65501 65502", + "bgp_nexthop": "192.168.0.2", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "is_filtered": false, + "origin": "IGP", + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_distinguisher": "0:0", + "peer_type": "loc-rib instance", + "policy": "loc-rib" + }, + "2001::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2001::1111/128", + "is_filtered": false, + "nxhp_ip": "192:168::2", + "origin": "IGP", + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_distinguisher": "0:0", + "peer_type": "loc-rib instance", + "policy": "loc-rib", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step2.json new file mode 100644 index 000000000000..0aa6bd4feae2 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step2.json @@ -0,0 +1,43 @@ +{ + "loc-rib": { + "update": { + "2001::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2001::1111/128", + "is_filtered": false, + "label": 105, + "nxhp_ip": "192:168::2", + "nxhp_rd1": "0:0", + "nxhp_rd2": "0:0", + "origin": "IGP", + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_distinguisher": "0:0", + "peer_type": "loc-rib instance", + "policy": "loc-rib", + "rd": "555:2", + "safi": 128 + }, + "172.31.0.15/32": { + "afi": 1, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "is_filtered": false, + "label": 102, + "nxhp_ip": "192.168.0.2", + "nxhp_rd": "0:0", + "origin": "IGP", + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_distinguisher": "0:0", + "peer_type": "loc-rib instance", + "policy": "loc-rib", + "rd": "444:2", + "safi": 128 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step1.json new file mode 100644 index 000000000000..d30ef9fd3217 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step1.json @@ -0,0 +1,36 @@ +{ + "post-policy": { + "update": { + "172.31.0.15/32": { + "as_path": "65501 65502", + "bgp_nexthop": "192.168.0.2", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "post-policy" + }, + "2001::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2001::1111/128", + "ipv6": true, + "nxhp_ip": "192:168::2", + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "post-policy", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step2.json new file mode 100644 index 000000000000..9bf2d577693f --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step2.json @@ -0,0 +1,45 @@ +{ + "post-policy": { + "update": { + "172.31.0.15/32": { + "afi": 1, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "label": 102, + "nxhp_ip": "192.168.0.2", + "nxhp_rd": "0:0", + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "post-policy", + "rd": "444:2", + "safi": 128 + }, + "2001::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2001::1111/128", + "ipv6": true, + "label": 105, + "nxhp_ip": "192:168::2", + "nxhp_rd1": "0:0", + "nxhp_rd2": "0:0", + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "post-policy", + "rd": "555:2", + "safi": 128 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step1.json new file mode 100644 index 000000000000..fafe6f7c21e3 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step1.json @@ -0,0 +1,36 @@ +{ + "pre-policy": { + "update": { + "172.31.0.15/32": { + "as_path": "65501 65502", + "bgp_nexthop": "192.168.0.2", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "pre-policy" + }, + "2001::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2001::1111/128", + "ipv6": true, + "nxhp_ip": "192:168::2", + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "pre-policy", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step2.json new file mode 100644 index 000000000000..95acb5903a5d --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step2.json @@ -0,0 +1,45 @@ +{ + "pre-policy": { + "update": { + "172.31.0.15/32": { + "afi": 1, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "label": 102, + "nxhp_ip": "192.168.0.2", + "nxhp_rd": "0:0", + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "pre-policy", + "rd": "444:2", + "safi": 128 + }, + "2001::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2001::1111/128", + "ipv6": true, + "label": 105, + "nxhp_ip": "192:168::2", + "nxhp_rd1": "0:0", + "nxhp_rd2": "0:0", + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "pre-policy", + "rd": "555:2", + "safi": 128 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step1.json new file mode 100644 index 000000000000..3891fbb15e47 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step1.json @@ -0,0 +1,28 @@ +{ + "loc-rib": { + "withdraw": { + "172.31.0.15/32": { + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "is_filtered": false, + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_distinguisher": "0:0", + "peer_type": "loc-rib instance", + "policy": "loc-rib" + }, + "2001::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2001::1111/128", + "is_filtered": false, + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_distinguisher": "0:0", + "peer_type": "loc-rib instance", + "policy": "loc-rib", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json new file mode 100644 index 000000000000..1e5040ba60b2 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json @@ -0,0 +1,34 @@ +{ + "loc-rib": { + "withdraw": { + "172.31.0.15/32": { + "afi": 1, + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "is_filtered": false, + "label": 0, + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_distinguisher": "0:0", + "peer_type": "loc-rib instance", + "policy": "loc-rib", + "rd": "444:2", + "safi": 128 + }, + "2001::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2001::1111/128", + "is_filtered": false, + "label": 0, + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_distinguisher": "0:0", + "peer_type": "loc-rib instance", + "policy": "loc-rib", + "rd": "555:2", + "safi": 128 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step1.json new file mode 100644 index 000000000000..3224b525e217 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step1.json @@ -0,0 +1,30 @@ +{ + "post-policy": { + "withdraw": { + "172.31.0.15/32": { + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "post-policy" + }, + "2001::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2001::1111/128", + "ipv6": true, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "post-policy", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json new file mode 100644 index 000000000000..9eb221d4d0a2 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json @@ -0,0 +1,36 @@ +{ + "post-policy": { + "withdraw": { + "2001::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2001::1111/128", + "ipv6": true, + "label": 0, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "post-policy", + "rd": "555:2", + "safi": 128 + }, + "172.31.0.15/32": { + "afi": 1, + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "label": 0, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "post-policy", + "rd": "444:2", + "safi": 128 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step1.json new file mode 100644 index 000000000000..8add68c022d4 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step1.json @@ -0,0 +1,30 @@ +{ + "pre-policy": { + "withdraw": { + "172.31.0.15/32": { + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "pre-policy" + }, + "2001::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2001::1111/128", + "ipv6": true, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "pre-policy", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json new file mode 100644 index 000000000000..eea7501b2287 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json @@ -0,0 +1,36 @@ +{ + "pre-policy": { + "withdraw": { + "2001::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2001::1111/128", + "ipv6": true, + "label": 0, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "pre-policy", + "rd": "555:2", + "safi": 128 + }, + "172.31.0.15/32": { + "afi": 1, + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "label": 0, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "pre-policy", + "rd": "444:2", + "safi": 128 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-loc-rib-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-loc-rib-step1.json new file mode 100644 index 000000000000..ba31bf1d5df7 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-loc-rib-step1.json @@ -0,0 +1,32 @@ +{ + "loc-rib": { + "update": { + "172.31.0.15/32": { + "as_path": "65501 65502", + "bgp_nexthop": "192.168.0.2", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "is_filtered": false, + "origin": "IGP", + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_type": "loc-rib instance", + "policy": "loc-rib" + }, + "2111::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2111::1111/128", + "is_filtered": false, + "nxhp_ip": "192:168::2", + "origin": "IGP", + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_type": "loc-rib instance", + "policy": "loc-rib", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-post-policy-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-post-policy-step1.json new file mode 100644 index 000000000000..d5d9d6518265 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-post-policy-step1.json @@ -0,0 +1,36 @@ +{ + "post-policy": { + "update": { + "172.31.0.15/32": { + "as_path": "65501 65502", + "bgp_nexthop": "192.168.0.2", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "post-policy" + }, + "2111::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2111::1111/128", + "ipv6": true, + "nxhp_ip": "192:168::2", + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "post-policy", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-pre-policy-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-pre-policy-step1.json new file mode 100644 index 000000000000..e11badc040a9 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-pre-policy-step1.json @@ -0,0 +1,36 @@ +{ + "pre-policy": { + "update": { + "172.31.0.15/32": { + "as_path": "65501 65502", + "bgp_nexthop": "192.168.0.2", + "bmp_log_type": "update", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "pre-policy" + }, + "2111::1111/128": { + "afi": 2, + "as_path": "65501 65502", + "bmp_log_type": "update", + "ip_prefix": "2111::1111/128", + "ipv6": true, + "nxhp_ip": "192:168::2", + "origin": "IGP", + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "pre-policy", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-loc-rib-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-loc-rib-step1.json new file mode 100644 index 000000000000..37ddc09ff85b --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-loc-rib-step1.json @@ -0,0 +1,26 @@ +{ + "loc-rib": { + "withdraw": { + "172.31.0.15/32": { + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "is_filtered": false, + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_type": "loc-rib instance", + "policy": "loc-rib" + }, + "2111::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2111::1111/128", + "is_filtered": false, + "peer_asn": 65501, + "peer_bgp_id": "192.168.0.1", + "peer_type": "loc-rib instance", + "policy": "loc-rib", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-post-policy-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-post-policy-step1.json new file mode 100644 index 000000000000..de84307a4e6b --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-post-policy-step1.json @@ -0,0 +1,30 @@ +{ + "post-policy": { + "withdraw": { + "172.31.0.15/32": { + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "post-policy" + }, + "2111::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2111::1111/128", + "ipv6": true, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "post-policy", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-pre-policy-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-pre-policy-step1.json new file mode 100644 index 000000000000..1c34498b7a38 --- /dev/null +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-pre-policy-step1.json @@ -0,0 +1,30 @@ +{ + "pre-policy": { + "withdraw": { + "172.31.0.15/32": { + "bmp_log_type": "withdraw", + "ip_prefix": "172.31.0.15/32", + "ipv6": false, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192.168.0.2", + "peer_type": "global instance", + "policy": "pre-policy" + }, + "2111::1111/128": { + "afi": 2, + "bmp_log_type": "withdraw", + "ip_prefix": "2111::1111/128", + "ipv6": true, + "peer_asn": 65502, + "peer_bgp_id": "192.168.0.2", + "peer_distinguisher": "0:0", + "peer_ip": "192:168::2", + "peer_type": "global instance", + "policy": "pre-policy", + "safi": 1 + } + } + } +} diff --git a/tests/topotests/bgp_bmp/r1/frr.conf b/tests/topotests/bgp_bmp/r1/frr.conf new file mode 100644 index 000000000000..f7cb669b3dd2 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/frr.conf @@ -0,0 +1,67 @@ +interface r1-eth0 + ip address 192.0.2.1/24 +! +interface r1-eth1 + ip address 192.168.0.1/24 + ipv6 address 192:168::1/64 +! +router bgp 65501 + bgp router-id 192.168.0.1 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 192.168.0.2 remote-as 65502 + neighbor 192:168::2 remote-as 65502 +! + bmp targets bmp1 + bmp connect 192.0.2.10 port 1789 min-retry 100 max-retry 10000 + bmp monitor ipv4 unicast pre-policy + bmp monitor ipv6 unicast pre-policy + bmp monitor ipv4 vpn pre-policy + bmp monitor ipv6 vpn pre-policy + bmp monitor ipv4 unicast post-policy + bmp monitor ipv6 unicast post-policy + bmp monitor ipv4 vpn post-policy + bmp monitor ipv6 vpn post-policy + bmp monitor ipv4 unicast loc-rib + bmp monitor ipv6 unicast loc-rib + bmp monitor ipv4 vpn loc-rib + bmp monitor ipv6 vpn loc-rib + exit +! + address-family ipv4 vpn + neighbor 192.168.0.2 activate + neighbor 192.168.0.2 soft-reconfiguration inbound + exit-address-family + address-family ipv6 vpn + neighbor 192:168::2 activate + neighbor 192:168::2 soft-reconfiguration inbound + exit-address-family + address-family ipv4 unicast + neighbor 192.168.0.2 activate + neighbor 192.168.0.2 soft-reconfiguration inbound + no neighbor 192:168::2 activate + exit-address-family +! + address-family ipv6 unicast + neighbor 192:168::2 activate + neighbor 192:168::2 soft-reconfiguration inbound + exit-address-family +! +router bgp 65501 vrf vrf1 + bgp router-id 192.168.0.1 + bgp log-neighbor-changes + address-family ipv4 unicast + label vpn export 101 + rd vpn export 444:1 + rt vpn both 52:100 + export vpn + import vpn + exit-address-family + address-family ipv6 unicast + label vpn export 103 + rd vpn export 555:1 + rt vpn both 54:200 + export vpn + import vpn + exit-address-family +exit diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step1.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step1.json new file mode 100644 index 000000000000..038c87ca9dd0 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step1.json @@ -0,0 +1,21 @@ +{ + "routes": { + "172.31.0.15/32": [ + { + "bestpath": true, + "pathFrom": "external", + "path": "65502", + "origin": "IGP", + "nexthops": [ + { + "ip": "192.168.0.2", + "hostname": "r2", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} + diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step2.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step2.json new file mode 100644 index 000000000000..275f7f30e9e5 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step2.json @@ -0,0 +1,25 @@ +{ + "routes": { + "routeDistinguishers": { + "444:2": { + "172.31.0.15/32": [ + { + "bestpath": true, + "pathFrom": "external", + "path": "65502", + "origin": "IGP", + "nexthops": [ + { + "ip": "192.168.0.2", + "hostname": "r2", + "afi": "ipv4", + "used": true + } + ] + } + ] + } + } + } +} + diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step1.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step1.json new file mode 100644 index 000000000000..22a6c605c187 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step1.json @@ -0,0 +1,6 @@ +{ + "routes": { + "2001::1111/128": null + } +} + diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step2.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step2.json new file mode 100644 index 000000000000..0f930ee71f32 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step2.json @@ -0,0 +1,10 @@ +{ + "routes": { + "routeDistinguishers": { + "444:2": { + "2001::1111/128": null + } + } + } +} + diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step1.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step1.json new file mode 100644 index 000000000000..ed5cea68ce64 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step1.json @@ -0,0 +1,27 @@ +{ + "routes": { + "2001::1111/128": [ + { + "bestpath": true, + "pathFrom": "external", + "path": "65502", + "origin": "IGP", + "nexthops": [ + { + "ip": "192:168::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ] + } +} + diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step2.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step2.json new file mode 100644 index 000000000000..c4c0c16284cb --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step2.json @@ -0,0 +1,25 @@ +{ + "routes": { + "routeDistinguishers": { + "555:2": { + "2001::1111/128": [ + { + "bestpath": true, + "pathFrom": "external", + "path": "65502", + "origin": "IGP", + "nexthops": [ + { + "ip": "192:168::2", + "hostname": "r2", + "afi": "ipv6", + "used": true + } + ] + } + ] + } + } + } +} + diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step1.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step1.json new file mode 100644 index 000000000000..22a6c605c187 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step1.json @@ -0,0 +1,6 @@ +{ + "routes": { + "2001::1111/128": null + } +} + diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step2.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step2.json new file mode 100644 index 000000000000..7b652afca6ed --- /dev/null +++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step2.json @@ -0,0 +1,10 @@ +{ + "routes": { + "routeDistinguishers": { + "555:2": { + "2001::1111/128": null + } + } + } +} + diff --git a/tests/topotests/bgp_bmp/r1vrf/frr.conf b/tests/topotests/bgp_bmp/r1vrf/frr.conf new file mode 100644 index 000000000000..cb8a7d2b14e4 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1vrf/frr.conf @@ -0,0 +1,35 @@ +interface r1vrf-eth0 + ip address 192.0.2.1/24 +! +interface r1vrf-eth1 + ip address 192.168.0.1/24 + ipv6 address 192:168::1/64 +! +router bgp 65501 vrf vrf1 + bgp router-id 192.168.0.1 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 192.168.0.2 remote-as 65502 + neighbor 192:168::2 remote-as 65502 +! + bmp targets bmp1 + bmp connect 192.0.2.10 port 1789 min-retry 100 max-retry 10000 + bmp monitor ipv4 unicast pre-policy + bmp monitor ipv6 unicast pre-policy + bmp monitor ipv4 unicast post-policy + bmp monitor ipv6 unicast post-policy + bmp monitor ipv4 unicast loc-rib + bmp monitor ipv6 unicast loc-rib + exit +! + address-family ipv4 unicast + neighbor 192.168.0.2 activate + neighbor 192.168.0.2 soft-reconfiguration inbound + no neighbor 192:168::2 activate + exit-address-family +! + address-family ipv6 unicast + neighbor 192:168::2 activate + neighbor 192:168::2 soft-reconfiguration inbound + exit-address-family +! diff --git a/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-update-step1.json b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-update-step1.json new file mode 100644 index 000000000000..dc0228db61f0 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-update-step1.json @@ -0,0 +1,20 @@ +{ + "routes": { + "172.31.0.15/32": [ + { + "bestpath": true, + "pathFrom": "external", + "path": "65502", + "origin": "IGP", + "nexthops": [ + { + "ip": "192.168.0.2", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} + diff --git a/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-withdraw-step1.json b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-withdraw-step1.json new file mode 100644 index 000000000000..6a778137768a --- /dev/null +++ b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-withdraw-step1.json @@ -0,0 +1,6 @@ +{ + "routes": { + "172.31.0.15/32": null + } +} + diff --git a/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-update-step1.json b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-update-step1.json new file mode 100644 index 000000000000..64c8622ab523 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-update-step1.json @@ -0,0 +1,25 @@ +{ + "routes": { + "2111::1111/128": [ + { + "bestpath": true, + "pathFrom": "external", + "path": "65502", + "origin": "IGP", + "nexthops": [ + { + "ip": "192:168::2", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ] + } +} + diff --git a/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-withdraw-step1.json b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-withdraw-step1.json new file mode 100644 index 000000000000..93f4a75e8c47 --- /dev/null +++ b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-withdraw-step1.json @@ -0,0 +1,6 @@ +{ + "routes": { + "2111::1111/128": null + } +} + diff --git a/tests/topotests/bgp_bmp/r2/frr.conf b/tests/topotests/bgp_bmp/r2/frr.conf new file mode 100644 index 000000000000..250071f48477 --- /dev/null +++ b/tests/topotests/bgp_bmp/r2/frr.conf @@ -0,0 +1,54 @@ +interface r2-eth0 + ip address 192.168.0.2/24 + ipv6 address 192:168::2/64 +! +interface r2-eth1 + ip address 172.31.0.2/24 + ipv6 address 172:31::2/64 +! +router bgp 65502 + bgp router-id 192.168.0.2 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.0.1 remote-as 65501 + neighbor 192:168::1 remote-as 65501 +! + address-family ipv4 unicast + neighbor 192.168.0.1 activate + no neighbor 192:168::1 activate + redistribute connected + exit-address-family +! + address-family ipv4 vpn + neighbor 192.168.0.1 activate + exit-address-family +! + address-family ipv6 vpn + neighbor 192:168::1 activate + exit-address-family +! + address-family ipv6 unicast + neighbor 192:168::1 activate + redistribute connected + exit-address-family +! +router bgp 65502 vrf vrf1 + bgp router-id 192.168.0.2 + bgp log-neighbor-changes + no bgp network import-check + address-family ipv4 unicast + label vpn export 102 + rd vpn export 444:2 + rt vpn both 52:100 + export vpn + import vpn + exit-address-family + address-family ipv6 unicast + label vpn export 105 + rd vpn export 555:2 + rt vpn both 54:200 + export vpn + import vpn + exit-address-family +exit diff --git a/tests/topotests/bgp_bmp/r2vrf/frr.conf b/tests/topotests/bgp_bmp/r2vrf/frr.conf new file mode 100644 index 000000000000..5268190dec21 --- /dev/null +++ b/tests/topotests/bgp_bmp/r2vrf/frr.conf @@ -0,0 +1,27 @@ +interface r2vrf-eth0 + ip address 192.168.0.2/24 + ipv6 address 192:168::2/64 +! +interface r2vrf-eth1 + ip address 172.31.0.2/24 + ipv6 address 172:31::2/64 +! +router bgp 65502 + bgp router-id 192.168.0.2 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.0.1 remote-as 65501 + neighbor 192:168::1 remote-as 65501 +! + address-family ipv4 unicast + neighbor 192.168.0.1 activate + no neighbor 192:168::1 activate + redistribute connected + exit-address-family +! + address-family ipv6 unicast + neighbor 192:168::1 activate + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_bmp/test_bgp_bmp_1.py b/tests/topotests/bgp_bmp/test_bgp_bmp_1.py new file mode 100644 index 000000000000..be3e07929a0f --- /dev/null +++ b/tests/topotests/bgp_bmp/test_bgp_bmp_1.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright 2023 6WIND S.A. +# Authored by Farid Mihoub +# + +""" +test_bgp_bmp.py: Test BGP BMP functionalities + + +------+ +------+ +------+ + | | | | | | + | BMP1 |------------| R1 |---------------| R2 | + | | | | | | + +------+ +------+ +------+ + +Setup two routers R1 and R2 with one link configured with IPv4 and +IPv6 addresses. +Configure BGP in R1 and R2 to exchange prefixes from +the latter to the first router. +Setup a link between R1 and the BMP server, activate the BMP feature in R1 +and ensure the monitored BGP sessions logs are well present on the BMP server. +""" + +from functools import partial +import json +import os +import pytest +import sys + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join("../")) +sys.path.append(os.path.join("../lib/")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.bgp import verify_bgp_convergence_from_running_config +from lib.bgp import bgp_configure_prefixes +from .bgpbmp import ( + bmp_check_for_prefixes, + bmp_check_for_peer_message, + bmp_update_seq, +) +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +pytestmark = [pytest.mark.bgpd] + +PRE_POLICY = "pre-policy" +POST_POLICY = "post-policy" +LOC_RIB = "loc-rib" + +UPDATE_EXPECTED_JSON = False +DEBUG_PCAP = False + + +def build_topo(tgen): + tgen.add_router("r1") + tgen.add_router("r2") + tgen.add_bmp_server("bmp1", ip="192.0.2.10", defaultRoute="via 192.0.2.1") + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["bmp1"]) + + tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "r1-eth1", "r2-eth0") + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + if DEBUG_PCAP: + pcap_file = os.path.join(tgen.logdir, "r1/bmp.pcap") + tgen.gears["r1"].run( + "tcpdump -nni r1-eth0 -s 0 -w {} &".format(pcap_file), stdout=None + ) + + for rname, router in tgen.routers().items(): + logger.info("Loading router %s" % rname) + router.load_frr_config( + os.path.join(CWD, "{}/frr.conf".format(rname)), + [(TopoRouter.RD_ZEBRA, None), (TopoRouter.RD_BGP, "-M bmp")], + ) + + tgen.start_router() + + logger.info("starting BMP servers") + for bmp_name, server in tgen.get_bmp_servers().items(): + server.start(log_file=os.path.join(tgen.logdir, bmp_name, "bmp.log")) + + +def teardown_module(_mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_convergence(): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + result = verify_bgp_convergence_from_running_config(tgen, dut="r1") + assert result is True, "BGP is not converging" + + +def _test_prefixes(policy, vrf=None, step=0): + """ + Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes. + Check if the previous actions are logged in the BMP server with the right + message type and the right policy. + """ + tgen = get_topogen() + + safi = "vpn" if vrf else "unicast" + + prefixes = ["172.31.0.15/32", "2001::1111/128"] + + for type in ("update", "withdraw"): + bmp_update_seq(tgen.gears["bmp1"], os.path.join(tgen.logdir, "bmp1", "bmp.log")) + + bgp_configure_prefixes( + tgen.gears["r2"], + 65502, + "unicast", + prefixes, + vrf=vrf, + update=(type == "update"), + ) + + logger.info(f"checking for prefixes {type}") + + for ipver in [4, 6]: + if UPDATE_EXPECTED_JSON: + continue + ref_file = "{}/r1/show-bgp-ipv{}-{}-step{}.json".format( + CWD, ipver, type, step + ) + expected = json.loads(open(ref_file).read()) + + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r1"], + f"show bgp ipv{ipver} {safi} json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = f"r1: BGP IPv{ipver} convergence failed" + assert res is None, assertmsg + + # check + test_func = partial( + bmp_check_for_prefixes, + prefixes, + type, + policy, + step, + tgen.gears["bmp1"], + os.path.join(tgen.logdir, "bmp1"), + tgen.gears["r1"], + f"{CWD}/bmp1", + UPDATE_EXPECTED_JSON, + LOC_RIB, + ) + success, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert success, "Checking the updated prefixes has failed ! %s" % res + + +def test_bmp_server_logging(): + """ + Assert the logging of the bmp server. + """ + + def check_for_log_file(): + tgen = get_topogen() + output = tgen.gears["bmp1"].run( + "ls {}".format(os.path.join(tgen.logdir, "bmp1")) + ) + if "bmp.log" not in output: + return False + return True + + success, _ = topotest.run_and_expect(check_for_log_file, True, count=30, wait=1) + assert success, "The BMP server is not logging" + + +def test_peer_up(): + """ + Checking for BMP peers up messages + """ + + tgen = get_topogen() + peers = ["192.168.0.2", "192:168::2", "0.0.0.0"] + + logger.info("checking for BMP peers up messages") + + test_func = partial( + bmp_check_for_peer_message, + peers, + "peer up", + tgen.gears["bmp1"], + os.path.join(tgen.logdir, "bmp1", "bmp.log"), + ) + success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) + assert success, "Checking the updated prefixes has been failed !." + + +def test_bmp_bgp_unicast(): + """ + Add/withdraw bgp unicast prefixes and check the bmp logs. + """ + logger.info("*** Unicast prefixes pre-policy logging ***") + _test_prefixes(PRE_POLICY, step=1) + logger.info("*** Unicast prefixes post-policy logging ***") + _test_prefixes(POST_POLICY, step=1) + logger.info("*** Unicast prefixes loc-rib logging ***") + _test_prefixes(LOC_RIB, step=1) + + +def test_bmp_bgp_vpn(): + # check for the prefixes in the BMP server logging file + logger.info("***** VPN prefixes pre-policy logging *****") + _test_prefixes(PRE_POLICY, vrf="vrf1", step=2) + logger.info("***** VPN prefixes post-policy logging *****") + _test_prefixes(POST_POLICY, vrf="vrf1", step=2) + logger.info("***** VPN prefixes loc-rib logging *****") + _test_prefixes(LOC_RIB, vrf="vrf1", step=2) + + +def test_peer_down(): + """ + Checking for BMP peers down messages + """ + tgen = get_topogen() + + tgen.gears["r2"].vtysh_cmd("clear bgp *") + + peers = ["192.168.0.2", "192:168::2"] + + logger.info("checking for BMP peers down messages") + + test_func = partial( + bmp_check_for_peer_message, + peers, + "peer down", + tgen.gears["bmp1"], + os.path.join(tgen.logdir, "bmp1", "bmp.log"), + ) + success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) + assert success, "Checking the updated prefixes has been failed !." + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_bmp/test_bgp_bmp_2.py b/tests/topotests/bgp_bmp/test_bgp_bmp_2.py new file mode 100644 index 000000000000..e8f67515bd5d --- /dev/null +++ b/tests/topotests/bgp_bmp/test_bgp_bmp_2.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright 2023 6WIND S.A. +# Authored by Farid Mihoub +# + +""" +test_bgp_bmp.py: Test BGP BMP functionalities + + +------+ +------+ +------+ + | | | | | | + | BMP1 |------------| R1 |---------------| R2 | + | | | | | | + +------+ +------+ +------+ + +Setup two routers R1 and R2 with one link configured with IPv4 and +IPv6 addresses. +Configure BGP in R1 and R2 to exchange prefixes from +the latter to the first router. +Setup a link between R1 and the BMP server, activate the BMP feature in R1 +and ensure the monitored BGP sessions logs are well present on the BMP server. +""" + +from functools import partial +import json +import os +import platform +import pytest +import sys + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join("../")) +sys.path.append(os.path.join("../lib/")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.bgp import verify_bgp_convergence_from_running_config +from lib.bgp import bgp_configure_prefixes +from .bgpbmp import ( + bmp_check_for_prefixes, + bmp_check_for_peer_message, + bmp_update_seq, + bmp_reset_seq, +) + + +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +pytestmark = [pytest.mark.bgpd] + +PRE_POLICY = "pre-policy" +POST_POLICY = "post-policy" +LOC_RIB = "loc-rib" + +UPDATE_EXPECTED_JSON = False +DEBUG_PCAP = False + + +def build_topo(tgen): + tgen.add_router("r1vrf") + tgen.add_router("r2vrf") + tgen.add_bmp_server("bmp1vrf", ip="192.0.2.10", defaultRoute="via 192.0.2.1") + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1vrf"]) + switch.add_link(tgen.gears["bmp1vrf"]) + + tgen.add_link(tgen.gears["r1vrf"], tgen.gears["r2vrf"], "r1vrf-eth1", "r2vrf-eth0") + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + tgen.net["r1vrf"].cmd( + """ +ip link add vrf1 type vrf table 10 +ip link set vrf1 up +ip link set r1vrf-eth1 master vrf1 +""" + ) + bmp_reset_seq() + if DEBUG_PCAP: + pcap_file = os.path.join(tgen.logdir, "r1vrf/bmp.pcap") + tgen.gears["r1vrf"].run( + "tcpdump -nni r1vrf-eth0 -s 0 -w {} &".format(pcap_file), stdout=None + ) + + for rname, router in tgen.routers().items(): + logger.info("Loading router %s" % rname) + router.load_frr_config( + os.path.join(CWD, "{}/frr.conf".format(rname)), + [(TopoRouter.RD_ZEBRA, None), (TopoRouter.RD_BGP, "-M bmp")], + ) + + tgen.start_router() + + logger.info("starting BMP servers") + for bmp_name, server in tgen.get_bmp_servers().items(): + server.start(log_file=os.path.join(tgen.logdir, bmp_name, "bmp.log")) + + +def teardown_module(_mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_convergence(): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + result = verify_bgp_convergence_from_running_config(tgen, dut="r1vrf") + assert result is True, "BGP is not converging" + + +def _test_prefixes(policy, step=1): + """ + Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes. + Check if the previous actions are logged in the BMP server with the right + message type and the right policy. + """ + tgen = get_topogen() + + prefixes = ["172.31.0.15/32", "2111::1111/128"] + + for type in ("update", "withdraw"): + bmp_update_seq( + tgen.gears["bmp1vrf"], os.path.join(tgen.logdir, "bmp1vrf", "bmp.log") + ) + + # add prefixes + bgp_configure_prefixes( + tgen.gears["r2vrf"], 65502, "unicast", prefixes, update=(type == "update") + ) + + logger.info(f"checking for prefixes {type}") + + for ipver in [4, 6]: + if UPDATE_EXPECTED_JSON: + continue + ref_file = "{}/r1vrf/show-bgp-ipv{}-{}-step{}.json".format( + CWD, ipver, type, step + ) + expected = json.loads(open(ref_file).read()) + + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r1vrf"], + f"show bgp vrf vrf1 ipv{ipver} json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = f"r1vrf: BGP IPv{ipver} convergence failed" + assert res is None, assertmsg + + # check + test_func = partial( + bmp_check_for_prefixes, + prefixes, + type, + policy, + step, + tgen.gears["bmp1vrf"], + os.path.join(tgen.logdir, "bmp1vrf"), + tgen.gears["r1vrf"], + f"{CWD}/bmp1vrf", + UPDATE_EXPECTED_JSON, + LOC_RIB, + ) + success, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert success, "Checking the updated prefixes has failed ! %s" % res + + +def test_bmp_server_logging(): + """ + Assert the logging of the bmp server. + """ + + def check_for_log_file(): + tgen = get_topogen() + output = tgen.gears["bmp1vrf"].run( + "ls {}".format(os.path.join(tgen.logdir, "bmp1vrf")) + ) + if "bmp.log" not in output: + return False + return True + + success, _ = topotest.run_and_expect(check_for_log_file, True, count=30, wait=1) + assert success, "The BMP server is not logging" + + +def test_peer_up(): + """ + Checking for BMP peers up messages + """ + + tgen = get_topogen() + peers = ["192.168.0.2", "192:168::2", "0.0.0.0"] + + logger.info("checking for BMP peers up messages") + + test_func = partial( + bmp_check_for_peer_message, + peers, + "peer up", + tgen.gears["bmp1vrf"], + os.path.join(tgen.logdir, "bmp1vrf", "bmp.log"), + ) + success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) + assert success, "Checking the updated prefixes has been failed !." + + +def test_bmp_bgp_unicast(): + """ + Add/withdraw bgp unicast prefixes and check the bmp logs. + """ + logger.info("*** Unicast prefixes pre-policy logging ***") + _test_prefixes(PRE_POLICY) + logger.info("*** Unicast prefixes post-policy logging ***") + _test_prefixes(POST_POLICY) + logger.info("*** Unicast prefixes loc-rib logging ***") + _test_prefixes(LOC_RIB) + + +def test_peer_down(): + """ + Checking for BMP peers down messages + """ + tgen = get_topogen() + + tgen.gears["r2vrf"].vtysh_cmd("clear bgp *") + + peers = ["192.168.0.2", "192:168::2"] + + logger.info("checking for BMP peers down messages") + + test_func = partial( + bmp_check_for_peer_message, + peers, + "peer down", + tgen.gears["bmp1vrf"], + os.path.join(tgen.logdir, "bmp1vrf", "bmp.log"), + ) + success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) + assert success, "Checking the updated prefixes has been failed !." + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_color_extcommunities/r1/bgpd.conf b/tests/topotests/bgp_color_extcommunities/r1/bgpd.conf index d4ca392b1a28..53764a575cca 100644 --- a/tests/topotests/bgp_color_extcommunities/r1/bgpd.conf +++ b/tests/topotests/bgp_color_extcommunities/r1/bgpd.conf @@ -11,7 +11,13 @@ router bgp 65001 exit-address-family ! route-map rmap permit 10 +<<<<<<< HEAD set extcommunity color 1 set extcommunity rt 80:987 set extcommunity color 100 55555 200 +======= + set extcommunity color 01:1 + set extcommunity rt 80:987 + set extcommunity color 01:100 01:55555 01:200 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) exit diff --git a/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py b/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py index 09091198a8c5..038260f6e79a 100644 --- a/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py +++ b/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py @@ -105,7 +105,11 @@ def _bgp_check_route(router, exists): { "valid": True, "extendedCommunity": { +<<<<<<< HEAD "string": "RT:80:987 Color:100 Color:200 Color:55555" +======= + "string": "RT:80:987 Color:01:100 Color:01:200 Color:01:55555" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }, } ], diff --git a/tests/topotests/bgp_ecmp_topo1/r1/bgpd.conf b/tests/topotests/bgp_ecmp_topo1/r1/bgpd.conf index 49981ac58968..fb9e15cf70ab 100644 --- a/tests/topotests/bgp_ecmp_topo1/r1/bgpd.conf +++ b/tests/topotests/bgp_ecmp_topo1/r1/bgpd.conf @@ -8,6 +8,7 @@ router bgp 100 no bgp ebgp-requires-policy neighbor 10.0.1.101 remote-as 99 neighbor 10.0.1.101 timers 3 10 +<<<<<<< HEAD neighbor 10.0.1.102 remote-as 99 neighbor 10.0.1.102 timers 3 10 neighbor 10.0.1.103 remote-as 99 @@ -46,6 +47,66 @@ router bgp 100 neighbor 10.0.4.119 timers 3 10 neighbor 10.0.4.120 remote-as 120 neighbor 10.0.4.120 timers 3 10 +======= + neighbor 10.0.1.101 timers connect 1 + neighbor 10.0.1.102 remote-as 99 + neighbor 10.0.1.102 timers 3 10 + neighbor 10.0.1.102 timers connect 1 + neighbor 10.0.1.103 remote-as 99 + neighbor 10.0.1.103 timers 3 10 + neighbor 10.0.1.103 timers connect 1 + neighbor 10.0.1.104 remote-as 99 + neighbor 10.0.1.104 timers 3 10 + neighbor 10.0.1.104 timers connect 1 + neighbor 10.0.1.105 remote-as 99 + neighbor 10.0.1.105 timers 3 10 + neighbor 10.0.1.105 timers connect 1 + neighbor 10.0.2.106 remote-as 99 + neighbor 10.0.2.106 timers 3 10 + neighbor 10.0.1.106 timers connect 1 + neighbor 10.0.2.107 remote-as 99 + neighbor 10.0.2.107 timers 3 10 + neighbor 10.0.1.107 timers connect 1 + neighbor 10.0.2.108 remote-as 99 + neighbor 10.0.2.108 timers 3 10 + neighbor 10.0.1.108 timers connect 1 + neighbor 10.0.2.109 remote-as 99 + neighbor 10.0.2.109 timers 3 10 + neighbor 10.0.1.109 timers connect 1 + neighbor 10.0.2.110 remote-as 99 + neighbor 10.0.2.110 timers 3 10 + neighbor 10.0.1.110 timers connect 1 + neighbor 10.0.3.111 remote-as 111 + neighbor 10.0.3.111 timers 3 10 + neighbor 10.0.1.111 timers connect 1 + neighbor 10.0.3.112 remote-as 112 + neighbor 10.0.3.112 timers 3 10 + neighbor 10.0.1.112 timers connect 1 + neighbor 10.0.3.113 remote-as 113 + neighbor 10.0.3.113 timers 3 10 + neighbor 10.0.1.113 timers connect 1 + neighbor 10.0.3.114 remote-as 114 + neighbor 10.0.3.114 timers 3 10 + neighbor 10.0.1.114 timers connect 1 + neighbor 10.0.3.115 remote-as 115 + neighbor 10.0.3.115 timers 3 10 + neighbor 10.0.1.115 timers connect 1 + neighbor 10.0.4.116 remote-as 116 + neighbor 10.0.4.116 timers 3 10 + neighbor 10.0.1.116 timers connect 1 + neighbor 10.0.4.117 remote-as 117 + neighbor 10.0.4.117 timers 3 10 + neighbor 10.0.1.117 timers connect 1 + neighbor 10.0.4.118 remote-as 118 + neighbor 10.0.4.118 timers 3 10 + neighbor 10.0.1.118 timers connect 1 + neighbor 10.0.4.119 remote-as 119 + neighbor 10.0.4.119 timers 3 10 + neighbor 10.0.1.119 timers connect 1 + neighbor 10.0.4.120 remote-as 120 + neighbor 10.0.4.120 timers 3 10 + neighbor 10.0.1.120 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json new file mode 100644 index 000000000000..7532ce933167 --- /dev/null +++ b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json @@ -0,0 +1,131 @@ +{ + "bgpLocalRouterId":"192.168.100.21", + "defaultLocPrf":100, + "localAS":65000, + "192.168.101.41:2":{ + "rd":"192.168.101.41:2", + "[5]:[0]:[32]:[192.168.101.41]":{ + "prefix":"[5]:[0]:[32]:[192.168.101.41]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"internal", + "routeType":5, + "ethTag":0, + "ipLen":32, + "ip":"192.168.101.41", + "metric":0, + "locPrf":100, + "weight":0, + "peerId":"192.168.100.41", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.41", + "hostname":"r2", + "afi":"ipv4", + "used":true + } + ] + } + ] + }, + "[5]:[0]:[128]:[fd00::2]":{ + "prefix":"[5]:[0]:[128]:[fd00::2]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"internal", + "routeType":5, + "ethTag":0, + "ipLen":128, + "ip":"fd00::2", + "metric":0, + "locPrf":100, + "weight":0, + "peerId":"192.168.100.41", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.41", + "hostname":"r2", + "afi":"ipv4", + "used":true + } + ] + } + ] + } + }, + "192.168.102.21:2":{ + "rd":"192.168.102.21:2", + "[5]:[0]:[32]:[192.168.102.21]":{ + "prefix":"[5]:[0]:[32]:[192.168.102.21]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"external", + "routeType":5, + "ethTag":0, + "ipLen":32, + "ip":"192.168.102.21", + "metric":0, + "weight":32768, + "peerId":"(unspec)", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.21", + "hostname":"r1", + "afi":"ipv4", + "used":true + } + ] + } + ] + }, + "[5]:[0]:[128]:[fd00::1]":{ + "prefix":"[5]:[0]:[128]:[fd00::1]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"external", + "routeType":5, + "ethTag":0, + "ipLen":128, + "ip":"fd00::1", + "metric":0, + "weight":32768, + "peerId":"(unspec)", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.21", + "hostname":"r1", + "afi":"ipv4", + "used":true + } + ] + } + ] + } + }, + "numPrefix":4, + "totalPrefix":4 +} diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json new file mode 100644 index 000000000000..a14ba1291e7b --- /dev/null +++ b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json @@ -0,0 +1,191 @@ +{ + "bgpLocalRouterId":"192.168.100.21", + "defaultLocPrf":100, + "localAS":65000, + "192.168.101.41:2":{ + "rd":"192.168.101.41:2", + "[5]:[0]:[32]:[192.168.101.41]":{ + "prefix":"[5]:[0]:[32]:[192.168.101.41]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"internal", + "routeType":5, + "ethTag":0, + "ipLen":32, + "ip":"192.168.101.41", + "metric":0, + "locPrf":100, + "weight":0, + "peerId":"192.168.100.41", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.41", + "hostname":"r2", + "afi":"ipv4", + "used":true + } + ] + } + ] + }, + "[5]:[0]:[32]:[192.168.102.41]":{ + "prefix":"[5]:[0]:[32]:[192.168.102.41]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"internal", + "routeType":5, + "ethTag":0, + "ipLen":32, + "ip":"192.168.102.41", + "metric":0, + "locPrf":100, + "weight":0, + "peerId":"192.168.100.41", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.41", + "hostname":"r2", + "afi":"ipv4", + "used":true + } + ] + } + ] + }, + "[5]:[0]:[128]:[fd00::2]":{ + "prefix":"[5]:[0]:[128]:[fd00::2]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"internal", + "routeType":5, + "ethTag":0, + "ipLen":128, + "ip":"fd00::2", + "metric":0, + "locPrf":100, + "weight":0, + "peerId":"192.168.100.41", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.41", + "hostname":"r2", + "afi":"ipv4", + "used":true + } + ] + } + ] + }, + "[5]:[0]:[128]:[fd00::3]":{ + "prefix":"[5]:[0]:[128]:[fd00::3]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"internal", + "routeType":5, + "ethTag":0, + "ipLen":128, + "ip":"fd00::3", + "metric":0, + "locPrf":100, + "weight":0, + "peerId":"192.168.100.41", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.41", + "hostname":"r2", + "afi":"ipv4", + "used":true + } + ] + } + ] + } + }, + "192.168.102.21:2":{ + "rd":"192.168.102.21:2", + "[5]:[0]:[32]:[192.168.102.21]":{ + "prefix":"[5]:[0]:[32]:[192.168.102.21]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"external", + "routeType":5, + "ethTag":0, + "ipLen":32, + "ip":"192.168.102.21", + "metric":0, + "weight":32768, + "peerId":"(unspec)", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.21", + "hostname":"r1", + "afi":"ipv4", + "used":true + } + ] + } + ] + }, + "[5]:[0]:[128]:[fd00::1]":{ + "prefix":"[5]:[0]:[128]:[fd00::1]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"external", + "routeType":5, + "ethTag":0, + "ipLen":128, + "ip":"fd00::1", + "metric":0, + "weight":32768, + "peerId":"(unspec)", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.21", + "hostname":"r1", + "afi":"ipv4", + "used":true + } + ] + } + ] + } + }, + "numPrefix":6, + "totalPrefix":6 +} diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json b/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json new file mode 100644 index 000000000000..597bca5fd3f1 --- /dev/null +++ b/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json @@ -0,0 +1,131 @@ +{ + "bgpLocalRouterId":"192.168.100.41", + "defaultLocPrf":100, + "localAS":65000, + "192.168.101.41:2":{ + "rd":"192.168.101.41:2", + "[5]:[0]:[32]:[192.168.101.41]":{ + "prefix":"[5]:[0]:[32]:[192.168.101.41]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"external", + "routeType":5, + "ethTag":0, + "ipLen":32, + "ip":"192.168.101.41", + "metric":0, + "weight":32768, + "peerId":"(unspec)", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.41", + "hostname":"r2", + "afi":"ipv4", + "used":true + } + ] + } + ] + }, + "[5]:[0]:[128]:[fd00::2]":{ + "prefix":"[5]:[0]:[128]:[fd00::2]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"external", + "routeType":5, + "ethTag":0, + "ipLen":128, + "ip":"fd00::2", + "metric":0, + "weight":32768, + "peerId":"(unspec)", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.41", + "hostname":"r2", + "afi":"ipv4", + "used":true + } + ] + } + ] + } + }, + "192.168.102.21:2":{ + "rd":"192.168.102.21:2", + "[5]:[0]:[32]:[192.168.102.21]":{ + "prefix":"[5]:[0]:[32]:[192.168.102.21]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"internal", + "routeType":5, + "ethTag":0, + "ipLen":32, + "ip":"192.168.102.21", + "metric":0, + "locPrf":100, + "weight":0, + "peerId":"192.168.100.21", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.21", + "hostname":"r1", + "afi":"ipv4", + "used":true + } + ] + } + ] + }, + "[5]:[0]:[128]:[fd00::1]":{ + "prefix":"[5]:[0]:[128]:[fd00::1]", + "prefixLen":352, + "paths":[ + { + "valid":true, + "bestpath":true, + "selectionReason":"First path received", + "pathFrom":"internal", + "routeType":5, + "ethTag":0, + "ipLen":128, + "ip":"fd00::1", + "metric":0, + "locPrf":100, + "weight":0, + "peerId":"192.168.100.21", + "path":"", + "origin":"IGP", + "nexthops":[ + { + "ip":"192.168.100.21", + "hostname":"r1", + "afi":"ipv4", + "used":true + } + ] + } + ] + } + }, + "numPrefix":4, + "totalPrefix":4 +} diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf index de5a0efc445f..fb319dee8b56 100644 --- a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf @@ -20,6 +20,7 @@ router bgp 65000 vrf r2-vrf-101 no bgp network import-check address-family ipv4 unicast network 192.168.101.41/32 +<<<<<<< HEAD exit-address-family address-family ipv6 unicast network fd00::2/128 @@ -29,3 +30,32 @@ router bgp 65000 vrf r2-vrf-101 advertise ipv6 unicast exit-address-family ! +======= + network 192.168.102.41/32 + exit-address-family + address-family ipv6 unicast + network fd00::2/128 + network fd00::3/128 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast route-map rmap4 + advertise ipv6 unicast route-map rmap6 + exit-address-family + ! +access-list acl4_1 seq 10 permit 192.168.101.41/32 +access-list acl4_2 seq 10 permit 192.168.102.41/32 +ipv6 access-list acl6_1 seq 10 permit fd00::2/128 +ipv6 access-list acl6_2 seq 10 permit fd00::3/128 +route-map rmap4 permit 1 + match ip address acl4_1 +exit +route-map rmap4 deny 2 + match ip address acl4_2 +exit +route-map rmap6 permit 1 + match ipv6 address acl6_1 +exit +route-map rmap6 deny 2 + match ipv6 address acl6_2 +exit +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py index 2d027081cb55..158e2b4a4432 100644 --- a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py +++ b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py @@ -13,6 +13,11 @@ with route advertisements on a separate netns. """ +<<<<<<< HEAD +======= +import json +from functools import partial +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) import os import sys import pytest @@ -160,6 +165,39 @@ def teardown_module(_mod): tgen.stop_topology() +<<<<<<< HEAD +======= +def _test_evpn_ping_router(pingrouter, ipv4_only=False): + """ + internal function to check ping between r1 and r2 + """ + # Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn) + logger.info( + "Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)" + ) + output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = ( + "expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok" + ) + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK") + + if ipv4_only: + return + + logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(r2-vrf-101 = fd00::2)") + output = pingrouter.run("ip netns exec r1-vrf-101 ping fd00::2 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assert 0, "expected ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) should be ok" + else: + logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) OK") + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_protocols_convergence(): """ Assert that all protocols have converged @@ -168,7 +206,38 @@ def test_protocols_convergence(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD topotest.sleep(4, "waiting 4 seconds for bgp convergence") +======= + # Check BGP IPv4 routing tables on r1 + logger.info("Checking BGP L2VPN EVPN routes for convergence on r1") + + for rname in ("r1", "r2"): + router = tgen.gears[rname] + json_file = "{}/{}/bgp_l2vpn_evpn_routes.json".format(CWD, router.name) + if not os.path.isfile(json_file): + assert 0, "bgp_l2vpn_evpn_routes.json file not found" + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show bgp l2vpn evpn json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + +def test_protocols_dump_info(): + """ + Dump EVPN information + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # Check IPv4/IPv6 routing tables. output = tgen.gears["r1"].vtysh_cmd("show bgp l2vpn evpn", isjson=False) logger.info("==== result from show bgp l2vpn evpn") @@ -203,6 +272,18 @@ def test_protocols_convergence(): logger.info("==== result from show evpn rmac vni all") logger.info(output) +<<<<<<< HEAD +======= + +def test_router_check_ip(): + """ + Check routes are correctly installed + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) expected = { "fd00::2/128": [ { @@ -210,7 +291,11 @@ def test_protocols_convergence(): "vrfName": "r1-vrf-101", "nexthops": [ { +<<<<<<< HEAD "ip": "::ffff:c0a8:6429", +======= + "ip": "::ffff:192.168.100.41", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } ], } @@ -221,6 +306,7 @@ def test_protocols_convergence(): ) assert result is None, "ipv6 route check failed" +<<<<<<< HEAD expected = { "101": { "numNextHops": 2, @@ -234,10 +320,41 @@ def test_protocols_convergence(): } result = topotest.router_json_cmp( tgen.gears["r1"], "show evpn next-hops vni all json", expected +======= + +def _test_router_check_evpn_contexts(router, ipv4_only=False): + """ + Check EVPN nexthops and RMAC number are correctly configured + """ + if ipv4_only: + expected = { + "101": { + "numNextHops": 1, + "192.168.100.41": { + "nexthopIp": "192.168.100.41", + }, + } + } + else: + expected = { + "101": { + "numNextHops": 2, + "192.168.100.41": { + "nexthopIp": "192.168.100.41", + }, + "::ffff:192.168.100.41": { + "nexthopIp": "::ffff:192.168.100.41", + }, + } + } + result = topotest.router_json_cmp( + router, "show evpn next-hops vni all json", expected +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) assert result is None, "evpn next-hops check failed" expected = {"101": {"numRmacs": 1}} +<<<<<<< HEAD result = topotest.router_json_cmp( tgen.gears["r1"], "show evpn rmac vni all json", expected ) @@ -265,12 +382,85 @@ def test_protocols_convergence(): assert 0, "expected ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) should be ok" else: logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) OK") +======= + result = topotest.router_json_cmp(router, "show evpn rmac vni all json", expected) + assert result is None, "evpn rmac number check failed" + + +def test_router_check_evpn_contexts(): + """ + Check EVPN nexthops and RMAC number are correctly configured + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + _test_router_check_evpn_contexts(tgen.gears["r1"]) + + +def test_evpn_ping(): + """ + Check ping between R1 and R2 is ok + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + _test_evpn_ping_router(tgen.gears["r1"]) + + +def test_evpn_disable_routemap(): + """ + Check the removal of a route-map on R2. More EVPN Prefixes are expected + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + tgen.gears["r2"].vtysh_cmd( + """ + configure terminal\n + router bgp 65000 vrf r2-vrf-101\n + address-family l2vpn evpn\n + advertise ipv4 unicast\n + advertise ipv6 unicast\n + """ + ) + router = tgen.gears["r1"] + json_file = "{}/{}/bgp_l2vpn_evpn_routes_all.json".format(CWD, router.name) + if not os.path.isfile(json_file): + assert 0, "bgp_l2vpn_evpn_routes.json file not found" + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show bgp l2vpn evpn json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + +def test_evpn_remove_ip(): + """ + Check the removal of an EVPN route is correctly handled + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) config_no_ipv6 = { "r2": { "raw_config": [ "router bgp 65000 vrf r2-vrf-101", "address-family ipv6 unicast", +<<<<<<< HEAD +======= + "no network fd00::3/128", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "no network fd00::2/128", ] } @@ -293,6 +483,10 @@ def test_protocols_convergence(): } result = verify_bgp_rib(tgen, "ipv6", "r1", ipv6_routes, expected=False) assert result is not True, "expect IPv6 route fd00::2/128 withdrawn" +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) output = tgen.gears["r1"].vtysh_cmd("show evpn next-hops vni all", isjson=False) logger.info("==== result from show evpn next-hops vni all") logger.info(output) @@ -300,6 +494,7 @@ def test_protocols_convergence(): logger.info("==== result from show evpn next-hops vni all") logger.info(output) +<<<<<<< HEAD expected = { "101": { "numNextHops": 1, @@ -331,6 +526,29 @@ def test_protocols_convergence(): assert 0, assertmsg else: logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK") +======= + +def test_router_check_evpn_contexts_again(): + """ + Check EVPN nexthops and RMAC number are correctly configured + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + _test_router_check_evpn_contexts(tgen.gears["r1"], ipv4_only=True) + + +def test_evpn_ping_again(): + """ + Check ping between R1 and R2 is ok + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + _test_evpn_ping_router(tgen.gears["r1"], ipv4_only=True) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_memory_leak(): diff --git a/tests/topotests/bgp_extended_link_bandwidth/r1/frr.conf b/tests/topotests/bgp_extended_link_bandwidth/r1/frr.conf index d0c0813e842d..78ebd11ec22c 100644 --- a/tests/topotests/bgp_extended_link_bandwidth/r1/frr.conf +++ b/tests/topotests/bgp_extended_link_bandwidth/r1/frr.conf @@ -22,7 +22,11 @@ ip prefix-list p200 seq 5 permit 10.10.10.200/32 ! route-map r2 permit 10 match ip address prefix-list p40 +<<<<<<< HEAD set extcommunity bandwidth 40000 +======= + set extcommunity bandwidth 40000 non-transitive +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) route-map r2 permit 20 match ip address prefix-list p100 set extcommunity bandwidth 100000 diff --git a/tests/topotests/bgp_extended_link_bandwidth/r2/frr.conf b/tests/topotests/bgp_extended_link_bandwidth/r2/frr.conf index 5cad150aef0b..57489b14c081 100644 --- a/tests/topotests/bgp_extended_link_bandwidth/r2/frr.conf +++ b/tests/topotests/bgp_extended_link_bandwidth/r2/frr.conf @@ -2,9 +2,21 @@ int r2-eth0 ip address 192.168.1.2/24 ! +<<<<<<< HEAD +======= +int r2-eth1 + ip address 192.168.2.2/24 +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) router bgp 65000 no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as internal neighbor 192.168.1.1 timers 1 3 neighbor 192.168.1.1 timers connect 1 +<<<<<<< HEAD +======= + neighbor 192.168.2.1 remote-as external + neighbor 192.168.2.1 timers 1 3 + neighbor 192.168.2.1 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! diff --git a/tests/topotests/bgp_extended_link_bandwidth/r3/frr.conf b/tests/topotests/bgp_extended_link_bandwidth/r3/frr.conf new file mode 100644 index 000000000000..61b13c8893c3 --- /dev/null +++ b/tests/topotests/bgp_extended_link_bandwidth/r3/frr.conf @@ -0,0 +1,16 @@ +! +int r3-eth0 + ip address 192.168.2.1/24 +! +int r3-eth1 + ip address 192.168.3.1/24 +! +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 192.168.2.2 remote-as external + neighbor 192.168.2.2 timers 1 3 + neighbor 192.168.2.2 timers connect 1 + neighbor 192.168.3.2 remote-as external + neighbor 192.168.3.2 timers 1 3 + neighbor 192.168.3.2 timers connect 1 +! diff --git a/tests/topotests/bgp_extended_link_bandwidth/r4/frr.conf b/tests/topotests/bgp_extended_link_bandwidth/r4/frr.conf new file mode 100644 index 000000000000..49f0caf7de19 --- /dev/null +++ b/tests/topotests/bgp_extended_link_bandwidth/r4/frr.conf @@ -0,0 +1,10 @@ +! +int r4-eth0 + ip address 192.168.3.2/24 +! +router bgp 65004 + no bgp ebgp-requires-policy + neighbor 192.168.3.1 remote-as external + neighbor 192.168.3.1 timers 1 3 + neighbor 192.168.3.1 timers connect 1 +! diff --git a/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py b/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py index e9006b81c930..3972ced4a671 100644 --- a/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py +++ b/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py @@ -22,7 +22,11 @@ def setup_module(mod): +<<<<<<< HEAD topodef = {"s1": ("r1", "r2")} +======= + topodef = {"s1": ("r1", "r2"), "s2": ("r2", "r3"), "s3": ("r3", "r4")} +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tgen = Topogen(topodef, mod.__name__) tgen.start_topology() @@ -46,9 +50,17 @@ def test_bgp_dynamic_capability_role(): pytest.skip(tgen.errors) r2 = tgen.gears["r2"] +<<<<<<< HEAD def _bgp_converge(): output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast json detail")) +======= + r3 = tgen.gears["r3"] + r4 = tgen.gears["r4"] + + def _bgp_converge(router): + output = json.loads(router.vtysh_cmd("show bgp ipv4 unicast json detail")) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) expected = { "routes": { "10.10.10.40/32": { @@ -84,9 +96,66 @@ def _bgp_converge(): test_func = functools.partial( _bgp_converge, +<<<<<<< HEAD ) _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, "Can't see link bandwidths as expected" +======= + r2, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "r2 (iBGP) should see link bandwidth extended communities" + + test_func = functools.partial( + _bgp_converge, + r3, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert ( + result is None + ), "r3 (eBGP) should see link bandwidth extended communities (including non-transitive)" + + def _bgp_check_non_transitive_extended_communities(): + output = json.loads(r4.vtysh_cmd("show bgp ipv4 unicast json detail")) + expected = { + "routes": { + "10.10.10.40/32": { + "paths": [ + { + "extendedIpv6Community": None, + } + ] + }, + "10.10.10.100/32": { + "paths": [ + { + "extendedIpv6Community": { + "string": "LB:65000:12500000000 (100.000 Gbps)", + } + } + ] + }, + "10.10.10.200/32": { + "paths": [ + { + "extendedIpv6Community": { + "string": "LB:65000:25000000000 (200.000 Gbps)", + } + } + ] + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_non_transitive_extended_communities, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert ( + result is None + ), "r4 (eBGP) should NOT see non-transitive link bandwidth extended communities" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if __name__ == "__main__": diff --git a/tests/topotests/bgp_flowspec/r1/bgpd.conf b/tests/topotests/bgp_flowspec/r1/bgpd.conf index 4b7a20f95800..030051c15ca7 100644 --- a/tests/topotests/bgp_flowspec/r1/bgpd.conf +++ b/tests/topotests/bgp_flowspec/r1/bgpd.conf @@ -6,6 +6,10 @@ router bgp 100 bgp router-id 10.0.1.1 neighbor 10.0.1.101 remote-as 100 neighbor 10.0.1.101 timers 3 10 +<<<<<<< HEAD +======= + neighbor 10.0.1.101 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) neighbor 10.0.1.101 update-source 10.0.1.1 address-family ipv6 flowspec local-install r1-eth0 diff --git a/tests/topotests/bgp_invalid_nexthop/__init__.py b/tests/topotests/bgp_invalid_nexthop/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_invalid_nexthop/exabgp.env b/tests/topotests/bgp_invalid_nexthop/exabgp.env new file mode 100644 index 000000000000..28e642360a39 --- /dev/null +++ b/tests/topotests/bgp_invalid_nexthop/exabgp.env @@ -0,0 +1,53 @@ +[exabgp.api] +encoder = text +highres = false +respawn = false +socket = '' + +[exabgp.bgp] +openwait = 60 + +[exabgp.cache] +attributes = true +nexthops = true + +[exabgp.daemon] +daemonize = true +pid = '/var/run/exabgp/exabgp.pid' +user = 'exabgp' +##daemonize = false + +[exabgp.log] +all = false +configuration = true +daemon = true +destination = '/var/log/exabgp.log' +enable = true +level = INFO +message = false +network = true +packets = false +parser = false +processes = true +reactor = true +rib = false +routes = false +short = false +timers = false + +[exabgp.pdb] +enable = false + +[exabgp.profile] +enable = false +file = '' + +[exabgp.reactor] +speed = 1.0 + +[exabgp.tcp] +acl = false +bind = '' +delay = 0 +once = false +port = 179 diff --git a/tests/topotests/bgp_invalid_nexthop/peer1/exabgp.cfg b/tests/topotests/bgp_invalid_nexthop/peer1/exabgp.cfg new file mode 100644 index 000000000000..45b0f20d77a7 --- /dev/null +++ b/tests/topotests/bgp_invalid_nexthop/peer1/exabgp.cfg @@ -0,0 +1,19 @@ +neighbor fc00::1 { + router-id 10.0.0.2; + local-address fc00::2; + local-as 65002; + peer-as 65001; + group-updates false; + + family { + ipv4 unicast; + ipv6 unicast; + } + + static { + route 2001:db8:100::/64 { + next-hop 0.0.0.0; + next-hop fc00::2; + } + } +} diff --git a/tests/topotests/bgp_invalid_nexthop/r1/frr.conf b/tests/topotests/bgp_invalid_nexthop/r1/frr.conf new file mode 100644 index 000000000000..f96aeb43668c --- /dev/null +++ b/tests/topotests/bgp_invalid_nexthop/r1/frr.conf @@ -0,0 +1,15 @@ +! +interface r1-eth0 + ip address fc00::1/64 +! +router bgp 65001 + bgp router-id 10.0.0.1 + no bgp default ipv4-unicast + no bgp ebgp-requires-policy + neighbor fc00::2 remote-as external + neighbor fc00::2 timers 3 10 + neighbor fc00::2 timers connect 1 + address-family ipv6 + neighbor fc00::2 activate + exit-address-family +! diff --git a/tests/topotests/bgp_invalid_nexthop/test_bgp_invalid_nexthop.py b/tests/topotests/bgp_invalid_nexthop/test_bgp_invalid_nexthop.py new file mode 100644 index 000000000000..ae482aa9c6a5 --- /dev/null +++ b/tests/topotests/bgp_invalid_nexthop/test_bgp_invalid_nexthop.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024 by +# Donatas Abraitis +# + +""" +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, get_topogen + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + r1 = tgen.add_router("r1") + peer1 = tgen.add_exabgp_peer("peer1", ip="fc00::2/64", defaultRoute="via fc00::1") + + switch = tgen.add_switch("s1") + switch.add_link(r1) + switch.add_link(peer1) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + for _, (rname, router) in enumerate(tgen.routers().items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + peer = tgen.gears["peer1"] + peer.start(os.path.join(CWD, "peer1"), os.path.join(CWD, "exabgp.env")) + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_invalid_nexthop(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + def _bgp_converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv6 unicast json")) + expected = { + "routes": { + "2001:db8:100::/64": [ + {"valid": True, "nexthops": [{"ip": "fc00::2", "afi": "ipv6"}]} + ] + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "2001:db8:100::/64 does not have a valid nexthop" + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py index 803b51c04327..51eb00ae2184 100644 --- a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py +++ b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py @@ -670,7 +670,11 @@ def bgp_prefix_received_v4_mapped_v6_nh(router): { "nexthops": [ { +<<<<<<< HEAD "ip": "::ffff:a00:501", +======= + "ip": "::ffff:10.0.5.1", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "hostname": "r1", "afi": "ipv6", "scope": "global", @@ -754,7 +758,11 @@ def bgp_prefix_received_v4_mapped_v6_nh(router): assert ( result is None ), "Testcase {} : Failed \n Error: Nexthop for prefix 11.0.20.1 \ +<<<<<<< HEAD is not ::ffff:a00:501".format( +======= + is not ::ffff:10.0.5.1".format( +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tc_name ) diff --git a/tests/topotests/bgp_lu_topo1/R3/bgpd.conf b/tests/topotests/bgp_lu_topo1/R3/bgpd.conf index 31d26ea1ed37..72d9b9d8e165 100644 --- a/tests/topotests/bgp_lu_topo1/R3/bgpd.conf +++ b/tests/topotests/bgp_lu_topo1/R3/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug bgp updates ! diff --git a/tests/topotests/bgp_lu_topo1/R3/zebra.conf b/tests/topotests/bgp_lu_topo1/R3/zebra.conf index ea4a1482dd42..fbd85f82a1dc 100644 --- a/tests/topotests/bgp_lu_topo1/R3/zebra.conf +++ b/tests/topotests/bgp_lu_topo1/R3/zebra.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/zebra.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug zebra events ! debug zebra packet detail diff --git a/tests/topotests/bgp_lu_topo2/R3/bgpd.conf b/tests/topotests/bgp_lu_topo2/R3/bgpd.conf index 6443445b802b..7941534e81ba 100644 --- a/tests/topotests/bgp_lu_topo2/R3/bgpd.conf +++ b/tests/topotests/bgp_lu_topo2/R3/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) no log unique-id ! ! diff --git a/tests/topotests/bgp_lu_topo2/R3/staticd.conf b/tests/topotests/bgp_lu_topo2/R3/staticd.conf index 867fc5a837f4..03ba465ea32f 100644 --- a/tests/topotests/bgp_lu_topo2/R3/staticd.conf +++ b/tests/topotests/bgp_lu_topo2/R3/staticd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/staticd.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) no log unique-id ! ! diff --git a/tests/topotests/bgp_lu_topo2/R3/zebra.conf b/tests/topotests/bgp_lu_topo2/R3/zebra.conf index dd24deb2141d..385f4df7515d 100644 --- a/tests/topotests/bgp_lu_topo2/R3/zebra.conf +++ b/tests/topotests/bgp_lu_topo2/R3/zebra.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/zebra.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) no log unique-id ! ! diff --git a/tests/topotests/bgp_match_peer/r1/frr.conf b/tests/topotests/bgp_match_peer/r1/frr.conf index f30da3b896a2..1d917af751fb 100644 --- a/tests/topotests/bgp_match_peer/r1/frr.conf +++ b/tests/topotests/bgp_match_peer/r1/frr.conf @@ -17,6 +17,10 @@ router bgp 65001 neighbor 192.168.1.2 route-map all in neighbor r3 route-map all in neighbor r4 route-map all in +<<<<<<< HEAD +======= + neighbor r4 route-map r4 out +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) exit-address-family ! route-map all permit 5 @@ -24,7 +28,11 @@ route-map all permit 5 set metric 1 ! route-map all permit 10 +<<<<<<< HEAD match peer 192.168.1.2 +======= + match src-peer 192.168.1.2 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) set metric 2 ! route-map all permit 15 @@ -35,3 +43,9 @@ route-map all permit 20 match peer r4 set metric 4 ! +<<<<<<< HEAD +======= +route-map r4 permit 10 + match src-peer r3 +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/bgp_match_peer/test_bgp_match_peer.py b/tests/topotests/bgp_match_peer/test_bgp_match_peer.py index 4eb7473df0af..cd797165995b 100644 --- a/tests/topotests/bgp_match_peer/test_bgp_match_peer.py +++ b/tests/topotests/bgp_match_peer/test_bgp_match_peer.py @@ -82,6 +82,32 @@ def _bgp_converge(): _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, "Can't converge" +<<<<<<< HEAD +======= + def _bgp_show_advertised_routes(): + output = json.loads( + r1.vtysh_cmd("show bgp ipv4 unicast neighbors r4 advertised-routes json") + ) + expected = { + "advertisedRoutes": { + "10.0.0.3/32": { + "network": "10.0.0.3/32", + "nextHop": "192.168.1.3", + "path": "65003", + } + }, + "totalPrefixCounter": 1, + } + + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_show_advertised_routes, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't filter by source peer" + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_max_med_on_startup/r1/bgpd.conf b/tests/topotests/bgp_max_med_on_startup/r1/bgpd.conf index 41bf96344ad0..c062cb3a6075 100644 --- a/tests/topotests/bgp_max_med_on_startup/r1/bgpd.conf +++ b/tests/topotests/bgp_max_med_on_startup/r1/bgpd.conf @@ -1,6 +1,10 @@ ! router bgp 65001 +<<<<<<< HEAD bgp max-med on-startup 5 777 +======= + bgp max-med on-startup 30 777 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 neighbor 192.168.255.2 timers 3 10 diff --git a/tests/topotests/bgp_max_med_on_startup/test_bgp_max_med_on_startup.py b/tests/topotests/bgp_max_med_on_startup/test_bgp_max_med_on_startup.py index 545d7bd245a9..8dcbac0f40d3 100644 --- a/tests/topotests/bgp_max_med_on_startup/test_bgp_max_med_on_startup.py +++ b/tests/topotests/bgp_max_med_on_startup/test_bgp_max_med_on_startup.py @@ -82,12 +82,20 @@ def _bgp_has_routes(router, metric): # Check session is established test_func = functools.partial(_bgp_converge, router2) +<<<<<<< HEAD _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) +======= + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1.0) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert result is None, "Failed bgp convergence on r2" # Check metric has value of max-med test_func = functools.partial(_bgp_has_routes, router2, 777) +<<<<<<< HEAD _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) +======= + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1.0) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert result is None, "r2 does not receive routes with metric 777" # Check that when the max-med timer expires, metric is updated diff --git a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf index cd7f44ac6650..6defe54db68f 100644 --- a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf +++ b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf @@ -19,10 +19,20 @@ router bgp 100 view 1 timers bgp 60 180 neighbor 172.16.1.1 remote-as 65001 neighbor 172.16.1.1 timers 3 10 +<<<<<<< HEAD neighbor 172.16.1.2 remote-as 65002 neighbor 172.16.1.2 timers 3 10 neighbor 172.16.1.5 remote-as 65005 neighbor 172.16.1.5 timers 3 10 +======= + neighbor 172.16.1.1 timers connect 1 + neighbor 172.16.1.2 remote-as 65002 + neighbor 172.16.1.2 timers 3 10 + neighbor 172.16.1.2 timers connect 1 + neighbor 172.16.1.5 remote-as 65005 + neighbor 172.16.1.5 timers 3 10 + neighbor 172.16.1.5 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 100 view 2 bgp router-id 172.30.1.1 @@ -32,8 +42,15 @@ router bgp 100 view 2 timers bgp 60 180 neighbor 172.16.1.3 remote-as 65003 neighbor 172.16.1.3 timers 3 10 +<<<<<<< HEAD + neighbor 172.16.1.4 remote-as 65004 + neighbor 172.16.1.4 timers 3 10 +======= + neighbor 172.16.1.3 timers connect 1 neighbor 172.16.1.4 remote-as 65004 neighbor 172.16.1.4 timers 3 10 + neighbor 172.16.1.4 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 100 view 3 bgp router-id 172.30.1.1 @@ -43,10 +60,20 @@ router bgp 100 view 3 timers bgp 60 180 neighbor 172.16.1.6 remote-as 65006 neighbor 172.16.1.6 timers 3 10 +<<<<<<< HEAD + neighbor 172.16.1.7 remote-as 65007 + neighbor 172.16.1.7 timers 3 10 + neighbor 172.16.1.8 remote-as 65008 + neighbor 172.16.1.8 timers 3 10 +======= + neighbor 172.16.1.6 timers connect 1 neighbor 172.16.1.7 remote-as 65007 neighbor 172.16.1.7 timers 3 10 + neighbor 172.16.1.7 timers connect 1 neighbor 172.16.1.8 remote-as 65008 neighbor 172.16.1.8 timers 3 10 + neighbor 172.16.1.8 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! route-map local1 permit 10 set community 100:9999 additive diff --git a/tests/topotests/bgp_nexthop_ipv6/r1/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r1/bgpd.conf index 7efa1b79fa5d..9088b835aaa7 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r1/bgpd.conf +++ b/tests/topotests/bgp_nexthop_ipv6/r1/bgpd.conf @@ -2,6 +2,10 @@ router bgp 65000 no bgp ebgp-requires-policy neighbor fd00:0:2::9 remote-as internal neighbor fd00:0:2::9 timers 3 10 +<<<<<<< HEAD +======= + neighbor fd00:0:2::9 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv4 unicast redistribute connected route-map RMAP4 ! diff --git a/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step1.json index 9923edb348da..248fe98c4c08 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step1.json +++ b/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step1.json @@ -22,7 +22,17 @@ "ip": "fd00:0:2::2", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:r2:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -48,7 +58,17 @@ "ip": "fd00:0:2::4", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:r4:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -61,7 +81,17 @@ "ip": "fd00:0:3::5", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -74,7 +104,17 @@ "ip": "fd00:0:4::6", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -100,7 +140,17 @@ "ip": "fd00:0:2::2", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:r2:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -126,7 +176,17 @@ "ip": "fd00:0:2::4", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:r4:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -139,7 +199,17 @@ "ip": "fd00:0:3::5", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -152,7 +222,17 @@ "ip": "fd00:0:4::6", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] diff --git a/tests/topotests/bgp_nexthop_ipv6/r2/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r2/bgpd.conf index 4d4ae44e284b..3b34b9dde985 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r2/bgpd.conf +++ b/tests/topotests/bgp_nexthop_ipv6/r2/bgpd.conf @@ -2,6 +2,10 @@ router bgp 65000 no bgp ebgp-requires-policy neighbor fd00:0:2::9 remote-as internal neighbor fd00:0:2::9 timers 3 10 +<<<<<<< HEAD +======= + neighbor fd00:0:2::9 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv4 unicast redistribute connected route-map RMAP4 ! diff --git a/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step1.json index bb2efa16d9e8..d5c628218e94 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step1.json +++ b/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step1.json @@ -9,7 +9,17 @@ "ip": "fd00:0:2::1", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:r1:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -48,7 +58,17 @@ "ip": "fd00:0:2::4", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:r4:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -61,7 +81,17 @@ "ip": "fd00:0:3::5", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -74,7 +104,17 @@ "ip": "fd00:0:4::6", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -87,7 +127,17 @@ "ip": "fd00:0:2::1", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:r1:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -126,7 +176,17 @@ "ip": "fd00:0:2::4", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:r4:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -139,7 +199,17 @@ "ip": "fd00:0:3::5", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -152,7 +222,17 @@ "ip": "fd00:0:4::6", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-sw", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] diff --git a/tests/topotests/bgp_nexthop_ipv6/r4/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r4/bgpd.conf index b14c9bace4a6..e1404762fa10 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r4/bgpd.conf +++ b/tests/topotests/bgp_nexthop_ipv6/r4/bgpd.conf @@ -2,6 +2,10 @@ router bgp 65001 no bgp ebgp-requires-policy neighbor fd00:0:2::9 remote-as external neighbor fd00:0:2::9 timers 3 10 +<<<<<<< HEAD +======= + neighbor fd00:0:2::9 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv4 unicast redistribute connected route-map RMAP4 ! diff --git a/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step2.json index 35a31e63f921..31eb7a4ff30f 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step2.json +++ b/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step2.json @@ -9,6 +9,7 @@ "ip": "fd00:0:2::1", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -16,6 +17,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -28,6 +32,7 @@ "ip": "fd00:0:2::2", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -35,6 +40,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -47,6 +55,7 @@ "ip": "fd00:0:2::3", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -54,6 +63,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -117,6 +129,7 @@ "ip": "fd00:0:2::1", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -124,6 +137,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -136,6 +152,7 @@ "ip": "fd00:0:2::2", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -143,6 +160,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -155,6 +175,7 @@ "ip": "fd00:0:2::3", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -162,6 +183,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] diff --git a/tests/topotests/bgp_nexthop_ipv6/r5/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r5/bgpd.conf index becea2bbe648..d04730a576eb 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r5/bgpd.conf +++ b/tests/topotests/bgp_nexthop_ipv6/r5/bgpd.conf @@ -2,6 +2,10 @@ router bgp 65002 no bgp ebgp-requires-policy neighbor fd00:0:3::9 remote-as external neighbor fd00:0:3::9 timers 3 10 +<<<<<<< HEAD +======= + neighbor fd00:0:3::9 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv4 unicast redistribute connected route-map RMAP4 ! diff --git a/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step1.json index d0875474ae94..62b14650bbcf 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step1.json +++ b/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step1.json @@ -47,6 +47,7 @@ "ip": "fd00:0:3::9", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -54,6 +55,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -155,6 +159,7 @@ "ip": "fd00:0:3::9", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -162,6 +167,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] diff --git a/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step2.json index d0875474ae94..37bb0ea7c0ad 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step2.json +++ b/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step2.json @@ -9,6 +9,7 @@ "ip": "fd00:0:3::9", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -16,6 +17,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -28,6 +32,7 @@ "ip": "fd00:0:3::9", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -35,6 +40,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -47,6 +55,7 @@ "ip": "fd00:0:3::9", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -54,6 +63,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -117,6 +129,7 @@ "ip": "fd00:0:3::9", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -124,6 +137,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -136,6 +152,7 @@ "ip": "fd00:0:3::9", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -143,6 +160,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -155,6 +175,7 @@ "ip": "fd00:0:3::9", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global" }, { @@ -162,6 +183,9 @@ "hostname": "rr", "afi": "ipv6", "scope": "link-local", +======= + "scope": "global", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] diff --git a/tests/topotests/bgp_nexthop_ipv6/r6/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r6/bgpd.conf index 801736ab988e..b087b1ca983c 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r6/bgpd.conf +++ b/tests/topotests/bgp_nexthop_ipv6/r6/bgpd.conf @@ -2,6 +2,10 @@ router bgp 65000 no bgp ebgp-requires-policy neighbor fd00:0:4::9 remote-as internal neighbor fd00:0:4::9 timers 3 10 +<<<<<<< HEAD +======= + neighbor fd00:0:4::9 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv4 unicast redistribute connected route-map RMAP4 ! diff --git a/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step1.json index cd48dd4697ce..b161fa5bb235 100644 --- a/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step1.json +++ b/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step1.json @@ -9,7 +9,17 @@ "ip": "fd00:0:2::1", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-r6", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -22,7 +32,17 @@ "ip": "fd00:0:2::2", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-r6", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -48,7 +68,17 @@ "ip": "fd00:0:2::4", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-r6", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -61,7 +91,17 @@ "ip": "fd00:0:3::5", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-r6", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -87,7 +127,17 @@ "ip": "fd00:0:2::1", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-r6", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -100,7 +150,17 @@ "ip": "fd00:0:2::2", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-r6", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -126,7 +186,17 @@ "ip": "fd00:0:2::4", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-r6", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] @@ -139,7 +209,17 @@ "ip": "fd00:0:3::5", "hostname": "rr", "afi": "ipv6", +<<<<<<< HEAD "scope": "global", +======= + "scope": "global" + }, + { + "ip": "link-local:rr:eth-r6", + "hostname": "rr", + "afi": "ipv6", + "scope": "link-local", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "used": true } ] diff --git a/tests/topotests/bgp_nexthop_ipv6/rr/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/rr/bgpd.conf index 6dcded15258c..8d4cbee67b0e 100644 --- a/tests/topotests/bgp_nexthop_ipv6/rr/bgpd.conf +++ b/tests/topotests/bgp_nexthop_ipv6/rr/bgpd.conf @@ -2,6 +2,7 @@ router bgp 65000 no bgp ebgp-requires-policy neighbor fd00:0:2::1 remote-as internal neighbor fd00:0:2::1 timers 3 10 +<<<<<<< HEAD neighbor fd00:0:2::2 remote-as internal neighbor fd00:0:2::2 timers 3 10 neighbor fd00:0:2::3 remote-as internal @@ -12,6 +13,24 @@ router bgp 65000 neighbor fd00:0:3::5 timers 3 10 neighbor fd00:0:4::6 remote-as internal neighbor fd00:0:4::6 timers 3 10 +======= + neighbor fd00:0:2::1 timers connect 1 + neighbor fd00:0:2::2 remote-as internal + neighbor fd00:0:2::2 timers 3 10 + neighbor fd00:0:2::2 timers connect 1 + neighbor fd00:0:2::3 remote-as internal + neighbor fd00:0:2::3 timers 3 10 + neighbor fd00:0:2::3 timers connect 1 + neighbor fd00:0:2::4 remote-as external + neighbor fd00:0:2::4 timers 3 10 + neighbor fd00:0:2::4 timers connect 1 + neighbor fd00:0:3::5 remote-as external + neighbor fd00:0:3::5 timers 3 10 + neighbor fd00:0:3::5 timers connect 1 + neighbor fd00:0:4::6 remote-as internal + neighbor fd00:0:4::6 timers 3 10 + neighbor fd00:0:4::6 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv4 unicast neighbor fd00:0:2::1 route-reflector-client neighbor fd00:0:2::2 route-reflector-client @@ -19,12 +38,28 @@ router bgp 65000 neighbor fd00:0:4::6 route-reflector-client address-family ipv6 unicast neighbor fd00:0:2::1 route-reflector-client +<<<<<<< HEAD + neighbor fd00:0:2::1 activate + neighbor fd00:0:2::2 route-reflector-client + neighbor fd00:0:2::2 activate + neighbor fd00:0:2::3 route-reflector-client + neighbor fd00:0:2::3 activate + neighbor fd00:0:2::4 nexthop-local unchanged + neighbor fd00:0:2::4 activate + neighbor fd00:0:3::5 activate +======= + neighbor fd00:0:2::1 nexthop-local unchanged neighbor fd00:0:2::1 activate neighbor fd00:0:2::2 route-reflector-client + neighbor fd00:0:2::2 nexthop-local unchanged neighbor fd00:0:2::2 activate neighbor fd00:0:2::3 route-reflector-client + neighbor fd00:0:2::3 nexthop-local unchanged neighbor fd00:0:2::3 activate neighbor fd00:0:2::4 nexthop-local unchanged neighbor fd00:0:2::4 activate + neighbor fd00:0:3::5 nexthop-local unchanged neighbor fd00:0:3::5 activate + neighbor fd00:0:4::6 nexthop-local unchanged +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) neighbor fd00:0:4::6 activate diff --git a/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py b/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py index 24d71f5622ae..4f960cb58f0a 100644 --- a/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py +++ b/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py @@ -36,7 +36,11 @@ def build_topo(tgen): +<<<<<<< HEAD """ +======= + r""" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) All peers are FRR BGP peers except r3 that is a exabgp peer. rr is a route-reflector for AS 65000 iBGP peers. Exabgp does not send any IPv6 Link-Local nexthop @@ -165,6 +169,24 @@ def replace_link_local(expected, cache): nexthop["ip"] = ip +<<<<<<< HEAD +======= +def check_rr_sub_group(expected): + tgen = get_topogen() + + rr = tgen.gears["rr"] + + output = json.loads(rr.vtysh_cmd("show bgp update-groups json")) + actual = [ + subgroup["peers"] + for entry in output.get("default", {}).values() + for subgroup in entry["subGroup"] + ] + + return topotest.json_cmp(actual, expected) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def teardown_module(_mod): "Teardown the pytest environment" tgen = get_topogen() @@ -207,7 +229,10 @@ def test_bgp_ipv6_table_step1(): link_local_cache = {} router_list = tgen.routers().values() for router in router_list: +<<<<<<< HEAD # router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name) +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name) expected = json.loads(open(ref_file).read()) replace_link_local(expected, link_local_cache) @@ -222,6 +247,22 @@ def test_bgp_ipv6_table_step1(): assertmsg = "{}: BGP IPv6 Nexthop failure".format(router.name) assert res is None, assertmsg +<<<<<<< HEAD +======= + # check rr sub-groups + expected = [ + ["fd00:0:2::1", "fd00:0:2::2"], + ["fd00:0:2::3"], + ["fd00:0:2::4"], + ["fd00:0:3::5"], + ["fd00:0:4::6"], + ] + + test_func = partial(check_rr_sub_group, expected) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Peer group split failed" + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_bgp_ipv6_table_step2(): tgen = get_topogen() @@ -236,13 +277,25 @@ def test_bgp_ipv6_table_step2(): configure terminal router bgp 65000 address-family ipv6 unicast +<<<<<<< HEAD no neighbor fd00:0:2::4 nexthop-local unchanged +======= + no neighbor fd00:0:2::1 nexthop-local unchanged + no neighbor fd00:0:2::2 nexthop-local unchanged + no neighbor fd00:0:2::3 nexthop-local unchanged + no neighbor fd00:0:2::4 nexthop-local unchanged + no neighbor fd00:0:3::5 nexthop-local unchanged + no neighbor fd00:0:4::6 nexthop-local unchanged +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) """ ) router_list = tgen.routers().values() for router in router_list: +<<<<<<< HEAD # router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name) +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ref_file = "{}/{}/show_bgp_ipv6_step2.json".format(CWD, router.name) expected = json.loads(open(ref_file).read()) replace_link_local(expected, link_local_cache) @@ -257,6 +310,73 @@ def test_bgp_ipv6_table_step2(): assertmsg = "{}: BGP IPv6 Nexthop failure".format(router.name) assert res is None, assertmsg +<<<<<<< HEAD +======= + # check rr sub-groups + expected = [ + ["fd00:0:2::1", "fd00:0:2::2"], + ["fd00:0:2::3"], + ["fd00:0:3::5", "fd00:0:2::4"], + ["fd00:0:4::6"], + ] + + test_func = partial(check_rr_sub_group, expected) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Peer group split failed" + + +def test_bgp_ipv6_table_step3(): + tgen = get_topogen() + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + rr = tgen.gears["rr"] + rr.vtysh_cmd( + """ +configure terminal +router bgp 65000 + address-family ipv6 unicast + neighbor fd00:0:2::1 nexthop-local unchanged + neighbor fd00:0:2::2 nexthop-local unchanged + neighbor fd00:0:2::3 nexthop-local unchanged + neighbor fd00:0:2::4 nexthop-local unchanged + neighbor fd00:0:3::5 nexthop-local unchanged + neighbor fd00:0:4::6 nexthop-local unchanged +""" + ) + + router_list = tgen.routers().values() + for router in router_list: + ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name) + expected = json.loads(open(ref_file).read()) + replace_link_local(expected, link_local_cache) + + test_func = partial( + topotest.router_json_cmp, + router, + "show bgp ipv6 unicast json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = "{}: BGP IPv6 Nexthop failure".format(router.name) + assert res is None, assertmsg + + # check rr sub-groups + expected = [ + ["fd00:0:2::1", "fd00:0:2::2"], + ["fd00:0:2::3"], + ["fd00:0:2::4"], + ["fd00:0:3::5"], + ["fd00:0:4::6"], + ] + + test_func = partial(check_rr_sub_group, expected) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Peer group split failed" + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_path_attribute_discard/r1/frr.conf b/tests/topotests/bgp_path_attribute_discard/r1/frr.conf index ae7fbdd9a93a..106528a31ca1 100644 --- a/tests/topotests/bgp_path_attribute_discard/r1/frr.conf +++ b/tests/topotests/bgp_path_attribute_discard/r1/frr.conf @@ -6,4 +6,8 @@ router bgp 65001 no bgp ebgp-requires-policy neighbor 10.0.0.254 remote-as external neighbor 10.0.0.254 timers 3 10 +<<<<<<< HEAD +======= + neighbor 10.0.0.254 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! diff --git a/tests/topotests/bgp_path_attribute_discard/r2/frr.conf b/tests/topotests/bgp_path_attribute_discard/r2/frr.conf index 1dafbdd8e19f..ba9674e0b7a0 100644 --- a/tests/topotests/bgp_path_attribute_discard/r2/frr.conf +++ b/tests/topotests/bgp_path_attribute_discard/r2/frr.conf @@ -6,5 +6,9 @@ router bgp 65254 no bgp ebgp-requires-policy neighbor 10.0.0.254 remote-as internal neighbor 10.0.0.254 timers 3 10 +<<<<<<< HEAD +======= + neighbor 10.0.0.254 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) neighbor 10.0.0.254 path-attribute discard 26 ! diff --git a/tests/topotests/bgp_peer_group/r1/frr.conf b/tests/topotests/bgp_peer_group/r1/frr.conf index 035c8e4cf16e..bb6156e6cf50 100644 --- a/tests/topotests/bgp_peer_group/r1/frr.conf +++ b/tests/topotests/bgp_peer_group/r1/frr.conf @@ -5,6 +5,12 @@ interface r1-eth0 interface r1-eth1 ip address 192.168.251.1/30 ! +<<<<<<< HEAD +======= +interface r1-eth2 + ip address 192.168.252.1/30 +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ip forwarding ! router bgp 65001 @@ -17,5 +23,13 @@ router bgp 65001 neighbor PG1 remote-as external neighbor PG1 timers 3 20 neighbor PG1 graceful-restart-disable +<<<<<<< HEAD + neighbor 192.168.251.2 peer-group PG1 +======= + neighbor PG2 peer-group + neighbor PG2 local-as 65554 no-prepend replace-as neighbor 192.168.251.2 peer-group PG1 + neighbor 192.168.252.2 remote-as 65004 + neighbor 192.168.252.2 peer-group PG2 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! diff --git a/tests/topotests/bgp_peer_group/r4/frr.conf b/tests/topotests/bgp_peer_group/r4/frr.conf new file mode 100644 index 000000000000..b1da90f0644e --- /dev/null +++ b/tests/topotests/bgp_peer_group/r4/frr.conf @@ -0,0 +1,7 @@ +! +interface r4-eth0 + ip address 192.168.252.2/30 +! +router bgp 65004 + neighbor 192.168.252.1 remote-as external +! diff --git a/tests/topotests/bgp_peer_group/test_bgp_peer-group.py b/tests/topotests/bgp_peer_group/test_bgp_peer-group.py index 45f713b8a240..4d7869495f94 100644 --- a/tests/topotests/bgp_peer_group/test_bgp_peer-group.py +++ b/tests/topotests/bgp_peer_group/test_bgp_peer-group.py @@ -30,7 +30,11 @@ def build_topo(tgen): +<<<<<<< HEAD for routern in range(1, 4): +======= + for routern in range(1, 5): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tgen.add_router("r{}".format(routern)) switch = tgen.add_switch("s1") @@ -42,6 +46,13 @@ def build_topo(tgen): switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r2"]) +<<<<<<< HEAD +======= + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r4"]) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) @@ -84,6 +95,14 @@ def _bgp_peer_group_configured(): "bgpState": "Established", "neighborCapabilities": {"gracefulRestart": "received"}, }, +<<<<<<< HEAD +======= + "192.168.252.2": { + "peerGroup": "PG2", + "bgpState": "Established", + "neighborCapabilities": {"gracefulRestart": "advertisedAndReceived"}, + }, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return topotest.json_cmp(output, expected) @@ -110,6 +129,27 @@ def _bgp_peer_group_check_advertised_routes(): assert result is None, "Failed checking advertised routes from r3" +<<<<<<< HEAD +======= +def test_show_running_remote_as_peer_group(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + output = ( + tgen.gears["r1"] + .cmd( + 'vtysh -c "show running bgpd" | grep "^ neighbor 192.168.252.2 remote-as 65004"' + ) + .rstrip() + ) + assert ( + output == " neighbor 192.168.252.2 remote-as 65004" + ), "192.168.252.2 remote-as is flushed" + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_bgp_peer_group_remote_as_del_readd(): tgen = get_topogen() diff --git a/tests/topotests/bgp_peer_type_multipath_relax/r1/bgpd.conf b/tests/topotests/bgp_peer_type_multipath_relax/r1/bgpd.conf index 038f108aa8b2..6b092c569a65 100644 --- a/tests/topotests/bgp_peer_type_multipath_relax/r1/bgpd.conf +++ b/tests/topotests/bgp_peer_type_multipath_relax/r1/bgpd.conf @@ -8,9 +8,23 @@ router bgp 64510 bgp bestpath compare-routerid bgp bestpath peer-type multipath-relax neighbor 10.0.1.2 remote-as 64510 +<<<<<<< HEAD neighbor 10.0.3.2 remote-as 64502 neighbor 10.0.4.2 remote-as 64503 neighbor 10.0.5.2 remote-as 64511 +======= + neighbor 10.0.1.2 timers 3 10 + neighbor 10.0.1.2 timers connect 1 + neighbor 10.0.3.2 remote-as 64502 + neighbor 10.0.3.2 timers 3 10 + neighbor 10.0.3.2 timers connect 1 + neighbor 10.0.4.2 remote-as 64503 + neighbor 10.0.4.2 timers 3 10 + neighbor 10.0.4.2 timers connect 1 + neighbor 10.0.5.2 remote-as 64511 + neighbor 10.0.5.2 timers 3 10 + neighbor 10.0.5.2 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! line vty ! diff --git a/tests/topotests/bgp_peer_type_multipath_relax/r2/bgpd.conf b/tests/topotests/bgp_peer_type_multipath_relax/r2/bgpd.conf index 2362a19f265a..7c5242e1d869 100644 --- a/tests/topotests/bgp_peer_type_multipath_relax/r2/bgpd.conf +++ b/tests/topotests/bgp_peer_type_multipath_relax/r2/bgpd.conf @@ -7,7 +7,15 @@ router bgp 64511 bgp router-id 10.0.5.2 no bgp ebgp-requires-policy neighbor 10.0.2.2 remote-as 64511 +<<<<<<< HEAD neighbor 10.0.5.1 remote-as 64510 +======= + neighbor 10.0.2.2 timers 3 10 + neighbor 10.0.2.2 timers connect 1 + neighbor 10.0.5.1 remote-as 64510 + neighbor 10.0.5.1 timers 3 10 + neighbor 10.0.5.1 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! address-family ipv4 unicast neighbor 10.0.5.1 route-map dropall in diff --git a/tests/topotests/bgp_prefix_sid/r1/bgpd.conf b/tests/topotests/bgp_prefix_sid/r1/bgpd.conf index e02226f2fd64..ba8c0df152b6 100644 --- a/tests/topotests/bgp_prefix_sid/r1/bgpd.conf +++ b/tests/topotests/bgp_prefix_sid/r1/bgpd.conf @@ -7,8 +7,15 @@ router bgp 1 no bgp ebgp-requires-policy neighbor 10.0.0.101 remote-as 2 neighbor 10.0.0.101 timers 3 10 +<<<<<<< HEAD neighbor 10.0.0.102 remote-as 3 neighbor 10.0.0.102 timers 3 10 +======= + neighbor 10.0.0.101 timers connect 1 + neighbor 10.0.0.102 remote-as 3 + neighbor 10.0.0.102 timers 3 10 + neighbor 10.0.0.102 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! address-family ipv4 labeled-unicast neighbor 10.0.0.101 activate diff --git a/tests/topotests/bgp_prefix_sid2/r1/bgpd.conf b/tests/topotests/bgp_prefix_sid2/r1/bgpd.conf index b3ca0e114d17..63ec986fd2b7 100644 --- a/tests/topotests/bgp_prefix_sid2/r1/bgpd.conf +++ b/tests/topotests/bgp_prefix_sid2/r1/bgpd.conf @@ -18,6 +18,10 @@ router bgp 1 no bgp ebgp-requires-policy neighbor 10.0.0.101 remote-as 2 neighbor 10.0.0.101 timers 3 10 +<<<<<<< HEAD +======= + neighbor 10.0.0.101 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! address-family ipv6 vpn neighbor 10.0.0.101 activate diff --git a/tests/topotests/bgp_route_server_client/exabgp.env b/tests/topotests/bgp_route_server_client/exabgp.env new file mode 100644 index 000000000000..28e642360a39 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/exabgp.env @@ -0,0 +1,53 @@ +[exabgp.api] +encoder = text +highres = false +respawn = false +socket = '' + +[exabgp.bgp] +openwait = 60 + +[exabgp.cache] +attributes = true +nexthops = true + +[exabgp.daemon] +daemonize = true +pid = '/var/run/exabgp/exabgp.pid' +user = 'exabgp' +##daemonize = false + +[exabgp.log] +all = false +configuration = true +daemon = true +destination = '/var/log/exabgp.log' +enable = true +level = INFO +message = false +network = true +packets = false +parser = false +processes = true +reactor = true +rib = false +routes = false +short = false +timers = false + +[exabgp.pdb] +enable = false + +[exabgp.profile] +enable = false +file = '' + +[exabgp.reactor] +speed = 1.0 + +[exabgp.tcp] +acl = false +bind = '' +delay = 0 +once = false +port = 179 diff --git a/tests/topotests/bgp_route_server_client/r1/bgpd.conf b/tests/topotests/bgp_route_server_client/r1/bgpd.conf index e464e6c50b88..c0ccb01ba4d9 100644 --- a/tests/topotests/bgp_route_server_client/r1/bgpd.conf +++ b/tests/topotests/bgp_route_server_client/r1/bgpd.conf @@ -5,7 +5,11 @@ router bgp 65001 no bgp enforce-first-as neighbor 2001:db8:1::1 remote-as external neighbor 2001:db8:1::1 timers 3 10 +<<<<<<< HEAD neighbor 2001:db8:1::1 timers connect 5 +======= + neighbor 2001:db8:1::1 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv6 unicast redistribute connected neighbor 2001:db8:1::1 activate diff --git a/tests/topotests/bgp_route_server_client/r1/show_bgp_ipv6_step1.json b/tests/topotests/bgp_route_server_client/r1/show_bgp_ipv6_step1.json new file mode 100644 index 000000000000..387d7b3374b7 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r1/show_bgp_ipv6_step1.json @@ -0,0 +1,95 @@ +{ + "routerId": "10.10.10.1", + "localAS": 65001, + "routes": { + "2001:db8:1::/64": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::1/128": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::3/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::4/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::5/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_route_server_client/r1/show_bgp_ipv6_step2.json b/tests/topotests/bgp_route_server_client/r1/show_bgp_ipv6_step2.json new file mode 100644 index 000000000000..f9e68b897723 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r1/show_bgp_ipv6_step2.json @@ -0,0 +1,113 @@ +{ + "routerId": "10.10.10.1", + "localAS": 65001, + "routes": { + "2001:db8:1::/64": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r2:r2-eth0", + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::1/128": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::3/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r2:r2-eth0", + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::4/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::5/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_route_server_client/r2/bgpd.conf b/tests/topotests/bgp_route_server_client/r2/bgpd.conf index 3b0a24b8ba5b..dbec0aa7d971 100644 --- a/tests/topotests/bgp_route_server_client/r2/bgpd.conf +++ b/tests/topotests/bgp_route_server_client/r2/bgpd.conf @@ -3,6 +3,7 @@ router bgp 65000 view RS no bgp ebgp-requires-policy neighbor 2001:db8:1::2 remote-as external neighbor 2001:db8:1::2 timers 3 10 +<<<<<<< HEAD neighbor 2001:db8:1::2 timers connect 5 neighbor 2001:db8:3::2 remote-as external neighbor 2001:db8:3::2 timers 3 10 @@ -12,6 +13,27 @@ router bgp 65000 view RS neighbor 2001:db8:1::2 activate neighbor 2001:db8:3::2 activate neighbor 2001:db8:1::2 route-server-client +======= + neighbor 2001:db8:1::2 timers connect 1 + neighbor 2001:db8:1::3 remote-as external + neighbor 2001:db8:1::3 timers 3 10 + neighbor 2001:db8:1::3 timers connect 1 + neighbor 2001:db8:1::4 remote-as external + neighbor 2001:db8:1::4 timers 3 10 + neighbor 2001:db8:1::4 timers connect 1 + neighbor 2001:db8:3::2 remote-as external + neighbor 2001:db8:3::2 timers 3 10 + neighbor 2001:db8:3::2 timers connect 1 + address-family ipv6 unicast + redistribute connected + neighbor 2001:db8:1::2 activate + neighbor 2001:db8:1::3 activate + neighbor 2001:db8:1::4 activate + neighbor 2001:db8:3::2 activate + neighbor 2001:db8:1::2 route-server-client + neighbor 2001:db8:1::3 route-server-client + neighbor 2001:db8:1::4 route-server-client +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) neighbor 2001:db8:3::2 route-server-client exit-address-family ! diff --git a/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_step1.json b/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_step1.json new file mode 100644 index 000000000000..c2f31f8c32ed --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_step1.json @@ -0,0 +1,208 @@ +{ + "routerId": "10.10.10.2", + "localAS": 65000, + "routes": { + "2001:db8:1::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r1", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r1", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r4", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r4", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r3", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r3:r3-eth0", + "hostname": "r3", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::1/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r1", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r1", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r4", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r4", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::3/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r3", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r3:r3-eth0", + "hostname": "r3", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::4/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r4", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r4", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r1", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r1", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::5/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r1", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r1", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r4", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r4", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_step2.json b/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_step2.json new file mode 100644 index 000000000000..c2f31f8c32ed --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_step2.json @@ -0,0 +1,208 @@ +{ + "routerId": "10.10.10.2", + "localAS": 65000, + "routes": { + "2001:db8:1::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r1", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r1", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r4", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r4", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r3", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r3:r3-eth0", + "hostname": "r3", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::1/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r1", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r1", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r4", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r4", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::3/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r3", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r3:r3-eth0", + "hostname": "r3", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::4/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r4", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r4", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r1", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r1", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::5/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r1", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r1", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r4", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r4:r4-eth0", + "hostname": "r4", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_summary.json b/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_summary.json new file mode 100644 index 000000000000..8a42a11c47a9 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r2/show_bgp_ipv6_summary.json @@ -0,0 +1,6 @@ +{ + "ipv6Unicast": { + "failedPeers": 0, + "totalPeers": 4 + } +} diff --git a/tests/topotests/bgp_route_server_client/r3/bgpd.conf b/tests/topotests/bgp_route_server_client/r3/bgpd.conf index 60a5ffc559a0..db8ad7fc2770 100644 --- a/tests/topotests/bgp_route_server_client/r3/bgpd.conf +++ b/tests/topotests/bgp_route_server_client/r3/bgpd.conf @@ -2,9 +2,16 @@ router bgp 65003 bgp router-id 10.10.10.3 no bgp ebgp-requires-policy +<<<<<<< HEAD neighbor 2001:db8:3::1 remote-as external neighbor 2001:db8:3::1 timers 3 10 neighbor 2001:db8:3::1 timers connect 5 +======= + no bgp enforce-first-as + neighbor 2001:db8:3::1 remote-as external + neighbor 2001:db8:3::1 timers 3 10 + neighbor 2001:db8:3::1 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) address-family ipv6 unicast redistribute connected neighbor 2001:db8:3::1 activate diff --git a/tests/topotests/bgp_route_server_client/r3/show_bgp_ipv6_step1.json b/tests/topotests/bgp_route_server_client/r3/show_bgp_ipv6_step1.json new file mode 100644 index 000000000000..bf8d74801dc3 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r3/show_bgp_ipv6_step1.json @@ -0,0 +1,84 @@ +{ + "routerId": "10.10.10.3", + "localAS": 65003, + "routes": { + "2001:db8:1::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r3", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::1/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::3/128": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r3", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::4/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::5/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_route_server_client/r3/show_bgp_ipv6_step2.json b/tests/topotests/bgp_route_server_client/r3/show_bgp_ipv6_step2.json new file mode 100644 index 000000000000..31c1eb781611 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r3/show_bgp_ipv6_step2.json @@ -0,0 +1,96 @@ +{ + "routerId": "10.10.10.3", + "localAS": 65003, + "routes": { + "2001:db8:1::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r3", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::1/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r2:r2-eth1", + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::3/128": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r3", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::4/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::3", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r2:r2-eth1", + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::5/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_route_server_client/r4/bgpd.conf b/tests/topotests/bgp_route_server_client/r4/bgpd.conf new file mode 100644 index 000000000000..66a15730186f --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r4/bgpd.conf @@ -0,0 +1,13 @@ +! +router bgp 65004 + bgp router-id 10.10.10.4 + no bgp ebgp-requires-policy + no bgp enforce-first-as + neighbor 2001:db8:1::1 remote-as external + neighbor 2001:db8:1::1 timers 3 10 + neighbor 2001:db8:1::1 timers connect 1 + address-family ipv6 unicast + redistribute connected + neighbor 2001:db8:1::1 activate + exit-address-family +! diff --git a/tests/topotests/bgp_route_server_client/r4/show_bgp_ipv6_step1.json b/tests/topotests/bgp_route_server_client/r4/show_bgp_ipv6_step1.json new file mode 100644 index 000000000000..5c090d9cf947 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r4/show_bgp_ipv6_step1.json @@ -0,0 +1,95 @@ +{ + "routerId": "10.10.10.4", + "localAS": 65004, + "routes": { + "2001:db8:1::/64": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r4", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::1/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::3/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::4/128": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r4", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::5/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_route_server_client/r4/show_bgp_ipv6_step2.json b/tests/topotests/bgp_route_server_client/r4/show_bgp_ipv6_step2.json new file mode 100644 index 000000000000..01db18e926d4 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r4/show_bgp_ipv6_step2.json @@ -0,0 +1,113 @@ +{ + "routerId": "10.10.10.4", + "localAS": 65004, + "routes": { + "2001:db8:1::/64": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r4", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r2:r2-eth0", + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::1/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r1:r1-eth0", + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::3/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:3::2", + "hostname": "r2", + "afi": "ipv6", + "scope": "global" + }, + { + "ip": "link-local:r2:r2-eth0", + "hostname": "r2", + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "2001:db8:f::4/128": [ + { + "nexthops": [ + { + "ip": "::", + "hostname": "r4", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "2001:db8:f::5/128": [ + { + "nexthops": [ + { + "ip": "2001:db8:1::4", + "hostname": "r2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_route_server_client/r4/zebra.conf b/tests/topotests/bgp_route_server_client/r4/zebra.conf new file mode 100644 index 000000000000..849884045d98 --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r4/zebra.conf @@ -0,0 +1,7 @@ +! +int lo + ipv6 address 2001:db8:f::4/128 +! +int r4-eth0 + ipv6 address 2001:db8:1::3/64 +! diff --git a/tests/topotests/bgp_route_server_client/r5/exabgp.cfg b/tests/topotests/bgp_route_server_client/r5/exabgp.cfg new file mode 100644 index 000000000000..b151f16caaeb --- /dev/null +++ b/tests/topotests/bgp_route_server_client/r5/exabgp.cfg @@ -0,0 +1,16 @@ +neighbor 2001:db8:1::1{ + router-id 10.10.10.5; + local-address 2001:db8:1::4; + local-as 65005; + peer-as 65000; + + family { + ipv6 unicast; + } + + static { + route 2001:db8:1::0/64 next-hop 2001:db8:1::4; + route 2001:db8:f::5/128 next-hop 2001:db8:1::4; + } + hold-time 10; +} diff --git a/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py b/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py index 29d9842d59dd..4512103df36a 100644 --- a/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py +++ b/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py @@ -13,6 +13,10 @@ import sys import json import pytest +<<<<<<< HEAD +======= +from functools import partial +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) import functools pytestmark = [pytest.mark.bgpd] @@ -26,6 +30,7 @@ def build_topo(tgen): +<<<<<<< HEAD for routern in range(1, 4): tgen.add_router("r{}".format(routern)) @@ -36,6 +41,51 @@ def build_topo(tgen): switch = tgen.add_switch("s2") switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r3"]) +======= + """ + All peers are FRR BGP peers except r5 that is a exabgp peer. + Exabgp does not send any IPv6 Link-Local nexthop + + r2 is a route-server view RS AS 65000 + Other routers rX has AS 6500X + + +---+ + | r3| + +---+ + | + 2001:db8:3::0/64 + | + eth1 + +---+ + |r2 | + +---+ + eth0 + | + 2001:db8:1::0/64 + / | \ + +---+ +---+ +---+ + | r1| | r4| |r5 | + +---+ +---+ +---+ + """ + + for routern in range(1, 5): + tgen.add_router("r{}".format(routern)) + + sw1 = tgen.add_switch("s1") + sw1.add_link(tgen.gears["r1"]) + sw1.add_link(tgen.gears["r2"]) + sw1.add_link(tgen.gears["r4"]) + + sw2 = tgen.add_switch("s2") + sw2.add_link(tgen.gears["r2"]) + sw2.add_link(tgen.gears["r3"]) + + ## Add iBGP ExaBGP neighbor + peer_ip = "2001:db8:1::4" ## peer + peer_route = "via 2001:db8:1::1" ## router + r5 = tgen.add_exabgp_peer("r5", ip=peer_ip, defaultRoute=peer_route) + sw1.add_link(r5) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def setup_module(mod): @@ -54,18 +104,134 @@ def setup_module(mod): tgen.start_router() +<<<<<<< HEAD +======= + # Start r5 exabgp peer + r5 = tgen.gears["r5"] + r5.start(os.path.join(CWD, "r5"), os.path.join(CWD, "exabgp.env")) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def teardown_module(mod): tgen = get_topogen() tgen.stop_topology() +<<<<<<< HEAD def test_bgp_route_server_client(): +======= +def get_link_local(rname, ifname, cache): + ip = cache.get(rname, {}).get(ifname) + if ip: + return ip + + tgen = get_topogen() + out = tgen.gears[rname].vtysh_cmd("show interface %s json" % ifname, isjson=True) + for address in out[ifname]["ipAddresses"]: + if not address["address"].startswith("fe80::"): + continue + ip = address["address"].split("/")[0] + cache.setdefault(rname, {})[ifname] = ip + return ip + + +def replace_link_local(expected, cache): + for prefix, prefix_infos in expected.get("routes", {}).items(): + for prefix_info in prefix_infos: + for nexthop in prefix_info.get("nexthops", []): + ip = nexthop.get("ip", "") + if not ip.startswith("link-local:"): + continue + rname = ip.split(":")[1] + ifname = ip.split(":")[2] + ip = get_link_local(rname, ifname, cache) + nexthop["ip"] = ip + + +def check_r2_sub_group(expected): + tgen = get_topogen() + + r2 = tgen.gears["r2"] + + output = json.loads(r2.vtysh_cmd("show bgp view RS update-groups json")) + actual = [ + subgroup["peers"] + for entry in output.get("RS", {}).values() + for subgroup in entry["subGroup"] + ] + + return topotest.json_cmp(actual, expected) + + +def test_converge_protocols(): + "Wait for protocol convergence" + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r2 = tgen.gears["r2"] + ref_file = "{}/{}/show_bgp_ipv6_summary.json".format(CWD, r2.name) + expected = json.loads(open(ref_file).read()) + + test_func = partial( + topotest.router_json_cmp, + r2, + "show bgp view RS ipv6 summary json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = "{}: BGP convergence failed".format(r2.name) + assert res is None, assertmsg + + +def test_bgp_route_server_client_step1(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + global link_local_cache + link_local_cache = {} + router_list = tgen.routers().values() + for router in router_list: + if router.name == "r2": + # route-server + cmd = "show bgp view RS ipv6 unicast json" + else: + cmd = "show bgp ipv6 unicast json" + + ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name) + expected = json.loads(open(ref_file).read()) + replace_link_local(expected, link_local_cache) + + test_func = partial( + topotest.router_json_cmp, + router, + cmd, + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = "{}: BGP IPv6 table failure".format(router.name) + assert res is None, assertmsg + + # check r2 sub-groups + expected = [["2001:db8:1::4"], ["2001:db8:1::3", "2001:db8:1::2", "2001:db8:3::2"]] + + test_func = functools.partial(check_r2_sub_group, expected) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Peer group split failed" + + +def test_bgp_route_server_client_step2(): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD r1 = tgen.gears["r1"] r2 = tgen.gears["r2"] @@ -121,6 +287,104 @@ def _bgp_gua_lla_next_hop(router): test_func = functools.partial(_bgp_gua_lla_next_hop, r2) _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Cannot see BGP LLA next hop from r3 in r2" +======= + r2 = tgen.gears["r2"] + r2.vtysh_cmd( + """ +configure terminal +router bgp 65000 view RS + address-family ipv6 unicast + neighbor 2001:db8:1::2 nexthop-local unchanged + neighbor 2001:db8:1::3 nexthop-local unchanged + neighbor 2001:db8:1::4 nexthop-local unchanged + neighbor 2001:db8:3::2 nexthop-local unchanged +""" + ) + + router_list = tgen.routers().values() + for router in router_list: + if router.name == "r2": + # route-server + cmd = "show bgp view RS ipv6 unicast json" + else: + cmd = "show bgp ipv6 unicast json" + + ref_file = "{}/{}/show_bgp_ipv6_step2.json".format(CWD, router.name) + expected = json.loads(open(ref_file).read()) + replace_link_local(expected, link_local_cache) + + test_func = partial( + topotest.router_json_cmp, + router, + cmd, + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = "{}: BGP IPv6 table failure".format(router.name) + assert res is None, assertmsg + + # check r2 sub-groups + expected = [ + ["2001:db8:1::4"], + ["2001:db8:1::3", "2001:db8:1::2"], + ["2001:db8:3::2"], + ] + + test_func = functools.partial(check_r2_sub_group, expected) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Peer group split failed" + + +def test_bgp_route_server_client_step3(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r2 = tgen.gears["r2"] + r2.vtysh_cmd( + """ +configure terminal +router bgp 65000 view RS + address-family ipv6 unicast + no neighbor 2001:db8:1::2 nexthop-local unchanged + no neighbor 2001:db8:1::3 nexthop-local unchanged + no neighbor 2001:db8:1::4 nexthop-local unchanged + no neighbor 2001:db8:3::2 nexthop-local unchanged +""" + ) + + global link_local_cache + link_local_cache = {} + router_list = tgen.routers().values() + for router in router_list: + if router.name == "r2": + # route-server + cmd = "show bgp view RS ipv6 unicast json" + else: + cmd = "show bgp ipv6 unicast json" + + ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name) + expected = json.loads(open(ref_file).read()) + replace_link_local(expected, link_local_cache) + + test_func = partial( + topotest.router_json_cmp, + router, + cmd, + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = "{}: BGP IPv6 table failure".format(router.name) + assert res is None, assertmsg + + # check r2 sub-groups + expected = [["2001:db8:1::4"], ["2001:db8:1::3", "2001:db8:1::2", "2001:db8:3::2"]] + + test_func = functools.partial(check_r2_sub_group, expected) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Peer group split failed" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if __name__ == "__main__": diff --git a/tests/topotests/bgp_rpki_topo1/r2/bgpd.conf b/tests/topotests/bgp_rpki_topo1/r2/bgpd.conf index 4de177dc2586..8f0461c4d6fd 100644 --- a/tests/topotests/bgp_rpki_topo1/r2/bgpd.conf +++ b/tests/topotests/bgp_rpki_topo1/r2/bgpd.conf @@ -9,6 +9,10 @@ router bgp 65002 neighbor 192.168.4.4 timers connect 1 address-family ipv4 unicast neighbor 192.168.4.4 next-hop-self +<<<<<<< HEAD +======= + neighbor 192.168.4.4 send-community extended rpki +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) exit-address-family ! router bgp 65002 vrf vrf10 diff --git a/tests/topotests/bgp_set_metric_igp/__init__.py b/tests/topotests/bgp_set_metric_igp/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_set_metric_igp/r1/frr.conf b/tests/topotests/bgp_set_metric_igp/r1/frr.conf new file mode 100644 index 000000000000..018ea0269eda --- /dev/null +++ b/tests/topotests/bgp_set_metric_igp/r1/frr.conf @@ -0,0 +1,13 @@ +! +int r1-eth0 + ip address 10.0.0.1/24 +! +int r1-eth1 + ip address 10.0.1.1/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 10.0.0.2 remote-as external + neighbor 10.0.1.2 remote-as external +! diff --git a/tests/topotests/bgp_set_metric_igp/r2/frr.conf b/tests/topotests/bgp_set_metric_igp/r2/frr.conf new file mode 100644 index 000000000000..bce06c47f065 --- /dev/null +++ b/tests/topotests/bgp_set_metric_igp/r2/frr.conf @@ -0,0 +1,36 @@ +! +int r2-eth0 + ip address 10.0.0.2/24 + ip router isis n2 + isis circuit-type level-2-only + isis fast-reroute lfa level-2 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +int r2-eth1 + ip address 10.0.2.1/24 + ip router isis n2 + isis circuit-type level-2-only + isis fast-reroute lfa level-2 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 10.0.0.1 remote-as external + neighbor 10.0.2.2 remote-as internal + address-family ipv4 unicast + neighbor 10.0.0.1 route-map igp out + exit-address-family +! +router isis n2 + is-type level-2-only + net 49.0001.0000.0000.0002.00 + lsp-mtu 1440 +exit +! +route-map igp permit 10 + set metric igp +exit diff --git a/tests/topotests/bgp_set_metric_igp/r3/frr.conf b/tests/topotests/bgp_set_metric_igp/r3/frr.conf new file mode 100644 index 000000000000..312f97d08a4a --- /dev/null +++ b/tests/topotests/bgp_set_metric_igp/r3/frr.conf @@ -0,0 +1,38 @@ +! +int r3-eth0 + ip address 10.0.1.2/24 + ip router isis n3 + isis circuit-type level-2-only + isis fast-reroute lfa level-2 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +int r3-eth1 + ip address 10.0.3.1/24 + ip router isis n3 + isis circuit-type level-2-only + isis fast-reroute lfa level-2 + isis metric level-1 10 + isis metric level-2 100 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 10.0.1.1 remote-as external + neighbor 10.0.3.2 remote-as internal + address-family ipv4 unicast + neighbor 10.0.1.1 route-map igp out + exit-address-family +! +router isis n3 + is-type level-2-only + net 49.0001.0000.0000.0003.00 + lsp-mtu 1440 +exit +! +route-map igp permit 10 + set metric igp +exit diff --git a/tests/topotests/bgp_set_metric_igp/r4/frr.conf b/tests/topotests/bgp_set_metric_igp/r4/frr.conf new file mode 100644 index 000000000000..04165b80b244 --- /dev/null +++ b/tests/topotests/bgp_set_metric_igp/r4/frr.conf @@ -0,0 +1,41 @@ +! +int r4-eth0 + ip address 10.0.2.2/24 + ip router isis n4 + isis circuit-type level-2-only + isis fast-reroute lfa level-2 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +int r4-eth1 + ip address 10.0.3.2/24 + ip router isis n4 + isis circuit-type level-2-only + isis fast-reroute lfa level-2 + isis metric level-1 10 + isis metric level-2 100 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +int r4-eth2 + ip address 10.0.4.1/24 + ip router isis n4 + isis circuit-type level-2-only + isis fast-reroute lfa level-2 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 10.0.2.1 remote-as internal + neighbor 10.0.3.1 remote-as internal + neighbor 10.0.4.2 remote-as external +! +router isis n4 + is-type level-2-only + net 49.0001.0000.0000.0004.00 + lsp-mtu 1440 +exit diff --git a/tests/topotests/bgp_set_metric_igp/r5/frr.conf b/tests/topotests/bgp_set_metric_igp/r5/frr.conf new file mode 100644 index 000000000000..af23677b72b5 --- /dev/null +++ b/tests/topotests/bgp_set_metric_igp/r5/frr.conf @@ -0,0 +1,14 @@ +! +int r5-eth0 + ip address 10.0.4.2/24 +! +router bgp 65005 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 10.0.4.1 remote-as external + neighbor 10.0.4.1 timers 1 3 + neighbor 10.0.4.1 timers connect 1 + address-family ipv4 unicast + network 10.5.5.5/32 + exit-address-family +! diff --git a/tests/topotests/bgp_set_metric_igp/test_bgp_set_metric_igp.py b/tests/topotests/bgp_set_metric_igp/test_bgp_set_metric_igp.py new file mode 100644 index 000000000000..8fbe817689d1 --- /dev/null +++ b/tests/topotests/bgp_set_metric_igp/test_bgp_set_metric_igp.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by +# Donatas Abraitis +# + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, get_topogen + +pytestmark = [pytest.mark.bgpd] + + +def setup_module(mod): + topodef = { + "s1": ("r1", "r2"), + "s2": ("r1", "r3"), + "s3": ("r2", "r4"), + "s4": ("r3", "r4"), + "s5": ("r4", "r5"), + } + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_set_metric_igp(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + def _bgp_converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast json")) + expected = { + "routes": { + "10.5.5.5/32": [ + { + "valid": True, + "bestpath": True, + "selectionReason": "MED", + "metric": 20, + "nexthops": [ + { + "ip": "10.0.0.2", + "hostname": "r2", + } + ], + }, + { + "valid": True, + "bestpath": None, + "metric": 110, + "nexthops": [ + { + "ip": "10.0.1.2", + "hostname": "r3", + } + ], + }, + ] + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=5) + assert result is None, "10.5.5.5/32 best path is not via r2 (MED == 20)" + + r2.vtysh_cmd( + """ +configure terminal +interface r2-eth1 + isis metric level-2 6000 +""" + ) + + def _bgp_converge_after_isis_metric_changes(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast json")) + expected = { + "routes": { + "10.5.5.5/32": [ + { + "valid": True, + "bestpath": None, + "metric": 6010, + "nexthops": [ + { + "ip": "10.0.0.2", + "hostname": "r2", + } + ], + }, + { + "valid": True, + "bestpath": True, + "selectionReason": "MED", + "metric": 110, + "nexthops": [ + { + "ip": "10.0.1.2", + "hostname": "r3", + } + ], + }, + ] + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge_after_isis_metric_changes, + ) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=5) + assert result is None, "10.5.5.5/32 best path is not via r3 (MED == 110)" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce1/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce1/bgpd.conf index b598666dfb02..eb3237ab1d5b 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce1/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce1/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log debugging +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 65001 timers bgp 3 9 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce1/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce1/zebra.conf index 4a8579845c89..b68a6bc53c71 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce1/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce1/zebra.conf @@ -1,5 +1,8 @@ +<<<<<<< HEAD log file /tmp/zebra.log log stdout +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce2/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce2/bgpd.conf index e388ccba8a75..c679d3eef494 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce2/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce2/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log debugging +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 65001 bgp router-id 192.168.200.10 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce2/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce2/zebra.conf index 5e0aa5d3f038..7ea55091067e 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce2/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce2/zebra.conf @@ -1,5 +1,8 @@ +<<<<<<< HEAD log file /tmp/zebra.log log stdout +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce3/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce3/bgpd.conf index e388ccba8a75..c679d3eef494 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce3/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce3/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log debugging +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 65001 bgp router-id 192.168.200.10 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce3/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce3/zebra.conf index fabc11e84d79..6303a57d471f 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce3/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce3/zebra.conf @@ -1,5 +1,8 @@ +<<<<<<< HEAD log file /tmp/zebra.log log stdout +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce4/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce4/bgpd.conf index e388ccba8a75..c679d3eef494 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce4/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce4/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log debugging +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 65001 bgp router-id 192.168.200.10 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce4/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce4/zebra.conf index e369f41b39e9..3352000907ec 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce4/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce4/zebra.conf @@ -1,5 +1,8 @@ +<<<<<<< HEAD log file /tmp/zebra.log log stdout +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r1/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r1/bgpd.conf index 098e55d0ed34..7c0653bdff52 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r1/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r1/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log debugging +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 65000 bgp router-id 10.1.1.1 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r2/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r2/zebra.conf index 4fec8af3dbeb..91ba4e4a6a46 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r2/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r2/zebra.conf @@ -1,5 +1,8 @@ +<<<<<<< HEAD log file /tmp/zebra.log log stdout +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r3/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r3/zebra.conf index e43399559377..cb114c3181b8 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r3/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r3/zebra.conf @@ -1,5 +1,8 @@ +<<<<<<< HEAD log file /tmp/zebra.log log stdout +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r4/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r4/bgpd.conf index 2a834c799ef2..9b84093083c0 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r4/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r4/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log debugging +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 65000 bgp router-id 10.4.4.4 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r4/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r4/zebra.conf index 14580e5b3a36..e509342ca04b 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r4/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r4/zebra.conf @@ -1,5 +1,8 @@ +<<<<<<< HEAD log file /tmp/zebra.log log stdout +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py b/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py index 5467cf4d841b..1fc62105da7c 100644 --- a/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py +++ b/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py @@ -368,17 +368,30 @@ def test_protocols_convergence(): # check that r2 peerings are ok logger.info("Checking BGP ipv4 vpn summary for r2") +<<<<<<< HEAD router = tgen.gears["r2"] json_file = "{}/{}/ipv4_vpn_summary.json".format(CWD, router.name) expected = json.loads(open(json_file).read()) test_func = partial( topotest.router_json_cmp, router, +======= + r2 = tgen.gears["r2"] + json_file = "{}/{}/ipv4_vpn_summary.json".format(CWD, r2.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, + r2, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "show bgp ipv4 vpn summary json", expected, ) _, result = topotest.run_and_expect(test_func, None, count=20, wait=0.5) +<<<<<<< HEAD assertmsg = '"{}" JSON output mismatches'.format(router.name) +======= + assertmsg = '"{}" JSON output mismatches'.format(r2.name) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert result is None, assertmsg @@ -400,11 +413,19 @@ def test_mpls_setup_ok(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD router = tgen.gears["r2"] # diagnostic logger.info("Dumping mplsvpn nexthop table") router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False) +======= + r2 = tgen.gears["r2"] + + # diagnostic + logger.info("Dumping mplsvpn nexthop table") + r2.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vpnv4_checks = { "172.31.1.0/24": "r1", @@ -414,10 +435,17 @@ def test_mpls_setup_ok(): } logger.info( "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on all devices".format( +<<<<<<< HEAD router.name ) ) check_show_bgp_vpn_ok(router, vpnv4_checks) +======= + r2.name + ) + ) + check_show_bgp_vpn_ok(r2, vpnv4_checks) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) logger.info("h1, check that ping from h1 to (h2,h3) is ok") check_ping("h1", "172.31.1.10", True, 20, 0.5) @@ -436,6 +464,7 @@ def test_r3_prefixes_removed(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD router = tgen.gears["r3"] logger.info("{}, keeping only 172.31.3.0/24 network".format(router.name)) router.vtysh_cmd("configure terminal\ninterface r3-eth1 vrf vrf1\nshutdown\n") @@ -445,33 +474,69 @@ def test_r3_prefixes_removed(): logger.info( "{}, check that 'show bgp ipv4 vpn' has only 172.31.3.0/24 network from r3".format( router.name +======= + r3 = tgen.gears["r3"] + logger.info("{}, keeping only 172.31.3.0/24 network".format(r3.name)) + r3.vtysh_cmd( + """ +configure terminal +interface r3-eth1 vrf vrf1 + shutdown +! +interface r3-eth2 vrf vrf1 + shutdown\n +""" + ) + + r2 = tgen.gears["r2"] + logger.info( + "{}, check that 'show bgp ipv4 vpn' has only 172.31.3.0/24 network from r3".format( + r2.name +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) ) for prefix in ("172.31.1.0/24", "172.31.2.0/24"): test_func = functools.partial( check_show_bgp_vpn_prefix_not_found, +<<<<<<< HEAD router, +======= + r2, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "ipv4", prefix, "444:3", ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +<<<<<<< HEAD assert success, "{}, vpnv4 update {} still present".format(router.name, prefix) # diagnostic logger.info("Dumping mplsvpn nexthop table") router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False) +======= + assert success, "{}, vpnv4 update {} still present".format(r2.name, prefix) + + # diagnostic + logger.info("Dumping mplsvpn nexthop table") + r2.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) prefix = "172.31.3.0/24" logger.info( "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format( +<<<<<<< HEAD router.name +======= + r2.name +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) ) vpnv4_checks = { prefix: "r1", } +<<<<<<< HEAD label_ip_entries = check_show_bgp_vpn_ok(router, vpnv4_checks) router = tgen.gears["r3"] @@ -482,16 +547,39 @@ def test_r3_prefixes_removed(): logger.info( "{}, check that 'show bgp ipv4 vpn' has not {} network from r3".format( router.name, prefix +======= + label_ip_entries = check_show_bgp_vpn_ok(r2, vpnv4_checks) + + r3 = tgen.gears["r3"] + logger.info("{}, removing {} network".format(r3.name, prefix)) + r3.vtysh_cmd( + """ +configure terminal +interface r3-eth3 vrf vrf1 + shutdown\n +""" + ) + + r2 = tgen.gears["r2"] + logger.info( + "{}, check that 'show bgp ipv4 vpn' has not {} network from r3".format( + r2.name, prefix +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) ) test_func = functools.partial( check_show_bgp_vpn_prefix_not_found, +<<<<<<< HEAD router, +======= + r2, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "ipv4", prefix, "444:3", ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +<<<<<<< HEAD assert success, "{}, vpnv4 update {} still present".format(router.name, prefix) logger.info( @@ -501,6 +589,17 @@ def test_r3_prefixes_removed(): ) test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, label_ip_entries[prefix] +======= + assert success, "{}, vpnv4 update {} still present".format(r2.name, prefix) + + logger.info( + "{}, check that 'show mpls table {}' is not present".format( + r2.name, label_ip_entries[prefix] + ) + ) + test_func = functools.partial( + check_show_mpls_table_entry_label_not_found, r2, label_ip_entries[prefix] +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry with in_label {} still present".format( @@ -517,6 +616,7 @@ def test_r3_prefixes_added_back(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD router = tgen.gears["r3"] prefix = "172.31.3.0/24" logger.info("{}, restoring the {} network from r3".format(router.name, prefix)) @@ -526,27 +626,57 @@ def test_r3_prefixes_added_back(): logger.info( "{}, check that 'show bgp ipv4 vpn' has {} network from r3".format( router.name, prefix +======= + r3 = tgen.gears["r3"] + prefix = "172.31.3.0/24" + logger.info("{}, restoring the {} network from r3".format(r3.name, prefix)) + r3.vtysh_cmd( + """ +configure terminal + interface r3-eth3 vrf vrf1 + no shutdown +""" + ) + + r2 = tgen.gears["r2"] + logger.info( + "{}, check that 'show bgp ipv4 vpn' has {} network from r3".format( + r2.name, prefix +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) ) test_func = functools.partial( check_show_bgp_vpn_prefix_found, +<<<<<<< HEAD router, +======= + r2, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "ipv4", prefix, "444:3", ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +<<<<<<< HEAD assert success, "{}, vpnv4 update {} not present".format(router.name, prefix) logger.info( "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format( router.name +======= + assert success, "{}, vpnv4 update {} not present".format(r2.name, prefix) + + logger.info( + "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format( + r2.name +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) ) vpnv4_checks = { prefix: "r1", } +<<<<<<< HEAD check_show_bgp_vpn_ok(router, vpnv4_checks) router = tgen.gears["r3"] @@ -560,16 +690,48 @@ def test_r3_prefixes_added_back(): test_func = functools.partial( check_show_bgp_vpn_prefix_found, router, +======= + check_show_bgp_vpn_ok(r2, vpnv4_checks) + + r3 = tgen.gears["r3"] + logger.info( + "{}, restoring the redistribute connected prefixes from r3".format(r3.name) + ) + r3.vtysh_cmd( + """ +configure terminal +interface r3-eth1 vrf vrf1 + no shutdown +! +interface r3-eth2 vrf vrf1 + no shutdown +""" + ) + + r2 = tgen.gears["r2"] + for prefix in ("172.31.1.0/24", "172.31.2.0/24"): + test_func = functools.partial( + check_show_bgp_vpn_prefix_found, + r2, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "ipv4", prefix, "444:3", ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +<<<<<<< HEAD assert success, "{}, vpnv4 update {} not present".format(router.name, prefix) # diagnostic logger.info("Dumping mplsvpn nexthop table") tgen.gears["r2"].vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False) +======= + assert success, "{}, vpnv4 update {} not present".format(r2.name, prefix) + + # diagnostic + logger.info("Dumping mplsvpn nexthop table") + r2.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_unconfigure_nexthop_change_nexthop_self(): @@ -583,13 +745,18 @@ def test_unconfigure_nexthop_change_nexthop_self(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD router = tgen.gears["r2"] +======= + r2 = tgen.gears["r2"] +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vpnv4_checks = { "172.31.1.0/24": "r1", "172.31.2.0/24": "r1", "172.31.3.0/24": "r1", } logger.info( +<<<<<<< HEAD "{}, Get the list of labels allocated for prefixes from r3".format(router.name) ) label_ip_entries = check_show_bgp_vpn_ok(router, vpnv4_checks) @@ -600,27 +767,58 @@ def test_unconfigure_nexthop_change_nexthop_self(): router = tgen.gears["r2"] router.vtysh_cmd( "configure terminal\nrouter bgp 65500\naddress-family ipv4 vpn\nno neighbor 192.0.2.100 next-hop-self\n" +======= + "{}, Get the list of labels allocated for prefixes from r3".format(r2.name) + ) + label_ip_entries = check_show_bgp_vpn_ok(r2, vpnv4_checks) + + logger.info("{}, disable next-hop-self for 192.0.2.100 neighbor".format(r2.name)) + + r2.vtysh_cmd( + """ +configure terminal +router bgp 65500 + address-family ipv4 vpn + no neighbor 192.0.2.100 next-hop-self +""" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) for prefix, label in label_ip_entries.items(): logger.info( "{}, check mpls entry for {} with in_label {} is not present'".format( +<<<<<<< HEAD router.name, prefix, label ) ) test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, label +======= + r2.name, prefix, label + ) + ) + test_func = functools.partial( + check_show_mpls_table_entry_label_not_found, r2, label +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry for {} with in_label {} still present".format( prefix, label ) +<<<<<<< HEAD router = tgen.gears["r1"] for prefix, label in label_ip_entries.items(): test_func = functools.partial( check_show_bgp_vpn_prefix_not_found, router, +======= + r1 = tgen.gears["r1"] + for prefix, label in label_ip_entries.items(): + test_func = functools.partial( + check_show_bgp_vpn_prefix_not_found, + r1, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "ipv4", prefix, "444:3", @@ -628,12 +826,20 @@ def test_unconfigure_nexthop_change_nexthop_self(): ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, mpls vpn update {} label {} is present".format( +<<<<<<< HEAD router.name, prefix, label +======= + r1.name, prefix, label +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) for prefix, label in label_ip_entries.items(): test_func = functools.partial( check_show_bgp_vpn_prefix_found, +<<<<<<< HEAD router, +======= + r1, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "ipv4", prefix, "444:3", @@ -641,12 +847,20 @@ def test_unconfigure_nexthop_change_nexthop_self(): ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, mpls vpn update {} label {} is present".format( +<<<<<<< HEAD router.name, prefix, label +======= + r1.name, prefix, label +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) # diagnostic logger.info("Dumping mplsvpn nexthop table") +<<<<<<< HEAD tgen.gears["r2"].vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False) +======= + tgen.gears["r2"].vtysh_cmd("show bgp mplsvpn-nh-label-bind detail") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_reconfigure_nexthop_change_nexthop_self(): @@ -660,10 +874,22 @@ def test_reconfigure_nexthop_change_nexthop_self(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD router = tgen.gears["r2"] logger.info("{}, enable next-hop-self for 192.0.2.100 neighbor".format(router.name)) router.vtysh_cmd( "configure terminal\nrouter bgp 65500\naddress-family ipv4 vpn\nneighbor 192.0.2.100 next-hop-self\n" +======= + r2 = tgen.gears["r2"] + logger.info("{}, enable next-hop-self for 192.0.2.100 neighbor".format(r2.name)) + r2.vtysh_cmd( + """ +configure terminal +router bgp 65500 + address-family ipv4 vpn + neighbor 192.0.2.100 next-hop-self +""" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) vpnv4_checks = { "172.31.1.0/24": "r1", @@ -672,17 +898,28 @@ def test_reconfigure_nexthop_change_nexthop_self(): } logger.info( "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format( +<<<<<<< HEAD router.name ) ) check_show_bgp_vpn_ok(router, vpnv4_checks) +======= + r2.name + ) + ) + check_show_bgp_vpn_ok(r2, vpnv4_checks) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) logger.info("h1, check that ping from h1 to (h2,h3) is ok") check_ping("h1", "172.31.1.10", True, 20, 0.5) check_ping("h1", "172.31.2.10", True, 20, 0.5) # diagnostic logger.info("Dumping mplsvpn nexthop table") +<<<<<<< HEAD router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False) +======= + r2.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_declare_vpn_network_with_different_label(): @@ -696,6 +933,7 @@ def test_declare_vpn_network_with_different_label(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD router = tgen.gears["r3"] logger.info( "{}, declare static 33.33.33.33/32 network rd 33:33 label 33".format( @@ -710,6 +948,23 @@ def test_declare_vpn_network_with_different_label(): ) router = tgen.gears["r2"] +======= + r3 = tgen.gears["r3"] + logger.info( + "{}, declare static 33.33.33.33/32 network rd 33:33 label 33".format(r3.name) + ) + r3.vtysh_cmd( + """ +configure terminal +router bgp 65501 + no bgp network import-check\n" + address-family ipv4 vpn + network 33.33.33.33/32 rd 444:3 label 33 +""" + ) + + r2 = tgen.gears["r2"] +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vpnv4_entries = { "172.31.1.0/24": None, "172.31.2.0/24": None, @@ -720,7 +975,11 @@ def test_declare_vpn_network_with_different_label(): for prefix, label in vpnv4_entries.items(): test_func = functools.partial( check_show_bgp_vpn_prefix_found, +<<<<<<< HEAD router, +======= + r2, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "ipv4", prefix, "444:3", @@ -729,7 +988,11 @@ def test_declare_vpn_network_with_different_label(): ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {}, label {} not present".format( +<<<<<<< HEAD router.name, prefix, label +======= + r2.name, prefix, label +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) vpnv4_checks = { @@ -740,10 +1003,17 @@ def test_declare_vpn_network_with_different_label(): } logger.info( "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format( +<<<<<<< HEAD router.name ) ) check_show_bgp_vpn_ok(router, vpnv4_checks) +======= + r2.name + ) + ) + check_show_bgp_vpn_ok(r2, vpnv4_checks) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_filter_vpn_network_from_r1(): @@ -757,13 +1027,18 @@ def test_filter_vpn_network_from_r1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD router = tgen.gears["r2"] +======= + r2 = tgen.gears["r2"] +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vpnv4_checks = { "172.31.0.0/24": "r3", } logger.info( "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r3".format( +<<<<<<< HEAD router.name ) ) @@ -783,11 +1058,36 @@ def test_filter_vpn_network_from_r1(): test_func = functools.partial( check_show_bgp_vpn_prefix_not_found, router, +======= + r2.name + ) + ) + label_ip_entries = check_show_bgp_vpn_ok(r2, vpnv4_checks) + + for prefix, label in label_ip_entries.items(): + logger.info("{}, filter prefix {} from r1".format(r2.name, prefix)) + r2.vtysh_cmd( + """ +configure terminal +route-map rmap deny 1 + match ip next-hop address 192.0.2.1 +! +router bgp 65500 + address-family ipv4 vpn + neighbor 192.0.2.100 route-map rmap in +""" + ) + logger.info("{}, check that prefix {} is not present".format(r2.name, prefix)) + test_func = functools.partial( + check_show_bgp_vpn_prefix_not_found, + r2, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "ipv4", "172.31.0.0/24", "444:1", ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +<<<<<<< HEAD assert success, "{}, vpnv4 update {}, is still present".format( router.name, prefix ) @@ -803,6 +1103,19 @@ def test_filter_vpn_network_from_r1(): ) test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, int(label) +======= + assert success, "{}, vpnv4 update {}, is still present".format(r2.name, prefix) + + # diagnostic + logger.info("Dumping mplsvpn nexthop table") + r2.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail") + + logger.info( + "{}, check that show mpls table {} is not present".format(r2.name, label) + ) + test_func = functools.partial( + check_show_mpls_table_entry_label_not_found, r2, int(label) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry for {} with in_label {} still present".format( @@ -821,6 +1134,7 @@ def test_unfilter_vpn_network_from_r1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD router = tgen.gears["r2"] prefix = "172.31.0.0/24" @@ -835,12 +1149,29 @@ def test_unfilter_vpn_network_from_r1(): ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {}, is not present".format(router.name, prefix) +======= + r2 = tgen.gears["r2"] + prefix = "172.31.0.0/24" + + logger.info("{}, filter prefix {} from r1".format(r2.name, prefix)) + r2.vtysh_cmd( + "configure terminal\nrouter bgp 65500\naddress-family ipv4 vpn\nno neighbor 192.0.2.100 route-map rmap in\n" + ) + + logger.info("{}, check that prefix {} is present".format(r2.name, prefix)) + test_func = functools.partial( + check_show_bgp_vpn_prefix_found, r2, "ipv4", prefix, "444:1" + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assert success, "{}, vpnv4 update {}, is not present".format(r2.name, prefix) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vpnv4_checks = { "172.31.0.0/24": "r3", } logger.info( "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on all devices".format( +<<<<<<< HEAD router.name ) ) @@ -849,6 +1180,16 @@ def test_unfilter_vpn_network_from_r1(): # diagnostic logger.info("Dumping mplsvpn nexthop table") router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False) +======= + r2.name + ) + ) + check_show_bgp_vpn_ok(r2, vpnv4_checks) + + # diagnostic + logger.info("Dumping mplsvpn nexthop table") + r2.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_memory_leak(): diff --git a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py index 146687d5881b..1ffe357e2983 100644 --- a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py @@ -187,7 +187,11 @@ def bgp_vpnv4_table_check( test_func = functools.partial( check_bgp_vpnv4_prefix_presence, router, prefix, table_version ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "{}, prefix ipv4 vpn {} is not installed yet".format( router.name, prefix ) @@ -321,7 +325,11 @@ def mpls_table_check(router, blacklist=None, label_list=None, whitelist=None): test_func = functools.partial( check_show_mpls_table, router, blacklist, label_list, whitelist ) +<<<<<<< HEAD success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, result = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "{}, MPLS labels check fail: {}".format(router.name, result) @@ -347,10 +355,44 @@ def check_show_bgp_vpn_prefix_found(router, ipversion, prefix, rd): return topotest.json_cmp(output, expected) +<<<<<<< HEAD def check_show_mpls_table_entry_label_found(router, inlabel, interface): output = json.loads(router.vtysh_cmd("show mpls table {} json".format(inlabel))) expected = { "inLabel": inlabel, +======= +def check_show_mpls_table_entry_label_found_nexthop( + expected_router, get_router, network, nexthop +): + label = get_mpls_label(get_router, network) + if label < 0: + return False + + output = json.loads( + expected_router.vtysh_cmd("show mpls table {} json".format(label)) + ) + expected = { + "inLabel": label, + "installed": True, + "nexthops": [{"nexthop": nexthop}], + } + return topotest.json_cmp(output, expected) + + +def check_show_mpls_table_entry_label_found( + expected_router, get_router, interface, network=None, label=None +): + if not label: + label = get_mpls_label(get_router, network) + if label < 0: + return False + + output = json.loads( + expected_router.vtysh_cmd("show mpls table {} json".format(label)) + ) + expected = { + "inLabel": label, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "installed": True, "nexthops": [{"interface": interface}], } @@ -395,6 +437,20 @@ def mpls_entry_get_interface(router, label): return outgoing_interface +<<<<<<< HEAD +======= +def get_mpls_label(router, network): + label = router.vtysh_cmd( + "show ip route vrf vrf1 %s json" % network, + isjson=True, + ) + label = label.get(f"{network}", [{}])[0].get("nexthops", [{}])[0] + label = int(label.get("labels", [-1])[0]) + + return label + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_protocols_convergence(): """ Assert that all protocols have converged @@ -415,7 +471,11 @@ def test_protocols_convergence(): "show bgp vrf vrf1 ipv4 json", expected, ) +<<<<<<< HEAD _, result = topotest.run_and_expect(test_func, None, count=20, wait=0.5) +======= + _, result = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg @@ -429,7 +489,11 @@ def test_protocols_convergence(): "show bgp ipv4 vpn json", expected, ) +<<<<<<< HEAD _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + _, result = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg @@ -471,7 +535,11 @@ def _bgp_prefix_not_found(router, vrf, ipversion, prefix): test_func = functools.partial( _bgp_prefix_not_found, tgen.gears["r1"], "vrf1", "ipv4", "172.31.0.11/32" ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert ( success ), "r1, prefix 172.31.0.11/32 from r11 did not disappear. r11 still connected to rr ?" @@ -509,7 +577,11 @@ def test_flapping_bgp_vrf_up(): "172.31.0.11/32", "444:1", ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert ( success ), "r2, prefix 172.31.0.11/32 from r11 not present. r11 still disconnected from rr ?" @@ -539,7 +611,11 @@ def test_recursive_route(): "172.31.0.30/32", "444:1", ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r2, vpnv4 update 172.31.0.30 not found" bgp_vpnv4_table_check(tgen.gears["r2"], group=PREFIXES_R11 + ["172.31.0.30/32"]) @@ -565,7 +641,11 @@ def test_recursive_route(): "172.31.0.30/32", "444:1", ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r2, vpnv4 update 172.31.0.30 still present" @@ -591,7 +671,11 @@ def test_prefix_changes_interface(): "172.31.0.50/32", "444:1", ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r2, vpnv4 update 172.31.0.50 not found" # diagnostic @@ -637,7 +721,11 @@ def test_prefix_changes_interface(): "444:1", label=oldlabel, ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert ( success ), "r2, vpnv4 update 172.31.0.50 with old label {0} still present".format(oldlabel) @@ -654,7 +742,11 @@ def test_prefix_changes_interface(): "172.31.0.50/32", "444:1", ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r2, vpnv4 update 172.31.0.50 not found" label_list = set() @@ -719,9 +811,19 @@ def test_changing_default_label_value(): "r1, mpls table, check that MPLS entry with inLabel set to 222 has vrf1 interface" ) test_func = functools.partial( +<<<<<<< HEAD check_show_mpls_table_entry_label_found, router, 222, "vrf1" ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + check_show_mpls_table_entry_label_found, + tgen.gears["r1"], + router, + "vrf1", + label=222, + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r1, mpls entry with label 222 not found" # check label repartition is ok @@ -769,7 +871,11 @@ def test_unconfigure_allocation_mode_nexthop(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, 17 ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r1, mpls entry with label 17 still present" # Check vpnv4 routes from r1 @@ -821,7 +927,11 @@ def test_reconfigure_allocation_mode_nexthop(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, 17 ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r1, mpls entry with label 17 still present" # Check vpnv4 routes from r1 @@ -837,6 +947,129 @@ def test_reconfigure_allocation_mode_nexthop(): mpls_table_check(router, label_list=label_list) +<<<<<<< HEAD +======= +def test_network_command(): + """ + Test with network declaration + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + logger.info("Disabling redistribute static") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nno redistribute static\n", + isjson=False, + ) + logger.info("Checking BGP VPNv4 labels on r2") + for p in ["172.31.0.24/32", "172.31.0.15/32"]: + test_func = functools.partial( + check_show_bgp_vpn_prefix_not_found, tgen.gears["r2"], "ipv4", p, "444:1" + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) + assert success, "network %s should not present on r2" % p + + logger.info("Use network command for host networks declared in static instead") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nnetwork 172.31.0.14/32\n", + isjson=False, + ) + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nnetwork 172.31.0.15/32\n", + isjson=False, + ) + logger.info("Checking BGP VPNv4 labels on r2") + bgp_vpnv4_table_check(tgen.gears["r2"], group=["172.31.0.12/32", "172.31.0.15/32"]) + bgp_vpnv4_table_check(tgen.gears["r2"], group=["172.31.0.14/32"]) + mpls_table_check(tgen.gears["r1"], whitelist=["192.0.2.14"]) + + logger.info(" Remove network to 172.31.0.14/32") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nno network 172.31.0.14/32\n", + isjson=False, + ) + test_func = functools.partial( + check_show_bgp_vpn_prefix_not_found, + tgen.gears["r2"], + "ipv4", + "172.31.0.14/32", + "444:1", + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) + assert success, "network 172.31.0.14/32 should not present on r2" + mpls_table_check(tgen.gears["r1"], blacklist=["192.0.2.14"]) + + logger.info("Disabling redistribute connected and enabling redistribute static") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\n" + "redistribute static\n no redistribute connected", + isjson=False, + ) + logger.info("Use network command for connect network 192.168.255.0/24 in vrf") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\n" + "network 192.168.255.0/24\n", + isjson=False, + ) + logger.info("Checking BGP VPNv4 labels on r2") + bgp_vpnv4_table_check(tgen.gears["r2"], group=["192.168.255.0/24"]) + logger.info("Checking no mpls entry associated to 192.168.255.0/24") + mpls_table_check(tgen.gears["r1"], blacklist=["192.168.255.0"]) + logger.info("Checking 192.168.255.0/24 fallback to vrf") + test_func = functools.partial( + check_show_mpls_table_entry_label_found, + tgen.gears["r1"], + tgen.gears["r2"], + "vrf1", + network="192.168.255.0/24", + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) + assert success, "192.168.255.0/24 does not fallback to vrf" + + logger.info( + "Use network command for statically routed network 192.168.3.0/24 in vrf" + ) + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nvrf vrf1\n" "ip route 192.168.3.0/24 192.0.2.11\n" + ) + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\n" + "network 192.168.3.0/24\n", + isjson=False, + ) + logger.info("Checking 192.168.3.0/24 route on r2") + test_func = functools.partial( + check_show_mpls_table_entry_label_found_nexthop, + tgen.gears["r1"], + tgen.gears["r2"], + "192.168.3.0/24", + "192.0.2.11", + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) + assert success, "label from r2 is not present on r1 for 192.168.3.0/24" + + # diagnostic + logger.info("Dumping label nexthop table") + tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 label-nexthop detail", isjson=False) + logger.info("Dumping bgp network import-check-table") + tgen.gears["r1"].vtysh_cmd( + "show bgp vrf vrf1 import-check-table detail", isjson=False + ) + + logger.info("Restoring 172.31.0.14 prefix on r1") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nnetwork 172.31.0.14/32\n", + isjson=False, + ) + logger.info("Restoring redistribute connected") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\n" + "no redistribute static\n redistribute connected", + isjson=False, + ) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() diff --git a/tests/topotests/bgp_vpnv4_route_leak_basic/r1/frr.conf b/tests/topotests/bgp_vpnv4_route_leak_basic/r1/frr.conf new file mode 100644 index 000000000000..d3ababde3a81 --- /dev/null +++ b/tests/topotests/bgp_vpnv4_route_leak_basic/r1/frr.conf @@ -0,0 +1,75 @@ +int dummy0 + ip address 10.0.4.1/24 + no shut +! +int dummy1 + ip address 10.0.0.1/24 + no shut +! +int dummy2 + ip address 10.0.1.1/24 + no shut +! +int dummy3 + ip address 10.0.2.1/24 + no shut +! +int dummy4 + ip address 10.0.3.1/24 + no shut +! +int EVA + no shut +! +int DONNA + no shut +! +ip router-id 10.0.4.1 +! +router bgp 99 + no bgp ebgp-requires-policy + address-family ipv4 unicast + redistribute connected + rd vpn export 10.0.4.1:1 + rt vpn export 10.0.4.1:1 + rt vpn import 10.0.4.1:101 + export vpn + import vpn + ! +! +router bgp 99 vrf DONNA + no bgp ebgp-requires-policy + address-family ipv4 unicast + redistribute connected + label vpn export 101 + rd vpn export 10.0.4.1:1 + rt vpn export 10.0.4.1:101 + rt vpn import 10.0.4.1:1 10.0.4.1:102 10.0.4.1:103 + export vpn + import vpn + ! +! +router bgp 99 vrf EVA + no bgp ebgp-requires-policy + address-family ipv4 unicast + redistribute connected + label vpn export 102 + rd vpn export 10.0.4.1:1 + rt vpn export 10.0.4.1:102 + rt vpn import 10.0.4.1:101 10.0.4.1:103 + export vpn + import vpn + ! +! +router bgp 99 vrf ZITA + no bgp ebgp-requires-policy + no bgp network import-check + address-family ipv4 unicast + network 172.16.101.0/24 + label vpn export 103 + rd vpn export 10.0.4.1:1 + rt vpn export 10.0.4.1:103 + export vpn + import vpn + ! +! diff --git a/tests/topotests/bgp_vpnv4_route_leak_basic/setup_vrfs b/tests/topotests/bgp_vpnv4_route_leak_basic/setup_vrfs new file mode 100644 index 000000000000..f62c5cd21115 --- /dev/null +++ b/tests/topotests/bgp_vpnv4_route_leak_basic/setup_vrfs @@ -0,0 +1,17 @@ +#!/bin/bash + +ip link add DONNA type vrf table 1001 +ip link add EVA type vrf table 1002 + +ip link add dummy0 type dummy # vrf default +ip link add dummy1 type dummy +ip link add dummy2 type dummy +ip link add dummy3 type dummy +ip link add dummy4 type dummy + +ip link set dummy1 master DONNA +ip link set dummy2 master EVA +ip link set dummy3 master DONNA +ip link set dummy4 master EVA + + diff --git a/tests/topotests/bgp_vpnv4_route_leak_basic/test_bgp_vpnv4_route_leak_basic.py b/tests/topotests/bgp_vpnv4_route_leak_basic/test_bgp_vpnv4_route_leak_basic.py new file mode 100644 index 000000000000..a44f07b5600e --- /dev/null +++ b/tests/topotests/bgp_vpnv4_route_leak_basic/test_bgp_vpnv4_route_leak_basic.py @@ -0,0 +1,517 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_bgp_vpnv4_route_leak_basic.py +# +# Copyright (c) 2018 Cumulus Networks, Inc. +# Donald Sharp +# Copyright (c) 2024 6WIND SAS +# + +""" +Test basic VPNv4 route leaking +""" + +import os +import sys +from functools import partial +import pytest + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from lib.checkping import check_ping + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + "Build function" + + for routern in range(1, 2): + tgen.add_router("r{}".format(routern)) + + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + # For all registered routers, load the unified configuration file + for rname, router in tgen.routers().items(): + router.run("/bin/bash {}/setup_vrfs".format(CWD)) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + # After loading the configurations, this function loads configured daemons. + tgen.start_router() + # tgen.mininet_cli() + + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + + # This function tears down the whole topology. + tgen.stop_topology() + + +def test_vrf_route_leak_donna(): + logger.info("Ensure that routes are leaked back and forth") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + # Test DONNA VRF. + expect = { + "10.0.0.0/24": [ + { + "protocol": "connected", + } + ], + "10.0.1.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "EVA", + "vrf": "EVA", + "active": True, + }, + ], + }, + ], + "10.0.2.0/24": [{"protocol": "connected"}], + "10.0.3.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "EVA", + "vrf": "EVA", + "active": True, + }, + ], + }, + ], + "10.0.4.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "dummy0", + "vrf": "default", + "active": True, + }, + ], + }, + ], + "172.16.101.0/24": [ + { + "protocol": "bgp", + "selected": None, + "nexthops": [ + { + "fib": None, + "interfaceName": "unknown", + "vrf": "Unknown", + "active": None, + }, + ], + }, + ], + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + +def test_vrf_route_leak_eva(): + logger.info("Ensure that routes are leaked back and forth") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + # Test EVA VRF. + expect = { + "10.0.0.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, + ], + "10.0.1.0/24": [ + { + "protocol": "connected", + } + ], + "10.0.2.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, + ], + "10.0.3.0/24": [ + { + "protocol": "connected", + } + ], + "172.16.101.0/24": [ + { + "protocol": "bgp", + "selected": None, + "nexthops": [ + { + "fib": None, + "interfaceName": "unknown", + "vrf": "Unknown", + "active": None, + }, + ], + }, + ], + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf EVA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF EVA check failed:\n{}".format(diff) + + +def test_vrf_route_leak_default(): + logger.info("Ensure that routes are leaked back and forth") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + # Test default VRF. + expect = { + "10.0.0.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, + ], + "10.0.2.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, + ], + "10.0.4.0/24": [ + { + "protocol": "connected", + } + ], + } + + test_func = partial(topotest.router_json_cmp, r1, "show ip route json", expect) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF default check failed:\n{}".format(diff) + + +def test_ping(): + "Simple ping tests" + + tgen = get_topogen() + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + logger.info("Ping from default to DONNA") + check_ping("r1", "10.0.0.1", True, 10, 0.5, source_addr="10.0.4.1") + + +def test_vrf_route_leak_donna_after_eva_down(): + logger.info("Ensure that route states change after EVA interface goes down") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r1.vtysh_cmd( + """ +configure +interface EVA + shutdown +""" + ) + + # Test DONNA VRF. + expect = { + "10.0.1.0/24": [ + { + "protocol": "bgp", + "selected": None, + "nexthops": [ + { + "fib": None, + "interfaceName": "EVA", + "vrf": "EVA", + "active": None, + }, + ], + }, + ], + "10.0.3.0/24": [ + { + "protocol": "bgp", + "selected": None, + "nexthops": [ + { + "fib": None, + "interfaceName": "EVA", + "vrf": "EVA", + "active": None, + }, + ], + }, + ], + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + """ + Check that "show ip route vrf DONNA json" and the JSON at key "DONNA" of + "show ip route vrf all json" gives the same result. + """ + + def check_vrf_table(router, vrf, expect): + output = router.vtysh_cmd("show ip route vrf all json", isjson=True) + vrf_table = output.get(vrf, {}) + + return topotest.json_cmp(vrf_table, expect) + + test_func = partial(check_vrf_table, r1, "DONNA", expect) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + +def test_vrf_route_leak_donna_after_eva_up(): + logger.info("Ensure that route states change after EVA interface goes up") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r1.vtysh_cmd( + """ +configure +interface EVA + no shutdown +""" + ) + + # Test DONNA VRF. + expect = { + "10.0.1.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "EVA", + "vrf": "EVA", + "active": True, + }, + ], + }, + ], + "10.0.3.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "EVA", + "vrf": "EVA", + "active": True, + }, + ], + }, + ], + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + +def test_vrf_route_leak_donna_add_vrf_zita(): + logger.info("Add VRF ZITA and ensure that the route from VRF ZITA is updated") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r1.cmd("ip link add ZITA type vrf table 1003") + + # Test DONNA VRF. + expect = { + "172.16.101.0/24": [ + { + "protocol": "bgp", + "selected": None, + "nexthops": [ + { + "fib": None, + "interfaceName": "ZITA", + "vrf": "ZITA", + "active": None, + }, + ], + }, + ], + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + +def test_vrf_route_leak_donna_set_zita_up(): + logger.info("Set VRF ZITA up and ensure that the route from VRF ZITA is updated") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r1.vtysh_cmd( + """ +configure +interface ZITA + no shutdown +""" + ) + + # Test DONNA VRF. + expect = { + "172.16.101.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "ZITA", + "vrf": "ZITA", + "active": True, + }, + ], + }, + ], + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + +def test_vrf_route_leak_donna_delete_vrf_zita(): + logger.info("Delete VRF ZITA and ensure that the route from VRF ZITA is deleted") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r1.cmd("ip link delete ZITA") + + # Test DONNA VRF. + expect = { + "172.16.101.0/24": None, + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py index 5fef6e9e6062..45667943a637 100644 --- a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py @@ -186,7 +186,11 @@ def bgp_vpnv6_table_check( test_func = functools.partial( check_bgp_vpnv6_prefix_presence, router, prefix, table_version ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "{}, prefix ipv6 vpn {} is not installed yet".format( router.name, prefix ) @@ -316,7 +320,11 @@ def mpls_table_check(router, blacklist=None, label_list=None, whitelist=None): test_func = functools.partial( check_show_mpls_table, router, blacklist, label_list, whitelist ) +<<<<<<< HEAD success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, result = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "{}, MPLS labels check fail: {}".format(router.name, result) @@ -342,10 +350,44 @@ def check_show_bgp_vpn_prefix_found(router, ipversion, prefix, rd): return topotest.json_cmp(output, expected) +<<<<<<< HEAD def check_show_mpls_table_entry_label_found(router, inlabel, interface): output = json.loads(router.vtysh_cmd("show mpls table {} json".format(inlabel))) expected = { "inLabel": inlabel, +======= +def check_show_mpls_table_entry_label_found_nexthop( + expected_router, get_router, network, nexthop +): + label = get_mpls_label(get_router, network) + if label < 0: + return False + + output = json.loads( + expected_router.vtysh_cmd("show mpls table {} json".format(label)) + ) + expected = { + "inLabel": label, + "installed": True, + "nexthops": [{"nexthop": nexthop}], + } + return topotest.json_cmp(output, expected) + + +def check_show_mpls_table_entry_label_found( + expected_router, get_router, interface, network=None, label=None +): + if not label: + label = get_mpls_label(get_router, network) + if label < 0: + return False + + output = json.loads( + expected_router.vtysh_cmd("show mpls table {} json".format(label)) + ) + expected = { + "inLabel": label, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "installed": True, "nexthops": [{"interface": interface}], } @@ -366,6 +408,20 @@ def get_table_version(router): return table["tableVersion"] +<<<<<<< HEAD +======= +def get_mpls_label(router, network): + label = router.vtysh_cmd( + "show ipv6 route vrf vrf1 %s json" % network, + isjson=True, + ) + label = label.get(f"{network}", [{}])[0].get("nexthops", [{}])[0] + label = int(label.get("labels", [-1])[0]) + + return label + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def mpls_entry_get_interface(router, label): """ Assert that the label is in MPLS table @@ -411,7 +467,11 @@ def test_protocols_convergence(): "show bgp vrf vrf1 ipv6 json", expected, ) +<<<<<<< HEAD _, result = topotest.run_and_expect(test_func, None, count=20, wait=0.5) +======= + _, result = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg @@ -425,7 +485,11 @@ def test_protocols_convergence(): "show bgp ipv6 vpn json", expected, ) +<<<<<<< HEAD _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + _, result = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg @@ -467,7 +531,11 @@ def _bgp_prefix_not_found(router, vrf, ipversion, prefix): test_func = functools.partial( _bgp_prefix_not_found, tgen.gears["r1"], "vrf1", "ipv6", "172:31::11/128" ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert ( success ), "r1, prefix 172:31::11/128 from r11 did not disappear. r11 still connected to rr ?" @@ -509,7 +577,11 @@ def test_flapping_bgp_vrf_up(): "172:31::11/128", "444:1", ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert ( success ), "r2, prefix 172:31::11/128 from r11 not present. r11 still disconnected from rr ?" @@ -547,7 +619,11 @@ def _prefix30_found(router): # Check r2 received vpnv6 update with 172:31::30 test_func = functools.partial(_prefix30_found, tgen.gears["r2"]) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r2, VPNv6 update 172:31::30 not found" # that route should be sent along with label for 192::2:11 @@ -570,7 +646,11 @@ def _prefix30_found(router): # Check r2 removed 172:31::30 vpnv6 update test_func = functools.partial(_prefix30_not_found, tgen.gears["r2"]) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r2, VPNv6 update 172:31::30 still present" @@ -596,7 +676,11 @@ def test_prefix_changes_interface(): "172:31::50/128", "444:1", ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r2, VPNv6 update 172:31::50 not found" # diagnostic @@ -642,7 +726,11 @@ def test_prefix_changes_interface(): "444:1", label=oldlabel, ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert ( success ), "r2, vpnv6 update 172:31::50 with old label {0} still present".format(oldlabel) @@ -659,7 +747,11 @@ def test_prefix_changes_interface(): "172:31::50/128", "444:1", ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r2, vpnv6 update 172:31::50 not found" label_list = set() @@ -724,9 +816,19 @@ def test_changing_default_label_value(): "r1, mpls table, check that MPLS entry with inLabel set to 222 has vrf1 interface" ) test_func = functools.partial( +<<<<<<< HEAD check_show_mpls_table_entry_label_found, router, 222, "vrf1" ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + check_show_mpls_table_entry_label_found, + tgen.gears["r1"], + router, + "vrf1", + label=222, + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r1, mpls entry with label 222 not found" # check label repartition is ok @@ -772,7 +874,11 @@ def test_unconfigure_allocation_mode_nexthop(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, 17 ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r1, mpls entry with label 17 still present" # Check vpnv6 routes from r1 @@ -821,7 +927,11 @@ def test_reconfigure_allocation_mode_nexthop(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, 17 ) +<<<<<<< HEAD success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +======= + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) assert success, "r1, mpls entry with label 17 still present" # Check vpnv6 routes from r1 @@ -837,6 +947,136 @@ def test_reconfigure_allocation_mode_nexthop(): mpls_table_check(router, label_list=label_list) +<<<<<<< HEAD +======= +def test_network_command(): + """ + Test with network declaration + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + logger.info("Disabling redistribute static") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\nno redistribute static\n", + isjson=False, + ) + logger.info("Checking BGP VPNv6 labels on r2") + for p in ["172:31::14/128", "172:31::15/128"]: + test_func = functools.partial( + check_show_bgp_vpn_prefix_not_found, tgen.gears["r2"], "ipv6", p, "444:1" + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) + assert success, "network %s should not present on r2" % p + + logger.info("Use network command for host networks declared in static instead") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\nnetwork 172:31::14/128\n", + isjson=False, + ) + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\nnetwork 172:31::15/128\n", + isjson=False, + ) + logger.info("Checking BGP VPNv6 labels on r2") + # 172:31::12 uses LL as nexthop + # 172:31::16 uses GA as nexthop + bgp_vpnv6_table_check(tgen.gears["r2"], group=["172:31::12/128"]) + bgp_vpnv6_table_check(tgen.gears["r2"], group=["172:31::15/128"]) + + bgp_vpnv6_table_check(tgen.gears["r2"], group=["172:31::14/128"]) + mpls_table_check(tgen.gears["r1"], whitelist=["192:2::14"]) + + logger.info(" Remove network to 172:31::14/128") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\nno network 172:31::14/128\n", + isjson=False, + ) + logger.info("Checking BGP VPNv6 labels on r2") + test_func = functools.partial( + check_show_bgp_vpn_prefix_not_found, + tgen.gears["r2"], + "ipv6", + "172:31::14/128", + "444:1", + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) + assert success, "network %s should not present on r2" % p + mpls_table_check(tgen.gears["r1"], blacklist=["192:2::14"]) + + logger.info("Disabling redistribute connected and enabling redistribute static") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\n" + "redistribute static\n no redistribute connected", + isjson=False, + ) + logger.info( + "Use network command for connected host network 192:168::255:0/112 in vrf" + ) + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\n" + "network 192:168::255:0/112\n", + isjson=False, + ) + logger.info("Checking BGP VPNv6 labels on r2") + bgp_vpnv6_table_check(tgen.gears["r2"], group=["192:168::255:0/112"]) + logger.info("Checking no mpls entry associated to 192:168::255:0/112") + mpls_table_check(tgen.gears["r1"], blacklist=["192:168:255::0"]) + logger.info("Checking 192:168::255:0/112 fallback to vrf") + test_func = functools.partial( + check_show_mpls_table_entry_label_found, + tgen.gears["r1"], + tgen.gears["r2"], + "vrf1", + network="192:168::255:0/112", + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) + assert success, "192:168::255:0/112 does not fallback to vrf" + + logger.info( + "Use network command for statically routed network 192:168::3:0/112 in vrf" + ) + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nvrf vrf1\n" "ipv6 route 192:168::3:0/112 192:2::11\n" + ) + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\n" + "network 192:168::3:0/112\n", + isjson=False, + ) + logger.info("Checking 192:168::3:0/112 route on r2") + test_func = functools.partial( + check_show_mpls_table_entry_label_found_nexthop, + tgen.gears["r1"], + tgen.gears["r2"], + "192:168::3:0/112", + "192:2::11", + ) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=3) + assert success, "label from r2 is not present on r1 for 192:168::3:0/112" + + # diagnostic + logger.info("Dumping label nexthop table") + tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 label-nexthop detail", isjson=False) + logger.info("Dumping bgp network import-check-table") + tgen.gears["r1"].vtysh_cmd( + "show bgp vrf vrf1 import-check-table detail", isjson=False + ) + + logger.info("Restoring 172:31::14 prefix on r1") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\nnetwork 172:31::14/128\n", + isjson=False, + ) + logger.info("Restoring redistribute connected") + tgen.gears["r1"].vtysh_cmd( + "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\n" + "no redistribute static\n redistribute connected", + isjson=False, + ) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() diff --git a/tests/topotests/bgp_vrf_netns/r1/bgpd.conf b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf index 572dce745574..43cc6308112f 100644 --- a/tests/topotests/bgp_vrf_netns/r1/bgpd.conf +++ b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf @@ -5,6 +5,10 @@ router bgp 100 vrf r1-bgp-cust1 no bgp ebgp-requires-policy neighbor 10.0.1.101 remote-as 99 neighbor 10.0.1.101 timers 3 10 +<<<<<<< HEAD +======= + neighbor 10.0.1.101 timers connect 1 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! diff --git a/tests/topotests/conftest.py b/tests/topotests/conftest.py index 44536e945efe..0f4eafff40d0 100755 --- a/tests/topotests/conftest.py +++ b/tests/topotests/conftest.py @@ -522,9 +522,20 @@ def pytest_configure(config): is_xdist = True is_worker = True +<<<<<<< HEAD resource.setrlimit( resource.RLIMIT_CORE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY) ) +======= + try: + resource.setrlimit( + resource.RLIMIT_CORE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY) + ) + except ValueError: + # The hard limit cannot be raised. Raise the soft limit to previous hard limit + core_rlimits = resource.getrlimit(resource.RLIMIT_CORE) + resource.setrlimit(resource.RLIMIT_CORE, (core_rlimits[1], core_rlimits[1])) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # ----------------------------------------------------- # Set some defaults for the pytest.ini [pytest] section # --------------------------------------------------- diff --git a/tests/topotests/docker/README.md b/tests/topotests/docker/README.md index 2b40994cf61f..a342e0026856 100644 --- a/tests/topotests/docker/README.md +++ b/tests/topotests/docker/README.md @@ -68,5 +68,9 @@ without pulling from the registry using the following commands: ```console make topotests-build +<<<<<<< HEAD TOPOTEST_PULL=0 make topotests +======= +make topotests +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ``` diff --git a/tests/topotests/docker/build.sh b/tests/topotests/docker/build.sh index aec20587ba39..63b7913f9c1b 100755 --- a/tests/topotests/docker/build.sh +++ b/tests/topotests/docker/build.sh @@ -1,11 +1,19 @@ +<<<<<<< HEAD #!/bin/bash +======= +#!/usr/bin/env bash +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # SPDX-License-Identifier: MIT # # Copyright 2018 Network Device Education Foundation, Inc. ("NetDEF") cd "$(dirname "$0")"/.. +<<<<<<< HEAD exec docker build --pull \ +======= +exec $(command -v docker || command -v podman) build --pull \ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) --compress \ -t frrouting/topotests:latest \ . diff --git a/tests/topotests/docker/frr-topotests.sh b/tests/topotests/docker/frr-topotests.sh index ce373d9bd082..619cf1fba4fa 100755 --- a/tests/topotests/docker/frr-topotests.sh +++ b/tests/topotests/docker/frr-topotests.sh @@ -1,4 +1,8 @@ +<<<<<<< HEAD #!/bin/bash +======= +#!/usr/bin/env bash +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # SPDX-License-Identifier: MIT # # Copyright 2018 Network Device Education Foundation, Inc. ("NetDEF") @@ -45,9 +49,12 @@ if [[ "$1" = "-h" ]] || [[ "$1" = "--help" ]]; then TOPOTEST_OPTIONS These options are appended to the docker-run command for starting the tests. +<<<<<<< HEAD TOPOTEST_PULL If set to 0, don't try to pull the most recent version of the docker image from dockerhub. +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) TOPOTEST_SANITIZER Controls whether to use the address sanitizer. Enabled by default, set to 0 to disable. @@ -116,6 +123,7 @@ if [ -z "$TOPOTEST_FRR" ]; then git -C "$TOPOTEST_FRR" ls-files -z > "${TOPOTEST_LOGS}/git-ls-files" fi +<<<<<<< HEAD if [ -z "$TOPOTEST_BUILDCACHE" ]; then TOPOTEST_BUILDCACHE=topotest-buildcache docker volume inspect "${TOPOTEST_BUILDCACHE}" &> /dev/null \ @@ -124,6 +132,14 @@ fi if [ "${TOPOTEST_PULL:-1}" = "1" ]; then docker pull frrouting/topotests:latest +======= +cmd="$(command -v docker || command -v podman)" + +if [ -z "$TOPOTEST_BUILDCACHE" ]; then + TOPOTEST_BUILDCACHE=topotest-buildcache + "${cmd}" volume inspect "${TOPOTEST_BUILDCACHE}" &> /dev/null \ + || "${cmd}" volume create "${TOPOTEST_BUILDCACHE}" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) fi if [[ -n "$TMUX" ]]; then @@ -152,4 +168,8 @@ if [ -t 0 ]; then set -- -t "$@" fi +<<<<<<< HEAD exec docker run "$@" +======= +exec "${cmd}" run "$@" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/docker/inner/compile_frr.sh b/tests/topotests/docker/inner/compile_frr.sh index 4a88dc677f3c..820ea6557c89 100755 --- a/tests/topotests/docker/inner/compile_frr.sh +++ b/tests/topotests/docker/inner/compile_frr.sh @@ -58,9 +58,12 @@ if [ ! -e Makefile ]; then fi bash configure >&3 \ +<<<<<<< HEAD --enable-static-bin \ --enable-static \ --enable-shared \ +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) --enable-dev-build \ --with-moduledir=/usr/lib/frr/modules \ --prefix=/usr \ @@ -69,6 +72,11 @@ if [ ! -e Makefile ]; then --sbindir=/usr/lib/frr \ --enable-multipath=0 \ --enable-fpm \ +<<<<<<< HEAD +======= + --enable-grpc \ + --enable-scripting \ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) --enable-sharpd \ $EXTRA_CONFIGURE \ --with-pkg-extra-version=-topotests \ diff --git a/tests/topotests/docker/inner/entrypoint.sh b/tests/topotests/docker/inner/entrypoint.sh index 44e16db4b9ff..ae6da066fb3a 100755 --- a/tests/topotests/docker/inner/entrypoint.sh +++ b/tests/topotests/docker/inner/entrypoint.sh @@ -20,6 +20,14 @@ cd "${FRR_BUILD_DIR}/tests/topotests" log_info "Setting permissions on /tmp so we can generate logs" chmod 1777 /tmp +<<<<<<< HEAD +======= +# This is a MUST, otherwise we have: +# AddressSanitizer:DEADLYSIGNAL +# Segmentation fault +sysctl -w vm.mmap_rnd_bits=28 + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if [ $# -eq 0 ] || ([[ "$1" != /* ]] && [[ "$1" != ./* ]]); then export TOPOTESTS_CHECK_MEMLEAK=/tmp/memleak_ export TOPOTESTS_CHECK_STDERR=Yes diff --git a/tests/topotests/high_ecmp/r1/frr.conf b/tests/topotests/high_ecmp/r1/frr.conf new file mode 100644 index 000000000000..4382f94cf122 --- /dev/null +++ b/tests/topotests/high_ecmp/r1/frr.conf @@ -0,0 +1,267 @@ +int lo + ip addr 192.168.1.1/32 +router bgp 1001 + timers bgp 5 20 + no bgp ebgp-requires-policy + neighbor r1-eth0 interface remote-as external + neighbor r1-eth1 interface remote-as external + neighbor r1-eth2 interface remote-as external + neighbor r1-eth3 interface remote-as external + neighbor r1-eth4 interface remote-as external + neighbor r1-eth5 interface remote-as external + neighbor r1-eth6 interface remote-as external + neighbor r1-eth7 interface remote-as external + neighbor r1-eth8 interface remote-as external + neighbor r1-eth9 interface remote-as external + neighbor r1-eth10 interface remote-as external + neighbor r1-eth11 interface remote-as external + neighbor r1-eth12 interface remote-as external + neighbor r1-eth13 interface remote-as external + neighbor r1-eth14 interface remote-as external + neighbor r1-eth15 interface remote-as external + neighbor r1-eth16 interface remote-as external + neighbor r1-eth17 interface remote-as external + neighbor r1-eth18 interface remote-as external + neighbor r1-eth19 interface remote-as external + neighbor r1-eth20 interface remote-as external + neighbor r1-eth21 interface remote-as external + neighbor r1-eth22 interface remote-as external + neighbor r1-eth23 interface remote-as external + neighbor r1-eth24 interface remote-as external + neighbor r1-eth25 interface remote-as external + neighbor r1-eth26 interface remote-as external + neighbor r1-eth27 interface remote-as external + neighbor r1-eth28 interface remote-as external + neighbor r1-eth29 interface remote-as external + neighbor r1-eth30 interface remote-as external + neighbor r1-eth31 interface remote-as external + neighbor r1-eth32 interface remote-as external + neighbor r1-eth33 interface remote-as external + neighbor r1-eth34 interface remote-as external + neighbor r1-eth35 interface remote-as external + neighbor r1-eth36 interface remote-as external + neighbor r1-eth37 interface remote-as external + neighbor r1-eth38 interface remote-as external + neighbor r1-eth39 interface remote-as external + neighbor r1-eth40 interface remote-as external + neighbor r1-eth41 interface remote-as external + neighbor r1-eth42 interface remote-as external + neighbor r1-eth43 interface remote-as external + neighbor r1-eth44 interface remote-as external + neighbor r1-eth45 interface remote-as external + neighbor r1-eth46 interface remote-as external + neighbor r1-eth47 interface remote-as external + neighbor r1-eth48 interface remote-as external + neighbor r1-eth49 interface remote-as external + neighbor r1-eth50 interface remote-as external + neighbor r1-eth51 interface remote-as external + neighbor r1-eth52 interface remote-as external + neighbor r1-eth53 interface remote-as external + neighbor r1-eth54 interface remote-as external + neighbor r1-eth55 interface remote-as external + neighbor r1-eth56 interface remote-as external + neighbor r1-eth57 interface remote-as external + neighbor r1-eth58 interface remote-as external + neighbor r1-eth59 interface remote-as external + neighbor r1-eth60 interface remote-as external + neighbor r1-eth61 interface remote-as external + neighbor r1-eth62 interface remote-as external + neighbor r1-eth63 interface remote-as external + neighbor r1-eth64 interface remote-as external + neighbor r1-eth65 interface remote-as external + neighbor r1-eth66 interface remote-as external + neighbor r1-eth67 interface remote-as external + neighbor r1-eth68 interface remote-as external + neighbor r1-eth69 interface remote-as external + neighbor r1-eth70 interface remote-as external + neighbor r1-eth71 interface remote-as external + neighbor r1-eth72 interface remote-as external + neighbor r1-eth73 interface remote-as external + neighbor r1-eth74 interface remote-as external + neighbor r1-eth75 interface remote-as external + neighbor r1-eth76 interface remote-as external + neighbor r1-eth77 interface remote-as external + neighbor r1-eth78 interface remote-as external + neighbor r1-eth79 interface remote-as external + neighbor r1-eth80 interface remote-as external + neighbor r1-eth81 interface remote-as external + neighbor r1-eth82 interface remote-as external + neighbor r1-eth83 interface remote-as external + neighbor r1-eth84 interface remote-as external + neighbor r1-eth85 interface remote-as external + neighbor r1-eth86 interface remote-as external + neighbor r1-eth87 interface remote-as external + neighbor r1-eth88 interface remote-as external + neighbor r1-eth89 interface remote-as external + neighbor r1-eth90 interface remote-as external + neighbor r1-eth91 interface remote-as external + neighbor r1-eth92 interface remote-as external + neighbor r1-eth93 interface remote-as external + neighbor r1-eth94 interface remote-as external + neighbor r1-eth95 interface remote-as external + neighbor r1-eth96 interface remote-as external + neighbor r1-eth97 interface remote-as external + neighbor r1-eth98 interface remote-as external + neighbor r1-eth99 interface remote-as external + neighbor r1-eth100 interface remote-as external + neighbor r1-eth101 interface remote-as external + neighbor r1-eth102 interface remote-as external + neighbor r1-eth103 interface remote-as external + neighbor r1-eth104 interface remote-as external + neighbor r1-eth105 interface remote-as external + neighbor r1-eth106 interface remote-as external + neighbor r1-eth107 interface remote-as external + neighbor r1-eth108 interface remote-as external + neighbor r1-eth109 interface remote-as external + neighbor r1-eth110 interface remote-as external + neighbor r1-eth111 interface remote-as external + neighbor r1-eth112 interface remote-as external + neighbor r1-eth113 interface remote-as external + neighbor r1-eth114 interface remote-as external + neighbor r1-eth115 interface remote-as external + neighbor r1-eth116 interface remote-as external + neighbor r1-eth117 interface remote-as external + neighbor r1-eth118 interface remote-as external + neighbor r1-eth119 interface remote-as external + neighbor r1-eth120 interface remote-as external + neighbor r1-eth121 interface remote-as external + neighbor r1-eth122 interface remote-as external + neighbor r1-eth123 interface remote-as external + neighbor r1-eth124 interface remote-as external + neighbor r1-eth125 interface remote-as external + neighbor r1-eth126 interface remote-as external + neighbor r1-eth127 interface remote-as external + neighbor r1-eth128 interface remote-as external + neighbor r1-eth129 interface remote-as external + neighbor r1-eth130 interface remote-as external + neighbor r1-eth131 interface remote-as external + neighbor r1-eth132 interface remote-as external + neighbor r1-eth133 interface remote-as external + neighbor r1-eth134 interface remote-as external + neighbor r1-eth135 interface remote-as external + neighbor r1-eth136 interface remote-as external + neighbor r1-eth137 interface remote-as external + neighbor r1-eth138 interface remote-as external + neighbor r1-eth139 interface remote-as external + neighbor r1-eth140 interface remote-as external + neighbor r1-eth141 interface remote-as external + neighbor r1-eth142 interface remote-as external + neighbor r1-eth143 interface remote-as external + neighbor r1-eth144 interface remote-as external + neighbor r1-eth145 interface remote-as external + neighbor r1-eth146 interface remote-as external + neighbor r1-eth147 interface remote-as external + neighbor r1-eth148 interface remote-as external + neighbor r1-eth149 interface remote-as external + neighbor r1-eth150 interface remote-as external + neighbor r1-eth151 interface remote-as external + neighbor r1-eth152 interface remote-as external + neighbor r1-eth153 interface remote-as external + neighbor r1-eth154 interface remote-as external + neighbor r1-eth155 interface remote-as external + neighbor r1-eth156 interface remote-as external + neighbor r1-eth157 interface remote-as external + neighbor r1-eth158 interface remote-as external + neighbor r1-eth159 interface remote-as external + neighbor r1-eth160 interface remote-as external + neighbor r1-eth161 interface remote-as external + neighbor r1-eth162 interface remote-as external + neighbor r1-eth163 interface remote-as external + neighbor r1-eth164 interface remote-as external + neighbor r1-eth165 interface remote-as external + neighbor r1-eth166 interface remote-as external + neighbor r1-eth167 interface remote-as external + neighbor r1-eth168 interface remote-as external + neighbor r1-eth169 interface remote-as external + neighbor r1-eth170 interface remote-as external + neighbor r1-eth171 interface remote-as external + neighbor r1-eth172 interface remote-as external + neighbor r1-eth173 interface remote-as external + neighbor r1-eth174 interface remote-as external + neighbor r1-eth175 interface remote-as external + neighbor r1-eth176 interface remote-as external + neighbor r1-eth177 interface remote-as external + neighbor r1-eth178 interface remote-as external + neighbor r1-eth179 interface remote-as external + neighbor r1-eth180 interface remote-as external + neighbor r1-eth181 interface remote-as external + neighbor r1-eth182 interface remote-as external + neighbor r1-eth183 interface remote-as external + neighbor r1-eth184 interface remote-as external + neighbor r1-eth185 interface remote-as external + neighbor r1-eth186 interface remote-as external + neighbor r1-eth187 interface remote-as external + neighbor r1-eth188 interface remote-as external + neighbor r1-eth189 interface remote-as external + neighbor r1-eth190 interface remote-as external + neighbor r1-eth191 interface remote-as external + neighbor r1-eth192 interface remote-as external + neighbor r1-eth193 interface remote-as external + neighbor r1-eth194 interface remote-as external + neighbor r1-eth195 interface remote-as external + neighbor r1-eth196 interface remote-as external + neighbor r1-eth197 interface remote-as external + neighbor r1-eth198 interface remote-as external + neighbor r1-eth199 interface remote-as external + neighbor r1-eth200 interface remote-as external + neighbor r1-eth201 interface remote-as external + neighbor r1-eth202 interface remote-as external + neighbor r1-eth203 interface remote-as external + neighbor r1-eth204 interface remote-as external + neighbor r1-eth205 interface remote-as external + neighbor r1-eth206 interface remote-as external + neighbor r1-eth207 interface remote-as external + neighbor r1-eth208 interface remote-as external + neighbor r1-eth209 interface remote-as external + neighbor r1-eth210 interface remote-as external + neighbor r1-eth211 interface remote-as external + neighbor r1-eth212 interface remote-as external + neighbor r1-eth213 interface remote-as external + neighbor r1-eth214 interface remote-as external + neighbor r1-eth215 interface remote-as external + neighbor r1-eth216 interface remote-as external + neighbor r1-eth217 interface remote-as external + neighbor r1-eth218 interface remote-as external + neighbor r1-eth219 interface remote-as external + neighbor r1-eth220 interface remote-as external + neighbor r1-eth221 interface remote-as external + neighbor r1-eth222 interface remote-as external + neighbor r1-eth223 interface remote-as external + neighbor r1-eth224 interface remote-as external + neighbor r1-eth225 interface remote-as external + neighbor r1-eth226 interface remote-as external + neighbor r1-eth227 interface remote-as external + neighbor r1-eth228 interface remote-as external + neighbor r1-eth229 interface remote-as external + neighbor r1-eth230 interface remote-as external + neighbor r1-eth231 interface remote-as external + neighbor r1-eth232 interface remote-as external + neighbor r1-eth233 interface remote-as external + neighbor r1-eth234 interface remote-as external + neighbor r1-eth235 interface remote-as external + neighbor r1-eth236 interface remote-as external + neighbor r1-eth237 interface remote-as external + neighbor r1-eth238 interface remote-as external + neighbor r1-eth239 interface remote-as external + neighbor r1-eth240 interface remote-as external + neighbor r1-eth241 interface remote-as external + neighbor r1-eth242 interface remote-as external + neighbor r1-eth243 interface remote-as external + neighbor r1-eth244 interface remote-as external + neighbor r1-eth245 interface remote-as external + neighbor r1-eth246 interface remote-as external + neighbor r1-eth247 interface remote-as external + neighbor r1-eth248 interface remote-as external + neighbor r1-eth249 interface remote-as external + neighbor r1-eth250 interface remote-as external + neighbor r1-eth251 interface remote-as external + neighbor r1-eth252 interface remote-as external + neighbor r1-eth253 interface remote-as external + neighbor r1-eth254 interface remote-as external + neighbor r1-eth255 interface remote-as external + neighbor r1-eth256 interface remote-as external + neighbor r1-eth257 interface remote-as external + neighbor r1-eth258 interface remote-as external + neighbor r1-eth259 interface remote-as external + address-family ipv4 uni + redistribute sharp diff --git a/tests/topotests/high_ecmp/r2/frr.conf b/tests/topotests/high_ecmp/r2/frr.conf new file mode 100644 index 000000000000..a9d65360f5ba --- /dev/null +++ b/tests/topotests/high_ecmp/r2/frr.conf @@ -0,0 +1,267 @@ +int lo + ip addr 192.168.1.2/32 +! +router bgp 1002 + timers bgp 5 20 + no bgp ebgp-requires-policy + read-quanta 1 + neighbor r2-eth0 interface remote-as external + neighbor r2-eth1 interface remote-as external + neighbor r2-eth2 interface remote-as external + neighbor r2-eth3 interface remote-as external + neighbor r2-eth4 interface remote-as external + neighbor r2-eth5 interface remote-as external + neighbor r2-eth6 interface remote-as external + neighbor r2-eth7 interface remote-as external + neighbor r2-eth8 interface remote-as external + neighbor r2-eth9 interface remote-as external + neighbor r2-eth10 interface remote-as external + neighbor r2-eth11 interface remote-as external + neighbor r2-eth12 interface remote-as external + neighbor r2-eth13 interface remote-as external + neighbor r2-eth14 interface remote-as external + neighbor r2-eth15 interface remote-as external + neighbor r2-eth16 interface remote-as external + neighbor r2-eth17 interface remote-as external + neighbor r2-eth18 interface remote-as external + neighbor r2-eth19 interface remote-as external + neighbor r2-eth20 interface remote-as external + neighbor r2-eth21 interface remote-as external + neighbor r2-eth22 interface remote-as external + neighbor r2-eth23 interface remote-as external + neighbor r2-eth24 interface remote-as external + neighbor r2-eth25 interface remote-as external + neighbor r2-eth26 interface remote-as external + neighbor r2-eth27 interface remote-as external + neighbor r2-eth28 interface remote-as external + neighbor r2-eth29 interface remote-as external + neighbor r2-eth30 interface remote-as external + neighbor r2-eth31 interface remote-as external + neighbor r2-eth32 interface remote-as external + neighbor r2-eth33 interface remote-as external + neighbor r2-eth34 interface remote-as external + neighbor r2-eth35 interface remote-as external + neighbor r2-eth36 interface remote-as external + neighbor r2-eth37 interface remote-as external + neighbor r2-eth38 interface remote-as external + neighbor r2-eth39 interface remote-as external + neighbor r2-eth40 interface remote-as external + neighbor r2-eth41 interface remote-as external + neighbor r2-eth42 interface remote-as external + neighbor r2-eth43 interface remote-as external + neighbor r2-eth44 interface remote-as external + neighbor r2-eth45 interface remote-as external + neighbor r2-eth46 interface remote-as external + neighbor r2-eth47 interface remote-as external + neighbor r2-eth48 interface remote-as external + neighbor r2-eth49 interface remote-as external + neighbor r2-eth50 interface remote-as external + neighbor r2-eth51 interface remote-as external + neighbor r2-eth52 interface remote-as external + neighbor r2-eth53 interface remote-as external + neighbor r2-eth54 interface remote-as external + neighbor r2-eth55 interface remote-as external + neighbor r2-eth56 interface remote-as external + neighbor r2-eth57 interface remote-as external + neighbor r2-eth58 interface remote-as external + neighbor r2-eth59 interface remote-as external + neighbor r2-eth60 interface remote-as external + neighbor r2-eth61 interface remote-as external + neighbor r2-eth62 interface remote-as external + neighbor r2-eth63 interface remote-as external + neighbor r2-eth64 interface remote-as external + neighbor r2-eth65 interface remote-as external + neighbor r2-eth66 interface remote-as external + neighbor r2-eth67 interface remote-as external + neighbor r2-eth68 interface remote-as external + neighbor r2-eth69 interface remote-as external + neighbor r2-eth70 interface remote-as external + neighbor r2-eth71 interface remote-as external + neighbor r2-eth72 interface remote-as external + neighbor r2-eth73 interface remote-as external + neighbor r2-eth74 interface remote-as external + neighbor r2-eth75 interface remote-as external + neighbor r2-eth76 interface remote-as external + neighbor r2-eth77 interface remote-as external + neighbor r2-eth78 interface remote-as external + neighbor r2-eth79 interface remote-as external + neighbor r2-eth80 interface remote-as external + neighbor r2-eth81 interface remote-as external + neighbor r2-eth82 interface remote-as external + neighbor r2-eth83 interface remote-as external + neighbor r2-eth84 interface remote-as external + neighbor r2-eth85 interface remote-as external + neighbor r2-eth86 interface remote-as external + neighbor r2-eth87 interface remote-as external + neighbor r2-eth88 interface remote-as external + neighbor r2-eth89 interface remote-as external + neighbor r2-eth90 interface remote-as external + neighbor r2-eth91 interface remote-as external + neighbor r2-eth92 interface remote-as external + neighbor r2-eth93 interface remote-as external + neighbor r2-eth94 interface remote-as external + neighbor r2-eth95 interface remote-as external + neighbor r2-eth96 interface remote-as external + neighbor r2-eth97 interface remote-as external + neighbor r2-eth98 interface remote-as external + neighbor r2-eth99 interface remote-as external + neighbor r2-eth100 interface remote-as external + neighbor r2-eth101 interface remote-as external + neighbor r2-eth102 interface remote-as external + neighbor r2-eth103 interface remote-as external + neighbor r2-eth104 interface remote-as external + neighbor r2-eth105 interface remote-as external + neighbor r2-eth106 interface remote-as external + neighbor r2-eth107 interface remote-as external + neighbor r2-eth108 interface remote-as external + neighbor r2-eth109 interface remote-as external + neighbor r2-eth110 interface remote-as external + neighbor r2-eth111 interface remote-as external + neighbor r2-eth112 interface remote-as external + neighbor r2-eth113 interface remote-as external + neighbor r2-eth114 interface remote-as external + neighbor r2-eth115 interface remote-as external + neighbor r2-eth116 interface remote-as external + neighbor r2-eth117 interface remote-as external + neighbor r2-eth118 interface remote-as external + neighbor r2-eth119 interface remote-as external + neighbor r2-eth120 interface remote-as external + neighbor r2-eth121 interface remote-as external + neighbor r2-eth122 interface remote-as external + neighbor r2-eth123 interface remote-as external + neighbor r2-eth124 interface remote-as external + neighbor r2-eth125 interface remote-as external + neighbor r2-eth126 interface remote-as external + neighbor r2-eth127 interface remote-as external + neighbor r2-eth128 interface remote-as external + neighbor r2-eth129 interface remote-as external + neighbor r2-eth130 interface remote-as external + neighbor r2-eth131 interface remote-as external + neighbor r2-eth132 interface remote-as external + neighbor r2-eth133 interface remote-as external + neighbor r2-eth134 interface remote-as external + neighbor r2-eth135 interface remote-as external + neighbor r2-eth136 interface remote-as external + neighbor r2-eth137 interface remote-as external + neighbor r2-eth138 interface remote-as external + neighbor r2-eth139 interface remote-as external + neighbor r2-eth140 interface remote-as external + neighbor r2-eth141 interface remote-as external + neighbor r2-eth142 interface remote-as external + neighbor r2-eth143 interface remote-as external + neighbor r2-eth144 interface remote-as external + neighbor r2-eth145 interface remote-as external + neighbor r2-eth146 interface remote-as external + neighbor r2-eth147 interface remote-as external + neighbor r2-eth148 interface remote-as external + neighbor r2-eth149 interface remote-as external + neighbor r2-eth150 interface remote-as external + neighbor r2-eth151 interface remote-as external + neighbor r2-eth152 interface remote-as external + neighbor r2-eth153 interface remote-as external + neighbor r2-eth154 interface remote-as external + neighbor r2-eth155 interface remote-as external + neighbor r2-eth156 interface remote-as external + neighbor r2-eth157 interface remote-as external + neighbor r2-eth158 interface remote-as external + neighbor r2-eth159 interface remote-as external + neighbor r2-eth160 interface remote-as external + neighbor r2-eth161 interface remote-as external + neighbor r2-eth162 interface remote-as external + neighbor r2-eth163 interface remote-as external + neighbor r2-eth164 interface remote-as external + neighbor r2-eth165 interface remote-as external + neighbor r2-eth166 interface remote-as external + neighbor r2-eth167 interface remote-as external + neighbor r2-eth168 interface remote-as external + neighbor r2-eth169 interface remote-as external + neighbor r2-eth170 interface remote-as external + neighbor r2-eth171 interface remote-as external + neighbor r2-eth172 interface remote-as external + neighbor r2-eth173 interface remote-as external + neighbor r2-eth174 interface remote-as external + neighbor r2-eth175 interface remote-as external + neighbor r2-eth176 interface remote-as external + neighbor r2-eth177 interface remote-as external + neighbor r2-eth178 interface remote-as external + neighbor r2-eth179 interface remote-as external + neighbor r2-eth180 interface remote-as external + neighbor r2-eth181 interface remote-as external + neighbor r2-eth182 interface remote-as external + neighbor r2-eth183 interface remote-as external + neighbor r2-eth184 interface remote-as external + neighbor r2-eth185 interface remote-as external + neighbor r2-eth186 interface remote-as external + neighbor r2-eth187 interface remote-as external + neighbor r2-eth188 interface remote-as external + neighbor r2-eth189 interface remote-as external + neighbor r2-eth190 interface remote-as external + neighbor r2-eth191 interface remote-as external + neighbor r2-eth192 interface remote-as external + neighbor r2-eth193 interface remote-as external + neighbor r2-eth194 interface remote-as external + neighbor r2-eth195 interface remote-as external + neighbor r2-eth196 interface remote-as external + neighbor r2-eth197 interface remote-as external + neighbor r2-eth198 interface remote-as external + neighbor r2-eth199 interface remote-as external + neighbor r2-eth200 interface remote-as external + neighbor r2-eth201 interface remote-as external + neighbor r2-eth202 interface remote-as external + neighbor r2-eth203 interface remote-as external + neighbor r2-eth204 interface remote-as external + neighbor r2-eth205 interface remote-as external + neighbor r2-eth206 interface remote-as external + neighbor r2-eth207 interface remote-as external + neighbor r2-eth208 interface remote-as external + neighbor r2-eth209 interface remote-as external + neighbor r2-eth210 interface remote-as external + neighbor r2-eth211 interface remote-as external + neighbor r2-eth212 interface remote-as external + neighbor r2-eth213 interface remote-as external + neighbor r2-eth214 interface remote-as external + neighbor r2-eth215 interface remote-as external + neighbor r2-eth216 interface remote-as external + neighbor r2-eth217 interface remote-as external + neighbor r2-eth218 interface remote-as external + neighbor r2-eth219 interface remote-as external + neighbor r2-eth220 interface remote-as external + neighbor r2-eth221 interface remote-as external + neighbor r2-eth222 interface remote-as external + neighbor r2-eth223 interface remote-as external + neighbor r2-eth224 interface remote-as external + neighbor r2-eth225 interface remote-as external + neighbor r2-eth226 interface remote-as external + neighbor r2-eth227 interface remote-as external + neighbor r2-eth228 interface remote-as external + neighbor r2-eth229 interface remote-as external + neighbor r2-eth230 interface remote-as external + neighbor r2-eth231 interface remote-as external + neighbor r2-eth232 interface remote-as external + neighbor r2-eth233 interface remote-as external + neighbor r2-eth234 interface remote-as external + neighbor r2-eth235 interface remote-as external + neighbor r2-eth236 interface remote-as external + neighbor r2-eth237 interface remote-as external + neighbor r2-eth238 interface remote-as external + neighbor r2-eth239 interface remote-as external + neighbor r2-eth240 interface remote-as external + neighbor r2-eth241 interface remote-as external + neighbor r2-eth242 interface remote-as external + neighbor r2-eth243 interface remote-as external + neighbor r2-eth244 interface remote-as external + neighbor r2-eth245 interface remote-as external + neighbor r2-eth246 interface remote-as external + neighbor r2-eth247 interface remote-as external + neighbor r2-eth248 interface remote-as external + neighbor r2-eth249 interface remote-as external + neighbor r2-eth250 interface remote-as external + neighbor r2-eth251 interface remote-as external + neighbor r2-eth252 interface remote-as external + neighbor r2-eth253 interface remote-as external + neighbor r2-eth254 interface remote-as external + neighbor r2-eth255 interface remote-as external + neighbor r2-eth256 interface remote-as external + neighbor r2-eth257 interface remote-as external + neighbor r2-eth258 interface remote-as external + neighbor r2-eth259 interface remote-as external diff --git a/tests/topotests/high_ecmp/test_high_ecmp.py b/tests/topotests/high_ecmp/test_high_ecmp.py new file mode 100644 index 000000000000..d28a1ee0690e --- /dev/null +++ b/tests/topotests/high_ecmp/test_high_ecmp.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_high_ecmp.py +# +# Copyright (c) 2024 by +# Nvidia Corporation +# Donald Sharp +# + +""" +test_high_ecmp.py: Testing two routers with 256 interfaces and BGP setup + on it. + +""" + +import os +import re +import sys +import pytest +import json + +pytestmark = [pytest.mark.bgpd] + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# Required to instantiate the topology builder class. + +##################################################### +## +## Network Topology Definition +## +##################################################### + + +def build_topo(tgen): + + tgen.add_router("r1") + tgen.add_router("r2") + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + # Let's create 257 interfaces between the two switches + for switch in range(1, 257): + switch = tgen.add_switch("sw{}".format(switch)) + switch.add_link(r1) + switch.add_link(r2) + + +##################################################### +## +## Tests starting +## +##################################################### + + +def setup_module(module): + "Setup topology" + tgen = Topogen(build_topo, module.__name__) + tgen.start_topology() + + # This is a sample of configuration loading. + router_list = tgen.routers() + for rname, router in router_list.items(): + router.load_frr_config( + os.path.join(CWD, "{}/frr.conf".format(rname)), + [ + (TopoRouter.RD_ZEBRA, "-s 180000000"), + (TopoRouter.RD_BGP, None), + (TopoRouter.RD_SHARP, None), + ], + ) + + tgen.start_router() + + +def teardown_module(_mod): + "Teardown the pytest environment" + tgen = get_topogen() + + # This function tears down the whole topology. + tgen.stop_topology() + + +def test_nothing(): + "Do Nothing" + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py index 1cec2f16f057..9348147a3cf1 100644 --- a/tests/topotests/isis_topo1/test_isis_topo1.py +++ b/tests/topotests/isis_topo1/test_isis_topo1.py @@ -12,6 +12,10 @@ """ test_isis_topo1.py: Test ISIS topology. """ +<<<<<<< HEAD +======= +import time +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) import datetime import functools import json @@ -237,9 +241,15 @@ def test_isis_summary_json(): assertmsg = "Test isis summary json failed in '{}' data '{}'".format( rname, json_output ) +<<<<<<< HEAD assert json_output["vrf"] == "default", assertmsg assert json_output["areas"][0]["area"] == "1", assertmsg assert json_output["areas"][0]["levels"][0]["id"] != "3", assertmsg +======= + assert json_output["vrfs"][0]["vrf"] == "default", assertmsg + assert json_output["vrfs"][0]["areas"][0]["area"] == "1", assertmsg + assert json_output["vrfs"][0]["areas"][0]["levels"][0]["id"] != "3", assertmsg +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_isis_interface_json(): @@ -314,6 +324,110 @@ def test_isis_neighbor_json(): ), assertmsg +<<<<<<< HEAD +======= +def test_isis_neighbor_state(): + "Check that the neighbor states remain normal when the ISIS type is switched." + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking 'show isis neighbor state on a p2p link'") + + # Establish a P2P link + # When the IS-IS type of r3 is set to level-1-2 and the IS-IS type of r5 is set to level-1, + # it is expected that all neighbors exist and are in the Up state + r3 = tgen.gears["r3"] + r3.vtysh_cmd( + """ + configure + router isis 1 + no redistribute ipv4 connected level-1 + no redistribute ipv4 connected level-2 + no redistribute ipv6 connected level-1 + no redistribute ipv6 connected level-2 + interface r3-eth1 + no isis circuit-type + isis network point-to-point + end + """ + ) + r5 = tgen.gears["r5"] + r5.vtysh_cmd( + """ + configure + router isis 1 + no redistribute ipv4 connected level-1 + no redistribute ipv6 connected level-1 + no redistribute ipv4 table 20 level-1 + interface r5-eth0 + no isis circuit-type + isis network point-to-point + end + """ + ) + result = _check_isis_neighbor_json("r3", "r5", True, "Up") + assert result is True, result + result = _check_isis_neighbor_json("r5", "r3", True, "Up") + assert result is True, result + + # Remove the configuration that affects the switch of IS-IS type. + # Configure the IS-IS type of r3 to transition from level-1-2 to level-2-only, + # while maintaining the IS-IS type of r5 as level-1. + # In this scenario, + # the expectation is that some neighbors do not exist or are in the Initializing state + r3.vtysh_cmd( + """ + configure + router isis 1 + is-type level-2-only + end + """ + ) + result = _check_isis_neighbor_json("r3", "r5", False, "Initializing") + assert result is True, result + result = _check_isis_neighbor_json("r5", "r3", False, "Initializing") + assert result is True, result + + # Restore to initial configuration + logger.info("Checking 'restore to initial configuration'") + r3.vtysh_cmd( + """ + configure + interface r3-eth1 + isis circuit-type level-1 + no isis network point-to-point + router isis 1 + no is-type + redistribute ipv4 connected level-1 + redistribute ipv4 connected level-2 + redistribute ipv6 connected level-1 + redistribute ipv6 connected level-2 + end + """ + ) + r5.vtysh_cmd( + """ + configure + interface r5-eth0 + isis circuit-type level-1 + no isis network point-to-point + router isis 1 + redistribute ipv4 connected level-1 + redistribute ipv6 connected level-1 + redistribute ipv4 table 20 level-1 + end + """ + ) + result = _check_isis_neighbor_json("r3", "r5", True, "Up") + assert result is True, result + result = _check_isis_neighbor_json("r5", "r3", True, "Up") + assert result is True, result + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_isis_database_json(): "Check json struct in show isis database json" @@ -623,6 +737,68 @@ def test_isis_hello_padding_during_adjacency_formation(): assert result is True, result +<<<<<<< HEAD +======= +def _check_isis_neighbor_json( + self, neighbor, neighbor_expected, neighbor_state_expected +): + tgen = get_topogen() + router = tgen.gears[self] + logger.info( + f"check_isis_neighbor_json {router} {neighbor} {neighbor_expected} {neighbor_state_expected}" + ) + + result = _check_isis_neighbor_exist(self, neighbor) + if result == True: + return _check_isis_neighbor_state(self, neighbor, neighbor_state_expected) + elif neighbor_expected == True: + return "{} with expected neighbor {} got none ".format(router.name, neighbor) + else: + return True + + +@retry(retry_timeout=60) +def _check_isis_neighbor_exist(self, neighbor): + tgen = get_topogen() + router = tgen.gears[self] + logger.info(f"check_isis_neighbor_exist {router} {neighbor}") + neighbor_json = router.vtysh_cmd("show isis neighbor json", isjson=True) + + circuits = neighbor_json.get("areas", [])[0].get("circuits", []) + for circuit in circuits: + if "adj" in circuit and circuit["adj"] == neighbor: + return True + + return "The neighbor {} of router {} has not been learned yet ".format( + neighbor, router.name + ) + + +@retry(retry_timeout=5) +def _check_isis_neighbor_state(self, neighbor, neighbor_state_expected): + tgen = get_topogen() + router = tgen.gears[self] + logger.info( + f"check_isis_neighbor_state {router} {neighbor} {neighbor_state_expected}" + ) + neighbor_json = router.vtysh_cmd( + "show isis neighbor {} json".format(neighbor), isjson=True + ) + + circuits = neighbor_json.get("areas", [])[0].get("circuits", []) + for circuit in circuits: + interface = circuit.get("interface", {}) + if "state" in interface: + neighbor_state = interface["state"] + if neighbor_state == neighbor_state_expected: + return True + + return "{} peer with expected neighbor_state {} got {} ".format( + router.name, neighbor_state_expected, neighbor_state + ) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) @retry(retry_timeout=10) def check_last_iih_packet_for_padding(router, expect_padding): logfilename = "{}/{}".format(router.gearlogdir, "isisd.log") diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index bcd1c748120f..16e4d2378904 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -5638,3 +5638,25 @@ def configure_bgp_soft_configuration(tgen, dut, neighbor_dict, direction): ) ) return True +<<<<<<< HEAD +======= + + +def bgp_configure_prefixes(router, asn, safi, prefixes, vrf=None, update=True): + """ + Configure the bgp prefixes. + """ + withdraw = "no " if not update else "" + vrf = " vrf {}".format(vrf) if vrf else "" + for p in prefixes: + ip = ipaddress.ip_network(p) + cmd = [ + "conf t\n", + f"router bgp {asn}{vrf}\n" + f"address-family ipv{ip.version} {safi}\n" + f"{withdraw}network {ip}\n".format(withdraw, ip), + "exit-address-family\n", + ] + logger.debug(f"setting prefix: ipv{ip.version} {safi} {ip}") + router.vtysh_cmd("".join(cmd)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/lib/bmp_collector/bgp/update/path_attributes.py b/tests/topotests/lib/bmp_collector/bgp/update/path_attributes.py index 3694cb4fe3df..698e6dd13eb8 100644 --- a/tests/topotests/lib/bmp_collector/bgp/update/path_attributes.py +++ b/tests/topotests/lib/bmp_collector/bgp/update/path_attributes.py @@ -72,6 +72,15 @@ def dissect(cls, data): if path_attr_cls == cls.UNKNOWN_ATTR: return data[offset + attr_len :], None +<<<<<<< HEAD +======= + # RFC1771, 4.3 UPDATE Message Format + # The path segment length is a 1-octet long field containing + # the number of ASs in the path segment value field. + if type_code == PATH_ATTR_TYPE_AS_PATH and attr_len == 0: + return data[offset:], path_attr_cls.dissect(data[offset : offset + 2]) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return data[offset + attr_len :], path_attr_cls.dissect( data[offset : offset + attr_len] ) diff --git a/tests/topotests/lib/bmp_collector/bmp.py b/tests/topotests/lib/bmp_collector/bmp.py index 237decdd5ecb..2ee582f82eae 100644 --- a/tests/topotests/lib/bmp_collector/bmp.py +++ b/tests/topotests/lib/bmp_collector/bmp.py @@ -10,11 +10,20 @@ - XXX: more bmp messages types to dissect - XXX: complete bgp message dissection """ +<<<<<<< HEAD import datetime +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) import ipaddress import json import os import struct +<<<<<<< HEAD +======= +import sys + +from datetime import datetime +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) from bgp.update import BGPUpdate from bgp.update.rd import RouteDistinguisher @@ -48,6 +57,16 @@ def log2file(logs, log_file): f.write(json.dumps(logs) + "\n") +<<<<<<< HEAD +======= +def timestamp_print(message, file=sys.stderr): + """Helper function to timestamp_print messages with timestamps.""" + + current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(f"[{current_time}] {message}", file=file) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # ------------------------------------------------------------------------------ class BMPCodes: """ @@ -196,14 +215,28 @@ def dissect(cls, data, log_file=None): data = data[msglen:] if version != BMPCodes.VERSION: +<<<<<<< HEAD # XXX: log something +======= + timestamp_print( + f"Expected BMP version {BMPCodes.VERSION} but got version {version}." + ) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return data msg_cls = cls.lookup_msg_type(msgtype) if msg_cls == cls.UNKNOWN_TYPE: +<<<<<<< HEAD # XXX: log something return data +======= + timestamp_print(f"Got unknown message type ") + return data + + timestamp_print(f"Got message type: {msg_cls}") + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) msg_cls.MSG_LEN = msglen - cls.MIN_LEN logs = msg_cls.dissect(msg_data) logs["seq"] = SEQ @@ -281,7 +314,11 @@ def dissect(cls, data): "peer_distinguisher": str(RouteDistinguisher(peer_distinguisher)), "peer_asn": peer_asn, "peer_bgp_id": peer_bgp_id, +<<<<<<< HEAD "timestamp": str(datetime.datetime.fromtimestamp(timestamp)), +======= + "timestamp": str(datetime.fromtimestamp(timestamp)), +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } ) @@ -316,7 +353,12 @@ class BMPStatisticsReport: # ------------------------------------------------------------------------------ +<<<<<<< HEAD class BMPPeerDownNotification: +======= +@BMPMsg.register_msg_type(BMPCodes.BMP_MSG_TYPE_PEER_DOWN_NOTIFICATION) +class BMPPeerDownNotification(BMPPerPeerMessage): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) """ 0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -326,7 +368,24 @@ class BMPPeerDownNotification: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ """ +<<<<<<< HEAD pass +======= + @classmethod + def dissect(cls, data): + data, peer_msg = super().dissect(data) + + msg = { + **peer_msg, + **{ + "bmp_log_type": "peer down", + }, + } + + # XXX: dissect the bgp open message + + return msg +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # ------------------------------------------------------------------------------ @@ -360,6 +419,10 @@ def dissect(cls, data): msg = { **peer_msg, **{ +<<<<<<< HEAD +======= + "bmp_log_type": "peer up", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "local_ip": bin2str_ipaddress(local_addr, peer_msg.get("ipv6")), "local_port": int(local_port), "remote_port": int(remote_port), diff --git a/tests/topotests/lib/bmp_collector/bmpserver.py b/tests/topotests/lib/bmp_collector/bmpserver.py new file mode 100755 index 000000000000..c42c3875633f --- /dev/null +++ b/tests/topotests/lib/bmp_collector/bmpserver.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: ISC + +# Copyright 2023 6WIND S.A. +# Authored by Farid Mihoub +# +import argparse +import errno +import logging + +# XXX: something more reliable should be used "Twisted" a great choice. +import os +import signal +import socket +import sys + +from datetime import datetime + +from bmp import BMPMsg + +BGP_MAX_SIZE = 4096 + +# Global variable to track shutdown signal +shutdown = False + +parser = argparse.ArgumentParser() +parser.add_argument("-a", "--address", type=str, default="0.0.0.0") +parser.add_argument("-p", "--port", type=int, default=1789) +parser.add_argument("-l", "--logfile", type=str, default="/var/log/bmp.log") +parser.add_argument("-r", "--pidfile", type=str, default="/var/run/bmp.pid") + + +def handle_signal(signum, frame): + global shutdown + timestamp_print(f"Received signal {signum}, shutting down.") + shutdown = True + + +def timestamp_print(message, file=sys.stderr): + """Helper function to timestamp_print messages with timestamps.""" + + current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(f"[{current_time}] {message}", file=file) + + +def check_pid(pid): + if pid < 0: # user input error + return False + if pid == 0: # all processes + return False + try: + os.kill(pid, 0) + return True + except OSError as err: + if err.errno == errno.EPERM: # a process we were denied access to + return True + if err.errno == errno.ESRCH: # No such process + return False + # should never happen + return False + + +def savepid(): + ownid = os.getpid() + + flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY + mode = ((os.R_OK | os.W_OK) << 6) | (os.R_OK << 3) | os.R_OK + + try: + fd = os.open(pid_file, flags, mode) + except OSError: + try: + pid = open(pid_file, "r").readline().strip() + if check_pid(int(pid)): + timestamp_print( + "PID file already exists and program still running %s\n" % pid_file + ) + return False + else: + # If pid is not running, reopen file without O_EXCL + fd = os.open(pid_file, flags ^ os.O_EXCL, mode) + except (OSError, IOError, ValueError): + timestamp_print( + "issue accessing PID file %s (most likely permission or ownership)\n" + % pid_file + ) + return False + + try: + f = os.fdopen(fd, "w") + line = "%d\n" % ownid + f.write(line) + f.close() + saved_pid = True + except IOError: + timestamp_print("Can not create PID file %s\n" % pid_file) + return False + timestamp_print("Created PID file %s with value %d\n" % (pid_file, ownid)) + return True + + +def removepid(): + try: + os.remove(pid_file) + except OSError as exc: + if exc.errno == errno.ENOENT: + pass + else: + timestamp_print("Can not remove PID file %s\n" % pid_file) + return + timestamp_print("Removed PID file %s\n" % pid_file) + + +def main(): + global shutdown + + # Set up signal handling for SIGTERM and SIGINT + signal.signal(signal.SIGTERM, handle_signal) + signal.signal(signal.SIGINT, handle_signal) + + args = parser.parse_args() + ADDRESS, PORT = args.address, args.port + LOG_FILE = args.logfile + + global pid_file + pid_file = args.pidfile + + timestamp_print(f"Starting bmpserver on {args.address}:{args.port}") + + savepid() + + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + try: + s.bind((ADDRESS, PORT)) + s.listen() + timestamp_print(f"Listening on TCP {args.address}:{args.port}") + + connection, client_address = s.accept() + timestamp_print(f"TCP session opened from {client_address}") + + try: + while not shutdown: # Check for shutdown signal + data = connection.recv(BGP_MAX_SIZE) + if shutdown: + break + + if not data: + # connection closed + break + + timestamp_print( + f"Data received from {client_address}: length {len(data)}" + ) + + while len(data) > BMPMsg.MIN_LEN: + data = BMPMsg.dissect(data, log_file=LOG_FILE) + + timestamp_print(f"Finished dissecting data from {client_address}") + + except Exception as e: + timestamp_print(f"{e}") + pass + except KeyboardInterrupt: + timestamp_print(f"Got Keyboard Interrupt.") + pass + finally: + timestamp_print(f"TCP session closed with {client_address}") + connection.close() + except socket.error as sock_err: + timestamp_print(f"Socket error: {e}") + except Exception as e: + timestamp_print(f"{e}") + finally: + timestamp_print(f"Server shutting down on {ADDRESS}:{PORT}") + removepid() + + +if __name__ == "__main__": + try: + sys.exit(main()) + except KeyboardInterrupt: + logging.info("BMP server was interrupted and is shutting down.") + removepid() + sys.exit(0) diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py index 369a794ebc7c..0a27c215fab0 100644 --- a/tests/topotests/lib/pim.py +++ b/tests/topotests/lib/pim.py @@ -1720,6 +1720,7 @@ def verify_pim_rp_info( ) return errormsg +<<<<<<< HEAD if not iamRP: if rp_json["iAmRP"] == False: logger.info( @@ -1740,6 +1741,28 @@ def verify_pim_rp_info( % (dut, grp_addr, "false", rp_json["iAmRP"]) ) return errormsg +======= + if not iamRP: + if rp_json["iAmRP"] == False: + logger.info( + "[DUT %s]: Verifying group " + "and iAmNotRP [PASSED]!!" + " Found Expected: (%s, %s:%s)", + dut, + grp_addr, + "iAmRP", + rp_json["iAmRP"], + ) + else: + errormsg = ( + "[DUT %s]: Verifying group" + "%s and iAmRP [FAILED]!! " + "Expected: (iAmRP: %s)," + " Found: (iAmRP: %s)" + % (dut, grp_addr, "false", rp_json["iAmRP"]) + ) + return errormsg +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) return True diff --git a/tests/topotests/lib/snmptest.py b/tests/topotests/lib/snmptest.py index 8e2e76d154b4..19289f5b6749 100644 --- a/tests/topotests/lib/snmptest.py +++ b/tests/topotests/lib/snmptest.py @@ -104,12 +104,23 @@ def get_next(self, oid): return None return self._get_snmp_value(result) +<<<<<<< HEAD def walk(self, oid): +======= + def walk(self, oid, raw=False): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) cmd = "snmpwalk {0} {1} 2>&1 | grep -v SNMPv2-PDU".format( self._snmp_config(), oid ) result = self.router.cmd(cmd) +<<<<<<< HEAD +======= + + if raw: + return result + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return self._parse_multiline(result) def parse_notif_ipv4(self, notif): diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py index b1da29636530..140de1339c71 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -850,12 +850,30 @@ def load_frr_config(self, source, daemons=None): result = self.run(grep_cmd, warn=False).strip() if result: self.load_config(daemon, "") +<<<<<<< HEAD +======= + if daemonstr == "ospf": + grep_cmd = "grep -E 'router ospf ([0-9]+*)' {} | grep -o -E '([0-9]*)'".format( + source_path + ) + result = self.run(grep_cmd, warn=False) + if result: # instances + instances = result.split("\n") + for inst in instances: + if inst != "": + self.load_config(daemon, "", None, inst) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) else: for item in daemons: daemon, param = item self.load_config(daemon, "", param) +<<<<<<< HEAD def load_config(self, daemon, source=None, param=None): +======= + def load_config(self, daemon, source=None, param=None, instance=None): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) """Loads daemon configuration from the specified source Possible daemon values are: TopoRouter.RD_ZEBRA, TopoRouter.RD_RIP, TopoRouter.RD_RIPNG, TopoRouter.RD_OSPF, TopoRouter.RD_OSPF6, @@ -873,7 +891,11 @@ def load_config(self, daemon, source=None, param=None): """ daemonstr = self.RD.get(daemon) self.logger.debug('loading "{}" configuration: {}'.format(daemonstr, source)) +<<<<<<< HEAD return self.net.loadConf(daemonstr, source, param) +======= + return self.net.loadConf(daemonstr, source, param, instance) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def check_router_running(self): """ @@ -1276,6 +1298,7 @@ def __str__(self): return gear def start(self, log_file=None): +<<<<<<< HEAD log_arg = "-l {}".format(log_file) if log_file else "" self.run( "{}/bmp_collector/bmpserver -a {} -p {} {}&".format( @@ -1286,6 +1309,27 @@ def start(self, log_file=None): def stop(self): self.run("pkill -9 -f bmpserver") +======= + log_dir = os.path.join(self.logdir, self.name) + self.run("chmod 777 {}".format(log_dir)) + + log_err = os.path.join(log_dir, "bmpserver.log") + + log_arg = "-l {}".format(log_file) if log_file else "" + self.pid_file = os.path.join(log_dir, "bmpserver.pid") + + with open(log_err, "w") as err: + self.run( + "{}/bmp_collector/bmpserver.py -a {} -p {} -r {} {}&".format( + CWD, self.ip, self.port, self.pid_file, log_arg + ), + stdout=None, + stderr=err, + ) + + def stop(self): + self.run(f"kill $(cat {self.pid_file}") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return "" diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index bd989583553d..d8f87167b12a 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -1463,6 +1463,10 @@ def __init__(self, name, *posargs, **params): "snmptrapd": 0, "fpm_listener": 0, } +<<<<<<< HEAD +======= + self.daemon_instances = {"ospfd": []} +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) self.daemons_options = {"zebra": ""} self.reportCores = True self.version = None @@ -1632,7 +1636,11 @@ def checkCapability(self, daemon, param): return False return True +<<<<<<< HEAD def loadConf(self, daemon, source=None, param=None): +======= + def loadConf(self, daemon, source=None, param=None, instance=None): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) """Enabled and set config for a daemon. Arranges for loading of daemon configuration from the specified source. Possible @@ -1666,6 +1674,11 @@ def loadConf(self, daemon, source=None, param=None): self.daemons[daemon] = 1 if param is not None: self.daemons_options[daemon] = param +<<<<<<< HEAD +======= + if instance is not None: + self.daemon_instances[daemon].append(instance) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) conf_file = "/etc/{}/{}.conf".format(self.routertype, daemon) if source and not os.path.exists(source): logger.warning( @@ -1903,16 +1916,32 @@ def startRouterDaemons(self, daemons=None, tgen=None): tail_log_files = [] check_daemon_files = [] +<<<<<<< HEAD def start_daemon(daemon, extra_opts=None): +======= + def start_daemon(daemon, instance=None): +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) daemon_opts = self.daemons_options.get(daemon, "") # get pid and vty filenames and remove the files m = re.match(r"(.* |^)-n (\d+)( ?.*|$)", daemon_opts) dfname = daemon if not m else "{}-{}".format(daemon, m.group(2)) +<<<<<<< HEAD runbase = "/var/run/{}/{}".format(self.routertype, dfname) # If this is a new system bring-up remove the pid/vty files, otherwise # do not since apparently presence of the pidfile impacts BGP GR self.cmd_status("rm -f {0}.pid {0}.vty".format(runbase)) +======= + if instance != None: + inst = "-" + instance + dfname = daemon + inst + else: + inst = "" + runbase = "/var/run/{}/{}".format(self.routertype, dfname) + # If this is a new system bring-up remove the pid/vty files, otherwise + # do not since apparently presence of the pidfile impacts BGP GR + self.cmd_status("rm -f {0}{1}.pid {0}{1}.vty".format(runbase, inst)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def do_gdb_or_rr(gdb): routers = gdb_routers if gdb else rr_routers @@ -1923,7 +1952,11 @@ def do_gdb_or_rr(gdb): and (not daemons or daemon in daemons or "all" in daemons) ) +<<<<<<< HEAD rediropt = " > {0}.out 2> {0}.err".format(daemon) +======= + rediropt = " > {0}.out 2> {0}.err".format(dfname) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if daemon == "fpm_listener": binary = "/usr/lib/frr/fpm_listener" cmdenv = "" @@ -1952,7 +1985,11 @@ def do_gdb_or_rr(gdb): if asan_abort: cmdenv += "abort_on_error=1:" cmdenv += "log_path={0}/{1}.asan.{2} ".format( +<<<<<<< HEAD self.logdir, self.name, daemon +======= + self.logdir, self.name, dfname +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) if cov_option: @@ -1967,7 +2004,11 @@ def do_gdb_or_rr(gdb): os.path.join(this_dir, "../../../tools/valgrind.supp") ) +<<<<<<< HEAD valgrind_logbase = f"{self.logdir}/{self.name}.valgrind.{daemon}" +======= + valgrind_logbase = f"{self.logdir}/{self.name}.valgrind.{dfname}" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if do_gdb_or_rr(True): cmdenv += " exec" cmdenv += ( @@ -1989,18 +2030,30 @@ def do_gdb_or_rr(gdb): ) cmdopt = "{} --command-log-always ".format(daemon_opts) +<<<<<<< HEAD cmdopt += "--log file:{}.log --log-level debug".format(daemon) +======= + if instance != None: + cmdopt += " --instance " + instance + cmdopt += "--log file:{}.log --log-level debug".format(dfname) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if daemon in logd_options: logdopt = logd_options[daemon] if "all" in logdopt or self.name in logdopt: tail_log_files.append( +<<<<<<< HEAD "{}/{}/{}.log".format(self.logdir, self.name, daemon) ) if extra_opts: cmdopt += " " + extra_opts +======= + "{}/{}/{}.log".format(self.logdir, self.name, dfname) + ) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if do_gdb_or_rr(True) and do_gdb_or_rr(False): logger.warning("cant' use gdb and rr at same time") @@ -2037,7 +2090,11 @@ def do_gdb_or_rr(gdb): else: cmd = " ".join([cmdenv, binary, cmdopt]) p = self.popen(cmd) +<<<<<<< HEAD self.valgrind_gdb_daemons[daemon] = p +======= + self.valgrind_gdb_daemons[dfname] = p +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if p.poll() and p.returncode: self.logger.error( '%s: Failed to launch "%s" (%s) with perf using: %s', @@ -2161,7 +2218,11 @@ def emacs_gdb_ready(): ["perf record {} --".format(perf_options), binary, cmdopt] ) p = self.popen(cmd) +<<<<<<< HEAD self.perf_daemons[daemon] = p +======= + self.perf_daemons[dfname] = p +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if p.poll() and p.returncode: self.logger.error( '%s: Failed to launch "%s" (%s) with perf using: %s', @@ -2184,7 +2245,11 @@ def emacs_gdb_ready(): ] ) p = self.popen(cmd) +<<<<<<< HEAD self.rr_daemons[daemon] = p +======= + self.rr_daemons[dfname] = p +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if p.poll() and p.returncode: self.logger.error( '%s: Failed to launch "%s" (%s) with rr using: %s', @@ -2205,7 +2270,13 @@ def emacs_gdb_ready(): ): cmdopt += " -d " cmdopt += rediropt +<<<<<<< HEAD +======= + self.logger.info('cmdenv "{}"'.format(cmdenv)) + self.logger.info('binary "{}"'.format(binary)) + self.logger.info('cmdopt "{}"'.format(cmdopt)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) try: self.cmd_raises(" ".join([cmdenv, binary, cmdopt]), warn=False) except subprocess.CalledProcessError as error: @@ -2237,7 +2308,11 @@ def emacs_gdb_ready(): # Start Zebra after mgmtd if "zebra" in daemons_list: +<<<<<<< HEAD start_daemon("zebra", "-s 90000000") +======= + start_daemon("zebra") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) while "zebra" in daemons_list: daemons_list.remove("zebra") @@ -2265,7 +2340,18 @@ def emacs_gdb_ready(): for daemon in daemons_list: if self.daemons[daemon] == 0: continue +<<<<<<< HEAD start_daemon(daemon) +======= + if ( + daemon in self.daemon_instances.keys() + and len(self.daemon_instances[daemon]) > 0 + ): + for inst in self.daemon_instances[daemon]: + start_daemon(daemon, inst) + else: + start_daemon(daemon) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # Check if daemons are running. wait_time = 30 if (gdb_routers or gdb_daemons) else 10 @@ -2381,6 +2467,57 @@ def killRouterDaemons(self, daemons, wait=True, assertOnError=True): return errors +<<<<<<< HEAD +======= + def check_daemon(self, daemon, reportLeaks=True, traces="", instance=None): + reportMade = False + if instance == None: + dname = daemon + else: + dname = daemon + "-" + instance + # Look for core file + corefiles = glob.glob( + "{}/{}/{}_core*.dmp".format(self.logdir, self.name, daemon) + ) + if len(corefiles) > 0: + backtrace = gdb_core(self, daemon, corefiles) + traces = ( + traces + + f"\nCORE FOUND: {self.name}: {daemon} crashed. Backtrace follows:\n{backtrace}" + ) + reportMade = True + elif reportLeaks: + log = self.getStdErr(dname) + if "memstats" in log: + sys.stderr.write("%s: %s has memory leaks:\n" % (self.name, dname)) + traces = traces + "\n%s: %s has memory leaks:\n" % ( + self.name, + dname, + ) + log = re.sub("core_handler: ", "", log) + log = re.sub( + r"(showing active allocations in memory group [a-zA-Z0-9]+)", + r"\n ## \1", + log, + ) + log = re.sub("memstats: ", " ", log) + sys.stderr.write(log) + reportMade = True + # Look for AddressSanitizer Errors and append to /tmp/AddressSanitzer.txt if found + if checkAddressSanitizerError( + self.getStdErr(dname), self.name, dname, self.logdir + ): + sys.stderr.write( + "%s: Daemon %s killed by AddressSanitizer" % (self.name, dname) + ) + traces = traces + "\n%s: Daemon %s killed by AddressSanitizer" % ( + self.name, + dname, + ) + reportMade = True + return reportMade + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def checkRouterCores(self, reportLeaks=True, reportOnce=False): if reportOnce and not self.reportCores: return @@ -2388,6 +2525,7 @@ def checkRouterCores(self, reportLeaks=True, reportOnce=False): traces = "" for daemon in self.daemons: if self.daemons[daemon] == 1: +<<<<<<< HEAD # Look for core file corefiles = glob.glob( "{}/{}/{}_core*.dmp".format(self.logdir, self.name, daemon) @@ -2430,6 +2568,17 @@ def checkRouterCores(self, reportLeaks=True, reportOnce=False): daemon, ) reportMade = True +======= + if ( + daemon in self.daemon_instances.keys() + and len(self.daemon_instances[daemon]) > 0 + ): + for inst in self.daemon_instances[daemon]: + self.check_daemon(daemon, reportLeaks, traces, inst) + else: + self.check_daemon(daemon, reportLeaks, traces) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if reportMade: self.reportCores = False return traces diff --git a/tests/topotests/msdp_topo1/r1/pimd.conf b/tests/topotests/msdp_topo1/r1/pimd.conf index 3c116a003bea..0cd0cd699a18 100644 --- a/tests/topotests/msdp_topo1/r1/pimd.conf +++ b/tests/topotests/msdp_topo1/r1/pimd.conf @@ -22,5 +22,10 @@ ip pim rp 10.254.254.1 ip pim join-prune-interval 5 ! router pim +<<<<<<< HEAD +======= + msdp log neighbor-events + msdp log sa-events +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) msdp peer 192.168.0.2 password 1234 ! diff --git a/tests/topotests/msdp_topo1/test_msdp_topo1.py b/tests/topotests/msdp_topo1/test_msdp_topo1.py index ff80052d2665..00452ede89fa 100755 --- a/tests/topotests/msdp_topo1/test_msdp_topo1.py +++ b/tests/topotests/msdp_topo1/test_msdp_topo1.py @@ -17,6 +17,10 @@ import sys import json from functools import partial +<<<<<<< HEAD +======= +import re +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) import pytest # Save the Current Working Directory to find configuration files. @@ -510,6 +514,71 @@ def test_msdp_sa_filter(): assert val is None, "multicast route convergence failure" +<<<<<<< HEAD +======= +def test_msdp_log_events(): + "Test that the enabled logs are working as expected." + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1_log = tgen.gears["r1"].net.getLog("log", "pimd") + + # Look up for informational messages that should have been enabled. + match = re.search("MSDP peer 192.168.1.2 state changed to established", r1_log) + assert match is not None + + match = re.search(r"MSDP SA \(192.168.10.100\,229.1.2.3\) created", r1_log) + assert match is not None + + +def test_msdp_shutdown(): + "Shutdown MSDP sessions between r1, r2, r3, then check the state." + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + tgen.gears["r1"].vtysh_cmd( + """ + configure terminal + router pim + msdp shutdown + """ + ) + + r1_expect = { + "192.168.0.2": { + "state": "inactive", + }, + "192.168.1.2": { + "state": "inactive", + }, + } + r2_expect = { + "192.168.0.1": { + "state": "listen", + } + } + r3_expect = { + "192.168.1.1": { + "state": "listen", + } + } + for router in [("r1", r1_expect), ("r2", r2_expect), ("r3", r3_expect)]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router[0]], + "show ip msdp peer json", + router[1], + ) + logger.info("Waiting for {} msdp peer data".format(router[0])) + _, val = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert val is None, "multicast route convergence failure" + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() diff --git a/tests/topotests/ospf_instance_redistribute/r1/frr.conf b/tests/topotests/ospf_instance_redistribute/r1/frr.conf new file mode 100644 index 000000000000..578bc29b47a0 --- /dev/null +++ b/tests/topotests/ospf_instance_redistribute/r1/frr.conf @@ -0,0 +1,6 @@ +interface lo + ip address 192.168.100.1/24 +! + +router ospf 3 + redistribute sharp diff --git a/tests/topotests/ospf_instance_redistribute/test_ospf_instance_redistribute.py b/tests/topotests/ospf_instance_redistribute/test_ospf_instance_redistribute.py index ea4507736e74..d038886dcc33 100644 --- a/tests/topotests/ospf_instance_redistribute/test_ospf_instance_redistribute.py +++ b/tests/topotests/ospf_instance_redistribute/test_ospf_instance_redistribute.py @@ -63,9 +63,13 @@ def setup_module(module): # This is a sample of configuration loading. r1 = tgen.gears["r1"] +<<<<<<< HEAD r1.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf")) r1.load_config(TopoRouter.RD_OSPF, os.path.join(CWD, "r1/ospfd-3.conf"), "-n 3") r1.load_config(TopoRouter.RD_SHARP, os.path.join(CWD, "r1/sharpd.conf")) +======= + r1.load_frr_config(os.path.join(CWD, "r1/frr.conf")) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tgen.start_router() @@ -84,6 +88,40 @@ def test_install_sharp_instance_routes(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD +======= + r1 = tgen.gears["r1"] + logger.info("Ensure that connected routes are actually installed") + expected = { + "192.168.100.0/24": [ + { + "prefix": "192.168.100.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfName": "default", + "selected": True, + "destSelected": True, + "installed": True, + "nexthops": [ + { + "fib": True, + "directlyConnected": True, + "interfaceName": "lo", + "active": True, + "weight": 1, + } + ], + } + ] + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route connected json", expected + ) + + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) logger.info("Installing sharp routes") r1 = tgen.gears["r1"] r1.vtysh_cmd("sharp install route 4.5.6.7 nexthop 192.168.100.2 1") diff --git a/tests/topotests/ospf_metric_propagation/h1/frr.conf b/tests/topotests/ospf_metric_propagation/h1/frr.conf index 1196a192dd50..fee3822f4cb4 100644 --- a/tests/topotests/ospf_metric_propagation/h1/frr.conf +++ b/tests/topotests/ospf_metric_propagation/h1/frr.conf @@ -1,10 +1,17 @@ ! hostname h1 +<<<<<<< HEAD password zebra log file /tmp/h1-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ip route 0.0.0.0/0 10.0.91.1 ! interface h1-eth0 ip address 10.0.91.2/24 -! \ No newline at end of file +<<<<<<< HEAD +! +======= +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/ospf_metric_propagation/h2/frr.conf b/tests/topotests/ospf_metric_propagation/h2/frr.conf index f951fe6ba1d6..93b23aaadf05 100644 --- a/tests/topotests/ospf_metric_propagation/h2/frr.conf +++ b/tests/topotests/ospf_metric_propagation/h2/frr.conf @@ -1,10 +1,17 @@ ! hostname h2 +<<<<<<< HEAD password zebra log file /tmp/h2-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ip route 0.0.0.0/0 10.0.94.4 ! interface h2-eth0 ip address 10.0.94.2/24 -! \ No newline at end of file +<<<<<<< HEAD +! +======= +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/ospf_metric_propagation/r1/frr.conf b/tests/topotests/ospf_metric_propagation/r1/frr.conf index 4966e6a9da1b..05cc081cb9ff 100644 --- a/tests/topotests/ospf_metric_propagation/r1/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r1/frr.conf @@ -1,8 +1,11 @@ ! hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r1-eth0 ip address 10.0.1.1/24 @@ -93,4 +96,8 @@ route-map costplus permit 30 route-map costplus permit 40 set metric-type type-1 set metric +1 - exit \ No newline at end of file +<<<<<<< HEAD + exit +======= + exit +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/ospf_metric_propagation/r2/frr.conf b/tests/topotests/ospf_metric_propagation/r2/frr.conf index 0ac5001b1b99..d350f91612d5 100644 --- a/tests/topotests/ospf_metric_propagation/r2/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r2/frr.conf @@ -1,8 +1,11 @@ ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r2-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r2-eth0 ip address 10.0.1.2/24 diff --git a/tests/topotests/ospf_metric_propagation/r3/frr.conf b/tests/topotests/ospf_metric_propagation/r3/frr.conf index 0859173f7971..90f7fdff381c 100644 --- a/tests/topotests/ospf_metric_propagation/r3/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r3/frr.conf @@ -1,8 +1,11 @@ ! hostname r3 +<<<<<<< HEAD password zebra log file /tmp/r3-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r3-eth0 ip address 10.0.3.3/24 diff --git a/tests/topotests/ospf_metric_propagation/r4/frr.conf b/tests/topotests/ospf_metric_propagation/r4/frr.conf index 743da272727f..b7368852c9b6 100644 --- a/tests/topotests/ospf_metric_propagation/r4/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r4/frr.conf @@ -1,8 +1,11 @@ ! hostname r4 +<<<<<<< HEAD password zebra log file /tmp/r4-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r4-eth0 ip address 10.0.3.4/24 diff --git a/tests/topotests/ospf_metric_propagation/ra/frr.conf b/tests/topotests/ospf_metric_propagation/ra/frr.conf index 2434faeabc97..0e11ba30ce73 100644 --- a/tests/topotests/ospf_metric_propagation/ra/frr.conf +++ b/tests/topotests/ospf_metric_propagation/ra/frr.conf @@ -1,8 +1,11 @@ ! hostname ra +<<<<<<< HEAD password zebra log file /tmp/ra-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface ra-eth0 ip address 10.0.50.5/24 diff --git a/tests/topotests/ospf_metric_propagation/rb/frr.conf b/tests/topotests/ospf_metric_propagation/rb/frr.conf index b83532a8405a..2789e7b4cfda 100644 --- a/tests/topotests/ospf_metric_propagation/rb/frr.conf +++ b/tests/topotests/ospf_metric_propagation/rb/frr.conf @@ -1,8 +1,11 @@ ! hostname rb +<<<<<<< HEAD password zebra log file /tmp/rb-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface rb-eth0 ip address 10.0.50.6/24 diff --git a/tests/topotests/ospf_metric_propagation/rc/frr.conf b/tests/topotests/ospf_metric_propagation/rc/frr.conf index dd8077c3949f..5da5806017cd 100644 --- a/tests/topotests/ospf_metric_propagation/rc/frr.conf +++ b/tests/topotests/ospf_metric_propagation/rc/frr.conf @@ -1,8 +1,11 @@ ! hostname rc +<<<<<<< HEAD password zebra log file /tmp/rc-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface rc-eth0 ip address 10.0.70.7/24 diff --git a/tests/topotests/ospf_multi_instance/r1/frr.conf b/tests/topotests/ospf_multi_instance/r1/frr.conf new file mode 100644 index 000000000000..b9752c63ad96 --- /dev/null +++ b/tests/topotests/ospf_multi_instance/r1/frr.conf @@ -0,0 +1,16 @@ +! +hostname r1 +! +interface lo + ip address 1.1.1.1/32 + ip ospf area 0 +! +interface r1-eth0 + ip address 10.1.1.1/24 + ip ospf area 0 +! +! +router ospf + ospf router-id 1.1.1.1 + distance 20 +! diff --git a/tests/topotests/ospf_multi_instance/r2/frr.conf b/tests/topotests/ospf_multi_instance/r2/frr.conf new file mode 100644 index 000000000000..8501e0edc07d --- /dev/null +++ b/tests/topotests/ospf_multi_instance/r2/frr.conf @@ -0,0 +1,37 @@ +! +hostname r2 +password zebra +! debug ospf event +! debug ospf lsa +! debug ospf default-information +! debug ospf zebra redistribute + +ip forwarding +! +interface lo1 + ip address 2.2.2.1/32 + ip ospf 1 area 0 + no shut +! +interface lo2 + ip address 2.2.2.2/32 + ip ospf 2 area 0 + no shut +! +interface r2-eth0 + ip address 10.1.1.2/24 + ip ospf 1 area 0 +! +interface r2-eth1 + ip address 10.1.2.2/24 + ip ospf 2 area 0 +! +router ospf 1 + ospf router-id 2.2.2.1 + distance 20 +! +router ospf 2 + ospf router-id 2.2.2.2 + distance 20 +! + diff --git a/tests/topotests/ospf_multi_instance/r3/frr.conf b/tests/topotests/ospf_multi_instance/r3/frr.conf new file mode 100644 index 000000000000..e6f681a46206 --- /dev/null +++ b/tests/topotests/ospf_multi_instance/r3/frr.conf @@ -0,0 +1,16 @@ +! +hostname r3 +! +interface lo + ip address 3.3.3.1/32 + ip ospf area 0 +! +interface r3-eth0 + ip address 10.1.2.3/24 + ip ospf area 0 +! +! +router ospf + ospf router-id 3.3.3.1 + distance 20 +! diff --git a/tests/topotests/ospf_multi_instance/test_ospf_multi_instance.py b/tests/topotests/ospf_multi_instance/test_ospf_multi_instance.py new file mode 100644 index 000000000000..de44140c09dc --- /dev/null +++ b/tests/topotests/ospf_multi_instance/test_ospf_multi_instance.py @@ -0,0 +1,403 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_ospf_multi_instance.py +# +# Copyright (c) 2024 LabN Consulting +# Acee Lindem +# + +import os +import sys +from functools import partial +import pytest + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +from lib.common_config import ( + step, + create_interface_in_kernel, +) + + +""" +test_ospf_metric_propagation.py: Test OSPF/BGP metric propagation +""" + +TOPOLOGY = """ + + +---------+ +--------------------+ +---------+ + | r1 | | r2 | r2 | | r3 | + | | | ospf 1 | ospf 2 | | | + | 1.1.1.1 | eth0 eth0| 2.2.2.1 | 2.2.2.2 |eth1 eth0| 3.3.3.1 | + | +-------------+ | +-------------+ | + | | 10.1.1.0/24 | | | 10.1.2.0/24 | | + +---------+ +--------------------+ +---------+ + + +""" + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# Required to instantiate the topology builder class. + +pytestmark = [pytest.mark.ospfd, pytest.mark.bgpd] + + +def build_topo(tgen): + "Build function" + + # Create 3 routers + tgen.add_router("r1") + tgen.add_router("r2") + tgen.add_router("r3") + + # Interconect router 1, 2 (0) + switch = tgen.add_switch("s1-1-2") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + # Interconect router 2, 3 (1) + switch = tgen.add_switch("s2-2-3") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + # Add more loopbacks to r2 + create_interface_in_kernel( + tgen, "r2", "lo1", "2.2.2.1", netmask="255.255.255.255", create=True + ) + create_interface_in_kernel( + tgen, "r2", "lo2", "2.2.2.2", netmask="255.255.255.255", create=True + ) + + +def setup_module(mod): + logger.info("OSPF Multi-Instance:\n {}".format(TOPOLOGY)) + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + # Starting Routers + router_list = tgen.routers() + + for rname, router in router_list.items(): + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + # Initialize all routers. + tgen.start_router() + + +def teardown_module(): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def test_multi_instance_default_origination(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip("Skipped because of router(s) failure") + + step("Configure a local default route") + r1 = tgen.gears["r1"] + r1.vtysh_cmd("conf t\nip route 0.0.0.0/0 Null0") + + step("Verify the R1 configuration and install of 'ip route 0.0.0.0/0 Null0'") + prefix_suppression_cfg = ( + tgen.net["r1"] + .cmd('vtysh -c "show running" | grep "^ip route 0.0.0.0/0 Null0"') + .rstrip() + ) + assertmsg = "'ip route 0.0.0.0/0 Null0' applied, but not present in configuration" + assert prefix_suppression_cfg == "ip route 0.0.0.0/0 Null0", assertmsg + + input_dict = { + "0.0.0.0/0": [ + { + "prefix": "0.0.0.0/0", + "prefixLen": 0, + "protocol": "static", + "nexthops": [ + { + "blackhole": True, + } + ], + } + ] + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 0.0.0.0/0 json", input_dict + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assertmsg = "0.0.0.0/0 not installed on router r1" + assert result is None, assertmsg + + step( + "Verify the R1 configuration and advertisement of 'default-information originate'" + ) + r1.vtysh_cmd("conf t\nrouter ospf\n default-information originate") + + input_dict = { + "asExternalLinkStates": [ + { + "lsaType": "AS-external-LSA", + "linkStateId": "0.0.0.0", + "advertisingRouter": "1.1.1.1", + "networkMask": 0, + "metricType": "E2 (Larger than any link state path)", + "metric": 10, + "forwardAddress": "0.0.0.0", + "externalRouteTag": 0, + } + ] + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip ospf database json", input_dict + ) + + r2 = tgen.gears["r2"] + step("Verify the OSPF instance 1 installation of default route on router 2") + input_dict = { + "0.0.0.0/0": [ + { + "prefix": "0.0.0.0/0", + "prefixLen": 0, + "protocol": "ospf", + "instance": 1, + "nexthops": [ + { + "ip": "10.1.1.1", + "interfaceName": "r2-eth0", + } + ], + } + ] + } + test_func = partial( + topotest.router_json_cmp, r2, "show ip route 0.0.0.0/0 json", input_dict + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assertmsg = "0.0.0.0/0 not installed on router r2" + assert result is None, assertmsg + + step("Configure OSPF 'default-intformation originate' on router r2 instance 2") + r2.vtysh_cmd("conf t\nrouter ospf 2\n default-information originate") + + step("Verify r2 instance 2 AS-External default origination") + input_dict = { + "ospfInstance": 2, + "routerId": "2.2.2.2", + "asExternalLinkStates": [ + { + "lsaType": "AS-external-LSA", + "linkStateId": "0.0.0.0", + "advertisingRouter": "2.2.2.2", + "networkMask": 0, + "metricType": "E2 (Larger than any link state path)", + "tos": 0, + "metric": 10, + "forwardAddress": "0.0.0.0", + "externalRouteTag": 0, + } + ], + } + test_func = partial( + topotest.router_json_cmp, + r2, + "show ip ospf 2 database external json", + input_dict, + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assertmsg = "AS-External default not originated by router r2 OSPF instance 2" + assert result is None, assertmsg + + step("Update the OSPF instance 2 distance so it will be preferred over instance 1") + r2.vtysh_cmd("conf t\nrouter ospf 2\n distance 15") + + step("Generate a default route from OSPF on r3") + r3 = tgen.gears["r3"] + r3.vtysh_cmd("conf t\nrouter ospf\n default-information originate") + r3.vtysh_cmd("conf t\nip route 0.0.0.0/0 Null0") + + step("Verify r3 AS-External default origination on r2") + input_dict = { + "ospfInstance": 2, + "routerId": "2.2.2.2", + "asExternalLinkStates": [ + { + "lsaType": "AS-external-LSA", + "linkStateId": "0.0.0.0", + "advertisingRouter": "3.3.3.1", + "length": 36, + "networkMask": 0, + "metricType": "E2 (Larger than any link state path)", + "tos": 0, + "metric": 10, + "forwardAddress": "0.0.0.0", + "externalRouteTag": 0, + } + ], + } + test_func = partial( + topotest.router_json_cmp, + r2, + "show ip ospf 2 database external json", + input_dict, + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assertmsg = "AS-External default not originated by router r3 OSPF" + assert result is None, assertmsg + + step("Verify r3's default installed by OSPF instance 2 is preferred on r2") + input_dict = { + "0.0.0.0/0": [ + { + "prefix": "0.0.0.0/0", + "prefixLen": 0, + "protocol": "ospf", + "instance": 2, + "distance": 15, + "nexthops": [ + { + "ip": "10.1.2.3", + "interfaceName": "r2-eth1", + } + ], + } + ] + } + test_func = partial( + topotest.router_json_cmp, r2, "show ip route 0.0.0.0/0 json", input_dict + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assertmsg = "0.0.0.0/0 from r3 not installed on router r2" + assert result is None, assertmsg + + step( + "Verify that r2's OSPF instance 2 AS-External LSA default is flushed due to default from r3" + ) + input_dict = { + "ospfInstance": 2, + "routerId": "2.2.2.2", + "asExternalLinkStates": [ + { + "lsaAge": 3600, + "lsaType": "AS-external-LSA", + "linkStateId": "0.0.0.0", + "advertisingRouter": "2.2.2.2", + "networkMask": 0, + "metricType": "E2 (Larger than any link state path)", + "tos": 0, + "metric": 10, + "forwardAddress": "0.0.0.0", + "externalRouteTag": 0, + } + ], + } + test_func = partial( + topotest.router_json_cmp, + r2, + "show ip ospf 2 database external json", + input_dict, + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assertmsg = "AS-External default not flushed by router r2 OSPF instance 2" + assert result is None, assertmsg + + step("Remove r3's default route and verify that its advertisement is flushed") + r3.vtysh_cmd("conf t\nno ip route 0.0.0.0/0 Null0") + input_dict = { + "routerId": "3.3.3.1", + "asExternalLinkStates": [ + { + "lsaAge": 3600, + "lsaType": "AS-external-LSA", + "linkStateId": "0.0.0.0", + "advertisingRouter": "3.3.3.1", + "networkMask": 0, + "metricType": "E2 (Larger than any link state path)", + "tos": 0, + "metric": 10, + "forwardAddress": "0.0.0.0", + "externalRouteTag": 0, + } + ], + } + test_func = partial( + topotest.router_json_cmp, r3, "show ip ospf database external json", input_dict + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assertmsg = "AS-External default not flushed by router r3 OSPF" + assert result is None, assertmsg + + step( + "Verify that r2's OSPF instance 2 AS-External default is advertised and installed by r3" + ) + input_dict = { + "routerId": "3.3.3.1", + "asExternalLinkStates": [ + { + "lsaType": "AS-external-LSA", + "linkStateId": "0.0.0.0", + "advertisingRouter": "2.2.2.2", + "networkMask": 0, + "metricType": "E2 (Larger than any link state path)", + "tos": 0, + "metric": 10, + "forwardAddress": "0.0.0.0", + "externalRouteTag": 0, + } + ], + } + test_func = partial( + topotest.router_json_cmp, r3, "show ip ospf database external json", input_dict + ) + assertmsg = "AS-External default not originated by r2 OSPF instance 2" + assert result is None, assertmsg + + step("Verify r2's OSPF instance 2 is AS-External default is installed on r3") + input_dict = { + "0.0.0.0/0": [ + { + "prefix": "0.0.0.0/0", + "prefixLen": 0, + "protocol": "ospf", + "distance": 20, + "nexthops": [ + { + "ip": "10.1.2.2", + "interfaceName": "r3-eth0", + } + ], + } + ] + } + test_func = partial( + topotest.router_json_cmp, r3, "show ip route 0.0.0.0/0 json", input_dict + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assertmsg = "0.0.0.0/0 from router r2 not installed on r3" + assert result is None, assertmsg + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf index 995958132c93..325122edeb40 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf @@ -1,7 +1,10 @@ ! hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r1-eth0 ip address 10.0.1.1/24 diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf index 29909de6461d..b6763311f48b 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf @@ -1,7 +1,10 @@ ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r2-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r2-eth0 ip address 10.0.2.2/24 diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf index 35fe22e9f9bc..02414b5f9531 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf @@ -1,7 +1,10 @@ ! hostname r3 +<<<<<<< HEAD password zebra log file /tmp/r3-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r3-eth0 ip address 10.0.3.3/24 diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf index 721c3d91c388..e84aa8bf0989 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf @@ -1,7 +1,10 @@ ! hostname r4 +<<<<<<< HEAD password zebra log file /tmp/r4-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r4-eth0 ip address 10.0.4.4/24 diff --git a/tests/topotests/ospf_netns_vrf/r1/ospfd.conf b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf index ba131465612b..1da567a16535 100644 --- a/tests/topotests/ospf_netns_vrf/r1/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf @@ -1,7 +1,10 @@ ! hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-ospfd.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r1-eth0 vrf r1-ospf-cust1 ip ospf hello-interval 1 diff --git a/tests/topotests/ospf_netns_vrf/r1/zebra.conf b/tests/topotests/ospf_netns_vrf/r1/zebra.conf index 56d7a9764e01..ad81aecddd15 100644 --- a/tests/topotests/ospf_netns_vrf/r1/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r1/zebra.conf @@ -4,8 +4,11 @@ ! debug zebra event ! hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-zebra.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r1-eth0 vrf r1-ospf-cust1 ip address 10.0.1.1/24 diff --git a/tests/topotests/ospf_netns_vrf/r2/ospfd.conf b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf index 01b6b1526b1c..fa25010bcf0b 100644 --- a/tests/topotests/ospf_netns_vrf/r2/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf @@ -1,7 +1,10 @@ ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r2-ospfd.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r2-eth0 vrf r2-ospf-cust1 ip ospf hello-interval 1 diff --git a/tests/topotests/ospf_netns_vrf/r2/zebra.conf b/tests/topotests/ospf_netns_vrf/r2/zebra.conf index 6ff72d1267f6..68bd2c59d5de 100644 --- a/tests/topotests/ospf_netns_vrf/r2/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r2/zebra.conf @@ -1,7 +1,10 @@ ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r2-zebra.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r2-eth0 vrf r2-ospf-cust1 ip address 10.0.2.1/24 diff --git a/tests/topotests/ospf_netns_vrf/r3/ospfd.conf b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf index abfaa5b9eff1..9cf9d2ffa398 100644 --- a/tests/topotests/ospf_netns_vrf/r3/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf @@ -1,7 +1,10 @@ ! hostname r3 +<<<<<<< HEAD password zebra log file /tmp/r3-ospfd.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! interface r3-eth0 vrf r3-ospf-cust1 diff --git a/tests/topotests/ospf_netns_vrf/r3/zebra.conf b/tests/topotests/ospf_netns_vrf/r3/zebra.conf index 15341500480a..bb1f14c76455 100644 --- a/tests/topotests/ospf_netns_vrf/r3/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r3/zebra.conf @@ -1,7 +1,10 @@ ! hostname r3 +<<<<<<< HEAD password zebra log file /tmp/r3-zebra.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r3-eth0 vrf r3-ospf-cust1 ip address 10.0.3.1/24 diff --git a/tests/topotests/ospf_p2mp/r1/frr-p2mp-non-broadcast.conf b/tests/topotests/ospf_p2mp/r1/frr-p2mp-non-broadcast.conf index ca84349cdcf2..c5cce73ab729 100644 --- a/tests/topotests/ospf_p2mp/r1/frr-p2mp-non-broadcast.conf +++ b/tests/topotests/ospf_p2mp/r1/frr-p2mp-non-broadcast.conf @@ -1,8 +1,11 @@ ! hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r1-eth0 ip address 10.1.0.1/24 diff --git a/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf index 89f255bb44ea..58bb06fd6a7e 100644 --- a/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf @@ -1,13 +1,19 @@ ! +<<<<<<< HEAD !log file ospfd.log debug +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! debug ospf event ! debug ospf client ! debug ospf lsa ! debug ospf packet all hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ip forwarding ! interface r1-eth0 diff --git a/tests/topotests/ospf_p2mp/r2/frr-p2mp-non-broadcast.conf b/tests/topotests/ospf_p2mp/r2/frr-p2mp-non-broadcast.conf index 6e26897c494b..228cc42b4af8 100644 --- a/tests/topotests/ospf_p2mp/r2/frr-p2mp-non-broadcast.conf +++ b/tests/topotests/ospf_p2mp/r2/frr-p2mp-non-broadcast.conf @@ -1,8 +1,11 @@ ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r2-eth0 ip address 10.1.0.2/24 diff --git a/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf index 429330987e06..9c9ed002dc8a 100644 --- a/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf @@ -1,14 +1,20 @@ ! +<<<<<<< HEAD !log file ospfd.log debug +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! debug ospf event ! debug ospf client ! debug ospf lsa ! debug ospf packet all ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r2-eth0 ip address 10.1.0.2/24 diff --git a/tests/topotests/ospf_p2mp/r3/frr-p2mp-non-broadcast.conf b/tests/topotests/ospf_p2mp/r3/frr-p2mp-non-broadcast.conf index a69e0557bee7..7b53b7d1b615 100644 --- a/tests/topotests/ospf_p2mp/r3/frr-p2mp-non-broadcast.conf +++ b/tests/topotests/ospf_p2mp/r3/frr-p2mp-non-broadcast.conf @@ -1,8 +1,11 @@ ! hostname r3 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r3-eth0 ip address 10.1.0.3/24 diff --git a/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf index eada78450e81..86ca6f9915f8 100644 --- a/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf @@ -1,14 +1,20 @@ ! +<<<<<<< HEAD !log file ospfd.log debug +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! debug ospf event ! debug ospf client ! debug ospf lsa ! debug ospf packet all ! hostname r3 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r3-eth0 ip address 10.1.0.3/24 diff --git a/tests/topotests/ospf_p2mp/r4/frr-p2mp-non-broadcast.conf b/tests/topotests/ospf_p2mp/r4/frr-p2mp-non-broadcast.conf index 1b8388584b82..1adaad648a72 100644 --- a/tests/topotests/ospf_p2mp/r4/frr-p2mp-non-broadcast.conf +++ b/tests/topotests/ospf_p2mp/r4/frr-p2mp-non-broadcast.conf @@ -1,8 +1,11 @@ ! hostname r4 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r4-eth0 ip address 10.1.0.4/24 diff --git a/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf index 3146ea095762..3f528fe5b1e0 100644 --- a/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf @@ -1,14 +1,20 @@ ! +<<<<<<< HEAD !log file ospfd.log debug +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! debug ospf event ! debug ospf client ! debug ospf lsa ! debug ospf packet all ! hostname r4 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log ip forwarding +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! interface r4-eth0 ip address 10.1.0.4/24 diff --git a/tests/topotests/ospf_prefix_suppression/r1/frr.conf b/tests/topotests/ospf_prefix_suppression/r1/frr.conf index 437b4741533a..918203575e69 100644 --- a/tests/topotests/ospf_prefix_suppression/r1/frr.conf +++ b/tests/topotests/ospf_prefix_suppression/r1/frr.conf @@ -1,7 +1,10 @@ ! hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ip forwarding ! interface r1-eth0 diff --git a/tests/topotests/ospf_prefix_suppression/r2/frr.conf b/tests/topotests/ospf_prefix_suppression/r2/frr.conf index 68390f15f12b..3fb649fb21db 100644 --- a/tests/topotests/ospf_prefix_suppression/r2/frr.conf +++ b/tests/topotests/ospf_prefix_suppression/r2/frr.conf @@ -1,7 +1,10 @@ ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ip forwarding ! interface r2-eth0 diff --git a/tests/topotests/ospf_prefix_suppression/r3/frr.conf b/tests/topotests/ospf_prefix_suppression/r3/frr.conf index 984a39d989c6..1f2754c14a7e 100644 --- a/tests/topotests/ospf_prefix_suppression/r3/frr.conf +++ b/tests/topotests/ospf_prefix_suppression/r3/frr.conf @@ -1,7 +1,10 @@ ! hostname r3 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ip forwarding ! interface r3-eth0 diff --git a/tests/topotests/ospfapi/test_ospf_clientapi.py b/tests/topotests/ospfapi/test_ospf_clientapi.py index 89a34ff9b58d..fda9bb7c8b7a 100644 --- a/tests/topotests/ospfapi/test_ospf_clientapi.py +++ b/tests/topotests/ospfapi/test_ospf_clientapi.py @@ -218,10 +218,18 @@ def _test_router_id(tgen, testbin): step("router id: check for modified router id") r1.vtysh_multicmd("conf t\nrouter ospf\nospf router-id 1.1.1.1") +<<<<<<< HEAD +======= + r1.vtysh_multicmd("clear ip ospf process") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) _wait_output(p, "SUCCESS: {}".format(waitlist[1])) step("router id: check for restored router id") r1.vtysh_multicmd("conf t\nrouter ospf\nospf router-id 1.0.0.0") +<<<<<<< HEAD +======= + r1.vtysh_multicmd("clear ip ospf process") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) _wait_output(p, "SUCCESS: {}".format(waitlist[2])) except Exception as error: logging.error("ERROR: %s", error) diff --git a/tests/topotests/pim_autorp/r1/frr.conf b/tests/topotests/pim_autorp/r1/frr.conf index 2fddbc3ae29e..6fc7bad9be6e 100644 --- a/tests/topotests/pim_autorp/r1/frr.conf +++ b/tests/topotests/pim_autorp/r1/frr.conf @@ -1,16 +1,39 @@ ! hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log debug pim autorp ! interface r1-eth0 ip address 10.10.76.1/24 +======= +! +!debug pim autorp +! +interface r1-eth0 + ip address 10.0.0.1/24 + ip igmp + ip pim +! +interface r1-eth1 + ip address 10.0.1.1/24 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ip igmp ip pim ! ip forwarding ! +<<<<<<< HEAD router pim autorp discovery -! \ No newline at end of file +! +======= +ip route 10.0.2.0/24 10.0.0.2 50 +ip route 10.0.3.0/24 10.0.0.2 50 +! +router pim + autorp discovery + rp 10.0.3.4 224.0.1.0/24 +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/pim_autorp/r2/frr.conf b/tests/topotests/pim_autorp/r2/frr.conf index fd3c0cad3990..fd9b02efa924 100644 --- a/tests/topotests/pim_autorp/r2/frr.conf +++ b/tests/topotests/pim_autorp/r2/frr.conf @@ -1,16 +1,39 @@ ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r2-frr.log debug pim autorp ! interface r2-eth0 ip address 10.10.76.2/24 +======= +! +!debug pim autorp +! +interface r2-eth0 + ip address 10.0.0.2/24 + ip igmp + ip pim +! +interface r2-eth1 + ip address 10.0.2.2/24 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ip igmp ip pim ! ip forwarding ! +<<<<<<< HEAD router pim autorp discovery -! \ No newline at end of file +! +======= +ip route 10.0.1.0/24 10.0.0.1 50 +ip route 10.0.3.0/24 10.0.2.4 50 +! +router pim + autorp discovery + rp 10.0.3.4 224.0.1.0/24 +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/tests/topotests/pim_autorp/r3/frr.conf b/tests/topotests/pim_autorp/r3/frr.conf new file mode 100644 index 000000000000..31726f2c015c --- /dev/null +++ b/tests/topotests/pim_autorp/r3/frr.conf @@ -0,0 +1,24 @@ +! +hostname r3 +! +!debug pim autorp +! +interface r3-eth0 + ip address 10.0.1.3/24 + ip igmp + ip pim +! +interface r3-eth1 + ip address 10.0.3.3/24 + ip igmp + ip pim +! +ip forwarding +! +ip route 10.0.0.0/24 10.0.1.1 50 +ip route 10.0.2.0/24 10.0.3.4 50 +! +router pim + autorp discovery + rp 10.0.3.4 224.0.1.0/24 +! diff --git a/tests/topotests/pim_autorp/r4/frr.conf b/tests/topotests/pim_autorp/r4/frr.conf new file mode 100644 index 000000000000..9d37da99aa7b --- /dev/null +++ b/tests/topotests/pim_autorp/r4/frr.conf @@ -0,0 +1,24 @@ +! +hostname r4 +! +!debug pim autorp +! +interface r4-eth0 + ip address 10.0.2.4/24 + ip igmp + ip pim +! +interface r4-eth1 + ip address 10.0.3.4/24 + ip igmp + ip pim +! +ip forwarding +! +ip route 10.0.0.0/24 10.0.2.2 50 +ip route 10.0.1.0/24 10.0.2.2 50 +! +router pim + autorp discovery + rp 10.0.3.4 224.0.1.0/24 +! diff --git a/tests/topotests/pim_autorp/test_pim_autorp.py b/tests/topotests/pim_autorp/test_pim_autorp.py index ad618af29e3d..daecd9f0d876 100644 --- a/tests/topotests/pim_autorp/test_pim_autorp.py +++ b/tests/topotests/pim_autorp/test_pim_autorp.py @@ -11,10 +11,15 @@ import os import sys import pytest +<<<<<<< HEAD +======= +import json +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) from functools import partial # pylint: disable=C0413 # Import topogen and topotest helpers +<<<<<<< HEAD from lib import topotest from lib.topogen import Topogen, get_topogen from lib.topolog import logger @@ -23,6 +28,11 @@ verify_pim_rp_info, verify_pim_rp_info_is_empty, ) +======= +from lib.topogen import Topogen, topotest, get_topogen +from lib.topolog import logger +from lib.pim import verify_pim_rp_info +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) from lib.common_config import step, write_test_header from time import sleep @@ -32,6 +42,7 @@ """ TOPOLOGY = """ +<<<<<<< HEAD Basic AutoRP functionality +---+---+ +---+---+ @@ -39,6 +50,28 @@ + R1 + <------------------> + R2 | | | .1 .2 | | +---+---+ +---+---+ +======= + Test PIM AutoRP functionality: + AutoRP candidate RP announcements + Mapping agent announcement receive and send discovery + AutoRP discovery to active RP info + + +---+---+ +---+---+ + | | 10.0.0.0/24 | | + + R1 +----------------------+ R2 | + | | .1 .2 | | + +---+---+ r1-eth0 r2-eth0 +---+---+ + .1 | r1-eth1 r2-eth1 | .2 + | | + 10.0.1.0/24 | | 10.0.2.0/24 + | | + .3 | r3-eth0 r4-eth0 | .4 + +---+---+ r3-eth1 r4-eth1 +---+---+ + | | .3 .4 | | + + R3 +----------------------+ R4 | + | | 10.0.3.0/24 | | + +---+---+ +---+---+ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) """ # Save the Current Working Directory to find configuration files. @@ -55,11 +88,22 @@ def build_topo(tgen): # Create routers tgen.add_router("r1") tgen.add_router("r2") +<<<<<<< HEAD # Create link between router 1 and 2 switch = tgen.add_switch("s1-2") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r2"]) +======= + tgen.add_router("r3") + tgen.add_router("r4") + + # Create topology links + tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "r1-eth0", "r2-eth0") + tgen.add_link(tgen.gears["r1"], tgen.gears["r3"], "r1-eth1", "r3-eth0") + tgen.add_link(tgen.gears["r2"], tgen.gears["r4"], "r2-eth1", "r4-eth0") + tgen.add_link(tgen.gears["r3"], tgen.gears["r4"], "r3-eth1", "r4-eth1") +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def setup_module(mod): @@ -68,6 +112,7 @@ def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) tgen.start_topology() +<<<<<<< HEAD # Router 1 will be the router configured with "fake" autorp configuration, so give it a default route # to router 2 so that routing to the RP address is not an issue # r1_defrt_setup_cmds = [ @@ -77,6 +122,8 @@ def setup_module(mod): # tgen.net["r1"].cmd(cmd) logger.info("Testing PIM AutoRP support") +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) router_list = tgen.routers() for rname, router in router_list.items(): logger.info("Loading router %s" % rname) @@ -95,8 +142,13 @@ def teardown_module(mod): tgen.stop_topology() +<<<<<<< HEAD def test_pim_autorp_discovery_single_rp(request): "Test PIM AutoRP Discovery with single RP" +======= +def test_pim_autorp_init(request): + "Test PIM AutoRP startup with only the static RP" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) @@ -104,6 +156,7 @@ def test_pim_autorp_discovery_single_rp(request): if tgen.routers_have_failure(): pytest.skip(tgen.errors) +<<<<<<< HEAD step("Start with no RP configuration") result = verify_pim_rp_info_is_empty(tgen, "r1") assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) @@ -135,6 +188,255 @@ def test_pim_autorp_discovery_single_rp(request): def test_pim_autorp_discovery_multiple_rp(request): "Test PIM AutoRP Discovery with multiple RP's" +======= + step("Verify start-up with no extra RP configuration") + expected = json.loads( + """ + { + "10.0.3.4":[ + { + "rpAddress":"10.0.3.4", + "group":"224.0.1.0/24", + "source":"Static" + } + ] + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim rp-info json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct rp-info".format(rtr) + + step("Verify start-up with AutoRP only discovery enabled") + expected = json.loads( + """ + { + "discovery":{ + "enabled": true + }, + "announce": { + "enabled":false + }, + "mapping-agent": { + "enabled":false + } + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim autorp json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct autorp configuration".format( + rtr + ) + + +def test_pim_autorp_no_mapping_agent_rp(request): + "Test PIM AutoRP candidate with no mapping agent" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Start a candidate RP on r2 + tgen.routers()["r2"].vtysh_cmd( + """ + conf + router pim + autorp announce 10.0.0.2 224.0.0.0/4 + autorp announce scope 31 interval 1 holdtime 5 + """ + ) + + # Without a mapping agent, we should still have no RP + step("Verify no RP without mapping agent") + expected = json.loads( + """ + { + "10.0.3.4":[ + { + "rpAddress":"10.0.3.4", + "group":"224.0.1.0/24", + "source":"Static" + } + ] + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim rp-info json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct rp-info".format(rtr) + + step("Verify candidate RP in AutoRP on R2") + expected = json.loads( + """ + { + "discovery":{ + "enabled": true + }, + "announce": { + "enabled":true, + "scope":31, + "interval":1, + "holdtime":5, + "rpList":[ + { + "rpAddress":"10.0.0.2", + "groupRange":"224.0.0.0/4", + "prefixList":"-" + } + ] + }, + "mapping-agent": { + "enabled":false + } + }""" + ) + test_func = partial( + topotest.router_json_cmp, tgen.gears["r2"], "show ip pim autorp json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct autorp configuration".format("r2") + + +def test_pim_autorp_discovery_rp(request): + "Test PIM AutoRP candidate advertised by mapping agent" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Start the mapping agent on R1 + tgen.routers()["r1"].vtysh_cmd( + """ + conf + router pim + autorp send-rp-discovery source interface r1-eth0 + autorp send-rp-discovery scope 31 interval 1 holdtime 5 + """ + ) + + step("Verify rp-info of the only candidate RP") + expected = json.loads( + """ + { + "10.0.3.4":[ + { + "rpAddress":"10.0.3.4", + "group":"224.0.1.0/24", + "source":"Static" + } + ], + "10.0.0.2":[ + { + "rpAddress":"10.0.0.2", + "group":"224.0.0.0/4", + "source":"AutoRP" + } + ] + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim rp-info json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct rp-info".format(rtr) + + step("Verify mapping-agent in AutoRP on R1") + expected = json.loads( + """ + { + "announce": { + "enabled":false + }, + "mapping-agent": { + "enabled":true, + "active":true, + "scope":31, + "interval":1, + "holdtime":5, + "source":"interface", + "interface":"r1-eth0", + "address":"10.0.0.1", + "rpList":{ + "10.0.0.2":{ + "rpAddress":"10.0.0.2", + "groupRanges":[ + { + "negative":false, + "prefix":"224.0.0.0/4" + } + ] + } + } + } + }""" + ) + test_func = partial( + topotest.router_json_cmp, tgen.gears["r1"], "show ip pim autorp json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct autorp configuration".format("r1") + + step("Verify AutoRP discovery RP's") + expected = json.loads( + """ + { + "discovery":{ + "enabled": true, + "rpList":{ + "10.0.0.2":{ + "rpAddress":"10.0.0.2", + "holdtime":5, + "groupRanges":[ + { + "negative":false, + "prefix":"224.0.0.0/4" + } + ] + } + } + } + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim autorp json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct autorp configuration".format( + rtr + ) + + +def test_pim_autorp_discovery_multiple_rp_same(request): + "Test PIM AutoRP Discovery with multiple RP's for same group prefix" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) @@ -142,6 +444,7 @@ def test_pim_autorp_discovery_multiple_rp(request): if tgen.routers_have_failure(): pytest.skip("skipped because of router(s) failure") +<<<<<<< HEAD step("Start with no RP configuration") result = verify_pim_rp_info_is_empty(tgen, "r2") assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) @@ -178,6 +481,311 @@ def test_pim_autorp_discovery_multiple_rp(request): True, ) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) +======= + # Start a candidate RP on r3 + tgen.routers()["r3"].vtysh_cmd( + """ + conf + router pim + autorp announce 10.0.1.3 224.0.0.0/4 + autorp announce scope 31 interval 1 holdtime 5 + """ + ) + + # The new candidate RP has the same group range but a higher IP, they should all + # switch to this RP + step("Verify rp-info of the candidate RP with the higher IP") + expected = json.loads( + """ + { + "10.0.3.4":[ + { + "rpAddress":"10.0.3.4", + "group":"224.0.1.0/24", + "source":"Static" + } + ], + "10.0.1.3":[ + { + "rpAddress":"10.0.1.3", + "group":"224.0.0.0/4", + "source":"AutoRP" + } + ] + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim rp-info json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct rp-info".format(rtr) + + step("Verify AutoRP discovery RP's") + expected = json.loads( + """ + { + "discovery":{ + "enabled": true, + "rpList":{ + "10.0.0.2":{ + "rpAddress":"10.0.0.2", + "holdtime":5, + "groupRanges":[ + { + "negative":false, + "prefix":"224.0.0.0/4" + } + ] + }, + "10.0.1.3":{ + "rpAddress":"10.0.1.3", + "holdtime":5, + "groupRanges":[ + { + "negative":false, + "prefix":"224.0.0.0/4" + } + ] + } + } + } + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim autorp json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct autorp configuration".format( + rtr + ) + + +def test_pim_autorp_discovery_multiple_rp_different(request): + "Test PIM AutoRP Discovery with multiple RP's for different group prefixes" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Switch R3 candidate to prefix list with different groups + step("Change R3 candidate to a prefix list") + tgen.routers()["r3"].vtysh_cmd( + """ + conf + ip prefix-list MYLIST permit 225.0.0.0/8 + ip prefix-list MYLIST permit 226.0.0.0/8 + router pim + autorp announce 10.0.1.3 group-list MYLIST + """ + ) + + # Now that R3 doesn't conflict, we should see both RP's + step("Verify rp-info of both candidate RP's") + expected = json.loads( + """ + { + "10.0.3.4":[ + { + "rpAddress":"10.0.3.4", + "group":"224.0.1.0/24", + "source":"Static" + } + ], + "10.0.0.2":[ + { + "rpAddress":"10.0.0.2", + "group":"224.0.0.0/4", + "source":"AutoRP" + } + ], + "10.0.1.3":[ + { + "rpAddress":"10.0.1.3", + "prefixList":"__AUTORP_10.0.1.3__", + "source":"AutoRP" + } + ] + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim rp-info json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct rp-info".format(rtr) + + step("Verify AutoRP discovery RP's") + expected = json.loads( + """ + { + "discovery":{ + "enabled": true, + "rpList":{ + "10.0.0.2":{ + "rpAddress":"10.0.0.2", + "holdtime":5, + "groupRanges":[ + { + "negative":false, + "prefix":"224.0.0.0/4" + } + ] + }, + "10.0.1.3":{ + "rpAddress":"10.0.1.3", + "holdtime":5, + "groupRanges":[ + { + "negative":false, + "prefix":"225.0.0.0/8" + }, + { + "negative":false, + "prefix":"226.0.0.0/8" + } + ] + } + } + } + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim autorp json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct autorp configuration".format( + rtr + ) + + +def test_pim_autorp_discovery_neg_prefixes(request): + "Test PIM AutoRP Discovery with negative prefixes" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Add negative prefixes to the R3 candidate prefix list + step("Change R3 candidate prefix list to include overlapping negative prefixes") + tgen.routers()["r3"].vtysh_cmd( + """ + conf + ip prefix-list MYLIST deny 225.1.0.0/16 + ip prefix-list MYLIST deny 226.1.0.0/16 + """ + ) + + step("Verify rp-info stays the same") + expected = json.loads( + """ + { + "10.0.3.4":[ + { + "rpAddress":"10.0.3.4", + "group":"224.0.1.0/24", + "source":"Static" + } + ], + "10.0.0.2":[ + { + "rpAddress":"10.0.0.2", + "group":"224.0.0.0/4", + "source":"AutoRP" + } + ], + "10.0.1.3":[ + { + "rpAddress":"10.0.1.3", + "prefixList":"__AUTORP_10.0.1.3__", + "source":"AutoRP" + } + ] + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim rp-info json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct rp-info".format(rtr) + + step("Verify AutoRP discovery RP's") + expected = json.loads( + """ + { + "discovery":{ + "enabled": true, + "rpList":{ + "10.0.0.2":{ + "rpAddress":"10.0.0.2", + "holdtime":5, + "groupRanges":[ + { + "negative":false, + "prefix":"224.0.0.0/4" + } + ] + }, + "10.0.1.3":{ + "rpAddress":"10.0.1.3", + "holdtime":5, + "groupRanges":[ + { + "negative":false, + "prefix":"225.0.0.0/8" + }, + { + "negative":false, + "prefix":"226.0.0.0/8" + }, + { + "negative":true, + "prefix":"225.1.0.0/16" + }, + { + "negative":true, + "prefix":"226.1.0.0/16" + } + ] + } + } + } + }""" + ) + for rtr in ["r1", "r2", "r3", "r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim autorp json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct autorp configuration".format( + rtr + ) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_pim_autorp_discovery_static(request): @@ -189,6 +797,7 @@ def test_pim_autorp_discovery_static(request): if tgen.routers_have_failure(): pytest.skip("skipped because of router(s) failure") +<<<<<<< HEAD step("Start with no RP configuration") result = verify_pim_rp_info_is_empty(tgen, "r2") assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) @@ -325,6 +934,62 @@ def test_pim_autorp_announce_group(request): # TODO: Verify AutoRP mapping agent receives updated candidate RP announcement # Mapping agent is not yet implemented # sleep(10) +======= + # Add in a static RP with a specific range and make sure both are used + step("Add static RP configuration to r4") + tgen.routers()["r4"].vtysh_cmd( + """ + conf t + router pim + rp 10.0.2.2 239.0.0.0/24 + """ + ) + + step("Verify static rp-info from r4") + expected = json.loads( + """ + { + "10.0.3.4":[ + { + "rpAddress":"10.0.3.4", + "group":"224.0.1.0/24", + "source":"Static" + } + ], + "10.0.0.2":[ + { + "rpAddress":"10.0.0.2", + "group":"224.0.0.0/4", + "source":"AutoRP" + } + ], + "10.0.1.3":[ + { + "rpAddress":"10.0.1.3", + "prefixList":"__AUTORP_10.0.1.3__", + "source":"AutoRP" + } + ], + "10.0.2.2":[ + { + "rpAddress":"10.0.2.2", + "group":"239.0.0.0/24", + "source":"Static" + } + ] + }""" + ) + + for rtr in ["r4"]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[rtr], + "show ip pim rp-info json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, "{} does not have correct rp-info".format(rtr) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_memory_leak(): diff --git a/tests/topotests/pim_basic/test_pim.py b/tests/topotests/pim_basic/test_pim.py index ce1abe42bb09..d90a16f02ed4 100644 --- a/tests/topotests/pim_basic/test_pim.py +++ b/tests/topotests/pim_basic/test_pim.py @@ -132,14 +132,24 @@ def test_pim_send_mcast_stream(): # Let's establish a S,G stream from r2 -> r1 CWD = os.path.dirname(os.path.realpath(__file__)) r2.run( +<<<<<<< HEAD "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r2-eth0 > /tmp/bar".format( CWD +======= + "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r2-eth0 > {}/r2/mcast_tx_output".format( + CWD, tgen.logdir +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) ) # And from r3 -> r1 r3.run( +<<<<<<< HEAD "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r3-eth0 > /tmp/bar".format( CWD +======= + "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r3-eth0 > {}/r3/mcast_tx_output".format( + CWD, tgen.logdir +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) ) diff --git a/tests/topotests/pim_boundary_acl/r1/frr.conf b/tests/topotests/pim_boundary_acl/r1/frr.conf new file mode 100644 index 000000000000..cc639b304b37 --- /dev/null +++ b/tests/topotests/pim_boundary_acl/r1/frr.conf @@ -0,0 +1,39 @@ +hostname r1 +! +!debug pim events +!debug igmp events +!debug igmp packets +! +ip prefix-list pim-oil-plist seq 10 deny 229.1.1.0/24 +ip prefix-list pim-oil-plist seq 20 permit any +! +access-list pim-acl seq 10 deny ip host 10.0.20.2 232.1.1.0 0.0.0.255 +access-list pim-acl seq 20 permit ip any any +! +interface r1-eth0 + ip address 10.0.20.1/24 + ip igmp + ip pim +! +interface r1-eth1 + ip address 10.0.30.1/24 + ip pim +! +interface r1-eth2 + ip address 10.0.40.1/24 + ip igmp + ip pim +! +interface lo + ip address 10.254.0.1/32 + ip pim +! +router pim + rp 10.254.0.3 + join-prune-interval 5 +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 10.0.30.3 remote-as external + neighbor 10.0.30.3 timers 3 10 + redistribute connected diff --git a/tests/topotests/pim_boundary_acl/r2/frr.conf b/tests/topotests/pim_boundary_acl/r2/frr.conf new file mode 100644 index 000000000000..10ace947b2bc --- /dev/null +++ b/tests/topotests/pim_boundary_acl/r2/frr.conf @@ -0,0 +1,19 @@ +hostname r2 +! +!debug pim events +!debug igmp events +!debug igmp packets +! +ip prefix-list pim-oil-plist seq 10 deny 229.1.1.0/24 +ip prefix-list pim-oil-plist seq 20 permit any +! +access-list pim-acl seq 10 deny ip host 10.0.20.2 232.1.1.0 0.0.0.255 +access-list pim-acl seq 20 permit ip any any +! +interface r2-eth0 + ip address 10.0.20.2/24 + ip pim +! +interface lo + ip address 10.254.0.2/32 +! diff --git a/tests/topotests/pim_boundary_acl/r3/frr.conf b/tests/topotests/pim_boundary_acl/r3/frr.conf new file mode 100644 index 000000000000..972077426643 --- /dev/null +++ b/tests/topotests/pim_boundary_acl/r3/frr.conf @@ -0,0 +1,13 @@ +hostname r3 +! +!debug pim events +!debug igmp events +!debug igmp packets +! +interface r3-eth0 + ip address 10.0.40.4/24 + ip pim +! +interface lo + ip address 10.254.0.4/32 +! diff --git a/tests/topotests/pim_boundary_acl/rp/frr.conf b/tests/topotests/pim_boundary_acl/rp/frr.conf new file mode 100644 index 000000000000..f6eed2391705 --- /dev/null +++ b/tests/topotests/pim_boundary_acl/rp/frr.conf @@ -0,0 +1,22 @@ +hostname rp +! +interface rp-eth0 + ip address 10.0.30.3/24 + ip pim +! +interface lo + ip address 10.254.0.3/32 + ip pim +! +router pim + rp 10.254.0.3 + join-prune-interval 5 + register-accept-list ACCEPT +! +ip prefix-list ACCEPT seq 5 permit 10.0.20.0/24 le 32 +! +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 10.0.30.1 remote-as external + neighbor 10.0.30.1 timers 3 10 + redistribute connected \ No newline at end of file diff --git a/tests/topotests/pim_boundary_acl/test_pim_boundary_acl.py b/tests/topotests/pim_boundary_acl/test_pim_boundary_acl.py new file mode 100644 index 000000000000..1488e610c8ce --- /dev/null +++ b/tests/topotests/pim_boundary_acl/test_pim_boundary_acl.py @@ -0,0 +1,523 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_pim_boundary_acl.py +# +# Copyright (c) 2024 Architecture Technology Corporation +# Corey Siltala +# + +""" +test_pim_boundary_acl.py: Test multicast boundary commands (access-lists and prefix-lists) +""" + +import os +import sys +import pytest +import json +from functools import partial + +pytestmark = [pytest.mark.pimd] + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +ASM_GROUP="229.1.1.1" +SSM_GROUP="232.1.1.1" + +def build_topo(tgen): + "Build function" + + for routern in range(1, 4): + tgen.add_router("r{}".format(routern)) + + tgen.add_router("rp") + + # rp ------ r1 -------- r2 + # \ + # --------- r3 + # r1 -> .1 + # r2 -> .2 + # rp -> .3 + # r3 -> .4 + # loopback network is 10.254.0.X/32 + # + # r1 <- sw1 -> r2 + # r1-eth0 <-> r2-eth0 + # 10.0.20.0/24 + sw = tgen.add_switch("sw1") + sw.add_link(tgen.gears["r1"]) + sw.add_link(tgen.gears["r2"]) + + # r1 <- sw2 -> rp + # r1-eth1 <-> rp-eth0 + # 10.0.30.0/24 + sw = tgen.add_switch("sw2") + sw.add_link(tgen.gears["r1"]) + sw.add_link(tgen.gears["rp"]) + + # r1 <- sw3 -> r3 + # r1-eth2 <-> r3-eth0 + # 10.0.40.0/24 + sw = tgen.add_switch("sw3") + sw.add_link(tgen.gears["r1"]) + sw.add_link(tgen.gears["r3"]) + + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + # For all registered routers, load the zebra configuration file + for rname, router in tgen.routers().items(): + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + # After loading the configurations, this function loads configured daemons. + tgen.start_router() + # tgen.mininet_cli() + + +def teardown_module(): + "Teardown the pytest environment" + tgen = get_topogen() + + # This function tears down the whole topology. + tgen.stop_topology() + + +def test_pim_rp_setup(): + "Ensure basic routing has come up and the rp has an outgoing interface" + # Ensure rp and r1 establish pim neighbor ship and bgp has come up + # Finally ensure that the rp has an outgoing interface on r1 + tgen = get_topogen() + + r1 = tgen.gears["r1"] + expected = { + "10.254.0.3":[ + { + "outboundInterface":"r1-eth1", + "group":"224.0.0.0/4", + "source":"Static" + } + ] + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip pim rp-info json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = '"{}" JSON output mismatches'.format(r1.name) + assert result is None, assertmsg + # tgen.mininet_cli() + + +def test_pim_asm_igmp_join_acl(): + "Test ASM IGMP joins with prefix-list ACLs" + logger.info("Send IGMP joins from r2 to r1 with ACL enabled and disabled") + + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r2 = tgen.gears["r2"] + r1 = tgen.gears["r1"] + + # No IGMP sources other than from self for AutoRP Discovery group initially + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "224.0.1.40":"*", + "229.1.1.1":None + }, + "r1-eth2":{ + "name":"r1-eth2", + "224.0.1.40":"*", + "229.1.1.1":None + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected no IGMP sources other than for AutoRP Discovery" + + # Send IGMP join from r2, check if r1 has IGMP source + r2.vtysh_cmd(( + """ + configure terminal + interface {} + ip igmp join {} + """ + ).format("r2-eth0", ASM_GROUP)) + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "229.1.1.1":{ + "group":"229.1.1.1", + "sources":[ + { + "source":"*", + "timer":"--:--", + "forwarded":False, + "uptime":"*" + } + ] + } + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP source to be present but is absent" + + # Test inbound boundary on r1 + # Enable multicast boundary on r1, toggle IGMP join on r2 + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + no ip igmp join {} + """ + ).format(ASM_GROUP)) + r1.vtysh_cmd( + """ + configure terminal + interface r1-eth0 + ip multicast boundary oil pim-oil-plist + """ + ) + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + ip igmp join {} + """ + ).format(ASM_GROUP)) + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "229.1.1.1":None + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP source to be absent but is present" + + # Test outbound boundary on r2 + # Enable multicast boundary on r2, toggle IGMP join (test outbound) + # Note: json_cmp treats "*" as wildcard but in this case that's actually what the source is + expected = { + "vrf":"default", + "r2-eth0":{ + "name":"r2-eth0", + "groups":[ + { + "source":"*", + "group":"229.1.1.1", + "primaryAddr":"10.0.20.2", + "sockFd":"*", + "upTime":"*" + } + ] + } + } + test_func = partial( + topotest.router_json_cmp, r2, "show ip igmp join json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP join to be present but is absent" + + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + no ip igmp join {} + ip multicast boundary oil pim-oil-plist + ip igmp join {} + """ + ).format(ASM_GROUP, ASM_GROUP)) + expected = { + "vrf":"default", + "r2-eth0":None + } + test_func = partial( + topotest.router_json_cmp, r2, "show ip igmp join json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP join to be absent but is present" + + # Cleanup + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + no ip igmp join {} + no ip multicast boundary oil pim-oil-plist + """ + ).format(ASM_GROUP)) + + +def test_pim_ssm_igmp_join_acl(): + "Test SSM IGMP joins with extended ACLs" + logger.info("Send IGMP joins from r2 to r1 with ACL enabled and disabled") + + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r3 = tgen.gears["r3"] + r2 = tgen.gears["r2"] + r1 = tgen.gears["r1"] + + # No IGMP sources other than from self for AutoRP Discovery group initially + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "224.0.1.40":"*", + "229.1.1.1":None, + "232.1.1.1":None + }, + "r1-eth2":{ + "name":"r1-eth2", + "224.0.1.40":"*", + "229.1.1.1":None, + "232.1.1.1":None + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", {} + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected no IGMP sources other than from AutoRP Discovery" + + # Send IGMP join from r2, check if r1 has IGMP source + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + ip igmp join {} 10.0.20.2 + """ + ).format(SSM_GROUP)) + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "232.1.1.1":{ + "group":"232.1.1.1", + "sources":[ + { + "source":"10.0.20.2", + "timer":"*", + "forwarded":False, + "uptime":"*" + } + ] + } + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP source to be present but is absent" + + # Test inbound boundary on r1 + # Enable multicast boundary on r1, toggle IGMP join on r2 + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + no ip igmp join {} 10.0.20.2 + """ + ).format(SSM_GROUP)) + r1.vtysh_cmd( + """ + configure terminal + interface r1-eth0 + ip multicast boundary pim-acl + """ + ) + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + ip igmp join {} 10.0.20.2 + """ + ).format(SSM_GROUP)) + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "232.1.1.1":None + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP source to be absent but is present" + + # Add lower, more-specific permit rule to access-list + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + no ip igmp join {} 10.0.20.2 + """ + ).format(SSM_GROUP)) + r1.vtysh_cmd(( + """ + configure terminal + access-list pim-acl seq 5 permit ip host 10.0.20.2 {} 0.0.0.128 + """ + ).format(SSM_GROUP)) + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + ip igmp join {} 10.0.20.2 + """ + ).format(SSM_GROUP)) + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "232.1.1.1":{ + "group":"232.1.1.1", + "sources":[ + { + "source":"10.0.20.2", + "timer":"*", + "forwarded":False, + "uptime":"*" + } + ] + } + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP source to be present but is absent" + + # Test outbound boundary on r2 + # Enable multicast boundary on r2, toggle IGMP join (test outbound) + expected = { + "vrf":"default", + "r2-eth0":{ + "name":"r2-eth0", + "groups":[ + { + "source":"10.0.20.2", + "group":"232.1.1.1", + "primaryAddr":"10.0.20.2", + "sockFd":"*", + "upTime":"*" + } + ] + } + } + test_func = partial( + topotest.router_json_cmp, r2, "show ip igmp join json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP join to be present but is absent" + + # Enable boundary ACL, check join is absent + r2.vtysh_cmd(( + """ + configure terminal + interface r2-eth0 + no ip igmp join {} 10.0.20.2 + ip multicast boundary pim-acl + ip igmp join {} 10.0.20.2 + """ + ).format(SSM_GROUP, SSM_GROUP)) + expected = { + "vrf":"default", + "r2-eth0":None + } + test_func = partial( + topotest.router_json_cmp, r2, "show ip igmp join json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP join to be absent but is present" + # Check sources on r1 again, should be absent even though we permitted it because r2 is blocking it outbound + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "232.1.1.1":None + }, + "r1-eth2":{ + "name":"r1-eth2", + "232.1.1.1":None + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP source to be absent but is present" + + # Send IGMP join from r3 with different source, should show up on r1 + # Add lower, more-specific permit rule to access-list + r3.vtysh_cmd(( + """ + configure terminal + interface r3-eth0 + ip igmp join {} 10.0.40.4 + """ + ).format(SSM_GROUP)) + expected = { + "r1-eth0":{ + "name":"r1-eth0", + "232.1.1.1":None + }, + "r1-eth2":{ + "name":"r1-eth2", + "232.1.1.1":{ + "group":"232.1.1.1", + "sources":[ + { + "source":"10.0.40.4", + "timer":"*", + "forwarded":False, + "uptime":"*" + } + ] + } + } + } + test_func = partial( + topotest.router_json_cmp, r1, "show ip igmp sources json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Expected IGMP source to be present but is absent" + + # PIM join + # PIM-DM forwarding + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/pim_cand_rp_bsr/r1/frr.conf b/tests/topotests/pim_cand_rp_bsr/r1/frr.conf index 899e9c068413..062e79b4c887 100644 --- a/tests/topotests/pim_cand_rp_bsr/r1/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r1/frr.conf @@ -1,7 +1,10 @@ ! hostname r1 +<<<<<<< HEAD password zebra log file /tmp/r1-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! !debug pim packet !debug pim bsm diff --git a/tests/topotests/pim_cand_rp_bsr/r2/frr.conf b/tests/topotests/pim_cand_rp_bsr/r2/frr.conf index 85af461d5eb9..26062acece4a 100644 --- a/tests/topotests/pim_cand_rp_bsr/r2/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r2/frr.conf @@ -1,7 +1,10 @@ ! hostname r2 +<<<<<<< HEAD password zebra log file /tmp/r2-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! !debug pim packet !debug pim bsm diff --git a/tests/topotests/pim_cand_rp_bsr/r3/frr.conf b/tests/topotests/pim_cand_rp_bsr/r3/frr.conf index 022c44ea58b7..0f487ac91c8a 100644 --- a/tests/topotests/pim_cand_rp_bsr/r3/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r3/frr.conf @@ -1,7 +1,10 @@ ! hostname r3 +<<<<<<< HEAD password zebra log file /tmp/r3-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! !debug pim packet !debug pim bsm diff --git a/tests/topotests/pim_cand_rp_bsr/r4/frr.conf b/tests/topotests/pim_cand_rp_bsr/r4/frr.conf index 2d0a035f9a9d..b0a772adc11e 100644 --- a/tests/topotests/pim_cand_rp_bsr/r4/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r4/frr.conf @@ -1,7 +1,10 @@ ! hostname r4 +<<<<<<< HEAD password zebra log file /tmp/r4-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! interface lo diff --git a/tests/topotests/pim_cand_rp_bsr/r5/frr.conf b/tests/topotests/pim_cand_rp_bsr/r5/frr.conf index 552e51f417f6..57205c9b1f54 100644 --- a/tests/topotests/pim_cand_rp_bsr/r5/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r5/frr.conf @@ -1,7 +1,10 @@ ! hostname r5 +<<<<<<< HEAD password zebra log file /tmp/r5-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! interface r5-eth0 diff --git a/tests/topotests/pim_cand_rp_bsr/r6/frr.conf b/tests/topotests/pim_cand_rp_bsr/r6/frr.conf index 20955a12c709..0d03a23ef839 100644 --- a/tests/topotests/pim_cand_rp_bsr/r6/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r6/frr.conf @@ -1,7 +1,10 @@ ! hostname r6 +<<<<<<< HEAD password zebra log file /tmp/r6-frr.log +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! ! interface r6-eth0 diff --git a/tests/topotests/pim_embedded_rp/__init__.py b/tests/topotests/pim_embedded_rp/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/pim_embedded_rp/r1/frr.conf b/tests/topotests/pim_embedded_rp/r1/frr.conf new file mode 100644 index 000000000000..3c712d0f31bc --- /dev/null +++ b/tests/topotests/pim_embedded_rp/r1/frr.conf @@ -0,0 +1,28 @@ +log commands +! +interface r1-eth0 + ipv6 address 2001:db8:10::1/64 + ipv6 ospf6 area 0 + ipv6 ospf6 dead-interval 8 + ipv6 ospf6 hello-interval 4 + ipv6 pim +! +interface r1-eth1 + ipv6 address 2001:db8:20::1/64 + ipv6 ospf6 area 0 + ipv6 ospf6 dead-interval 8 + ipv6 ospf6 hello-interval 4 + ipv6 pim +! +interface lo + ip address 10.254.254.1/32 + ipv6 address 2001:db8:ffff::1/128 + ipv6 ospf6 area 0 + ipv6 pim +! +router ospf6 + redistribute connected +! +router pim6 + rp 2001:db8:ffff::1 +! diff --git a/tests/topotests/pim_embedded_rp/r2/frr.conf b/tests/topotests/pim_embedded_rp/r2/frr.conf new file mode 100644 index 000000000000..ec89874be020 --- /dev/null +++ b/tests/topotests/pim_embedded_rp/r2/frr.conf @@ -0,0 +1,39 @@ +log commands +! +interface r2-eth0 + ipv6 address 2001:db8:10::2/64 + ipv6 ospf6 area 0 + ipv6 ospf6 dead-interval 8 + ipv6 ospf6 hello-interval 4 + ipv6 pim +! +interface r2-eth1 + ipv6 address 2001:db8:30::20/64 + ipv6 ospf6 area 0 + ipv6 ospf6 dead-interval 8 + ipv6 ospf6 hello-interval 4 + ipv6 pim +! +interface r2-eth2 + ipv6 address 2001:db8:100::1/64 + ipv6 ospf6 area 0 + ipv6 mld + ipv6 pim +! +interface lo + ip address 10.254.254.2/32 + ipv6 address 2001:db8:ffff::2/128 + ipv6 ospf6 area 0 + ipv6 pim +! +router ospf6 + redistribute connected +! +router pim6 + embedded-rp + embedded-rp limit 3 + embedded-rp group-list embedded-groups +! +! Only permit embedded RPs pointing to r1 or r2 (myself) +ipv6 prefix-list embedded-groups permit FF75:0130:2001:db8:ffff::/80 +ipv6 prefix-list embedded-groups permit FF75:0230:2001:db8:ffff::/80 diff --git a/tests/topotests/pim_embedded_rp/r3/frr.conf b/tests/topotests/pim_embedded_rp/r3/frr.conf new file mode 100644 index 000000000000..198c899796c2 --- /dev/null +++ b/tests/topotests/pim_embedded_rp/r3/frr.conf @@ -0,0 +1,34 @@ +log commands +! +interface r3-eth0 + ipv6 address 2001:db8:20::2/64 + ipv6 ospf6 area 0 + ipv6 ospf6 dead-interval 8 + ipv6 ospf6 hello-interval 4 + ipv6 pim +! +interface r3-eth1 + ipv6 address 2001:db8:30::30/64 + ipv6 ospf6 area 0 + ipv6 ospf6 dead-interval 8 + ipv6 ospf6 hello-interval 4 + ipv6 pim +! +interface r3-eth2 + ipv6 address 2001:db8:200::1/64 + ipv6 ospf6 area 0 + ipv6 mld + ipv6 pim +! +interface lo + ip address 10.254.254.3/32 + ipv6 address 2001:db8:ffff::3/128 + ipv6 ospf6 area 0 + ipv6 pim +! +router ospf6 + redistribute connected +! +router pim6 + embedded-rp +! diff --git a/tests/topotests/pim_embedded_rp/test_pim_embedded_rp.py b/tests/topotests/pim_embedded_rp/test_pim_embedded_rp.py new file mode 100644 index 000000000000..3c9f0799004d --- /dev/null +++ b/tests/topotests/pim_embedded_rp/test_pim_embedded_rp.py @@ -0,0 +1,264 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 Network Education Foundation, Inc. ("NetDEF") +# Rafael Zalamena + +import os +import sys +import pytest +from functools import partial + +from lib import topotest + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger + +from lib.pim import McastTesterHelper + +""" +pim_embedded_rp.py: Test PIM embedded RP functionality. +""" + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# Required to instantiate the topology builder class. +pytestmark = [pytest.mark.pim6d] + + +def build_topo(tgen): + tgen.add_router("r1") + tgen.add_router("r2") + tgen.add_router("r3") + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r3"]) + + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + tgen.add_host("h1", "2001:DB8:100::100", "via 2001:DB8:100::1") + tgen.add_host("h2", "2001:DB8:200::100", "via 2001:DB8:200::1") + + switch = tgen.add_switch("s10") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["h1"]) + + switch = tgen.add_switch("s20") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["h2"]) + + +app_helper = McastTesterHelper() + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for _, router in router_list.items(): + router.load_frr_config(os.path.join(CWD, f"{router.name}/frr.conf")) + + tgen.start_router() + app_helper.init(tgen) + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_ospfv3_convergence(): + "Wait for OSPFv3 protocol convergence" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for protocols to converge") + + def expect_loopback_route(router, iptype, route, proto): + "Wait until route is present on RIB for protocol." + logger.info(f"waiting route {route} in {router}") + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + f"show {iptype} route json", + {route: [{"protocol": proto}]}, + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=8) + assert result is None, f'"{router}" convergence failure' + + # Wait for R1 + expect_loopback_route("r1", "ipv6", "2001:db8:ffff::2/128", "ospf6") + expect_loopback_route("r1", "ipv6", "2001:db8:ffff::3/128", "ospf6") + + # Wait for R2 + expect_loopback_route("r2", "ipv6", "2001:db8:ffff::1/128", "ospf6") + expect_loopback_route("r2", "ipv6", "2001:db8:ffff::3/128", "ospf6") + + # Wait for R3 + expect_loopback_route("r3", "ipv6", "2001:db8:ffff::1/128", "ospf6") + expect_loopback_route("r3", "ipv6", "2001:db8:ffff::2/128", "ospf6") + + +def expect_pim_rp(router, rp, group, interface=None, missing=False): + "Wait until RP is present." + tgen = get_topogen() + maximum_wait = 15 + log_message = f"waiting RP {rp} for {group} in {router}" + if missing: + log_message += \ + f" to be missing ({maximum_wait} seconds maximum)" + + logger.info(log_message) + + expected = {rp: [{"group": f"{group}/128"}]} + if interface is not None: + expected[rp][0]["outboundInterface"] = interface + + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + f"show ipv6 pim rp-info json", + expected + ) + _, result = topotest.run_and_expect( + test_func, None, count=maximum_wait, wait=1) + if missing: + assert result is not None, f'"{router}" convergence failure' + else: + assert result is None, f'"{router}" convergence failure' + + +def test_embedded_rp_mld_join(): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + success_group = "ff75:130:2001:db8:ffff::100" + filtered_group = "ff75:330:2001:db8:ffff::200" + app_helper.run("h1", [success_group, "h1-eth0"]) + app_helper.run("h1", [filtered_group, "h1-eth0"]) + + # Expect first valid join request + expect_pim_rp("r2", "2001:db8:ffff::1", success_group, interface="r2-eth0") + + # Expect filtered join request + expect_pim_rp("r2", "2001:db8:ffff::2", filtered_group, missing=True) + + # Send over the limit join request + groups = [ + "ff75:130:2001:db8:ffff::300", + "ff75:130:2001:db8:ffff::301", + "ff75:130:2001:db8:ffff::302", + ] + for group in groups: + app_helper.run("h1", [group, "h1-eth0"]) + topotest.sleep(2, "Waiting MLD join to be sent") + + expect_pim_rp("r2", "2001:db8:ffff::1", groups[0], interface="r2-eth0") + expect_pim_rp("r2", "2001:db8:ffff::1", groups[1], interface="r2-eth0") + # Over the limit entry + expect_pim_rp("r2", "2001:db8:ffff::1", groups[2], missing=True) + + app_helper.stop_all_hosts() + + # Clean up the embedded RPs so we don't cross the limit next phase + tgen.gears["r2"].vtysh_cmd("clear ipv6 mroute") + + +def test_embedded_rp_pim_join(): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # + # Test sending PIM join with embedded RP information to router R2 + # + group = "ff75:230:2001:db8:ffff::400" + app_helper.run("h2", [group, "h2-eth0"]) + expect_pim_rp("r3", "2001:db8:ffff::2", group, interface="r3-eth1") + expect_pim_rp("r2", "2001:db8:ffff::2", group, interface="lo") + + app_helper.stop_all_hosts() + + +def test_embedded_rp_spt_switch(): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Clean up the embedded RPs so we don't cross the limit next phase + tgen.gears["r1"].vtysh_cmd("clear ipv6 mroute") + tgen.gears["r2"].vtysh_cmd("clear ipv6 mroute") + tgen.gears["r3"].vtysh_cmd("clear ipv6 mroute") + + group = "ff75:130:2001:db8:ffff::500" + rp = "2001:db8:ffff::1" + source = "2001:db8:100::100" + + # Join from r3 (host h2) + app_helper.run("h2", [group, "h2-eth0"]) + # Wait for embedded RP to show up + expect_pim_rp("r3", rp, group, interface="r3-eth0") + + # Send stream from r2 (host h1) + app_helper.run("h1", ["--send=0.7", group, "h1-eth0"]) + + # Check if R1 has the correct multicast route + logger.info("Waiting r1 multicast route installation") + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r1"], + f"show ipv6 pim state json", + {group: {"*": {}, source: {}}} + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=8) + assert result is None, '"r1" convergence failure' + + # Check if R2 has the correct multicast route + logger.info("Waiting r2 multicast route installation") + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r2"], + f"show ipv6 pim state json", + {group: {source: {"r2-eth2": {"r2-eth1": {}}}}} + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=8) + assert result is None, '"r2" convergence failure' + + # Check if R3 has the correct multicast route + logger.info("Waiting r3 multicast route installation") + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r3"], + f"show ipv6 pim state json", + {group: {source: {"r3-eth1": {"r3-eth2": {}}}}} + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=8) + assert result is None, '"r3" convergence failure' + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/pytest.ini b/tests/topotests/pytest.ini index b234a84252b3..734808f7ae3f 100644 --- a/tests/topotests/pytest.ini +++ b/tests/topotests/pytest.ini @@ -32,7 +32,11 @@ log_file_date_format = %Y-%m-%d %H:%M:%S junit_logging = all junit_log_passing_tests = true +<<<<<<< HEAD norecursedirs = .git example_munet example_test example_topojson_test lib munet docker +======= +norecursedirs = .git example_munet example_test example_topojson_test lib munet docker high_ecmp +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # Directory to store test results and run logs in, default shown # rundir = /tmp/topotests diff --git a/tests/topotests/simple_snmp_test/r1/bgpd.conf b/tests/topotests/simple_snmp_test/r1/bgpd.conf index 00d1e1767085..d99206acf459 100644 --- a/tests/topotests/simple_snmp_test/r1/bgpd.conf +++ b/tests/topotests/simple_snmp_test/r1/bgpd.conf @@ -1,4 +1,7 @@ +<<<<<<< HEAD log file /tmp/bgpd.log debugging +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! router bgp 100 bgp router-id 1.1.1.1 diff --git a/tests/topotests/simple_snmp_test/r1/isisd.conf b/tests/topotests/simple_snmp_test/r1/isisd.conf index 435abde330df..e4ac884378ab 100644 --- a/tests/topotests/simple_snmp_test/r1/isisd.conf +++ b/tests/topotests/simple_snmp_test/r1/isisd.conf @@ -3,6 +3,11 @@ log stdout debugging ! debug isis route-events ! debug isis events ! +<<<<<<< HEAD +======= +agentx +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) interface r1-eth0 ip router isis ISIS1 ipv6 router isis ISIS1 diff --git a/tests/topotests/simple_snmp_test/r1/ospf6d.conf b/tests/topotests/simple_snmp_test/r1/ospf6d.conf new file mode 100644 index 000000000000..e81151710ba6 --- /dev/null +++ b/tests/topotests/simple_snmp_test/r1/ospf6d.conf @@ -0,0 +1,12 @@ +agentx + +int r1-eth0 + ipv6 ospf6 area 0.0.0.0 + +int r1-eth1 + ipv6 ospf6 area 0.0.0.0 +int r1-eth2 + ipv6 ospf6 area 0.0.0.0 + +router ospf6 + redistribute local \ No newline at end of file diff --git a/tests/topotests/simple_snmp_test/r1/ospfd.conf b/tests/topotests/simple_snmp_test/r1/ospfd.conf new file mode 100644 index 000000000000..cc0d9e52c2df --- /dev/null +++ b/tests/topotests/simple_snmp_test/r1/ospfd.conf @@ -0,0 +1,11 @@ +agentx + +int r1-eth0 + ip ospf area 0.0.0.0 +int r1-eth1 + ip ospf area 0.0.0.0 +int r1-eth2 + ip ospf area 0.0.0.0 + +router ospf + redistribute local \ No newline at end of file diff --git a/tests/topotests/simple_snmp_test/r1/ripd.conf b/tests/topotests/simple_snmp_test/r1/ripd.conf new file mode 100644 index 000000000000..71cdb058cf79 --- /dev/null +++ b/tests/topotests/simple_snmp_test/r1/ripd.conf @@ -0,0 +1,8 @@ +! +! +router rip + network 0.0.0.0/0 + redistribute local +! +agentx +! \ No newline at end of file diff --git a/tests/topotests/simple_snmp_test/r1/zebra.conf b/tests/topotests/simple_snmp_test/r1/zebra.conf index 5281d0055d9b..d333eb45c1c2 100644 --- a/tests/topotests/simple_snmp_test/r1/zebra.conf +++ b/tests/topotests/simple_snmp_test/r1/zebra.conf @@ -1,5 +1,10 @@ log file zebra.log ! +<<<<<<< HEAD +======= +agentx +! +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) interface r1-eth0 ip address 192.168.12.12/24 ipv6 address 2000:1:1:12::12/64 @@ -18,5 +23,8 @@ interface lo ipv6 address 2000:1:1:1::1/128 ! ! +<<<<<<< HEAD ! +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) line vty diff --git a/tests/topotests/simple_snmp_test/test_simple_snmp.py b/tests/topotests/simple_snmp_test/test_simple_snmp.py index 0387e2927405..54311f1949a9 100755 --- a/tests/topotests/simple_snmp_test/test_simple_snmp.py +++ b/tests/topotests/simple_snmp_test/test_simple_snmp.py @@ -24,7 +24,12 @@ # Import topogen and topotest helpers from lib.topogen import Topogen, TopoRouter, get_topogen from lib.snmptest import SnmpTester +<<<<<<< HEAD +======= +from time import sleep +from lib.topolog import logger +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) pytestmark = [pytest.mark.bgpd, pytest.mark.isisd, pytest.mark.snmp] @@ -59,10 +64,21 @@ def setup_module(mod): # For all registered routers, load the zebra configuration file for rname, router in router_list.items(): router.load_config( +<<<<<<< HEAD TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) router.load_config( TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) +======= + TopoRouter.RD_ZEBRA, + os.path.join(CWD, "{}/zebra.conf".format(rname)), + "-M snmp", + ) + router.load_config( + TopoRouter.RD_ISIS, + os.path.join(CWD, "{}/isisd.conf".format(rname)), + "-M snmp", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ) router.load_config( TopoRouter.RD_BGP, @@ -70,6 +86,24 @@ def setup_module(mod): "-M snmp", ) router.load_config( +<<<<<<< HEAD +======= + TopoRouter.RD_RIP, + os.path.join(CWD, "{}/ripd.conf".format(rname)), + "-M snmp", + ) + router.load_config( + TopoRouter.RD_OSPF, + os.path.join(CWD, "{}/ospfd.conf".format(rname)), + "-M snmp", + ) + router.load_config( + TopoRouter.RD_OSPF6, + os.path.join(CWD, "{}/ospf6d.conf".format(rname)), + "-M snmp", + ) + router.load_config( +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) TopoRouter.RD_SNMP, os.path.join(CWD, "{}/snmpd.conf".format(rname)), "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap", @@ -77,6 +111,19 @@ def setup_module(mod): # After loading the configurations, this function loads configured daemons. tgen.start_router() +<<<<<<< HEAD +======= + # Why this sleep? If you are using zebra w/ snmp we have a chicken + # and egg problem with the snmpd. snmpd is being started up with + # ip addresses, and as such snmpd may not be ready to listen yet + # (see startup stuff in topotest.py ) with the 2 second delay + # on starting snmpd after zebra. As such if we want to test + # anything in zebra we need to sleep a bit to allow the connection + # to happen. I have no good way to test to see if zebra is up + # and running with snmp at this point in time. So this will have + # to do. + sleep(17) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def teardown_module(): @@ -103,6 +150,25 @@ def test_r1_bgp_version(): assert r1_snmp.test_oid_walk("bgpVersion", ["10"]) assert r1_snmp.test_oid_walk("bgpVersion", ["10"], ["0"]) +<<<<<<< HEAD +======= + assert r1_snmp.test_oid( + "IP-FORWARD-MIB::ipForwardDest.192.168.12.0", "192.168.12.0" + ) + + assert r1_snmp.test_oid("ISIS-MIB::isisSysVersion", "one(1)") + # rip is not auto-loading agentx from mgmtd + # assert r1_snmp.test_oid("RIPv2-MIB::rip2GlobalQueries", "0") + + assert r1_snmp.test_oid("OSPF-MIB::ospfVersionNumber", "version2(2)") + assert r1_snmp.test_oid("OSPFV3-MIB::ospfv3VersionNumber", "version3(3)") + + # Let's just dump everything and make sure we get some additional test + # coverage + logger.info("Let's walk everything") + logger.info(r1_snmp.walk(".1", raw=True)) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def test_memory_leak(): "Run the memory leak test and report results." diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r1/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r1/bgpd.conf index 9d28957d99eb..42f99be6d849 100644 --- a/tests/topotests/zebra_fec_nexthop_resolution/r1/bgpd.conf +++ b/tests/topotests/zebra_fec_nexthop_resolution/r1/bgpd.conf @@ -1,5 +1,9 @@ ! router bgp 65500 +<<<<<<< HEAD +======= + timers bgp 3 9 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp router-id 192.0.2.1 neighbor 192.0.2.3 remote-as 65500 neighbor 192.0.2.3 update-source lo @@ -7,6 +11,10 @@ router bgp 65500 neighbor 192.0.2.7 ttl-security hops 10 neighbor 192.0.2.7 disable-connected-check neighbor 192.0.2.7 update-source lo +<<<<<<< HEAD +======= + neighbor 192.0.2.7 timers connect 5 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ! address-family ipv4 unicast network 192.0.2.1/32 diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r2/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r2/bgpd.conf index 46d2c9a01d67..ca992731978f 100644 --- a/tests/topotests/zebra_fec_nexthop_resolution/r2/bgpd.conf +++ b/tests/topotests/zebra_fec_nexthop_resolution/r2/bgpd.conf @@ -1,4 +1,8 @@ router bgp 65500 +<<<<<<< HEAD +======= + timers bgp 3 9 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp router-id 192.0.2.2 neighbor 192.0.2.1 remote-as 65500 neighbor 192.0.2.1 update-source lo diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r3/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r3/bgpd.conf index 060777e7fe33..7224319bb515 100644 --- a/tests/topotests/zebra_fec_nexthop_resolution/r3/bgpd.conf +++ b/tests/topotests/zebra_fec_nexthop_resolution/r3/bgpd.conf @@ -1,4 +1,8 @@ router bgp 65500 +<<<<<<< HEAD +======= + timers bgp 3 9 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp router-id 192.0.2.3 neighbor 192.0.2.1 remote-as 65500 neighbor 192.0.2.1 update-source lo diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r4/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r4/bgpd.conf index dc052da86347..7e1ad9b11738 100644 --- a/tests/topotests/zebra_fec_nexthop_resolution/r4/bgpd.conf +++ b/tests/topotests/zebra_fec_nexthop_resolution/r4/bgpd.conf @@ -1,5 +1,9 @@ ! router bgp 65500 +<<<<<<< HEAD +======= + timers bgp 3 9 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp router-id 192.0.2.4 neighbor 192.0.2.1 remote-as 65500 neighbor 192.0.2.1 ttl-security hops 10 diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r5/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r5/bgpd.conf index 1c73154e27bf..1d8d51e57148 100644 --- a/tests/topotests/zebra_fec_nexthop_resolution/r5/bgpd.conf +++ b/tests/topotests/zebra_fec_nexthop_resolution/r5/bgpd.conf @@ -1,4 +1,8 @@ router bgp 65500 +<<<<<<< HEAD +======= + timers bgp 3 9 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp router-id 192.0.2.5 neighbor 192.0.2.3 remote-as 65500 neighbor 192.0.2.3 update-source lo diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r7/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r7/bgpd.conf index eeda9d9cfa9d..69783f7bd968 100644 --- a/tests/topotests/zebra_fec_nexthop_resolution/r7/bgpd.conf +++ b/tests/topotests/zebra_fec_nexthop_resolution/r7/bgpd.conf @@ -1,10 +1,18 @@ ! router bgp 65500 +<<<<<<< HEAD +======= + timers bgp 3 9 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bgp router-id 192.0.2.7 neighbor 192.0.2.1 remote-as 65500 neighbor 192.0.2.1 ttl-security hops 10 neighbor 192.0.2.1 disable-connected-check neighbor 192.0.2.1 update-source lo +<<<<<<< HEAD +======= + neighbor 192.0.2.1 timers connect 5 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) neighbor 192.0.2.5 remote-as 65500 neighbor 192.0.2.5 update-source lo ! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/test_zebra_fec_nexthop_resolution.py b/tests/topotests/zebra_fec_nexthop_resolution/test_zebra_fec_nexthop_resolution.py index 984ff3c18526..98e2676cfa09 100644 --- a/tests/topotests/zebra_fec_nexthop_resolution/test_zebra_fec_nexthop_resolution.py +++ b/tests/topotests/zebra_fec_nexthop_resolution/test_zebra_fec_nexthop_resolution.py @@ -156,16 +156,27 @@ def test_zebra_fec_nexthop_resolution_bgp(): def _check_bgp_session(): r1 = tgen.gears["r1"] +<<<<<<< HEAD tgen.gears["r3"].vtysh_cmd("config \n no mpls fec nexthop-resolution \n end") tgen.gears["r3"].vtysh_cmd("config \n mpls fec nexthop-resolution \n end") tgen.gears["r5"].vtysh_cmd("config \n no mpls fec nexthop-resolution \n end") tgen.gears["r5"].vtysh_cmd("config \n mpls fec nexthop-resolution \n end") +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) output = json.loads(r1.vtysh_cmd("show bgp summary json")) if output["ipv4Unicast"]["peers"]["192.0.2.7"]["state"] == "Established": return None return False +<<<<<<< HEAD +======= + tgen.gears["r3"].vtysh_cmd("config \n no mpls fec nexthop-resolution \n end") + tgen.gears["r3"].vtysh_cmd("config \n mpls fec nexthop-resolution \n end") + tgen.gears["r5"].vtysh_cmd("config \n no mpls fec nexthop-resolution \n end") + tgen.gears["r5"].vtysh_cmd("config \n mpls fec nexthop-resolution \n end") + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) test_func1 = functools.partial(_check_bgp_session) _, result1 = topotest.run_and_expect(test_func1, None, count=60, wait=0.5) assert result1 is None, "Failed to verify the fec_nexthop_resolution: bgp session" diff --git a/tests/topotests/zebra_rib/r1/frr-import.conf b/tests/topotests/zebra_rib/r1/frr-import.conf new file mode 100644 index 000000000000..687843be0c43 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/frr-import.conf @@ -0,0 +1,17 @@ +! +hostname r1 +password zebra +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +interface r1-eth1 + ip address 10.10.0.1/24 +! +ip route 10.1.0.0/24 10.0.0.2 table 10 +ip route 10.2.0.0/24 10.0.0.2 table 10 +ip route 10.3.0.0/24 10.10.0.2 table 10 +ip route 10.4.0.0/24 10.10.0.2 table 10 +! +ip forwarding +! diff --git a/tests/topotests/zebra_rib/r1/import_init_mrib_table.json b/tests/topotests/zebra_rib/r1/import_init_mrib_table.json new file mode 100644 index 000000000000..80c19dacf206 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_init_mrib_table.json @@ -0,0 +1,110 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_init_table.json b/tests/topotests/zebra_rib/r1/import_init_table.json new file mode 100644 index 000000000000..80c19dacf206 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_init_table.json @@ -0,0 +1,110 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_2.json b/tests/topotests/zebra_rib/r1/import_mrib_table_2.json new file mode 100644 index 000000000000..61aaaede6e52 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_2.json @@ -0,0 +1,226 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_3.json b/tests/topotests/zebra_rib/r1/import_mrib_table_3.json new file mode 100644 index 000000000000..27a0b9f26470 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_3.json @@ -0,0 +1,255 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.20.0.0/24": [ + { + "prefix": "10.20.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_4.json b/tests/topotests/zebra_rib/r1/import_mrib_table_4.json new file mode 100644 index 000000000000..5a8f0eecd5a4 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_4.json @@ -0,0 +1,226 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_2.json b/tests/topotests/zebra_rib/r1/import_table_2.json new file mode 100644 index 000000000000..61aaaede6e52 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_2.json @@ -0,0 +1,226 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_3.json b/tests/topotests/zebra_rib/r1/import_table_3.json new file mode 100644 index 000000000000..27a0b9f26470 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_3.json @@ -0,0 +1,255 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.20.0.0/24": [ + { + "prefix": "10.20.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_4.json b/tests/topotests/zebra_rib/r1/import_table_4.json new file mode 100644 index 000000000000..5a8f0eecd5a4 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_4.json @@ -0,0 +1,226 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/sharp_rmap.ref b/tests/topotests/zebra_rib/r1/sharp_rmap.ref index 47a9eb6a4925..6cef976de4d8 100644 --- a/tests/topotests/zebra_rib/r1/sharp_rmap.ref +++ b/tests/topotests/zebra_rib/r1/sharp_rmap.ref @@ -1,6 +1,11 @@ ZEBRA: +<<<<<<< HEAD route-map: sharp Invoked: 500 Optimization: enabled Processed Change: false permit, sequence 10 Invoked 244 +======= +route-map: sharp Invoked: 500 (X milliseconds total) Optimization: enabled Processed Change: false + permit, sequence 10 Invoked 244 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: ip address 10 Set clauses: @@ -8,7 +13,11 @@ route-map: sharp Invoked: 500 Optimization: enabled Processed Change: false Call clause: Action: Exit routemap +<<<<<<< HEAD permit, sequence 20 Invoked 256 +======= + permit, sequence 20 Invoked 256 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: Set clauses: src 192.168.213.1 diff --git a/tests/topotests/zebra_rib/r1/static_rmap.ref b/tests/topotests/zebra_rib/r1/static_rmap.ref index 2de98bd51444..eba414d3a845 100644 --- a/tests/topotests/zebra_rib/r1/static_rmap.ref +++ b/tests/topotests/zebra_rib/r1/static_rmap.ref @@ -1,6 +1,11 @@ ZEBRA: +<<<<<<< HEAD route-map: static Invoked: 2 Optimization: enabled Processed Change: false permit, sequence 10 Invoked 2 +======= +route-map: static Invoked: 2 (X milliseconds total) Optimization: enabled Processed Change: false + permit, sequence 10 Invoked 2 (X milliseconds total) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) Match clauses: Set clauses: src 192.168.215.1 diff --git a/tests/topotests/zebra_rib/test_zebra_import.py b/tests/topotests/zebra_rib/test_zebra_import.py new file mode 100644 index 000000000000..7819548ad223 --- /dev/null +++ b/tests/topotests/zebra_rib/test_zebra_import.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC +# +# test_zebra_import.py +# +# Copyright (c) 2024 ATCorp +# Nathan Bahr +# + +import os +import sys +from functools import partial +import pytest +import json +import platform + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.common_config import step, write_test_header + +""" +test_zebra_import.py: Test zebra table import functionality +""" + +TOPOLOGY = """ + Single router zebra functionality + + +---+---+ + 10.0.0.1/24 | | 10.10.0.1/24 + <--->+ R1 +<---> + | | + +---+---+ +""" + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +pytestmark = [pytest.mark.sharpd] +krel = platform.release() + +def build_topo(tgen): + "Build function" + + tgen.add_router("r1") + sw1 = tgen.add_switch("sw1") + sw2 = tgen.add_switch("sw2") + sw1.add_link(tgen.gears["r1"], "r1-eth0") + sw2.add_link(tgen.gears["r1"], "r1-eth1") + +def setup_module(mod): + "Sets up the pytest environment" + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr-import.conf".format(rname))) + + # Initialize all routers. + tgen.start_router() + for router in router_list.values(): + if router.has_version("<", "4.0"): + tgen.set_error("unsupported version") + + +def teardown_module(): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def test_zebra_urib_import(request): + "Verify router starts with the initial URIB" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + step("Verify initial main routing table") + initial_json_file = "{}/r1/import_init_table.json".format(CWD) + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + r1.vtysh_cmd( + """ + conf term + ip import-table 10 + """) + + import_json_file = "{}/r1/import_table_2.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Add a new static route and verify it gets added") + r1.vtysh_cmd( + """ + conf term + ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + sync_json_file = "{}/r1/import_table_3.json".format(CWD) + expected = json.loads(open(sync_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Remove the static route and verify it gets removed") + r1.vtysh_cmd( + """ + conf term + no ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Disable table import and verify it goes back to the initial table") + r1.vtysh_cmd( + """ + conf term + no ip import-table 10 + """ + ) + + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Re-import with distance and verify correct distance") + r1.vtysh_cmd( + """ + conf term + ip import-table 10 distance 123 + """) + + import_json_file = "{}/r1/import_table_4.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + +def test_zebra_mrib_import(request): + "Verify router starts with the initial MRIB" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + step("Verify initial main MRIB routing table") + initial_json_file = "{}/r1/import_init_mrib_table.json".format(CWD) + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + r1.vtysh_cmd( + """ + conf term + ip import-table 10 mrib + """) + + import_json_file = "{}/r1/import_mrib_table_2.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Add a new static route and verify it gets added") + r1.vtysh_cmd( + """ + conf term + ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + sync_json_file = "{}/r1/import_mrib_table_3.json".format(CWD) + expected = json.loads(open(sync_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Remove the static route and verify it gets removed") + r1.vtysh_cmd( + """ + conf term + no ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Disable table import and verify it goes back to the initial table") + r1.vtysh_cmd( + """ + conf term + no ip import-table 10 mrib + """ + ) + + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Re-import with distance and verify correct distance") + r1.vtysh_cmd( + """ + conf term + ip import-table 10 mrib distance 123 + """) + + import_json_file = "{}/r1/import_mrib_table_4.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/zebra_rib/test_zebra_rib.py b/tests/topotests/zebra_rib/test_zebra_rib.py index c0a79ed79d8c..8e2878c16f73 100644 --- a/tests/topotests/zebra_rib/test_zebra_rib.py +++ b/tests/topotests/zebra_rib/test_zebra_rib.py @@ -246,6 +246,10 @@ def check_initial_routes_installed(router): def check_static_map_correct_runs(): actual = r1.vtysh_cmd("show route-map static") +<<<<<<< HEAD +======= + actual = re.sub(r"\([0-9].* milli", "(X milli", actual) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) actual = ("\n".join(actual.splitlines()) + "\n").rstrip() return topotest.get_textdiff( actual, @@ -266,6 +270,10 @@ def check_static_map_correct_runs(): def check_sharp_map_correct_runs(): actual = r1.vtysh_cmd("show route-map sharp") +<<<<<<< HEAD +======= + actual = re.sub(r"\([0-9].* milli", "(X milli", actual) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) actual = ("\n".join(actual.splitlines()) + "\n").rstrip() return topotest.get_textdiff( actual, diff --git a/tools/etc/frr/support_bundle_commands.conf b/tools/etc/frr/support_bundle_commands.conf index b3889e8784e1..23e4178e5dc7 100644 --- a/tools/etc/frr/support_bundle_commands.conf +++ b/tools/etc/frr/support_bundle_commands.conf @@ -56,6 +56,10 @@ show evpn next-hops vni all show evpn rmac vni all show evpn vni detail +<<<<<<< HEAD +======= +show bmp +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) CMD_LIST_END # Zebra Support Bundle Command List @@ -74,6 +78,13 @@ show ip fib show ipv6 fib show nexthop-group rib show route-map +<<<<<<< HEAD +======= +show mpls table +show mpls fec +show mpls ldp +show mpls pseudowires +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) show memory show interface vrf all show vrf @@ -134,9 +145,24 @@ CMD_LIST_END # CMD_LIST_END # ISIS Support Bundle Command List +<<<<<<< HEAD # PROC_NAME:isis # CMD_LIST_START # CMD_LIST_END +======= +PROC_NAME:isis +CMD_LIST_START +show isis database detail +show isis interface detail +show isis route +show isis mpls ldp-sync +show isis mpls-te database detail +show isis mpls-te interface +show isis mpls-te router +show isis neighbor detail +show isis topology +CMD_LIST_END +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) # BFD Support Bundle Command List # PROC_NAME:bfd @@ -151,6 +177,7 @@ CMD_LIST_END # PIM Support Bundle Command List PROC_NAME:pim CMD_LIST_START +<<<<<<< HEAD show ip multicast show ip pim interface show ip pim interface traffic @@ -171,6 +198,53 @@ show ip pim join show ip pim state show ip pim statistics show ip pim rpf +======= +show ip igmp vrf all groups detail +show ip igmp vrf all interface detail +show ip igmp vrf all join +show ip igmp vrf all join-group +show ip igmp vrf all proxy +show ip igmp sources +show ip igmp vrf all static-group +show ip igmp statistics + +show ip mroute vrf all +show ip multicast vrf all + +show ip msdp vrf all mesh-group +show ip msdp vrf all peer +show ip msdp vrf all sa detail + +show ip pim vrf all autorp +show ip pim bsm-database +show ip pim bsr +show ip pim bsr candidate-bsr +show ip pim bsr candidate-rp +show ip pim bsr candidate-rp-database +show ip pim bsr groups +show ip pim bsr rp-info +show ip pim channel +show ip pim group-type +show ip pim vrf all interface detail +show ip pim interface traffic +show ip pim vrf all join +show ip pim jp-agg +show ip pim local-membership +show ip pim mlag summary +show ip pim mlag vrf all interface +show ip pim vrf all mlag upstream +show ip pim vrf all neighbor detail +show ip pim nexthop +show ip pim vrf all rp-info +show ip pim vrf all rpf +show ip pim secondary +show ip pim vrf all state +show ip pim statistics +show ip pim vrf all upstream +show ip pim upstream-join-desired +show ip pim upstream-rpf +show ip pim vxlan-groups +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) CMD_LIST_END # OSPFv3 Support Bundle Command List @@ -216,6 +290,7 @@ CMD_LIST_END #PIMv6 Support Bundle Command List PROC_NAME:pim6 CMD_LIST_START +<<<<<<< HEAD show ipv6 pim channel show ipv6 pim interface show ipv6 pim interface traffic @@ -242,6 +317,39 @@ show ipv6 mroute show ipv6 pim bsr show ipv6 pim bsrp-info show ipv6 pim bsm-databases +======= +show ipv6 mld vrf all interface detail +show ipv6 mld vrf all statistics +show ipv6 mld vrf all joins detail +show ipv6 mld vrf all groups + +show ipv6 mroute vrf all +show ipv6 multicast vrf all + +show ipv6 pim bsm-database +show ipv6 pim bsr +show ipv6 pim bsr candidate-bsr +show ipv6 pim bsr candidate-rp +show ipv6 pim bsr candidate-rp-database +show ipv6 pim bsr groups +show ipv6 pim bsr rp-info +show ipv6 pim channel +show ipv6 pim vrf all interface detail +show ipv6 pim interface traffic +show ipv6 pim vrf all join +show ipv6 pim jp-agg +show ipv6 pim local-membership +show ipv6 pim nexthop +show ipv6 pim vrf all neighbor detail +show ipv6 pim vrf all rp-info +show ipv6 pim vrf all rpf +show ipv6 pim secondary +show ipv6 pim vrf all state +show ipv6 pim statistics +show ipv6 pim vrf all upstream +show ipv6 pim upstream-join-desired +show ipv6 pim upstream-rpf +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) CMD_LIST_END #MGMT Support Bundle Command List diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 08a1f1e07eac..feece77533d3 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -255,7 +255,15 @@ def get_normalized_interface_vrf(line): }, "router rip": {}, "router ripng": {}, +<<<<<<< HEAD "router isis ": {}, +======= + "router isis ": { + "segment-routing srv6": { + "node-msd": {}, + }, + }, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "router openfabric ": {}, "router ospf": {}, "router ospf6": {}, @@ -275,7 +283,11 @@ def get_normalized_interface_vrf(line): "policy ": {"candidate-path ": {}}, "pcep": {"pcc": {}, "pce ": {}, "pce-config ": {}}, }, +<<<<<<< HEAD "srv6": {"locators": {"locator ": {}}}, +======= + "srv6": {"locators": {"locator ": {}}, "encapsulation": {}}, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) }, "nexthop-group ": {}, "route-map ": {}, diff --git a/tools/frr_babeltrace.py b/tools/frr_babeltrace.py index 9832568b3736..3ac617e83585 100755 --- a/tools/frr_babeltrace.py +++ b/tools/frr_babeltrace.py @@ -18,6 +18,10 @@ import babeltrace +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ########################### common parsers - start ############################ def print_ip_addr(field_val): """ @@ -48,24 +52,40 @@ def print_mac(field_val): """ return ":".join("%02x" % fb for fb in field_val) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def print_net_ipv4_addr(field_val): """ pretty print ctf_integer_network ipv4 """ return str(ipaddress.IPv4Address(field_val)) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def print_esi(field_val): """ pretty print ethernet segment id, esi_t """ return ":".join("%02x" % fb for fb in field_val) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def get_field_list(event): """ only fetch fields added via the TP, skip metadata etc. """ return event.field_list_with_scope(babeltrace.CTFScope.EVENT_FIELDS) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_event(event, field_parsers): """ Wild card event parser; doesn't make things any prettier @@ -79,8 +99,36 @@ def parse_event(event, field_parsers): else: field_info[field] = event.get(field) print(event.name, field_info) +<<<<<<< HEAD +############################ common parsers - end ############################# + +======= + + +def print_family_str(field_val): + """ + pretty print kernel family to string + """ + if field_val == socket.AF_INET: + cmd_str = "ipv4" + elif field_val == socket.AF_INET6: + cmd_str = "ipv6" + elif field_val == socket.AF_BRIDGE: + cmd_str = "bridge" + elif field_val == 128: # RTNL_FAMILY_IPMR: + cmd_str = "ipv4MR" + elif field_val == 129: # RTNL_FAMILY_IP6MR: + cmd_str = "ipv6MR" + else: + cmd_str = "Invalid family" + + return cmd_str + + ############################ common parsers - end ############################# + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ############################ evpn parsers - start ############################# def parse_frr_bgp_evpn_mac_ip_zsend(event): """ @@ -92,6 +140,7 @@ def parse_frr_bgp_evpn_mac_ip_zsend(event): ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr) ctf_array(unsigned char, esi, esi, sizeof(esi_t)) """ +<<<<<<< HEAD field_parsers = {"ip": print_ip_addr, "mac": print_mac, "esi": print_esi, @@ -99,6 +148,18 @@ def parse_frr_bgp_evpn_mac_ip_zsend(event): parse_event(event, field_parsers) +======= + field_parsers = { + "ip": print_ip_addr, + "mac": print_mac, + "esi": print_esi, + "vtep": print_net_ipv4_addr, + } + + parse_event(event, field_parsers) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_bum_vtep_zsend(event): """ bgp evpn bum-vtep parser; raw format - @@ -110,6 +171,10 @@ def parse_frr_bgp_evpn_bum_vtep_zsend(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_nh_rmac_send(event): """ bgp evpn nh-rmac parser; raw format - @@ -119,17 +184,29 @@ def parse_frr_bgp_evpn_mh_nh_rmac_send(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_local_es_add_zrecv(event): """ bgp evpn local-es parser; raw format - ctf_array(unsigned char, esi, esi, sizeof(esi_t)) ctf_integer_network_hex(unsigned int, vtep, vtep.s_addr) """ +<<<<<<< HEAD field_parsers = {"esi": print_esi, "vtep": print_net_ipv4_addr} parse_event(event, field_parsers) +======= + field_parsers = {"esi": print_esi, "vtep": print_net_ipv4_addr} + + parse_event(event, field_parsers) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_local_es_del_zrecv(event): """ bgp evpn local-es parser; raw format - @@ -139,6 +216,10 @@ def parse_frr_bgp_evpn_mh_local_es_del_zrecv(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_local_es_evi_add_zrecv(event): """ bgp evpn local-es-evi parser; raw format - @@ -148,6 +229,10 @@ def parse_frr_bgp_evpn_mh_local_es_evi_add_zrecv(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_local_es_evi_del_zrecv(event): """ bgp evpn local-es-evi parser; raw format - @@ -157,6 +242,10 @@ def parse_frr_bgp_evpn_mh_local_es_evi_del_zrecv(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_es_evi_vtep_add(event): """ bgp evpn remote ead evi remote vtep add; raw format - @@ -167,6 +256,10 @@ def parse_frr_bgp_evpn_mh_es_evi_vtep_add(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_es_evi_vtep_del(event): """ bgp evpn remote ead evi remote vtep del; raw format - @@ -177,6 +270,10 @@ def parse_frr_bgp_evpn_mh_es_evi_vtep_del(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_local_ead_es_evi_route_upd(event): """ bgp evpn local ead evi vtep; raw format - @@ -187,6 +284,10 @@ def parse_frr_bgp_evpn_mh_local_ead_es_evi_route_upd(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_mh_local_ead_es_evi_route_del(event): """ bgp evpn local ead evi vtep del; raw format - @@ -197,6 +298,10 @@ def parse_frr_bgp_evpn_mh_local_ead_es_evi_route_del(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_local_vni_add_zrecv(event): """ bgp evpn local-vni parser; raw format - @@ -208,6 +313,10 @@ def parse_frr_bgp_evpn_local_vni_add_zrecv(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_local_l3vni_add_zrecv(event): """ bgp evpn local-l3vni parser; raw format - @@ -215,12 +324,24 @@ def parse_frr_bgp_evpn_local_l3vni_add_zrecv(event): ctf_array(unsigned char, svi_rmac, svi_rmac, sizeof(struct ethaddr)) ctf_array(unsigned char, vrr_rmac, vrr_rmac, sizeof(struct ethaddr)) """ +<<<<<<< HEAD field_parsers = {"vtep": print_net_ipv4_addr, "svi_rmac": print_mac, "vrr_rmac": print_mac} parse_event(event, field_parsers) +======= + field_parsers = { + "vtep": print_net_ipv4_addr, + "svi_rmac": print_mac, + "vrr_rmac": print_mac, + } + + parse_event(event, field_parsers) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_local_macip_add_zrecv(event): """ bgp evpn local-mac-ip parser; raw format - @@ -234,6 +355,10 @@ def parse_frr_bgp_evpn_local_macip_add_zrecv(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_local_macip_del_zrecv(event): """ bgp evpn local-mac-ip del parser; raw format - @@ -245,16 +370,32 @@ def parse_frr_bgp_evpn_local_macip_del_zrecv(event): parse_event(event, field_parsers) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_advertise_type5(event): """ local originated type-5 route """ +<<<<<<< HEAD field_parsers = {"ip": print_ip_addr, "rmac": print_mac, "vtep": print_net_ipv4_addr} parse_event(event, field_parsers) +======= + field_parsers = { + "ip": print_ip_addr, + "rmac": print_mac, + "vtep": print_net_ipv4_addr, + } + + parse_event(event, field_parsers) + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def parse_frr_bgp_evpn_withdraw_type5(event): """ local originated type-5 route withdraw @@ -263,8 +404,15 @@ def parse_frr_bgp_evpn_withdraw_type5(event): parse_event(event, field_parsers) +<<<<<<< HEAD +############################ evpn parsers - end *############################# + +======= + ############################ evpn parsers - end *############################# + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) def main(): """ FRR lttng trace output parser; babel trace plugin @@ -319,5 +467,9 @@ def main(): else: parse_event(event, {}) +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if __name__ == "__main__": main() diff --git a/tools/gcc-plugins/frr-format.c b/tools/gcc-plugins/frr-format.c index 963741e4798f..7889f5a2dc9f 100644 --- a/tools/gcc-plugins/frr-format.c +++ b/tools/gcc-plugins/frr-format.c @@ -2685,7 +2685,12 @@ tree type_normalize (tree type, tree *cousin, tree target = NULL) { while (1) { +<<<<<<< HEAD if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == POINTER_TYPE) +======= + if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == POINTER_TYPE + || TREE_CODE (type) == ARRAY_TYPE) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return type; if (target) /* Strip off any "const" etc. */ diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c index 9f566bd1e24f..5986914dfd91 100644 --- a/tools/start-stop-daemon.c +++ b/tools/start-stop-daemon.c @@ -66,6 +66,15 @@ #include #endif +<<<<<<< HEAD +======= +/* this is in zebra.h, but including that here isn't a good fit... */ +#ifndef HAVE_STRLCPY +size_t strlcpy(char *__restrict dest, + const char *__restrict src, size_t destsize); +#endif + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static int testmode = 0; static int quietmode = 0; static int exitnodo = 1; @@ -749,8 +758,12 @@ static void do_stop(int signal_nr, int quietmode, int *n_killed, static void set_what_stop(const char *str) { +<<<<<<< HEAD strncpy(what_stop, str, sizeof(what_stop)); what_stop[sizeof(what_stop) - 1] = '\0'; +======= + strlcpy(what_stop, str, sizeof(what_stop)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static int run_stop_schedule(void) diff --git a/tools/subdir.am b/tools/subdir.am index f2ed2332b8bd..58448a0bc6d1 100644 --- a/tools/subdir.am +++ b/tools/subdir.am @@ -39,7 +39,11 @@ tools_gen_northbound_callbacks_LDADD = lib/libfrr.la $(LIBYANG_LIBS) tools_gen_yang_deviations_SOURCES = tools/gen_yang_deviations.c tools_gen_yang_deviations_LDADD = lib/libfrr.la $(LIBYANG_LIBS) +<<<<<<< HEAD tools_ssd_SOURCES = tools/start-stop-daemon.c +======= +tools_ssd_SOURCES = tools/start-stop-daemon.c lib/strlcpy.c +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) tools_ssd_CPPFLAGS = # don't bother autoconf'ing these for a simple optional tool diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 92f37f193a96..7d7ddff9fd90 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -281,9 +281,12 @@ static int vtysh_client_run(struct vtysh_client *vclient, const char *line, nread = vtysh_client_receive( vclient, bufvalid, buf + bufsz - bufvalid - 1, pass_fd); +<<<<<<< HEAD if (nread < 0 && (errno == EINTR || errno == EAGAIN)) continue; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (nread <= 0) { if (vty->of) vty_out(vty, @@ -699,7 +702,11 @@ static char *trim(char *s) int vtysh_mark_file(const char *filename) { struct vty *vty; +<<<<<<< HEAD FILE *confp = NULL; +======= + FILE *confp = NULL, *closefp = NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int ret; vector vline; int tried = 0; @@ -712,7 +719,11 @@ int vtysh_mark_file(const char *filename) if (strncmp("-", filename, 1) == 0) confp = stdin; else +<<<<<<< HEAD confp = fopen(filename, "r"); +======= + confp = closefp = fopen(filename, "r"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (confp == NULL) { fprintf(stderr, "%% Can't open config file %s due to '%s'.\n", @@ -852,9 +863,14 @@ int vtysh_mark_file(const char *filename) vty_close(vty); XFREE(MTYPE_VTYSH_CMD, vty_buf_copy); +<<<<<<< HEAD if (confp != stdin) fclose(confp); +======= + if (closefp) + fclose(closefp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 64198132cc64..f5d90d77576e 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -350,6 +350,10 @@ int main(int argc, char **argv, char **env) char pathspace[MAXPATHLEN] = ""; const char *histfile = NULL; const char *histfile_env = getenv("VTYSH_HISTFILE"); +<<<<<<< HEAD +======= + const char *logpath = getenv("VTYSH_LOG"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* SUID: drop down to calling user & go back up when needed */ elevuid = geteuid(); @@ -643,9 +647,13 @@ int main(int argc, char **argv, char **env) } } +<<<<<<< HEAD if (getenv("VTYSH_LOG")) { const char *logpath = getenv("VTYSH_LOG"); +======= + if (logpath != NULL) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) logfile = fopen(logpath, "a"); if (!logfile) { fprintf(stderr, "Failed to open logfile (%s): %s\n", diff --git a/yang/frr-bfdd.yang b/yang/frr-bfdd.yang index 02ed9214599f..4da300ef3159 100644 --- a/yang/frr-bfdd.yang +++ b/yang/frr-bfdd.yang @@ -65,7 +65,11 @@ module frr-bfdd { typedef multiplier { description "Detection multiplier"; type uint8 { +<<<<<<< HEAD range "2..255"; +======= + range "1..255"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -169,7 +173,11 @@ module frr-bfdd { leaf desired-transmission-interval { type uint32 { +<<<<<<< HEAD range "10000..60000000"; +======= + range "10000..max"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } units microseconds; default 300000; @@ -178,7 +186,11 @@ module frr-bfdd { leaf required-receive-interval { type uint32 { +<<<<<<< HEAD range "10000..60000000"; +======= + range "10000..max"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } units microseconds; default 300000; @@ -210,7 +222,11 @@ module frr-bfdd { leaf desired-echo-transmission-interval { type uint32 { +<<<<<<< HEAD range "10000..60000000"; +======= + range "10000..max"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } units microseconds; default 50000; @@ -219,7 +235,11 @@ module frr-bfdd { leaf required-echo-receive-interval { type uint32 { +<<<<<<< HEAD range "0 | 10000..60000000"; +======= + range "0 | 10000..max"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } units microseconds; default 50000; diff --git a/yang/frr-bgp-route-map.yang b/yang/frr-bgp-route-map.yang index 44058ab04ece..d3181dba742f 100644 --- a/yang/frr-bgp-route-map.yang +++ b/yang/frr-bgp-route-map.yang @@ -94,6 +94,15 @@ module frr-bgp-route-map { "Match peer address"; } +<<<<<<< HEAD +======= + identity src-peer { + base frr-route-map:rmap-match-type; + description + "Match source peer address"; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) identity mac-address-list { base frr-route-map:rmap-match-type; description @@ -526,7 +535,11 @@ identity set-extcommunity-color { typedef color-list { type string { +<<<<<<< HEAD pattern '((429496729[0-5]|42949672[0-8][0-9]|' +======= + pattern '((00|01|10|11):(429496729[0-5]|42949672[0-8][0-9]|' +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) + '4294967[0-1][0-9]{2}|429496[0-6][0-9]{3}|' + '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + '429[0-3][0-9]{6}|42[0-8][0-9]{7}|' @@ -534,10 +547,18 @@ identity set-extcommunity-color { + '[1-9][0-9]{0,8})(\s*))+'; } description +<<<<<<< HEAD "The color-list type represent a set of colors of value (1..4294967295) values are separated by white spaces"; reference "RFC 9012 - The BGP Tunnel Encapsulation Attribute"; +======= + "The color-list type represent a set of colors of value (examples 00:200 01:200 10:200) + values are separated by white spaces"; + reference + "RFC 9012 - The BGP Tunnel Encapsulation Attribute. + RFC 9256 - Segment Routing Policy Architecture."; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:rmap-match-condition/frr-route-map:match-condition" { @@ -688,6 +709,40 @@ identity set-extcommunity-color { } } +<<<<<<< HEAD +======= + case src-peer { + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:src-peer')"; + choice peer { + description + "Value of the peer"; + case src-peer-ipv4-address { + description + "IP address of peer"; + leaf src-peer-ipv4-address { + type inet:ipv4-address; + } + } + + case src-peer-interface { + description + "Interface name of peer"; + leaf src-peer-interface { + type string; + } + } + + case src-peer-ipv6-address { + description + "IPv6 address of peer"; + leaf src-peer-ipv6-address { + type inet:ipv6-address; + } + } + } + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) case access-list-name { when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:mac-address-list') or " + "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:as-path-list') or " diff --git a/yang/frr-pim-rp.yang b/yang/frr-pim-rp.yang index dbd5513ee57b..08ebd49ad37a 100644 --- a/yang/frr-pim-rp.yang +++ b/yang/frr-pim-rp.yang @@ -21,6 +21,13 @@ module frr-pim-rp { prefix frr-route-types; } +<<<<<<< HEAD +======= + import frr-interface { + prefix "frr-interface"; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) organization "FRRouting"; @@ -64,6 +71,17 @@ module frr-pim-rp { "RFC XXXX: A YANG Data Model for PIM RP"; } +<<<<<<< HEAD +======= + revision 2024-09-26 { + description + "Add support for embedded RP."; + reference + "RFC 3956: Embedding the Rendezvous Point (RP) Address in an IPv6 + Multicast Address"; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) typedef plist-ref { type string; } @@ -111,6 +129,45 @@ module frr-pim-rp { } // static-rp } // static-rp-container +<<<<<<< HEAD +======= + grouping embedded-rp-group { + container embedded-rp { + description "Embedded RP configurations."; + + leaf enable { + description + "Toggle embedded RP state: + + When enabled the learned RP from the multicast group address + will be preferred over any static or dynamic RP configuration. + + When disabled the packet will be processed as usual."; + type boolean; + default "false"; + } + + leaf group-list { + description + "Restrict embedded RP prefix ranges. + + The default is to treat all multicast groups in FF70::/12 + range as embedded RP. When a group prefix list is configured + and group does not match one of its permit entries it will + be treated as regular multicast group."; + type plist-ref; + } + + leaf maximum-rps { + description + "Maximum allowed number of RPs to learn."; + type uint32; + default 25; + } + } // embedded-rp container + } // embedded-rp group + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) grouping auto-rp-container { description "Grouping of AutoRP container."; @@ -134,7 +191,11 @@ module frr-pim-rp { leaf announce-interval { type uint16; description +<<<<<<< HEAD "The time between sending C-RP announcement packets."; +======= + "The time between sending C-RP announcement packets (seconds)."; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } leaf announce-holdtime { @@ -172,6 +233,60 @@ module frr-pim-rp { } } } // candidate-rp-list +<<<<<<< HEAD +======= + + container mapping-agent { + leaf send-rp-discovery { + type boolean; + default false; + description + "Make this router an AutoRP mapping agent"; + } + + leaf discovery-scope { + type uint8; + default 31; + description + "The TTL of the discovery packet"; + } + + leaf discovery-interval { + type uint16 { + range "1 .. 65535"; + } + default 60; + description + "The time between sending discovery advertisements (seconds)"; + } + + leaf discovery-holdtime { + type uint16 { + range "0 .. 65535"; + } + default 180; + description + "The hold time in seconds advertised in the discovery packet."; + } + + choice source-address-or-interface { + description "Source address to use for mapping agent operation"; + default if-loopback; + leaf address { + type inet:ip-address; + } + leaf interface { + type frr-interface:interface-ref; + } + leaf if-loopback { + type empty; + } + leaf if-any { + type empty; + } + } + } // mapping-agent +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } // auto-rp } // auto-rp-container @@ -194,6 +309,16 @@ module frr-pim-rp { "Only applicable to IPv4 address family."; } } +<<<<<<< HEAD +======= + + uses embedded-rp-group { + when "../frr-pim:address-family = 'frr-rt:ipv6'" { + description + "Only available for IPv6 addresses."; + } + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } // rp } // augment } diff --git a/yang/frr-pim.yang b/yang/frr-pim.yang index 6a6c52185ddb..833f9492361c 100644 --- a/yang/frr-pim.yang +++ b/yang/frr-pim.yang @@ -78,6 +78,13 @@ module frr-pim { type string; } +<<<<<<< HEAD +======= + typedef access-list-ref { + type string; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Groupings */ @@ -250,6 +257,30 @@ module frr-pim { container msdp { description "Global MSDP configuration."; uses msdp-timers; +<<<<<<< HEAD +======= + + leaf log-neighbor-events { + type boolean; + default false; + description + "Log all MSDP neighbor related events."; + } + + leaf log-sa-events { + type boolean; + default false; + description + "Log all MSDP SA related events."; + } + + leaf shutdown { + type boolean; + default false; + description + "Shutdown MSDP functionality."; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } list msdp-mesh-groups { @@ -486,7 +517,17 @@ module frr-pim { leaf multicast-boundary-oil { type plist-ref; description +<<<<<<< HEAD "Prefix-List to define multicast boundary"; +======= + "Prefix-List to define multicast boundary by group"; + } + + leaf multicast-boundary-acl { + type access-list-ref; + description + "Access-list to define multicast boundary by source and group"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } list mroute { diff --git a/yang/frr-route-map.yang b/yang/frr-route-map.yang index c875a6ec7f05..ab41cb6d0cd5 100644 --- a/yang/frr-route-map.yang +++ b/yang/frr-route-map.yang @@ -355,6 +355,25 @@ module frr-route-map { "Subtract round trip time to metric"; } } +<<<<<<< HEAD +======= + + case use-igp { + leaf use-igp { + type boolean; + description + "Use metric from IGP procotol"; + } + } + + case use-aigp { + leaf use-aigp { + type boolean; + description + "Use metric from AIGP (Accumulated IGP)"; + } + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } diff --git a/zebra/connected.c b/zebra/connected.c index ce26c14c0525..d4050df9830d 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -191,6 +191,12 @@ static void connected_remove_kernel_for_connected(afi_t afi, safi_t safi, struct rib_dest_t *dest; struct route_table *table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf->vrf->vrf_id); +<<<<<<< HEAD +======= + if (!table) + return; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) rn = route_node_match(table, p); if (!rn) return; diff --git a/zebra/debug.c b/zebra/debug.c index cf1701be1938..2be6011c91d7 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -29,6 +29,10 @@ unsigned long zebra_debug_evpn_mh; unsigned long zebra_debug_pbr; unsigned long zebra_debug_neigh; unsigned long zebra_debug_tc; +<<<<<<< HEAD +======= +unsigned long zebra_debug_srv6; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFINE_HOOK(zebra_debug_show_debugging, (struct vty *vty), (vty)); @@ -121,6 +125,12 @@ DEFUN_NOSH (show_debugging_zebra, if (IS_ZEBRA_DEBUG_PBR) vty_out(vty, " Zebra PBR debugging is on\n"); +<<<<<<< HEAD +======= + if (IS_ZEBRA_DEBUG_SRV6) + vty_out(vty, " Zebra SRv6 is on\n"); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) hook_call(zebra_debug_show_debugging, vty); cmd_show_lib_debugs(vty); @@ -372,6 +382,24 @@ DEFUN (debug_zebra_tc, return CMD_SUCCESS; } +<<<<<<< HEAD +======= +DEFPY(debug_zebra_srv6, + debug_zebra_srv6_cmd, + "[no$no] debug zebra srv6", + NO_STR + DEBUG_STR + "Zebra configuration\n" + "Debug zebra SRv6 events\n") +{ + if (no) + UNSET_FLAG(zebra_debug_srv6, ZEBRA_DEBUG_SRV6); + else + SET_FLAG(zebra_debug_srv6, ZEBRA_DEBUG_SRV6); + return CMD_SUCCESS; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFPY (debug_zebra_mlag, debug_zebra_mlag_cmd, "[no$no] debug zebra mlag", @@ -754,6 +782,14 @@ static int config_write_debug(struct vty *vty) write++; } +<<<<<<< HEAD +======= + if (IS_ZEBRA_DEBUG_SRV6) { + vty_out(vty, "debug zebra srv6\n"); + write++; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return write; } @@ -793,6 +829,10 @@ void zebra_debug_init(void) install_element(ENABLE_NODE, &debug_zebra_rib_cmd); install_element(ENABLE_NODE, &debug_zebra_fpm_cmd); install_element(ENABLE_NODE, &debug_zebra_dplane_cmd); +<<<<<<< HEAD +======= + install_element(ENABLE_NODE, &debug_zebra_srv6_cmd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(ENABLE_NODE, &debug_zebra_mlag_cmd); install_element(ENABLE_NODE, &debug_zebra_nexthop_cmd); install_element(ENABLE_NODE, &debug_zebra_pbr_cmd); @@ -845,6 +885,10 @@ void zebra_debug_init(void) install_element(CONFIG_NODE, &no_debug_zebra_fpm_cmd); install_element(CONFIG_NODE, &no_debug_zebra_dplane_cmd); install_element(CONFIG_NODE, &no_debug_zebra_pbr_cmd); +<<<<<<< HEAD +======= + install_element(CONFIG_NODE, &debug_zebra_srv6_cmd); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) install_element(CONFIG_NODE, &debug_zebra_mlag_cmd); install_element(CONFIG_NODE, &debug_zebra_evpn_mh_cmd); diff --git a/zebra/debug.h b/zebra/debug.h index 075d903c6b0e..404b04c5f391 100644 --- a/zebra/debug.h +++ b/zebra/debug.h @@ -62,6 +62,11 @@ extern "C" { #define ZEBRA_DEBUG_TC 0x01 +<<<<<<< HEAD +======= +#define ZEBRA_DEBUG_SRV6 0x01 + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Debug related macro. */ #define IS_ZEBRA_DEBUG_EVENT (zebra_debug_event & ZEBRA_DEBUG_EVENT) @@ -122,6 +127,11 @@ extern "C" { #define IS_ZEBRA_DEBUG_TC (zebra_debug_tc & ZEBRA_DEBUG_TC) +<<<<<<< HEAD +======= +#define IS_ZEBRA_DEBUG_SRV6 (zebra_debug_srv6 & ZEBRA_DEBUG_SRV6) + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern unsigned long zebra_debug_event; extern unsigned long zebra_debug_packet; extern unsigned long zebra_debug_kernel; @@ -139,6 +149,10 @@ extern unsigned long zebra_debug_evpn_mh; extern unsigned long zebra_debug_pbr; extern unsigned long zebra_debug_neigh; extern unsigned long zebra_debug_tc; +<<<<<<< HEAD +======= +extern unsigned long zebra_debug_srv6; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern void zebra_debug_init(void); diff --git a/zebra/dpdk/zebra_dplane_dpdk.c b/zebra/dpdk/zebra_dplane_dpdk.c index 411155167f64..894e9e7f6ce5 100644 --- a/zebra/dpdk/zebra_dplane_dpdk.c +++ b/zebra/dpdk/zebra_dplane_dpdk.c @@ -400,6 +400,10 @@ static void zd_dpdk_rule_update(struct zebra_dplane_ctx *ctx) case DPLANE_OP_INTF_INSTALL: case DPLANE_OP_INTF_UPDATE: case DPLANE_OP_INTF_DELETE: +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) break; } } @@ -459,6 +463,10 @@ static void zd_dpdk_process_update(struct zebra_dplane_ctx *ctx) case DPLANE_OP_INTF_INSTALL: case DPLANE_OP_INTF_UPDATE: case DPLANE_OP_INTF_DELETE: +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) atomic_fetch_add_explicit(&dpdk_stat->ignored_updates, 1, memory_order_relaxed); diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index c12a569ff52c..44d36191866d 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -68,6 +68,11 @@ static const char *prov_name = "dplane_fpm_nl"; +<<<<<<< HEAD +======= +static atomic_bool fpm_cleaning_up; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct fpm_nl_ctx { /* data plane connection. */ int socket; @@ -524,6 +529,19 @@ static void fpm_connect(struct event *t); static void fpm_reconnect(struct fpm_nl_ctx *fnc) { +<<<<<<< HEAD +======= + bool cleaning_p = false; + + /* This is being called in the FPM pthread: ensure we don't deadlock + * with similar code that may be run in the main pthread. + */ + if (!atomic_compare_exchange_strong_explicit( + &fpm_cleaning_up, &cleaning_p, true, memory_order_seq_cst, + memory_order_seq_cst)) + return; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Cancel all zebra threads first. */ event_cancel_async(zrouter.master, &fnc->t_lspreset, NULL); event_cancel_async(zrouter.master, &fnc->t_lspwalk, NULL); @@ -551,6 +569,15 @@ static void fpm_reconnect(struct fpm_nl_ctx *fnc) EVENT_OFF(fnc->t_read); EVENT_OFF(fnc->t_write); +<<<<<<< HEAD +======= + /* Reset the barrier value */ + cleaning_p = true; + atomic_compare_exchange_strong_explicit( + &fpm_cleaning_up, &cleaning_p, false, memory_order_seq_cst, + memory_order_seq_cst); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* FPM is disabled, don't attempt to connect. */ if (fnc->disabled) return; @@ -1058,6 +1085,10 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx) case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET: case DPLANE_OP_NONE: case DPLANE_OP_STARTUP_STAGE: +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) break; } @@ -1512,8 +1543,17 @@ static void fpm_process_queue(struct event *t) /* Re-schedule if we ran out of buffer space */ if (no_bufs) { +<<<<<<< HEAD event_add_event(fnc->fthread->master, fpm_process_queue, fnc, 0, &fnc->t_dequeue); +======= + if (processed_contexts) + event_add_event(fnc->fthread->master, fpm_process_queue, fnc, 0, + &fnc->t_dequeue); + else + event_add_timer_msec(fnc->fthread->master, fpm_process_queue, fnc, 10, + &fnc->t_dequeue); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) event_add_timer(fnc->fthread->master, fpm_process_wedged, fnc, DPLANE_FPM_NL_WEDGIE_TIME, &fnc->t_wedged); } else @@ -1525,7 +1565,11 @@ static void fpm_process_queue(struct event *t) * until the dataplane thread gets scheduled for new, * unrelated work. */ +<<<<<<< HEAD if (dplane_provider_out_ctx_queue_len(fnc->prov) > 0) +======= + if (processed_contexts) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) dplane_provider_work_ready(); } @@ -1619,6 +1663,19 @@ static int fpm_nl_start(struct zebra_dplane_provider *prov) static int fpm_nl_finish_early(struct fpm_nl_ctx *fnc) { +<<<<<<< HEAD +======= + bool cleaning_p = false; + + /* This is being called in the main pthread: ensure we don't deadlock + * with similar code that may be run in the FPM pthread. + */ + if (!atomic_compare_exchange_strong_explicit( + &fpm_cleaning_up, &cleaning_p, true, memory_order_seq_cst, + memory_order_seq_cst)) + return 0; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Disable all events and close socket. */ EVENT_OFF(fnc->t_lspreset); EVENT_OFF(fnc->t_lspwalk); @@ -1639,6 +1696,15 @@ static int fpm_nl_finish_early(struct fpm_nl_ctx *fnc) fnc->socket = -1; } +<<<<<<< HEAD +======= + /* Reset the barrier value */ + cleaning_p = true; + atomic_compare_exchange_strong_explicit( + &fpm_cleaning_up, &cleaning_p, false, memory_order_seq_cst, + memory_order_seq_cst); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 8beae125d2da..0ccab2b4f4ee 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -1568,6 +1568,18 @@ static int netlink_request_tunneldump(struct zebra_ns *zns, int family, return netlink_request(&zns->netlink_cmd, &req); } +<<<<<<< HEAD +======= +/* Prototype for tunneldump walker */ +static int tunneldump_walk_cb(struct interface *ifp, void *arg); + +struct tunneldump_ctx { + struct zebra_ns *zns; + struct zebra_dplane_info *dp_info; + int ret; +}; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Currently we only ask for vxlan l3svd vni information. * In the future this can be expanded. @@ -1575,6 +1587,7 @@ static int netlink_request_tunneldump(struct zebra_ns *zns, int family, int netlink_tunneldump_read(struct zebra_ns *zns) { int ret = 0; +<<<<<<< HEAD struct zebra_dplane_info dp_info; struct route_node *rn; struct interface *tmp_if = NULL; @@ -1672,6 +1685,64 @@ static void vlan_id_range_state_change(struct interface *ifp, uint16_t id_start, for (uint16_t i = id_start; i <= id_end; i++) vxlan_vni_state_change(zif, i, state); +======= + struct tunneldump_ctx ctx = {}; + struct zebra_dplane_info dp_info; + + zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); + + /* Set up context and call iterator */ + ctx.zns = zns; + ctx.dp_info = &dp_info; + + zebra_ns_ifp_walk(zns, tunneldump_walk_cb, &ctx); + + ret = ctx.ret; + + return ret; +} + +static int tunneldump_walk_cb(struct interface *ifp, void *arg) +{ + int ret; + struct tunneldump_ctx *ctx = arg; + struct zebra_if *zif; + + zif = ifp->info; + if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) + goto done; + + ret = netlink_request_tunneldump(ctx->zns, PF_BRIDGE, ifp->ifindex); + if (ret < 0) { + ctx->ret = ret; + return NS_WALK_STOP; + } + + ret = netlink_parse_info(netlink_link_change, &(ctx->zns->netlink_cmd), + ctx->dp_info, 0, true); + + if (ret < 0) { + ctx->ret = ret; + return NS_WALK_STOP; + } + +done: + return NS_WALK_CONTINUE; +} + +static uint8_t netlink_get_dplane_vlan_state(uint8_t state) +{ + if (state == BR_STATE_LISTENING) + return ZEBRA_DPLANE_BR_STATE_LISTENING; + else if (state == BR_STATE_LEARNING) + return ZEBRA_DPLANE_BR_STATE_LEARNING; + else if (state == BR_STATE_FORWARDING) + return ZEBRA_DPLANE_BR_STATE_FORWARDING; + else if (state == BR_STATE_BLOCKING) + return ZEBRA_DPLANE_BR_STATE_BLOCKING; + + return ZEBRA_DPLANE_BR_STATE_DISABLED; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /** @@ -1686,7 +1757,10 @@ static void vlan_id_range_state_change(struct interface *ifp, uint16_t id_start, int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) { int len, rem; +<<<<<<< HEAD struct interface *ifp; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct br_vlan_msg *bvm; struct bridge_vlan_info *vinfo; struct rtattr *vtb[BRIDGE_VLANDB_ENTRY_MAX + 1] = {}; @@ -1694,6 +1768,12 @@ int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) uint8_t state; uint32_t vrange; int type; +<<<<<<< HEAD +======= + uint32_t count = 0; + struct zebra_dplane_ctx *ctx = NULL; + struct zebra_vxlan_vlan_array *vlan_array = NULL; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* We only care about state changes for now */ if (!(h->nlmsg_type == RTM_NEWVLAN)) @@ -1713,6 +1793,7 @@ int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (bvm->family != AF_BRIDGE) return 0; +<<<<<<< HEAD ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), bvm->ifindex); if (!ifp) { zlog_debug("Cannot find bridge-vlan IF (%u) for vlan update", @@ -1732,6 +1813,12 @@ int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) zlog_debug("%s %s IF %s NS %u", nl_msg_type_to_str(h->nlmsg_type), nl_family_to_str(bvm->family), ifp->name, ns_id); +======= + ctx = dplane_ctx_alloc(); + dplane_ctx_set_ns_id(ctx, ns_id); + dplane_ctx_set_op(ctx, DPLANE_OP_VLAN_INSTALL); + dplane_ctx_set_vlan_ifindex(ctx, bvm->ifindex); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Loop over "ALL" BRIDGE_VLANDB_ENTRY */ rem = len; @@ -1762,12 +1849,25 @@ int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (!vtb[BRIDGE_VLANDB_ENTRY_STATE]) continue; +<<<<<<< HEAD +======= + count++; + vlan_array = + XREALLOC(MTYPE_VLAN_CHANGE_ARR, vlan_array, + sizeof(struct zebra_vxlan_vlan_array) + + count * sizeof(struct zebra_vxlan_vlan)); + + memset(&vlan_array->vlans[count - 1], 0, + sizeof(struct zebra_vxlan_vlan)); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) state = *(uint8_t *)RTA_DATA(vtb[BRIDGE_VLANDB_ENTRY_STATE]); if (vtb[BRIDGE_VLANDB_ENTRY_RANGE]) vrange = *(uint32_t *)RTA_DATA( vtb[BRIDGE_VLANDB_ENTRY_RANGE]); +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN) { if (vrange) zlog_debug("VLANDB_ENTRY: VID (%u-%u) state=%s", @@ -1782,6 +1882,26 @@ int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) ifp, vinfo->vid, (vrange ? vrange : vinfo->vid), state); } +======= + vlan_array->vlans[count - 1].state = + netlink_get_dplane_vlan_state(state); + vlan_array->vlans[count - 1].vid = vinfo->vid; + vlan_array->vlans[count - 1].vrange = vrange; + } + + if (count) { + vlan_array->count = count; + dplane_ctx_set_vxlan_vlan_array(ctx, vlan_array); + if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("RTM_NEWVLAN for ifindex %u NS %u, enqueuing for zebra main", + bvm->ifindex, ns_id); + + dplane_provider_enqueue_to_zebra(ctx); + } else + dplane_ctx_fini(&ctx); + + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } diff --git a/zebra/interface.c b/zebra/interface.c index d146004781a5..21f3c2798870 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -43,10 +43,31 @@ DEFINE_MTYPE_STATIC(ZEBRA, ZINFO, "Zebra Interface Information"); DEFINE_HOOK(zebra_if_extra_info, (struct vty * vty, struct interface *ifp), (vty, ifp)); +<<<<<<< HEAD DEFINE_MTYPE(ZEBRA, ZIF_DESC, "Intf desc"); static void if_down_del_nbr_connected(struct interface *ifp); +======= +DEFINE_MTYPE_STATIC(ZEBRA, ZIF_DESC, "Intf desc"); + +static void if_down_del_nbr_connected(struct interface *ifp); + +static const char *if_zebra_data_state(uint8_t state) +{ + switch (state) { + case IF_ZEBRA_DATA_UNSPEC: + return "Not specified by CLI"; + case IF_ZEBRA_DATA_ON: + return "Enabled by CLI"; + case IF_ZEBRA_DATA_OFF: + return "Disabled by CLI"; + } + + return "STATE IS WRONG DEV ESCAPE"; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static void if_zebra_speed_update(struct event *thread) { struct interface *ifp = EVENT_ARG(thread); @@ -215,6 +236,11 @@ static int if_zebra_delete_hook(struct interface *ifp) if_nhg_dependents_release(ifp); nhg_connected_tree_free(&zebra_if->nhg_dependents); +<<<<<<< HEAD +======= + zebra_ns_unlink_ifp(ifp); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) XFREE(MTYPE_ZIF_DESC, zebra_if->desc); EVENT_OFF(zebra_if->speed_update); @@ -225,6 +251,7 @@ static int if_zebra_delete_hook(struct interface *ifp) return 0; } +<<<<<<< HEAD /* Build the table key */ static void if_build_key(uint32_t ifindex, struct prefix *p) { @@ -267,10 +294,13 @@ void if_unlink_per_ns(struct interface *ifp) ifp->node = NULL; } +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Look up an interface by identifier within a NS */ struct interface *if_lookup_by_index_per_ns(struct zebra_ns *ns, uint32_t ifindex) { +<<<<<<< HEAD struct prefix p; struct route_node *rn; struct interface *ifp = NULL; @@ -281,6 +311,12 @@ struct interface *if_lookup_by_index_per_ns(struct zebra_ns *ns, ifp = (struct interface *)rn->info; route_unlock_node(rn); /* lookup */ } +======= + struct interface *ifp = NULL; + + ifp = zebra_ns_lookup_ifp(ns, ifindex); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return ifp; } @@ -288,6 +324,7 @@ struct interface *if_lookup_by_index_per_ns(struct zebra_ns *ns, struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns, const char *ifname) { +<<<<<<< HEAD struct route_node *rn; struct interface *ifp; @@ -300,6 +337,13 @@ struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns, } return NULL; +======= + struct interface *ifp; + + ifp = zebra_ns_lookup_ifp_name(ns, ifname); + + return ifp; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } struct interface *if_lookup_by_index_per_nsid(ns_id_t ns_id, uint32_t ifindex) @@ -419,6 +463,10 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc) return 0; } +<<<<<<< HEAD +======= +#ifndef HAVE_NETLINK +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* if_flags_mangle: A place for hacks that require mangling * or tweaking the interface flags. * @@ -470,6 +518,10 @@ void if_flags_update(struct interface *ifp, uint64_t newflags) if_up(ifp, true); } } +<<<<<<< HEAD +======= +#endif +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Wake up configured address if it is not in current kernel address. */ @@ -571,7 +623,12 @@ void if_add_update(struct interface *ifp) zns = zvrf->zns; else zns = zebra_ns_lookup(NS_DEFAULT); +<<<<<<< HEAD if_link_per_ns(zns, ifp); +======= + + zebra_ns_link_ifp(zns, ifp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if_data = ifp->info; assert(if_data); @@ -776,7 +833,11 @@ void if_delete_update(struct interface **pifp) /* Send out notification on interface delete. */ zebra_interface_delete_update(ifp); +<<<<<<< HEAD if_unlink_per_ns(ifp); +======= + zebra_ns_unlink_ifp(ifp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Update ifindex after distributing the delete message. This is in case any client needs to have the old value of ifindex available @@ -784,7 +845,10 @@ void if_delete_update(struct interface **pifp) for setting ifindex to IFINDEX_INTERNAL after processing the interface deletion message. */ if_set_index(ifp, IFINDEX_INTERNAL); +<<<<<<< HEAD ifp->node = NULL; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); @@ -1082,11 +1146,52 @@ void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex, } /* +<<<<<<< HEAD +======= + * Callback for per-ns link fixup iteration + */ +static int zif_link_fixup_cb(struct interface *ifp, void *arg) +{ + struct zebra_if *zif; + + zif = ifp->info; + /* update bond-member to bond linkages */ + if ((IS_ZEBRA_IF_BOND_SLAVE(ifp)) && + (zif->bondslave_info.bond_ifindex != IFINDEX_INTERNAL) && + !zif->bondslave_info.bond_if) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("bond mbr %s map to bond %d", zif->ifp->name, + zif->bondslave_info.bond_ifindex); + zebra_l2_map_slave_to_bond(zif, ifp->vrf->vrf_id); + } + + /* update SVI linkages */ + if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) { + zif->link = if_lookup_by_index_per_nsid(zif->link_nsid, + zif->link_ifindex); + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("interface %s/%d's lower fixup to %s/%d", + ifp->name, ifp->ifindex, + zif->link ? zif->link->name : "unk", + zif->link_ifindex); + } + + /* Update VLAN<=>SVI map */ + if (IS_ZEBRA_IF_VLAN(ifp)) + zebra_evpn_acc_bd_svi_set(zif, NULL, + !!if_is_operative(ifp)); + + return NS_WALK_CONTINUE; +} + +/* +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * during initial link dump kernel does not order lower devices before * upper devices so we need to fixup link dependencies at the end of dump */ void zebra_if_update_all_links(struct zebra_ns *zns) { +<<<<<<< HEAD struct route_node *rn; struct interface *ifp; struct zebra_if *zif; @@ -1126,6 +1231,12 @@ void zebra_if_update_all_links(struct zebra_ns *zns) zebra_evpn_acc_bd_svi_set(zif, NULL, !!if_is_operative(ifp)); } +======= + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("fixup link dependencies"); + + zebra_ns_ifp_walk(zns, zif_link_fixup_cb, NULL); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static bool if_ignore_set_protodown(const struct interface *ifp, bool new_down, @@ -1999,10 +2110,16 @@ static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx) !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { /* Add interface notification from kernel */ if (IS_ZEBRA_DEBUG_KERNEL) +<<<<<<< HEAD zlog_debug( "RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d sl_type %d master %u", name, ifindex, vrf_id, zif_type, zif_slave_type, master_ifindex); +======= + zlog_debug("RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d sl_type %d master %u flags 0x%llx", + name, ifindex, vrf_id, zif_type, zif_slave_type, + master_ifindex, (unsigned long long)flags); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (ifp == NULL) { /* unknown interface */ @@ -2087,10 +2204,16 @@ static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx) /* Interface update. */ if (IS_ZEBRA_DEBUG_KERNEL) +<<<<<<< HEAD zlog_debug( "RTM_NEWLINK update for %s(%u) sl_type %d master %u", name, ifp->ifindex, zif_slave_type, master_ifindex); +======= + zlog_debug("RTM_NEWLINK update for %s(%u) sl_type %d master %u flags 0x%llx", + name, ifp->ifindex, zif_slave_type, master_ifindex, + (unsigned long long)flags); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) set_ifindex(ifp, ifindex, zns); ifp->mtu6 = ifp->mtu = mtu; @@ -2680,8 +2803,13 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) vty_out(vty, "mtu6 %d ", ifp->mtu6); vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags)); +<<<<<<< HEAD if (zebra_if->mpls) vty_out(vty, " MPLS enabled\n"); +======= + vty_out(vty, " MPLS %s %s\n", zebra_if->mpls ? "enabled" : "", + if_zebra_data_state(zebra_if->multicast)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (zebra_if->linkdown) vty_out(vty, " Ignore all v4 routes with linkdown\n"); @@ -2693,6 +2821,13 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) if (zebra_if->v6mcast_on) vty_out(vty, " v6 Multicast forwarding is on\n"); +<<<<<<< HEAD +======= + vty_out(vty, " Multicast config is %s\n", if_zebra_data_state(zebra_if->multicast)); + + vty_out(vty, " Shutdown config is %s\n", if_zebra_data_state(zebra_if->shutdown)); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Hardware address. */ vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type)); if (ifp->hw_addr_len != 0) { @@ -3041,10 +3176,21 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, json_object_boolean_add(json_if, "mplsEnabled", zebra_if->mpls); json_object_boolean_add(json_if, "linkDown", zebra_if->linkdown); json_object_boolean_add(json_if, "linkDownV6", zebra_if->linkdownv6); +<<<<<<< HEAD json_object_boolean_add(json_if, "mcForwardingV4", zebra_if->v4mcast_on); json_object_boolean_add(json_if, "mcForwardingV6", zebra_if->v6mcast_on); +======= + json_object_boolean_add(json_if, "mcForwardingV4", zebra_if->v4mcast_on); + json_object_boolean_add(json_if, "mcForwardingV6", zebra_if->v6mcast_on); + + json_object_string_add(json_if, "multicastConfig", if_zebra_data_state(zebra_if->multicast)); + + json_object_string_add(json_if, "shutdownConfig", if_zebra_data_state(zebra_if->shutdown)); + + json_object_string_add(json_if, "mplsConfig", if_zebra_data_state(zebra_if->mpls_config)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (ifp->ifindex == IFINDEX_INTERNAL) { json_object_boolean_add(json_if, "pseudoInterface", true); diff --git a/zebra/interface.h b/zebra/interface.h index 8d19c1838fbf..7292ac8c77b9 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -94,9 +94,12 @@ enum zebra_if_flags { #define ZEBRA_IF_IS_PROTODOWN_ONLY_EXTERNAL(zif) \ ((zif)->protodown_rc == ZEBRA_PROTODOWN_EXTERNAL) +<<<<<<< HEAD /* Mem type for zif desc */ DECLARE_MTYPE(ZIF_DESC); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* `zebra' daemon local interface structure. */ struct zebra_if { /* back pointer to the interface */ @@ -215,6 +218,12 @@ struct zebra_if { char neigh_mac[6]; struct in6_addr v6_2_v4_ll_addr6; +<<<<<<< HEAD +======= + /* Linkage for per-vrf/per-NS ifp container */ + struct ifp_tree_link *ns_tree_link; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* The description of the interface */ char *desc; }; @@ -262,12 +271,18 @@ extern void zebra_if_init(void); extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t); extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *, const char *); +<<<<<<< HEAD extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern struct interface *if_lookup_by_index_per_nsid(ns_id_t nsid, uint32_t ifindex); extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int); +<<<<<<< HEAD extern void if_unlink_per_ns(struct interface *); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *fip, char mac[6], struct in6_addr *address, diff --git a/zebra/ioctl.c b/zebra/ioctl.c index a35784cd36e4..b55d04f14663 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -390,6 +390,10 @@ int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx) #endif /* HAVE_STRUCT_IFALIASREQ */ #endif /* HAVE_NETLINK */ +<<<<<<< HEAD +======= +#ifndef HAVE_NETLINK +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* get interface flags */ void if_get_flags(struct interface *ifp) { @@ -485,6 +489,10 @@ void if_get_flags(struct interface *ifp) out: if_flags_update(ifp, (ifreqflags.ifr_flags & 0x0000ffff)); } +<<<<<<< HEAD +======= +#endif +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Set interface flags */ int if_set_flags(struct interface *ifp, uint64_t flags) diff --git a/zebra/ipforward_proc.c b/zebra/ipforward_proc.c index 08fbfede42af..423358178335 100644 --- a/zebra/ipforward_proc.c +++ b/zebra/ipforward_proc.c @@ -17,10 +17,22 @@ extern struct zebra_privs_t zserv_privs; static const char proc_net_snmp[] = "/proc/net/snmp"; +<<<<<<< HEAD static void dropline(FILE *fp) { while (getc(fp) != '\n') ; +======= +static bool dropline(FILE *fp) +{ + int ch; + + do { + ch = getc(fp); + } while (ch != EOF && ch != '\n'); + + return ch != EOF; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } int ipforward(void) @@ -36,7 +48,14 @@ int ipforward(void) return -1; /* We don't care about the first line. */ +<<<<<<< HEAD dropline(fp); +======= + if (!dropline(fp)) { + fclose(fp); + return 0; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Get ip_statistics.IpForwarding : 1 => ip forwarding enabled diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 84aabc425456..111c175aaad2 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -405,10 +405,13 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, return netlink_route_change(h, ns_id, startup); case RTM_DELROUTE: return netlink_route_change(h, ns_id, startup); +<<<<<<< HEAD case RTM_NEWLINK: return netlink_link_change(h, ns_id, startup); case RTM_DELLINK: return 0; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) case RTM_NEWNEIGH: case RTM_DELNEIGH: case RTM_GETNEIGH: @@ -430,10 +433,13 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, case RTM_NEWTFILTER: case RTM_DELTFILTER: return netlink_tfilter_change(h, ns_id, startup); +<<<<<<< HEAD case RTM_NEWVLAN: return netlink_vlan_change(h, ns_id, startup); case RTM_DELVLAN: return netlink_vlan_change(h, ns_id, startup); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Messages we may receive, but ignore */ case RTM_NEWCHAIN: @@ -442,6 +448,11 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, return 0; /* Messages handled in the dplane thread */ +<<<<<<< HEAD +======= + case RTM_NEWLINK: + case RTM_DELLINK: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) case RTM_NEWADDR: case RTM_DELADDR: case RTM_NEWNETCONF: @@ -449,6 +460,11 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, case RTM_NEWTUNNEL: case RTM_DELTUNNEL: case RTM_GETTUNNEL: +<<<<<<< HEAD +======= + case RTM_NEWVLAN: + case RTM_DELVLAN: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; default: /* @@ -492,6 +508,13 @@ static int dplane_netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, case RTM_DELLINK: return netlink_link_change(h, ns_id, startup); +<<<<<<< HEAD +======= + case RTM_NEWVLAN: + case RTM_DELVLAN: + return netlink_vlan_change(h, ns_id, startup); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) default: break; } @@ -932,7 +955,11 @@ static int netlink_recv_msg(struct nlsock *nl, struct msghdr *msg) } while (status == -1 && errno == EINTR); if (status == -1) { +<<<<<<< HEAD if (errno == EWOULDBLOCK || errno == EAGAIN) +======= + if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EMSGSIZE) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; flog_err(EC_ZEBRA_RECVMSG_OVERRUN, "%s recvmsg overrun: %s", nl->name, safe_strerror(errno)); @@ -1621,6 +1648,10 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth, case DPLANE_OP_IPSET_ENTRY_ADD: case DPLANE_OP_IPSET_ENTRY_DELETE: case DPLANE_OP_STARTUP_STAGE: +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return FRR_NETLINK_ERROR; case DPLANE_OP_GRE_SET: @@ -1862,8 +1893,13 @@ void kernel_init(struct zebra_ns *zns) * setsockopt multicast group subscriptions that don't fit in nl_groups */ grp = RTNLGRP_BRVLAN; +<<<<<<< HEAD ret = setsockopt(zns->netlink.sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &grp, sizeof(grp)); +======= + ret = setsockopt(zns->netlink_dplane_in.sock, SOL_NETLINK, + NETLINK_ADD_MEMBERSHIP, &grp, sizeof(grp)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (ret < 0) zlog_notice( diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 5cfbe7a896dd..115a4600940c 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1627,6 +1627,10 @@ void kernel_update_multi(struct dplane_ctx_list_head *ctx_list) case DPLANE_OP_INTF_ADDR_DEL: case DPLANE_OP_STARTUP_STAGE: case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET: +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_err("Unhandled dplane data for %s", dplane_op2str(dplane_ctx_get_op(ctx))); res = ZEBRA_DPLANE_REQUEST_FAILURE; diff --git a/zebra/main.c b/zebra/main.c index 4d9b7c3bbe35..d36bbb64c878 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -54,6 +54,11 @@ #define ZEBRA_PTM_SUPPORT +<<<<<<< HEAD +======= +char *zserv_path; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* process id. */ pid_t pid; @@ -314,17 +319,56 @@ FRR_DAEMON_INFO(zebra, ZEBRA, ); /* clang-format on */ +<<<<<<< HEAD +======= +void zebra_main_router_started(void) +{ + /* + * Clean up zebra-originated routes. The requests will be sent to OS + * immediately, so originating PID in notifications from kernel + * will be equal to the current getpid(). To know about such routes, + * we have to have route_read() called before. + * If FRR is gracefully restarting, we either wait for clients + * (e.g., BGP) to signal GR is complete else we wait for specified + * duration. + */ + zrouter.startup_time = monotime(NULL); + zrouter.rib_sweep_time = 0; + zrouter.graceful_restart = zebra_di.graceful_restart; + if (!zrouter.graceful_restart) + event_add_timer(zrouter.master, rib_sweep_route, NULL, 0, NULL); + else { + int gr_cleanup_time; + + gr_cleanup_time = zebra_di.gr_cleanup_time ? zebra_di.gr_cleanup_time + : ZEBRA_GR_DEFAULT_RIB_SWEEP_TIME; + event_add_timer(zrouter.master, rib_sweep_route, NULL, gr_cleanup_time, + &zrouter.t_rib_sweep); + } + + zserv_start(zserv_path); +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Main startup routine. */ int main(int argc, char **argv) { // int batch_mode = 0; +<<<<<<< HEAD char *zserv_path = NULL; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct sockaddr_storage dummy; socklen_t dummylen; bool asic_offload = false; bool v6_with_v4_nexthop = false; bool notify_on_ack = true; +<<<<<<< HEAD +======= + zserv_path = NULL; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) vrf_configure_backend(VRF_BACKEND_VRF_LITE); frr_preinit(&zebra_di, argc, argv); @@ -436,6 +480,12 @@ int main(int argc, char **argv) zebra_if_init(); zebra_debug_init(); +<<<<<<< HEAD +======= + /* Open Zebra API server socket */ + zserv_open(zserv_path); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Initialize NS( and implicitly the VRF module), and make kernel * routing socket. */ @@ -475,6 +525,7 @@ int main(int argc, char **argv) */ frr_config_fork(); +<<<<<<< HEAD /* After we have successfully acquired the pidfile, we can be sure * about being the only copy of zebra process, which is submitting * changes to the FIB. @@ -500,6 +551,13 @@ int main(int argc, char **argv) event_add_timer(zrouter.master, rib_sweep_route, NULL, gr_cleanup_time, &zrouter.t_rib_sweep); } +======= + /* + * After we have successfully acquired the pidfile, we can be sure + * about being the only copy of zebra process, which is submitting + * changes to the FIB. + */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Needed for BSD routing socket. */ pid = getpid(); @@ -510,9 +568,12 @@ int main(int argc, char **argv) /* Start the ted module, before zserv */ zebra_opaque_start(); +<<<<<<< HEAD /* Start Zebra API server */ zserv_start(zserv_path); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Init label manager */ label_manager_init(); diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 2de0917a7e43..0674c449bf4c 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -35,10 +35,17 @@ /* array holding redistribute info about table redistribution */ /* bit AFI is set if that AFI is redistributing routes from this table */ +<<<<<<< HEAD static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; static uint32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id) +======= +static int zebra_import_table_used[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +static uint32_t zebra_import_table_distance[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; + +int is_zebra_import_table_enabled(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { /* * Make sure that what we are called with actualy makes sense @@ -46,9 +53,18 @@ int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id) if (afi == AFI_MAX) return 0; +<<<<<<< HEAD if (is_zebra_valid_kernel_table(table_id) && table_id < ZEBRA_KERNEL_TABLE_MAX) return zebra_import_table_used[afi][table_id]; +======= + if (safi == SAFI_MAX) + return 0; + + if (is_zebra_valid_kernel_table(table_id) && + table_id < ZEBRA_KERNEL_TABLE_MAX) + return zebra_import_table_used[afi][safi][table_id]; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -687,7 +703,11 @@ void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id) } } +<<<<<<< HEAD int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, +======= +int zebra_add_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct route_entry *re, const char *rmap_name) { struct route_entry *newre; @@ -705,7 +725,11 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, if (ret != RMAP_PERMITMATCH) { UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED); +<<<<<<< HEAD zebra_del_import_table_entry(zvrf, rn, re); +======= + zebra_del_import_table_entry(zvrf, safi, rn, re); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -724,26 +748,45 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, if (same) { UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED); +<<<<<<< HEAD zebra_del_import_table_entry(zvrf, rn, same); +======= + zebra_del_import_table_entry(zvrf, safi, rn, same); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } UNSET_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE); +<<<<<<< HEAD newre = zebra_rib_route_entry_new( 0, ZEBRA_ROUTE_TABLE, re->table, re->flags, re->nhe_id, zvrf->table_id, re->metric, re->mtu, zebra_import_table_distance[afi][re->table], re->tag); +======= + newre = zebra_rib_route_entry_new(0, ZEBRA_ROUTE_TABLE, re->table, re->flags, re->nhe_id, + zvrf->table_id, re->metric, re->mtu, + zebra_import_table_distance[afi][safi][re->table], + re->tag); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ng = nexthop_group_new(); copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL); +<<<<<<< HEAD rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng, false); +======= + rib_add_multipath(afi, safi, &p, NULL, newre, ng, false); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) nexthop_group_delete(&ng); return 0; } +<<<<<<< HEAD int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, +======= +int zebra_del_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct route_entry *re) { struct prefix p; @@ -752,17 +795,27 @@ int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, afi = family2afi(rn->p.family); prefix_copy(&p, &rn->p); +<<<<<<< HEAD rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE, re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop, re->nhe_id, zvrf->table_id, re->metric, re->distance, +======= + rib_delete(afi, safi, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE, re->table, re->flags, &p, NULL, + re->nhe->nhg.nexthop, re->nhe_id, zvrf->table_id, re->metric, re->distance, +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) false); return 0; } /* Assuming no one calls this with the main routing table */ +<<<<<<< HEAD int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, uint32_t distance, const char *rmap_name, int add) +======= +int zebra_import_table(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id, + uint32_t distance, const char *rmap_name, bool add) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct route_table *table; struct route_entry *re; @@ -776,17 +829,30 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, if (afi >= AFI_MAX) return -1; +<<<<<<< HEAD +======= + if (safi >= SAFI_MAX) + return -1; + + /* Always import from the URIB sub-table */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, vrf_id, table_id); if (table == NULL) { return 0; } else if (IS_ZEBRA_DEBUG_RIB) { +<<<<<<< HEAD zlog_debug("%s routes from table %d", add ? "Importing" : "Unimporting", table_id); +======= + zlog_debug("%s routes from table %d into %s", add ? "Importing" : "Unimporting", + table_id, safi2str(safi)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (add) { if (rmap_name) +<<<<<<< HEAD zebra_add_import_table_route_map(afi, rmap_name, table_id); else { @@ -794,10 +860,18 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, zebra_get_import_table_route_map(afi, table_id); if (rmap_name) { zebra_del_import_table_route_map(afi, table_id); +======= + zebra_add_import_table_route_map(afi, safi, rmap_name, table_id); + else { + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); + if (rmap_name) { + zebra_del_import_table_route_map(afi, safi, table_id); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) rmap_name = NULL; } } +<<<<<<< HEAD zebra_import_table_used[afi][table_id] = 1; zebra_import_table_distance[afi][table_id] = distance; } else { @@ -808,6 +882,17 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, rmap_name = zebra_get_import_table_route_map(afi, table_id); if (rmap_name) { zebra_del_import_table_route_map(afi, table_id); +======= + zebra_import_table_used[afi][safi][table_id] = 1; + zebra_import_table_distance[afi][safi][table_id] = distance; + } else { + zebra_import_table_used[afi][safi][table_id] = 0; + zebra_import_table_distance[afi][safi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT; + + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); + if (rmap_name) { + zebra_del_import_table_route_map(afi, safi, table_id); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) rmap_name = NULL; } } @@ -831,10 +916,16 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) { if (add) +<<<<<<< HEAD zebra_add_import_table_entry(zvrf, rn, re, rmap_name); else zebra_del_import_table_entry(zvrf, rn, re); +======= + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); + else + zebra_del_import_table_entry(zvrf, safi, rn, re); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } return 0; @@ -844,10 +935,15 @@ int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id) { int i; afi_t afi; +<<<<<<< HEAD +======= + safi_t safi; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int write = 0; char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"}; const char *rmap_name; +<<<<<<< HEAD for (afi = AFI_IP; afi < AFI_MAX; afi++) { for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { if (!is_zebra_import_table_enabled(afi, vrf_id, i)) @@ -864,6 +960,24 @@ int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id) } rmap_name = zebra_get_import_table_route_map(afi, i); +======= + FOREACH_AFI_SAFI (afi, safi) { + for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { + if (!is_zebra_import_table_enabled(afi, safi, vrf_id, i)) + continue; + + if (zebra_import_table_distance[afi][safi][i] != + ZEBRA_TABLE_DISTANCE_DEFAULT) { + vty_out(vty, "%s import-table %d %sdistance %d", afi_str[afi], i, + (safi == SAFI_MULTICAST ? "mrib " : ""), + zebra_import_table_distance[afi][safi][i]); + } else { + vty_out(vty, "%s import-table %d%s", afi_str[afi], i, + (safi == SAFI_MULTICAST ? " mrib" : "")); + } + + rmap_name = zebra_get_import_table_route_map(afi, safi, i); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (rmap_name) vty_out(vty, " route-map %s", rmap_name); @@ -875,21 +989,34 @@ int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id) return write; } +<<<<<<< HEAD static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, afi_t afi, int table_id, const char *rmap) +======= +static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, afi_t afi, safi_t safi, + int table_id, const char *rmap) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { struct route_table *table; struct route_entry *re; struct route_node *rn; const char *rmap_name; +<<<<<<< HEAD rmap_name = zebra_get_import_table_route_map(afi, table_id); if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0)) return; table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, table_id); +======= + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); + if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0)) + return; + + table = zebra_vrf_get_table_with_table_id(afi, safi, zvrf->vrf->vrf_id, table_id); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!table) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug("%s: Table id=%d not found", __func__, @@ -916,7 +1043,11 @@ static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) +<<<<<<< HEAD zebra_add_import_table_entry(zvrf, rn, re, rmap_name); +======= + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } return; @@ -926,6 +1057,7 @@ static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf, const char *rmap) { afi_t afi; +<<<<<<< HEAD int i; for (afi = AFI_IP; afi < AFI_MAX; afi++) { @@ -936,6 +1068,17 @@ static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf, zebra_import_table_rm_update_vrf_afi(zvrf, afi, i, rmap); +======= + safi_t safi; + int i; + + FOREACH_AFI_SAFI (afi, safi) { + for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { + if (!is_zebra_import_table_enabled(afi, safi, zvrf->vrf->vrf_id, i)) + continue; + + zebra_import_table_rm_update_vrf_afi(zvrf, afi, safi, i, rmap); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } } diff --git a/zebra/redistribute.h b/zebra/redistribute.h index 4347454eb7c6..7875ad9d462f 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -56,6 +56,7 @@ extern void zebra_interface_vrf_update_del(struct interface *ifp, extern void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id); +<<<<<<< HEAD extern int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, uint32_t distance, const char *rmap_name, int add); @@ -69,6 +70,16 @@ extern int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_entry *re); extern int is_zebra_import_table_enabled(afi_t, vrf_id_t vrf_id, uint32_t table_id); +======= +extern int zebra_import_table(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id, + uint32_t distance, const char *rmap_name, bool add); + +extern int zebra_add_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, + struct route_entry *re, const char *rmap_name); +extern int zebra_del_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, + struct route_entry *re); +extern int is_zebra_import_table_enabled(afi_t, safi_t safi, vrf_id_t vrf_id, uint32_t table_id); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern int zebra_import_table_config(struct vty *, vrf_id_t vrf_id); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index ab07ef8d2124..f4cf126ab7ff 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -3683,6 +3683,16 @@ netlink_vxlan_flood_update_ctx(const struct zebra_dplane_ctx *ctx, int cmd, if (dplane_ctx_get_type(ctx) != 0) proto = zebra2proto(dplane_ctx_get_type(ctx)); +<<<<<<< HEAD +======= + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("Tx %s family %s IF %s(%u) VNI %u MAC %pEA VTEP %pIA vid %u", + nl_msg_type_to_str(cmd), nl_family_to_str(PF_BRIDGE), + dplane_ctx_get_ifname(ctx), dplane_ctx_get_ifindex(ctx), + dplane_ctx_neigh_get_vni(ctx), &dst_mac, + dplane_ctx_neigh_get_ipaddr(ctx), dplane_ctx_mac_get_vlan(ctx)); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return netlink_neigh_update_msg_encode( ctx, cmd, (const void *)&dst_mac, ETH_ALEN, dplane_ctx_neigh_get_ipaddr(ctx), false, PF_BRIDGE, 0, NTF_SELF, diff --git a/zebra/table_manager.h b/zebra/table_manager.h index 21691994cba6..38b36cad2f07 100644 --- a/zebra/table_manager.h +++ b/zebra/table_manager.h @@ -24,6 +24,10 @@ extern "C" { #if !defined(GNU_LINUX) /* BSD systems */ +<<<<<<< HEAD +======= +#define RT_TABLE_ID_MAIN 0 +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #else /* Linux Systems */ diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 7dae75baccd9..635fe7f44b50 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -647,7 +647,11 @@ static int zsend_nexthop_lookup_mrib(struct zserv *client, struct ipaddr *addr, { struct stream *s; unsigned long nump; +<<<<<<< HEAD uint8_t num; +======= + uint16_t num; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct nexthop *nexthop; /* Get output stream. */ @@ -667,7 +671,11 @@ static int zsend_nexthop_lookup_mrib(struct zserv *client, struct ipaddr *addr, /* remember position for nexthop_num */ nump = stream_get_endp(s); /* reserve room for nexthop_num */ +<<<<<<< HEAD stream_putc(s, 0); +======= + stream_putw(s, 0); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) nhg = rib_get_fib_nhg(re); for (ALL_NEXTHOPS_PTR(nhg, nexthop)) { if (rnh_nexthop_valid(re, nexthop)) @@ -675,11 +683,19 @@ static int zsend_nexthop_lookup_mrib(struct zserv *client, struct ipaddr *addr, } /* store nexthop_num */ +<<<<<<< HEAD stream_putc_at(s, nump, num); } else { stream_putc(s, 0); /* distance */ stream_putl(s, 0); /* metric */ stream_putc(s, 0); /* nexthop_num */ +======= + stream_putw_at(s, nump, num); + } else { + stream_putc(s, 0); /* distance */ + stream_putl(s, 0); /* metric */ + stream_putw(s, 0); /* nexthop_num */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } stream_putw_at(s, 0, stream_get_endp(s)); diff --git a/zebra/zebra_cli.c b/zebra/zebra_cli.c index 6ee0fdbb8d90..782fe547afe9 100644 --- a/zebra/zebra_cli.c +++ b/zebra/zebra_cli.c @@ -2252,6 +2252,12 @@ static void lib_vrf_mpls_fec_nexthop_resolution_cli_write( } } +<<<<<<< HEAD +======= +#if CONFDATE > 20251207 +CPP_NOTICE("Remove no-op netns command") +#endif +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) DEFPY_YANG (vrf_netns, vrf_netns_cmd, "[no] netns ![NAME$netns_name]", diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 00e990e856fd..c4d57351b4e8 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -35,6 +35,11 @@ DEFINE_MTYPE_STATIC(ZEBRA, DP_PROV, "Zebra DPlane Provider"); DEFINE_MTYPE_STATIC(ZEBRA, DP_NETFILTER, "Zebra Netfilter Internal Object"); DEFINE_MTYPE_STATIC(ZEBRA, DP_NS, "DPlane NSes"); +<<<<<<< HEAD +======= +DEFINE_MTYPE(ZEBRA, VLAN_CHANGE_ARR, "Vlan Change Array"); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #ifndef AOK # define AOK 0 #endif @@ -371,6 +376,17 @@ struct dplane_srv6_encap_ctx { }; /* +<<<<<<< HEAD +======= + * VLAN info for the dataplane + */ +struct dplane_vlan_info { + ifindex_t ifindex; + struct zebra_vxlan_vlan_array *vlan_array; +}; + +/* +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * The context block used to exchange info about route updates across * the boundary between the zebra main context (and pthread) and the * dataplane layer (and pthread). @@ -416,6 +432,10 @@ struct zebra_dplane_ctx { struct dplane_pw_info pw; struct dplane_br_port_info br_port; struct dplane_intf_info intf; +<<<<<<< HEAD +======= + struct dplane_vlan_info vlan_info; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct dplane_mac_info macinfo; struct dplane_neigh_info neigh; struct dplane_rule_info rule; @@ -885,6 +905,14 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) case DPLANE_OP_STARTUP_STAGE: case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET: break; +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL: + if (ctx->u.vlan_info.vlan_array) + XFREE(MTYPE_VLAN_CHANGE_ARR, + ctx->u.vlan_info.vlan_array); + break; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -1030,6 +1058,7 @@ enum dplane_op_e dplane_ctx_get_op(const struct zebra_dplane_ctx *ctx) const char *dplane_op2str(enum dplane_op_e op) { +<<<<<<< HEAD const char *ret = "UNKNOWN"; switch (op) { @@ -1168,6 +1197,104 @@ const char *dplane_op2str(enum dplane_op_e op) case DPLANE_OP_GRE_SET: ret = "GRE_SET"; break; +======= + switch (op) { + case DPLANE_OP_NONE: + return "NONE"; + + /* Route update */ + case DPLANE_OP_ROUTE_INSTALL: + return "ROUTE_INSTALL"; + case DPLANE_OP_ROUTE_UPDATE: + return "ROUTE_UPDATE"; + case DPLANE_OP_ROUTE_DELETE: + return "ROUTE_DELETE"; + case DPLANE_OP_ROUTE_NOTIFY: + return "ROUTE_NOTIFY"; + + /* Nexthop update */ + case DPLANE_OP_NH_INSTALL: + return "NH_INSTALL"; + case DPLANE_OP_NH_UPDATE: + return "NH_UPDATE"; + case DPLANE_OP_NH_DELETE: + return "NH_DELETE"; + + case DPLANE_OP_LSP_INSTALL: + return "LSP_INSTALL"; + case DPLANE_OP_LSP_UPDATE: + return "LSP_UPDATE"; + case DPLANE_OP_LSP_DELETE: + return "LSP_DELETE"; + case DPLANE_OP_LSP_NOTIFY: + return "LSP_NOTIFY"; + + case DPLANE_OP_PW_INSTALL: + return "PW_INSTALL"; + case DPLANE_OP_PW_UNINSTALL: + return "PW_UNINSTALL"; + + case DPLANE_OP_SYS_ROUTE_ADD: + return "SYS_ROUTE_ADD"; + case DPLANE_OP_SYS_ROUTE_DELETE: + return "SYS_ROUTE_DEL"; + + case DPLANE_OP_BR_PORT_UPDATE: + return "BR_PORT_UPDATE"; + + case DPLANE_OP_ADDR_INSTALL: + return "ADDR_INSTALL"; + case DPLANE_OP_ADDR_UNINSTALL: + return "ADDR_UNINSTALL"; + + case DPLANE_OP_MAC_INSTALL: + return "MAC_INSTALL"; + case DPLANE_OP_MAC_DELETE: + return "MAC_DELETE"; + + case DPLANE_OP_NEIGH_INSTALL: + return "NEIGH_INSTALL"; + case DPLANE_OP_NEIGH_UPDATE: + return "NEIGH_UPDATE"; + case DPLANE_OP_NEIGH_DELETE: + return "NEIGH_DELETE"; + case DPLANE_OP_VTEP_ADD: + return "VTEP_ADD"; + case DPLANE_OP_VTEP_DELETE: + return "VTEP_DELETE"; + + case DPLANE_OP_RULE_ADD: + return "RULE_ADD"; + case DPLANE_OP_RULE_DELETE: + return "RULE_DELETE"; + case DPLANE_OP_RULE_UPDATE: + return "RULE_UPDATE"; + + case DPLANE_OP_NEIGH_DISCOVER: + return "NEIGH_DISCOVER"; + + case DPLANE_OP_IPTABLE_ADD: + return "IPTABLE_ADD"; + case DPLANE_OP_IPTABLE_DELETE: + return "IPTABLE_DELETE"; + case DPLANE_OP_IPSET_ADD: + return "IPSET_ADD"; + case DPLANE_OP_IPSET_DELETE: + return "IPSET_DELETE"; + case DPLANE_OP_IPSET_ENTRY_ADD: + return "IPSET_ENTRY_ADD"; + case DPLANE_OP_IPSET_ENTRY_DELETE: + return "IPSET_ENTRY_DELETE"; + case DPLANE_OP_NEIGH_IP_INSTALL: + return "NEIGH_IP_INSTALL"; + case DPLANE_OP_NEIGH_IP_DELETE: + return "NEIGH_IP_DELETE"; + case DPLANE_OP_NEIGH_TABLE_UPDATE: + return "NEIGH_TABLE_UPDATE"; + + case DPLANE_OP_GRE_SET: + return "GRE_SET"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) case DPLANE_OP_INTF_ADDR_ADD: return "INTF_ADDR_ADD"; @@ -1179,6 +1306,7 @@ const char *dplane_op2str(enum dplane_op_e op) return "INTF_NETCONFIG"; case DPLANE_OP_INTF_INSTALL: +<<<<<<< HEAD ret = "INTF_INSTALL"; break; case DPLANE_OP_INTF_UPDATE: @@ -1222,10 +1350,46 @@ const char *dplane_op2str(enum dplane_op_e op) } return ret; +======= + return "INTF_INSTALL"; + case DPLANE_OP_INTF_UPDATE: + return "INTF_UPDATE"; + case DPLANE_OP_INTF_DELETE: + return "INTF_DELETE"; + + case DPLANE_OP_TC_QDISC_INSTALL: + return "TC_QDISC_INSTALL"; + case DPLANE_OP_TC_QDISC_UNINSTALL: + return "TC_QDISC_UNINSTALL"; + case DPLANE_OP_TC_CLASS_ADD: + return "TC_CLASS_ADD"; + case DPLANE_OP_TC_CLASS_DELETE: + return "TC_CLASS_DELETE"; + case DPLANE_OP_TC_CLASS_UPDATE: + return "TC_CLASS_UPDATE"; + case DPLANE_OP_TC_FILTER_ADD: + return "TC_FILTER_ADD"; + case DPLANE_OP_TC_FILTER_DELETE: + return "TC_FILTER_DELETE"; + case DPLANE_OP_TC_FILTER_UPDATE: + return "TC__FILTER_UPDATE"; + case DPLANE_OP_STARTUP_STAGE: + return "STARTUP_STAGE"; + + case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET: + return "SRV6_ENCAP_SRCADDR_SET"; + + case DPLANE_OP_VLAN_INSTALL: + return "NEW_VLAN"; + } + + return "UNKNOWN"; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } const char *dplane_res2str(enum zebra_dplane_result res) { +<<<<<<< HEAD const char *ret = ""; switch (res) { @@ -1241,6 +1405,18 @@ const char *dplane_res2str(enum zebra_dplane_result res) } return ret; +======= + switch (res) { + case ZEBRA_DPLANE_REQUEST_FAILURE: + return "FAILURE"; + case ZEBRA_DPLANE_REQUEST_QUEUED: + return "QUEUED"; + case ZEBRA_DPLANE_REQUEST_SUCCESS: + return "SUCCESS"; + } + + return ""; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } void dplane_ctx_set_dest(struct zebra_dplane_ctx *ctx, @@ -3321,6 +3497,38 @@ uint32_t dplane_get_in_queue_len(void) memory_order_seq_cst); } +<<<<<<< HEAD +======= +void dplane_ctx_set_vlan_ifindex(struct zebra_dplane_ctx *ctx, ifindex_t ifindex) +{ + DPLANE_CTX_VALID(ctx); + ctx->u.vlan_info.ifindex = ifindex; +} + +ifindex_t dplane_ctx_get_vlan_ifindex(struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.vlan_info.ifindex; +} + +void dplane_ctx_set_vxlan_vlan_array(struct zebra_dplane_ctx *ctx, + struct zebra_vxlan_vlan_array *vlan_array) +{ + DPLANE_CTX_VALID(ctx); + + ctx->u.vlan_info.vlan_array = vlan_array; +} + +const struct zebra_vxlan_vlan_array * +dplane_ctx_get_vxlan_vlan_array(struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.vlan_info.vlan_array; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Internal helper that copies information from a zebra ns object; this is * called in the zebra main pthread context as part of dplane ctx init. @@ -6720,6 +6928,15 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx) dplane_op2str(dplane_ctx_get_op(ctx)), &ctx->u.srv6_encap.srcaddr); break; +<<<<<<< HEAD +======= + + case DPLANE_OP_VLAN_INSTALL: + zlog_debug("Dplane %s on idx %u", + dplane_op2str(dplane_ctx_get_op(ctx)), + dplane_ctx_get_vlan_ifindex(ctx)); + break; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -6888,6 +7105,10 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx) case DPLANE_OP_INTF_ADDR_ADD: case DPLANE_OP_INTF_ADDR_DEL: case DPLANE_OP_INTF_NETCONFIG: +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) break; case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET: diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index a3318bf5e995..91ea8e3f7075 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -24,6 +24,11 @@ extern "C" { #endif +<<<<<<< HEAD +======= +DECLARE_MTYPE(VLAN_CHANGE_ARR); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Retrieve the dataplane API version number; see libfrr.h to decode major, * minor, sub version values. * Plugins should pay attention to the major version number, at least, to @@ -204,6 +209,12 @@ enum dplane_op_e { DPLANE_OP_TC_FILTER_DELETE, DPLANE_OP_TC_FILTER_UPDATE, +<<<<<<< HEAD +======= + /* VLAN update */ + DPLANE_OP_VLAN_INSTALL, + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Startup Control */ DPLANE_OP_STARTUP_STAGE, @@ -211,6 +222,16 @@ enum dplane_op_e { DPLANE_OP_SRV6_ENCAP_SRCADDR_SET, }; +<<<<<<< HEAD +======= +/* Operational status of Bridge Ports */ +#define ZEBRA_DPLANE_BR_STATE_DISABLED 0x01 +#define ZEBRA_DPLANE_BR_STATE_LISTENING 0x02 +#define ZEBRA_DPLANE_BR_STATE_LEARNING 0x04 +#define ZEBRA_DPLANE_BR_STATE_FORWARDING 0x08 +#define ZEBRA_DPLANE_BR_STATE_BLOCKING 0x10 + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * The vxlan/evpn neighbor management code needs some values to use * when programming neighbor changes. Offer some platform-neutral values @@ -1078,6 +1099,29 @@ void dplane_set_in_queue_limit(uint32_t limit, bool set); /* Retrieve the current queue depth of incoming, unprocessed updates */ uint32_t dplane_get_in_queue_len(void); +<<<<<<< HEAD +======= +void dplane_ctx_set_vlan_ifindex(struct zebra_dplane_ctx *ctx, + ifindex_t ifindex); +ifindex_t dplane_ctx_get_vlan_ifindex(struct zebra_dplane_ctx *ctx); +struct zebra_vxlan_vlan_array; + +/* + * In netlink_vlan_change(), the memory allocated for vlan_array is freed + * in two cases + * 1) Inline free in netlink_vlan_change() when there are no new + * vlans to process i.e. nothing is enqueued to main thread. + * 2) Dplane-ctx takes over the vlan memory which gets freed in + * rib_process_dplane_results() after handling the vlan install + * + * Note: MTYPE of interest for this purpose is MTYPE_VLAN_CHANGE_ARR + */ +void dplane_ctx_set_vxlan_vlan_array(struct zebra_dplane_ctx *ctx, + struct zebra_vxlan_vlan_array *vlan_array); +const struct zebra_vxlan_vlan_array * +dplane_ctx_get_vxlan_vlan_array(struct zebra_dplane_ctx *ctx); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Vty/cli apis */ diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index a733b5917f94..910dbc2d5489 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -610,6 +610,7 @@ void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket, return; } +<<<<<<< HEAD static int zebra_evpn_map_vlan_ns(struct ns *ns, void *_in_param, void **_p_zevpn) @@ -629,11 +630,25 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns, uint8_t bridge_vlan_aware; assert(p_zevpn && in_param); +======= +/* Callback for per-NS ifp walk */ +static int zebra_evpn_map_vlan_ns(struct interface *tmp_if, void *_in_param) +{ + bool found = false; + struct interface *br_if; + struct zebra_evpn *zevpn; + struct zebra_if *zif; + struct zebra_from_svi_param *in_param = _in_param; + vni_t vni_id = 0; + + assert(in_param); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) br_if = in_param->br_if; assert(br_if); zif = in_param->zif; assert(zif); +<<<<<<< HEAD vid = in_param->vid; bridge_vlan_aware = in_param->bridge_vlan_aware; @@ -669,11 +684,37 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns, } } +======= + + /* + * See if this interface (or interface plus VLAN Id) maps to a + * VxLAN + */ + /* TODO: Optimize with a hash. */ + zif = tmp_if->info; + if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) + goto done; + if (!if_is_operative(tmp_if)) + goto done; + + if (zif->brslave_info.br_if != br_if) + goto done; + + vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, br_if); + if (vni_id) + found = true; + +done: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!found) return NS_WALK_CONTINUE; zevpn = zebra_evpn_lookup(vni_id); +<<<<<<< HEAD *p_zevpn = zevpn; +======= + in_param->zevpn = zevpn; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NS_WALK_STOP; } @@ -685,13 +726,19 @@ struct zebra_evpn *zebra_evpn_map_vlan(struct interface *ifp, struct interface *br_if, vlanid_t vid) { struct zebra_if *zif; +<<<<<<< HEAD struct zebra_evpn **p_zevpn; struct zebra_evpn *zevpn = NULL; struct zebra_from_svi_param in_param; +======= + struct zebra_from_svi_param in_param = {}; + vni_t vni_id = 0; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Determine if bridge is VLAN-aware or not */ zif = br_if->info; assert(zif); +<<<<<<< HEAD in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif); in_param.vid = vid; in_param.br_if = br_if; @@ -721,6 +768,35 @@ static int zebra_evpn_from_svi_ns(struct ns *ns, vni_t vni_id = 0; vlanid_t vid = 0; uint8_t bridge_vlan_aware; +======= + + /* Special case for vlan */ + if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif)) { + vni_id = zebra_l2_bridge_if_vni_find(zif, vid); + if (vni_id) + return zebra_evpn_lookup(vni_id); + } + + in_param.vid = vid; + in_param.br_if = br_if; + in_param.zif = zif; + + zebra_ns_ifp_walk_all(zebra_evpn_map_vlan_ns, &in_param); + + return in_param.zevpn; +} + +/* Callback for from_svi ifp walker */ +static int zebra_evpn_from_svi_ns(struct interface *tmp_if, void *_in_param) +{ + struct interface *br_if; + struct zebra_evpn *zevpn; + struct zebra_if *zif; + struct zebra_if *br_zif; + struct zebra_from_svi_param *in_param = _in_param; + bool found = false; + vni_t vni_id = 0; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!in_param) return NS_WALK_STOP; @@ -728,6 +804,7 @@ static int zebra_evpn_from_svi_ns(struct ns *ns, br_if = in_param->br_if; zif = in_param->zif; assert(zif); +<<<<<<< HEAD bridge_vlan_aware = in_param->bridge_vlan_aware; vid = in_param->vid; br_zif = br_if->info; @@ -764,12 +841,37 @@ static int zebra_evpn_from_svi_ns(struct ns *ns, } } +======= + br_zif = br_if->info; + assert(br_zif); + + if (!tmp_if) + goto done; + zif = tmp_if->info; + if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) + goto done; + if (!if_is_operative(tmp_if)) + goto done; + + if (zif->brslave_info.br_if != br_if) + goto done; + + vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, br_if); + if (vni_id) + found = true; + +done: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!found) return NS_WALK_CONTINUE; zevpn = zebra_evpn_lookup(vni_id); +<<<<<<< HEAD if (p_zevpn) *p_zevpn = zevpn; +======= + in_param->zevpn = zevpn; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NS_WALK_STOP; } @@ -780,17 +882,34 @@ static int zebra_evpn_from_svi_ns(struct ns *ns, struct zebra_evpn *zebra_evpn_from_svi(struct interface *ifp, struct interface *br_if) { +<<<<<<< HEAD struct zebra_evpn *zevpn = NULL; struct zebra_evpn **p_zevpn; struct zebra_if *zif; struct zebra_from_svi_param in_param; +======= + struct zebra_if *zif; + struct zebra_l2_bridge_vlan *bvlan; + struct zebra_from_svi_param in_param = {}; + vni_t vni_id = 0; + struct zebra_evpn *zevpn; + struct zebra_l2info_vlan *vl; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!br_if) return NULL; /* Make sure the linked interface is a bridge. */ +<<<<<<< HEAD if (!IS_ZEBRA_IF_BRIDGE(br_if)) return NULL; +======= + if (!IS_ZEBRA_IF_BRIDGE(br_if)) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s: br_if NOT a bridge", __func__); + return NULL; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Determine if bridge is VLAN-aware or not */ zif = br_if->info; @@ -798,16 +917,27 @@ struct zebra_evpn *zebra_evpn_from_svi(struct interface *ifp, in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif); in_param.vid = 0; +<<<<<<< HEAD if (in_param.bridge_vlan_aware) { struct zebra_l2info_vlan *vl; if (!IS_ZEBRA_IF_VLAN(ifp)) return NULL; +======= + /* Don't need to search in this case */ + if (in_param.bridge_vlan_aware) { + if (!IS_ZEBRA_IF_VLAN(ifp)) + return NULL; + + zevpn = NULL; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zif = ifp->info; assert(zif); vl = &zif->l2info.vl; in_param.vid = vl->vid; +<<<<<<< HEAD } in_param.br_if = br_if; @@ -849,6 +979,51 @@ static int zvni_map_to_macvlan_ns(struct ns *ns, void *_in_param, void **_p_ifp) } } +======= + + bvlan = zebra_l2_bridge_if_vlan_find(br_if->info, vl->vid); + if (bvlan && bvlan->access_bd && bvlan->access_bd->vni) { + vni_id = bvlan->access_bd->vni; + zevpn = zebra_evpn_lookup(vni_id); + } + + return zevpn; + } + + /* See if this interface (or interface plus VLAN Id) maps to a VxLAN: + * search all NSes + */ + in_param.br_if = br_if; + in_param.zif = zif; + zebra_ns_ifp_walk_all(zebra_evpn_from_svi_ns, &in_param); + + return in_param.zevpn; +} + +static int zvni_map_to_macvlan_ns(struct interface *tmp_if, void *_in_param) +{ + struct zebra_from_svi_param *in_param = _in_param; + struct zebra_if *zif; + + assert(in_param); + + /* Identify corresponding VLAN interface. */ + + /* Check oper status of the SVI. */ + if (!tmp_if || !if_is_operative(tmp_if)) + goto done; + + zif = tmp_if->info; + if (!zif || zif->zif_type != ZEBRA_IF_MACVLAN) + goto done; + + if (zif->link == in_param->svi_if) { + in_param->ret_ifp = tmp_if; + return NS_WALK_STOP; + } + +done: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NS_WALK_CONTINUE; } @@ -857,17 +1032,27 @@ static int zvni_map_to_macvlan_ns(struct ns *ns, void *_in_param, void **_p_ifp) struct interface *zebra_evpn_map_to_macvlan(struct interface *br_if, struct interface *svi_if) { +<<<<<<< HEAD struct interface *tmp_if = NULL; struct zebra_if *zif; struct interface **p_ifp; struct zebra_from_svi_param in_param; +======= + struct zebra_if *zif; + struct zebra_from_svi_param in_param = {}; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Defensive check, caller expected to invoke only with valid bridge. */ if (!br_if) return NULL; if (!svi_if) { +<<<<<<< HEAD zlog_debug("svi_if is not passed."); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s: svi_if is not passed.", __func__); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NULL; } @@ -879,11 +1064,18 @@ struct interface *zebra_evpn_map_to_macvlan(struct interface *br_if, in_param.br_if = br_if; in_param.zif = NULL; in_param.svi_if = svi_if; +<<<<<<< HEAD p_ifp = &tmp_if; /* Identify corresponding VLAN interface. */ ns_walk_func(zvni_map_to_macvlan_ns, (void *)&in_param, (void **)p_ifp); return tmp_if; +======= + + /* Identify corresponding VLAN interface. */ + zebra_ns_ifp_walk_all(zvni_map_to_macvlan_ns, &in_param); + return in_param.ret_ifp; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* @@ -1324,8 +1516,14 @@ int zebra_evpn_vtep_install(struct zebra_evpn *zevpn, struct zebra_vtep *zvtep) int zebra_evpn_vtep_uninstall(struct zebra_evpn *zevpn, struct in_addr *vtep_ip) { if (!zevpn->vxlan_if) { +<<<<<<< HEAD zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf", zevpn->vni, zevpn); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf", + zevpn->vni, zevpn); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } diff --git a/zebra/zebra_evpn.h b/zebra/zebra_evpn.h index c946425dd52f..ecdcc08439e0 100644 --- a/zebra/zebra_evpn.h +++ b/zebra/zebra_evpn.h @@ -116,7 +116,14 @@ struct zebra_evpn { struct zebra_from_svi_param { struct interface *br_if; struct interface *svi_if; +<<<<<<< HEAD struct zebra_if *zif; +======= + struct interface *ret_ifp; + struct zebra_if *zif; + struct zebra_evpn *zevpn; + struct zebra_l3vni *zl3vni; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) uint8_t bridge_vlan_aware; vlanid_t vid; }; diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h index 588917f4c036..af1fb87c5df7 100644 --- a/zebra/zebra_l2.h +++ b/zebra/zebra_l2.h @@ -146,6 +146,20 @@ union zebra_l2if_info { struct zebra_l2info_gre gre; }; +<<<<<<< HEAD +======= +struct zebra_vxlan_vlan { + uint8_t state; + uint32_t vrange; + vlanid_t vid; +}; + +struct zebra_vxlan_vlan_array { + uint16_t count; + struct zebra_vxlan_vlan vlans[0]; +}; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* NOTE: These macros are to be invoked only in the "correct" context. * IOW, the macro VNI_FROM_ZEBRA_IF() will assume the interface is * of type ZEBRA_IF_VXLAN. diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 9549af5f14bc..a40248225c36 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -37,7 +37,10 @@ DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object"); DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object"); DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object"); +<<<<<<< HEAD DEFINE_MTYPE_STATIC(ZEBRA, NH_LABEL, "Nexthop label"); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) bool mpls_enabled; bool mpls_pw_reach_strict; /* Strict reachability checking */ @@ -1453,6 +1456,7 @@ static int nhlfe_del(struct zebra_nhlfe *nhlfe) static void nhlfe_out_label_update(struct zebra_nhlfe *nhlfe, struct mpls_label_stack *nh_label) { +<<<<<<< HEAD struct mpls_label_stack *nh_label_tmp; int i; @@ -1478,6 +1482,9 @@ static void nhlfe_out_label_update(struct zebra_nhlfe *nhlfe, /* Copy the label stack into the array */ for (i = 0; i < nh_label->num_labels; i++) nhlfe->nexthop->nh_label->label[i] = nh_label->label[i]; +======= + nexthop_change_labels(nhlfe->nexthop, nh_label); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } static int mpls_lsp_uninstall_all(struct hash *lsp_table, struct zebra_lsp *lsp, diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c index 63ac7877d0f9..954b1f795bb3 100644 --- a/zebra/zebra_nb_state.c +++ b/zebra/zebra_nb_state.c @@ -900,6 +900,10 @@ lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_bh_type_get_elem( if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE) return NULL; +<<<<<<< HEAD +======= + (void)type_str; /* clang-SA */ +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) switch (nexthop->bh_type) { case BLACKHOLE_NULL: type_str = "null"; diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index 4cee3b89f198..49a7e30cc893 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -159,6 +159,10 @@ ns_id_t zebra_ns_id_get(const char *netnspath, int fd_param) int fd = -1, sock, ret; unsigned int seq; ns_id_t return_nsid = NS_UNKNOWN; +<<<<<<< HEAD +======= + int nl_errno; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* netns path check */ if (!netnspath && fd_param == -1) @@ -231,6 +235,7 @@ ns_id_t zebra_ns_id_get(const char *netnspath, int fd_param) ret = -1; if (err->error < 0) +<<<<<<< HEAD errno = -err->error; else errno = err->error; @@ -239,12 +244,23 @@ ns_id_t zebra_ns_id_get(const char *netnspath, int fd_param) * return EEXIST error to get GETNSID */ errno = EEXIST; +======= + nl_errno = -err->error; + else + nl_errno = err->error; + if (nl_errno == 0) { + /* request NEWNSID was successfull + * return EEXIST error to get GETNSID + */ + nl_errno = EEXIST; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } else { /* other errors ignored * attempt to get nsid */ ret = -1; +<<<<<<< HEAD errno = EEXIST; } } @@ -257,6 +273,19 @@ ns_id_t zebra_ns_id_get(const char *netnspath, int fd_param) if (netnspath) close(fd); if (errno == ENOTSUP) { +======= + nl_errno = EEXIST; + } + } + + if (ret != 0 && nl_errno != EEXIST) { + flog_err(EC_LIB_SOCKET, "netlink( %u) recvfrom() error 2 when reading: %s", fd, + safe_strerror(nl_errno)); + close(sock); + if (netnspath) + close(fd); + if (nl_errno == ENOTSUP) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("NEWNSID locally generated"); return zebra_ns_id_get_fallback(netnspath); } diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index 3ac4fdd73716..2fee23fdd287 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -378,19 +378,38 @@ void zebra_ns_notify_parse(void) { struct dirent *dent; DIR *srcdir = opendir(NS_RUN_DIR); +<<<<<<< HEAD +======= + int srcdirfd; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (srcdir == NULL) { flog_err_sys(EC_LIB_SYSTEM_CALL, "NS parsing init: failed to parse %s", NS_RUN_DIR); return; } +<<<<<<< HEAD +======= + + srcdirfd = dirfd(srcdir); + if (srcdirfd < 0) { + closedir(srcdir); + flog_err_sys(EC_LIB_SYSTEM_CALL, "NS parsing init: failed to parse %s", NS_RUN_DIR); + return; + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) while ((dent = readdir(srcdir)) != NULL) { struct stat st; if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; +<<<<<<< HEAD if (fstatat(dirfd(srcdir), dent->d_name, &st, 0) < 0) { +======= + if (fstatat(srcdirfd, dent->d_name, &st, 0) < 0) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) flog_err_sys( EC_LIB_SYSTEM_CALL, "NS parsing init: failed to parse entry %s", diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index ffd749fcf17e..2c2b578c4c2f 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -28,9 +28,191 @@ extern struct zebra_privs_t zserv_privs; DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_NS, "Zebra Name Space"); +<<<<<<< HEAD static struct zebra_ns *dzns; +======= +DEFINE_MTYPE_STATIC(ZEBRA, ZNS_IFP, "Zebra NS Ifp"); + +static int ifp_tree_cmp(const struct ifp_tree_link *a, const struct ifp_tree_link *b); + +DECLARE_RBTREE_UNIQ(ifp_tree, struct ifp_tree_link, link, ifp_tree_cmp); + +static struct zebra_ns *dzns; + +static int ifp_tree_cmp(const struct ifp_tree_link *a, const struct ifp_tree_link *b) +{ + return (a->ifindex - b->ifindex); +} + +/* + * Link an ifp into its parent NS + */ +void zebra_ns_link_ifp(struct zebra_ns *zns, struct interface *ifp) +{ + struct zebra_if *zif; + struct ifp_tree_link *link, tlink = {}; + + zif = ifp->info; + assert(zif != NULL); + + if (zif->ns_tree_link) { + assert(zif->ns_tree_link->zns == zns); + assert(zif->ns_tree_link->ifp == ifp); + return; + } + + /* Lookup first - already linked? */ + tlink.ifindex = ifp->ifindex; + link = ifp_tree_find(&zns->ifp_tree, &tlink); + if (link) { + assert(link->ifp == ifp); + return; + } + + /* Allocate new linkage struct and add */ + link = XCALLOC(MTYPE_ZNS_IFP, sizeof(struct ifp_tree_link)); + link->ifp = ifp; + link->ifindex = ifp->ifindex; + link->zns = zns; + + ifp_tree_add(&zns->ifp_tree, link); + + zif->ns_tree_link = link; +} + +/* + * Unlink an ifp from its parent NS (probably because the ifp is being deleted) + */ +void zebra_ns_unlink_ifp(struct interface *ifp) +{ + struct zebra_if *zif; + struct ifp_tree_link *link; + struct zebra_ns *zns; + + zif = ifp->info; + if (zif && zif->ns_tree_link) { + link = zif->ns_tree_link; + zns = link->zns; + + ifp_tree_del(&zns->ifp_tree, link); + + zif->ns_tree_link = NULL; + + XFREE(MTYPE_ZNS_IFP, link); + } +} + +/* + * ifp lookup apis + */ +struct interface *zebra_ns_lookup_ifp(struct zebra_ns *zns, uint32_t ifindex) +{ + struct interface *ifp = NULL; + struct ifp_tree_link *link, tlink = {}; + + /* Init temp struct for lookup */ + tlink.ifindex = ifindex; + + link = ifp_tree_find(&zns->ifp_tree, &tlink); + if (link) + ifp = link->ifp; + + return ifp; +} + +static int lookup_ifp_name_cb(struct interface *ifp, void *arg); + +struct ifp_name_ctx { + const char *ifname; + struct interface *ifp; +}; + +struct interface *zebra_ns_lookup_ifp_name(struct zebra_ns *zns, const char *ifname) +{ + struct ifp_name_ctx ctx = {}; + + /* Hand context struct into walker function for use in its callback */ + ctx.ifname = ifname; + zebra_ns_ifp_walk(zns, lookup_ifp_name_cb, &ctx); + + return ctx.ifp; +} + +static int lookup_ifp_name_cb(struct interface *ifp, void *arg) +{ + struct ifp_name_ctx *pctx = arg; + + if (strcmp(ifp->name, pctx->ifname) == 0) { + pctx->ifp = ifp; + return NS_WALK_STOP; + } + + return NS_WALK_CONTINUE; +} + +/* Iterate collection of ifps, calling application's callback. Callback uses + * return semantics from lib/ns.h: return NS_WALK_STOP to stop the iteration. + * Caller's 'arg' is included in each callback. + */ +int zebra_ns_ifp_walk(struct zebra_ns *zns, + int (*func)(struct interface *ifp, void *arg), void *arg) +{ + struct ifp_tree_link *link; + int ret = NS_WALK_CONTINUE; + + frr_each (ifp_tree, &zns->ifp_tree, link) { + ret = (func)(link->ifp, arg); + if (ret == NS_WALK_STOP) + break; + } + + if (ret == NS_WALK_STOP) + return NS_WALK_STOP; + else + return NS_WALK_CONTINUE; +} + +/* + * Walk all NSes, and all ifps for each NS. + */ +struct ns_ifp_walk_ctx { + int (*func)(struct interface *ifp, void *arg); + void *arg; + int ret; +}; + +static int ns_ifp_walker(struct ns *ns, void *in_param, void **unused); + +void zebra_ns_ifp_walk_all(int (*func)(struct interface *ifp, void *arg), void *arg) +{ + struct ns_ifp_walk_ctx ctx = {}; + + ctx.func = func; + ctx.arg = arg; + + ns_walk_func(ns_ifp_walker, &ctx, NULL); +} + +static int ns_ifp_walker(struct ns *ns, void *in_param, void **unused) +{ + struct zebra_ns *zns; + struct ns_ifp_walk_ctx *ctx = in_param; + int ret = NS_WALK_CONTINUE; + + zns = ns->info; + if (zns == NULL) + goto done; + + ret = zebra_ns_ifp_walk(zns, ctx->func, ctx->arg); + +done: + + return ret; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete); struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id) @@ -58,7 +240,11 @@ static int zebra_ns_new(struct ns *ns) zns->ns_id = ns->ns_id; /* Do any needed per-NS data structure allocation. */ +<<<<<<< HEAD zns->if_table = route_table_init(); +======= + ifp_tree_init(&zns->ifp_tree); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -66,11 +252,28 @@ static int zebra_ns_new(struct ns *ns) static int zebra_ns_delete(struct ns *ns) { struct zebra_ns *zns = (struct zebra_ns *)ns->info; +<<<<<<< HEAD +======= + struct zebra_if *zif; + struct ifp_tree_link *link; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (IS_ZEBRA_DEBUG_EVENT) zlog_info("ZNS %s with id %u (deleted)", ns->name, ns->ns_id); if (!zns) return 0; +<<<<<<< HEAD +======= + + /* Clean up ifp tree */ + while ((link = ifp_tree_pop(&zns->ifp_tree)) != NULL) { + zif = link->ifp->info; + + zif->ns_tree_link = NULL; + XFREE(MTYPE_ZNS_IFP, link); + } + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) XFREE(MTYPE_ZEBRA_NS, ns->info); return 0; } @@ -123,6 +326,20 @@ void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx) vlan_read(zns); kernel_read_pbr_rules(zns); kernel_read_tc_qdisc(zns); +<<<<<<< HEAD +======= + + /* + * At this point FRR has requested and read a bunch + * of data from the dplane about initial state of + * the system. Zebra now needs to initialize + * the gr subsystem ( or the route sweeping + * subsystem ) to allow that to properly work. + * This must be done *immediately* after the + * load of all data from the underlying dplane. + */ + zebra_main_router_started(); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) break; } } @@ -146,10 +363,13 @@ int zebra_ns_enable(ns_id_t ns_id, void **info) */ static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete) { +<<<<<<< HEAD if (zns->if_table) route_table_finish(zns->if_table); zns->if_table = NULL; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zebra_dplane_ns_enable(zns, false /*Disable*/); kernel_terminate(zns, complete); diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index d5fd5869bca4..0867536a8150 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -32,6 +32,23 @@ struct nlsock { }; #endif +<<<<<<< HEAD +======= +/* Tree of interfaces: external linkage struct, and rbtree */ +PREDECL_RBTREE_UNIQ(ifp_tree); + +struct ifp_tree_link { + struct ifp_tree_item link; + + ifindex_t ifindex; + + struct interface *ifp; + + /* Backpointer */ + struct zebra_ns *zns; +}; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct zebra_ns { /* net-ns name. */ char name[VRF_NAMSIZ]; @@ -53,7 +70,12 @@ struct zebra_ns { struct nlsock ge_netlink_cmd; /* command channel for generic netlink */ #endif +<<<<<<< HEAD struct route_table *if_table; +======= + /* Tree of interfaces in this ns */ + struct ifp_tree_head ifp_tree; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Back pointer */ struct ns *ns; @@ -61,6 +83,26 @@ struct zebra_ns { struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id); +<<<<<<< HEAD +======= +/* Manage collection of ifps per-NS */ +void zebra_ns_link_ifp(struct zebra_ns *zns, struct interface *ifp); +void zebra_ns_unlink_ifp(struct interface *ifp); +struct interface *zebra_ns_lookup_ifp(struct zebra_ns *zns, uint32_t ifindex); +struct interface *zebra_ns_lookup_ifp_name(struct zebra_ns *zns, const char *ifname); + +/* Iterate collection of ifps, calling application's callback. Callback uses + * return semantics from lib/ns.h: return NS_WALK_STOP to stop the iteration. + * Caller's 'arg' is included in each callback. + * The iterator returns STOP or CONTINUE also. + */ +int zebra_ns_ifp_walk(struct zebra_ns *zns, + int (*func)(struct interface *ifp, void *arg), void *arg); + +/* Walk all NSes, and all ifps for each NS. */ +void zebra_ns_ifp_walk_all(int (*func)(struct interface *ifp, void *arg), void *arg); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) int zebra_ns_init(void); int zebra_ns_enable(ns_id_t ns_id, void **info); int zebra_ns_disabled(struct ns *ns); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 752f8282df69..4f87db8bb06e 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -639,13 +639,19 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re, { struct rib_table_info *info = srcdest_rnode_table_info(rn); struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); +<<<<<<< HEAD const struct prefix *p, *src_p; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) enum zebra_dplane_result ret; rib_dest_t *dest = rib_dest_from_rnode(rn); +<<<<<<< HEAD srcdest_rnode_prefixes(rn, &p, &src_p); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Install the resolved nexthop object first. */ @@ -778,13 +784,85 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq, struct rnh *rnh; /* +<<<<<<< HEAD * We are storing the rnh's associated withb * the tracked nexthop as a list of the rn's. +======= + * We are storing the rnh's associated with + * the tracked nexthop as a list of the rnh's + * on the rn that we have matched to. As an + * example if you have these rnh's: + * rnh 1.1.1.1 + * rnh 1.1.1.2 + * rnh 1.1.3.4 + * rnh 4.5.6.7 + * Now imagine that you have in the tree these + * prefix's: + * 1.1.1.1/32 + * 1.1.1.0/24 + * 1.1.0.0/16 + * 0.0.0.0/0 + * + * The 1.1.1.1 rnh would be stored on 1.1.1.1/32 + * The 1.1.1.2 rnh would be stored on 1.1.1.0/24 + * The 1.1.3.4 rnh would be stored on the 1.1.0.0/16 + * and finally the 4.5.6.7 would be stored on the 0.0.0.0/0 + * prefix. + * +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * Unresolved rnh's are placed at the top * of the tree list.( 0.0.0.0/0 for v4 and 0::0/0 for v6 ) * As such for each rn we need to walk up the tree * and see if any rnh's need to see if they * would match a more specific route +<<<<<<< HEAD +======= + * + * Now if a 1.1.1.2/32 prefix was added to the tree + * this function would start at this new node and + * see that the 1.1.1.2/32 node has no rnh's and + * there is nothing to do on this node currently, + * so the function would walk the parent pointers, until the + * 1.1.1.0/24 node is hit with the 1.1.1.2 rnh. This function + * would then call zebra_evaluate_rnh() which would then + * do a LPM and match on the 1.1.1.2/32 node. This function + * would then pull the 1.1.1.2 rnh off the 1.1.1.0/24 node + * and place it on the 1.1.1.1/32 node and notify the upper + * level protocols interested about the change( as necessary ). + * At this point in time a sequence number is added to note + * that the rnh has been moved. + * The function would also continue to walk up the tree + * looking at the list of rnh's and moving them around + * as necessary. Since in this example nothing else + * would change no further actions are made. + * + * Another case to consider is a node being deleted + * suppose the 1.1.1.2/32 route is being deleted. + * This function would start at the 1.1.1.1/32 node, + * perform a LPM and settle on the 1.1.1.0/24 node + * as where it belongs. The code would update appropriate + * interested parties and additionally also mark the sequence + * number and walk up the tree. Eventually it would get to + * the 1.1.1.0/24 node and since the seqno matches we would + * know that it is not necessary to reconsider this node + * as it was already moved to this spot. + * + * This all works because each node's parent pointer points + * to a node that has a prefix that contains this node. Eventually + * the parent traversal will hit the 0.0.0.0/0 node and we know + * we are done. We know this is pretty efficient because when + * a more specific is added as we walk the tree we can + * find the rnh's that matched to a less specific very easily + * and move them to a more specific node. Also vice-versa as a + * more specific node is removed. + * + * Long term the rnh code might be improved some as the rnh's + * are stored as a list. This might be transformed to a better + * data structure. This has not proven to be necessary yet as + * that we have not seen any particular case where a rn is + * storing more than a couple rnh's. If we find a case + * where this matters something might need to be done. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) */ while (rn) { if (IS_ZEBRA_DEBUG_NHT_DETAILED) @@ -1261,7 +1339,10 @@ static void rib_process(struct route_node *rn) if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)) { proto_re_changed = re; if (!nexthop_active_update(rn, re, old_fib)) { +<<<<<<< HEAD const struct prefix *p; +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct rib_table_info *info; if (re->type == ZEBRA_ROUTE_TABLE) { @@ -1295,7 +1376,10 @@ static void rib_process(struct route_node *rn) } info = srcdest_rnode_table_info(rn); +<<<<<<< HEAD srcdest_rnode_prefixes(rn, &p, NULL); +======= +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zsend_route_notify_owner( rn, re, ZAPI_ROUTE_FAIL_INSTALL, info->afi, info->safi); @@ -3955,6 +4039,10 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process) { rib_dest_t *dest; afi_t afi; +<<<<<<< HEAD +======= + safi_t safi; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) const char *rmap_name; assert(re && rn); @@ -3972,11 +4060,21 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process) afi = (rn->p.family == AF_INET) ? AFI_IP : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; +<<<<<<< HEAD if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) { struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); rmap_name = zebra_get_import_table_route_map(afi, re->table); zebra_add_import_table_entry(zvrf, rn, re, rmap_name); +======= + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (is_zebra_import_table_enabled(afi, safi, re->vrf_id, re->table)) { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + + rmap_name = zebra_get_import_table_route_map(afi, safi, re->table); + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } if (process) @@ -4034,6 +4132,10 @@ void rib_unlink(struct route_node *rn, struct route_entry *re) void rib_delnode(struct route_node *rn, struct route_entry *re) { afi_t afi; +<<<<<<< HEAD +======= + safi_t safi; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (IS_ZEBRA_DEBUG_RIB) rnode_debug(rn, re->vrf_id, "rn %p, re %p, removing", @@ -4047,6 +4149,7 @@ void rib_delnode(struct route_node *rn, struct route_entry *re) afi = (rn->p.family == AF_INET) ? AFI_IP : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; +<<<<<<< HEAD if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) { struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); @@ -4056,6 +4159,19 @@ void rib_delnode(struct route_node *rn, struct route_entry *re) zlog_debug("%s(%u):%pRN: Freeing route rn %p, re %p (%s)", vrf_id_to_name(re->vrf_id), re->vrf_id, rn, rn, re, zebra_route_string(re->type)); +======= + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (is_zebra_import_table_enabled(afi, safi, re->vrf_id, re->table)) { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + + zebra_del_import_table_entry(zvrf, safi, rn, re); + /* Just clean up if non main table */ + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug("%s %s(%u):%pRN: Freeing route rn %p, re %p (%s)", + safi2str(safi), vrf_id_to_name(re->vrf_id), re->vrf_id, + rn, rn, re, zebra_route_string(re->type)); + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } rib_queue_add(rn); @@ -4341,9 +4457,13 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, if (ng) { nhe.nhg.nexthop = ng->nexthop; +<<<<<<< HEAD if (re->type == ZEBRA_ROUTE_CONNECT || re->type == ZEBRA_ROUTE_LOCAL || re->type == ZEBRA_ROUTE_KERNEL) +======= + if (RIB_SYSTEM_ROUTE(re)) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) SET_FLAG(nhe.flags, NEXTHOP_GROUP_INITIAL_DELAY_INSTALL); } else if (re->nhe_id > 0) nhe.id = re->nhe_id; @@ -5005,6 +5125,12 @@ static void rib_process_dplane_results(struct event *thread) zebra_ns_startup_continue(ctx); break; +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL: + zebra_vlan_dplane_result(ctx); + break; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* Dispatch by op code */ dplane_ctx_fini(&ctx); diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 7c25fb3ef39d..658316013bae 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -1140,7 +1140,11 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client, struct stream *s = NULL; struct route_entry *re; unsigned long nump; +<<<<<<< HEAD uint8_t num; +======= + uint16_t num; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct nexthop *nh; struct route_node *rn; int ret; @@ -1211,7 +1215,11 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client, stream_putl(s, re->metric); num = 0; nump = stream_get_endp(s); +<<<<<<< HEAD stream_putc(s, 0); +======= + stream_putw(s, 0); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) nhg = rib_get_fib_nhg(re); for (ALL_NEXTHOPS_PTR(nhg, nh)) @@ -1239,13 +1247,21 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client, } } +<<<<<<< HEAD stream_putc_at(s, nump, num); +======= + stream_putw_at(s, nump, num); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } else { stream_putc(s, 0); // type stream_putw(s, 0); // instance stream_putc(s, 0); // distance stream_putl(s, 0); // metric +<<<<<<< HEAD stream_putc(s, 0); // nexthops +======= + stream_putw(s, 0); // nexthops +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } stream_putw_at(s, 0, stream_get_endp(s)); @@ -1271,7 +1287,11 @@ void show_nexthop_json_helper(json_object *json_nexthop, bool display_vrfid = false; uint8_t rn_family; +<<<<<<< HEAD if (re == NULL || nexthop->vrf_id != re->vrf_id) +======= + if ((re == NULL || nexthop->vrf_id != re->vrf_id) && nexthop->type != NEXTHOP_TYPE_BLACKHOLE) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) display_vrfid = true; if (rn) @@ -1292,7 +1312,11 @@ void show_route_nexthop_helper(struct vty *vty, const struct route_node *rn, bool display_vrfid = false; uint8_t rn_family; +<<<<<<< HEAD if (re == NULL || nexthop->vrf_id != re->vrf_id) +======= + if ((re == NULL || nexthop->vrf_id != re->vrf_id) && nexthop->type != NEXTHOP_TYPE_BLACKHOLE) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) display_vrfid = true; if (rn) diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 46afbcecfa98..4c7b79e589f3 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -29,7 +29,11 @@ static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER; static struct event *zebra_t_rmap_update = NULL; +<<<<<<< HEAD char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +======= +char *zebra_import_table_routemap[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct zebra_rmap_obj { struct nexthop *nexthop; @@ -1235,6 +1239,7 @@ route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re, return (ret); } +<<<<<<< HEAD char *zebra_get_import_table_route_map(afi_t afi, uint32_t table) { return zebra_import_table_routemap[afi][table]; @@ -1250,6 +1255,21 @@ void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, void zebra_del_import_table_route_map(afi_t afi, uint32_t table) { XFREE(MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][table]); +======= +char *zebra_get_import_table_route_map(afi_t afi, safi_t safi, uint32_t table) +{ + return zebra_import_table_routemap[afi][safi][table]; +} + +void zebra_add_import_table_route_map(afi_t afi, safi_t safi, const char *rmap_name, uint32_t table) +{ + zebra_import_table_routemap[afi][safi][table] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name); +} + +void zebra_del_import_table_route_map(afi_t afi, safi_t safi, uint32_t table) +{ + XFREE(MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][safi][table]); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } route_map_result_t zebra_import_table_route_map_check(int family, diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index 2039e80e3a74..604ae6df14f9 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -14,10 +14,17 @@ extern "C" { #endif extern void zebra_route_map_init(void); +<<<<<<< HEAD extern char *zebra_get_import_table_route_map(afi_t afi, uint32_t table); extern void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, uint32_t table); extern void zebra_del_import_table_route_map(afi_t afi, uint32_t table); +======= +extern char *zebra_get_import_table_route_map(afi_t afi, safi_t safi, uint32_t table); +extern void zebra_add_import_table_route_map(afi_t afi, safi_t safi, const char *rmap_name, + uint32_t table); +extern void zebra_del_import_table_route_map(afi_t afi, safi_t safi, uint32_t table); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) extern route_map_result_t zebra_import_table_route_map_check( int family, struct route_entry *re, const struct prefix *p, diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index c86c6be1ef56..eb3b32377da4 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -329,6 +329,11 @@ static inline uint8_t if_netlink_get_frr_protodown_r_bit(void) return zrouter.protodown_r_bit; } +<<<<<<< HEAD +======= +extern void zebra_main_router_started(void); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* zebra_northbound.c */ extern const struct frr_yang_module_info frr_zebra_info; diff --git a/zebra/zebra_script.c b/zebra/zebra_script.c index 6c34d12c6409..8631f67490a2 100644 --- a/zebra/zebra_script.c +++ b/zebra/zebra_script.c @@ -418,6 +418,10 @@ void lua_pushzebra_dplane_ctx(lua_State *L, const struct zebra_dplane_ctx *ctx) case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET: case DPLANE_OP_NONE: case DPLANE_OP_STARTUP_STAGE: +<<<<<<< HEAD +======= + case DPLANE_OP_VLAN_INSTALL: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) break; } /* Dispatch by op code */ } diff --git a/zebra/zebra_srte.c b/zebra/zebra_srte.c index c0b83382c457..eaac37837fd6 100644 --- a/zebra/zebra_srte.c +++ b/zebra/zebra_srte.c @@ -145,7 +145,11 @@ static int zebra_sr_policy_notify_update_client(struct zebra_sr_policy *policy, stream_putc(s, nhlfe->distance); stream_putl(s, 0); /* metric - not available */ nump = stream_get_endp(s); +<<<<<<< HEAD stream_putc(s, 0); +======= + stream_putw(s, 0); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } zapi_nexthop_from_nexthop(&znh, nhlfe->nexthop); @@ -155,7 +159,11 @@ static int zebra_sr_policy_notify_update_client(struct zebra_sr_policy *policy, num++; } +<<<<<<< HEAD stream_putc_at(s, nump, num); +======= + stream_putw_at(s, nump, num); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) stream_putw_at(s, 0, stream_get_endp(s)); client->nh_last_upd_time = monotime(NULL); diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 082d4609aacd..a271e3d81840 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -214,7 +214,11 @@ void zebra_srv6_locator_format_set(struct srv6_locator *locator, locator->sid_format = format; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: Locator %s format has changed, old=%s new=%s", __func__, locator->name, locator->sid_format ? ((struct srv6_sid_format *) @@ -237,7 +241,11 @@ void zebra_srv6_locator_format_set(struct srv6_locator *locator, zebra_srv6_sid_ctx_free(ctx); } +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: Locator %s format has changed, send SRV6_LOCATOR_DEL notification to zclients", __func__, locator->name); @@ -269,7 +277,11 @@ void zebra_srv6_locator_format_set(struct srv6_locator *locator, block_new->refcnt++; locator->sid_block = block_new; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: Locator %s format has changed, send SRV6_LOCATOR_ADD notification to zclients", __func__, locator->name); @@ -293,13 +305,21 @@ void zebra_srv6_sid_format_changed_cb(struct srv6_sid_format *format) struct listnode *node, *nnode; struct zebra_srv6_sid_ctx *ctx; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: SID format %s has changed. Notifying zclients.", __func__, format->name); for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) { if (locator->sid_format == format) { +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: Locator %s has changed because its format (%s) has been modified. Notifying zclients.", __func__, locator->name, format->name); @@ -801,7 +821,11 @@ static int zebra_srv6_manager_get_locator_chunk(struct srv6_locator **loc, if (!*loc) zlog_err("Unable to assign locator chunk to %s instance %u", zebra_route_string(client->proto), client->instance); +<<<<<<< HEAD else if (IS_ZEBRA_DEBUG_PACKET) +======= + else if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_info("Assigned locator chunk %s to %s instance %u", (*loc)->name, zebra_route_string(client->proto), client->instance); @@ -835,7 +859,11 @@ static int release_srv6_locator_chunk(uint8_t proto, uint16_t instance, if (!loc) return -1; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: Releasing srv6-locator on %s", __func__, locator_name); @@ -892,7 +920,11 @@ int release_daemon_srv6_locator_chunks(struct zserv *client) struct srv6_locator *loc; struct srv6_locator_chunk *chunk; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: Releasing chunks for client proto %s, instance %d, session %u", __func__, zebra_route_string(client->proto), client->instance, client->session_id); @@ -912,7 +944,11 @@ int release_daemon_srv6_locator_chunks(struct zserv *client) } } +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: Released %d srv6-locator chunks", __func__, count); @@ -1159,7 +1195,11 @@ static bool alloc_srv6_sid_func_explicit(struct zebra_srv6_sid_block *block, format = block->sid_format; +<<<<<<< HEAD if (ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: trying to allocate explicit SID function %u from block %pFX", __func__, sid_func, &block->prefix); @@ -1305,7 +1345,11 @@ static bool alloc_srv6_sid_func_explicit(struct zebra_srv6_sid_block *block, block->u.uncompressed.num_func_allocated++; } +<<<<<<< HEAD if (ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: allocated explicit SID function %u from block %pFX", __func__, sid_func, &block->prefix); @@ -1331,7 +1375,11 @@ static bool alloc_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block, format = block->sid_format; +<<<<<<< HEAD if (ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: trying to allocate dynamic SID function from block %pFX", __func__, &block->prefix); @@ -1465,7 +1513,11 @@ static bool alloc_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block, block->u.uncompressed.num_func_allocated++; } +<<<<<<< HEAD if (ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: allocated dynamic SID function %u from block %pFX", __func__, *sid_func, &block->prefix); @@ -1510,7 +1562,11 @@ static int get_srv6_sid_explicit(struct zebra_srv6_sid **sid, * return the existing SID */ if (sid_same(&s->sid->value, sid_value)) { +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: returning existing SRv6 SID %pI6 ctx %s", __func__, &s->sid->value, srv6_sid_ctx2str(buf, @@ -1569,7 +1625,11 @@ static int get_srv6_sid_explicit(struct zebra_srv6_sid **sid, * deallocate the current SID function before allocating the new one */ if (zctx->sid) { +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: ctx %s already associated with a dynamic SID %pI6, releasing dynamic SID", __func__, srv6_sid_ctx2str(buf, sizeof(buf), @@ -1595,7 +1655,11 @@ static int get_srv6_sid_explicit(struct zebra_srv6_sid **sid, zctx->sid = *sid; listnode_add(srv6->sids, zctx); +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: allocated explicit SRv6 SID %pI6 for context %s", __func__, &(*sid)->value, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); @@ -1648,7 +1712,11 @@ static int get_srv6_sid_dynamic(struct zebra_srv6_sid **sid, } } if (memcmp(&s->ctx, ctx, sizeof(struct srv6_sid_ctx)) == 0) { +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: returning existing SID %s %pI6", __func__, srv6_sid_ctx2str(buf, sizeof(buf), @@ -1695,7 +1763,11 @@ static int get_srv6_sid_dynamic(struct zebra_srv6_sid **sid, zctx->sid = *sid; listnode_add(srv6->sids, zctx); +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: allocated new dynamic SRv6 SID %pI6 for context %s", __func__, &(*sid)->value, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); @@ -1733,7 +1805,11 @@ int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx, (sid_value) ? SRV6_SID_ALLOC_MODE_EXPLICIT : SRV6_SID_ALLOC_MODE_DYNAMIC; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: received SRv6 SID alloc request: SID ctx %s (%pI6), mode=%s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value, srv6_sid_alloc_mode2str(alloc_mode)); @@ -1794,7 +1870,11 @@ static bool release_srv6_sid_func_explicit(struct zebra_srv6_sid_block *block, format = block->sid_format; +<<<<<<< HEAD if (ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: trying to release explicit SRv6 SID function %u from block %pFX", __func__, sid_func, &block->prefix); @@ -1918,7 +1998,11 @@ static bool release_srv6_sid_func_explicit(struct zebra_srv6_sid_block *block, zebra_srv6_sid_func_free(sid_func_ptr); } +<<<<<<< HEAD if (ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: released explicit SRv6 SID function %u from block %pFX", __func__, sid_func, &block->prefix); @@ -1944,7 +2028,11 @@ static int release_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block, format = block->sid_format; +<<<<<<< HEAD if (ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: trying to release dynamic SRv6 SID function %u from block %pFX", __func__, sid_func, &block->prefix); @@ -2107,7 +2195,11 @@ static int release_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block, } } +<<<<<<< HEAD if (ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: released dynamic SRv6 SID function %u from block %pFX", __func__, sid_func, &block->prefix); @@ -2129,7 +2221,11 @@ int release_srv6_sid(struct zserv *client, struct zebra_srv6_sid_ctx *zctx) if (!zctx || !zctx->sid) return -1; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: releasing SRv6 SID %pI6 associated with ctx %s (proto=%u, instance=%u)", __func__, &zctx->sid->value, srv6_sid_ctx2str(buf, sizeof(buf), &zctx->ctx), @@ -2145,7 +2241,11 @@ int release_srv6_sid(struct zserv *client, struct zebra_srv6_sid_ctx *zctx) /* Remove the client from the list of clients using the SID */ listnode_delete(zctx->sid->client_list, client); +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: released SRv6 SID %pI6 associated with ctx %s (proto=%u, instance=%u)", __func__, &zctx->sid->value, srv6_sid_ctx2str(buf, sizeof(buf), &zctx->ctx), @@ -2156,7 +2256,11 @@ int release_srv6_sid(struct zserv *client, struct zebra_srv6_sid_ctx *zctx) * and remove it from the SRv6 database. */ if (listcount(zctx->sid->client_list) == 0) { +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: SRv6 SID %pI6 associated with ctx %s is no longer in use, removing it from SRv6 database", __func__, &zctx->sid->value, srv6_sid_ctx2str(buf, sizeof(buf), @@ -2251,7 +2355,11 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, struct zserv *c; char buf[256]; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: getting SRv6 SID for ctx %s, sid_value=%pI6, locator_name=%s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value ? sid_value : &in6addr_any, locator_name); @@ -2266,7 +2374,12 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, zsend_srv6_sid_notify(client, ctx, sid_value, 0, 0, NULL, ZAPI_SRV6_SID_FAIL_ALLOC); } else if (ret == 0) { +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + assert(*sid); + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: got existing SRv6 SID for ctx %s: sid_value=%pI6 (func=%u) (proto=%u, instance=%u, sessionId=%u), notify client", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), @@ -2281,7 +2394,11 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, : NULL, ZAPI_SRV6_SID_ALLOCATED); } else { +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: got new SRv6 SID for ctx %s: sid_value=%pI6 (func=%u) (proto=%u, instance=%u, sessionId=%u), notifying all clients", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), @@ -2318,7 +2435,11 @@ int release_daemon_srv6_sids(struct zserv *client) int count = 0; int ret; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: releasing SRv6 SIDs for client proto %s, instance %d, session %u", __func__, zebra_route_string(client->proto), client->instance, client->session_id); @@ -2333,7 +2454,11 @@ int release_daemon_srv6_sids(struct zserv *client) count++; } +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: released %d SRv6 SIDs", __func__, count); return count; @@ -2356,7 +2481,11 @@ static int srv6_manager_release_sid_internal(struct zserv *client, char buf[256]; const char *locator_name = NULL; +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: releasing SRv6 SID associated with ctx %s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); @@ -2370,7 +2499,11 @@ static int srv6_manager_release_sid_internal(struct zserv *client, break; } +<<<<<<< HEAD if (IS_ZEBRA_DEBUG_PACKET) +======= + if (IS_ZEBRA_DEBUG_SRV6) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zlog_debug("%s: no SID associated with ctx %s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index e464e47b1f0c..5b9ac0f3370c 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -398,6 +398,10 @@ vrf_id_t zebra_vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { zvrf = vrf->info; +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (zvrf == NULL) continue; /* case vrf with netns : match the netnsid */ @@ -408,6 +412,10 @@ vrf_id_t zebra_vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) /* VRF is VRF_BACKEND_VRF_LITE */ if (zvrf->table_id != table_id) continue; +<<<<<<< HEAD +======= + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return zvrf_id(zvrf); } } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 303146c292d3..07f571220348 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -370,7 +370,11 @@ static void show_nexthop_detail_helper(struct vty *vty, break; } +<<<<<<< HEAD if (re->vrf_id != nexthop->vrf_id) { +======= + if (re->vrf_id != nexthop->vrf_id && nexthop->type != NEXTHOP_TYPE_BLACKHOLE) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id); vty_out(vty, "(vrf %s)", VRF_LOGNAME(vrf)); @@ -858,6 +862,30 @@ static void vty_show_ip_route_detail_json(struct vty *vty, vty_json(vty, json); } +<<<<<<< HEAD +======= +static void zebra_vty_display_vrf_header(struct vty *vty, struct zebra_vrf *zvrf, uint32_t tableid) +{ + if (!tableid) + vty_out(vty, "VRF %s:\n", zvrf_name(zvrf)); + else { + if (vrf_is_backend_netns()) + vty_out(vty, "VRF %s table %u:\n", zvrf_name(zvrf), tableid); + else { + vrf_id_t vrf = zebra_vrf_lookup_by_table(tableid, zvrf->zns->ns_id); + + if (vrf == VRF_DEFAULT && tableid != RT_TABLE_ID_MAIN) + vty_out(vty, "table %u:\n", tableid); + else { + struct zebra_vrf *zvrf2 = zebra_vrf_lookup_by_id(vrf); + + vty_out(vty, "VRF %s table %u:\n", zvrf_name(zvrf2), tableid); + } + } + } +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, struct route_table *table, afi_t afi, bool use_fib, route_tag_t tag, @@ -937,6 +965,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, } if (ctx->multi && ctx->header_done) vty_out(vty, "\n"); +<<<<<<< HEAD if (ctx->multi || zvrf_id(zvrf) != VRF_DEFAULT || tableid) { if (!tableid) @@ -948,6 +977,11 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, zvrf_name(zvrf), tableid); } +======= + if (ctx->multi || zvrf_id(zvrf) != VRF_DEFAULT || tableid) + zebra_vty_display_vrf_header(vty, zvrf, tableid); + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) ctx->header_done = true; first = 0; } @@ -3594,17 +3628,28 @@ static int zebra_ip_config(struct vty *vty) return write; } +<<<<<<< HEAD DEFUN (ip_zebra_import_table_distance, ip_zebra_import_table_distance_cmd, "ip import-table (1-252) [distance (1-255)] [route-map RMAP_NAME]", IP_STR "import routes from non-main kernel table\n" "kernel routing table id\n" +======= +DEFPY (ip_zebra_import_table_distance, + ip_zebra_import_table_distance_cmd, + "ip import-table (1-252)$table_id [mrib]$mrib [distance (1-255)$distance] [route-map RMAP_NAME$rmap]", + IP_STR + "import routes from non-main kernel table\n" + "kernel routing table id\n" + "Import into the MRIB instead of the URIB\n" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "Distance for imported routes\n" "Default distance value\n" "route-map for filtering\n" "route-map name\n") { +<<<<<<< HEAD uint32_t table_id = 0; table_id = strtoul(argv[2]->arg, NULL, 10); @@ -3624,10 +3669,20 @@ DEFUN (ip_zebra_import_table_distance, table_id); if (rmap) XFREE(MTYPE_ROUTE_MAP_NAME, rmap); +======= + safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST; + + if (distance_str == NULL) + distance = ZEBRA_TABLE_DISTANCE_DEFAULT; + + if (!is_zebra_valid_kernel_table(table_id)) { + vty_out(vty, "Invalid routing table ID, %ld. Must be in range 1-252\n", table_id); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return CMD_WARNING; } if (is_zebra_main_routing_table(table_id)) { +<<<<<<< HEAD vty_out(vty, "Invalid routing table ID, %d. Must be non-default table\n", table_id); @@ -3642,6 +3697,13 @@ DEFUN (ip_zebra_import_table_distance, XFREE(MTYPE_ROUTE_MAP_NAME, rmap); return ret; +======= + vty_out(vty, "Invalid routing table ID, %ld. Must be non-default table\n", table_id); + return CMD_WARNING; + } + + return zebra_import_table(AFI_IP, safi, VRF_DEFAULT, table_id, distance, rmap, true); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } DEFUN_HIDDEN (zebra_packet_process, @@ -3700,20 +3762,34 @@ DEFUN_HIDDEN (no_zebra_workqueue_timer, return CMD_SUCCESS; } +<<<<<<< HEAD DEFUN (no_ip_zebra_import_table, no_ip_zebra_import_table_cmd, "no ip import-table (1-252) [distance (1-255)] [route-map NAME]", +======= +DEFPY (no_ip_zebra_import_table, + no_ip_zebra_import_table_cmd, + "no ip import-table (1-252)$table_id [mrib]$mrib [distance (1-255)] [route-map NAME]", +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) NO_STR IP_STR "import routes from non-main kernel table\n" "kernel routing table id\n" +<<<<<<< HEAD +======= + "Import into the MRIB instead of the URIB\n" +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) "Distance for imported routes\n" "Default distance value\n" "route-map for filtering\n" "route-map name\n") { +<<<<<<< HEAD uint32_t table_id = 0; table_id = strtoul(argv[3]->arg, NULL, 10); +======= + safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!is_zebra_valid_kernel_table(table_id)) { vty_out(vty, @@ -3722,6 +3798,7 @@ DEFUN (no_ip_zebra_import_table, } if (is_zebra_main_routing_table(table_id)) { +<<<<<<< HEAD vty_out(vty, "Invalid routing table ID, %d. Must be non-default table\n", table_id); @@ -3732,6 +3809,16 @@ DEFUN (no_ip_zebra_import_table, return CMD_SUCCESS; return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0)); +======= + vty_out(vty, "Invalid routing table ID, %ld. Must be non-default table\n", table_id); + return CMD_WARNING; + } + + if (!is_zebra_import_table_enabled(AFI_IP, safi, VRF_DEFAULT, table_id)) + return CMD_SUCCESS; + + return (zebra_import_table(AFI_IP, safi, VRF_DEFAULT, table_id, 0, NULL, false)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } DEFPY (zebra_nexthop_group_keep, diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index f1ae42e32043..d89fead2c42c 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -172,8 +172,12 @@ static int host_rb_entry_compare(const struct host_rb_entry *hle1, return 0; } else { +<<<<<<< HEAD zlog_debug("%s: Unexpected family type: %d", __func__, hle1->p.family); +======= + assert(!"Received unexpected family type, dev escape"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } } @@ -859,6 +863,7 @@ static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data) vty_out(vty, "\n"); } +<<<<<<< HEAD static int zvni_map_to_svi_ns(struct ns *ns, void *_in_param, void **_p_ifp) @@ -892,6 +897,32 @@ static int zvni_map_to_svi_ns(struct ns *ns, return NS_WALK_STOP; } } +======= +static int zvni_map_to_svi_ns(struct interface *tmp_if, void *_in_param) +{ + struct zebra_from_svi_param *in_param = _in_param; + struct zebra_l2info_vlan *vl; + struct zebra_if *zif; + + assert(in_param); + + /* TODO: Optimize with a hash. */ + + /* Check oper status of the SVI. */ + if (!tmp_if || !if_is_operative(tmp_if)) + goto done; + zif = tmp_if->info; + if (!zif || zif->zif_type != ZEBRA_IF_VLAN || zif->link != in_param->br_if) + goto done; + vl = (struct zebra_l2info_vlan *)&zif->l2info.vl; + + if (vl->vid == in_param->vid) { + in_param->ret_ifp = tmp_if; + return NS_WALK_STOP; + } + +done: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NS_WALK_CONTINUE; } @@ -904,10 +935,16 @@ static int zvni_map_to_svi_ns(struct ns *ns, */ struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if) { +<<<<<<< HEAD struct interface *tmp_if = NULL; struct zebra_if *zif; struct zebra_from_svi_param in_param; struct interface **p_ifp; +======= + struct zebra_if *zif; + struct zebra_from_svi_param in_param = {}; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* Defensive check, caller expected to invoke only with valid bridge. */ if (!br_if) return NULL; @@ -922,12 +959,20 @@ struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if) in_param.vid = vid; in_param.br_if = br_if; +<<<<<<< HEAD in_param.zif = NULL; p_ifp = &tmp_if; /* Identify corresponding VLAN interface. */ ns_walk_func(zvni_map_to_svi_ns, (void *)&in_param, (void **)p_ifp); return tmp_if; +======= + + /* Identify corresponding VLAN interface. */ + zebra_ns_ifp_walk_all(zvni_map_to_svi_ns, &in_param); + + return in_param.ret_ifp; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn) @@ -1007,9 +1052,15 @@ static int zevpn_build_vni_hash_table(struct zebra_if *zif, */ zevpn = zebra_evpn_lookup(vni); if (zevpn) { +<<<<<<< HEAD zlog_debug( "EVPN hash already present for IF %s(%u) L2-VNI %u", ifp->name, ifp->ifindex, vni); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("EVPN hash already present for IF %s(%u) L2-VNI %u", + ifp->name, ifp->ifindex, vni); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Inform BGP if intf is up and mapped to @@ -1026,9 +1077,15 @@ static int zevpn_build_vni_hash_table(struct zebra_if *zif, } else { zevpn = zebra_evpn_add(vni); if (!zevpn) { +<<<<<<< HEAD zlog_debug( "Failed to add EVPN hash, IF %s(%u) L2-VNI %u", ifp->name, ifp->ifindex, vni); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Failed to add EVPN hash, IF %s(%u) L2-VNI %u", + ifp->name, ifp->ifindex, vni); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return 0; } @@ -1072,6 +1129,7 @@ static int zevpn_build_vni_hash_table(struct zebra_if *zif, return 0; } +<<<<<<< HEAD static int zevpn_build_hash_table_zns(struct ns *ns, void *param_in __attribute__((unused)), void **param_out __attribute__((unused))) @@ -1114,6 +1172,34 @@ static int zevpn_build_hash_table_zns(struct ns *ns, zebra_vxlan_if_vni_iterate(zif, zevpn_build_vni_hash_table, NULL); } +======= +static int zevpn_build_hash_table_zns(struct interface *ifp, void *arg) +{ + struct zebra_vrf *zvrf = arg; + struct zebra_if *zif; + struct zebra_l2info_vxlan *vxl; + + zif = ifp->info; + if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) + goto done; + + vxl = &zif->l2info.vxl; + /* link of VXLAN interface should be in zebra_evpn_vrf */ + if (zvrf->zns->ns_id != vxl->link_nsid) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Intf %s(%u) link not in same namespace as BGP EVPN core instance", + ifp->name, ifp->ifindex); + goto done; + } + + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Building vni table for %s-if %s", + IS_ZEBRA_VXLAN_IF_VNI(zif) ? "vni" : "svd", ifp->name); + + zebra_vxlan_if_vni_iterate(zif, zevpn_build_vni_hash_table, NULL); + +done: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NS_WALK_CONTINUE; } @@ -1124,7 +1210,17 @@ static int zevpn_build_hash_table_zns(struct ns *ns, static void zevpn_build_hash_table(void) { +<<<<<<< HEAD ns_walk_func(zevpn_build_hash_table_zns, NULL, NULL); +======= + struct zebra_vrf *zvrf; + + zvrf = zebra_vrf_get_evpn(); + if (zvrf == NULL) + return; + + zebra_ns_ifp_walk_all(zevpn_build_hash_table_zns, zvrf); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* @@ -1375,9 +1471,15 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, /* Create the RMAC entry, or update its vtep, if necessary. */ zrmac = zl3vni_rmac_add(zl3vni, rmac); if (!zrmac) { +<<<<<<< HEAD zlog_debug( "Failed to add RMAC %pEA L3VNI %u Remote VTEP %pIA", rmac, zl3vni->vni, vtep_ip); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Failed to add RMAC %pEA L3VNI %u Remote VTEP %pIA", + rmac, zl3vni->vni, vtep_ip); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info)); @@ -1699,9 +1801,15 @@ static int zl3vni_remote_nh_add(struct zebra_l3vni *zl3vni, if (!nh) { nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac); if (!nh) { +<<<<<<< HEAD zlog_debug( "Failed to add NH %pIA as Neigh (RMAC %pEA L3-VNI %u prefix %pFX)", vtep_ip, rmac, zl3vni->vni, host_prefix); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Failed to add NH %pIA as Neigh (RMAC %pEA L3-VNI %u prefix %pFX)", + vtep_ip, rmac, zl3vni->vni, host_prefix); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } @@ -1757,9 +1865,15 @@ static int svd_remote_nh_add(struct zebra_l3vni *zl3vni, if (!nh) { nh = svd_nh_add(vtep_ip, rmac); if (!nh) { +<<<<<<< HEAD zlog_debug( "Failed to add NH %pIA as SVD Neigh (RMAC %pEA prefix %pFX)", vtep_ip, rmac, host_prefix); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Failed to add NH %pIA as SVD Neigh (RMAC %pEA prefix %pFX)", + vtep_ip, rmac, host_prefix); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } @@ -1805,7 +1919,12 @@ static int svd_remote_nh_del(struct zebra_l3vni *zl3vni, nh = svd_nh_lookup(vtep_ip); if (!nh) { +<<<<<<< HEAD zlog_debug("Failed to del NH %pIA as SVD Neigh", vtep_ip); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Failed to del NH %pIA as SVD Neigh", vtep_ip); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } @@ -1968,6 +2087,7 @@ static int zl3vni_del(struct zebra_l3vni *zl3vni) return 0; } +<<<<<<< HEAD static int zl3vni_map_to_vxlan_if_ns(struct ns *ns, void *_zl3vni, void **_pifp) @@ -2019,11 +2139,55 @@ static int zl3vni_map_to_vxlan_if_ns(struct ns *ns, return NS_WALK_STOP; } +======= +/* Context arg for zl3vni map iteration */ +struct zl3vni_map_arg { + struct zebra_vrf *zvrf; + struct zebra_l3vni *zl3vni; + struct interface *ret_ifp; +}; + +static int zl3vni_map_to_vxlan_if_ns(struct interface *ifp, void *arg) +{ + struct zl3vni_map_arg *ctx = arg; + struct zebra_l3vni *zl3vni = ctx->zl3vni; + struct zebra_vrf *zvrf = ctx->zvrf; + struct zebra_if *zif = NULL; + struct zebra_l2info_vxlan *vxl; + struct zebra_vxlan_vni *vni = NULL; + + /* look for vxlan-interface */ + + zif = ifp->info; + if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) + goto done; + + vxl = &zif->l2info.vxl; + vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni); + if (!vni || vni->vni != zl3vni->vni) + goto done; + + /* link of VXLAN interface should be in zebra_evpn_vrf */ + if (zvrf->zns->ns_id != vxl->link_nsid) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Intf %s(%u) VNI %u, link not in same namespace as BGP EVPN core instance", + ifp->name, ifp->ifindex, vni->vni); + goto done; + } + + zl3vni->local_vtep_ip = zif->l2info.vxl.vtep_ip; + ctx->ret_ifp = ifp; + + return NS_WALK_STOP; + +done: +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NS_WALK_CONTINUE; } struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni) { +<<<<<<< HEAD struct interface **p_ifp; struct interface *ifp = NULL; @@ -2032,6 +2196,19 @@ struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni) ns_walk_func(zl3vni_map_to_vxlan_if_ns, (void *)zl3vni, (void **)p_ifp); return ifp; +======= + struct zl3vni_map_arg arg = {}; + + arg.zl3vni = zl3vni; + arg.zvrf = zebra_vrf_get_evpn(); + + if (arg.zvrf == NULL) + return NULL; + + zebra_ns_ifp_walk_all(zl3vni_map_to_vxlan_if_ns, &arg); + + return arg.ret_ifp; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni) @@ -2086,6 +2263,7 @@ struct zebra_l3vni *zl3vni_from_vrf(vrf_id_t vrf_id) return zl3vni_lookup(zvrf->l3vni); } +<<<<<<< HEAD static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni) { int found = 0; @@ -2137,6 +2315,37 @@ static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni) return NS_WALK_CONTINUE; *p_zl3vni = zl3vni_lookup(vni_id); +======= +/* loop through all vxlan-interface */ +static int zl3vni_from_svi_ns(struct interface *tmp_if, void *_in_param) +{ + int found = 0; + vni_t vni_id = 0; + struct zebra_from_svi_param *in_param = _in_param; + struct zebra_if *zif = NULL; + + assert(in_param); + + zif = tmp_if->info; + if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) + goto done; + if (!if_is_operative(tmp_if)) + goto done; + + if (zif->brslave_info.br_if != in_param->br_if) + goto done; + + vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, in_param->br_if); + if (vni_id) { + in_param->zl3vni = zl3vni_lookup(vni_id); + found = 1; + } + +done: + if (!found) + return NS_WALK_CONTINUE; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return NS_WALK_STOP; } @@ -2147,10 +2356,18 @@ static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni) static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp, struct interface *br_if) { +<<<<<<< HEAD struct zebra_l3vni *zl3vni = NULL; struct zebra_if *zif = NULL; struct zebra_from_svi_param in_param = {}; struct zebra_l3vni **p_zl3vni; +======= + struct zebra_if *zif = NULL; + vni_t vni_id = 0; + struct zebra_if *br_zif = NULL; + struct zebra_from_svi_param in_param = {}; + struct zebra_l2info_vlan *vl; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!br_if) return NULL; @@ -2158,6 +2375,7 @@ static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp, /* Make sure the linked interface is a bridge. */ if (!IS_ZEBRA_IF_BRIDGE(br_if)) return NULL; +<<<<<<< HEAD in_param.br_if = br_if; /* Determine if bridge is VLAN-aware or not */ @@ -2167,6 +2385,17 @@ static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp, if (in_param.bridge_vlan_aware) { struct zebra_l2info_vlan *vl; +======= + + in_param.br_if = br_if; + + /* Determine if bridge is VLAN-aware or not */ + br_zif = br_if->info; + assert(br_zif); + + in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif); + if (in_param.bridge_vlan_aware) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (!IS_ZEBRA_IF_VLAN(ifp)) return NULL; @@ -2174,15 +2403,28 @@ static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp, assert(zif); vl = &zif->l2info.vl; in_param.vid = vl->vid; +<<<<<<< HEAD +======= + + vni_id = zebra_l2_bridge_if_vni_find(br_zif, in_param.vid); + if (vni_id) + return zl3vni_lookup(vni_id); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */ /* TODO: Optimize with a hash. */ +<<<<<<< HEAD p_zl3vni = &zl3vni; ns_walk_func(zl3vni_from_svi_ns, (void *)&in_param, (void **)p_zl3vni); return zl3vni; +======= + zebra_ns_ifp_walk_all(zl3vni_from_svi_ns, &in_param); + + return in_param.zl3vni; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if) @@ -2336,6 +2578,39 @@ static void zevpn_add_to_l3vni_list(struct hash_bucket *bucket, void *ctxt) listnode_add_sort(zl3vni->l2vnis, zevpn); } +<<<<<<< HEAD +======= +/* Helper for vni transition iterator */ + +struct vni_trans_ctx { + vni_t vni; + struct zebra_vxlan_vni *vnip; + struct interface *ret_ifp; +}; + +static int vni_trans_cb(struct interface *ifp, void *arg) +{ + struct vni_trans_ctx *ctx = arg; + struct zebra_if *zif; + struct zebra_vxlan_vni *vnip; + + /* Find VxLAN interface for this VNI. */ + zif = ifp->info; + if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) + goto done; + + vnip = zebra_vxlan_if_vni_find(zif, ctx->vni); + if (vnip) { + ctx->ret_ifp = ifp; + ctx->vnip = vnip; + return NS_WALK_STOP; + } + +done: + return NS_WALK_CONTINUE; +} + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Handle transition of vni from l2 to l3 and vice versa. * This function handles only the L2VNI add/delete part of @@ -2386,6 +2661,7 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, return -1; } } else { +<<<<<<< HEAD struct zebra_ns *zns; struct route_node *rn; struct interface *ifp; @@ -2394,11 +2670,20 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, struct zebra_l2info_vxlan *vxl; struct interface *vlan_if; bool found = false; +======= + struct zebra_vxlan_vni *vnip; + struct zebra_l2info_vxlan *vxl; + struct interface *vlan_if; + struct zebra_if *zif; + struct zebra_ns *zns; + struct vni_trans_ctx ctx = {}; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Adding L2-VNI %u - transition from L3-VNI", vni); +<<<<<<< HEAD /* Find VxLAN interface for this VNI. */ zns = zebra_ns_lookup(NS_DEFAULT); for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { @@ -2419,6 +2704,16 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, } if (!found) { +======= + zns = zebra_ns_lookup(NS_DEFAULT); + + ctx.vni = vni; + + /* Find VxLAN interface for this VNI. */ + zebra_ns_ifp_walk(zns, vni_trans_cb, &ctx); + + if (ctx.ret_ifp == NULL) { +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) if (IS_ZEBRA_DEBUG_VXLAN) zlog_err( "Adding L2-VNI - Failed to find VxLAN interface for VNI %u", @@ -2431,6 +2726,13 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, if (zevpn) return 0; +<<<<<<< HEAD +======= + zif = ctx.ret_ifp->info; + vnip = ctx.vnip; + vxl = &zif->l2info.vxl; + +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zevpn = zebra_evpn_add(vni); /* Find bridge interface for the VNI */ @@ -2443,6 +2745,7 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, listnode_add_sort_nodup(zl3vni->l2vnis, zevpn); } +<<<<<<< HEAD zevpn->vxlan_if = ifp; zevpn->local_vtep_ip = vxl->vtep_ip; @@ -2450,6 +2753,15 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, if (if_is_operative(ifp) && zif->brslave_info.br_if) { zebra_evpn_send_add_to_client(zevpn); zebra_evpn_read_mac_neigh(zevpn, ifp); +======= + zevpn->vxlan_if = ctx.ret_ifp; + zevpn->local_vtep_ip = vxl->vtep_ip; + + /* Inform BGP if the VNI is up and mapped to a bridge. */ + if (if_is_operative(ctx.ret_ifp) && zif->brslave_info.br_if) { + zebra_evpn_send_add_to_client(zevpn); + zebra_evpn_read_mac_neigh(zevpn, ctx.ret_ifp); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) } } @@ -4108,9 +4420,15 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp, } if (!zevpn->vxlan_if) { +<<<<<<< HEAD zlog_debug( "VNI %u hash %p doesn't have intf upon local neighbor DEL", zevpn->vni, zevpn); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("VNI %u hash %p doesn't have intf upon local neighbor DEL", + zevpn->vni, zevpn); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } @@ -4284,7 +4602,12 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) char esi_buf[ESI_STR_LEN]; if (!EVPN_ENABLED(zvrf)) { +<<<<<<< HEAD zlog_debug("EVPN not enabled, ignoring remote MACIP ADD"); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("EVPN not enabled, ignoring remote MACIP ADD"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -4556,9 +4879,15 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, if (!zevpn) return 0; if (!zevpn->vxlan_if) { +<<<<<<< HEAD zlog_debug( "VNI %u hash %p doesn't have intf upon local MAC DEL", zevpn->vni, zevpn); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("VNI %u hash %p doesn't have intf upon local MAC DEL", + zevpn->vni, zevpn); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } @@ -4626,15 +4955,26 @@ void zebra_vxlan_remote_vtep_del_zapi(ZAPI_HANDLER_ARGS) struct in_addr vtep_ip; if (!is_evpn_enabled()) { +<<<<<<< HEAD zlog_debug( "%s: EVPN is not enabled yet we have received a VTEP DEL msg", __func__); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s: EVPN is not enabled yet we have received a VTEP DEL msg", + __func__); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } if (!EVPN_ENABLED(zvrf)) { +<<<<<<< HEAD zlog_debug("Recv VTEP DEL zapi for non-EVPN VRF %u", zvrf_id(zvrf)); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Recv VTEP DEL zapi for non-EVPN VRF %u", zvrf_id(zvrf)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -4679,8 +5019,13 @@ void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni, struct zebra_vrf *zvrf; if (!is_evpn_enabled()) { +<<<<<<< HEAD zlog_debug("%s: Can't process vtep del: EVPN is not enabled", __func__); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s: Can't process vtep del: EVPN is not enabled", __func__); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -4689,8 +5034,13 @@ void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni, return; if (!EVPN_ENABLED(zvrf)) { +<<<<<<< HEAD zlog_debug("Can't process VTEP DEL for non-EVPN VRF %u", zvrf_id(zvrf)); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Can't process VTEP DEL for non-EVPN VRF %u", zvrf_id(zvrf)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -4706,9 +5056,15 @@ void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni, ifp = zevpn->vxlan_if; if (!ifp) { +<<<<<<< HEAD zlog_debug( "VNI %u hash %p doesn't have intf upon remote VTEP DEL", zevpn->vni, zevpn); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("VNI %u hash %p doesn't have intf upon remote VTEP DEL", + zevpn->vni, zevpn); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } zif = ifp->info; @@ -4743,8 +5099,13 @@ void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni, struct zebra_vrf *zvrf; if (!is_evpn_enabled()) { +<<<<<<< HEAD zlog_debug("%s: EVPN not enabled: can't process a VTEP ADD", __func__); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s: EVPN not enabled: can't process a VTEP ADD", __func__); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -4753,8 +5114,13 @@ void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni, return; if (!EVPN_ENABLED(zvrf)) { +<<<<<<< HEAD zlog_debug("Can't process VTEP ADD for non-EVPN VRF %u", zvrf_id(zvrf)); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Can't process VTEP ADD for non-EVPN VRF %u", zvrf_id(zvrf)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -4780,8 +5146,18 @@ void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni, zif = ifp->info; /* If down or not mapped to a bridge, we're done. */ +<<<<<<< HEAD if (!if_is_operative(ifp) || !zif->brslave_info.br_if) return; +======= + if (!if_is_operative(ifp) || !zif->brslave_info.br_if) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s VNI %u VTEP %pI4 ifp %s oper %u br_if %u skipping update", + __func__, zevpn->vni, &vtep_ip, ifp->name, if_is_operative(ifp), + !zif->brslave_info.br_if); + return; + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip); if (zvtep) { @@ -4821,15 +5197,26 @@ void zebra_vxlan_remote_vtep_add_zapi(ZAPI_HANDLER_ARGS) int flood_control; if (!is_evpn_enabled()) { +<<<<<<< HEAD zlog_debug( "%s: EVPN not enabled yet we received a VTEP ADD zapi msg", __func__); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s: EVPN not enabled yet we received a VTEP ADD zapi msg", + __func__); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } if (!EVPN_ENABLED(zvrf)) { +<<<<<<< HEAD zlog_debug("Recv VTEP ADD zapi for non-EVPN VRF %u", zvrf_id(zvrf)); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Recv VTEP ADD zapi for non-EVPN VRF %u", zvrf_id(zvrf)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -4897,8 +5284,14 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, const struct prefix *p, svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifp_zif->link_ifindex); if (!svi_if) { +<<<<<<< HEAD zlog_debug("MACVLAN %s(%u) without link information", ifp->name, ifp->ifindex); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("MACVLAN %s(%u) without link information", ifp->name, + ifp->ifindex); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } @@ -4946,8 +5339,14 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, const struct prefix *p, return 0; if (!zevpn->vxlan_if) { +<<<<<<< HEAD zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up", zevpn->vni, zevpn); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up", zevpn->vni, + zevpn); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } @@ -5064,9 +5463,15 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) return 0; if (!zevpn->vxlan_if) { +<<<<<<< HEAD zlog_debug( "VNI %u hash %p doesn't have intf upon SVI up", zevpn->vni, zevpn); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("VNI %u hash %p doesn't have intf upon SVI up", + zevpn->vni, zevpn); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return -1; } @@ -5376,8 +5781,13 @@ void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS) struct interface *ifp = NULL; if (!EVPN_ENABLED(zvrf)) { +<<<<<<< HEAD zlog_debug("EVPN SVI-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("EVPN SVI-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -5484,8 +5894,13 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS) struct zebra_vxlan_vni *zl2_info_vni = NULL; if (!EVPN_ENABLED(zvrf)) { +<<<<<<< HEAD zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -5549,8 +5964,13 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) struct interface *ifp = NULL; if (!EVPN_ENABLED(zvrf)) { +<<<<<<< HEAD zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); +======= + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u", zvrf_id(zvrf)); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -6246,3 +6666,117 @@ extern void zebra_evpn_init(void) { hook_register(zserv_client_close, zebra_evpn_cfg_clean_up); } +<<<<<<< HEAD +======= + +static const char *port_state2str(uint8_t state) +{ + switch (state) { + case ZEBRA_DPLANE_BR_STATE_DISABLED: + return "DISABLED"; + case ZEBRA_DPLANE_BR_STATE_LISTENING: + return "LISTENING"; + case ZEBRA_DPLANE_BR_STATE_LEARNING: + return "LEARNING"; + case ZEBRA_DPLANE_BR_STATE_FORWARDING: + return "FORWARDING"; + case ZEBRA_DPLANE_BR_STATE_BLOCKING: + return "BLOCKING"; + } + + return "UNKNOWN"; +} + +static void vxlan_vni_state_change(struct zebra_if *zif, uint16_t id, + uint8_t state) +{ + struct zebra_vxlan_vni *vnip; + + vnip = zebra_vxlan_if_vlanid_vni_find(zif, id); + + if (!vnip) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Cannot find VNI for VID (%u) IF %s for vlan state update", + id, zif->ifp->name); + + return; + } + + switch (state) { + case ZEBRA_DPLANE_BR_STATE_FORWARDING: + zebra_vxlan_if_vni_up(zif->ifp, vnip); + break; + case ZEBRA_DPLANE_BR_STATE_BLOCKING: + zebra_vxlan_if_vni_down(zif->ifp, vnip); + break; + case ZEBRA_DPLANE_BR_STATE_DISABLED: + case ZEBRA_DPLANE_BR_STATE_LISTENING: + case ZEBRA_DPLANE_BR_STATE_LEARNING: + default: + /* Not used for anything at the moment */ + break; + } +} + +static void vlan_id_range_state_change(struct interface *ifp, uint16_t id_start, + uint16_t id_end, uint8_t state) +{ + struct zebra_if *zif; + + zif = (struct zebra_if *)ifp->info; + + if (!zif) + return; + + for (uint16_t i = id_start; i <= id_end; i++) + vxlan_vni_state_change(zif, i, state); +} + +void zebra_vlan_dplane_result(struct zebra_dplane_ctx *ctx) +{ + int i; + struct interface *ifp = NULL; + ns_id_t ns_id = dplane_ctx_get_ns_id(ctx); + enum dplane_op_e op = dplane_ctx_get_op(ctx); + const struct zebra_vxlan_vlan_array *vlan_array = + dplane_ctx_get_vxlan_vlan_array(ctx); + ifindex_t ifindex = dplane_ctx_get_vlan_ifindex(ctx); + + ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), ifindex); + if (!ifp) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Cannot find bridge-vlan IF (%u) for vlan update", ifindex); + return; + } + + if (!IS_ZEBRA_IF_VXLAN(ifp)) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("Ignoring non-vxlan IF (%s) for vlan update", + ifp->name); + + return; + } + + if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Dequeuing in zebra main..%s IF %s ifindex %u NS %u", + dplane_op2str(op), ifp->name, ifindex, ns_id); + + for (i = 0; i < vlan_array->count; i++) { + vlanid_t vid = vlan_array->vlans[i].vid; + uint8_t state = vlan_array->vlans[i].state; + uint32_t vrange = vlan_array->vlans[i].vrange; + + if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN) { + if (vrange) + zlog_debug("VLANDB_ENTRY: VID (%u-%u) state=%s", + vid, vrange, port_state2str(state)); + else + zlog_debug("VLANDB_ENTRY: VID (%u) state=%s", + vid, port_state2str(state)); + } + + vlan_id_range_state_change(ifp, vid, (vrange ? vrange : vid), + state); + } +} +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index eb02de6f7b40..c62eb62b63ca 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -221,7 +221,11 @@ extern int zebra_vxlan_dp_network_mac_del(struct interface *ifp, extern void zebra_vxlan_set_accept_bgp_seq(bool set); extern bool zebra_vxlan_get_accept_bgp_seq(void); +<<<<<<< HEAD +======= +extern void zebra_vlan_dplane_result(struct zebra_dplane_ctx *ctx); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) #ifdef __cplusplus } #endif diff --git a/zebra/zebra_vxlan_if.c b/zebra/zebra_vxlan_if.c index 17ab05c1f3f5..b3731144445c 100644 --- a/zebra/zebra_vxlan_if.c +++ b/zebra/zebra_vxlan_if.c @@ -1032,7 +1032,17 @@ int zebra_vxlan_if_vni_up(struct interface *ifp, struct zebra_vxlan_vni *vnip) /* If part of a bridge, inform BGP about this VNI. */ /* Also, read and populate local MACs and neighbors. */ if (zif->brslave_info.br_if) { +<<<<<<< HEAD zebra_evpn_send_add_to_client(zevpn); +======= + if (if_is_operative(zevpn->vxlan_if)) { + zebra_evpn_send_add_to_client(zevpn); + } else { + if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s VNI %u vxlan_if %s oper down skipping vni up to client", + __func__, zevpn->vni, zevpn->vxlan_if->name); + } +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zebra_evpn_read_mac_neigh(zevpn, ifp); } } diff --git a/zebra/zserv.c b/zebra/zserv.c index 07e399664316..9005147d242d 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -57,6 +57,10 @@ extern struct zebra_privs_t zserv_privs; /* The listener socket for clients connecting to us */ static int zsock; +<<<<<<< HEAD +======= +static bool started_p; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* The lock that protects access to zapi client objects */ static pthread_mutex_t client_mutex; @@ -929,9 +933,22 @@ void zserv_close(void) /* Free client list's mutex */ pthread_mutex_destroy(&client_mutex); +<<<<<<< HEAD } void zserv_start(char *path) +======= + + started_p = false; +} + + +/* + * Open zebra's ZAPI listener socket. This is done early during startup, + * before zebra is ready to listen and accept client connections. + */ +void zserv_open(const char *path) +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) { int ret; mode_t old_mask; @@ -973,6 +990,29 @@ void zserv_start(char *path) path, safe_strerror(errno)); close(zsock); zsock = -1; +<<<<<<< HEAD +======= + } + + umask(old_mask); +} + +/* + * Start listening for ZAPI client connections. + */ +void zserv_start(const char *path) +{ + int ret; + + /* This may be called more than once during startup - potentially once + * per netns - but only do this work once. + */ + if (started_p) + return; + + if (zsock <= 0) { + flog_err_sys(EC_LIB_SOCKET, "Zserv socket open failed"); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) return; } @@ -986,7 +1026,11 @@ void zserv_start(char *path) return; } +<<<<<<< HEAD umask(old_mask); +======= + started_p = true; +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) zserv_event(NULL, ZSERV_ACCEPT); } diff --git a/zebra/zserv.h b/zebra/zserv.h index 87d2b4adbf81..0b9dd1d915c1 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -256,15 +256,35 @@ extern void zserv_init(void); extern void zserv_close(void); /* +<<<<<<< HEAD * Start Zebra API server. * * Allocates resources, creates the server socket and begins listening on the * socket. +======= + * Open Zebra API server socket. + * + * Create and open the server socket. +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) * * path * where to place the Unix domain socket */ +<<<<<<< HEAD extern void zserv_start(char *path); +======= +extern void zserv_open(const char *path); + +/* + * Start Zebra API server. + * + * Allocates resources and begins listening on the server socket. + * + * path + * where to place the Unix domain socket + */ +extern void zserv_start(const char *path); +>>>>>>> 9b0b9282d (bgpd: Fix bgp core with a possible Intf delete) /* * Send a message to a connected Zebra API client.