diff options
| -rw-r--r-- | bgpd/bgp_conditional_adv.c | 78 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 20 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_updgrp_adv.c | 4 | ||||
| -rw-r--r-- | doc/user/isisd.rst | 7 | ||||
| -rw-r--r-- | isisd/isis_cli.c | 44 | ||||
| -rw-r--r-- | pimd/pim_nb_config.c | 9 | ||||
| -rw-r--r-- | ripd/ripd.c | 1050 | ||||
| -rw-r--r-- | tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf | 1 | ||||
| -rw-r--r-- | tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py | 2 | ||||
| -rwxr-xr-x | tests/topotests/ospf_netns_vrf/__init__.py (renamed from tests/topotests/ospf_topo1_vrf/__init__.py) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r1/ospfd.conf (renamed from tests/topotests/ospf_topo1_vrf/r1/ospfd.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r1/ospfroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r1/ospfroute.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r1/ospfroute_down.txt (renamed from tests/topotests/ospf_topo1_vrf/r1/ospfroute_down.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r1/zebra.conf (renamed from tests/topotests/ospf_topo1_vrf/r1/zebra.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r1/zebraroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r1/zebraroute.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt (renamed from tests/topotests/ospf_topo1_vrf/r1/zebraroutedown.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r2/ospfd.conf (renamed from tests/topotests/ospf_topo1_vrf/r2/ospfd.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r2/ospfroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r2/ospfroute.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r2/ospfroute_down.txt (renamed from tests/topotests/ospf_topo1_vrf/r2/ospfroute_down.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r2/zebra.conf (renamed from tests/topotests/ospf_topo1_vrf/r2/zebra.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r2/zebraroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r2/zebraroute.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt (renamed from tests/topotests/ospf_topo1_vrf/r2/zebraroutedown.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r3/ospfd.conf (renamed from tests/topotests/ospf_topo1_vrf/r3/ospfd.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r3/ospfroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r3/ospfroute.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r3/ospfroute_down.txt (renamed from tests/topotests/ospf_topo1_vrf/r3/ospfroute_down.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r3/zebra.conf (renamed from tests/topotests/ospf_topo1_vrf/r3/zebra.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r3/zebraroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r3/zebraroute.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt (renamed from tests/topotests/ospf_topo1_vrf/r3/zebraroutedown.txt) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.dot (renamed from tests/topotests/ospf_topo1_vrf/test_ospf_topo1-vrf.dot) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.jpg (renamed from tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.jpg) | bin | 65859 -> 65859 bytes | |||
| -rw-r--r-- | tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py (renamed from tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.py) | 4 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/r1/ospf-route.json (renamed from tests/topotests/ospf_topo2/r1/ospf-route.json) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/r1/ospfd.conf (renamed from tests/topotests/ospf_topo2/r1/ospfd.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/r1/v4_route.json (renamed from tests/topotests/ospf_topo2/r1/v4_route.json) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/r1/zebra.conf (renamed from tests/topotests/ospf_topo2/r1/zebra.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/r2/ospf-route.json (renamed from tests/topotests/ospf_topo2/r2/ospf-route.json) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/r2/ospfd.conf (renamed from tests/topotests/ospf_topo2/r2/ospfd.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/r2/v4_route.json (renamed from tests/topotests/ospf_topo2/r2/v4_route.json) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/r2/zebra.conf (renamed from tests/topotests/ospf_topo2/r2/zebra.conf) | 0 | ||||
| -rw-r--r-- | tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py (renamed from tests/topotests/ospf_topo2/test_ospf_topo2.py) | 4 |
41 files changed, 580 insertions, 645 deletions
diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c index c0dd3d6f81..e5a4b0e9f7 100644 --- a/bgpd/bgp_conditional_adv.c +++ b/bgpd/bgp_conditional_adv.c @@ -82,7 +82,7 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, struct peer_af *paf; const struct prefix *dest_p; struct update_subgroup *subgrp; - struct attr dummy_attr = {0}, attr = {0}; + struct attr advmap_attr = {0}, attr = {0}; struct bgp_path_info_extra path_extra = {0}; route_map_result_t ret; @@ -110,55 +110,53 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, assert(dest_p); for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { - dummy_attr = *pi->attr; + advmap_attr = *pi->attr; /* Fill temp path_info */ prep_for_rmap_apply(&path, &path_extra, dest, pi, - pi->peer, &dummy_attr); + pi->peer, &advmap_attr); - RESET_FLAG(dummy_attr.rmap_change_flags); + RESET_FLAG(advmap_attr.rmap_change_flags); ret = route_map_apply(rmap, dest_p, &path); - bgp_attr_flush(&dummy_attr); - - if (ret != RMAP_PERMITMATCH) + if (ret != RMAP_PERMITMATCH || + !bgp_check_selected(pi, peer, addpath_capable, afi, + safi)) { + bgp_attr_flush(&advmap_attr); continue; + } - if (bgp_check_selected(pi, peer, addpath_capable, afi, - safi)) { - /* Skip route-map checks in - * subgroup_announce_check while executing from - * the conditional advertise scanner process. - * otherwise when route-map is also configured - * on same peer, routes in advertise-map may not - * be advertised as expected. + /* Skip route-map checks in + * subgroup_announce_check while executing from + * the conditional advertise scanner process. + * otherwise when route-map is also configured + * on same peer, routes in advertise-map may not + * be advertised as expected. + */ + if (update_type == ADVERTISE && + subgroup_announce_check(dest, pi, subgrp, dest_p, + &attr, &advmap_attr)) { + bgp_adj_out_set_subgroup(dest, subgrp, &attr, + pi); + } else { + /* If default originate is enabled for + * the peer, do not send explicit + * withdraw. This will prevent deletion + * of default route advertised through + * default originate. */ - if ((update_type == ADVERTISE) - && subgroup_announce_check(dest, pi, subgrp, - dest_p, &attr, - true)) - bgp_adj_out_set_subgroup(dest, subgrp, - &attr, pi); - else { - /* If default originate is enabled for - * the peer, do not send explicit - * withdraw. This will prevent deletion - * of default route advertised through - * default originate. - */ - if (CHECK_FLAG( - peer->af_flags[afi][safi], - PEER_FLAG_DEFAULT_ORIGINATE) - && is_default_prefix(dest_p)) - break; - - bgp_adj_out_unset_subgroup( - dest, subgrp, 1, - bgp_addpath_id_for_peer( - peer, afi, safi, - &pi->tx_addpath)); - } + if (CHECK_FLAG(peer->af_flags[afi][safi], + PEER_FLAG_DEFAULT_ORIGINATE) && + is_default_prefix(dest_p)) + break; + + bgp_adj_out_unset_subgroup( + dest, subgrp, 1, + bgp_addpath_id_for_peer( + peer, afi, safi, + &pi->tx_addpath)); } + bgp_attr_flush(&advmap_attr); } } UNSET_FLAG(subgrp->sflags, SUBGRP_STATUS_TABLE_REPARSING); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 8311cb207c..0238e36cdf 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1836,7 +1836,7 @@ void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr) bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct update_subgroup *subgrp, const struct prefix *p, struct attr *attr, - bool skip_rmap_check) + struct attr *post_attr) { struct bgp_filter *filter; struct peer *from; @@ -2067,8 +2067,16 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, } } - /* For modify attribute, copy it to temporary structure. */ - *attr = *piattr; + /* For modify attribute, copy it to temporary structure. + * post_attr comes from BGP conditional advertisements, where + * attributes are already processed by advertise-map route-map, + * and this needs to be saved instead of overwriting from the + * path attributes. + */ + if (post_attr) + *attr = *post_attr; + else + *attr = *piattr; /* If local-preference is not set. */ if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) @@ -2162,8 +2170,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, bgp_peer_as_override(bgp, afi, safi, peer, attr); /* Route map & unsuppress-map apply. */ - if (!skip_rmap_check - && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) { + if (!post_attr && + (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) { struct bgp_path_info rmap_path = {0}; struct bgp_path_info_extra dummy_rmap_path_extra = {0}; struct attr dummy_attr = {0}; @@ -2699,7 +2707,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, if (selected) { if (subgroup_announce_check(dest, selected, subgrp, p, &attr, - false)) { + NULL)) { /* Route is selected, if the route is already installed * in FIB, then it is advertised */ diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 317995594a..a8ec2dc907 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -785,7 +785,7 @@ extern bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct update_subgroup *subgrp, const struct prefix *p, struct attr *attr, - bool skip_rmap_check); + struct attr *post_attr); extern void bgp_peer_clear_node_queue_drain_immediate(struct peer *peer); extern void bgp_process_queues_drain_immediate(void); diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index dd140e48af..97b32643b0 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -691,7 +691,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp, safi)) { if (subgroup_announce_check(dest, ri, subgrp, dest_p, &attr, - false)) { + NULL)) { /* Check if route can be advertised */ if (advertise) { if (!bgp_check_withdrawal(bgp, @@ -910,7 +910,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) if (subgroup_announce_check( dest, pi, subgrp, bgp_dest_get_prefix(dest), - &attr, false)) + &attr, NULL)) bgp_adj_out_set_subgroup( dest, subgrp, &attr, pi); diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 5d53f60f93..f7d42d8200 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -396,13 +396,6 @@ Known limitations: may not exceed 65535. Optionally sets also the Segment Routing Local Block. The negative command always unsets both. -.. clicmd:: segment-routing local-block (16-1048575) (16-1048575) - - Set the Segment Routing Local Block i.e. the label range used by MPLS - to store label in the MPLS FIB for Adjacency SID. Note that the block size - may not exceed 65535. This command is deprecated in favor of the combined - 'segment-routing global-block A B local-block C D' command. - .. clicmd:: segment-routing node-msd (1-16) Set the Maximum Stack Depth supported by the router. The value depend of the diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 089ad5747c..c23b0f0dc1 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -1560,48 +1560,6 @@ void cli_show_isis_label_blocks(struct vty *vty, const struct lyd_node *dnode, } /* - * XPath: /frr-isisd:isis/instance/segment-routing/srlb - */ -DEFPY_HIDDEN( - isis_sr_local_block_label_range, isis_sr_local_block_label_range_cmd, - "segment-routing local-block (16-1048575)$lower_bound (16-1048575)$upper_bound", - SR_STR - "Segment Routing Local Block label range\n" - "The lower bound of the block\n" - "The upper bound of the block (block size may not exceed 65535)\n") -{ -#if CONFDATE > 20220217 -CPP_NOTICE("Use of the local-block command is deprecated") -#endif - nb_cli_enqueue_change(vty, - "./segment-routing/label-blocks/srlb/lower-bound", - NB_OP_MODIFY, lower_bound_str); - nb_cli_enqueue_change(vty, - "./segment-routing/label-blocks/srlb/upper-bound", - NB_OP_MODIFY, upper_bound_str); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_HIDDEN(no_isis_sr_local_block_label_range, - no_isis_sr_local_block_label_range_cmd, - "no segment-routing local-block [(16-1048575) (16-1048575)]", - NO_STR SR_STR - "Segment Routing Local Block label range\n" - "The lower bound of the block\n" - "The upper bound of the block (block size may not exceed 65535)\n") -{ - nb_cli_enqueue_change(vty, - "./segment-routing/label-blocks/srlb/lower-bound", - NB_OP_MODIFY, NULL); - nb_cli_enqueue_change(vty, - "./segment-routing/label-blocks/srlb/upper-bound", - NB_OP_MODIFY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -/* * XPath: /frr-isisd:isis/instance/segment-routing/msd/node-msd */ DEFPY_YANG (isis_sr_node_msd, @@ -3189,8 +3147,6 @@ void isis_cli_init(void) install_element(ISIS_NODE, &no_isis_sr_enable_cmd); install_element(ISIS_NODE, &isis_sr_global_block_label_range_cmd); install_element(ISIS_NODE, &no_isis_sr_global_block_label_range_cmd); - install_element(ISIS_NODE, &isis_sr_local_block_label_range_cmd); - install_element(ISIS_NODE, &no_isis_sr_local_block_label_range_cmd); install_element(ISIS_NODE, &isis_sr_node_msd_cmd); install_element(ISIS_NODE, &no_isis_sr_node_msd_cmd); install_element(ISIS_NODE, &isis_sr_prefix_sid_cmd); diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index 3766157295..8a78489ae0 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -31,6 +31,7 @@ #include "pim_ssm.h" #include "pim_ssmpingd.h" #include "pim_vxlan.h" +#include "pim_util.h" #include "log.h" #include "lib_errors.h" @@ -2833,6 +2834,14 @@ int lib_interface_gmp_address_family_static_group_create( ifp_name); return NB_ERR_VALIDATION; } + + yang_dnode_get_ip(&group_addr, args->dnode, "./group-addr"); + if (pim_is_group_224_0_0_0_24(group_addr.ip._v4_addr)) { + snprintf( + args->errmsg, args->errmsg_len, + "Groups within 224.0.0.0/24 are reserved and cannot be joined"); + return NB_ERR_VALIDATION; + } break; case NB_EV_PREPARE: case NB_EV_ABORT: diff --git a/ripd/ripd.c b/ripd/ripd.c index b7b62e28e1..8bfb200305 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -224,13 +224,15 @@ struct rip_info *rip_ecmp_replace(struct rip *rip, struct rip_info *rinfo_new) rip_zebra_ipv4_delete(rip, rp); /* Re-use the first entry, and delete the others. */ - for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo)) - if (tmp_rinfo != rinfo) { - RIP_TIMER_OFF(tmp_rinfo->t_timeout); - RIP_TIMER_OFF(tmp_rinfo->t_garbage_collect); - list_delete_node(list, node); - rip_info_free(tmp_rinfo); - } + for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo)) { + if (tmp_rinfo == rinfo) + continue; + + RIP_TIMER_OFF(tmp_rinfo->t_timeout); + RIP_TIMER_OFF(tmp_rinfo->t_garbage_collect); + list_delete_node(list, node); + rip_info_free(tmp_rinfo); + } RIP_TIMER_OFF(rinfo->t_timeout); RIP_TIMER_OFF(rinfo->t_garbage_collect); @@ -332,61 +334,56 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, const char *inout = rip_distribute == RIP_FILTER_OUT ? "out" : "in"; /* Input distribute-list filtering. */ - if (ri->list[rip_distribute]) { - if (access_list_apply(ri->list[rip_distribute], - (struct prefix *)p) - == FILTER_DENY) { - if (IS_RIP_DEBUG_PACKET) - zlog_debug("%pFX filtered by distribute %s", p, - inout); - return -1; - } + if (ri->list[rip_distribute] && + access_list_apply(ri->list[rip_distribute], (struct prefix *)p) == + FILTER_DENY) { + if (IS_RIP_DEBUG_PACKET) + zlog_debug("%pFX filtered by distribute %s", p, inout); + return -1; } - if (ri->prefix[rip_distribute]) { - if (prefix_list_apply(ri->prefix[rip_distribute], - (struct prefix *)p) - == PREFIX_DENY) { - if (IS_RIP_DEBUG_PACKET) - zlog_debug("%pFX filtered by prefix-list %s", p, - inout); - return -1; - } + + if (ri->prefix[rip_distribute] && + prefix_list_apply(ri->prefix[rip_distribute], (struct prefix *)p) == + PREFIX_DENY) { + if (IS_RIP_DEBUG_PACKET) + zlog_debug("%pFX filtered by prefix-list %s", p, inout); + return -1; } /* All interface filter check. */ dist = distribute_lookup(ri->rip->distribute_ctx, NULL); - if (dist) { - if (dist->list[distribute]) { - alist = access_list_lookup(AFI_IP, - dist->list[distribute]); + if (!dist) + return 0; - if (alist) { - if (access_list_apply(alist, (struct prefix *)p) - == FILTER_DENY) { - if (IS_RIP_DEBUG_PACKET) - zlog_debug( - "%pFX filtered by distribute %s", - p, inout); - return -1; - } + if (dist->list[distribute]) { + alist = access_list_lookup(AFI_IP, dist->list[distribute]); + + if (alist) { + if (access_list_apply(alist, (struct prefix *)p) == + FILTER_DENY) { + if (IS_RIP_DEBUG_PACKET) + zlog_debug( + "%pFX filtered by distribute %s", + p, inout); + return -1; } } - if (dist->prefix[distribute]) { - plist = prefix_list_lookup(AFI_IP, - dist->prefix[distribute]); - - if (plist) { - if (prefix_list_apply(plist, (struct prefix *)p) - == PREFIX_DENY) { - if (IS_RIP_DEBUG_PACKET) - zlog_debug( - "%pFX filtered by prefix-list %s", - p, inout); - return -1; - } + } + if (dist->prefix[distribute]) { + plist = prefix_list_lookup(AFI_IP, dist->prefix[distribute]); + + if (plist) { + if (prefix_list_apply(plist, (struct prefix *)p) == + PREFIX_DENY) { + if (IS_RIP_DEBUG_PACKET) + zlog_debug( + "%pFX filtered by prefix-list %s", + p, inout); + return -1; } } } + return 0; } @@ -532,46 +529,46 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, && IPV4_ADDR_SAME(&rinfo->nh.gate.ipv4, nexthop)) break; - if (!listnextnode(node)) { - /* Not found in the list */ + if (listnextnode(node)) + continue; - if (rte->metric > rinfo->metric) { - /* New route has a greater metric. - * Discard it. */ - route_unlock_node(rp); - return; - } + /* Not found in the list */ - if (rte->metric < rinfo->metric) - /* New route has a smaller metric. - * Replace the ECMP list - * with the new one in below. */ - break; + if (rte->metric > rinfo->metric) { + /* New route has a greater metric. + * Discard it. */ + route_unlock_node(rp); + return; + } - /* Metrics are same. We compare the distances. - */ - old_dist = rinfo->distance - ? rinfo->distance + if (rte->metric < rinfo->metric) + /* New route has a smaller metric. + * Replace the ECMP list + * with the new one in below. */ + break; + + /* Metrics are same. We compare the distances. + */ + old_dist = rinfo->distance ? rinfo->distance : ZEBRA_RIP_DISTANCE_DEFAULT; - if (new_dist > old_dist) { - /* New route has a greater distance. - * Discard it. */ - route_unlock_node(rp); - return; - } + if (new_dist > old_dist) { + /* New route has a greater distance. + * Discard it. */ + route_unlock_node(rp); + return; + } - if (new_dist < old_dist) - /* New route has a smaller distance. - * Replace the ECMP list - * with the new one in below. */ - break; + if (new_dist < old_dist) + /* New route has a smaller distance. + * Replace the ECMP list + * with the new one in below. */ + break; - /* Metrics and distances are both same. Keep - * "rinfo" null and - * the new route is added in the ECMP list in - * below. */ - } + /* Metrics and distances are both same. Keep + * "rinfo" null and + * the new route is added in the ECMP list in + * below. */ } if (rinfo) { @@ -1278,15 +1275,14 @@ static void rip_response_process(struct rip_packet *packet, int size, } /* For RIPv1, there won't be a valid netmask. - - This is a best guess at the masks. If everyone was using old - Ciscos before the 'ip subnet zero' option, it would be almost - right too :-) - - Cisco summarize ripv1 advertisements to the classful boundary - (/16 for class B's) except when the RIP packet does to inside - the classful network in question. */ - + * This is a best guess at the masks. If everyone was using old + * Ciscos before the 'ip subnet zero' option, it would be almost + * right too :-) + * + * Cisco summarize ripv1 advertisements to the classful boundary + * (/16 for class B's) except when the RIP packet does to inside + * the classful network in question. + */ if ((packet->version == RIPv1 && rte->prefix.s_addr != INADDR_ANY) || (packet->version == RIPv2 @@ -1467,19 +1463,16 @@ static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to, if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) { /* * ZEBRA_IFA_SECONDARY is set on linux when an interface is - * configured - * with multiple addresses on the same subnet: the first address - * on the subnet is configured "primary", and all subsequent - * addresses - * on that subnet are treated as "secondary" addresses. - * In order to avoid routing-table bloat on other rip listeners, - * we do not send out RIP packets with ZEBRA_IFA_SECONDARY - * source addrs. + * configured with multiple addresses on the same + * subnet: the first address on the subnet is configured + * "primary", and all subsequent addresses on that subnet + * are treated as "secondary" addresses. In order to avoid + * routing-table bloat on other rip listeners, we do not send + * out RIP packets with ZEBRA_IFA_SECONDARY source addrs. * XXX Since Linux is the only system for which the - * ZEBRA_IFA_SECONDARY - * flag is set, we would end up sending a packet for a - * "secondary" - * source address on non-linux systems. + * ZEBRA_IFA_SECONDARY flag is set, we would end up + * sending a packet for a "secondary" source address on + * non-linux systems. */ if (IS_RIP_DEBUG_PACKET) zlog_debug("duplicate dropped"); @@ -2123,270 +2116,240 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, subnetted = 1; } - for (rp = route_top(rip->table); rp; rp = route_next(rp)) - if ((list = rp->info) != NULL && listcount(list) != 0) { - rinfo = listgetdata(listhead(list)); - /* For RIPv1, if we are subnetted, output subnets in our - * network */ - /* that have the same mask as the output "interface". - * For other */ - /* networks, only the classfull version is output. */ + for (rp = route_top(rip->table); rp; rp = route_next(rp)) { + list = rp->info; - if (version == RIPv1) { - p = (struct prefix_ipv4 *)&rp->p; + if (list == NULL) + continue; - if (IS_RIP_DEBUG_PACKET) - zlog_debug( - "RIPv1 mask check, %pFX considered for output", - &rp->p); - - if (subnetted - && prefix_match( - (struct prefix *)&ifaddrclass, - &rp->p)) { - if ((ifc->address->prefixlen - != rp->p.prefixlen) - && (rp->p.prefixlen - != IPV4_MAX_BITLEN)) - continue; - } else { - memcpy(&classfull, &rp->p, - sizeof(struct prefix_ipv4)); - apply_classful_mask_ipv4(&classfull); - if (rp->p.u.prefix4.s_addr != INADDR_ANY - && classfull.prefixlen - != rp->p.prefixlen) - continue; - } - if (IS_RIP_DEBUG_PACKET) - zlog_debug( - "RIPv1 mask check, %pFX made it through", - &rp->p); - } else - p = (struct prefix_ipv4 *)&rp->p; + if (listcount(list) == 0) + continue; - /* Apply output filters. */ - ret = rip_filter(RIP_FILTER_OUT, p, ri); - if (ret < 0) - continue; + rinfo = listgetdata(listhead(list)); + /* + * For RIPv1, if we are subnetted, output subnets in our + * network that have the same mask as the output "interface". + * For other networks, only the classfull version is output. + */ + if (version == RIPv1) { + p = (struct prefix_ipv4 *)&rp->p; - /* Changed route only output. */ - if (route_type == rip_changed_route - && (!(rinfo->flags & RIP_RTF_CHANGED))) - continue; + if (IS_RIP_DEBUG_PACKET) + zlog_debug( + "RIPv1 mask check, %pFX considered for output", + &rp->p); + + if (subnetted && + prefix_match((struct prefix *)&ifaddrclass, + &rp->p)) { + if ((ifc->address->prefixlen != + rp->p.prefixlen) && + (rp->p.prefixlen != IPV4_MAX_BITLEN)) + continue; + } else { + memcpy(&classfull, &rp->p, + sizeof(struct prefix_ipv4)); + apply_classful_mask_ipv4(&classfull); + if (rp->p.u.prefix4.s_addr != INADDR_ANY && + classfull.prefixlen != rp->p.prefixlen) + continue; + } + if (IS_RIP_DEBUG_PACKET) + zlog_debug( + "RIPv1 mask check, %pFX made it through", + &rp->p); + } else + p = (struct prefix_ipv4 *)&rp->p; - /* Split horizon. */ - /* if (split_horizon == rip_split_horizon) */ - if (ri->split_horizon == RIP_SPLIT_HORIZON) { - /* - * We perform split horizon for RIP and - * connected route. - * For rip routes, we want to suppress the route - * if we would - * end up sending the route back on the - * interface that we - * learned it from, with a higher metric. For - * connected routes, - * we suppress the route if the prefix is a - * subset of the - * source address that we are going to use for - * the packet - * (in order to handle the case when multiple - * subnets are - * configured on the same interface). - */ - int suppress = 0; - struct rip_info *tmp_rinfo = NULL; - struct connected *tmp_ifc = NULL; - - for (ALL_LIST_ELEMENTS_RO(list, listnode, - tmp_rinfo)) - if (tmp_rinfo->type == ZEBRA_ROUTE_RIP - && tmp_rinfo->nh.ifindex - == ifc->ifp->ifindex) { - suppress = 1; - break; - } + /* Apply output filters. */ + ret = rip_filter(RIP_FILTER_OUT, p, ri); + if (ret < 0) + continue; + + /* Changed route only output. */ + if (route_type == rip_changed_route && + (!(rinfo->flags & RIP_RTF_CHANGED))) + continue; - if (!suppress - && rinfo->type == ZEBRA_ROUTE_CONNECT) { - for (ALL_LIST_ELEMENTS_RO( - ifc->ifp->connected, - listnode, tmp_ifc)) - if (prefix_match( - (struct prefix *)p, - tmp_ifc->address)) { - suppress = 1; - break; - } + /* Split horizon. */ + if (ri->split_horizon == RIP_SPLIT_HORIZON) { + /* + * We perform split horizon for RIP and connected + * route. For rip routes, we want to suppress the + * route if we would end up sending the route back on + * the interface that we learned it from, with a + * higher metric. For connected routes, we suppress + * the route if the prefix is a subset of the source + * address that we are going to use for the packet + * (in order to handle the case when multiple subnets + * are configured on the same interface). + */ + int suppress = 0; + struct rip_info *tmp_rinfo = NULL; + struct connected *tmp_ifc = NULL; + + for (ALL_LIST_ELEMENTS_RO(list, listnode, tmp_rinfo)) + if (tmp_rinfo->type == ZEBRA_ROUTE_RIP && + tmp_rinfo->nh.ifindex == + ifc->ifp->ifindex) { + suppress = 1; + break; } - if (suppress) - continue; + if (!suppress && rinfo->type == ZEBRA_ROUTE_CONNECT) { + for (ALL_LIST_ELEMENTS_RO(ifc->ifp->connected, + listnode, tmp_ifc)) + if (prefix_match((struct prefix *)p, + tmp_ifc->address)) { + suppress = 1; + break; + } } - /* Preparation for route-map. */ - rinfo->metric_set = 0; - rinfo->nexthop_out.s_addr = 0; - rinfo->metric_out = rinfo->metric; - rinfo->tag_out = rinfo->tag; - rinfo->ifindex_out = ifc->ifp->ifindex; - - /* In order to avoid some local loops, - * if the RIP route has a nexthop via this interface, - * keep the nexthop, - * otherwise set it to 0. The nexthop should not be - * propagated - * beyond the local broadcast/multicast area in order - * to avoid an IGP multi-level recursive look-up. - * see (4.4) - */ - if (rinfo->nh.ifindex == ifc->ifp->ifindex) - rinfo->nexthop_out = rinfo->nh.gate.ipv4; + if (suppress) + continue; + } + + /* Preparation for route-map. */ + rinfo->metric_set = 0; + rinfo->nexthop_out.s_addr = 0; + rinfo->metric_out = rinfo->metric; + rinfo->tag_out = rinfo->tag; + rinfo->ifindex_out = ifc->ifp->ifindex; + + /* In order to avoid some local loops, if the RIP route has + * a nexthop via this interface, keep the nexthop, otherwise + * set it to 0. The nexthop should not be propagated beyond + * the local broadcast/multicast area in order to avoid an + * IGP multi-level recursive look-up. see (4.4) + */ + if (rinfo->nh.ifindex == ifc->ifp->ifindex) + rinfo->nexthop_out = rinfo->nh.gate.ipv4; - /* Interface route-map */ - if (ri->routemap[RIP_FILTER_OUT]) { - ret = route_map_apply( - ri->routemap[RIP_FILTER_OUT], - (struct prefix *)p, rinfo); + /* Interface route-map */ + if (ri->routemap[RIP_FILTER_OUT]) { + ret = route_map_apply(ri->routemap[RIP_FILTER_OUT], + (struct prefix *)p, rinfo); - if (ret == RMAP_DENYMATCH) { - if (IS_RIP_DEBUG_PACKET) - zlog_debug( - "RIP %pFX is filtered by route-map out", - p); - continue; - } + if (ret == RMAP_DENYMATCH) { + if (IS_RIP_DEBUG_PACKET) + zlog_debug( + "RIP %pFX is filtered by route-map out", + p); + continue; } + } - /* Apply redistribute route map - continue, if deny */ - if (rip->redist[rinfo->type].route_map.name - && rinfo->sub_type != RIP_ROUTE_INTERFACE) { - ret = route_map_apply( - rip->redist[rinfo->type].route_map.map, - (struct prefix *)p, rinfo); + /* Apply redistribute route map - continue, if deny */ + if (rip->redist[rinfo->type].route_map.name && + rinfo->sub_type != RIP_ROUTE_INTERFACE) { + ret = route_map_apply( + rip->redist[rinfo->type].route_map.map, + (struct prefix *)p, rinfo); - if (ret == RMAP_DENYMATCH) { - if (IS_RIP_DEBUG_PACKET) - zlog_debug( - "%pFX is filtered by route-map", - p); - continue; - } + if (ret == RMAP_DENYMATCH) { + if (IS_RIP_DEBUG_PACKET) + zlog_debug( + "%pFX is filtered by route-map", + p); + continue; } + } - /* When route-map does not set metric. */ - if (!rinfo->metric_set) { - /* If redistribute metric is set. */ - if (rip->redist[rinfo->type].metric_config - && rinfo->metric != RIP_METRIC_INFINITY) { - rinfo->metric_out = - rip->redist[rinfo->type].metric; - } else { - /* If the route is not connected or - localy generated - one, use default-metric value*/ - if (rinfo->type != ZEBRA_ROUTE_RIP - && rinfo->type - != ZEBRA_ROUTE_CONNECT - && rinfo->metric - != RIP_METRIC_INFINITY) - rinfo->metric_out = - rip->default_metric; - } + /* When route-map does not set metric. */ + if (!rinfo->metric_set) { + /* If redistribute metric is set. */ + if (rip->redist[rinfo->type].metric_config && + rinfo->metric != RIP_METRIC_INFINITY) { + rinfo->metric_out = + rip->redist[rinfo->type].metric; + } else { + /* If the route is not connected or localy + * generated one, use default-metric value + */ + if (rinfo->type != ZEBRA_ROUTE_RIP && + rinfo->type != ZEBRA_ROUTE_CONNECT && + rinfo->metric != RIP_METRIC_INFINITY) + rinfo->metric_out = rip->default_metric; } + } - /* Apply offset-list */ - if (rinfo->metric != RIP_METRIC_INFINITY) - rip_offset_list_apply_out(p, ifc->ifp, - &rinfo->metric_out); - - if (rinfo->metric_out > RIP_METRIC_INFINITY) - rinfo->metric_out = RIP_METRIC_INFINITY; - - /* Perform split-horizon with poisoned reverse - * for RIP and connected routes. - **/ - if (ri->split_horizon - == RIP_SPLIT_HORIZON_POISONED_REVERSE) { - /* - * We perform split horizon for RIP and - * connected route. - * For rip routes, we want to suppress the route - * if we would - * end up sending the route back on the - * interface that we - * learned it from, with a higher metric. For - * connected routes, - * we suppress the route if the prefix is a - * subset of the - * source address that we are going to use for - * the packet - * (in order to handle the case when multiple - * subnets are - * configured on the same interface). - */ - struct rip_info *tmp_rinfo = NULL; - struct connected *tmp_ifc = NULL; - - for (ALL_LIST_ELEMENTS_RO(list, listnode, - tmp_rinfo)) - if (tmp_rinfo->type == ZEBRA_ROUTE_RIP - && tmp_rinfo->nh.ifindex - == ifc->ifp->ifindex) + /* Apply offset-list */ + if (rinfo->metric != RIP_METRIC_INFINITY) + rip_offset_list_apply_out(p, ifc->ifp, + &rinfo->metric_out); + + if (rinfo->metric_out > RIP_METRIC_INFINITY) + rinfo->metric_out = RIP_METRIC_INFINITY; + + /* Perform split-horizon with poisoned reverse + * for RIP and connected routes. + **/ + if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) { + /* + * We perform split horizon for RIP and connected + * route. For rip routes, we want to suppress the + * route if we would end up sending the route back + * on the interface that we learned it from, with a + * higher metric. For connected routes, we suppress + * the route if the prefix is a subset of the source + * address that we are going to use for the packet + * (in order to handle the case when multiple + * subnets are configured on the same interface). + */ + struct rip_info *tmp_rinfo = NULL; + struct connected *tmp_ifc = NULL; + + for (ALL_LIST_ELEMENTS_RO(list, listnode, tmp_rinfo)) + if (tmp_rinfo->type == ZEBRA_ROUTE_RIP && + tmp_rinfo->nh.ifindex == ifc->ifp->ifindex) + rinfo->metric_out = RIP_METRIC_INFINITY; + + if (rinfo->metric_out != RIP_METRIC_INFINITY && + rinfo->type == ZEBRA_ROUTE_CONNECT) { + for (ALL_LIST_ELEMENTS_RO(ifc->ifp->connected, + listnode, tmp_ifc)) + if (prefix_match((struct prefix *)p, + tmp_ifc->address)) { rinfo->metric_out = RIP_METRIC_INFINITY; - - if (rinfo->metric_out != RIP_METRIC_INFINITY - && rinfo->type == ZEBRA_ROUTE_CONNECT) { - for (ALL_LIST_ELEMENTS_RO( - ifc->ifp->connected, - listnode, tmp_ifc)) - if (prefix_match( - (struct prefix *)p, - tmp_ifc->address)) { - rinfo->metric_out = - RIP_METRIC_INFINITY; - break; - } - } + break; + } } + } - /* Prepare preamble, auth headers, if needs be */ - if (num == 0) { - stream_putc(s, RIP_RESPONSE); - stream_putc(s, version); - stream_putw(s, 0); - - /* auth header for !v1 && !no_auth */ - if ((ri->auth_type != RIP_NO_AUTH) - && (version != RIPv1)) - doff = rip_auth_header_write( - s, ri, key, auth_str, - RIP_AUTH_SIMPLE_SIZE); - } + /* Prepare preamble, auth headers, if needs be */ + if (num == 0) { + stream_putc(s, RIP_RESPONSE); + stream_putc(s, version); + stream_putw(s, 0); + + /* auth header for !v1 && !no_auth */ + if ((ri->auth_type != RIP_NO_AUTH) && + (version != RIPv1)) + doff = rip_auth_header_write( + s, ri, key, auth_str, + RIP_AUTH_SIMPLE_SIZE); + } - /* Write RTE to the stream. */ - num = rip_write_rte(num, s, p, version, rinfo); - if (num == rtemax) { - if (version == RIPv2 - && ri->auth_type == RIP_AUTH_MD5) - rip_auth_md5_set(s, ri, doff, auth_str, - RIP_AUTH_SIMPLE_SIZE); - - ret = rip_send_packet(STREAM_DATA(s), - stream_get_endp(s), to, - ifc); - - if (ret >= 0 && IS_RIP_DEBUG_SEND) - rip_packet_dump((struct rip_packet *) - STREAM_DATA(s), - stream_get_endp(s), - "SEND"); - num = 0; - stream_reset(s); - } + /* Write RTE to the stream. */ + num = rip_write_rte(num, s, p, version, rinfo); + if (num == rtemax) { + if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5) + rip_auth_md5_set(s, ri, doff, auth_str, + RIP_AUTH_SIMPLE_SIZE); + + ret = rip_send_packet(STREAM_DATA(s), + stream_get_endp(s), to, ifc); + + if (ret >= 0 && IS_RIP_DEBUG_SEND) + rip_packet_dump( + (struct rip_packet *)STREAM_DATA(s), + stream_get_endp(s), "SEND"); + num = 0; + stream_reset(s); } + } /* Flush unwritten RTE. */ if (num != 0) { @@ -2482,61 +2445,59 @@ static void rip_update_process(struct rip *rip, int route_type) if (ri->passive) continue; - if (ri->running) { - /* - * If there is no version configuration in the - * interface, - * use rip's version setting. - */ - int vsend = ((ri->ri_send == RI_RIP_UNSPEC) - ? rip->version_send - : ri->ri_send); + if (!ri->running) + continue; - if (IS_RIP_DEBUG_EVENT) - zlog_debug("SEND UPDATE to %s ifindex %d", - ifp->name, ifp->ifindex); - - /* send update on each connected network */ - for (ALL_LIST_ELEMENTS(ifp->connected, ifnode, ifnnode, - connected)) { - if (connected->address->family == AF_INET) { - if (vsend & RIPv1) - rip_update_interface( - connected, RIPv1, - route_type); - if ((vsend & RIPv2) - && if_is_multicast(ifp)) - rip_update_interface( - connected, RIPv2, - route_type); - } + /* + * If there is no version configuration in the + * interface, use rip's version setting. + */ + int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? rip->version_send + : ri->ri_send); + + if (IS_RIP_DEBUG_EVENT) + zlog_debug("SEND UPDATE to %s ifindex %d", ifp->name, + ifp->ifindex); + + /* send update on each connected network */ + for (ALL_LIST_ELEMENTS(ifp->connected, ifnode, ifnnode, + connected)) { + if (connected->address->family == AF_INET) { + if (vsend & RIPv1) + rip_update_interface(connected, RIPv1, + route_type); + if ((vsend & RIPv2) && if_is_multicast(ifp)) + rip_update_interface(connected, RIPv2, + route_type); } } } /* RIP send updates to each neighbor. */ - for (rp = route_top(rip->neighbor); rp; rp = route_next(rp)) - if (rp->info != NULL) { - p = &rp->p; - - connected = if_lookup_address(&p->u.prefix4, AF_INET, - rip->vrf->vrf_id); - if (!connected) { - zlog_warn( - "Neighbor %pI4 doesn't have connected interface!", - &p->u.prefix4); - continue; - } + for (rp = route_top(rip->neighbor); rp; rp = route_next(rp)) { + if (rp->info == NULL) + continue; - /* Set destination address and port */ - memset(&to, 0, sizeof(struct sockaddr_in)); - to.sin_addr = p->u.prefix4; - to.sin_port = htons(RIP_PORT_DEFAULT); + p = &rp->p; - /* RIP version is rip's configuration. */ - rip_output_process(connected, &to, route_type, - rip->version_send); + connected = if_lookup_address(&p->u.prefix4, AF_INET, + rip->vrf->vrf_id); + if (!connected) { + zlog_warn( + "Neighbor %pI4 doesn't have connected interface!", + &p->u.prefix4); + continue; } + + /* Set destination address and port */ + memset(&to, 0, sizeof(struct sockaddr_in)); + to.sin_addr = p->u.prefix4; + to.sin_port = htons(RIP_PORT_DEFAULT); + + /* RIP version is rip's configuration. */ + rip_output_process(connected, &to, route_type, + rip->version_send); + } } /* RIP's periodical timer. */ @@ -2569,14 +2530,18 @@ static void rip_clear_changed_flag(struct rip *rip) struct list *list = NULL; struct listnode *listnode = NULL; - for (rp = route_top(rip->table); rp; rp = route_next(rp)) - if ((list = rp->info) != NULL) - for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { - UNSET_FLAG(rinfo->flags, RIP_RTF_CHANGED); - /* This flag can be set only on the first entry. - */ - break; - } + for (rp = route_top(rip->table); rp; rp = route_next(rp)) { + list = rp->info; + + if (list == NULL) + continue; + + for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { + UNSET_FLAG(rinfo->flags, RIP_RTF_CHANGED); + /* This flag can be set only on the first entry. */ + break; + } + } } /* Triggered update interval timer. */ @@ -2632,34 +2597,39 @@ void rip_redistribute_withdraw(struct rip *rip, int type) struct rip_info *rinfo = NULL; struct list *list = NULL; - for (rp = route_top(rip->table); rp; rp = route_next(rp)) - if ((list = rp->info) != NULL) { - rinfo = listgetdata(listhead(list)); - if (rinfo->type == type - && rinfo->sub_type != RIP_ROUTE_INTERFACE) { - /* Perform poisoned reverse. */ - rinfo->metric = RIP_METRIC_INFINITY; - RIP_TIMER_ON(rinfo->t_garbage_collect, - rip_garbage_collect, - rip->garbage_time); - RIP_TIMER_OFF(rinfo->t_timeout); - rinfo->flags |= RIP_RTF_CHANGED; + for (rp = route_top(rip->table); rp; rp = route_next(rp)) { + list = rp->info; - if (IS_RIP_DEBUG_EVENT) { - struct prefix_ipv4 *p = - (struct prefix_ipv4 *)&rp->p; + if (list == NULL) + continue; - zlog_debug( - "Poisone %pFX on the interface %s with an infinity metric [withdraw]", - p, - ifindex2ifname( - rinfo->nh.ifindex, - rip->vrf->vrf_id)); - } + rinfo = listgetdata(listhead(list)); - rip_event(rip, RIP_TRIGGERED_UPDATE, 0); - } + if (rinfo->type != type) + continue; + + if (rinfo->sub_type == RIP_ROUTE_INTERFACE) + continue; + + /* Perform poisoned reverse. */ + rinfo->metric = RIP_METRIC_INFINITY; + RIP_TIMER_ON(rinfo->t_garbage_collect, rip_garbage_collect, + rip->garbage_time); + RIP_TIMER_OFF(rinfo->t_timeout); + rinfo->flags |= RIP_RTF_CHANGED; + + if (IS_RIP_DEBUG_EVENT) { + struct prefix_ipv4 *p = (struct prefix_ipv4 *)&rp->p; + + zlog_debug( + "Poisone %pFX on the interface %s with an infinity metric [withdraw]", + p, + ifindex2ifname(rinfo->nh.ifindex, + rip->vrf->vrf_id)); } + + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); + } } struct rip *rip_lookup_by_vrf_id(vrf_id_t vrf_id) @@ -2916,19 +2886,20 @@ static void rip_distance_show(struct vty *vty, struct rip *rip) vty_out(vty, " Distance: (default is %u)\n", rip->distance ? rip->distance : ZEBRA_RIP_DISTANCE_DEFAULT); - for (rn = route_top(rip->distance_table); rn; rn = route_next(rn)) - if ((rdistance = rn->info) != NULL) { - if (header) { - vty_out(vty, - " Address Distance List\n"); - header = 0; - } - snprintfrr(buf, sizeof(buf), "%pFX", &rn->p); - vty_out(vty, " %-20s %4d %s\n", buf, - rdistance->distance, - rdistance->access_list ? rdistance->access_list - : ""); + for (rn = route_top(rip->distance_table); rn; rn = route_next(rn)) { + rdistance = rn->info; + + if (rdistance == NULL) + continue; + + if (header) { + vty_out(vty, " Address Distance List\n"); + header = 0; } + snprintfrr(buf, sizeof(buf), "%pFX", &rn->p); + vty_out(vty, " %-20s %4d %s\n", buf, rdistance->distance, + rdistance->access_list ? rdistance->access_list : ""); + } } /* Update ECMP routes to zebra when ECMP is disabled. */ @@ -2939,31 +2910,38 @@ void rip_ecmp_disable(struct rip *rip) struct list *list; struct listnode *node, *nextnode; - for (rp = route_top(rip->table); rp; rp = route_next(rp)) - if ((list = rp->info) != NULL && listcount(list) > 1) { - rinfo = listgetdata(listhead(list)); - if (!rip_route_rte(rinfo)) - continue; + for (rp = route_top(rip->table); rp; rp = route_next(rp)) { + list = rp->info; - /* Drop all other entries, except the first one. */ - for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo)) - if (tmp_rinfo != rinfo) { - RIP_TIMER_OFF(tmp_rinfo->t_timeout); - RIP_TIMER_OFF( - tmp_rinfo->t_garbage_collect); - list_delete_node(list, node); - rip_info_free(tmp_rinfo); - } + if (!list) + continue; + if (listcount(list) == 0) + continue; - /* Update zebra. */ - rip_zebra_ipv4_add(rip, rp); + rinfo = listgetdata(listhead(list)); + if (!rip_route_rte(rinfo)) + continue; - /* Set the route change flag. */ - SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); + /* Drop all other entries, except the first one. */ + for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo)) { + if (tmp_rinfo == rinfo) + continue; - /* Signal the output process to trigger an update. */ - rip_event(rip, RIP_TRIGGERED_UPDATE, 0); + RIP_TIMER_OFF(tmp_rinfo->t_timeout); + RIP_TIMER_OFF(tmp_rinfo->t_garbage_collect); + list_delete_node(list, node); + rip_info_free(tmp_rinfo); } + + /* Update zebra. */ + rip_zebra_ipv4_add(rip, rp); + + /* Set the route change flag. */ + SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); + + /* Signal the output process to trigger an update. */ + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); + } } /* Print out routes update time. */ @@ -3044,82 +3022,77 @@ DEFUN (show_ip_rip, " (i) - interface\n\n" " Network Next Hop Metric From Tag Time\n"); - for (np = route_top(rip->table); np; np = route_next(np)) - if ((list = np->info) != NULL) - for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { - int len; - - len = vty_out( - vty, "%c(%s) %pFX", - /* np->lock, For debugging. */ - zebra_route_char(rinfo->type), - rip_route_type_print(rinfo->sub_type), - &np->p); - - len = 24 - len; - - if (len > 0) - vty_out(vty, "%*s", len, " "); - - switch (rinfo->nh.type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, "%-20pI4 %2d ", - &rinfo->nh.gate.ipv4, - rinfo->metric); - break; - case NEXTHOP_TYPE_IFINDEX: - vty_out(vty, - "0.0.0.0 %2d ", - rinfo->metric); - break; - case NEXTHOP_TYPE_BLACKHOLE: - vty_out(vty, - "blackhole %2d ", - rinfo->metric); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - vty_out(vty, - "V6 Address Hidden %2d ", - rinfo->metric); - break; - } + for (np = route_top(rip->table); np; np = route_next(np)) { + list = np->info; - /* Route which exist in kernel routing table. */ - if ((rinfo->type == ZEBRA_ROUTE_RIP) - && (rinfo->sub_type == RIP_ROUTE_RTE)) { - vty_out(vty, "%-15pI4 ", - &rinfo->from); - vty_out(vty, "%3" ROUTE_TAG_PRI " ", - (route_tag_t)rinfo->tag); - rip_vty_out_uptime(vty, rinfo); - } else if (rinfo->metric - == RIP_METRIC_INFINITY) { - vty_out(vty, "self "); - vty_out(vty, "%3" ROUTE_TAG_PRI " ", - (route_tag_t)rinfo->tag); - rip_vty_out_uptime(vty, rinfo); - } else { - if (rinfo->external_metric) { - len = vty_out( - vty, "self (%s:%d)", - zebra_route_string( - rinfo->type), - rinfo->external_metric); - len = 16 - len; - if (len > 0) - vty_out(vty, "%*s", len, - " "); - } else - vty_out(vty, - "self "); - vty_out(vty, "%3" ROUTE_TAG_PRI, - (route_tag_t)rinfo->tag); - } + if (!list) + continue; + + for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { + int len; + + len = vty_out(vty, "%c(%s) %pFX", + /* np->lock, For debugging. */ + zebra_route_char(rinfo->type), + rip_route_type_print(rinfo->sub_type), + &np->p); + + len = 24 - len; + + if (len > 0) + vty_out(vty, "%*s", len, " "); - vty_out(vty, "\n"); + switch (rinfo->nh.type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + vty_out(vty, "%-20pI4 %2d ", + &rinfo->nh.gate.ipv4, rinfo->metric); + break; + case NEXTHOP_TYPE_IFINDEX: + vty_out(vty, "0.0.0.0 %2d ", + rinfo->metric); + break; + case NEXTHOP_TYPE_BLACKHOLE: + vty_out(vty, "blackhole %2d ", + rinfo->metric); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + vty_out(vty, "V6 Address Hidden %2d ", + rinfo->metric); + break; + } + + /* Route which exist in kernel routing table. */ + if ((rinfo->type == ZEBRA_ROUTE_RIP) && + (rinfo->sub_type == RIP_ROUTE_RTE)) { + vty_out(vty, "%-15pI4 ", &rinfo->from); + vty_out(vty, "%3" ROUTE_TAG_PRI " ", + (route_tag_t)rinfo->tag); + rip_vty_out_uptime(vty, rinfo); + } else if (rinfo->metric == RIP_METRIC_INFINITY) { + vty_out(vty, "self "); + vty_out(vty, "%3" ROUTE_TAG_PRI " ", + (route_tag_t)rinfo->tag); + rip_vty_out_uptime(vty, rinfo); + } else { + if (rinfo->external_metric) { + len = vty_out( + vty, "self (%s:%d)", + zebra_route_string(rinfo->type), + rinfo->external_metric); + len = 16 - len; + if (len > 0) + vty_out(vty, "%*s", len, " "); + } else + vty_out(vty, "self "); + vty_out(vty, "%3" ROUTE_TAG_PRI, + (route_tag_t)rinfo->tag); } + + vty_out(vty, "\n"); + } + } return CMD_SUCCESS; } @@ -3219,20 +3192,17 @@ DEFUN (show_ip_rip_status, vty_out(vty, " Routing for Networks:\n"); rip_show_network_config(vty, rip); - { - int found_passive = 0; - FOR_ALL_INTERFACES (rip->vrf, ifp) { - ri = ifp->info; - - if ((ri->enable_network || ri->enable_interface) - && ri->passive) { - if (!found_passive) { - vty_out(vty, - " Passive Interface(s):\n"); - found_passive = 1; - } - vty_out(vty, " %s\n", ifp->name); + int found_passive = 0; + FOR_ALL_INTERFACES (rip->vrf, ifp) { + ri = ifp->info; + + if ((ri->enable_network || ri->enable_interface) && + ri->passive) { + if (!found_passive) { + vty_out(vty, " Passive Interface(s):\n"); + found_passive = 1; } + vty_out(vty, " %s\n", ifp->name); } } diff --git a/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf index 82525fac64..73f837c69b 100644 --- a/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf +++ b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf @@ -19,6 +19,7 @@ route-map ADV-MAP-1 permit 20 ! route-map ADV-MAP-2 permit 10 match ip address prefix-list IP2 + set metric 911 ! route-map EXIST-MAP permit 10 match community DEFAULT-ROUTE diff --git a/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py index e9b393ba7f..6153aee418 100644 --- a/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py +++ b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py @@ -334,7 +334,7 @@ def test_bgp_conditional_advertisement(): "192.0.2.1/32": None, "192.0.2.5/32": None, "10.139.224.0/20": None, - "203.0.113.1/32": [{"protocol": "bgp"}], + "203.0.113.1/32": [{"protocol": "bgp", "metric": 911}], } return topotest.json_cmp(output, expected) diff --git a/tests/topotests/ospf_topo1_vrf/__init__.py b/tests/topotests/ospf_netns_vrf/__init__.py index e69de29bb2..e69de29bb2 100755 --- a/tests/topotests/ospf_topo1_vrf/__init__.py +++ b/tests/topotests/ospf_netns_vrf/__init__.py diff --git a/tests/topotests/ospf_topo1_vrf/r1/ospfd.conf b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf index e1e2bfb99a..e1e2bfb99a 100644 --- a/tests/topotests/ospf_topo1_vrf/r1/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf diff --git a/tests/topotests/ospf_topo1_vrf/r1/ospfroute.txt b/tests/topotests/ospf_netns_vrf/r1/ospfroute.txt index d617ab36d9..d617ab36d9 100644 --- a/tests/topotests/ospf_topo1_vrf/r1/ospfroute.txt +++ b/tests/topotests/ospf_netns_vrf/r1/ospfroute.txt diff --git a/tests/topotests/ospf_topo1_vrf/r1/ospfroute_down.txt b/tests/topotests/ospf_netns_vrf/r1/ospfroute_down.txt index 4f7fd699cf..4f7fd699cf 100644 --- a/tests/topotests/ospf_topo1_vrf/r1/ospfroute_down.txt +++ b/tests/topotests/ospf_netns_vrf/r1/ospfroute_down.txt diff --git a/tests/topotests/ospf_topo1_vrf/r1/zebra.conf b/tests/topotests/ospf_netns_vrf/r1/zebra.conf index 56d7a9764e..56d7a9764e 100644 --- a/tests/topotests/ospf_topo1_vrf/r1/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r1/zebra.conf diff --git a/tests/topotests/ospf_topo1_vrf/r1/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r1/zebraroute.txt index 979af20c59..979af20c59 100644 --- a/tests/topotests/ospf_topo1_vrf/r1/zebraroute.txt +++ b/tests/topotests/ospf_netns_vrf/r1/zebraroute.txt diff --git a/tests/topotests/ospf_topo1_vrf/r1/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt index ec99fad762..ec99fad762 100644 --- a/tests/topotests/ospf_topo1_vrf/r1/zebraroutedown.txt +++ b/tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt diff --git a/tests/topotests/ospf_topo1_vrf/r2/ospfd.conf b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf index c1984276f4..c1984276f4 100644 --- a/tests/topotests/ospf_topo1_vrf/r2/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf diff --git a/tests/topotests/ospf_topo1_vrf/r2/ospfroute.txt b/tests/topotests/ospf_netns_vrf/r2/ospfroute.txt index 89763ff733..89763ff733 100644 --- a/tests/topotests/ospf_topo1_vrf/r2/ospfroute.txt +++ b/tests/topotests/ospf_netns_vrf/r2/ospfroute.txt diff --git a/tests/topotests/ospf_topo1_vrf/r2/ospfroute_down.txt b/tests/topotests/ospf_netns_vrf/r2/ospfroute_down.txt index d946f02dfd..d946f02dfd 100644 --- a/tests/topotests/ospf_topo1_vrf/r2/ospfroute_down.txt +++ b/tests/topotests/ospf_netns_vrf/r2/ospfroute_down.txt diff --git a/tests/topotests/ospf_topo1_vrf/r2/zebra.conf b/tests/topotests/ospf_netns_vrf/r2/zebra.conf index 6ff72d1267..6ff72d1267 100644 --- a/tests/topotests/ospf_topo1_vrf/r2/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r2/zebra.conf diff --git a/tests/topotests/ospf_topo1_vrf/r2/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r2/zebraroute.txt index df66e92abc..df66e92abc 100644 --- a/tests/topotests/ospf_topo1_vrf/r2/zebraroute.txt +++ b/tests/topotests/ospf_netns_vrf/r2/zebraroute.txt diff --git a/tests/topotests/ospf_topo1_vrf/r2/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt index 4afc354ca7..4afc354ca7 100644 --- a/tests/topotests/ospf_topo1_vrf/r2/zebraroutedown.txt +++ b/tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt diff --git a/tests/topotests/ospf_topo1_vrf/r3/ospfd.conf b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf index b73d547e3e..b73d547e3e 100644 --- a/tests/topotests/ospf_topo1_vrf/r3/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf diff --git a/tests/topotests/ospf_topo1_vrf/r3/ospfroute.txt b/tests/topotests/ospf_netns_vrf/r3/ospfroute.txt index 917702b14c..917702b14c 100644 --- a/tests/topotests/ospf_topo1_vrf/r3/ospfroute.txt +++ b/tests/topotests/ospf_netns_vrf/r3/ospfroute.txt diff --git a/tests/topotests/ospf_topo1_vrf/r3/ospfroute_down.txt b/tests/topotests/ospf_netns_vrf/r3/ospfroute_down.txt index 966185e495..966185e495 100644 --- a/tests/topotests/ospf_topo1_vrf/r3/ospfroute_down.txt +++ b/tests/topotests/ospf_netns_vrf/r3/ospfroute_down.txt diff --git a/tests/topotests/ospf_topo1_vrf/r3/zebra.conf b/tests/topotests/ospf_netns_vrf/r3/zebra.conf index 1534150048..1534150048 100644 --- a/tests/topotests/ospf_topo1_vrf/r3/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r3/zebra.conf diff --git a/tests/topotests/ospf_topo1_vrf/r3/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r3/zebraroute.txt index b435c2ebe5..b435c2ebe5 100644 --- a/tests/topotests/ospf_topo1_vrf/r3/zebraroute.txt +++ b/tests/topotests/ospf_netns_vrf/r3/zebraroute.txt diff --git a/tests/topotests/ospf_topo1_vrf/r3/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt index f30a4be6c6..f30a4be6c6 100644 --- a/tests/topotests/ospf_topo1_vrf/r3/zebraroutedown.txt +++ b/tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt diff --git a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1-vrf.dot b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.dot index 789fdd7c09..789fdd7c09 100644 --- a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1-vrf.dot +++ b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.dot diff --git a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.jpg b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.jpg Binary files differindex 85f2e52f8e..85f2e52f8e 100644 --- a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.jpg +++ b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.jpg diff --git a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.py b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py index 44de61d82a..621d8079dc 100644 --- a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.py +++ b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -# test_ospf_topo1.py +# test_ospf_netns_vrf.py # Part of NetDEF Topology Tests # # Copyright (c) 2017 by @@ -23,7 +23,7 @@ # """ -test_ospf_topo1.py: Test the FRR OSPF routing daemon. +test_ospf_netns_vrf.py: Test OSPF with Network Namespace VRFs. """ import os diff --git a/tests/topotests/ospf_topo2/r1/ospf-route.json b/tests/topotests/ospf_unnumbered/r1/ospf-route.json index 6beb7e9bed..6beb7e9bed 100644 --- a/tests/topotests/ospf_topo2/r1/ospf-route.json +++ b/tests/topotests/ospf_unnumbered/r1/ospf-route.json diff --git a/tests/topotests/ospf_topo2/r1/ospfd.conf b/tests/topotests/ospf_unnumbered/r1/ospfd.conf index 65843cbb83..65843cbb83 100644 --- a/tests/topotests/ospf_topo2/r1/ospfd.conf +++ b/tests/topotests/ospf_unnumbered/r1/ospfd.conf diff --git a/tests/topotests/ospf_topo2/r1/v4_route.json b/tests/topotests/ospf_unnumbered/r1/v4_route.json index 76c6396169..76c6396169 100644 --- a/tests/topotests/ospf_topo2/r1/v4_route.json +++ b/tests/topotests/ospf_unnumbered/r1/v4_route.json diff --git a/tests/topotests/ospf_topo2/r1/zebra.conf b/tests/topotests/ospf_unnumbered/r1/zebra.conf index d96d9707c1..d96d9707c1 100644 --- a/tests/topotests/ospf_topo2/r1/zebra.conf +++ b/tests/topotests/ospf_unnumbered/r1/zebra.conf diff --git a/tests/topotests/ospf_topo2/r2/ospf-route.json b/tests/topotests/ospf_unnumbered/r2/ospf-route.json index 3cfd255bfd..3cfd255bfd 100644 --- a/tests/topotests/ospf_topo2/r2/ospf-route.json +++ b/tests/topotests/ospf_unnumbered/r2/ospf-route.json diff --git a/tests/topotests/ospf_topo2/r2/ospfd.conf b/tests/topotests/ospf_unnumbered/r2/ospfd.conf index b032f1a8ac..b032f1a8ac 100644 --- a/tests/topotests/ospf_topo2/r2/ospfd.conf +++ b/tests/topotests/ospf_unnumbered/r2/ospfd.conf diff --git a/tests/topotests/ospf_topo2/r2/v4_route.json b/tests/topotests/ospf_unnumbered/r2/v4_route.json index 1638536388..1638536388 100644 --- a/tests/topotests/ospf_topo2/r2/v4_route.json +++ b/tests/topotests/ospf_unnumbered/r2/v4_route.json diff --git a/tests/topotests/ospf_topo2/r2/zebra.conf b/tests/topotests/ospf_unnumbered/r2/zebra.conf index f9dd2c4471..f9dd2c4471 100644 --- a/tests/topotests/ospf_topo2/r2/zebra.conf +++ b/tests/topotests/ospf_unnumbered/r2/zebra.conf diff --git a/tests/topotests/ospf_topo2/test_ospf_topo2.py b/tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py index 1ad62ff18e..a9640adca3 100644 --- a/tests/topotests/ospf_topo2/test_ospf_topo2.py +++ b/tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -# test_ospf_topo2.py +# test_ospf_unnumbered.py # # Copyright (c) 2019 by # Cumulus Networks, Inc @@ -23,7 +23,7 @@ # """ -test_ospf_topo2.py: Test the OSPF unnumbered. +test_ospf_unnumbered.py: Test the OSPF unnumbered. """ import os |
