--- a/components/openvswitch/files/lib/dpif-solaris.c Fri Aug 05 11:10:27 2016 -0700
+++ b/components/openvswitch/files/lib/dpif-solaris.c Fri Aug 05 17:24:49 2016 -0700
@@ -165,7 +165,8 @@
OVS_REQ_RDLOCK(dpif->port_rwlock);
static int
dpif_solaris_get_uplink_port_info(struct dpif_solaris *dpif,
- odp_port_t port_no, odp_port_t *uport_nop, int *xfdp);
+ odp_port_t port_no, odp_port_t *uport_nop, int *xfdp,
+ enum ovs_vport_type *vtypep);
static void dpif_solaris_flow_remove(struct dpif_solaris *dpif,
struct dpif_solaris_flow *flow)
OVS_REQ_WRLOCK(dpif->flow_rwlock);
@@ -857,7 +858,8 @@
static int
dpif_solaris_get_uplink_port_info(struct dpif_solaris *dpif,
- odp_port_t port_no, odp_port_t *uport_nop, int *xfdp)
+ odp_port_t port_no, odp_port_t *uport_nop, int *xfdp,
+ enum ovs_vport_type *vtypep)
{
struct dpif_solaris_port *port, *uport;
@@ -869,6 +871,9 @@
if (port == NULL)
goto done;
+ if (vtypep != NULL)
+ *vtypep = port->vtype;
+
HMAP_FOR_EACH(uport, node, &dpif->ports) {
if (uport->is_uplink &&
strcmp(port->physname, uport->linkname) == 0) {
@@ -1380,7 +1385,7 @@
ovs_rwlock_unlock(&dpif->port_rwlock);
if (error != 0) {
VLOG_DBG("dpif_solaris_get_priority_details: "
- "Error getting port %d\n", outport);
+ "failed to get port %d\n", outport);
return (error);
}
@@ -1388,7 +1393,7 @@
error = netdev_get_queue(netdev, queueid, details);
if (error != 0) {
VLOG_DBG("dpif_solaris_get_priority_details: "
- " Error getting queue %d\n", queueid);
+ "failed to get queue %d\n", queueid);
return (error);
}
VLOG_DBG("dpif_solaris_get_priority_details: done");
@@ -1505,7 +1510,7 @@
}
} else {
VLOG_DBG("dpif_solaris_flow_put(): "
- "Error getting inport %d\n", inport);
+ "failed to get inport %d\n", inport);
}
} else {
VLOG_ERR("dpif_solaris_flow_put mask %s "
@@ -1888,7 +1893,8 @@
VLOG_DBG("dpif_solaris_port_output %d tunnel %ld", port_no,
tnl == NULL ? 0 : tnl->tun_id);
- error = dpif_solaris_get_uplink_port_info(dpif, port_no, NULL, &fd);
+ error = dpif_solaris_get_uplink_port_info(dpif, port_no, NULL,
+ &fd, NULL);
if (error != 0 || fd == -1) {
if (may_steal) {
ofpbuf_delete(packet);
@@ -2085,6 +2091,7 @@
int type = nl_attr_type(a);
odp_port_t pin, pout;
struct flow_tnl *tnl = NULL;
+ enum ovs_vport_type vtype;
int err;
VLOG_DBG("dp_solaris_execute_cb type %d", type);
@@ -2101,25 +2108,34 @@
/*
* If in_port number is OFPP_NONE, this means this packet out
* request comes from the controller.
+ *
+ * if the in or outport is the internal port, and its uplink
+ * can not be found, it means there is no physical uplink
+ * added to the bridge yet, directly drop the packet.
*/
if (md->in_port.odp_port != ODPP_NONE) {
err = dpif_solaris_get_uplink_port_info(dpif,
- md->in_port.odp_port, &pin, NULL);
+ md->in_port.odp_port, &pin, NULL, &vtype);
if (err != 0) {
- VLOG_DBG("dp_solaris_execute_cb "
- "OVS_ACTION_ATTR_OUTPUT Error getting "
- "uplink for inport %d ",
- md->in_port.odp_port);
+ if (vtype != OVS_VPORT_TYPE_INTERNAL) {
+ VLOG_DBG("dp_solaris_execute_cb "
+ "OVS_ACTION_ATTR_OUTPUT failed to"
+ "get uplink for inport %d ",
+ md->in_port.odp_port);
+ }
if (may_steal)
ofpbuf_delete(packet);
break;
}
err = dpif_solaris_get_uplink_port_info(dpif, port_no,
- &pout, NULL);
+ &pout, NULL, &vtype);
if (err != 0) {
- VLOG_DBG("dp_solaris_execute_cb "
- "OVS_ACTION_ATTR_OUTPUT Error getting "
- "uplink for outport %d ", port_no);
+ if (vtype != OVS_VPORT_TYPE_INTERNAL) {
+ VLOG_DBG("dp_solaris_execute_cb "
+ "OVS_ACTION_ATTR_OUTPUT failed to "
+ "get uplink for outport %d",
+ port_no);
+ }
if (may_steal)
ofpbuf_delete(packet);
break;
@@ -2160,11 +2176,20 @@
VLOG_DBG("dp_solaris_execute_cb OVS_ACTION_ATTR_USERSPACE");
err = dpif_solaris_get_uplink_port_info(dpif,
- md->in_port.odp_port, &pin, NULL);
+ md->in_port.odp_port, &pin, NULL, &vtype);
if (err != 0) {
- VLOG_DBG("dp_solaris_execute_cb OVS_ACTION_ATTR_OUTPUT "
- "Error getting uplink for inport %d",
- md->in_port.odp_port);
+ if (vtype != OVS_VPORT_TYPE_INTERNAL) {
+ VLOG_DBG("dp_solaris_execute_cb "
+ "OVS_ACTION_ATTR_USERSPACE failed to get "
+ "uplink for inport %d",
+ md->in_port.odp_port);
+ } else {
+ VLOG_DBG("dp_solaris_execute_cb "
+ "OVS_ACTION_ATTR_USERSPACE from an internal"
+ "port %d which is not associated with a "
+ "physical uplink",
+ md->in_port.odp_port);
+ }
if (may_steal)
ofpbuf_delete(packet);
break;
--- a/components/openvswitch/files/lib/util-solaris.c Fri Aug 05 11:10:27 2016 -0700
+++ b/components/openvswitch/files/lib/util-solaris.c Fri Aug 05 17:24:49 2016 -0700
@@ -62,6 +62,10 @@
#include "util.h"
#include "dpif-solaris.h"
+#ifndef MAX_OF_ACTIONS_SIZE
+#define MAX_OF_ACTIONS_SIZE 4096
+#endif
+
static rc_conn_t *rad_conn = NULL;
static boolean_t b_true = B_TRUE;
@@ -72,6 +76,11 @@
char ifsp_devnm[LIFNAMSIZ]; /* only the device name */
} ifspec_t;
+typedef struct {
+ uint32_t ofp_min;
+ uint32_t ofp_max;
+} ofport_range_t;
+
static int
extract_uint(const char *valstr, uint_t *val)
{
@@ -1280,36 +1289,115 @@
#define FP_NAME_VAL_DELIM '@'
#define FP_MULTI_ACTION_DELIM '#'
#define FP_ACTION_NAME_VALUE_DELIM '-'
+#define FP_ACTION_PORT_RANGE_DELIM ':'
#define FP_ACTION_MULTI_VAL_DELIM '^'
#define FP_MULTI_ACTION_DELIM_STR "#"
static int
+uint32cmp(const void *a, const void *b)
+{
+ return (*(uint32_t *)a - *(uint32_t *)b);
+}
+
+static int
+ofport_list2range(uint32_t *ofports, int nofports, ofport_range_t **range,
+ int *range_cnt)
+{
+ int i, nr = 1;
+ uint32_t *sort32;
+ ofport_range_t *ur;
+
+ sort32 = malloc(nofports * sizeof (uint32_t));
+ if (sort32 == NULL)
+ return (ENOMEM);
+
+ for (i = 0; i < nofports; i++)
+ sort32[i] = ofports[i];
+
+ if (nofports > 1)
+ qsort(sort32, nofports, sizeof (uint32_t), uint32cmp);
+
+ ur = *range;
+ ur->ofp_min = ur->ofp_max = sort32[0];
+
+ for (i = 1; i < nofports; i++) {
+ if (sort32[i] - sort32[i-1] == 1) {
+ ur->ofp_max = sort32[i];
+ } else {
+ ur++; nr++;
+ ur->ofp_min = ur->ofp_max = sort32[i];
+ }
+ }
+ free(sort32);
+ *range_cnt = nr;
+ return (0);
+}
+
+static int
flow_ofports2propstr(char *str, size_t strsize, uint32_t *ofports,
int nofports)
{
char buf[DLADM_STRSIZE];
- int i;
+ int i, err, range_cnt;
+ ofport_range_t *ofports_range;
if (nofports == 0) {
- (void) snprintf(buf, sizeof (buf), "%soutports%cdrop",
+ if (snprintf(buf, sizeof (buf), "%soutports%cdrop",
strlen(str) == 0 ? "" : FP_MULTI_ACTION_DELIM_STR,
- FP_NAME_VAL_DELIM);
+ FP_NAME_VAL_DELIM) >= sizeof (buf)) {
+ return (ENOBUFS);
+ }
if (strlcat(str, buf, strsize) >= strsize)
- return (EINVAL);
+ return (ENOBUFS);
return (0);
}
- for (i = 0; i < nofports; i++) {
- (void) snprintf(buf, sizeof (buf), "%soutports%c%u",
- (i == 0) && strlen(str) == 0 ? "" :
- FP_MULTI_ACTION_DELIM_STR, FP_NAME_VAL_DELIM, ofports[i]);
+ ofports_range = malloc(nofports * sizeof (ofport_range_t));
+ if (ofports_range == NULL)
+ return (ENOMEM);
+
+ err = ofport_list2range(ofports, nofports, &ofports_range, &range_cnt);
+ if (err != 0) {
+ free(ofports_range);
+ return (err);
+ }
+
+ if (snprintf(buf, sizeof (buf), "%soutports", strlen(str) == 0 ? "" :
+ FP_MULTI_ACTION_DELIM_STR) >= sizeof (buf)) {
+ goto no_buffer;
+ }
+
+ if (strlcat(str, buf, strsize) >= strsize)
+ goto no_buffer;
+
+ for (i = 0; i < range_cnt; i++) {
+ if (ofports_range[i].ofp_min == ofports_range[i].ofp_max) {
+ if (snprintf(buf, sizeof (buf), "%c%u", (i == 0) ?
+ FP_NAME_VAL_DELIM : FP_ACTION_MULTI_VAL_DELIM,
+ ofports_range[i].ofp_min) >= sizeof (buf)) {
+ goto no_buffer;
+ }
+ } else {
+ if (snprintf(buf, sizeof (buf), "%c%u%c%u",
+ (i == 0) ? FP_NAME_VAL_DELIM :
+ FP_ACTION_MULTI_VAL_DELIM, ofports_range[i].ofp_min,
+ FP_ACTION_PORT_RANGE_DELIM,
+ ofports_range[i].ofp_max) >= sizeof (buf)) {
+ goto no_buffer;
+ }
+ }
if (strlcat(str, buf, strsize) >= strsize)
- return (EINVAL);
+ goto no_buffer;
}
+ free(ofports_range);
return (0);
+
+no_buffer:
+ free(ofports_range);
+ return (ENOBUFS);
}
static int
@@ -1652,6 +1740,47 @@
goto out;
}
+ if (f->tunnel.ip_dst) {
+ err = dlmgr_DLValue_fm_putulong(ddvp, ddmp,
+ "tun-id", ntohll(f->tunnel.tun_id),
+ ntohll(m->tunnel.tun_id), dstr, sizeof (dstr));
+ if (err != 0)
+ goto out;
+
+ flow_addr2str(NULL, NULL, f->tunnel.ip_src, m->tunnel.ip_src,
+ buf, rbuf, sizeof (buf), sizeof (rbuf));
+ if (strlen(buf) != 0) {
+ err = dlmgr_DLValue_fm_putstring(ddvp, ddmp,
+ "tun-local-ip", buf, rbuf, dstr, sizeof (dstr));
+ if (err != 0)
+ goto out;
+ }
+
+ flow_addr2str(NULL, NULL, f->tunnel.ip_dst, m->tunnel.ip_dst,
+ buf, rbuf, sizeof (buf), sizeof (rbuf));
+ if (strlen(buf) != 0) {
+ err = dlmgr_DLValue_fm_putstring(ddvp, ddmp,
+ "tun-remote-ip", buf, rbuf, dstr, sizeof (dstr));
+ if (err != 0)
+ goto out;
+ }
+
+ err = dlmgr_DLValue_fm_putulong(ddvp, ddmp, "tun-dsfield",
+ f->tunnel.ip_tos, m->tunnel.ip_tos, dstr, sizeof (dstr));
+ if (err != 0)
+ goto out;
+
+ err = dlmgr_DLValue_fm_putulong(ddvp, ddmp, "tun-ttl",
+ f->tunnel.ip_ttl, m->tunnel.ip_ttl, dstr, sizeof (dstr));
+ if (err != 0)
+ goto out;
+
+ err = dlmgr_DLValue_fm_putulong(ddvp, ddmp, "tun-flags",
+ f->tunnel.flags, m->tunnel.flags, dstr, sizeof (dstr));
+ if (err != 0)
+ goto out;
+ }
+
out:
dpif_log(err, "solaris_flow_to_DLVal FLOWATTR: %s", dstr);
return (err);
@@ -1699,19 +1828,19 @@
{
char *sstr = NULL, *dstr = NULL;
char buf[DLADM_STRSIZE];
- int err = 0;
+ int err = ENOBUFS;
sstr = _link_ntoa(ek->eth_src, NULL, ETHERADDRL, IFT_ETHER);
dstr = _link_ntoa(ek->eth_dst, NULL, ETHERADDRL, IFT_ETHER);
if (sstr != NULL && dstr != NULL) {
- (void) snprintf(buf, sizeof (buf),
- "%ssetether%cether_src%c%s%cether_dst%c%s",
+ if (snprintf(buf, sizeof (buf),
+ "%sset-ether%cether_src%c%s%cether_dst%c%s",
(strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
FP_NAME_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM, sstr,
FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
- dstr);
- if (strlcat(str, buf, strsize) >= strsize)
- err = EINVAL;
+ dstr) < sizeof (buf) &&
+ strlcat(str, buf, strsize) < strsize)
+ err = 0;
}
free(sstr);
free(dstr);
@@ -1727,28 +1856,30 @@
struct in_addr ipaddr;
char *cp;
char buf[DLADM_STRSIZE];
- int err = 0;
ipaddr.s_addr = ipv4->ipv4_src;
cp = inet_ntoa(ipaddr);
- (void) snprintf(buf, sizeof (buf), "%sset-ipv4%cdst%c%s%c",
+ if (snprintf(buf, sizeof (buf), "%sset-ipv4%csrc%c%s%c",
(strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
FP_NAME_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM, cp,
- FP_ACTION_MULTI_VAL_DELIM);
+ FP_ACTION_MULTI_VAL_DELIM) >= sizeof (buf))
+ return (ENOBUFS);
ipaddr.s_addr = ipv4->ipv4_dst;
cp = inet_ntoa(ipaddr);
- (void) snprintf(buf, sizeof (buf),
+ if (snprintf(buf, sizeof (buf),
"%sdst%c%s%cprotocol%c%s%ctos%c0x%x%choplimit%c%d",
buf, FP_ACTION_NAME_VALUE_DELIM, cp, FP_ACTION_MULTI_VAL_DELIM,
FP_ACTION_NAME_VALUE_DELIM, solaris_proto2str(ipv4->ipv4_proto),
FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
ipv4->ipv4_tos, FP_ACTION_MULTI_VAL_DELIM,
- FP_ACTION_NAME_VALUE_DELIM, ipv4->ipv4_ttl);
+ FP_ACTION_NAME_VALUE_DELIM, ipv4->ipv4_ttl) >= sizeof (buf))
+ return (ENOBUFS);
+
if (strlcat(str, buf, strsize) >= strsize)
- err = EINVAL;
-
- return (err);
+ return (ENOBUFS);
+
+ return (0);
}
static int
@@ -1757,16 +1888,17 @@
{
char abuf[INET6_ADDRSTRLEN];
char buf[DLADM_STRSIZE];
- int err = 0;
(void) inet_ntop(AF_INET6, ipv6->ipv6_src, abuf, INET6_ADDRSTRLEN);
- (void) snprintf(buf, sizeof (buf),
+ if (snprintf(buf, sizeof (buf),
"%sset-ipv6%csrc%c%s%c", (strlen(str) == 0) ? "" :
FP_MULTI_ACTION_DELIM_STR, FP_NAME_VAL_DELIM,
- FP_ACTION_NAME_VALUE_DELIM, abuf, FP_ACTION_MULTI_VAL_DELIM);
+ FP_ACTION_NAME_VALUE_DELIM, abuf, FP_ACTION_MULTI_VAL_DELIM) >=
+ sizeof (buf))
+ return (ENOBUFS);
(void) inet_ntop(AF_INET6, ipv6->ipv6_dst, abuf, INET6_ADDRSTRLEN);
- (void) snprintf(buf, sizeof (buf),
+ if (snprintf(buf, sizeof (buf),
"%sdst%c%s%clabel%c0x%x%cprotocol%c%s%ctos%c0x%x%choplimit%c%d",
buf, FP_ACTION_NAME_VALUE_DELIM, abuf, FP_ACTION_MULTI_VAL_DELIM,
FP_ACTION_NAME_VALUE_DELIM, ipv6->ipv6_label,
@@ -1774,11 +1906,13 @@
solaris_proto2str(ipv6->ipv6_proto), FP_ACTION_MULTI_VAL_DELIM,
FP_ACTION_NAME_VALUE_DELIM, ipv6->ipv6_tclass,
FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
- ipv6->ipv6_hlimit);
+ ipv6->ipv6_hlimit) >= sizeof (buf))
+ return (ENOBUFS);
+
if (strlcat(str, buf, strsize) >= strsize)
- err = EINVAL;
-
- return (err);
+ return (ENOBUFS);
+
+ return (0);
}
static int
@@ -1786,17 +1920,18 @@
uint16_t src, uint16_t dst)
{
char buf[DLADM_STRSIZE];
- int err = 0;
-
- (void) snprintf(buf, sizeof (buf),
+
+ if (snprintf(buf, sizeof (buf),
"%s%s%csport%c%d%cdport%c%d", (strlen(str) == 0) ? "" :
FP_MULTI_ACTION_DELIM_STR, key, FP_NAME_VAL_DELIM,
FP_ACTION_NAME_VALUE_DELIM, src, FP_ACTION_MULTI_VAL_DELIM,
- FP_ACTION_NAME_VALUE_DELIM, dst);
+ FP_ACTION_NAME_VALUE_DELIM, dst) >= sizeof (buf))
+ return (ENOBUFS);
+
if (strlcat(str, buf, strsize) >= strsize)
- err = EINVAL;
-
- return (err);
+ return (ENOBUFS);
+
+ return (0);
}
static int
@@ -1806,28 +1941,30 @@
struct in_addr ipaddr;
char *cp;
char buf[DLADM_STRSIZE];
- int err = 0;
ipaddr.s_addr = tnl->ip_src;
cp = inet_ntoa(ipaddr);
- (void) snprintf(buf, sizeof (buf), "%sset-tunnel%csrc%c%s%c",
+ if (snprintf(buf, sizeof (buf), "%sset-tunnel%csrc%c%s%c",
(strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
FP_NAME_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM, cp,
- FP_ACTION_MULTI_VAL_DELIM);
+ FP_ACTION_MULTI_VAL_DELIM) >= sizeof (buf))
+ return (ENOBUFS);
ipaddr.s_addr = tnl->ip_dst;
cp = inet_ntoa(ipaddr);
- (void) snprintf(buf, sizeof (buf),
+ if (snprintf(buf, sizeof (buf),
"%sdst%c%s%ctun_id%c0x%"PRIx64"%ctos%c0x%x%choplimit%c%d",
buf, FP_ACTION_NAME_VALUE_DELIM, cp, FP_ACTION_MULTI_VAL_DELIM,
FP_ACTION_NAME_VALUE_DELIM, ntohll(tnl->tun_id),
FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
tnl->ip_tos, FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
- tnl->ip_ttl);
+ tnl->ip_ttl) >= sizeof (buf))
+ return (ENOBUFS);
+
if (strlcat(str, buf, strsize) >= strsize)
- err = EINVAL;
-
- return (err);
+ return (ENOBUFS);
+
+ return (0);
}
static int
@@ -1837,9 +1974,9 @@
{
const struct nlattr *a;
unsigned int left;
- char buf[DLADM_STRSIZE];
- char str[DLADM_STRSIZE];
- char dstr[DLADM_STRSIZE];
+ char buf[MAX_OF_ACTIONS_SIZE];
+ char str[MAX_OF_ACTIONS_SIZE];
+ char dstr[MAX_OF_ACTIONS_SIZE];
int err = 0, nofports = 0;
uint32_t ofports[MAC_OF_MAXPORT];
enum ovs_action_attr type = -1, lasttype;
@@ -1864,8 +2001,6 @@
if ((type != OVS_ACTION_ATTR_OUTPUT) ||
(lasttype != OVS_ACTION_ATTR_OUTPUT)) {
if (lasttype == OVS_ACTION_ATTR_OUTPUT) {
- dpif_log(0, "solaris_nlattr_to_DLVal outports "
- "total %d ports", nofports);
err = flow_ofports2propstr(str, sizeof (str),
ofports, nofports);
if (err != 0)
@@ -1884,8 +2019,6 @@
err = ENOBUFS;
break;
}
- dpif_log(0, "solaris_nlattr_to_DLVal %d ports: %u",
- nofports+1, nl_attr_get_u32(a));
ofports[nofports++] = u32_to_odp(nl_attr_get_u32(a));
break;
case OVS_ACTION_ATTR_USERSPACE: {
@@ -1917,12 +2050,16 @@
if (cookie.slow_path.reason != SLOW_CONTROLLER)
break;
- (void) snprintf(buf, sizeof (buf), "%scontroller%c%u",
+ if (snprintf(buf, sizeof (buf), "%scontroller%c%u",
(strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
- FP_NAME_VAL_DELIM, PORT_PF_PACKET_UPLINK);
+ FP_NAME_VAL_DELIM, PORT_PF_PACKET_UPLINK) >=
+ sizeof (buf)) {
+ err = ENOBUFS;
+ break;
+ }
if (strlcat(str, buf, sizeof (str)) >= sizeof (str)) {
- err = EINVAL;
+ err = ENOBUFS;
break;
}
break;
@@ -2014,23 +2151,30 @@
vlan = nl_attr_get_unspec(a,
sizeof (struct ovs_action_push_vlan));
- (void) snprintf(buf, sizeof (buf), "%svlan-tag%c%u",
+ if (snprintf(buf, sizeof (buf), "%svlan-tag%c%u",
(strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
- FP_NAME_VAL_DELIM, ntohs(vlan->vlan_tci));
+ FP_NAME_VAL_DELIM, ntohs(vlan->vlan_tci)) >=
+ sizeof (buf)) {
+ err = ENOBUFS;
+ break;
+ }
if (strlcat(str, buf, sizeof (str)) >= sizeof (str)) {
- err = EINVAL;
+ err = ENOBUFS;
break;
}
break;
}
case OVS_ACTION_ATTR_POP_VLAN:
- (void) snprintf(buf, sizeof (buf), "%svlan-strip%c%s",
+ if (snprintf(buf, sizeof (buf), "%svlan-strip%c%s",
(strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
- FP_NAME_VAL_DELIM, "on");
+ FP_NAME_VAL_DELIM, "on") >= sizeof (buf)) {
+ err = ENOBUFS;
+ break;
+ }
if (strlcat(str, buf, sizeof (str)) >= sizeof (str)) {
- err = EINVAL;
+ err = ENOBUFS;
break;
}
break;
@@ -2065,8 +2209,7 @@
sizeof (dstr));
out:
- if (err == 0)
- dpif_log(err, "solaris_nlattr_to_DLVal %s", dstr);
+ dpif_log(err, "solaris_nlattr_to_DLVal %s %d", dstr, err);
return (err);
}
@@ -2312,8 +2455,25 @@
bcopy(&fa, &f->nd_target, sizeof (f->nd_target));
} else if (strcmp(key, "tcp-flags") == 0) {
f->tcp_flags = htons((uint16_t)*val->ddlv_ulval);
+ } else if (strcmp(key, "tun-id") == 0) {
+ f->tunnel.tun_id = htonll((uint64_t)*val->ddlv_ulval);
+ } else if (strcmp(key, "tun-local-ip") == 0 ||
+ strcmp(key, "tun-remote-ip") == 0) {
+ err = flow_str2addr(val->ddlv_sval, &fa, &af);
+ if (err != 0 || af != AF_INET)
+ goto out;
+ IN6_V4MAPPED_TO_INADDR(&fa, &v4);
+ if (strcmp(key, "tun-local-ip") == 0)
+ f->tunnel.ip_src = v4.s_addr;
+ else
+ f->tunnel.ip_dst = v4.s_addr;
+ } else if (strcmp(key, "tun-dsfield") == 0) {
+ f->tunnel.ip_tos = (uint8_t)*val->ddlv_ulval;
+ } else if (strcmp(key, "tun-ttl") == 0) {
+ f->tunnel.ip_ttl = (uint8_t)*val->ddlv_ulval;
+ } else if (strcmp(key, "tun-flags") == 0) {
+ f->tunnel.flags = (uint16_t)*val->ddlv_ulval;
}
-
out:
if (err != 0)
dpif_log(err, "solaris_flowinfo2flowmap %s failed", key);
@@ -2402,9 +2562,10 @@
}
static int
-flow_propval2action_outports_drop(char **propvals, int nval OVS_UNUSED,
+flow_propval2action_outports_drop(char **propvals, int nval,
struct ofpbuf *action)
{
+ int i;
char *endp = NULL;
int64_t n;
@@ -2412,11 +2573,13 @@
return (0);
errno = 0;
- n = strtoull(propvals[0], &endp, 10);
- if ((errno != 0) || *endp != '\0')
- return (EINVAL);
-
- nl_msg_put_u32(action, OVS_ACTION_ATTR_OUTPUT, (uint32_t)n);
+ for (i = 0; i < nval; i++) {
+ n = strtoull(propvals[i], &endp, 10);
+ if ((errno != 0) || *endp != '\0')
+ return (EINVAL);
+ nl_msg_put_u32(action, OVS_ACTION_ATTR_OUTPUT, (uint32_t)n);
+ }
+
return (0);
}
@@ -2676,7 +2839,7 @@
goto out;
tos_set = B_TRUE;
ipv6.ipv6_tclass = value;
- } else if (strcmp(pval, "ttl") == 0) {
+ } else if (strcmp(pval, "hoplimit") == 0) {
if (ipv6.ipv6_hlimit != 0)
goto out;
errno = 0;
@@ -2943,22 +3106,72 @@
dpif_log(0, "flow_propstr2vals key %s val %s", key, val);
len = strlen(val);
- for (i = 0, j = 0, curr = val; i < len; i++) {
- if ((c = val[i]) != FP_ACTION_MULTI_VAL_DELIM && i != len -1)
- continue;
-
- if (c == FP_ACTION_MULTI_VAL_DELIM)
- val[i] = '\0';
-
- if (strlcpy(propvals[j++], curr, DLADM_PROP_VAL_MAX) >=
- DLADM_PROP_VAL_MAX) {
- dpif_log(EINVAL, "flow_propstr2vals key %s %dth string "
- "too long %s", key, j - 1, curr);
- return (EINVAL);
+
+ if (strcmp(key, "outports") == 0) {
+ char *ofp_min, *ofp_max, *tmp = NULL, *endp = NULL;
+ char ofport_val[10];
+ uint32_t of_min, of_max, i_of;
+ boolean_t match, is_range;
+ match = is_range = B_FALSE;
+ ofp_min = ofp_max = val;
+
+ for (i = 0, j = 0, curr = val; i < len; i++) {
+ ofp_min = ofp_max = curr;
+ c = val[i];
+ match = (c == FP_ACTION_MULTI_VAL_DELIM ||
+ c == FP_ACTION_PORT_RANGE_DELIM);
+ if (!match && i != len -1)
+ continue;
+ if (match)
+ val[i] = '\0';
+
+ if (c == FP_ACTION_PORT_RANGE_DELIM) {
+ tmp = curr;
+ curr = val + i + 1;
+ is_range = B_TRUE;
+ continue;
+ }
+
+ if (is_range == B_TRUE) {
+ ofp_min = tmp;
+ is_range = B_FALSE;
+ }
+ of_min = (uint32_t)strtoul(ofp_min, &endp, 10);
+ of_max = (uint32_t)strtoul(ofp_max, &endp, 10);
+
+ for (i_of = of_min; i_of <= of_max; i_of++) {
+ bzero(ofport_val, sizeof (ofport_val));
+ snprintf(ofport_val, sizeof (ofport_val), "%u",
+ i_of);
+
+ if (strlcpy(propvals[j++], ofport_val,
+ DLADM_PROP_VAL_MAX) >= DLADM_PROP_VAL_MAX) {
+ dpif_log(EINVAL, "flow_propstr2vals"
+ "key %s %dth string too long %s",
+ key, j - 1, ofport_val);
+ return (EINVAL);
+ }
+ }
+ curr = val + i + 1;
}
- curr = val + i + 1;
+ } else {
+ for (i = 0, j = 0, curr = val; i < len; i++) {
+ if ((c = val[i]) != FP_ACTION_MULTI_VAL_DELIM &&
+ i != len -1)
+ continue;
+
+ if (c == FP_ACTION_MULTI_VAL_DELIM)
+ val[i] = '\0';
+
+ if (strlcpy(propvals[j++], curr, DLADM_PROP_VAL_MAX) >=
+ DLADM_PROP_VAL_MAX) {
+ dpif_log(EINVAL, "flow_propstr2vals key %s %dth"
+ " string too long %s", key, j - 1, curr);
+ return (EINVAL);
+ }
+ curr = val + i + 1;
+ }
}
-
*valcntp = j;
for (i = 0; i < j; i++)
dpif_log(0, "flow_propstr2vals key %s %dth: %s", key, i+1,
@@ -2969,7 +3182,7 @@
static int
flow_propval2action_ofaction(char *propval, struct ofpbuf *action)
{
- char ofaction_str[DLADM_STRSIZE];
+ char ofaction_str[4096];
char **pvals, *buf = NULL;
size_t len;
char *curr, *key, c;
@@ -3068,7 +3281,7 @@
void *arg)
{
struct ofpbuf *action = arg;
- char propval[DLADM_STRSIZE];
+ char propval[4096];
int valcnt, err = 0;
switch (val->ddlv_type) {
@@ -3078,7 +3291,7 @@
if (strlen(val->ddlv_sval) == 0)
goto out;
valcnt = 1;
- if (strlcpy(propval, val->ddlv_sval, DLADM_STRSIZE) >=
+ if (strlcpy(propval, val->ddlv_sval, sizeof (propval)) >=
DLADM_STRSIZE)
goto out;
break;
@@ -3088,7 +3301,7 @@
valcnt = val->ddlv_slist_count;
if (valcnt != 1 || strlen(val->ddlv_slist[0]) == 0)
goto out;
- if (strlcpy(propval, val->ddlv_slist[0], DLADM_STRSIZE) >=
+ if (strlcpy(propval, val->ddlv_slist[0], sizeof (propval)) >=
DLADM_STRSIZE)
goto out;
break;
@@ -3096,7 +3309,7 @@
if (val->ddlv_ulval == NULL || *val->ddlv_ulval == 0)
goto out;
valcnt = 1;
- (void) snprintf(propval, DLADM_STRSIZE, "%llu",
+ (void) snprintf(propval, sizeof (propval), "%llu",
*val->ddlv_ulval);
break;
case DDLVT_BOOLEAN: