~ubuntu-branches/ubuntu/wily/openvswitch/wily

« back to all changes in this revision

Viewing changes to vswitchd/bridge.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-08-10 11:35:15 UTC
  • mfrom: (1.1.30)
  • Revision ID: package-import@ubuntu.com-20150810113515-575vj06oq29emxsn
Tags: 2.4.0~git20150810.97bab95-0ubuntu1
* New upstream snapshot from 2.4 branch:
  - d/*: Align any relevant packaging changes with upstream.
* d/*: wrap-and-sort.
* d/openvswitch-{common,vswitch}.install: Correct install location for
  bash completion files.
* d/tests/openflow.py: Explicitly use ovs-testcontroller as provided
  by 2.4.0 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
 
1
/* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
2
2
 *
3
3
 * Licensed under the Apache License, Version 2.0 (the "License");
4
4
 * you may not use this file except in compliance with the License.
18
18
#include <errno.h>
19
19
#include <inttypes.h>
20
20
#include <stdlib.h>
 
21
 
21
22
#include "async-append.h"
22
23
#include "bfd.h"
23
24
#include "bitmap.h"
26
27
#include "coverage.h"
27
28
#include "daemon.h"
28
29
#include "dirs.h"
 
30
#include "dpif.h"
29
31
#include "dynamic-string.h"
30
32
#include "hash.h"
31
33
#include "hmap.h"
33
35
#include "jsonrpc.h"
34
36
#include "lacp.h"
35
37
#include "list.h"
 
38
#include "ovs-lldp.h"
36
39
#include "mac-learning.h"
 
40
#include "mcast-snooping.h"
37
41
#include "meta-flow.h"
38
42
#include "netdev.h"
 
43
#include "nx-match.h"
39
44
#include "ofp-print.h"
40
45
#include "ofp-util.h"
41
46
#include "ofpbuf.h"
42
47
#include "ofproto/bond.h"
43
48
#include "ofproto/ofproto.h"
 
49
#include "ovs-numa.h"
44
50
#include "poll-loop.h"
45
51
#include "seq.h"
46
52
#include "sha1.h"
57
63
#include "vlandev.h"
58
64
#include "lib/vswitch-idl.h"
59
65
#include "xenserver.h"
60
 
#include "vlog.h"
 
66
#include "openvswitch/vlog.h"
61
67
#include "sflow_api.h"
62
68
#include "vlan-bitmap.h"
63
69
#include "packets.h"
71
77
     *
72
78
     * They are immutable: they never change between iface_create() and
73
79
     * iface_destroy(). */
74
 
    struct list port_elem;      /* Element in struct port's "ifaces" list. */
 
80
    struct ovs_list port_elem;  /* Element in struct port's "ifaces" list. */
75
81
    struct hmap_node name_node; /* In struct bridge's "iface_by_name" hmap. */
76
82
    struct hmap_node ofp_port_node; /* In struct bridge's "ifaces" hmap. */
77
83
    struct port *port;          /* Containing port. */
102
108
 
103
109
    /* An ordinary bridge port has 1 interface.
104
110
     * A bridge port for bonding has at least 2 interfaces. */
105
 
    struct list ifaces;         /* List of "struct iface"s. */
 
111
    struct ovs_list ifaces;    /* List of "struct iface"s. */
106
112
};
107
113
 
108
114
struct bridge {
124
130
    /* Port mirroring. */
125
131
    struct hmap mirrors;        /* "struct mirror" indexed by UUID. */
126
132
 
 
133
    /* Auto Attach */
 
134
    struct hmap mappings;       /* "struct" indexed by UUID */
 
135
 
127
136
    /* Used during reconfiguration. */
128
137
    struct shash wanted_ports;
129
138
 
133
142
    struct ovsrec_interface *synth_local_ifacep;
134
143
};
135
144
 
 
145
struct aa_mapping {
 
146
    struct hmap_node hmap_node; /* In struct bridge's "mappings" hmap. */
 
147
    struct bridge *bridge;
 
148
    uint32_t isid;
 
149
    uint16_t vlan;
 
150
    char *br_name;
 
151
};
 
152
 
136
153
/* All bridges, indexed by name. */
137
154
static struct hmap all_bridges = HMAP_INITIALIZER(&all_bridges);
138
155
 
173
190
 * we check the return status of each update transaction and do not start new
174
191
 * update if the previous transaction status is 'TXN_INCOMPLETE'.
175
192
 *
176
 
 * 'status_txn' is NULL if there is no ongoing status update.
 
193
 * 'statux_txn' is NULL if there is no ongoing status update.
177
194
 *
178
 
 * If the previous database transaction was incomplete or failed (is not
179
 
 * 'TXN_SUCCESS' or 'TXN_UNCHANGED'), 'force_status_commit' is set to true.
180
 
 * This means that 'status_txn' must be committed next iteration of bridge_run()
181
 
 * even if the connectivity or netdev sequence numbers do not change.
 
195
 * If the previous database transaction was failed (is not 'TXN_SUCCESS',
 
196
 * 'TXN_UNCHANGED' or 'TXN_INCOMPLETE'), 'status_txn_try_again' is set to true,
 
197
 * which will cause the main thread wake up soon and retry the status update.
182
198
 */
183
199
static struct ovsdb_idl_txn *status_txn;
184
 
static bool force_status_commit = true;
 
200
static bool status_txn_try_again;
185
201
 
186
202
/* When the status update transaction returns 'TXN_INCOMPLETE', should register a
187
203
 * timeout in 'STATUS_CHECK_AGAIN_MSEC' to check again. */
188
204
#define STATUS_CHECK_AGAIN_MSEC 100
189
205
 
 
206
/* Statistics update to database. */
 
207
static struct ovsdb_idl_txn *stats_txn;
 
208
 
190
209
/* Each time this timer expires, the bridge fetches interface and mirror
191
210
 * statistics and pushes them into the database. */
192
211
static int stats_timer_interval;
193
212
static long long int stats_timer = LLONG_MIN;
194
213
 
195
 
/* Current stats database transaction, NULL if there is no ongoing
196
 
 * transaction. */
197
 
static struct ovsdb_idl_txn *stats_txn;
198
 
 
199
 
/* In some datapaths, creating and destroying OpenFlow ports can be extremely
200
 
 * expensive.  This can cause bridge_reconfigure() to take a long time during
201
 
 * which no other work can be done.  To deal with this problem, we limit port
202
 
 * adds and deletions to a window of OFP_PORT_ACTION_WINDOW milliseconds per
203
 
 * call to bridge_reconfigure().  If there is more work to do after the limit
204
 
 * is reached, 'need_reconfigure', is flagged and it's done on the next loop.
205
 
 * This allows the rest of the code to catch up on important things like
206
 
 * forwarding packets. */
207
 
#define OFP_PORT_ACTION_WINDOW 10
 
214
/* Each time this timer expires, the bridge fetches the list of port/VLAN
 
215
 * membership that has been modified by the AA.
 
216
 */
 
217
#define AA_REFRESH_INTERVAL (1000) /* In milliseconds. */
 
218
static long long int aa_refresh_timer = LLONG_MIN;
208
219
 
209
220
static void add_del_bridges(const struct ovsrec_open_vswitch *);
210
221
static void bridge_run__(void);
229
240
static void bridge_configure_netflow(struct bridge *);
230
241
static void bridge_configure_forward_bpdu(struct bridge *);
231
242
static void bridge_configure_mac_table(struct bridge *);
 
243
static void bridge_configure_mcast_snooping(struct bridge *);
232
244
static void bridge_configure_sflow(struct bridge *, int *sflow_bridge_number);
233
245
static void bridge_configure_ipfix(struct bridge *);
234
 
static void bridge_configure_stp(struct bridge *);
 
246
static void bridge_configure_spanning_tree(struct bridge *);
235
247
static void bridge_configure_tables(struct bridge *);
236
248
static void bridge_configure_dp_desc(struct bridge *);
 
249
static void bridge_configure_aa(struct bridge *);
 
250
static void bridge_aa_refresh_queued(struct bridge *);
 
251
static bool bridge_aa_need_refresh(struct bridge *);
237
252
static void bridge_configure_remotes(struct bridge *,
238
253
                                     const struct sockaddr_in *managers,
239
254
                                     size_t n_managers);
285
300
                                         ofp_port_t ofp_port);
286
301
static void iface_set_mac(const struct bridge *, const struct port *, struct iface *);
287
302
static void iface_set_ofport(const struct ovsrec_interface *, ofp_port_t ofport);
288
 
static void iface_clear_db_record(const struct ovsrec_interface *if_cfg);
 
303
static void iface_clear_db_record(const struct ovsrec_interface *if_cfg, char *errp);
289
304
static void iface_configure_qos(struct iface *, const struct ovsrec_qos *);
290
305
static void iface_configure_cfm(struct iface *);
291
306
static void iface_refresh_cfm_stats(struct iface *);
297
312
    const struct ovsrec_interface *);
298
313
static ofp_port_t iface_pick_ofport(const struct ovsrec_interface *);
299
314
 
 
315
 
