Skip to content

Commit 4e022ec

Browse files
yew011blp
authored andcommitted
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>
1 parent e6cc0ba commit 4e022ec

60 files changed

Lines changed: 779 additions & 634 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

include/openflow/openflow-1.0.h

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,22 @@
2828
* 0xff00...0xfff7 "reserved" but not assigned a meaning by OpenFlow 1.0
2929
* 0xfff8...0xffff "reserved" OFPP_* ports with assigned meanings
3030
*/
31-
enum ofp_port {
32-
/* Ranges. */
33-
OFPP_MAX = 0xff00, /* Maximum number of physical switch ports. */
34-
OFPP_FIRST_RESV = 0xfff8, /* First assigned reserved port number. */
35-
OFPP_LAST_RESV = 0xffff, /* Last assigned reserved port number. */
36-
37-
/* Reserved output "ports". */
38-
OFPP_IN_PORT = 0xfff8, /* Send the packet out the input port. This
39-
virtual port must be explicitly used
40-
in order to send back out of the input
41-
port. */
42-
OFPP_TABLE = 0xfff9, /* Perform actions in flow table.
43-
NB: This can only be the destination
44-
port for packet-out messages. */
45-
OFPP_NORMAL = 0xfffa, /* Process with normal L2/L3 switching. */
46-
OFPP_FLOOD = 0xfffb, /* All physical ports except input port and
47-
those disabled by STP. */
48-
OFPP_ALL = 0xfffc, /* All physical ports except input port. */
49-
OFPP_CONTROLLER = 0xfffd, /* Send to controller. */
50-
OFPP_LOCAL = 0xfffe, /* Local openflow "port". */
51-
OFPP_NONE = 0xffff /* Not associated with a physical port. */
52-
};
31+
32+
/* Ranges. */
33+
#define OFPP_MAX OFP_PORT_C(0xff00) /* Max # of switch ports. */
34+
#define OFPP_FIRST_RESV OFP_PORT_C(0xfff8) /* First assigned reserved port. */
35+
#define OFPP_LAST_RESV OFP_PORT_C(0xffff) /* Last assigned reserved port. */
36+
37+
/* Reserved output "ports". */
38+
#define OFPP_IN_PORT OFP_PORT_C(0xfff8) /* Where the packet came in. */
39+
#define OFPP_TABLE OFP_PORT_C(0xfff9) /* Perform actions in flow table. */
40+
#define OFPP_NORMAL OFP_PORT_C(0xfffa) /* Process with normal L2/L3. */
41+
#define OFPP_FLOOD OFP_PORT_C(0xfffb) /* All ports except input port and
42+
* ports disabled by STP. */
43+
#define OFPP_ALL OFP_PORT_C(0xfffc) /* All ports except input port. */
44+
#define OFPP_CONTROLLER OFP_PORT_C(0xfffd) /* Send to controller. */
45+
#define OFPP_LOCAL OFP_PORT_C(0xfffe) /* Local openflow "port". */
46+
#define OFPP_NONE OFP_PORT_C(0xffff) /* Not associated with any port. */
5347

5448
/* OpenFlow 1.0 specific capabilities supported by the datapath (struct
5549
* ofp_switch_features, member capabilities). */

include/openflow/openflow-1.1.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@
6767
* an OpenFlow 1.0 reserved port number to or from, respectively, the
6868
* corresponding OpenFlow 1.1 reserved port number.
6969
*/
70-
#define OFPP11_MAX 0xffffff00
71-
#define OFPP11_OFFSET (OFPP11_MAX - OFPP_MAX)
70+
#define OFPP11_MAX OFP11_PORT_C(0xffffff00)
71+
#define OFPP11_OFFSET 0xffff0000 /* OFPP11_MAX - OFPP_MAX */
7272

