shared_vlan_learning.c (9995B)
1 /* Feature : Shared VLAN learning 2 * 3 * Usage : BCM.0> cint shared_vlan_learning.c 4 * 5 * config : vlan_config.bcm 6 * 7 * Log file : shared_vlan_learning_log.txt 8 * 9 * Test Topology : 10 * 11 * +------------------------------+ 12 * | | 13 * | | 14 * | | 15 * ingress_port | | egress_port 16 * +----------------+ SWITCH +-----------------+ 17 * | | 18 * | | 19 * | | 20 * | | 21 * | | 22 * +------------------------------+ 23 * Summary: 24 * ======== 25 * This is a an example script shows how to enable shared vlan learning(SVL) feature. 26 * 27 * Detailed steps done in the CINT script: 28 * ======================================= 29 * 1) Step1 - Test Setup (Done in test_setup()): 30 * ============================================= 31 * a) Select two ports ingress_port and egress_port. 32 * 33 * 2) Step2 - Configuration (Done in config_svl()): 34 * ================================================ 35 * a) Creates two vlans 100 and 200 add ingress_port and egress_port as members. 36 * 37 * b) Enable shared VLAN learning on switch. 38 * 39 * c) Set 300 as forwarding ID for both vlans 100 & 200. 40 * 41 * 3) Step3 - Verification (Done in verify()): 42 * =========================================== 43 * a) Send vlan 100 and 200 tagged packets. 44 * 45 * b) Expected Result: 46 * =================== 47 * Verify that mac is learnt based on forwarding ID 300 using "l2 show". 48 */ 49 50 cint_reset(); 51 bcm_port_t ingress_port, egress_port; 52 /* This function is written so that hardcoding of port 53 numbers in Cint scripts is removed. This function gives 54 required number of ports 55 */ 56 bcm_error_t portNumbersGet(int unit, int *port_list, int num_ports) 57 { 58 59 int i=0,port=0,rv=0; 60 bcm_port_config_t configP; 61 bcm_pbmp_t ports_pbmp; 62 63 rv = bcm_port_config_get(unit,&configP); 64 if(BCM_FAILURE(rv)) { 65 printf("\nError in retrieving port configuration: %s.\n",bcm_errmsg(rv)); 66 return rv; 67 } 68 69 ports_pbmp = configP.e; 70 for (i= 1; i < BCM_PBMP_PORT_MAX; i++) { 71 if (BCM_PBMP_MEMBER(&ports_pbmp,i)&& (port < num_ports)) { 72 port_list[port]=i; 73 port++; 74 } 75 } 76 77 if (( port == 0 ) || ( port != num_ports )) { 78 printf("portNumbersGet() failed \n"); 79 return -1; 80 } 81 82 return BCM_E_NONE; 83 84 } 85 86 /* 87 * Configures the port in loopback mode and installs 88 * an IFP rule. This IFP rule copies the packets ingressing 89 * on the specified port to CPU. 90 */ 91 bcm_error_t ingress_port_setup(int unit, bcm_port_t port) 92 { 93 bcm_field_qset_t qset; 94 bcm_field_group_t group; 95 bcm_field_entry_t entry; 96 97 BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_MAC)); 98 99 BCM_FIELD_QSET_INIT(qset); 100 BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyInPort); 101 102 BCM_IF_ERROR_RETURN(bcm_field_group_create(unit, qset, BCM_FIELD_GROUP_PRIO_ANY, &group)); 103 104 BCM_IF_ERROR_RETURN(bcm_field_entry_create(unit, group, &entry)); 105 106 BCM_IF_ERROR_RETURN(bcm_field_qualify_InPort(unit, entry, port, BCM_FIELD_EXACT_MATCH_MASK)); 107 BCM_IF_ERROR_RETURN(bcm_field_action_add(unit, entry, bcmFieldActionCopyToCpu, 0, 0)); 108 109 BCM_IF_ERROR_RETURN(bcm_field_entry_install(unit, entry)); 110 return BCM_E_NONE; 111 } 112 113 /* 114 * Configures the port in loopback mode and installs 115 * an IFP rule. This IFP rule copies the packets ingressing 116 * on the specified port to CPU and drop the packets. This is 117 * to avoid continuous loopback of the packet. 118 */ 119 bcm_error_t egress_port_setup(int unit, bcm_port_t port) 120 { 121 bcm_field_qset_t qset; 122 bcm_field_group_t group; 123 bcm_field_entry_t entry; 124 125 BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_MAC)); 126 BCM_IF_ERROR_RETURN(bcm_port_discard_set(unit, port, BCM_PORT_DISCARD_ALL)); 127 128 BCM_FIELD_QSET_INIT(qset); 129 BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyInPort); 130 131 BCM_IF_ERROR_RETURN(bcm_field_group_create(unit, qset, BCM_FIELD_GROUP_PRIO_ANY, &group)); 132 133 BCM_IF_ERROR_RETURN(bcm_field_entry_create(unit, group, &entry)); 134 135 BCM_IF_ERROR_RETURN(bcm_field_qualify_InPort(unit, entry, port, BCM_FIELD_EXACT_MATCH_MASK)); 136 BCM_IF_ERROR_RETURN(bcm_field_action_add(unit, entry, bcmFieldActionCopyToCpu, 0, 0)); 137 BCM_IF_ERROR_RETURN(bcm_field_action_add(unit, entry, bcmFieldActionDrop, 0, 0)); 138 139 BCM_IF_ERROR_RETURN(bcm_field_entry_install(unit, entry)); 140 141 return BCM_E_NONE; 142 } 143 144 /* 145 * This functions gets the port numbers and sets up ingress and 146 * egress ports. Check ingress_port_setup() and egress_port_setup(). 147 */ 148 bcm_error_t test_setup(int unit) 149 { 150 int port_list[2]; 151 152 if (BCM_E_NONE != portNumbersGet(unit, port_list, 2)) { 153 printf("portNumbersGet() failed\n"); 154 return -1; 155 } 156 157 ingress_port = port_list[0]; 158 egress_port = port_list[1]; 159 160 if (BCM_E_NONE != ingress_port_setup(unit, ingress_port)) { 161 printf("ingress_port_setup() failed for port %d\n", ingress_port); 162 return -1; 163 } 164 165 if (BCM_E_NONE != egress_port_setup(unit, egress_port)) { 166 printf("egress_port_setup() failed for port %d\n", egress_port); 167 return -1; 168 } 169 170 bshell(unit, "pw start report +raw +decode"); 171 return BCM_E_NONE; 172 } 173 /* Creates two vlans 100 and 200 add ingress_port and egress_port as members. 174 * 175 * Enable shared VLAN learning on switch. 176 * 177 * Set 300 as forwarding ID for both vlans 100 & 200. 178 */ 179 bcm_error_t config_svl(int unit) 180 { 181 bcm_error_t rv; 182 bcm_pbmp_t pbmp,ubmp; 183 bcm_vlan_t vlan_100 = 100, vlan_200 = 200; 184 bcm_vlan_control_vlan_t control; 185 int F_ID = 300; /* forwarding database ID */ 186 187 /* create vlan 100 */ 188 rv = bcm_vlan_create(unit, vlan_100); 189 if (BCM_FAILURE(rv)) { 190 printf("Error executing bcm_vlan_create(): %s.\n", bcm_errmsg(rv)); 191 return rv; 192 } 193 /* Add port ingress_port to vlan 100 */ 194 BCM_PBMP_CLEAR(ubmp); 195 BCM_PBMP_CLEAR(pbmp); 196 BCM_PBMP_PORT_ADD(pbmp, ingress_port); 197 rv = bcm_vlan_port_add(unit, vlan_100, pbmp, ubmp); 198 if (BCM_FAILURE(rv)) { 199 printf("Error executing bcm_vlan_port_add(): %s.\n", bcm_errmsg(rv)); 200 return rv; 201 } 202 203 /* create vlan 200 */ 204 rv = bcm_vlan_create(unit, vlan_200); 205 if (BCM_FAILURE(rv)) { 206 printf("Error executing bcm_vlan_create(): %s.\n", bcm_errmsg(rv)); 207 return rv; 208 } 209 210 /* Add port egress_port to vlan 200 */ 211 BCM_PBMP_CLEAR(ubmp); 212 BCM_PBMP_CLEAR(pbmp); 213 BCM_PBMP_PORT_ADD(pbmp, egress_port); 214 rv = bcm_vlan_port_add(unit, vlan_200, pbmp, ubmp); 215 if (BCM_FAILURE(rv)) { 216 printf("Error executing bcm_vlan_port_add(): %s.\n", bcm_errmsg(rv)); 217 return rv; 218 } 219 220 /* Switch control to enable Shared VLAN learning feature */ 221 rv = bcm_switch_control_set(unit, bcmSwitchSharedVlanEnable, TRUE); 222 if (BCM_FAILURE(rv)) { 223 printf("Error executing bcm_switch_control_set(): %s.\n", bcm_errmsg(rv)); 224 return rv; 225 } 226 227 bcm_vlan_control_vlan_t_init(&control); 228 control.forwarding_vlan = F_ID; 229 230 /* Setting the forwarding ID for both vlan 100 & 200 to be learned under */ 231 rv = bcm_vlan_control_vlan_set(unit, vlan_100, control); 232 if (BCM_FAILURE(rv)) { 233 printf("Error executing bcm_vlan_control_vlan_set(): %s.\n", bcm_errmsg(rv)); 234 return rv; 235 } 236 237 rv = bcm_vlan_control_vlan_set(unit, vlan_200, control); 238 if (BCM_FAILURE(rv)) { 239 printf("Error executing bcm_vlan_control_vlan_set(): %s.\n", bcm_errmsg(rv)); 240 return rv; 241 } 242 return BCM_E_NONE; 243 } 244 /* Send vlan 100 and 200 tagged packets and verify that mac is 245 * learnt based on forwarding ID 300 using "l2 show". 246 */ 247 void verify(int unit) 248 { 249 char str[512]; 250 251 bshell(unit, "hm ieee"); 252 253 254 /* Send 1 VLAN 100 tagged packet. 255 * Ethernet header: DA=00:00:00:00:00:01, SA=00:00:00:00:00:02 256 * 257 * 000000000001 000000000002 258 * 8100 0064 259 * 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F46E12242 260 */ 261 printf("Sending VLAN 100 tagged packet on port %d\n", ingress_port); 262 snprintf(str, 512, "tx 1 pbm=%d data=0x00000000000100000000000281000064000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F46E12242; sleep 1", ingress_port); 263 bshell(unit, str); 264 printf("\nExecuting \"l2 show\" after sending VLAN 100 tagged packet\n"); 265 bshell(unit, "l2 show"); 266 267 /* Send 1 VLAN 200 tagged packet. 268 * Ethernet header: DA=00:00:00:00:00:03, SA=00:00:00:00:00:04 269 * 270 * 000000000003 000000000004 271 * 8100 00c8 272 * 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F27DEDA48 273 */ 274 printf("Sending VLAN 200 tagged packet on port %d\n", ingress_port); 275 snprintf(str, 512, "tx 1 pbm=%d data=0x000000000003000000000004810000C8000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F27DEDA48; sleep 1", ingress_port); 276 bshell(unit, str); 277 printf("\nExecuting \"l2 show\" after sending VLAN 200 tagged packet\n"); 278 bshell(unit, "l2 show"); 279 } 280 281 /* 282 * This functions does the following 283 * a)test setup 284 * b)actual configuration (Done in config_svl()) 285 * c)demonstrates the functionality (Done in verify()). 286 */ 287 bcm_error_t execute() 288 { 289 bcm_error_t rv; 290 int unit = 0; 291 292 bshell(unit, "config show; a ; version"); 293 294 if (BCM_FAILURE((rv = test_setup(unit)))) { 295 printf("test_setup() failed.\n"); 296 return -1; 297 } 298 printf("Completed test setup successfully.\n"); 299 300 if (BCM_FAILURE((rv = config_svl(unit)))) { 301 printf("config_svl() failed.\n"); 302 return -1; 303 } 304 printf("Completed configuration(i.e executing config_svl()) successfully.\n"); 305 306 verify(unit); 307 return BCM_E_NONE; 308 } 309 310 const char *auto_execute = (ARGC == 1) ? ARGV[0] : "YES"; 311 if (!sal_strcmp(auto_execute, "YES")) { 312 print execute(); 313 } 314