+/* MPLS related definitions */
+#define MPLS_TTL_MASK 0x000000ff
+#define MPLS_TTL_SHIFT 0
+
+#define MPLS_BOS_MASK 0x00000100
+#define MPLS_BOS_SHIFT 8
+
+#define MPLS_TC_MASK 0x00000e00
+#define MPLS_TC_SHIFT 9
+
+#define MPLS_LABEL_MASK 0xfffff000
+#define MPLS_LABEL_SHIFT 12
+
+#define MPLS_HLEN 4
+
+struct mpls_hdr {
+ ovs_16aligned_be32 mpls_lse;
+};
+BUILD_ASSERT_DECL(MPLS_HLEN == sizeof(struct mpls_hdr));
+
+/* Given a mpls label stack entry in network byte order
+ * return mpls label in host byte order */
+static inline uint32_t
+mpls_lse_to_label(ovs_be32 mpls_lse)
+{
+ return (ntohl(mpls_lse) & MPLS_LABEL_MASK) >> MPLS_LABEL_SHIFT;
+}
+
+/* Given a mpls label stack entry in network byte order
+ * return mpls tc */
+static inline uint8_t
+mpls_lse_to_tc(ovs_be32 mpls_lse)
+{
+ return (ntohl(mpls_lse) & MPLS_TC_MASK) >> MPLS_TC_SHIFT;
+}
+
+/* Given a mpls label stack entry in network byte order
+ * return mpls ttl */
+static inline uint8_t
+mpls_lse_to_ttl(ovs_be32 mpls_lse)
+{
+ return (ntohl(mpls_lse) & MPLS_TTL_MASK) >> MPLS_TTL_SHIFT;
+}
+
+/* Set TTL in mpls lse. */
+static inline void
+flow_set_mpls_lse_ttl(ovs_be32 *mpls_lse, uint8_t ttl)
+{
+ *mpls_lse &= ~htonl(MPLS_TTL_MASK);
+ *mpls_lse |= htonl(ttl << MPLS_TTL_SHIFT);
+}
+
+/* Given a mpls label stack entry in network byte order
+ * return mpls BoS bit */
+static inline uint8_t
+mpls_lse_to_bos(ovs_be32 mpls_lse)
+{
+ return (mpls_lse & htonl(MPLS_BOS_MASK)) != 0;
+}
+