/*
- * Copyright (c) 2010, 2011 Nicira Networks.
+ * Copyright (c) 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.
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
+#include <linux/openvswitch.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include "netlink-notifier.h"
#include "netlink-socket.h"
#include "ofpbuf.h"
-#include "openvswitch/datapath-protocol.h"
#include "openvswitch/tunnel.h"
#include "packets.h"
#include "route-table.h"
#include "shash.h"
#include "socket-util.h"
+#include "unaligned.h"
#include "vlog.h"
VLOG_DEFINE_THIS_MODULE(netdev_vport);
return (is_vport_class(class) ? vport_class_cast(class)->type
: class == &netdev_internal_class ? OVS_VPORT_TYPE_INTERNAL
- : class == &netdev_linux_class ? OVS_VPORT_TYPE_NETDEV
+ : (class == &netdev_linux_class ||
+ class == &netdev_tap_class) ? OVS_VPORT_TYPE_NETDEV
: OVS_VPORT_TYPE_UNSPEC);
}
{
struct netdev_dev_vport *netdev_dev = netdev_dev_vport_cast(netdev_dev_);
+ ofpbuf_delete(netdev_dev->options);
route_table_unregister();
free(netdev_dev);
}
return error;
}
-static int
-netdev_vport_get_mtu(const struct netdev *netdev OVS_UNUSED,
- int *mtup OVS_UNUSED)
-{
- return EOPNOTSUPP;
-}
-
-static int
-netdev_vport_set_mtu(const struct netdev *netdev OVS_UNUSED,
- int mtu OVS_UNUSED)
+/* Copies 'src' into 'dst', performing format conversion in the process.
+ *
+ * 'src' is allowed to be misaligned. */
+static void
+netdev_stats_from_ovs_vport_stats(struct netdev_stats *dst,
+ const struct ovs_vport_stats *src)
+{
+ dst->rx_packets = get_unaligned_u64(&src->rx_packets);
+ dst->tx_packets = get_unaligned_u64(&src->tx_packets);
+ dst->rx_bytes = get_unaligned_u64(&src->rx_bytes);
+ dst->tx_bytes = get_unaligned_u64(&src->tx_bytes);
+ dst->rx_errors = get_unaligned_u64(&src->rx_errors);
+ dst->tx_errors = get_unaligned_u64(&src->tx_errors);
+ dst->rx_dropped = get_unaligned_u64(&src->rx_dropped);
+ dst->tx_dropped = get_unaligned_u64(&src->tx_dropped);
+ dst->multicast = 0;
+ dst->collisions = 0;
+ dst->rx_length_errors = 0;
+ dst->rx_over_errors = 0;
+ dst->rx_crc_errors = 0;
+ dst->rx_frame_errors = 0;
+ dst->rx_fifo_errors = 0;
+ dst->rx_missed_errors = 0;
+ dst->tx_aborted_errors = 0;
+ dst->tx_carrier_errors = 0;
+ dst->tx_fifo_errors = 0;
+ dst->tx_heartbeat_errors = 0;
+ dst->tx_window_errors = 0;
+}
+
+/* Copies 'src' into 'dst', performing format conversion in the process. */
+static void
+netdev_stats_to_ovs_vport_stats(struct ovs_vport_stats *dst,
+ const struct netdev_stats *src)
{
- return EOPNOTSUPP;
+ dst->rx_packets = src->rx_packets;
+ dst->tx_packets = src->tx_packets;
+ dst->rx_bytes = src->rx_bytes;
+ dst->tx_bytes = src->tx_bytes;
+ dst->rx_errors = src->rx_errors;
+ dst->tx_errors = src->tx_errors;
+ dst->rx_dropped = src->rx_dropped;
+ dst->tx_dropped = src->tx_dropped;
}
int
return EOPNOTSUPP;
}
- netdev_stats_from_rtnl_link_stats64(stats, reply.stats);
+ netdev_stats_from_ovs_vport_stats(stats, reply.stats);
ofpbuf_delete(buf);
int
netdev_vport_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
{
- struct rtnl_link_stats64 rtnl_stats;
+ struct ovs_vport_stats rtnl_stats;
struct dpif_linux_vport vport;
int err;
- netdev_stats_to_rtnl_link_stats64(&rtnl_stats, stats);
+ netdev_stats_to_ovs_vport_stats(&rtnl_stats, stats);
dpif_linux_vport_init(&vport);
vport.cmd = OVS_VPORT_CMD_SET;
}
static int
-netdev_vport_get_status(const struct netdev *netdev, struct shash *sh)
+netdev_vport_get_drv_info(const struct netdev *netdev, struct shash *sh)
{
const char *iface = netdev_vport_get_tnl_iface(netdev);
struct shash_node *node;
bool ipsec_mech_set = false;
ovs_be32 daddr = htonl(0);
+ ovs_be32 saddr = htonl(0);
uint32_t flags;
flags = TNL_F_DF_DEFAULT | TNL_F_PMTUD | TNL_F_HDR_CACHE;
if (lookup_ip(node->data, &in_addr)) {
VLOG_WARN("%s: bad %s 'local_ip'", name, type);
} else {
- nl_msg_put_be32(options, OVS_TUNNEL_ATTR_SRC_IPV4,
- in_addr.s_addr);
+ saddr = in_addr.s_addr;
}
} else if (!strcmp(node->name, "tos")) {
if (!strcmp(node->data, "inherit")) {
}
nl_msg_put_be32(options, OVS_TUNNEL_ATTR_DST_IPV4, daddr);
+ if (saddr) {
+ if (ip_is_multicast(daddr)) {
+ VLOG_WARN("%s: remote_ip is multicast, ignoring local_ip", name);
+ } else {
+ nl_msg_put_be32(options, OVS_TUNNEL_ATTR_SRC_IPV4, saddr);
+ }
+ }
+
nl_msg_put_u32(options, OVS_TUNNEL_ATTR_FLAGS, flags);
return 0;
netdev_vport_open, \
netdev_vport_close, \
\
- NULL, /* enumerate */ \
- \
NULL, /* listen */ \
NULL, /* recv */ \
NULL, /* recv_wait */ \
\
netdev_vport_set_etheraddr, \
netdev_vport_get_etheraddr, \
- netdev_vport_get_mtu, \
- netdev_vport_set_mtu, \
+ NULL, /* get_mtu */ \
+ NULL, /* set_mtu */ \
NULL, /* get_ifindex */ \
NULL, /* get_carrier */ \
+ NULL, /* get_carrier_resets */ \
NULL, /* get_miimon */ \
netdev_vport_get_stats, \
netdev_vport_set_stats, \
\
NULL, /* get_features */ \
NULL, /* set_advertisements */ \
- NULL, /* get_vlan_vid */ \
\
NULL, /* set_policing */ \
NULL, /* get_qos_types */ \
{
static const struct vport_class vport_classes[] = {
{ OVS_VPORT_TYPE_GRE,
- { "gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
+ { "gre", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_GRE,
- { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
+ { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_CAPWAP,
- { "capwap", VPORT_FUNCTIONS(netdev_vport_get_status) },
+ { "capwap", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_PATCH,