return sizeof(struct p_header80);
 }
 
-static void prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size)
+static unsigned int prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size)
 {
        h->magic   = cpu_to_be32(DRBD_MAGIC);
        h->command = cpu_to_be16(cmd);
        h->length  = cpu_to_be16(size);
+       return sizeof(struct p_header80);
 }
 
-static void prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size)
+static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size)
 {
        h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
        h->command = cpu_to_be16(cmd);
        h->length  = cpu_to_be32(size);
+       return sizeof(struct p_header95);
 }
 
-static void prepare_header(struct drbd_tconn *tconn, int vnr, struct p_header *h,
-                          enum drbd_packet cmd, int size)
+static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr, void *buffer,
+                                  enum drbd_packet cmd, int size)
 {
        if (tconn->agreed_pro_version >= 95)
-               prepare_header95(&h->h95, cmd, size);
+               return prepare_header95(buffer, cmd, size);
        else
-               prepare_header80(&h->h80, cmd, size);
+               return prepare_header80(buffer, cmd, size);
 }
 
 void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock)
                mutex_unlock(&sock->mutex);
                return NULL;
        }
-       return sock->sbuf;
+       return sock->sbuf + drbd_header_size(tconn);
 }
 
 void *drbd_prepare_command(struct drbd_conf *mdev, struct drbd_socket *sock)
         */
        msg_flags = data ? MSG_MORE : 0;
 
-       prepare_header(tconn, vnr, sock->sbuf, cmd,
-                      header_size - sizeof(struct p_header) + size);
+       header_size += prepare_header(tconn, vnr, sock->sbuf, cmd,
+                                     header_size + size);
        err = drbd_send_all(tconn, sock->socket, sock->sbuf, header_size,
                            msg_flags);
        if (data && !err)
        sock = &tconn->meta;
        if (!conn_prepare_command(tconn, sock))
                return -EIO;
-       return conn_send_command(tconn, sock, P_PING, sizeof(struct p_header), NULL, 0);
+       return conn_send_command(tconn, sock, P_PING, 0, NULL, 0);
 }
 
 int drbd_send_ping_ack(struct drbd_tconn *tconn)
        sock = &tconn->meta;
        if (!conn_prepare_command(tconn, sock))
                return -EIO;
-       return conn_send_command(tconn, sock, P_PING_ACK, sizeof(struct p_header), NULL, 0);
+       return conn_send_command(tconn, sock, P_PING_ACK, 0, NULL, 0);
 }
 
 int drbd_send_sync_param(struct drbd_conf *mdev)
 {
        struct drbd_socket *sock = &mdev->tconn->data;
        unsigned int header_size = drbd_header_size(mdev->tconn);
-       struct p_compressed_bm *p = sock->sbuf;
+       struct p_compressed_bm *p = sock->sbuf + header_size;
        int len, err;
 
-       len = fill_bitmap_rle_bits(mdev, p, DRBD_SOCKET_BUFFER_SIZE - sizeof(*p) /* FIXME */, c);
+       len = fill_bitmap_rle_bits(mdev, p,
+                       DRBD_SOCKET_BUFFER_SIZE - header_size - sizeof(*p), c);
        if (len < 0)
                return -EIO;
 
                                     P_COMPRESSED_BITMAP, sizeof(*p) + len,
                                     NULL, 0);
                c->packets[0]++;
-               c->bytes[0] += sizeof(*p) + len;
+               c->bytes[0] += header_size + sizeof(*p) + len;
 
                if (c->bit_offset >= c->bm_bits)
                        len = 0; /* DONE */
                 * send a buffer full of plain text bits instead. */
                unsigned int data_size;
                unsigned long num_words;
-               struct p_header *h = sock->sbuf;
+               unsigned long *p = sock->sbuf + header_size;
 
                data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
