cfm: Support high priority CCM broadcasts.
[openvswitch] / lib / cfm.c
index d62d4e209c55eafff45a6bd8baf496fa6739d3ba..537eeaa11ed1c066f09eb3ef1e294cb7d07d1fd3 100644 (file)
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -97,6 +97,7 @@ struct cfm {
     uint8_t ccm_interval;  /* The CCM transmission interval. */
     int ccm_interval_ms;   /* 'ccm_interval' in milliseconds. */
     uint16_t ccm_vlan;     /* Vlan tag of CCM PDUs. */
+    uint8_t ccm_pcp;       /* Priority of CCM PDUs. */
     uint8_t maid[CCM_MAID_LEN]; /* The MAID of this CFM. */
 
     struct timer tx_timer;    /* Send CCM when expired. */
@@ -361,8 +362,9 @@ cfm_compose_ccm(struct cfm *cfm, struct ofpbuf *packet,
     timer_set_duration(&cfm->tx_timer, cfm->ccm_interval_ms);
     eth_compose(packet, cfm_ccm_addr(cfm), eth_src, ETH_TYPE_CFM, sizeof *ccm);
 
-    if (cfm->ccm_vlan) {
-        eth_push_vlan(packet, htons(cfm->ccm_vlan));
+    if (cfm->ccm_vlan || cfm->ccm_pcp) {
+        uint16_t tci = cfm->ccm_vlan | (cfm->ccm_pcp << VLAN_PCP_SHIFT);
+        eth_push_vlan(packet, htons(tci));
     }
 
     ccm = packet->l3;
@@ -420,6 +422,7 @@ cfm_configure(struct cfm *cfm, const struct cfm_settings *s)
     interval_ms = ccm_interval_to_ms(interval);
 
     cfm->ccm_vlan = s->ccm_vlan & VLAN_VID_MASK;
+    cfm->ccm_pcp = s->ccm_pcp & (VLAN_PCP_MASK >> VLAN_PCP_SHIFT);
     if (cfm->extended && interval_ms != s->interval) {
         interval = 0;
         interval_ms = MIN(s->interval, UINT16_MAX);