On second thought, I noticed that this doesn't fix odd behaviour in the
netflow expiration test.

I sent out a patch to revert the original patch:
http://openvswitch.org/pipermail/dev/2014-June/041868.html


On 23 June 2014 18:29, Joe Stringer <joestrin...@nicira.com> wrote:

> Alex, could you review this series?
>
> I think that the correct solution is to perform "retroactive
> side-effects", that is, perform side effects as though they had happened at
> the time that the flow was hit. Anything that may hide these effects (like
> mac table flush) would need to be taken into account. However, such
> information is unavailable, and would be non-trivial to collect and
> maintain. So I propose that this solution as a slightly better effort than
> what we had previously.
>
>
> On 16 June 2014 17:09, Joe Stringer <joestrin...@nicira.com> wrote:
>
>> Commit a48c85b2d6 (revalidator: Use xcache when revalidation is
>> required.) introduced a bug where xlate_actions effects from the old
>> cache would be performed. This could cause stale mac-learning entries to
>> re-appear, and in some cases, learnt flows to be re-learnt even after
>> the parent flow is deleted.
>>
>> This patch splits the attribution of stats from the execution of side
>> effects for the flow, always attributing the stats to the rules that
>> created them, but selectively executing side-effects based on the
>> validity of the flow.
>>
>> This handles three cases in slightly different ways:
>> * If revalidation is unnecessary, attribute stats and perform
>>   side-effects using the existing xcache.
>> * If revalidation is necessary, and the flow is valid, then attribute
>>   stats using the existing xcache, then perform full revalidation.
>>   Perform side-effects based on the newly built xcache.
>> * If revalidation is necessary, and the flow is invalid, then attribute
>>   stats using the old xcache, and do not perform side-effects.
>>
>> VMware-BZ: #1268574
>>
>> Reported-by: Len Gao <l...@vmware.com>
>> Signed-off-by: Joe Stringer <joestrin...@nicira.com>
>> ---
>>  ofproto/ofproto-dpif-upcall.c |   10 ++++--
>>  ofproto/ofproto-dpif-xlate.c  |   73
>> +++++++++++++++++++++++++++++++----------
>>  ofproto/ofproto-dpif-xlate.h  |    3 +-
>>  3 files changed, 65 insertions(+), 21 deletions(-)
>>
>> diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
>> index b38f226..281955f 100644
>> --- a/ofproto/ofproto-dpif-upcall.c
>> +++ b/ofproto/ofproto-dpif-upcall.c
>> @@ -1148,12 +1148,14 @@ revalidate_ukey(struct udpif *udpif, struct
>> udpif_key *ukey,
>>
>>      may_learn = push.n_packets > 0;
>>      if (ukey->xcache) {
>> -        xlate_push_stats(ukey->xcache, may_learn, &push);
>> +        /* Defer side-effects if the xcache might be out of date. */
>> +        bool execute_side_effects = may_learn && !udpif->need_revalidate;
>> +
>> +        xlate_push_stats(ukey->xcache, execute_side_effects, &push);
>>          if (udpif->need_revalidate) {
>>              xlate_cache_clear(ukey->xcache);
>>              push.n_packets = 0;
>>              push.n_bytes = 0;
>> -            may_learn = false;
>>          } else {
>>              ok = true;
>>              goto exit;
>> @@ -1173,7 +1175,6 @@ revalidate_ukey(struct udpif *udpif, struct
>> udpif_key *ukey,
>>      xlate_in_init(&xin, ofproto, &flow, NULL, push.tcp_flags, NULL);
>>      xin.resubmit_stats = push.n_packets ? &push : NULL;
>>      xin.xcache = ukey->xcache;
>> -    xin.may_learn = may_learn;
>>      xin.skip_wildcards = !udpif->need_revalidate;
>>      xlate_actions(&xin, &xout);
>>      xoutp = &xout;
>> @@ -1214,6 +1215,9 @@ revalidate_ukey(struct udpif *udpif, struct
>> udpif_key *ukey,
>>          }
>>      }
>>      ok = true;
>> +    if (may_learn) {
>> +        xlate_push_effects(ukey->xcache, &push);
>> +    }
>>
>>  exit:
>>      if (netflow) {
>> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
>> index 71eaad1..ca1b62e 100644
>> --- a/ofproto/ofproto-dpif-xlate.c
>> +++ b/ofproto/ofproto-dpif-xlate.c
>> @@ -338,6 +338,8 @@ static bool dscp_from_skb_priority(const struct xport
>> *, uint32_t skb_priority,
>>
>>  static struct xc_entry *xlate_cache_add_entry(struct xlate_cache *xc,
>>                                                enum xc_type type);
>> +static void xlate_push_stats__(struct xlate_cache *,
>> +                               const struct dpif_flow_stats *);
>>  static void xlate_xbridge_init(struct xlate_cfg *, struct xbridge *);
>>  static void xlate_xbundle_init(struct xlate_cfg *, struct xbundle *);
>>  static void xlate_xport_init(struct xlate_cfg *, struct xport *);
>> @@ -3886,10 +3888,46 @@ xlate_cache_normal(struct ofproto_dpif *ofproto,
>> struct flow *flow, int vlan)
>>      update_learning_table(xbridge, flow, &wc, vlan, xbundle);
>>  }
>>
>> -/* Push stats and perform side effects of flow translation. */
>> +/* Perform side effects of flow translation. */
>>  void
>> -xlate_push_stats(struct xlate_cache *xcache, bool may_learn,
>> -                 const struct dpif_flow_stats *stats)
>> +xlate_push_effects(struct xlate_cache *xcache,
>> +                   const struct dpif_flow_stats *stats)
>> +{
>> +    struct xc_entry *entry;
>> +    struct ofpbuf entries = xcache->entries;
>> +
>> +    XC_ENTRY_FOR_EACH (entry, entries, xcache) {
>> +        switch (entry->type) {
>> +        case XC_RULE:
>> +        case XC_BOND:
>> +        case XC_NETDEV:
>> +        case XC_NETFLOW:
>> +        case XC_MIRROR:
>> +        case XC_GROUP:
>> +            /* Handled by xlate_push_stats__(). */
>> +            break;
>> +
>> +        case XC_LEARN:
>> +            ofproto_dpif_flow_mod(entry->u.learn.ofproto, entry->
>> u.learn.fm);
>> +            break;
>> +        case XC_NORMAL:
>> +            xlate_cache_normal(entry->u.normal.ofproto,
>> entry->u.normal.flow,
>> +                               entry->u.normal.vlan);
>> +            break;
>> +        case XC_FIN_TIMEOUT:
>> +            xlate_fin_timeout__(entry->u.fin.rule, stats->tcp_flags,
>> +                                entry->u.fin.idle, entry->u.fin.hard);
>> +            break;
>> +        default:
>> +            OVS_NOT_REACHED();
>> +        }
>> +    }
>> +}
>> +
>> +/* Push stats using the cache provided. */
>> +static void
>> +xlate_push_stats__(struct xlate_cache *xcache,
>> +                   const struct dpif_flow_stats *stats)
>>  {
>>      struct xc_entry *entry;
>>      struct ofpbuf entries = xcache->entries;
>> @@ -3915,30 +3953,31 @@ xlate_push_stats(struct xlate_cache *xcache, bool
>> may_learn,
>>                                  entry->u.mirror.mirrors,
>>                                  stats->n_packets, stats->n_bytes);
>>              break;
>> -        case XC_LEARN:
>> -            if (may_learn) {
>> -                ofproto_dpif_flow_mod(entry->u.learn.ofproto,
>> -                                      entry->u.learn.fm);
>> -            }
>> -            break;
>> -        case XC_NORMAL:
>> -            xlate_cache_normal(entry->u.normal.ofproto,
>> entry->u.normal.flow,
>> -                               entry->u.normal.vlan);
>> -            break;
>> -        case XC_FIN_TIMEOUT:
>> -            xlate_fin_timeout__(entry->u.fin.rule, stats->tcp_flags,
>> -                                entry->u.fin.idle, entry->u.fin.hard);
>> -            break;
>>          case XC_GROUP:
>>              group_dpif_credit_stats(entry->u.group.group,
>> entry->u.group.bucket,
>>                                      stats);
>>              break;
>> +        case XC_LEARN:
>> +        case XC_NORMAL:
>> +        case XC_FIN_TIMEOUT:
>> +            /* Handled by xlate_push_effects(). */
>> +            break;
>>          default:
>>              OVS_NOT_REACHED();
>>          }
>>      }
>>  }
>>
>> +void
>> +xlate_push_stats(struct xlate_cache *xcache, bool execute_side_effects,
>> +                 const struct dpif_flow_stats *stats)
>> +{
>> +    xlate_push_stats__(xcache, stats);
>> +    if (execute_side_effects) {
>> +        xlate_push_effects(xcache, stats);
>> +    }
>> +}
>> +
>>  static void
>>  xlate_dev_unref(struct xc_entry *entry)
>>  {
>> diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
>> index 6065db3..5d40203 100644
>> --- a/ofproto/ofproto-dpif-xlate.h
>> +++ b/ofproto/ofproto-dpif-xlate.h
>> @@ -182,8 +182,9 @@ void xlate_out_copy(struct xlate_out *dst, const
>> struct xlate_out *src);
>>  int xlate_send_packet(const struct ofport_dpif *, struct ofpbuf *);
>>
>>  struct xlate_cache *xlate_cache_new(void);
>> -void xlate_push_stats(struct xlate_cache *, bool may_learn,
>> +void xlate_push_stats(struct xlate_cache *, bool execute_side_effects,
>>                        const struct dpif_flow_stats *);
>> +void xlate_push_effects(struct xlate_cache *, const struct
>> dpif_flow_stats *);
>>  void xlate_cache_clear(struct xlate_cache *);
>>  void xlate_cache_delete(struct xlate_cache *);
>>
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> dev mailing list
>> dev@openvswitch.org
>> http://openvswitch.org/mailman/listinfo/dev
>>
>
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to