54
55
ovs_be16 port_priority; /* Port priority. */
55
56
ovs_be16 port_id; /* Port ID. */
56
57
uint8_t state; /* State mask. See LACP_STATE macros. */
57
} __attribute__((packed));
58
59
BUILD_ASSERT_DECL(LACP_INFO_LEN == sizeof(struct lacp_info));
60
61
#define LACP_PDU_LEN 110
62
64
uint8_t subtype; /* Always 1. */
63
65
uint8_t version; /* Always 1. */
76
78
uint8_t collector_len; /* Always 16. */
77
79
ovs_be16 collector_delay; /* Maximum collector delay. Set to UINT16_MAX. */
78
80
uint8_t z3[64]; /* Combination of several fields. Always 0. */
79
} __attribute__((packed));
80
82
BUILD_ASSERT_DECL(LACP_PDU_LEN == sizeof(struct lacp_pdu));
82
84
/* Implementation. */
120
124
struct timer rx; /* Expected message receive timer. */
123
static struct list all_lacps = LIST_INITIALIZER(&all_lacps);
125
static void lacp_update_attached(struct lacp *);
127
static void slave_destroy(struct slave *);
128
static void slave_set_defaulted(struct slave *);
129
static void slave_set_expired(struct slave *);
130
static void slave_get_actor(struct slave *, struct lacp_info *actor);
131
static void slave_get_priority(struct slave *, struct lacp_info *priority);
132
static bool slave_may_tx(const struct slave *);
133
static struct slave *slave_lookup(const struct lacp *, const void *slave);
134
static bool info_tx_equal(struct lacp_info *, struct lacp_info *);
127
static struct ovs_mutex mutex;
128
static struct list all_lacps__ = LIST_INITIALIZER(&all_lacps__);
129
static struct list *const all_lacps OVS_GUARDED_BY(mutex) = &all_lacps__;
131
static void lacp_update_attached(struct lacp *) OVS_REQ_WRLOCK(mutex);
133
static void slave_destroy(struct slave *) OVS_REQ_WRLOCK(mutex);
134
static void slave_set_defaulted(struct slave *) OVS_REQ_WRLOCK(mutex);
135
static void slave_set_expired(struct slave *) OVS_REQ_WRLOCK(mutex);
136
static void slave_get_actor(struct slave *, struct lacp_info *actor)
137
OVS_REQ_WRLOCK(mutex);
138
static void slave_get_priority(struct slave *, struct lacp_info *priority)
139
OVS_REQ_WRLOCK(mutex);
140
static bool slave_may_tx(const struct slave *)
141
OVS_REQ_WRLOCK(mutex);
142
static struct slave *slave_lookup(const struct lacp *, const void *slave)
143
OVS_REQ_WRLOCK(mutex);
144
static bool info_tx_equal(struct lacp_info *, struct lacp_info *)
145
OVS_REQ_WRLOCK(mutex);
136
147
static unixctl_cb_func lacp_unixctl_show;
191
202
/* Creates a LACP object. */
204
lacp_create(void) OVS_EXCLUDED(mutex)
206
static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
195
207
struct lacp *lacp;
209
if (ovsthread_once_start(&once)) {
210
ovs_mutex_init(&mutex, PTHREAD_MUTEX_RECURSIVE);
211
ovsthread_once_done(&once);
197
214
lacp = xzalloc(sizeof *lacp);
198
215
hmap_init(&lacp->slaves);
199
list_push_back(&all_lacps, &lacp->node);
216
atomic_init(&lacp->ref_cnt, 1);
218
ovs_mutex_lock(&mutex);
219
list_push_back(all_lacps, &lacp->node);
220
ovs_mutex_unlock(&mutex);
225
lacp_ref(const struct lacp *lacp_)
227
struct lacp *lacp = CONST_CAST(struct lacp *, lacp_);
230
atomic_add(&lacp->ref_cnt, 1, &orig);
231
ovs_assert(orig > 0);
203
236
/* Destroys 'lacp' and its slaves. Does nothing if 'lacp' is NULL. */
205
lacp_destroy(struct lacp *lacp)
238
lacp_unref(struct lacp *lacp) OVS_EXCLUDED(mutex)
246
atomic_sub(&lacp->ref_cnt, 1, &orig);
247
ovs_assert(orig > 0);
208
249
struct slave *slave, *next;
251
ovs_mutex_lock(&mutex);
210
252
HMAP_FOR_EACH_SAFE (slave, next, node, &lacp->slaves) {
211
253
slave_destroy(slave);
215
257
list_remove(&lacp->node);
216
258
free(lacp->name);
260
ovs_mutex_unlock(&mutex);
221
264
/* Configures 'lacp' with settings from 's'. */
223
266
lacp_configure(struct lacp *lacp, const struct lacp_settings *s)
225
269
ovs_assert(!eth_addr_is_zero(s->id));
271
ovs_mutex_lock(&mutex);
227
272
if (!lacp->name || strcmp(s->name, lacp->name)) {
228
273
free(lacp->name);
229
274
lacp->name = xstrdup(s->name);
239
284
lacp->active = s->active;
240
285
lacp->fast = s->fast;
286
ovs_mutex_unlock(&mutex);
243
289
/* Returns true if 'lacp' is configured in active mode, false if 'lacp' is
244
290
* configured for passive mode. */
246
lacp_is_active(const struct lacp *lacp)
292
lacp_is_active(const struct lacp *lacp) OVS_EXCLUDED(mutex)
295
ovs_mutex_lock(&mutex);
297
ovs_mutex_unlock(&mutex);
251
301
/* Processes 'packet' which was received on 'slave_'. This function should be
255
305
lacp_process_packet(struct lacp *lacp, const void *slave_,
256
306
const struct ofpbuf *packet)
258
309
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
259
struct slave *slave = slave_lookup(lacp, slave_);
260
310
const struct lacp_pdu *pdu;
261
311
long long int tx_rate;
314
ovs_mutex_lock(&mutex);
315
slave = slave_lookup(lacp, slave_);
263
320
pdu = parse_lacp_packet(packet);
265
322
VLOG_WARN_RL(&rl, "%s: received an unparsable LACP PDU.", lacp->name);
269
326
slave->status = LACP_CURRENT;
279
336
lacp->update = true;
280
337
slave->partner = pdu->actor;
341
ovs_mutex_unlock(&mutex);
284
344
/* Returns the lacp_status of the given 'lacp' object (which may be NULL). */
286
lacp_status(const struct lacp *lacp)
346
lacp_status(const struct lacp *lacp) OVS_EXCLUDED(mutex)
348
enum lacp_status ret;
350
ovs_mutex_lock(&mutex);
289
return LACP_DISABLED;
290
353
} else if (lacp->negotiated) {
291
return LACP_NEGOTIATED;
354
ret = LACP_NEGOTIATED;
293
return LACP_CONFIGURED;
356
ret = LACP_CONFIGURED;
358
ovs_mutex_unlock(&mutex);
297
362
/* Registers 'slave_' as subordinate to 'lacp'. This should be called at least
301
366
lacp_slave_register(struct lacp *lacp, void *slave_,
302
367
const struct lacp_slave_settings *s)
304
struct slave *slave = slave_lookup(lacp, slave_);
372
ovs_mutex_lock(&mutex);
373
slave = slave_lookup(lacp, slave_);
307
375
slave = xzalloc(sizeof *slave);
308
376
slave->lacp = lacp;
333
401
slave_set_expired(slave);
404
ovs_mutex_unlock(&mutex);
338
407
/* Unregisters 'slave_' with 'lacp'. */
340
409
lacp_slave_unregister(struct lacp *lacp, const void *slave_)
342
struct slave *slave = slave_lookup(lacp, slave_);
414
ovs_mutex_lock(&mutex);
415
slave = slave_lookup(lacp, slave_);
345
417
slave_destroy(slave);
346
418
lacp->update = true;
420
ovs_mutex_unlock(&mutex);
350
423
/* This function should be called whenever the carrier status of 'slave_' has
351
424
* changed. If 'lacp' is null, this function has no effect.*/
353
426
lacp_slave_carrier_changed(const struct lacp *lacp, const void *slave_)
356
struct slave *slave = slave_lookup(lacp, slave_);
358
if (slave->status == LACP_CURRENT || slave->lacp->active) {
359
slave_set_expired(slave);
434
ovs_mutex_lock(&mutex);
435
slave = slave_lookup(lacp, slave_);
440
if (slave->status == LACP_CURRENT || slave->lacp->active) {
441
slave_set_expired(slave);
445
ovs_mutex_unlock(&mutex);
365
slave_may_enable__(struct slave *slave)
449
slave_may_enable__(struct slave *slave) OVS_REQ_WRLOCK(mutex)
367
451
/* The slave may be enabled if it's attached to an aggregator and its
368
452
* partner is synchronized.*/
374
458
* convenience, returns true if 'lacp' is NULL. */
376
460
lacp_slave_may_enable(const struct lacp *lacp, const void *slave_)
379
return slave_may_enable__(slave_lookup(lacp, slave_));
467
ovs_mutex_lock(&mutex);
468
slave = slave_lookup(lacp, slave_);
469
ret = slave ? slave_may_enable__(slave) : false;
470
ovs_mutex_unlock(&mutex);
385
/* Returns the port ID used for 'slave_' in LACP communications. */
387
lacp_slave_get_port_id(const struct lacp *lacp, const void *slave_)
389
struct slave *slave = slave_lookup(lacp, slave_);
390
return slave->port_id;
393
477
/* Returns true if partner information on 'slave_' is up to date. 'slave_'
394
478
* not being current, generally indicates a connectivity problem, or a
395
479
* misconfigured (or broken) partner. */
397
481
lacp_slave_is_current(const struct lacp *lacp, const void *slave_)
399
return slave_lookup(lacp, slave_)->status != LACP_DEFAULTED;
487
ovs_mutex_lock(&mutex);
488
slave = slave_lookup(lacp, slave_);
489
ret = slave ? slave->status != LACP_DEFAULTED : false;
490
ovs_mutex_unlock(&mutex);
402
494
/* This function should be called periodically to update 'lacp'. */
404
lacp_run(struct lacp *lacp, lacp_send_pdu *send_pdu)
496
lacp_run(struct lacp *lacp, lacp_send_pdu *send_pdu) OVS_EXCLUDED(mutex)
406
498
struct slave *slave;
500
ovs_mutex_lock(&mutex);
408
501
HMAP_FOR_EACH (slave, node, &lacp->slaves) {
409
502
if (timer_expired(&slave->rx)) {
410
503
if (slave->status == LACP_CURRENT) {
444
537
timer_set_duration(&slave->tx, duration);
540
ovs_mutex_unlock(&mutex);
449
543
/* Causes poll_block() to wake up when lacp_run() needs to be called again. */
451
lacp_wait(struct lacp *lacp)
545
lacp_wait(struct lacp *lacp) OVS_EXCLUDED(mutex)
453
547
struct slave *slave;
549
ovs_mutex_lock(&mutex);
455
550
HMAP_FOR_EACH (slave, node, &lacp->slaves) {
456
551
if (slave_may_tx(slave)) {
457
552
timer_wait(&slave->tx);
468
564
/* Updates the attached status of all slaves controlled by 'lacp' and sets its
469
565
* negotiated parameter to true if any slaves are attachable. */
471
lacp_update_attached(struct lacp *lacp)
567
lacp_update_attached(struct lacp *lacp) OVS_REQ_WRLOCK(mutex)
473
569
struct slave *lead, *slave;
474
570
struct lacp_info lead_pri;
640
slave_may_tx(const struct slave *slave)
738
slave_may_tx(const struct slave *slave) OVS_REQ_WRLOCK(mutex)
642
740
return slave->lacp->active || slave->status != LACP_DEFAULTED;
645
743
static struct slave *
646
slave_lookup(const struct lacp *lacp, const void *slave_)
744
slave_lookup(const struct lacp *lacp, const void *slave_) OVS_REQ_WRLOCK(mutex)
648
746
struct slave *slave;
682
780
static struct lacp *
683
lacp_find(const char *name)
781
lacp_find(const char *name) OVS_REQ_WRLOCK(&mutex)
685
783
struct lacp *lacp;
687
LIST_FOR_EACH (lacp, node, &all_lacps) {
785
LIST_FOR_EACH (lacp, node, all_lacps) {
688
786
if (!strcmp(lacp->name, name)) {
733
lacp_print_details(struct ds *ds, struct lacp *lacp)
831
lacp_print_details(struct ds *ds, struct lacp *lacp) OVS_REQ_WRLOCK(&mutex)
735
833
struct shash slave_shash = SHASH_INITIALIZER(&slave_shash);
736
834
const struct shash_node **sorted_slaves = NULL;
833
931
lacp_unixctl_show(struct unixctl_conn *conn, int argc, const char *argv[],
834
void *aux OVS_UNUSED)
932
void *aux OVS_UNUSED) OVS_EXCLUDED(mutex)
836
934
struct ds ds = DS_EMPTY_INITIALIZER;
837
935
struct lacp *lacp;
937
ovs_mutex_lock(&mutex);
840
939
lacp = lacp_find(argv[1]);
842
941
unixctl_command_reply_error(conn, "no such lacp object");
845
944
lacp_print_details(&ds, lacp);
847
LIST_FOR_EACH (lacp, node, &all_lacps) {
946
LIST_FOR_EACH (lacp, node, all_lacps) {
848
947
lacp_print_details(&ds, lacp);
852
951
unixctl_command_reply(conn, ds_cstr(&ds));
955
ovs_mutex_unlock(&mutex);