From: liuyongqiang <liu.liuyongqi...@huawei.com>

this patch work for the ovs serporting the IEEE 802.1ah
protocol(Mac in Mac or PBB)

IEEE 802.1ah (PBB or MAC-in-MAC):
PBB (also known as MAC-in-MAC) is used by SPs to resolve these problems.
PBB introduces a hierarchical network architecture with associated new
frame formats which extend the work completed by Provider Bridges (IEEE
802.1ad). In PBB architecture, Customer networks (using 802.1q bridging)
are aggregated into Provider Bridged networks (using 802.1ad). These, in
turn, are aggregated into PBB networks which utilize the 802.1ah frame
format. The frame format employs a MAC tunneling encapsulation scheme for
tunneling customer Ethernet frames within provider Ethernet frames across
the PBBN. A VLAN ID is used to segregate the backbone into broadcast
domains and a new 24-bit service identifier (I-SID) is defined and used to
associate a given Customer MAC frame with a provider service instance.
There is a clear segregation between I-SIDs and B-VLANs which was missing
in 802.1ad.
PBB network (PBBN) has following benefits:
1.Imposes no change to Ethernet switching process in the core bridges.
2.Supports Ethernet private line (E-Line), Ethernet Transparent (E-LAN)
and Ethernet Tree (E-Tree) services.
3.Provides a clear demarcation point between the customer and provider
domain.
4.Learns customer MAC addresses only through the backbone edge bridges
(BEB).
5.Supports upto 2^24 service instances.
6.Achieves additional PBBN scaling and interconnection using hierarchical
and peer PBBN features.

this patch defined the basic data structure and basic function of PBB
actions.

Signed-off-by: liuyongqiang <liu.liuyongqi...@huawei.com>
---
 datapath/actions.c                                |   6 ++
 datapath/linux/compat/include/linux/openvswitch.h |  15 +++
 lib/dpif-netdev.c                                 |   2 +
 lib/dpif.c                                        |   2 +
 lib/odp-execute.c                                 |   6 ++
 lib/odp-util.c                                    |  26 ++++++
 lib/ofp-actions.c                                 | 106 ++++++++++++++++++++++
 lib/ofp-actions.h                                 |  14 +++
 lib/packets.h                                     |  71 +++++++++++++++
 ofproto/ofproto-dpif-xlate.c                      |   6 ++
 10 files changed, 254 insertions(+)

