diff options
| -rw-r--r-- | bgpd/bgp_bfd.c | 19 | ||||
| -rw-r--r-- | bgpd/bgp_bfd.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_fsm.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_nexthop.c | 13 | ||||
| -rw-r--r-- | bgpd/bgp_nexthop.h | 6 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 11 | ||||
| -rw-r--r-- | bgpd/bgp_routemap.c | 75 | ||||
| -rw-r--r-- | doc/user/routemap.rst | 11 | ||||
| m--------- | libyang | 0 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 4 | ||||
| -rw-r--r-- | pimd/pim_rp.c | 8 |
11 files changed, 140 insertions, 12 deletions
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 1f650aaeb7..5f4db3dfa8 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -200,6 +200,25 @@ static void bgp_bfd_update_peer(struct peer *peer) bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_UPDATE); } +/** + * bgp_bfd_reset_peer - reinitialise bfd + * ensures that bfd state machine is restarted + * to be synced with remote bfd + */ +void bgp_bfd_reset_peer(struct peer *peer) +{ + struct bfd_info *bfd_info; + + if (!peer->bfd_info) + return; + bfd_info = (struct bfd_info *)peer->bfd_info; + + /* if status is not down, reset bfd */ + if (bfd_info->status != BFD_STATUS_DOWN) + bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER); + bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER); +} + /* * bgp_bfd_update_type - update session type with BFD through zebra. */ diff --git a/bgpd/bgp_bfd.h b/bgpd/bgp_bfd.h index caa5651e3a..b96ebb6c96 100644 --- a/bgpd/bgp_bfd.h +++ b/bgpd/bgp_bfd.h @@ -31,6 +31,8 @@ extern void bgp_bfd_register_peer(struct peer *peer); extern void bgp_bfd_deregister_peer(struct peer *peer); +extern void bgp_bfd_reset_peer(struct peer *peer); + extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr); diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 0051b8d606..f4fbfe4c60 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1956,8 +1956,7 @@ static int bgp_establish(struct peer *peer) hash_release(peer->bgp->peerhash, peer); hash_get(peer->bgp->peerhash, peer, hash_alloc_intern); - bgp_bfd_deregister_peer(peer); - bgp_bfd_register_peer(peer); + bgp_bfd_reset_peer(peer); return ret; } diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index ab0c3a3f11..8e43801d2d 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -612,7 +612,8 @@ int bgp_multiaccess_check_v6(struct in6_addr nexthop, struct peer *peer) } int bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop, - struct update_subgroup *subgrp) + struct update_subgroup *subgrp, + struct peer *exclude) { struct bgp_node *rn1 = NULL, *rn2 = NULL; struct peer_af *paf = NULL; @@ -632,6 +633,9 @@ int bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop, return 0; SUBGRP_FOREACH_PEER (subgrp, paf) { + /* Skip peer we're told to exclude - e.g., source of route. */ + if (paf->peer == exclude) + continue; p.u.prefix6 = paf->peer->su.sin6.sin6_addr; rn2 = bgp_node_match(bgp->connected_table[AFI_IP6], &p); @@ -650,7 +654,8 @@ int bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop, } int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, - struct update_subgroup *subgrp) + struct update_subgroup *subgrp, + struct peer *exclude) { struct bgp_node *rn1, *rn2; struct peer_af *paf; @@ -670,6 +675,10 @@ int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, return 0; SUBGRP_FOREACH_PEER (subgrp, paf) { + /* Skip peer we're told to exclude - e.g., source of route. */ + if (paf->peer == exclude) + continue; + p.u.prefix4 = paf->peer->su.sin.sin_addr; rn2 = bgp_node_match(bgp->connected_table[AFI_IP], &p); diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h index af4c0bc047..4a25c83cd5 100644 --- a/bgpd/bgp_nexthop.h +++ b/bgpd/bgp_nexthop.h @@ -82,9 +82,11 @@ struct bgp_addrv6 { extern void bgp_connected_add(struct bgp *bgp, struct connected *c); extern void bgp_connected_delete(struct bgp *bgp, struct connected *c); extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, - struct update_subgroup *subgrp); + struct update_subgroup *subgrp, + struct peer *exclude); extern int bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop, - struct update_subgroup *subgrp); + struct update_subgroup *subgrp, + struct peer *exclude); extern int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer); extern int bgp_multiaccess_check_v6(struct in6_addr nexthop, struct peer *peer); extern int bgp_config_write_scan_time(struct vty *); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ad089d9d25..0fdf2d3a8e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2006,7 +2006,7 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi, if ((p->family == AF_INET) && (!bgp_subgrp_multiaccess_check_v4( piattr->nexthop, - subgrp))) + subgrp, from))) subgroup_announce_reset_nhop( (peer_cap_enhe(peer, afi, safi) ? AF_INET6 @@ -2016,7 +2016,7 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi, if ((p->family == AF_INET6) && (!bgp_subgrp_multiaccess_check_v6( piattr->mp_nexthop_global, - subgrp))) + subgrp, from))) subgroup_announce_reset_nhop( (peer_cap_enhe(peer, afi, safi) ? AF_INET6 @@ -2107,6 +2107,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn, if (debug) prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf)); + rn->reason = bgp_path_selection_none; /* bgp deterministic-med */ new_select = NULL; if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) { @@ -2186,6 +2187,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn, new_select = NULL; for (pi = bgp_node_get_bgp_path_info(rn); (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) { + enum bgp_path_selection_reason reason; + if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) old_select = pi; @@ -2226,8 +2229,12 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn, bgp_path_info_unset_flag(rn, pi, BGP_PATH_DMED_CHECK); + reason = rn->reason; if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg, debug, pfx_buf, afi, safi, &rn->reason)) { + if (new_select == NULL && + reason != bgp_path_selection_none) + rn->reason = reason; new_select = pi; } } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 52b5402737..029570df35 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -2830,6 +2830,57 @@ static const struct route_map_rule_cmd route_match_ipv6_next_hop_cmd = { route_match_ipv6_next_hop_free }; +/* `match ip next-hop IP_ADDRESS' */ + +static enum route_map_cmd_result_t +route_match_ipv4_next_hop(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct in_addr *addr = rule; + struct bgp_path_info *path; + + if (type == RMAP_BGP) { + path = object; + + if (path->attr->nexthop.s_addr == addr->s_addr || + (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4 && + IPV4_ADDR_SAME(&path->attr->mp_nexthop_global_in, addr))) + return RMAP_MATCH; + + return RMAP_NOMATCH; + } + + return RMAP_NOMATCH; +} + +static void *route_match_ipv4_next_hop_compile(const char *arg) +{ + struct in_addr *address; + int ret; + + address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in_addr)); + + ret = inet_pton(AF_INET, arg, address); + if (!ret) { + XFREE(MTYPE_ROUTE_MAP_COMPILED, address); + return NULL; + } + + return address; +} + +static void route_match_ipv4_next_hop_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +static const struct route_map_rule_cmd route_match_ipv4_next_hop_cmd = { + "ip next-hop address", + route_match_ipv4_next_hop, + route_match_ipv4_next_hop_compile, + route_match_ipv4_next_hop_free +}; + /* `match ipv6 address prefix-list PREFIX_LIST' */ static enum route_map_cmd_result_t @@ -5110,6 +5161,28 @@ DEFUN (no_match_ipv6_next_hop, RMAP_EVENT_MATCH_DELETED); } +DEFPY (match_ipv4_next_hop, + match_ipv4_next_hop_cmd, + "[no$no] match ip next-hop address [A.B.C.D]", + NO_STR + MATCH_STR + IP_STR + "Match IP next-hop address of route\n" + "IP address\n" + "IP address of next-hop\n") +{ + int idx_ipv4 = 4; + + if (no) + return bgp_route_match_delete(vty, "ip next-hop address", NULL, + RMAP_EVENT_MATCH_DELETED); + + if (argv[idx_ipv4]->arg) + return bgp_route_match_add(vty, "ip next-hop address", + argv[idx_ipv4]->arg, + RMAP_EVENT_MATCH_ADDED); + return CMD_SUCCESS; +} DEFUN (set_ipv6_nexthop_peer, set_ipv6_nexthop_peer_cmd, @@ -5563,6 +5636,7 @@ void bgp_route_map_init(void) route_map_install_match(&route_match_ipv6_address_cmd); route_map_install_match(&route_match_ipv6_next_hop_cmd); + route_map_install_match(&route_match_ipv4_next_hop_cmd); route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); route_map_install_match(&route_match_ipv6_next_hop_type_cmd); route_map_install_set(&route_set_ipv6_nexthop_global_cmd); @@ -5572,6 +5646,7 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &match_ipv6_next_hop_cmd); install_element(RMAP_NODE, &no_match_ipv6_next_hop_cmd); + install_element(RMAP_NODE, &match_ipv4_next_hop_cmd); install_element(RMAP_NODE, &set_ipv6_nexthop_global_cmd); install_element(RMAP_NODE, &no_set_ipv6_nexthop_global_cmd); install_element(RMAP_NODE, &set_ipv6_nexthop_prefer_global_cmd); diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst index 472e2c53ff..f557cbe022 100644 --- a/doc/user/routemap.rst +++ b/doc/user/routemap.rst @@ -151,10 +151,15 @@ Route Map Match Command Matches the specified `prefix-len`. This is a Zebra specific command. -.. index:: match ip next-hop IPV4_ADDR -.. clicmd:: match ip next-hop IPV4_ADDR +.. index:: match ip next-hop address IPV4_ADDR +.. clicmd:: match ip next-hop address IPV4_ADDR - Matches the specified `ipv4_addr`. + This is a BGP specific match command. Matches the specified `ipv4_addr`. + +.. index:: match ipv6 next-hop IPV6_ADDR +.. clicmd:: match ipv6 next-hop IPV6_ADDR + + This is a BGP specific match command. Matches the specified `ipv6_addr`. .. index:: match as-path AS_PATH .. clicmd:: match as-path AS_PATH diff --git a/libyang b/libyang new file mode 160000 +Subproject 4241fbbe72216ae2b84f10d25acb1bc84eb967e diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index af25d930d1..8bfad8ee27 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1520,6 +1520,10 @@ static void pim_show_interface_traffic(struct pim_instance *pim, pim_ifp->pim_ifstat_join_recv); json_object_int_add(json_row, "joinTx", pim_ifp->pim_ifstat_join_send); + json_object_int_add(json_row, "pruneTx", + pim_ifp->pim_ifstat_prune_send); + json_object_int_add(json_row, "pruneRx", + pim_ifp->pim_ifstat_prune_recv); json_object_int_add(json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv); json_object_int_add(json_row, "registerTx", diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 355aa07048..a9f1d9335a 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -1294,10 +1294,16 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) json_row, "outboundInterface", rp_info->rp.source_nexthop .interface->name); - + else + json_object_string_add( + json_row, "outboundInterface", + "Unknown"); if (rp_info->i_am_rp) json_object_boolean_true_add(json_row, "iAmRP"); + else + json_object_boolean_false_add(json_row, + "iAmRP"); if (rp_info->plist) json_object_string_add(json_row, |
