components/openvswitch/files/lib/util-solaris.c
changeset 6924 e8aaad6b5075
parent 6556 692ea531a2fc
child 7000 22f549e6467a
equal deleted inserted replaced
6923:338aea22bf22 6924:e8aaad6b5075
  1339 {
  1339 {
  1340 	char	buf[DLADM_STRSIZE];
  1340 	char	buf[DLADM_STRSIZE];
  1341 	int	i, err, range_cnt;
  1341 	int	i, err, range_cnt;
  1342 	ofport_range_t	*ofports_range;
  1342 	ofport_range_t	*ofports_range;
  1343 
  1343 
  1344 	if (nofports == 0) {
  1344 
  1345 		if (snprintf(buf, sizeof (buf), "%soutports%cdrop",
  1345 	if (nofports == 0)
  1346 		    strlen(str) == 0 ? "" : FP_MULTI_ACTION_DELIM_STR,
       
  1347 		    FP_NAME_VAL_DELIM) >= sizeof (buf)) {
       
  1348 			return (ENOBUFS);
       
  1349 		}
       
  1350 
       
  1351 		if (strlcat(str, buf, strsize) >= strsize)
       
  1352 			return (ENOBUFS);
       
  1353 
       
  1354 		return (0);
  1346 		return (0);
  1355 	}
       
  1356 
  1347 
  1357 	ofports_range = malloc(nofports * sizeof (ofport_range_t));
  1348 	ofports_range = malloc(nofports * sizeof (ofport_range_t));
  1358 	if (ofports_range == NULL)
  1349 	if (ofports_range == NULL)
  1359 		return (ENOMEM);
  1350 		return (ENOMEM);
  1360 
  1351 
  1988 	    sizeof (dstr));
  1979 	    sizeof (dstr));
  1989 	if (err != 0)
  1980 	if (err != 0)
  1990 		goto out;
  1981 		goto out;
  1991 
  1982 
  1992 	/* if actions_len == 0, then the action is drop */
  1983 	/* if actions_len == 0, then the action is drop */
  1993 	if (actions_len == 0) {
  1984 	if (actions_len == 0)
  1994 		err = flow_ofports2propstr(str, sizeof (str), ofports, 0);
  1985 		goto out;
  1995 		goto out;
       
  1996 	}
       
  1997 
  1986 
  1998 	NL_ATTR_FOR_EACH_UNSAFE(a, left, actions_nlattr, actions_len) {
  1987 	NL_ATTR_FOR_EACH_UNSAFE(a, left, actions_nlattr, actions_len) {
  1999 		lasttype = type;
  1988 		lasttype = type;
  2000 		type = nl_attr_type(a);
  1989 		type = nl_attr_type(a);
  2001 		if ((type != OVS_ACTION_ATTR_OUTPUT) ||
  1990 		if ((type != OVS_ACTION_ATTR_OUTPUT) ||
  2560 
  2549 
  2561 	return (err);
  2550 	return (err);
  2562 }
  2551 }
  2563 
  2552 
  2564 static int
  2553 static int
  2565 flow_propval2action_outports_drop(char **propvals, int nval,
       
  2566     struct ofpbuf *action)
       
  2567 {
       
  2568 	int i;
       
  2569 	char *endp = NULL;
       
  2570 	int64_t n;
       
  2571 
       
  2572 	if (strcmp(propvals[0], "drop") == 0)
       
  2573 		return (0);
       
  2574 
       
  2575 	errno = 0;
       
  2576 	for (i = 0; i < nval; i++) {
       
  2577 		n = strtoull(propvals[i], &endp, 10);
       
  2578 		if ((errno != 0) || *endp != '\0')
       
  2579 			return (EINVAL);
       
  2580 		nl_msg_put_u32(action, OVS_ACTION_ATTR_OUTPUT, (uint32_t)n);
       
  2581 	}
       
  2582 
       
  2583 	return (0);
       
  2584 }
       
  2585 
       
  2586 static int
       
  2587 flow_propval2action_setpri(char **propvals OVS_UNUSED, int nval OVS_UNUSED,
  2554 flow_propval2action_setpri(char **propvals OVS_UNUSED, int nval OVS_UNUSED,
  2588     struct ofpbuf *action OVS_UNUSED)
  2555     struct ofpbuf *action OVS_UNUSED)
  2589 {
  2556 {
  2590 	/* TBD */
  2557 	/* TBD */
  2591 	return (0);
  2558 	return (0);
  2854 			if (ipv6.ipv6_label != 0)
  2821 			if (ipv6.ipv6_label != 0)
  2855 				goto out;
  2822 				goto out;
  2856 			errno = 0;
  2823 			errno = 0;
  2857 			endp = NULL;
  2824 			endp = NULL;
  2858 			value = strtoul(sep, &endp, 16);
  2825 			value = strtoul(sep, &endp, 16);
  2859 			if (errno != 0 || value == 0 || value > 0xff ||
  2826 			if (errno != 0 || value > 0xff || *endp != '\0') {
  2860 			    *endp != '\0') {
       
  2861 				goto out;
  2827 				goto out;
  2862 			}
  2828 			}
  2863 			ipv6.ipv6_label = value;
  2829 			ipv6.ipv6_label = value;
  2864 		}
  2830 		}
  2865 	}
  2831 	}
  3096 	nl_msg_end_nested(action, start_ofs);
  3062 	nl_msg_end_nested(action, start_ofs);
  3097 	return (0);
  3063 	return (0);
  3098 }
  3064 }
  3099 
  3065 
  3100 static int
  3066 static int
  3101 flow_propstr2vals(char *key, char *val, char ***propvalsp, int *valcntp)
  3067 flow_propstr2outports(char *key, char *val, uint32_t outports[], int *valcntp)
  3102 {
  3068 {
  3103 	char **propvals = *propvalsp, *curr;
  3069 	char *curr;
  3104 	int i, j, len;
  3070 	int maxcnt = *valcntp, i, j, len;
       
  3071 	char *ofp_min, *ofp_max, *tmp = NULL, *endp = NULL;
       
  3072 	uint32_t of_min, of_max, i_of;
       
  3073 	boolean_t match, is_range;
  3105 	char c;
  3074 	char c;
  3106 
  3075 
  3107 	dpif_log(0, "flow_propstr2vals key %s val %s", key, val);
  3076 	dpif_log(0, "flow_propstr2vals key %s val %s", key, val);
  3108 	len = strlen(val);
  3077 	len = strlen(val);
  3109 
  3078 
  3110 	if (strcmp(key, "outports") == 0) {
  3079 	ovs_assert(strcmp(key, "outports") == 0);
  3111 		char *ofp_min, *ofp_max, *tmp = NULL, *endp = NULL;
  3080 
  3112 		char ofport_val[10];
  3081 	match = is_range = B_FALSE;
  3113 		uint32_t of_min, of_max, i_of;
  3082 	ofp_min = ofp_max = val;
  3114 		boolean_t match, is_range;
  3083 
  3115 		match = is_range = B_FALSE;
  3084 	for (i = 0, j = 0, curr = val; i < len && j < maxcnt; i++) {
  3116 		ofp_min = ofp_max = val;
  3085 		ofp_min = ofp_max = curr;
  3117 
  3086 		c = val[i];
  3118 		for (i = 0, j = 0, curr = val; i < len; i++) {
  3087 		match = (c == FP_ACTION_MULTI_VAL_DELIM ||
  3119 			ofp_min = ofp_max = curr;
  3088 		    c == FP_ACTION_PORT_RANGE_DELIM);
  3120 			c = val[i];
  3089 		if (!match && i != len -1)
  3121 			match = (c == FP_ACTION_MULTI_VAL_DELIM ||
  3090 			continue;
  3122 			    c == FP_ACTION_PORT_RANGE_DELIM);
  3091 		if (match)
  3123 			if (!match && i != len -1)
  3092 			val[i] = '\0';
  3124 				continue;
  3093 
  3125 			if (match)
  3094 		if (c == FP_ACTION_PORT_RANGE_DELIM) {
  3126 				val[i] = '\0';
  3095 			tmp = curr;
  3127 
       
  3128 			if (c == FP_ACTION_PORT_RANGE_DELIM) {
       
  3129 				tmp = curr;
       
  3130 				curr = val + i + 1;
       
  3131 				is_range = B_TRUE;
       
  3132 				continue;
       
  3133 			}
       
  3134 
       
  3135 			if (is_range == B_TRUE) {
       
  3136 				ofp_min = tmp;
       
  3137 				is_range = B_FALSE;
       
  3138 			}
       
  3139 			of_min = (uint32_t)strtoul(ofp_min, &endp, 10);
       
  3140 			of_max = (uint32_t)strtoul(ofp_max, &endp, 10);
       
  3141 
       
  3142 			for (i_of = of_min; i_of <= of_max; i_of++) {
       
  3143 				bzero(ofport_val, sizeof (ofport_val));
       
  3144 				snprintf(ofport_val, sizeof (ofport_val), "%u",
       
  3145 				    i_of);
       
  3146 
       
  3147 				if (strlcpy(propvals[j++], ofport_val,
       
  3148 				    DLADM_PROP_VAL_MAX) >= DLADM_PROP_VAL_MAX) {
       
  3149 					dpif_log(EINVAL, "flow_propstr2vals"
       
  3150 					    "key %s %dth string too long %s",
       
  3151 					    key, j - 1, ofport_val);
       
  3152 					return (EINVAL);
       
  3153 				}
       
  3154 			}
       
  3155 			curr = val + i + 1;
  3096 			curr = val + i + 1;
  3156 		}
  3097 			is_range = B_TRUE;
  3157 	} else {
  3098 			continue;
  3158 		for (i = 0, j = 0, curr = val; i < len; i++) {
  3099 		}
  3159 			if ((c = val[i]) != FP_ACTION_MULTI_VAL_DELIM &&
  3100 
  3160 			    i != len -1)
  3101 		if (is_range == B_TRUE) {
  3161 				continue;
  3102 			ofp_min = tmp;
  3162 
  3103 			is_range = B_FALSE;
  3163 			if (c == FP_ACTION_MULTI_VAL_DELIM)
  3104 		}
  3164 				val[i] = '\0';
  3105 		of_min = (uint32_t)strtoul(ofp_min, &endp, 10);
  3165 
  3106 		of_max = (uint32_t)strtoul(ofp_max, &endp, 10);
  3166 			if (strlcpy(propvals[j++], curr, DLADM_PROP_VAL_MAX) >=
  3107 
  3167 			    DLADM_PROP_VAL_MAX) {
  3108 		for (i_of = of_min; i_of <= of_max; i_of++)
  3168 				dpif_log(EINVAL, "flow_propstr2vals key %s %dth"
  3109 			outports[j++] = i_of;
  3169 				    " string too long %s", key, j - 1, curr);
  3110 		curr = val + i + 1;
  3170 				return (EINVAL);
  3111 	}
  3171 			}
  3112 	if (j >= maxcnt)
  3172 			curr = val + i + 1;
  3113 		dpif_log(ENOBUFS, "flow_propstr2outports action truncated");
  3173 		}
  3114 	*valcntp = j;
  3174 	}
  3115 	for (i = 0; i < j; i++)
       
  3116 		dpif_log(0, "flow_propstr2outports key %s %dth: %d", key, i+1,
       
  3117 		    outports[i]);
       
  3118 	return (0);
       
  3119 }
       
  3120 
       
  3121 static int
       
  3122 flow_propstr2vals(char *key, char *val, char ***propvalsp, int *valcntp)
       
  3123 {
       
  3124 	char **propvals = *propvalsp, *curr;
       
  3125 	int maxcnt = *valcntp, i, j, len;
       
  3126 	char c;
       
  3127 
       
  3128 	dpif_log(0, "flow_propstr2vals key %s val %s", key, val);
       
  3129 	len = strlen(val);
       
  3130 
       
  3131 	ovs_assert(strcmp(key, "outports") != 0);
       
  3132 	for (i = 0, j = 0, curr = val; i < len && j < maxcnt; i++) {
       
  3133 		if ((c = val[i]) != FP_ACTION_MULTI_VAL_DELIM &&
       
  3134 		    i != len -1)
       
  3135 			continue;
       
  3136 
       
  3137 		if (c == FP_ACTION_MULTI_VAL_DELIM)
       
  3138 			val[i] = '\0';
       
  3139 
       
  3140 		if (strlcpy(propvals[j++], curr, DLADM_PROP_VAL_MAX) >=
       
  3141 		    DLADM_PROP_VAL_MAX) {
       
  3142 			dpif_log(EINVAL, "flow_propstr2vals key %s %dth"
       
  3143 			    " string too long %s", key, j - 1, curr);
       
  3144 			return (EINVAL);
       
  3145 		}
       
  3146 		curr = val + i + 1;
       
  3147 	}
       
  3148 	if (j >= maxcnt)
       
  3149 		dpif_log(ENOBUFS, "flow_propstr2vals action truncated");
  3175 	*valcntp = j;
  3150 	*valcntp = j;
  3176 	for (i = 0; i < j; i++)
  3151 	for (i = 0; i < j; i++)
  3177 		dpif_log(0, "flow_propstr2vals key %s %dth: %s", key, i+1,
  3152 		dpif_log(0, "flow_propstr2vals key %s %dth: %s", key, i+1,
  3178 		    propvals[i]);
  3153 		    propvals[i]);
  3179 	return (0);
  3154 	return (0);
  3182 static int
  3157 static int
  3183 flow_propval2action_ofaction(char *propval, struct ofpbuf *action)
  3158 flow_propval2action_ofaction(char *propval, struct ofpbuf *action)
  3184 {
  3159 {
  3185 	char ofaction_str[4096];
  3160 	char ofaction_str[4096];
  3186 	char **pvals, *buf = NULL;
  3161 	char **pvals, *buf = NULL;
       
  3162 	uint32_t outports[MAC_OF_MAXPORT];
  3187 	size_t len;
  3163 	size_t len;
  3188 	char *curr, *key, c;
  3164 	char *curr, *key, c;
  3189 	boolean_t match;
  3165 	boolean_t match;
  3190 	int nval, err = 0, i;
  3166 	int nval, err = 0, i, j;
  3191 
  3167 
  3192 	buf = malloc((sizeof (char *) +
  3168 	buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) *
  3193 	    DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT);
  3169 	    DLADM_PROP_VAL_MAX);
  3194 
  3170 
  3195 	pvals = (char **)(void *)buf;
  3171 	pvals = (char **)(void *)buf;
  3196 	for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) {
  3172 	for (i = 0; i < DLADM_PROP_VAL_MAX; i++) {
  3197 		pvals[i] = buf + sizeof (char *) * DLADM_MAX_PROP_VALCNT +
  3173 		pvals[i] = buf + sizeof (char *) * DLADM_PROP_VAL_MAX +
  3198 		    i * DLADM_PROP_VAL_MAX;
  3174 		    i * DLADM_PROP_VAL_MAX;
  3199 	}
  3175 	}
  3200 
  3176 
  3201 	if (strlcpy(ofaction_str, propval, sizeof (ofaction_str)) >=
  3177 	if (strlcpy(ofaction_str, propval, sizeof (ofaction_str)) >=
  3202 	    sizeof (ofaction_str)) {
  3178 	    sizeof (ofaction_str)) {
  3229 		if (key == NULL) {
  3205 		if (key == NULL) {
  3230 			err = EINVAL;
  3206 			err = EINVAL;
  3231 			goto done;
  3207 			goto done;
  3232 		}
  3208 		}
  3233 
  3209 
  3234 		err = flow_propstr2vals(key, curr, &pvals, &nval);
  3210 		if (strcmp(key, "outports") == 0) {
       
  3211 			nval = MAC_OF_MAXPORT;
       
  3212 			err = flow_propstr2outports(key, curr, outports, &nval);
       
  3213 		} else {
       
  3214 			nval = DLADM_PROP_VAL_MAX;
       
  3215 			err = flow_propstr2vals(key, curr, &pvals, &nval);
       
  3216 		}
  3235 		if (err != 0)
  3217 		if (err != 0)
  3236 			goto done;
  3218 			goto done;
  3237 
  3219 
  3238 		if (strcmp(key, "outports") == 0)
  3220 		if (strcmp(key, "outports") == 0) {
  3239 			err = flow_propval2action_outports_drop(pvals, nval,
  3221 			for (j = 0; j < nval; j++)
  3240 			    action);
  3222 				nl_msg_put_u32(action, OVS_ACTION_ATTR_OUTPUT,
  3241 		else if (strcmp(key, "max-bw") == 0)
  3223 				    outports[j]);
       
  3224 		} else if (strcmp(key, "max-bw") == 0)
  3242 			err = flow_propval2action_setpri(pvals, nval, action);
  3225 			err = flow_propval2action_setpri(pvals, nval, action);
  3243 		else if (strcmp(key, "controller") == 0)
  3226 		else if (strcmp(key, "controller") == 0)
  3244 			err = flow_propval2action_controller(pvals, nval,
  3227 			err = flow_propval2action_controller(pvals, nval,
  3245 			    action);
  3228 			    action);
  3246 		else if (strcmp(key, "vlan-tag") == 0)
  3229 		else if (strcmp(key, "vlan-tag") == 0)
  3290 			goto out;
  3273 			goto out;
  3291 		if (strlen(val->ddlv_sval) == 0)
  3274 		if (strlen(val->ddlv_sval) == 0)
  3292 			goto out;
  3275 			goto out;
  3293 		valcnt = 1;
  3276 		valcnt = 1;
  3294 		if (strlcpy(propval, val->ddlv_sval, sizeof (propval)) >=
  3277 		if (strlcpy(propval, val->ddlv_sval, sizeof (propval)) >=
  3295 		    DLADM_STRSIZE)
  3278 		    sizeof (propval))
  3296 			goto out;
  3279 			goto out;
  3297 		break;
  3280 		break;
  3298 	case DDLVT_STRINGS:
  3281 	case DDLVT_STRINGS:
  3299 		if (val->ddlv_slist_count == 0)
  3282 		if (val->ddlv_slist_count == 0)
  3300 			goto out;
  3283 			goto out;
  3301 		valcnt = val->ddlv_slist_count;
  3284 		valcnt = val->ddlv_slist_count;
  3302 		if (valcnt != 1 || strlen(val->ddlv_slist[0]) == 0)
  3285 		if (valcnt != 1 || strlen(val->ddlv_slist[0]) == 0)
  3303 			goto out;
  3286 			goto out;
  3304 		if (strlcpy(propval, val->ddlv_slist[0], sizeof (propval)) >=
  3287 		if (strlcpy(propval, val->ddlv_slist[0], sizeof (propval)) >=
  3305 		    DLADM_STRSIZE)
  3288 		    sizeof (propval))
  3306 			goto out;
  3289 			goto out;
  3307 		break;
  3290 		break;
  3308 	case DDLVT_ULONG:
  3291 	case DDLVT_ULONG:
  3309 		if (val->ddlv_ulval == NULL || *val->ddlv_ulval == 0)
  3292 		if (val->ddlv_ulval == NULL || *val->ddlv_ulval == 0)
  3310 			goto out;
  3293 			goto out;