diff --git a/include/openflow/openflow-1.0.h b/include/openflow/openflow-1.0.h index c30fa921599..f2b90db3304 100644 --- a/include/openflow/openflow-1.0.h +++ b/include/openflow/openflow-1.0.h @@ -28,28 +28,22 @@ * 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). */ diff --git a/include/openflow/openflow-1.1.h b/include/openflow/openflow-1.1.h index ec94cee79e9..f7c2e78bca0 100644 --- a/include/openflow/openflow-1.1.h +++ b/include/openflow/openflow-1.1.h @@ -67,8 +67,8 @@ * 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 diff --git a/include/openvswitch/types.h b/include/openvswitch/types.h index 72caa5c385d..d07c1e87255 100644 --- a/include/openvswitch/types.h +++ b/include/openvswitch/types.h @@ -1,5 +1,5 @@ /* - * 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. @@ -60,4 +60,16 @@ typedef struct { 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 */ diff --git a/lib/bundle.c b/lib/bundle.c index b3821e85bd0..d1834d0e9ce 100644 --- a/lib/bundle.c +++ b/lib/bundle.c @@ -35,14 +35,14 @@ 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; } @@ -51,10 +51,10 @@ execute_ab(const struct ofpact_bundle *bundle, 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; @@ -85,10 +85,11 @@ execute_hrw(const struct ofpact_bundle *bundle, * 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: @@ -186,7 +187,7 @@ bundle_from_openflow(const struct nx_action_bundle *nab, } 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); @@ -200,7 +201,7 @@ bundle_check(const struct ofpact_bundle *bundle, int max_ports, } 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); @@ -246,7 +247,7 @@ bundle_to_nxast(const struct ofpact_bundle *bundle, struct ofpbuf *openflow) 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])); } } @@ -271,7 +272,7 @@ bundle_parse__(const char *s, char **save_ptr, bundle = ofpact_put_BUNDLE(ofpacts); for (;;) { - uint16_t slave_port; + ofp_port_t slave_port; char *slave; slave = strtok_r(NULL, ", []", save_ptr); diff --git a/lib/bundle.h b/lib/bundle.h index 2619aebad0c..3e92374176b 100644 --- a/lib/bundle.h +++ b/lib/bundle.h @@ -35,13 +35,13 @@ struct ofpbuf; * * 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); diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 2095cabad1f..fb87f8185f1 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -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 diff --git a/lib/dpif-linux.h b/lib/dpif-linux.h index 81062aa81ca..ec94ccfd63d 100644 --- a/lib/dpif-linux.h +++ b/lib/dpif-linux.h @@ -22,6 +22,8 @@ #include #include +#include "flow.h" + struct ofpbuf; struct dpif_linux_vport { @@ -30,7 +32,7 @@ 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. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 5a54627efb5..8e5e6df752d 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -104,7 +104,7 @@ struct dp_netdev { /* 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; @@ -141,15 +141,15 @@ static struct shash dp_netdevs = SHASH_INITIALIZER(&dp_netdevs); /* 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 *, @@ -218,10 +218,12 @@ create_dpif_netdev(struct dp_netdev *dp) 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; @@ -241,7 +243,7 @@ choose_port(struct dp_netdev *dp, const char *name) 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; } @@ -250,11 +252,11 @@ choose_port(struct dp_netdev *dp, const char *name) 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 @@ -275,7 +277,7 @@ create_dp_netdev(const char *name, const struct dpif_class *class, 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; @@ -379,7 +381,7 @@ dpif_netdev_get_stats(const struct dpif *dpif, struct dpif_dp_stats *stats) 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; @@ -429,7 +431,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type, } 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; @@ -437,25 +439,26 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type, 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); } @@ -463,27 +466,28 @@ dpif_netdev_port_add(struct dpif *dpif, struct netdev *netdev, } 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; } } @@ -504,7 +508,7 @@ get_port_by_name(struct dp_netdev *dp, } 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; @@ -515,7 +519,7 @@ do_del_port(struct dp_netdev *dp, uint32_t port_no) } list_remove(&port->node); - dp->ports[port->port_no] = NULL; + dp->ports[odp_to_u32(port_no)] = NULL; dp->serial++; netdev_close(port->netdev); @@ -537,7 +541,7 @@ answer_port_query(const struct dp_netdev_port *port, } 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); @@ -566,10 +570,10 @@ dpif_netdev_port_query_by_name(const struct dpif *dpif, const char *devname, 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 @@ -599,7 +603,7 @@ dpif_netdev_flow_flush(struct dpif *dpif) } struct dp_netdev_port_state { - uint32_t port_no; + odp_port_t port_no; char *name; }; @@ -616,17 +620,18 @@ dpif_netdev_port_dump_next(const struct dpif *dpif, void *state_, { 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; } } @@ -708,9 +713,7 @@ dpif_netdev_flow_from_nlattrs(const struct nlattr *key, uint32_t key_len, 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; } @@ -899,7 +902,7 @@ dpif_netdev_flow_dump_next(const struct dpif *dpif, void *state_, 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; @@ -954,7 +957,7 @@ dpif_netdev_execute(struct dpif *dpif, const struct dpif_execute *execute) 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) { @@ -1049,11 +1052,13 @@ dp_netdev_port_input(struct dp_netdev *dp, struct dp_netdev_port *port, { 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); @@ -1140,7 +1145,7 @@ dp_netdev_output_userspace(struct dp_netdev *dp, const struct ofpbuf *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; diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 666c2244eb2..d6315ed6110 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -127,10 +127,10 @@ struct dpif_class { * 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 @@ -139,14 +139,14 @@ struct dpif_class { * 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 @@ -162,7 +162,7 @@ struct dpif_class { * * 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 diff --git a/lib/dpif.c b/lib/dpif.c index 370de3c713a..4193dcbb15c 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -434,18 +434,18 @@ dpif_port_open_type(const char *datapath_type, const char *port_type) } /* 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); @@ -461,7 +461,7 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, uint32_t *port_nop) } 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; @@ -472,7 +472,7 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, uint32_t *port_nop) /* 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; @@ -530,7 +530,7 @@ dpif_port_exists(const struct dpif *dpif, const char *devname) * 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); @@ -576,7 +576,7 @@ dpif_port_query_by_name(const struct dpif *dpif, const char *devname, /* 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); @@ -586,7 +586,7 @@ dpif_get_max_ports(const struct dpif *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 @@ -595,7 +595,7 @@ dpif_get_max_ports(const struct dpif *dpif) * 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) @@ -607,7 +607,7 @@ dpif_port_get_pid(const struct dpif *dpif, uint32_t 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; diff --git a/lib/dpif.h b/lib/dpif.h index 11d7445a63f..7f1b6c942fe 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -377,8 +377,8 @@ int dpif_get_dp_stats(const struct dpif *, struct dpif_dp_stats *); 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. * @@ -386,19 +386,19 @@ int dpif_port_del(struct dpif *, uint32_t port_no); 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; diff --git a/lib/flow.c b/lib/flow.c index 3e507344c14..32ac99a6aac 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -1,5 +1,5 @@ /* - * 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. @@ -337,7 +337,7 @@ parse_icmpv6(struct ofpbuf *b, struct flow *flow) } /* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and - * 'ofp_in_port'. + * 'in_port'. * * Initializes 'packet' header pointers as follows: * @@ -357,7 +357,7 @@ parse_icmpv6(struct ofpbuf *b, struct flow *flow) */ 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; @@ -371,7 +371,9 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark, 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; @@ -498,7 +500,7 @@ flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd) 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 * diff --git a/lib/flow.h b/lib/flow.h index b07b9ed209d..a0209377358 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -68,6 +68,14 @@ struct flow_tnl { 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. * @@ -87,9 +95,7 @@ struct flow { 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. */ @@ -122,11 +128,12 @@ struct flow_metadata { 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 *); @@ -170,6 +177,42 @@ flow_hash(const struct flow *flow, uint32_t basis) 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); diff --git a/lib/learn.c b/lib/learn.c index 606ea9ed0b0..0cc562d60bb 100644 --- a/lib/learn.c +++ b/lib/learn.c @@ -355,9 +355,9 @@ learn_execute(const struct ofpact_learn *learn, const struct flow *flow, 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 diff --git a/lib/learning-switch.c b/lib/learning-switch.c index ab37dccd7a4..e786913c6db 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -1,5 +1,5 @@ /* - * 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. @@ -48,7 +48,7 @@ VLOG_DEFINE_THIS_MODULE(learning_switch); 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. */ }; @@ -460,26 +460,27 @@ process_switch_features(struct lswitch *sw, struct ofp_header *oh) 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); } } @@ -496,7 +497,7 @@ lswitch_choose_destination(struct lswitch *sw, const struct flow *flow) 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; } @@ -512,11 +513,11 @@ lswitch_choose_destination(struct lswitch *sw, const struct flow *flow) } 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; @@ -531,7 +532,7 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) { 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; @@ -541,6 +542,7 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) struct ofpbuf pkt; struct flow flow; + union flow_in_port in_port_; error = ofputil_decode_packet_in(&pi, oh); if (error) { @@ -558,7 +560,8 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) /* 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. */ @@ -569,7 +572,8 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) 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); diff --git a/lib/mac-learning.h b/lib/mac-learning.h index 1cbacfe0979..9feca00578b 100644 --- a/lib/mac-learning.h +++ b/lib/mac-learning.h @@ -49,7 +49,7 @@ struct mac_entry { /* Learned port. */ union { void *p; - uint16_t ofp_port; + ofp_port_t ofp_port; } port; }; diff --git a/lib/match.c b/lib/match.c index 512253ec2e3..6d66ebaab54 100644 --- a/lib/match.c +++ b/lib/match.c @@ -271,10 +271,10 @@ match_set_tun_flags_masked(struct match *match, uint16_t flags, uint16_t mask) } 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 @@ -916,9 +916,9 @@ match_format(const struct match *match, struct ds *s, unsigned int priority) 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) { diff --git a/lib/match.h b/lib/match.h index d435aa4ecea..0ea1f2d6bac 100644 --- a/lib/match.h +++ b/lib/match.h @@ -60,7 +60,7 @@ void match_set_tun_tos(struct match *match, uint8_t tos); 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); diff --git a/lib/meta-flow.c b/lib/meta-flow.c index f9e044ddd32..067720255fa 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -698,7 +698,7 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) 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: @@ -937,7 +937,7 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value) return true; case MFF_IN_PORT_OXM: { - uint16_t port; + ofp_port_t port; return !ofputil_port_from_ofp11(value->be32, &port); } @@ -1011,11 +1011,10 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow, 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: @@ -1198,11 +1197,11 @@ mf_set_value(const struct mf_field *mf, 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; @@ -1387,13 +1386,13 @@ mf_set_flow_value(const struct mf_field *mf, 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; } @@ -1594,8 +1593,8 @@ mf_set_wild(const struct mf_field *mf, struct match *match) 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: @@ -2012,7 +2011,7 @@ mf_random_value(const struct mf_field *mf, union mf_value *value) 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: @@ -2203,12 +2202,12 @@ static char * 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; } @@ -2219,7 +2218,7 @@ static char * 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)) { @@ -2475,7 +2474,7 @@ mf_format(const struct mf_field *mf, 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; @@ -2483,7 +2482,7 @@ mf_format(const struct mf_field *mf, /* 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 */ diff --git a/lib/netlink.c b/lib/netlink.c index c8e5905abc5..7e7884e6057 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -1,5 +1,5 @@ /* - * 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. @@ -21,6 +21,7 @@ #include #include #include "coverage.h" +#include "flow.h" #include "netlink-protocol.h" #include "ofpbuf.h" #include "timeval.h" @@ -295,6 +296,15 @@ nl_msg_put_be64(struct ofpbuf *msg, uint16_t type, ovs_be64 value) 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 @@ -570,6 +580,15 @@ nl_attr_get_be64(const struct nlattr *nla) 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. */ diff --git a/lib/netlink.h b/lib/netlink.h index a5c129ab296..afe2277ec59 100644 --- a/lib/netlink.h +++ b/lib/netlink.h @@ -68,6 +68,7 @@ void nl_msg_put_u64(struct ofpbuf *, uint16_t type, uint64_t value); 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); @@ -170,6 +171,7 @@ uint64_t nl_attr_get_u64(const struct nlattr *); 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 *); diff --git a/lib/nx-match.c b/lib/nx-match.c index ecdaa65a253..8bdd8ec9d23 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -568,12 +568,12 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match, 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))); } } diff --git a/lib/odp-util.c b/lib/odp-util.c index 2fc61e21544..d70cf171f05 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -2252,14 +2252,14 @@ ovs_to_odp_frag(uint8_t nw_frag) /* 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; @@ -2276,8 +2276,8 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow, 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, @@ -2808,10 +2808,11 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len, } 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. */ diff --git a/lib/odp-util.h b/lib/odp-util.h index d38fb82f6d4..bcde078fc7a 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -34,7 +34,8 @@ struct nlattr; 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); @@ -100,7 +101,7 @@ int odp_flow_from_string(const char *s, 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); diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index c9e000fc0b8..45d8601837d 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -42,7 +42,7 @@ output_from_openflow10(const struct ofp10_action_output *oao, 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); @@ -55,9 +55,10 @@ enqueue_from_openflow10(const struct ofp10_action_enqueue *oae, 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; } @@ -72,7 +73,7 @@ resubmit_from_openflow(const struct nx_action_resubmit *nar, 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; } @@ -88,7 +89,7 @@ resubmit_table_from_openflow(const struct nx_action_resubmit *nar, 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; } @@ -1142,8 +1143,8 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow, } 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; @@ -1157,7 +1158,8 @@ ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports, 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; } @@ -1240,7 +1242,7 @@ ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports, * 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; @@ -1339,7 +1341,7 @@ ofpact_resubmit_to_nxast(const struct ofpact_resubmit *resubmit, 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 @@ -1574,7 +1576,7 @@ ofpact_output_to_openflow10(const struct ofpact_output *output, 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); } @@ -1585,7 +1587,7 @@ ofpact_enqueue_to_openflow10(const struct ofpact_enqueue *enqueue, 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); } @@ -1929,7 +1931,7 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], /* 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: @@ -1983,7 +1985,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, uint16_t port) * 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; @@ -2064,12 +2066,12 @@ ofpact_format(const struct ofpact *a, struct ds *s) 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); diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h index 4e7fb5cd0a7..4fc40b3db7d 100644 --- a/lib/ofp-actions.h +++ b/lib/ofp-actions.h @@ -198,7 +198,7 @@ struct ofpact_null { * 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. */ }; @@ -217,7 +217,7 @@ struct ofpact_controller { * Used for OFPAT10_ENQUEUE. */ struct ofpact_enqueue { struct ofpact ofpact; - uint16_t port; + ofp_port_t port; uint32_t queue; }; @@ -247,7 +247,7 @@ struct ofpact_bundle { /* Slaves for output. */ unsigned int n_slaves; - uint16_t slaves[]; + ofp_port_t slaves[]; }; /* OFPACT_SET_VLAN_VID. @@ -379,7 +379,7 @@ struct ofpact_metadata { * 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; }; @@ -493,7 +493,7 @@ enum ofperr ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow, 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. */ @@ -507,7 +507,7 @@ void ofpacts_put_openflow11_instructions(const struct ofpact[], /* 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); diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 1c5c761e53f..1890050c638 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -135,7 +135,7 @@ parse_enqueue(char *arg, struct ofpbuf *ofpacts) } 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); } @@ -152,7 +152,7 @@ parse_output(char *arg, struct ofpbuf *ofpacts) 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; } } @@ -650,7 +650,7 @@ str_to_ofpact__(char *pos, char *act, char *arg, } return false; } else { - uint16_t port; + ofp_port_t port; if (ofputil_port_from_string(act, &port)) { ofpact_put_OUTPUT(ofpacts)->port = port; } else { @@ -1076,7 +1076,7 @@ parse_flow_monitor_request(struct ofputil_flow_monitor_request *fmr, 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 { @@ -1229,8 +1229,8 @@ parse_ofp_exact_flow(struct flow *flow, const char *s) } } - if (!flow->in_port) { - flow->in_port = OFPP_NONE; + if (!flow->in_port.ofp_port) { + flow->in_port.ofp_port = OFPP_NONE; } exit: diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 549616c9019..42fd9a6d645 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -62,7 +62,7 @@ ofp_packet_to_string(const void *data, size_t len) 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) { @@ -204,8 +204,8 @@ compare_ports(const void *a_, const void *b_) { 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; } @@ -585,7 +585,7 @@ static void print_wild(struct ds *string, const char *leader, int is_wild, 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; @@ -665,7 +665,7 @@ ofp10_match_to_string(const struct ofp10_match *om, int verbosity) } } 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, @@ -1167,7 +1167,7 @@ print_port_stat(struct ds *string, const char *leader, uint64_t stat, int more) 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); @@ -1205,7 +1205,7 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh, } 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); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 26da477aec5..90f4f35f416 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -90,7 +90,7 @@ ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc) 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)) { @@ -145,7 +145,7 @@ ofputil_match_from_ofp10_match(const struct ofp10_match *ofmatch, /* 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; @@ -190,7 +190,7 @@ ofputil_match_to_ofp10_match(const struct match *match, /* 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) { @@ -244,7 +244,7 @@ ofputil_match_to_ofp10_match(const struct match *match, /* 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); @@ -311,7 +311,7 @@ ofputil_match_from_ofp11_match(const struct ofp11_match *ofmatch, 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); @@ -466,10 +466,10 @@ ofputil_match_to_ofp11_match(const struct match *match, 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); @@ -1567,7 +1567,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, 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. */ @@ -1598,7 +1598,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, 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(); @@ -1653,7 +1653,7 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm, 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); @@ -1691,7 +1691,7 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm, 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; @@ -1713,7 +1713,7 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm, 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); @@ -1766,7 +1766,7 @@ ofputil_decode_ofpst10_flow_request(struct ofputil_flow_stats_request *fsr, { 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); @@ -1818,7 +1818,7 @@ ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr, } 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; @@ -1902,7 +1902,7 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr, 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; } @@ -1920,7 +1920,7 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr, 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; @@ -2443,7 +2443,7 @@ ofputil_decode_packet_in_finish(struct ofputil_packet_in *pin, 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; @@ -2502,7 +2502,7 @@ ofputil_decode_packet_in(struct ofputil_packet_in *pin, 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); @@ -2620,7 +2620,7 @@ ofputil_encode_packet_in(const struct ofputil_packet_in *pin, 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); @@ -2737,7 +2737,7 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po, 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) { @@ -2747,7 +2747,8 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po, 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); @@ -2834,7 +2835,7 @@ ofputil_decode_ofp10_phy_port(struct ofputil_phy_port *pp, { 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); @@ -2902,7 +2903,7 @@ ofputil_encode_ofp10_phy_port(const struct ofputil_phy_port *pp, { 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); @@ -3312,7 +3313,7 @@ ofputil_decode_port_mod(const struct ofp_header *oh, 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; @@ -3354,7 +3355,7 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm, 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); @@ -3690,7 +3691,7 @@ ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request *rq, 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); @@ -3715,7 +3716,7 @@ ofputil_append_flow_monitor_request( 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; } @@ -3923,7 +3924,7 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po, 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; } @@ -4042,22 +4043,22 @@ ofputil_frag_handling_from_string(const char *s, enum ofp_config_flags *flags) * * 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; } } @@ -4067,18 +4068,18 @@ ofputil_port_from_ofp11(ovs_be32 ofp11_port, uint16_t *ofp10_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: @@ -4092,7 +4093,7 @@ ofputil_check_output_port(uint16_t port, int max_ports) 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; @@ -4128,46 +4129,42 @@ ofputil_check_output_port(uint16_t port, int max_ports) * 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}, @@ -4190,7 +4187,7 @@ ofputil_port_from_string(const char *s, uint16_t *portp) * 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; @@ -4531,7 +4528,7 @@ ofputil_parse_key_value(char **stringp, char **keyp, char **valuep) * 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; @@ -4540,7 +4537,7 @@ ofputil_encode_dump_ports_request(enum ofp_version ofp_version, uint16_t port) 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: @@ -4563,7 +4560,7 @@ static void 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)); @@ -4647,7 +4644,7 @@ ofputil_port_stats_from_ofp10(struct ofputil_port_stats *ops, { 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)); @@ -4787,7 +4784,7 @@ ofputil_decode_port_stats(struct ofputil_port_stats *ps, struct ofpbuf *msg) * 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: @@ -4799,7 +4796,7 @@ ofputil_decode_port_stats_request(const struct ofp_header *request, 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; } @@ -4826,7 +4823,7 @@ ofputil_decode_queue_stats_request(const struct ofp_header *request, 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; @@ -4864,8 +4861,8 @@ ofputil_encode_queue_stats_request(enum ofp_version ofp_version, 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; } @@ -4895,7 +4892,7 @@ static enum ofperr 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)); @@ -5000,7 +4997,7 @@ static void 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)); diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 1c8d6cd2880..42ab88b7a73 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -32,12 +32,14 @@ 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. */ @@ -219,7 +221,7 @@ struct ofputil_flow_mod { 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. */ @@ -241,7 +243,7 @@ struct ofputil_flow_stats_request { struct match match; ovs_be64 cookie; ovs_be64 cookie_mask; - uint16_t out_port; + ofp_port_t out_port; uint8_t table_id; }; @@ -350,7 +352,7 @@ struct ofputil_packet_out { 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. */ }; @@ -390,7 +392,7 @@ enum ofputil_port_state { /* 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; @@ -498,7 +500,7 @@ struct ofpbuf *ofputil_encode_port_status(const struct ofputil_port_status *, /* 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; @@ -535,7 +537,7 @@ struct ofpbuf *ofputil_encode_table_stats_reply( 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; }; @@ -677,7 +679,7 @@ void *ofputil_put_action(enum ofputil_action_code, struct ofpbuf *buf); #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, @@ -691,23 +693,23 @@ union ofp_action *ofputil_actions_clone(const union ofp_action *, size_t n); 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; }; @@ -719,7 +721,7 @@ ofputil_encode_queue_stats_request(enum ofp_version ofp_version, 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; }; diff --git a/lib/util.c b/lib/util.c index cd4019eb7c4..a11841229b1 100644 --- a/lib/util.c +++ b/lib/util.c @@ -27,7 +27,6 @@ #include #include "byte-order.h" #include "coverage.h" -#include "openvswitch/types.h" #include "vlog.h" VLOG_DEFINE_THIS_MODULE(util); diff --git a/lib/util.h b/lib/util.h index f5589e35b5a..c436a437a8f 100644 --- a/lib/util.h +++ b/lib/util.h @@ -1,5 +1,5 @@ /* - * 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. @@ -26,6 +26,7 @@ #include #include #include "compiler.h" +#include "openvswitch/types.h" #ifndef va_copy #ifdef __va_copy diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 09519681ccc..9ddae5c2292 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -1039,7 +1039,7 @@ ofconn_send_error(const struct ofconn *ofconn, /* 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); } @@ -1646,7 +1646,7 @@ any_extras_changed(const struct connmgr *mgr, 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) { diff --git a/ofproto/connmgr.h b/ofproto/connmgr.h index 429e678229c..0242116c967 100644 --- a/ofproto/connmgr.h +++ b/ofproto/connmgr.h @@ -125,7 +125,7 @@ void ofconn_send_error(const struct ofconn *, const struct ofp_header *request, 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 *); @@ -157,7 +157,7 @@ void connmgr_set_in_band_queue(struct connmgr *, int queue_id); /* 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); @@ -173,7 +173,7 @@ struct ofmonitor { enum nx_flow_monitor_flags flags; /* Matching. */ - uint16_t out_port; + ofp_port_t out_port; uint8_t table_id; struct minimatch match; }; diff --git a/ofproto/in-band.c b/ofproto/in-band.c index ba6fc54066a..0746babea32 100644 --- a/ofproto/in-band.c +++ b/ofproto/in-band.c @@ -225,7 +225,7 @@ refresh_local(struct in_band *ib) /* 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 @@ -239,7 +239,7 @@ in_band_rule_check(const struct flow *flow, uint32_t local_odp_port, 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; } } diff --git a/ofproto/in-band.h b/ofproto/in-band.h index 4f52e003bfc..54493122aa8 100644 --- a/ofproto/in-band.h +++ b/ofproto/in-band.h @@ -21,6 +21,7 @@ #include #include #include +#include "flow.h" struct flow; struct in_band; @@ -39,7 +40,7 @@ void in_band_set_remotes(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 */ diff --git a/ofproto/netflow.c b/ofproto/netflow.c index 7efb0267833..2e32f219cb5 100644 --- a/ofproto/netflow.c +++ b/ofproto/netflow.c @@ -97,11 +97,13 @@ gen_netflow_rec(struct netflow *nf, struct netflow_flow *nf_flow, 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); @@ -275,7 +277,7 @@ netflow_flow_init(struct netflow_flow *nf_flow OVS_UNUSED) 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; diff --git a/ofproto/netflow.h b/ofproto/netflow.h index 96915456794..7e6debcd20f 100644 --- a/ofproto/netflow.h +++ b/ofproto/netflow.h @@ -1,5 +1,5 @@ /* - * 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. @@ -38,11 +38,9 @@ struct netflow_options { 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. */ @@ -51,7 +49,7 @@ struct netflow_flow { 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. */ }; diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index 9ad0eaf27d8..5d53ee08e1a 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -46,7 +46,7 @@ struct dpif_sflow_port { 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 { @@ -142,12 +142,13 @@ sflow_agent_send_packet_cb(void *ds_, SFLAgent *agent OVS_UNUSED, } 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; } @@ -167,7 +168,7 @@ sflow_agent_get_counters(void *ds_, SFLPoller *poller, 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; } @@ -338,12 +339,12 @@ dpif_sflow_add_poller(struct dpif_sflow *ds, struct dpif_sflow_port *dsp) 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; @@ -362,7 +363,7 @@ dpif_sflow_add_port(struct dpif_sflow *ds, struct ofport *ofport, 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) { @@ -382,7 +383,7 @@ dpif_sflow_del_port__(struct dpif_sflow *ds, struct dpif_sflow_port *dsp) } 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) { @@ -488,7 +489,7 @@ dpif_sflow_set_options(struct dpif_sflow *ds, 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; @@ -496,7 +497,7 @@ dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *ds, 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; diff --git a/ofproto/ofproto-dpif-sflow.h b/ofproto/ofproto-dpif-sflow.h index 02a0f179c9b..d0f83bce36f 100644 --- a/ofproto/ofproto-dpif-sflow.h +++ b/ofproto/ofproto-dpif-sflow.h @@ -38,8 +38,8 @@ void dpif_sflow_clear(struct dpif_sflow *); 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 *); @@ -47,9 +47,10 @@ 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 */ diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 2c902e205af..a52a8cffecb 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -80,7 +80,7 @@ struct xlate_ctx { 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. */ }; @@ -100,13 +100,13 @@ static void do_xlate_actions(const struct ofpact *, size_t ofpacts_len, 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); @@ -130,7 +130,7 @@ vlan_is_mirrored(const struct ofmirror *m, int vlan) } 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; @@ -183,7 +183,7 @@ add_mirror_actions(struct xlate_ctx *ctx, const struct flow *orig_flow) 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; @@ -219,7 +219,7 @@ add_mirror_actions(struct xlate_ctx *ctx, const struct flow *orig_flow) 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; } @@ -553,7 +553,7 @@ xlate_normal(struct xlate_ctx *ctx) 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"); @@ -659,7 +659,7 @@ compose_sample_action(const struct ofproto_dpif *ofproto, 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; @@ -694,18 +694,18 @@ static size_t 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); @@ -738,7 +738,7 @@ compose_ipfix_action(const struct ofproto_dpif *ofproto, 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; } @@ -757,7 +757,7 @@ add_sflow_action(struct xlate_ctx *ctx) { 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; } @@ -829,7 +829,7 @@ process_special(struct xlate_ctx *ctx, const struct flow *flow, } 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); @@ -838,7 +838,7 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t 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 @@ -862,7 +862,7 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, 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); @@ -873,13 +873,13 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, 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; } @@ -913,7 +913,7 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, */ 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 */ } @@ -929,7 +929,7 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, &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)) { @@ -946,11 +946,11 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, 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++; @@ -965,7 +965,7 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, } 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); } @@ -1014,17 +1014,17 @@ ctx_rule_hooks(struct xlate_ctx *ctx, struct rule_dpif *rule, 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); @@ -1032,7 +1032,7 @@ xlate_table_action(struct xlate_ctx *ctx, /* 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); @@ -1060,12 +1060,12 @@ static void 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; @@ -1082,9 +1082,9 @@ flood_packets(struct xlate_ctx *ctx, bool all) 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; } @@ -1260,18 +1260,19 @@ compose_dec_mpls_ttl_action(struct xlate_ctx *ctx) 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); @@ -1289,7 +1290,7 @@ xlate_output_action(struct xlate_ctx *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"); @@ -1317,7 +1318,8 @@ xlate_output_reg_action(struct xlate_ctx *ctx, 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); } } @@ -1325,7 +1327,7 @@ static void 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; @@ -1340,8 +1342,8 @@ xlate_enqueue_action(struct xlate_ctx *ctx, /* 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; } @@ -1374,7 +1376,7 @@ xlate_set_queue_action(struct xlate_ctx *ctx, uint32_t queue_id) } 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; @@ -1399,12 +1401,12 @@ static void 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); } @@ -1970,17 +1972,17 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) } } - 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; } diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 9ee9b330aab..f5f0cd0fe20 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -37,7 +37,7 @@ struct xlate_out { 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]; diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 3ae3cb868b9..6fa7894d417 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -277,17 +277,17 @@ struct priority_to_dscp { 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) @@ -396,7 +396,7 @@ static struct shash all_dpif_backers = SHASH_INITIALIZER(&all_dpif_backers); 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 @@ -584,17 +584,18 @@ type_run(const char *type) } 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; @@ -603,7 +604,7 @@ type_run(const char *type) } 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); @@ -877,7 +878,7 @@ close_dpif_backer(struct dpif_backer *backer) /* 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 @@ -1003,7 +1004,7 @@ construct(struct ofproto *ofproto_) { 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; @@ -1013,7 +1014,8 @@ construct(struct ofproto *ofproto_) } 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; @@ -1469,7 +1471,7 @@ port_construct(struct ofport *port_) * 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; } @@ -1497,7 +1499,7 @@ port_construct(struct ofport *port_) } 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); @@ -1535,7 +1537,7 @@ port_destruct(struct ofport *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); } @@ -2178,7 +2180,7 @@ bundle_del_port(struct ofport_dpif *port) } 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; @@ -2821,14 +2823,14 @@ set_mac_table_config(struct ofproto *ofproto_, unsigned int idle_time, /* 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; @@ -3025,7 +3027,7 @@ port_add(struct ofproto *ofproto_, struct netdev *netdev) 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); @@ -3033,7 +3035,8 @@ port_add(struct ofproto *ofproto_, struct netdev *netdev) 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)); } } @@ -3046,7 +3049,7 @@ port_add(struct ofproto *ofproto_, struct netdev *netdev) } 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); @@ -3292,8 +3295,8 @@ static void 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 @@ -3600,7 +3603,7 @@ static int 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; @@ -3613,13 +3616,13 @@ ofproto_receive(const struct dpif_backer *backer, struct ofpbuf *packet, } 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; } @@ -3694,7 +3697,7 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls, 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; @@ -3734,7 +3737,7 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls, 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); @@ -3838,7 +3841,7 @@ handle_sflow_upcall(struct dpif_backer *backer, 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) @@ -4383,7 +4386,7 @@ execute_odp_actions(struct ofproto_dpif *ofproto, const struct flow *flow, 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); @@ -4481,7 +4484,7 @@ facet_account(struct facet *facet) 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); @@ -4804,7 +4807,7 @@ facet_push_stats(struct facet *facet, bool may_learn) 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); } @@ -5163,9 +5166,10 @@ rule_dpif_miss_rule(struct ofproto_dpif *ofproto, const struct flow *flow) { 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; } @@ -5337,13 +5341,15 @@ send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet) 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); @@ -5400,7 +5406,8 @@ compose_slow_path(const struct ofproto_dpif *ofproto, const struct flow *flow, 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, @@ -5420,7 +5427,8 @@ put_userspace_action(const struct ofproto_dpif *ofproto, 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); } @@ -5596,7 +5604,8 @@ packet_out(struct ofproto *ofproto_, struct ofpbuf *packet, 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); @@ -5931,6 +5940,9 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[], 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); @@ -5939,7 +5951,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[], /* 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); } } @@ -6204,13 +6216,13 @@ dpif_show_backer(const struct dpif_backer *backer, struct ds *ds) 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:"); @@ -6437,7 +6449,7 @@ ofproto_dpif_unixctl_init(void) * 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_); @@ -6469,9 +6481,9 @@ set_realdev(struct ofport *ofport_, uint16_t realdev_ofp_port, int vid) } 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 @@ -6481,9 +6493,9 @@ hash_realdev_vid(uint16_t realdev_ofp_port, int vid) * * 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); @@ -6502,11 +6514,12 @@ vsp_realdev_to_vlandev(const struct ofproto_dpif *ofproto, } 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; @@ -6525,9 +6538,9 @@ vlandev_find(const struct ofproto_dpif *ofproto, uint16_t vlandev_ofp_port) * 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; @@ -6552,17 +6565,17 @@ vsp_vlandev_to_realdev(const struct ofproto_dpif *ofproto, 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; } @@ -6586,7 +6599,7 @@ vsp_remove(struct ofport_dpif *port) } 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); @@ -6597,7 +6610,7 @@ vsp_add(struct ofport_dpif *port, uint16_t realdev_ofp_port, int vid) 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; @@ -6610,20 +6623,20 @@ vsp_add(struct ofport_dpif *port, uint16_t realdev_ofp_port, int vid) } } -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; @@ -6633,8 +6646,8 @@ odp_port_to_ofport(const struct dpif_backer *backer, uint32_t odp_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; diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 12a9d7e437d..b9f5eab4534 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -127,7 +127,7 @@ struct ofport_dpif { 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. */ @@ -151,7 +151,7 @@ struct ofport_dpif { * 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; }; @@ -228,12 +228,13 @@ mirror_mask_ffs(mirror_mask_t mask) } 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 *, @@ -260,9 +261,9 @@ bool stp_should_process_flow(const struct flow *, struct flow_wildcards *); 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); diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 41b589f5f9f..565cb01c12e 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -63,8 +63,8 @@ struct ofproto { 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; @@ -103,10 +103,10 @@ struct ofproto { }; 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". * @@ -117,7 +117,7 @@ struct ofport { 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; @@ -248,12 +248,12 @@ void ofproto_rule_update_used(struct rule *, long long int used); 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 *); @@ -694,7 +694,7 @@ struct ofproto_class { * 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, @@ -1320,7 +1320,7 @@ struct ofproto_class { * 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; diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index eabe850a604..afd8e170c76 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -449,7 +449,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type, /* 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. */ @@ -498,9 +498,9 @@ ofproto_init_tables(struct ofproto *ofproto, int n_tables) * 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; } @@ -707,7 +707,7 @@ ofproto_get_stp_status(struct ofproto *ofproto, * * 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); @@ -728,7 +728,7 @@ ofproto_port_set_stp(struct ofproto *ofproto, uint16_t 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); @@ -753,7 +753,7 @@ ofproto_port_get_stp_status(struct ofproto *ofproto, uint16_t 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) { @@ -774,7 +774,7 @@ ofproto_port_set_queues(struct ofproto *ofproto, uint16_t ofp_port, /* 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) { @@ -789,7 +789,7 @@ ofproto_port_clear_cfm(struct ofproto *ofproto, uint16_t ofp_port) * * 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; @@ -818,7 +818,7 @@ ofproto_port_set_cfm(struct ofproto *ofproto, uint16_t ofp_port, /* 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; @@ -846,7 +846,7 @@ ofproto_port_set_bfd(struct ofproto *ofproto, uint16_t ofp_port, * 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); @@ -860,7 +860,7 @@ ofproto_port_get_bfd_status(struct ofproto *ofproto, uint16_t 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 @@ -1497,16 +1497,17 @@ ofproto_port_open_type(const char *datapath_type, const char *port_type) * '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) { @@ -1542,7 +1543,7 @@ ofproto_port_query_by_name(const struct ofproto *ofproto, const char *devname, /* 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) : ""; @@ -1679,43 +1680,48 @@ reinit_ports(struct ofproto *p) 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)); } } @@ -1806,7 +1812,8 @@ ofport_install(struct ofproto *p, 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); @@ -1882,7 +1889,7 @@ ofproto_port_set_state(struct ofport *port, enum ofputil_port_state state) } 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) { @@ -1926,12 +1933,13 @@ ofport_destroy(struct ofport *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; } @@ -1968,6 +1976,7 @@ update_port(struct ofproto *ofproto, const char *name) 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)) { @@ -2029,7 +2038,8 @@ init_ports(struct ofproto *p) 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); @@ -2153,7 +2163,7 @@ ofproto_rule_destroy(struct rule *rule) /* 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)); @@ -2162,7 +2172,7 @@ ofproto_rule_has_out_port(const struct rule *rule, uint16_t 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; @@ -2191,13 +2201,15 @@ ofoperation_has_out_port(const struct ofoperation *op, uint16_t out_port) * * 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); } @@ -2358,6 +2370,7 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) 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); @@ -2373,7 +2386,8 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) 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; } @@ -2391,7 +2405,8 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) } /* 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, @@ -2579,7 +2594,7 @@ handle_port_stats_request(struct ofconn *ofconn, 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); @@ -2748,7 +2763,7 @@ static enum ofperr 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; @@ -2825,7 +2840,7 @@ static enum ofperr 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; @@ -3008,7 +3023,7 @@ ofproto_get_netflow_ids(const struct ofproto *ofproto, * 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); @@ -4331,7 +4346,7 @@ ofopgroup_complete(struct ofopgroup *group) 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); @@ -5088,8 +5103,8 @@ ofproto_has_vlan_usage_changed(const struct ofproto *ofproto) * 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; diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 5f8244c5a0e..2609c941ff6 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -158,7 +158,7 @@ void ofproto_parse_name(const char *name, char **dp_name, char **dp_type); 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); @@ -185,7 +185,7 @@ void ofproto_get_memory_usage(const struct ofproto *, struct simap *); 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 *); @@ -218,8 +218,8 @@ int ofproto_port_dump_done(struct ofproto_port_dump *); 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, @@ -255,21 +255,21 @@ int ofproto_set_stp(struct ofproto *, const struct ofproto_stp_settings *); 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); @@ -298,7 +298,7 @@ enum port_vlan_mode { 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 */ @@ -317,7 +317,7 @@ struct ofproto_bundle_settings { * 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, @@ -406,7 +406,8 @@ struct ofproto_cfm_status { 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 *); /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.) @@ -418,8 +419,8 @@ bool ofproto_port_get_cfm_status(const struct ofproto *, uint16_t ofp_port, 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 } diff --git a/ofproto/pinsched.c b/ofproto/pinsched.c index 57e8e2327b3..4c5f3e8369a 100644 --- a/ofproto/pinsched.c +++ b/ofproto/pinsched.c @@ -21,6 +21,7 @@ #include #include #include +#include "flow.h" #include "hash.h" #include "hmap.h" #include "ofpbuf.h" @@ -35,7 +36,7 @@ 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'. */ }; @@ -101,9 +102,9 @@ pinqueue_destroy(struct pinsched *ps, struct pinqueue *q) } 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) { @@ -184,7 +185,7 @@ get_token(struct pinsched *ps) } 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) { diff --git a/ofproto/pinsched.h b/ofproto/pinsched.h index 061cb01a090..06b22f44176 100644 --- a/ofproto/pinsched.h +++ b/ofproto/pinsched.h @@ -18,6 +18,7 @@ #define PINSCHED_H_H 1 #include +#include "flow.h" struct ofpbuf; @@ -27,7 +28,7 @@ void pinsched_get_limits(const struct pinsched *, 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 *); diff --git a/ofproto/pktbuf.c b/ofproto/pktbuf.c index 2ec1f0de8d0..65fcef6800d 100644 --- a/ofproto/pktbuf.c +++ b/ofproto/pktbuf.c @@ -51,7 +51,7 @@ struct packet { struct ofpbuf *buffer; uint32_t cookie; long long int timeout; - uint16_t in_port; + ofp_port_t in_port; }; struct pktbuf { @@ -104,7 +104,7 @@ make_id(unsigned int buffer_idx, unsigned int cookie) * 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; @@ -161,7 +161,7 @@ pktbuf_get_null(void) * 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. * @@ -171,7 +171,7 @@ pktbuf_get_null(void) * 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; @@ -218,7 +218,7 @@ pktbuf_retrieve(struct pktbuf *pb, uint32_t id, struct ofpbuf **bufferp, error: *bufferp = NULL; if (in_port) { - *in_port = UINT16_MAX; + *in_port = OFPP_NONE; } return error; } diff --git a/ofproto/pktbuf.h b/ofproto/pktbuf.h index ec99aead3ac..eb1b1fff315 100644 --- a/ofproto/pktbuf.h +++ b/ofproto/pktbuf.h @@ -30,10 +30,10 @@ int pktbuf_capacity(void); 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 *); diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index 636c5492e89..dedfca89257 100644 --- a/ofproto/tunnel.c +++ b/ofproto/tunnel.c @@ -36,7 +36,7 @@ struct tnl_match { 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; @@ -71,7 +71,7 @@ static void tnl_port_mod_log(const struct tnl_port *, const char *action); 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; @@ -118,7 +118,7 @@ tnl_port_add__(const struct ofport *ofport, uint32_t odp_port, * 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); } @@ -129,7 +129,7 @@ tnl_port_add(const struct ofport *ofport, uint32_t odp_port) * '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; @@ -173,7 +173,7 @@ tnl_port_receive(const struct flow *flow) 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; @@ -210,9 +210,9 @@ tnl_port_receive(const struct flow *flow) /* 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) { @@ -220,7 +220,7 @@ tnl_port_send(const struct tnl_port *tnl_port, struct flow *flow, 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); diff --git a/ofproto/tunnel.h b/ofproto/tunnel.h index 803e2d94d74..343eb9697a2 100644 --- a/ofproto/tunnel.h +++ b/ofproto/tunnel.h @@ -31,15 +31,15 @@ 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 diff --git a/tests/test-bundle.c b/tests/test-bundle.c index c4759912511..0e7525c3877 100644 --- a/tests/test-bundle.c +++ b/tests/test-bundle.c @@ -31,7 +31,7 @@ #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; @@ -43,7 +43,7 @@ struct slave_group { }; 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; @@ -57,7 +57,7 @@ slave_lookup(struct slave_group *sg, uint16_t slave_id) } static bool -slave_enabled_cb(uint16_t slave_id, void *aux) +slave_enabled_cb(ofp_port_t slave_id, void *aux) { struct slave *slave; @@ -122,7 +122,7 @@ main(int argc, char *argv[]) /* 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. "); @@ -138,7 +138,7 @@ main(int argc, char *argv[]) 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 @@ -186,13 +186,13 @@ main(int argc, char *argv[]) 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++; diff --git a/tests/test-classifier.c b/tests/test-classifier.c index f6164947b60..cd081a594ab 100644 --- a/tests/test-classifier.c +++ b/tests/test-classifier.c @@ -240,8 +240,9 @@ match(const struct cls_rule *wild_, const struct flow *fixed) 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(); } @@ -298,7 +299,7 @@ static ovs_be64 tun_id_values[] = { 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) }; @@ -410,7 +411,8 @@ compare_classifiers(struct classifier *cls, struct tcls *tcls) 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)]; @@ -546,7 +548,7 @@ make_rule(int wc_fields, unsigned int priority, int value_pat) } 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(); } diff --git a/tests/test-flows.c b/tests/test-flows.c index c77372fe3ce..8308bf85843 100644 --- a/tests/test-flows.c +++ b/tests/test-flows.c @@ -58,7 +58,7 @@ main(int argc OVS_UNUSED, char *argv[]) struct ofp10_match extracted_match; struct match match; struct flow flow; - + union flow_in_port in_port_; n++; retval = pcap_read(pcap, &packet); @@ -68,7 +68,8 @@ main(int argc OVS_UNUSED, char *argv[]) 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); diff --git a/tests/test-odp.c b/tests/test-odp.c index 3bb3a0cb8aa..b1d2853ec8c 100644 --- a/tests/test-odp.c +++ b/tests/test-odp.c @@ -73,7 +73,7 @@ parse_keys(bool wc_keys) /* 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", diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c index c82171afb84..a87a30514ef 100644 --- a/utilities/ovs-dpctl.c +++ b/utilities/ovs-dpctl.c @@ -308,7 +308,7 @@ dpctl_add_if(int argc OVS_UNUSED, char *argv[]) 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; @@ -335,7 +335,7 @@ dpctl_add_if(int argc OVS_UNUSED, char *argv[]) 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); } @@ -388,7 +388,7 @@ dpctl_set_if(int argc, char *argv[]) char *type = NULL; const char *name; struct smap args; - uint32_t port_no; + odp_port_t port_no; char *option; int error; @@ -441,7 +441,7 @@ dpctl_set_if(int argc, char *argv[]) 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)); @@ -476,7 +476,7 @@ dpctl_set_if(int argc, char *argv[]) } 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; @@ -500,11 +500,11 @@ dpctl_del_if(int argc OVS_UNUSED, char *argv[]) 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; diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 48f0fbf4a8f..28e3863b26f 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -632,7 +632,7 @@ ofctl_dump_tables(int argc OVS_UNUSED, char *argv[]) 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; @@ -670,7 +670,7 @@ fetch_port_by_features(const char *vconn_name, } 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; @@ -685,7 +685,7 @@ fetch_port_by_features(const char *vconn_name, 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; @@ -729,8 +729,8 @@ fetch_port_by_stats(const char *vconn_name, } 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; } @@ -746,6 +746,16 @@ fetch_port_by_stats(const char *vconn_name, 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 @@ -754,13 +764,13 @@ static void 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 @@ -779,10 +789,10 @@ fetch_ofputil_phy_port(const char *vconn_name, const char *port_name, /* 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; @@ -1489,7 +1499,7 @@ ofctl_dump_ports(int argc, char *argv[]) { 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; diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 35138105eaf..6f573df8905 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -67,13 +67,13 @@ struct if_cfg { 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 { @@ -86,7 +86,7 @@ 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. */ @@ -245,7 +245,8 @@ static bool mirror_configure(struct mirror *); 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 *, @@ -255,9 +256,9 @@ static struct iface *iface_lookup(const struct bridge *, const char *name); 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 *); @@ -265,7 +266,7 @@ static void iface_refresh_cfm_stats(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.) * @@ -1277,13 +1278,14 @@ add_del_bridges(const struct ovsrec_open_vswitch *cfg) } 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); } @@ -1318,7 +1320,7 @@ bridge_refresh_one_ofp_port(struct bridge *br, { 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) { @@ -1421,7 +1423,7 @@ bridge_refresh_ofp_port(struct bridge *br) 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; @@ -1449,7 +1451,7 @@ iface_do_create(const struct bridge *br, } 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) { @@ -1485,7 +1487,7 @@ iface_do_create(const struct bridge *br, * * 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; @@ -1547,7 +1549,7 @@ iface_create(struct bridge *br, struct if_cfg *if_cfg, uint16_t ofp_port) 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); @@ -3291,7 +3293,7 @@ iface_configure_lacp(struct iface *iface, struct lacp_slave_settings *s) 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) { @@ -3479,12 +3481,13 @@ if_cfg_lookup(const struct bridge *br, const char *name) } 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; } @@ -3520,10 +3523,10 @@ iface_set_mac(struct iface *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); } @@ -3709,11 +3712,13 @@ iface_is_synthetic(const struct iface *iface) 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; } @@ -4091,7 +4096,7 @@ static void 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;