2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-29 15:28:56 +00:00

Create specific types for ofp and odp port

Until now, datapath ports and openflow ports were both represented by
unsigned integers of various sizes. With implicit conversions, etc., it is
easy to mix them up and use one where the other is expected.  This commit
creates two typedefs, ofp_port_t and odp_port_t.  Both of these two types
are marked by "__attribute__((bitwise))" so that sparse can be used to
detect any misuse.

Signed-off-by: Alex Wang <alexw@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Alex Wang
2013-06-19 16:58:44 -07:00
committed by Ben Pfaff
parent e6cc0babc2
commit 4e022ec09e
60 changed files with 778 additions and 633 deletions

View File

@@ -169,7 +169,8 @@ static int dpif_linux_init(void);
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 *);
@@ -261,7 +262,7 @@ open_dpif(const struct dpif_linux_dp *dp, struct dpif **dpifp)
static void
destroy_channels(struct dpif_linux *dpif)
{
int i;
unsigned int i;
if (dpif->epoll_fd < 0) {
return;
@@ -280,7 +281,7 @@ destroy_channels(struct dpif_linux *dpif)
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);
@@ -300,9 +301,10 @@ destroy_channels(struct dpif_linux *dpif)
}
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;
@@ -310,9 +312,9 @@ add_channel(struct dpif_linux *dpif, uint32_t port_no, struct nl_sock *sock)
/* 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",
@@ -333,29 +335,30 @@ add_channel(struct dpif_linux *dpif, uint32_t port_no, struct nl_sock *sock)
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;
}
@@ -482,7 +485,7 @@ netdev_to_ovs_vport_type(const struct netdev *netdev)
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;
@@ -541,7 +544,7 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
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);
}
@@ -573,7 +576,7 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
}
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;
@@ -591,7 +594,7 @@ dpif_linux_port_del(struct dpif *dpif_, uint32_t port_no)
}
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;
@@ -622,7 +625,7 @@ dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no,
}
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);
@@ -635,23 +638,24 @@ dpif_linux_port_query_by_name(const struct dpif *dpif, const char *devname,
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);
}
}
@@ -1562,7 +1566,7 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport,
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]) {
@@ -1592,8 +1596,8 @@ dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *vport,
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) {
@@ -1624,7 +1628,7 @@ void
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