diff --git a/datapath/actions.c b/datapath/actions.c
index b527cb6..f693969 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -885,6 +885,12 @@ static int do_execute_actions(struct datapath *dp, struct 
sk_buff *skb,
                        err = pop_mpls(skb, key, nla_get_be16(a));
                        break;
 
+               case OVS_ACTION_ATTR_PUSH_PBB:
+                       break;
+
+               case OVS_ACTION_ATTR_POP_PBB:
+                       break;
+
                case OVS_ACTION_ATTR_PUSH_VLAN:
                        err = push_vlan(skb, key, nla_data(a));
                        if (unlikely(err)) /* skb already freed. */
diff --git a/datapath/linux/compat/include/linux/openvswitch.h 
b/datapath/linux/compat/include/linux/openvswitch.h
index b2257e6..d0c4440 100644
--- a/datapath/linux/compat/include/linux/openvswitch.h
+++ b/datapath/linux/compat/include/linux/openvswitch.h
@@ -545,6 +545,19 @@ struct ovs_action_push_mpls {
 };
 
 /**
+ * struct ovs_action_push_pbb - %OVS_ACTION_ATTR_PUSH_PBB action argument.
+ * @pbb_pri: pbb  i-tag entry to push.
+ * @pbb_ethertype: Ethertype to set in the encapsulating ethernet frame.
+ *
+ * The only values @pbb_ethertype should ever be given are %ETH_P_8021AH,
+ *  Other are rejected.
+ */
+struct ovs_action_push_pbb {
+    __be32 pbb_itag;
+    __be16 pbb_ethertype; /* ETH_P_8021AH*/
+};
+
+/**
  * struct ovs_action_push_vlan - %OVS_ACTION_ATTR_PUSH_VLAN action argument.
  * @vlan_tpid: Tag protocol identifier (TPID) to push.
  * @vlan_tci: Tag control identifier (TCI) to push.  The CFI bit must be set
@@ -629,6 +642,8 @@ enum ovs_action_attr {
        OVS_ACTION_ATTR_HASH,         /* struct ovs_action_hash. */
        OVS_ACTION_ATTR_PUSH_MPLS,    /* struct ovs_action_push_mpls. */
        OVS_ACTION_ATTR_POP_MPLS,     /* __be16 ethertype. */
+       OVS_ACTION_ATTR_PUSH_PBB,     /* struct ovs_action_push_pbb. */
+       OVS_ACTION_ATTR_POP_PBB,     /* __be16 ethertype. */
        OVS_ACTION_ATTR_SET_MASKED,   /* One nested OVS_KEY_ATTR_* including
                                       * data immediately followed by a mask.
                                       * The data must be zero for the unmasked
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index a1db620..841fb2e 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -2911,6 +2911,8 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, 
int cnt,
     case OVS_ACTION_ATTR_POP_VLAN:
     case OVS_ACTION_ATTR_PUSH_MPLS:
     case OVS_ACTION_ATTR_POP_MPLS:
+    case OVS_ACTION_ATTR_PUSH_PBB:
+    case OVS_ACTION_ATTR_POP_PBB:
     case OVS_ACTION_ATTR_SET:
     case OVS_ACTION_ATTR_SET_MASKED:
     case OVS_ACTION_ATTR_SAMPLE:
diff --git a/lib/dpif.c b/lib/dpif.c
index 91e9baf..057641b 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1041,6 +1041,8 @@ dpif_execute_helper_cb(void *aux_, struct dpif_packet 
**packets, int cnt,
     case OVS_ACTION_ATTR_POP_VLAN:
     case OVS_ACTION_ATTR_PUSH_MPLS:
     case OVS_ACTION_ATTR_POP_MPLS:
+    case OVS_ACTION_ATTR_PUSH_PBB:
+    case OVS_ACTION_ATTR_POP_PBB:
     case OVS_ACTION_ATTR_SET:
     case OVS_ACTION_ATTR_SET_MASKED:
     case OVS_ACTION_ATTR_SAMPLE:
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index e2bc6de..691a8da 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -499,6 +499,12 @@ odp_execute_actions(void *dp, struct dpif_packet 
**packets, int cnt,
             }
             break;
 
+        case OVS_ACTION_ATTR_PUSH_PBB:
+            break;
+
+        case OVS_ACTION_ATTR_POP_PBB:
+            break;
+
         case OVS_ACTION_ATTR_SET:
             for (i = 0; i < cnt; i++) {
                 odp_execute_set_action(packets[i], nl_attr_get(a), md);
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 8f5ed08..ac24fbb 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -79,6 +79,8 @@ odp_action_len(uint16_t type)
     case OVS_ACTION_ATTR_POP_VLAN: return 0;
     case OVS_ACTION_ATTR_PUSH_MPLS: return sizeof(struct ovs_action_push_mpls);
     case OVS_ACTION_ATTR_POP_MPLS: return sizeof(ovs_be16);
+    case OVS_ACTION_ATTR_PUSH_PBB: return sizeof(struct ovs_action_push_pbb);
+    case OVS_ACTION_ATTR_POP_PBB: return 0;
     case OVS_ACTION_ATTR_RECIRC: return sizeof(uint32_t);
     case OVS_ACTION_ATTR_HASH: return sizeof(struct ovs_action_hash);
     case OVS_ACTION_ATTR_SET: return -2;
@@ -454,6 +456,18 @@ format_mpls_lse(struct ds *ds, ovs_be32 mpls_lse)
 }
 
 static void
+format_pbb_itag(struct ds *ds, ovs_be32 pbb_itag)
+{
+    ds_put_format(ds, "i-sid=%"PRIu32",res=%d,uca=%d,del=%d,pcp=%d",
+                  pbb_itag_to_isid(pbb_itag),
+                  pbb_itag_to_res(pbb_itag),
+                  pbb_itag_to_uca(pbb_itag),
+                  pbb_itag_to_del(pbb_itag),
+                  pbb_itag_to_pcp(pbb_itag));
+
+}
+
+static void
 format_mpls(struct ds *ds, const struct ovs_key_mpls *mpls_key,
             const struct ovs_key_mpls *mpls_mask, int n)
 {
@@ -586,6 +600,18 @@ format_odp_action(struct ds *ds, const struct nlattr *a)
         ds_put_format(ds, "pop_mpls(eth_type=0x%"PRIx16")", ntohs(ethertype));
         break;
     }
+    case OVS_ACTION_ATTR_PUSH_PBB:{
+        const struct ovs_action_push_pbb *pbb = nl_attr_get(a);
+        ds_put_cstr(ds, "push_pbb(");
+        format_pbb_itag(ds, pbb->pbb_itag);
+        ds_put_format(ds, ",eth_type=0x%"PRIx16")", ntohs(pbb->pbb_ethertype));
+        break;
+    }
+    case OVS_ACTION_ATTR_POP_PBB: {
+        ovs_be16 ethertype = nl_attr_get_be16(a);
+        ds_put_format(ds, "pop_pbb(eth_type=0x%"PRIx16")", ntohs(ethertype));
+        break;
+    }
     case OVS_ACTION_ATTR_SAMPLE:
         format_odp_sample_action(ds, a);
         break;
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 9904fed..ea2f0f1 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -187,6 +187,16 @@ enum ofp_raw_action_type {
      * ETH_TYPE_MPLS otherwise, not the label.] */
     OFPAT_RAW_POP_MPLS,
 
+    /* NX1.0(34), OF1.1+(29): ovs_be16.
+     *
+     * [The argument is the Ethertype, e.g. ETH_TYPE_PBB_8021AH, not the 
label.] */
+    OFPAT_RAW_PUSH_PBB,
+
+    /* NX1.0(35), OF1.1+(30): ovs_be16.
+     *
+     * [The argument is the Ethertype, e.g. ETH_TYPE_PBB_8021AH, not the 
label.] */
+    OFPAT_RAW_POP_PBB,
+
     /* NX1.0(4), OF1.1+(21): uint32_t. */
     OFPAT_RAW_SET_QUEUE,
 
@@ -3030,6 +3040,84 @@ format_POP_MPLS(const struct ofpact_pop_mpls *a, struct 
ds *s)
     ds_put_format(s, "pop_mpls:0x%04"PRIx16, ntohs(a->ethertype));
 }
 
