25375056 Guest LDom packets may not flow w/o in-guest network activity (userland part)
25292405 Open vSwitch latency regression
--- a/components/openvswitch/files/lib/dpif-solaris.c Thu Jan 19 14:29:43 2017 -0800
+++ b/components/openvswitch/files/lib/dpif-solaris.c Thu Jan 19 16:57:09 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -1914,8 +1914,8 @@
ofpbuf_use_stack(&buf, &state->maskbuf,
sizeof (state->maskbuf));
- odp_flow_key_from_mask(&buf, &flow->m, &flow->m,
- flow->f.in_port.odp_port, SIZE_MAX);
+ odp_flow_key_from_mask(&buf, &flow->m, &flow->f,
+ UINT32_MAX, SIZE_MAX);
*mask = ofpbuf_data(&buf);
*mask_len = ofpbuf_size(&buf);
@@ -2998,6 +2998,52 @@
return (err);
}
+void
+dpif_solaris_send_rarp(const char *name)
+{
+ struct dpif_solaris *dpif;
+ int fd = -1;
+ odp_port_t port_no;
+ boolean_t port_found = B_FALSE;
+ struct dpif_solaris_port *port = NULL;
+ uint8_t hwaddr[ETHERADDRL];
+
+ VLOG_DBG("dpif_get_uplink_fd: getting TX socket for %s\n", name);
+ dpif = get_dp_by_name("ovs-system");
+ if (dpif == NULL) {
+ VLOG_DBG("dpif_solaris_send_rarp: error getting datapath\n");
+ return;
+ }
+ ovs_rwlock_rdlock(&dpif->port_rwlock);
+ HMAP_FOR_EACH(port, node, &dpif->ports) {
+ if (strcmp(port->name, name) == 0) {
+ port_no = port->port_no;
+ port_found = B_TRUE;
+ break;
+ }
+ }
+ ovs_rwlock_unlock(&dpif->port_rwlock);
+ if (!port_found) {
+ VLOG_DBG("dpif_solaris_send_rarp: Error getting port for %s\n",
+ name);
+ return;
+ }
+
+ if (netdev_get_etheraddr(port->netdev, hwaddr) != 0) {
+ VLOG_DBG("dpif_solaris_send_rarp: Error getting port %s's "
+ "ethernet address\n", name);
+ return;
+ }
+
+ if (dpif_solaris_get_uplink_port_info(dpif, port_no,
+ NULL, &fd, NULL) == 0) {
+ if (solaris_send_rarp(fd, hwaddr) == 0)
+ VLOG_DBG("dpif_get_uplink_fd: RARP success!");
+ else
+ VLOG_ERR("dpif_get_uplink_fd: RARP error!");
+ }
+}
+
const struct dpif_class dpif_solaris_class = {
"system",
dpif_solaris_enumerate,
--- a/components/openvswitch/files/lib/dpif-solaris.h Thu Jan 19 14:29:43 2017 -0800
+++ b/components/openvswitch/files/lib/dpif-solaris.h Thu Jan 19 16:57:09 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -36,5 +36,6 @@
void dpif_log(int, const char *, ...);
void dpif_solaris_migrate_internal_port(const char *, const char *);
struct netdev *dpif_solaris_obtain_netdev_to_migrate(char *, bool *);
+void dpif_solaris_send_rarp(const char *);
#endif /* DPIF_SOLARIS_H */
--- a/components/openvswitch/files/lib/netdev-solaris.c Thu Jan 19 14:29:43 2017 -0800
+++ b/components/openvswitch/files/lib/netdev-solaris.c Thu Jan 19 16:57:09 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -81,6 +81,8 @@
/* Protects all members below. */
struct ovs_mutex mutex;
+ boolean_t rarp_sent;
+
/*
* Bit mask of cached properties. These can be cached because
* nothing besides vswitchd is altering the properties.
@@ -147,6 +149,7 @@
static int netdev_solaris_init(void);
static struct netdev_solaris *netdev_solaris_cast(const struct netdev *);
+static void netdev_solaris_send_rarp(const struct netdev *);
/* Maintaining a mapping of every netdev->name to its bridge name. */
struct shash port_to_bridge_map = SHASH_INITIALIZER(&port_to_bridge_map);
@@ -702,6 +705,28 @@
static void
netdev_solaris_run(void)
{
+ struct shash device_shash;
+ struct shash_node *node;
+
+ shash_init(&device_shash);
+ netdev_get_devices(&netdev_solaris_class, &device_shash);
+ SHASH_FOR_EACH(node, &device_shash) {
+ struct netdev *netdev = node->data;
+ struct netdev_solaris *dev = netdev_solaris_cast(netdev);
+
+ /*
+ * No lock is needed to protect dev->rarp_sent. Because
+ * netdev_solaris_run() is called single threaded in the
+ * main() function.
+ */
+ if (!dev->rarp_sent) {
+ netdev_solaris_send_rarp(netdev);
+ dev->rarp_sent = B_TRUE;
+ }
+ netdev_close(netdev);
+ }
+
+ shash_destroy(&device_shash);
}
static void
@@ -714,6 +739,7 @@
{
struct netdev_solaris *netdev = xzalloc(sizeof (*netdev));
+ netdev->rarp_sent = B_FALSE;
return (&netdev->up);
}
@@ -1198,6 +1224,24 @@
return (solaris_is_uplink_class(netdev->class));
}
+/*
+ * Send an Reverse ARP for this link, if it is not an uplink.
+ */
+static void
+netdev_solaris_send_rarp(const struct netdev *netdev_)
+{
+ const char *netdev_name = netdev_get_name(netdev_);
+
+ VLOG_DBG("netdev_solaris_send_rarp:send RARP device %s", netdev_name);
+
+ if (netdev_solaris_is_uplink(netdev_)) {
+ VLOG_DBG("netdev_solaris_send_rarp: uplink\n");
+ return;
+ }
+
+ dpif_solaris_send_rarp(netdev_name);
+}
+
static int
netdev_solaris_get_etheraddr(const struct netdev *netdev_,
uint8_t mac[ETH_ADDR_LEN])
--- a/components/openvswitch/files/lib/util-solaris.c Thu Jan 19 14:29:43 2017 -0800
+++ b/components/openvswitch/files/lib/util-solaris.c Thu Jan 19 16:57:09 2017 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
*/
#include <config.h>
@@ -47,8 +47,10 @@
#include <libdllink.h>
#include <zone.h>
#include <net/if_types.h>
+#include <net/if_arp.h>
#include <inet/arp.h>
#include <sys/socket.h>
+#include <sys/ethernet.h>
#include <netdb.h>
#include <rad/radclient.h>
#include <rad/client/1/dlmgr.h>
@@ -81,6 +83,10 @@
uint32_t ofp_max;
} ofport_range_t;
+static ether_addr_t bcast_addr = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
static int
extract_uint(const char *valstr, uint_t *val)
{
@@ -1591,6 +1597,7 @@
char dstr[DLADM_STRSIZE];
int err = 0;
boolean_t is_arp = (ntohs(f->dl_type) == 0x806);
+ boolean_t is_rarp = (ntohs(f->dl_type) == 0x8035);
dstr[0] = '\0';
if (f->dl_type != htons(FLOW_DL_TYPE_NONE)) {
@@ -1600,7 +1607,7 @@
goto out;
}
- if (is_arp) {
+ if (is_arp || is_rarp) {
if (f->nw_proto != 0 || m->nw_proto != 0) {
err = dlmgr_DLValue_fm_putulong(ddvp, ddmp, "arp-op",
f->nw_proto, m->nw_proto, dstr, sizeof (dstr));
@@ -1626,22 +1633,25 @@
goto out;
}
- flow_addr2str(NULL, NULL, f->nw_src, m->nw_src, buf, rbuf,
- sizeof (buf), sizeof (rbuf));
- if (strlen(buf) != 0) {
- err = dlmgr_DLValue_fm_putstring(ddvp, ddmp, "arp-sip",
- buf, rbuf, dstr, sizeof (dstr));
- if (err != 0)
- goto out;
- }
-
- flow_addr2str(NULL, NULL, f->nw_dst, m->nw_dst, buf, rbuf,
- sizeof (buf), sizeof (rbuf));
- if (strlen(buf) != 0) {
- err = dlmgr_DLValue_fm_putstring(ddvp, ddmp, "arp-tip",
- buf, rbuf, dstr, sizeof (dstr));
- if (err != 0)
- goto out;
+ /* sip and tip of REVARP_REQUEST is undefined */
+ if (f->nw_proto != REVARP_REQUEST) {
+ flow_addr2str(NULL, NULL, f->nw_src, m->nw_src, buf,
+ rbuf, sizeof (buf), sizeof (rbuf));
+ if (strlen(buf) != 0) {
+ err = dlmgr_DLValue_fm_putstring(ddvp, ddmp,
+ "arp-sip", buf, rbuf, dstr, sizeof (dstr));
+ if (err != 0)
+ goto out;
+ }
+
+ flow_addr2str(NULL, NULL, f->nw_dst, m->nw_dst, buf,
+ rbuf, sizeof (buf), sizeof (rbuf));
+ if (strlen(buf) != 0) {
+ err = dlmgr_DLValue_fm_putstring(ddvp, ddmp,
+ "arp-tip", buf, rbuf, dstr, sizeof (dstr));
+ if (err != 0)
+ goto out;
+ }
}
} else {
if (f->nw_proto != 0 || m->nw_proto != 0) {
@@ -2568,6 +2578,9 @@
status = dlmgr__rad_dict_string_DLValue_map(mdict,
solaris_flowinfo2flowmap, m);
+ /* IP fragmentation is not supported, always return 0xff for its mask */
+ if (is_ip_any(f))
+ m->nw_frag = 0xff;
dlmgr_DLValue_free(mlist);
if (status != RCE_OK)
return (EINVAL);
@@ -3968,3 +3981,62 @@
kstat2_close(&handle);
}
+
+#define ARH_FIXED_LEN 8
+/*
+ * Send RARP packet on the given socket using the given MAC addresses.
+ * Need to work with multiple MAC addresses
+ */
+int
+solaris_send_rarp(int sockfd, const uint8_t *hwaddr)
+{
+ int count;
+ uint8_t rarp_pkt[ETHERMIN];
+ struct ether_header *ehp;
+ struct arphdr *arh;
+ uint8_t *cp;
+ uint8_t *cp1;
+ uint8_t plen = 4;
+ int naddrs = 1;
+ int err;
+
+ bzero(rarp_pkt, ETHERMIN);
+ ehp = (struct ether_header *)rarp_pkt;
+ bcopy(&bcast_addr, &ehp->ether_dhost, ETHERADDRL);
+ ehp->ether_type = htons(ETHERTYPE_REVARP);
+ arh = (struct arphdr *)(rarp_pkt + sizeof (struct ether_header));
+ cp = (uint8_t *)arh;
+ arh->ar_hrd = htons(ARPHRD_ETHER);
+ arh->ar_pro = htons(ETHERTYPE_IP);
+ arh->ar_hln = ETHERADDRL;
+ arh->ar_pln = plen;
+ arh->ar_op = htons(REVARP_REQUEST);
+
+ cp += ARH_FIXED_LEN;
+ cp1 = cp;
+ /* For now, only one ethernet address is supported */
+ for (count = 0; count < naddrs; count++) {
+ cp = cp1;
+ bcopy(hwaddr, &ehp->ether_shost, ETHERADDRL);
+ bcopy(hwaddr, cp, ETHERADDRL);
+ cp += ETHERADDRL;
+ bzero(cp, plen);
+ cp += plen;
+
+ bcopy(hwaddr, cp, ETHERADDRL);
+ cp += ETHERADDRL;
+ bzero(cp, plen);
+
+ /*
+ * Send the packet; Sending only one, we could send
+ * multiple with an interval between them.
+ */
+ errno = 0;
+ if (send(sockfd, (void *)rarp_pkt, ETHERMIN, 0) < 0) {
+ err = errno;
+ dpif_log(err, "RARP send() failed");
+ return (err);
+ }
+ }
+ return (0);
+}
--- a/components/openvswitch/files/lib/util-solaris.h Thu Jan 19 14:29:43 2017 -0800
+++ b/components/openvswitch/files/lib/util-solaris.h Thu Jan 19 16:57:09 2017 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef UTIL_SOLARIS_H
@@ -103,6 +103,7 @@
boolean_t solaris_dlparse_zonelinkname(const char *, char *, zoneid_t *);
void solaris_parse_cpuinfo(long int *);
+int solaris_send_rarp(int, const uint8_t *);
#define SOLARIS_MAX_BUFSIZE 1024
#endif /* UTIL_SOLARIS_H */