[ovs-dev] [PATCH V2] feature: Create specific types for ofp and odp port

Alex Wang alexw at nicira.com
Mon Jun 10 15:50:40 UTC 2013


Subject: [PATCH] This patch implements "ofp_is_less_than()" and use it
to replace the PORT_COMPARE() function for port comparison.
Date: Mon, 10 Jun 2013 09:05:50 -0700
Message-Id: <1370880350-22000-1-git-send-email-alexw at nicira.com>
X-Mailer: git-send-email 1.7.9.5

This patch implements "ofp_is_less_than()" and use it to replace the
PORT_COMPARE() function for port comparison.

Signed-off-by: Alex Wang <alexw at nicira.com>

---

This patch is for addressing the "REMAINING ISSUE" in previous patch.
Want to hear more comments, thanks.

---
 lib/dpif-netdev.c     |    5 +++--
 lib/flow.h            |   39 ++++++++++++++++++++++++++++++---------
 lib/learn.c           |    2 +-
 lib/learning-switch.c |    2 +-
 lib/ofp-actions.c     |    6 +++---
 lib/ofp-print.c       |    5 +++--
 lib/ofp-util.c        |   12 ++++++------
 ofproto/ofproto.c     |   15 ++++++++-------
 8 files changed, 55 insertions(+), 31 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index b2b5a61..7232576 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -475,7 +475,8 @@ dpif_netdev_port_del(struct dpif *dpif, odp_port_t port_no)
 static bool
 is_valid_port_number(odp_port_t port_no)
 {
-    return PORT_COMPARE(port_no, <, MAX_PORTS);
+    uint32_t port_no_ = (OVS_FORCE uint32_t) port_no;
+    return port_no_ < MAX_PORTS;
 }

 static int
@@ -715,7 +716,7 @@ dpif_netdev_flow_from_nlattrs(const struct nlattr
*key, uint32_t key_len,
         return EINVAL;
     }

