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'.
176
* 'status_txn' is NULL if there is no ongoing status update.
193
* 'statux_txn' is NULL if there is no ongoing status update.
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.
183
199
static struct ovsdb_idl_txn *status_txn;
184
static bool force_status_commit = true;
200
static bool status_txn_try_again;
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
206
/* Statistics update to database. */
207
static struct ovsdb_idl_txn *stats_txn;
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;
195
/* Current stats database transaction, NULL if there is no ongoing
197
static struct ovsdb_idl_txn *stats_txn;
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.
217
#define AA_REFRESH_INTERVAL (1000) /* In milliseconds. */
218
static long long int aa_refresh_timer = LLONG_MIN;
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);
381
401
ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_system_version);
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);
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);
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);
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,
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);
1352
port_configure_rstp(const struct ofproto *ofproto, struct port *port,
1353
struct ofproto_port_rstp_settings *port_s, int *port_num_counter)
1355
const char *config_str;
1356
struct iface *iface;
1358
if (!smap_get_bool(&port->cfg->other_config, "rstp-enable", true)) {
1359
port_s->enable = false;
1362
port_s->enable = true;
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",
1369
port_s->enable = false;
1373
iface = CONTAINER_OF(list_front(&port->ifaces), struct iface, port_elem);
1375
/* Internal ports shouldn't participate in spanning tree, so
1377
if (!strcmp(iface->type, "internal")) {
1378
VLOG_DBG("port %s: disable RSTP on internal ports", port->name);
1379
port_s->enable = false;
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;
1390
config_str = smap_get(&port->cfg->other_config, "rstp-port-num");
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;
1398
port_s->port_num = port_num;
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;
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;
1410
config_str = smap_get(&port->cfg->other_config, "rstp-path-cost");
1412
port_s->path_cost = strtoul(config_str, NULL, 10);
1414
enum netdev_features current;
1417
netdev_get_features(iface->netdev, ¤t, 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);
1422
config_str = smap_get(&port->cfg->other_config, "rstp-port-priority");
1424
port_s->priority = strtoul(config_str, NULL, 0);
1426
port_s->priority = RSTP_DEFAULT_PORT_PRIORITY;
1429
config_str = smap_get(&port->cfg->other_config, "rstp-admin-p2p-mac");
1431
port_s->admin_p2p_mac_state = strtoul(config_str, NULL, 0);
1433
port_s->admin_p2p_mac_state = RSTP_ADMIN_P2P_MAC_FORCE_TRUE;
1436
port_s->admin_port_state = smap_get_bool(&port->cfg->other_config,
1437
"rstp-admin-port-state", true);
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);
1292
1447
/* Set spanning tree configuration on 'br'. */
1294
bridge_configure_stp(struct bridge *br)
1449
bridge_configure_stp(struct bridge *br, bool enable_stp)
1296
if (!br->cfg->stp_enable) {
1297
1452
ofproto_set_stp(br->ofproto, NULL);
1299
1454
struct ofproto_stp_settings br_s;
1543
bridge_configure_rstp(struct bridge *br, bool enable_rstp)
1546
ofproto_set_rstp(br->ofproto, NULL);
1548
struct ofproto_rstp_settings br_s;
1549
const char *config_str;
1551
int port_num_counter;
1553
config_str = smap_get(&br->cfg->other_config, "rstp-address");
1555
uint8_t ea[ETH_ADDR_LEN];
1557
if (eth_addr_from_string(config_str, ea)) {
1558
br_s.address = eth_addr_to_uint64(ea);
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));
1567
br_s.address = eth_addr_to_uint64(br->ea);
1570
config_str = smap_get(&br->cfg->other_config, "rstp-priority");
1572
br_s.priority = strtoul(config_str, NULL, 0);
1574
br_s.priority = RSTP_DEFAULT_PRIORITY;
1577
config_str = smap_get(&br->cfg->other_config, "rstp-ageing-time");
1579
br_s.ageing_time = strtoul(config_str, NULL, 0);
1581
br_s.ageing_time = RSTP_DEFAULT_AGEING_TIME;
1584
config_str = smap_get(&br->cfg->other_config,
1585
"rstp-force-protocol-version");
1587
br_s.force_protocol_version = strtoul(config_str, NULL, 0);
1589
br_s.force_protocol_version = FPV_DEFAULT;
1592
config_str = smap_get(&br->cfg->other_config, "rstp-max-age");
1594
br_s.bridge_max_age = strtoul(config_str, NULL, 10);
1596
br_s.bridge_max_age = RSTP_DEFAULT_BRIDGE_MAX_AGE;
1599
config_str = smap_get(&br->cfg->other_config, "rstp-forward-delay");
1601
br_s.bridge_forward_delay = strtoul(config_str, NULL, 10);
1603
br_s.bridge_forward_delay = RSTP_DEFAULT_BRIDGE_FORWARD_DELAY;
1606
config_str = smap_get(&br->cfg->other_config,
1607
"rstp-transmit-hold-count");
1609
br_s.transmit_hold_count = strtoul(config_str, NULL, 10);
1611
br_s.transmit_hold_count = RSTP_DEFAULT_TRANSMIT_HOLD_COUNT;
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);
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;
1625
port_configure_rstp(br->ofproto, port, &port_s,
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,
1633
VLOG_ERR("port %s: could not enable RSTP", port->name);
1642
bridge_configure_spanning_tree(struct bridge *br)
1644
bool enable_rstp = br->cfg->rstp_enable;
1645
bool enable_stp = br->cfg->stp_enable;
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);
1653
bridge_configure_stp(br, enable_stp);
1654
bridge_configure_rstp(br, enable_rstp);
1388
1658
bridge_has_bond_fake_iface(const struct bridge *br, const char *name)
1614
1888
ofproto_set_mac_table_config(br->ofproto, idle_time, mac_table_size);
1891
/* Set multicast snooping table configuration for 'br'. */
1893
bridge_configure_mcast_snooping(struct bridge *br)
1895
if (!br->cfg->mcast_snooping_enable) {
1896
ofproto_set_mcast_snooping(br->ofproto, NULL);
1899
struct ofproto_mcast_snooping_settings br_s;
1900
const char *idle_time_str;
1901
const char *max_entries_str;
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);
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);
1915
br_s.flood_unreg = !smap_get_bool(&br->cfg->other_config,
1916
"mcast-snooping-disable-flood-unregistered",
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",
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",
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)
2485
br_refresh_rstp_status(struct bridge *br)
2487
struct smap smap = SMAP_INITIALIZER(&smap);
2488
struct ofproto *ofproto = br->ofproto;
2489
struct ofproto_rstp_status status;
2491
if (ofproto_get_rstp_status(ofproto, &status)) {
2494
if (!status.enabled) {
2495
ovsrec_bridge_set_rstp_status(br->cfg, NULL);
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);
2515
port_refresh_rstp_status(struct port *port)
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];
2524
if (port_is_synthetic(port)) {
2528
/* RSTP doesn't currently support bonds. */
2529
if (!list_is_singleton(&port->ifaces)) {
2530
ovsrec_port_set_rstp_status(port->cfg, NULL);
2534
iface = CONTAINER_OF(list_front(&port->ifaces), struct iface, port_elem);
2535
if (ofproto_port_get_rstp_status(ofproto, iface->ofp_port, &status)) {
2539
if (!status.enabled) {
2540
ovsrec_port_set_rstp_status(port->cfg, NULL);
2541
ovsrec_port_set_rstp_statistics(port->cfg, NULL, NULL, 0);
2544
/* Set Status column. */
2547
smap_add_format(&smap, "rstp_port_id", RSTP_PORT_ID_FMT,
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);
2560
ovsrec_port_set_rstp_status(port->cfg, &smap);
2561
smap_destroy(&smap);
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));
2146
2577
port_refresh_bond_status(struct port *port, bool force_update)
2579
uint8_t mac[ETH_ADDR_LEN];
2150
2581
/* Return if port is not a bond */
2151
2582
if (list_is_singleton(&port->ifaces)) {
2261
2682
ofproto_free_ofproto_controller_info(&info);
2685
/* Update interface and mirror statistics if necessary. */
2687
run_stats_update(void)
2689
const struct ovsrec_open_vswitch *cfg = ovsrec_open_vswitch_first(idl);
2696
/* Statistics update interval should always be greater than or equal to
2698
stats_interval = MAX(smap_get_int(&cfg->other_config,
2699
"stats-update-interval",
2701
if (stats_timer_interval != stats_interval) {
2702
stats_timer_interval = stats_interval;
2703
stats_timer = LLONG_MIN;
2706
if (time_msec() >= stats_timer) {
2707
enum ovsdb_idl_txn_status status;
2709
/* Rate limit the update. Do not start a new update if the
2710
* previous one is not done. */
2714
stats_txn = ovsdb_idl_txn_create(idl);
2715
HMAP_FOR_EACH (br, node, &all_bridges) {
2719
HMAP_FOR_EACH (port, hmap_node, &br->ports) {
2720
struct iface *iface;
2722
LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
2723
iface_refresh_stats(iface);
2725
port_refresh_stp_stats(port);
2727
HMAP_FOR_EACH (m, hmap_node, &br->mirrors) {
2728
mirror_refresh_stats(m);
2731
refresh_controller_status();
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);
2744
stats_update_wait(void)
2746
/* If the 'stats_txn' is non-null (transaction incomplete), waits for the
2747
* transaction to complete. Otherwise, waits for the 'stats_timer'. */
2749
ovsdb_idl_txn_wait(stats_txn);
2751
poll_timer_wait_until(stats_timer);
2755
/* Update bridge/port/interface status if necessary. */
2757
run_status_update(void)
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) {
2768
connectivity_seqno = seq;
2769
status_txn = ovsdb_idl_txn_create(idl);
2770
HMAP_FOR_EACH (br, node, &all_bridges) {
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;
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);
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. */
2795
enum ovsdb_idl_txn_status status;
2797
status = ovsdb_idl_txn_commit(status_txn);
2798
if (status != TXN_INCOMPLETE) {
2799
ovsdb_idl_txn_destroy(status_txn);
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;
2806
status_txn_try_again = true;
2811
/* Refresh AA port status if necessary. */
2812
if (time_msec() >= aa_refresh_timer) {
2815
HMAP_FOR_EACH (br, node, &all_bridges) {
2816
if (bridge_aa_need_refresh(br)) {
2817
struct ovsdb_idl_txn *txn;
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);
2826
aa_refresh_timer = time_msec() + AA_REFRESH_INTERVAL;
2831
status_update_wait(void)
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. */
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);
2843
seq_wait(connectivity_seq_get(), connectivity_seqno);
2265
2848
bridge_run__(void)
2399
/* Statistics update interval should always be greater than or equal to
2402
stats_interval = MAX(smap_get_int(&cfg->other_config,
2403
"stats-update-interval",
2406
stats_interval = 5000;
2408
if (stats_timer_interval != stats_interval) {
2409
stats_timer_interval = stats_interval;
2410
stats_timer = LLONG_MIN;
2413
/* Refresh interface and mirror stats if necessary. */
2414
if (time_msec() >= stats_timer && cfg) {
2415
enum ovsdb_idl_txn_status status;
2417
/* Rate limit the update. Do not start a new update if the
2418
* previous one is not done. */
2420
stats_txn = ovsdb_idl_txn_create(idl);
2421
HMAP_FOR_EACH (br, node, &all_bridges) {
2425
HMAP_FOR_EACH (port, hmap_node, &br->ports) {
2426
struct iface *iface;
2428
LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
2429
iface_refresh_stats(iface);
2431
port_refresh_stp_stats(port);
2433
HMAP_FOR_EACH (m, hmap_node, &br->mirrors) {
2434
mirror_refresh_stats(m);
2437
refresh_controller_status();
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);
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) {
2459
br_refresh_stp_status(br);
2460
HMAP_FOR_EACH (port, hmap_node, &br->ports) {
2461
struct iface *iface;
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);
2475
enum ovsdb_idl_txn_status status;
2477
status = ovsdb_idl_txn_commit(status_txn);
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)
2484
force_status_commit = false;
2486
force_status_commit = true;
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);
2990
run_status_update();
2497
2991
run_system_stats();
3175
3664
"field not used: %s", br->name, name);
3667
use_default_prefixes = false;
3178
3668
s.prefix_fields[s.n_prefix_fields++] = mf->id;
3180
if (s.n_prefix_fields > 0) {
3182
struct ds ds = DS_EMPTY_INITIALIZER;
3183
for (k = 0; k < s.n_prefix_fields; k++) {
3185
ds_put_char(&ds, ',');
3187
ds_put_cstr(&ds, mf_from_id(s.prefix_fields[k])->name);
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);
3678
struct ds ds = DS_EMPTY_INITIALIZER;
3679
for (k = 0; k < s.n_prefix_fields; k++) {
3681
ds_put_char(&ds, ',');
3189
VLOG_INFO("bridge %s table %d: Prefix lookup with: %s.",
3190
br->name, i, ds_cstr(&ds));
3683
ds_put_cstr(&ds, mf_from_id(s.prefix_fields[k])->name);
3685
if (s.n_prefix_fields == 0) {
3686
ds_put_cstr(&ds, "none");
3688
VLOG_INFO("bridge %s table %d: Prefix lookup with: %s.",
3689
br->name, i, ds_cstr(&ds));
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"));
3711
static struct aa_mapping *
3712
bridge_aa_mapping_find(struct bridge *br, const int64_t isid)
3714
struct aa_mapping *m;
3716
HMAP_FOR_EACH_IN_BUCKET (m,
3718
hash_bytes(&isid, sizeof isid, 0),
3720
if (isid == m->isid) {
3727
static struct aa_mapping *
3728
bridge_aa_mapping_create(struct bridge *br,
3732
struct aa_mapping *m;
3734
m = xzalloc(sizeof *m);
3738
m->br_name = xstrdup(br->name);
3739
hmap_insert(&br->mappings,
3741
hash_bytes(&isid, sizeof isid, 0));
3747
bridge_aa_mapping_destroy(struct aa_mapping *m)
3750
struct bridge *br = m->bridge;
3753
ofproto_aa_mapping_unregister(br->ofproto, m);
3756
hmap_remove(&br->mappings, &m->hmap_node);
3765
bridge_aa_mapping_configure(struct aa_mapping *m)
3767
struct aa_mapping_settings s;
3773
ofproto_aa_mapping_register(m->bridge->ofproto, m, &s);
3779
bridge_configure_aa(struct bridge *br)
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;
3788
ofproto_set_aa(br->ofproto, NULL, NULL);
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);
3797
mc = ovsrec_autoattach_get_mappings(auto_attach,
3799
OVSDB_TYPE_INTEGER);
3800
HMAP_FOR_EACH_SAFE (m, next, hmap_node, &br->mappings) {
3801
union ovsdb_atom atom;
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,
3807
bridge_aa_mapping_destroy(m);
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]);
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]);
3824
if (!bridge_aa_mapping_configure(m)) {
3825
bridge_aa_mapping_destroy(m);
3832
bridge_aa_need_refresh(struct bridge *br)
3834
return ofproto_aa_vlan_get_queue_size(br->ofproto) > 0;
3838
bridge_aa_update_trunks(struct port *port, struct bridge_aa_vlan *m)
3840
int64_t *trunks = NULL;
3842
bool found = false, reconfigure = false;
3844
for (i = 0; i < port->cfg->n_trunks; i++) {
3845
if (port->cfg->trunks[i] == m->vlan) {
3852
case BRIDGE_AA_VLAN_OPER_ADD:
3854
trunks = xmalloc(sizeof *trunks * (port->cfg->n_trunks + 1));
3856
for (i = 0; i < port->cfg->n_trunks; i++) {
3857
trunks[i] = port->cfg->trunks[i];
3859
trunks[i++] = m->vlan;
3865
case BRIDGE_AA_VLAN_OPER_REMOVE:
3869
trunks = xmalloc(sizeof *trunks * (port->cfg->n_trunks - 1));
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];
3882
case BRIDGE_AA_VLAN_OPER_UNDEF:
3884
VLOG_WARN("unrecognized operation %u", m->oper);
3889
/* VLAN switching under trunk mode cause the trunk port to switch all
3890
* VLANs, see ovs-vswitchd.conf.db
3893
static char *vlan_mode_access = "access";
3894
ovsrec_port_set_vlan_mode(port->cfg, vlan_mode_access);
3898
static char *vlan_mode_trunk = "trunk";
3899
ovsrec_port_set_vlan_mode(port->cfg, vlan_mode_trunk);
3902
ovsrec_port_set_trunks(port->cfg, trunks, i);
3904
/* Force reconfigure of the port. */
3905
port_configure(port);
3910
bridge_aa_refresh_queued(struct bridge *br)
3912
struct ovs_list *list = xmalloc(sizeof *list);
3913
struct bridge_aa_vlan *node, *next;
3916
ofproto_aa_vlan_get_queued(br->ofproto, list);
3918
LIST_FOR_EACH_SAFE (node, next, list_node, list) {
3921
VLOG_INFO("ifname=%s, vlan=%u, oper=%u", node->port_name, node->vlan,
3924
port = port_lookup(br, node->port_name);
3926
bridge_aa_update_trunks(port, node);
3929
list_remove(&node->list_node);
3930
free(node->port_name);
3213
3938
/* Port functions. */