[ovs-dev] [of1.1 09/11] netdev: Abstract "features" interface away from OpenFlow 1.0.

Ben Pfaff blp at nicira.com
Thu Feb 16 00:37:52 UTC 2012


netdev_get_features() and other functions have always used OpenFlow 1.0
"enum ofp_port_features" bits as part of their interface.  This commit
switches over to using an internally defined interface that is not tied
directly to any OpenFlow version, making evolution of each side of the
interface easier in the future.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/netdev-linux.c           |  115 +++++++++++++++++++++++-------------------
 lib/netdev-provider.h        |   13 +++--
 lib/netdev.c                 |   60 +++++++++++++---------
 lib/netdev.h                 |   35 +++++++++++--
 lib/ofp-util.c               |   32 ++++++++++++
 lib/ofp-util.h               |    5 ++
 ofproto/ofproto-dpif-sflow.c |    4 +-
 ofproto/ofproto.c            |   15 +++--
 vswitchd/bridge.c            |    4 +-
 9 files changed, 186 insertions(+), 97 deletions(-)

diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 6ad0852..ce889a7 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -1387,14 +1387,17 @@ netdev_pseudo_get_stats(const struct netdev *netdev_,
 
 /* Stores the features supported by 'netdev' into each of '*current',
  * '*advertised', '*supported', and '*peer' that are non-null.  Each value is a
- * bitmap of "enum ofp_port_features" bits, in host byte order.  Returns 0 if
- * successful, otherwise a positive errno value. */
+ * bitmap of NETDEV_* bits.  Returns 0 if successful, otherwise a positive
+ * errno value. */
 static int
 netdev_linux_get_features(const struct netdev *netdev,
-                          uint32_t *current, uint32_t *advertised,
-                          uint32_t *supported, uint32_t *peer)
+                          enum netdev_features *current,
+                          enum netdev_features *advertised,
+                          enum netdev_features *supported,
+                          enum netdev_features *peer)
 {
     struct ethtool_cmd ecmd;
+    uint32_t speed;
     int error;
 
     memset(&ecmd, 0, sizeof ecmd);
@@ -1407,102 +1410,109 @@ netdev_linux_get_features(const struct netdev *netdev,
     /* Supported features. */
     *supported = 0;
     if (ecmd.supported & SUPPORTED_10baseT_Half) {
-        *supported |= OFPPF_10MB_HD;
+        *supported |= NETDEV_F_10MB_HD;
     }
     if (ecmd.supported & SUPPORTED_10baseT_Full) {
-        *supported |= OFPPF_10MB_FD;
+        *supported |= NETDEV_F_10MB_FD;
     }
     if (ecmd.supported & SUPPORTED_100baseT_Half)  {
-        *supported |= OFPPF_100MB_HD;
+        *supported |= NETDEV_F_100MB_HD;
     }
     if (ecmd.supported & SUPPORTED_100baseT_Full) {
-        *supported |= OFPPF_100MB_FD;
+        *supported |= NETDEV_F_100MB_FD;
     }
     if (ecmd.supported & SUPPORTED_1000baseT_Half) {
-        *supported |= OFPPF_1GB_HD;
+        *supported |= NETDEV_F_1GB_HD;
     }
     if (ecmd.supported & SUPPORTED_1000baseT_Full) {
-        *supported |= OFPPF_1GB_FD;
+        *supported |= NETDEV_F_1GB_FD;
     }
     if (ecmd.supported & SUPPORTED_10000baseT_Full) {
-        *supported |= OFPPF_10GB_FD;
+        *supported |= NETDEV_F_10GB_FD;
     }
     if (ecmd.supported & SUPPORTED_TP) {
-        *supported |= OFPPF_COPPER;
+        *supported |= NETDEV_F_COPPER;
     }
     if (ecmd.supported & SUPPORTED_FIBRE) {
-        *supported |= OFPPF_FIBER;
+        *supported |= NETDEV_F_FIBER;
     }
     if (ecmd.supported & SUPPORTED_Autoneg) {
-        *supported |= OFPPF_AUTONEG;
+        *supported |= NETDEV_F_AUTONEG;
     }
     if (ecmd.supported & SUPPORTED_Pause) {
-        *supported |= OFPPF_PAUSE;
+        *supported |= NETDEV_F_PAUSE;
     }
     if (ecmd.supported & SUPPORTED_Asym_Pause) {
-        *supported |= OFPPF_PAUSE_ASYM;
+        *supported |= NETDEV_F_PAUSE_ASYM;
     }
 
     /* Advertised features. */
     *advertised = 0;
     if (ecmd.advertising & ADVERTISED_10baseT_Half) {
-        *advertised |= OFPPF_10MB_HD;
+        *advertised |= NETDEV_F_10MB_HD;
     }
     if (ecmd.advertising & ADVERTISED_10baseT_Full) {
-        *advertised |= OFPPF_10MB_FD;
+        *advertised |= NETDEV_F_10MB_FD;
     }
     if (ecmd.advertising & ADVERTISED_100baseT_Half) {
-        *advertised |= OFPPF_100MB_HD;
+        *advertised |= NETDEV_F_100MB_HD;
     }
     if (ecmd.advertising & ADVERTISED_100baseT_Full) {
-        *advertised |= OFPPF_100MB_FD;
+        *advertised |= NETDEV_F_100MB_FD;
     }
     if (ecmd.advertising & ADVERTISED_1000baseT_Half) {
-        *advertised |= OFPPF_1GB_HD;
+        *advertised |= NETDEV_F_1GB_HD;
     }
     if (ecmd.advertising & ADVERTISED_1000baseT_Full) {
-        *advertised |= OFPPF_1GB_FD;
+        *advertised |= NETDEV_F_1GB_FD;
     }
     if (ecmd.advertising & ADVERTISED_10000baseT_Full) {
-        *advertised |= OFPPF_10GB_FD;
+        *advertised |= NETDEV_F_10GB_FD;
     }
     if (ecmd.advertising & ADVERTISED_TP) {
-        *advertised |= OFPPF_COPPER;
+        *advertised |= NETDEV_F_COPPER;
     }
     if (ecmd.advertising & ADVERTISED_FIBRE) {
-        *advertised |= OFPPF_FIBER;
+        *advertised |= NETDEV_F_FIBER;
     }
     if (ecmd.advertising & ADVERTISED_Autoneg) {
-        *advertised |= OFPPF_AUTONEG;
+        *advertised |= NETDEV_F_AUTONEG;
     }
     if (ecmd.advertising & ADVERTISED_Pause) {
-        *advertised |= OFPPF_PAUSE;
+        *advertised |= NETDEV_F_PAUSE;
     }
     if (ecmd.advertising & ADVERTISED_Asym_Pause) {
-        *advertised |= OFPPF_PAUSE_ASYM;
+        *advertised |= NETDEV_F_PAUSE_ASYM;
     }
 
     /* Current settings. */
-    if (ecmd.speed == SPEED_10) {
-        *current = ecmd.duplex ? OFPPF_10MB_FD : OFPPF_10MB_HD;
-    } else if (ecmd.speed == SPEED_100) {
-        *current = ecmd.duplex ? OFPPF_100MB_FD : OFPPF_100MB_HD;
-    } else if (ecmd.speed == SPEED_1000) {
-        *current = ecmd.duplex ? OFPPF_1GB_FD : OFPPF_1GB_HD;
-    } else if (ecmd.speed == SPEED_10000) {
-        *current = OFPPF_10GB_FD;
+    speed = (ecmd.speed_hi << 16) | ecmd.speed;
+    if (speed == SPEED_10) {
+        *current = ecmd.duplex ? NETDEV_F_10MB_FD : NETDEV_F_10MB_HD;
+    } else if (speed == SPEED_100) {
+        *current = ecmd.duplex ? NETDEV_F_100MB_FD : NETDEV_F_100MB_HD;
+    } else if (speed == SPEED_1000) {
+        *current = ecmd.duplex ? NETDEV_F_1GB_FD : NETDEV_F_1GB_HD;
+    } else if (speed == SPEED_10000) {
+        *current = NETDEV_F_10GB_FD;
+    } else if (speed == 40000) {
+        *current = NETDEV_F_40GB_FD;
+    } else if (speed == 100000) {
+        *current = NETDEV_F_100GB_FD;
+    } else if (speed == 1000000) {
+        *current = NETDEV_F_1TB_FD;
     } else {
         *current = 0;
     }
 
     if (ecmd.port == PORT_TP) {
-        *current |= OFPPF_COPPER;
+        *current |= NETDEV_F_COPPER;
     } else if (ecmd.port == PORT_FIBRE) {
-        *current |= OFPPF_FIBER;
+        *current |= NETDEV_F_FIBER;
     }
 
     if (ecmd.autoneg) {
-        *current |= OFPPF_AUTONEG;
+        *current |= NETDEV_F_AUTONEG;
     }
 
     /* Peer advertisements. */
@@ -1513,7 +1523,8 @@ netdev_linux_get_features(const struct netdev *netdev,
 
 /* Set the features advertised by 'netdev' to 'advertise'. */
 static int
-netdev_linux_set_advertisements(struct netdev *netdev, uint32_t advertise)
+netdev_linux_set_advertisements(struct netdev *netdev,
+                                enum netdev_features advertise)
 {
     struct ethtool_cmd ecmd;
     int error;
@@ -1526,40 +1537,40 @@ netdev_linux_set_advertisements(struct netdev *netdev, uint32_t advertise)
     }
 
     ecmd.advertising = 0;
-    if (advertise & OFPPF_10MB_HD) {
+    if (advertise & NETDEV_F_10MB_HD) {
         ecmd.advertising |= ADVERTISED_10baseT_Half;
     }
-    if (advertise & OFPPF_10MB_FD) {
+    if (advertise & NETDEV_F_10MB_FD) {
         ecmd.advertising |= ADVERTISED_10baseT_Full;
     }
-    if (advertise & OFPPF_100MB_HD) {
+    if (advertise & NETDEV_F_100MB_HD) {
         ecmd.advertising |= ADVERTISED_100baseT_Half;
     }
-    if (advertise & OFPPF_100MB_FD) {
+    if (advertise & NETDEV_F_100MB_FD) {
         ecmd.advertising |= ADVERTISED_100baseT_Full;
     }
-    if (advertise & OFPPF_1GB_HD) {
+    if (advertise & NETDEV_F_1GB_HD) {
         ecmd.advertising |= ADVERTISED_1000baseT_Half;
     }
-    if (advertise & OFPPF_1GB_FD) {
+    if (advertise & NETDEV_F_1GB_FD) {
         ecmd.advertising |= ADVERTISED_1000baseT_Full;
     }
-    if (advertise & OFPPF_10GB_FD) {
+    if (advertise & NETDEV_F_10GB_FD) {
         ecmd.advertising |= ADVERTISED_10000baseT_Full;
     }
-    if (advertise & OFPPF_COPPER) {
+    if (advertise & NETDEV_F_COPPER) {
         ecmd.advertising |= ADVERTISED_TP;
     }
-    if (advertise & OFPPF_FIBER) {
+    if (advertise & NETDEV_F_FIBER) {
         ecmd.advertising |= ADVERTISED_FIBRE;
     }
-    if (advertise & OFPPF_AUTONEG) {
+    if (advertise & NETDEV_F_AUTONEG) {
         ecmd.advertising |= ADVERTISED_Autoneg;
     }
-    if (advertise & OFPPF_PAUSE) {
+    if (advertise & NETDEV_F_PAUSE) {
         ecmd.advertising |= ADVERTISED_Pause;
     }
-    if (advertise & OFPPF_PAUSE_ASYM) {
+    if (advertise & NETDEV_F_PAUSE_ASYM) {
         ecmd.advertising |= ADVERTISED_Asym_Pause;
     }
     return netdev_linux_do_ethtool(netdev_get_name(netdev), &ecmd,
diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
index d5a30c8..2ef75b3 100644
--- a/lib/netdev-provider.h
+++ b/lib/netdev-provider.h
@@ -308,20 +308,23 @@ struct netdev_class {
 
     /* Stores the features supported by 'netdev' into each of '*current',
      * '*advertised', '*supported', and '*peer'.  Each value is a bitmap of
-     * "enum ofp_port_features" bits, in host byte order.
+     * NETDEV_F_* bits.
      *
      * This function may be set to null if it would always return EOPNOTSUPP.
      */
     int (*get_features)(const struct netdev *netdev,
-                        uint32_t *current, uint32_t *advertised,
-                        uint32_t *supported, uint32_t *peer);
+                        enum netdev_features *current,
+                        enum netdev_features *advertised,
+                        enum netdev_features *supported,
+                        enum netdev_features *peer);
 
     /* Set the features advertised by 'netdev' to 'advertise', which is a
-     * bitmap of "enum ofp_port_features" bits, in host byte order.
+     * set of NETDEV_F_* bits.
      *
      * This function may be set to null for a network device that does not
      * support configuring advertisements. */
-    int (*set_advertisements)(struct netdev *netdev, uint32_t advertise);
+    int (*set_advertisements)(struct netdev *netdev,
+                              enum netdev_features advertise);
 
     /* Attempts to set input rate limiting (policing) policy, such that up to
      * 'kbits_rate' kbps of traffic is accepted, with a maximum accumulative
diff --git a/lib/netdev.c b/lib/netdev.c
index eff6e4c..30688f2 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -576,13 +576,17 @@ netdev_get_ifindex(const struct netdev *netdev)
  * cases this function will always return EOPNOTSUPP. */
 int
 netdev_get_features(const struct netdev *netdev,
-                    uint32_t *current, uint32_t *advertised,
-                    uint32_t *supported, uint32_t *peer)
+                    enum netdev_features *current,
+                    enum netdev_features *advertised,
+                    enum netdev_features *supported,
+                    enum netdev_features *peer)
 {
     int (*get_features)(const struct netdev *netdev,
-                        uint32_t *current, uint32_t *advertised,
-                        uint32_t *supported, uint32_t *peer);
-    uint32_t dummy[4];
+                        enum netdev_features *current,
+                        enum netdev_features *advertised,
+                        enum netdev_features *supported,
+                        enum netdev_features *peer);
+    enum netdev_features dummy[4];
     int error;
 
     if (!current) {
@@ -608,39 +612,47 @@ netdev_get_features(const struct netdev *netdev,
     return error;
 }
 
-/* Returns the maximum speed of a network connection that has the "enum
- * ofp_port_features" bits in 'features', in bits per second.  If no bits that
- * indicate a speed are set in 'features', assumes 100Mbps. */
+/* Returns the maximum speed of a network connection that has the NETDEV_F_*
+ * bits in 'features', in bits per second.  If no bits that indicate a speed
+ * are set in 'features', assumes 100Mbps. */
 uint64_t
-netdev_features_to_bps(uint32_t features)
+netdev_features_to_bps(enum netdev_features features)
 {
     enum {
-        F_10000MB = OFPPF_10GB_FD,
-        F_1000MB = OFPPF_1GB_HD | OFPPF_1GB_FD,
-        F_100MB = OFPPF_100MB_HD | OFPPF_100MB_FD,
-        F_10MB = OFPPF_10MB_HD | OFPPF_10MB_FD
+        F_1000000MB = NETDEV_F_1TB_FD,
+        F_100000MB = NETDEV_F_100GB_FD,
+        F_40000MB = NETDEV_F_40GB_FD,
+        F_10000MB = NETDEV_F_10GB_FD,
+        F_1000MB = NETDEV_F_1GB_HD | NETDEV_F_1GB_FD,
+        F_100MB = NETDEV_F_100MB_HD | NETDEV_F_100MB_FD,
+        F_10MB = NETDEV_F_10MB_HD | NETDEV_F_10MB_FD
     };
 
-    return (  features & F_10000MB  ? UINT64_C(10000000000)
-            : features & F_1000MB   ? UINT64_C(1000000000)
-            : features & F_100MB    ? UINT64_C(100000000)
-            : features & F_10MB     ? UINT64_C(10000000)
-                                    : UINT64_C(100000000));
+    return (  features & F_1000000MB ? UINT64_C(1000000000000)
+            : features & F_100000MB  ? UINT64_C(100000000000)
+            : features & F_40000MB   ? UINT64_C(40000000000)
+            : features & F_10000MB   ? UINT64_C(10000000000)
+            : features & F_1000MB    ? UINT64_C(1000000000)
+            : features & F_100MB     ? UINT64_C(100000000)
+            : features & F_10MB      ? UINT64_C(10000000)
+                                     : UINT64_C(100000000));
 }
 
-/* Returns true if any of the "enum ofp_port_features" bits that indicate a
- * full-duplex link are set in 'features', otherwise false. */
+/* Returns true if any of the NETDEV_F_* bits that indicate a full-duplex link
+ * are set in 'features', otherwise false. */
 bool
-netdev_features_is_full_duplex(uint32_t features)
+netdev_features_is_full_duplex(enum netdev_features features)
 {
-    return (features & (OFPPF_10MB_FD | OFPPF_100MB_FD | OFPPF_1GB_FD
-                        | OFPPF_10GB_FD)) != 0;
+    return (features & (NETDEV_F_10MB_FD | NETDEV_F_100MB_FD | NETDEV_F_1GB_FD
+                        | NETDEV_F_10GB_FD | NETDEV_F_40GB_FD
+                        | NETDEV_F_100GB_FD | NETDEV_F_1TB_FD)) != 0;
 }
 
 /* Set the features advertised by 'netdev' to 'advertise'.  Returns 0 if
  * successful, otherwise a positive errno value. */
 int
-netdev_set_advertisements(struct netdev *netdev, uint32_t advertise)
+netdev_set_advertisements(struct netdev *netdev,
+                          enum netdev_features advertise)
 {
     return (netdev_get_dev(netdev)->netdev_class->set_advertisements
             ? netdev_get_dev(netdev)->netdev_class->set_advertisements(
diff --git a/lib/netdev.h b/lib/netdev.h
index 24a9b64..ea278ff 100644
--- a/lib/netdev.h
+++ b/lib/netdev.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -120,12 +120,35 @@ int netdev_get_etheraddr(const struct netdev *, uint8_t mac[6]);
 bool netdev_get_carrier(const struct netdev *);
 long long int netdev_get_carrier_resets(const struct netdev *);
 int netdev_set_miimon_interval(struct netdev *, long long int interval);
+
+/* Features. */
+enum netdev_features {
+    NETDEV_F_10MB_HD =    1 << 0,  /* 10 Mb half-duplex rate support. */
+    NETDEV_F_10MB_FD =    1 << 1,  /* 10 Mb full-duplex rate support. */
+    NETDEV_F_100MB_HD =   1 << 2,  /* 100 Mb half-duplex rate support. */
+    NETDEV_F_100MB_FD =   1 << 3,  /* 100 Mb full-duplex rate support. */
+    NETDEV_F_1GB_HD =     1 << 4,  /* 1 Gb half-duplex rate support. */
+    NETDEV_F_1GB_FD =     1 << 5,  /* 1 Gb full-duplex rate support. */
+    NETDEV_F_10GB_FD =    1 << 6,  /* 10 Gb full-duplex rate support. */
+    NETDEV_F_40GB_FD =    1 << 7,  /* 40 Gb full-duplex rate support. */
+    NETDEV_F_100GB_FD =   1 << 8,  /* 100 Gb full-duplex rate support. */
+    NETDEV_F_1TB_FD =     1 << 9,  /* 1 Tb full-duplex rate support. */
+    NETDEV_F_OTHER =      1 << 10, /* Other rate, not in the list. */
+    NETDEV_F_COPPER =     1 << 11, /* Copper medium. */
+    NETDEV_F_FIBER =      1 << 12, /* Fiber medium. */
+    NETDEV_F_AUTONEG =    1 << 13, /* Auto-negotiation. */
+    NETDEV_F_PAUSE =      1 << 14, /* Pause. */
+    NETDEV_F_PAUSE_ASYM = 1 << 15, /* Asymmetric pause. */
+};
+
 int netdev_get_features(const struct netdev *,
-                        uint32_t *current, uint32_t *advertised,
-                        uint32_t *supported, uint32_t *peer);
-uint64_t netdev_features_to_bps(uint32_t features);
-bool netdev_features_is_full_duplex(uint32_t features);
-int netdev_set_advertisements(struct netdev *, uint32_t advertise);
+                        enum netdev_features *current,
+                        enum netdev_features *advertised,
+                        enum netdev_features *supported,
+                        enum netdev_features *peer);
+uint64_t netdev_features_to_bps(enum netdev_features features);
+bool netdev_features_is_full_duplex(enum netdev_features features);
+int netdev_set_advertisements(struct netdev *, enum netdev_features advertise);
 
 /* TCP/IP stack interface. */
 int netdev_get_in4(const struct netdev *, struct in_addr *address,
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 5cb07b5..10e7e6f 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -30,6 +30,7 @@
 #include "learn.h"
 #include "multipath.h"
 #include "meta-flow.h"
+#include "netdev.h"
 #include "nx-match.h"
 #include "ofp-errors.h"
 #include "ofp-util.h"
@@ -2184,6 +2185,37 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
 
     return 0;
 }
+
+/* ofputil_phy_port */
+
+/* NETDEV_F_* to and from OFPPF_* and OFPPF10_*. */
+BUILD_ASSERT_DECL((int) NETDEV_F_10MB_HD    == OFPPF_10MB_HD);  /* bit 0 */
+BUILD_ASSERT_DECL((int) NETDEV_F_10MB_FD    == OFPPF_10MB_FD);  /* bit 1 */
+BUILD_ASSERT_DECL((int) NETDEV_F_100MB_HD   == OFPPF_100MB_HD); /* bit 2 */
+BUILD_ASSERT_DECL((int) NETDEV_F_100MB_FD   == OFPPF_100MB_FD); /* bit 3 */
+BUILD_ASSERT_DECL((int) NETDEV_F_1GB_HD     == OFPPF_1GB_HD);   /* bit 4 */
+BUILD_ASSERT_DECL((int) NETDEV_F_1GB_FD     == OFPPF_1GB_FD);   /* bit 5 */
+BUILD_ASSERT_DECL((int) NETDEV_F_10GB_FD    == OFPPF_10GB_FD);  /* bit 6 */
+
+/* NETDEV_F_ bits 11...15 are OFPPF10_ bits 7...11: */
+BUILD_ASSERT_DECL((int) NETDEV_F_COPPER == (OFPPF_COPPER << 4));
+BUILD_ASSERT_DECL((int) NETDEV_F_FIBER == (OFPPF_FIBER << 4));
+BUILD_ASSERT_DECL((int) NETDEV_F_AUTONEG == (OFPPF_AUTONEG << 4));
+BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE == (OFPPF_PAUSE << 4));
+BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE_ASYM == (OFPPF_PAUSE_ASYM << 4));
+
+enum netdev_features
+ofputil_netdev_port_features_from_ofp10(ovs_be32 ofp10_)
+{
+    uint32_t ofp10 = ntohl(ofp10_);
+    return (ofp10 & 0x7f) | ((ofp10 & 0xf80) << 4);
+}
+
+ovs_be32
+ofputil_netdev_port_features_to_ofp10(enum netdev_features features)
+{
+    return htonl((features & 0x7f) | ((features & 0xf800) >> 4));
+}
 
 struct ofpbuf *
 ofputil_encode_packet_out(const struct ofputil_packet_out *po)
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 90c49c4..5cbd711 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -23,6 +23,7 @@
 #include <stdint.h>
 #include "classifier.h"
 #include "flow.h"
+#include "netdev.h"
 #include "openflow/nicira-ext.h"
 #include "openvswitch/types.h"
 
@@ -321,6 +322,10 @@ enum ofperr ofputil_decode_packet_out(struct ofputil_packet_out *,
                                       const struct ofp_packet_out *);
 struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *);
 
+/* OFPFF_* bits. */
+enum netdev_features ofputil_netdev_port_features_from_ofp10(ovs_be32 ofp10);
+ovs_be32 ofputil_netdev_port_features_to_ofp10(enum netdev_features);
+
 /* OpenFlow protocol utility functions. */
 void *make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **);
 void *make_nxmsg(size_t openflow_len, uint32_t subtype, struct ofpbuf **);
diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c
index 5825636..73da2af 100644
--- a/ofproto/ofproto-dpif-sflow.c
+++ b/ofproto/ofproto-dpif-sflow.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
  * Copyright (c) 2009 InMon Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -160,11 +160,11 @@ sflow_agent_get_counters(void *ds_, SFLPoller *poller,
 {
     struct dpif_sflow *ds = ds_;
     SFLCounters_sample_element elem;
+    enum netdev_features current;
     struct dpif_sflow_port *dsp;
     SFLIf_counters *counters;
     struct netdev_stats stats;
     enum netdev_flags flags;
-    uint32_t current;
 
     dsp = dpif_sflow_find_port(ds, poller->bridgePort);
     if (!dsp) {
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index ae51ee0..156ff08 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1402,7 +1402,7 @@ reinit_ports(struct ofproto *p)
 static struct netdev *
 ofport_open(const struct ofproto_port *ofproto_port, struct ofp_phy_port *opp)
 {
-    uint32_t curr, advertised, supported, peer;
+    enum netdev_features curr, advertised, supported, peer;
     enum netdev_flags flags;
     struct netdev *netdev;
     int error;
@@ -1424,10 +1424,10 @@ ofport_open(const struct ofproto_port *ofproto_port, struct ofp_phy_port *opp)
     ovs_strzcpy(opp->name, ofproto_port->name, sizeof opp->name);
     opp->config = flags & NETDEV_UP ? 0 : htonl(OFPPC_PORT_DOWN);
     opp->state = netdev_get_carrier(netdev) ? 0 : htonl(OFPPS_LINK_DOWN);
-    opp->curr = htonl(curr);
-    opp->advertised = htonl(advertised);
-    opp->supported = htonl(supported);
-    opp->peer = htonl(peer);
+    opp->curr = ofputil_netdev_port_features_to_ofp10(curr);
+    opp->advertised = ofputil_netdev_port_features_to_ofp10(advertised);
+    opp->supported = ofputil_netdev_port_features_to_ofp10(supported);
+    opp->peer = ofputil_netdev_port_features_to_ofp10(peer);
 
     return netdev;
 }
@@ -2037,7 +2037,10 @@ handle_port_mod(struct ofconn *ofconn, const struct ofp_header *oh)
     } else {
         update_port_config(port, opm->config, opm->mask);
         if (opm->advertise) {
-            netdev_set_advertisements(port->netdev, ntohl(opm->advertise));
+            enum netdev_features adv;
+
+            adv = ofputil_netdev_port_features_from_ofp10(opm->advertise);
+            netdev_set_advertisements(port->netdev, adv);
         }
     }
     return 0;
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index f6cf119..7d8adad 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -842,7 +842,7 @@ port_configure_stp(const struct ofproto *ofproto, struct port *port,
     if (config_str) {
         port_s->path_cost = strtoul(config_str, NULL, 10);
     } else {
-        uint32_t current;
+        enum netdev_features current;
 
         if (netdev_get_features(iface->netdev, &current, NULL, NULL, NULL)) {
             /* Couldn't get speed, so assume 100Mb/s. */
@@ -1479,8 +1479,8 @@ iface_refresh_status(struct iface *iface)
 {
     struct shash sh;
 
+    enum netdev_features current;
     enum netdev_flags flags;
-    uint32_t current;
     int64_t bps;
     int mtu;
     int64_t mtu_64;
-- 
1.7.2.5




More information about the dev mailing list