+/* Push PBB action. */
+static enum ofperr
+decode_OFPAT_RAW_PUSH_PBB(ovs_be16 ethertype, struct ofpbuf *out)
+{
+    struct ofpact_push_pbb *oam;
+
+    if (!eth_type_pbb(ethertype)) {
+        return OFPERR_OFPBAC_BAD_ARGUMENT;
+    }
+    oam = ofpact_put_PUSH_PBB(out);
+    oam->ethertype = ethertype;
+
+    return 0;
+}
+
+static void
+encode_PUSH_PBB(const struct ofpact_push_pbb *push_pbb,
+                 enum ofp_version ofp_version, struct ofpbuf *out)
+{
+    put_OFPAT_PUSH_PBB(out, ofp_version, push_pbb->ethertype);
+}
+
+static char * WARN_UNUSED_RESULT
+parse_PUSH_PBB(char *arg, struct ofpbuf *ofpacts,
+                enum ofputil_protocol *usable_protocols OVS_UNUSED)
+{
+    uint16_t ethertype;
+    char *error;
+
+    error = str_to_u16(arg, "push_pbb", &ethertype);
+    if (!error) {
+        ofpact_put_PUSH_PBB(ofpacts)->ethertype = htons(ethertype);
+    }
+    return error;
+}
+
+static void
+format_PUSH_PBB(const struct ofpact_push_pbb *a, struct ds *s)
+{
+    ds_put_format(s, "push_pbb:0x%04"PRIx16, ntohs(a->ethertype));
+}
+
+/* Pop PBB action. */
+
+static enum ofperr
+decode_OFPAT_RAW_POP_PBB(ovs_be16 ethertype, struct ofpbuf *out)
+{
+    ofpact_put_POP_PBB(out)->ethertype = ethertype;
+    return 0;
+}
+
+static void
+encode_POP_PBB(const struct ofpact_pop_pbb *pop_pbb,
+                enum ofp_version ofp_version, struct ofpbuf *out)
+{
+    put_OFPAT_POP_PBB(out, ofp_version, pop_pbb->ethertype);
+}
+
+static char * WARN_UNUSED_RESULT
+parse_POP_PBB(char *arg, struct ofpbuf *ofpacts,
+                    enum ofputil_protocol *usable_protocols OVS_UNUSED)
+{
+    uint16_t ethertype;
+    char *error;
+
+    error = str_to_u16(arg, "pop_pbb", &ethertype);
+    if (!error) {
+        ofpact_put_POP_PBB(ofpacts)->ethertype = htons(ethertype);
+    }
+    return error;
+}
+
+static void
+format_POP_PBB(const struct ofpact_pop_pbb *a, struct ds *s)
+{
+    ds_put_format(s, "pop_pbb:0x%04"PRIx16, ntohs(a->ethertype));
+}
+
 /* Set tunnel ID actions. */
 
 static enum ofperr
