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) |