X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=c175c58f2b73ce30f343918314bdc86b29ee8bd5;hb=380cbf380247322ae7d18117fc9dd30137cc460c;hp=a00d4cfa8fbc4a364f08bf2150cfc24b6a166978;hpb=bc1b010c2b8bd17973287388da8c171332b70b3f;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index a00d4cfa..c175c58f 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -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" @@ -156,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); @@ -466,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); @@ -1272,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) @@ -2473,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. */ @@ -3138,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; }