-    if (PORT_COMPARE(flow->in_port.odp_port, >=, MAX_PORTS)) {
+    if (flow->in_port.port32 >= MAX_PORTS) {
         return EINVAL;
     }

diff --git a/lib/flow.h b/lib/flow.h
index 02ba9b1..29ba7eb 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -57,12 +57,6 @@ BUILD_ASSERT_DECL(FLOW_NW_FRAG_LATER == NX_IP_FRAG_LATER);
 #define FLOW_TNL_F_CSUM (1 << 1)
 #define FLOW_TNL_F_KEY (1 << 2)

-/* Cast both left and right values to 'uint32_t' using the OVS_FORCE attribute
- * macro. Then, compare using the provided rational operator. */
-#define PORT_COMPARE(L_OPERAND, OPERATOR, R_OPERAND)     \
-    (((OVS_FORCE uint32_t) L_OPERAND) OPERATOR		 \
-     ((OVS_FORCE uint32_t) R_OPERAND))
-
 const char *flow_tun_flag_to_string(uint32_t flags);

 struct flow_tnl {
@@ -207,6 +201,14 @@ static inline int
ofp11_port_to_ofp_port(ofp11_port_t ofp11_port,
 static inline void ofp_port_to_ofp11_port(ofp_port_t ofp_port,
                                           ofp11_port_t *ofp11_portp);

+static inline bool ofp_port_is_less_than(ofp_port_t ofp_port,
+                                         ofp_port_t limit);
+static inline bool odp_port_is_less_than(odp_port_t odp_port,
+                                         odp_port_t limit);
+static inline bool ofp11_port_is_less_than(ofp11_port_t ofp11_port,
+                                           ofp11_port_t limit);
+
+
 static inline ovs_be16
 ofp_htons(ofp_port_t ofp_port)
 {
@@ -280,9 +282,10 @@ odp_port_increment(odp_port_t *odp_portp, uint32_t incr)
 static inline int
 ofp11_port_to_ofp_port(ofp11_port_t ofp11_port, ofp_port_t *ofp_portp)
 {
-    if (PORT_COMPARE(ofp11_port, <, OFPP_MAX)) {
+    if (ofp11_port_is_less_than(ofp11_port,
+                                (OVS_FORCE ofp11_port_t) OFPP_MAX)) {
         *ofp_portp = (OVS_FORCE ofp_port_t) ofp11_port;
-    } else if (PORT_COMPARE(ofp11_port, >=, OFPP11_MAX)) {
+    } else if (!ofp11_port_is_less_than(ofp11_port, OFPP11_MAX)) {
         *ofp_portp = (OVS_FORCE ofp_port_t)((OVS_FORCE uint32_t)ofp11_port
                                             - OFPP11_OFFSET);
     } else {
@@ -296,7 +299,7 @@ ofp11_port_to_ofp_port(ofp11_port_t ofp11_port,
ofp_port_t *ofp_portp)
 static inline void
 ofp_port_to_ofp11_port(ofp_port_t ofp_port, ofp11_port_t *ofp11_portp)
 {
-    if (PORT_COMPARE(ofp_port, <, OFPP_MAX)) {
+    if (ofp_port_is_less_than(ofp_port, OFPP_MAX)) {
         *ofp11_portp = (OVS_FORCE ofp11_port_t) ofp_port;
     } else {
         *ofp11_portp = (OVS_FORCE ofp11_port_t) ((OVS_FORCE uint32_t)ofp_port
@@ -304,6 +307,24 @@ ofp_port_to_ofp11_port(ofp_port_t ofp_port,
ofp11_port_t *ofp11_portp)
     }
 }

+static inline bool
+ofp_port_is_less_than(ofp_port_t ofp_port, ofp_port_t limit)
+{
+    return (OVS_FORCE uint16_t) ofp_port < (OVS_FORCE uint16_t) limit;
+}
+
+static inline
+bool odp_port_is_less_than(odp_port_t odp_port, odp_port_t limit)
+{
+    return (OVS_FORCE uint32_t) odp_port < (OVS_FORCE uint32_t) limit;
+}
+
+static inline bool
+ofp11_port_is_less_than(ofp11_port_t ofp11_port, ofp11_port_t limit)
+{
+    return (OVS_FORCE uint32_t) ofp11_port < (OVS_FORCE uint32_t) limit;
+}
+
 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 964c06c..5fb9299 100644
--- a/lib/learn.c
+++ b/lib/learn.c
@@ -357,7 +357,7 @@ learn_execute(const struct ofpact_learn *learn,
const struct flow *flow,
                 || is_all_zeros(value.u8, sizeof value - 2)) {
                 ofp_port_t port = ofp_ntohs(value.be16[7]);

-                if (PORT_COMPARE(port, <, OFPP_MAX)
+                if (ofp_port_is_less_than(port, 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 94c4267..60a0307 100644
--- a/lib/learning-switch.c
+++ b/lib/learning-switch.c
@@ -573,7 +573,7 @@ process_packet_in(struct lswitch *sw, const struct
ofp_header *oh)
     if (out_port == OFPP_NONE) {
         /* No actions. */
     } else if (queue_id == UINT32_MAX
-               || PORT_COMPARE(out_port, >=, OFPP_MAX)) {
+               || !ofp_port_is_less_than(out_port, OFPP_MAX)) {
         ofpact_put_OUTPUT(&ofpacts)->port = out_port;
     } else {
         struct ofpact_enqueue *enqueue = ofpact_put_ENQUEUE(&ofpacts);
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 77cee33..96ae745 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -57,7 +57,7 @@ enqueue_from_openflow10(const struct
ofp10_action_enqueue *oae,
     enqueue = ofpact_put_ENQUEUE(out);
     enqueue->port = ofp_ntohs(oae->port);
     enqueue->queue = ntohl(oae->queue_id);
-    if (PORT_COMPARE(enqueue->port, >=, OFPP_MAX)
+    if (!ofp_port_is_less_than(enqueue->port, OFPP_MAX)
         && enqueue->port != OFPP_IN_PORT
         && enqueue->port != OFPP_LOCAL) {
         return OFPERR_OFPBAC_BAD_OUT_PORT;
@@ -1158,7 +1158,7 @@ ofpact_check__(const struct ofpact *a, const
struct flow *flow,

     case OFPACT_ENQUEUE:
         enqueue = ofpact_get_ENQUEUE(a);
-        if (PORT_COMPARE(enqueue->port, >=, max_ports)
+        if (!ofp_port_is_less_than(enqueue->port, max_ports)
             && enqueue->port != OFPP_IN_PORT
             && enqueue->port != OFPP_LOCAL) {
             return OFPERR_OFPBAC_BAD_OUT_PORT;
@@ -2071,7 +2071,7 @@ ofpact_format(const struct ofpact *a, struct ds *s)
     switch (a->type) {
     case OFPACT_OUTPUT:
         port = ofpact_get_OUTPUT(a)->port;
-        if (PORT_COMPARE(port, <, OFPP_MAX)) {
+        if (ofp_port_is_less_than(port, OFPP_MAX)) {
             ds_put_format(s, "output:%"PRIu16, port);
         } else {
             ofputil_format_port(port, s);
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 6c534b6..7a6b9bd 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -205,7 +205,8 @@ compare_ports(const void *a_, const void *b_)
     ofp_port_t ap = a->port_no;
     ofp_port_t bp = b->port_no;

-    return PORT_COMPARE(ap, <, bp) ? -1 : PORT_COMPARE(ap, >, bp);
+    return ofp_port_is_less_than(ap, bp) ? -1
+           : !(ap == bp);
 }

 static void
@@ -1198,7 +1199,7 @@ ofp_print_ofpst_port_reply(struct ds *string,
const struct ofp_header *oh,
         }

         ds_put_cstr(string, "  port ");
-        if (PORT_COMPARE(ps.port_no, <, 10)) {
+        if (ofp_port_is_less_than(ps.port_no, (OVS_FORCE ofp_port_t) 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 dd6655d..d73f8ab 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -2740,7 +2740,7 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
         NOT_REACHED();
     }

-    if (PORT_COMPARE(po->in_port, >=, OFPP_MAX)
+    if (!ofp_port_is_less_than(po->in_port, 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,
@@ -4085,7 +4085,7 @@ ofputil_check_output_port(ofp_port_t port,
ofp_port_t max_ports)
         return 0;

     default:
-        if (PORT_COMPARE(port, <, max_ports)) {
+        if (ofp_port_is_less_than(port, max_ports)) {
             return 0;
         }
         return OFPERR_OFPBAC_BAD_OUT_PORT;
@@ -4127,13 +4127,13 @@ ofputil_port_from_string(const char *s,
ofp_port_t *portp)

     *portp = 0;
     if (str_to_uint(s, 10, &port32)) {
-        if (PORT_COMPARE(port32, <, OFPP_MAX)) {
+        if (port32 < (OVS_FORCE uint16_t) OFPP_MAX) {
             /* Pass. */
-        } else if (PORT_COMPARE(port32, <, OFPP_FIRST_RESV)) {
+        } else if (port32 < (OVS_FORCE uint16_t) 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);
-        } else if (PORT_COMPARE(port32, <=, OFPP_LAST_RESV)) {
+        } else if (port32 <= (OVS_FORCE uint16_t) OFPP_LAST_RESV) {
             struct ds msg;

             ds_init(&msg);
@@ -4142,7 +4142,7 @@ ofputil_port_from_string(const char *s, ofp_port_t *portp)
                            "compatibility with future versions of OpenFlow",
                            ds_cstr(&msg), port32);
             ds_destroy(&msg);
-        } else if (PORT_COMPARE(port32, <, OFPP11_MAX)) {
+        } else if (port32 < (OVS_FORCE uint32_t) OFPP11_MAX) {
             VLOG_WARN("port %u is outside the supported range 0 through "
                       "%"PRIx16" or 0x%x through 0x%"PRIx32, port32,
                       UINT16_MAX, (OVS_FORCE uint32_t) OFPP11_MAX, UINT32_MAX);
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 658931c..e8318cc 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -500,7 +500,8 @@ ofproto_init_tables(struct ofproto *ofproto, int n_tables)
 void
 ofproto_init_max_ports(struct ofproto *ofproto, ofp_port_t max_ports)
 {
-    ovs_assert(PORT_COMPARE(max_ports, <=, OFPP_MAX));
+    ovs_assert(ofp_port_is_less_than(max_ports, OFPP_MAX)
+               || max_ports == OFPP_MAX);
     ofproto->max_ports = max_ports;
 }

@@ -1693,7 +1694,7 @@ alloc_ofp_port(struct ofproto *ofproto, const
char *netdev_name)
                                                 netdev_name);
     ofp_port = ofp_port ? ofp_port : OFPP_NONE;

-    if (PORT_COMPARE(ofp_port, >=, ofproto->max_ports)
+    if (!ofp_port_is_less_than(ofp_port, ofproto->max_ports)
         || bitmap_is_set(ofproto->ofp_port_ids,
                          (OVS_FORCE uint16_t) ofp_port)) {
         /* Search for a free OpenFlow port number.  We try not to
@@ -1701,8 +1702,8 @@ alloc_ofp_port(struct ofproto *ofproto, const
char *netdev_name)
          * flows. */
         for (;;) {
             ofp_port_increment(&(ofproto->alloc_port_no), 1);
-            if (PORT_COMPARE(ofproto->alloc_port_no,
-                           >=, ofproto->max_ports)) {
+            if (!ofp_port_is_less_than(ofproto->alloc_port_no,
+                                       ofproto->max_ports)) {
                 ofproto->alloc_port_no = 0;
             }
             if (!bitmap_is_set(ofproto->ofp_port_ids,
@@ -1722,7 +1723,7 @@ alloc_ofp_port(struct ofproto *ofproto, const
char *netdev_name)
 static void
 dealloc_ofp_port(const struct ofproto *ofproto, ofp_port_t ofp_port)
 {
-    if (PORT_COMPARE(ofp_port, <, ofproto->max_ports)) {
+    if (ofp_port_is_less_than(ofp_port, ofproto->max_ports)) {
         bitmap_set0(ofproto->ofp_port_ids, (OVS_FORCE uint16_t) ofp_port);
     }
 }
@@ -2388,8 +2389,8 @@ handle_packet_out(struct ofconn *ofconn, const
struct ofp_header *oh)
     if (error) {
         goto exit_free_ofpacts;
     }
-    if (PORT_COMPARE(po.in_port, >=, p->max_ports)
-        && PORT_COMPARE(po.in_port, <, OFPP_MAX)) {
+    if (!ofp_port_is_less_than(po.in_port, p->max_ports)
+        && ofp_port_is_less_than(po.in_port, OFPP_MAX)) {
         error = OFPERR_OFPBRC_BAD_PORT;
         goto exit_free_ofpacts;
     }
-- 
1.7.9.5




On Fri, Jun 7, 2013 at 11:11 AM, Alex Wang <alexw at nicira.com> wrote:

> Currently datapath ports and openflow ports are both represented by
> unsigned
> integers of various sizes. With implicit casts, etc. it is easy to mix them
> up and use one where the other is expected. This commit creates two
> typedefs
> ofp_port_t and odp_port_t. Both of these two types are marked by
> "__attribute__((bitwise))" so that Sparse can be used to detect any misuse.
>
> Signed-off-by: Alex Wang <alexw at nicira.com>
>
> ---
> v1->v2:
> - rebased branch to up-to-date master, resolved conflicts
>
> SOME DESIGN IDEAS
>
> include/openvswitch/types.h :
> - Typedefs ofp_port_t, odp_port_t and ofp11_port_t
>
> include/openflow/openflow-1.0.h, openflow-1.1.h :
> - Defines Openflow related macros e.g. OFPP_NONE, OFPP_MAX
>
> lib/dpif-linux.c, dpif-netdev.c :
> - Explicitly casts odp_port_t to uint32_t, since the odp_port variable is
> used
>   as array index
> - The MAX_PORT macro is not converted to odp_port_t, since it is compared
> with
>   other UINT types and used as array size
>
> lib/flow.h, flow.c :
> - Defines "union flow_in_port", which can be ofp_port_t, odp_port_t or
>   ofp11_port_t. And each "struct flow" contains a "union flow_in_port
> in_port"
> - Defines ofp/odp_port_t related utility functions, e.g. ofp_htons,
> odp_htonl
> - The in_port argument of "flow_extract()" function is changed to of type
>   "union flow_in_port *", since it is called with both odp/ofp port number
>
> lib/odp-util.c, ofp-util.c :
> - Nasty, a lot of conversions between Openflow protocol data structures and
>   internal abstract data structures. Also a lot of explicity cast using
>   OVS_FORCE macro
>
> ofproto/ofproto.c ofproto-dpif.c, vswitch/bridge.c :
> - A lot of changes in struct element and function headers. Convert from
> uint
>   to corresponding ofp/odp_port_t type
>
> REMAINING ISSUE
>
> When doing comparisions like '<', '<=', etc, both ofp_port_t and odp_port_t
> will be converted to int, even though the L- and R- operands have same
> type.
> This seems to be caused by "usual arithmetic conversion" and I have not
> found
> a satisfying solution yet.
>
> As a workaround, I defined a macro function "PORT_COMPARE()" in
> "lib/flow.h",
> which uses OVS_FORCE to cast both operands to uint32_t and conducts the
> comparision. It also makes it easy to check all such comparisons. Just
> grep "PORT_COMPARE".
>
> ---
>  include/linux/openvswitch.h     |    2 +-
>  include/openflow/openflow-1.0.h |   56 +++++----
>  include/openflow/openflow-1.1.h |    4 +-
>  include/openvswitch/types.h     |    6 +
>  lib/bundle.c                    |   22 ++--
>  lib/bundle.h                    |    6 +-
>  lib/dpif-linux.c                |   58 +++++----
>  lib/dpif-linux.h                |    4 +-
>  lib/dpif-netdev.c               |   87 +++++++-------
>  lib/dpif-provider.h             |   10 +-
>  lib/dpif.c                      |   22 ++--
>  lib/dpif.h                      |   14 +--
>  lib/flow.c                      |    8 +-
>  lib/flow.h                      |  144 +++++++++++++++++++++-
>  lib/learn.c                     |    4 +-
>  lib/learning-switch.c           |   30 +++--
>  lib/mac-learning.h              |    2 +-
>  lib/match.c                     |   10 +-
>  lib/match.h                     |    2 +-
>  lib/meta-flow.c                 |   35 +++---
>  lib/meta-flow.h                 |    2 +-
>  lib/nx-match.c                  |    6 +-
>  lib/odp-util.c                  |   10 +-
>  lib/odp-util.h                  |    4 +-
>  lib/ofp-actions.c               |   34 +++---
>  lib/ofp-actions.h               |   12 +-
>  lib/ofp-parse.c                 |   12 +-
>  lib/ofp-print.c                 |   16 +--
>  lib/ofp-util.c                  |  144 +++++++++++-----------
>  lib/ofp-util.h                  |   34 +++---
>  lib/sflow.h                     |    2 +
>  lib/sflow_api.h                 |    6 +-
>  lib/sflow_poller.c              |    4 +-
>  ofproto/connmgr.c               |    4 +-
>  ofproto/connmgr.h               |    6 +-
>  ofproto/in-band.c               |    4 +-
>  ofproto/in-band.h               |    3 +-
>  ofproto/netflow.c               |   12 +-
>  ofproto/netflow.h               |   12 +-
>  ofproto/ofproto-dpif-sflow.c    |   17 +--
>  ofproto/ofproto-dpif-sflow.h    |    9 +-
>  ofproto/ofproto-dpif.c          |  249
> +++++++++++++++++++++------------------
>  ofproto/ofproto-provider.h      |   18 +--
>  ofproto/ofproto.c               |  105 ++++++++++-------
>  ofproto/ofproto.h               |   37 +++---
>  ofproto/pinsched.c              |    9 +-
>  ofproto/pinsched.h              |    3 +-
>  ofproto/pktbuf.c                |   10 +-
>  ofproto/pktbuf.h                |    4 +-
>  ofproto/tunnel.c                |   12 +-
>  ofproto/tunnel.h                |    6 +-
>  tests/test-bundle.c             |   16 +--
>  tests/test-classifier.c         |   12 +-
>  tests/test-flows.c              |    5 +-
>  tests/test-odp.c                |    2 +-
>  utilities/ovs-dpctl.c           |   14 +--
>  utilities/ovs-ofctl.c           |   19 +--
>  vswitchd/bridge.c               |   52 ++++----
>  58 files changed, 840 insertions(+), 612 deletions(-)
>
> diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
> index e890fd8..add1287 100644
> --- a/include/linux/openvswitch.h
> +++ b/include/linux/openvswitch.h
> @@ -116,7 +116,7 @@ struct ovs_vport_stats {
>  };
>
>  /* Fixed logical ports. */
> -#define OVSP_LOCAL      ((__u32)0)
> +#define OVSP_LOCAL      ((OVS_FORCE odp_port_t) 0)
>
>  /* Packet transfer. */
>
> diff --git a/include/openflow/openflow-1.0.h
> b/include/openflow/openflow-1.0.h
> index c30fa92..439cc91 100644
> --- a/include/openflow/openflow-1.0.h
> +++ b/include/openflow/openflow-1.0.h
> @@ -28,28 +28,40 @@
>   * 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. */
> +/* Maximum number of physical switch ports. */
> +#define OFPP_MAX        ((OVS_FORCE ofp_port_t) 0xff00)
> +
> +/* First assigned reserved port number. */
> +#define OFPP_FIRST_RESV ((OVS_FORCE ofp_port_t) 0xfff8)
> +
> +/* Last assigned reserved port number. */
> +#define OFPP_LAST_RESV  ((OVS_FORCE ofp_port_t) 0xffff)
> +
> +/* Reserved output "ports". */
> +/* Send the packet out the input port.  This virtual port must be
> explicitly
> + * used in order to send back out of the input port. */
> +#define OFPP_IN_PORT    ((OVS_FORCE ofp_port_t) 0xfff8)
> +
> +/* Perform actions in flow table. NB: This can only be the destination
> port
> + * for packet-out messages. */
> +#define OFPP_TABLE      ((OVS_FORCE ofp_port_t) 0xfff9)
> +
> +/* Process with normal L2/L3 switching. */
> +#define OFPP_NORMAL     ((OVS_FORCE ofp_port_t) 0xfffa)
> +
> +/* All physical ports except input port and those disabled by STP. */
> +#define OFPP_FLOOD      ((OVS_FORCE ofp_port_t) 0xfffb)
> +
> +/* All physical ports except input port. */
> +#define OFPP_ALL        ((OVS_FORCE ofp_port_t) 0xfffc)
> +/* Send to controller. */
> +#define OFPP_CONTROLLER ((OVS_FORCE ofp_port_t) 0xfffd)
> +/* Local openflow "port". */
> +#define OFPP_LOCAL      ((OVS_FORCE ofp_port_t) 0xfffe)
> +/* Not associated with a physical port. */
> +#define OFPP_NONE       ((OVS_FORCE ofp_port_t) 0xffff)
>
>  /* 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 ec94cee..6ed2400 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    ((OVS_FORCE ofp11_port_t) 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 72caa5c..7e1e59d 100644
> --- a/include/openvswitch/types.h
> +++ b/include/openvswitch/types.h
> @@ -60,4 +60,10 @@ 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. */
> +typedef uint16_t OVS_BITWISE ofp_port_t;
> +typedef uint32_t OVS_BITWISE odp_port_t;
> +typedef uint32_t OVS_BITWISE ofp11_port_t;
> +
>  #endif /* openvswitch/types.h */
> diff --git a/lib/bundle.c b/lib/bundle.c
> index 92ac1e1..f18268c 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,9 +51,9 @@ 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,
> -            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;
> @@ -79,9 +79,9 @@ execute_hrw(const struct ofpact_bundle *bundle, const
> struct flow *flow,
>  /* Executes 'bundle' on 'flow'.  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,
> -               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:
> @@ -179,7 +179,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);
> @@ -193,7 +193,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);
> @@ -239,7 +239,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] = ofp_htons(bundle->slaves[i]);
>      }
>  }
>
> @@ -264,7 +264,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 5b6bb67..7395b71 100644
> --- a/lib/bundle.h
> +++ b/lib/bundle.h
> @@ -34,12 +34,12 @@ struct ofpbuf;
>   *
>   * See include/openflow/nicira-ext.h for NXAST_BUNDLE specification. */
>
> -uint16_t bundle_execute(const struct ofpact_bundle *, const struct flow *,
> -                        bool (*slave_enabled)(uint16_t ofp_port, void
> *aux),
> +ofp_port_t bundle_execute(const struct ofpact_bundle *, const struct flow
> *,
> +                        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 1383b58..a502224 100644
> --- a/lib/dpif-linux.c
> +++ b/lib/dpif-linux.c
> @@ -167,7 +167,7 @@ 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 *);
> @@ -278,7 +278,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 = (OVS_FORCE odp_port_t) i;
>          vport_request.upcall_pid = &upcall_pid;
>          dpif_linux_vport_transact(&vport_request, NULL, NULL);
>
> @@ -298,9 +298,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 = (OVS_FORCE uint32_t) port_no;
>
>      if (dpif->epoll_fd < 0) {
>          return 0;
> @@ -308,9 +309,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",
> @@ -331,29 +332,31 @@ 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 = (OVS_FORCE uint32_t) 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;
>      }
> @@ -480,7 +483,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;
> @@ -539,7 +542,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 != OVSP_NONE) {
>              VLOG_INFO("%s: requested port %"PRIu32" is in use",
>                        dpif_name(dpif_), *port_nop);
>          }
> @@ -571,7 +574,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;
> @@ -589,7 +592,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;
> @@ -620,7 +623,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);
> @@ -633,23 +636,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 (OVS_FORCE odp_port_t) 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 = (OVS_FORCE uint32_t) port_no;
>
>      if (dpif->epoll_fd < 0) {
>          return 0;
>      } else {
>          /* The UINT32_MAX "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);
>      }
>  }
> @@ -1553,7 +1557,8 @@ 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 = (OVS_FORCE odp_port_t)
> +                      nl_attr_get_u32(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]) {
> @@ -1583,8 +1588,9 @@ 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 != OVSP_NONE) {
> +        nl_msg_put_u32(buf, OVS_VPORT_ATTR_PORT_NO,
> +                       (OVS_FORCE uint32_t) vport->port_no);
>      }
>
>      if (vport->type != OVS_VPORT_TYPE_UNSPEC) {
> @@ -1615,7 +1621,7 @@ void
>  dpif_linux_vport_init(struct dpif_linux_vport *vport)
>  {
>      memset(vport, 0, sizeof *vport);
> -    vport->port_no = UINT32_MAX;
> +    vport->port_no = OVSP_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 81062aa..492e543 100644
> --- a/lib/dpif-linux.h
> +++ b/lib/dpif-linux.h
> @@ -22,6 +22,8 @@
>  #include <stdint.h>
>  #include <linux/openvswitch.h>
>
> +#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;                    /* OVSP_NONE if unknown. */
>      enum ovs_vport_type type;
>
>      /* Attributes.
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> index 52aedb6..b2b5a61 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 0 on failure. */
> +static uint32_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;
> @@ -254,7 +256,7 @@ choose_port(struct dp_netdev *dp, const char *name)
>          }
>      }
>
> -    return -1;
> +    return 0;
>  }
>
>  static int
> @@ -379,13 +381,14 @@ 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;
>      struct netdev *netdev;
>      struct netdev_rx *rx;
>      const char *open_type;
> +    uint32_t port_idx = (OVS_FORCE uint32_t) port_no;
>      int mtu;
>      int error;
>
> @@ -429,7 +432,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[port_idx] = port;
>      dp->serial++;
>
>      return 0;
> @@ -437,53 +440,55 @@ 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;
> +    uint32_t port_no = (OVS_FORCE uint32_t) *port_nop;
>
>      dpif_port = netdev_vport_get_dpif_port(netdev, namebuf, sizeof
> namebuf);
> -    if (*port_nop != UINT32_MAX) {
> -        if (*port_nop >= MAX_PORTS) {
> +    if (port_no != UINT32_MAX) {
> +        if (port_no >= MAX_PORTS) {
>              return EFBIG;
> -        } else if (dp->ports[*port_nop]) {
> +        } else if (dp->ports[port_no]) {
>              return EBUSY;
>          }
> -        port_no = *port_nop;
>      } else {
>          port_no = choose_port(dp, dpif_port);
>      }
>      if (port_no >= 0) {
> -        *port_nop = port_no;
> -        return do_add_port(dp, dpif_port, netdev_get_type(netdev),
> port_no);
> +        *port_nop = (OVS_FORCE odp_port_t) port_no;
> +        return do_add_port(dp, dpif_port, netdev_get_type(netdev),
> *port_nop);
>      }
>      return EFBIG;
>  }
>
>  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 == OVSP_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 PORT_COMPARE(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)
>  {
> +    uint32_t port_idx = (OVS_FORCE uint32_t) port_no;
> +
>      if (!is_valid_port_number(port_no)) {
>          *portp = NULL;
>          return EINVAL;
>      } else {
> -        *portp = dp->ports[port_no];
> +        *portp = dp->ports[port_idx];
>          return *portp ? 0 : ENOENT;
>      }
>  }
> @@ -504,9 +509,10 @@ 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;
> +    uint32_t port_idx = (OVS_FORCE uint32_t) port_no;
>      int error;
>
>      error = get_port_by_number(dp, port_no, &port);
> @@ -515,7 +521,7 @@ do_del_port(struct dp_netdev *dp, uint32_t port_no)
>      }
>
>      list_remove(&port->node);
> -    dp->ports[port->port_no] = NULL;
> +    dp->ports[port_idx] = NULL;
>      dp->serial++;
>
>      netdev_close(port->netdev);
> @@ -537,7 +543,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 +572,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 (OVS_FORCE odp_port_t) MAX_PORTS;
>  }
>
>  static void
> @@ -599,7 +605,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 +622,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 = (OVS_FORCE uint32_t) 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 = (OVS_FORCE odp_port_t) (port_idx + 1);
>              return 0;
>          }
>      }
> @@ -708,9 +715,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 (PORT_COMPARE(flow->in_port.odp_port, >=, MAX_PORTS)) {
>          return EINVAL;
>      }
>
> @@ -898,7 +903,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;
> @@ -948,7 +953,7 @@ dpif_netdev_execute(struct dpif *dpif, const struct
> dpif_execute *execute)
>      ofpbuf_reserve(&copy, DP_NETDEV_HEADROOM);
>      ofpbuf_put(&copy, execute->packet->data, execute->packet->size);
>
> -    flow_extract(&copy, 0, 0, NULL, -1, &key);
> +    flow_extract(&copy, 0, 0, NULL, NULL, &key);
>      error = dpif_netdev_flow_from_nlattrs(execute->key, execute->key_len,
>                                            &key);
>      if (!error) {
> @@ -1043,11 +1048,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);
> @@ -1134,7 +1141,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 bea822f..6af6733 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 6aa52d5..0b616b0 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 OVSP_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 OVSP_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 = OVSP_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 = OVSP_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 OVSP_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 fd05b2f..12e5ad0 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 3c12984..431e586 100644
> --- a/lib/flow.c
> +++ b/lib/flow.c
> @@ -337,7 +337,7 @@ invalid:
>  }
>
>  /* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
> - * 'ofp_in_port'.
> + * 'in_port'.
>   *
>   * Initializes 'packet' header pointers as follows:
>   *
> @@ -357,7 +357,7 @@ invalid:
>   */
>  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,7 @@ 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;
> +    flow->in_port = in_port ? *in_port : flow->in_port;
>      flow->skb_priority = skb_priority;
>      flow->skb_mark = skb_mark;
>
> @@ -498,7 +498,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 0fdf4ef..02ba9b1 100644
> --- a/lib/flow.h
> +++ b/lib/flow.h
> @@ -57,6 +57,12 @@ BUILD_ASSERT_DECL(FLOW_NW_FRAG_LATER ==
> NX_IP_FRAG_LATER);
>  #define FLOW_TNL_F_CSUM (1 << 1)
>  #define FLOW_TNL_F_KEY (1 << 2)
>
> +/* Cast both left and right values to 'uint32_t' using the OVS_FORCE
> attribute
> + * macro. Then, compare using the provided rational operator. */
> +#define PORT_COMPARE(L_OPERAND, OPERATOR, R_OPERAND)     \
> +    (((OVS_FORCE uint32_t) L_OPERAND) OPERATOR          \
> +     ((OVS_FORCE uint32_t) R_OPERAND))
> +
>  const char *flow_tun_flag_to_string(uint32_t flags);
>
>  struct flow_tnl {
> @@ -68,6 +74,13 @@ struct flow_tnl {
>      uint8_t ip_ttl;
>  };
>
> +union flow_in_port {           /* Input port union. The port can be
> either */
> +    ofp_port_t   ofp_port;     /* OpenFlow port number or the datapath
> port */
> +    odp_port_t   odp_port;     /* number. */
> +    ofp11_port_t ofp11_port;   /* For the OpenFlow-1.1 or above
> protocols. */
> +    uint32_t     port32;       /* For using in arithmetic opertions */
> +};
> +
>  /*
>  * A flow in the network.
>  *
> @@ -82,14 +95,12 @@ struct flow {
>      struct in6_addr ipv6_src;   /* IPv6 source address. */
>      struct in6_addr ipv6_dst;   /* IPv6 destination address. */
>      struct in6_addr nd_target;  /* IPv6 neighbor discovery (ND) target. */
> +    union flow_in_port in_port; /* Input port union.*/
>      uint32_t skb_priority;      /* Packet priority for QoS. */
>      uint32_t regs[FLOW_N_REGS]; /* Registers. */
>      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. */
>      uint32_t skb_mark;          /* Packet mark. */
>      ovs_be32 mpls_lse;          /* MPLS label stack entry. */
>      uint16_t mpls_depth;        /* Depth of MPLS stack. */
> @@ -122,11 +133,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 +182,128 @@ flow_hash(const struct flow *flow, uint32_t basis)
>      return hash_words((const uint32_t *) flow, sizeof *flow / 4, basis);
>  }
>
> +/* ofp/odp port related utility functions. */
> +static inline ovs_be16 ofp_htons(ofp_port_t ofp_port);
> +static inline ovs_be32 odp_htonl(odp_port_t odp_port);
> +static inline ovs_be32 ofp11_htonl(ofp11_port_t ofp11_port);
> +static inline ofp_port_t ofp_ntohs(ovs_be16 netshort);
> +static inline odp_port_t odp_ntohl(ovs_be32 netlong);
> +static inline ofp11_port_t ofp11_ntohl(ovs_be32 netlong);
> +
> +static inline uint32_t hash_ofp_port(ofp_port_t ofp_port,
> +                                     uint32_t basis);
> +static inline uint32_t hash_odp_port(odp_port_t odp_port_t,
> +                                     uint32_t basis);
> +static inline uint32_t hash_ofp11_port(ofp11_port_t ofp11_port,
> +                                       uint32_t basis);
> +
> +static inline void ofp_port_increment(ofp_port_t *ofp_portp,
> +                                      uint16_t incr);
> +static inline void odp_port_increment(odp_port_t *odp_portp,
> +                                      uint32_t incr);
> +
> +static inline int ofp11_port_to_ofp_port(ofp11_port_t ofp11_port,
> +                                         ofp_port_t *ofp_portp);
> +static inline void ofp_port_to_ofp11_port(ofp_port_t ofp_port,
> +                                          ofp11_port_t *ofp11_portp);
> +
> +static inline ovs_be16
> +ofp_htons(ofp_port_t ofp_port)
> +{
> +    return htons((OVS_FORCE uint16_t) ofp_port);
> +}
> +
> +static inline ovs_be32
> +odp_htonl(odp_port_t odp_port)
> +{
> +    return htonl((OVS_FORCE uint32_t) odp_port);
> +}
> +
> +static inline ovs_be32
> +ofp11_htonl(ofp11_port_t ofp11_port)
> +{
> +    return htonl((OVS_FORCE uint32_t) ofp11_port);
> +}
> +
> +static inline ofp_port_t
> +ofp_ntohs(ovs_be16 netshort)
> +{
> +    return (OVS_FORCE ofp_port_t) ntohs(netshort);
> +}
> +
> +static inline odp_port_t
> +odp_ntohl(ovs_be32 netlong)
> +{
> +    return (OVS_FORCE odp_port_t) ntohl(netlong);
> +}
> +
> +static inline ofp11_port_t
> +ofp11_ntohl(ovs_be32 netlong)
> +{
> +    return (OVS_FORCE ofp11_port_t) ntohl(netlong);
> +}
> +
> +static inline uint32_t
> +hash_ofp_port(ofp_port_t ofp_port, uint32_t basis)
> +{
> +    return hash_int((OVS_FORCE uint16_t) ofp_port, basis);
> +}
> +
> +static inline uint32_t
> +hash_odp_port(odp_port_t odp_port, uint32_t basis)
> +{
> +    return hash_int((OVS_FORCE uint32_t) odp_port, basis);
> +}
> +
> +static inline uint32_t
> +hash_ofp11_port(ofp11_port_t ofp11_port, uint32_t basis)
> +{
> +    return hash_int((OVS_FORCE uint32_t) ofp11_port, basis);
> +}
> +
> +static inline void
> +ofp_port_increment(ofp_port_t *ofp_portp, uint16_t incr)
> +{
> +    *ofp_portp = (OVS_FORCE ofp_port_t) ((OVS_FORCE uint16_t) *ofp_portp
> +                                         + incr);
> +}
> +
> +static inline void
> +odp_port_increment(odp_port_t *odp_portp, uint32_t incr)
> +{
> +    *odp_portp = (OVS_FORCE odp_port_t) ((OVS_FORCE uint32_t) *odp_portp
> +                                         + incr);
> +}
> +
> +/* Convert ofp11_port to ofp_port. Return 0 on success and set *ofp_portp
> + * to the corresponding ofp_port number. Return -1 on failure. */
> +static inline int
> +ofp11_port_to_ofp_port(ofp11_port_t ofp11_port, ofp_port_t *ofp_portp)
> +{
> +    if (PORT_COMPARE(ofp11_port, <, OFPP_MAX)) {
> +        *ofp_portp = (OVS_FORCE ofp_port_t) ofp11_port;
> +    } else if (PORT_COMPARE(ofp11_port, >=, OFPP11_MAX)) {
> +        *ofp_portp = (OVS_FORCE ofp_port_t)((OVS_FORCE uint32_t)ofp11_port
> +                                            - OFPP11_OFFSET);
> +    } else {
> +        return -1;
> +    }
> +    return 0;
> +}
> +
> +/* Convert ofp_port to ofp11_port. This function is always successful and
> sets
> + * *ofp11_portp to the corresponding ofp11_port number. */
> +static inline void
> +ofp_port_to_ofp11_port(ofp_port_t ofp_port, ofp11_port_t *ofp11_portp)
> +{
> +    if (PORT_COMPARE(ofp_port, <, OFPP_MAX)) {
> +        *ofp11_portp = (OVS_FORCE ofp11_port_t) ofp_port;
> +    } else {
> +        *ofp11_portp = (OVS_FORCE ofp11_port_t) ((OVS_FORCE
> uint32_t)ofp_port
> +                                                 + OFPP11_OFFSET);
> +    }
> +}
> +
>  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 ab403be..964c06c 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 = ofp_ntohs(value.be16[7]);
>
> -                if (port < OFPP_MAX
> +                if (PORT_COMPARE(port, <, 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 ab37dcc..94c4267 100644
> --- a/lib/learning-switch.c
> +++ b/lib/learning-switch.c
> @@ -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, in host byte
> order. */
>      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_ofp_port(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_ofp_port(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
> +               || PORT_COMPARE(out_port, >=, 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 666b00f..f01479a 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 512253e..4ee8ed6 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 = OFPP_NONE;
> +    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 d435aa4..0ea1f2d 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 54bc4c2..4d7149e 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 = ofp_htons(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, 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;
> @@ -1388,13 +1387,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 = 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;
>      }
>
> @@ -1595,8 +1594,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:
> @@ -2013,7 +2012,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(ofp_ntohs(value->be16));
>          break;
>
>      case MFF_IPV6_LABEL:
> @@ -2204,12 +2203,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 = ofp_htons(port);
>          *maskp = htons(UINT16_MAX);
>          return NULL;
>      }
> @@ -2220,7 +2219,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)) {
> @@ -2476,7 +2475,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;
> @@ -2484,7 +2483,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(ofp_ntohs(value->be16), s);
>              break;
>          }
>          /* fall through */
> diff --git a/lib/meta-flow.h b/lib/meta-flow.h
> index a85a193..dc54899 100644
> --- a/lib/meta-flow.h
> +++ b/lib/meta-flow.h
> @@ -276,7 +276,7 @@ struct mf_field {
>      uint32_t nxm_header;        /* An NXM_* (or OXM_*) constant. */
>      const char *nxm_name;       /* The nxm_header constant's name. */
>      uint32_t oxm_header;        /* An OXM_* (or NXM_*) constant. */
> -    const char *oxm_name;          /* The oxm_header constant's name */
> +    const char *oxm_name;       /* The oxm_header constant's name */
>  };
>
>  /* The representation of a field's value. */
> diff --git a/lib/nx-match.c b/lib/nx-match.c
> index e111000..9a8fbef 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, ofp_htons(in_port));
>          }
>      }
>
> diff --git a/lib/odp-util.c b/lib/odp-util.c
> index cc8b1dd..1e65756 100644
> --- a/lib/odp-util.c
> +++ b/lib/odp-util.c
> @@ -1558,7 +1558,7 @@ ovs_to_odp_frag(uint8_t nw_frag)
>   * 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;
> @@ -1576,7 +1576,8 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const
> struct flow *flow,
>      }
>
>      if (odp_in_port != OVSP_NONE) {
> -        nl_msg_put_u32(buf, OVS_KEY_ATTR_IN_PORT, odp_in_port);
> +        nl_msg_put_u32(buf, OVS_KEY_ATTR_IN_PORT,
> +                       (OVS_FORCE uint32_t) odp_in_port);
>      }
>
>      eth_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ETHERNET,
> @@ -2098,10 +2099,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
> +        = (OVS_FORCE odp_port_t)
> nl_attr_get_u32(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 = OVSP_NONE;
>      }
>
>      /* Ethernet header. */
> diff --git a/lib/odp-util.h b/lib/odp-util.h
> index 6213418..307ac76 100644
> --- a/lib/odp-util.h
> +++ b/lib/odp-util.h
> @@ -33,7 +33,7 @@ struct nlattr;
>  struct ofpbuf;
>  struct simap;
>
> -#define OVSP_NONE UINT32_MAX
> +#define OVSP_NONE ((OVS_FORCE odp_port_t) UINT32_MAX)
>
>  void format_odp_actions(struct ds *, const struct nlattr *odp_actions,
>                          size_t actions_len);
> @@ -95,7 +95,7 @@ int odp_flow_key_from_string(const char *s, const struct
> simap *port_names,
>                               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 58d0098..77cee33 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 = 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 = ofp_ntohs(oae->port);
>      enqueue->queue = ntohl(oae->queue_id);
> -    if (enqueue->port >= OFPP_MAX && enqueue->port != OFPP_IN_PORT
> +    if (PORT_COMPARE(enqueue->port, >=, 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 = 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 = ofp_ntohs(nar->in_port);
>      resubmit->table_id = nar->table;
>      return 0;
>  }
> @@ -1142,8 +1143,8 @@ exit:
>  }
>
>  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 (PORT_COMPARE(enqueue->port, >=, 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 = ofp_htons(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 = ofp_htons(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 = ofp_htons(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 (PORT_COMPARE(port, <, 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 9a74bcc..8aa943e 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 1c5c761..09a8856 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 = (OVS_FORCE ofp_port_t) 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 = (OVS_FORCE ofp_port_t) 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 = (OVS_FORCE ofp_port_t) 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 0a9917a..6c534b6 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) {
> @@ -202,10 +202,10 @@ 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;
> +    ofp_port_t ap = a->port_no;
> +    ofp_port_t bp = b->port_no;
>
> -    return ap < bp ? -1 : ap > bp;
> +    return PORT_COMPARE(ap, <, bp) ? -1 : PORT_COMPARE(ap, >, bp);
>  }
>
>  static void
> @@ -583,7 +583,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;
> @@ -663,7 +663,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));
> +                    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,
> @@ -1160,7 +1160,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);
> @@ -1198,7 +1198,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 (PORT_COMPARE(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 cc2dc36..dd6655d 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 = OFPP_NONE;
>      }
>
>      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 = 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 = ofp_htons(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 = 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 = 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 = ofp_htons(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 = ofp_htons(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 = 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 = 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 = ofp_htons(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 = ofp_htons(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 = 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 = ofp_htons(pin->fmd.in_port);
>          opi->reason = pin->reason;
>          opi->buffer_id = htonl(pin->buffer_id);
>
> @@ -2730,7 +2730,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 = ofp_ntohs(opo->in_port);
>
>          error = ofpacts_pull_openflow10(&b, ntohs(opo->actions_len),
> ofpacts);
>          if (error) {
> @@ -2740,7 +2740,8 @@ ofputil_decode_packet_out(struct ofputil_packet_out
> *po,
>          NOT_REACHED();
>      }
>
> -    if (po->in_port >= OFPP_MAX && po->in_port != OFPP_LOCAL
> +    if (PORT_COMPARE(po->in_port, >=, 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);
> @@ -2827,7 +2828,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 = 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);
>
> @@ -2895,7 +2896,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 = ofp_htons(pp->port_no);
>      memcpy(opp->hw_addr, pp->hw_addr, ETH_ADDR_LEN);
>      ovs_strlcpy(opp->name, pp->name, OFP_MAX_PORT_NAME_LEN);
>
> @@ -3305,7 +3306,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 = 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;
> @@ -3347,7 +3348,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 = ofp_htons(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);
> @@ -3683,7 +3684,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 = ofp_ntohs(nfmr->out_port);
>      rq->table_id = nfmr->table_id;
>
>      return nx_pull_match(msg, ntohs(nfmr->match_len), &rq->match, NULL,
> NULL);
> @@ -3708,7 +3709,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 = ofp_htons(rq->out_port);
>      nfmr->match_len = htons(match_len);
>      nfmr->table_id = rq->table_id;
>  }
> @@ -3916,7 +3917,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 = ofp_htons(po->in_port);
>          opo->actions_len = htons(msg->size - actions_ofs);
>          break;
>      }
> @@ -4035,22 +4036,20 @@ 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);
> +    ofp11_port_t ofp11_port_h = ofp11_ntohl(ofp11_port);
> +    int error;
>
> -    if (ofp11_port_h < OFPP_MAX) {
> -        *ofp10_port = ofp11_port_h;
> -        return 0;
> -    } else if (ofp11_port_h >= OFPP11_MAX) {
> -        *ofp10_port = ofp11_port_h - OFPP11_OFFSET;
> +    error = ofp11_port_to_ofp_port(ofp11_port_h, ofp10_port);
> +    if (!error) {
>          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);
> +                     "range 0 through %u or 0x%"PRIx32" through
> 0x%"PRIx32,
> +                     ofp11_port_h, (OVS_FORCE uint32_t) OFPP_MAX - 1,
> +                     OFPP11_MAX, UINT32_MAX);
>          return OFPERR_OFPBAC_BAD_OUT_PORT;
>      }
>  }
> @@ -4060,18 +4059,19 @@ 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);
> +    ofp11_port_t ofp11_port;
> +
> +    ofp_port_to_ofp11_port(ofp10_port, &ofp11_port);
> +    return ofp11_htonl(ofp11_port);
>  }
>
>  /* 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:
> @@ -4085,7 +4085,7 @@ ofputil_check_output_port(uint16_t port, int
> max_ports)
>          return 0;
>
>      default:
> -        if (port < max_ports) {
> +        if (PORT_COMPARE(port, <, max_ports)) {
>              return 0;
>          }
>          return OFPERR_OFPBAC_BAD_OUT_PORT;
> @@ -4121,46 +4121,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 (PORT_COMPARE(port32, <, OFPP_MAX)) {
> +            /* Pass. */
> +        } else if (PORT_COMPARE(port32, <, 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 (PORT_COMPARE(port32, <=, OFPP_LAST_RESV)) {
>              struct ds msg;
>
>              ds_init(&msg);
> -            ofputil_format_port(port32, &msg);
> +            ofputil_format_port((OVS_FORCE ofp_port_t) 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 (PORT_COMPARE(port32, <, 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, (OVS_FORCE uint32_t) OFPP11_MAX,
> UINT32_MAX);
>              return false;
>          } else {
> -            *portp = port32 - OFPP11_OFFSET;
> -            return true;
> +            port32 -= OFPP11_OFFSET;
>          }
> +
> +        *portp = (OVS_FORCE ofp_port_t) 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},
> @@ -4183,7 +4179,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;
>
> @@ -4524,7 +4520,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;
>
> @@ -4533,7 +4529,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 = ofp_htons(port);
>          break;
>      }
>      case OFP11_VERSION:
> @@ -4556,7 +4552,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 = ofp_htons(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));
> @@ -4640,7 +4636,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 = 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));
> @@ -4780,7 +4776,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:
> @@ -4792,7 +4788,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 = ofp_ntohs(psr10->port_no);
>          return 0;
>      }
>
> @@ -4819,7 +4815,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 = 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;
> @@ -4857,8 +4853,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 = ofp_htons(oqsr->port_no == OFPP_ANY
> +                                 ? OFPP_ALL : oqsr->port_no);
>          req->queue_id = htonl(oqsr->queue_id);
>          break;
>      }
> @@ -4888,7 +4884,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 = 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));
> @@ -4993,7 +4989,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 = ofp_htons(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 010c34d..c1d7f53 100644
> --- a/lib/ofp-util.h
> +++ b/lib/ofp-util.h
> @@ -31,12 +31,12 @@
>  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. */
> @@ -218,7 +218,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. */
> @@ -240,7 +240,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;
>  };
>
> @@ -346,7 +346,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. */
>  };
> @@ -386,7 +386,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;
> @@ -494,7 +494,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;
> @@ -531,7 +531,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;
>  };
> @@ -673,7 +673,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,
> @@ -687,23 +687,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;
>  };
>
> @@ -715,7 +715,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/sflow.h b/lib/sflow.h
> index 0d1f2b9..58288b1 100644
> --- a/lib/sflow.h
> +++ b/lib/sflow.h
> @@ -8,6 +8,8 @@
>  #ifndef SFLOW_H
>  #define SFLOW_H 1
>
> +#include "flow.h"
> +
>  typedef enum {
>      SFL_DSCLASS_IFINDEX = 0,
>      SFL_DSCLASS_VLAN = 1,
> diff --git a/lib/sflow_api.h b/lib/sflow_api.h
> index 3cc060b..a5fa78d 100644
> --- a/lib/sflow_api.h
> +++ b/lib/sflow_api.h
> @@ -153,7 +153,7 @@ typedef struct _SFLPoller {
>      struct _SFLAgent *agent; /* pointer to my agent */
>      void *magic;             /* ptr to pass back in getCountersFn() */
>      getCountersFn_t getCountersFn;
> -    u_int32_t bridgePort; /* port number local to bridge */
> +    odp_port_t bridgePort; /* port number local to bridge */
>      /* private fields */
>      SFLReceiver *myReceiver;
>      time_t countersCountdown;
> @@ -279,8 +279,8 @@ void sfl_agent_set_agentSubId(SFLAgent *agent,
> u_int32_t subId);
>
>  /* The poller may need a separate number to reference the local bridge
> port
>     to get counters if it is not the same as the global ifIndex */
> -void sfl_poller_set_bridgePort(SFLPoller *poller, u_int32_t port_no);
> -u_int32_t sfl_poller_get_bridgePort(SFLPoller *poller);
> +void sfl_poller_set_bridgePort(SFLPoller *poller, odp_port_t port_no);
> +odp_port_t sfl_poller_get_bridgePort(SFLPoller *poller);
>
>  /* call this to indicate a discontinuity with a counter like samplePool
> so that the
>     sflow collector will ignore the next delta */
> diff --git a/lib/sflow_poller.c b/lib/sflow_poller.c
> index d2e4155..e0c122f 100644
> --- a/lib/sflow_poller.c
> +++ b/lib/sflow_poller.c
> @@ -104,11 +104,11 @@ void sfl_poller_set_sFlowCpInterval(SFLPoller
> *poller, u_int32_t sFlowCpInterval
>    to get counters if it is not the same as the global ifIndex.
>  */
>
> -void sfl_poller_set_bridgePort(SFLPoller *poller, u_int32_t port_no) {
> +void sfl_poller_set_bridgePort(SFLPoller *poller, odp_port_t port_no) {
>      poller->bridgePort = port_no;
>  }
>
> -u_int32_t sfl_poller_get_bridgePort(SFLPoller *poller) {
> +odp_port_t sfl_poller_get_bridgePort(SFLPoller *poller) {
>      return poller->bridgePort;
>  }
>
> diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
> index 1a1ab6c..effd058 100644
> --- a/ofproto/connmgr.c
> +++ b/ofproto/connmgr.c
> @@ -1038,7 +1038,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);
>  }
> @@ -1644,7 +1644,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 506f9c7..2a60ee5 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 ba6fc54..d83624b 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_u32(a) == (OVS_FORCE uint32_t)
> local_odp_port) {
>                  return true;
>              }
>          }
> diff --git a/ofproto/in-band.h b/ofproto/in-band.h
> index 4f52e00..5449312 100644
> --- a/ofproto/in-band.h
> +++ b/ofproto/in-band.h
> @@ -21,6 +21,7 @@
>  #include <stddef.h>
>  #include <sys/socket.h>
>  #include <netinet/in.h>
> +#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 7366986..c4894e2 100644
> --- a/ofproto/netflow.c
> +++ b/ofproto/netflow.c
> @@ -85,11 +85,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
> +            | ((OVS_FORCE uint16_t) expired->flow.in_port.ofp_port &
> 0x1ff));
> +        nf_rec->output = htons(iface
> +            | ((OVS_FORCE uint16_t) 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 = ofp_htons(expired->flow.in_port.ofp_port);
> +        nf_rec->output = ofp_htons(nf_flow->output_iface);
>      }
>      nf_rec->packet_count = htonl(packet_count);
>      nf_rec->byte_count = htonl(byte_count);
> @@ -263,7 +265,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 c01ff15..5e0290d 100644
> --- a/ofproto/netflow.h
> +++ b/ofproto/netflow.h
> @@ -38,11 +38,11 @@ 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 OFPP_NONE
> +#define NF_OUT_MULTI ((OVS_FORCE ofp_port_t) \
> +                      ((OVS_FORCE uint16_t) OFPP_NONE - 1))
> +#define NF_OUT_DROP  ((OVS_FORCE ofp_port_t) \
> +                      ((OVS_FORCE uint16_t) OFPP_NONE - 2))
>
>  struct netflow_flow {
>      long long int last_expired;   /* Time this flow last timed out. */
> @@ -51,7 +51,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 9ad0eaf..d5a9524 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_odp_port(odp_port, 0),
> +                                      &ds->ports) {
>          if (dsp->odp_port == odp_port) {
>              return dsp;
>          }
> @@ -343,7 +344,7 @@ dpif_sflow_add_poller(struct dpif_sflow *ds, struct
> dpif_sflow_port *dsp)
>
>  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_odp_port(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 02a0f17..d0f83bc 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.c b/ofproto/ofproto-dpif.c
> index ec2d95d..e5a937c 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -189,7 +189,7 @@ static void bundle_del_port(struct ofport_dpif *);
>  static void bundle_run(struct ofbundle *);
>  static void bundle_wait(struct ofbundle *);
>  static struct ofbundle *lookup_input_bundle(const struct ofproto_dpif *,
> -                                            uint16_t in_port, bool warn,
> +                                            ofp_port_t in_port, bool warn,
>                                              struct ofport_dpif
> **in_ofportp);
>
>  /* A controller may use OFPP_NONE as the ingress port to indicate that
> @@ -232,7 +232,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];
> @@ -327,7 +327,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. */
>  };
> @@ -343,7 +343,7 @@ static void xlate_actions(struct xlate_in *, struct
> xlate_out *);
>
>  static void xlate_actions_for_side_effects(struct xlate_in *);
>
> -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 size_t put_userspace_action(const struct ofproto_dpif *,
> @@ -513,7 +513,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.
> */
> @@ -536,7 +536,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;
>  };
>
> @@ -559,22 +559,22 @@ 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 uint16_t vsp_realdev_to_vlandev(const struct ofproto_dpif *,
> -                                       uint16_t realdev_ofp_port,
> -                                       ovs_be16 vlan_tci);
> +static ofp_port_t vsp_realdev_to_vlandev(const struct ofproto_dpif *,
> +                                         ofp_port_t realdev,
> +                                         ovs_be16 vlan_tci);
>  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 uint32_t ofp_port_to_odp_port(const struct ofproto_dpif *,
> -                                     uint16_t ofp_port);
> -static uint16_t odp_port_to_ofp_port(const struct ofproto_dpif *,
> -                                     uint32_t odp_port);
> +static odp_port_t ofp_port_to_odp_port(const struct ofproto_dpif *,
> +                                       ofp_port_t ofp_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)
> @@ -659,7 +659,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);
>
>  struct avg_subfacet_rates {
>      double add_rate;     /* Moving average of new flows created per
> minute. */
> @@ -677,13 +677,13 @@ struct ofproto_dpif {
>      /* Special OpenFlow rules. */
>      struct rule_dpif *miss_rule; /* Sends flow table misses to
> controller. */
>      struct rule_dpif *no_packet_in_rule; /* Drops flow table misses. */
> -    struct rule_dpif *drop_frags_rule; /* Used in OFPC_FRAG_DROP mode. */
> +    struct rule_dpif *drop_frags_rule;   /* Used in OFPC_FRAG_DROP mode.
> */
>
>      /* Bridging. */
>      struct netflow *netflow;
>      struct dpif_sflow *sflow;
>      struct dpif_ipfix *ipfix;
> -    struct hmap bundles;        /* Contains "struct ofbundle"s. */
> +    struct hmap bundles;                 /* Contains "struct ofbundle"s.
> */
>      struct mac_learning *ml;
>      struct ofmirror *mirrors[MAX_MIRRORS];
>      bool has_mirrors;
> @@ -780,9 +780,9 @@ ofproto_dpif_cast(const struct ofproto *ofproto)
>  }
>
>  static struct ofport_dpif *get_ofp_port(const struct ofproto_dpif *,
> -                                        uint16_t ofp_port);
> +                                        ofp_port_t ofp_port);
>  static struct ofport_dpif *get_odp_port(const struct ofproto_dpif *,
> -                                        uint32_t odp_port);
> +                                        odp_port_t odp_port);
>  static void ofproto_trace(struct ofproto_dpif *, const struct flow *,
>                            const struct ofpbuf *,
>                            const struct initial_vals *, struct ds *);
> @@ -805,7 +805,7 @@ static void send_netflow_active_timeouts(struct
> ofproto_dpif *);
>  static int send_packet(const struct ofport_dpif *, struct ofpbuf *packet);
>  static size_t compose_sflow_action(const struct ofproto_dpif *,
>                                     struct ofpbuf *odp_actions,
> -                                   const struct flow *, uint32_t
> odp_port);
> +                                   const struct flow *, odp_port_t
> odp_port);
>  static void compose_ipfix_action(const struct ofproto_dpif *,
>                                   struct ofpbuf *odp_actions,
>                                   const struct flow *);
> @@ -974,17 +974,19 @@ 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 = OVSP_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,
> +                                      (OVS_FORCE uint32_t) odp_port);
>                              node = simap_find(&backer->tnl_backers,
> dp_port);
>                          }
>                      }
>                  }
>
> -                iter->odp_port = node ? node->data : OVSP_NONE;
> +                iter->odp_port = node ? (OVS_FORCE odp_port_t) node->data
> +                                        : OVSP_NONE;
>                  if (tnl_port_reconfigure(&iter->up, iter->odp_port,
>                                           &iter->tnl_port)) {
>                      backer->need_revalidate = REV_RECONFIGURE;
> @@ -993,7 +995,7 @@ type_run(const char *type)
>          }
>
>          SIMAP_FOR_EACH (node, &tmp_backers) {
> -            dpif_port_del(backer->dpif, node->data);
> +            dpif_port_del(backer->dpif, (OVS_FORCE odp_port_t)
> node->data);
>          }
>          simap_destroy(&tmp_backers);
>
> @@ -1239,7 +1241,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
> @@ -1350,7 +1352,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;
>
> @@ -1360,7 +1362,10 @@ 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_,
> +                           (OVS_FORCE ofp_port_t)
> +                              MIN((OVS_FORCE int) max_ports,
> +                                  (OVS_FORCE int) OFPP_MAX));
>
>      ofproto->netflow = NULL;
>      ofproto->sflow = NULL;
> @@ -1860,7 +1865,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_odp_port(port->odp_port, 0));
>      }
>      dpif_port_destroy(&dpif_port);
>
> @@ -2511,7 +2516,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;
> @@ -3154,14 +3159,14 @@ set_mac_table_config(struct ofproto *ofproto_,
> unsigned int idle_time,
>  /* Ports. */
>
>  static 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;
>  }
>
>  static 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;
> @@ -3336,7 +3341,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 = OVSP_NONE;
>          int error;
>
>          error = dpif_port_add(ofproto->backer->dpif, netdev, &port_no);
> @@ -3344,7 +3349,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, (OVS_FORCE uint32_t) port_no);
>          }
>      }
>
> @@ -3357,7 +3363,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);
> @@ -3926,7 +3932,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,
>                  struct initial_vals *initial_vals)
>  {
>      const struct ofport_dpif *port;
> @@ -3944,13 +3950,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;
>      }
> @@ -4025,7 +4031,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;
> @@ -4064,7 +4070,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);
> @@ -4168,7 +4174,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, NULL)
> @@ -4706,7 +4712,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);
> @@ -4803,7 +4809,8 @@ 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,
> +                                (OVS_FORCE odp_port_t)
> nl_attr_get_u32(a));
>              if (port && port->bundle && port->bundle->bond) {
>                  bond_account(port->bundle->bond, &facet->flow,
>                               vlan_tci_to_vid(vlan_tci), n_bytes);
> @@ -5132,7 +5139,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);
>          }
> @@ -5477,9 +5484,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;
>      }
>
> @@ -5654,13 +5662,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);
> @@ -5724,7 +5734,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,
> +                                         OVSP_NONE);
>          odp_put_userspace_action(pid, &cookie, sizeof cookie.slow_path,
> &buf);
>      } else {
>          put_userspace_action(ofproto, &buf, flow, &cookie,
> @@ -5744,7 +5755,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);
>  }
> @@ -5779,7 +5791,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;
> @@ -5814,12 +5826,12 @@ 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;
>      }
>
> @@ -5858,7 +5870,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;
>      }
>
> @@ -5913,7 +5925,7 @@ fix_sflow_action(struct xlate_ctx *ctx)
>  }
>
>  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);
> @@ -5921,7 +5933,7 @@ compose_output_action__(struct xlate_ctx *ctx,
> uint16_t ofp_port,
>      uint32_t flow_skb_mark;
>      uint8_t flow_nw_tos;
>      struct priority_to_dscp *pdscp;
> -    uint32_t out_port, odp_port;
> +    odp_port_t out_port, odp_port;
>
>      /* If 'struct flow' gets additional metadata, we'll need to zero it
> out
>       * before traversing a patch port. */
> @@ -5957,25 +5969,26 @@ compose_output_action__(struct xlate_ctx *ctx,
> uint16_t ofp_port,
>          }
>
>          ctx->ofproto = ofproto_dpif_cast(peer->up.ofproto);
> -        ctx->xin->flow.in_port = peer->up.ofp_port;
> +        ctx->xin->flow.in_port.ofp_port = peer->up.ofp_port;
>          ctx->xin->flow.metadata = htonll(0);
>          memset(&ctx->xin->flow.tunnel, 0, sizeof ctx->xin->flow.tunnel);
>          memset(ctx->xin->flow.regs, 0, sizeof ctx->xin->flow.regs);
>
> -        in_port = get_ofp_port(ctx->ofproto, ctx->xin->flow.in_port);
> +        in_port = get_ofp_port(ctx->ofproto,
> ctx->xin->flow.in_port.ofp_port);
>          special = process_special(ctx->ofproto, &ctx->xin->flow, in_port,
>                                    ctx->xin->packet);
>          if (special) {
>              ctx->xout->slow = special;
>          } else if (!in_port || may_receive(in_port, ctx)) {
>              if (!in_port || stp_forward_in_state(in_port->stp_state)) {
> -                xlate_table_action(ctx, ctx->xin->flow.in_port, 0, true);
> +                xlate_table_action(ctx, ctx->xin->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, ctx->xin->flow.in_port, 0, true);
> +                xlate_table_action(ctx, ctx->xin->flow.in_port.ofp_port,
> 0, true);
>                  ctx->base_flow = old_base_flow;
>                  ctx->xout->odp_actions.size = old_size;
>              }
> @@ -6025,7 +6038,7 @@ compose_output_action__(struct xlate_ctx *ctx,
> uint16_t ofp_port,
>                                   &ctx->xout->odp_actions);
>          ctx->xin->flow.tunnel = flow_tnl; /* Restore tunnel metadata */
>      } else {
> -        uint16_t vlandev_port;
> +        ofp_port_t vlandev_port;
>          odp_port = ofport->odp_port;
>          vlandev_port = vsp_realdev_to_vlandev(ctx->ofproto, ofp_port,
>                                                ctx->xin->flow.vlan_tci);
> @@ -6039,7 +6052,8 @@ compose_output_action__(struct xlate_ctx *ctx,
> uint16_t ofp_port,
>      }
>      commit_odp_actions(&ctx->xin->flow, &ctx->base_flow,
>                         &ctx->xout->odp_actions);
> -    nl_msg_put_u32(&ctx->xout->odp_actions, OVS_ACTION_ATTR_OUTPUT,
> out_port);
> +    nl_msg_put_u32(&ctx->xout->odp_actions,
> +                   OVS_ACTION_ATTR_OUTPUT, (OVS_FORCE uint32_t) out_port);
>
>      ctx->sflow_odp_port = odp_port;
>      ctx->sflow_n_outputs++;
> @@ -6053,7 +6067,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);
>  }
> @@ -6102,24 +6116,24 @@ 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__(ctx->ofproto, &ctx->xin->flow,
> table_id);
>
>          tag_the_flow(ctx, rule);
>
>          /* 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);
>
> @@ -6147,12 +6161,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;
> @@ -6169,9 +6183,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;
>          }
>
> @@ -6324,18 +6338,19 @@ execute_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);
> @@ -6353,7 +6368,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");
> @@ -6377,7 +6392,8 @@ xlate_output_reg_action(struct xlate_ctx *ctx,
>  {
>      uint64_t port = mf_get_subfield(&or->src, &ctx->xin->flow);
>      if (port <= UINT16_MAX) {
> -        xlate_output_action(ctx, port, or->max_len, false);
> +        xlate_output_action(ctx, (OVS_FORCE ofp_port_t) port,
> +                            or->max_len, false);
>      }
>  }
>
> @@ -6385,7 +6401,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;
> @@ -6401,8 +6417,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;
>      }
>
> @@ -6435,7 +6451,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;
> @@ -6460,12 +6476,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, slave_enabled_cb,
>                            ctx->ofproto);
>      if (bundle->dst.field) {
> -        nxm_reg_load(&bundle->dst, port, &ctx->xin->flow);
> +        nxm_reg_load(&bundle->dst, (OVS_FORCE uint16_t) port,
> &ctx->xin->flow);
>      } else {
>          xlate_output_action(ctx, port, 0, false);
>      }
> @@ -6976,7 +6992,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out
> *xout)
>          }
>      }
>
> -    in_port = get_ofp_port(ctx.ofproto, ctx.xin->flow.in_port);
> +    in_port = get_ofp_port(ctx.ofproto, ctx.xin->flow.in_port.ofp_port);
>      special = process_special(ctx.ofproto, &ctx.xin->flow, in_port,
>                                ctx.xin->packet);
>      if (special) {
> @@ -6985,7 +7001,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out
> *xout)
>          static struct vlog_rate_limit trace_rl = VLOG_RATE_LIMIT_INIT(1,
> 1);
>          struct initial_vals initial_vals;
>          size_t sample_actions_len;
> -        uint32_t local_odp_port;
> +        odp_port_t local_odp_port;
>
>          initial_vals.vlan_tci = ctx.base_flow.vlan_tci;
>
> @@ -7246,7 +7262,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;
> @@ -7282,7 +7298,8 @@ 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,
> +                              (OVS_FORCE odp_port_t) nl_attr_get_u32(a));
>          if (ofport && ofport->bundle) {
>              mirrors |= ofport->bundle->dst_mirrors;
>          }
> @@ -7407,7 +7424,7 @@ update_learning_table(struct ofproto_dpif *ofproto,
>  }
>
>  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;
> @@ -7517,7 +7534,8 @@ xlate_normal(struct xlate_ctx *ctx)
>
>      ctx->xout->has_normal = true;
>
> -    in_bundle = lookup_input_bundle(ctx->ofproto, ctx->xin->flow.in_port,
> +    in_bundle = lookup_input_bundle(ctx->ofproto,
> +                                    ctx->xin->flow.in_port.ofp_port,
>                                      ctx->xin->packet != NULL, &in_port);
>      if (!in_bundle) {
>          xlate_report(ctx, "no input bundle, dropping");
> @@ -7735,7 +7753,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);
>
> @@ -8070,6 +8089,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);
> @@ -8078,7 +8100,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);
>              initial_vals.vlan_tci = flow.vlan_tci;
>          }
>      }
> @@ -8322,7 +8344,7 @@ show_dp_format(const struct ofproto_dpif *ofproto,
> struct ds *ds)
>          struct ofport *ofport = node->data;
>          const char *name = netdev_get_name(ofport->netdev);
>          const char *type = netdev_get_type(ofport->netdev);
> -        uint32_t odp_port;
> +        odp_port_t odp_port;
>
>          ds_put_format(ds, "\t%s %u/", name, ofport->ofp_port);
>
> @@ -8524,7 +8546,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_);
> @@ -8556,9 +8578,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((OVS_FORCE uint16_t) realdev_ofp_port, vid);
>  }
>
>  /* Returns the OFP port number of the Linux VLAN device that corresponds
> to
> @@ -8568,9 +8590,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. */
> -static uint16_t
> +static 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);
> @@ -8589,11 +8611,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_ofp_port(vlandev_ofp_port, 0),
>                               &ofproto->vlandev_map) {
>          if (vsp->vlandev_ofp_port == vlandev_ofp_port) {
>              return vsp;
> @@ -8612,9 +8635,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;
> @@ -8639,17 +8662,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;
>  }
> @@ -8673,7 +8696,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);
>
> @@ -8684,7 +8707,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_ofp_port(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;
> @@ -8697,20 +8720,20 @@ vsp_add(struct ofport_dpif *port, uint16_t
> realdev_ofp_port, int vid)
>      }
>  }
>
> -static uint32_t
> -ofp_port_to_odp_port(const struct ofproto_dpif *ofproto, uint16_t
> ofp_port)
> +static 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;
>  }
>
>  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_odp_port(odp_port, 0),
>                               &backer->odp_to_ofport_map) {
>          if (port->odp_port == odp_port) {
>              return port;
> @@ -8720,8 +8743,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-provider.h b/ofproto/ofproto-provider.h
> index db0d589..7bc92be 100644
> --- a/ofproto/ofproto-provider.h
> +++ b/ofproto/ofproto-provider.h
> @@ -65,8 +65,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;
> @@ -243,12 +243,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 *);
>
> @@ -689,7 +689,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,
> @@ -1315,7 +1315,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 3788c2f..658931c 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -448,7 +448,8 @@ 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((OVS_FORCE uint16_t)
> +                                            ofproto->max_ports);
>      bitmap_set1(ofproto->ofp_port_ids, 0);
>
>      /* Check that hidden tables, if any, are at the end. */
> @@ -497,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(PORT_COMPARE(max_ports, <=, OFPP_MAX));
>      ofproto->max_ports = max_ports;
>  }
>
> @@ -709,7 +710,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);
> @@ -730,7 +731,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);
> @@ -755,7 +756,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)
>  {
> @@ -776,7 +777,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) {
> @@ -791,7 +792,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;
> @@ -820,7 +821,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;
> @@ -848,7 +849,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);
> @@ -862,7 +863,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
> @@ -1499,16 +1500,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,
> +                  (OVS_FORCE uint16_t) ofp_port);
>          update_port(ofproto, netdev_name);
>      }
>      if (ofp_portp) {
> @@ -1544,7 +1546,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) :
> "<unknown>";
> @@ -1681,26 +1683,30 @@ 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;
> +    ofp_port_t ofp_port;
> +    ofp_port_t end_port_no = ofproto->alloc_port_no;
>
> -    ofp_port = simap_get(&ofproto->ofp_requests, netdev_name);
> +    ofp_port = (OVS_FORCE ofp_port_t) simap_get(&ofproto->ofp_requests,
> +                                                netdev_name);
>      ofp_port = ofp_port ? ofp_port : OFPP_NONE;
>
> -    if (ofp_port >= ofproto->max_ports
> -            || bitmap_is_set(ofproto->ofp_port_ids, ofp_port)) {
> +    if (PORT_COMPARE(ofp_port, >=, ofproto->max_ports)
> +        || bitmap_is_set(ofproto->ofp_port_ids,
> +                         (OVS_FORCE uint16_t) 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) {
> +            ofp_port_increment(&(ofproto->alloc_port_no), 1);
> +            if (PORT_COMPARE(ofproto->alloc_port_no,
> +                           >=, ofproto->max_ports)) {
>                  ofproto->alloc_port_no = 0;
>              }
>              if (!bitmap_is_set(ofproto->ofp_port_ids,
> -                               ofproto->alloc_port_no)) {
> +                   (OVS_FORCE uint16_t) ofproto->alloc_port_no)) {
>                  ofp_port = ofproto->alloc_port_no;
>                  break;
>              }
> @@ -1709,15 +1715,15 @@ alloc_ofp_port(struct ofproto *ofproto, const char
> *netdev_name)
>              }
>          }
>      }
> -    bitmap_set1(ofproto->ofp_port_ids, ofp_port);
> +    bitmap_set1(ofproto->ofp_port_ids, (OVS_FORCE uint16_t) ofp_port);
>      return ofp_port;
>  }
>
>  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 (PORT_COMPARE(ofp_port, <, ofproto->max_ports)) {
> +        bitmap_set0(ofproto->ofp_port_ids, (OVS_FORCE uint16_t) ofp_port);
>      }
>  }
>
> @@ -1808,7 +1814,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_ofp_port(ofport->ofp_port, 0));
>      shash_add(&p->port_by_name, netdev_name, ofport);
>
>      update_mtu(p, ofport);
> @@ -1884,7 +1891,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) {
> @@ -1928,12 +1935,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_ofp_port(ofp_port, 0),
> +                             &ofproto->ports) {
>          if (port->ofp_port == ofp_port) {
>              return port;
>          }
> @@ -1970,6 +1978,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)) {
> @@ -2031,7 +2040,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,
> +                          (OVS_FORCE uint16_t) iface_hint->ofp_port);
>              }
>
>              netdev = ofport_open(p, &ofproto_port, &pp);
> @@ -2155,7 +2165,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));
> @@ -2164,7 +2174,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;
> @@ -2193,13 +2203,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);
>  }
>
> @@ -2360,6 +2372,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);
> @@ -2375,7 +2388,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 (PORT_COMPARE(po.in_port, >=, p->max_ports)
> +        && PORT_COMPARE(po.in_port, <, OFPP_MAX)) {
>          error = OFPERR_OFPBRC_BAD_PORT;
>          goto exit_free_ofpacts;
>      }
> @@ -2393,7 +2407,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,
> @@ -2581,7 +2596,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);
> @@ -2717,7 +2732,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;
> @@ -2768,7 +2783,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;
> @@ -2925,7 +2940,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);
> @@ -4249,7 +4264,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);
> @@ -5002,8 +5017,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 18241e7..90da2a0 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 57e8e23..95f9ca5 100644
> --- a/ofproto/pinsched.c
> +++ b/ofproto/pinsched.c
> @@ -21,6 +21,7 @@
>  #include <arpa/inet.h>
>  #include <stdint.h>
>  #include <stdlib.h>
> +#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_ofp_port(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 061cb01..06b22f4 100644
> --- a/ofproto/pinsched.h
> +++ b/ofproto/pinsched.h
> @@ -18,6 +18,7 @@
>  #define PINSCHED_H_H 1
>
>  #include <stdint.h>
> +#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 2ec1f0d..65fcef6 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 ec99aea..eb1b1ff 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 df28df3..a0e5f3d 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;
> @@ -212,7 +212,7 @@ tnl_port_receive(const struct flow *flow)
>   * '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
>   * shouldn't occur. */
> -uint32_t
> +odp_port_t
>  tnl_port_send(const struct tnl_port *tnl_port, struct flow *flow)
>  {
>      const struct netdev_tunnel_config *cfg;
> diff --git a/ofproto/tunnel.h b/ofproto/tunnel.h
> index 34c1133..828a4f0 100644
> --- a/ofproto/tunnel.h
> +++ b/ofproto/tunnel.h
> @@ -31,14 +31,14 @@
>  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 *);
> +odp_port_t tnl_port_send(const struct tnl_port *, struct flow *);
>
>  /* 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 f5b24b4..488e7f3 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] = (OVS_FORCE uint32_t) OFPP_NONE;
>      }
>
>      /* Cycles through each possible liveness permutation for the given
> @@ -186,11 +186,11 @@ 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;
>
> -            old_slave_id = flow->regs[0];
> +            old_slave_id = (OVS_FORCE ofp_port_t) flow->regs[0];
>              ofp_port = bundle_execute(bundle, flow, slave_enabled_cb,
> &sg);
> -            flow->regs[0] = ofp_port;
> +            flow->regs[0] = (OVS_FORCE uint32_t) 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 18dee86..6e8b6d8 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[] = { (OVS_FORCE ofp_port_t) 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 c77372f..1e7e8a3 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 = (OVS_FORCE ofp_port_t) 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 268a105..dc88ddf 100644
> --- a/tests/test-odp.c
> +++ b/tests/test-odp.c
> @@ -70,7 +70,7 @@ parse_keys(void)
>          /* 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 54505e8..f801d7e 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 = OVSP_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 = (OVS_FORCE odp_port_t) 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 != (OVS_FORCE odp_port_t) atoi(value)) {
>                      ovs_error(0, "%s: can't change port number from "
>                                "%"PRIu32" to %d",
>                                name, port_no, atoi(value));
> @@ -476,7 +476,7 @@ next:
>  }
>
>  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 = (OVS_FORCE odp_port_t) 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 48f0fbf..0d037a9 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, uint32_t port_no,
>                         struct ofputil_phy_port *pp, bool *trunc)
>  {
>      struct ofputil_switch_features features;
> @@ -671,7 +671,7 @@ fetch_port_by_features(const char *vconn_name,
>
>      while (!ofputil_pull_phy_port(oh->version, &b, pp)) {
>          if (port_no != UINT_MAX
> -            ? port_no == pp->port_no
> +            ? port_no == (OVS_FORCE uint32_t) pp->port_no
>              : !strcmp(pp->name, port_name)) {
>              found = true;
>              goto exit;
> @@ -685,7 +685,7 @@ exit:
>
>  static bool
>  fetch_port_by_stats(const char *vconn_name,
> -                    const char *port_name, unsigned int port_no,
> +                    const char *port_name, uint32_t port_no,
>                      struct ofputil_phy_port *pp)
>  {
>      struct ofpbuf *request;
> @@ -729,8 +729,9 @@ 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 != UINT_MAX
> +                    ? port_no == (OVS_FORCE uint32_t) pp->port_no
> +                    : !strcmp(pp->name, port_name)) {
>                      found = true;
>                      break;
>                  }
> @@ -754,7 +755,7 @@ static void
>  fetch_ofputil_phy_port(const char *vconn_name, const char *port_name,
>                         struct ofputil_phy_port *pp)
>  {
> -    unsigned int port_no;
> +    uint32_t port_no;
>      bool found;
>      bool trunc;
>
> @@ -779,10 +780,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 +1490,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 f5c4202..0988ef4 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. */
> @@ -246,7 +246,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 *,
> @@ -256,9 +257,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 *);
> @@ -266,7 +267,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.)
>   *
> @@ -1268,13 +1269,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_ofp_port(ofp_port, 0));
>      iface_set_ofport(iface->cfg, ofp_port);
>  }
>
> @@ -1309,7 +1311,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) {
> @@ -1412,7 +1414,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;
> @@ -1440,7 +1442,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) {
> @@ -1476,7 +1478,7 @@ error:
>   *
>   * Return true if an iface is successfully created, false otherwise. */
>  static bool
> -iface_create(struct bridge *br, struct if_cfg *if_cfg, uint16_t ofp_port)
> +iface_create(struct bridge *br, struct if_cfg *if_cfg, ofp_port_t
> ofp_port)
>  {
>      const struct ovsrec_interface *iface_cfg = if_cfg->cfg;
>      const struct ovsrec_port *port_cfg = if_cfg->parent;
> @@ -1487,6 +1489,7 @@ iface_create(struct bridge *br, struct if_cfg
> *if_cfg, uint16_t ofp_port)
>      int error;
>      bool ok = true;
>
> +    VLOG_INFO("iface_create ofp_port: %u", ofp_port);
>      /* Do the bits that can fail up front.
>       *
>       * It's a bit dangerous to call bridge_run_fast() here as ofproto's
> @@ -1538,7 +1541,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);
> @@ -3299,7 +3302,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 = (OVS_FORCE int) iface->ofp_port;
>      }
>
>      if (priority <= 0 || priority > UINT16_MAX) {
> @@ -3487,12 +3490,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_ofp_port(ofp_port, 0),
> +                             &br->ifaces) {
>          if (iface->ofp_port == ofp_port) {
>              return iface;
>          }
> @@ -3528,10 +3532,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 : (OVS_FORCE uint16_t) ofport;
>      if (if_cfg && !ovsdb_idl_row_is_synthetic(&if_cfg->header_)) {
>          ovsrec_interface_set_ofport(if_cfg, &port_, 1);
>      }
> @@ -3717,11 +3721,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 ? (OVS_FORCE ofp_port_t)
> *cfg->ofport
> +                                      : OFPP_NONE;
> +    return cfg->n_ofport_request ? (OVS_FORCE ofp_port_t)
> *cfg->ofport_request
> +                                 : ofport;
>  }
>
>
> @@ -4099,7 +4105,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;
>
> --
> 1.7.9.5
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openvswitch.org/pipermail/ovs-dev/attachments/20130610/2f3a384f/attachment-0003.html>


More information about the dev mailing list