X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdpif-linux.c;h=7293063fe79ec3dedd2eecc7b75e1bfa1703e076;hb=780325b5b8d4c0552b4b7719e0a38200d99f6b08;hp=63d7afbae93766055966ad5d8cfb3155b25bd7f2;hpb=989fd548031d532be32a10129e0c97d45fd98b9a;p=sliver-openvswitch.git diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 63d7afbae..7293063fe 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ #include "dpif-linux.h" -#include #include #include #include @@ -48,7 +47,6 @@ #include "odp-util.h" #include "ofpbuf.h" #include "openvswitch/datapath-compat.h" -#include "openvswitch/tunnel.h" #include "packets.h" #include "poll-loop.h" #include "random.h" @@ -422,18 +420,76 @@ dpif_linux_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats) return error; } +static const char * +get_vport_type(const struct dpif_linux_vport *vport) +{ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); + + switch (vport->type) { + case OVS_VPORT_TYPE_NETDEV: + return "system"; + + case OVS_VPORT_TYPE_INTERNAL: + return "internal"; + + case OVS_VPORT_TYPE_GRE: + return "gre"; + + case OVS_VPORT_TYPE_GRE64: + return "gre64"; + + case OVS_VPORT_TYPE_VXLAN: + return "vxlan"; + + case OVS_VPORT_TYPE_LISP: + return "lisp"; + + case OVS_VPORT_TYPE_UNSPEC: + case __OVS_VPORT_TYPE_MAX: + break; + } + + VLOG_WARN_RL(&rl, "dp%d: port `%s' has unsupported type %u", + vport->dp_ifindex, vport->name, (unsigned int) vport->type); + return "unknown"; +} + +static enum ovs_vport_type +netdev_to_ovs_vport_type(const struct netdev *netdev) +{ + const char *type = netdev_get_type(netdev); + + if (!strcmp(type, "tap") || !strcmp(type, "system")) { + return OVS_VPORT_TYPE_NETDEV; + } else if (!strcmp(type, "internal")) { + return OVS_VPORT_TYPE_INTERNAL; + } else if (strstr(type, "gre64")) { + return OVS_VPORT_TYPE_GRE64; + } else if (strstr(type, "gre")) { + return OVS_VPORT_TYPE_GRE; + } else if (!strcmp(type, "vxlan")) { + return OVS_VPORT_TYPE_VXLAN; + } else if (!strcmp(type, "lisp")) { + return OVS_VPORT_TYPE_LISP; + } else { + return OVS_VPORT_TYPE_UNSPEC; + } +} + static int dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, uint32_t *port_nop) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); - const char *name = netdev_get_name(netdev); + const struct netdev_tunnel_config *tnl_cfg; + const char *name = netdev_vport_get_dpif_port(netdev); const char *type = netdev_get_type(netdev); struct dpif_linux_vport request, reply; - const struct ofpbuf *options; struct nl_sock *sock = NULL; uint32_t upcall_pid; struct ofpbuf *buf; + uint64_t options_stub[64 / 8]; + struct ofpbuf options; int error; if (dpif->epoll_fd >= 0) { @@ -446,7 +502,7 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, dpif_linux_vport_init(&request); request.cmd = OVS_VPORT_CMD_NEW; request.dp_ifindex = dpif->dp_ifindex; - request.type = netdev_vport_get_vport_type(netdev); + request.type = netdev_to_ovs_vport_type(netdev); if (request.type == OVS_VPORT_TYPE_UNSPEC) { VLOG_WARN_RL(&error_rl, "%s: cannot create port `%s' because it has " "unsupported type `%s'", @@ -456,16 +512,19 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, } request.name = name; - options = netdev_vport_get_options(netdev); - if (options && options->size) { - request.options = options->data; - request.options_len = options->size; - } - if (request.type == OVS_VPORT_TYPE_NETDEV) { netdev_linux_ethtool_set_flag(netdev, ETH_FLAG_LRO, "LRO", false); } + tnl_cfg = netdev_get_tunnel_config(netdev); + if (tnl_cfg && tnl_cfg->dst_port != 0) { + ofpbuf_use_stack(&options, options_stub, sizeof options_stub); + nl_msg_put_u16(&options, OVS_TUNNEL_ATTR_DST_PORT, + ntohs(tnl_cfg->dst_port)); + request.options = options.data; + request.options_len = options.size; + } + request.port_no = *port_nop; upcall_pid = sock ? nl_sock_pid(sock) : 0; request.upcall_pid = &upcall_pid; @@ -475,9 +534,11 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, *port_nop = reply.port_no; VLOG_DBG("%s: assigning port %"PRIu32" to netlink pid %"PRIu32, dpif_name(dpif_), reply.port_no, upcall_pid); - } else if (error == EBUSY && *port_nop != UINT32_MAX) { - VLOG_INFO("%s: requested port %"PRIu32" is in use", - dpif_name(dpif_), *port_nop); + } else { + if (error == EBUSY && *port_nop != UINT32_MAX) { + VLOG_INFO("%s: requested port %"PRIu32" is in use", + dpif_name(dpif_), *port_nop); + } nl_sock_destroy(sock); ofpbuf_delete(buf); return error; @@ -546,7 +607,7 @@ dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no, error = ENODEV; } else if (dpif_port) { dpif_port->name = xstrdup(reply.name); - dpif_port->type = xstrdup(netdev_vport_get_netdev_type(&reply)); + dpif_port->type = xstrdup(get_vport_type(&reply)); dpif_port->port_no = reply.port_no; } ofpbuf_delete(buf); @@ -646,7 +707,7 @@ dpif_linux_port_dump_next(const struct dpif *dpif OVS_UNUSED, void *state_, } dpif_port->name = CONST_CAST(char *, vport.name); - dpif_port->type = CONST_CAST(char *, netdev_vport_get_netdev_type(&vport)); + dpif_port->type = CONST_CAST(char *, get_vport_type(&vport)); dpif_port->port_no = vport.port_no; return 0; } @@ -958,7 +1019,7 @@ dpif_linux_operate__(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops) struct nl_transaction *txnsp[MAX_OPS]; size_t i; - assert(n_ops <= MAX_OPS); + ovs_assert(n_ops <= MAX_OPS); for (i = 0; i < n_ops; i++) { struct op_auxdata *aux = &auxes[i]; struct dpif_op *op = ops[i]; @@ -1175,7 +1236,7 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall, [OVS_PACKET_ATTR_KEY] = { .type = NL_A_NESTED }, /* OVS_PACKET_CMD_ACTION only. */ - [OVS_PACKET_ATTR_USERDATA] = { .type = NL_A_U64, .optional = true }, + [OVS_PACKET_ATTR_USERDATA] = { .type = NL_A_UNSPEC, .optional = true }, }; struct ovs_header *ovs_header; @@ -1213,9 +1274,7 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall, upcall->key = CONST_CAST(struct nlattr *, nl_attr_get(a[OVS_PACKET_ATTR_KEY])); upcall->key_len = nl_attr_get_size(a[OVS_PACKET_ATTR_KEY]); - upcall->userdata = (a[OVS_PACKET_ATTR_USERDATA] - ? nl_attr_get_u64(a[OVS_PACKET_ATTR_USERDATA]) - : 0); + upcall->userdata = a[OVS_PACKET_ATTR_USERDATA]; *dp_ifindex = ovs_header->dp_ifindex; return 0; @@ -1464,10 +1523,6 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport, [OVS_VPORT_ATTR_UPCALL_PID] = { .type = NL_A_U32 }, [OVS_VPORT_ATTR_STATS] = { NL_POLICY_FOR(struct ovs_vport_stats), .optional = true }, - [OVS_VPORT_ATTR_ADDRESS] = { .type = NL_A_UNSPEC, - .min_len = ETH_ADDR_LEN, - .max_len = ETH_ADDR_LEN, - .optional = true }, [OVS_VPORT_ATTR_OPTIONS] = { .type = NL_A_NESTED, .optional = true }, }; @@ -1501,9 +1556,6 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport, if (a[OVS_VPORT_ATTR_STATS]) { vport->stats = nl_attr_get(a[OVS_VPORT_ATTR_STATS]); } - if (a[OVS_VPORT_ATTR_ADDRESS]) { - vport->address = nl_attr_get(a[OVS_VPORT_ATTR_ADDRESS]); - } if (a[OVS_VPORT_ATTR_OPTIONS]) { vport->options = nl_attr_get(a[OVS_VPORT_ATTR_OPTIONS]); vport->options_len = nl_attr_get_size(a[OVS_VPORT_ATTR_OPTIONS]); @@ -1546,11 +1598,6 @@ dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *vport, vport->stats, sizeof *vport->stats); } - if (vport->address) { - nl_msg_put_unspec(buf, OVS_VPORT_ATTR_ADDRESS, - vport->address, ETH_ADDR_LEN); - } - if (vport->options) { nl_msg_put_nested(buf, OVS_VPORT_ATTR_OPTIONS, vport->options, vport->options_len); @@ -1579,7 +1626,7 @@ dpif_linux_vport_transact(const struct dpif_linux_vport *request, struct ofpbuf *request_buf; int error; - assert((reply != NULL) == (bufp != NULL)); + ovs_assert((reply != NULL) == (bufp != NULL)); error = dpif_linux_init(); if (error) { @@ -1730,7 +1777,7 @@ dpif_linux_dp_transact(const struct dpif_linux_dp *request, struct ofpbuf *request_buf; int error; - assert((reply != NULL) == (bufp != NULL)); + ovs_assert((reply != NULL) == (bufp != NULL)); request_buf = ofpbuf_new(1024); dpif_linux_dp_to_ofpbuf(request, request_buf); @@ -1851,9 +1898,9 @@ dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow *flow, } /* We never need to send these to the kernel. */ - assert(!flow->stats); - assert(!flow->tcp_flags); - assert(!flow->used); + ovs_assert(!flow->stats); + ovs_assert(!flow->tcp_flags); + ovs_assert(!flow->used); if (flow->clear) { nl_msg_put_flag(buf, OVS_FLOW_ATTR_CLEAR); @@ -1880,7 +1927,7 @@ dpif_linux_flow_transact(struct dpif_linux_flow *request, struct ofpbuf *request_buf; int error; - assert((reply != NULL) == (bufp != NULL)); + ovs_assert((reply != NULL) == (bufp != NULL)); if (reply) { request->nlmsg_flags |= NLM_F_ECHO; @@ -1928,7 +1975,7 @@ report_loss(struct dpif *dpif_, struct dpif_channel *ch) static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); struct ds s; - if (VLOG_DROP_ERR(&rl)) { + if (VLOG_DROP_WARN(&rl)) { return; }