* output port is actually a tunnel port. Contains the output tunnel key
  * extracted from the packet as nested %OVS_TUNNEL_KEY_ATTR_* attributes.
  * @OVS_PACKET_ATTR_MRU: Present for an %OVS_PACKET_CMD_ACTION and
+ * @OVS_PACKET_ATTR_LEN: Packet size before truncation.
  * %OVS_PACKET_ATTR_USERSPACE action specify the Maximum received fragment
  * size.
  *
        OVS_PACKET_ATTR_PROBE,      /* Packet operation is a feature probe,
                                       error logging should be suppressed. */
        OVS_PACKET_ATTR_MRU,        /* Maximum received IP fragment size. */
+       OVS_PACKET_ATTR_LEN,            /* Packet size before truncation. */
        __OVS_PACKET_ATTR_MAX
 };
 
 
 {
        size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
                + nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */
-               + nla_total_size(ovs_key_attr_size()); /* OVS_PACKET_ATTR_KEY */
+               + nla_total_size(ovs_key_attr_size()) /* OVS_PACKET_ATTR_KEY */
+               + nla_total_size(sizeof(unsigned int)); /* OVS_PACKET_ATTR_LEN */
 
        /* OVS_PACKET_ATTR_USERDATA */
        if (upcall_info->userdata)
                pad_packet(dp, user_skb);
        }
 
+       /* Add OVS_PACKET_ATTR_LEN when packet is truncated */
+       if (cutlen > 0) {
+               if (nla_put_u32(user_skb, OVS_PACKET_ATTR_LEN,
+                               skb->len)) {
+                       err = -ENOBUFS;
+                       goto out;
+               }
+               pad_packet(dp, user_skb);
+       }
+
        /* Only reserve room for attribute header, packet data is added
         * in skb_zerocopy() */
        if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) {