-               num_words = min_t(size_t, data_size / sizeof(unsigned long),
+               num_words = min_t(size_t, data_size / sizeof(*p),
                                  c->bm_words - c->word_offset);
-               len = num_words * sizeof(unsigned long);
+               len = num_words * sizeof(*p);
                if (len)
-                       drbd_bm_get_lel(mdev, c->word_offset, num_words,
-                                       (unsigned long *)h->payload);
-               err = __send_command(mdev->tconn, mdev->vnr, sock, P_BITMAP,
-                                    sizeof(*h) + len, NULL, 0);
+                       drbd_bm_get_lel(mdev, c->word_offset, num_words, p);
+               err = __send_command(mdev->tconn, mdev->vnr, sock, P_BITMAP, len, NULL, 0);
                c->word_offset += num_words;
                c->bit_offset = c->word_offset * BITS_PER_LONG;
 
 {
        int err;
 
-       BUILD_BUG_ON(sizeof(struct p_connection_features) != 80);
-
        if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
                printk(KERN_ERR
                       "drbd: invalid minor_count (%d)\n", minor_count);
 
        enum drbd_packet cmd;
        unsigned int size;
        unsigned int vnr;
+       void *data;
 };
 
 enum finish_epoch {
        return s_estab;
 }
 
-static int decode_header(struct drbd_tconn *, struct p_header *, struct packet_info *);
+static int decode_header(struct drbd_tconn *, void *, struct packet_info *);
 
 static int send_first_packet(struct drbd_tconn *tconn, struct drbd_socket *sock,
                             enum drbd_packet cmd)
 {
        if (!conn_prepare_command(tconn, sock))
                return -EIO;
-       return conn_send_command(tconn, sock, cmd, sizeof(struct p_header), NULL, 0);
+       return conn_send_command(tconn, sock, cmd, 0, NULL, 0);
 }
 
 static int receive_first_packet(struct drbd_tconn *tconn, struct socket *sock)
        return -1;
 }
 
