This patch avoids the relatively inefficient miss handling processes dictated by the dpif process, by calling into ofproto-dpif directly through a callback.
Signed-off-by: Ethan Jackson <et...@nicira.com> --- lib/dpif-netdev.c | 299 ++++++++++++++++++++++++------------------ lib/dpif-provider.h | 5 +- lib/dpif.c | 4 +- lib/dpif.h | 18 ++- ofproto/ofproto-dpif-upcall.c | 109 ++++++--------- tests/dpif-netdev.at | 10 +- tests/ofproto-dpif.at | 54 ++++---- 7 files changed, 262 insertions(+), 237 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index c637d9f..d4a30bb 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -85,14 +85,7 @@ static struct ovs_mutex dp_netdev_mutex = OVS_MUTEX_INITIALIZER; static struct shash dp_netdevs OVS_GUARDED_BY(dp_netdev_mutex) = SHASH_INITIALIZER(&dp_netdevs); -struct dp_netdev_queue { - unsigned int packet_count; - - struct dpif_upcall upcalls[NETDEV_MAX_RX_BATCH]; - struct ofpbuf bufs[NETDEV_MAX_RX_BATCH]; -}; - -#define DP_NETDEV_QUEUE_INITIALIZER { .packet_count = 0 } +static struct vlog_rate_limit upcall_rl = VLOG_RATE_LIMIT_INIT(600, 600); /* Datapath based on the network device interface from netdev.h. * @@ -140,7 +133,8 @@ struct dp_netdev { /* Protects access to ofproto-dpif-upcall interface during revalidator * thread synchronization. */ struct fat_rwlock upcall_rwlock; - exec_upcall_cb *upcall_cb; /* Callback function for executing upcalls. */ + upcall_callback *upcall_cb; /* Callback function for executing upcalls. */ + void *upcall_aux; /* Forwarding threads. */ struct latch exit_latch; @@ -320,12 +314,6 @@ static void do_del_port(struct dp_netdev *dp, struct dp_netdev_port *) OVS_REQUIRES(dp->port_mutex); static int dpif_netdev_open(const struct dpif_class *, const char *name, bool create, struct dpif **); -static int dp_netdev_queue_userspace_packet(struct dp_netdev_queue *, - struct ofpbuf *, int type, - const struct miniflow *, - const struct nlattr *); -static void dp_netdev_execute_userspace_queue(struct dp_netdev_queue *, - struct dp_netdev *); static void dp_netdev_execute_actions(struct dp_netdev *dp, struct dpif_packet **, int c, bool may_steal, struct pkt_metadata *, @@ -474,6 +462,7 @@ create_dp_netdev(const char *name, const struct dpif_class *class, /* Disable upcalls by default. */ dp_netdev_disable_upcall(dp); + dp->upcall_aux = NULL; dp->upcall_cb = NULL; ovs_mutex_lock(&dp->port_mutex); @@ -1232,6 +1221,35 @@ dp_netdev_flow_add(struct dp_netdev *dp, struct match *match, classifier_insert(&dp->cls, CONST_CAST(struct cls_rule *, &netdev_flow->cr)); + if (OVS_UNLIKELY(VLOG_IS_DBG_ENABLED())) { + struct ds ds = DS_EMPTY_INITIALIZER; + struct ofpbuf key, mask; + + ofpbuf_init(&key, 0); + ofpbuf_init(&mask, 0); + + ds_put_cstr(&ds, "flow_add: "); + + odp_flow_key_from_flow(&key, &match->flow, &match->wc.masks, + match->flow.in_port.odp_port, true); + + odp_flow_key_from_mask(&mask, &match->wc.masks, &match->flow, + odp_to_u32(match->wc.masks.in_port.odp_port), + SIZE_MAX, true); + + odp_flow_format(ofpbuf_data(&key), ofpbuf_size(&key), + ofpbuf_data(&mask), ofpbuf_size(&mask), NULL, &ds, + true); + + ds_put_cstr(&ds, ", actions:"); + format_odp_actions(&ds, actions, actions_len); + VLOG_DBG("%s", ds_cstr(&ds)); + + ds_destroy(&ds); + ofpbuf_uninit(&key); + ofpbuf_uninit(&mask); + } + return 0; } @@ -1822,6 +1840,44 @@ dp_netdev_count_packet(struct dp_netdev *dp, enum dp_stat_type type, int cnt) ovs_mutex_unlock(&bucket->mutex); } +static int +dp_netdev_upcall(struct dp_netdev *dp, struct dpif_packet *packet_, + struct flow *flow, struct flow_wildcards *wc, + enum dpif_upcall_type type, const struct nlattr *userdata, + struct ofpbuf *actions, struct ofpbuf *put_actions) +{ + struct ofpbuf *packet = &packet_->ofpbuf; + + if (type == DPIF_UC_MISS) { + dp_netdev_count_packet(dp, DP_STAT_MISS, 1); + } + + if (OVS_UNLIKELY(!VLOG_DROP_DBG(&upcall_rl))) { + struct ds ds = DS_EMPTY_INITIALIZER; + struct ofpbuf key; + char *packet_str; + + ofpbuf_init(&key, 0); + odp_flow_key_from_flow(&key, flow, &wc->masks, flow->in_port.odp_port, + true); + + packet_str = ofp_packet_to_string(ofpbuf_data(packet), + ofpbuf_size(packet)); + + odp_flow_key_format(ofpbuf_data(&key), ofpbuf_size(&key), &ds); + + VLOG_DBG("%s: %s upcall:\n%s\n%s", dp->name, + dpif_upcall_type_to_string(type), ds_cstr(&ds), packet_str); + + ofpbuf_uninit(&key); + free(packet_str); + ds_destroy(&ds); + } + + return dp->upcall_cb(packet, flow, wc, type, userdata, actions, + put_actions, dp->upcall_aux); +} + struct packet_batch { unsigned int packet_count; unsigned int byte_count; @@ -1876,12 +1932,12 @@ static void dp_netdev_input(struct dp_netdev *dp, struct dpif_packet **packets, int cnt, struct pkt_metadata *md) { - struct dp_netdev_queue q = DP_NETDEV_QUEUE_INITIALIZER; struct packet_batch batches[NETDEV_MAX_RX_BATCH]; struct netdev_flow_key keys[NETDEV_MAX_RX_BATCH]; const struct miniflow *mfs[NETDEV_MAX_RX_BATCH]; /* NULL at bad packets. */ struct cls_rule *rules[NETDEV_MAX_RX_BATCH]; size_t n_batches, i; + bool may_miss; for (i = 0; i < cnt; i++) { if (OVS_UNLIKELY(ofpbuf_size(&packets[i]->ofpbuf) < ETH_HEADER_LEN)) { @@ -1895,7 +1951,72 @@ dp_netdev_input(struct dp_netdev *dp, struct dpif_packet **packets, int cnt, mfs[i] = &keys[i].flow; } - classifier_lookup_miniflow_batch(&dp->cls, mfs, rules, cnt); + may_miss = !classifier_lookup_miniflow_batch(&dp->cls, mfs, rules, cnt); + if (OVS_UNLIKELY(may_miss) && !fat_rwlock_tryrdlock(&dp->upcall_rwlock)) { + uint64_t actions_stub[512 / 8], slow_stub[512 / 8]; + struct ofpbuf actions, put_actions; + struct match match; + + ofpbuf_use_stub(&actions, actions_stub, sizeof actions_stub); + ofpbuf_use_stub(&put_actions, slow_stub, sizeof slow_stub); + + for (i = 0; i < cnt; i++) { + const struct dp_netdev_flow *netdev_flow; + struct ofpbuf *add_actions; + + if (OVS_LIKELY(rules[i] || !mfs[i])) { + continue; + } + + /* It's possible that an earlier slow path execution installed + * the rule this flow needs. In this case, it's a lot cheaper + * to catch it here than execute a miss. */ + netdev_flow = dp_netdev_lookup_flow(dp, mfs[i]); + if (netdev_flow) { + rules[i] = CONST_CAST(struct cls_rule *, &netdev_flow->cr); + continue; + } + + miniflow_expand(mfs[i], &match.flow); + flow_wildcards_init_catchall(&match.wc); + + ofpbuf_clear(&actions); + ofpbuf_clear(&put_actions); + + if (dp_netdev_upcall(dp, packets[i], &match.flow, &match.wc, + DPIF_UC_MISS, NULL, &actions, &put_actions)) { + continue; + } + + /* We can't allow the packet batching in the next loop to execute + * the actions. Otherwise, if there are any slow path actions, + * we'll send the packet up twice. */ + dp_netdev_execute_actions(dp, &packets[i], 1, false, md, + ofpbuf_data(&actions), + ofpbuf_size(&actions)); + + add_actions = ofpbuf_size(&put_actions) + ? &put_actions + : &actions; + + ovs_mutex_lock(&dp->flow_mutex); + /* XXX: There's a brief race where this flow could have already + * been installed since we last did the flow lookup. This could be + * solved by moving the mutex lock outside the loop, but that's an + * awful long time to be locking everyone out of making flow + * installs. If we move to a per-core classifier, it would be + * reasonable. */ + if (!dp_netdev_lookup_flow(dp, mfs[i])) { + dp_netdev_flow_add(dp, &match, ofpbuf_data(add_actions), + ofpbuf_size(add_actions)); + } + ovs_mutex_unlock(&dp->flow_mutex); + } + + ofpbuf_uninit(&actions); + ofpbuf_uninit(&put_actions); + fat_rwlock_unlock(&dp->upcall_rwlock); + } n_batches = 0; for (i = 0; i < cnt; i++) { @@ -1903,17 +2024,7 @@ dp_netdev_input(struct dp_netdev *dp, struct dpif_packet **packets, int cnt, struct packet_batch *batch; size_t j; - if (OVS_UNLIKELY(!mfs[i])) { - continue; - } - - if (OVS_UNLIKELY(!rules[i])) { - struct ofpbuf *buf = &packets[i]->ofpbuf; - - dp_netdev_count_packet(dp, DP_STAT_MISS, 1); - dp_netdev_queue_userspace_packet(&q, buf, DPIF_UC_MISS, - mfs[i], NULL); - dpif_packet_delete(packets[i]); + if (OVS_UNLIKELY(!rules[i] || !mfs[i])) { continue; } @@ -1942,10 +2053,6 @@ dp_netdev_input(struct dp_netdev *dp, struct dpif_packet **packets, int cnt, for (i = 0; i < n_batches; i++) { packet_batch_execute(&batches[i], dp); } - - if (q.packet_count) { - dp_netdev_execute_userspace_queue(&q, dp); - } } static void @@ -1959,86 +2066,16 @@ dp_netdev_port_input(struct dp_netdev *dp, struct dpif_packet **packets, dp_netdev_input(dp, packets, cnt, &md); } -static int -dp_netdev_queue_userspace_packet(struct dp_netdev_queue *q, - struct ofpbuf *packet, int type, - const struct miniflow *key, - const struct nlattr *userdata) -{ - if (q->packet_count < NETDEV_MAX_RX_BATCH) { - int cnt = q->packet_count; - struct dpif_upcall *upcall = &q->upcalls[cnt]; - struct ofpbuf *buf = &q->bufs[cnt]; - size_t buf_size; - struct flow flow; - void *data; - - upcall->type = type; - - /* Allocate buffer big enough for everything. */ - buf_size = ODPUTIL_FLOW_KEY_BYTES; - if (userdata) { - buf_size += NLA_ALIGN(userdata->nla_len); - } - buf_size += ofpbuf_size(packet); - ofpbuf_init(buf, buf_size); - - /* Put ODP flow. */ - miniflow_expand(key, &flow); - odp_flow_key_from_flow(buf, &flow, NULL, flow.in_port.odp_port, true); - upcall->key = ofpbuf_data(buf); - upcall->key_len = ofpbuf_size(buf); - - /* Put userdata. */ - if (userdata) { - upcall->userdata = ofpbuf_put(buf, userdata, - NLA_ALIGN(userdata->nla_len)); - } - - /* We have to perform a copy of the packet, because we cannot send DPDK - * mbufs to a non pmd thread. When the upcall processing will be done - * in the pmd thread, this copy can be avoided */ - data = ofpbuf_put(buf, ofpbuf_data(packet), ofpbuf_size(packet)); - ofpbuf_use_stub(&upcall->packet, data, ofpbuf_size(packet)); - ofpbuf_set_size(&upcall->packet, ofpbuf_size(packet)); - - q->packet_count++; - return 0; - } else { - return ENOBUFS; - } -} - -static void -dp_netdev_execute_userspace_queue(struct dp_netdev_queue *q, - struct dp_netdev *dp) -{ - struct dpif_upcall *upcalls = q->upcalls; - struct ofpbuf *bufs = q->bufs; - int cnt = q->packet_count; - - if (!fat_rwlock_tryrdlock(&dp->upcall_rwlock)) { - ovs_assert(dp->upcall_cb); - dp->upcall_cb(dp->dpif, upcalls, bufs, cnt); - fat_rwlock_unlock(&dp->upcall_rwlock); - } else { - int i; - - for (i = 0; i < cnt; i++) { - ofpbuf_uninit(&bufs[i]); - ofpbuf_uninit(&upcalls[i].packet); - } - } -} - struct dp_netdev_execute_aux { struct dp_netdev *dp; }; static void -dpif_netdev_register_upcall_cb(struct dpif *dpif, exec_upcall_cb *cb) +dpif_netdev_register_upcall_cb(struct dpif *dpif, upcall_callback *cb, + void *aux) { struct dp_netdev *dp = get_dp_netdev(dpif); + dp->upcall_aux = aux; dp->upcall_cb = cb; } @@ -2049,14 +2086,15 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, OVS_NO_THREAD_SAFETY_ANALYSIS { struct dp_netdev_execute_aux *aux = aux_; + uint32_t *depth = recirc_depth_get(); + struct dp_netdev *dp = aux->dp; int type = nl_attr_type(a); struct dp_netdev_port *p; - uint32_t *depth = recirc_depth_get(); int i; switch ((enum ovs_action_attr)type) { case OVS_ACTION_ATTR_OUTPUT: - p = dp_netdev_lookup_port(aux->dp, u32_to_odp(nl_attr_get_u32(a))); + p = dp_netdev_lookup_port(dp, u32_to_odp(nl_attr_get_u32(a))); if (OVS_LIKELY(p)) { netdev_send(p->netdev, packets, cnt, may_steal); } else if (may_steal) { @@ -2066,35 +2104,36 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, } break; - case OVS_ACTION_ATTR_USERSPACE: { - const struct nlattr *userdata; - struct netdev_flow_key key; - struct dp_netdev_queue q = DP_NETDEV_QUEUE_INITIALIZER; - - userdata = nl_attr_find_nested(a, OVS_USERSPACE_ATTR_USERDATA); - - miniflow_initialize(&key.flow, key.buf); - - for (i = 0; i < cnt; i++) { - struct ofpbuf *packet; + case OVS_ACTION_ATTR_USERSPACE: + if (!fat_rwlock_tryrdlock(&dp->upcall_rwlock)) { + const struct nlattr *userdata; + struct ofpbuf actions; + struct flow flow; - packet = &packets[i]->ofpbuf; + userdata = nl_attr_find_nested(a, OVS_USERSPACE_ATTR_USERDATA); + ofpbuf_init(&actions, 0); - miniflow_extract(packet, md, &key.flow); + for (i = 0; i < cnt; i++) { + ofpbuf_clear(&actions); + + flow_extract(&packets[i]->ofpbuf, md, &flow); + if (!dp_netdev_upcall(dp, packets[i], &flow, NULL, + DPIF_UC_ACTION, userdata, &actions, + NULL)) { + dp_netdev_execute_actions(dp, &packets[i], 1, false, md, + ofpbuf_data(&actions), + ofpbuf_size(&actions)); + } - dp_netdev_queue_userspace_packet(&q, packet, - DPIF_UC_ACTION, &key.flow, - userdata); - if (may_steal) { - dpif_packet_delete(packets[i]); + if (may_steal) { + dpif_packet_delete(packets[i]); + } } + ofpbuf_uninit(&actions); + fat_rwlock_unlock(&dp->upcall_rwlock); } - if (q.packet_count) { - dp_netdev_execute_userspace_queue(&q, aux->dp); - } break; - } case OVS_ACTION_ATTR_HASH: { const struct ovs_action_hash *hash_act; @@ -2148,7 +2187,7 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, /* Hash is private to each packet */ recirc_md.dp_hash = packets[i]->dp_hash; - dp_netdev_input(aux->dp, &recirc_pkt, 1, &recirc_md); + dp_netdev_input(dp, &recirc_pkt, 1, &recirc_md); } (*depth)--; diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index bf24a9d..478a08b 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -419,8 +419,9 @@ struct dpif_class { * to register an upcall function and enable / disable upcalls. * * Registers an upcall callback function with 'dpif'. This is only used if - * if 'dpif' directly executes upcall functions. */ - void (*register_upcall_cb)(struct dpif *, exec_upcall_cb *); + * if 'dpif' directly executes upcall functions. 'aux' is passed to the + * callback on invocation. */ + void (*register_upcall_cb)(struct dpif *, upcall_callback *, void *aux); /* Enables upcalls if 'dpif' directly executes upcall functions. */ void (*enable_upcall)(struct dpif *); diff --git a/lib/dpif.c b/lib/dpif.c index 43141df..c428530 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1349,10 +1349,10 @@ dpif_handlers_set(struct dpif *dpif, uint32_t n_handlers) } void -dpif_register_upcall_cb(struct dpif *dpif, exec_upcall_cb *cb) +dpif_register_upcall_cb(struct dpif *dpif, upcall_callback *cb, void *aux) { if (dpif->dpif_class->register_upcall_cb) { - dpif->dpif_class->register_upcall_cb(dpif, cb); + dpif->dpif_class->register_upcall_cb(dpif, cb, aux); } } diff --git a/lib/dpif.h b/lib/dpif.h index f4a2a9e..4fb49d4 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -399,12 +399,13 @@ extern "C" { #endif struct dpif; +struct dpif_class; +struct dpif_flow; struct ds; struct flow; +struct flow_wildcards; struct nlattr; struct sset; -struct dpif_class; -struct dpif_flow; int dp_register_provider(const struct dpif_class *); int dp_unregister_provider(const char *type); @@ -670,8 +671,16 @@ struct dpif_upcall { struct nlattr *userdata; /* Argument to OVS_ACTION_ATTR_USERSPACE. */ }; -typedef void exec_upcall_cb(struct dpif *, struct dpif_upcall *, - struct ofpbuf *, int cnt); +/* Called by dpif-netdev to process upcalls for flow misses. Optionally + * populates a wildcard mask in 'wc'. The datapath will execute, and + * if 'type' is DPIF_UC_MISS, install 'actions. May provide 'put_actions', + * which if populated the datapath will install instead of 'actions'. */ +typedef int upcall_callback(const struct ofpbuf *packet, const struct flow *flow, + struct flow_wildcards *wc, enum dpif_upcall_type, + const struct nlattr *userdata, + struct ofpbuf *actions, struct ofpbuf *put_actions, + void *aux); +void dpif_register_upcall_cb(struct dpif *, upcall_callback *, void *aux); int dpif_recv_set(struct dpif *, bool enable); int dpif_handlers_set(struct dpif *, uint32_t n_handlers); @@ -679,7 +688,6 @@ int dpif_recv(struct dpif *, uint32_t handler_id, struct dpif_upcall *, struct ofpbuf *); void dpif_recv_purge(struct dpif *); void dpif_recv_wait(struct dpif *, uint32_t handler_id); -void dpif_register_upcall_cb(struct dpif *, exec_upcall_cb *); void dpif_enable_upcall(struct dpif *); void dpif_disable_upcall(struct dpif *); diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index bf10dec..4c7835b 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -246,9 +246,10 @@ static void ukey_delete(struct revalidator *, struct udpif_key *); static enum upcall_type classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata); -static void exec_upcalls(struct dpif *, struct dpif_upcall *, struct ofpbuf *, - int cnt); - +static int upcall_cb(const struct ofpbuf *packet, const struct flow *flow, + struct flow_wildcards *wc, enum dpif_upcall_type, + const struct nlattr *userdata, struct ofpbuf *actions, + struct ofpbuf *put_actions, void *aux); static int upcall_receive(struct upcall *, const struct dpif_backer *, const struct ofpbuf *packet, enum dpif_upcall_type, const struct nlattr *userdata, const struct flow *); @@ -288,7 +289,7 @@ udpif_create(struct dpif_backer *backer, struct dpif *dpif) atomic_init(&udpif->n_flows_timestamp, LLONG_MIN); ovs_mutex_init(&udpif->n_flows_mutex); - dpif_register_upcall_cb(dpif, exec_upcalls); + dpif_register_upcall_cb(dpif, upcall_cb, udpif); return udpif; } @@ -917,77 +918,53 @@ upcall_uninit(struct upcall *upcall) } } -static struct udpif * -find_udpif(struct dpif *dpif) -{ - struct udpif *udpif; - - LIST_FOR_EACH (udpif, list_node, &all_udpifs) { - if (udpif->dpif == dpif) { - return udpif; - } - } - return NULL; -} -static void -exec_upcalls(struct dpif *dpif, struct dpif_upcall *dupcalls, - struct ofpbuf *bufs OVS_UNUSED, int cnt) +static int +upcall_cb(const struct ofpbuf *packet, const struct flow *flow, + struct flow_wildcards *wc, enum dpif_upcall_type type, + const struct nlattr *userdata, struct ofpbuf *actions, + struct ofpbuf *put_actions, void *aux) { - struct upcall upcalls[UPCALL_MAX_BATCH]; - struct udpif *udpif; - int i, j; - - udpif = find_udpif(dpif); - ovs_assert(udpif); - - for (i = 0; i < cnt; i += UPCALL_MAX_BATCH) { - size_t n_upcalls = 0; - for (j = i; j < MIN(i + UPCALL_MAX_BATCH, cnt); j++) { - struct upcall *upcall = &upcalls[n_upcalls]; - struct dpif_upcall *dupcall = &dupcalls[j]; - struct pkt_metadata md; - struct flow flow; - int error; - - dpif_print_packet(dpif, dupcall); - - if (odp_flow_key_to_flow(dupcall->key, dupcall->key_len, &flow) - == ODP_FIT_ERROR) { - continue; - } - - error = upcall_receive(upcall, udpif->backer, &dupcall->packet, - dupcall->type, dupcall->userdata, &flow); - if (error) { - goto cleanup; - } - - upcall->key = dupcall->key; - upcall->key_len = dupcall->key_len; + struct udpif *udpif = aux; + unsigned int flow_limit; + struct upcall upcall; + bool megaflow; + int error; - md = pkt_metadata_from_flow(&flow); - flow_extract(&dupcall->packet, &md, &flow); + atomic_read(&udpif->flow_limit, &flow_limit); + if (udpif_get_n_flows(udpif) >= flow_limit) { + return ENOSPC; + } - error = process_upcall(udpif, upcall, NULL); - if (error) { - goto cleanup; - } + error = upcall_receive(&upcall, udpif->backer, packet, type, userdata, + flow); + if (error) { + goto out; + } - n_upcalls++; - continue; + error = process_upcall(udpif, &upcall, actions); + if (error) { + goto out; + } -cleanup: - upcall_uninit(upcall); - } + if (upcall.xout.slow && put_actions) { + ofpbuf_put(put_actions, ofpbuf_data(&upcall.put_actions), + ofpbuf_size(&upcall.put_actions)); + } - if (n_upcalls) { - handle_upcalls(udpif, upcalls, n_upcalls); - for (j = 0; j < n_upcalls; j++) { - upcall_uninit(&upcalls[j]); - } + if (wc) { + atomic_read(&enable_megaflows, &megaflow); + if (megaflow) { + /* XXX: This could be avoided with sufficient API changes. */ + memcpy(wc, &upcall.xout.wc, sizeof *wc); + } else { + memset(wc, 0xff, sizeof *wc); } } + +out: + upcall_uninit(&upcall); + return error; } static int diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at index f887452..0545ea7 100644 --- a/tests/dpif-netdev.at +++ b/tests/dpif-netdev.at @@ -9,8 +9,8 @@ m4_define([STRIP_XOUT], [[sed ' s/bytes:[0-9]*/bytes:0/ ' | sort]]) m4_define([FILTER_FLOW_INSTALL], [[ -grep ' put' | sed ' - s/.*put\[create\] // +grep 'flow_add' | sed ' + s/.*flow_add: // ' | sort | uniq]]) m4_define([FILTER_FLOW_DUMP], [[ grep 'flow_dump ' | sed ' @@ -32,7 +32,7 @@ OVS_VSWITCHD_START( fail-mode=secure -- \ add-port br1 p2 -- set interface p2 type=dummy options:stream=unix:$OVS_RUNDIR/p0.sock ofport_request=2 -- \ add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-ofctl add-flow br1 action=normal]) @@ -58,7 +58,7 @@ OVS_VSWITCHD_START( [add-port br0 p1 -- set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p0.sock set bridge br0 datapath-type=dummy other-config:datapath-id=1234 \ fail-mode=secure]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)']) @@ -93,7 +93,7 @@ OVS_VSWITCHD_START( [add-port br0 p1 -- set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p0.sock set bridge br0 datapath-type=dummy other-config:datapath-id=1234 \ fail-mode=secure]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)']) diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 0253cb0..c1f6719 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -23,7 +23,7 @@ OVS_VSWITCHD_START( add-port br1 p4 -- set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 -- \ add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --]) WAIT_FOR_DUMMY_PORTS([p3], [p4]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-ofctl add-flow br1 action=normal]) @@ -4611,7 +4611,7 @@ AT_SETUP([ofproto-dpif - MPLS actions that result in a userspace action]) OVS_VSWITCHD_START([dnl add-port br0 p1 -- set Interface p1 type=dummy ]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ON_EXIT([kill `cat ovs-ofctl.pid`]) AT_CAPTURE_FILE([ofctl_monitor.log]) @@ -4648,7 +4648,7 @@ AT_SETUP([ofproto-dpif - MPLS actions that result in a drop]) OVS_VSWITCHD_START([dnl add-port br0 p1 -- set Interface p1 type=dummy ]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ON_EXIT([kill `cat ovs-ofctl.pid`]) AT_CAPTURE_FILE([ofctl_monitor.log]) @@ -4693,7 +4693,7 @@ ADD_OF_PORTS([br0], [2]) ADD_OF_PORTS([br1], [3]) AT_CHECK([ovs-appctl time/stop]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) AT_CHECK([ovs-ofctl add-flow br0 actions=LOCAL,output:1,output:2]) AT_CHECK([ovs-ofctl add-flow br1 actions=LOCAL,output:1,output:3]) @@ -4778,7 +4778,7 @@ AT_BANNER([ofproto-dpif -- megaflows]) AT_SETUP([ofproto-dpif megaflow - port classification]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1 actions=output(2) @@ -4796,7 +4796,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - L2 classification]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1,dl_src=50:54:00:00:00:09 actions=output(2) @@ -4814,7 +4814,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - L3 classification]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_CHECK([ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- --id=@N1 create Flow_Table name=t0 prefixes=nw_dst,nw_src], [0], [ignore], []) AT_DATA([flows.txt], [dnl @@ -4833,7 +4833,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - IPv6 classification]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_CHECK([ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- --id=@N1 create Flow_Table name=t0 prefixes=ipv6_dst,ipv6_src], [0], [ignore], []) AT_DATA([flows.txt], [dnl @@ -4852,7 +4852,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - L4 classification]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1,icmp,icmp_type=8 actions=output(2) @@ -4870,7 +4870,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - normal]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)']) @@ -4885,7 +4885,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - mpls]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 dl_src=50:54:00:00:00:09 actions=push_mpls:0x8847,2 @@ -4908,7 +4908,7 @@ AT_CLEANUP m4_define([CHECK_MEGAFLOW_NETFLOW], [AT_SETUP([ofproto-dpif megaflow - netflow - $2 collector]) OVS_VSWITCHD_START - AT_CHECK([ovs-appctl vlog/set dpif:dbg]) + AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) dnl NetFlow configuration disables wildcarding relevant fields @@ -4943,7 +4943,7 @@ OVS_VSWITCHD_START( set interface p3 type=dummy ofport_request=3]) AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK ]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)']) @@ -4964,7 +4964,7 @@ OVS_VSWITCHD_START( set interface p3 type=dummy ofport_request=3]) AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK ]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)']) @@ -4999,7 +4999,7 @@ OVS_VSWITCHD_START( AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK ]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [7]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-ofctl add-flow br1 action=normal]) @@ -5017,7 +5017,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - resubmit port action]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1,ip actions=resubmit(90) @@ -5036,7 +5036,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - resubmit table action]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1,ip actions=resubmit(,1) @@ -5056,7 +5056,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - goto_table action]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1,ip actions=goto_table(1) @@ -5075,7 +5075,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - mirroring, select_all]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2], [3]) ovs-vsctl \ set Bridge br0 mirrors=@m --\ @@ -5098,7 +5098,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - mirroring, select_vlan]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2], [3]) ovs-vsctl \ set Bridge br0 mirrors=@m --\ @@ -5121,7 +5121,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - move action]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1 ip,actions=move:NXM_OF_IP_SRC[[]]->NXM_NX_REG0[[]],resubmit(90) @@ -5141,7 +5141,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - push action]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1 ip,actions=push:NXM_OF_IP_SRC[[]],output(2) @@ -5159,7 +5159,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - learning]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1 actions=load:2->NXM_NX_REG0[[0..15]],learn(table=1,priority=65535,NXM_OF_ETH_SRC[[]],NXM_OF_VLAN_TCI[[0..11]],output:NXM_NX_REG0[[0..15]]),output:2 @@ -5187,7 +5187,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - tunnels]) OVS_VSWITCHD_START( [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1]) -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) AT_CHECK([ovs-vsctl add-port br0 p2 -- set Interface p2 type=gre \ options:remote_ip=1.1.1.1 ofport_request=2 options:key=flow]) AT_CHECK([ovs-vsctl add-port br0 p3 -- set Interface p3 type=dummy \ @@ -5219,7 +5219,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - dec_ttl]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_CHECK([ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- --id=@N1 create Flow_Table name=t0 prefixes=nw_dst,nw_src], [0], [ignore], []) AT_DATA([flows.txt], [dnl @@ -5238,7 +5238,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - set dl_dst]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1 actions=mod_dl_dst(50:54:00:00:00:0a),output(2) @@ -5266,7 +5266,7 @@ AT_CLEANUP AT_SETUP([ofproto-dpif megaflow - disabled]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl vlog/set dpif:dbg]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl table=0 in_port=1,ip,nw_dst=10.0.0.1 actions=output(2) -- 1.8.1.2 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev