2009-07-08 13:19:16 -07:00
|
|
|
/*
|
2010-01-22 14:37:10 -05:00
|
|
|
* Copyright (c) 2008, 2009, 2010 Nicira Networks.
|
2009-07-08 13:19:16 -07:00
|
|
|
*
|
2009-06-15 15:11:30 -07:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at:
|
2009-07-08 13:19:16 -07:00
|
|
|
*
|
2009-06-15 15:11:30 -07:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
2009-07-08 13:19:16 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef DPIF_H
|
|
|
|
#define DPIF_H 1
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
2010-08-04 14:08:26 -07:00
|
|
|
#include "openflow/openflow.h"
|
|
|
|
#include "openvswitch/datapath-protocol.h"
|
|
|
|
#include "util.h"
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2010-02-17 10:36:57 -05:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2009-06-16 10:09:10 -07:00
|
|
|
struct dpif;
|
2010-12-03 14:41:38 -08:00
|
|
|
struct netdev;
|
2010-12-10 10:40:58 -08:00
|
|
|
struct nlattr;
|
2009-07-08 13:19:16 -07:00
|
|
|
struct ofpbuf;
|
2009-07-06 11:06:36 -07:00
|
|
|
struct svec;
|
2010-02-01 11:36:01 -05:00
|
|
|
struct dpif_class;
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2009-06-19 14:09:09 -07:00
|
|
|
void dp_run(void);
|
|
|
|
void dp_wait(void);
|
2010-02-01 11:36:01 -05:00
|
|
|
|
|
|
|
int dp_register_provider(const struct dpif_class *);
|
|
|
|
int dp_unregister_provider(const char *type);
|
2010-01-22 14:37:10 -05:00
|
|
|
void dp_enumerate_types(struct svec *types);
|
2010-02-01 11:36:01 -05:00
|
|
|
|
2010-01-22 14:37:10 -05:00
|
|
|
int dp_enumerate_names(const char *type, struct svec *names);
|
|
|
|
void dp_parse_name(const char *datapath_name, char **name, char **type);
|
2009-06-19 14:09:09 -07:00
|
|
|
|
2010-01-22 14:37:10 -05:00
|
|
|
int dpif_open(const char *name, const char *type, struct dpif **);
|
|
|
|
int dpif_create(const char *name, const char *type, struct dpif **);
|
|
|
|
int dpif_create_and_open(const char *name, const char *type, struct dpif **);
|
2009-07-08 13:19:16 -07:00
|
|
|
void dpif_close(struct dpif *);
|
|
|
|
|
2009-06-16 11:00:22 -07:00
|
|
|
const char *dpif_name(const struct dpif *);
|
2010-01-22 14:37:10 -05:00
|
|
|
const char *dpif_base_name(const struct dpif *);
|
2009-07-06 11:06:36 -07:00
|
|
|
int dpif_get_all_names(const struct dpif *, struct svec *);
|
2009-07-08 13:19:16 -07:00
|
|
|
|
|
|
|
int dpif_delete(struct dpif *);
|
|
|
|
|
|
|
|
int dpif_get_dp_stats(const struct dpif *, struct odp_stats *);
|
|
|
|
int dpif_get_drop_frags(const struct dpif *, bool *drop_frags);
|
|
|
|
int dpif_set_drop_frags(struct dpif *, bool drop_frags);
|
|
|
|
|
2010-12-03 14:41:38 -08:00
|
|
|
int dpif_port_add(struct dpif *, struct netdev *, uint16_t *port_nop);
|
2009-07-08 13:19:16 -07:00
|
|
|
int dpif_port_del(struct dpif *, uint16_t port_no);
|
|
|
|
int dpif_port_query_by_number(const struct dpif *, uint16_t port_no,
|
|
|
|
struct odp_port *);
|
|
|
|
int dpif_port_query_by_name(const struct dpif *, const char *devname,
|
|
|
|
struct odp_port *);
|
2009-06-15 16:51:46 -07:00
|
|
|
int dpif_port_get_name(struct dpif *, uint16_t port_no,
|
|
|
|
char *name, size_t name_size);
|
datapath: Change listing ports to use an iterator concept.
One of the goals for Open vSwitch is to decouple kernel and userspace
software, so that either one can be upgraded or rolled back independent of
the other. To do this in full generality, it must be possible to add new
features to the kernel vport layer without changing userspace software. In
turn, that means that the odp_port structure must become variable-length.
This does not, however, fit in well with the ODP_PORT_LIST ioctl in its
current form, because that would require userspace to know how much space
to allocate for each port in advance, or to allocate as much space as
could possibly be needed. Neither choice is very attractive.
This commit prepares for a different solution, by replacing ODP_PORT_LIST
by a new ioctl ODP_VPORT_DUMP that retrieves information about a single
vport from the datapath on each call. It is much cleaner to allocate the
maximum amount of space for a single vport than to do so for possibly a
large number of vports.
It would be faster to retrieve a number of vports in batch instead of just
one at a time, but that will naturally happen later when the kernel
datapath interface is changed to use Netlink, so this patch does not bother
with it.
The Netlink version won't need to take the starting port number from
userspace, since Netlink sockets can keep track of that state as part
of their "dump" feature.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
2011-01-10 13:12:12 -08:00
|
|
|
|
|
|
|
struct dpif_port_dump {
|
|
|
|
const struct dpif *dpif;
|
|
|
|
int error;
|
|
|
|
void *state;
|
|
|
|
};
|
|
|
|
void dpif_port_dump_start(struct dpif_port_dump *, const struct dpif *);
|
|
|
|
bool dpif_port_dump_next(struct dpif_port_dump *, struct odp_port *);
|
|
|
|
int dpif_port_dump_done(struct dpif_port_dump *);
|
|
|
|
|
|
|
|
/* Iterates through each ODP_PORT in DPIF, using DUMP as state.
|
|
|
|
*
|
|
|
|
* Arguments all have pointer type.
|
|
|
|
*
|
|
|
|
* If you break out of the loop, then you need to free the dump structure by
|
|
|
|
* hand using dpif_port_dump_done(). */
|
|
|
|
#define DPIF_PORT_FOR_EACH(ODP_PORT, DUMP, DPIF) \
|
|
|
|
for (dpif_port_dump_start(DUMP, DPIF); \
|
|
|
|
(dpif_port_dump_next(DUMP, ODP_PORT) \
|
|
|
|
? true \
|
|
|
|
: (dpif_port_dump_done(DUMP), false)); \
|
|
|
|
)
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2009-06-24 10:24:09 -07:00
|
|
|
int dpif_port_poll(const struct dpif *, char **devnamep);
|
|
|
|
void dpif_port_poll_wait(const struct dpif *);
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
int dpif_flow_flush(struct dpif *);
|
|
|
|
int dpif_flow_put(struct dpif *, struct odp_flow_put *);
|
|
|
|
int dpif_flow_del(struct dpif *, struct odp_flow *);
|
|
|
|
int dpif_flow_get(const struct dpif *, struct odp_flow *);
|
|
|
|
int dpif_flow_get_multiple(const struct dpif *, struct odp_flow[], size_t n);
|
datapath: Change listing flows to use an iterator concept.
One of the goals for Open vSwitch is to decouple kernel and userspace
software, so that either one can be upgraded or rolled back independent of
the other. To do this in full generality, it must be possible to change
the kernel's idea of the flow key separately from the userspace version.
In turn, that means that flow keys must become variable-length. This does
not, however, fit in well with the ODP_FLOW_LIST ioctl in its current form,
because that would require userspace to know how much space to allocate
for each flow's key in advance, or to allocate as much space as could
possibly be needed. Neither choice is very attractive.
This commit prepares for a different solution, by replacing ODP_FLOW_LIST
by a new ioctl ODP_FLOW_DUMP that retrieves a single flow from the datapath
on each call. It is much cleaner to allocate the maximum amount of space
for a single flow key than to do so for possibly a very large number of
flow keys.
As a side effect, this patch also fixes a race condition that sometimes
made "ovs-dpctl dump-flows" print an error: previously, flows were listed
and then their actions were retrieved, which left a window in which
ovs-vswitchd could delete the flow. Now dumping a flow and its actions is
a single step, closing that window.
Dumping all of the flows in a datapath is no longer an atomic step, so now
it is possible to miss some flows or see a single flow twice during
iteration, if the flow table is modified by another process. It doesn't
look like this should be a problem for ovs-vswitchd.
It would be faster to retrieve a number of flows in batch instead of just
one at a time, but that will naturally happen later when the kernel
datapath interface is changed to use Netlink, so this patch does not bother
with it.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
2010-12-28 10:39:52 -08:00
|
|
|
|
|
|
|
struct dpif_flow_dump {
|
|
|
|
const struct dpif *dpif;
|
|
|
|
int error;
|
|
|
|
void *state;
|
|
|
|
};
|
|
|
|
void dpif_flow_dump_start(struct dpif_flow_dump *, const struct dpif *);
|
|
|
|
bool dpif_flow_dump_next(struct dpif_flow_dump *, struct odp_flow *);
|
|
|
|
int dpif_flow_dump_done(struct dpif_flow_dump *);
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2010-12-10 10:40:58 -08:00
|
|
|
int dpif_execute(struct dpif *, const struct nlattr *actions,
|
|
|
|
size_t actions_len, const struct ofpbuf *);
|
2009-07-08 13:19:16 -07:00
|
|
|
|
datapath: Report kernel's flow key when passing packets up to userspace.
One of the goals for Open vSwitch is to decouple kernel and userspace
software, so that either one can be upgraded or rolled back independent of
the other. To do this in full generality, it must be possible to change
the kernel's idea of the flow key separately from the userspace version.
This commit takes one step in that direction by making the kernel report
its idea of the flow that a packet belongs to whenever it passes a packet
up to userspace. This means that userspace can intelligently figure out
what to do:
- If userspace's notion of the flow for the packet matches the kernel's,
then nothing special is necessary.
- If the kernel has a more specific notion for the flow than userspace,
for example if the kernel decoded IPv6 headers but userspace stopped
at the Ethernet type (because it does not understand IPv6), then again
nothing special is necessary: userspace can still set up the flow in
the usual way.
- If userspace has a more specific notion for the flow than the kernel,
for example if userspace decoded an IPv6 header but the kernel
stopped at the Ethernet type, then userspace can forward the packet
manually, without setting up a flow in the kernel. (This case is
bad from a performance point of view, but at least it is correct.)
This commit does not actually make userspace flexible enough to handle
changes in the kernel flow key structure, although userspace does now
have enough information to do that intelligently. This will have to wait
for later commits.
This commit is bigger than it would otherwise be because it is rolled
together with changing "struct odp_msg" to a sequence of Netlink
attributes. The alternative, to do each of those changes in a separate
patch, seemed like overkill because it meant that either we would have to
introduce and then kill off Netlink attributes for in_port and tun_id, if
Netlink conversion went first, or shove yet another variable-length header
into the stuff already after odp_msg, if adding the flow key to odp_msg
went first.
This commit will slow down performance of checksumming packets sent up to
userspace. I'm not entirely pleased with how I did it. I considered a
couple of alternatives, but none of them seemed that much better.
Suggestions welcome. Not changing anything wasn't an option,
unfortunately. At any rate some slowdown will become unavoidable when OVS
actually starts using Netlink instead of just Netlink framing.
(Actually, I thought of one option where we could avoid that: make
userspace do the checksum instead, by passing csum_start and csum_offset as
part of what goes to userspace. But that's not perfect either.)
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
2011-01-24 14:59:57 -08:00
|
|
|
/* A packet passed up from the datapath to userspace.
|
|
|
|
*
|
|
|
|
* If 'key' or 'actions' is nonnull, then it points into data owned by
|
|
|
|
* 'packet', so their memory cannot be freed separately. (This is hardly a
|
|
|
|
* great way to do things but it works out OK for the dpif providers and
|
|
|
|
* clients that exist so far.)
|
|
|
|
*/
|
|
|
|
struct dpif_upcall {
|
|
|
|
uint32_t type; /* One of _ODPL_*_NR. */
|
|
|
|
|
|
|
|
/* All types. */
|
|
|
|
struct ofpbuf *packet; /* Packet data. */
|
|
|
|
struct nlattr *key; /* Flow key. */
|
|
|
|
size_t key_len; /* Length of 'key' in bytes. */
|
|
|
|
|
|
|
|
/* _ODPL_ACTION_NR only. */
|
|
|
|
uint64_t userdata; /* Argument to ODPAT_CONTROLLER. */
|
|
|
|
|
|
|
|
/* _ODPL_SFLOW_NR only. */
|
|
|
|
uint32_t sample_pool; /* # of sampling candidate packets so far. */
|
|
|
|
struct nlattr *actions; /* Associated flow actions. */
|
|
|
|
size_t actions_len;
|
|
|
|
};
|
2010-08-04 14:08:26 -07:00
|
|
|
|
2009-06-17 14:18:10 -07:00
|
|
|
int dpif_recv_get_mask(const struct dpif *, int *listen_mask);
|
|
|
|
int dpif_recv_set_mask(struct dpif *, int listen_mask);
|
2010-01-04 13:08:37 -08:00
|
|
|
int dpif_get_sflow_probability(const struct dpif *, uint32_t *probability);
|
|
|
|
int dpif_set_sflow_probability(struct dpif *, uint32_t probability);
|
datapath: Report kernel's flow key when passing packets up to userspace.
One of the goals for Open vSwitch is to decouple kernel and userspace
software, so that either one can be upgraded or rolled back independent of
the other. To do this in full generality, it must be possible to change
the kernel's idea of the flow key separately from the userspace version.
This commit takes one step in that direction by making the kernel report
its idea of the flow that a packet belongs to whenever it passes a packet
up to userspace. This means that userspace can intelligently figure out
what to do:
- If userspace's notion of the flow for the packet matches the kernel's,
then nothing special is necessary.
- If the kernel has a more specific notion for the flow than userspace,
for example if the kernel decoded IPv6 headers but userspace stopped
at the Ethernet type (because it does not understand IPv6), then again
nothing special is necessary: userspace can still set up the flow in
the usual way.
- If userspace has a more specific notion for the flow than the kernel,
for example if userspace decoded an IPv6 header but the kernel
stopped at the Ethernet type, then userspace can forward the packet
manually, without setting up a flow in the kernel. (This case is
bad from a performance point of view, but at least it is correct.)
This commit does not actually make userspace flexible enough to handle
changes in the kernel flow key structure, although userspace does now
have enough information to do that intelligently. This will have to wait
for later commits.
This commit is bigger than it would otherwise be because it is rolled
together with changing "struct odp_msg" to a sequence of Netlink
attributes. The alternative, to do each of those changes in a separate
patch, seemed like overkill because it meant that either we would have to
introduce and then kill off Netlink attributes for in_port and tun_id, if
Netlink conversion went first, or shove yet another variable-length header
into the stuff already after odp_msg, if adding the flow key to odp_msg
went first.
This commit will slow down performance of checksumming packets sent up to
userspace. I'm not entirely pleased with how I did it. I considered a
couple of alternatives, but none of them seemed that much better.
Suggestions welcome. Not changing anything wasn't an option,
unfortunately. At any rate some slowdown will become unavoidable when OVS
actually starts using Netlink instead of just Netlink framing.
(Actually, I thought of one option where we could avoid that: make
userspace do the checksum instead, by passing csum_start and csum_offset as
part of what goes to userspace. But that's not perfect either.)
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
2011-01-24 14:59:57 -08:00
|
|
|
int dpif_recv(struct dpif *, struct dpif_upcall *);
|
2009-06-17 14:18:10 -07:00
|
|
|
int dpif_recv_purge(struct dpif *);
|
2009-07-08 13:19:16 -07:00
|
|
|
void dpif_recv_wait(struct dpif *);
|
|
|
|
|
2009-06-16 10:59:43 -07:00
|
|
|
void dpif_get_netflow_ids(const struct dpif *,
|
|
|
|
uint8_t *engine_type, uint8_t *engine_id);
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2010-07-20 11:23:21 -07:00
|
|
|
int dpif_queue_to_priority(const struct dpif *, uint32_t queue_id,
|
|
|
|
uint32_t *priority);
|
|
|
|
|
2010-02-17 10:36:57 -05:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
#endif /* dpif.h */
|