~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to lib/multipath.c

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2010, 2011, 2012 Nicira, Inc.
 
2
 * Copyright (c) 2010, 2011, 2012, 2013 Nicira, Inc.
3
3
 *
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);
103
103
 
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
 
106
 * the result. */
106
107
void
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)
108
110
{
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);
113
115
 
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);
115
118
}
116
119
 
117
120
static uint16_t
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.
194
197
 *
195
 
 * Prints an error on stderr and aborts the program if 's_' syntax is
196
 
 * invalid. */
197
 
void
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)
199
202
{
200
 
    char *s = xstrdup(s_);
201
203
    char *save_ptr = NULL;
202
204
    char *fields, *basis, *algorithm, *n_links_str, *arg, *dst;
 
205
    char *error;
203
206
    int n_links;
204
207
 
205
208
    fields = strtok_r(s, ", ", &save_ptr);
209
212
    arg = strtok_r(NULL, ", ", &save_ptr);
210
213
    dst = strtok_r(NULL, ", ", &save_ptr);
211
214
    if (!dst) {
212
 
        ovs_fatal(0, "%s: not enough arguments to multipath action", s_);
 
215
        return xasprintf("%s: not enough arguments to multipath action", s_);
213
216
    }
214
217
 
215
218
    ofpact_init_MULTIPATH(mp);
218
221
    } else if (!strcasecmp(fields, "symmetric_l4")) {
219
222
        mp->fields = NX_HASH_FIELDS_SYMMETRIC_L4;
220
223
    } else {
221
 
        ovs_fatal(0, "%s: unknown fields `%s'", s_, fields);
 
224
        return xasprintf("%s: unknown fields `%s'", s_, fields);
222
225
    }
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;
232
235
    } else {
233
 
        ovs_fatal(0, "%s: unknown algorithm `%s'", s_, algorithm);
 
236
        return xasprintf("%s: unknown algorithm `%s'", s_, algorithm);
234
237
    }
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",
238
 
                  s_, n_links);
 
240
        return xasprintf("%s: n_links %d is not in valid range 1 to 65536",
 
241
                         s_, n_links);
239
242
    }
240
243
    mp->max_link = n_links - 1;
241
244
    mp->arg = atoi(arg);
242
245
 
243
 
    mf_parse_subfield(&mp->dst, dst);
 
246
    error = mf_parse_subfield(&mp->dst, dst);
 
247
    if (error) {
 
248
        return error;
 
249
    }
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);
248
254
    }
249
255
 
 
256
    return NULL;
 
257
}
 
258
 
 
259
/* Parses 's_' as a set of arguments to the "multipath" action and initializes
 
260
 * 'mp' accordingly.  ovs-ofctl(8) describes the format parsed.
 
261
 *
 
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_)
 
266
{
 
267
    char *s = xstrdup(s_);
 
268
    char *error = multipath_parse__(mp, s_, s);
250
269
    free(s);
 
270
    return error;
251
271
}
252
272
 
253
273
/* Appends a description of 'mp' to 's', in the format that ovs-ofctl(8)