X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=c175c58f2b73ce30f343918314bdc86b29ee8bd5;hb=ef0ce8aeeeb95d2d64a8a22bd5839d7f684a31f5;hp=396c7206f319877c644604386168c9f88b86681c;hpb=0e15264f96e3caff662c7998cc739a3dd5c1c0f2;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 396c7206..c175c58f 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks +/* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,8 @@ #include "jsonrpc.h" #include "lacp.h" #include "list.h" +#include "mac-learning.h" +#include "meta-flow.h" #include "netdev.h" #include "ofp-print.h" #include "ofpbuf.h" @@ -40,6 +42,7 @@ #include "sha1.h" #include "shash.h" #include "socket-util.h" +#include "stream.h" #include "stream-ssl.h" #include "sset.h" #include "system-stats.h" @@ -155,8 +158,10 @@ static void bridge_configure_datapath_id(struct bridge *); static void bridge_configure_flow_eviction_threshold(struct bridge *); static void bridge_configure_netflow(struct bridge *); static void bridge_configure_forward_bpdu(struct bridge *); +static void bridge_configure_mac_idle_time(struct bridge *); static void bridge_configure_sflow(struct bridge *, int *sflow_bridge_number); static void bridge_configure_stp(struct bridge *); +static void bridge_configure_tables(struct bridge *); static void bridge_configure_remotes(struct bridge *, const struct sockaddr_in *managers, size_t n_managers); @@ -318,6 +323,7 @@ bridge_init(const char *remote) lacp_init(); bond_init(); cfm_init(); + stp_init(); } void @@ -373,10 +379,10 @@ collect_in_band_managers(const struct ovsrec_open_vswitch *ovs_cfg, SSET_FOR_EACH (target, &targets) { struct sockaddr_in *sin = &managers[n_managers]; - if ((!strncmp(target, "tcp:", 4) - && inet_parse_active(target + 4, JSONRPC_TCP_PORT, sin)) || - (!strncmp(target, "ssl:", 4) - && inet_parse_active(target + 4, JSONRPC_SSL_PORT, sin))) { + if (stream_parse_target_with_default_ports(target, + JSONRPC_TCP_PORT, + JSONRPC_SSL_PORT, + sin)) { n_managers++; } } @@ -464,10 +470,12 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) bridge_configure_mirrors(br); bridge_configure_flow_eviction_threshold(br); bridge_configure_forward_bpdu(br); + bridge_configure_mac_idle_time(br); bridge_configure_remotes(br, managers, n_managers); bridge_configure_netflow(br); bridge_configure_sflow(br, &sflow_bridge_number); bridge_configure_stp(br); + bridge_configure_tables(br); } free(managers); @@ -1270,6 +1278,20 @@ bridge_configure_forward_bpdu(struct bridge *br) ofproto_set_forward_bpdu(br->ofproto, forward_bpdu); } +/* Set MAC aging time for 'br'. */ +static void +bridge_configure_mac_idle_time(struct bridge *br) +{ + const char *idle_time_str; + int idle_time; + + idle_time_str = bridge_get_other_config(br->cfg, "mac-aging-time"); + idle_time = (idle_time_str && atoi(idle_time_str) + ? atoi(idle_time_str) + : MAC_ENTRY_DEFAULT_IDLE_TIME); + ofproto_set_mac_idle_time(br->ofproto, idle_time); +} + static void bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN], struct iface **hw_addr_iface) @@ -2471,6 +2493,66 @@ bridge_configure_remotes(struct bridge *br, sset_destroy(&snoops); } } + +static void +bridge_configure_tables(struct bridge *br) +{ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + int n_tables; + int i, j; + + n_tables = ofproto_get_n_tables(br->ofproto); + j = 0; + for (i = 0; i < n_tables; i++) { + struct ofproto_table_settings s; + + s.name = NULL; + s.max_flows = UINT_MAX; + s.groups = NULL; + s.n_groups = 0; + + if (j < br->cfg->n_flow_tables && i == br->cfg->key_flow_tables[j]) { + struct ovsrec_flow_table *cfg = br->cfg->value_flow_tables[j++]; + + s.name = cfg->name; + if (cfg->n_flow_limit && *cfg->flow_limit < UINT_MAX) { + s.max_flows = *cfg->flow_limit; + } + if (cfg->overflow_policy + && !strcmp(cfg->overflow_policy, "evict")) { + size_t k; + + s.groups = xmalloc(cfg->n_groups * sizeof *s.groups); + for (k = 0; k < cfg->n_groups; k++) { + const char *string = cfg->groups[k]; + char *msg; + + msg = mf_parse_subfield__(&s.groups[k], &string); + if (msg) { + VLOG_WARN_RL(&rl, "bridge %s table %d: error parsing " + "'groups' (%s)", br->name, i, msg); + free(msg); + } else if (*string) { + VLOG_WARN_RL(&rl, "bridge %s table %d: 'groups' " + "element '%s' contains trailing garbage", + br->name, i, cfg->groups[k]); + } else { + s.n_groups++; + } + } + } + } + + ofproto_configure_table(br->ofproto, i, &s); + + free(s.groups); + } + for (; j < br->cfg->n_flow_tables; j++) { + VLOG_WARN_RL(&rl, "bridge %s: ignoring configuration for flow table " + "%"PRId64" not supported by this datapath", br->name, + br->cfg->key_flow_tables[j]); + } +} /* Port functions. */ @@ -2663,9 +2745,14 @@ port_configure_lacp(struct port *port, struct lacp_settings *s) s->name = port->name; system_id = get_port_other_config(port->cfg, "lacp-system-id", NULL); - if (!system_id - || sscanf(system_id, ETH_ADDR_SCAN_FMT, - ETH_ADDR_SCAN_ARGS(s->id)) != ETH_ADDR_SCAN_COUNT) { + if (system_id) { + if (sscanf(system_id, ETH_ADDR_SCAN_FMT, + ETH_ADDR_SCAN_ARGS(s->id)) != ETH_ADDR_SCAN_COUNT) { + VLOG_WARN("port %s: LACP system ID (%s) must be an Ethernet" + " address.", port->name, system_id); + return NULL; + } + } else { memcpy(s->id, port->bridge->ea, ETH_ADDR_LEN); } @@ -2740,7 +2827,7 @@ port_configure_bond(struct port *port, struct bond_settings *s, size_t i; s->name = port->name; - s->balance = BM_SLB; + s->balance = BM_AB; if (port->cfg->bond_mode) { if (!bond_mode_from_string(&s->balance, port->cfg->bond_mode)) { VLOG_WARN("port %s: unknown bond_mode %s, defaulting to %s", @@ -2750,11 +2837,11 @@ port_configure_bond(struct port *port, struct bond_settings *s, } else { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); - /* XXX: Post version 1.4.*, change the default bond_mode to - * active-backup. Until then, warn that the change is imminent. */ + /* XXX: Post version 1.5.*, the default bond_mode changed from SLB to + * active-backup. At some point we should remove this warning. */ VLOG_WARN_RL(&rl, "port %s: Using the default bond_mode %s. Note that" - " in future versions, the default bond_mode is expected" - " to change to active-backup", port->name, + " in previous versions, the default bond_mode was" + " balance-slb", port->name, bond_mode_to_string(s->balance)); } if (s->balance == BM_SLB && port->bridge->cfg->n_flood_vlans) { @@ -2783,7 +2870,7 @@ port_configure_bond(struct port *port, struct bond_settings *s, s->basis = atoi(get_port_other_config(port->cfg, "bond-hash-basis", "0")); s->rebalance_interval = atoi( get_port_other_config(port->cfg, "bond-rebalance-interval", "10000")); - if (s->rebalance_interval < 1000) { + if (s->rebalance_interval && s->rebalance_interval < 1000) { s->rebalance_interval = 1000; } @@ -3131,6 +3218,8 @@ iface_configure_cfm(struct iface *iface) "0")); s.ccm_vlan = atoi(get_interface_other_config(iface->cfg, "cfm_ccm_vlan", "0")); + s.ccm_pcp = atoi(get_interface_other_config(iface->cfg, "cfm_ccm_pcp", + "0")); if (s.interval <= 0) { s.interval = 1000; } @@ -3411,8 +3500,9 @@ collect_splinter_vlans(const struct ovsrec_open_vswitch *ovs_cfg) * in the process of reconstructing all of them. */ free_registered_blocks(); - splinter_vlans = NULL; + splinter_vlans = bitmap_allocate(4096); sset_init(&splinter_ifaces); + vlan_splinters_enabled_anywhere = false; for (i = 0; i < ovs_cfg->n_bridges; i++) { struct ovsrec_bridge *br_cfg = ovs_cfg->bridges[i]; size_t j; @@ -3425,21 +3515,22 @@ collect_splinter_vlans(const struct ovsrec_open_vswitch *ovs_cfg) struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k]; if (vlan_splinters_is_enabled(iface_cfg)) { + vlan_splinters_enabled_anywhere = true; sset_add(&splinter_ifaces, iface_cfg->name); - - if (!splinter_vlans) { - splinter_vlans = bitmap_allocate(4096); - } vlan_bitmap_from_array__(port_cfg->trunks, port_cfg->n_trunks, splinter_vlans); } } + + if (port_cfg->tag && *port_cfg->tag > 0 && *port_cfg->tag < 4095) { + bitmap_set1(splinter_vlans, *port_cfg->tag); + } } } - vlan_splinters_enabled_anywhere = splinter_vlans != NULL; - if (!splinter_vlans) { + if (!vlan_splinters_enabled_anywhere) { + free(splinter_vlans); sset_destroy(&splinter_ifaces); return NULL; }