From: Nemanja Marjanovic Date: Mon, 21 Jan 2019 11:11:21 +0000 (+0000) Subject: pipeline: support QinQ PPPoE encapsulation X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=8692f6591e52658ffe66df86da70f56fab4b76e6;p=dpdk.git pipeline: support QinQ PPPoE encapsulation Add support of QinQ PPPoE packet encapsulation action. Signed-off-by: Nemanja Marjanovic Acked-by: Cristian Dumitrescu --- diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c index 8a2bb13dc7..ba8fd3f5bf 100644 --- a/lib/librte_pipeline/rte_table_action.c +++ b/lib/librte_pipeline/rte_table_action.c @@ -420,6 +420,7 @@ encap_valid(enum rte_table_action_encap_type encap) case RTE_TABLE_ACTION_ENCAP_MPLS: case RTE_TABLE_ACTION_ENCAP_PPPOE: case RTE_TABLE_ACTION_ENCAP_VXLAN: + case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE: return 1; default: return 0; @@ -520,6 +521,13 @@ struct encap_vxlan_ipv6_vlan_data { struct vxlan_hdr vxlan; } __attribute__((__packed__)); +struct encap_qinq_pppoe_data { + struct ether_hdr ether; + struct vlan_hdr svlan; + struct vlan_hdr cvlan; + struct pppoe_ppp_hdr pppoe_ppp; +} __attribute__((__packed__)); + static size_t encap_data_size(struct rte_table_action_encap_config *encap) { @@ -551,6 +559,9 @@ encap_data_size(struct rte_table_action_encap_config *encap) else return sizeof(struct encap_vxlan_ipv6_data); + case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE: + return sizeof(struct encap_qinq_pppoe_data); + default: return 0; } @@ -587,6 +598,9 @@ encap_apply_check(struct rte_table_action_encap_params *p, case RTE_TABLE_ACTION_ENCAP_VXLAN: return 0; + case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE: + return 0; + default: return -EINVAL; } @@ -664,6 +678,38 @@ encap_qinq_apply(void *data, return 0; } +static int +encap_qinq_pppoe_apply(void *data, + struct rte_table_action_encap_params *p) +{ + struct encap_qinq_pppoe_data *d = data; + + /* Ethernet */ + ether_addr_copy(&p->qinq.ether.da, &d->ether.d_addr); + ether_addr_copy(&p->qinq.ether.sa, &d->ether.s_addr); + d->ether.ether_type = rte_htons(ETHER_TYPE_VLAN); + + /* SVLAN */ + d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp, + p->qinq.svlan.dei, + p->qinq.svlan.vid)); + d->svlan.eth_proto = rte_htons(ETHER_TYPE_VLAN); + + /* CVLAN */ + d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp, + p->qinq.cvlan.dei, + p->qinq.cvlan.vid)); + d->cvlan.eth_proto = rte_htons(ETHER_TYPE_PPPOE_SESSION); + + /* PPPoE and PPP*/ + d->pppoe_ppp.ver_type_code = rte_htons(0x1100); + d->pppoe_ppp.session_id = rte_htons(p->qinq_pppoe.pppoe.session_id); + d->pppoe_ppp.length = 0; /* not pre-computed */ + d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP); + + return 0; +} + static int encap_mpls_apply(void *data, struct rte_table_action_encap_params *p) @@ -909,6 +955,9 @@ encap_apply(void *data, case RTE_TABLE_ACTION_ENCAP_VXLAN: return encap_vxlan_apply(data, p, cfg); + case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE: + return encap_qinq_pppoe_apply(data, p); + default: return -EINVAL; } @@ -1107,6 +1156,18 @@ pkt_work_encap(struct rte_mbuf *mbuf, break; } + case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE: + { + struct encap_qinq_pppoe_data *qinq_pppoe = + encap(ip, data, sizeof(struct encap_qinq_pppoe_data)); + qinq_pppoe->pppoe_ppp.length = rte_htons(total_length + 2); + mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) + + sizeof(struct encap_qinq_pppoe_data)); + mbuf->pkt_len = mbuf->data_len = total_length + + sizeof(struct encap_qinq_pppoe_data); + break; + } + case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN: { if (cfg->vxlan.ip_version) diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h index c96061291f..53d16af8a9 100644 --- a/lib/librte_pipeline/rte_table_action.h +++ b/lib/librte_pipeline/rte_table_action.h @@ -380,6 +380,9 @@ enum rte_table_action_encap_type { * Ether -> { Ether | VLAN | IP | UDP | VXLAN | Ether } */ RTE_TABLE_ACTION_ENCAP_VXLAN, + + /** IP -> { Ether | S-VLAN | C-VLAN | PPPoE | PPP | IP } */ + RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE, }; /** Pre-computed Ethernet header fields for encapsulation action. */ @@ -529,6 +532,16 @@ struct rte_table_action_encap_config { }; }; +/** QinQ_PPPoE encap paramaeters. */ +struct rte_table_encap_ether_qinq_pppoe { + + /** Only valid when *type* is set to QinQ. */ + struct rte_table_action_ether_hdr ether; + struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */ + struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */ + struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */ +}; + /** Encap action parameters (per table rule). */ struct rte_table_action_encap_params { /** Encapsulation type. */ @@ -553,6 +566,9 @@ struct rte_table_action_encap_params { /** Only valid when *type* is set to VXLAN. */ struct rte_table_action_encap_vxlan_params vxlan; + + /** Only valid when *type* is set to QinQ_PPPoE. */ + struct rte_table_encap_ether_qinq_pppoe qinq_pppoe; }; };