diff options
author | Martin Varghese <martin.varghese@nokia.com> | 2021-11-29 11:52:05 +0530 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2022-01-17 02:04:20 +0100 |
commit | 1917ace89364d366777b34467e952358d2d85b41 (patch) | |
tree | 109d821fbb510ed2df3cf8358d496af8d2830364 /lib/packets.c | |
parent | 4a6a4734622e42367faf39cd3938bc8a57786282 (diff) | |
download | openvswitch-1917ace89364d366777b34467e952358d2d85b41.tar.gz |
Encap & Decap actions for MPLS packet type.
The encap & decap actions are extended to support MPLS packet type.
Encap & decap actions adds and removes MPLS header at start of the
packet.
The existing PUSH MPLS & POP MPLS actions inserts & removes MPLS
header between ethernet header and the IP header. Though this behaviour
is fine for L3 VPN where an IP packet is encapsulated inside a MPLS
tunnel, it does not suffice the L2 VPN requirements. In L2 VPN the
ethernet packets must be encapsulated inside MPLS tunnel.
In this change the encap & decap actions are extended to support MPLS
packet type. The encap & decap adds and removes MPLS header at the
start of packet as depicted below.
Encapsulation:
Actions - encap(mpls),encap(ethernet)
Incoming packet -> | ETH | IP | Payload |
1 Actions - encap(mpls) [Datapath action - ADD_MPLS:0x8847]
Outgoing packet -> | MPLS | ETH | Payload|
2 Actions - encap(ethernet) [ Datapath action - push_eth ]
Outgoing packet -> | ETH | MPLS | ETH | Payload|
Decapsulation:
Incoming packet -> | ETH | MPLS | ETH | IP | Payload |
Actions - decap(),decap(packet_type(ns=0,type=0))
1 Actions - decap() [Datapath action - pop_eth)
Outgoing packet -> | MPLS | ETH | IP | Payload|
2 Actions - decap(packet_type(ns=0,type=0)) [Datapath action - POP_MPLS:0x6558]
Outgoing packet -> | ETH | IP | Payload|
Signed-off-by: Martin Varghese <martin.varghese@nokia.com>
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'lib/packets.c')
-rw-r--r-- | lib/packets.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/packets.c b/lib/packets.c index 4a7643c5d..d0fba8176 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -418,6 +418,40 @@ push_mpls(struct dp_packet *packet, ovs_be16 ethtype, ovs_be32 lse) pkt_metadata_init_conn(&packet->md); } +void +add_mpls(struct dp_packet *packet, ovs_be16 ethtype, ovs_be32 lse, + bool l3_encap) +{ + if (!eth_type_mpls(ethtype)) { + return; + } + + if (!l3_encap) { + ovs_be32 *header = dp_packet_push_uninit(packet, MPLS_HLEN); + + *header = lse; + packet->l2_5_ofs = 0; + packet->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE, + ntohs(ethtype)); + } else { + size_t len; + char *header; + + if (!is_mpls(packet)) { + /* Set MPLS label stack offset. */ + packet->l2_5_ofs = packet->l3_ofs; + } + set_ethertype(packet, ethtype); + + /* Push new MPLS shim header onto packet. */ + len = packet->l2_5_ofs; + header = dp_packet_resize_l2_5(packet, MPLS_HLEN); + memmove(header, header + MPLS_HLEN, len); + memcpy(header + len, &lse, sizeof lse); + } + pkt_metadata_init_conn(&packet->md); +} + /* If 'packet' is an MPLS packet, removes its outermost MPLS label stack entry. * If the label that was removed was the only MPLS label, changes 'packet''s * Ethertype to 'ethtype' (which ordinarily should not be an MPLS @@ -440,6 +474,18 @@ pop_mpls(struct dp_packet *packet, ovs_be16 ethtype) /* Invalidate offload flags as they are not valid after * decapsulation of MPLS header. */ dp_packet_reset_offload(packet); + + /* packet_type must be reset for the MPLS packets with no l2 header */ + if (!len) { + if (ethtype == htons(ETH_TYPE_TEB)) { + /* The inner packet must be classified as ethernet if the + * ethtype is ETH_TYPE_TEB. */ + packet->packet_type = htonl(PT_ETH); + } else { + packet->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE, + ntohs(ethtype)); + } + } } } |