/* 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);
/* 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. */
/* 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;
}
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,
/* 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
* 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) {
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(
/*
- * 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.
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,
#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"
return 0;
}
+\f
+/* 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)
#include <stdint.h>
#include "classifier.h"
#include "flow.h"
+#include "netdev.h"
#include "openflow/nicira-ext.h"
#include "openvswitch/types.h"
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 **);
/*
- * 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");
{
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) {
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;
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;
}
} 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;
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, ¤t, NULL, NULL, NULL)) {
/* Couldn't get speed, so assume 100Mb/s. */
{
struct shash sh;
+ enum netdev_features current;
enum netdev_flags flags;
- uint32_t current;
int64_t bps;
int mtu;
int64_t mtu_64;