git://git.onelab.eu
/
sliver-openvswitch.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ofproto: Inline trivial functions.
[sliver-openvswitch.git]
/
ofproto
/
pktbuf.c
diff --git
a/ofproto/pktbuf.c
b/ofproto/pktbuf.c
index
450cc3b
..
38ec348
100644
(file)
--- a/
ofproto/pktbuf.c
+++ b/
ofproto/pktbuf.c
@@
-1,5
+1,5
@@
/*
/*
- * Copyright (c) 2008, 2009
Nicira Networks
.
+ * Copyright (c) 2008, 2009
, 2010, 2011, 2012, 2013 Nicira, Inc
.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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 <inttypes.h>
#include <stdlib.h>
#include "coverage.h"
#include <inttypes.h>
#include <stdlib.h>
#include "coverage.h"
+#include "ofp-util.h"
#include "ofpbuf.h"
#include "timeval.h"
#include "util.h"
#include "vconn.h"
#include "ofpbuf.h"
#include "timeval.h"
#include "util.h"
#include "vconn.h"
-
-#define THIS_MODULE VLM_pktbuf
#include "vlog.h"
#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
/* 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
@@
-45,7
+51,7
@@
struct packet {
struct ofpbuf *buffer;
uint32_t cookie;
long long int timeout;
struct ofpbuf *buffer;
uint32_t cookie;
long long int timeout;
-
uint16
_t in_port;
+
ofp_port
_t in_port;
};
struct pktbuf {
};
struct pktbuf {
@@
-63,7
+69,7
@@
pktbuf_capacity(void)
struct pktbuf *
pktbuf_create(void)
{
struct pktbuf *
pktbuf_create(void)
{
- return x
calloc(1,
sizeof *pktbuf_create());
+ return x
zalloc(
sizeof *pktbuf_create());
}
void
}
void
@@
-86,8
+92,9
@@
make_id(unsigned int buffer_idx, unsigned int cookie)
}
/* Attempts to allocate an OpenFlow packet buffer id within 'pb'. The packet
}
/* Attempts to allocate an OpenFlow packet buffer id within 'pb'. The packet
- * buffer will store a copy of 'buffer' and the port number 'in_port', which
- * should be the datapath port number on which 'buffer' was received.
+ * buffer will store a copy of 'buffer_size' bytes in 'buffer' and the port
+ * number 'in_port', which should be the OpenFlow port number on which 'buffer'
+ * was received.
*
* If successful, returns the packet buffer id (a number other than
* UINT32_MAX). pktbuf_retrieve() can later be used to retrieve the buffer and
*
* If successful, returns the packet buffer id (a number other than
* UINT32_MAX). pktbuf_retrieve() can later be used to retrieve the buffer and
@@
-96,7
+103,8
@@
make_id(unsigned int buffer_idx, unsigned int cookie)
*
* The caller retains ownership of 'buffer'. */
uint32_t
*
* The caller retains ownership of 'buffer'. */
uint32_t
-pktbuf_save(struct pktbuf *pb, struct ofpbuf *buffer, uint16_t in_port)
+pktbuf_save(struct pktbuf *pb, const void *buffer, size_t buffer_size,
+ ofp_port_t in_port)
{
struct packet *p = &pb->packets[pb->buffer_idx];
pb->buffer_idx = (pb->buffer_idx + 1) & PKTBUF_MASK;
{
struct packet *p = &pb->packets[pb->buffer_idx];
pb->buffer_idx = (pb->buffer_idx + 1) & PKTBUF_MASK;
@@
-111,7
+119,10
@@
pktbuf_save(struct pktbuf *pb, struct ofpbuf *buffer, uint16_t in_port)
if (++p->cookie >= COOKIE_MAX) {
p->cookie = 0;
}
if (++p->cookie >= COOKIE_MAX) {
p->cookie = 0;
}
- p->buffer = ofpbuf_clone(buffer);
+
+ /* Use 2 bytes of headroom to 32-bit align the L3 header. */
+ p->buffer = ofpbuf_clone_data_with_headroom(buffer, buffer_size, 2);
+
p->timeout = time_msec() + OVERWRITE_MSECS;
p->in_port = in_port;
return make_id(p - pb->packets, p->cookie);
p->timeout = time_msec() + OVERWRITE_MSECS;
p->in_port = in_port;
return make_id(p - pb->packets, p->cookie);
@@
-144,28
+155,36
@@
pktbuf_get_null(void)
}
/* Attempts to retrieve a saved packet with the given 'id' from 'pb'. Returns
}
/* Attempts to retrieve a saved packet with the given 'id' from 'pb'. Returns
- * 0 if successful, otherwise an OpenFlow error code constructed with
- * ofp_mkerr().
+ * 0 if successful, otherwise an OpenFlow error code.
*
* On success, ordinarily stores the buffered packet in '*bufferp' and the
*
* On success, ordinarily stores the buffered packet in '*bufferp' and the
- *
datapath
port number on which the packet was received in '*in_port'. The
+ *
OpenFlow
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
* 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
OFPP_NONE
in '*in_port'.
*
*
- * On failure, stores NULL in in '*bufferp' and -1 in '*in_port'. */
-int
+ * 'in_port' may be NULL if the input port is not of interest.
+ *
+ * The L3 header of a returned packet will be 32-bit aligned.
+ *
+ * On failure, stores NULL in in '*bufferp' and UINT16_MAX in '*in_port'. */
+enum ofperr
pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp,
pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp,
-
uint16
_t *in_port)
+
ofp_port
_t *in_port)
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 20);
struct packet *p;
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 20);
struct packet *p;
- int error;
+ enum ofperr error;
+
+ if (id == UINT32_MAX) {
+ error = 0;
+ goto error;
+ }
if (!pb) {
VLOG_WARN_RL(&rl, "attempt to send buffered packet via connection "
"without buffers");
if (!pb) {
VLOG_WARN_RL(&rl, "attempt to send buffered packet via connection "
"without buffers");
- return
ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_COOKIE)
;
+ return
OFPERR_OFPBRC_BUFFER_UNKNOWN
;
}
p = &pb->packets[id & PKTBUF_MASK];
}
p = &pb->packets[id & PKTBUF_MASK];
@@
-173,28
+192,33
@@
pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp,
struct ofpbuf *buffer = p->buffer;
if (buffer) {
*bufferp = buffer;
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;
} else {
COVERAGE_INC(pktbuf_reuse_error);
VLOG_WARN_RL(&rl, "attempt to reuse buffer %08"PRIx32, id);
p->buffer = NULL;
COVERAGE_INC(pktbuf_retrieved);
return 0;
} else {
COVERAGE_INC(pktbuf_reuse_error);
VLOG_WARN_RL(&rl, "attempt to reuse buffer %08"PRIx32, id);
- error =
ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BUFFER_EMPTY)
;
+ error =
OFPERR_OFPBRC_BUFFER_EMPTY
;
}
} else if (id >> PKTBUF_BITS != COOKIE_MAX) {
}
} else if (id >> PKTBUF_BITS != COOKIE_MAX) {
- COVERAGE_INC(pktbuf_b
ad_cookie
);
+ COVERAGE_INC(pktbuf_b
uffer_unknown
);
VLOG_WARN_RL(&rl, "cookie mismatch: %08"PRIx32" != %08"PRIx32,
id, (id & PKTBUF_MASK) | (p->cookie << PKTBUF_BITS));
VLOG_WARN_RL(&rl, "cookie mismatch: %08"PRIx32" != %08"PRIx32,
id, (id & PKTBUF_MASK) | (p->cookie << PKTBUF_BITS));
- error =
ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_COOKIE)
;
+ error =
OFPERR_OFPBRC_BUFFER_UNKNOWN
;
} else {
COVERAGE_INC(pktbuf_null_cookie);
VLOG_INFO_RL(&rl, "Received null cookie %08"PRIx32" (this is normal "
"if the switch was recently in fail-open mode)", id);
error = 0;
}
} else {
COVERAGE_INC(pktbuf_null_cookie);
VLOG_INFO_RL(&rl, "Received null cookie %08"PRIx32" (this is normal "
"if the switch was recently in fail-open mode)", id);
error = 0;
}
+error:
*bufferp = NULL;
*bufferp = NULL;
- *in_port = -1;
+ if (in_port) {
+ *in_port = OFPP_NONE;
+ }
return error;
}
return error;
}
@@
-207,3
+231,23
@@
pktbuf_discard(struct pktbuf *pb, uint32_t id)
p->buffer = NULL;
}
}
p->buffer = NULL;
}
}
+
+/* Returns the number of packets buffered in 'pb'. Returns 0 if 'pb' is
+ * null. */
+unsigned int
+pktbuf_count_packets(const struct pktbuf *pb)
+{
+ int n = 0;
+
+ if (pb) {
+ int i;
+
+ for (i = 0; i < PKTBUF_CNT; i++) {
+ if (pb->packets[i].buffer) {
+ n++;
+ }
+ }
+ }
+
+ return n;
+}