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

l2_qos.c (14728B)


      1  /* Feature  : L2 QoS
      2  *
      3  *  Usage    : BCM.0> cint l2_qos.c
      4  *
      5  *  config   : vlan_config.bcm
      6  *
      7  *  Log file : l2_qos_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 cint example configures mapping between {L2 packet Priority + CFI bit} and
     26  *    {internal priority and CNG} using BCM APIs. It also shows how internal priority
     27  *    and CNG can be used to remark out going packet's priority and CFI fields.
     28  *
     29  *  Detailed steps done in the CINT script:
     30  *  =======================================
     31  *    1) Step1 - Test Setup (Done in test_setup()):
     32  *    =============================================
     33  *      a) Selects one ingress port and one egress port and configure them in Loopback mode.
     34  *         Install a rule to copy incoming packets to CPU and start packet watcher.
     35  *
     36  *    2) Step2 - Configuration (Done in l2_qos()):
     37  *    ============================================
     38  *      a) Creates a VLAN(20) and add ingress port and  egress port as members.
     39  *
     40  *      b) Configure ingress port's default VLAN as 20, default packet priority as 4 and CFI as 1.
     41  *
     42  *      c) Configure ingress QoS mapping as below and attach it to ingress_port.
     43  *               {packet priority(4) + CFI(1)} is mapped to {internal_priority(10) + CNG(Yellow)}.
     44  *
     45  *      d) Configure egress QoS mapping as below and attach it to egress_port.
     46  *               {{internal_priority(10) + CNG(Yellow)} is mapped {packet priority(2) + CFI(0)}.
     47  *
     48  *    3) Step3 - Verification (Done in verify()):
     49  *    ===========================================
     50  *      a) Send the below untagged packet on ingress port.
     51  *        
     52  *        Packet:
     53  *        =======
     54  *        Ethernet header: DA=00:00:00:00:00:02, SA=00:00:00:00:00:01
     55  *
     56  *        0000 0000 0002 0000 0000 0001 0001 0203
     57  *        0405 0607 0809 0A0B 0C0D 0E0F 1011 1213
     58  *        1415 1617 1819 1A1B 1C1D 1E1F 2021 2223
     59  *        2425 2627 2829 2A2B 2C2D 2E2F DF52 E538
     60  *
     61  *      b) Expected Result:
     62  *      ===================
     63  *        The packet going out of egress_port has packet priority as "2" and CFI as "0".
     64  *        Below is the packet that egresses out of egress_port.
     65  *
     66  *        Packet:
     67  *        =======
     68  *        Ethernet II, Src: 00:00:00_00:00:01 (00:00:00:00:00:01), Dst: 00:00:00_00:00:02 (00:00:00:00:00:02)
     69  *        802.1Q Virtual LAN, PRI: 2, CFI: 0, ID: 20
     70  *        010. .... .... .... = Priority: Spare (2)
     71  *          ...0 .... .... .... = CFI: Canonical (0)
     72  *            .... 0000 0001 0100 = ID: 20
     73  *
     74  *        0000 0000 0002 0000 0000 0001 8100 4014
     75  *        0001 0203 0405 0607 0809 0a0b 0c0d 0e0f
     76  *        1011 1213 1415 1617 1819 1a1b 1c1d 1e1f
     77  *        2021 2223 2425 2627 2829 2a2b 2c2d 2e2f
     78  *        df52 e538
     79  */
     80 /* Reset c interpreter*/
     81 cint_reset();
     82 bcm_port_t ingress_port, egress_port;
     83 
     84 /* This function is written so that hardcoding of port 
     85    numbers in Cint scripts is removed. This function gives
     86    required number of ports
     87 */
     88 bcm_error_t portNumbersGet(int unit, int *port_list, int num_ports)
     89 {
     90 
     91   int i=0,port=0,rv=0;
     92   bcm_port_config_t configP;
     93   bcm_pbmp_t ports_pbmp;
     94 
     95   rv = bcm_port_config_get(unit,&configP);
     96   if(BCM_FAILURE(rv)) {
     97     printf("\nError in retrieving port configuration: %s.\n",bcm_errmsg(rv));
     98     return rv;
     99   }
    100 
    101   ports_pbmp = configP.e;
    102   for (i= 1; i < BCM_PBMP_PORT_MAX; i++) {
    103     if (BCM_PBMP_MEMBER(&ports_pbmp,i)&& (port < num_ports)) {
    104       port_list[port]=i;
    105       port++;
    106     }
    107   }
    108 
    109   if (( port == 0 ) || ( port != num_ports )) {
    110       printf("portNumbersGet() failed \n");
    111       return -1;
    112   }
    113 
    114   return BCM_E_NONE;
    115 
    116 }
    117 
    118 /* 
    119  * Configures the port in loopback mode and installs
    120  * an IFP rule. This IFP rule copies the packets ingressing
    121  * on the specified port to CPU.
    122  */
    123 bcm_error_t ingress_port_setup(int unit, bcm_port_t port)
    124 {
    125   bcm_field_qset_t  qset;
    126   bcm_field_group_t group;
    127   bcm_field_entry_t entry;
    128 
    129   BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_MAC));
    130   
    131   BCM_FIELD_QSET_INIT(qset);
    132   BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyInPort);
    133   
    134   BCM_IF_ERROR_RETURN(bcm_field_group_create(unit, qset, BCM_FIELD_GROUP_PRIO_ANY, &group));
    135   
    136   BCM_IF_ERROR_RETURN(bcm_field_entry_create(unit, group, &entry));
    137   
    138   BCM_IF_ERROR_RETURN(bcm_field_qualify_InPort(unit, entry, port, BCM_FIELD_EXACT_MATCH_MASK));
    139   BCM_IF_ERROR_RETURN(bcm_field_action_add(unit, entry, bcmFieldActionCopyToCpu, 0, 0));
    140   
    141   BCM_IF_ERROR_RETURN(bcm_field_entry_install(unit, entry));
    142   return BCM_E_NONE;
    143 }
    144 
    145 /* 
    146  * Configures the port in loopback mode and installs
    147  * an IFP rule. This IFP rule copies the packets ingressing
    148  * on the specified port to CPU and drop the packets. This is
    149  * to avoid continuous loopback of the packet.
    150  */
    151 bcm_error_t egress_port_setup(int unit, bcm_port_t port)
    152 {
    153   bcm_field_qset_t  qset;
    154   bcm_field_group_t group;
    155   bcm_field_entry_t entry;
    156 
    157   BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_MAC));
    158   BCM_IF_ERROR_RETURN(bcm_port_discard_set(unit, port, BCM_PORT_DISCARD_ALL));
    159   
    160   BCM_FIELD_QSET_INIT(qset);
    161   BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyInPort);
    162   
    163   BCM_IF_ERROR_RETURN(bcm_field_group_create(unit, qset, BCM_FIELD_GROUP_PRIO_ANY, &group));
    164   
    165   BCM_IF_ERROR_RETURN(bcm_field_entry_create(unit, group, &entry));
    166   
    167   BCM_IF_ERROR_RETURN(bcm_field_qualify_InPort(unit, entry, port, BCM_FIELD_EXACT_MATCH_MASK));
    168   BCM_IF_ERROR_RETURN(bcm_field_action_add(unit, entry, bcmFieldActionCopyToCpu, 0, 0));
    169   BCM_IF_ERROR_RETURN(bcm_field_action_add(unit, entry, bcmFieldActionDrop, 0, 0));
    170   
    171   BCM_IF_ERROR_RETURN(bcm_field_entry_install(unit, entry));
    172 
    173   return BCM_E_NONE;
    174 }
    175 /* 
    176  * This functions gets the port numbers and sets up ingress and 
    177  * egress ports. Check ingress_port_setup() and egress_port_setup().
    178  */
    179 bcm_error_t test_setup(int unit)
    180 {
    181   int port_list[2];
    182 
    183   if (BCM_E_NONE != portNumbersGet(unit, port_list, 2)) {
    184     printf("portNumbersGet() failed\n");
    185     return -1;
    186   }
    187 
    188   ingress_port = port_list[0];
    189   egress_port = port_list[1];
    190 
    191   if (BCM_E_NONE != ingress_port_setup(unit, ingress_port)) {
    192     printf("ingress_port_setup() failed for port %d\n", ingress_port);
    193     return -1;
    194   }
    195 
    196   if (BCM_E_NONE != egress_port_setup(unit, egress_port)) {
    197       printf("egress_port_setup() failed for port %d\n", egress_port);
    198       return -1;
    199   }
    200 
    201   bshell(unit, "pw start report +raw +decode");
    202   return BCM_E_NONE;
    203 }
    204 
    205 /* Setup port configuration w.r.t untagged vlan id, port priority and drop precedence*/
    206 bcm_error_t port_config(int unit, bcm_port_t port, int vlan, uint8 priority, uint8 CFI)
    207 {
    208     bcm_error_t rv;   
    209     bcm_vlan_action_set_t action;
    210 
    211     rv = bcm_port_untagged_vlan_set(unit,port,vlan);
    212     if (BCM_FAILURE(rv)) {
    213         printf("Error executing bcm_port_untagged_vlan_set(): %s.\n", bcm_errmsg(rv));
    214         return rv;
    215     }
    216 
    217     /* set default packet priority value in port table */
    218     rv = bcm_port_untagged_priority_set(unit, port, priority);
    219     if (BCM_FAILURE(rv)) {
    220         printf("Error executing bcm_port_untagged_priority_set(): %s.\n", bcm_errmsg(rv));
    221         return rv;
    222     }
    223 
    224     rv = bcm_vlan_port_default_action_get(unit, port, &action);
    225     if (BCM_FAILURE(rv)) {
    226         printf("Error executing bcm_vlan_port_default_action_get(): %s.\n", bcm_errmsg(rv));
    227         return rv;
    228     }
    229 
    230     rv = bcm_vlan_port_default_action_delete(unit,port);
    231     if (BCM_FAILURE(rv)) {
    232         printf("Error executing bcm_vlan_port_default_action_delete(): %s.\n", bcm_errmsg(rv));
    233         return rv;
    234     }
    235 
    236     action.new_outer_cfi = CFI;
    237     action.priority      = priority;
    238     rv = bcm_vlan_port_default_action_set(unit,port,action);
    239     if (BCM_FAILURE(rv)) {
    240         printf("Error executing bcm_vlan_port_default_action_set(): %s.\n", bcm_errmsg(rv));
    241         return rv;
    242     }
    243 
    244     return BCM_E_NONE;
    245 }
    246 /* Setup L2 qos mapping */
    247 bcm_error_t
    248 qos_port_setup(int unit, bcm_port_t port, unsigned int flags, uint8 internal_pri, bcm_color_t clr, uint8 priority, uint8 CFI)
    249 {
    250     int qMapId = 0;
    251     bcm_error_t rv;   
    252     bcm_qos_map_t qMap;
    253     bcm_gport_t gport;
    254     BCM_GPORT_MODPORT_SET(gport, unit, port);
    255     /* Reserve hardware resources for QoS mapping */
    256     rv = bcm_qos_map_create(unit, flags, &qMapId);
    257     if (BCM_FAILURE(rv)) {
    258         printf("Error executing bcm_qos_map_create(): %s.\n", bcm_errmsg(rv));
    259         return rv;
    260     }
    261 
    262     qMap.int_pri = internal_pri;
    263     qMap.color   = clr;
    264     qMap.pkt_pri = priority;
    265     qMap.pkt_cfi = CFI;
    266     rv = bcm_qos_map_add(unit, flags, &qMap, qMapId);
    267     if (BCM_FAILURE(rv)) {
    268         printf("Error executing bcm_qos_map_add(): %s.\n", bcm_errmsg(rv));
    269         return rv;
    270     }
    271 
    272     if(flags & BCM_QOS_MAP_INGRESS) {
    273         rv = bcm_qos_port_map_set(unit, gport, qMapId, -1);
    274         if (BCM_FAILURE(rv)) {
    275           printf("Error executing bcm_qos_port_map_set(): %s.\n", bcm_errmsg(rv));
    276           return rv;
    277         }
    278     } else {
    279         rv = bcm_qos_port_map_set(unit, gport, -1, qMapId);
    280         if (BCM_FAILURE(rv)) {
    281           printf("Error executing bcm_qos_port_map_set(): %s.\n", bcm_errmsg(rv));
    282           return rv;
    283         }
    284     }
    285     return BCM_E_NONE;
    286 }
    287 /* Creates a VLAN(20) and add ingress port and  egress port as members.
    288  * 
    289  * Configure ingress port's default VLAN as 20, default packet priority as 4 and CFI as 1.
    290  *
    291  * Configure ingress QoS mapping as below and attach it to ingress_port.
    292  *             {packet priority(4) + CFI(1)} is mapped to {internal_priority(10) + CNG(Yellow)}.
    293  *
    294  * Configure egress QoS mapping as below and attach it to egress_port.
    295  *             {{internal_priority(10) + CNG(Yellow)} is mapped {packet priority(2) + CFI(0)}.
    296  */
    297 
    298 bcm_error_t l2_qos(int unit)
    299 {
    300   bcm_error_t rv;
    301   bcm_pbmp_t  pbmp, ubmp;
    302   bcm_vlan_t vlanId = 20;
    303   uint8 priority = 4, internal_priority = 10, CFI;
    304   /* Create the vlan with specific id if it is already present then error will be returned */
    305   rv = bcm_vlan_create(unit, vlanId);
    306   if (BCM_FAILURE(rv)) {
    307       printf("Error executing bcm_vlan_create(): %s.\n", bcm_errmsg(rv));
    308       return rv;
    309   }
    310 
    311   /*Add ingress_port and egress_port as members of vlanId*/
    312   BCM_PBMP_CLEAR(ubmp);
    313   BCM_PBMP_CLEAR(pbmp);
    314   BCM_PBMP_PORT_ADD(pbmp, ingress_port);
    315   BCM_PBMP_PORT_ADD(pbmp, egress_port);
    316 
    317   rv = bcm_vlan_port_add(unit, vlanId, pbmp, ubmp);
    318   if (BCM_FAILURE(rv)) {
    319       printf("Error executing bcm_vlan_port_add(): %s.\n", bcm_errmsg(rv));
    320       return rv;
    321   }
    322 
    323 /* set CFI and default packet priority values in port table for untagged packets */
    324   CFI = 1;
    325   rv = port_config(unit, ingress_port, vlanId, priority, CFI);
    326   if (BCM_FAILURE(rv)) {
    327       printf("Error executing port_config(): %s.\n", bcm_errmsg(rv));
    328       return rv;
    329   }
    330 
    331 /* Configure ingress priority mapping on port "ingress_port"
    332  * for mapping {packet priority 4 + CFI 1} to internal priority 10
    333  */
    334   rv = qos_port_setup(unit, ingress_port, BCM_QOS_MAP_INGRESS | BCM_QOS_MAP_L2, internal_priority, bcmColorYellow, priority, CFI);
    335   if (BCM_FAILURE(rv)) {
    336       printf("Error executing qos_port_setup() for ingress mapping: %s.\n", bcm_errmsg(rv));
    337       return rv;
    338   }
    339 
    340   /*Required for CFI remarking on egress port. Sets EGR_VLAN_CONTROL_1r.CFI_AS_CNGf = 1*/
    341   rv = bcm_switch_control_port_set(unit, egress_port, bcmSwitchColorSelect, BCM_COLOR_OUTER_CFI);
    342   if (BCM_FAILURE(rv)) {
    343       printf("Error executing bcm_switch_control_port_set(): %s.\n", bcm_errmsg(rv));
    344       return rv;
    345   }
    346 
    347   CFI = 0;
    348   /*
    349    * Configure egress QoS mapping as below and attach it to egress_port.
    350    * {{internal_priority(10) + CNG(Yellow)} to {packet priority(2) + CFI(0)}.
    351   */
    352   rv = qos_port_setup(unit, egress_port, BCM_QOS_MAP_EGRESS | BCM_QOS_MAP_L2, internal_priority, bcmColorYellow, 2, CFI);
    353   if (BCM_FAILURE(rv)) {
    354       printf("Error executing qos_port_setup() for egress mapping: %s.\n", bcm_errmsg(rv));
    355       return rv;
    356   }
    357 
    358   return BCM_E_NONE;
    359 }
    360 /*     This function does the following.
    361  *     ==============================
    362  *     Send the below untagged packet on ingress port.
    363  *      
    364  *      Packet:
    365  *      ======
    366  *      Ethernet header: DA=00:00:00:00:00:02, SA=00:00:00:00:00:01
    367  *
    368  *      0000 0000 0002 0000 0000 0001 0001 0203
    369  *      0405 0607 0809 0A0B 0C0D 0E0F 1011 1213
    370  *      1415 1617 1819 1A1B 1C1D 1E1F 2021 2223
    371  *      2425 2627 2829 2A2B 2C2D 2E2F DF52 E538
    372  *
    373  *      The below packet egresses on egress_port with packet priority 2 and CFI 0.
    374  *
    375  *      Packet:
    376  *      ======
    377  *      Ethernet II, Src: 00:00:00_00:00:01 (00:00:00:00:00:01), Dst: 00:00:00_00:00:02 (00:00:00:00:00:02)
    378  *      802.1Q Virtual LAN, PRI: 2, CFI: 0, ID: 20
    379  *      010. .... .... .... = Priority: Spare (2)
    380  *        ...0 .... .... .... = CFI: Canonical (0)
    381  *          .... 0000 0001 0100 = ID: 20
    382  *
    383  *      0000 0000 0002 0000 0000 0001 8100 4014
    384  *      0001 0203 0405 0607 0809 0a0b 0c0d 0e0f
    385  *      1011 1213 1415 1617 1819 1a1b 1c1d 1e1f
    386  *      2021 2223 2425 2627 2829 2a2b 2c2d 2e2f
    387  *      df52 e538
    388  */
    389 
    390 void verify(int unit)
    391 {
    392   char   str[512];
    393 
    394   bshell(unit, "hm ieee");
    395 
    396   printf("Sending untagged packet on ingress_port:%d\n", ingress_port);
    397   snprintf(str, 512, "tx 1 pbm=%d data=0x000000000002000000000001000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2FDF52E538; sleep 1", ingress_port);
    398   bshell(unit, str);
    399 
    400 }
    401 /*
    402  * This functions does the following
    403  * a)test setup
    404  * b)actual configuration (Done in l2_qos())
    405  * c)demonstrates the functionality (Done in verify()).
    406  */
    407 bcm_error_t execute()
    408 {
    409   bcm_error_t rv;
    410   int unit =0;
    411 
    412   bshell(unit, "config show; a ; version");
    413 
    414   if (BCM_FAILURE((rv = test_setup(unit)))) {
    415     printf("test_setup() failed.\n");
    416     return -1;
    417   }
    418   printf("Completed test setup successfully.\n");
    419 
    420   if (BCM_FAILURE((rv = l2_qos(unit)))) {
    421     printf("l2_qos() failed.\n");
    422     return -1;
    423   }
    424   printf("Completed configuration(i.e executing l2_qos()) successfully.\n");
    425 
    426   verify(unit);
    427   return BCM_E_NONE;
    428 }
    429 
    430 const char *auto_execute = (ARGC == 1) ? ARGV[0] : "YES";
    431 if (!sal_strcmp(auto_execute, "YES")) {
    432   print execute();
    433 }
    434