int flow_idle_time; /* Idle time for flows we set up. */
bool sent_config_request; /* Successfully sent config request? */
bool sent_features_request; /* Successfully sent features request? */
+ uint8_t default_ea[ETH_ADDR_LEN]; /* Default MAC. */
/* Support for remote controllers. */
char *controller; /* NULL if there is no remote controller;
static bool bridge_is_backlogged(const struct bridge *);
static void bridge_fetch_dp_ifaces(struct bridge *);
static void bridge_flush(struct bridge *);
+static void bridge_pick_local_hw_addr(struct bridge *,
+ struct iface *local_iface);
static void bridge_process_msg(struct bridge *, struct ofpbuf *);
static void revalidate_flow(struct bridge *, struct ft_flow *);
br->dp_idx, iface->name, iface->dp_ifidx);
j++;
}
+ if (!strcmp(iface->name, br->name)) {
+ bridge_pick_local_hw_addr(br, iface);
+ }
}
if (!port->n_ifaces) {
VLOG_ERR("%s port has no interfaces, dropping", port->name);
}
}
+static void
+bridge_set_local_hw_addr(struct bridge *br, struct iface *local_iface,
+ const uint8_t ea[ETH_ADDR_LEN])
+{
+ int error = netdev_nodev_set_etheraddr(local_iface->name, ea);
+ if (error) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+ VLOG_ERR_RL(&rl, "bridge %s: failed to set bridge Ethernet "
+ "address: %s", br->name, strerror(error));
+ }
+}
+
+static void
+bridge_pick_local_hw_addr(struct bridge *br, struct iface *local_iface)
+{
+ uint8_t ea[ETH_ADDR_LEN];
+ uint64_t requested_ea;
+ size_t i, j;
+ int error;
+
+ /* Did the user request a particular MAC? */
+ requested_ea = cfg_get_mac(0, "bridge.%s.mac", br->name);
+ if (requested_ea) {
+ eth_addr_from_uint64(requested_ea, ea);
+ if (eth_addr_is_multicast(ea)) {
+ VLOG_ERR("bridge %s: cannot set MAC address to multicast "
+ "address "ETH_ADDR_FMT, br->name, ETH_ADDR_ARGS(ea));
+ } else if (eth_addr_is_zero(ea)) {
+ VLOG_ERR("bridge %s: cannot set MAC address to zero", br->name);
+ } else {
+ bridge_set_local_hw_addr(br, local_iface, ea);
+ return;
+ }
+ }
+
+ /* Otherwise choose the minimum MAC address among all of the interfaces.
+ * (Xen uses FE:FF:FF:FF:FF:FF for virtual interfaces so this will get the
+ * MAC of the physical interface in such an environment.) */
+ memset(ea, 0xff, sizeof ea);
+ for (i = 0; i < br->n_ports; i++) {
+ struct port *port = br->ports[i];
+ if (port->is_mirror_output_port) {
+ continue;
+ }
+ for (j = 0; j < port->n_ifaces; j++) {
+ struct iface *iface = port->ifaces[j];
+ uint8_t iface_ea[ETH_ADDR_LEN];
+ if (iface == local_iface) {
+ continue;
+ }
+ error = netdev_nodev_get_etheraddr(iface->name, iface_ea);
+ if (!error) {
+ if (!eth_addr_is_multicast(iface_ea) &&
+ !eth_addr_is_reserved(iface_ea) &&
+ memcmp(iface_ea, ea, ETH_ADDR_LEN) < 0) {
+ memcpy(ea, iface_ea, ETH_ADDR_LEN);
+ }
+ } else {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+ VLOG_ERR_RL(&rl, "failed to obtain Ethernet address of %s: %s",
+ iface->name, strerror(error));
+ }
+ }
+ }
+ if (eth_addr_is_broadcast(ea)) {
+ memcpy(ea, br->default_ea, ETH_ADDR_LEN);
+ VLOG_WARN("bridge %s: using default bridge Ethernet "
+ "address "ETH_ADDR_FMT, br->name, ETH_ADDR_ARGS(ea));
+ } else {
+ VLOG_DBG("bridge %s: using bridge Ethernet address "ETH_ADDR_FMT,
+ br->name, ETH_ADDR_ARGS(ea));
+ }
+ bridge_set_local_hw_addr(br, local_iface, ea);
+}
+
void
bridge_run(void)
{
br->flow_idle_time = 5;
br->sent_config_request = false;
br->sent_features_request = false;
+ eth_addr_random(br->default_ea);
svec_init(&br->secchan_opts);
the names of its network devices as values for key
\fBbridge.\fIname\fB.port\fR.
.PP
+A bridge with a given \fIname\fR always has an associated network
+device with the same \fIname\fR. This network device may be included
+in the bridge, by specifying it as one of the values for key
+\fBbridge.\fIname\fB.port\fR, or it may be omitted. If it is
+included, then its MAC address is by default the lowest-numbered MAC
+address among the other bridge ports, ignoring bridge ports that are
+used as port mirroring destinations (see "Port mirroring", below). To
+use a specific MAC address instead, set \fBbridge.\fIname\fB.mac\fR to
+a MAC address in the format
+\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fR, where each
+\fIx\fR is a hex digit. If no valid MAC address can be determined
+either of these ways, then a MAC address is chosen randomly.
+.PP
The following syntax defines a bridge named \fBmybr\fR, configured
with network devices \fBeth0\fR, \fBeth1\fR, and \fBeth2\fR:
.RS