7373
/* Reserved wildcard port used only for flow mod (delete) and flow stats
7474
* requests. Selects all flows regardless of output port

include/openvswitch/types.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2011 Nicira, Inc.
2+
* Copyright (c) 2010, 2011, 2013 Nicira, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -60,4 +60,16 @@ typedef struct {
6060
ovs_be32 hi, lo;
6161
} ovs_32aligned_be64;
6262

63+
/* ofp_port_t represents the port number of a OpenFlow switch.
64+
* odp_port_t represents the port number on the datapath.
65+
* ofp11_port_t represents the OpenFlow-1.1 port number. */
66+
typedef uint16_t OVS_BITWISE ofp_port_t;
67+
typedef uint32_t OVS_BITWISE odp_port_t;
68+
typedef uint32_t OVS_BITWISE ofp11_port_t;
69+
70+
/* Macro functions that cast int types to ofp/odp/ofp11 types. */
71+
#define OFP_PORT_C(X) ((OVS_FORCE ofp_port_t) (X))
72+
#define ODP_PORT_C(X) ((OVS_FORCE odp_port_t) (X))
73+
#define OFP11_PORT_C(X) ((OVS_FORCE ofp11_port_t) (X))
74+
6375
#endif /* openvswitch/types.h */

lib/bundle.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535

3636
VLOG_DEFINE_THIS_MODULE(bundle);
3737

