return ENODEV;
}
+int
+netdev_get_carrier(const struct netdev *netdev, bool *carrier)
+{
+ char line[8];
+ int retval;
+ int error;
+ char *fn;
+ int fd;
+
+ *carrier = false;
+
+ fn = xasprintf("/sys/class/net/%s/carrier", netdev->name);
+ fd = open(fn, O_RDONLY);
+ if (fd < 0) {
+ error = errno;
+ VLOG_WARN_RL(&rl, "%s: open failed: %s", fn, strerror(error));
+ goto exit;
+ }
+
+ retval = read(fd, line, sizeof line);
+ if (retval < 0) {
+ error = errno;
+ if (error == EINVAL) {
+ /* This is the normal return value when we try to check carrier if
+ * the network device is not up. */
+ } else {
+ VLOG_WARN_RL(&rl, "%s: read failed: %s", fn, strerror(error));
+ }
+ goto exit_close;
+ } else if (retval == 0) {
+ error = EPROTO;
+ VLOG_WARN_RL(&rl, "%s: unexpected end of file", fn);
+ goto exit_close;
+ }
+
+ if (line[0] != '0' && line[0] != '1') {
+ error = EPROTO;
+ VLOG_WARN_RL(&rl, "%s: value is %c (expected 0 or 1)", fn, line[0]);
+ goto exit_close;
+ }
+ *carrier = line[0] != '0';
+ error = 0;
+
+exit_close:
+ close(fd);
+exit:
+ free(fn);
+ return error;
+}
+
int
netdev_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
{
if (flags & IFF_PROMISC) {
*flagsp |= NETDEV_PROMISC;
}
- if (flags & IFF_LOWER_UP) {
- *flagsp |= NETDEV_CARRIER;
- }
return 0;
}
enum netdev_flags {
NETDEV_UP = 0x0001, /* Device enabled? */
- NETDEV_PROMISC = 0x0002, /* Promiscuous mode? */
- NETDEV_CARRIER = 0x0004 /* Carrier detected? */
+ NETDEV_PROMISC = 0x0002 /* Promiscuous mode? */
};
enum netdev_pseudo_ethertype {
int netdev_turn_flags_on(struct netdev *, enum netdev_flags, bool permanent);
int netdev_turn_flags_off(struct netdev *, enum netdev_flags, bool permanent);
int netdev_arp_lookup(const struct netdev *, uint32_t ip, uint8_t mac[6]);
+int netdev_get_carrier(const struct netdev *, bool *carrier);
int netdev_get_stats(const struct netdev *, struct netdev_stats *);
int netdev_set_policing(struct netdev *, uint32_t kbits_rate,
uint32_t kbits_burst);
enum netdev_flags flags;
struct ofport *ofport;
struct netdev *netdev;
+ bool carrier;
int error;
error = netdev_open(odp_port->devname, NETDEV_ETH_TYPE_NONE, &netdev);
netdev_get_flags(netdev, &flags);
ofport->opp.config = flags & NETDEV_UP ? 0 : OFPPC_PORT_DOWN;
- ofport->opp.state = flags & NETDEV_CARRIER ? 0 : OFPPS_LINK_DOWN;
+
+ netdev_get_carrier(netdev, &carrier);
+ ofport->opp.state = carrier ? 0 : OFPPS_LINK_DOWN;
netdev_get_features(netdev,
&ofport->opp.curr, &ofport->opp.advertised,