@@ -237,9 +237,51 @@ dp_packet_resize__(struct dp_packet *b, size_t new_headroom, size_t new_tailroom
new_allocated = new_headroom + dp_packet_size(b) + new_tailroom;
switch (b->source) {
+ /* When resizing mbufs, both a single mbuf and multi-segment mbufs (where
+ * data is not contigously held in memory), both the headroom and the
+ * tailroom available will be used to make more space for where data needs
+ * to be inserted. I.e if there's not enough headroom, data may be shifted
+ * right if there's enough tailroom.
+ * However, this is not bulletproof and in some cases the space available
+ * won't be enough - in those cases, an error should be returned and the
+ * packet dropped. */
case DPBUF_DPDK:
- OVS_NOT_REACHED();
+ {
+ size_t miss_len;
+
+ if (new_headroom == dp_packet_headroom(b)) {
+ /* This is a tailroom adjustment. Since there's no tailroom space
+ * left, try and shift data towards the head to free up tail space,
+ * if there's enough headroom */
+
+ miss_len = new_tailroom - dp_packet_tailroom(b);
+
+ if (miss_len <= new_headroom) {
+ dp_packet_shift(b, -miss_len);
+ } else {
+ /* XXX: Handle error case and report error to caller */
+ OVS_NOT_REACHED();
+ }
+ } else {
+ /* Otherwise, this is a headroom adjustment. Try to shift data
+ * towards the tail to free up head space, if there's enough
+ * tailroom */
+
+ miss_len = new_headroom - dp_packet_headroom(b);
+
+ if (miss_len <= new_tailroom) {
+ dp_packet_shift(b, miss_len);
+ } else {
+ /* XXX: Handle error case and report error to caller */
+ OVS_NOT_REACHED();
+ }
+ }
+
+ new_base = dp_packet_base(b);
+
+ break;
+ }
case DPBUF_MALLOC:
if (new_headroom == dp_packet_headroom(b)) {
new_base = xrealloc(dp_packet_base(b), new_allocated);
@@ -263,7 +305,9 @@ dp_packet_resize__(struct dp_packet *b, size_t new_headroom, size_t new_tailroom
OVS_NOT_REACHED();
}
- dp_packet_set_allocated(b, new_allocated);
+ if (b->source != DPBUF_DPDK) {
+ dp_packet_set_allocated(b, new_allocated);
+ }
dp_packet_set_base(b, new_base);
new_data = (char *) new_base + new_headroom;