38-
static uint16_t
38+
static ofp_port_t
3939
execute_ab(const struct ofpact_bundle *bundle,
40-
bool (*slave_enabled)(uint16_t ofp_port, void *aux), void *aux)
40+
bool (*slave_enabled)(ofp_port_t ofp_port, void *aux), void *aux)
4141
{
4242
size_t i;
4343

4444
for (i = 0; i < bundle->n_slaves; i++) {
45-
uint16_t slave = bundle->slaves[i];
45+
ofp_port_t slave = bundle->slaves[i];
4646
if (slave_enabled(slave, aux)) {
4747
return slave;
4848
}
@@ -51,10 +51,10 @@ execute_ab(const struct ofpact_bundle *bundle,
5151
return OFPP_NONE;
5252
}
5353

54-
static uint16_t
54+
static ofp_port_t
5555
execute_hrw(const struct ofpact_bundle *bundle,
5656
const struct flow *flow, struct flow_wildcards *wc,
57-
bool (*slave_enabled)(uint16_t ofp_port, void *aux), void *aux)
57+
bool (*slave_enabled)(ofp_port_t ofp_port, void *aux), void *aux)
5858
{
5959
uint32_t flow_hash, best_hash;
6060
int best, i;
@@ -85,10 +85,11 @@ execute_hrw(const struct ofpact_bundle *bundle,
8585
* calculate the result. Uses 'slave_enabled' to determine if the slave
8686
* designated by 'ofp_port' is up. Returns the chosen slave, or
8787
* OFPP_NONE if none of the slaves are acceptable. */
88-
uint16_t
88+
ofp_port_t
8989
bundle_execute(const struct ofpact_bundle *bundle,
9090
const struct flow *flow, struct flow_wildcards *wc,
91-
bool (*slave_enabled)(uint16_t ofp_port, void *aux), void *aux)
91+
bool (*slave_enabled)(ofp_port_t ofp_port, void *aux),
92+
void *aux)
9293
{
9394
switch (bundle->algorithm) {
9495
case NX_BD_ALG_HRW:
@@ -186,7 +187,7 @@ bundle_from_openflow(const struct nx_action_bundle *nab,
186187
}
187188

188189
enum ofperr
189-
bundle_check(const struct ofpact_bundle *bundle, int max_ports,
190+
bundle_check(const struct ofpact_bundle *bundle, ofp_port_t max_ports,
190191
const struct flow *flow)
191192
{
192193
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
@@ -200,7 +201,7 @@ bundle_check(const struct ofpact_bundle *bundle, int max_ports,
200201
}
201202

202203
for (i = 0; i < bundle->n_slaves; i++) {
203-
uint16_t ofp_port = bundle->slaves[i];
204+
ofp_port_t ofp_port = bundle->slaves[i];
204205
enum ofperr error;
205206

206207
error = ofputil_check_output_port(ofp_port, max_ports);
@@ -246,7 +247,7 @@ bundle_to_nxast(const struct ofpact_bundle *bundle, struct ofpbuf *openflow)
246247

247248
slaves = ofpbuf_put_zeros(openflow, slaves_len);
248249
for (i = 0; i < bundle->n_slaves; i++) {
249-
slaves[i] = htons(bundle->slaves[i]);
250+
slaves[i] = htons(ofp_to_u16(bundle->slaves[i]));
250251
}
251252
}
252253

@@ -271,7 +272,7 @@ bundle_parse__(const char *s, char **save_ptr,
271272
bundle = ofpact_put_BUNDLE(ofpacts);
272273

273274
for (;;) {
274-
uint16_t slave_port;
275+
ofp_port_t slave_port;
275276
char *slave;
276277

277278
slave = strtok_r(NULL, ", []", save_ptr);

lib/bundle.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ struct ofpbuf;
3535
*
3636
* See include/openflow/nicira-ext.h for NXAST_BUNDLE specification. */
3737

38-
uint16_t bundle_execute(const struct ofpact_bundle *, const struct flow *,
38+
ofp_port_t bundle_execute(const struct ofpact_bundle *, const struct flow *,
3939
struct flow_wildcards *wc,
40-
bool (*slave_enabled)(uint16_t ofp_port, void *aux),
40+
bool (*slave_enabled)(ofp_port_t ofp_port, void *aux),
4141
void *aux);
4242
enum ofperr bundle_from_openflow(const struct nx_action_bundle *,
4343
struct ofpbuf *ofpact);
44-
enum ofperr bundle_check(const struct ofpact_bundle *, int max_ports,
44+
enum ofperr bundle_check(const struct ofpact_bundle *, ofp_port_t max_ports,
4545
const struct flow *);
4646
void bundle_to_nxast(const struct ofpact_bundle *, struct ofpbuf *of10);
4747
void bundle_parse(const char *, struct ofpbuf *ofpacts);

lib/dpif-linux.c

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ static int dpif_linux_init(void);
169169
static void open_dpif(const struct dpif_linux_dp *, struct dpif **);
170170
static bool dpif_linux_nln_parse(struct ofpbuf *, void *);
171171
static void dpif_linux_port_changed(const void *vport, void *dpif);
172-
static uint32_t dpif_linux_port_get_pid(const struct dpif *, uint32_t port_no);
172+
static uint32_t dpif_linux_port_get_pid(const struct dpif *,
173+
odp_port_t port_no);
173174

174175
static void dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *,
175176
struct ofpbuf *);
@@ -261,7 +262,7 @@ open_dpif(const struct dpif_linux_dp *dp, struct dpif **dpifp)
261262
static void
262263
destroy_channels(struct dpif_linux *dpif)
263264
{
264-
int i;
265+
unsigned int i;
265266

266267
if (dpif->epoll_fd < 0) {
267268
return;
@@ -280,7 +281,7 @@ destroy_channels(struct dpif_linux *dpif)
280281
dpif_linux_vport_init(&vport_request);
281282
vport_request.cmd = OVS_VPORT_CMD_SET;
282283
vport_request.dp_ifindex = dpif->dp_ifindex;
283-
vport_request.port_no = i;
284+
vport_request.port_no = u32_to_odp(i);
284285
vport_request.upcall_pid = &upcall_pid;
285286
dpif_linux_vport_transact(&vport_request, NULL, NULL);
286287

@@ -300,19 +301,20 @@ destroy_channels(struct dpif_linux *dpif)
300301
}
301302

302303
static int
303-
add_channel(struct dpif_linux *dpif, uint32_t port_no, struct nl_sock *sock)
304+
add_channel(struct dpif_linux *dpif, odp_port_t port_no, struct nl_sock *sock)
304305
{
305306
struct epoll_event event;
307+
uint32_t port_idx = odp_to_u32(port_no);
306308

307309
if (dpif->epoll_fd < 0) {
308310
return 0;
309311
}
310312

311313
/* We assume that the datapath densely chooses port numbers, which
312314
* can therefore be used as an index into an array of channels. */
313-
if (port_no >= dpif->uc_array_size) {
314-
int new_size = port_no + 1;
315-
int i;
315+
if (port_idx >= dpif->uc_array_size) {
316+
uint32_t new_size = port_idx + 1;
317+
uint32_t i;
316318

317319
if (new_size > MAX_PORTS) {
318320
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)
333335

334336
memset(&event, 0, sizeof event);
335337
event.events = EPOLLIN;
336-
event.data.u32 = port_no;
338+
event.data.u32 = port_idx;
337339
if (epoll_ctl(dpif->epoll_fd, EPOLL_CTL_ADD, nl_sock_fd(sock),
338340
&event) < 0) {
339341
return errno;
340342
}
341343

342-
nl_sock_destroy(dpif->channels[port_no].sock);
343-
dpif->channels[port_no].sock = sock;
344-
dpif->channels[port_no].last_poll = LLONG_MIN;
344+
nl_sock_destroy(dpif->channels[port_idx].sock);
345+
dpif->channels[port_idx].sock = sock;
346+
dpif->channels[port_idx].last_poll = LLONG_MIN;
345347

346348
return 0;
347349
}
348350

349351
static void
350-
del_channel(struct dpif_linux *dpif, uint32_t port_no)
352+
del_channel(struct dpif_linux *dpif, odp_port_t port_no)
351353
{
352354
struct dpif_channel *ch;
355+
uint32_t port_idx = odp_to_u32(port_no);
353356

354-
if (dpif->epoll_fd < 0 || port_no >= dpif->uc_array_size) {
357+
if (dpif->epoll_fd < 0 || port_idx >= dpif->uc_array_size) {
355358
return;
356359
}
357360

358-
ch = &dpif->channels[port_no];
361+
ch = &dpif->channels[port_idx];
359362
if (!ch->sock) {
360363
return;
361364
}
@@ -482,7 +485,7 @@ netdev_to_ovs_vport_type(const struct netdev *netdev)
482485

483486
static int
484487
dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
485-
uint32_t *port_nop)
488+
odp_port_t *port_nop)
486489
{
487490
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
488491
const struct netdev_tunnel_config *tnl_cfg;
@@ -541,7 +544,7 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
541544
VLOG_DBG("%s: assigning port %"PRIu32" to netlink pid %"PRIu32,
542545
dpif_name(dpif_), reply.port_no, upcall_pid);
543546
} else {
544-
if (error == EBUSY && *port_nop != UINT32_MAX) {
547+
if (error == EBUSY && *port_nop != ODPP_NONE) {
545548
VLOG_INFO("%s: requested port %"PRIu32" is in use",
546549
dpif_name(dpif_), *port_nop);
547550
}
@@ -573,7 +576,7 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
573576
}
574577

575578
static int
576-
dpif_linux_port_del(struct dpif *dpif_, uint32_t port_no)
579+
dpif_linux_port_del(struct dpif *dpif_, odp_port_t port_no)
577580
{
578581
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
579582
struct dpif_linux_vport vport;
@@ -591,7 +594,7 @@ dpif_linux_port_del(struct dpif *dpif_, uint32_t port_no)
591594
}
592595

593596
static int
594-
dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no,
597+
dpif_linux_port_query__(const struct dpif *dpif, odp_port_t port_no,
595598
const char *port_name, struct dpif_port *dpif_port)
596599
{
597600
struct dpif_linux_vport request;
@@ -622,7 +625,7 @@ dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no,
622625
}
623626

624627
static int
625-
dpif_linux_port_query_by_number(const struct dpif *dpif, uint32_t port_no,
628+
dpif_linux_port_query_by_number(const struct dpif *dpif, odp_port_t port_no,
626629
struct dpif_port *dpif_port)
627630
{
628631
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,
635638
return dpif_linux_port_query__(dpif, 0, devname, dpif_port);
636639
}
637640

638-
static int
641+
static odp_port_t
639642
dpif_linux_get_max_ports(const struct dpif *dpif OVS_UNUSED)
640643
{
641-
return MAX_PORTS;
644+
return u32_to_odp(MAX_PORTS);
642645
}
643646

644647
static uint32_t
645-
dpif_linux_port_get_pid(const struct dpif *dpif_, uint32_t port_no)
648+
dpif_linux_port_get_pid(const struct dpif *dpif_, odp_port_t port_no)
646649
{
647650
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
651+
uint32_t port_idx = odp_to_u32(port_no);
648652

649653
if (dpif->epoll_fd < 0) {
650654
return 0;
651655
} else {
652-
/* The UINT32_MAX "reserved" port number uses the "ovs-system"'s
656+
/* The ODPP_NONE "reserved" port number uses the "ovs-system"'s
653657
* channel, since it is not heavily loaded. */
654-
int idx = (port_no >= dpif->uc_array_size) ? 0 : port_no;
658+
uint32_t idx = port_idx >= dpif->uc_array_size ? 0 : port_idx;
655659
return nl_sock_pid(dpif->channels[idx].sock);
656660
}
657661
}
@@ -1562,7 +1566,7 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport,
15621566

15631567
vport->cmd = genl->cmd;
15641568
vport->dp_ifindex = ovs_header->dp_ifindex;
1565-
vport->port_no = nl_attr_get_u32(a[OVS_VPORT_ATTR_PORT_NO]);
1569+
vport->port_no = nl_attr_get_odp_port(a[OVS_VPORT_ATTR_PORT_NO]);
15661570
vport->type = nl_attr_get_u32(a[OVS_VPORT_ATTR_TYPE]);
15671571
vport->name = nl_attr_get_string(a[OVS_VPORT_ATTR_NAME]);
15681572
if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
@@ -1592,8 +1596,8 @@ dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *vport,
15921596
ovs_header = ofpbuf_put_uninit(buf, sizeof *ovs_header);
15931597
ovs_header->dp_ifindex = vport->dp_ifindex;
15941598

1595-
if (vport->port_no != UINT32_MAX) {
1596-
nl_msg_put_u32(buf, OVS_VPORT_ATTR_PORT_NO, vport->port_no);
1599+
if (vport->port_no != ODPP_NONE) {
1600+
nl_msg_put_odp_port(buf, OVS_VPORT_ATTR_PORT_NO, vport->port_no);
15971601
}
15981602

15991603
if (vport->type != OVS_VPORT_TYPE_UNSPEC) {
@@ -1624,7 +1628,7 @@ void
16241628
dpif_linux_vport_init(struct dpif_linux_vport *vport)
16251629
{
16261630
memset(vport, 0, sizeof *vport);
1627-
vport->port_no = UINT32_MAX;
1631+
vport->port_no = ODPP_NONE;
16281632
}
16291633

16301634
/* Executes 'request' in the kernel datapath. If the command fails, returns a

lib/dpif-linux.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <stdint.h>
2323
#include <linux/openvswitch.h>
2424

25+
#include "flow.h"
26+
2527
struct ofpbuf;
2628

2729
struct dpif_linux_vport {
@@ -30,7 +32,7 @@ struct dpif_linux_vport {
3032

3133
/* ovs_vport header. */
3234
int dp_ifindex;
33-
uint32_t port_no; /* UINT32_MAX if unknown. */
35+
odp_port_t port_no; /* ODPP_NONE if unknown. */
3436
enum ovs_vport_type type;
3537

3638
/* Attributes.

0 commit comments

Comments
 (0)