X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetdev-vport.c;h=4aa8bb04c114fde4f48b534507739aae73a75b4e;hb=85c9de194b9f432f7b8a66bda980cbab52a55b72;hp=72175b77ff7fb4bc6dadaf74110014db3752ac6a;hpb=b9ad7294a5b4faf886a5022c5ec53b500f93cf3f;p=sliver-openvswitch.git diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index 72175b77f..4aa8bb04c 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include #include @@ -30,22 +28,15 @@ #include "daemon.h" #include "dirs.h" #include "dpif.h" -#include "dpif-linux.h" #include "hash.h" #include "hmap.h" #include "list.h" -#include "netdev-linux.h" #include "netdev-provider.h" -#include "netlink.h" -#include "netlink-notifier.h" -#include "netlink-socket.h" #include "ofpbuf.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); @@ -53,6 +44,8 @@ VLOG_DEFINE_THIS_MODULE(netdev_vport); /* Default to the OTV port, per the VXLAN IETF draft. */ #define VXLAN_DST_PORT 8472 +#define LISP_DST_PORT 4341 + #define DEFAULT_TTL 64 struct netdev_dev_vport { @@ -69,7 +62,6 @@ struct netdev_dev_vport { }; struct vport_class { - enum ovs_vport_type type; const char *dpif_port; struct netdev_class netdev_class; }; @@ -77,6 +69,7 @@ struct vport_class { static int netdev_vport_create(const struct netdev_class *, const char *, struct netdev_dev **); static int get_patch_config(struct netdev_dev *, struct smap *args); +static int get_tunnel_config(struct netdev_dev *, struct smap *args); static void netdev_vport_poll_notify(struct netdev_dev_vport *); static bool @@ -111,26 +104,23 @@ get_netdev_tunnel_config(const struct netdev_dev *netdev_dev) return &netdev_dev_vport_cast(netdev_dev)->tnl_cfg; } -enum ovs_vport_type -netdev_vport_get_vport_type(const struct netdev *netdev) +bool +netdev_vport_is_patch(const struct netdev *netdev) { const struct netdev_dev *dev = netdev_get_dev(netdev); const struct netdev_class *class = netdev_dev_get_class(dev); - return (is_vport_class(class) ? vport_class_cast(class)->type - : class == &netdev_internal_class ? OVS_VPORT_TYPE_INTERNAL - : (class == &netdev_linux_class || - class == &netdev_tap_class) ? OVS_VPORT_TYPE_NETDEV - : OVS_VPORT_TYPE_UNSPEC); + return class->get_config == get_patch_config; } -bool -netdev_vport_is_patch(const struct netdev *netdev) +static bool +netdev_vport_needs_dst_port(const struct netdev_dev *dev) { - const struct netdev_dev *dev = netdev_get_dev(netdev); const struct netdev_class *class = netdev_dev_get_class(dev); + const char *type = netdev_dev_get_type(dev); - return class->get_config == get_patch_config; + return (class->get_config == get_tunnel_config && + (!strcmp("vxlan", type) || !strcmp("lisp", type))); } const char * @@ -140,9 +130,27 @@ netdev_vport_get_dpif_port(const struct netdev *netdev) const struct netdev_class *class = netdev_dev_get_class(dev); const char *dpif_port; - dpif_port = (is_vport_class(class) - ? vport_class_cast(class)->dpif_port - : NULL); + if (netdev_vport_needs_dst_port(dev)) { + const struct netdev_dev_vport *vport = netdev_vport_get_dev(netdev); + const char *type = netdev_dev_get_type(dev); + static char dpif_port_combined[IFNAMSIZ]; + + /* + * Note: IFNAMSIZ is 16 bytes long. The maximum length of a VXLAN + * or LISP port name below is 15 or 14 bytes respectively. Still, + * assert here on the size of strlen(type) in case that changes + * in the future. + */ + ovs_assert(strlen(type) + 10 < IFNAMSIZ); + snprintf(dpif_port_combined, IFNAMSIZ, "%s_sys_%d", type, + ntohs(vport->tnl_cfg.dst_port)); + return dpif_port_combined; + } else { + dpif_port = (is_vport_class(class) + ? vport_class_cast(class)->dpif_port + : NULL); + } + return dpif_port ? dpif_port : netdev_get_name(netdev); } @@ -205,58 +213,6 @@ netdev_vport_get_etheraddr(const struct netdev *netdev, return 0; } -/* 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; -} - -int -netdev_vport_get_stats(const struct netdev *netdev, struct netdev_stats *stats) -{ - struct dpif_linux_vport reply; - struct ofpbuf *buf; - int error; - - error = dpif_linux_vport_get(netdev_get_name(netdev), &reply, &buf); - if (error) { - return error; - } else if (!reply.stats) { - ofpbuf_delete(buf); - return EOPNOTSUPP; - } - - netdev_stats_from_ovs_vport_stats(stats, reply.stats); - - ofpbuf_delete(buf); - - return 0; -} - static int tunnel_get_status(const struct netdev *netdev, struct smap *smap) { @@ -364,11 +320,7 @@ set_tunnel_config(struct netdev_dev *dev_, const struct smap *args) ipsec_mech_set = false; memset(&tnl_cfg, 0, sizeof tnl_cfg); - if (!strcmp(type, "capwap")) { - VLOG_WARN_ONCE("CAPWAP tunnel support is deprecated."); - } - - needs_dst_port = !strcmp(type, "vxlan"); + needs_dst_port = netdev_vport_needs_dst_port(dev_); tnl_cfg.ipsec = strstr(type, "ipsec"); tnl_cfg.dont_fragment = true; @@ -377,6 +329,10 @@ set_tunnel_config(struct netdev_dev *dev_, const struct smap *args) struct in_addr in_addr; if (lookup_ip(node->value, &in_addr)) { VLOG_WARN("%s: bad %s 'remote_ip'", name, type); + } else if (ip_is_multicast(in_addr.s_addr)) { + VLOG_WARN("%s: multicast remote_ip="IP_FMT" not allowed", + name, IP_ARGS(in_addr.s_addr)); + return EINVAL; } else { tnl_cfg.ip_dst = in_addr.s_addr; } @@ -453,10 +409,15 @@ set_tunnel_config(struct netdev_dev *dev_, const struct smap *args) } /* Add a default destination port for VXLAN if none specified. */ - if (needs_dst_port && !tnl_cfg.dst_port) { + if (!strcmp(type, "vxlan") && !tnl_cfg.dst_port) { tnl_cfg.dst_port = htons(VXLAN_DST_PORT); } + /* Add a default destination port for LISP if none specified. */ + if (!strcmp(type, "lisp") && !tnl_cfg.dst_port) { + tnl_cfg.dst_port = htons(LISP_DST_PORT); + } + if (tnl_cfg.ipsec) { static pid_t pid = 0; if (pid <= 0) { @@ -489,14 +450,6 @@ set_tunnel_config(struct netdev_dev *dev_, const struct smap *args) name, type); return EINVAL; } - - if (tnl_cfg.ip_src) { - if (ip_is_multicast(tnl_cfg.ip_dst)) { - VLOG_WARN("%s: remote_ip is multicast, ignoring local_ip", name); - tnl_cfg.ip_src = 0; - } - } - if (!tnl_cfg.ttl) { tnl_cfg.ttl = DEFAULT_TTL; } @@ -564,7 +517,10 @@ get_tunnel_config(struct netdev_dev *dev, struct smap *args) if (tnl_cfg->dst_port) { uint16_t dst_port = ntohs(tnl_cfg->dst_port); - if (dst_port != VXLAN_DST_PORT) { + const char *type = netdev_dev_get_type(dev); + + if ((!strcmp("vxlan", type) && dst_port != VXLAN_DST_PORT) || + (!strcmp("lisp", type) && dst_port != LISP_DST_PORT)) { smap_add_format(args, "dst_port", "%d", dst_port); } } @@ -721,29 +677,23 @@ get_stats(const struct netdev *netdev, struct netdev_stats *stats) \ netdev_vport_change_seq -#define TUNNEL_CLASS(NAME, VPORT_TYPE, DPIF_PORT) \ - { VPORT_TYPE, DPIF_PORT, \ +#define TUNNEL_CLASS(NAME, DPIF_PORT) \ + { DPIF_PORT, \ { NAME, VPORT_FUNCTIONS(get_tunnel_config, \ set_tunnel_config, \ get_netdev_tunnel_config, \ tunnel_get_status) }} void -netdev_vport_register(void) +netdev_vport_tunnel_register(void) { static const struct vport_class vport_classes[] = { - TUNNEL_CLASS("gre", OVS_VPORT_TYPE_GRE, "gre_system"), - TUNNEL_CLASS("ipsec_gre", OVS_VPORT_TYPE_GRE, "gre_system"), - TUNNEL_CLASS("gre64", OVS_VPORT_TYPE_GRE64, "gre64_system"), - TUNNEL_CLASS("ipsec_gre64", OVS_VPORT_TYPE_GRE64, "gre64_system"), - TUNNEL_CLASS("capwap", OVS_VPORT_TYPE_CAPWAP, "capwap_system"), - TUNNEL_CLASS("vxlan", OVS_VPORT_TYPE_VXLAN, "vxlan_system"), - - { OVS_VPORT_TYPE_UNSPEC, NULL, - { "patch", VPORT_FUNCTIONS(get_patch_config, - set_patch_config, - NULL, - NULL) }}, + TUNNEL_CLASS("gre", "gre_system"), + TUNNEL_CLASS("ipsec_gre", "gre_system"), + TUNNEL_CLASS("gre64", "gre64_system"), + TUNNEL_CLASS("ipsec_gre64", "gre64_system"), + TUNNEL_CLASS("vxlan", "vxlan_system"), + TUNNEL_CLASS("lisp", "lisp_system") }; int i; @@ -752,3 +702,15 @@ netdev_vport_register(void) netdev_register_provider(&vport_classes[i].netdev_class); } } + +void +netdev_vport_patch_register(void) +{ + static const struct vport_class patch_class = + { NULL, + { "patch", VPORT_FUNCTIONS(get_patch_config, + set_patch_config, + NULL, + NULL) }}; + netdev_register_provider(&patch_class.netdev_class); +}