X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fpktbuf.c;h=fc4c66ca102e48e2dad99c71ac32d83ac4665a09;hb=d422c1189901d34125cd2d46552391c333d1f647;hp=495a1ee3772d695088f5fe49f600a52ca2a6f089;hpb=49bdc010dfc9f396eec608148ca0f4ea71a0c4dd;p=sliver-openvswitch.git diff --git a/ofproto/pktbuf.c b/ofproto/pktbuf.c index 495a1ee37..fc4c66ca1 100644 --- a/ofproto/pktbuf.c +++ b/ofproto/pktbuf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,20 @@ #include #include #include "coverage.h" +#include "ofp-util.h" #include "ofpbuf.h" #include "timeval.h" #include "util.h" #include "vconn.h" - -#define THIS_MODULE VLM_pktbuf #include "vlog.h" +VLOG_DEFINE_THIS_MODULE(pktbuf); + +COVERAGE_DEFINE(pktbuf_buffer_unknown); +COVERAGE_DEFINE(pktbuf_null_cookie); +COVERAGE_DEFINE(pktbuf_retrieved); +COVERAGE_DEFINE(pktbuf_reuse_error); + /* Buffers are identified by a 32-bit opaque ID. We divide the ID * into a buffer number (low bits) and a cookie (high bits). The buffer number * is an index into an array of buffers. The cookie distinguishes between @@ -111,7 +117,9 @@ pktbuf_save(struct pktbuf *pb, struct ofpbuf *buffer, uint16_t in_port) if (++p->cookie >= COOKIE_MAX) { p->cookie = 0; } - p->buffer = ofpbuf_clone(buffer); + p->buffer = ofpbuf_new_with_headroom(buffer->size, + sizeof(struct ofp_packet_in)); + ofpbuf_put(p->buffer, buffer->data, buffer->size); p->timeout = time_msec() + OVERWRITE_MSECS; p->in_port = in_port; return make_id(p - pb->packets, p->cookie); @@ -151,9 +159,14 @@ pktbuf_get_null(void) * datapath port number on which the packet was received in '*in_port'. The * caller becomes responsible for freeing the buffer. However, if 'id' * identifies a "null" packet buffer (created with pktbuf_get_null()), stores - * NULL in '*bufferp' and -1 in '*in_port'. + * NULL in '*bufferp' and UINT16_max in '*in_port'. + * + * 'in_port' may be NULL if the input port is not of interest. + * + * A returned packet will have at least sizeof(struct ofp_packet_in) bytes of + * headroom. * - * On failure, stores NULL in in '*bufferp' and -1 in '*in_port'. */ + * On failure, stores NULL in in '*bufferp' and UINT16_MAX in '*in_port'. */ int pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp, uint16_t *in_port) @@ -162,6 +175,11 @@ pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp, struct packet *p; int error; + if (id == UINT32_MAX) { + error = 0; + goto error; + } + if (!pb) { VLOG_WARN_RL(&rl, "attempt to send buffered packet via connection " "without buffers"); @@ -173,7 +191,9 @@ pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp, struct ofpbuf *buffer = p->buffer; if (buffer) { *bufferp = buffer; - *in_port = p->in_port; + if (in_port) { + *in_port = p->in_port; + } p->buffer = NULL; COVERAGE_INC(pktbuf_retrieved); return 0; @@ -193,8 +213,11 @@ pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp, "if the switch was recently in fail-open mode)", id); error = 0; } +error: *bufferp = NULL; - *in_port = -1; + if (in_port) { + *in_port = UINT16_MAX; + } return error; }