300
316
/* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
301
317
 *
302
318
 * This is deprecated.  It is only for compatibility with broken device drivers
315
331
                                    const unsigned long int *splinter_vlans,
316
332
                                    struct shash *ports);
317
333
 
 
334
static void discover_types(const struct ovsrec_open_vswitch *cfg);
 
335
 
318
336
static void
319
337
bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg)
320
338
{
374
392
 
375
393
    ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_cur_cfg);
376
394
    ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_statistics);
 
395
    ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_datapath_types);
 
396
    ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_iface_types);
377
397
    ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_external_ids);
378
398
    ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_ovs_version);
379
399
    ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_db_version);
381
401
    ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_system_version);
382
402
 
383
403
    ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_datapath_id);
 
404
    ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_datapath_version);
384
405
    ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_status);
 
406
    ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_rstp_status);
 
407
    ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_stp_enable);
 
408
    ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_rstp_enable);
385
409
    ovsdb_idl_omit(idl, &ovsrec_bridge_col_external_ids);
386
410
 
387
411
    ovsdb_idl_omit_alert(idl, &ovsrec_port_col_status);
 
412
    ovsdb_idl_omit_alert(idl, &ovsrec_port_col_rstp_status);
 
413
    ovsdb_idl_omit_alert(idl, &ovsrec_port_col_rstp_statistics);
388
414
    ovsdb_idl_omit_alert(idl, &ovsrec_port_col_statistics);
389
415
    ovsdb_idl_omit_alert(idl, &ovsrec_port_col_bond_active_slave);
390
416
    ovsdb_idl_omit(idl, &ovsrec_port_col_external_ids);
391
 
 
 
417
    ovsdb_idl_omit_alert(idl, &ovsrec_port_col_trunks);
 
418
    ovsdb_idl_omit_alert(idl, &ovsrec_port_col_vlan_mode);
392
419
    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_admin_state);
393
420
    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_duplex);
394
421
    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_link_speed);
408
435
    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_remote_opstate);
409
436
    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_bfd_status);
410
437
    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_lacp_current);
 
438
    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_error);
411
439
    ovsdb_idl_omit(idl, &ovsrec_interface_col_external_ids);
412
440
 
413
441
    ovsdb_idl_omit_alert(idl, &ovsrec_controller_col_is_connected);
445
473
    lacp_init();
446
474
    bond_init();
447
475
    cfm_init();
 
476
    bfd_init();
 
477
    ovs_numa_init();
448
478
    stp_init();
 
479
    lldp_init();
 
480
    rstp_init();
449
481
}
450
482
 
451
483
void
468
500
 * should not be and in fact is not directly involved in that.  But
469
501
 * ovs-vswitchd needs to make sure that ovsdb-server can reach the managers, so
470
502
 * it has to tell in-band control where the managers are to enable that.
471
 
 * (Thus, only managers connected in-band are collected.)
 
503
 * (Thus, only managers connected in-band and with non-loopback addresses
 
504
 * are collected.)
472
505
 */
473
506
static void
474
507
collect_in_band_managers(const struct ovsrec_open_vswitch *ovs_cfg,
499
532
 
500
533
        managers = xmalloc(sset_count(&targets) * sizeof *managers);
501
534
        SSET_FOR_EACH (target, &targets) {
502
 
            struct sockaddr_storage ss;
 
535
            union {
 
536
                struct sockaddr_storage ss;
 
537
                struct sockaddr_in in;
 
538
            } sa;
503
539
 
504
 
            if (stream_parse_target_with_default_port(target, OVSDB_OLD_PORT,
505
 
                                                      &ss)
506
 
                && ss.ss_family == AF_INET) {
507
 
                managers[n_managers++] = *(struct sockaddr_in *) &ss;
 
540
            /* Ignore loopback. */
 
541
            if (stream_parse_target_with_default_port(target, OVSDB_PORT,
 
542
                                                      &sa.ss)
 
543
                && sa.ss.ss_family == AF_INET
 
544
                && sa.in.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
 
545
                managers[n_managers++] = sa.in;
508
546
            }
509
547
        }
510
548
    }
529
567
                                        OFPROTO_FLOW_LIMIT_DEFAULT));
530
568
    ofproto_set_max_idle(smap_get_int(&ovs_cfg->other_config, "max-idle",
531
569
                                      OFPROTO_MAX_IDLE_DEFAULT));
 
570
    ofproto_set_n_dpdk_rxqs(smap_get_int(&ovs_cfg->other_config,
 
571
                                         "n-dpdk-rxqs", 0));
 
572
    ofproto_set_cpu_mask(smap_get(&ovs_cfg->other_config, "pmd-cpu-mask"));
532
573
 
533
574
    ofproto_set_threads(
534
575
        smap_get_int(&ovs_cfg->other_config, "n-handler-threads", 0),
581
622
                         ovs_strerror(error));
582
623
                shash_destroy(&br->wanted_ports);
583
624
                bridge_destroy(br);
 
625
            } else {
 
626
                /* Trigger storing datapath version. */
 
627
                seq_change(connectivity_seq_get());
584
628
            }
585
629
        }
586
630
    }
608
652
 
609
653
            LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
610
654
                iface_set_ofport(iface->cfg, iface->ofp_port);
 
655
                /* Clear eventual previous errors */
 
656
                ovsrec_interface_set_error(iface->cfg, NULL);
611
657
                iface_configure_cfm(iface);
612
658
                iface_configure_qos(iface, port->cfg->qos);
613
659
                iface_set_mac(br, port, iface);
614
660
                ofproto_port_set_bfd(br->ofproto, iface->ofp_port,
615
661
                                     &iface->cfg->bfd);
 
662
                ofproto_port_set_lldp(br->ofproto, iface->ofp_port,
 
663
                                      &iface->cfg->lldp);
616
664
            }
617
665
        }
618
666
        bridge_configure_mirrors(br);
619
667
        bridge_configure_forward_bpdu(br);
620
668
        bridge_configure_mac_table(br);
 
669
        bridge_configure_mcast_snooping(br);
621
670
        bridge_configure_remotes(br, managers, n_managers);
622
671
        bridge_configure_netflow(br);
623
672
        bridge_configure_sflow(br, &sflow_bridge_number);
624
673
        bridge_configure_ipfix(br);
625
 
        bridge_configure_stp(br);
 
674
        bridge_configure_spanning_tree(br);
626
675
        bridge_configure_tables(br);
627
676
        bridge_configure_dp_desc(br);
 
677
        bridge_configure_aa(br);
628
678
    }
629
679
    free(managers);
630
680
 
723
773
        }
724
774
 
725
775
        if (strcmp(ofproto_port.type, iface->type)
726
 
            || netdev_set_config(iface->netdev, &iface->cfg->options)) {
 
776
            || netdev_set_config(iface->netdev, &iface->cfg->options, NULL)) {
727
777
            /* The interface is the wrong type or can't be configured.
728
778
             * Delete it. */
729
779
            goto delete;
1161
1211
        if (be_cfg->cache_max_flows) {
1162
1212
            be_opts.cache_max_flows = *be_cfg->cache_max_flows;
1163
1213
        }
 
1214
 
 
1215
        be_opts.enable_tunnel_sampling = smap_get_bool(&be_cfg->other_config,
 
1216
                                             "enable-tunnel-sampling", true);
 
1217
 
 
1218
        be_opts.enable_input_sampling = !smap_get_bool(&be_cfg->other_config,
 
1219
                                              "enable-input-sampling", false);
 
1220
 
 
1221
        be_opts.enable_output_sampling = !smap_get_bool(&be_cfg->other_config,
 
1222
                                              "enable-output-sampling", false);
1164
1223
    }
1165
1224
 
1166
1225
    if (n_fe_opts > 0) {
1289
1348
    }
1290
1349
}
1291
1350
 
 
1351
static void
 
1352
port_configure_rstp(const struct ofproto *ofproto, struct port *port,
 
1353
        struct ofproto_port_rstp_settings *port_s, int *port_num_counter)
 
1354
{
 
1355
    const char *config_str;
 
1356
    struct iface *iface;
 
1357
 
 
1358
    if (!smap_get_bool(&port->cfg->other_config, "rstp-enable", true)) {
 
1359
        port_s->enable = false;
 
1360
        return;
 
1361
    } else {
 
1362
        port_s->enable = true;
 
1363
    }
 
1364
 
 
1365
    /* RSTP over bonds is not supported. */
 
1366
    if (!list_is_singleton(&port->ifaces)) {
 
1367
        VLOG_ERR("port %s: cannot enable RSTP on bonds, disabling",
 
1368
                port->name);
 
1369
        port_s->enable = false;
 
1370
        return;
 
1371
    }
 
1372
 
 
1373
    iface = CONTAINER_OF(list_front(&port->ifaces), struct iface, port_elem);
 
1374
 
 
1375
    /* Internal ports shouldn't participate in spanning tree, so
 
1376
     * skip them. */
 
1377
    if (!strcmp(iface->type, "internal")) {
 
1378
        VLOG_DBG("port %s: disable RSTP on internal ports", port->name);
 
1379
        port_s->enable = false;
 
1380
        return;
 
1381
    }
 
1382
 
 
1383
    /* RSTP on mirror output ports is not supported. */
 
1384
    if (ofproto_is_mirror_output_bundle(ofproto, port)) {
 
1385
        VLOG_DBG("port %s: disable RSTP on mirror ports", port->name);
 
1386
        port_s->enable = false;
 
1387
        return;
 
1388
    }
 
1389
 
 
1390
    config_str = smap_get(&port->cfg->other_config, "rstp-port-num");
 
1391
    if (config_str) {
 
1392
        unsigned long int port_num = strtoul(config_str, NULL, 0);
 
1393
        if (port_num < 1 || port_num > RSTP_MAX_PORTS) {
 
1394
            VLOG_ERR("port %s: invalid rstp-port-num", port->name);
 
1395
            port_s->enable = false;
 
1396
            return;
 
1397
        }
 
1398
        port_s->port_num = port_num;
 
1399
    } else {
 
1400
        if (*port_num_counter >= RSTP_MAX_PORTS) {
 
1401
            VLOG_ERR("port %s: too many RSTP ports, disabling", port->name);
 
1402
            port_s->enable = false;
 
1403
            return;
 
1404
        }
 
1405
        /* If rstp-port-num is not specified, use 0.
 
1406
         * rstp_port_set_port_number() will look for the first free one. */
 
1407
        port_s->port_num = 0;
 
1408
    }
 
1409
 
 
1410
    config_str = smap_get(&port->cfg->other_config, "rstp-path-cost");
 
1411
    if (config_str) {
 
1412
        port_s->path_cost = strtoul(config_str, NULL, 10);
 
1413
    } else {
 
1414
        enum netdev_features current;
 
1415
        unsigned int mbps;
 
1416
 
 
1417
        netdev_get_features(iface->netdev, &current, NULL, NULL, NULL);
 
1418
        mbps = netdev_features_to_bps(current, 100 * 1000 * 1000) / 1000000;
 
1419
        port_s->path_cost = rstp_convert_speed_to_cost(mbps);
 
1420
    }
 
1421
 
 
1422
    config_str = smap_get(&port->cfg->other_config, "rstp-port-priority");
 
1423
    if (config_str) {
 
1424
        port_s->priority = strtoul(config_str, NULL, 0);
 
1425
    } else {
 
1426
        port_s->priority = RSTP_DEFAULT_PORT_PRIORITY;
 
1427
    }
 
1428
 
 
1429
    config_str = smap_get(&port->cfg->other_config, "rstp-admin-p2p-mac");
 
1430
    if (config_str) {
 
1431
        port_s->admin_p2p_mac_state = strtoul(config_str, NULL, 0);
 
1432
    } else {
 
1433
        port_s->admin_p2p_mac_state = RSTP_ADMIN_P2P_MAC_FORCE_TRUE;
 
1434
    }
 
1435
 
 
1436
    port_s->admin_port_state = smap_get_bool(&port->cfg->other_config,
 
1437
                                             "rstp-admin-port-state", true);
 
1438
 
 
1439
    port_s->admin_edge_port = smap_get_bool(&port->cfg->other_config,
 
1440
                                            "rstp-port-admin-edge", false);
 
1441
    port_s->auto_edge = smap_get_bool(&port->cfg->other_config,
 
1442
                                      "rstp-port-auto-edge", true);
 
1443
    port_s->mcheck = smap_get_bool(&port->cfg->other_config,
 
1444
                                   "rstp-port-mcheck", false);
 
1445
}
 
