-/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "hmapx.h"
#include "ofproto.h"
#include "vlan-bitmap.h"
-#include "vlog.h"
+#include "openvswitch/vlog.h"
VLOG_DEFINE_THIS_MODULE(ofproto_dpif_mirror);
bool need_revalidate;
bool has_mirrors;
- int ref_cnt;
+ struct ovs_refcount ref_cnt;
};
struct mbundle {
size_t n_bundles, struct hmapx *mbundles);
static int mirror_scan(struct mbridge *);
static void mirror_update_dups(struct mbridge *);
-static int mirror_mask_ffs(mirror_mask_t);
struct mbridge *
mbridge_create(void)
struct mbridge *mbridge;
mbridge = xzalloc(sizeof *mbridge);
- mbridge->ref_cnt = 1;
+ ovs_refcount_init(&mbridge->ref_cnt);
hmap_init(&mbridge->mbundles);
return mbridge;
{
struct mbridge *mbridge = CONST_CAST(struct mbridge *, mbridge_);
if (mbridge) {
- ovs_assert(mbridge->ref_cnt > 0);
- mbridge->ref_cnt++;
+ ovs_refcount_ref(&mbridge->ref_cnt);
}
return mbridge;
}
return;
}
- ovs_assert(mbridge->ref_cnt > 0);
- if (--mbridge->ref_cnt) {
- return;
- }
+ if (ovs_refcount_unref(&mbridge->ref_cnt) == 1) {
+ for (i = 0; i < MAX_MIRRORS; i++) {
+ if (mbridge->mirrors[i]) {
+ mirror_destroy(mbridge, mbridge->mirrors[i]->aux);
+ }
+ }
- for (i = 0; i < MAX_MIRRORS; i++) {
- if (mbridge->mirrors[i]) {
- mirror_destroy(mbridge, mbridge->mirrors[i]->aux);
+ HMAP_FOR_EACH_SAFE (mbundle, next, hmap_node, &mbridge->mbundles) {
+ mbridge_unregister_bundle(mbridge, mbundle->ofbundle);
}
- }
- HMAP_FOR_EACH_SAFE (mbundle, next, hmap_node, &mbridge->mbundles) {
- mbridge_unregister_bundle(mbridge, mbundle->ofbundle);
+ hmap_destroy(&mbridge->mbundles);
+ free(mbridge);
}
-
- hmap_destroy(&mbridge->mbundles);
- free(mbridge);
}
bool
for (; mirrors; mirrors = zero_rightmost_1bit(mirrors)) {
struct mirror *m;
- m = mbridge->mirrors[mirror_mask_ffs(mirrors) - 1];
+ m = mbridge->mirrors[raw_ctz(mirrors)];
if (!m) {
/* In normal circumstances 'm' will not be NULL. However,
}
}
-/* Retrieves the mirror in 'mbridge' represented by the first bet set of
- * 'mirrors'. Returns true if such a mirror exists, false otherwise.
- * The caller takes ownership of, and is expected to deallocate, 'vlans' */
+/* Retrieves the mirror numbered 'index' in 'mbridge'. Returns true if such a
+ * mirror exists, false otherwise.
+ *
+ * If successful, '*vlans' receives the mirror's VLAN membership information,
+ * either a null pointer if the mirror includes all VLANs or a 4096-bit bitmap
+ * in which a 1-bit indicates that the mirror includes a particular VLAN,
+ * '*dup_mirrors' receives a bitmap of mirrors whose output duplicates mirror
+ * 'index', '*out' receives the output ofbundle (if any), and '*out_vlan'
+ * receives the output VLAN (if any). */
bool
-mirror_get(struct mbridge *mbridge, int index, unsigned long **vlans,
+mirror_get(struct mbridge *mbridge, int index, const unsigned long **vlans,
mirror_mask_t *dup_mirrors, struct ofbundle **out, int *out_vlan)
{
struct mirror *mirror;
return false;
}
- *vlans = vlan_bitmap_clone(mirror->vlans);
+ *vlans = mirror->vlans;
*dup_mirrors = mirror->dup_mirrors;
*out = mirror->out ? mirror->out->ofbundle : NULL;
*out_vlan = mirror->out_vlan;