commit cea7802cba88cca67acf3811bd5e1747cb755f6a
parent 4fd10f9bebb821a639f0385a61646588405da8e8
Author: Broadcom SDK Release <sdk.releases@broadcom.com>
Date: Thu, 6 Aug 2020 12:23:23 -0700
SDK-192126: 1) During propagation callback, bypass MC routes. 2) Fixed also
...
Devices: 56370_A0,56770_A0,56870_A0,56870_B0
Module: ALPM
Symptom:
When there were unicast and multicast routes on the same VRF, applying a
direct route change also applied to multicast, which shouldn't be done
1) During propagation callback, bypass MC routes. 2) Fixed also
vrf_init issue when MC routes are inserted first.
Diffstat:
3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/sdk-6.5.16/include/bcm_int/esw/alpm.h b/sdk-6.5.16/include/bcm_int/esw/alpm.h
@@ -315,6 +315,7 @@ typedef struct _alpm_pvt_node_s {
uint32 has_def; /* has default route */
uint32 tcam_idx; /* TCAM index in 1st level */
+ uint32 pvt_flags;
struct _alpm_bkt_node_s *def_pfx; /* Link to bkt_node for bkt def route */
struct _alpm_bkt_info_s bkt_info; /* Bucket info */
@@ -332,6 +333,7 @@ typedef struct _alpm_pvt_ctrl_s {
uint32 cnt_add;
uint32 cnt_del;
+ uint8 dr_inited; /* to indicate direct route inited first */
uint8 db_inited;
/* database type: FULL | REDUCED
* FULL : supports Destination AND
@@ -731,6 +733,8 @@ extern alpm_functions_t th_alpm_driver;
#define PVT_BKT_IDX(pvt_node) (PVT_BKT_INFO(pvt_node).bkt_idx)
#define PVT_SUB_BKT_IDX(pvt_node) (PVT_BKT_INFO(pvt_node).sub_bkt_idx)
#define PVT_BKT_VRF(pvt_node) ((pvt_node)->vrf_id)
+#define PVT_FLAGS(pvt_node) ((pvt_node)->pvt_flags)
+#define PVT_IS_IPMC(pvt_node) (PVT_FLAGS(pvt_node) & BCM_L3_IPMC)
#define PVT_BKT_PKM(pvt_node) ((pvt_node)->bkt_pkm)
#define PVT_BKT_IPT(pvt_node) (ALPM_PKM2IPT((pvt_node)->bkt_pkm))
#define PVT_BPM_LEN(pvt_node) ((pvt_node)->bpm_len)
@@ -849,6 +853,13 @@ extern alpm_functions_t th_alpm_driver;
#define ACB_VRF_SPLEN_DIFF2(u, acb, vrf_id, ipt) \
(ACB_PVT_CTRL(acb, vrf_id, ipt).spl_len_diff2)
+#define ACB_DR_INITED(u, acb, vrf_id, ipt) \
+ ((acb)->pvt_ctl[!!ipt] && \
+ ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited)
+#define ACB_DR_INIT_SET(u, acb, vrf_id, ipt) \
+ (ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited = TRUE)
+#define ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt) \
+ (ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited = FALSE)
#define ACB_BNK_CONF(acb) ((acb)->bnk_conf)
#define ACB_BNK_BMP(acb, vrf_id, ipt) \
diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm.c
@@ -453,6 +453,11 @@ alpm_ppg_assoc_data_cb(alpm_lib_trie_node_t *trie, alpm_lib_trie_bpm_cb_info_t *
pfx_len = ppg_data->key_len;
rpl_bpm_len = ppg_data->bpm_len;
+ /* bypass MC (direct route) for ppg in case of mix UC & MC in same VRF */
+ if (PVT_IS_IPMC(pvt_node)) {
+ return rv;
+ }
+
if (user_data->ppg_op == ALPM_PPG_INSERT) {
rpl_bpm_len = pfx_len;
}
@@ -655,6 +660,7 @@ alpm_pvt_trie_insert(int u, _bcm_defip_cfg_t *lpm_cfg)
/* Direct route pvt_node doesn't use bkt_trie, def_pfx & bkt_info */
PVT_KEY_LEN(pvt_node) = lpm_cfg->defip_sub_len;
PVT_KEY_CPY(pvt_node, lpm_cfg->user_data);
+ PVT_FLAGS(pvt_node) = lpm_cfg->defip_flags;
pvt_trie = ACB_PVT_TRIE(ACB_TOP(u), vrf_id, PVT_BKT_IPT(pvt_node));
rv = alpm_lib_trie_insert(pvt_trie, lpm_cfg->user_data,
@@ -679,6 +685,9 @@ alpm_pvt_trie_init(int u, int vrf_id, int ipt)
max_key_len = alpm_util_trie_max_key_len(u, ipt);
ALPM_IER(alpm_lib_trie_init(max_key_len, &ACB_PVT_TRIE(acb, vrf_id, ipt)));
ACB_VRF_INIT_SET(u, acb, vrf_id, ipt);
+ /* VRF DR partially inited: help to decide alpm_vrf_init
+ for case of mix MC & UC, in alpm_cb_insert */
+ ACB_DR_INIT_SET(u, acb, vrf_id, ipt);
return rv;
}
@@ -2414,6 +2423,7 @@ alpm_bkt_trie_split(int u, _alpm_cb_t *acb,
PVT_BKT_PKM(cpn) = pkm;
PVT_KEY_CPY(cpn, pvt_key);
PVT_KEY_LEN(cpn) = pvt_len;
+ PVT_FLAGS(cpn) = lpm_cfg->defip_flags;
*spl_pvt_node = cpn;
*spl_bkt_trie = cbt;
@@ -2860,6 +2870,7 @@ alpm_vrf_pvt_node_init(int u, _alpm_cb_t *acb,
PVT_BPM_LEN(tmp_node) = 0;
PVT_KEY_LEN(tmp_node) = pvt_cfg->defip_sub_len;
PVT_KEY_CPY(tmp_node, pvt_cfg->user_data);
+ PVT_FLAGS(tmp_node) = pvt_cfg->defip_flags;
PVT_IDX(tmp_node) = pvt_cfg->defip_index;
@@ -3062,6 +3073,7 @@ alpm_vrf_init(int u, _alpm_cb_t *acb, int vrf_id, int ipt, uint8 db_type)
ALPM_IEG_PRT_EXCEPT(alpm_cb_pvt_add(u, acb, vrf_id, ipt, &pvt_cfg), BCM_E_FULL);
ACB_VRF_INIT_SET(u, acb, vrf_id, ipt);
+ ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt); /* clear DR partially inited */
alpm_vrf_spl_len_calc(u, acb, vrf_id, db_type,
&ACB_VRF_SPLEN_DIFF1(u, acb, vrf_id, ipt),
@@ -4265,10 +4277,10 @@ alpm_cb_insert(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg)
_alpm_pvt_node_t *pvt_node, *upr_pvt_node;
_alpm_tcam_write_t tcam_write;
- /* Init ALPM structure for first insert */
- if (!ACB_VRF_INITED(u, acb, vrf_id, ipt)) {
+ /* Init ALPM structure for first insert or was DR partially inited (MC first) */
+ if (!ACB_VRF_INITED(u, acb, vrf_id, ipt) || ACB_DR_INITED(u, acb, vrf_id, ipt)) {
uint8 db_type = alpm_util_route_type_get(u, lpm_cfg);
- ALPM_IEG_PRT_EXCEPT(alpm_vrf_init(u, acb, vrf_id, ipt, db_type), BCM_E_FULL);
+ ALPM_IEG(alpm_vrf_init(u, acb, vrf_id, ipt, db_type));
}
if (ACB_BKT_FIXED_FMT(acb, vrf_id)) {
@@ -4972,6 +4984,7 @@ bcm_esw_alpm_delete(int u, _bcm_defip_cfg_t *lpm_cfg)
if (VRF_ROUTE_CNT(acb, vrf_id, ipt) == 0) {
(void)alpm_lib_trie_destroy(ACB_PVT_TRIE(acb, vrf_id, ipt));
ACB_VRF_INIT_CLEAR(u, acb, vrf_id, ipt);
+ ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt);
ACB_PVT_TRIE(acb, vrf_id, ipt) = NULL;
}
}
diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm_wb.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm_wb.c
@@ -142,6 +142,7 @@ alpm_wb_vrf_init(int u, _alpm_cb_t *acb, int vrf_id, int ipt)
alpm_lib_trie_init(max_key_len, &ACB_PVT_TRIE(acb, vrf_id, ipt)));
ACB_VRF_INIT_SET(u, acb, vrf_id, ipt);
+ ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt);
if (ACB_HAS_RTE(acb, vrf_id)) {
rv = alpm_lib_trie_init(max_key_len, &ALPM_VRF_TRIE(u, vrf_id, ipt));