Thanks!

I took a few minutes to add a proper test, as follows, and I'll push
this to master soon.

diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 3b816af..37c531b 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -2194,3 +2194,26 @@ br0 (dummy@ovs-dummy):
 
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
+AT_SETUP([ofproto-dpif - port duration])
+OVS_VSWITCHD_START([set Bridge br0 protocols=OpenFlow13])
+ADD_OF_PORTS([br0], 1, 2)
+
+ovs-appctl time/warp 10000
+
+AT_CHECK([ovs-ofctl -O openflow13 dump-ports br0], [0], [stdout])
+AT_CHECK([sed 's/=[[0-9]][[0-9]]\(\.[[0-9]]\{1,\}\)\{,1\}s/=?s/' stdout], [0],
+[dnl
+OFPST_PORT reply (OF1.3) (xid=0x2): 3 ports
+  port  1: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
+           tx pkts=0, bytes=0, drop=0, errs=0, coll=0
+           duration=?s
+  port  2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
+           tx pkts=0, bytes=0, drop=0, errs=0, coll=0
+           duration=?s
+  port LOCAL: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
+           tx pkts=0, bytes=0, drop=0, errs=0, coll=0
+           duration=?s
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP


On Fri, May 24, 2013 at 06:47:34AM +0000, Rajahalme, Jarno (NSN - FI/Espoo) 
wrote:
> Ben,
> 
> Tested, works, and looks good. I can now see port duration in "ovs-ofctl -O 
> OpenFlow13 dump-ports br0" :-)
> 
>   Jarno
> 
> On May 24, 2013, at 2:56 , ext Ben Pfaff wrote:
> 
> > Signed-off-by: Ben Pfaff <b...@nicira.com>
> > ---
> > OPENFLOW-1.1+              |    3 ++-
> > lib/ofp-print.c            |    6 ++++++
> > lib/ofp-util.c             |   17 +++++++----------
> > lib/ofp-util.h             |    2 ++
> > ofproto/ofproto-provider.h |    1 +
> > ofproto/ofproto.c          |   17 +++++++++++------
> > tests/ofp-print.at         |   39 +++++++++++++++++++++++++++++++++++++++
> > 7 files changed, 68 insertions(+), 17 deletions(-)
> > 
> > diff --git a/OPENFLOW-1.1+ b/OPENFLOW-1.1+
> > index b6a4222..d312dab 100644
> > --- a/OPENFLOW-1.1+
> > +++ b/OPENFLOW-1.1+
> > @@ -162,7 +162,8 @@ didn't compare the specs carefully yet.)
> >     * Rework tag order.  I'm not sure whether we need to do anything
> >       for this.
> > 
> > -    * Duration for stats.
> > +    * Duration for queue stats.  (Duration for port stats is already
> > +      implemented.)
> > 
> >     * On-demand flow counters.  I think this might be a real
> >       optimization in some cases for the software switch.
> > diff --git a/lib/ofp-print.c b/lib/ofp-print.c
> > index e899df3..0a9917a 100644
> > --- a/lib/ofp-print.c
> > +++ b/lib/ofp-print.c
> > @@ -1218,6 +1218,12 @@ ofp_print_ofpst_port_reply(struct ds *string, const 
> > struct ofp_header *oh,
> >         print_port_stat(string, "drop=", ps.stats.tx_dropped, 1);
> >         print_port_stat(string, "errs=", ps.stats.tx_errors, 1);
> >         print_port_stat(string, "coll=", ps.stats.collisions, 0);
> > +
> > +        if (ps.duration_sec != UINT32_MAX) {
> > +            ds_put_cstr(string, "           duration=");
> > +            ofp_print_duration(string, ps.duration_sec, ps.duration_nsec);
> > +            ds_put_char(string, '\n');
> > +        }
> >     }
> > }
> > 
> > diff --git a/lib/ofp-util.c b/lib/ofp-util.c
> > index b4ff09b..3c8d5a2 100644
> > --- a/lib/ofp-util.c
> > +++ b/lib/ofp-util.c
> > @@ -4595,11 +4595,8 @@ ofputil_port_stats_to_ofp13(const struct 
> > ofputil_port_stats *ops,
> >                             struct ofp13_port_stats *ps13)
> > {
> >     ofputil_port_stats_to_ofp11(ops, &ps13->ps);
> > -
> > -    /* OF 1.3 adds duration fields */
> > -    /* FIXME: Need to implement port alive duration (sec + nsec) */
> > -    ps13->duration_sec = htonl(~0);
> > -    ps13->duration_nsec = htonl(~0);
> > +    ps13->duration_sec = htonl(ops->duration_sec);
> > +    ps13->duration_nsec = htonl(ops->duration_nsec);
> > }
> > 
> > 
> > @@ -4655,6 +4652,7 @@ ofputil_port_stats_from_ofp10(struct 
> > ofputil_port_stats *ops,
> >     ops->stats.rx_over_errors = 
> > ntohll(get_32aligned_be64(&ps10->rx_over_err));
> >     ops->stats.rx_crc_errors = 
> > ntohll(get_32aligned_be64(&ps10->rx_crc_err));
> >     ops->stats.collisions = ntohll(get_32aligned_be64(&ps10->collisions));
> > +    ops->duration_sec = ops->duration_nsec = UINT32_MAX;
> > 
> >     return 0;
> > }
> > @@ -4683,6 +4681,7 @@ ofputil_port_stats_from_ofp11(struct 
> > ofputil_port_stats *ops,
> >     ops->stats.rx_over_errors = ntohll(ps11->rx_over_err);
> >     ops->stats.rx_crc_errors = ntohll(ps11->rx_crc_err);
> >     ops->stats.collisions = ntohll(ps11->collisions);
> > +    ops->duration_sec = ops->duration_nsec = UINT32_MAX;
> > 
> >     return 0;
> > }
> > @@ -4691,13 +4690,11 @@ static enum ofperr
> > ofputil_port_stats_from_ofp13(struct ofputil_port_stats *ops,
> >                               const struct ofp13_port_stats *ps13)
> > {
> > -    enum ofperr error =
> > -        ofputil_port_stats_from_ofp11(ops, &ps13->ps);
> > +    enum ofperr error = ofputil_port_stats_from_ofp11(ops, &ps13->ps);
> >     if (!error) {
> > -        /* FIXME: Get ps13->duration_sec and ps13->duration_nsec,
> > -         * Add to netdev_stats? */
> > +        ops->duration_sec = ntohl(ps13->duration_sec);
> > +        ops->duration_nsec = ntohl(ps13->duration_nsec);
> >     }
> > -
> >     return error;
> > }
> > 
> > diff --git a/lib/ofp-util.h b/lib/ofp-util.h
> > index 4d0d8ad..010c34d 100644
> > --- a/lib/ofp-util.h
> > +++ b/lib/ofp-util.h
> > @@ -689,6 +689,8 @@ bool ofputil_parse_key_value(char **stringp, char 
> > **keyp, char **valuep);
> > struct ofputil_port_stats {
> >     uint16_t port_no;
> >     struct netdev_stats stats;
> > +    uint32_t duration_sec;      /* UINT32_MAX if unknown. */
> > +    uint32_t duration_nsec;
> > };
> > 
> > struct ofpbuf *ofputil_encode_dump_ports_request(enum ofp_version 
> > ofp_version,
> > diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
> > index b9d6f0d..db0d589 100644
> > --- a/ofproto/ofproto-provider.h
> > +++ b/ofproto/ofproto-provider.h
> > @@ -119,6 +119,7 @@ struct ofport {
> >     struct ofputil_phy_port pp;
> >     uint16_t ofp_port;          /* OpenFlow port number. */
> >     unsigned int change_seq;
> > +    long long int created;      /* Time created, in msec. */
> >     int mtu;
> > };
> > 
> > diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> > index ca1dc89..2f91d65 100644
> > --- a/ofproto/ofproto.c
> > +++ b/ofproto/ofproto.c
> > @@ -203,6 +203,8 @@ static bool handle_openflow(struct ofconn *, struct 
> > ofpbuf *);
> > static enum ofperr handle_flow_mod__(struct ofproto *, struct ofconn *,
> >                                      const struct ofputil_flow_mod *,
> >                                      const struct ofp_header *);
> > +static void calc_duration(long long int start, long long int now,
> > +                          uint32_t *sec, uint32_t *nsec);
> > 
> > /* ofproto. */
> > static uint64_t pick_datapath_id(const struct ofproto *);
> > @@ -1787,6 +1789,7 @@ ofport_install(struct ofproto *p,
> >     ofport->change_seq = netdev_change_seq(netdev);
> >     ofport->pp = *pp;
> >     ofport->ofp_port = pp->port_no;
> > +    ofport->created = time_msec();
> > 
> >     /* Add port to 'p'. */
> >     hmap_insert(&p->ports, &ofport->hmap_node, hash_int(ofport->ofp_port, 
> > 0));
> > @@ -2544,6 +2547,9 @@ append_port_stat(struct ofport *port, struct list 
> > *replies)
> > {
> >     struct ofputil_port_stats ops = { .port_no = port->pp.port_no };
> > 
> > +    calc_duration(port->created, time_msec(),
> > +                  &ops.duration_sec, &ops.duration_nsec);
> > +
> >     /* Intentionally ignore return value, since errors will set
> >      * 'stats' to all-1s, which is correct for OpenFlow, and
> >      * netdev_get_stats() will log errors. */
> > @@ -2604,8 +2610,8 @@ handle_port_desc_stats_request(struct ofconn *ofconn,
> > }
> > 
> > static void
> > -calc_flow_duration__(long long int start, long long int now,
> > -                     uint32_t *sec, uint32_t *nsec)
> > +calc_duration(long long int start, long long int now,
> > +              uint32_t *sec, uint32_t *nsec)
> > {
> >     long long int msecs = now - start;
> >     *sec = msecs / 1000;
> > @@ -2824,8 +2830,7 @@ handle_flow_stats_request(struct ofconn *ofconn,
> >         fs.priority = rule->cr.priority;
> >         fs.cookie = rule->flow_cookie;
> >         fs.table_id = rule->table_id;
> > -        calc_flow_duration__(rule->created, now, &fs.duration_sec,
> > -                             &fs.duration_nsec);
> > +        calc_duration(rule->created, now, &fs.duration_sec, 
> > &fs.duration_nsec);
> >         fs.idle_timeout = rule->idle_timeout;
> >         fs.hard_timeout = rule->hard_timeout;
> >         fs.idle_age = age_secs(now - rule->used);
> > @@ -3438,8 +3443,8 @@ ofproto_rule_send_removed(struct rule *rule, uint8_t 
> > reason)
> >     fr.cookie = rule->flow_cookie;
> >     fr.reason = reason;
> >     fr.table_id = rule->table_id;
> > -    calc_flow_duration__(rule->created, time_msec(),
> > -                         &fr.duration_sec, &fr.duration_nsec);
> > +    calc_duration(rule->created, time_msec(),
> > +                  &fr.duration_sec, &fr.duration_nsec);
> >     fr.idle_timeout = rule->idle_timeout;
> >     fr.hard_timeout = rule->hard_timeout;
> >     rule->ofproto->ofproto_class->rule_get_stats(rule, &fr.packet_count,
> > diff --git a/tests/ofp-print.at b/tests/ofp-print.at
> > index 074a60b..caf0ecc 100644
> > --- a/tests/ofp-print.at
> > +++ b/tests/ofp-print.at
> > @@ -1395,6 +1395,45 @@ OFPST_PORT reply (OF1.2) (xid=0x2): 3 ports
> > ])
> > AT_CLEANUP
> > 
> > +AT_SETUP([OFPST_PORT reply - OF1.3])
> > +AT_KEYWORDS([ofp-print OFPT_STATS_REPLY])
> > +AT_CHECK([ovs-ofctl ofp-print "\
> > +04 13 01 60 00 00 00 02 00 04 00 00 00 00 00 00 \
> > +00 00 00 02 00 00 00 00 00 00 00 00 00 01 95 56 \
> > +00 00 00 00 00 00 00 88 00 00 00 00 02 5d 08 98 \
> > +00 00 00 00 00 00 2c f8 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 00 00 00 00 00 00 00 00 00 00 \
> > +00 00 00 00 00 00 00 00 00 00 00 01 00 0f 42 40 \
> > +ff ff ff fe 00 00 00 00 \
> > +00 00 00 00 00 00 00 44 00 00 00 00 00 00 9d 2c \
> > +00 00 00 00 00 00 16 7c 00 00 00 00 01 1e 36 44 \
> > +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 00 00 \
> > +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \
> > +ff ff ff ff ff ff ff ff \
> > +00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 44 \
> > +00 00 00 00 00 00 9d 2c 00 00 00 00 00 00 16 7c \
> > +00 00 00 00 01 1e 36 44 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 00 00 00 00 00 00 00 00 00 00 \
> > +00 00 00 00 00 00 00 00 00 00 00 00 07 54 d4 c0 \
> > +"], [0], [dnl
> > +OFPST_PORT reply (OF1.3) (xid=0x2): 3 ports
> > +  port  2: rx pkts=103766, bytes=39651480, drop=0, errs=0, frame=0, 
> > over=0, crc=0
> > +           tx pkts=136, bytes=11512, drop=0, errs=0, coll=0
> > +           duration=1.001s
> > +  port LOCAL: rx pkts=68, bytes=5756, drop=0, errs=0, frame=0, over=0, 
> > crc=0
> > +           tx pkts=40236, bytes=18757188, drop=0, errs=0, coll=0
> > +  port  1: rx pkts=68, bytes=5756, drop=0, errs=0, frame=0, over=0, crc=0
> > +           tx pkts=40236, bytes=18757188, drop=0, errs=0, coll=0
> > +           duration=0.123s
> > +])
> > +AT_CLEANUP
> > +
> > AT_SETUP([OFPST_QUEUE request - OF1.0])
> > AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST])
> > AT_CHECK([ovs-ofctl ofp-print "\
> > -- 
> > 1.7.2.5
> > 
> > _______________________________________________
> > 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