summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_mplsvpn.c24
-rw-r--r--bgpd/bgp_nht.c34
-rw-r--r--sharpd/sharp_vty.c4
-rwxr-xr-xtools/frr-reload.py84
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)