This patch includes Solaris bridge specific changes to OVS.
This patch has not been proposed upstream because we are not yet
proposing Solaris specific requirements upstream.
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 6cd30b8..67120d4 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -943,6 +943,12 @@ port_configure(struct port *port)
free(s.lacp_slaves);
}
+static boolean_t
+bridge_is_system(const struct bridge *br)
+{
+ return (strcmp(br->type, "system") == 0);
+}
+
/* Pick local port hardware address and datapath ID for 'br'. */
static void
bridge_configure_datapath_id(struct bridge *br)
@@ -954,6 +960,14 @@ bridge_configure_datapath_id(struct bridge *br)
char *dpid_string;
bridge_pick_local_hw_addr(br, ea, &hw_addr_iface);
+#ifdef __sun
+ /* Solaris "system" bridges are implicitly created VNICs. They
+ * already have their ethernet addresses set, so there is no
+ * reason to set them. We prefer that they be "auto" generated.
+ */
+ if (bridge_is_system(br))
+ goto skip;
+#endif
local_iface = iface_from_ofp_port(br, OFPP_LOCAL);
if (local_iface) {
int error = netdev_set_etheraddr(local_iface->netdev, ea);
@@ -964,6 +978,9 @@ bridge_configure_datapath_id(struct bridge *br)
br->name, ovs_strerror(error));
}
}
+#ifdef __sun
+skip:
+#endif
memcpy(br->ea, ea, ETH_ADDR_LEN);
dpid = bridge_pick_datapath_id(br, ea, hw_addr_iface);
@@ -1485,6 +1502,19 @@ iface_do_create(const struct bridge *br,
goto error;
}
+#ifdef __sun
+ if (bridge_is_system(br)) {
+ if (netdev_is_uplink(netdev)) {
+ VLOG_INFO("bridge %s: uplink %s", br->name, iface_cfg->name);
+ error = netdev_configure_uplink(netdev, br->name);
+ if (error) {
+ goto error;
+ }
+ }
+ netdev_add_port_to_bridge_mapping(netdev, br->name);
+ }
+#endif
+
*ofp_portp = iface_pick_ofport(iface_cfg);
error = ofproto_port_add(br->ofproto, netdev, ofp_portp);
if (error) {
@@ -1620,10 +1650,32 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
{
struct hmapx mirror_output_ports;
struct port *port;
+ struct iface *iface = NULL;
+ uint8_t iface_ea[ETH_ADDR_LEN];
bool found_addr = false;
int error;
int i;
+#ifdef __sun
+ /*
+ * Solaris does not currently support fake bridges.
+ */
+ if (bridge_is_system(br)) {
+ if (fake_br == NULL) {
+ iface = iface_lookup(br, br->name);
+ if (iface != NULL) {
+ error = netdev_get_etheraddr(iface->netdev, iface_ea);
+ if (error == 0) {
+ memcpy(ea, iface_ea, ETH_ADDR_LEN);
+ *hw_addr_iface = iface;
+ found_addr = true;
+ }
+ }
+ }
+ goto skip;
+ }
+#endif
+
/* Mirror output ports don't participate in picking the local hardware
* address. ofproto can't help us find out whether a given port is a
* mirror output because we haven't configured mirrors yet, so we need to
@@ -1639,9 +1691,7 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
/* Otherwise choose the minimum non-local MAC address among all of the
* interfaces. */
HMAP_FOR_EACH (port, hmap_node, &br->ports) {
- uint8_t iface_ea[ETH_ADDR_LEN];
struct iface *candidate;
- struct iface *iface;
/* Mirror output ports don't participate. */
if (hmapx_contains(&mirror_output_ports, port->cfg)) {
@@ -1708,13 +1758,15 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
found_addr = true;
}
}
+ hmapx_destroy(&mirror_output_ports);
+#ifdef __sun
+skip:
+#endif
if (!found_addr) {
memcpy(ea, br->default_ea, ETH_ADDR_LEN);
*hw_addr_iface = NULL;
}
-
- hmapx_destroy(&mirror_output_ports);
}
static void
diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c
index 3c843e1..a49f41e 100644
--- a/vswitchd/ovs-vswitchd.c
+++ b/vswitchd/ovs-vswitchd.c
@@ -61,6 +61,27 @@ static unixctl_cb_func ovs_vswitchd_exit;
static char *parse_options(int argc, char *argv[], char **unixctl_path);
static void usage(void) NO_RETURN;
+#ifdef __sun
+static void
+setfdlimit(void)
+{
+ struct rlimit rlimit;
+ rlim_t cur;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlimit) < 0) {
+ VLOG_ERR("getting the max fd limit failed so we are not able to "
+ "increase the current fd limit to max: %s", ovs_strerror(errno));
+ return;
+ }
+
+ cur = rlimit.rlim_cur;
+ rlimit.rlim_cur = rlimit.rlim_max;
+ if (setrlimit(RLIMIT_NOFILE, &rlimit) < 0)
+ VLOG_ERR("setting the # fds to %lu failed, proceeding with %lu as the "
+ "limit: %s", rlimit.rlim_max, cur, ovs_strerror(errno));
+}
+#endif
+
int
main(int argc, char *argv[])
{
@@ -93,6 +114,10 @@ main(int argc, char *argv[])
#endif
}
+#ifdef __sun
+ setfdlimit();
+#endif
+
retval = unixctl_server_create(unixctl_path, &unixctl);
if (retval) {
exit(EXIT_FAILURE);
diff --git a/vswitchd/system-stats.c b/vswitchd/system-stats.c
index 7789787..cee0255 100644
--- a/vswitchd/system-stats.c
+++ b/vswitchd/system-stats.c
@@ -29,6 +29,9 @@
#if HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
+#ifdef __sun
+#include <sys/loadavg.h>
+#endif
#include <unistd.h>
#include "daemon.h"