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) {