1446
 
1292
1447
/* Set spanning tree configuration on 'br'. */
1293
1448
static void
1294
 
bridge_configure_stp(struct bridge *br)
 
1449
bridge_configure_stp(struct bridge *br, bool enable_stp)
1295
1450
{
1296
 
    if (!br->cfg->stp_enable) {
 
1451
    if (!enable_stp) {
1297
1452
        ofproto_set_stp(br->ofproto, NULL);
1298
1453
    } else {
1299
1454
        struct ofproto_stp_settings br_s;
1384
1539
    }
1385
1540
}
1386
1541
 
 
1542
static void
 
1543
bridge_configure_rstp(struct bridge *br, bool enable_rstp)
 
1544
{
 
1545
    if (!enable_rstp) {
 
1546
        ofproto_set_rstp(br->ofproto, NULL);
 
1547
    } else {
 
1548
        struct ofproto_rstp_settings br_s;
 
1549
        const char *config_str;
 
1550
        struct port *port;
 
1551
        int port_num_counter;
 
1552
 
 
1553
        config_str = smap_get(&br->cfg->other_config, "rstp-address");
 
1554
        if (config_str) {
 
1555
            uint8_t ea[ETH_ADDR_LEN];
 
1556
 
 
1557
            if (eth_addr_from_string(config_str, ea)) {
 
1558
                br_s.address = eth_addr_to_uint64(ea);
 
1559
            }
 
1560
            else {
 
1561
                br_s.address = eth_addr_to_uint64(br->ea);
 
1562
                VLOG_ERR("bridge %s: invalid rstp-address, defaulting "
 
1563
                        "to "ETH_ADDR_FMT, br->name, ETH_ADDR_ARGS(br->ea));
 
1564
            }
 
1565
        }
 
1566
        else {
 
1567
            br_s.address = eth_addr_to_uint64(br->ea);
 
1568
        }
 
1569
 
 
1570
        config_str = smap_get(&br->cfg->other_config, "rstp-priority");
 
1571
        if (config_str) {
 
1572
            br_s.priority = strtoul(config_str, NULL, 0);
 
1573
        } else {
 
1574
            br_s.priority = RSTP_DEFAULT_PRIORITY;
 
1575
        }
 
1576
 
 
1577
        config_str = smap_get(&br->cfg->other_config, "rstp-ageing-time");
 
1578
        if (config_str) {
 
1579
            br_s.ageing_time = strtoul(config_str, NULL, 0);
 
1580
        } else {
 
1581
            br_s.ageing_time = RSTP_DEFAULT_AGEING_TIME;
 
1582
        }
 
1583
 
 
1584
        config_str = smap_get(&br->cfg->other_config,
 
1585
                              "rstp-force-protocol-version");
 
1586
        if (config_str) {
 
1587
            br_s.force_protocol_version = strtoul(config_str, NULL, 0);
 
1588
        } else {
 
1589
            br_s.force_protocol_version = FPV_DEFAULT;
 
1590
        }
 
1591
 
 
1592
        config_str = smap_get(&br->cfg->other_config, "rstp-max-age");
 
1593
        if (config_str) {
 
1594
            br_s.bridge_max_age = strtoul(config_str, NULL, 10);
 
1595
        } else {
 
1596
            br_s.bridge_max_age = RSTP_DEFAULT_BRIDGE_MAX_AGE;
 
1597
        }
 
1598
 
 
1599
        config_str = smap_get(&br->cfg->other_config, "rstp-forward-delay");
 
1600
        if (config_str) {
 
1601
            br_s.bridge_forward_delay = strtoul(config_str, NULL, 10);
 
1602
        } else {
 
1603
            br_s.bridge_forward_delay = RSTP_DEFAULT_BRIDGE_FORWARD_DELAY;
 
1604
        }
 
1605
 
 
1606
        config_str = smap_get(&br->cfg->other_config,
 
1607
                              "rstp-transmit-hold-count");
 
1608
        if (config_str) {
 
1609
            br_s.transmit_hold_count = strtoul(config_str, NULL, 10);
 
1610
        } else {
 
1611
            br_s.transmit_hold_count = RSTP_DEFAULT_TRANSMIT_HOLD_COUNT;
 
1612
        }
 
1613
 
 
1614
        /* Configure RSTP on the bridge. */
 
1615
        if (ofproto_set_rstp(br->ofproto, &br_s)) {
 
1616
            VLOG_ERR("bridge %s: could not enable RSTP", br->name);
 
1617
            return;
 
1618
        }
 
1619
 
 
1620
        port_num_counter = 0;
 
1621
        HMAP_FOR_EACH (port, hmap_node, &br->ports) {
 
1622
            struct ofproto_port_rstp_settings port_s;
 
1623
            struct iface *iface;
 
1624
 
 
1625
            port_configure_rstp(br->ofproto, port, &port_s,
 
1626
                    &port_num_counter);
 
1627
 
 
1628
            /* As bonds are not supported, just apply configuration to
 
1629
             * all interfaces. */
 
1630
            LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
 
1631
                if (ofproto_port_set_rstp(br->ofproto, iface->ofp_port,
 
1632
                            &port_s)) {
 
1633
                    VLOG_ERR("port %s: could not enable RSTP", port->name);
 
1634
                    continue;
 
1635
                }
 
1636
            }
 
1637
        }
 
1638
    }
 
1639
}
 
1640
 
 
1641
static void
 
1642
bridge_configure_spanning_tree(struct bridge *br)
 
1643
{
 
1644
    bool enable_rstp = br->cfg->rstp_enable;
 
1645
    bool enable_stp = br->cfg->stp_enable;
 
1646
 
 
1647
    if (enable_rstp && enable_stp) {
 
1648
        VLOG_WARN("%s: RSTP and STP are mutually exclusive but both are "
 
1649
                  "configured; enabling RSTP", br->name);
 
1650
        enable_stp = false;
 
1651
    }
 
1652
 
 
1653
    bridge_configure_stp(br, enable_stp);
 
1654
    bridge_configure_rstp(br, enable_rstp);
 
1655
}
 
1656
 
1387
1657
static bool
1388
1658
bridge_has_bond_fake_iface(const struct bridge *br, const char *name)
1389
1659
{
1446
1716
 * Returns 0 if successful, otherwise a positive errno value. */
1447
1717
static int
1448
1718
iface_set_netdev_config(const struct ovsrec_interface *iface_cfg,
1449
 
                        struct netdev *netdev)
 
1719
                        struct netdev *netdev, char **errp)
1450
1720
{
1451
 
    return netdev_set_config(netdev, &iface_cfg->options);
 
1721
    return netdev_set_config(netdev, &iface_cfg->options, errp);
1452
1722
}
1453
1723
 
1454
1724
/* Opens a network device for 'if_cfg' and configures it.  Adds the network
1460
1730
iface_do_create(const struct bridge *br,
1461
1731
                const struct ovsrec_interface *iface_cfg,
1462
1732
                const struct ovsrec_port *port_cfg,
1463
 
                ofp_port_t *ofp_portp, struct netdev **netdevp)
 
1733
                ofp_port_t *ofp_portp, struct netdev **netdevp,
 
1734
                char **errp)
1464
1735
{
1465
1736
    struct netdev *netdev = NULL;
1466
1737
    int error;
1475
1746
    error = netdev_open(iface_cfg->name,
1476
1747
                        iface_get_type(iface_cfg, br->cfg), &netdev);
1477
1748
    if (error) {
1478
 
        VLOG_WARN("could not open network device %s (%s)",
1479
 
                  iface_cfg->name, ovs_strerror(error));
 
1749
        VLOG_WARN_BUF(errp, "could not open network device %s (%s)",
 
1750
                      iface_cfg->name, ovs_strerror(error));
1480
1751
        goto error;
1481
1752
    }
1482
1753
 
1483
 
    error = iface_set_netdev_config(iface_cfg, netdev);
 
1754
    error = iface_set_netdev_config(iface_cfg, netdev, errp);
1484
1755
    if (error) {
1485
1756
        goto error;
1486
1757
    }
1521
1792
    struct iface *iface;
1522
1793
    ofp_port_t ofp_port;
1523
1794
    struct port *port;
 
1795
    char *errp = NULL;
1524
1796
    int error;
1525
1797
 
1526
1798
    /* Do the bits that can fail up front. */
