X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=vswitchd%2Fbridge.c;h=febf63bea52b1e1e4a037c4fbd093b4043382617;hb=fef94d151cc7a4d0484f984e61c440cd416919a4;hp=b266c1056d94e5421b67676df930cfa80e2493ad;hpb=da285df4bf68df22b0b987d3859b2d1a023125aa;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index b266c105..febf63be 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1,28 +1,16 @@ /* Copyright (c) 2008, 2009 Nicira Networks - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * In addition, as a special exception, Nicira Networks gives permission - * to link the code of its release of vswitchd with the OpenSSL project's - * "OpenSSL" library (or with modified versions of it that use the same - * license as the "OpenSSL" library), and distribute the linked - * executables. You must obey the GNU General Public License in all - * respects for all of the code used other than "OpenSSL". If you modify - * this file, you may extend this exception to your version of the file, - * but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #include @@ -39,6 +27,7 @@ #include #include #include +#include #include #include "bitmap.h" #include "cfg.h" @@ -335,6 +324,7 @@ bridge_configure_ssl(void) static char *private_key_file; static char *certificate_file; static char *cacert_file; + struct stat s; if (config_string_change("ssl.private-key", &private_key_file)) { vconn_ssl_set_private_key_file(private_key_file); @@ -344,7 +334,13 @@ bridge_configure_ssl(void) vconn_ssl_set_certificate_file(certificate_file); } - if (config_string_change("ssl.ca-cert", &cacert_file)) { + /* We assume that even if the filename hasn't changed, if the CA cert + * file has been removed, that we want to move back into + * boot-strapping mode. This opens a small security hole, because + * the old certificate will still be trusted until vSwitch is + * restarted. We may want to address this in vconn's SSL library. */ + if (config_string_change("ssl.ca-cert", &cacert_file) + || (stat(cacert_file, &s) && errno == ENOENT)) { vconn_ssl_set_ca_cert_file(cacert_file, cfg_get_bool(0, "ssl.bootstrap-ca-cert")); } @@ -732,10 +728,10 @@ bridge_pick_datapath_id(struct bridge *br, static uint64_t dpid_from_hash(const void *data, size_t n) { - uint8_t hash[SHA1HashSize]; + uint8_t hash[SHA1_DIGEST_SIZE]; BUILD_ASSERT_DECL(sizeof hash >= ETH_ADDR_LEN); - SHA1Bytes(data, n, hash); + sha1_bytes(data, n, hash); eth_addr_mark_random(hash); return eth_addr_to_uint64(hash); } @@ -1080,10 +1076,15 @@ bridge_reconfigure_controller(struct bridge *br) int rate_limit, burst_limit; if (!strcmp(controller, "discover")) { + bool update_resolv_conf = true; + + if (cfg_has("%s.update-resolv.conf", pfx)) { + update_resolv_conf = cfg_get_bool(0, "%s.update-resolv.conf", + pfx); + } ofproto_set_discovery(br->ofproto, true, cfg_get_string(0, "%s.accept-regex", pfx), - cfg_get_bool(0, "%s.update-resolv.conf", - pfx)); + update_resolv_conf); } else { struct netdev *netdev; bool in_band; @@ -1135,8 +1136,13 @@ bridge_reconfigure_controller(struct bridge *br) || !strcmp(fail_mode, "open"))); probe = cfg_get_int(0, "%s.inactivity-probe", pfx); - ofproto_set_probe_interval(br->ofproto, - probe ? probe : cfg_get_int(0, "mgmt.inactivity-probe")); + if (probe < 5) { + probe = cfg_get_int(0, "mgmt.inactivity-probe"); + if (probe < 5) { + probe = 15; + } + } + ofproto_set_probe_interval(br->ofproto, probe); max_backoff = cfg_get_int(0, "%s.max-backoff", pfx); if (!max_backoff) { @@ -1744,12 +1750,32 @@ process_flow(struct bridge *br, const flow_t *flow, goto done; } - /* Drop multicast and broadcast packets on inactive bonded interfaces, to + /* Multicast (and broadcast) packets on bonds need special attention, to * avoid receiving duplicates. */ if (in_port->n_ifaces > 1 && eth_addr_is_multicast(flow->dl_dst)) { *tags |= in_port->active_iface_tag; if (in_port->active_iface != in_iface->port_ifidx) { + /* Drop all multicast packets on inactive slaves. */ goto done; + } else { + /* Drop all multicast packets for which we have learned a different + * input port, because we probably sent the packet on one slaves + * and got it back on the active slave. Broadcast ARP replies are + * an exception to this rule: the host has moved to another + * switch. */ + int src_idx = mac_learning_lookup(br->ml, flow->dl_src, vlan); + if (src_idx != -1 && src_idx != in_port->port_idx) { + if (packet) { + if (!is_bcast_arp_reply(flow, packet)) { + goto done; + } + } else { + /* No way to know whether it's an ARP reply, because the + * flow entry doesn't include enough information and we + * don't have a packet. Punt. */ + return false; + } + } } } @@ -1757,27 +1783,9 @@ process_flow(struct bridge *br, const flow_t *flow, out_port = FLOOD_PORT; if (br->ml) { int out_port_idx; - bool may_learn; - - if (!packet) { - /* Don't try to learn from revalidation. */ - may_learn = false; - } else if (in_port->n_ifaces > 1) { - /* If the packet arrived on a bonded port, don't learn from it - * unless we haven't learned any port at all for that address - * (because we probably sent the packet on one bonded interface and - * got it back on the other). Broadcast ARP replies are an - * exception to this rule: the host has moved to another switch. */ - int src_idx = mac_learning_lookup(br->ml, flow->dl_src, vlan); - may_learn = (src_idx < 0 - || src_idx == in_port->port_idx - || is_bcast_arp_reply(flow, packet)); - } else { - may_learn = true; - } - /* Learn source MAC. */ - if (may_learn) { + /* Learn source MAC (but don't try to learn from revalidation). */ + if (packet) { tag_type rev_tag = mac_learning_learn(br->ml, flow->dl_src, vlan, in_port->port_idx); if (rev_tag) {