* 0xff00...0xfff7 "reserved" but not assigned a meaning by OpenFlow 1.0
* 0xfff8...0xffff "reserved" OFPP_* ports with assigned meanings
*/
-enum ofp_port {
- /* Ranges. */
- OFPP_MAX = 0xff00, /* Maximum number of physical switch ports. */
- OFPP_FIRST_RESV = 0xfff8, /* First assigned reserved port number. */
- OFPP_LAST_RESV = 0xffff, /* Last assigned reserved port number. */
-
- /* Reserved output "ports". */
- OFPP_IN_PORT = 0xfff8, /* Send the packet out the input port. This
- virtual port must be explicitly used
- in order to send back out of the input
- port. */
- OFPP_TABLE = 0xfff9, /* Perform actions in flow table.
- NB: This can only be the destination
- port for packet-out messages. */
- OFPP_NORMAL = 0xfffa, /* Process with normal L2/L3 switching. */
- OFPP_FLOOD = 0xfffb, /* All physical ports except input port and
- those disabled by STP. */
- OFPP_ALL = 0xfffc, /* All physical ports except input port. */
- OFPP_CONTROLLER = 0xfffd, /* Send to controller. */
- OFPP_LOCAL = 0xfffe, /* Local openflow "port". */
- OFPP_NONE = 0xffff /* Not associated with a physical port. */
-};
+
+/* Ranges. */
+#define OFPP_MAX OFP_PORT_C(0xff00) /* Max # of switch ports. */
+#define OFPP_FIRST_RESV OFP_PORT_C(0xfff8) /* First assigned reserved port. */
+#define OFPP_LAST_RESV OFP_PORT_C(0xffff) /* Last assigned reserved port. */
+
+/* Reserved output "ports". */
+#define OFPP_IN_PORT OFP_PORT_C(0xfff8) /* Where the packet came in. */
+#define OFPP_TABLE OFP_PORT_C(0xfff9) /* Perform actions in flow table. */
+#define OFPP_NORMAL OFP_PORT_C(0xfffa) /* Process with normal L2/L3. */
+#define OFPP_FLOOD OFP_PORT_C(0xfffb) /* All ports except input port and
+ * ports disabled by STP. */
+#define OFPP_ALL OFP_PORT_C(0xfffc) /* All ports except input port. */
+#define OFPP_CONTROLLER OFP_PORT_C(0xfffd) /* Send to controller. */
+#define OFPP_LOCAL OFP_PORT_C(0xfffe) /* Local openflow "port". */
+#define OFPP_NONE OFP_PORT_C(0xffff) /* Not associated with any port. */
/* OpenFlow 1.0 specific capabilities supported by the datapath (struct
* ofp_switch_features, member capabilities). */
* an OpenFlow 1.0 reserved port number to or from, respectively, the
* corresponding OpenFlow 1.1 reserved port number.
*/
-#define OFPP11_MAX 0xffffff00
-#define OFPP11_OFFSET (OFPP11_MAX - OFPP_MAX)
+#define OFPP11_MAX OFP11_PORT_C(0xffffff00)
+#define OFPP11_OFFSET 0xffff0000 /* OFPP11_MAX - OFPP_MAX */
/* Reserved wildcard port used only for flow mod (delete) and flow stats
* requests. Selects all flows regardless of output port
/*
- * Copyright (c) 2010, 2011 Nicira, Inc.
+ * Copyright (c) 2010, 2011, 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.
ovs_be32 hi, lo;
} ovs_32aligned_be64;
+/* ofp_port_t represents the port number of a OpenFlow switch.
+ * odp_port_t represents the port number on the datapath.
+ * ofp11_port_t represents the OpenFlow-1.1 port number. */
+typedef uint16_t OVS_BITWISE ofp_port_t;
+typedef uint32_t OVS_BITWISE odp_port_t;
+typedef uint32_t OVS_BITWISE ofp11_port_t;
+
+/* Macro functions that cast int types to ofp/odp/ofp11 types. */
+#define OFP_PORT_C(X) ((OVS_FORCE ofp_port_t) (X))
+#define ODP_PORT_C(X) ((OVS_FORCE odp_port_t) (X))
+#define OFP11_PORT_C(X) ((OVS_FORCE ofp11_port_t) (X))
+
#endif /* openvswitch/types.h */
VLOG_DEFINE_THIS_MODULE(bundle);
-static uint16_t
+static ofp_port_t
execute_ab(const struct ofpact_bundle *bundle,
- bool (*slave_enabled)(uint16_t ofp_port, void *aux), void *aux)
+ bool (*slave_enabled)(ofp_port_t ofp_port, void *aux), void *aux)
{
size_t i;
for (i = 0; i < bundle->n_slaves; i++) {
- uint16_t slave = bundle->slaves[i];
+ ofp_port_t slave = bundle->slaves[i];
if (slave_enabled(slave, aux)) {
return slave;
}
return OFPP_NONE;
}
-static uint16_t
+static ofp_port_t
execute_hrw(const struct ofpact_bundle *bundle,
const struct flow *flow, struct flow_wildcards *wc,
- bool (*slave_enabled)(uint16_t ofp_port, void *aux), void *aux)
+ bool (*slave_enabled)(ofp_port_t ofp_port, void *aux), void *aux)
{
uint32_t flow_hash, best_hash;
int best, i;
* calculate the result. Uses 'slave_enabled' to determine if the slave
* designated by 'ofp_port' is up. Returns the chosen slave, or
* OFPP_NONE if none of the slaves are acceptable. */
-uint16_t
+ofp_port_t
bundle_execute(const struct ofpact_bundle *bundle,
const struct flow *flow, struct flow_wildcards *wc,
- bool (*slave_enabled)(uint16_t ofp_port, void *aux), void *aux)
+ bool (*slave_enabled)(ofp_port_t ofp_port, void *aux),
+ void *aux)
{
switch (bundle->algorithm) {
case NX_BD_ALG_HRW:
}
enum ofperr
-bundle_check(const struct ofpact_bundle *bundle, int max_ports,
+bundle_check(const struct ofpact_bundle *bundle, ofp_port_t max_ports,
const struct flow *flow)
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
}
for (i = 0; i < bundle->n_slaves; i++) {
- uint16_t ofp_port = bundle->slaves[i];
+ ofp_port_t ofp_port = bundle->slaves[i];
enum ofperr error;
error = ofputil_check_output_port(ofp_port, max_ports);
slaves = ofpbuf_put_zeros(openflow, slaves_len);
for (i = 0; i < bundle->n_slaves; i++) {
- slaves[i] = htons(bundle->slaves[i]);
+ slaves[i] = htons(ofp_to_u16(bundle->slaves[i]));
}
}
bundle = ofpact_put_BUNDLE(ofpacts);
for (;;) {
- uint16_t slave_port;
+ ofp_port_t slave_port;
char *slave;
slave = strtok_r(NULL, ", []", save_ptr);
*
* See include/openflow/nicira-ext.h for NXAST_BUNDLE specification. */
-uint16_t bundle_execute(const struct ofpact_bundle *, const struct flow *,
+ofp_port_t bundle_execute(const struct ofpact_bundle *, const struct flow *,
struct flow_wildcards *wc,
- bool (*slave_enabled)(uint16_t ofp_port, void *aux),
+ bool (*slave_enabled)(ofp_port_t ofp_port, void *aux),
void *aux);
enum ofperr bundle_from_openflow(const struct nx_action_bundle *,
struct ofpbuf *ofpact);
-enum ofperr bundle_check(const struct ofpact_bundle *, int max_ports,
+enum ofperr bundle_check(const struct ofpact_bundle *, ofp_port_t max_ports,
const struct flow *);
void bundle_to_nxast(const struct ofpact_bundle *, struct ofpbuf *of10);
void bundle_parse(const char *, struct ofpbuf *ofpacts);
static void open_dpif(const struct dpif_linux_dp *, struct dpif **);
static bool dpif_linux_nln_parse(struct ofpbuf *, void *);
static void dpif_linux_port_changed(const void *vport, void *dpif);
-static uint32_t dpif_linux_port_get_pid(const struct dpif *, uint32_t port_no);
+static uint32_t dpif_linux_port_get_pid(const struct dpif *,
+ odp_port_t port_no);
static void dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *,
struct ofpbuf *);
static void
destroy_channels(struct dpif_linux *dpif)
{
- int i;
+ unsigned int i;
if (dpif->epoll_fd < 0) {
return;
dpif_linux_vport_init(&vport_request);
vport_request.cmd = OVS_VPORT_CMD_SET;
vport_request.dp_ifindex = dpif->dp_ifindex;
- vport_request.port_no = i;
+ vport_request.port_no = u32_to_odp(i);
vport_request.upcall_pid = &upcall_pid;
dpif_linux_vport_transact(&vport_request, NULL, NULL);
}
static int
-add_channel(struct dpif_linux *dpif, uint32_t port_no, struct nl_sock *sock)
+add_channel(struct dpif_linux *dpif, odp_port_t port_no, struct nl_sock *sock)
{
struct epoll_event event;
+ uint32_t port_idx = odp_to_u32(port_no);
if (dpif->epoll_fd < 0) {
return 0;
/* We assume that the datapath densely chooses port numbers, which
* can therefore be used as an index into an array of channels. */
- if (port_no >= dpif->uc_array_size) {
- int new_size = port_no + 1;
- int i;
+ if (port_idx >= dpif->uc_array_size) {
+ uint32_t new_size = port_idx + 1;
+ uint32_t i;
if (new_size > MAX_PORTS) {
VLOG_WARN_RL(&error_rl, "%s: datapath port %"PRIu32" too big",
memset(&event, 0, sizeof event);
event.events = EPOLLIN;
- event.data.u32 = port_no;
+ event.data.u32 = port_idx;
if (epoll_ctl(dpif->epoll_fd, EPOLL_CTL_ADD, nl_sock_fd(sock),
&event) < 0) {
return errno;
}
- nl_sock_destroy(dpif->channels[port_no].sock);
- dpif->channels[port_no].sock = sock;
- dpif->channels[port_no].last_poll = LLONG_MIN;
+ nl_sock_destroy(dpif->channels[port_idx].sock);
+ dpif->channels[port_idx].sock = sock;
+ dpif->channels[port_idx].last_poll = LLONG_MIN;
return 0;
}
static void
-del_channel(struct dpif_linux *dpif, uint32_t port_no)
+del_channel(struct dpif_linux *dpif, odp_port_t port_no)
{
struct dpif_channel *ch;
+ uint32_t port_idx = odp_to_u32(port_no);
- if (dpif->epoll_fd < 0 || port_no >= dpif->uc_array_size) {
+ if (dpif->epoll_fd < 0 || port_idx >= dpif->uc_array_size) {
return;
}
- ch = &dpif->channels[port_no];
+ ch = &dpif->channels[port_idx];
if (!ch->sock) {
return;
}
static int
dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
- uint32_t *port_nop)
+ odp_port_t *port_nop)
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
const struct netdev_tunnel_config *tnl_cfg;
VLOG_DBG("%s: assigning port %"PRIu32" to netlink pid %"PRIu32,
dpif_name(dpif_), reply.port_no, upcall_pid);
} else {
- if (error == EBUSY && *port_nop != UINT32_MAX) {
+ if (error == EBUSY && *port_nop != ODPP_NONE) {
VLOG_INFO("%s: requested port %"PRIu32" is in use",
dpif_name(dpif_), *port_nop);
}
}
static int
-dpif_linux_port_del(struct dpif *dpif_, uint32_t port_no)
+dpif_linux_port_del(struct dpif *dpif_, odp_port_t port_no)
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
struct dpif_linux_vport vport;
}
static int
-dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no,
+dpif_linux_port_query__(const struct dpif *dpif, odp_port_t port_no,
const char *port_name, struct dpif_port *dpif_port)
{
struct dpif_linux_vport request;
}
static int
-dpif_linux_port_query_by_number(const struct dpif *dpif, uint32_t port_no,
+dpif_linux_port_query_by_number(const struct dpif *dpif, odp_port_t port_no,
struct dpif_port *dpif_port)
{
return dpif_linux_port_query__(dpif, port_no, NULL, dpif_port);
return dpif_linux_port_query__(dpif, 0, devname, dpif_port);
}
-static int
+static odp_port_t
dpif_linux_get_max_ports(const struct dpif *dpif OVS_UNUSED)
{
- return MAX_PORTS;
+ return u32_to_odp(MAX_PORTS);
}
static uint32_t
-dpif_linux_port_get_pid(const struct dpif *dpif_, uint32_t port_no)
+dpif_linux_port_get_pid(const struct dpif *dpif_, odp_port_t port_no)
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
+ uint32_t port_idx = odp_to_u32(port_no);
if (dpif->epoll_fd < 0) {
return 0;
} else {
- /* The UINT32_MAX "reserved" port number uses the "ovs-system"'s
+ /* The ODPP_NONE "reserved" port number uses the "ovs-system"'s
* channel, since it is not heavily loaded. */
- int idx = (port_no >= dpif->uc_array_size) ? 0 : port_no;
+ uint32_t idx = port_idx >= dpif->uc_array_size ? 0 : port_idx;
return nl_sock_pid(dpif->channels[idx].sock);
}
}
vport->cmd = genl->cmd;
vport->dp_ifindex = ovs_header->dp_ifindex;
- vport->port_no = nl_attr_get_u32(a[OVS_VPORT_ATTR_PORT_NO]);
+ vport->port_no = nl_attr_get_odp_port(a[OVS_VPORT_ATTR_PORT_NO]);
vport->type = nl_attr_get_u32(a[OVS_VPORT_ATTR_TYPE]);
vport->name = nl_attr_get_string(a[OVS_VPORT_ATTR_NAME]);
if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
ovs_header = ofpbuf_put_uninit(buf, sizeof *ovs_header);
ovs_header->dp_ifindex = vport->dp_ifindex;
- if (vport->port_no != UINT32_MAX) {
- nl_msg_put_u32(buf, OVS_VPORT_ATTR_PORT_NO, vport->port_no);
+ if (vport->port_no != ODPP_NONE) {
+ nl_msg_put_odp_port(buf, OVS_VPORT_ATTR_PORT_NO, vport->port_no);
}
if (vport->type != OVS_VPORT_TYPE_UNSPEC) {
dpif_linux_vport_init(struct dpif_linux_vport *vport)
{
memset(vport, 0, sizeof *vport);
- vport->port_no = UINT32_MAX;
+ vport->port_no = ODPP_NONE;
}
/* Executes 'request' in the kernel datapath. If the command fails, returns a
#include <stdint.h>
#include <linux/openvswitch.h>
+#include "flow.h"
+
struct ofpbuf;
struct dpif_linux_vport {
/* ovs_vport header. */
int dp_ifindex;
- uint32_t port_no; /* UINT32_MAX if unknown. */
+ odp_port_t port_no; /* ODPP_NONE if unknown. */
enum ovs_vport_type type;
/* Attributes.
/* A port in a netdev-based datapath. */
struct dp_netdev_port {
- int port_no; /* Index into dp_netdev's 'ports'. */
+ odp_port_t port_no; /* Index into dp_netdev's 'ports'. */
struct list node; /* Element in dp_netdev's 'port_list'. */
struct netdev *netdev;
struct netdev_saved_flags *sf;
/* Maximum port MTU seen so far. */
static int max_mtu = ETH_PAYLOAD_MAX;
-static int get_port_by_number(struct dp_netdev *, uint32_t port_no,
+static int get_port_by_number(struct dp_netdev *, odp_port_t port_no,
struct dp_netdev_port **portp);
static int get_port_by_name(struct dp_netdev *, const char *devname,
struct dp_netdev_port **portp);
static void dp_netdev_free(struct dp_netdev *);
static void dp_netdev_flow_flush(struct dp_netdev *);
static int do_add_port(struct dp_netdev *, const char *devname,
- const char *type, uint32_t port_no);
-static int do_del_port(struct dp_netdev *, uint32_t port_no);
+ const char *type, odp_port_t port_no);
+static int do_del_port(struct dp_netdev *, odp_port_t port_no);
static int dpif_netdev_open(const struct dpif_class *, const char *name,
bool create, struct dpif **);
static int dp_netdev_output_userspace(struct dp_netdev *, const struct ofpbuf *,
return &dpif->dpif;
}
-static int
+/* Choose an unused, non-zero port number and return it on success.
+ * Return ODPP_NONE on failure. */
+static odp_port_t
choose_port(struct dp_netdev *dp, const char *name)
{
- int port_no;
+ uint32_t port_no;
if (dp->class != &dpif_netdev_class) {
const char *p;
port_no = start_no + strtol(p, NULL, 10);
if (port_no > 0 && port_no < MAX_PORTS
&& !dp->ports[port_no]) {
- return port_no;
+ return u32_to_odp(port_no);
}
break;
}
for (port_no = 1; port_no < MAX_PORTS; port_no++) {
if (!dp->ports[port_no]) {
- return port_no;
+ return u32_to_odp(port_no);
}
}
- return -1;
+ return ODPP_NONE;
}
static int
hmap_init(&dp->flow_table);
list_init(&dp->port_list);
- error = do_add_port(dp, name, "internal", OVSP_LOCAL);
+ error = do_add_port(dp, name, "internal", ODPP_LOCAL);
if (error) {
dp_netdev_free(dp);
return error;
static int
do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
- uint32_t port_no)
+ odp_port_t port_no)
{
struct netdev_saved_flags *sf;
struct dp_netdev_port *port;
}
list_push_back(&dp->port_list, &port->node);
- dp->ports[port_no] = port;
+ dp->ports[odp_to_u32(port_no)] = port;
dp->serial++;
return 0;
static int
dpif_netdev_port_add(struct dpif *dpif, struct netdev *netdev,
- uint32_t *port_nop)
+ odp_port_t *port_nop)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
const char *dpif_port;
- int port_no;
+ odp_port_t port_no;
dpif_port = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf);
- if (*port_nop != UINT32_MAX) {
- if (*port_nop >= MAX_PORTS) {
+ if (*port_nop != ODPP_NONE) {
+ uint32_t port_idx = odp_to_u32(*port_nop);
+ if (port_idx >= MAX_PORTS) {
return EFBIG;
- } else if (dp->ports[*port_nop]) {
+ } else if (dp->ports[port_idx]) {
return EBUSY;
}
port_no = *port_nop;
} else {
port_no = choose_port(dp, dpif_port);
}
- if (port_no >= 0) {
+ if (port_no != ODPP_NONE) {
*port_nop = port_no;
return do_add_port(dp, dpif_port, netdev_get_type(netdev), port_no);
}
}
static int
-dpif_netdev_port_del(struct dpif *dpif, uint32_t port_no)
+dpif_netdev_port_del(struct dpif *dpif, odp_port_t port_no)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
- return port_no == OVSP_LOCAL ? EINVAL : do_del_port(dp, port_no);
+ return (port_no == ODPP_LOCAL ?
+ EINVAL : do_del_port(dp, port_no));
}
static bool
-is_valid_port_number(uint32_t port_no)
+is_valid_port_number(odp_port_t port_no)
{
- return port_no < MAX_PORTS;
+ return odp_to_u32(port_no) < MAX_PORTS;
}
static int
get_port_by_number(struct dp_netdev *dp,
- uint32_t port_no, struct dp_netdev_port **portp)
+ odp_port_t port_no, struct dp_netdev_port **portp)
{
if (!is_valid_port_number(port_no)) {
*portp = NULL;
return EINVAL;
} else {
- *portp = dp->ports[port_no];
+ *portp = dp->ports[odp_to_u32(port_no)];
return *portp ? 0 : ENOENT;
}
}
}
static int
-do_del_port(struct dp_netdev *dp, uint32_t port_no)
+do_del_port(struct dp_netdev *dp, odp_port_t port_no)
{
struct dp_netdev_port *port;
int error;
}
list_remove(&port->node);
- dp->ports[port->port_no] = NULL;
+ dp->ports[odp_to_u32(port_no)] = NULL;
dp->serial++;
netdev_close(port->netdev);
}
static int
-dpif_netdev_port_query_by_number(const struct dpif *dpif, uint32_t port_no,
+dpif_netdev_port_query_by_number(const struct dpif *dpif, odp_port_t port_no,
struct dpif_port *dpif_port)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
return error;
}
-static int
+static odp_port_t
dpif_netdev_get_max_ports(const struct dpif *dpif OVS_UNUSED)
{
- return MAX_PORTS;
+ return u32_to_odp(MAX_PORTS);
}
static void
}
struct dp_netdev_port_state {
- uint32_t port_no;
+ odp_port_t port_no;
char *name;
};
{
struct dp_netdev_port_state *state = state_;
struct dp_netdev *dp = get_dp_netdev(dpif);
- uint32_t port_no;
+ uint32_t port_idx;
- for (port_no = state->port_no; port_no < MAX_PORTS; port_no++) {
- struct dp_netdev_port *port = dp->ports[port_no];
+ for (port_idx = odp_to_u32(state->port_no);
+ port_idx < MAX_PORTS; port_idx++) {
+ struct dp_netdev_port *port = dp->ports[port_idx];
if (port) {
free(state->name);
state->name = xstrdup(netdev_get_name(port->netdev));
dpif_port->name = state->name;
dpif_port->type = port->type;
dpif_port->port_no = port->port_no;
- state->port_no = port_no + 1;
+ state->port_no = u32_to_odp(port_idx + 1);
return 0;
}
}
return EINVAL;
}
- if (flow->in_port < OFPP_MAX
- ? flow->in_port >= MAX_PORTS
- : flow->in_port != OFPP_LOCAL && flow->in_port != OFPP_NONE) {
+ if (!is_valid_port_number(flow->in_port.odp_port)) {
return EINVAL;
}
struct ofpbuf buf;
ofpbuf_use_stack(&buf, &state->keybuf, sizeof state->keybuf);
- odp_flow_key_from_flow(&buf, &flow->key, flow->key.in_port);
+ odp_flow_key_from_flow(&buf, &flow->key, flow->key.in_port.odp_port);
*key = buf.data;
*key_len = buf.size;
ofpbuf_reserve(©, DP_NETDEV_HEADROOM);
ofpbuf_put(©, execute->packet->data, execute->packet->size);
- flow_extract(©, 0, 0, NULL, -1, &key);
+ flow_extract(©, 0, 0, NULL, NULL, &key);
error = dpif_netdev_flow_from_nlattrs(execute->key, execute->key_len,
&key);
if (!error) {
{
struct dp_netdev_flow *flow;
struct flow key;
+ union flow_in_port in_port_;
if (packet->size < ETH_HEADER_LEN) {
return;
}
- flow_extract(packet, skb_priority, skb_mark, tnl, port->port_no, &key);
+ in_port_.odp_port = port->port_no;
+ flow_extract(packet, skb_priority, skb_mark, tnl, &in_port_, &key);
flow = dp_netdev_lookup_flow(dp, &key);
if (flow) {
dp_netdev_flow_used(flow, packet);
ofpbuf_init(buf, buf_size);
/* Put ODP flow. */
- odp_flow_key_from_flow(buf, flow, flow->in_port);
+ odp_flow_key_from_flow(buf, flow, flow->in_port.odp_port);
upcall->key = buf->data;
upcall->key_len = buf->size;
* port number. Returns EBUSY if caller attempted to choose a port
* number, and it was in use. */
int (*port_add)(struct dpif *dpif, struct netdev *netdev,
- uint32_t *port_no);
+ odp_port_t *port_no);
/* Removes port numbered 'port_no' from 'dpif'. */
- int (*port_del)(struct dpif *dpif, uint32_t port_no);
+ int (*port_del)(struct dpif *dpif, odp_port_t port_no);
/* Queries 'dpif' for a port with the given 'port_no' or 'devname'.
* If 'port' is not null, stores information about the port into
* If 'port' is not null, the caller takes ownership of data in
* 'port' and must free it with dpif_port_destroy() when it is no
* longer needed. */
- int (*port_query_by_number)(const struct dpif *dpif, uint32_t port_no,
+ int (*port_query_by_number)(const struct dpif *dpif, odp_port_t port_no,
struct dpif_port *port);
int (*port_query_by_name)(const struct dpif *dpif, const char *devname,
struct dpif_port *port);
/* Returns one greater than the largest port number accepted in flow
* actions. */
- int (*get_max_ports)(const struct dpif *dpif);
+ odp_port_t (*get_max_ports)(const struct dpif *dpif);
/* Returns the Netlink PID value to supply in OVS_ACTION_ATTR_USERSPACE
* actions as the OVS_USERSPACE_ATTR_PID attribute's value, for use in
*
* A dpif provider that doesn't have meaningful Netlink PIDs can use NULL
* for this function. This is equivalent to always returning 0. */
- uint32_t (*port_get_pid)(const struct dpif *dpif, uint32_t port_no);
+ uint32_t (*port_get_pid)(const struct dpif *dpif, odp_port_t port_no);
/* Attempts to begin dumping the ports in a dpif. On success, returns 0
* and initializes '*statep' with any data needed for iteration. On
}
/* Attempts to add 'netdev' as a port on 'dpif'. If 'port_nop' is
- * non-null and its value is not UINT32_MAX, then attempts to use the
+ * non-null and its value is not ODPP_NONE, then attempts to use the
* value as the port number.
*
* If successful, returns 0 and sets '*port_nop' to the new port's port
* number (if 'port_nop' is non-null). On failure, returns a positive
- * errno value and sets '*port_nop' to UINT32_MAX (if 'port_nop' is
+ * errno value and sets '*port_nop' to ODPP_NONE (if 'port_nop' is
* non-null). */
int
-dpif_port_add(struct dpif *dpif, struct netdev *netdev, uint32_t *port_nop)
+dpif_port_add(struct dpif *dpif, struct netdev *netdev, odp_port_t *port_nop)
{
const char *netdev_name = netdev_get_name(netdev);
- uint32_t port_no = UINT32_MAX;
+ odp_port_t port_no = ODPP_NONE;
int error;
COVERAGE_INC(dpif_port_add);
} else {
VLOG_WARN_RL(&error_rl, "%s: failed to add %s as port: %s",
dpif_name(dpif), netdev_name, strerror(error));
- port_no = UINT32_MAX;
+ port_no = ODPP_NONE;
}
if (port_nop) {
*port_nop = port_no;
/* Attempts to remove 'dpif''s port number 'port_no'. Returns 0 if successful,
* otherwise a positive errno value. */
int
-dpif_port_del(struct dpif *dpif, uint32_t port_no)
+dpif_port_del(struct dpif *dpif, odp_port_t port_no)
{
int error;
* The caller owns the data in 'port' and must free it with
* dpif_port_destroy() when it is no longer needed. */
int
-dpif_port_query_by_number(const struct dpif *dpif, uint32_t port_no,
+dpif_port_query_by_number(const struct dpif *dpif, odp_port_t port_no,
struct dpif_port *port)
{
int error = dpif->dpif_class->port_query_by_number(dpif, port_no, port);
/* Returns one greater than the maximum port number accepted in flow
* actions. */
-int
+odp_port_t
dpif_get_max_ports(const struct dpif *dpif)
{
return dpif->dpif_class->get_max_ports(dpif);
* as the OVS_USERSPACE_ATTR_PID attribute's value, for use in flows whose
* packets arrived on port 'port_no'.
*
- * A 'port_no' of UINT32_MAX is a special case: it returns a reserved PID, not
+ * A 'port_no' of ODPP_NONE is a special case: it returns a reserved PID, not
* allocated to any port, that the client may use for special purposes.
*
* The return value is only meaningful when DPIF_UC_ACTION has been enabled in
* update all of the flows that it installed that contain
* OVS_ACTION_ATTR_USERSPACE actions. */
uint32_t
-dpif_port_get_pid(const struct dpif *dpif, uint32_t port_no)
+dpif_port_get_pid(const struct dpif *dpif, odp_port_t port_no)
{
return (dpif->dpif_class->port_get_pid
? (dpif->dpif_class->port_get_pid)(dpif, port_no)
* result is null-terminated. On failure, returns a positive errno value and
* makes 'name' the empty string. */
int
-dpif_port_get_name(struct dpif *dpif, uint32_t port_no,
+dpif_port_get_name(struct dpif *dpif, odp_port_t port_no,
char *name, size_t name_size)
{
struct dpif_port port;
const char *dpif_port_open_type(const char *datapath_type,
const char *port_type);
-int dpif_port_add(struct dpif *, struct netdev *, uint32_t *port_nop);
-int dpif_port_del(struct dpif *, uint32_t port_no);
+int dpif_port_add(struct dpif *, struct netdev *, odp_port_t *port_nop);
+int dpif_port_del(struct dpif *, odp_port_t port_no);
/* A port within a datapath.
*
struct dpif_port {
char *name; /* Network device name, e.g. "eth0". */
char *type; /* Network device type, e.g. "system". */
- uint32_t port_no; /* Port number within datapath. */
+ odp_port_t port_no; /* Port number within datapath. */
};
void dpif_port_clone(struct dpif_port *, const struct dpif_port *);
void dpif_port_destroy(struct dpif_port *);
bool dpif_port_exists(const struct dpif *dpif, const char *devname);
-int dpif_port_query_by_number(const struct dpif *, uint32_t port_no,
+int dpif_port_query_by_number(const struct dpif *, odp_port_t port_no,
struct dpif_port *);
int dpif_port_query_by_name(const struct dpif *, const char *devname,
struct dpif_port *);
-int dpif_port_get_name(struct dpif *, uint32_t port_no,
+int dpif_port_get_name(struct dpif *, odp_port_t port_no,
char *name, size_t name_size);
-int dpif_get_max_ports(const struct dpif *);
-uint32_t dpif_port_get_pid(const struct dpif *, uint32_t port_no);
+odp_port_t dpif_get_max_ports(const struct dpif *);
+uint32_t dpif_port_get_pid(const struct dpif *, odp_port_t port_no);
struct dpif_port_dump {
const struct dpif *dpif;
/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * 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.
}
/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
- * 'ofp_in_port'.
+ * 'in_port'.
*
* Initializes 'packet' header pointers as follows:
*
*/
void
flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
- const struct flow_tnl *tnl, uint16_t ofp_in_port,
+ const struct flow_tnl *tnl, const union flow_in_port *in_port,
struct flow *flow)
{
struct ofpbuf b = *packet;
ovs_assert(tnl != &flow->tunnel);
flow->tunnel = *tnl;
}
- flow->in_port = ofp_in_port;
+ if (in_port) {
+ flow->in_port = *in_port;
+ }
flow->skb_priority = skb_priority;
flow->skb_mark = skb_mark;
fmd->tun_dst = flow->tunnel.ip_dst;
fmd->metadata = flow->metadata;
memcpy(fmd->regs, flow->regs, sizeof fmd->regs);
- fmd->in_port = flow->in_port;
+ fmd->in_port = flow->in_port.ofp_port;
}
char *
uint8_t ip_ttl;
};
+/* Unfortunately, a "struct flow" sometimes has to handle OpenFlow port
+ * numbers and other times datapath (dpif) port numbers. This union allows
+ * access to both. */
+union flow_in_port {
+ ofp_port_t ofp_port;
+ odp_port_t odp_port;
+};
+
/*
* A flow in the network.
*
ovs_be32 nw_src; /* IPv4 source address. */
ovs_be32 nw_dst; /* IPv4 destination address. */
ovs_be32 ipv6_label; /* IPv6 flow label. */
- uint32_t in_port; /* Input port. OpenFlow port number
- unless in DPIF code, in which case it
- is the datapath port number. */
+ union flow_in_port in_port; /* Input port.*/
uint32_t skb_mark; /* Packet mark. */
ovs_be32 mpls_lse; /* MPLS label stack entry. */
uint16_t mpls_depth; /* Depth of MPLS stack. */
ovs_be32 tun_dst; /* Tunnel outer IPv4 dst addr */
ovs_be64 metadata; /* OpenFlow 1.1+ metadata field. */
uint32_t regs[FLOW_N_REGS]; /* Registers. */
- uint16_t in_port; /* OpenFlow port or zero. */
+ ofp_port_t in_port; /* OpenFlow port or zero. */
};
void flow_extract(struct ofpbuf *, uint32_t priority, uint32_t mark,
- const struct flow_tnl *, uint16_t in_port, struct flow *);
+ const struct flow_tnl *, const union flow_in_port *in_port,
+ struct flow *);
void flow_zero_wildcards(struct flow *, const struct flow_wildcards *);
void flow_get_metadata(const struct flow *, struct flow_metadata *);
return hash_words((const uint32_t *) flow, sizeof *flow / 4, basis);
}
+static inline uint16_t
+ofp_to_u16(ofp_port_t ofp_port)
+{
+ return (OVS_FORCE uint16_t) ofp_port;
+}
+
+static inline uint32_t
+odp_to_u32(odp_port_t odp_port)
+{
+ return (OVS_FORCE uint32_t) odp_port;
+}
+
+static inline uint32_t
+ofp11_to_u32(ofp11_port_t ofp11_port)
+{
+ return (OVS_FORCE uint32_t) ofp11_port;
+}
+
+static inline ofp_port_t
+u16_to_ofp(uint16_t port)
+{
+ return OFP_PORT_C(port);
+}
+
+static inline odp_port_t
+u32_to_odp(uint32_t port)
+{
+ return ODP_PORT_C(port);
+}
+
+static inline ofp11_port_t
+u32_to_ofp11(uint32_t port)
+{
+ return OFP11_PORT_C(port);
+}
+
uint32_t flow_hash_in_minimask(const struct flow *, const struct minimask *,
uint32_t basis);
\f
case NX_LEARN_DST_OUTPUT:
if (spec->n_bits <= 16
|| is_all_zeros(value.u8, sizeof value - 2)) {
- uint16_t port = ntohs(value.be16[7]);
+ ofp_port_t port = u16_to_ofp(ntohs(value.be16[7]));
- if (port < OFPP_MAX
+ if (ofp_to_u16(port) < ofp_to_u16(OFPP_MAX)
|| port == OFPP_IN_PORT
|| port == OFPP_FLOOD
|| port == OFPP_LOCAL
/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * 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.
struct lswitch_port {
struct hmap_node hmap_node; /* Hash node for port number. */
- uint16_t port_no; /* OpenFlow port number, in host byte order. */
+ ofp_port_t port_no; /* OpenFlow port number. */
uint32_t queue_id; /* OpenFlow queue number. */
};
if (lp && hmap_node_is_null(&lp->hmap_node)) {
lp->port_no = port.port_no;
hmap_insert(&sw->queue_numbers, &lp->hmap_node,
- hash_int(lp->port_no, 0));
+ hash_int(ofp_to_u16(lp->port_no), 0));
}
}
return 0;
}
-static uint16_t
+static ofp_port_t
lswitch_choose_destination(struct lswitch *sw, const struct flow *flow)
{
- uint16_t out_port;
+ ofp_port_t out_port;
/* Learn the source MAC. */
if (mac_learning_may_learn(sw->ml, flow->dl_src, 0)) {
struct mac_entry *mac = mac_learning_insert(sw->ml, flow->dl_src, 0);
- if (mac_entry_is_new(mac) || mac->port.ofp_port != flow->in_port) {
+ if (mac_entry_is_new(mac)
+ || mac->port.ofp_port != flow->in_port.ofp_port) {
VLOG_DBG_RL(&rl, "%016llx: learned that "ETH_ADDR_FMT" is on "
"port %"PRIu16, sw->datapath_id,
- ETH_ADDR_ARGS(flow->dl_src), flow->in_port);
+ ETH_ADDR_ARGS(flow->dl_src), flow->in_port.ofp_port);
- mac->port.ofp_port = flow->in_port;
+ mac->port.ofp_port = flow->in_port.ofp_port;
mac_learning_changed(sw->ml, mac);
}
}
mac = mac_learning_lookup(sw->ml, flow->dl_dst, 0, NULL);
if (mac) {
out_port = mac->port.ofp_port;
- if (out_port == flow->in_port) {
+ if (out_port == flow->in_port.ofp_port) {
/* Don't send a packet back out its input port. */
return OFPP_NONE;
}
}
static uint32_t
-get_queue_id(const struct lswitch *sw, uint16_t in_port)
+get_queue_id(const struct lswitch *sw, ofp_port_t in_port)
{
const struct lswitch_port *port;
- HMAP_FOR_EACH_WITH_HASH (port, hmap_node, hash_int(in_port, 0),
+ HMAP_FOR_EACH_WITH_HASH (port, hmap_node, hash_int(ofp_to_u16(in_port), 0),
&sw->queue_numbers) {
if (port->port_no == in_port) {
return port->queue_id;
{
struct ofputil_packet_in pi;
uint32_t queue_id;
- uint16_t out_port;
+ ofp_port_t out_port;
uint64_t ofpacts_stub[64 / 8];
struct ofpbuf ofpacts;
struct ofpbuf pkt;
struct flow flow;
+ union flow_in_port in_port_;
error = ofputil_decode_packet_in(&pi, oh);
if (error) {
/* Extract flow data from 'opi' into 'flow'. */
ofpbuf_use_const(&pkt, pi.packet, pi.packet_len);
- flow_extract(&pkt, 0, 0, NULL, pi.fmd.in_port, &flow);
+ in_port_.ofp_port = pi.fmd.in_port;
+ flow_extract(&pkt, 0, 0, NULL, &in_port_, &flow);
flow.tunnel.tun_id = pi.fmd.tun_id;
/* Choose output port. */
ofpbuf_use_stack(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
if (out_port == OFPP_NONE) {
/* No actions. */
- } else if (queue_id == UINT32_MAX || out_port >= OFPP_MAX) {
+ } else if (queue_id == UINT32_MAX
+ || ofp_to_u16(out_port) >= ofp_to_u16(OFPP_MAX)) {
ofpact_put_OUTPUT(&ofpacts)->port = out_port;
} else {
struct ofpact_enqueue *enqueue = ofpact_put_ENQUEUE(&ofpacts);
/* Learned port. */
union {
void *p;
- uint16_t ofp_port;
+ ofp_port_t ofp_port;
} port;
};
}
void
-match_set_in_port(struct match *match, uint16_t ofp_port)
+match_set_in_port(struct match *match, ofp_port_t ofp_port)
{
- match->wc.masks.in_port = UINT16_MAX;
- match->flow.in_port = ofp_port;
+ match->wc.masks.in_port.ofp_port = u16_to_ofp(UINT16_MAX);
+ match->flow.in_port.ofp_port = ofp_port;
}
void
ntohll(f->metadata), ntohll(wc->masks.metadata));
break;
}
- if (wc->masks.in_port) {
+ if (wc->masks.in_port.ofp_port) {
ds_put_cstr(s, "in_port=");
- ofputil_format_port(f->in_port, s);
+ ofputil_format_port(f->in_port.ofp_port, s);
ds_put_char(s, ',');
}
if (wc->masks.vlan_tci) {
void match_set_tun_tos_masked(struct match *match, uint8_t tos, uint8_t mask);
void match_set_tun_flags(struct match *match, uint16_t flags);
void match_set_tun_flags_masked(struct match *match, uint16_t flags, uint16_t mask);
-void match_set_in_port(struct match *, uint16_t ofp_port);
+void match_set_in_port(struct match *, ofp_port_t ofp_port);
void match_set_skb_mark(struct match *, uint32_t skb_mark);
void match_set_skb_priority(struct match *, uint32_t skb_priority);
void match_set_dl_type(struct match *, ovs_be16);
return !wc->masks.metadata;
case MFF_IN_PORT:
case MFF_IN_PORT_OXM:
- return !wc->masks.in_port;
+ return !wc->masks.in_port.ofp_port;
case MFF_SKB_PRIORITY:
return !wc->masks.skb_priority;
case MFF_SKB_MARK:
return true;
case MFF_IN_PORT_OXM: {
- uint16_t port;
+ ofp_port_t port;
return !ofputil_port_from_ofp11(value->be32, &port);
}
break;
case MFF_IN_PORT:
- value->be16 = htons(flow->in_port);
+ value->be16 = htons(ofp_to_u16(flow->in_port.ofp_port));
break;
-
case MFF_IN_PORT_OXM:
- value->be32 = ofputil_port_to_ofp11(flow->in_port);
+ value->be32 = ofputil_port_to_ofp11(flow->in_port.ofp_port);
break;
case MFF_SKB_PRIORITY:
break;
case MFF_IN_PORT:
- match_set_in_port(match, ntohs(value->be16));
+ match_set_in_port(match, u16_to_ofp(ntohs(value->be16)));
break;
case MFF_IN_PORT_OXM: {
- uint16_t port;
+ ofp_port_t port;
ofputil_port_from_ofp11(value->be32, &port);
match_set_in_port(match, port);
break;
break;
case MFF_IN_PORT:
- flow->in_port = ntohs(value->be16);
+ flow->in_port.ofp_port = u16_to_ofp(ntohs(value->be16));
break;
case MFF_IN_PORT_OXM: {
- uint16_t port;
+ ofp_port_t port;
ofputil_port_from_ofp11(value->be32, &port);
- flow->in_port = port;
+ flow->in_port.ofp_port = port;
break;
}
case MFF_IN_PORT:
case MFF_IN_PORT_OXM:
- match->flow.in_port = 0;
- match->wc.masks.in_port = 0;
+ match->flow.in_port.ofp_port = 0;
+ match->wc.masks.in_port.ofp_port = 0;
break;
case MFF_SKB_PRIORITY:
break;
case MFF_IN_PORT_OXM:
- value->be32 = ofputil_port_to_ofp11(ntohs(value->be16));
+ value->be32 = ofputil_port_to_ofp11(u16_to_ofp(ntohs(value->be16)));
break;
case MFF_IPV6_LABEL:
mf_from_ofp_port_string(const struct mf_field *mf, const char *s,
ovs_be16 *valuep, ovs_be16 *maskp)
{
- uint16_t port;
+ ofp_port_t port;
ovs_assert(mf->n_bytes == sizeof(ovs_be16));
if (ofputil_port_from_string(s, &port)) {
- *valuep = htons(port);
+ *valuep = htons(ofp_to_u16(port));
*maskp = htons(UINT16_MAX);
return NULL;
}
mf_from_ofp_port_string32(const struct mf_field *mf, const char *s,
ovs_be32 *valuep, ovs_be32 *maskp)
{
- uint16_t port;
+ ofp_port_t port;
ovs_assert(mf->n_bytes == sizeof(ovs_be32));
if (ofputil_port_from_string(s, &port)) {
switch (mf->string) {
case MFS_OFP_PORT_OXM:
if (!mask) {
- uint16_t port;
+ ofp_port_t port;
ofputil_port_from_ofp11(value->be32, &port);
ofputil_format_port(port, s);
break;
/* fall through */
case MFS_OFP_PORT:
if (!mask) {
- ofputil_format_port(ntohs(value->be16), s);
+ ofputil_format_port(u16_to_ofp(ntohs(value->be16)), s);
break;
}
/* fall through */
/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * 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.
#include <sys/types.h>
#include <unistd.h>
#include "coverage.h"
+#include "flow.h"
#include "netlink-protocol.h"
#include "ofpbuf.h"
#include "timeval.h"
nl_msg_put_unspec(msg, type, &value, sizeof value);
}
+/* Appends a Netlink attribute of the given 'type' and the given odp_port_t
+ * 'value' to 'msg'. */
+void
+nl_msg_put_odp_port(struct ofpbuf *msg, uint16_t type, odp_port_t value)
+{
+ nl_msg_put_u32(msg, type, odp_to_u32(value));
+}
+
+
/* Appends a Netlink attribute of the given 'type' and the given
* null-terminated string 'value' to 'msg'. */
void
return get_32aligned_be64(x);
}
+/* Returns the 32-bit odp_port_t value in 'nla''s payload.
+ *
+ * Asserts that 'nla''s payload is at least 4 bytes long. */
+odp_port_t
+nl_attr_get_odp_port(const struct nlattr *nla)
+{
+ return u32_to_odp(nl_attr_get_u32(nla));
+}
+
/* Returns the null-terminated string value in 'nla''s payload.
*
* Asserts that 'nla''s payload contains a null-terminated string. */
void nl_msg_put_be16(struct ofpbuf *, uint16_t type, ovs_be16 value);
void nl_msg_put_be32(struct ofpbuf *, uint16_t type, ovs_be32 value);
void nl_msg_put_be64(struct ofpbuf *, uint16_t type, ovs_be64 value);
+void nl_msg_put_odp_port(struct ofpbuf *, uint16_t type, odp_port_t value);
void nl_msg_put_string(struct ofpbuf *, uint16_t type, const char *value);
size_t nl_msg_start_nested(struct ofpbuf *, uint16_t type);
ovs_be16 nl_attr_get_be16(const struct nlattr *);
ovs_be32 nl_attr_get_be32(const struct nlattr *);
ovs_be64 nl_attr_get_be64(const struct nlattr *);
+odp_port_t nl_attr_get_odp_port(const struct nlattr *);
const char *nl_attr_get_string(const struct nlattr *);
void nl_attr_get_nested(const struct nlattr *, struct ofpbuf *);
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 20);
/* Metadata. */
- if (match->wc.masks.in_port) {
- uint16_t in_port = flow->in_port;
+ if (match->wc.masks.in_port.ofp_port) {
+ ofp_port_t in_port = flow->in_port.ofp_port;
if (oxm) {
nxm_put_32(b, OXM_OF_IN_PORT, ofputil_port_to_ofp11(in_port));
} else {
- nxm_put_16(b, NXM_OF_IN_PORT, htons(in_port));
+ nxm_put_16(b, NXM_OF_IN_PORT, htons(ofp_to_u16(in_port)));
}
}
/* Appends a representation of 'flow' as OVS_KEY_ATTR_* attributes to 'buf'.
* 'flow->in_port' is ignored (since it is likely to be an OpenFlow port
* number rather than a datapath port number). Instead, if 'odp_in_port'
- * is anything other than OVSP_NONE, it is included in 'buf' as the input
+ * is anything other than ODPP_NONE, it is included in 'buf' as the input
* port.
*
* 'buf' must have at least ODPUTIL_FLOW_KEY_BYTES bytes of space, or be
* capable of being expanded to allow for that much space. */
void
odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
- uint32_t odp_in_port)
+ odp_port_t odp_in_port)
{
struct ovs_key_ethernet *eth_key;
size_t encap;
nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, flow->skb_mark);
}
- if (odp_in_port != OVSP_NONE) {
- nl_msg_put_u32(buf, OVS_KEY_ATTR_IN_PORT, odp_in_port);
+ if (odp_in_port != ODPP_NONE) {
+ nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, odp_in_port);
}
eth_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ETHERNET,
}
if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IN_PORT)) {
- flow->in_port = nl_attr_get_u32(attrs[OVS_KEY_ATTR_IN_PORT]);
+ flow->in_port.odp_port
+ = nl_attr_get_odp_port(attrs[OVS_KEY_ATTR_IN_PORT]);
expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IN_PORT;
} else {
- flow->in_port = OVSP_NONE;
+ flow->in_port.odp_port = ODPP_NONE;
}
/* Ethernet header. */
struct ofpbuf;
struct simap;
-#define OVSP_NONE UINT32_MAX
+#define ODPP_LOCAL ODP_PORT_C(OVSP_LOCAL)
+#define ODPP_NONE ODP_PORT_C(UINT32_MAX)
void format_odp_actions(struct ds *, const struct nlattr *odp_actions,
size_t actions_len);
struct ofpbuf *, struct ofpbuf *);
void odp_flow_key_from_flow(struct ofpbuf *, const struct flow *,
- uint32_t odp_in_port);
+ odp_port_t odp_in_port);
uint32_t odp_flow_key_hash(const struct nlattr *, size_t);
struct ofpact_output *output;
output = ofpact_put_OUTPUT(out);
- output->port = ntohs(oao->port);
+ output->port = u16_to_ofp(ntohs(oao->port));
output->max_len = ntohs(oao->max_len);
return ofputil_check_output_port(output->port, OFPP_MAX);
struct ofpact_enqueue *enqueue;
enqueue = ofpact_put_ENQUEUE(out);
- enqueue->port = ntohs(oae->port);
+ enqueue->port = u16_to_ofp(ntohs(oae->port));
enqueue->queue = ntohl(oae->queue_id);
- if (enqueue->port >= OFPP_MAX && enqueue->port != OFPP_IN_PORT
+ if (ofp_to_u16(enqueue->port) >= ofp_to_u16(OFPP_MAX)
+ && enqueue->port != OFPP_IN_PORT
&& enqueue->port != OFPP_LOCAL) {
return OFPERR_OFPBAC_BAD_OUT_PORT;
}
resubmit = ofpact_put_RESUBMIT(out);
resubmit->ofpact.compat = OFPUTIL_NXAST_RESUBMIT;
- resubmit->in_port = ntohs(nar->in_port);
+ resubmit->in_port = u16_to_ofp(ntohs(nar->in_port));
resubmit->table_id = 0xff;
}
resubmit = ofpact_put_RESUBMIT(out);
resubmit->ofpact.compat = OFPUTIL_NXAST_RESUBMIT_TABLE;
- resubmit->in_port = ntohs(nar->in_port);
+ resubmit->in_port = u16_to_ofp(ntohs(nar->in_port));
resubmit->table_id = nar->table;
return 0;
}
}
\f
static enum ofperr
-ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports,
- ovs_be16 *dl_type)
+ofpact_check__(const struct ofpact *a, const struct flow *flow,
+ ofp_port_t max_ports, ovs_be16 *dl_type)
{
const struct ofpact_enqueue *enqueue;
case OFPACT_ENQUEUE:
enqueue = ofpact_get_ENQUEUE(a);
- if (enqueue->port >= max_ports && enqueue->port != OFPP_IN_PORT
+ if (ofp_to_u16(enqueue->port) >= ofp_to_u16(max_ports)
+ && enqueue->port != OFPP_IN_PORT
&& enqueue->port != OFPP_LOCAL) {
return OFPERR_OFPBAC_BAD_OUT_PORT;
}
* switch with no more than 'max_ports' ports. */
enum ofperr
ofpacts_check(const struct ofpact ofpacts[], size_t ofpacts_len,
- const struct flow *flow, int max_ports)
+ const struct flow *flow, ofp_port_t max_ports)
{
const struct ofpact *a;
ovs_be16 dl_type = flow->dl_type;
nar = ofputil_put_NXAST_RESUBMIT_TABLE(out);
nar->table = resubmit->table_id;
}
- nar->in_port = htons(resubmit->in_port);
+ nar->in_port = htons(ofp_to_u16(resubmit->in_port));
}
static void
struct ofp10_action_output *oao;
oao = ofputil_put_OFPAT10_OUTPUT(out);
- oao->port = htons(output->port);
+ oao->port = htons(ofp_to_u16(output->port));
oao->max_len = htons(output->max_len);
}
struct ofp10_action_enqueue *oae;
oae = ofputil_put_OFPAT10_ENQUEUE(out);
- oae->port = htons(enqueue->port);
+ oae->port = htons(ofp_to_u16(enqueue->port));
oae->queue_id = htonl(enqueue->queue);
}
\f
/* Returns true if 'action' outputs to 'port', false otherwise. */
static bool
-ofpact_outputs_to_port(const struct ofpact *ofpact, uint16_t port)
+ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
{
switch (ofpact->type) {
case OFPACT_OUTPUT:
* to 'port', false otherwise. */
bool
ofpacts_output_to_port(const struct ofpact *ofpacts, size_t ofpacts_len,
- uint16_t port)
+ ofp_port_t port)
{
const struct ofpact *a;
const struct ofpact_metadata *metadata;
const struct ofpact_tunnel *tunnel;
const struct ofpact_sample *sample;
- uint16_t port;
+ ofp_port_t port;
switch (a->type) {
case OFPACT_OUTPUT:
port = ofpact_get_OUTPUT(a)->port;
- if (port < OFPP_MAX) {
+ if (ofp_to_u16(port) < ofp_to_u16(OFPP_MAX)) {
ds_put_format(s, "output:%"PRIu16, port);
} else {
ofputil_format_port(port, s);
* Used for OFPAT10_OUTPUT. */
struct ofpact_output {
struct ofpact ofpact;
- uint16_t port; /* Output port. */
+ ofp_port_t port; /* Output port. */
uint16_t max_len; /* Max send len, for port OFPP_CONTROLLER. */
};
* Used for OFPAT10_ENQUEUE. */
struct ofpact_enqueue {
struct ofpact ofpact;
- uint16_t port;
+ ofp_port_t port;
uint32_t queue;
};
/* Slaves for output. */
unsigned int n_slaves;
- uint16_t slaves[];
+ ofp_port_t slaves[];
};
/* OFPACT_SET_VLAN_VID.
* Used for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE. */
struct ofpact_resubmit {
struct ofpact ofpact;
- uint16_t in_port;
+ ofp_port_t in_port;
uint8_t table_id;
};
uint8_t table_id,
struct ofpbuf *ofpacts);
enum ofperr ofpacts_check(const struct ofpact[], size_t ofpacts_len,
- const struct flow *, int max_ports);
+ const struct flow *, ofp_port_t max_ports);
enum ofperr ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len);
/* Converting ofpacts to OpenFlow. */
/* Working with ofpacts. */
bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len,
- uint16_t port);
+ ofp_port_t port);
bool ofpacts_equal(const struct ofpact a[], size_t a_len,
const struct ofpact b[], size_t b_len);
}
enqueue = ofpact_put_ENQUEUE(ofpacts);
- enqueue->port = str_to_u32(port);
+ enqueue->port = u16_to_ofp(str_to_u32(port));
enqueue->queue = str_to_u32(queue);
}
struct ofpact_output *output;
output = ofpact_put_OUTPUT(ofpacts);
- output->port = str_to_u32(arg);
+ output->port = u16_to_ofp(str_to_u32(arg));
output->max_len = output->port == OFPP_CONTROLLER ? UINT16_MAX : 0;
}
}
}
return false;
} else {
- uint16_t port;
+ ofp_port_t port;
if (ofputil_port_from_string(act, &port)) {
ofpact_put_OUTPUT(ofpacts)->port = port;
} else {
if (!strcmp(name, "table")) {
fmr->table_id = str_to_table_id(value);
} else if (!strcmp(name, "out_port")) {
- fmr->out_port = atoi(value);
+ fmr->out_port = u16_to_ofp(atoi(value));
} else if (mf_from_name(name)) {
parse_field(mf_from_name(name), value, &fmr->match);
} else {
}
}
- if (!flow->in_port) {
- flow->in_port = OFPP_NONE;
+ if (!flow->in_port.ofp_port) {
+ flow->in_port.ofp_port = OFPP_NONE;
}
exit:
struct flow flow;
ofpbuf_use_const(&buf, data, len);
- flow_extract(&buf, 0, 0, NULL, 0, &flow);
+ flow_extract(&buf, 0, 0, NULL, NULL, &flow);
flow_format(&ds, &flow);
if (buf.l7) {
{
const struct ofputil_phy_port *a = a_;
const struct ofputil_phy_port *b = b_;
- uint16_t ap = a->port_no;
- uint16_t bp = b->port_no;
+ uint16_t ap = ofp_to_u16(a->port_no);
+ uint16_t bp = ofp_to_u16(b->port_no);
return ap < bp ? -1 : ap > bp;
}
static void
print_wild_port(struct ds *string, const char *leader, int is_wild,
- int verbosity, uint16_t port)
+ int verbosity, ofp_port_t port)
{
if (is_wild && verbosity < 2) {
return;
}
}
print_wild_port(&f, "in_port=", w & OFPFW10_IN_PORT, verbosity,
- ntohs(om->in_port));
+ u16_to_ofp(ntohs(om->in_port)));
print_wild(&f, "dl_vlan=", w & OFPFW10_DL_VLAN, verbosity,
"%d", ntohs(om->dl_vlan));
print_wild(&f, "dl_vlan_pcp=", w & OFPFW10_DL_VLAN_PCP, verbosity,
static void
ofp_print_ofpst_port_request(struct ds *string, const struct ofp_header *oh)
{
- uint16_t ofp10_port;
+ ofp_port_t ofp10_port;
enum ofperr error;
error = ofputil_decode_port_stats_request(oh, &ofp10_port);
}
ds_put_cstr(string, " port ");
- if (ps.port_no < 10) {
+ if (ofp_to_u16(ps.port_no) < 10) {
ds_put_char(string, ' ');
}
ofputil_format_port(ps.port_no, string);
flow_wildcards_init_catchall(wc);
if (!(ofpfw & OFPFW10_IN_PORT)) {
- wc->masks.in_port = UINT16_MAX;
+ wc->masks.in_port.ofp_port = u16_to_ofp(UINT16_MAX);
}
if (!(ofpfw & OFPFW10_NW_TOS)) {
/* Initialize most of match->flow. */
match->flow.nw_src = ofmatch->nw_src;
match->flow.nw_dst = ofmatch->nw_dst;
- match->flow.in_port = ntohs(ofmatch->in_port);
+ match->flow.in_port.ofp_port = u16_to_ofp(ntohs(ofmatch->in_port));
match->flow.dl_type = ofputil_dl_type_from_openflow(ofmatch->dl_type);
match->flow.tp_src = ofmatch->tp_src;
match->flow.tp_dst = ofmatch->tp_dst;
/* Figure out most OpenFlow wildcards. */
ofpfw = 0;
- if (!wc->masks.in_port) {
+ if (!wc->masks.in_port.ofp_port) {
ofpfw |= OFPFW10_IN_PORT;
}
if (!wc->masks.dl_type) {
/* Compose most of the match structure. */
ofmatch->wildcards = htonl(ofpfw);
- ofmatch->in_port = htons(match->flow.in_port);
+ ofmatch->in_port = htons(ofp_to_u16(match->flow.in_port.ofp_port));
memcpy(ofmatch->dl_src, match->flow.dl_src, ETH_ADDR_LEN);
memcpy(ofmatch->dl_dst, match->flow.dl_dst, ETH_ADDR_LEN);
ofmatch->dl_type = ofputil_dl_type_to_openflow(match->flow.dl_type);
match_init_catchall(match);
if (!(wc & OFPFW11_IN_PORT)) {
- uint16_t ofp_port;
+ ofp_port_t ofp_port;
enum ofperr error;
error = ofputil_port_from_ofp11(ofmatch->in_port, &ofp_port);
ofmatch->omh.type = htons(OFPMT_STANDARD);
ofmatch->omh.length = htons(OFPMT11_STANDARD_LENGTH);
- if (!match->wc.masks.in_port) {
+ if (!match->wc.masks.in_port.ofp_port) {
wc |= OFPFW11_IN_PORT;
} else {
- ofmatch->in_port = ofputil_port_to_ofp11(match->flow.in_port);
+ ofmatch->in_port = ofputil_port_to_ofp11(match->flow.in_port.ofp_port);
}
memcpy(ofmatch->dl_src, match->flow.dl_src, ETH_ADDR_LEN);
fm->idle_timeout = ntohs(ofm->idle_timeout);
fm->hard_timeout = ntohs(ofm->hard_timeout);
fm->buffer_id = ntohl(ofm->buffer_id);
- fm->out_port = ntohs(ofm->out_port);
+ fm->out_port = u16_to_ofp(ntohs(ofm->out_port));
fm->flags = ntohs(ofm->flags);
} else if (raw == OFPRAW_NXT_FLOW_MOD) {
/* Nicira extended flow_mod. */
fm->idle_timeout = ntohs(nfm->idle_timeout);
fm->hard_timeout = ntohs(nfm->hard_timeout);
fm->buffer_id = ntohl(nfm->buffer_id);
- fm->out_port = ntohs(nfm->out_port);
+ fm->out_port = u16_to_ofp(ntohs(nfm->out_port));
fm->flags = ntohs(nfm->flags);
} else {
NOT_REACHED();
case OFPUTIL_P_OF13_OXM: {
struct ofp11_flow_mod *ofm;
- msg = ofpraw_alloc(OFPRAW_OFPT11_FLOW_MOD,
+ msg = ofpraw_alloc(OFPRAW_OFPT11_FLOW_MOD,
ofputil_protocol_to_ofp_version(protocol),
NXM_TYPICAL_LEN + fm->ofpacts_len);
ofm = ofpbuf_put_zeros(msg, sizeof *ofm);
ofm->hard_timeout = htons(fm->hard_timeout);
ofm->priority = htons(fm->priority);
ofm->buffer_id = htonl(fm->buffer_id);
- ofm->out_port = htons(fm->out_port);
+ ofm->out_port = htons(ofp_to_u16(fm->out_port));
ofm->flags = htons(fm->flags);
ofpacts_put_openflow10(fm->ofpacts, fm->ofpacts_len, msg);
break;
nfm->hard_timeout = htons(fm->hard_timeout);
nfm->priority = htons(fm->priority);
nfm->buffer_id = htonl(fm->buffer_id);
- nfm->out_port = htons(fm->out_port);
+ nfm->out_port = htons(ofp_to_u16(fm->out_port));
nfm->flags = htons(fm->flags);
nfm->match_len = htons(match_len);
ofpacts_put_openflow10(fm->ofpacts, fm->ofpacts_len, msg);
{
fsr->aggregate = aggregate;
ofputil_match_from_ofp10_match(&ofsr->match, &fsr->match);
- fsr->out_port = ntohs(ofsr->out_port);
+ fsr->out_port = u16_to_ofp(ntohs(ofsr->out_port));
fsr->table_id = ofsr->table_id;
fsr->cookie = fsr->cookie_mask = htonll(0);
}
fsr->aggregate = aggregate;
- fsr->out_port = ntohs(nfsr->out_port);
+ fsr->out_port = u16_to_ofp(ntohs(nfsr->out_port));
fsr->table_id = nfsr->table_id;
return 0;
ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr);
ofputil_match_to_ofp10_match(&fsr->match, &ofsr->match);
ofsr->table_id = fsr->table_id;
- ofsr->out_port = htons(fsr->out_port);
+ ofsr->out_port = htons(ofp_to_u16(fsr->out_port));
break;
}
fsr->cookie, fsr->cookie_mask);
nfsr = msg->l3;
- nfsr->out_port = htons(fsr->out_port);
+ nfsr->out_port = htons(ofp_to_u16(fsr->out_port));
nfsr->match_len = htons(match_len);
nfsr->table_id = fsr->table_id;
break;
pin->packet = b->data;
pin->packet_len = b->size;
- pin->fmd.in_port = match->flow.in_port;
+ pin->fmd.in_port = match->flow.in_port.ofp_port;
pin->fmd.tun_id = match->flow.tunnel.tun_id;
pin->fmd.tun_src = match->flow.tunnel.ip_src;
pin->fmd.tun_dst = match->flow.tunnel.ip_dst;
pin->packet = opi->data;
pin->packet_len = b.size;
- pin->fmd.in_port = ntohs(opi->in_port);
+ pin->fmd.in_port = u16_to_ofp(ntohs(opi->in_port));
pin->reason = opi->reason;
pin->buffer_id = ntohl(opi->buffer_id);
pin->total_len = ntohs(opi->total_len);
htonl(0), send_len);
opi = ofpbuf_put_zeros(packet, offsetof(struct ofp10_packet_in, data));
opi->total_len = htons(pin->total_len);
- opi->in_port = htons(pin->fmd.in_port);
+ opi->in_port = htons(ofp_to_u16(pin->fmd.in_port));
opi->reason = pin->reason;
opi->buffer_id = htonl(pin->buffer_id);
const struct ofp10_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
po->buffer_id = ntohl(opo->buffer_id);
- po->in_port = ntohs(opo->in_port);
+ po->in_port = u16_to_ofp(ntohs(opo->in_port));
error = ofpacts_pull_openflow10(&b, ntohs(opo->actions_len), ofpacts);
if (error) {
NOT_REACHED();
}
- if (po->in_port >= OFPP_MAX && po->in_port != OFPP_LOCAL
+ if (ofp_to_u16(po->in_port) >= ofp_to_u16(OFPP_MAX)
+ && po->in_port != OFPP_LOCAL
&& po->in_port != OFPP_NONE && po->in_port != OFPP_CONTROLLER) {
VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out has bad input port %#"PRIx16,
po->in_port);
{
memset(pp, 0, sizeof *pp);
- pp->port_no = ntohs(opp->port_no);
+ pp->port_no = u16_to_ofp(ntohs(opp->port_no));
memcpy(pp->hw_addr, opp->hw_addr, OFP_ETH_ALEN);
ovs_strlcpy(pp->name, opp->name, OFP_MAX_PORT_NAME_LEN);
{
memset(opp, 0, sizeof *opp);
- opp->port_no = htons(pp->port_no);
+ opp->port_no = htons(ofp_to_u16(pp->port_no));
memcpy(opp->hw_addr, pp->hw_addr, ETH_ADDR_LEN);
ovs_strlcpy(opp->name, pp->name, OFP_MAX_PORT_NAME_LEN);
if (raw == OFPRAW_OFPT10_PORT_MOD) {
const struct ofp10_port_mod *opm = b.data;
- pm->port_no = ntohs(opm->port_no);
+ pm->port_no = u16_to_ofp(ntohs(opm->port_no));
memcpy(pm->hw_addr, opm->hw_addr, ETH_ADDR_LEN);
pm->config = ntohl(opm->config) & OFPPC10_ALL;
pm->mask = ntohl(opm->mask) & OFPPC10_ALL;
b = ofpraw_alloc(OFPRAW_OFPT10_PORT_MOD, ofp_version, 0);
opm = ofpbuf_put_zeros(b, sizeof *opm);
- opm->port_no = htons(pm->port_no);
+ opm->port_no = htons(ofp_to_u16(pm->port_no));
memcpy(opm->hw_addr, pm->hw_addr, ETH_ADDR_LEN);
opm->config = htonl(pm->config & OFPPC10_ALL);
opm->mask = htonl(pm->mask & OFPPC10_ALL);
rq->id = ntohl(nfmr->id);
rq->flags = flags;
- rq->out_port = ntohs(nfmr->out_port);
+ rq->out_port = u16_to_ofp(ntohs(nfmr->out_port));
rq->table_id = nfmr->table_id;
return nx_pull_match(msg, ntohs(nfmr->match_len), &rq->match, NULL, NULL);
nfmr = ofpbuf_at_assert(msg, start_ofs, sizeof *nfmr);
nfmr->id = htonl(rq->id);
nfmr->flags = htons(rq->flags);
- nfmr->out_port = htons(rq->out_port);
+ nfmr->out_port = htons(ofp_to_u16(rq->out_port));
nfmr->match_len = htons(match_len);
nfmr->table_id = rq->table_id;
}
opo = msg->l3;
opo->buffer_id = htonl(po->buffer_id);
- opo->in_port = htons(po->in_port);
+ opo->in_port = htons(ofp_to_u16(po->in_port));
opo->actions_len = htons(msg->size - actions_ofs);
break;
}
*
* See the definition of OFP11_MAX for an explanation of the mapping. */
enum ofperr
-ofputil_port_from_ofp11(ovs_be32 ofp11_port, uint16_t *ofp10_port)
+ofputil_port_from_ofp11(ovs_be32 ofp11_port, ofp_port_t *ofp10_port)
{
uint32_t ofp11_port_h = ntohl(ofp11_port);
- if (ofp11_port_h < OFPP_MAX) {
- *ofp10_port = ofp11_port_h;
+ if (ofp11_port_h < ofp_to_u16(OFPP_MAX)) {
+ *ofp10_port = u16_to_ofp(ofp11_port_h);
return 0;
- } else if (ofp11_port_h >= OFPP11_MAX) {
- *ofp10_port = ofp11_port_h - OFPP11_OFFSET;
+ } else if (ofp11_port_h >= ofp11_to_u32(OFPP11_MAX)) {
+ *ofp10_port = u16_to_ofp(ofp11_port_h - OFPP11_OFFSET);
return 0;
} else {
*ofp10_port = OFPP_NONE;
VLOG_WARN_RL(&bad_ofmsg_rl, "port %"PRIu32" is outside the supported "
"range 0 through %d or 0x%"PRIx32" through 0x%"PRIx32,
- ofp11_port_h, OFPP_MAX - 1,
- (uint32_t) OFPP11_MAX, UINT32_MAX);
+ ofp11_port_h, ofp_to_u16(OFPP_MAX) - 1,
+ ofp11_to_u32(OFPP11_MAX), UINT32_MAX);
return OFPERR_OFPBAC_BAD_OUT_PORT;
}
}
*
* See the definition of OFP11_MAX for an explanation of the mapping. */
ovs_be32
-ofputil_port_to_ofp11(uint16_t ofp10_port)
+ofputil_port_to_ofp11(ofp_port_t ofp10_port)
{
- return htonl(ofp10_port < OFPP_MAX
- ? ofp10_port
- : ofp10_port + OFPP11_OFFSET);
+ return htonl(ofp_to_u16(ofp10_port) < ofp_to_u16(OFPP_MAX)
+ ? ofp_to_u16(ofp10_port)
+ : ofp_to_u16(ofp10_port) + OFPP11_OFFSET);
}
/* Checks that 'port' is a valid output port for the OFPAT10_OUTPUT action, given
* that the switch will never have more than 'max_ports' ports. Returns 0 if
* 'port' is valid, otherwise an OpenFlow return code. */
enum ofperr
-ofputil_check_output_port(uint16_t port, int max_ports)
+ofputil_check_output_port(ofp_port_t port, ofp_port_t max_ports)
{
switch (port) {
case OFPP_IN_PORT:
return 0;
default:
- if (port < max_ports) {
+ if (ofp_to_u16(port) < ofp_to_u16(max_ports)) {
return 0;
}
return OFPERR_OFPBAC_BAD_OUT_PORT;
* of OpenFlow 1.1+ port numbers, mapping those port numbers into the 16-bit
* range as described in include/openflow/openflow-1.1.h. */
bool
-ofputil_port_from_string(const char *s, uint16_t *portp)
+ofputil_port_from_string(const char *s, ofp_port_t *portp)
{
- unsigned int port32;
+ uint32_t port32;
*portp = 0;
if (str_to_uint(s, 10, &port32)) {
- if (port32 < OFPP_MAX) {
- *portp = port32;
- return true;
- } else if (port32 < OFPP_FIRST_RESV) {
+ if (port32 < ofp_to_u16(OFPP_MAX)) {
+ /* Pass. */
+ } else if (port32 < ofp_to_u16(OFPP_FIRST_RESV)) {
VLOG_WARN("port %u is a reserved OF1.0 port number that will "
"be translated to %u when talking to an OF1.1 or "
"later controller", port32, port32 + OFPP11_OFFSET);
- *portp = port32;
- return true;
- } else if (port32 <= OFPP_LAST_RESV) {
+ } else if (port32 <= ofp_to_u16(OFPP_LAST_RESV)) {
struct ds msg;
ds_init(&msg);
- ofputil_format_port(port32, &msg);
+ ofputil_format_port(u16_to_ofp(port32), &msg);
VLOG_WARN_ONCE("referring to port %s as %u is deprecated for "
"compatibility with future versions of OpenFlow",
ds_cstr(&msg), port32);
ds_destroy(&msg);
-
- *portp = port32;
- return true;
- } else if (port32 < OFPP11_MAX) {
+ } else if (port32 < ofp11_to_u32(OFPP11_MAX)) {
VLOG_WARN("port %u is outside the supported range 0 through "
"%"PRIx16" or 0x%x through 0x%"PRIx32, port32,
- UINT16_MAX, (unsigned int) OFPP11_MAX, UINT32_MAX);
+ UINT16_MAX, ofp11_to_u32(OFPP11_MAX), UINT32_MAX);
return false;
} else {
- *portp = port32 - OFPP11_OFFSET;
- return true;
+ port32 -= OFPP11_OFFSET;
}
+
+ *portp = u16_to_ofp(port32);
+ return true;
} else {
struct pair {
const char *name;
- uint16_t value;
+ ofp_port_t value;
};
static const struct pair pairs[] = {
#define OFPUTIL_NAMED_PORT(NAME) {#NAME, OFPP_##NAME},
* Most ports' string representation is just the port number, but for special
* ports, e.g. OFPP_LOCAL, it is the name, e.g. "LOCAL". */
void
-ofputil_format_port(uint16_t port, struct ds *s)
+ofputil_format_port(ofp_port_t port, struct ds *s)
{
const char *name;
* will be for Open Flow version 'ofp_version'. Returns message
* as a struct ofpbuf. Returns encoded message on success, NULL on error */
struct ofpbuf *
-ofputil_encode_dump_ports_request(enum ofp_version ofp_version, uint16_t port)
+ofputil_encode_dump_ports_request(enum ofp_version ofp_version, ofp_port_t port)
{
struct ofpbuf *request;
struct ofp10_port_stats_request *req;
request = ofpraw_alloc(OFPRAW_OFPST10_PORT_REQUEST, ofp_version, 0);
req = ofpbuf_put_zeros(request, sizeof *req);
- req->port_no = htons(port);
+ req->port_no = htons(ofp_to_u16(port));
break;
}
case OFP11_VERSION:
ofputil_port_stats_to_ofp10(const struct ofputil_port_stats *ops,
struct ofp10_port_stats *ps10)
{
- ps10->port_no = htons(ops->port_no);
+ ps10->port_no = htons(ofp_to_u16(ops->port_no));
memset(ps10->pad, 0, sizeof ps10->pad);
put_32aligned_be64(&ps10->rx_packets, htonll(ops->stats.rx_packets));
put_32aligned_be64(&ps10->tx_packets, htonll(ops->stats.tx_packets));
{
memset(ops, 0, sizeof *ops);
- ops->port_no = ntohs(ps10->port_no);
+ ops->port_no = u16_to_ofp(ntohs(ps10->port_no));
ops->stats.rx_packets = ntohll(get_32aligned_be64(&ps10->rx_packets));
ops->stats.tx_packets = ntohll(get_32aligned_be64(&ps10->tx_packets));
ops->stats.rx_bytes = ntohll(get_32aligned_be64(&ps10->rx_bytes));
* Returns 0 if successful, otherwise an OFPERR_* number. */
enum ofperr
ofputil_decode_port_stats_request(const struct ofp_header *request,
- uint16_t *ofp10_port)
+ ofp_port_t *ofp10_port)
{
switch ((enum ofp_version)request->version) {
case OFP13_VERSION:
case OFP10_VERSION: {
const struct ofp10_port_stats_request *psr10 = ofpmsg_body(request);
- *ofp10_port = ntohs(psr10->port_no);
+ *ofp10_port = u16_to_ofp(ntohs(psr10->port_no));
return 0;
}
case OFP10_VERSION: {
const struct ofp10_queue_stats_request *qsr10 = ofpmsg_body(request);
oqsr->queue_id = ntohl(qsr10->queue_id);
- oqsr->port_no = ntohs(qsr10->port_no);
+ oqsr->port_no = u16_to_ofp(ntohs(qsr10->port_no));
/* OF 1.0 uses OFPP_ALL for OFPP_ANY */
if (oqsr->port_no == OFPP_ALL) {
oqsr->port_no = OFPP_ANY;
request = ofpraw_alloc(OFPRAW_OFPST10_QUEUE_REQUEST, ofp_version, 0);
req = ofpbuf_put_zeros(request, sizeof *req);
/* OpenFlow 1.0 needs OFPP_ALL instead of OFPP_ANY */
- req->port_no = htons(oqsr->port_no == OFPP_ANY
- ? OFPP_ALL : oqsr->port_no);
+ req->port_no = htons(ofp_to_u16(oqsr->port_no == OFPP_ANY
+ ? OFPP_ALL : oqsr->port_no));
req->queue_id = htonl(oqsr->queue_id);
break;
}
ofputil_queue_stats_from_ofp10(struct ofputil_queue_stats *oqs,
const struct ofp10_queue_stats *qs10)
{
- oqs->port_no = ntohs(qs10->port_no);
+ oqs->port_no = u16_to_ofp(ntohs(qs10->port_no));
oqs->queue_id = ntohl(qs10->queue_id);
oqs->stats.tx_bytes = ntohll(get_32aligned_be64(&qs10->tx_bytes));
oqs->stats.tx_packets = ntohll(get_32aligned_be64(&qs10->tx_packets));
ofputil_queue_stats_to_ofp10(const struct ofputil_queue_stats *oqs,
struct ofp10_queue_stats *qs10)
{
- qs10->port_no = htons(oqs->port_no);
+ qs10->port_no = htons(ofp_to_u16(oqs->port_no));
memset(qs10->pad, 0, sizeof qs10->pad);
qs10->queue_id = htonl(oqs->queue_id);
put_32aligned_be64(&qs10->tx_bytes, htonll(oqs->stats.tx_bytes));
struct ofpbuf;
/* Port numbers. */
-enum ofperr ofputil_port_from_ofp11(ovs_be32 ofp11_port, uint16_t *ofp10_port);
-ovs_be32 ofputil_port_to_ofp11(uint16_t ofp10_port);
+enum ofperr ofputil_port_from_ofp11(ovs_be32 ofp11_port,
+ ofp_port_t *ofp10_port);
+ovs_be32 ofputil_port_to_ofp11(ofp_port_t ofp10_port);
-enum ofperr ofputil_check_output_port(uint16_t ofp_port, int max_ports);
-bool ofputil_port_from_string(const char *, uint16_t *portp);
-void ofputil_format_port(uint16_t port, struct ds *);
+enum ofperr ofputil_check_output_port(ofp_port_t ofp_port,
+ ofp_port_t max_ports);
+bool ofputil_port_from_string(const char *, ofp_port_t *portp);
+void ofputil_format_port(ofp_port_t port, struct ds *);
/* Converting OFPFW10_NW_SRC_MASK and OFPFW10_NW_DST_MASK wildcard bit counts
* to and from IP bitmasks. */
uint16_t idle_timeout;
uint16_t hard_timeout;
uint32_t buffer_id;
- uint16_t out_port;
+ ofp_port_t out_port;
uint16_t flags;
struct ofpact *ofpacts; /* Series of "struct ofpact"s. */
size_t ofpacts_len; /* Length of ofpacts, in bytes. */
struct match match;
ovs_be64 cookie;
ovs_be64 cookie_mask;
- uint16_t out_port;
+ ofp_port_t out_port;
uint8_t table_id;
};
const void *packet; /* Packet data, if buffer_id == UINT32_MAX. */
size_t packet_len; /* Length of packet data in bytes. */
uint32_t buffer_id; /* Buffer id or UINT32_MAX if no buffer. */
- uint16_t in_port; /* Packet's input port. */
+ ofp_port_t in_port; /* Packet's input port. */
struct ofpact *ofpacts; /* Actions. */
size_t ofpacts_len; /* Size of ofpacts in bytes. */
};
/* Abstract ofp10_phy_port or ofp11_port. */
struct ofputil_phy_port {
- uint16_t port_no;
+ ofp_port_t port_no;
uint8_t hw_addr[OFP_ETH_ALEN];
char name[OFP_MAX_PORT_NAME_LEN];
enum ofputil_port_config config;
/* Abstract ofp_port_mod. */
struct ofputil_port_mod {
- uint16_t port_no;
+ ofp_port_t port_no;
uint8_t hw_addr[OFP_ETH_ALEN];
enum ofputil_port_config config;
enum ofputil_port_config mask;
struct ofputil_flow_monitor_request {
uint32_t id;
enum nx_flow_monitor_flags flags;
- uint16_t out_port;
+ ofp_port_t out_port;
uint8_t table_id;
struct match match;
};
#define OFP_ACTION_ALIGN 8 /* Alignment of ofp_actions. */
enum ofperr validate_actions(const union ofp_action *, size_t n_actions,
- const struct flow *, int max_ports);
+ const struct flow *, ofp_port_t max_ports);
bool action_outputs_to_port(const union ofp_action *, ovs_be16 port);
enum ofperr ofputil_pull_actions(struct ofpbuf *, unsigned int actions_len,
bool ofputil_parse_key_value(char **stringp, char **keyp, char **valuep);
struct ofputil_port_stats {
- uint16_t port_no;
+ ofp_port_t port_no;
struct netdev_stats stats;
uint32_t duration_sec; /* UINT32_MAX if unknown. */
uint32_t duration_nsec;
};
struct ofpbuf *ofputil_encode_dump_ports_request(enum ofp_version ofp_version,
- uint16_t port);
+ ofp_port_t port);
void ofputil_append_port_stat(struct list *replies,
const struct ofputil_port_stats *ops);
size_t ofputil_count_port_stats(const struct ofp_header *);
int ofputil_decode_port_stats(struct ofputil_port_stats *, struct ofpbuf *msg);
enum ofperr ofputil_decode_port_stats_request(const struct ofp_header *request,
- uint16_t *ofp10_port);
+ ofp_port_t *ofp10_port);
struct ofputil_queue_stats_request {
- uint16_t port_no; /* OFPP_ANY means "all ports". */
+ ofp_port_t port_no; /* OFPP_ANY means "all ports". */
uint32_t queue_id;
};
const struct ofputil_queue_stats_request *oqsr);
struct ofputil_queue_stats {
- uint16_t port_no;
+ ofp_port_t port_no;
uint32_t queue_id;
struct netdev_queue_stats stats;
};
#include <unistd.h>
#include "byte-order.h"
#include "coverage.h"
-#include "openvswitch/types.h"
#include "vlog.h"
VLOG_DEFINE_THIS_MODULE(util);
/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * 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.
#include <stdlib.h>
#include <string.h>
#include "compiler.h"
+#include "openvswitch/types.h"
#ifndef va_copy
#ifdef __va_copy
/* Same as pktbuf_retrieve(), using the pktbuf owned by 'ofconn'. */
enum ofperr
ofconn_pktbuf_retrieve(struct ofconn *ofconn, uint32_t id,
- struct ofpbuf **bufferp, uint16_t *in_port)
+ struct ofpbuf **bufferp, ofp_port_t *in_port)
{
return pktbuf_retrieve(ofconn->pktbuf, id, bufferp, in_port);
}
bool
connmgr_must_output_local(struct connmgr *mgr, const struct flow *flow,
- uint32_t local_odp_port,
+ odp_port_t local_odp_port,
const struct nlattr *odp_actions,
size_t actions_len)
{
enum ofperr);
enum ofperr ofconn_pktbuf_retrieve(struct ofconn *, uint32_t id,
- struct ofpbuf **bufferp, uint16_t *in_port);
+ struct ofpbuf **bufferp, ofp_port_t *in_port);
bool ofconn_has_pending_opgroups(const struct ofconn *);
void ofconn_add_opgroup(struct ofconn *, struct list *);
/* In-band implementation. */
bool connmgr_must_output_local(struct connmgr *, const struct flow *,
- uint32_t local_odp_port,
+ odp_port_t local_odp_port,
const struct nlattr *odp_actions,
size_t actions_len);
enum nx_flow_monitor_flags flags;
/* Matching. */
- uint16_t out_port;
+ ofp_port_t out_port;
uint8_t table_id;
struct minimatch match;
};
/* Returns true if the rule that would match 'flow' with 'actions' is
* allowed to be set up in the datapath. */
bool
-in_band_rule_check(const struct flow *flow, uint32_t local_odp_port,
+in_band_rule_check(const struct flow *flow, odp_port_t local_odp_port,
const struct nlattr *actions, size_t actions_len)
{
/* Don't allow flows that would prevent DHCP replies from being seen
NL_ATTR_FOR_EACH_UNSAFE (a, left, actions, actions_len) {
if (nl_attr_type(a) == OVS_ACTION_ATTR_OUTPUT
- && nl_attr_get_u32(a) == local_odp_port) {
+ && nl_attr_get_odp_port(a) == local_odp_port) {
return true;
}
}
#include <stddef.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include "flow.h"
struct flow;
struct in_band;
bool in_band_run(struct in_band *);
void in_band_wait(struct in_band *);
-bool in_band_rule_check(const struct flow *, uint32_t local_odp_port,
+bool in_band_rule_check(const struct flow *, odp_port_t local_odp_port,
const struct nlattr *odp_actions, size_t actions_len);
#endif /* in-band.h */
nf_rec->nexthop = htonl(0);
if (nf->add_id_to_iface) {
uint16_t iface = (nf->engine_id & 0x7f) << 9;
- nf_rec->input = htons(iface | (expired->flow.in_port & 0x1ff));
- nf_rec->output = htons(iface | (nf_flow->output_iface & 0x1ff));
+ nf_rec->input = htons(iface
+ | (ofp_to_u16(expired->flow.in_port.ofp_port) & 0x1ff));
+ nf_rec->output = htons(iface
+ | (ofp_to_u16(nf_flow->output_iface) & 0x1ff));
} else {
- nf_rec->input = htons(expired->flow.in_port);
- nf_rec->output = htons(nf_flow->output_iface);
+ nf_rec->input = htons(ofp_to_u16(expired->flow.in_port.ofp_port));
+ nf_rec->output = htons(ofp_to_u16(nf_flow->output_iface));
}
nf_rec->packet_count = htonl(packet_count);
nf_rec->byte_count = htonl(byte_count);
void
netflow_flow_clear(struct netflow_flow *nf_flow)
{
- uint16_t output_iface = nf_flow->output_iface;
+ ofp_port_t output_iface = nf_flow->output_iface;
memset(nf_flow, 0, sizeof *nf_flow);
nf_flow->output_iface = output_iface;
/*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 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.
bool add_id_to_iface;
};
-enum netflow_output_ports {
- NF_OUT_FLOOD = UINT16_MAX,
- NF_OUT_MULTI = UINT16_MAX - 1,
- NF_OUT_DROP = UINT16_MAX - 2
-};
+#define NF_OUT_FLOOD OFP_PORT_C(UINT16_MAX)
+#define NF_OUT_MULTI OFP_PORT_C(UINT16_MAX - 1)
+#define NF_OUT_DROP OFP_PORT_C(UINT16_MAX - 2)
struct netflow_flow {
long long int last_expired; /* Time this flow last timed out. */
uint64_t packet_count_off; /* Packet count at last time out. */
uint64_t byte_count_off; /* Byte count at last time out. */
- uint16_t output_iface; /* Output interface index. */
+ ofp_port_t output_iface; /* Output interface index. */
uint8_t tcp_flags; /* Bitwise-OR of all TCP flags seen. */
};
struct hmap_node hmap_node; /* In struct dpif_sflow's "ports" hmap. */
SFLDataSource_instance dsi; /* sFlow library's notion of port number. */
struct ofport *ofport; /* To retrive port stats. */
- uint32_t odp_port;
+ odp_port_t odp_port;
};
struct dpif_sflow {
}
static struct dpif_sflow_port *
-dpif_sflow_find_port(const struct dpif_sflow *ds, uint32_t odp_port)
+dpif_sflow_find_port(const struct dpif_sflow *ds, odp_port_t odp_port)
{
struct dpif_sflow_port *dsp;
HMAP_FOR_EACH_IN_BUCKET (dsp, hmap_node,
- hash_int(odp_port, 0), &ds->ports) {
+ hash_int(odp_to_u32(odp_port), 0),
+ &ds->ports) {
if (dsp->odp_port == odp_port) {
return dsp;
}
struct netdev_stats stats;
enum netdev_flags flags;
- dsp = dpif_sflow_find_port(ds, poller->bridgePort);
+ dsp = dpif_sflow_find_port(ds, u32_to_odp(poller->bridgePort));
if (!dsp) {
return;
}
sflow_agent_get_counters);
sfl_poller_set_sFlowCpInterval(poller, ds->options->polling_interval);
sfl_poller_set_sFlowCpReceiver(poller, RECEIVER_INDEX);
- sfl_poller_set_bridgePort(poller, dsp->odp_port);
+ sfl_poller_set_bridgePort(poller, odp_to_u32(dsp->odp_port));
}
void
dpif_sflow_add_port(struct dpif_sflow *ds, struct ofport *ofport,
- uint32_t odp_port)
+ odp_port_t odp_port)
{
struct dpif_sflow_port *dsp;
int ifindex;
dsp->ofport = ofport;
dsp->odp_port = odp_port;
SFL_DS_SET(dsp->dsi, SFL_DSCLASS_IFINDEX, ifindex, 0);
- hmap_insert(&ds->ports, &dsp->hmap_node, hash_int(odp_port, 0));
+ hmap_insert(&ds->ports, &dsp->hmap_node, hash_int(odp_to_u32(odp_port), 0));
/* Add poller. */
if (ds->sflow_agent) {
}
void
-dpif_sflow_del_port(struct dpif_sflow *ds, uint32_t odp_port)
+dpif_sflow_del_port(struct dpif_sflow *ds, odp_port_t odp_port)
{
struct dpif_sflow_port *dsp = dpif_sflow_find_port(ds, odp_port);
if (dsp) {
int
dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *ds,
- uint32_t odp_port)
+ odp_port_t odp_port)
{
struct dpif_sflow_port *dsp = dpif_sflow_find_port(ds, odp_port);
return dsp ? SFL_DS_INDEX(dsp->dsi) : 0;
void
dpif_sflow_received(struct dpif_sflow *ds, struct ofpbuf *packet,
- const struct flow *flow, uint32_t odp_in_port,
+ const struct flow *flow, odp_port_t odp_in_port,
const union user_action_cookie *cookie)
{
SFL_FLOW_SAMPLE_TYPE fs;
bool dpif_sflow_is_enabled(const struct dpif_sflow *);
void dpif_sflow_add_port(struct dpif_sflow *ds, struct ofport *ofport,
- uint32_t odp_port);
-void dpif_sflow_del_port(struct dpif_sflow *, uint32_t odp_port);
+ odp_port_t odp_port);
+void dpif_sflow_del_port(struct dpif_sflow *, odp_port_t odp_port);
void dpif_sflow_run(struct dpif_sflow *);
void dpif_sflow_wait(struct dpif_sflow *);
void dpif_sflow_received(struct dpif_sflow *,
struct ofpbuf *,
const struct flow *,
- uint32_t odp_port,
+ odp_port_t odp_port,
const union user_action_cookie *);
-int dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *, uint32_t);
+int dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *,
+ odp_port_t odp_port);
#endif /* ofproto/ofproto-dpif-sflow.h */
uint32_t orig_skb_priority; /* Priority when packet arrived. */
uint8_t table_id; /* OpenFlow table ID where flow was found. */
uint32_t sflow_n_outputs; /* Number of output ports. */
- uint32_t sflow_odp_port; /* Output port for composing sFlow action. */
+ odp_port_t sflow_odp_port; /* Output port for composing sFlow action. */
uint16_t user_cookie_offset;/* Used for user_action_cookie fixup. */
bool exit; /* No further actions should be processed. */
};
struct xlate_ctx *);
static void xlate_normal(struct xlate_ctx *);
static void xlate_report(struct xlate_ctx *, const char *);
-static void xlate_table_action(struct xlate_ctx *, uint16_t in_port,
+static void xlate_table_action(struct xlate_ctx *, ofp_port_t in_port,
uint8_t table_id, bool may_packet_in);
static bool input_vid_is_valid(uint16_t vid, struct ofbundle *, bool warn);
static uint16_t input_vid_to_vlan(const struct ofbundle *, uint16_t vid);
static void output_normal(struct xlate_ctx *, const struct ofbundle *,
uint16_t vlan);
-static void compose_output_action(struct xlate_ctx *, uint16_t ofp_port);
+static void compose_output_action(struct xlate_ctx *, ofp_port_t ofp_port);
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
}
static struct ofbundle *
-lookup_input_bundle(const struct ofproto_dpif *ofproto, uint16_t in_port,
+lookup_input_bundle(const struct ofproto_dpif *ofproto, ofp_port_t in_port,
bool warn, struct ofport_dpif **in_ofportp)
{
struct ofport_dpif *ofport;
const struct nlattr *a;
size_t left;
- in_bundle = lookup_input_bundle(ctx->ofproto, orig_flow->in_port,
+ in_bundle = lookup_input_bundle(ctx->ofproto, orig_flow->in_port.ofp_port,
ctx->xin->packet != NULL, NULL);
if (!in_bundle) {
return;
continue;
}
- ofport = get_odp_port(ofproto, nl_attr_get_u32(a));
+ ofport = get_odp_port(ofproto, nl_attr_get_odp_port(a));
if (ofport && ofport->bundle) {
mirrors |= ofport->bundle->dst_mirrors;
}
memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI);
- in_bundle = lookup_input_bundle(ctx->ofproto, flow->in_port,
+ in_bundle = lookup_input_bundle(ctx->ofproto, flow->in_port.ofp_port,
ctx->xin->packet != NULL, &in_port);
if (!in_bundle) {
xlate_report(ctx, "no input bundle, dropping");
static void
compose_sflow_cookie(const struct ofproto_dpif *ofproto,
- ovs_be16 vlan_tci, uint32_t odp_port,
+ ovs_be16 vlan_tci, odp_port_t odp_port,
unsigned int n_outputs, union user_action_cookie *cookie)
{
int ifindex;
compose_sflow_action(const struct ofproto_dpif *ofproto,
struct ofpbuf *odp_actions,
const struct flow *flow,
- uint32_t odp_port)
+ odp_port_t odp_port)
{
uint32_t probability;
union user_action_cookie cookie;
- if (!ofproto->sflow || flow->in_port == OFPP_NONE) {
+ if (!ofproto->sflow || flow->in_port.ofp_port == OFPP_NONE) {
return 0;
}
probability = dpif_sflow_get_probability(ofproto->sflow);
compose_sflow_cookie(ofproto, htons(0), odp_port,
- odp_port == OVSP_NONE ? 0 : 1, &cookie);
+ odp_port == ODPP_NONE ? 0 : 1, &cookie);
return compose_sample_action(ofproto, odp_actions, flow, probability,
&cookie, sizeof cookie.sflow);
uint32_t probability;
union user_action_cookie cookie;
- if (!ofproto->ipfix || flow->in_port == OFPP_NONE) {
+ if (!ofproto->ipfix || flow->in_port.ofp_port == OFPP_NONE) {
return;
}
{
ctx->user_cookie_offset = compose_sflow_action(ctx->ofproto,
&ctx->xout->odp_actions,
- &ctx->xin->flow, OVSP_NONE);
+ &ctx->xin->flow, ODPP_NONE);
ctx->sflow_odp_port = 0;
ctx->sflow_n_outputs = 0;
}
}
static void
-compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
+compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
bool check_stp)
{
const struct ofport_dpif *ofport = get_ofp_port(ctx->ofproto, ofp_port);
ovs_be16 flow_vlan_tci;
uint32_t flow_skb_mark;
uint8_t flow_nw_tos;
- uint32_t out_port, odp_port;
+ odp_port_t out_port, odp_port;
uint8_t dscp;
/* If 'struct flow' gets additional metadata, we'll need to zero it out
enum slow_path_reason special;
ctx->ofproto = ofproto_dpif_cast(peer->up.ofproto);
- flow->in_port = peer->up.ofp_port;
+ flow->in_port.ofp_port = peer->up.ofp_port;
flow->metadata = htonll(0);
memset(&flow->tunnel, 0, sizeof flow->tunnel);
memset(flow->regs, 0, sizeof flow->regs);
ctx->xout->slow = special;
} else if (may_receive(peer, ctx)) {
if (stp_forward_in_state(peer->stp_state)) {
- xlate_table_action(ctx, flow->in_port, 0, true);
+ xlate_table_action(ctx, flow->in_port.ofp_port, 0, true);
} else {
/* Forwarding is disabled by STP. Let OFPP_NORMAL and the
* learning action look at the packet, then drop it. */
struct flow old_base_flow = ctx->base_flow;
size_t old_size = ctx->xout->odp_actions.size;
- xlate_table_action(ctx, flow->in_port, 0, true);
+ xlate_table_action(ctx, flow->in_port.ofp_port, 0, true);
ctx->base_flow = old_base_flow;
ctx->xout->odp_actions.size = old_size;
}
*/
struct flow_tnl flow_tnl = flow->tunnel;
odp_port = tnl_port_send(ofport->tnl_port, flow, &ctx->xout->wc);
- if (odp_port == OVSP_NONE) {
+ if (odp_port == ODPP_NONE) {
xlate_report(ctx, "Tunneling decided against output");
goto out; /* restore flow_nw_tos */
}
&ctx->xout->odp_actions);
flow->tunnel = flow_tnl; /* Restore tunnel metadata */
} else {
- uint16_t vlandev_port;
+ ofp_port_t vlandev_port;
odp_port = ofport->odp_port;
if (!hmap_is_empty(&ctx->ofproto->realdev_vid_map)) {
flow->skb_mark &= ~IPSEC_MARK;
}
- if (out_port != OVSP_NONE) {
+ if (out_port != ODPP_NONE) {
commit_odp_actions(flow, &ctx->base_flow,
&ctx->xout->odp_actions, &ctx->xout->wc);
- nl_msg_put_u32(&ctx->xout->odp_actions, OVS_ACTION_ATTR_OUTPUT,
- out_port);
+ nl_msg_put_odp_port(&ctx->xout->odp_actions, OVS_ACTION_ATTR_OUTPUT,
+ out_port);
ctx->sflow_odp_port = odp_port;
ctx->sflow_n_outputs++;
}
static void
-compose_output_action(struct xlate_ctx *ctx, uint16_t ofp_port)
+compose_output_action(struct xlate_ctx *ctx, ofp_port_t ofp_port)
{
compose_output_action__(ctx, ofp_port, true);
}
static void
xlate_table_action(struct xlate_ctx *ctx,
- uint16_t in_port, uint8_t table_id, bool may_packet_in)
+ ofp_port_t in_port, uint8_t table_id, bool may_packet_in)
{
if (ctx->recurse < MAX_RESUBMIT_RECURSION) {
struct rule_dpif *rule;
- uint16_t old_in_port = ctx->xin->flow.in_port;
+ ofp_port_t old_in_port = ctx->xin->flow.in_port.ofp_port;
uint8_t old_table_id = ctx->table_id;
ctx->table_id = table_id;
/* Look up a flow with 'in_port' as the input port. */
- ctx->xin->flow.in_port = in_port;
+ ctx->xin->flow.in_port.ofp_port = in_port;
rule = rule_dpif_lookup_in_table(ctx->ofproto, &ctx->xin->flow,
&ctx->xout->wc, table_id);
/* Restore the original input port. Otherwise OFPP_NORMAL and
* OFPP_IN_PORT will have surprising behavior. */
- ctx->xin->flow.in_port = old_in_port;
+ ctx->xin->flow.in_port.ofp_port = old_in_port;
rule = ctx_rule_hooks(ctx, rule, may_packet_in);
xlate_ofpact_resubmit(struct xlate_ctx *ctx,
const struct ofpact_resubmit *resubmit)
{
- uint16_t in_port;
+ ofp_port_t in_port;
uint8_t table_id;
in_port = resubmit->in_port;
if (in_port == OFPP_IN_PORT) {
- in_port = ctx->xin->flow.in_port;
+ in_port = ctx->xin->flow.in_port.ofp_port;
}
table_id = resubmit->table_id;
struct ofport_dpif *ofport;
HMAP_FOR_EACH (ofport, up.hmap_node, &ctx->ofproto->up.ports) {
- uint16_t ofp_port = ofport->up.ofp_port;
+ ofp_port_t ofp_port = ofport->up.ofp_port;
- if (ofp_port == ctx->xin->flow.in_port) {
+ if (ofp_port == ctx->xin->flow.in_port.ofp_port) {
continue;
}
static void
xlate_output_action(struct xlate_ctx *ctx,
- uint16_t port, uint16_t max_len, bool may_packet_in)
+ ofp_port_t port, uint16_t max_len, bool may_packet_in)
{
- uint16_t prev_nf_output_iface = ctx->xout->nf_output_iface;
+ ofp_port_t prev_nf_output_iface = ctx->xout->nf_output_iface;
ctx->xout->nf_output_iface = NF_OUT_DROP;
switch (port) {
case OFPP_IN_PORT:
- compose_output_action(ctx, ctx->xin->flow.in_port);
+ compose_output_action(ctx, ctx->xin->flow.in_port.ofp_port);
break;
case OFPP_TABLE:
- xlate_table_action(ctx, ctx->xin->flow.in_port, 0, may_packet_in);
+ xlate_table_action(ctx, ctx->xin->flow.in_port.ofp_port,
+ 0, may_packet_in);
break;
case OFPP_NORMAL:
xlate_normal(ctx);
break;
case OFPP_LOCAL:
default:
- if (port != ctx->xin->flow.in_port) {
+ if (port != ctx->xin->flow.in_port.ofp_port) {
compose_output_action(ctx, port);
} else {
xlate_report(ctx, "skipping output to input port");
memset(&value, 0xff, sizeof value);
mf_write_subfield_flow(&or->src, &value, &ctx->xout->wc.masks);
- xlate_output_action(ctx, port, or->max_len, false);
+ xlate_output_action(ctx, u16_to_ofp(port),
+ or->max_len, false);
}
}
xlate_enqueue_action(struct xlate_ctx *ctx,
const struct ofpact_enqueue *enqueue)
{
- uint16_t ofp_port = enqueue->port;
+ ofp_port_t ofp_port = enqueue->port;
uint32_t queue_id = enqueue->queue;
uint32_t flow_priority, priority;
int error;
/* Check output port. */
if (ofp_port == OFPP_IN_PORT) {
- ofp_port = ctx->xin->flow.in_port;
- } else if (ofp_port == ctx->xin->flow.in_port) {
+ ofp_port = ctx->xin->flow.in_port.ofp_port;
+ } else if (ofp_port == ctx->xin->flow.in_port.ofp_port) {
return;
}
}
static bool
-slave_enabled_cb(uint16_t ofp_port, void *ofproto_)
+slave_enabled_cb(ofp_port_t ofp_port, void *ofproto_)
{
struct ofproto_dpif *ofproto = ofproto_;
struct ofport_dpif *port;
xlate_bundle_action(struct xlate_ctx *ctx,
const struct ofpact_bundle *bundle)
{
- uint16_t port;
+ ofp_port_t port;
port = bundle_execute(bundle, &ctx->xin->flow, &ctx->xout->wc,
slave_enabled_cb, ctx->ofproto);
if (bundle->dst.field) {
- nxm_reg_load(&bundle->dst, port, &ctx->xin->flow);
+ nxm_reg_load(&bundle->dst, ofp_to_u16(port), &ctx->xin->flow);
} else {
xlate_output_action(ctx, port, 0, false);
}
}
}
- in_port = get_ofp_port(ctx.ofproto, flow->in_port);
+ in_port = get_ofp_port(ctx.ofproto, flow->in_port.ofp_port);
special = process_special(&ctx, flow, in_port, ctx.xin->packet);
if (special) {
ctx.xout->slow = special;
} else {
static struct vlog_rate_limit trace_rl = VLOG_RATE_LIMIT_INIT(1, 1);
size_t sample_actions_len;
- uint32_t local_odp_port;
+ odp_port_t local_odp_port;
- if (flow->in_port
- != vsp_realdev_to_vlandev(ctx.ofproto, flow->in_port,
+ if (flow->in_port.ofp_port
+ != vsp_realdev_to_vlandev(ctx.ofproto, flow->in_port.ofp_port,
flow->vlan_tci)) {
ctx.base_flow.vlan_tci = 0;
}
bool has_learn; /* Actions include NXAST_LEARN? */
bool has_normal; /* Actions output to OFPP_NORMAL? */
bool has_fin_timeout; /* Actions include NXAST_FIN_TIMEOUT? */
- uint16_t nf_output_iface; /* Output interface index for NetFlow. */
+ ofp_port_t nf_output_iface; /* Output interface index for NetFlow. */
mirror_mask_t mirrors; /* Bitmap of associated mirrors. */
uint64_t odp_actions_stub[256 / 8];
struct vlan_splinter {
struct hmap_node realdev_vid_node;
struct hmap_node vlandev_node;
- uint16_t realdev_ofp_port;
- uint16_t vlandev_ofp_port;
+ ofp_port_t realdev_ofp_port;
+ ofp_port_t vlandev_ofp_port;
int vid;
};
static bool vsp_adjust_flow(const struct ofproto_dpif *, struct flow *);
static void vsp_remove(struct ofport_dpif *);
-static void vsp_add(struct ofport_dpif *, uint16_t realdev_ofp_port, int vid);
+static void vsp_add(struct ofport_dpif *, ofp_port_t realdev_ofp_port, int vid);
-static uint16_t odp_port_to_ofp_port(const struct ofproto_dpif *,
- uint32_t odp_port);
+static ofp_port_t odp_port_to_ofp_port(const struct ofproto_dpif *,
+ odp_port_t odp_port);
static struct ofport_dpif *
ofport_dpif_cast(const struct ofport *ofport)
static void drop_key_clear(struct dpif_backer *);
static struct ofport_dpif *
-odp_port_to_ofport(const struct dpif_backer *, uint32_t odp_port);
+odp_port_to_ofport(const struct dpif_backer *, odp_port_t odp_port);
static void update_moving_averages(struct dpif_backer *backer);
/* Defer flow mod completion until "ovs-appctl ofproto/unclog"? (Useful only
} else {
node = simap_find(&backer->tnl_backers, dp_port);
if (!node) {
- uint32_t odp_port = UINT32_MAX;
+ odp_port_t odp_port = ODPP_NONE;
if (!dpif_port_add(backer->dpif, iter->up.netdev,
&odp_port)) {
- simap_put(&backer->tnl_backers, dp_port, odp_port);
+ simap_put(&backer->tnl_backers, dp_port,
+ odp_to_u32(odp_port));
node = simap_find(&backer->tnl_backers, dp_port);
}
}
}
- iter->odp_port = node ? node->data : OVSP_NONE;
+ iter->odp_port = node ? u32_to_odp(node->data) : ODPP_NONE;
if (tnl_port_reconfigure(&iter->up, iter->odp_port,
&iter->tnl_port)) {
backer->need_revalidate = REV_RECONFIGURE;
}
SIMAP_FOR_EACH (node, &tmp_backers) {
- dpif_port_del(backer->dpif, node->data);
+ dpif_port_del(backer->dpif, u32_to_odp(node->data));
}
simap_destroy(&tmp_backers);
/* Datapath port slated for removal from datapath. */
struct odp_garbage {
struct list list_node;
- uint32_t odp_port;
+ odp_port_t odp_port;
};
static int
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
struct shash_node *node, *next;
- int max_ports;
+ odp_port_t max_ports;
int error;
int i;
}
max_ports = dpif_get_max_ports(ofproto->backer->dpif);
- ofproto_init_max_ports(ofproto_, MIN(max_ports, OFPP_MAX));
+ ofproto_init_max_ports(ofproto_, u16_to_ofp(MIN(odp_to_u32(max_ports),
+ ofp_to_u16(OFPP_MAX))));
ofproto->netflow = NULL;
ofproto->sflow = NULL;
* because the patch port represents an interface that sFlow considers
* to be "internal" to the switch as a whole, and therefore not an
* candidate for counter polling. */
- port->odp_port = OVSP_NONE;
+ port->odp_port = ODPP_NONE;
ofport_update_peer(port);
return 0;
}
}
hmap_insert(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node,
- hash_int(port->odp_port, 0));
+ hash_int(odp_to_u32(port->odp_port), 0));
}
dpif_port_destroy(&dpif_port);
port->peer = NULL;
}
- if (port->odp_port != OVSP_NONE && !port->tnl_port) {
+ if (port->odp_port != ODPP_NONE && !port->tnl_port) {
hmap_remove(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node);
}
}
static bool
-bundle_add_port(struct ofbundle *bundle, uint16_t ofp_port,
+bundle_add_port(struct ofbundle *bundle, ofp_port_t ofp_port,
struct lacp_slave_settings *lacp)
{
struct ofport_dpif *port;
/* Ports. */
struct ofport_dpif *
-get_ofp_port(const struct ofproto_dpif *ofproto, uint16_t ofp_port)
+get_ofp_port(const struct ofproto_dpif *ofproto, ofp_port_t ofp_port)
{
struct ofport *ofport = ofproto_get_port(&ofproto->up, ofp_port);
return ofport ? ofport_dpif_cast(ofport) : NULL;
}
struct ofport_dpif *
-get_odp_port(const struct ofproto_dpif *ofproto, uint32_t odp_port)
+get_odp_port(const struct ofproto_dpif *ofproto, odp_port_t odp_port)
{
struct ofport_dpif *port = odp_port_to_ofport(ofproto->backer, odp_port);
return port && &ofproto->up == port->up.ofproto ? port : NULL;
dp_port_name = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf);
if (!dpif_port_exists(ofproto->backer->dpif, dp_port_name)) {
- uint32_t port_no = UINT32_MAX;
+ odp_port_t port_no = ODPP_NONE;
int error;
error = dpif_port_add(ofproto->backer->dpif, netdev, &port_no);
return error;
}
if (netdev_get_tunnel_config(netdev)) {
- simap_put(&ofproto->backer->tnl_backers, dp_port_name, port_no);
+ simap_put(&ofproto->backer->tnl_backers,
+ dp_port_name, odp_to_u32(port_no));
}
}
}
static int
-port_del(struct ofproto *ofproto_, uint16_t ofp_port)
+port_del(struct ofproto *ofproto_, ofp_port_t ofp_port)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
struct ofport_dpif *ofport = get_ofp_port(ofproto, ofp_port);
init_flow_miss_execute_op(struct flow_miss *miss, struct ofpbuf *packet,
struct flow_miss_op *op)
{
- if (miss->flow.in_port
- != vsp_realdev_to_vlandev(miss->ofproto, miss->flow.in_port,
+ if (miss->flow.in_port.ofp_port
+ != vsp_realdev_to_vlandev(miss->ofproto, miss->flow.in_port.ofp_port,
miss->flow.vlan_tci)) {
/* This packet was received on a VLAN splinter port. We
* added a VLAN to the packet to make the packet resemble
ofproto_receive(const struct dpif_backer *backer, struct ofpbuf *packet,
const struct nlattr *key, size_t key_len,
struct flow *flow, enum odp_key_fitness *fitnessp,
- struct ofproto_dpif **ofproto, uint32_t *odp_in_port)
+ struct ofproto_dpif **ofproto, odp_port_t *odp_in_port)
{
const struct ofport_dpif *port;
enum odp_key_fitness fitness;
}
if (odp_in_port) {
- *odp_in_port = flow->in_port;
+ *odp_in_port = flow->in_port.odp_port;
}
port = (tnl_port_should_receive(flow)
? ofport_dpif_cast(tnl_port_receive(flow))
- : odp_port_to_ofport(backer, flow->in_port));
- flow->in_port = port ? port->up.ofp_port : OFPP_NONE;
+ : odp_port_to_ofport(backer, flow->in_port.odp_port));
+ flow->in_port.ofp_port = port ? port->up.ofp_port : OFPP_NONE;
if (!port) {
goto exit;
}
struct flow_miss *miss = &misses[n_misses];
struct flow_miss *existing_miss;
struct ofproto_dpif *ofproto;
- uint32_t odp_in_port;
+ odp_port_t odp_in_port;
struct flow flow;
uint32_t hash;
int error;
ofproto->n_missed++;
flow_extract(upcall->packet, flow.skb_priority, flow.skb_mark,
- &flow.tunnel, flow.in_port, &miss->flow);
+ &flow.tunnel, &flow.in_port, &miss->flow);
/* Add other packets to a to-do list. */
hash = flow_hash(&miss->flow, 0);
struct ofproto_dpif *ofproto;
union user_action_cookie cookie;
struct flow flow;
- uint32_t odp_in_port;
+ odp_port_t odp_in_port;
if (ofproto_receive(backer, upcall->packet, upcall->key, upcall->key_len,
&flow, NULL, &ofproto, &odp_in_port)
ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
odp_flow_key_from_flow(&key, flow,
- ofp_port_to_odp_port(ofproto, flow->in_port));
+ ofp_port_to_odp_port(ofproto, flow->in_port.ofp_port));
error = dpif_execute(ofproto->backer->dpif, key.data, key.size,
odp_actions, actions_len, packet);
switch (nl_attr_type(a)) {
case OVS_ACTION_ATTR_OUTPUT:
- port = get_odp_port(ofproto, nl_attr_get_u32(a));
+ port = get_odp_port(ofproto, nl_attr_get_odp_port(a));
if (port && port->bundle && port->bundle->bond) {
bond_account(port->bundle->bond, &facet->flow,
vlan_tci_to_vid(vlan_tci), n_bytes);
facet->prev_byte_count = facet->byte_count;
facet->prev_used = facet->used;
- in_port = get_ofp_port(ofproto, facet->flow.in_port);
+ in_port = get_ofp_port(ofproto, facet->flow.in_port.ofp_port);
if (in_port && in_port->tnl_port) {
netdev_vport_inc_rx(in_port->up.netdev, &stats);
}
{
struct ofport_dpif *port;
- port = get_ofp_port(ofproto, flow->in_port);
+ port = get_ofp_port(ofproto, flow->in_port.ofp_port);
if (!port) {
- VLOG_WARN_RL(&rl, "packet-in on unknown port %"PRIu16, flow->in_port);
+ VLOG_WARN_RL(&rl, "packet-in on unknown OpenFlow port %"PRIu16,
+ flow->in_port.ofp_port);
return ofproto->miss_rule;
}
struct xlate_out xout;
struct xlate_in xin;
struct flow flow;
+ union flow_in_port in_port_;
int error;
ofpbuf_use_stub(&odp_actions, odp_actions_stub, sizeof odp_actions_stub);
ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
/* Use OFPP_NONE as the in_port to avoid special packet processing. */
- flow_extract(packet, 0, 0, NULL, OFPP_NONE, &flow);
+ in_port_.ofp_port = OFPP_NONE;
+ flow_extract(packet, 0, 0, NULL, &in_port_, &flow);
odp_flow_key_from_flow(&key, &flow, ofp_port_to_odp_port(ofproto,
OFPP_LOCAL));
dpif_flow_stats_extract(&flow, packet, time_msec(), &stats);
ofpbuf_use_stack(&buf, stub, stub_size);
if (slow & (SLOW_CFM | SLOW_BFD | SLOW_LACP | SLOW_STP)) {
- uint32_t pid = dpif_port_get_pid(ofproto->backer->dpif, UINT32_MAX);
+ uint32_t pid = dpif_port_get_pid(ofproto->backer->dpif,
+ ODPP_NONE);
odp_put_userspace_action(pid, &cookie, sizeof cookie.slow_path, &buf);
} else {
put_userspace_action(ofproto, &buf, flow, &cookie,
uint32_t pid;
pid = dpif_port_get_pid(ofproto->backer->dpif,
- ofp_port_to_odp_port(ofproto, flow->in_port));
+ ofp_port_to_odp_port(ofproto,
+ flow->in_port.ofp_port));
return odp_put_userspace_action(pid, cookie, cookie_size, odp_actions);
}
ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
odp_flow_key_from_flow(&key, flow,
- ofp_port_to_odp_port(ofproto, flow->in_port));
+ ofp_port_to_odp_port(ofproto,
+ flow->in_port.ofp_port));
dpif_flow_stats_extract(flow, packet, time_msec(), &stats);
if (!packet->size) {
flow_compose(packet, &flow);
} else {
+ union flow_in_port in_port_;
+
+ in_port_ = flow.in_port;
ds_put_cstr(&result, "Packet: ");
s = ofp_packet_to_string(packet->data, packet->size);
ds_put_cstr(&result, s);
/* Use the metadata from the flow and the packet argument
* to reconstruct the flow. */
flow_extract(packet, flow.skb_priority, flow.skb_mark, NULL,
- flow.in_port, &flow);
+ &in_port_, &flow);
}
}
const struct shash_node *node = ports[j];
struct ofport *ofport = node->data;
struct smap config;
- uint32_t odp_port;
+ odp_port_t odp_port;
ds_put_format(ds, "\t\t%s %u/", netdev_get_name(ofport->netdev),
ofport->ofp_port);
odp_port = ofp_port_to_odp_port(ofproto, ofport->ofp_port);
- if (odp_port != OVSP_NONE) {
+ if (odp_port != ODPP_NONE) {
ds_put_format(ds, "%"PRIu32":", odp_port);
} else {
ds_put_cstr(ds, "none:");
* widespread use, we will delete these interfaces. */
static int
-set_realdev(struct ofport *ofport_, uint16_t realdev_ofp_port, int vid)
+set_realdev(struct ofport *ofport_, ofp_port_t realdev_ofp_port, int vid)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport_->ofproto);
struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
}
static uint32_t
-hash_realdev_vid(uint16_t realdev_ofp_port, int vid)
+hash_realdev_vid(ofp_port_t realdev_ofp_port, int vid)
{
- return hash_2words(realdev_ofp_port, vid);
+ return hash_2words(ofp_to_u16(realdev_ofp_port), vid);
}
/* Returns the OFP port number of the Linux VLAN device that corresponds to
*
* Unless VLAN splinters are enabled for port 'realdev_ofp_port', this
* function just returns its 'realdev_ofp_port' argument. */
-uint16_t
+ofp_port_t
vsp_realdev_to_vlandev(const struct ofproto_dpif *ofproto,
- uint16_t realdev_ofp_port, ovs_be16 vlan_tci)
+ ofp_port_t realdev_ofp_port, ovs_be16 vlan_tci)
{
if (!hmap_is_empty(&ofproto->realdev_vid_map)) {
int vid = vlan_tci_to_vid(vlan_tci);
}
static struct vlan_splinter *
-vlandev_find(const struct ofproto_dpif *ofproto, uint16_t vlandev_ofp_port)
+vlandev_find(const struct ofproto_dpif *ofproto, ofp_port_t vlandev_ofp_port)
{
struct vlan_splinter *vsp;
- HMAP_FOR_EACH_WITH_HASH (vsp, vlandev_node, hash_int(vlandev_ofp_port, 0),
+ HMAP_FOR_EACH_WITH_HASH (vsp, vlandev_node,
+ hash_int(ofp_to_u16(vlandev_ofp_port), 0),
&ofproto->vlandev_map) {
if (vsp->vlandev_ofp_port == vlandev_ofp_port) {
return vsp;
* Returns 0 and does not modify '*vid' if 'vlandev_ofp_port' is not a Linux
* VLAN device. Unless VLAN splinters are enabled, this is what this function
* always does.*/
-static uint16_t
+static ofp_port_t
vsp_vlandev_to_realdev(const struct ofproto_dpif *ofproto,
- uint16_t vlandev_ofp_port, int *vid)
+ ofp_port_t vlandev_ofp_port, int *vid)
{
if (!hmap_is_empty(&ofproto->vlandev_map)) {
const struct vlan_splinter *vsp;
static bool
vsp_adjust_flow(const struct ofproto_dpif *ofproto, struct flow *flow)
{
- uint16_t realdev;
+ ofp_port_t realdev;
int vid;
- realdev = vsp_vlandev_to_realdev(ofproto, flow->in_port, &vid);
+ realdev = vsp_vlandev_to_realdev(ofproto, flow->in_port.ofp_port, &vid);
if (!realdev) {
return false;
}
/* Cause the flow to be processed as if it came in on the real device with
* the VLAN device's VLAN ID. */
- flow->in_port = realdev;
+ flow->in_port.ofp_port = realdev;
flow->vlan_tci = htons((vid & VLAN_VID_MASK) | VLAN_CFI);
return true;
}
}
static void
-vsp_add(struct ofport_dpif *port, uint16_t realdev_ofp_port, int vid)
+vsp_add(struct ofport_dpif *port, ofp_port_t realdev_ofp_port, int vid)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
vsp = xmalloc(sizeof *vsp);
hmap_insert(&ofproto->vlandev_map, &vsp->vlandev_node,
- hash_int(port->up.ofp_port, 0));
+ hash_int(ofp_to_u16(port->up.ofp_port), 0));
hmap_insert(&ofproto->realdev_vid_map, &vsp->realdev_vid_node,
hash_realdev_vid(realdev_ofp_port, vid));
vsp->realdev_ofp_port = realdev_ofp_port;
}
}
-uint32_t
-ofp_port_to_odp_port(const struct ofproto_dpif *ofproto, uint16_t ofp_port)
+odp_port_t
+ofp_port_to_odp_port(const struct ofproto_dpif *ofproto, ofp_port_t ofp_port)
{
const struct ofport_dpif *ofport = get_ofp_port(ofproto, ofp_port);
- return ofport ? ofport->odp_port : OVSP_NONE;
+ return ofport ? ofport->odp_port : ODPP_NONE;
}
static struct ofport_dpif *
-odp_port_to_ofport(const struct dpif_backer *backer, uint32_t odp_port)
+odp_port_to_ofport(const struct dpif_backer *backer, odp_port_t odp_port)
{
struct ofport_dpif *port;
HMAP_FOR_EACH_IN_BUCKET (port, odp_port_node,
- hash_int(odp_port, 0),
+ hash_int(odp_to_u32(odp_port), 0),
&backer->odp_to_ofport_map) {
if (port->odp_port == odp_port) {
return port;
return NULL;
}
-static uint16_t
-odp_port_to_ofp_port(const struct ofproto_dpif *ofproto, uint32_t odp_port)
+static ofp_port_t
+odp_port_to_ofp_port(const struct ofproto_dpif *ofproto, odp_port_t odp_port)
{
struct ofport_dpif *port;
struct hmap_node odp_port_node; /* In dpif_backer's "odp_to_ofport_map". */
struct ofport up;
- uint32_t odp_port;
+ odp_port_t odp_port;
struct ofbundle *bundle; /* Bundle that contains this port, if any. */
struct list bundle_node; /* In struct ofbundle's "ports" list. */
struct cfm *cfm; /* Connectivity Fault Management, if any. */
* drivers in old versions of Linux that do not properly support VLANs when
* VLAN devices are not used. When broken device drivers are no longer in
* widespread use, we will delete these interfaces. */
- uint16_t realdev_ofp_port;
+ ofp_port_t realdev_ofp_port;
int vlandev_vid;
};
}
struct ofport_dpif *get_ofp_port(const struct ofproto_dpif *,
- uint16_t ofp_port);
+ ofp_port_t ofp_port);
struct ofport_dpif *get_odp_port(const struct ofproto_dpif *,
- uint32_t odp_port);
+ odp_port_t odp_port);
-uint32_t ofp_port_to_odp_port(const struct ofproto_dpif *, uint16_t ofp_port);
+odp_port_t ofp_port_to_odp_port(const struct ofproto_dpif *,
+ ofp_port_t ofp_port);
struct rule_dpif *rule_dpif_lookup_in_table(struct ofproto_dpif *,
const struct flow *,
void stp_process_packet(const struct ofport_dpif *,
const struct ofpbuf *packet);
-uint16_t vsp_realdev_to_vlandev(const struct ofproto_dpif *,
- uint16_t realdev_ofp_port,
- ovs_be16 vlan_tci);
+ofp_port_t vsp_realdev_to_vlandev(const struct ofproto_dpif *,
+ ofp_port_t realdev_ofp_port,
+ ovs_be16 vlan_tci);
bool ofproto_dpif_dscp_from_priority(const struct ofport_dpif *,
uint32_t priority, uint8_t *dscp);
struct shash port_by_name;
unsigned long *ofp_port_ids;/* Bitmap of used OpenFlow port numbers. */
struct simap ofp_requests; /* OpenFlow port number requests. */
- uint16_t alloc_port_no; /* Last allocated OpenFlow port number. */
- uint16_t max_ports; /* Max possible OpenFlow port num, plus one. */
+ ofp_port_t alloc_port_no; /* Last allocated OpenFlow port number. */
+ ofp_port_t max_ports; /* Max possible OpenFlow port num, plus one. */
/* Flow tables. */
struct oftable *tables;
};
void ofproto_init_tables(struct ofproto *, int n_tables);
-void ofproto_init_max_ports(struct ofproto *, uint16_t max_ports);
+void ofproto_init_max_ports(struct ofproto *, ofp_port_t max_ports);
struct ofproto *ofproto_lookup(const char *name);
-struct ofport *ofproto_get_port(const struct ofproto *, uint16_t ofp_port);
+struct ofport *ofproto_get_port(const struct ofproto *, ofp_port_t ofp_port);
/* An OpenFlow port within a "struct ofproto".
*
struct ofproto *ofproto; /* The ofproto that contains this port. */
struct netdev *netdev;
struct ofputil_phy_port pp;
- uint16_t ofp_port; /* OpenFlow port number. */
+ ofp_port_t ofp_port; /* OpenFlow port number. */
unsigned int change_seq;
long long int created; /* Time created, in msec. */
int mtu;
void ofproto_rule_expire(struct rule *, uint8_t reason);
void ofproto_rule_destroy(struct rule *);
-bool ofproto_rule_has_out_port(const struct rule *, uint16_t out_port);
+bool ofproto_rule_has_out_port(const struct rule *, ofp_port_t out_port);
void ofoperation_complete(struct ofoperation *, enum ofperr);
struct rule *ofoperation_get_victim(struct ofoperation *);
-bool ofoperation_has_out_port(const struct ofoperation *, uint16_t out_port);
+bool ofoperation_has_out_port(const struct ofoperation *, ofp_port_t out_port);
bool ofproto_rule_is_hidden(const struct rule *);
* It doesn't matter whether the new port will be returned by a later call
* to ->port_poll(); the implementation may do whatever is more
* convenient. */
- int (*port_del)(struct ofproto *ofproto, uint16_t ofp_port);
+ int (*port_del)(struct ofproto *ofproto, ofp_port_t ofp_port);
/* Get port stats */
int (*port_get_stats)(const struct ofport *port,
* This function should be NULL if a an implementation does not support
* it. */
int (*set_realdev)(struct ofport *ofport,
- uint16_t realdev_ofp_port, int vid);
+ ofp_port_t realdev_ofp_port, int vid);
};
extern const struct ofproto_class ofproto_dpif_class;
/* The "max_ports" member should have been set by ->construct(ofproto).
* Port 0 is not a valid OpenFlow port, so mark that as unavailable. */
- ofproto->ofp_port_ids = bitmap_allocate(ofproto->max_ports);
+ ofproto->ofp_port_ids = bitmap_allocate(ofp_to_u16(ofproto->max_ports));
bitmap_set1(ofproto->ofp_port_ids, 0);
/* Check that hidden tables, if any, are at the end. */
* Reserved ports numbered OFPP_MAX and higher are special and not subject to
* the 'max_ports' restriction. */
void
-ofproto_init_max_ports(struct ofproto *ofproto, uint16_t max_ports)
+ofproto_init_max_ports(struct ofproto *ofproto, ofp_port_t max_ports)
{
- ovs_assert(max_ports <= OFPP_MAX);
+ ovs_assert(ofp_to_u16(max_ports) <= ofp_to_u16(OFPP_MAX));
ofproto->max_ports = max_ports;
}
*
* Returns 0 if successful, otherwise a positive errno value.*/
int
-ofproto_port_set_stp(struct ofproto *ofproto, uint16_t ofp_port,
+ofproto_port_set_stp(struct ofproto *ofproto, ofp_port_t ofp_port,
const struct ofproto_port_stp_settings *s)
{
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
*
* Returns 0 if successful, otherwise a positive errno value.*/
int
-ofproto_port_get_stp_status(struct ofproto *ofproto, uint16_t ofp_port,
+ofproto_port_get_stp_status(struct ofproto *ofproto, ofp_port_t ofp_port,
struct ofproto_port_stp_status *s)
{
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
*
* Returns 0 if successful, otherwise a positive errno value. */
int
-ofproto_port_set_queues(struct ofproto *ofproto, uint16_t ofp_port,
+ofproto_port_set_queues(struct ofproto *ofproto, ofp_port_t ofp_port,
const struct ofproto_port_queue *queues,
size_t n_queues)
{
/* Clears the CFM configuration from 'ofp_port' on 'ofproto'. */
void
-ofproto_port_clear_cfm(struct ofproto *ofproto, uint16_t ofp_port)
+ofproto_port_clear_cfm(struct ofproto *ofproto, ofp_port_t ofp_port)
{
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
if (ofport && ofproto->ofproto_class->set_cfm) {
*
* This function has no effect if 'ofproto' does not have a port 'ofp_port'. */
void
-ofproto_port_set_cfm(struct ofproto *ofproto, uint16_t ofp_port,
+ofproto_port_set_cfm(struct ofproto *ofproto, ofp_port_t ofp_port,
const struct cfm_settings *s)
{
struct ofport *ofport;
/* Configures BFD on 'ofp_port' in 'ofproto'. This function has no effect if
* 'ofproto' does not have a port 'ofp_port'. */
void
-ofproto_port_set_bfd(struct ofproto *ofproto, uint16_t ofp_port,
+ofproto_port_set_bfd(struct ofproto *ofproto, ofp_port_t ofp_port,
const struct smap *cfg)
{
struct ofport *ofport;
* OVS database. Has no effect if 'ofp_port' is not na OpenFlow port in
* 'ofproto'. */
int
-ofproto_port_get_bfd_status(struct ofproto *ofproto, uint16_t ofp_port,
+ofproto_port_get_bfd_status(struct ofproto *ofproto, ofp_port_t ofp_port,
struct smap *status)
{
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
* 0 if LACP partner information is not current (generally indicating a
* connectivity problem), or -1 if LACP is not enabled on 'ofp_port'. */
int
-ofproto_port_is_lacp_current(struct ofproto *ofproto, uint16_t ofp_port)
+ofproto_port_is_lacp_current(struct ofproto *ofproto, ofp_port_t ofp_port)
{
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
return (ofport && ofproto->ofproto_class->port_is_lacp_current
* 'ofp_portp' is non-null). */
int
ofproto_port_add(struct ofproto *ofproto, struct netdev *netdev,
- uint16_t *ofp_portp)
+ ofp_port_t *ofp_portp)
{
- uint16_t ofp_port = ofp_portp ? *ofp_portp : OFPP_NONE;
+ ofp_port_t ofp_port = ofp_portp ? *ofp_portp : OFPP_NONE;
int error;
error = ofproto->ofproto_class->port_add(ofproto, netdev);
if (!error) {
const char *netdev_name = netdev_get_name(netdev);
- simap_put(&ofproto->ofp_requests, netdev_name, ofp_port);
+ simap_put(&ofproto->ofp_requests, netdev_name,
+ ofp_to_u16(ofp_port));
update_port(ofproto, netdev_name);
}
if (ofp_portp) {
/* Deletes port number 'ofp_port' from the datapath for 'ofproto'.
* Returns 0 if successful, otherwise a positive errno. */
int
-ofproto_port_del(struct ofproto *ofproto, uint16_t ofp_port)
+ofproto_port_del(struct ofproto *ofproto, ofp_port_t ofp_port)
{
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
const char *name = ofport ? netdev_get_name(ofport->netdev) : "<unknown>";
sset_destroy(&devnames);
}
-static uint16_t
+static ofp_port_t
alloc_ofp_port(struct ofproto *ofproto, const char *netdev_name)
{
- uint16_t ofp_port;
- uint16_t end_port_no = ofproto->alloc_port_no;
+ uint16_t max_ports = ofp_to_u16(ofproto->max_ports);
+ uint16_t port_idx;
- ofp_port = simap_get(&ofproto->ofp_requests, netdev_name);
- ofp_port = ofp_port ? ofp_port : OFPP_NONE;
+ port_idx = simap_get(&ofproto->ofp_requests, netdev_name);
+ if (!port_idx) {
+ port_idx = UINT16_MAX;
+ }
+
+ if (port_idx >= max_ports
+ || bitmap_is_set(ofproto->ofp_port_ids, port_idx)) {
+ uint16_t end_port_no = ofp_to_u16(ofproto->alloc_port_no);
+ uint16_t alloc_port_no = end_port_no;
- if (ofp_port >= ofproto->max_ports
- || bitmap_is_set(ofproto->ofp_port_ids, ofp_port)) {
/* Search for a free OpenFlow port number. We try not to
* immediately reuse them to prevent problems due to old
* flows. */
for (;;) {
- if (++ofproto->alloc_port_no >= ofproto->max_ports) {
- ofproto->alloc_port_no = 0;
+ if (++alloc_port_no >= max_ports) {
+ alloc_port_no = 0;
}
- if (!bitmap_is_set(ofproto->ofp_port_ids,
- ofproto->alloc_port_no)) {
- ofp_port = ofproto->alloc_port_no;
+ if (!bitmap_is_set(ofproto->ofp_port_ids, alloc_port_no)) {
+ port_idx = alloc_port_no;
+ ofproto->alloc_port_no = u16_to_ofp(alloc_port_no);
break;
}
- if (ofproto->alloc_port_no == end_port_no) {
+ if (alloc_port_no == end_port_no) {
return OFPP_NONE;
}
}
}
- bitmap_set1(ofproto->ofp_port_ids, ofp_port);
- return ofp_port;
+ bitmap_set1(ofproto->ofp_port_ids, port_idx);
+ return u16_to_ofp(port_idx);
}
static void
-dealloc_ofp_port(const struct ofproto *ofproto, uint16_t ofp_port)
+dealloc_ofp_port(const struct ofproto *ofproto, ofp_port_t ofp_port)
{
- if (ofp_port < ofproto->max_ports) {
- bitmap_set0(ofproto->ofp_port_ids, ofp_port);
+ if (ofp_to_u16(ofp_port) < ofp_to_u16(ofproto->max_ports)) {
+ bitmap_set0(ofproto->ofp_port_ids, ofp_to_u16(ofp_port));
}
}
ofport->created = time_msec();
/* Add port to 'p'. */
- hmap_insert(&p->ports, &ofport->hmap_node, hash_int(ofport->ofp_port, 0));
+ hmap_insert(&p->ports, &ofport->hmap_node,
+ hash_int(ofp_to_u16(ofport->ofp_port), 0));
shash_add(&p->port_by_name, netdev_name, ofport);
update_mtu(p, ofport);
}
void
-ofproto_port_unregister(struct ofproto *ofproto, uint16_t ofp_port)
+ofproto_port_unregister(struct ofproto *ofproto, ofp_port_t ofp_port)
{
struct ofport *port = ofproto_get_port(ofproto, ofp_port);
if (port) {
}
struct ofport *
-ofproto_get_port(const struct ofproto *ofproto, uint16_t ofp_port)
+ofproto_get_port(const struct ofproto *ofproto, ofp_port_t ofp_port)
{
struct ofport *port;
HMAP_FOR_EACH_IN_BUCKET (port, hmap_node,
- hash_int(ofp_port, 0), &ofproto->ports) {
+ hash_int(ofp_to_u16(ofp_port), 0),
+ &ofproto->ports) {
if (port->ofp_port == ofp_port) {
return port;
}
netdev = (!ofproto_port_query_by_name(ofproto, name, &ofproto_port)
? ofport_open(ofproto, &ofproto_port, &pp)
: NULL);
+
if (netdev) {
port = ofproto_get_port(ofproto, ofproto_port.ofp_port);
if (port && !strcmp(netdev_get_name(port->netdev), name)) {
node = shash_find(&init_ofp_ports, name);
if (node) {
const struct iface_hint *iface_hint = node->data;
- simap_put(&p->ofp_requests, name, iface_hint->ofp_port);
+ simap_put(&p->ofp_requests, name,
+ ofp_to_u16(iface_hint->ofp_port));
}
netdev = ofport_open(p, &ofproto_port, &pp);
/* Returns true if 'rule' has an OpenFlow OFPAT_OUTPUT or OFPAT_ENQUEUE action
* that outputs to 'port' (output to OFPP_FLOOD and OFPP_ALL doesn't count). */
bool
-ofproto_rule_has_out_port(const struct rule *rule, uint16_t port)
+ofproto_rule_has_out_port(const struct rule *rule, ofp_port_t port)
{
return (port == OFPP_ANY
|| ofpacts_output_to_port(rule->ofpacts, rule->ofpacts_len, port));
/* Returns true if a rule related to 'op' has an OpenFlow OFPAT_OUTPUT or
* OFPAT_ENQUEUE action that outputs to 'out_port'. */
bool
-ofoperation_has_out_port(const struct ofoperation *op, uint16_t out_port)
+ofoperation_has_out_port(const struct ofoperation *op, ofp_port_t out_port)
{
if (ofproto_rule_has_out_port(op->rule, out_port)) {
return true;
*
* Takes ownership of 'packet'. */
static int
-rule_execute(struct rule *rule, uint16_t in_port, struct ofpbuf *packet)
+rule_execute(struct rule *rule, ofp_port_t in_port, struct ofpbuf *packet)
{
struct flow flow;
+ union flow_in_port in_port_;
ovs_assert(ofpbuf_headroom(packet) >= sizeof(struct ofp10_packet_in));
- flow_extract(packet, 0, 0, NULL, in_port, &flow);
+ in_port_.ofp_port = in_port;
+ flow_extract(packet, 0, 0, NULL, &in_port_, &flow);
return rule->ofproto->ofproto_class->rule_execute(rule, &flow, packet);
}
uint64_t ofpacts_stub[1024 / 8];
struct ofpbuf ofpacts;
struct flow flow;
+ union flow_in_port in_port_;
enum ofperr error;
COVERAGE_INC(ofproto_packet_out);
if (error) {
goto exit_free_ofpacts;
}
- if (po.in_port >= p->max_ports && po.in_port < OFPP_MAX) {
+ if (ofp_to_u16(po.in_port) >= ofp_to_u16(p->max_ports)
+ && ofp_to_u16(po.in_port) < ofp_to_u16(OFPP_MAX)) {
error = OFPERR_OFPBRC_BAD_PORT;
goto exit_free_ofpacts;
}
}
/* Verify actions against packet, then send packet if successful. */
- flow_extract(payload, 0, 0, NULL, po.in_port, &flow);
+ in_port_.ofp_port = po.in_port;
+ flow_extract(payload, 0, 0, NULL, &in_port_, &flow);
error = ofpacts_check(po.ofpacts, po.ofpacts_len, &flow, p->max_ports);
if (!error) {
error = p->ofproto_class->packet_out(p, payload, &flow,
struct ofproto *p = ofconn_get_ofproto(ofconn);
struct ofport *port;
struct list replies;
- uint16_t port_no;
+ ofp_port_t port_no;
enum ofperr error;
error = ofputil_decode_port_stats_request(request, &port_no);
collect_rules_loose(struct ofproto *ofproto, uint8_t table_id,
const struct match *match,
ovs_be64 cookie, ovs_be64 cookie_mask,
- uint16_t out_port, struct list *rules)
+ ofp_port_t out_port, struct list *rules)
{
struct oftable *table;
struct cls_rule cr;
collect_rules_strict(struct ofproto *ofproto, uint8_t table_id,
const struct match *match, unsigned int priority,
ovs_be64 cookie, ovs_be64 cookie_mask,
- uint16_t out_port, struct list *rules)
+ ofp_port_t out_port, struct list *rules)
{
struct oftable *table;
struct cls_rule cr;
* The caller must provide and owns '*status', but it does not own and must not
* modify or free the array returned in 'status->rmps'. */
bool
-ofproto_port_get_cfm_status(const struct ofproto *ofproto, uint16_t ofp_port,
+ofproto_port_get_cfm_status(const struct ofproto *ofproto, ofp_port_t ofp_port,
struct ofproto_cfm_status *status)
{
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
LIST_FOR_EACH (op, group_node, &group->ops) {
if (op->type != OFOPERATION_DELETE) {
struct ofpbuf *packet;
- uint16_t in_port;
+ ofp_port_t in_port;
error = ofconn_pktbuf_retrieve(group->ofconn, group->buffer_id,
&packet, &in_port);
* device as a VLAN splinter for VLAN ID 'vid'. If 'realdev_ofp_port' is zero,
* then the VLAN device is un-enslaved. */
int
-ofproto_port_set_realdev(struct ofproto *ofproto, uint16_t vlandev_ofp_port,
- uint16_t realdev_ofp_port, int vid)
+ofproto_port_set_realdev(struct ofproto *ofproto, ofp_port_t vlandev_ofp_port,
+ ofp_port_t realdev_ofp_port, int vid)
{
struct ofport *ofport;
int error;
struct iface_hint {
char *br_name; /* Name of owning bridge. */
char *br_type; /* Type of owning bridge. */
- uint16_t ofp_port; /* OpenFlow port number. */
+ ofp_port_t ofp_port; /* OpenFlow port number. */
};
void ofproto_init(const struct shash *iface_hints);
struct ofproto_port {
char *name; /* Network device name, e.g. "eth0". */
char *type; /* Network device type, e.g. "system". */
- uint16_t ofp_port; /* OpenFlow port number. */
+ ofp_port_t ofp_port; /* OpenFlow port number. */
};
void ofproto_port_clone(struct ofproto_port *, const struct ofproto_port *);
void ofproto_port_destroy(struct ofproto_port *);
const char *ofproto_port_open_type(const char *datapath_type,
const char *port_type);
-int ofproto_port_add(struct ofproto *, struct netdev *, uint16_t *ofp_portp);
-int ofproto_port_del(struct ofproto *, uint16_t ofp_port);
+int ofproto_port_add(struct ofproto *, struct netdev *, ofp_port_t *ofp_portp);
+int ofproto_port_del(struct ofproto *, ofp_port_t ofp_port);
int ofproto_port_get_stats(const struct ofport *, struct netdev_stats *stats);
int ofproto_port_query_by_name(const struct ofproto *, const char *devname,
int ofproto_get_stp_status(struct ofproto *, struct ofproto_stp_status *);
/* Configuration of ports. */
-void ofproto_port_unregister(struct ofproto *, uint16_t ofp_port);
+void ofproto_port_unregister(struct ofproto *, ofp_port_t ofp_port);
-void ofproto_port_clear_cfm(struct ofproto *, uint16_t ofp_port);
-void ofproto_port_set_cfm(struct ofproto *, uint16_t ofp_port,
+void ofproto_port_clear_cfm(struct ofproto *, ofp_port_t ofp_port);
+void ofproto_port_set_cfm(struct ofproto *, ofp_port_t ofp_port,
const struct cfm_settings *);
-void ofproto_port_set_bfd(struct ofproto *, uint16_t ofp_port,
+void ofproto_port_set_bfd(struct ofproto *, ofp_port_t ofp_port,
const struct smap *cfg);
-int ofproto_port_get_bfd_status(struct ofproto *, uint16_t ofp_port,
+int ofproto_port_get_bfd_status(struct ofproto *, ofp_port_t ofp_port,
struct smap *);
-int ofproto_port_is_lacp_current(struct ofproto *, uint16_t ofp_port);
-int ofproto_port_set_stp(struct ofproto *, uint16_t ofp_port,
+int ofproto_port_is_lacp_current(struct ofproto *, ofp_port_t ofp_port);
+int ofproto_port_set_stp(struct ofproto *, ofp_port_t ofp_port,
const struct ofproto_port_stp_settings *);
-int ofproto_port_get_stp_status(struct ofproto *, uint16_t ofp_port,
+int ofproto_port_get_stp_status(struct ofproto *, ofp_port_t ofp_port,
struct ofproto_port_stp_status *);
-int ofproto_port_set_queues(struct ofproto *, uint16_t ofp_port,
+int ofproto_port_set_queues(struct ofproto *, ofp_port_t ofp_port,
const struct ofproto_port_queue *,
size_t n_queues);
struct ofproto_bundle_settings {
char *name; /* For use in log messages. */
- uint16_t *slaves; /* OpenFlow port numbers for slaves. */
+ ofp_port_t *slaves; /* OpenFlow port numbers for slaves. */
size_t n_slaves;
enum port_vlan_mode vlan_mode; /* Selects mode for vlan and trunks */
* drivers in old versions of Linux that do not properly support VLANs when
* VLAN devices are not used. When broken device drivers are no longer in
* widespread use, we will delete these interfaces. */
- uint16_t realdev_ofp_port; /* OpenFlow port number of real device. */
+ ofp_port_t realdev_ofp_port;/* OpenFlow port number of real device. */
};
int ofproto_bundle_register(struct ofproto *, void *aux,
size_t n_rmps;
};
-bool ofproto_port_get_cfm_status(const struct ofproto *, uint16_t ofp_port,
+bool ofproto_port_get_cfm_status(const struct ofproto *,
+ ofp_port_t ofp_port,
struct ofproto_cfm_status *);
\f
/* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
void ofproto_get_vlan_usage(struct ofproto *, unsigned long int *vlan_bitmap);
bool ofproto_has_vlan_usage_changed(const struct ofproto *);
-int ofproto_port_set_realdev(struct ofproto *, uint16_t vlandev_ofp_port,
- uint16_t realdev_ofp_port, int vid);
+int ofproto_port_set_realdev(struct ofproto *, ofp_port_t vlandev_ofp_port,
+ ofp_port_t realdev_ofp_port, int vid);
#ifdef __cplusplus
}
#include <arpa/inet.h>
#include <stdint.h>
#include <stdlib.h>
+#include "flow.h"
#include "hash.h"
#include "hmap.h"
#include "ofpbuf.h"
struct pinqueue {
struct hmap_node node; /* In struct pinsched's 'queues' hmap. */
- uint16_t port_no; /* Port number. */
+ ofp_port_t port_no; /* Port number. */
struct list packets; /* Contains "struct ofpbuf"s. */
int n; /* Number of packets in 'packets'. */
};
}
static struct pinqueue *
-pinqueue_get(struct pinsched *ps, uint16_t port_no)
+pinqueue_get(struct pinsched *ps, ofp_port_t port_no)
{
- uint32_t hash = hash_int(port_no, 0);
+ uint32_t hash = hash_int(ofp_to_u16(port_no), 0);
struct pinqueue *q;
HMAP_FOR_EACH_IN_BUCKET (q, node, hash, &ps->queues) {
}
void
-pinsched_send(struct pinsched *ps, uint16_t port_no,
+pinsched_send(struct pinsched *ps, ofp_port_t port_no,
struct ofpbuf *packet, pinsched_tx_cb *cb, void *aux)
{
if (!ps) {
#define PINSCHED_H_H 1
#include <stdint.h>
+#include "flow.h"
struct ofpbuf;
int *rate_limit, int *burst_limit);
void pinsched_set_limits(struct pinsched *, int rate_limit, int burst_limit);
void pinsched_destroy(struct pinsched *);
-void pinsched_send(struct pinsched *, uint16_t port_no, struct ofpbuf *,
+void pinsched_send(struct pinsched *, ofp_port_t port_no, struct ofpbuf *,
pinsched_tx_cb *, void *aux);
void pinsched_run(struct pinsched *, pinsched_tx_cb *, void *aux);
void pinsched_wait(struct pinsched *);
struct ofpbuf *buffer;
uint32_t cookie;
long long int timeout;
- uint16_t in_port;
+ ofp_port_t in_port;
};
struct pktbuf {
* The caller retains ownership of 'buffer'. */
uint32_t
pktbuf_save(struct pktbuf *pb, const void *buffer, size_t buffer_size,
- uint16_t in_port)
+ ofp_port_t in_port)
{
struct packet *p = &pb->packets[pb->buffer_idx];
pb->buffer_idx = (pb->buffer_idx + 1) & PKTBUF_MASK;
* 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
- * NULL in '*bufferp' and UINT16_max in '*in_port'.
+ * NULL in '*bufferp' and OFPP_NONE in '*in_port'.
*
* 'in_port' may be NULL if the input port is not of interest.
*
* 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,
- uint16_t *in_port)
+ ofp_port_t *in_port)
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 20);
struct packet *p;
error:
*bufferp = NULL;
if (in_port) {
- *in_port = UINT16_MAX;
+ *in_port = OFPP_NONE;
}
return error;
}
struct pktbuf *pktbuf_create(void);
void pktbuf_destroy(struct pktbuf *);
uint32_t pktbuf_save(struct pktbuf *, const void *buffer, size_t buffer_size,
- uint16_t in_port);
+ ofp_port_t in_port);
uint32_t pktbuf_get_null(void);
enum ofperr pktbuf_retrieve(struct pktbuf *, uint32_t id,
- struct ofpbuf **bufferp, uint16_t *in_port);
+ struct ofpbuf **bufferp, ofp_port_t *in_port);
void pktbuf_discard(struct pktbuf *, uint32_t id);
unsigned int pktbuf_count_packets(const struct pktbuf *);
ovs_be64 in_key;
ovs_be32 ip_src;
ovs_be32 ip_dst;
- uint32_t odp_port;
+ odp_port_t odp_port;
uint32_t skb_mark;
bool in_key_flow;
bool ip_src_flow;
static const char *tnl_port_get_name(const struct tnl_port *);
static struct tnl_port *
-tnl_port_add__(const struct ofport *ofport, uint32_t odp_port,
+tnl_port_add__(const struct ofport *ofport, odp_port_t odp_port,
bool warn)
{
const struct netdev_tunnel_config *cfg;
* must be added before they can be used by the module. 'ofport' must be a
* tunnel. */
struct tnl_port *
-tnl_port_add(const struct ofport *ofport, uint32_t odp_port)
+tnl_port_add(const struct ofport *ofport, odp_port_t odp_port)
{
return tnl_port_add__(ofport, odp_port, true);
}
* 'ofport' and 'odp_port' should be the same as would be passed to
* tnl_port_add(). */
bool
-tnl_port_reconfigure(const struct ofport *ofport, uint32_t odp_port,
+tnl_port_reconfigure(const struct ofport *ofport, odp_port_t odp_port,
struct tnl_port **tnl_portp)
{
struct tnl_port *tnl_port = *tnl_portp;
struct tnl_match match;
memset(&match, 0, sizeof match);
- match.odp_port = flow->in_port;
+ match.odp_port = flow->in_port.odp_port;
match.ip_src = flow->tunnel.ip_dst;
match.ip_dst = flow->tunnel.ip_src;
match.in_key = flow->tunnel.tun_id;
/* Given that 'flow' should be output to the ofport corresponding to
* 'tnl_port', updates 'flow''s tunnel headers and returns the actual datapath
- * port that the output should happen on. May return OVSP_NONE if the output
+ * port that the output should happen on. May return ODPP_NONE if the output
* shouldn't occur. */
-uint32_t
+odp_port_t
tnl_port_send(const struct tnl_port *tnl_port, struct flow *flow,
struct flow_wildcards *wc)
{
char *pre_flow_str = NULL;
if (tnl_port == &void_tnl_port) {
- return OVSP_NONE;
+ return ODPP_NONE;
}
cfg = netdev_get_tunnel_config(tnl_port->ofport->netdev);
struct ofport;
struct tnl_port;
-bool tnl_port_reconfigure(const struct ofport *, uint32_t odp_port,
+bool tnl_port_reconfigure(const struct ofport *, odp_port_t odp_port,
struct tnl_port **);
-struct tnl_port *tnl_port_add(const struct ofport *, uint32_t odp_port);
+struct tnl_port *tnl_port_add(const struct ofport *, odp_port_t odp_port);
void tnl_port_del(struct tnl_port *);
const struct ofport *tnl_port_receive(const struct flow *);
-uint32_t tnl_port_send(const struct tnl_port *, struct flow *,
- struct flow_wildcards *wc);
+odp_port_t tnl_port_send(const struct tnl_port *, struct flow *,
+ struct flow_wildcards *wc);
/* Returns true if 'flow' should be submitted to tnl_port_receive(). */
static inline bool
#define MAX_SLAVES 8 /* Maximum supported by this test framework. */
struct slave {
- uint16_t slave_id;
+ ofp_port_t slave_id;
bool enabled;
size_t flow_count;
};
static struct slave *
-slave_lookup(struct slave_group *sg, uint16_t slave_id)
+slave_lookup(struct slave_group *sg, ofp_port_t slave_id)
{
size_t i;
}
static bool
-slave_enabled_cb(uint16_t slave_id, void *aux)
+slave_enabled_cb(ofp_port_t slave_id, void *aux)
{
struct slave *slave;
/* Generate 'slaves' array. */
sg.n_slaves = 0;
for (i = 0; i < bundle->n_slaves; i++) {
- uint16_t slave_id = bundle->slaves[i];
+ ofp_port_t slave_id = bundle->slaves[i];
if (slave_lookup(&sg, slave_id)) {
ovs_fatal(0, "Redundant slaves are not supported. ");
random_bytes(&flows[i], sizeof flows[i]);
memset(flows[i].zeros, 0, sizeof flows[i].zeros);
flows[i].mpls_depth = 0;
- flows[i].regs[0] = OFPP_NONE;
+ flows[i].regs[0] = ofp_to_u16(OFPP_NONE);
}
/* Cycles through each possible liveness permutation for the given
changed = 0;
for (j = 0; j < N_FLOWS; j++) {
struct flow *flow = &flows[j];
- uint16_t old_slave_id, ofp_port;
+ ofp_port_t old_slave_id, ofp_port;
struct flow_wildcards wc;
- old_slave_id = flow->regs[0];
+ old_slave_id = u16_to_ofp(flow->regs[0]);
ofp_port = bundle_execute(bundle, flow, &wc, slave_enabled_cb,
&sg);
- flow->regs[0] = ofp_port;
+ flow->regs[0] = ofp_to_u16(ofp_port);
if (ofp_port != OFPP_NONE) {
slave_lookup(&sg, ofp_port)->flow_count++;
eq = !((fixed->dl_type ^ wild.flow.dl_type)
& wild.wc.masks.dl_type);
} else if (f_idx == CLS_F_IDX_IN_PORT) {
- eq = !((fixed->in_port ^ wild.flow.in_port)
- & wild.wc.masks.in_port);
+ eq = !((fixed->in_port.ofp_port
+ ^ wild.flow.in_port.ofp_port)
+ & wild.wc.masks.in_port.ofp_port);
} else {
NOT_REACHED();
}
static ovs_be64 metadata_values[] = {
0,
CONSTANT_HTONLL(UINT64_C(0xfedcba9876543210)) };
-static uint16_t in_port_values[] = { 1, OFPP_LOCAL };
+static ofp_port_t in_port_values[] = { OFP_PORT_C(1), OFPP_LOCAL };
static ovs_be16 vlan_tci_values[] = { CONSTANT_HTONS(101), CONSTANT_HTONS(0) };
static ovs_be16 dl_type_values[]
= { CONSTANT_HTONS(ETH_TYPE_IP), CONSTANT_HTONS(ETH_TYPE_ARP) };
flow.nw_dst = nw_dst_values[get_value(&x, N_NW_DST_VALUES)];
flow.tunnel.tun_id = tun_id_values[get_value(&x, N_TUN_ID_VALUES)];
flow.metadata = metadata_values[get_value(&x, N_METADATA_VALUES)];
- flow.in_port = in_port_values[get_value(&x, N_IN_PORT_VALUES)];
+ flow.in_port.ofp_port = in_port_values[get_value(&x,
+ N_IN_PORT_VALUES)];
flow.vlan_tci = vlan_tci_values[get_value(&x, N_VLAN_TCI_VALUES)];
flow.dl_type = dl_type_values[get_value(&x, N_DL_TYPE_VALUES)];
flow.tp_src = tp_src_values[get_value(&x, N_TP_SRC_VALUES)];
} else if (f_idx == CLS_F_IDX_DL_TYPE) {
match.wc.masks.dl_type = htons(UINT16_MAX);
} else if (f_idx == CLS_F_IDX_IN_PORT) {
- match.wc.masks.in_port = UINT16_MAX;
+ match.wc.masks.in_port.ofp_port = OFPP_NONE;
} else {
NOT_REACHED();
}
struct ofp10_match extracted_match;
struct match match;
struct flow flow;
-
+ union flow_in_port in_port_;
n++;
retval = pcap_read(pcap, &packet);
ovs_fatal(retval, "error reading pcap file");
}
- flow_extract(packet, 0, 0, NULL, 1, &flow);
+ in_port_.ofp_port = u16_to_ofp(1);
+ flow_extract(packet, 0, 0, NULL, &in_port_, &flow);
match_init_exact(&match, &flow);
ofputil_match_to_ofp10_match(&match, &extracted_match);
/* Convert cls_rule back to odp_key. */
ofpbuf_uninit(&odp_key);
ofpbuf_init(&odp_key, 0);
- odp_flow_key_from_flow(&odp_key, &flow, flow.in_port);
+ odp_flow_key_from_flow(&odp_key, &flow, flow.in_port.odp_port);
if (odp_key.size > ODPUTIL_FLOW_KEY_BYTES) {
printf ("too long: %zu > %d\n",
char *save_ptr = NULL;
struct netdev *netdev = NULL;
struct smap args;
- uint32_t port_no = UINT32_MAX;
+ odp_port_t port_no = ODPP_NONE;
char *option;
int error;
if (!strcmp(key, "type")) {
type = value;
} else if (!strcmp(key, "port_no")) {
- port_no = atoi(value);
+ port_no = u32_to_odp(atoi(value));
} else if (!smap_add_once(&args, key, value)) {
ovs_error(0, "duplicate \"%s\" option", key);
}
char *type = NULL;
const char *name;
struct smap args;
- uint32_t port_no;
+ odp_port_t port_no;
char *option;
int error;
failure = true;
}
} else if (!strcmp(key, "port_no")) {
- if (port_no != atoi(value)) {
+ if (port_no != u32_to_odp(atoi(value))) {
ovs_error(0, "%s: can't change port number from "
"%"PRIu32" to %d",
name, port_no, atoi(value));
}
static bool
-get_port_number(struct dpif *dpif, const char *name, uint32_t *port)
+get_port_number(struct dpif *dpif, const char *name, odp_port_t *port)
{
struct dpif_port dpif_port;
run(parsed_dpif_open(argv[1], false, &dpif), "opening datapath");
for (i = 2; i < argc; i++) {
const char *name = argv[i];
- uint32_t port;
+ odp_port_t port;
int error;
if (!name[strspn(name, "0123456789")]) {
- port = atoi(name);
+ port = u32_to_odp(atoi(name));
} else if (!get_port_number(dpif, name, &port)) {
failure = true;
continue;
static bool
fetch_port_by_features(const char *vconn_name,
- const char *port_name, unsigned int port_no,
+ const char *port_name, ofp_port_t port_no,
struct ofputil_phy_port *pp, bool *trunc)
{
struct ofputil_switch_features features;
}
while (!ofputil_pull_phy_port(oh->version, &b, pp)) {
- if (port_no != UINT_MAX
+ if (port_no != OFPP_NONE
? port_no == pp->port_no
: !strcmp(pp->name, port_name)) {
found = true;
static bool
fetch_port_by_stats(const char *vconn_name,
- const char *port_name, unsigned int port_no,
+ const char *port_name, ofp_port_t port_no,
struct ofputil_phy_port *pp)
{
struct ofpbuf *request;
}
while (!ofputil_pull_phy_port(oh->version, &b, pp)) {
- if (port_no != UINT_MAX ? port_no == pp->port_no
- : !strcmp(pp->name, port_name)) {
+ if (port_no != OFPP_NONE ? port_no == pp->port_no
+ : !strcmp(pp->name, port_name)) {
found = true;
break;
}
return found;
}
+static bool
+str_to_ofp(const char *s, ofp_port_t *ofp_port)
+{
+ bool ret;
+ uint32_t port_;
+
+ ret = str_to_uint(s, 10, &port_);
+ *ofp_port = u16_to_ofp(port_);
+ return ret;
+}
/* Opens a connection to 'vconn_name', fetches the port structure for
* 'port_name' (which may be a port name or number), and copies it into
fetch_ofputil_phy_port(const char *vconn_name, const char *port_name,
struct ofputil_phy_port *pp)
{
- unsigned int port_no;
+ ofp_port_t port_no;
bool found;
bool trunc;
/* Try to interpret the argument as a port number. */
- if (!str_to_uint(port_name, 10, &port_no)) {
- port_no = UINT_MAX;
+ if (!str_to_ofp(port_name, &port_no)) {
+ port_no = OFPP_NONE;
}
/* Try to find the port based on the Features Reply. If it looks
/* Returns the port number corresponding to 'port_name' (which may be a port
* name or number) within the switch 'vconn_name'. */
-static uint16_t
+static ofp_port_t
str_to_port_no(const char *vconn_name, const char *port_name)
{
- uint16_t port_no;
+ ofp_port_t port_no;
if (ofputil_port_from_string(port_name, &port_no)) {
return port_no;
{
struct ofpbuf *request;
struct vconn *vconn;
- uint16_t port;
+ ofp_port_t port;
open_vconn(argv[1], &vconn);
port = argc > 2 ? str_to_port_no(argv[1], argv[2]) : OFPP_ANY;
struct hmap_node hmap_node; /* Node in bridge's if_cfg_todo. */
const struct ovsrec_interface *cfg; /* Interface record. */
const struct ovsrec_port *parent; /* Parent port record. */
- uint16_t ofport; /* Requested OpenFlow port number. */
+ ofp_port_t ofport; /* Requested OpenFlow port number. */
};
/* OpenFlow port slated for removal from ofproto. */
struct ofpp_garbage {
struct list list_node; /* Node in bridge's ofpp_garbage. */
- uint16_t ofp_port; /* Port to be deleted. */
+ ofp_port_t ofp_port; /* Port to be deleted. */
};
struct iface {
/* These members are valid only after bridge_reconfigure() causes them to
* be initialized. */
struct hmap_node ofp_port_node; /* In struct bridge's "ifaces" hmap. */
- uint16_t ofp_port; /* OpenFlow port number, */
+ ofp_port_t ofp_port; /* OpenFlow port number, */
/* OFPP_NONE if unknown. */
struct netdev *netdev; /* Network device. */
const char *type; /* Usually same as cfg->type. */
static void mirror_refresh_stats(struct mirror *);
static void iface_configure_lacp(struct iface *, struct lacp_slave_settings *);
-static bool iface_create(struct bridge *, struct if_cfg *, uint16_t ofp_port);
+static bool iface_create(struct bridge *, struct if_cfg *,
+ ofp_port_t ofp_port);
static bool iface_is_internal(const struct ovsrec_interface *iface,
const struct ovsrec_bridge *br);
static const char *iface_get_type(const struct ovsrec_interface *,
static struct iface *iface_find(const char *name);
static struct if_cfg *if_cfg_lookup(const struct bridge *, const char *name);
static struct iface *iface_from_ofp_port(const struct bridge *,
- uint16_t ofp_port);
+ ofp_port_t ofp_port);
static void iface_set_mac(struct iface *);
-static void iface_set_ofport(const struct ovsrec_interface *, uint16_t ofport);
+static void iface_set_ofport(const struct ovsrec_interface *, ofp_port_t ofport);
static void iface_clear_db_record(const struct ovsrec_interface *if_cfg);
static void iface_configure_qos(struct iface *, const struct ovsrec_qos *);
static void iface_configure_cfm(struct iface *);
static void iface_refresh_stats(struct iface *);
static void iface_refresh_status(struct iface *);
static bool iface_is_synthetic(const struct iface *);
-static uint16_t iface_pick_ofport(const struct ovsrec_interface *);
+static ofp_port_t iface_pick_ofport(const struct ovsrec_interface *);
/* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
*
}
static void
-iface_set_ofp_port(struct iface *iface, uint16_t ofp_port)
+iface_set_ofp_port(struct iface *iface, ofp_port_t ofp_port)
{
struct bridge *br = iface->port->bridge;
ovs_assert(iface->ofp_port == OFPP_NONE && ofp_port != OFPP_NONE);
iface->ofp_port = ofp_port;
- hmap_insert(&br->ifaces, &iface->ofp_port_node, hash_int(ofp_port, 0));
+ hmap_insert(&br->ifaces, &iface->ofp_port_node,
+ hash_int(ofp_to_u16(ofp_port), 0));
iface_set_ofport(iface->cfg, ofp_port);
}
{
const char *name = ofproto_port->name;
const char *type = ofproto_port->type;
- uint16_t ofp_port = ofproto_port->ofp_port;
+ ofp_port_t ofp_port = ofproto_port->ofp_port;
struct iface *iface = iface_lookup(br, name);
if (iface) {
static int
iface_do_create(const struct bridge *br,
const struct if_cfg *if_cfg,
- uint16_t *ofp_portp, struct netdev **netdevp)
+ ofp_port_t *ofp_portp, struct netdev **netdevp)
{
const struct ovsrec_interface *iface_cfg = if_cfg->cfg;
const struct ovsrec_port *port_cfg = if_cfg->parent;
}
if (*ofp_portp == OFPP_NONE) {
- uint16_t ofp_port = if_cfg->ofport;
+ ofp_port_t ofp_port = if_cfg->ofport;
error = ofproto_port_add(br->ofproto, netdev, &ofp_port);
if (error) {
*
* Return true if an iface is successfully created, false otherwise. */
static bool
-iface_create(struct bridge *br, struct if_cfg *if_cfg, uint16_t ofp_port)
+iface_create(struct bridge *br, struct if_cfg *if_cfg, ofp_port_t ofp_port)
{
const struct ovsrec_interface *iface_cfg = if_cfg->cfg;
const struct ovsrec_port *port_cfg = if_cfg->parent;
error = netdev_open(port->name, "internal", &netdev);
if (!error) {
- uint16_t fake_ofp_port = if_cfg->ofport;
+ ofp_port_t fake_ofp_port = if_cfg->ofport;
ofproto_port_add(br->ofproto, netdev, &fake_ofp_port);
netdev_close(netdev);
key = smap_get_int(&iface->cfg->other_config, "lacp-aggregation-key", 0);
if (portid <= 0 || portid > UINT16_MAX) {
- portid = iface->ofp_port;
+ portid = ofp_to_u16(iface->ofp_port);
}
if (priority <= 0 || priority > UINT16_MAX) {
}
static struct iface *
-iface_from_ofp_port(const struct bridge *br, uint16_t ofp_port)
+iface_from_ofp_port(const struct bridge *br, ofp_port_t ofp_port)
{
struct iface *iface;
HMAP_FOR_EACH_IN_BUCKET (iface, ofp_port_node,
- hash_int(ofp_port, 0), &br->ifaces) {
+ hash_int(ofp_to_u16(ofp_port), 0),
+ &br->ifaces) {
if (iface->ofp_port == ofp_port) {
return iface;
}
/* Sets the ofport column of 'if_cfg' to 'ofport'. */
static void
-iface_set_ofport(const struct ovsrec_interface *if_cfg, uint16_t ofport)
+iface_set_ofport(const struct ovsrec_interface *if_cfg, ofp_port_t ofport)
{
int64_t port_;
- port_ = (ofport == OFPP_NONE) ? -1 : ofport;
+ port_ = (ofport == OFPP_NONE) ? -1 : ofp_to_u16(ofport);
if (if_cfg && !ovsdb_idl_row_is_synthetic(&if_cfg->header_)) {
ovsrec_interface_set_ofport(if_cfg, &port_, 1);
}
return ovsdb_idl_row_is_synthetic(&iface->cfg->header_);
}
-static uint16_t
+static ofp_port_t
iface_pick_ofport(const struct ovsrec_interface *cfg)
{
- uint16_t ofport = cfg->n_ofport ? *cfg->ofport : OFPP_NONE;
- return cfg->n_ofport_request ? *cfg->ofport_request : ofport;
+ ofp_port_t ofport = cfg->n_ofport ? u16_to_ofp(*cfg->ofport)
+ : OFPP_NONE;
+ return cfg->n_ofport_request ? u16_to_ofp(*cfg->ofport_request)
+ : ofport;
}
\f
configure_splinter_port(struct port *port)
{
struct ofproto *ofproto = port->bridge->ofproto;
- uint16_t realdev_ofp_port;
+ ofp_port_t realdev_ofp_port;
const char *realdev_name;
struct iface *vlandev, *realdev;