openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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:
Msdk-6.5.16/src/bcm/esw/alpm2/alpm.c | 8+++++---
Msdk-6.5.16/src/bcm/esw/alpm2/alpm_tcam.c | 10+++++-----
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