@@ -4599,6 +4687,8 @@ ofpact_is_set_or_move_action(const struct ofpact *a)
     case OFPACT_POP_MPLS:
     case OFPACT_POP_QUEUE:
     case OFPACT_PUSH_MPLS:
+    case OFPACT_PUSH_PBB:
+    case OFPACT_POP_PBB:
     case OFPACT_PUSH_VLAN:
     case OFPACT_RESUBMIT:
     case OFPACT_SAMPLE:
@@ -4625,6 +4715,8 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a)
     case OFPACT_OUTPUT:
     case OFPACT_POP_MPLS:
     case OFPACT_PUSH_MPLS:
+    case OFPACT_PUSH_PBB:
+    case OFPACT_POP_PBB:
     case OFPACT_PUSH_VLAN:
     case OFPACT_REG_MOVE:
     case OFPACT_SET_FIELD:
@@ -4866,6 +4958,8 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type 
type)
     case OFPACT_DEC_MPLS_TTL:
     case OFPACT_PUSH_MPLS:
     case OFPACT_POP_MPLS:
+    case OFPACT_PUSH_PBB:
+    case OFPACT_POP_PBB:
     case OFPACT_SET_TUNNEL:
     case OFPACT_SET_QUEUE:
     case OFPACT_POP_QUEUE:
@@ -5431,6 +5525,12 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, 
struct ofpact *a,
         flow->dl_type = ofpact_get_POP_MPLS(a)->ethertype;
         return 0;
 
+    case OFPACT_PUSH_PBB:
+        return 0;
+
+    case OFPACT_POP_PBB:
+        return 0;
+
     case OFPACT_SAMPLE:
         return 0;
 
@@ -5707,6 +5807,8 @@ get_ofpact_map(enum ofp_version version)
         { OFPACT_GROUP, 22 },
         { OFPACT_SET_IP_TTL, 23 },
         { OFPACT_DEC_TTL, 24 },
+        { OFPACT_PUSH_PBB, 26 },
+        { OFPACT_POP_PBB, 27 },
         { 0, -1 },
     };
 
@@ -5726,6 +5828,8 @@ get_ofpact_map(enum ofp_version version)
         { OFPACT_SET_IP_TTL, 23 },
         { OFPACT_DEC_TTL, 24 },
         { OFPACT_SET_FIELD, 25 },
+        { OFPACT_PUSH_PBB, 26 },
+        { OFPACT_POP_PBB, 27 },
         /* OF1.3+ OFPAT_PUSH_PBB (26) not supported. */
         /* OF1.3+ OFPAT_POP_PBB (27) not supported. */
         { 0, -1 },
@@ -5846,6 +5950,8 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, 
ofp_port_t port)
     case OFPACT_EXIT:
     case OFPACT_PUSH_MPLS:
     case OFPACT_POP_MPLS:
+    case OFPACT_PUSH_PBB:
+    case OFPACT_POP_PBB:
     case OFPACT_SAMPLE:
     case OFPACT_CLEAR_ACTIONS:
     case OFPACT_WRITE_ACTIONS:
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index e863cdc..c4b5a64 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -86,6 +86,8 @@
     OFPACT(DEC_MPLS_TTL,    ofpact_null,        ofpact, "dec_mpls_ttl") \
     OFPACT(PUSH_MPLS,       ofpact_push_mpls,   ofpact, "push_mpls")    \
     OFPACT(POP_MPLS,        ofpact_pop_mpls,    ofpact, "pop_mpls")     \
+    OFPACT(PUSH_PBB,       ofpact_push_pbb,   ofpact, "push_pbb")       \
+    OFPACT(POP_PBB,        ofpact_pop_pbb,    ofpact, "pop_pbb")        \
                                                                         \
     /* Metadata. */                                                     \
     OFPACT(SET_TUNNEL,      ofpact_tunnel,      ofpact, "set_tunnel")   \
@@ -409,6 +411,18 @@ struct ofpact_pop_mpls {
     ovs_be16 ethertype;
 };
 
+/* Used for NXAST_PUSH_PBB, OFPAT11_PUSH_PBB. */
+struct ofpact_push_pbb {
+   struct ofpact ofpact;
+   ovs_be16 ethertype;
+};
+
+/* Used for NXAST_POP_PBB, OFPAT11_POP_PBB. */
+struct ofpact_pop_pbb {
+   struct ofpact ofpact;
+   ovs_be16 ethertype;
+};
+
 /* OFPACT_SET_TUNNEL.
  *
  * Used for NXAST_SET_TUNNEL, NXAST_SET_TUNNEL64. */
