commit 18b588b16f8ed2d56405679f0efcd937a3ec4359
parent 5f7c27b0a22f6ef32c3d275460dd20b051599668
Author: Broadcom SDK Release <sdk.releases@broadcom.com>
Date: Mon, 8 Apr 2019 10:05:19 -0700
SDK-174695: In the previous release, ALPM sw states could be out of sync when...
Devices: 56980_A0,56980_B0
Module: ALPM
Symptom:
Inappropriate handling on alpm_bkt_add_to_npvt->alpm_bkt_insert
returning -6 causes alpm SW state corruption.
In the previous release, ALPM sw states could be out of sync when LPM
TCAM reaches full in Parallel mode, and causes mis-forwarding or bucket
split segmentation fault. In current release, this issue has been fixed.
Diffstat:
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm.c
@@ -3560,10 +3560,12 @@ alpm_cb_split(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg,
if (!ACB_BKT_FIXED_FMT(acb, 1) && ACB_HAS_TCAM(acb)) {
/* Check if an extra split is required */
rv = alpm_bkt_ent_get(u, vrf_id, acb, npvt_node, lpm_cfg->defip_sub_len, NULL, NULL, 1);
- if (rv == BCM_E_FULL &&
+ if (rv == BCM_E_FULL) {
+ int rsvd = (ipt == ALPM_IPT_V6) ? 1 : 0;
/* Cannot affort another split, so should return here */
- !bcm_esw_alpm_tcam_avail(u, vrf_id, ipt, PVT_KEY_LEN(npvt_node), 0)) {
- ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL);
+ if (bcm_esw_alpm_tcam_avail(u, vrf_id, ipt, PVT_KEY_LEN(npvt_node), 0) <= rsvd) {
+ ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL);
+ }
}
}
diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm_tcam.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm_tcam.c
@@ -1287,7 +1287,7 @@ _tcam_cfg_insert(int u, int zid, _bcm_defip_cfg_t *lpm_cfg, uint32 write_flags)
int
bcm_esw_alpm_tcam_avail(int u, int vrf_id, int ipt, int key_len, int mc)
{
- int pfx, zid;
+ int pfx, zid, fent, cnt = 0;
if (!TCAMC(u)) {
return 0;
@@ -1296,14 +1296,14 @@ bcm_esw_alpm_tcam_avail(int u, int vrf_id, int ipt, int key_len, int mc)
zid = _tcam_zone_zid_get(u, ALPM_VRF_ID_TO_VRF(u, vrf_id), ipt, ALPM_128B(u), mc);
pfx = _TCAMZ_PFX_MAX_IDX(u, zid);
while (pfx >= 0) {
- if (_TCAM_STATE_FENT(u, zid, pfx) > 0) {
- return 1;
+ fent = _TCAM_STATE_FENT(u, zid, pfx);
+ if (fent > 0) {
+ cnt += fent;
}
-
pfx = _TCAM_STATE_NEXT(u, zid, pfx);
}
- return 0;
+ return cnt;
}
int