X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fnetflow.c;h=e9382afe9be707b2feccd6d0d2d84992e29265be;hb=28c5588e8e1a8d091c5d2275232c35f2968a97fa;hp=c91ecf0682e6f551213d65ac68ce41f3edb4238c;hpb=8e407f2744c0fad4fe4785c7be5849eb6ad1f903;p=sliver-openvswitch.git diff --git a/ofproto/netflow.c b/ofproto/netflow.c index c91ecf068..e9382afe9 100644 --- a/ofproto/netflow.c +++ b/ofproto/netflow.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ struct netflow { struct hmap flows; /* Contains 'netflow_flows'. */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; }; struct netflow_flow { @@ -79,6 +79,7 @@ struct netflow_flow { }; static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; +static atomic_uint netflow_count = ATOMIC_VAR_INIT(0); static struct netflow_flow *netflow_flow_lookup(const struct netflow *, const struct flow *) @@ -97,8 +98,7 @@ netflow_mask_wc(struct flow *flow, struct flow_wildcards *wc) memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst); - memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); - memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst); + flow_unwildcard_tp_ports(flow, wc); wc->masks.nw_tos |= IP_DSCP_MASK; } @@ -110,7 +110,7 @@ gen_netflow_rec(struct netflow *nf, struct netflow_flow *nf_flow, struct netflow_v5_header *nf_hdr; struct netflow_v5_record *nf_rec; - if (!nf->packet.size) { + if (!ofpbuf_size(&nf->packet)) { struct timespec now; time_wall_timespec(&now); @@ -127,7 +127,7 @@ gen_netflow_rec(struct netflow *nf, struct netflow_flow *nf_flow, nf_hdr->sampling_interval = htons(0); } - nf_hdr = nf->packet.data; + nf_hdr = ofpbuf_data(&nf->packet); nf_hdr->count = htons(ntohs(nf_hdr->count) + 1); nf_rec = ofpbuf_put_zeros(&nf->packet, sizeof *nf_rec); @@ -170,7 +170,7 @@ gen_netflow_rec(struct netflow *nf, struct netflow_flow *nf_flow, } void -netflow_flow_update(struct netflow *nf, struct flow *flow, +netflow_flow_update(struct netflow *nf, const struct flow *flow, ofp_port_t output_iface, const struct dpif_flow_stats *stats) OVS_EXCLUDED(mutex) @@ -270,7 +270,6 @@ netflow_expire__(struct netflow *nf, struct netflow_flow *nf_flow) } /* Update flow tracking data. */ - nf_flow->created = 0; nf_flow->packet_count = 0; nf_flow->byte_count = 0; nf_flow->tcp_flags = 0; @@ -313,9 +312,9 @@ netflow_run__(struct netflow *nf) OVS_REQUIRES(mutex) long long int now = time_msec(); struct netflow_flow *nf_flow, *next; - if (nf->packet.size) { - collectors_send(nf->collectors, nf->packet.data, nf->packet.size); - nf->packet.size = 0; + if (ofpbuf_size(&nf->packet)) { + collectors_send(nf->collectors, ofpbuf_data(&nf->packet), ofpbuf_size(&nf->packet)); + ofpbuf_set_size(&nf->packet, 0); } if (!nf->active_timeout || now < nf->next_timeout) { @@ -354,7 +353,7 @@ netflow_wait(struct netflow *nf) OVS_EXCLUDED(mutex) if (nf->active_timeout) { poll_timer_wait_until(nf->next_timeout); } - if (nf->packet.size) { + if (ofpbuf_size(&nf->packet)) { poll_immediate_wake(); } ovs_mutex_unlock(&mutex); @@ -396,6 +395,8 @@ struct netflow * netflow_create(void) { struct netflow *nf = xzalloc(sizeof *nf); + int junk; + nf->engine_type = 0; nf->engine_id = 0; nf->boot_time = time_msec(); @@ -403,8 +404,9 @@ netflow_create(void) nf->add_id_to_iface = false; nf->netflow_cnt = 0; hmap_init(&nf->flows); - atomic_init(&nf->ref_cnt, 1); + ovs_refcount_init(&nf->ref_cnt); ofpbuf_init(&nf->packet, 1500); + atomic_add(&netflow_count, 1, &junk); return nf; } @@ -413,9 +415,7 @@ netflow_ref(const struct netflow *nf_) { struct netflow *nf = CONST_CAST(struct netflow *, nf_); if (nf) { - int orig; - atomic_add(&nf->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&nf->ref_cnt); } return nf; } @@ -423,20 +423,25 @@ netflow_ref(const struct netflow *nf_) void netflow_unref(struct netflow *nf) { - int orig; - - if (!nf) { - return; - } + if (nf && ovs_refcount_unref(&nf->ref_cnt) == 1) { + int orig; - atomic_sub(&nf->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { - ofpbuf_uninit(&nf->packet); + atomic_sub(&netflow_count, 1, &orig); collectors_destroy(nf->collectors); + ofpbuf_uninit(&nf->packet); free(nf); } } + +/* Returns true if there exist any netflow objects, false otherwise. */ +bool +netflow_exists(void) +{ + int n; + + atomic_read(&netflow_count, &n); + return n > 0; +} /* Helpers. */