X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif-upcall.c;h=9bf1336601101159e74e9ad7a442ac347d931fa6;hb=b256dc525c8ef663daf2330463e67a26207cc5f1;hp=938cfdebc3a3720c59291bdfb043da3a9cd37cdf;hpb=1ebeaaa7f0c3f0f94f28377404c52a11cca50d86;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 938cfdebc..9bf133660 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -168,6 +168,9 @@ struct udpif_key { bool mark; /* Used by mark and sweep GC algorithm. */ struct odputil_keybuf key_buf; /* Memory for 'key'. */ + struct xlate_cache *xcache; /* Cache for xlate entries that + * are affected by this ukey. + * Used for stats and learning.*/ }; /* 'udpif_flow_dump's hold the state associated with one iteration in a flow @@ -1314,6 +1317,7 @@ ukey_create(const struct nlattr *key, size_t key_len, long long int used) ukey->mark = false; ukey->created = used ? used : time_msec(); memset(&ukey->stats, 0, sizeof ukey->stats); + ukey->xcache = NULL; return ukey; } @@ -1322,6 +1326,7 @@ static void ukey_delete(struct revalidator *revalidator, struct udpif_key *ukey) { hmap_remove(&revalidator->ukeys, &ukey->hmap_node); + xlate_cache_delete(ukey->xcache); free(ukey); } @@ -1341,12 +1346,13 @@ revalidate_ukey(struct udpif *udpif, struct udpif_flow_dump *udump, struct xlate_in xin; int error; size_t i; - bool ok; + bool may_learn, ok; ok = false; xoutp = NULL; actions = NULL; netflow = NULL; + may_learn = push.n_packets > 0; /* If we don't need to revalidate, we can simply push the stats contained * in the udump, otherwise we'll have to get the actions so we can check @@ -1373,15 +1379,29 @@ revalidate_ukey(struct udpif *udpif, struct udpif_flow_dump *udump, goto exit; } + if (ukey->xcache && !udump->need_revalidate) { + xlate_push_stats(ukey->xcache, may_learn, &push); + ok = true; + goto exit; + } + error = xlate_receive(udpif->backer, NULL, ukey->key, ukey->key_len, &flow, &ofproto, NULL, NULL, &netflow, &odp_in_port); if (error) { goto exit; } + if (udump->need_revalidate) { + xlate_cache_clear(ukey->xcache); + } + if (!ukey->xcache) { + ukey->xcache = xlate_cache_new(); + } + xlate_in_init(&xin, ofproto, &flow, NULL, push.tcp_flags, NULL); xin.resubmit_stats = push.n_packets ? &push : NULL; - xin.may_learn = push.n_packets > 0; + xin.xcache = ukey->xcache; + xin.may_learn = may_learn; xin.skip_wildcards = !udump->need_revalidate; xlate_actions(&xin, &xout); xoutp = &xout; @@ -1487,6 +1507,13 @@ push_dump_ops(struct revalidator *revalidator, struct ofproto_dpif *ofproto; struct netflow *netflow; struct flow flow; + bool may_learn; + + may_learn = push->n_packets > 0; + if (op->ukey && op->ukey->xcache) { + xlate_push_stats(op->ukey->xcache, may_learn, push); + continue; + } if (!xlate_receive(udpif->backer, NULL, op->op.u.flow_del.key, op->op.u.flow_del.key_len, &flow, &ofproto, @@ -1496,7 +1523,7 @@ push_dump_ops(struct revalidator *revalidator, xlate_in_init(&xin, ofproto, &flow, NULL, push->tcp_flags, NULL); xin.resubmit_stats = push->n_packets ? push : NULL; - xin.may_learn = push->n_packets > 0; + xin.may_learn = may_learn; xin.skip_wildcards = true; xlate_actions_for_side_effects(&xin);