X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fstp.c;h=dbe48e82374e5a113670b3633e01bcf0014019ac;hb=28c5588e8e1a8d091c5d2275232c35f2968a97fa;hp=818f2ca3dc9a3f61f390f429e703b75f58580efb;hpb=c5f81b20da9bbf0ac406a88718597a4e84729a98;p=sliver-openvswitch.git diff --git a/lib/stp.c b/lib/stp.c index 818f2ca3d..dbe48e823 100644 --- a/lib/stp.c +++ b/lib/stp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 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. @@ -143,7 +143,7 @@ struct stp { void (*send_bpdu)(struct ofpbuf *bpdu, int port_no, void *aux); void *aux; - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; }; static struct ovs_mutex mutex; @@ -306,7 +306,7 @@ stp_create(const char *name, stp_identifier bridge_id, p->path_cost = 19; /* Recommended default for 100 Mb/s link. */ stp_initialize_port(p, STP_DISABLED); } - atomic_init(&stp->ref_cnt, 1); + ovs_refcount_init(&stp->ref_cnt); list_push_back(all_stps, &stp->node); ovs_mutex_unlock(&mutex); @@ -318,9 +318,7 @@ stp_ref(const struct stp *stp_) { struct stp *stp = CONST_CAST(struct stp *, stp_); if (stp) { - int orig; - atomic_add(&stp->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&stp->ref_cnt); } return stp; } @@ -329,20 +327,11 @@ stp_ref(const struct stp *stp_) void stp_unref(struct stp *stp) { - int orig; - - if (!stp) { - return; - } - - atomic_sub(&stp->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { + if (stp && ovs_refcount_unref(&stp->ref_cnt) == 1) { ovs_mutex_lock(&mutex); list_remove(&stp->node); ovs_mutex_unlock(&mutex); free(stp->name); - atomic_destroy(&stp->ref_cnt); free(stp); } } @@ -695,6 +684,15 @@ stp_learn_in_state(enum stp_state state) return (state & (STP_DISABLED | STP_LEARNING | STP_FORWARDING)) != 0; } +/* Returns true if 'state' is one in which rx&tx bpdu should be done on + * on a port, false otherwise. */ +bool +stp_listen_in_state(enum stp_state state) +{ + return (state & + (STP_LISTENING | STP_LEARNING | STP_FORWARDING)) != 0; +} + /* Returns the name for the given 'role' (for use in debugging and log * messages). */ const char * @@ -1537,14 +1535,15 @@ stp_send_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size) /* Skeleton. */ pkt = ofpbuf_new(ETH_HEADER_LEN + LLC_HEADER_LEN + bpdu_size); - pkt->l2 = eth = ofpbuf_put_zeros(pkt, sizeof *eth); + eth = ofpbuf_put_zeros(pkt, sizeof *eth); llc = ofpbuf_put_zeros(pkt, sizeof *llc); - pkt->l3 = ofpbuf_put(pkt, bpdu, bpdu_size); + ofpbuf_set_frame(pkt, eth); + ofpbuf_set_l3(pkt, ofpbuf_put(pkt, bpdu, bpdu_size)); /* 802.2 header. */ memcpy(eth->eth_dst, eth_addr_stp, ETH_ADDR_LEN); /* p->stp->send_bpdu() must fill in source address. */ - eth->eth_type = htons(pkt->size - ETH_HEADER_LEN); + eth->eth_type = htons(ofpbuf_size(pkt) - ETH_HEADER_LEN); /* LLC header. */ llc->llc_dsap = STP_LLC_DSAP;