diff --git a/lib/packets.h b/lib/packets.h
index 26c6ff1..9a0b141 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -244,6 +244,7 @@ ovs_be32 set_mpls_lse_values(uint8_t ttl, uint8_t tc, 
uint8_t bos,
 #define ETH_TYPE_RARP          0x8035
 #define ETH_TYPE_MPLS          0x8847
 #define ETH_TYPE_MPLS_MCAST    0x8848
+#define ETH_TYPE_PBB_8021AH    0x88E7
 
 static inline bool eth_type_mpls(ovs_be16 eth_type)
 {
@@ -251,6 +252,11 @@ static inline bool eth_type_mpls(ovs_be16 eth_type)
         eth_type == htons(ETH_TYPE_MPLS_MCAST);
 }
 
+static inline bool eth_type_pbb(ovs_be16 eth_type)
+{
+    return eth_type == htons(ETH_TYPE_PBB_8021AH);
+}
+
 /* Minimum value for an Ethernet type.  Values below this are IEEE 802.2 frame
  * lengths. */
 #define ETH_TYPE_MIN           0x600
@@ -416,6 +422,71 @@ mpls_lse_to_bos(ovs_be32 mpls_lse)
     return (mpls_lse & htonl(MPLS_BOS_MASK)) != 0;
 }
 
+/* PBB related definitions */
+#define PBB_ISID_MASK       0x00ffffff
+#define PBB_ISID_SHIFT      0
+
+#define PBB_RES_MASK       0x7000000
+#define PBB_RES_SHIFT      24
+
+#define PBB_UCA_MASK        0x8000000
+#define PBB_UCA_SHIFT        27
+
+#define PBB_DEL_MASK     0x10000000
+#define PBB_DEL_SHIFT     28
+
+#define PBB_PCP_MASK     0xe0000000
+#define PBB_PCP_SHIFT    29
+
+#define PBB_HLEN           4
+
+struct pbb_hdr {
+    ovs_16aligned_be32 pbb_itag;
+};
+BUILD_ASSERT_DECL(PBB_HLEN == sizeof(struct pbb_hdr));
+
+
+/* Given a pbb itag stack entry in network byte order
+ * return pbb i-sid in host byte order */
+static inline uint32_t
+pbb_itag_to_isid(ovs_be32 pbb_itag)
+{
+    return (ntohl(pbb_itag) & PBB_ISID_MASK) >> PBB_ISID_SHIFT;
+}
+
+/* Given a pbb itag stack entry in network byte order
+ * return pbb res */
+static inline uint8_t
+pbb_itag_to_res(ovs_be32 pbb_itag)
+{
+    return (ntohl(pbb_itag) & PBB_RES_MASK) >> PBB_RES_SHIFT;
+}
+
+/* Given a pbb itag stack entry in network byte order
+ * return pbb uca */
+static inline uint8_t
+pbb_itag_to_uca(ovs_be32 pbb_itag)
+{
+    return (pbb_itag & htonl(PBB_UCA_MASK)) != 0;
+}
+
+/* Given a pbb itag stack entry in network byte order
+ * return pbb del  */
+static inline uint8_t
+pbb_itag_to_del(ovs_be32 pbb_itag)
+{
+    return (pbb_itag & htonl(MPLS_BOS_MASK)) != 0;
+}
+
+/* Given a pbb itag stack entry in network byte order
+ * return pbb pcp */
+static inline uint8_t
+pbb_itag_to_pcp(ovs_be32 pbb_itag)
+{
+    return (ntohl(pbb_itag) & PBB_PCP_MASK) >> PBB_PCP_SHIFT;
+}
+
+
 #define IP_FMT "%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32
 #define IP_ARGS(ip)                             \
     ntohl(ip) >> 24,                            \
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index a881dfb..409d1b1 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -3834,6 +3834,12 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t 
ofpacts_len,
             compose_mpls_pop_action(ctx, ofpact_get_POP_MPLS(a)->ethertype);
             break;
 
+        case OFPACT_PUSH_PBB:
+            break;
+
+        case OFPACT_POP_PBB:
+            break;
+
         case OFPACT_SET_MPLS_LABEL:
             compose_set_mpls_label_action(
                 ctx, ofpact_get_SET_MPLS_LABEL(a)->label);
-- 
1.9.4.msysgit.1


_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to