diff options
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 24 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 34 | ||||
| -rw-r--r-- | sharpd/sharp_vty.c | 4 | ||||
| -rwxr-xr-x | tools/frr-reload.py | 84 |
4 files changed, 121 insertions, 25 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index b3d8d1b82d..4d8c4ac2ac 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -532,6 +532,7 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, bool alloced = false; int label = 0; uint8_t offset = 0; + uint8_t len = 0; if (!bgp || !sid_locator || !sid) return false; @@ -540,10 +541,11 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, *sid_locator = chunk->prefix.prefix; *sid = chunk->prefix.prefix; offset = chunk->block_bits_length + chunk->node_bits_length; + len = chunk->function_bits_length ?: 16; if (index != 0) { label = index << 12; - transpose_sid(sid, label, offset, 16); + transpose_sid(sid, label, offset, len); if (sid_exist(bgp, sid)) return false; alloced = true; @@ -552,7 +554,7 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, for (size_t i = 1; i < 255; i++) { label = i << 12; - transpose_sid(sid, label, offset, 16); + transpose_sid(sid, label, offset, len); if (sid_exist(bgp, sid)) continue; alloced = true; @@ -633,13 +635,29 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi) tovpn_sid_transpose_label; } +/* + * This function shifts "label" 4 bits to the right and + * embeds it by length "len", starting at offset "offset" + * as seen from the MSB (Most Significant Bit) of "sid". + * + * e.g. if "label" is 0x1000 and "len" is 16, "label" is + * embedded in "sid" as follows: + * + * <---- len -----> + * label: 0000 0001 0000 0000 0000 + * sid: .... 0000 0001 0000 0000 + * <---- len -----> + * ^ + * | + * offset from MSB + */ void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset, uint8_t len) { for (uint8_t idx = 0; idx < len; idx++) { uint8_t tidx = offset + idx; sid->s6_addr[tidx / 8] &= ~(0x1 << (7 - tidx % 8)); - if (label >> (19 - idx) & 0x1) + if (label >> (len + 3 - idx) & 0x1) sid->s6_addr[tidx / 8] |= 0x1 << (7 - tidx % 8); } } diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index dc4f30a906..3433e1471c 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -390,7 +390,8 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer) } static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc, - struct zapi_route *nhr) + struct zapi_route *nhr, + bool import_check) { struct nexthop *nexthop; struct nexthop *oldnh; @@ -421,7 +422,21 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc, if (nhr->nexthop_num != bnc->nexthop_num) bnc->change_flags |= BGP_NEXTHOP_CHANGED; - if (nhr->nexthop_num) { + if (import_check && (nhr->type == ZEBRA_ROUTE_BGP || + !prefix_same(&bnc->prefix, &nhr->prefix))) { + SET_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED); + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID); + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE); + + bnc_nexthop_free(bnc); + bnc->nexthop = NULL; + + if (BGP_DEBUG(nht, NHT)) + zlog_debug( + "%s: Import Check does not resolve to the same prefix for %pFX received %pFX or matching route is BGP", + __func__, &bnc->prefix, &nhr->prefix); + } else if (nhr->nexthop_num) { struct peer *peer = bnc->nht_info; /* notify bgp fsm if nbr ip goes from invalid->valid */ @@ -695,7 +710,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) "parse nexthop update(%pFX(%u)(%s)): bnc info not found for nexthop cache", &nhr.prefix, nhr.srte_color, bgp->name_pretty); } else - bgp_process_nexthop_update(bnc_nhc, &nhr); + bgp_process_nexthop_update(bnc_nhc, &nhr, false); tree = &bgp->import_check_table[afi]; @@ -706,17 +721,8 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) "parse nexthop update(%pFX(%u)(%s)): bnc info not found for import check", &nhr.prefix, nhr.srte_color, bgp->name_pretty); return; - } else { - if (nhr.type == ZEBRA_ROUTE_BGP - || !prefix_same(&bnc_import->prefix, &nhr.prefix)) { - if (BGP_DEBUG(nht, NHT)) - zlog_debug( - "%s: Import Check does not resolve to the same prefix for %pFX received %pFX", - __func__, &bnc_import->prefix, &nhr.prefix); - return; - } - bgp_process_nexthop_update(bnc_import, &nhr); } + bgp_process_nexthop_update(bnc_import, &nhr, true); /* * HACK: if any BGP route is dependant on an SR-policy that doesn't @@ -739,7 +745,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) || CHECK_FLAG(bnc_iter->flags, BGP_NEXTHOP_VALID)) continue; - bgp_process_nexthop_update(bnc_iter, &nhr); + bgp_process_nexthop_update(bnc_iter, &nhr, false); } } } diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 889643f65e..2281b3ce26 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -104,7 +104,7 @@ DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd, p.family = AF_INET6; } else { type_import = true; - p = *(const struct prefix *)inhop; + prefix_copy(&p, inhop); } sharp_nh_tracker_get(&p); @@ -149,7 +149,7 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd, } else { type_import = true; - p = *(const struct prefix *)inhop; + prefix_copy(&p, inhop); } sharp_nh_tracker_get(&p); diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 4f30f7fbd8..f47f9a7eb0 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -763,6 +763,38 @@ def check_for_exit_vrf(lines_to_add, lines_to_del): return (lines_to_add, lines_to_del) +def bgp_delete_inst_move_line(lines_to_del): + # Deletion of bgp default inst followed by + # bgp vrf inst leads to issue of default + # instance can not be removed. + # Move the bgp default instance line to end. + bgp_defult_inst = False + bgp_vrf_inst = False + + for (ctx_keys, line) in lines_to_del: + # Find bgp default inst + if ( + ctx_keys[0].startswith("router bgp") + and not line + and "vrf" not in ctx_keys[0] + ): + bgp_defult_inst = True + # Find bgp vrf inst + if ctx_keys[0].startswith("router bgp") and not line and "vrf" in ctx_keys[0]: + bgp_vrf_inst = True + + if bgp_defult_inst and bgp_vrf_inst: + for (ctx_keys, line) in lines_to_del: + # move bgp default inst to end + if ( + ctx_keys[0].startswith("router bgp") + and not line + and "vrf" not in ctx_keys[0] + ): + lines_to_del.remove((ctx_keys, line)) + lines_to_del.append((ctx_keys, line)) + + def bgp_delete_nbr_remote_as_line(lines_to_add): # Handle deletion of neighbor <nbr> remote-as line from # lines_to_add if the nbr is configured with peer-group and @@ -841,19 +873,44 @@ def bgp_delete_nbr_remote_as_line(lines_to_add): lines_to_add.remove((ctx_keys, line)) -""" -This method handles deletion of bgp peer group config. -The objective is to delete config lines related to peers -associated with the peer-group and move the peer-group -config line to the end of the lines_to_del list. -""" +def bgp_remove_neighbor_cfg(lines_to_del, del_nbr_dict): + + # This method handles deletion of bgp neighbor configs, + # if there is neighbor to peer-group cmd is in delete list. + # As 'no neighbor .* peer-group' deletes the neighbor, + # subsequent neighbor speciic config line deletion results + # in error. + lines_to_del_to_del = [] + + for (ctx_keys, line) in lines_to_del: + if ( + ctx_keys[0].startswith("router bgp") + and line + and line.startswith("neighbor ") + ): + if ctx_keys[0] in del_nbr_dict: + for nbr in del_nbr_dict[ctx_keys[0]]: + re_nbr_pg = re.search('neighbor (\S+) .*peer-group (\S+)', line) + nb_exp = "neighbor %s .*" % nbr + if not re_nbr_pg: + re_nb = re.search(nb_exp, line) + if re_nb: + lines_to_del_to_del.append((ctx_keys, line)) + + for (ctx_keys, line) in lines_to_del_to_del: + lines_to_del.remove((ctx_keys, line)) def delete_move_lines(lines_to_add, lines_to_del): + # This method handles deletion of bgp peer group config. + # The objective is to delete config lines related to peers + # associated with the peer-group and move the peer-group + # config line to the end of the lines_to_del list. bgp_delete_nbr_remote_as_line(lines_to_add) del_dict = dict() + del_nbr_dict = dict() # Stores the lines to move to the end of the pending list. lines_to_del_to_del = [] # Stores the lines to move to end of the pending list. @@ -937,6 +994,16 @@ def delete_move_lines(lines_to_add, lines_to_del): if re_nb_remoteas: lines_to_del_to_app.append((ctx_keys, line)) + # 'no neighbor peer [interface] peer-group <>' is in lines_to_del + # copy the neighbor and look for all config removal lines associated + # to neighbor and delete them from the lines_to_del + re_nbr_pg = re.search('neighbor (\S+) .*peer-group (\S+)', line) + if re_nbr_pg: + if ctx_keys[0] not in del_nbr_dict: + del_nbr_dict[ctx_keys[0]] = list() + if re_nbr_pg.group(1) not in del_nbr_dict[ctx_keys[0]]: + del_nbr_dict[ctx_keys[0]].append(re_nbr_pg.group(1)) + # {'router bgp 65001': {'PG': [], 'PG1': []}, # 'router bgp 65001 vrf vrf1': {'PG': [], 'PG1': []}} if ctx_keys[0] not in del_dict: @@ -948,6 +1015,9 @@ def delete_move_lines(lines_to_add, lines_to_del): found_pg_del_cmd = True if found_pg_del_cmd == False: + bgp_delete_inst_move_line(lines_to_del) + if del_nbr_dict: + bgp_remove_neighbor_cfg(lines_to_del, del_nbr_dict) return (lines_to_add, lines_to_del) for (ctx_keys, line) in lines_to_del_to_app: @@ -1001,6 +1071,8 @@ def delete_move_lines(lines_to_add, lines_to_del): lines_to_del.remove((ctx_keys, line)) lines_to_del.append((ctx_keys, line)) + bgp_delete_inst_move_line(lines_to_del) + return (lines_to_add, lines_to_del) |