-static int decode_header(struct drbd_tconn *tconn, struct p_header *h, struct packet_info *pi)
+static int decode_header(struct drbd_tconn *tconn, void *header, struct packet_info *pi)
 {
-       if (h->h80.magic == cpu_to_be32(DRBD_MAGIC)) {
-               pi->cmd = be16_to_cpu(h->h80.command);
-               pi->size = be16_to_cpu(h->h80.length);
-               pi->vnr = 0;
-       } else if (h->h95.magic == cpu_to_be16(DRBD_MAGIC_BIG)) {
-               pi->cmd = be16_to_cpu(h->h95.command);
-               pi->size = be32_to_cpu(h->h95.length) & 0x00ffffff;
+       unsigned int header_size = drbd_header_size(tconn);
+
+       if (header_size == sizeof(struct p_header95) &&
+           *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) {
+               struct p_header95 *h = header;
+
+               pi->cmd = be16_to_cpu(h->command);
+               pi->size = be32_to_cpu(h->length) & 0x00ffffff;
+               pi->vnr  = 0;
+       } else if (header_size == sizeof(struct p_header80) &&
+                  *(__be32 *)header == cpu_to_be32(DRBD_MAGIC)) {
+               struct p_header80 *h = header;
+               pi->cmd = be16_to_cpu(h->command);
+               pi->size = be16_to_cpu(h->length);
                pi->vnr = 0;
        } else {
-               conn_err(tconn, "magic?? on data m: 0x%08x c: %d l: %d\n",
-                   be32_to_cpu(h->h80.magic),
-                   be16_to_cpu(h->h80.command),
-                   be16_to_cpu(h->h80.length));
+               conn_err(tconn, "Wrong magic value 0x%08x in protocol version %d\n",
+                        be32_to_cpu(*(__be32 *)header),
+                        tconn->agreed_pro_version);
                return -EINVAL;
        }
+       pi->data = header + header_size;
        return 0;
 }
 
 static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-       struct p_header *h = tconn->data.rbuf;
+       void *buffer = tconn->data.rbuf;
        int err;
 
-       err = drbd_recv_all_warn(tconn, h, drbd_header_size(tconn));
+       err = drbd_recv_all_warn(tconn, buffer, drbd_header_size(tconn));
        if (err)
                return err;
 
-       err = decode_header(tconn, h, pi);
+       err = decode_header(tconn, buffer, pi);
        tconn->last_received = jiffies;
 
        return err;
 {
        struct drbd_conf *mdev;
        int rv;
-       struct p_barrier *p = tconn->data.rbuf;
+       struct p_barrier *p = pi->data;
        struct drbd_epoch *epoch;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        struct drbd_request *req;
        sector_t sector;
        int err;
-       struct p_data *p = tconn->data.rbuf;
+       struct p_data *p = pi->data;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        if (!mdev)
        struct drbd_conf *mdev;
        sector_t sector;
        int err;
-       struct p_data *p = tconn->data.rbuf;
+       struct p_data *p = pi->data;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        if (!mdev)
        struct drbd_conf *mdev;
        sector_t sector;
        struct drbd_peer_request *peer_req;
-       struct p_data *p = tconn->data.rbuf;
+       struct p_data *p = pi->data;
        u32 peer_seq = be32_to_cpu(p->seq_num);
        int rw = WRITE;
        u32 dp_flags;
        struct digest_info *di = NULL;
        int size, verb;
        unsigned int fault_type;
-       struct p_block_req *p = tconn->data.rbuf;
+       struct p_block_req *p = pi->data;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        if (!mdev)
 
 static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-       struct p_protocol *p = tconn->data.rbuf;
+       struct p_protocol *p = pi->data;
        int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
        int p_want_lose, p_two_primaries, cf;
        char p_integrity_alg[SHARED_SECRET_MAX] = "";
 static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_rs_param_95 *p = tconn->data.rbuf;
+       struct p_rs_param_95 *p;
        unsigned int header_size, data_size, exp_max_sz;
        struct crypto_hash *verify_tfm = NULL;
        struct crypto_hash *csums_tfm = NULL;
        }
 
        if (apv <= 88) {
-               header_size = sizeof(struct p_rs_param) - sizeof(struct p_header);
+               header_size = sizeof(struct p_rs_param);
                data_size = pi->size - header_size;
        } else if (apv <= 94) {
-               header_size = sizeof(struct p_rs_param_89) - sizeof(struct p_header);
+               header_size = sizeof(struct p_rs_param_89);
                data_size = pi->size - header_size;
                D_ASSERT(data_size == 0);
        } else {
-               header_size = sizeof(struct p_rs_param_95) - sizeof(struct p_header);
+               header_size = sizeof(struct p_rs_param_95);
                data_size = pi->size - header_size;
                D_ASSERT(data_size == 0);
        }
 
        /* initialize verify_alg and csums_alg */
+       p = pi->data;
        memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
 
-       err = drbd_recv_all(mdev->tconn, &p->head.payload, header_size);
+       err = drbd_recv_all(mdev->tconn, p, header_size);
        if (err)
                return err;
 
 static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_sizes *p = tconn->data.rbuf;
+       struct p_sizes *p = pi->data;
        enum determine_dev_size dd = unchanged;
        sector_t p_size, p_usize, my_usize;
        int ldsc = 0; /* local disk size changed */
 static int receive_uuids(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_uuids *p = tconn->data.rbuf;
+       struct p_uuids *p = pi->data;
        u64 *p_uuid;
        int i, updated_uuids = 0;
 
 static int receive_req_state(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_req_state *p = tconn->data.rbuf;
+       struct p_req_state *p = pi->data;
        union drbd_state mask, val;
        enum drbd_state_rv rv;
 
 
 static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-       struct p_req_state *p = tconn->data.rbuf;
+       struct p_req_state *p = pi->data;
        union drbd_state mask, val;
        enum drbd_state_rv rv;
 
 static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_state *p = tconn->data.rbuf;
+       struct p_state *p = pi->data;
        union drbd_state os, ns, peer_state;
        enum drbd_disk_state real_peer_disk;
        enum chg_state_flags cs_flags;
 static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_rs_uuid *p = tconn->data.rbuf;
+       struct p_rs_uuid *p = pi->data;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        if (!mdev)
  */
 static int
 receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size,
-                    struct p_header *h, struct bm_xfer_ctx *c)
+                    unsigned long *p, struct bm_xfer_ctx *c)
 {
-       unsigned long *buffer = (unsigned long *)h->payload;
        unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
                                 drbd_header_size(mdev->tconn);
-       unsigned int num_words = min_t(size_t, data_size / sizeof(unsigned long),
+       unsigned int num_words = min_t(size_t, data_size / sizeof(*p),
                                       c->bm_words - c->word_offset);
-       unsigned int want = num_words * sizeof(unsigned long);
+       unsigned int want = num_words * sizeof(*p);
        int err;
 
        if (want != size) {
        }
        if (want == 0)
                return 0;
-       err = drbd_recv_all(mdev->tconn, buffer, want);
+       err = drbd_recv_all(mdev->tconn, p, want);
        if (err)
                return err;
 
-       drbd_bm_merge_lel(mdev, c->word_offset, num_words, buffer);
+       drbd_bm_merge_lel(mdev, c->word_offset, num_words, p);
 
        c->word_offset += num_words;
        c->bit_offset = c->word_offset * BITS_PER_LONG;
                unsigned int len)
 {
        if (dcbp_get_code(p) == RLE_VLI_Bits)
-               return recv_bm_rle_bits(mdev, p, c, len);
+               return recv_bm_rle_bits(mdev, p, c, len - sizeof(*p));
 
        /* other variants had been implemented for evaluation,
         * but have been dropped as this one turned out to be "best"
        struct drbd_conf *mdev;
        struct bm_xfer_ctx c;
        int err;
-       struct p_header *h = tconn->data.rbuf;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        if (!mdev)
        };
 
        for(;;) {
-               if (pi->cmd == P_BITMAP) {
-                       err = receive_bitmap_plain(mdev, pi->size, h, &c);
-               } else if (pi->cmd == P_COMPRESSED_BITMAP) {
+               if (pi->cmd == P_BITMAP)
+                       err = receive_bitmap_plain(mdev, pi->size, pi->data, &c);
+               else if (pi->cmd == P_COMPRESSED_BITMAP) {
                        /* MAYBE: sanity check that we speak proto >= 90,
                         * and the feature is enabled! */
-                       struct p_compressed_bm *p;
+                       struct p_compressed_bm *p = pi->data;
 
                        if (pi->size > DRBD_SOCKET_BUFFER_SIZE - drbd_header_size(tconn)) {
                                dev_err(DEV, "ReportCBitmap packet too large\n");
                                err = -EIO;
                                goto out;
                        }
-
-                       p = mdev->tconn->data.rbuf;
-                       err = drbd_recv_all(mdev->tconn, p->head.payload, pi->size);
-                       if (err)
-                              goto out;
-                       if (pi->size <= (sizeof(*p) - sizeof(p->head))) {
+                       if (pi->size <= sizeof(*p)) {
                                dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", pi->size);
                                err = -EIO;
                                goto out;
                        }
+                       err = drbd_recv_all(mdev->tconn, p, pi->size);
+                       if (err)
+                              goto out;
                        err = decode_bitmap_c(mdev, p, &c, pi->size);
                } else {
                        dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd);
 static int receive_out_of_sync(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_block_desc *p = tconn->data.rbuf;
+       struct p_block_desc *p = pi->data;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        if (!mdev)
        [P_DATA_REPLY]      = { 1, sizeof(struct p_data), receive_DataReply },
        [P_RS_DATA_REPLY]   = { 1, sizeof(struct p_data), receive_RSDataReply } ,
        [P_BARRIER]         = { 0, sizeof(struct p_barrier), receive_Barrier } ,
-       [P_BITMAP]          = { 1, sizeof(struct p_header), receive_bitmap } ,
-       [P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } ,
-       [P_UNPLUG_REMOTE]   = { 0, sizeof(struct p_header), receive_UnplugRemote },
+       [P_BITMAP]          = { 1, 0, receive_bitmap } ,
+       [P_COMPRESSED_BITMAP] = { 1, 0, receive_bitmap } ,
+       [P_UNPLUG_REMOTE]   = { 0, 0, receive_UnplugRemote },
        [P_DATA_REQUEST]    = { 0, sizeof(struct p_block_req), receive_DataRequest },
        [P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
-       [P_SYNC_PARAM]      = { 1, sizeof(struct p_header), receive_SyncParam },
-       [P_SYNC_PARAM89]    = { 1, sizeof(struct p_header), receive_SyncParam },
+       [P_SYNC_PARAM]      = { 1, 0, receive_SyncParam },
+       [P_SYNC_PARAM89]    = { 1, 0, receive_SyncParam },
        [P_PROTOCOL]        = { 1, sizeof(struct p_protocol), receive_protocol },
        [P_UUIDS]           = { 0, sizeof(struct p_uuids), receive_uuids },
        [P_SIZES]           = { 0, sizeof(struct p_sizes), receive_sizes },
 
 static void drbdd(struct drbd_tconn *tconn)
 {
-       struct p_header *header = tconn->data.rbuf;
        struct packet_info pi;
        size_t shs; /* sub header size */
        int err;
                        goto err_out;
                }
 
-               shs = cmd->pkt_size - sizeof(struct p_header);
-               if (pi.size - shs > 0 && !cmd->expect_payload) {
+               shs = cmd->pkt_size;
+               if (pi.size > shs && !cmd->expect_payload) {
                        conn_err(tconn, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size);
                        goto err_out;
                }
 
                if (shs) {
-                       err = drbd_recv_all_warn(tconn, &header->payload, shs);
+                       err = drbd_recv_all_warn(tconn, pi.data, shs);
                        if (err)
                                goto err_out;
                        pi.size -= shs;
 static int drbd_do_features(struct drbd_tconn *tconn)
 {
        /* ASSERT current == tconn->receiver ... */
-       struct p_connection_features *p = tconn->data.rbuf;
-       const int expect = sizeof(struct p_connection_features) - sizeof(struct p_header80);
+       struct p_connection_features *p;
+       const int expect = sizeof(struct p_connection_features);
        struct packet_info pi;
        int err;
 
                return -1;
        }
 
-       err = drbd_recv_all_warn(tconn, &p->head.payload, expect);
+       p = pi.data;
+       err = drbd_recv_all_warn(tconn, p, expect);
        if (err)
                return 0;
 
                rv = 0;
                goto fail;
        }
-       rv = !conn_send_command(tconn, sock, P_AUTH_CHALLENGE,
-                               sizeof(struct p_header),
+       rv = !conn_send_command(tconn, sock, P_AUTH_CHALLENGE, 0,
                                my_challenge, CHALLENGE_LEN);
        if (!rv)
                goto fail;
                rv = 0;
                goto fail;
        }
-       rv = !conn_send_command(tconn, sock, P_AUTH_RESPONSE,
-                               sizeof(struct p_header),
+       rv = !conn_send_command(tconn, sock, P_AUTH_RESPONSE, 0,
                                response, resp_size);
        if (!rv)
                goto fail;
 
 static int got_conn_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-       struct p_req_state_reply *p = tconn->meta.rbuf;
+       struct p_req_state_reply *p = pi->data;
        int retcode = be32_to_cpu(p->retcode);
 
        if (retcode >= SS_SUCCESS) {
 static int got_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_req_state_reply *p = tconn->meta.rbuf;
+       struct p_req_state_reply *p = pi->data;
        int retcode = be32_to_cpu(p->retcode);
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
 static int got_IsInSync(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_block_ack *p = tconn->meta.rbuf;
+       struct p_block_ack *p = pi->data;
        sector_t sector = be64_to_cpu(p->sector);
        int blksize = be32_to_cpu(p->blksize);
 
 static int got_BlockAck(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_block_ack *p = tconn->meta.rbuf;
+       struct p_block_ack *p = pi->data;
        sector_t sector = be64_to_cpu(p->sector);
        int blksize = be32_to_cpu(p->blksize);
        enum drbd_req_event what;
 static int got_NegAck(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_block_ack *p = tconn->meta.rbuf;
+       struct p_block_ack *p = pi->data;
        sector_t sector = be64_to_cpu(p->sector);
        int size = be32_to_cpu(p->blksize);
        bool missing_ok = tconn->net_conf->wire_protocol == DRBD_PROT_A ||
 static int got_NegDReply(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_block_ack *p = tconn->meta.rbuf;
+       struct p_block_ack *p = pi->data;
        sector_t sector = be64_to_cpu(p->sector);
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        struct drbd_conf *mdev;
        sector_t sector;
        int size;
-       struct p_block_ack *p = tconn->meta.rbuf;
+       struct p_block_ack *p = pi->data;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        if (!mdev)
 static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_barrier_ack *p = tconn->meta.rbuf;
+       struct p_barrier_ack *p = pi->data;
 
        mdev = vnr_to_mdev(tconn, pi->vnr);
        if (!mdev)
 static int got_OVResult(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct drbd_conf *mdev;
-       struct p_block_ack *p = tconn->meta.rbuf;
+       struct p_block_ack *p = pi->data;
        struct drbd_work *w;
        sector_t sector;
        int size;
 };
 
 static struct asender_cmd asender_tbl[] = {
-       [P_PING]            = { sizeof(struct p_header), got_Ping },
-       [P_PING_ACK]        = { sizeof(struct p_header), got_PingAck },
+       [P_PING]            = { 0, got_Ping },
+       [P_PING_ACK]        = { 0, got_PingAck },
        [P_RECV_ACK]        = { sizeof(struct p_block_ack), got_BlockAck },
        [P_WRITE_ACK]       = { sizeof(struct p_block_ack), got_BlockAck },
        [P_RS_WRITE_ACK]    = { sizeof(struct p_block_ack), got_BlockAck },
 int drbd_asender(struct drbd_thread *thi)
 {
        struct drbd_tconn *tconn = thi->tconn;
-       struct p_header *h = tconn->meta.rbuf;
        struct asender_cmd *cmd = NULL;
        struct packet_info pi;
        int rv;
-       void *buf    = h;
+       void *buf    = tconn->meta.rbuf;
        int received = 0;
        unsigned int header_size = drbd_header_size(tconn);
        int expect   = header_size;
                }
 
                if (received == expect && cmd == NULL) {
-                       if (decode_header(tconn, h, &pi))
+                       if (decode_header(tconn, tconn->meta.rbuf, &pi))
                                goto reconnect;
                        cmd = &asender_tbl[pi.cmd];
                        if (pi.cmd >= ARRAY_SIZE(asender_tbl) || !cmd->fn) {
                                        pi.cmd, pi.size);
                                goto disconnect;
                        }
-                       expect = cmd->pkt_size;
+                       expect = header_size + cmd->pkt_size;
                        if (pi.size != expect - header_size) {
                                conn_err(tconn, "Wrong packet size on meta (c: %d, l: %d)\n",
                                        pi.cmd, pi.size);
                        if (cmd == &asender_tbl[P_PING_ACK])
                                ping_timeout_active = 0;
 
-                       buf      = h;
+                       buf      = tconn->meta.rbuf;
                        received = 0;
                        expect   = header_size;
                        cmd      = NULL;