1527
1799
    ovs_assert(!iface_lookup(br, iface_cfg->name));
1528
 
    error = iface_do_create(br, iface_cfg, port_cfg, &ofp_port, &netdev);
 
1800
    error = iface_do_create(br, iface_cfg, port_cfg, &ofp_port, &netdev, &errp);
1529
1801
    if (error) {
1530
 
        iface_clear_db_record(iface_cfg);
 
1802
        iface_clear_db_record(iface_cfg, errp);
 
1803
        free(errp);
1531
1804
        return false;
1532
1805
    }
1533
1806
 
1553
1826
 
1554
1827
    /* Populate initial status in database. */
1555
1828
    iface_refresh_stats(iface);
 
1829
    iface_refresh_netdev_status(iface);
1556
1830
 
1557
1831
    /* Add bond fake iface if necessary. */
1558
1832
    if (port_is_bond_fake_iface(port)) {
1614
1888
    ofproto_set_mac_table_config(br->ofproto, idle_time, mac_table_size);
1615
1889
}
1616
1890
 
 
1891
/* Set multicast snooping table configuration for 'br'. */
 
1892
static void
 
1893
bridge_configure_mcast_snooping(struct bridge *br)
 
1894
{
 
1895
    if (!br->cfg->mcast_snooping_enable) {
 
1896
        ofproto_set_mcast_snooping(br->ofproto, NULL);
 
1897
    } else {
 
1898
        struct port *port;
 
1899
        struct ofproto_mcast_snooping_settings br_s;
 
1900
        const char *idle_time_str;
 
1901
        const char *max_entries_str;
 
1902
 
 
1903
        idle_time_str = smap_get(&br->cfg->other_config,
 
1904
                                 "mcast-snooping-aging-time");
 
1905
        br_s.idle_time = (idle_time_str && atoi(idle_time_str)
 
1906
                          ? atoi(idle_time_str)
 
1907
                          : MCAST_ENTRY_DEFAULT_IDLE_TIME);
 
1908
 
 
1909
        max_entries_str = smap_get(&br->cfg->other_config,
 
1910
                                   "mcast-snooping-table-size");
 
1911
        br_s.max_entries = (max_entries_str && atoi(max_entries_str)
 
1912
                            ? atoi(max_entries_str)
 
1913
                            : MCAST_DEFAULT_MAX_ENTRIES);
 
1914
 
 
1915
        br_s.flood_unreg = !smap_get_bool(&br->cfg->other_config,
 
1916
                                    "mcast-snooping-disable-flood-unregistered",
 
1917
                                    false);
 
1918
 
 
1919
        /* Configure multicast snooping on the bridge */
 
1920
        if (ofproto_set_mcast_snooping(br->ofproto, &br_s)) {
 
1921
            VLOG_ERR("bridge %s: could not enable multicast snooping",
 
1922
                     br->name);
 
1923
            return;
 
1924
        }
 
1925
 
 
1926
        HMAP_FOR_EACH (port, hmap_node, &br->ports) {
 
1927
            struct ofproto_mcast_snooping_port_settings port_s;
 
1928
            port_s.flood = smap_get_bool(&port->cfg->other_config,
 
1929
                                       "mcast-snooping-flood", false);
 
1930
            port_s.flood_reports = smap_get_bool(&port->cfg->other_config,
 
1931
                                       "mcast-snooping-flood-reports", false);
 
1932
            if (ofproto_port_set_mcast_snooping(br->ofproto, port, &port_s)) {
 
1933
                VLOG_ERR("port %s: could not configure mcast snooping",
 
1934
                         port->name);
 
1935
            }
 
1936
        }
 
1937
    }
 
1938
}
 
1939
 
1617
1940
static void
1618
1941
find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
1619
1942
                   const struct port *fake_br, struct iface **hw_addr_iface)
1826
2149
    }
1827
2150
 
1828
2151
    if (iface->change_seq == netdev_get_change_seq(iface->netdev)
1829
 
        && !force_status_commit) {
 
2152
        && !status_txn_try_again) {
1830
2153
        return;
1831
2154
    }
1832
2155
 
1899
2222
static void
1900
2223
iface_refresh_ofproto_status(struct iface *iface)
1901
2224
{
1902
 
    struct smap smap;
1903
 
    int current, error;
 
2225
    int current;
1904
2226
 
1905
2227
    if (iface_is_synthetic(iface)) {
1906
2228
        return;
1915
2237
        ovsrec_interface_set_lacp_current(iface->cfg, NULL, 0);
1916
2238
    }
1917
2239
 
1918
 
    iface_refresh_cfm_stats(iface);
1919
 
 
1920
 
    smap_init(&smap);
1921
 
    error = ofproto_port_get_bfd_status(iface->port->bridge->ofproto,
1922
 
                                        iface->ofp_port, force_status_commit,
1923
 
                                        &smap);
1924
 
    if (error >= 0) {
 
2240
    if (ofproto_port_cfm_status_changed(iface->port->bridge->ofproto,
 
2241
                                        iface->ofp_port)
 
2242
        || status_txn_try_again) {
 
2243
        iface_refresh_cfm_stats(iface);
 
2244
    }
 
2245
 
 
2246
    if (ofproto_port_bfd_status_changed(iface->port->bridge->ofproto,
 
2247
                                        iface->ofp_port)
 
2248
        || status_txn_try_again) {
 
2249
        struct smap smap;
 
2250
 
 
2251
        smap_init(&smap);
 
2252
        ofproto_port_get_bfd_status(iface->port->bridge->ofproto,
 
2253
                                    iface->ofp_port, &smap);
1925
2254
        ovsrec_interface_set_bfd_status(iface->cfg, &smap);
 
2255
        smap_destroy(&smap);
1926
2256
    }
1927
 
    smap_destroy(&smap);
1928
2257
}
1929
2258
 
1930
2259
/* Writes 'iface''s CFM statistics to the database. 'iface' must not be
1933
2262
iface_refresh_cfm_stats(struct iface *iface)
1934
2263
{
1935
2264
    const struct ovsrec_interface *cfg = iface->cfg;
1936
 
    struct ofproto_cfm_status status;
 
2265
    struct cfm_status status;
1937
2266
    int error;
1938
2267
 
1939
2268
    error = ofproto_port_get_cfm_status(iface->port->bridge->ofproto,
1940
 
                                        iface->ofp_port, force_status_commit,
1941
 
                                        &status);
1942
 
    if (error < 0) {
1943
 
        /* Do nothing if there is no status change since last update. */
1944
 
    } else if (error > 0) {
 
2269
                                        iface->ofp_port, &status);
 
2270
    if (error > 0) {
1945
2271
        ovsrec_interface_set_cfm_fault(cfg, NULL, 0);
1946
2272
        ovsrec_interface_set_cfm_fault_status(cfg, NULL, 0);
1947
2273
        ovsrec_interface_set_cfm_remote_opstate(cfg, NULL);
1964
2290
                reasons[j++] = cfm_fault_reason_to_str(reason);
1965
2291
            }
1966
2292
        }
1967
 
        ovsrec_interface_set_cfm_fault_status(cfg, (char **) reasons, j);
 
2293
        ovsrec_interface_set_cfm_fault_status(cfg, reasons, j);
1968
2294
 
1969
2295
        ovsrec_interface_set_cfm_flap_count(cfg, &cfm_flap_count, 1);
1970
2296
 
2009
2335
    enum { N_IFACE_STATS = IFACE_STATS };
2010
2336
#undef IFACE_STAT
2011
2337
    int64_t values[N_IFACE_STATS];
2012
 
    char *keys[N_IFACE_STATS];
 
2338
    const char *keys[N_IFACE_STATS];
2013
2339
    int n;
2014
2340
 
2015
2341
    struct netdev_stats stats;
2039
2365
}
2040
2366
 
2041
2367
static void
 
2368
br_refresh_datapath_info(struct bridge *br)
 
2369
{
 
2370
    const char *version;
 
2371
 
 
2372
    version = (br->ofproto && br->ofproto->ofproto_class->get_datapath_version
 
2373
               ? br->ofproto->ofproto_class->get_datapath_version(br->ofproto)
 
2374
               : NULL);
 
2375
 
 
2376
    ovsrec_bridge_set_datapath_version(br->cfg,
 
2377
                                       version ? version : "<unknown>");
 
2378
}
 
2379
 
 
2380
static void
2042
2381
br_refresh_stp_status(struct bridge *br)
2043
2382
{
2044
2383
    struct smap smap = SMAP_INITIALIZER(&smap);
2108
2447
    struct ofproto *ofproto = port->bridge->ofproto;
2109
2448
    struct iface *iface;
2110
2449
    struct ofproto_port_stp_stats stats;
2111
 
    char *keys[3];
 
2450
    const char *keys[3];
2112
2451
    int64_t int_values[3];
2113
2452
 
2114
2453
    if (port_is_synthetic(port)) {
2143
2482
}
2144
2483
 
2145
2484
static void
 
2485
br_refresh_rstp_status(struct bridge *br)
 
2486
{
 
2487
    struct smap smap = SMAP_INITIALIZER(&smap);
 
2488
    struct ofproto *ofproto = br->ofproto;
 
2489
    struct ofproto_rstp_status status;
 
2490
 
 
2491
    if (ofproto_get_rstp_status(ofproto, &status)) {
 
2492
        return;
 
2493
    }
 
2494
    if (!status.enabled) {
 
2495
        ovsrec_bridge_set_rstp_status(br->cfg, NULL);
 
2496
        return;
 
2497
    }
 
2498
    smap_add_format(&smap, "rstp_bridge_id", RSTP_ID_FMT,
 
2499
                    RSTP_ID_ARGS(status.bridge_id));
 
2500
    smap_add_format(&smap, "rstp_root_path_cost", "%"PRIu32,
 
2501
                    status.root_path_cost);
 
2502
    smap_add_format(&smap, "rstp_root_id", RSTP_ID_FMT,
 
2503
                    RSTP_ID_ARGS(status.root_id));
 
2504
    smap_add_format(&smap, "rstp_designated_id", RSTP_ID_FMT,
 
2505
                    RSTP_ID_ARGS(status.designated_id));
 
2506
    smap_add_format(&smap, "rstp_designated_port_id", RSTP_PORT_ID_FMT,
 
2507
                    status.designated_port_id);
 
2508
    smap_add_format(&smap, "rstp_bridge_port_id", RSTP_PORT_ID_FMT,
 
2509
                    status.bridge_port_id);
 
2510
    ovsrec_bridge_set_rstp_status(br->cfg, &smap);
 
2511
    smap_destroy(&smap);
 
2512
}
 
2513
 
 
2514
static void
 
2515
port_refresh_rstp_status(struct port *port)
 
2516
{
 
2517
    struct ofproto *ofproto = port->bridge->ofproto;
 
2518
    struct iface *iface;
 
2519
    struct ofproto_port_rstp_status status;
 
2520
    const char *keys[4];
 
2521
    int64_t int_values[4];
 
2522
    struct smap smap;
 
2523
 
 
2524
    if (port_is_synthetic(port)) {
 
2525
        return;
 
2526
    }
 
2527
 
 
2528
    /* RSTP doesn't currently support bonds. */
 
2529
    if (!list_is_singleton(&port->ifaces)) {
 
2530
        ovsrec_port_set_rstp_status(port->cfg, NULL);
 
2531
        return;
 
2532
    }
 
2533
 
 
2534
    iface = CONTAINER_OF(list_front(&port->ifaces), struct iface, port_elem);
 
2535
    if (ofproto_port_get_rstp_status(ofproto, iface->ofp_port, &status)) {
 
2536
        return;
 
2537
    }
 
2538
 
 
2539
    if (!status.enabled) {
 
2540
        ovsrec_port_set_rstp_status(port->cfg, NULL);
 
2541
        ovsrec_port_set_rstp_statistics(port->cfg, NULL, NULL, 0);
 
2542
        return;
 
2543
    }
 
2544
    /* Set Status column. */
 
2545
    smap_init(&smap);
 
2546
 
 
2547
    smap_add_format(&smap, "rstp_port_id", RSTP_PORT_ID_FMT,
 
2548
                    status.port_id);
 
2549
    smap_add_format(&smap, "rstp_port_role", "%s",
 
2550
                    rstp_port_role_name(status.role));
 
2551
    smap_add_format(&smap, "rstp_port_state", "%s",
 
2552
                    rstp_state_name(status.state));
 
2553
    smap_add_format(&smap, "rstp_designated_bridge_id", RSTP_ID_FMT,
 
2554
                    RSTP_ID_ARGS(status.designated_bridge_id));
 
2555
    smap_add_format(&smap, "rstp_designated_port_id", RSTP_PORT_ID_FMT,
 
2556
                    status.designated_port_id);
 
2557
    smap_add_format(&smap, "rstp_designated_path_cost", "%"PRIu32,
 
2558
                    status.designated_path_cost);
 
2559
 
 
2560
    ovsrec_port_set_rstp_status(port->cfg, &smap);
 
2561
    smap_destroy(&smap);
 
2562
 
 
2563
    /* Set Statistics column. */
 
2564
    keys[0] = "rstp_tx_count";
 
2565
    int_values[0] = status.tx_count;
 
2566
    keys[1] = "rstp_rx_count";
 
2567
    int_values[1] = status.rx_count;
 
2568
    keys[2] = "rstp_uptime";
 
2569
    int_values[2] = status.uptime;
 
2570
    keys[3] = "rstp_error_count";
 
2571
    int_values[3] = status.error_count;
 
2572
    ovsrec_port_set_rstp_statistics(port->cfg, keys, int_values,
 
2573
            ARRAY_SIZE(int_values));
 
2574
}
 
2575
 
 
2576
static void
2146
2577
port_refresh_bond_status(struct port *port, bool force_update)
2147
2578
{
2148
 
    uint8_t mac[6];
 
2579
    uint8_t mac[ETH_ADDR_LEN];
2149
2580
 
2150
2581
    /* Return if port is not a bond */
2151
2582
    if (list_is_singleton(&port->ifaces)) {
2237
2668
            shash_find_data(&info, cfg->target);
2238
2669
 
2239
2670
        if (cinfo) {
2240
 
            struct smap smap = SMAP_INITIALIZER(&smap);
2241
 
            const char **values = cinfo->pairs.values;
2242
 
            const char **keys = cinfo->pairs.keys;
2243
 
            size_t i;
2244
 
 
2245
 
            for (i = 0; i < cinfo->pairs.n; i++) {
2246
 
                smap_add(&smap, keys[i], values[i]);
2247
 
            }
2248
 
 
2249
2671
            ovsrec_controller_set_is_connected(cfg, cinfo->is_connected);
2250
2672
            ovsrec_controller_set_role(cfg, ofp12_controller_role_to_str(
2251
2673
                                           cinfo->role));
2252
 
            ovsrec_controller_set_status(cfg, &smap);
2253
 
            smap_destroy(&smap);
 
2674
            ovsrec_controller_set_status(cfg, &cinfo->pairs);
2254
2675
        } else {
2255
2676
            ovsrec_controller_set_is_connected(cfg, false);
2256
2677
            ovsrec_controller_set_role(cfg, NULL);
2260
2681
 
2261
2682
    ofproto_free_ofproto_controller_info(&info);
2262
2683
}
 
2684
 
 
2685
/* Update interface and mirror statistics if necessary. */
 
2686
static void
 
2687
run_stats_update(void)
 
2688
{
 
2689
    const struct ovsrec_open_vswitch *cfg = ovsrec_open_vswitch_first(idl);
 
2690
    int stats_interval;
 
2691
 
 
2692
    if (!cfg) {
 
2693
        return;
 
2694
    }
 
2695
 
 
2696
    /* Statistics update interval should always be greater than or equal to
 
2697
     * 5000 ms. */
 
2698
    stats_interval = MAX(smap_get_int(&cfg->other_config,
 
2699
                                      "stats-update-interval",
 
2700
                                      5000), 5000);
 
2701
    if (stats_timer_interval != stats_interval) {
 
2702
        stats_timer_interval = stats_interval;
 
2703
        stats_timer = LLONG_MIN;
 
2704
    }
 
2705
 
 
2706
    if (time_msec() >= stats_timer) {
 
2707
        enum ovsdb_idl_txn_status status;
 
2708
 
 
2709
        /* Rate limit the update.  Do not start a new update if the
 
2710
         * previous one is not done. */
 
2711
        if (!stats_txn) {
 
2712
            struct bridge *br;
 
2713
 
 
2714
            stats_txn = ovsdb_idl_txn_create(idl);
 
2715
            HMAP_FOR_EACH (br, node, &all_bridges) {
 
2716
                struct port *port;
 
2717
                struct mirror *m;
 
2718
 
 
2719
                HMAP_FOR_EACH (port, hmap_node, &br->ports) {
 
2720
                    struct iface *iface;
 
2721
 
 
2722
                    LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
 
2723
                        iface_refresh_stats(iface);
 
2724
                    }
 
2725
                    port_refresh_stp_stats(port);
 
2726
                }
 
2727
                HMAP_FOR_EACH (m, hmap_node, &br->mirrors) {
 
2728
                    mirror_refresh_stats(m);
 
2729
                }
 
2730
            }
 
2731
            refresh_controller_status();
 
2732
        }
 
2733
 
 
2734
        status = ovsdb_idl_txn_commit(stats_txn);
 
2735
        if (status != TXN_INCOMPLETE) {
 
2736
            stats_timer = time_msec() + stats_timer_interval;
 
2737
            ovsdb_idl_txn_destroy(stats_txn);
 
2738
            stats_txn = NULL;
 
2739
        }
 
2740
    }
 
2741
}
 
2742
 
 
2743
static void
 
2744
stats_update_wait(void)
 
2745
{
 
2746
    /* If the 'stats_txn' is non-null (transaction incomplete), waits for the
 
2747
     * transaction to complete.  Otherwise, waits for the 'stats_timer'. */
 
2748
    if (stats_txn) {
 
2749
        ovsdb_idl_txn_wait(stats_txn);
 
2750
    } else {
 
2751
        poll_timer_wait_until(stats_timer);
 
2752
    }
 
2753
}
 
2754
 
 
2755
/* Update bridge/port/interface status if necessary. */
 
2756
static void
 
2757
run_status_update(void)
 
2758
{
 
2759
    if (!status_txn) {
 
2760
        uint64_t seq;
 
2761
 
 
2762
        /* Rate limit the update.  Do not start a new update if the
 
2763
         * previous one is not done. */
 
2764
        seq = seq_read(connectivity_seq_get());
 
2765
        if (seq != connectivity_seqno || status_txn_try_again) {
 
2766
            struct bridge *br;
 
2767
 
 
2768
            connectivity_seqno = seq;
 
2769
            status_txn = ovsdb_idl_txn_create(idl);
 
2770
            HMAP_FOR_EACH (br, node, &all_bridges) {
 
2771
                struct port *port;
 
2772
 
 
2773
                br_refresh_stp_status(br);
 
2774
                br_refresh_rstp_status(br);
 
2775
                br_refresh_datapath_info(br);
 
2776
                HMAP_FOR_EACH (port, hmap_node, &br->ports) {
 
2777
                    struct iface *iface;
 
2778
 
 
2779
                    port_refresh_stp_status(port);
 
2780
                    port_refresh_rstp_status(port);
 
2781
                    port_refresh_bond_status(port, status_txn_try_again);
 
2782
                    LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
 
2783
                        iface_refresh_netdev_status(iface);
 
2784
                        iface_refresh_ofproto_status(iface);
 
2785
                    }
 
2786
                }
 
2787
            }
 
2788
        }
 
2789
    }
 
2790
 
 
2791
    /* Commit the transaction and get the status. If the transaction finishes,
 
2792
     * then destroy the transaction. Otherwise, keep it so that we can check
 
2793
     * progress the next time that this function is called. */
 
2794
    if (status_txn) {
 
2795
        enum ovsdb_idl_txn_status status;
 
2796
 
 
2797
        status = ovsdb_idl_txn_commit(status_txn);
 
2798
        if (status != TXN_INCOMPLETE) {
 
2799
            ovsdb_idl_txn_destroy(status_txn);
 
2800
            status_txn = NULL;
 
2801
 
 
2802
            /* Sets the 'status_txn_try_again' if the transaction fails. */
 
2803
            if (status == TXN_SUCCESS || status == TXN_UNCHANGED) {
 
2804
                status_txn_try_again = false;
 
2805
            } else {
 
2806
                status_txn_try_again = true;
 
2807
            }
 
2808
        }
 
2809
    }
 
2810
 
 
2811
    /* Refresh AA port status if necessary. */
 
2812
    if (time_msec() >= aa_refresh_timer) {
 
2813
        struct bridge *br;
 
2814
 
 
2815
        HMAP_FOR_EACH (br, node, &all_bridges) {
 
2816
            if (bridge_aa_need_refresh(br)) {
 
2817
                struct ovsdb_idl_txn *txn;
 
2818
 
 
2819
                txn = ovsdb_idl_txn_create(idl);
 
2820
                bridge_aa_refresh_queued(br);
 
2821
                ovsdb_idl_txn_commit(txn);
 
2822
                ovsdb_idl_txn_destroy(txn);
 
2823
            }
 
2824
        }
 
2825
 
 
2826
        aa_refresh_timer = time_msec() + AA_REFRESH_INTERVAL;
 
2827
    }
 
2828
}
 
2829
 
 
2830
static void
 
2831
status_update_wait(void)
 
2832
{
 
2833
    /* If the 'status_txn' is non-null (transaction incomplete), waits for the
 
2834
     * transaction to complete.  If the status update to database needs to be
 
2835
     * run again (transaction fails), registers a timeout in
 
2836
     * 'STATUS_CHECK_AGAIN_MSEC'.  Otherwise, waits on the global connectivity
 
2837
     * sequence number. */
 
2838
    if (status_txn) {
 
2839
        ovsdb_idl_txn_wait(status_txn);
 
2840
    } else if (status_txn_try_again) {
 
2841
        poll_timer_wait_until(time_msec() + STATUS_CHECK_AGAIN_MSEC);
 
2842
    } else {
 
2843
        seq_wait(connectivity_seq_get(), connectivity_seqno);
 
2844
    }
 
2845
}
2263
2846
 
2264
2847
static void
2265
2848
bridge_run__(void)
2289
2872
    const struct ovsrec_open_vswitch *cfg;
2290
2873
 
2291
2874
    bool vlan_splinters_changed;
2292
 
    struct bridge *br;
2293
 
    int stats_interval;
2294
2875
 
2295
2876
    ovsrec_open_vswitch_init(&null_cfg);
2296
2877
 
2312
2893
         * disable system stats collection. */
2313
2894
        system_stats_enable(false);
2314
2895
        return;
2315
 
    } else if (!ovsdb_idl_has_lock(idl)) {
 
2896
    } else if (!ovsdb_idl_has_lock(idl)
 
2897
               || !ovsdb_idl_has_ever_connected(idl)) {
 
2898
        /* Returns if not holding the lock or not done retrieving db
 
2899
         * contents. */
2316
2900
        return;
2317
2901
    }
2318
2902
    cfg = ovsrec_open_vswitch_first(idl);
2349
2933
     * usage has changed. */
2350
2934
    vlan_splinters_changed = false;
2351
2935
    if (vlan_splinters_enabled_anywhere) {
 
2936
        struct bridge *br;
 
2937
 
2352
2938
        HMAP_FOR_EACH (br, node, &all_bridges) {
2353
2939
            if (ofproto_has_vlan_usage_changed(br->ofproto)) {
2354
2940
                vlan_splinters_changed = true;
2366
2952
 
2367
2953
        if (cfg) {
2368
2954
            ovsrec_open_vswitch_set_cur_cfg(cfg, cfg->next_cfg);
 
2955
            discover_types(cfg);
2369
2956
        }
2370
2957
 
2371
2958
        /* If we are completing our initial configuration for this run
2372
2959
         * of ovs-vswitchd, then keep the transaction around to monitor
2373
2960
         * it for completion. */
2374
2961
        if (initial_config_done) {
 
2962
            /* Always sets the 'status_txn_try_again' to check again,
 
2963
             * in case that this transaction fails. */
 
2964
            status_txn_try_again = true;
2375
2965
            ovsdb_idl_txn_commit(txn);
2376
2966
            ovsdb_idl_txn_destroy(txn);
2377
2967
        } else {
2396
2986
        }
2397
2987
    }
2398
2988
 
2399
 
    /* Statistics update interval should always be greater than or equal to
2400
 
     * 5000 ms. */
2401
 
    if (cfg) {
2402
 
        stats_interval = MAX(smap_get_int(&cfg->other_config,
2403
 
                                          "stats-update-interval",
2404
 
                                          5000), 5000);
2405
 
    } else {
2406
 
        stats_interval = 5000;
2407
 
    }
2408
 
    if (stats_timer_interval != stats_interval) {
2409
 
        stats_timer_interval = stats_interval;
2410
 
        stats_timer = LLONG_MIN;
2411
 
    }
2412
 
 
2413
 
    /* Refresh interface and mirror stats if necessary. */
2414
 
    if (time_msec() >= stats_timer && cfg) {
2415
 
        enum ovsdb_idl_txn_status status;
2416
 
 
2417
 
        /* Rate limit the update.  Do not start a new update if the
2418
 
         * previous one is not done. */
2419
 
        if (!stats_txn) {
2420
 
            stats_txn = ovsdb_idl_txn_create(idl);
2421
 
            HMAP_FOR_EACH (br, node, &all_bridges) {
2422
 
                struct port *port;
2423
 
                struct mirror *m;
2424
 
 
2425
 
                HMAP_FOR_EACH (port, hmap_node, &br->ports) {
2426
 
                    struct iface *iface;
2427
 
 
2428
 
                    LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
2429
 
                        iface_refresh_stats(iface);
2430
 
                    }
2431
 
                    port_refresh_stp_stats(port);
2432
 
                }
2433
 
                HMAP_FOR_EACH (m, hmap_node, &br->mirrors) {
2434
 
                    mirror_refresh_stats(m);
2435
 
                }
2436
 
            }
2437
 
            refresh_controller_status();
2438
 
        }
2439
 
 
2440
 
        status = ovsdb_idl_txn_commit(stats_txn);
2441
 
        if (status != TXN_INCOMPLETE) {
2442
 
            stats_timer = time_msec() + stats_timer_interval;
2443
 
            ovsdb_idl_txn_destroy(stats_txn);
2444
 
            stats_txn = NULL;
2445
 
        }
2446
 
    }
2447
 
 
2448
 
    if (!status_txn) {
2449
 
        uint64_t seq;
2450
 
 
2451
 
        /* Check the need to update status. */
2452
 
        seq = seq_read(connectivity_seq_get());
2453
 
        if (seq != connectivity_seqno || force_status_commit) {
2454
 
            connectivity_seqno = seq;
2455
 
            status_txn = ovsdb_idl_txn_create(idl);
2456
 
            HMAP_FOR_EACH (br, node, &all_bridges) {
2457
 
                struct port *port;
2458
 
 
2459
 
                br_refresh_stp_status(br);
2460
 
                HMAP_FOR_EACH (port, hmap_node, &br->ports) {
2461
 
                    struct iface *iface;
2462
 
 
2463
 
                    port_refresh_stp_status(port);
2464
 
                    port_refresh_bond_status(port, force_status_commit);
2465
 
                    LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
2466
 
                        iface_refresh_netdev_status(iface);
2467
 
                        iface_refresh_ofproto_status(iface);
2468
 
                    }
2469
 
                }
2470
 
            }
2471
 
        }
2472
 
    }
2473
 
 
2474
 
    if (status_txn) {
2475
 
        enum ovsdb_idl_txn_status status;
2476
 
 
2477
 
        status = ovsdb_idl_txn_commit(status_txn);
2478
 
 
2479
 
        /* If the transaction is incomplete or fails, 'status_txn'
2480
 
         * needs to be committed next iteration of bridge_run() even if
2481
 
         * connectivity or netdev sequence numbers do not change. */
2482
 
        if (status == TXN_SUCCESS || status == TXN_UNCHANGED)
2483
 
        {
2484
 
            force_status_commit = false;
2485
 
        } else {
2486
 
            force_status_commit = true;
2487
 
        }
2488
 
 
2489
 
        /* Do not destroy "status_txn" if the transaction is
2490
 
         * "TXN_INCOMPLETE". */
2491
 
        if (status != TXN_INCOMPLETE) {
2492
 
            ovsdb_idl_txn_destroy(status_txn);
2493
 
            status_txn = NULL;
2494
 
        }
2495
 
    }
2496
 
 
 
2989
    run_stats_update();
 
2990
    run_status_update();
2497
2991
    run_system_stats();
2498
2992
}
2499
2993
 
2521
3015
        HMAP_FOR_EACH (br, node, &all_bridges) {
2522
3016
            ofproto_wait(br->ofproto);
2523
3017
        }
2524
 
 
2525
 
        poll_timer_wait_until(stats_timer);
2526
 
    }
2527
 
 
2528
 
    /* This prevents the process from constantly waking up on
2529
 
     * connectivity seq, when there is no connection to ovsdb. */
2530
 
    if (ovsdb_idl_has_lock(idl)) {
2531
 
        /* If the status database transaction is 'TXN_INCOMPLETE' or is
2532
 
         * unsuccessful, register a timeout in 'STATUS_CHECK_AGAIN_MSEC'.
2533
 
         * Else, wait on the global connectivity sequence number.  Note,
2534
 
         * this also helps batch multiple status changes into one
2535
 
         * transaction. */
2536
 
        if (force_status_commit) {
2537
 
            poll_timer_wait_until(time_msec() + STATUS_CHECK_AGAIN_MSEC);
2538
 
        } else {
2539
 
            seq_wait(connectivity_seq_get(), connectivity_seqno);
2540
 
        }
 
3018
        stats_update_wait();
 
3019
        status_update_wait();
2541
3020
    }
2542
3021
 
2543
3022
    system_stats_wait();
2679
3158
    hmap_init(&br->iface_by_name);
2680
3159
    hmap_init(&br->mirrors);
2681
3160
 
 
3161
    hmap_init(&br->mappings);
2682
3162
    hmap_insert(&all_bridges, &br->node, hash_string(br->name, 0));
2683
3163
}
2684
3164
 
2702
3182
        hmap_destroy(&br->ports);
2703
3183
        hmap_destroy(&br->iface_by_name);
2704
3184
        hmap_destroy(&br->mirrors);
 
3185
        hmap_destroy(&br->mappings);
2705
3186
        free(br->name);
2706
3187
        free(br->type);
2707
3188
        free(br);
3118
3599
    j = 0;
3119
3600
    for (i = 0; i < n_tables; i++) {
3120
3601
        struct ofproto_table_settings s;
 
3602
        bool use_default_prefixes = true;
3121
3603
 
3122
3604
        s.name = NULL;
3123
3605
        s.max_flows = UINT_MAX;
3159
3641
            s.n_prefix_fields = 0;
3160
3642
            for (k = 0; k < cfg->n_prefixes; k++) {
3161
3643
                const char *name = cfg->prefixes[k];
3162
 
                const struct mf_field *mf = mf_from_name(name);
 
3644
                const struct mf_field *mf;
 
3645
 
 
3646
                if (strcmp(name, "none") == 0) {
 
3647
                    use_default_prefixes = false;
 
3648
                    s.n_prefix_fields = 0;
 
3649
                    break;
 
3650
                }
 
3651
                mf = mf_from_name(name);
3163
3652
                if (!mf) {
3164
3653
                    VLOG_WARN("bridge %s: 'prefixes' with unknown field: %s",
3165
3654
                              br->name, name);
3175
3664
                              "field not used: %s", br->name, name);
3176
3665
                    continue;
3177
3666
                }
 
3667
                use_default_prefixes = false;
3178
3668
                s.prefix_fields[s.n_prefix_fields++] = mf->id;
3179
3669
            }
3180
 
            if (s.n_prefix_fields > 0) {
3181
 
                int k;
3182
 
                struct ds ds = DS_EMPTY_INITIALIZER;
3183
 
                for (k = 0; k < s.n_prefix_fields; k++) {
3184
 
                    if (k) {
3185
 
                        ds_put_char(&ds, ',');
3186
 
                    }
3187
 
                    ds_put_cstr(&ds, mf_from_id(s.prefix_fields[k])->name);
 
3670
        }
 
3671
        if (use_default_prefixes) {
 
3672
            /* Use default values. */
 
3673
            s.n_prefix_fields = ARRAY_SIZE(default_prefix_fields);
 
3674
            memcpy(s.prefix_fields, default_prefix_fields,
 
3675
                   sizeof default_prefix_fields);
 
3676
        } else {
 
3677
            int k;
 
3678
            struct ds ds = DS_EMPTY_INITIALIZER;
 
3679
            for (k = 0; k < s.n_prefix_fields; k++) {
 
3680
                if (k) {
 
3681
                    ds_put_char(&ds, ',');
3188
3682
                }
3189
 
                VLOG_INFO("bridge %s table %d: Prefix lookup with: %s.",
3190
 
                          br->name, i, ds_cstr(&ds));
3191
 
                ds_destroy(&ds);
3192
 
            }
 
3683
                ds_put_cstr(&ds, mf_from_id(s.prefix_fields[k])->name);
 
3684
            }
 
3685
            if (s.n_prefix_fields == 0) {
 
3686
                ds_put_cstr(&ds, "none");
 
3687
            }
 
3688
            VLOG_INFO("bridge %s table %d: Prefix lookup with: %s.",
 
3689
                      br->name, i, ds_cstr(&ds));
 
3690
            ds_destroy(&ds);
3193
3691
        }
3194
3692
 
3195
3693
        ofproto_configure_table(br->ofproto, i, &s);
3209
3707
    ofproto_set_dp_desc(br->ofproto,
3210
3708
                        smap_get(&br->cfg->other_config, "dp-desc"));
3211
3709
}
 
3710
 
 
3711
static struct aa_mapping *
 
3712
bridge_aa_mapping_find(struct bridge *br, const int64_t isid)
 
3713
{
 
3714
    struct aa_mapping *m;
 
3715
 
 
3716
    HMAP_FOR_EACH_IN_BUCKET (m,
 
3717
                             hmap_node,
 
3718
                             hash_bytes(&isid, sizeof isid, 0),
 
3719
                             &br->mappings) {
 
3720
        if (isid == m->isid) {
 
3721
            return m;
 
3722
        }
 
3723
    }
 
3724
    return NULL;
 
3725
}
 
3726
 
 
3727
static struct aa_mapping *
 
3728
bridge_aa_mapping_create(struct bridge *br,
 
3729
                         const int64_t isid,
 
3730
                         const int64_t vlan)
 
3731
{
 
3732
    struct aa_mapping *m;
 
3733
 
 
3734
    m = xzalloc(sizeof *m);
 
3735
    m->bridge = br;
 
3736
    m->isid = isid;
 
3737
    m->vlan = vlan;
 
3738
    m->br_name = xstrdup(br->name);
 
3739
    hmap_insert(&br->mappings,
 
3740
                &m->hmap_node,
 
3741
                hash_bytes(&isid, sizeof isid, 0));
 
3742
 
 
3743
    return m;
 
3744
}
 
3745
 
 
3746
static void
 
3747
bridge_aa_mapping_destroy(struct aa_mapping *m)
 
3748
{
 
3749
    if (m) {
 
3750
        struct bridge *br = m->bridge;
 
3751
 
 
3752
        if (br->ofproto) {
 
3753
            ofproto_aa_mapping_unregister(br->ofproto, m);
 
3754
        }
 
3755
 
 
3756
        hmap_remove(&br->mappings, &m->hmap_node);
 
3757
        if (m->br_name) {
 
3758
            free(m->br_name);
 
3759
        }
 
3760
        free(m);
 
3761
    }
 
3762
}
 
3763
 
 
3764
static bool
 
3765
bridge_aa_mapping_configure(struct aa_mapping *m)
 
3766
{
 
3767
    struct aa_mapping_settings s;
 
3768
 
 
3769
    s.isid = m->isid;
 
3770
    s.vlan = m->vlan;
 
3771
 
 
3772
    /* Configure. */
 
3773
    ofproto_aa_mapping_register(m->bridge->ofproto, m, &s);
 
3774
 
 
3775
    return true;
 
3776
}
 
3777
 
 
3778
static void
 
3779
bridge_configure_aa(struct bridge *br)
 
3780
{
 
3781
    const struct ovsdb_datum *mc;
 
3782
    struct ovsrec_autoattach *auto_attach = br->cfg->auto_attach;
 
3783
    struct aa_settings aa_s;
 
3784
    struct aa_mapping *m, *next;
 
3785
    size_t i;
 
3786
 
 
3787
    if (!auto_attach) {
 
3788
        ofproto_set_aa(br->ofproto, NULL, NULL);
 
3789
        return;
 
3790
    }
 
3791
 
 
3792
    memset(&aa_s, 0, sizeof aa_s);
 
3793
    aa_s.system_description = auto_attach->system_description;
 
3794
    aa_s.system_name = auto_attach->system_name;
 
3795
    ofproto_set_aa(br->ofproto, NULL, &aa_s);
 
3796
 
 
3797
    mc = ovsrec_autoattach_get_mappings(auto_attach,
 
3798
                                        OVSDB_TYPE_INTEGER,
 
3799
                                        OVSDB_TYPE_INTEGER);
 
3800
    HMAP_FOR_EACH_SAFE (m, next, hmap_node, &br->mappings) {
 
3801
        union ovsdb_atom atom;
 
3802
 
 
3803
        atom.integer = m->isid;
 
3804
        if (ovsdb_datum_find_key(mc, &atom, OVSDB_TYPE_UUID) == UINT_MAX) {
 
3805
            VLOG_INFO("Deleting isid=%"PRIu32", vlan=%"PRIu16,
 
3806
                      m->isid, m->vlan);
 
3807
            bridge_aa_mapping_destroy(m);
 
3808
        }
 
3809
    }
 
3810
 
 
3811
    /* Add new mappings and reconfigure existing ones. */
 
3812
    for (i = 0; i < auto_attach->n_mappings; ++i) {
 
3813
        struct aa_mapping *m =
 
3814
            bridge_aa_mapping_find(br, auto_attach->key_mappings[i]);
 
3815
 
 
3816
        if (!m) {
 
3817
            VLOG_INFO("Adding isid=%"PRId64", vlan=%"PRId64,
 
3818
                      auto_attach->key_mappings[i],
 
3819
                      auto_attach->value_mappings[i]);
 
3820
            m = bridge_aa_mapping_create(br,
 
3821
                                         auto_attach->key_mappings[i],
 
3822
                                         auto_attach->value_mappings[i]);
 
3823
 
 
3824
            if (!bridge_aa_mapping_configure(m)) {
 
3825
                bridge_aa_mapping_destroy(m);
 
3826
            }
 
3827
        }
 
3828
    }
 
3829
}
 
3830
 
 
3831
static bool
 
3832
bridge_aa_need_refresh(struct bridge *br)
 
3833
{
 
3834
    return ofproto_aa_vlan_get_queue_size(br->ofproto) > 0;
 
3835
}
 
3836
 
 
3837
static void
 
3838
bridge_aa_update_trunks(struct port *port, struct bridge_aa_vlan *m)
 
3839
{
 
3840
    int64_t *trunks = NULL;
 
3841
    unsigned int i = 0;
 
3842
    bool found = false, reconfigure = false;
 
3843
 
 
3844
    for (i = 0; i < port->cfg->n_trunks; i++) {
 
3845
        if (port->cfg->trunks[i] == m->vlan) {
 
3846
            found = true;
 
3847
            break;
 
3848
        }
 
3849
    }
 
3850
 
 
3851
    switch (m->oper) {
 
3852
        case BRIDGE_AA_VLAN_OPER_ADD:
 
3853
            if (!found) {
 
3854
                trunks = xmalloc(sizeof *trunks * (port->cfg->n_trunks + 1));
 
3855
 
 
3856
                for (i = 0; i < port->cfg->n_trunks; i++) {
 
3857
                    trunks[i] = port->cfg->trunks[i];
 
3858
                }
 
3859
                trunks[i++] = m->vlan;
 
3860
                reconfigure = true;
 
3861
            }
 
3862
 
 
3863
            break;
 
3864
 
 
3865
        case BRIDGE_AA_VLAN_OPER_REMOVE:
 
3866
            if (found) {
 
3867
                unsigned int j = 0;
 
3868
 
 
3869
                trunks = xmalloc(sizeof *trunks * (port->cfg->n_trunks - 1));
 
3870
 
 
3871
                for (i = 0; i < port->cfg->n_trunks; i++) {
 
3872
                    if (port->cfg->trunks[i] != m->vlan) {
 
3873
                        trunks[j++] = port->cfg->trunks[i];
 
3874
                    }
 
3875
                }
 
3876
                i = j;
 
3877
                reconfigure = true;
 
3878
            }
 
3879
 
 
3880
            break;
 
3881
 
 
3882
        case BRIDGE_AA_VLAN_OPER_UNDEF:
 
3883
        default:
 
3884
            VLOG_WARN("unrecognized operation %u", m->oper);
 
3885
            break;
 
3886
    }
 
3887
 
 
3888
    if (reconfigure) {
 
3889
        /* VLAN switching under trunk mode cause the trunk port to switch all
 
3890
         * VLANs, see ovs-vswitchd.conf.db
 
3891
         */
 
3892
        if (i == 0)  {
 
3893
            static char *vlan_mode_access = "access";
 
3894
            ovsrec_port_set_vlan_mode(port->cfg, vlan_mode_access);
 
3895
        }
 
3896
 
 
3897
        if (i == 1) {
 
3898
            static char *vlan_mode_trunk = "trunk";
 
3899
            ovsrec_port_set_vlan_mode(port->cfg, vlan_mode_trunk);
 
3900
        }
 
3901
 
 
3902
        ovsrec_port_set_trunks(port->cfg, trunks, i);
 
3903
 
 
3904
        /* Force reconfigure of the port. */
 
3905
        port_configure(port);
 
3906
    }
 
3907
}
 
3908
 
 
3909
static void
 
3910
bridge_aa_refresh_queued(struct bridge *br)
 
3911
{
 
3912
    struct ovs_list *list = xmalloc(sizeof *list);
 
3913
    struct bridge_aa_vlan *node, *next;
 
3914
 
 
3915
    list_init(list);
 
3916
    ofproto_aa_vlan_get_queued(br->ofproto, list);
 
3917
 
 
3918
    LIST_FOR_EACH_SAFE (node, next, list_node, list) {
 
3919
        struct port *port;
 
3920
 
 
3921
        VLOG_INFO("ifname=%s, vlan=%u, oper=%u", node->port_name, node->vlan,
 
3922
                  node->oper);
 
3923
 
 
3924
        port = port_lookup(br, node->port_name);
 
3925
        if (port) {
 
3926
            bridge_aa_update_trunks(port, node);
 
3927
        }
 
3928
 
 
3929
        list_remove(&node->list_node);
 
3930
        free(node->port_name);
 
3931
        free(node);
 
3932
    }
 
3933
 
 
3934
    free(list);
 
3935
}
 
3936
 
3212
3937
 
3213
3938
/* Port functions. */
3214
3939
 
3441
4166
        s->rebalance_interval = 1000;
3442
4167
    }
3443
4168
 
3444
 
    s->fake_iface = port->cfg->bond_fake_iface;
3445
 
 
3446
4169
    s->lacp_fallback_ab_cfg = smap_get_bool(&port->cfg->other_config,
3447
4170
                                       "lacp-fallback-ab", false);
3448
4171
 
3514
4237
        list_remove(&iface->port_elem);
3515
4238
        hmap_remove(&br->iface_by_name, &iface->name_node);
3516
4239
 
3517
 
        netdev_close(iface->netdev);
 
4240
        /* The user is changing configuration here, so netdev_remove needs to be
 
4241
         * used as opposed to netdev_close */
 
4242
        netdev_remove(iface->netdev);
3518
4243
 
3519
4244
        free(iface->name);
3520
4245
        free(iface);
3632
4357
 * This is appropriate when 'if_cfg''s interface cannot be created or is
3633
4358
 * otherwise invalid. */
3634
4359
static void
3635
 
iface_clear_db_record(const struct ovsrec_interface *if_cfg)
 
4360
iface_clear_db_record(const struct ovsrec_interface *if_cfg, char *errp)
3636
4361
{
3637
4362
    if (!ovsdb_idl_row_is_synthetic(&if_cfg->header_)) {
3638
4363
        iface_set_ofport(if_cfg, OFPP_NONE);
 
4364
        ovsrec_interface_set_error(if_cfg, errp);
3639
4365
        ovsrec_interface_set_status(if_cfg, NULL);
3640
4366
        ovsrec_interface_set_admin_state(if_cfg, NULL);
3641
4367
        ovsrec_interface_set_duplex(if_cfg, NULL);
3668
4394
 
3669
4395
    ofpbuf_init(&queues_buf, 0);
3670
4396
 
3671
 
    if (!qos || qos->type[0] == '\0' || qos->n_queues < 1) {
 
4397
    if (!qos || qos->type[0] == '\0') {
3672
4398
        netdev_set_qos(iface->netdev, NULL, NULL);
3673
4399
    } else {
3674
4400
        const struct ovsdb_datum *queues;
3723
4449
    }
3724
4450
 
3725
4451
    if (iface->ofp_port != OFPP_NONE) {
3726
 
        const struct ofproto_port_queue *port_queues = ofpbuf_data(&queues_buf);
3727
 
        size_t n_queues = ofpbuf_size(&queues_buf) / sizeof *port_queues;
 
4452
        const struct ofproto_port_queue *port_queues = queues_buf.data;
 
4453
        size_t n_queues = queues_buf.size / sizeof *port_queues;
3728
4454
 
3729
4455
        ofproto_port_set_queues(iface->port->bridge->ofproto, iface->ofp_port,
3730
4456
                                port_queues, n_queues);
3731
4457
    }
3732
4458
 
3733
4459
    netdev_set_policing(iface->netdev,
3734
 
                        iface->cfg->ingress_policing_rate,
3735
 
                        iface->cfg->ingress_policing_burst);
 
4460
                        MIN(UINT32_MAX, iface->cfg->ingress_policing_rate),
 
4461
                        MIN(UINT32_MAX, iface->cfg->ingress_policing_burst));
3736
4462
 
3737
4463
    ofpbuf_uninit(&queues_buf);
3738
4464
}
4287
5013
{
4288
5014
    struct ofproto *ofproto = m->bridge->ofproto;
4289
5015
    uint64_t tx_packets, tx_bytes;
4290
 
    char *keys[2];
 
5016
    const char *keys[2];
4291
5017
    int64_t values[2];
4292
5018
    size_t stat_cnt = 0;
4293
5019
 
4309
5035
 
4310
5036
    ovsrec_mirror_set_statistics(m->cfg, keys, values, stat_cnt);
4311
5037
}
 
5038
 
 
5039
/*
 
5040
 * Add registered netdev and dpif types to ovsdb to allow external
 
5041
 * applications to query the capabilities of the Open vSwitch instance
 
5042
 * running on the node.
 
5043
 */
 
5044
static void
 
5045
discover_types(const struct ovsrec_open_vswitch *cfg)
 
5046
{
 
5047
    struct sset types;
 
5048
 
 
5049
    /* Datapath types. */
 
5050
    sset_init(&types);
 
5051
    dp_enumerate_types(&types);
 
5052
    const char **datapath_types = sset_array(&types);
 
5053
    ovsrec_open_vswitch_set_datapath_types(cfg, datapath_types,
 
5054
                                           sset_count(&types));
 
5055
    free(datapath_types);
 
5056
    sset_destroy(&types);
 
5057
 
 
5058
    /* Port types. */
 
5059
    sset_init(&types);
 
5060
    netdev_enumerate_types(&types);
 
5061
    const char **iface_types = sset_array(&types);
 
5062
    ovsrec_open_vswitch_set_iface_types(cfg, iface_types, sset_count(&types));
 
5063
    free(iface_types);
 
5064
    sset_destroy(&types);
 
5065
}