2
* Copyright (c) 2010, 2011, 2012 Nicira, Inc.
2
* Copyright (c) 2010, 2011, 2012, 2013 Nicira, Inc.
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
102
102
unsigned int n_links, unsigned int arg);
104
104
/* Executes 'mp' based on the current contents of 'flow', writing the results
105
* back into 'flow'. */
105
* back into 'flow'. Sets fields in 'wc' that were used to calculate
107
multipath_execute(const struct ofpact_multipath *mp, struct flow *flow)
108
multipath_execute(const struct ofpact_multipath *mp, struct flow *flow,
109
struct flow_wildcards *wc)
109
111
/* Calculate value to store. */
110
112
uint32_t hash = flow_hash_fields(flow, mp->fields, mp->basis);
111
113
uint16_t link = multipath_algorithm(hash, mp->algorithm,
112
114
mp->max_link + 1, mp->arg);
114
nxm_reg_load(&mp->dst, link, flow);
116
flow_mask_hash_fields(flow, wc, mp->fields);
117
nxm_reg_load(&mp->dst, link, flow, wc);
192
195
/* Parses 's_' as a set of arguments to the "multipath" action and initializes
193
196
* 'mp' accordingly. ovs-ofctl(8) describes the format parsed.
195
* Prints an error on stderr and aborts the program if 's_' syntax is
198
multipath_parse(struct ofpact_multipath *mp, const char *s_)
198
* Returns NULL if successful, otherwise a malloc()'d string describing the
199
* error. The caller is responsible for freeing the returned string.*/
200
static char * WARN_UNUSED_RESULT
201
multipath_parse__(struct ofpact_multipath *mp, const char *s_, char *s)
200
char *s = xstrdup(s_);
201
203
char *save_ptr = NULL;
202
204
char *fields, *basis, *algorithm, *n_links_str, *arg, *dst;
205
208
fields = strtok_r(s, ", ", &save_ptr);
209
212
arg = strtok_r(NULL, ", ", &save_ptr);
210
213
dst = strtok_r(NULL, ", ", &save_ptr);
212
ovs_fatal(0, "%s: not enough arguments to multipath action", s_);
215
return xasprintf("%s: not enough arguments to multipath action", s_);
215
218
ofpact_init_MULTIPATH(mp);
218
221
} else if (!strcasecmp(fields, "symmetric_l4")) {
219
222
mp->fields = NX_HASH_FIELDS_SYMMETRIC_L4;
221
ovs_fatal(0, "%s: unknown fields `%s'", s_, fields);
224
return xasprintf("%s: unknown fields `%s'", s_, fields);
223
226
mp->basis = atoi(basis);
224
227
if (!strcasecmp(algorithm, "modulo_n")) {
230
233
} else if (!strcasecmp(algorithm, "iter_hash")) {
231
234
mp->algorithm = NX_MP_ALG_ITER_HASH;
233
ovs_fatal(0, "%s: unknown algorithm `%s'", s_, algorithm);
236
return xasprintf("%s: unknown algorithm `%s'", s_, algorithm);
235
238
n_links = atoi(n_links_str);
236
239
if (n_links < 1 || n_links > 65536) {
237
ovs_fatal(0, "%s: n_links %d is not in valid range 1 to 65536",
240
return xasprintf("%s: n_links %d is not in valid range 1 to 65536",
240
243
mp->max_link = n_links - 1;
241
244
mp->arg = atoi(arg);
243
mf_parse_subfield(&mp->dst, dst);
246
error = mf_parse_subfield(&mp->dst, dst);
244
250
if (mp->dst.n_bits < 16 && n_links > (1u << mp->dst.n_bits)) {
245
ovs_fatal(0, "%s: %d-bit destination field has %u possible values, "
246
"less than specified n_links %d",
247
s_, mp->dst.n_bits, 1u << mp->dst.n_bits, n_links);
251
return xasprintf("%s: %d-bit destination field has %u possible "
252
"values, less than specified n_links %d",
253
s_, mp->dst.n_bits, 1u << mp->dst.n_bits, n_links);
259
/* Parses 's_' as a set of arguments to the "multipath" action and initializes
260
* 'mp' accordingly. ovs-ofctl(8) describes the format parsed.
262
* Returns NULL if successful, otherwise a malloc()'d string describing the
263
* error. The caller is responsible for freeing the returned string. */
264
char * WARN_UNUSED_RESULT
265
multipath_parse(struct ofpact_multipath *mp, const char *s_)
267
char *s = xstrdup(s_);
268
char *error = multipath_parse__(mp, s_, s);
253
273
/* Appends a description of 'mp' to 's', in the format that ovs-ofctl(8)