Applied to master and branch-1.11, thanks.  Do we need this on
branch-1.10 also?

On Tue, Apr 30, 2013 at 10:38:53PM -0700, Neil Mckee wrote:
> I learned how to squash patches...
> 
> Change sFlow model to reflect per-bridge sampling.  Before we were presenting 
> a separate
> sFlow data-source (sampler) for each ifIndex-interface,  and it was causing 
> problems with
> samples that did not easily map to an ifIndex being aliased together and 
> breaking the sFlow
> containment rules.  This patch changes the model to present a single sFlow 
> data-source for
> each bridge.  Now we can still make all reasonable effort to map packet 
> samples to
> ingress/egress ifIndex numbers,  knowing that the fallback to "unknown" does 
> not break the
> sFlow model.   Note that interface-counter-polling is still handled the same 
> way as before,
> with sFlow counter-polling data only being exported for ifIndex-interfaces.
> 
> Signed-off-by: Neil McKee <neil.mc...@inmon.com>
> 
> ---
>  lib/sflow.h                  |  7 ++++
>  ofproto/ofproto-dpif-sflow.c | 80 
> +++++++++++++++++++++-----------------------
>  ofproto/ofproto-dpif.c       |  6 +++-
>  ofproto/tunnel.c             |  1 -
>  tests/ofproto-dpif.at        | 48 +++++++++++++-------------
>  5 files changed, 75 insertions(+), 67 deletions(-)
> 
> diff --git a/lib/sflow.h b/lib/sflow.h
> index 8ea9693..0d1f2b9 100644
> --- a/lib/sflow.h
> +++ b/lib/sflow.h
> @@ -8,6 +8,13 @@
>  #ifndef SFLOW_H
>  #define SFLOW_H 1
>  
> +typedef enum {
> +    SFL_DSCLASS_IFINDEX = 0,
> +    SFL_DSCLASS_VLAN = 1,
> +    SFL_DSCLASS_PHYSICAL_ENTITY = 2,
> +    SFL_DSCLASS_LOGICAL_ENTITY = 3
> +} SFL_DSCLASS;
> +
>  enum SFLAddress_type {
>      SFLADDRESSTYPE_IP_V4 = 1,
>      SFLADDRESSTYPE_IP_V6 = 2
> diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c
> index 69362ab..9ad0eaf 100644
> --- a/ofproto/ofproto-dpif-sflow.c
> +++ b/ofproto/ofproto-dpif-sflow.c
> @@ -341,39 +341,32 @@ dpif_sflow_add_poller(struct dpif_sflow *ds, struct 
> dpif_sflow_port *dsp)
>      sfl_poller_set_bridgePort(poller, dsp->odp_port);
>  }
>  
> -static void
> -dpif_sflow_add_sampler(struct dpif_sflow *ds, struct dpif_sflow_port *dsp)
> -{
> -    SFLSampler *sampler = sfl_agent_addSampler(ds->sflow_agent, &dsp->dsi);
> -    sfl_sampler_set_sFlowFsPacketSamplingRate(sampler, 
> ds->options->sampling_rate);
> -    sfl_sampler_set_sFlowFsMaximumHeaderSize(sampler, 
> ds->options->header_len);
> -    sfl_sampler_set_sFlowFsReceiver(sampler, RECEIVER_INDEX);
> -}
> -
>  void
>  dpif_sflow_add_port(struct dpif_sflow *ds, struct ofport *ofport,
>                      uint32_t odp_port)
>  {
>      struct dpif_sflow_port *dsp;
> -    uint32_t ifindex;
> +    int ifindex;
>  
>      dpif_sflow_del_port(ds, odp_port);
>  
> -    /* Add to table of ports. */
> -    dsp = xmalloc(sizeof *dsp);
>      ifindex = netdev_get_ifindex(ofport->netdev);
> +
>      if (ifindex <= 0) {
> -        ifindex = (ds->sflow_agent->subId << 16) + odp_port;
> +        /* Not an ifindex port, so do not add a cross-reference to it here */
> +        return;
>      }
> +
> +    /* Add to table of ports. */
> +    dsp = xmalloc(sizeof *dsp);
>      dsp->ofport = ofport;
>      dsp->odp_port = odp_port;
> -    SFL_DS_SET(dsp->dsi, 0, ifindex, 0);
> +    SFL_DS_SET(dsp->dsi, SFL_DSCLASS_IFINDEX, ifindex, 0);
>      hmap_insert(&ds->ports, &dsp->hmap_node, hash_int(odp_port, 0));
>  
> -    /* Add poller and sampler. */
> +    /* Add poller. */
>      if (ds->sflow_agent) {
>          dpif_sflow_add_poller(ds, dsp);
> -        dpif_sflow_add_sampler(ds, dsp);
>      }
>  }
>  
> @@ -406,6 +399,9 @@ dpif_sflow_set_options(struct dpif_sflow *ds,
>      SFLReceiver *receiver;
>      SFLAddress agentIP;
>      time_t now;
> +    SFLDataSource_instance dsi;
> +    uint32_t dsIndex;
> +    SFLSampler *sampler;
>  
>      if (sset_is_empty(&options->targets) || !options->sampling_rate) {
>          /* No point in doing any work if there are no targets or nothing to
> @@ -473,10 +469,20 @@ dpif_sflow_set_options(struct dpif_sflow *ds,
>      /* Set the sampling_rate down in the datapath. */
>      ds->probability = MAX(1, UINT32_MAX / ds->options->sampling_rate);
>  
> -    /* Add samplers and pollers for the currently known ports. */
> +    /* Add a single sampler for the bridge. This appears as a PHYSICAL_ENTITY
> +       because it is associated with the hypervisor, and interacts with the 
> server
> +       hardware directly.  The sub_id is used to distinguish this sampler 
> from
> +       others on other bridges within the same agent. */
> +    dsIndex = 1000 + options->sub_id;
> +    SFL_DS_SET(dsi, SFL_DSCLASS_PHYSICAL_ENTITY, dsIndex, 0);
> +    sampler = sfl_agent_addSampler(ds->sflow_agent, &dsi);
> +    sfl_sampler_set_sFlowFsPacketSamplingRate(sampler, 
> ds->options->sampling_rate);
> +    sfl_sampler_set_sFlowFsMaximumHeaderSize(sampler, 
> ds->options->header_len);
> +    sfl_sampler_set_sFlowFsReceiver(sampler, RECEIVER_INDEX);
> +
> +    /* Add pollers for the currently known ifindex-ports */
>      HMAP_FOR_EACH (dsp, hmap_node, &ds->ports) {
>          dpif_sflow_add_poller(ds, dsp);
> -        dpif_sflow_add_sampler(ds, dsp);
>      }
>  }
>  
> @@ -499,43 +505,35 @@ dpif_sflow_received(struct dpif_sflow *ds, struct 
> ofpbuf *packet,
>      SFLFlow_sample_element switchElem;
>      SFLSampler *sampler;
>      struct dpif_sflow_port *in_dsp;
> -    struct netdev_stats stats;
>      ovs_be16 vlan_tci;
> -    int error;
>  
> -    /* Build a flow sample */
> -    memset(&fs, 0, sizeof fs);
> -
> -    in_dsp = dpif_sflow_find_port(ds, odp_in_port);
> -    if (!in_dsp) {
> +    sampler = ds->sflow_agent->samplers;
> +    if (!sampler) {
>          return;
>      }
> -    fs.input = SFL_DS_INDEX(in_dsp->dsi);
>  
> -    error = ofproto_port_get_stats(in_dsp->ofport, &stats);
> -    if (error) {
> -        VLOG_WARN_RL(&rl, "netdev get-stats error %s", strerror(error));
> -        return;
> -    }
> -    fs.sample_pool = stats.rx_packets;
> +    /* Build a flow sample. */
> +    memset(&fs, 0, sizeof fs);
>  
> -    /* We are going to give it to the sampler that represents this input 
> port.
> -     * By implementing "ingress-only" sampling like this we ensure that we
> -     * never have to offer the same sample to more than one sampler. */
> -    sampler = sfl_agent_getSamplerByIfIndex(ds->sflow_agent, fs.input);
> -    if (!sampler) {
> -        VLOG_WARN_RL(&rl, "no sampler for input ifIndex (%"PRIu32")",
> -                     fs.input);
> -        return;
> +    /* Look up the input ifIndex if this port has one. Otherwise just
> +     * leave it as 0 (meaning 'unknown') and continue. */
> +    in_dsp = dpif_sflow_find_port(ds, odp_in_port);
> +    if (in_dsp) {
> +        fs.input = SFL_DS_INDEX(in_dsp->dsi);
>      }
>  
> +    /* Make the assumption that the random number generator in the datapath 
> converges
> +     * to the configured mean, and just increment the samplePool by the 
> configured
> +     * sampling rate every time. */
> +    sampler->samplePool += 
> sfl_sampler_get_sFlowFsPacketSamplingRate(sampler);
> +
>      /* Sampled header. */
>      memset(&hdrElem, 0, sizeof hdrElem);
>      hdrElem.tag = SFLFLOW_HEADER;
>      header = &hdrElem.flowType.header;
>      header->header_protocol = SFLHEADER_ETHERNET_ISO8023;
>      /* The frame_length should include the Ethernet FCS (4 bytes),
> -       but it has already been stripped,  so we need to add 4 here. */
> +     * but it has already been stripped,  so we need to add 4 here. */
>      header->frame_length = packet->size + 4;
>      /* Ethernet FCS stripped off. */
>      header->stripped = 4;
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 3ae3532..4306d40 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -1782,7 +1782,11 @@ port_construct(struct ofport *port_)
>      port->carrier_seq = netdev_get_carrier_resets(netdev);
>  
>      if (netdev_vport_is_patch(netdev)) {
> -        /* XXX By bailing out here, we don't do required sFlow work. */
> +        /* By bailing out here, we don't submit the port to the sFlow module
> +      * to be considered for counter polling export.  This is correct
> +      * because the patch port represents an interface that sFlow considers
> +      * to be "internal" to the switch as a whole, and therefore not an
> +      * candidate for counter polling. */
>          port->odp_port = OVSP_NONE;
>          return 0;
>      }
> diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
> index 8aa7fbe..8d29184 100644
> --- a/ofproto/tunnel.c
> +++ b/ofproto/tunnel.c
> @@ -32,7 +32,6 @@
>  
>  /* XXX:
>   *
> - * Ability to generate metadata for packet-outs
>   * Disallow netdevs with names like "gre64_system" to prevent collisions. */
>  
>  VLOG_DEFINE_THIS_MODULE(tunnel);
> diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
> index b1d2f26..b813fd0 100644
> --- a/tests/ofproto-dpif.at
> +++ b/tests/ofproto-dpif.at
> @@ -1252,7 +1252,7 @@ AT_CHECK([[sort sflow.log | $EGREP 'HEADER|ERROR' | sed 
> 's/ /\
>       /g']], [0], [dnl
>  HEADER
>       dgramSeqNo=1
> -     ds=127.0.0.1>0:1003
> +     ds=127.0.0.1>2:1000
>       fsSeqNo=1
>       in_vlan=0
>       in_priority=0
> @@ -1261,7 +1261,7 @@ HEADER
>       meanSkip=1
>       samplePool=1
>       dropEvents=0
> -     in_ifindex=1003
> +     in_ifindex=1004
>       in_format=0
>       out_ifindex=2
>       out_format=2
> @@ -1269,10 +1269,10 @@ HEADER
>       pkt_len=64
>       stripped=4
>       hdr_len=60
> -     
> hdr=FF-FF-FF-FF-FF-FF-50-54-00-00-00-07-08-06-00-01-08-00-06-04-00-01-50-54-00-00-00-07-C0-A8-00-01-00-00-00-00-00-00-C0-A8-00-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
> +     
> hdr=FF-FF-FF-FF-FF-FF-50-54-00-00-00-05-08-06-00-01-08-00-06-04-00-01-50-54-00-00-00-05-C0-A8-00-02-00-00-00-00-00-00-C0-A8-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
>  HEADER
>       dgramSeqNo=1
> -     ds=127.0.0.1>0:1003
> +     ds=127.0.0.1>2:1000
>       fsSeqNo=2
>       in_vlan=0
>       in_priority=0
> @@ -1283,16 +1283,16 @@ HEADER
>       dropEvents=0
>       in_ifindex=1003
>       in_format=0
> -     out_ifindex=1004
> -     out_format=0
> +     out_ifindex=2
> +     out_format=2
>       hdr_prot=1
>       pkt_len=64
>       stripped=4
>       hdr_len=60
> -     
> hdr=50-54-00-00-00-05-50-54-00-00-00-07-08-00-45-00-00-1C-00-00-00-00-40-01-F9-8D-C0-A8-00-02-C0-A8-00-01-00-00-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
> +     
> hdr=FF-FF-FF-FF-FF-FF-50-54-00-00-00-07-08-06-00-01-08-00-06-04-00-01-50-54-00-00-00-07-C0-A8-00-01-00-00-00-00-00-00-C0-A8-00-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
>  HEADER
>       dgramSeqNo=1
> -     ds=127.0.0.1>0:1003
> +     ds=127.0.0.1>2:1000
>       fsSeqNo=3
>       in_vlan=0
>       in_priority=0
> @@ -1301,55 +1301,55 @@ HEADER
>       meanSkip=1
>       samplePool=3
>       dropEvents=0
> -     in_ifindex=1003
> +     in_ifindex=1004
>       in_format=0
> -     out_ifindex=1004
> +     out_ifindex=1003
>       out_format=0
>       hdr_prot=1
>       pkt_len=64
>       stripped=4
>       hdr_len=60
> -     
> hdr=50-54-00-00-00-05-50-54-00-00-00-07-86-DD-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
> +     
> hdr=50-54-00-00-00-07-50-54-00-00-00-05-08-00-45-00-00-1C-00-00-00-00-40-01-F9-8D-C0-A8-00-01-C0-A8-00-02-08-00-F7-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
>  HEADER
>       dgramSeqNo=1
> -     ds=127.0.0.1>0:1004
> -     fsSeqNo=1
> +     ds=127.0.0.1>2:1000
> +     fsSeqNo=4
>       in_vlan=0
>       in_priority=0
>       out_vlan=0
>       out_priority=0
>       meanSkip=1
> -     samplePool=1
> +     samplePool=4
>       dropEvents=0
> -     in_ifindex=1004
> +     in_ifindex=1003
>       in_format=0
> -     out_ifindex=2
> -     out_format=2
> +     out_ifindex=1004
> +     out_format=0
>       hdr_prot=1
>       pkt_len=64
>       stripped=4
>       hdr_len=60
> -     
> hdr=FF-FF-FF-FF-FF-FF-50-54-00-00-00-05-08-06-00-01-08-00-06-04-00-01-50-54-00-00-00-05-C0-A8-00-02-00-00-00-00-00-00-C0-A8-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
> +     
> hdr=50-54-00-00-00-05-50-54-00-00-00-07-08-00-45-00-00-1C-00-00-00-00-40-01-F9-8D-C0-A8-00-02-C0-A8-00-01-00-00-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
>  HEADER
>       dgramSeqNo=1
> -     ds=127.0.0.1>0:1004
> -     fsSeqNo=2
> +     ds=127.0.0.1>2:1000
> +     fsSeqNo=5
>       in_vlan=0
>       in_priority=0
>       out_vlan=0
>       out_priority=0
>       meanSkip=1
> -     samplePool=2
> +     samplePool=5
>       dropEvents=0
> -     in_ifindex=1004
> +     in_ifindex=1003
>       in_format=0
> -     out_ifindex=1003
> +     out_ifindex=1004
>       out_format=0
>       hdr_prot=1
>       pkt_len=64
>       stripped=4
>       hdr_len=60
> -     
> hdr=50-54-00-00-00-07-50-54-00-00-00-05-08-00-45-00-00-1C-00-00-00-00-40-01-F9-8D-C0-A8-00-01-C0-A8-00-02-08-00-F7-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
> +     
> hdr=50-54-00-00-00-05-50-54-00-00-00-07-86-DD-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
>  ])
>  
>  AT_CHECK([[sort sflow.log | $EGREP 'IFCOUNTERS|ERROR' | head -6 | sed 's/ /\
> -- 
> 1.8.1.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