return 0;
}
+static const char *
+dpif_netdev_port_open_type(const struct dpif_class *class, const char *type)
+{
+ return strcmp(type, "internal") ? type
+ : class != &dpif_netdev_class ? "dummy"
+ : "tap";
+}
+
static struct dpif *
create_dpif_netdev(struct dp_netdev *dp)
{
struct dp_netdev **dpp)
{
struct dp_netdev *dp;
- int port_no;
int error;
int i;
hmap_init(&dp->flow_table);
list_init(&dp->port_list);
- port_no = !strncmp(name, "br", 2) ? choose_port(dp, name) : OVSP_LOCAL;
- error = do_add_port(dp, name, "internal", port_no);
+ error = do_add_port(dp, name, "internal", OVSP_LOCAL);
if (error) {
dp_netdev_free(dp);
return error;
/* XXX reject devices already in some dp_netdev. */
/* Open and validate network device. */
- open_type = (strcmp(type, "internal") ? type
- : dp->class != &dpif_netdev_class ? "dummy"
- : "tap");
+ open_type = dpif_netdev_port_open_type(dp->class, type);
error = netdev_open(devname, open_type, &netdev);
if (error) {
return error;
dpif_netdev_flow_from_nlattrs(const struct nlattr *key, uint32_t key_len,
struct flow *flow)
{
- if (odp_flow_key_to_flow(key, key_len, flow)) {
+ if (odp_flow_key_to_flow(key, key_len, flow) != ODP_FIT_PERFECT) {
/* This should not happen: it indicates that odp_flow_key_from_flow()
* and odp_flow_key_to_flow() disagree on the acceptable form of a
* flow. Log the problem as an error, with enough details to enable
ofpbuf_reserve(©, DP_NETDEV_HEADROOM);
ofpbuf_put(©, execute->packet->data, execute->packet->size);
- flow_extract(©, 0, NULL, -1, &key);
+ flow_extract(©, 0, 0, NULL, -1, &key);
error = dpif_netdev_flow_from_nlattrs(execute->key, execute->key_len,
&key);
if (!error) {
if (packet->size < ETH_HEADER_LEN) {
return;
}
- flow_extract(packet, 0, NULL, port->port_no, &key);
+ flow_extract(packet, 0, 0, NULL, port->port_no, &key);
flow = dp_netdev_lookup_flow(dp, &key);
if (flow) {
dp_netdev_flow_used(flow, packet);
{
enum ovs_key_attr type = nl_attr_type(a);
const struct ovs_key_ipv4 *ipv4_key;
+ const struct ovs_key_ipv6 *ipv6_key;
const struct ovs_key_tcp *tcp_key;
const struct ovs_key_udp *udp_key;
switch (type) {
case OVS_KEY_ATTR_TUN_ID:
case OVS_KEY_ATTR_PRIORITY:
- case OVS_KEY_ATTR_IPV6:
+ case OVS_KEY_ATTR_SKB_MARK:
case OVS_KEY_ATTR_IPV4_TUNNEL:
/* not implemented */
break;
ipv4_key->ipv4_tos, ipv4_key->ipv4_ttl);
break;
+ case OVS_KEY_ATTR_IPV6:
+ ipv6_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_ipv6));
+ packet_set_ipv6(packet, ipv6_key->ipv6_proto, ipv6_key->ipv6_src,
+ ipv6_key->ipv6_dst, ipv6_key->ipv6_tclass,
+ ipv6_key->ipv6_label, ipv6_key->ipv6_hlimit);
+ break;
+
case OVS_KEY_ATTR_TCP:
tcp_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_tcp));
packet_set_tcp_port(packet, tcp_key->tcp_src, tcp_key->tcp_dst);
const struct dpif_class dpif_netdev_class = {
"netdev",
dpif_netdev_enumerate,
+ dpif_netdev_port_open_type,
dpif_netdev_open,
dpif_netdev_close,
dpif_netdev_destroy,