pipeline: support QinQ PPPoE encapsulation

Add support of QinQ PPPoE packet encapsulation action.

Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This commit is contained in:
Nemanja Marjanovic 2019-01-21 11:11:21 +00:00 committed by Cristian Dumitrescu
parent ebe3a76991
commit 8692f6591e
2 changed files with 77 additions and 0 deletions

View File

@ -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)

View File

@ -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;
};
};