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

« back to all changes in this revision

Viewing changes to lib/ofp-actions.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:
16
16
 
17
17
#include <config.h>
18
18
#include "ofp-actions.h"
19
 
#include "autopath.h"
20
19
#include "bundle.h"
21
20
#include "byte-order.h"
22
21
#include "compiler.h"
43
42
    struct ofpact_output *output;
44
43
 
45
44
    output = ofpact_put_OUTPUT(out);
46
 
    output->port = ntohs(oao->port);
 
45
    output->port = u16_to_ofp(ntohs(oao->port));
47
46
    output->max_len = ntohs(oao->max_len);
48
47
 
49
48
    return ofputil_check_output_port(output->port, OFPP_MAX);
56
55
    struct ofpact_enqueue *enqueue;
57
56
 
58
57
    enqueue = ofpact_put_ENQUEUE(out);
59
 
    enqueue->port = ntohs(oae->port);
 
58
    enqueue->port = u16_to_ofp(ntohs(oae->port));
60
59
    enqueue->queue = ntohl(oae->queue_id);
61
 
    if (enqueue->port >= OFPP_MAX && enqueue->port != OFPP_IN_PORT
 
60
    if (ofp_to_u16(enqueue->port) >= ofp_to_u16(OFPP_MAX)
 
61
        && enqueue->port != OFPP_IN_PORT
62
62
        && enqueue->port != OFPP_LOCAL) {
63
63
        return OFPERR_OFPBAC_BAD_OUT_PORT;
64
64
    }
73
73
 
74
74
    resubmit = ofpact_put_RESUBMIT(out);
75
75
    resubmit->ofpact.compat = OFPUTIL_NXAST_RESUBMIT;
76
 
    resubmit->in_port = ntohs(nar->in_port);
 
76
    resubmit->in_port = u16_to_ofp(ntohs(nar->in_port));
77
77
    resubmit->table_id = 0xff;
78
78
}
79
79
 
89
89
 
90
90
    resubmit = ofpact_put_RESUBMIT(out);
91
91
    resubmit->ofpact.compat = OFPUTIL_NXAST_RESUBMIT_TABLE;
92
 
    resubmit->in_port = ntohs(nar->in_port);
 
92
    resubmit->in_port = u16_to_ofp(ntohs(nar->in_port));
93
93
    resubmit->table_id = nar->table;
94
94
    return 0;
95
95
}
219
219
}
220
220
 
221
221
static enum ofperr
 
222
sample_from_openflow(const struct nx_action_sample *nas,
 
223
                     struct ofpbuf *out)
 
224
{
 
225
    struct ofpact_sample *sample;
 
226
 
 
227
    sample = ofpact_put_SAMPLE(out);
 
228
    sample->probability = ntohs(nas->probability);
 
229
    sample->collector_set_id = ntohl(nas->collector_set_id);
 
230
    sample->obs_domain_id = ntohl(nas->obs_domain_id);
 
231
    sample->obs_point_id = ntohl(nas->obs_point_id);
 
232
 
 
233
    if (sample->probability == 0) {
 
234
        return OFPERR_OFPBAC_BAD_ARGUMENT;
 
235
    }
 
236
 
 
237
    return 0;
 
238
}
 
239
 
 
240
static enum ofperr
222
241
decode_nxast_action(const union ofp_action *a, enum ofputil_action_code *code)
223
242
{
224
243
    const struct nx_action_header *nah = (const struct nx_action_header *) a;
317
336
        break;
318
337
 
319
338
    case OFPUTIL_NXAST_WRITE_METADATA:
320
 
        nawm = (const struct nx_action_write_metadata *) a;
 
339
        nawm = ALIGNED_CAST(const struct nx_action_write_metadata *, a);
321
340
        error = metadata_from_nxast(nawm, out);
322
341
        break;
323
342
 
337
356
 
338
357
    case OFPUTIL_NXAST_REG_LOAD:
339
358
        error = nxm_reg_load_from_openflow(
340
 
            (const struct nx_action_reg_load *) a, out);
 
359
            ALIGNED_CAST(const struct nx_action_reg_load *, a), out);
 
360
        break;
 
361
 
 
362
    case OFPUTIL_NXAST_STACK_PUSH:
 
363
        error = nxm_stack_push_from_openflow(
 
364
            (const struct nx_action_stack *) a, out);
 
365
        break;
 
366
 
 
367
    case OFPUTIL_NXAST_STACK_POP:
 
368
        error = nxm_stack_pop_from_openflow(
 
369
            (const struct nx_action_stack *) a, out);
341
370
        break;
342
371
 
343
372
    case OFPUTIL_NXAST_NOTE:
346
375
        break;
347
376
 
348
377
    case OFPUTIL_NXAST_SET_TUNNEL64:
349
 
        nast64 = (const struct nx_action_set_tunnel64 *) a;
 
378
        nast64 = ALIGNED_CAST(const struct nx_action_set_tunnel64 *, a);
350
379
        tunnel = ofpact_put_SET_TUNNEL(out);
351
380
        tunnel->ofpact.compat = code;
352
381
        tunnel->tun_id = ntohll(nast64->tun_id);
357
386
                                        ofpact_put_MULTIPATH(out));
358
387
        break;
359
388
 
360
 
    case OFPUTIL_NXAST_AUTOPATH__DEPRECATED:
361
 
        error = autopath_from_openflow((const struct nx_action_autopath *) a,
362
 
                                       ofpact_put_AUTOPATH(out));
363
 
        break;
364
 
 
365
389
    case OFPUTIL_NXAST_BUNDLE:
366
390
    case OFPUTIL_NXAST_BUNDLE_LOAD:
367
391
        error = bundle_from_openflow((const struct nx_action_bundle *) a, out);
378
402
        break;
379
403
 
380
404
    case OFPUTIL_NXAST_LEARN:
381
 
        error = learn_from_openflow((const struct nx_action_learn *) a, out);
 
405
        error = learn_from_openflow(
 
406
            ALIGNED_CAST(const struct nx_action_learn *, a), out);
382
407
        break;
383
408
 
384
409
    case OFPUTIL_NXAST_EXIT:
402
427
    case OFPUTIL_NXAST_CONTROLLER:
403
428
        controller_from_openflow((const struct nx_action_controller *) a, out);
404
429
        break;
 
430
 
 
431
    case OFPUTIL_NXAST_PUSH_MPLS: {
 
432
        struct nx_action_push_mpls *nxapm = (struct nx_action_push_mpls *)a;
 
433
        if (!eth_type_mpls(nxapm->ethertype)) {
 
434
            return OFPERR_OFPBAC_BAD_ARGUMENT;
 
435
        }
 
436
        ofpact_put_PUSH_MPLS(out)->ethertype = nxapm->ethertype;
 
437
        break;
 
438
    }
 
439
 
 
440
    case OFPUTIL_NXAST_SET_MPLS_TTL: {
 
441
        struct nx_action_mpls_ttl *nxamt = (struct nx_action_mpls_ttl *)a;
 
442
        ofpact_put_SET_MPLS_TTL(out)->ttl = nxamt->ttl;
 
443
        break;
 
444
    }
 
445
 
 
446
    case OFPUTIL_NXAST_DEC_MPLS_TTL:
 
447
        ofpact_put_DEC_MPLS_TTL(out);
 
448
        break;
 
449
 
 
450
    case OFPUTIL_NXAST_POP_MPLS: {
 
451
        struct nx_action_pop_mpls *nxapm = (struct nx_action_pop_mpls *)a;
 
452
        if (eth_type_mpls(nxapm->ethertype)) {
 
453
            return OFPERR_OFPBAC_BAD_ARGUMENT;
 
454
        }
 
455
        ofpact_put_POP_MPLS(out)->ethertype = nxapm->ethertype;
 
456
        break;
 
457
    }
 
458
 
 
459
    case OFPUTIL_NXAST_SAMPLE:
 
460
        error = sample_from_openflow(
 
461
            (const struct nx_action_sample *) a, out);
 
462
        break;
405
463
    }
406
464
 
407
465
    return error;
774
832
        return nxm_reg_load_from_openflow12_set_field(
775
833
            (const struct ofp12_action_set_field *)a, out);
776
834
 
 
835
    case OFPUTIL_OFPAT11_SET_MPLS_TTL: {
 
836
        struct ofp11_action_mpls_ttl *oamt = (struct ofp11_action_mpls_ttl *)a;
 
837
        ofpact_put_SET_MPLS_TTL(out)->ttl = oamt->mpls_ttl;
 
838
        break;
 
839
    }
 
840
 
 
841
    case OFPUTIL_OFPAT11_DEC_MPLS_TTL:
 
842
        ofpact_put_DEC_MPLS_TTL(out);
 
843
        break;
 
844
 
 
845
    case OFPUTIL_OFPAT11_PUSH_MPLS: {
 
846
        struct ofp11_action_push *oap = (struct ofp11_action_push *)a;
 
847
        if (!eth_type_mpls(oap->ethertype)) {
 
848
            return OFPERR_OFPBAC_BAD_ARGUMENT;
 
849
        }
 
850
        ofpact_put_PUSH_MPLS(out)->ethertype = oap->ethertype;
 
851
        break;
 
852
    }
 
853
 
 
854
    case OFPUTIL_OFPAT11_POP_MPLS: {
 
855
        struct ofp11_action_pop_mpls *oapm = (struct ofp11_action_pop_mpls *)a;
 
856
        if (eth_type_mpls(oapm->ethertype)) {
 
857
            return OFPERR_OFPBAC_BAD_ARGUMENT;
 
858
        }
 
859
        ofpact_put_POP_MPLS(out)->ethertype = oapm->ethertype;
 
860
        break;
 
861
    }
 
862
 
777
863
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
778
864
#include "ofp-util.def"
779
865
        return ofpact_from_nxast(a, code, out);
796
882
    instruction_get_##ENUM(const struct ofp11_instruction *inst)\
797
883
    {                                                           \
798
884
        ovs_assert(inst->type == htons(ENUM));                  \
799
 
        return (struct STRUCT *)inst;                           \
 
885
        return ALIGNED_CAST(struct STRUCT *, inst);             \
800
886
    }                                                           \
801
887
                                                                \
802
888
    static inline void                                          \
829
915
};
830
916
 
831
917
const char *
832
 
ofpact_instruction_name_from_type(enum ovs_instruction_type type)
 
918
ovs_instruction_name_from_type(enum ovs_instruction_type type)
833
919
{
834
920
    return inst_info[type].name;
835
921
}
836
922
 
837
923
int
838
 
ofpact_instruction_type_from_name(const char *name)
 
924
ovs_instruction_type_from_name(const char *name)
839
925
{
840
926
    const struct instruction_type_info *p;
841
927
    for (p = inst_info; p < &inst_info[ARRAY_SIZE(inst_info)]; p++) {
846
932
    return -1;
847
933
}
848
934
 
 
935
enum ovs_instruction_type
 
936
ovs_instruction_type_from_ofpact_type(enum ofpact_type type)
 
937
{
 
938
    switch (type) {
 
939
    case OFPACT_METER:
 
940
        return OVSINST_OFPIT13_METER;
 
941
    case OFPACT_CLEAR_ACTIONS:
 
942
        return OVSINST_OFPIT11_CLEAR_ACTIONS;
 
943
    case OFPACT_WRITE_METADATA:
 
944
        return OVSINST_OFPIT11_WRITE_METADATA;
 
945
    case OFPACT_GOTO_TABLE:
 
946
        return OVSINST_OFPIT11_GOTO_TABLE;
 
947
    case OFPACT_OUTPUT:
 
948
    case OFPACT_CONTROLLER:
 
949
    case OFPACT_ENQUEUE:
 
950
    case OFPACT_OUTPUT_REG:
 
951
    case OFPACT_BUNDLE:
 
952
    case OFPACT_SET_VLAN_VID:
 
953
    case OFPACT_SET_VLAN_PCP:
 
954
    case OFPACT_STRIP_VLAN:
 
955
    case OFPACT_PUSH_VLAN:
 
956
    case OFPACT_SET_ETH_SRC:
 
957
    case OFPACT_SET_ETH_DST:
 
958
    case OFPACT_SET_IPV4_SRC:
 
959
    case OFPACT_SET_IPV4_DST:
 
960
    case OFPACT_SET_IPV4_DSCP:
 
961
    case OFPACT_SET_L4_SRC_PORT:
 
962
    case OFPACT_SET_L4_DST_PORT:
 
963
    case OFPACT_REG_MOVE:
 
964
    case OFPACT_REG_LOAD:
 
965
    case OFPACT_STACK_PUSH:
 
966
    case OFPACT_STACK_POP:
 
967
    case OFPACT_DEC_TTL:
 
968
    case OFPACT_SET_MPLS_TTL:
 
969
    case OFPACT_DEC_MPLS_TTL:
 
970
    case OFPACT_PUSH_MPLS:
 
971
    case OFPACT_POP_MPLS:
 
972
    case OFPACT_SET_TUNNEL:
 
973
    case OFPACT_SET_QUEUE:
 
974
    case OFPACT_POP_QUEUE:
 
975
    case OFPACT_FIN_TIMEOUT:
 
976
    case OFPACT_RESUBMIT:
 
977
    case OFPACT_LEARN:
 
978
    case OFPACT_MULTIPATH:
 
979
    case OFPACT_NOTE:
 
980
    case OFPACT_EXIT:
 
981
    case OFPACT_SAMPLE:
 
982
    default:
 
983
        return OVSINST_OFPIT11_APPLY_ACTIONS;
 
984
    }
 
985
}
 
986
 
849
987
static inline struct ofp11_instruction *
850
988
instruction_next(const struct ofp11_instruction *inst)
851
989
{
918
1056
        }
919
1057
 
920
1058
        if (out[type]) {
921
 
            return OFPERR_OFPBAC_UNSUPPORTED_ORDER; /* No specific code for
922
 
                                                     * a duplicate instruction
923
 
                                                     * exist */
 
1059
            return OFPERR_ONFBIC_DUP_INSTRUCTION;
924
1060
        }
925
1061
        out[type] = inst;
926
1062
    }
935
1071
 
936
1072
static void
937
1073
get_actions_from_instruction(const struct ofp11_instruction *inst,
938
 
                         const union ofp_action **actions,
939
 
                         size_t *n_actions)
 
1074
                             const union ofp_action **actions,
 
1075
                             size_t *n_actions)
940
1076
{
941
 
    *actions = (const union ofp_action *) (inst + 1);
 
1077
    *actions = ALIGNED_CAST(const union ofp_action *, inst + 1);
942
1078
    *n_actions = (ntohs(inst->len) - sizeof *inst) / OFP11_INSTRUCTION_ALIGN;
943
1079
}
944
1080
 
1001
1137
        goto exit;
1002
1138
    }
1003
1139
 
 
1140
    if (insts[OVSINST_OFPIT13_METER]) {
 
1141
        const struct ofp13_instruction_meter *oim;
 
1142
        struct ofpact_meter *om;
 
1143
 
 
1144
        oim = ALIGNED_CAST(const struct ofp13_instruction_meter *,
 
1145
                           insts[OVSINST_OFPIT13_METER]);
 
1146
 
 
1147
        om = ofpact_put_METER(ofpacts);
 
1148
        om->meter_id = ntohl(oim->meter_id);
 
1149
    }
1004
1150
    if (insts[OVSINST_OFPIT11_APPLY_ACTIONS]) {
1005
1151
        const union ofp_action *actions;
1006
1152
        size_t n_actions;
1022
1168
        const struct ofp11_instruction_write_metadata *oiwm;
1023
1169
        struct ofpact_metadata *om;
1024
1170
 
1025
 
        oiwm = (const struct ofp11_instruction_write_metadata *)
1026
 
            insts[OVSINST_OFPIT11_WRITE_METADATA];
 
1171
        oiwm = ALIGNED_CAST(const struct ofp11_instruction_write_metadata *,
 
1172
                            insts[OVSINST_OFPIT11_WRITE_METADATA]);
1027
1173
 
1028
1174
        om = ofpact_put_WRITE_METADATA(ofpacts);
1029
1175
        om->metadata = oiwm->metadata;
1052
1198
    return error;
1053
1199
}
1054
1200
 
 
1201
/* May modify flow->dl_type, caller must restore it. */
1055
1202
static enum ofperr
1056
 
ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports)
 
1203
ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports,
 
1204
               uint8_t table_id)
1057
1205
{
1058
1206
    const struct ofpact_enqueue *enqueue;
1059
1207
 
1067
1215
 
1068
1216
    case OFPACT_ENQUEUE:
1069
1217
        enqueue = ofpact_get_ENQUEUE(a);
1070
 
        if (enqueue->port >= max_ports && enqueue->port != OFPP_IN_PORT
 
1218
        if (ofp_to_u16(enqueue->port) >= ofp_to_u16(max_ports)
 
1219
            && enqueue->port != OFPP_IN_PORT
1071
1220
            && enqueue->port != OFPP_LOCAL) {
1072
1221
            return OFPERR_OFPBAC_BAD_OUT_PORT;
1073
1222
        }
1098
1247
    case OFPACT_REG_LOAD:
1099
1248
        return nxm_reg_load_check(ofpact_get_REG_LOAD(a), flow);
1100
1249
 
 
1250
    case OFPACT_STACK_PUSH:
 
1251
        return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), flow);
 
1252
 
 
1253
    case OFPACT_STACK_POP:
 
1254
        return nxm_stack_pop_check(ofpact_get_STACK_POP(a), flow);
 
1255
 
1101
1256
    case OFPACT_DEC_TTL:
 
1257
    case OFPACT_SET_MPLS_TTL:
 
1258
    case OFPACT_DEC_MPLS_TTL:
1102
1259
    case OFPACT_SET_TUNNEL:
1103
1260
    case OFPACT_SET_QUEUE:
1104
1261
    case OFPACT_POP_QUEUE:
1112
1269
    case OFPACT_MULTIPATH:
1113
1270
        return multipath_check(ofpact_get_MULTIPATH(a), flow);
1114
1271
 
1115
 
    case OFPACT_AUTOPATH:
1116
 
        return autopath_check(ofpact_get_AUTOPATH(a), flow);
1117
 
 
1118
1272
    case OFPACT_NOTE:
1119
1273
    case OFPACT_EXIT:
1120
1274
        return 0;
1121
1275
 
 
1276
    case OFPACT_PUSH_MPLS:
 
1277
        flow->dl_type = ofpact_get_PUSH_MPLS(a)->ethertype;
 
1278
        return 0;
 
1279
 
 
1280
    case OFPACT_POP_MPLS:
 
1281
        flow->dl_type = ofpact_get_POP_MPLS(a)->ethertype;
 
1282
        return 0;
 
1283
 
 
1284
    case OFPACT_SAMPLE:
 
1285
        return 0;
 
1286
 
1122
1287
    case OFPACT_CLEAR_ACTIONS:
1123
1288
    case OFPACT_WRITE_METADATA:
 
1289
        return 0;
 
1290
 
 
1291
    case OFPACT_METER: {
 
1292
        uint32_t mid = ofpact_get_METER(a)->meter_id;
 
1293
        if (mid == 0 || mid > OFPM13_MAX) {
 
1294
            return OFPERR_OFPMMFC_INVALID_METER;
 
1295
        }
 
1296
        return 0;
 
1297
    }
 
1298
 
1124
1299
    case OFPACT_GOTO_TABLE:
 
1300
        if (ofpact_get_GOTO_TABLE(a)->table_id <= table_id) {
 
1301
            return OFPERR_OFPBRC_BAD_TABLE_ID;
 
1302
        }
1125
1303
        return 0;
1126
1304
 
1127
1305
    default:
1131
1309
 
1132
1310
/* Checks that the 'ofpacts_len' bytes of actions in 'ofpacts' are
1133
1311
 * appropriate for a packet with the prerequisites satisfied by 'flow' in a
1134
 
 * switch with no more than 'max_ports' ports. */
 
1312
 * switch with no more than 'max_ports' ports.
 
1313
 *
 
1314
 * May temporarily modify 'flow', but restores the changes before returning. */
1135
1315
enum ofperr
1136
1316
ofpacts_check(const struct ofpact ofpacts[], size_t ofpacts_len,
1137
 
              const struct flow *flow, int max_ports)
 
1317
              struct flow *flow, ofp_port_t max_ports, uint8_t table_id)
1138
1318
{
1139
1319
    const struct ofpact *a;
 
1320
    ovs_be16 dl_type = flow->dl_type;
 
1321
    enum ofperr error = 0;
1140
1322
 
1141
1323
    OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
1142
 
        enum ofperr error = ofpact_check__(a, flow, max_ports);
 
1324
        error = ofpact_check__(a, flow, max_ports, table_id);
1143
1325
        if (error) {
1144
 
            return error;
 
1326
            break;
1145
1327
        }
1146
1328
    }
1147
 
 
1148
 
    return 0;
 
1329
    flow->dl_type = dl_type; /* Restore. */
 
1330
    return error;
1149
1331
}
1150
1332
 
1151
1333
/* Verifies that the 'ofpacts_len' bytes of actions in 'ofpacts' are
1160
1342
    OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
1161
1343
        enum ovs_instruction_type next;
1162
1344
 
1163
 
        if (a->type == OFPACT_CLEAR_ACTIONS) {
1164
 
            next = OVSINST_OFPIT11_CLEAR_ACTIONS;
1165
 
        } else if (a->type == OFPACT_WRITE_METADATA) {
1166
 
            next = OVSINST_OFPIT11_WRITE_METADATA;
1167
 
        } else if (a->type == OFPACT_GOTO_TABLE) {
1168
 
            next = OVSINST_OFPIT11_GOTO_TABLE;
1169
 
        } else {
1170
 
            next = OVSINST_OFPIT11_APPLY_ACTIONS;
1171
 
        }
1172
 
 
 
1345
        next = ovs_instruction_type_from_ofpact_type(a->type);
1173
1346
        if (inst != OVSINST_OFPIT11_APPLY_ACTIONS && next <= inst) {
1174
 
            const char *name = ofpact_instruction_name_from_type(inst);
1175
 
            const char *next_name = ofpact_instruction_name_from_type(next);
 
1347
            const char *name = ovs_instruction_name_from_type(inst);
 
1348
            const char *next_name = ovs_instruction_name_from_type(next);
1176
1349
 
1177
1350
            if (next == inst) {
1178
1351
                VLOG_WARN("duplicate %s instruction not allowed, for OpenFlow "
1218
1391
        nar = ofputil_put_NXAST_RESUBMIT_TABLE(out);
1219
1392
        nar->table = resubmit->table_id;
1220
1393
    }
1221
 
    nar->in_port = htons(resubmit->in_port);
 
1394
    nar->in_port = htons(ofp_to_u16(resubmit->in_port));
1222
1395
}
1223
1396
 
1224
1397
static void
1264
1437
    if (remainder) {
1265
1438
        ofpbuf_put_zeros(out, OFP_ACTION_ALIGN - remainder);
1266
1439
    }
1267
 
    nan = (struct nx_action_note *)((char *)out->data + start_ofs);
 
1440
    nan = ofpbuf_at(out, start_ofs, sizeof *nan);
1268
1441
    nan->len = htons(out->size - start_ofs);
1269
1442
}
1270
1443
 
1313
1486
}
1314
1487
 
1315
1488
static void
 
1489
ofpact_sample_to_nxast(const struct ofpact_sample *os,
 
1490
                       struct ofpbuf *out)
 
1491
{
 
1492
    struct nx_action_sample *nas;
 
1493
 
 
1494
    nas = ofputil_put_NXAST_SAMPLE(out);
 
1495
    nas->probability = htons(os->probability);
 
1496
    nas->collector_set_id = htonl(os->collector_set_id);
 
1497
    nas->obs_domain_id = htonl(os->obs_domain_id);
 
1498
    nas->obs_point_id = htonl(os->obs_point_id);
 
1499
}
 
1500
 
 
1501
static void
1316
1502
ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
1317
1503
{
1318
1504
    switch (a->type) {
1336
1522
        nxm_reg_load_to_nxast(ofpact_get_REG_LOAD(a), out);
1337
1523
        break;
1338
1524
 
 
1525
    case OFPACT_STACK_PUSH:
 
1526
        nxm_stack_push_to_nxast(ofpact_get_STACK_PUSH(a), out);
 
1527
        break;
 
1528
 
 
1529
    case OFPACT_STACK_POP:
 
1530
        nxm_stack_pop_to_nxast(ofpact_get_STACK_POP(a), out);
 
1531
        break;
 
1532
 
1339
1533
    case OFPACT_DEC_TTL:
1340
1534
        ofpact_dec_ttl_to_nxast(ofpact_get_DEC_TTL(a), out);
1341
1535
        break;
1342
1536
 
 
1537
    case OFPACT_SET_MPLS_TTL:
 
1538
        ofputil_put_NXAST_SET_MPLS_TTL(out)->ttl
 
1539
            = ofpact_get_SET_MPLS_TTL(a)->ttl;
 
1540
        break;
 
1541
 
 
1542
    case OFPACT_DEC_MPLS_TTL:
 
1543
        ofputil_put_NXAST_DEC_MPLS_TTL(out);
 
1544
        break;
 
1545
 
1343
1546
    case OFPACT_SET_TUNNEL:
1344
1547
        ofpact_set_tunnel_to_nxast(ofpact_get_SET_TUNNEL(a), out);
1345
1548
        break;
1373
1576
        multipath_to_nxast(ofpact_get_MULTIPATH(a), out);
1374
1577
        break;
1375
1578
 
1376
 
    case OFPACT_AUTOPATH:
1377
 
        autopath_to_nxast(ofpact_get_AUTOPATH(a), out);
1378
 
        break;
1379
 
 
1380
1579
    case OFPACT_NOTE:
1381
1580
        ofpact_note_to_nxast(ofpact_get_NOTE(a), out);
1382
1581
        break;
1385
1584
        ofputil_put_NXAST_EXIT(out);
1386
1585
        break;
1387
1586
 
 
1587
    case OFPACT_PUSH_MPLS:
 
1588
        ofputil_put_NXAST_PUSH_MPLS(out)->ethertype =
 
1589
            ofpact_get_PUSH_MPLS(a)->ethertype;
 
1590
        break;
 
1591
 
 
1592
    case OFPACT_POP_MPLS:
 
1593
        ofputil_put_NXAST_POP_MPLS(out)->ethertype =
 
1594
            ofpact_get_POP_MPLS(a)->ethertype;
 
1595
        break;
 
1596
 
 
1597
    case OFPACT_SAMPLE:
 
1598
        ofpact_sample_to_nxast(ofpact_get_SAMPLE(a), out);
 
1599
        break;
 
1600
 
1388
1601
    case OFPACT_OUTPUT:
1389
1602
    case OFPACT_ENQUEUE:
1390
1603
    case OFPACT_SET_VLAN_VID:
1400
1613
    case OFPACT_SET_L4_DST_PORT:
1401
1614
    case OFPACT_CLEAR_ACTIONS:
1402
1615
    case OFPACT_GOTO_TABLE:
 
1616
    case OFPACT_METER:
1403
1617
        NOT_REACHED();
1404
1618
    }
1405
1619
}
1413
1627
    struct ofp10_action_output *oao;
1414
1628
 
1415
1629
    oao = ofputil_put_OFPAT10_OUTPUT(out);
1416
 
    oao->port = htons(output->port);
 
1630
    oao->port = htons(ofp_to_u16(output->port));
1417
1631
    oao->max_len = htons(output->max_len);
1418
1632
}
1419
1633
 
1424
1638
    struct ofp10_action_enqueue *oae;
1425
1639
 
1426
1640
    oae = ofputil_put_OFPAT10_ENQUEUE(out);
1427
 
    oae->port = htons(enqueue->port);
 
1641
    oae->port = htons(ofp_to_u16(enqueue->port));
1428
1642
    oae->queue_id = htonl(enqueue->queue);
1429
1643
}
1430
1644
 
1492
1706
    case OFPACT_PUSH_VLAN:
1493
1707
    case OFPACT_CLEAR_ACTIONS:
1494
1708
    case OFPACT_GOTO_TABLE:
 
1709
    case OFPACT_METER:
1495
1710
        /* XXX */
1496
1711
        break;
1497
1712
 
1500
1715
    case OFPACT_BUNDLE:
1501
1716
    case OFPACT_REG_MOVE:
1502
1717
    case OFPACT_REG_LOAD:
 
1718
    case OFPACT_STACK_PUSH:
 
1719
    case OFPACT_STACK_POP:
1503
1720
    case OFPACT_DEC_TTL:
 
1721
    case OFPACT_SET_MPLS_TTL:
 
1722
    case OFPACT_DEC_MPLS_TTL:
1504
1723
    case OFPACT_SET_TUNNEL:
1505
1724
    case OFPACT_WRITE_METADATA:
1506
1725
    case OFPACT_SET_QUEUE:
1509
1728
    case OFPACT_RESUBMIT:
1510
1729
    case OFPACT_LEARN:
1511
1730
    case OFPACT_MULTIPATH:
1512
 
    case OFPACT_AUTOPATH:
1513
1731
    case OFPACT_NOTE:
1514
1732
    case OFPACT_EXIT:
 
1733
    case OFPACT_PUSH_MPLS:
 
1734
    case OFPACT_POP_MPLS:
 
1735
    case OFPACT_SAMPLE:
1515
1736
        ofpact_to_nxast(a, out);
1516
1737
        break;
1517
1738
    }
1632
1853
        ofpact_dec_ttl_to_openflow11(ofpact_get_DEC_TTL(a), out);
1633
1854
        break;
1634
1855
 
 
1856
    case OFPACT_SET_MPLS_TTL:
 
1857
        ofputil_put_OFPAT11_SET_MPLS_TTL(out)->mpls_ttl
 
1858
            = ofpact_get_SET_MPLS_TTL(a)->ttl;
 
1859
        break;
 
1860
 
 
1861
    case OFPACT_DEC_MPLS_TTL:
 
1862
        ofputil_put_OFPAT11_DEC_MPLS_TTL(out);
 
1863
        break;
 
1864
 
1635
1865
    case OFPACT_WRITE_METADATA:
1636
1866
        /* OpenFlow 1.1 uses OFPIT_WRITE_METADATA to express this action. */
1637
1867
        break;
1638
1868
 
 
1869
    case OFPACT_PUSH_MPLS:
 
1870
        ofputil_put_OFPAT11_PUSH_MPLS(out)->ethertype =
 
1871
            ofpact_get_PUSH_MPLS(a)->ethertype;
 
1872
        break;
 
1873
 
 
1874
    case OFPACT_POP_MPLS:
 
1875
        ofputil_put_OFPAT11_POP_MPLS(out)->ethertype =
 
1876
            ofpact_get_POP_MPLS(a)->ethertype;
 
1877
 
 
1878
        break;
 
1879
 
1639
1880
    case OFPACT_CLEAR_ACTIONS:
1640
1881
    case OFPACT_GOTO_TABLE:
 
1882
    case OFPACT_METER:
1641
1883
        NOT_REACHED();
1642
1884
 
1643
1885
    case OFPACT_CONTROLLER:
1645
1887
    case OFPACT_BUNDLE:
1646
1888
    case OFPACT_REG_MOVE:
1647
1889
    case OFPACT_REG_LOAD:
 
1890
    case OFPACT_STACK_PUSH:
 
1891
    case OFPACT_STACK_POP:
1648
1892
    case OFPACT_SET_TUNNEL:
1649
1893
    case OFPACT_POP_QUEUE:
1650
1894
    case OFPACT_FIN_TIMEOUT:
1651
1895
    case OFPACT_RESUBMIT:
1652
1896
    case OFPACT_LEARN:
1653
1897
    case OFPACT_MULTIPATH:
1654
 
    case OFPACT_AUTOPATH:
1655
1898
    case OFPACT_NOTE:
1656
1899
    case OFPACT_EXIT:
 
1900
    case OFPACT_SAMPLE:
1657
1901
        ofpact_to_nxast(a, out);
1658
1902
        break;
1659
1903
    }
1698
1942
    const struct ofpact *a;
1699
1943
 
1700
1944
    OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
1701
 
        /* XXX Write-Actions */
1702
 
 
1703
 
        if (a->type == OFPACT_CLEAR_ACTIONS) {
 
1945
        switch (ovs_instruction_type_from_ofpact_type(a->type)) {
 
1946
        case OVSINST_OFPIT11_CLEAR_ACTIONS:
1704
1947
            instruction_put_OFPIT11_CLEAR_ACTIONS(openflow);
1705
 
        } else if (a->type == OFPACT_GOTO_TABLE) {
 
1948
            break;
 
1949
 
 
1950
        case OVSINST_OFPIT11_GOTO_TABLE: {
1706
1951
            struct ofp11_instruction_goto_table *oigt;
1707
 
 
1708
1952
            oigt = instruction_put_OFPIT11_GOTO_TABLE(openflow);
1709
1953
            oigt->table_id = ofpact_get_GOTO_TABLE(a)->table_id;
1710
1954
            memset(oigt->pad, 0, sizeof oigt->pad);
1711
 
        } else if (a->type == OFPACT_WRITE_METADATA) {
 
1955
            break;
 
1956
        }
 
1957
 
 
1958
        case OVSINST_OFPIT11_WRITE_METADATA: {
1712
1959
            const struct ofpact_metadata *om;
1713
1960
            struct ofp11_instruction_write_metadata *oiwm;
1714
1961
 
1716
1963
            oiwm = instruction_put_OFPIT11_WRITE_METADATA(openflow);
1717
1964
            oiwm->metadata = om->metadata;
1718
1965
            oiwm->metadata_mask = om->mask;
1719
 
        } else if (!ofpact_is_instruction(a)) {
1720
 
            /* Apply-actions */
 
1966
            break;
 
1967
        }
 
1968
 
 
1969
        case OVSINST_OFPIT13_METER: {
 
1970
            const struct ofpact_meter *om;
 
1971
            struct ofp13_instruction_meter *oim;
 
1972
 
 
1973
            om = ofpact_get_METER(a);
 
1974
            oim = instruction_put_OFPIT13_METER(openflow);
 
1975
            oim->meter_id = htonl(om->meter_id);
 
1976
            break;
 
1977
        }
 
1978
 
 
1979
        case OVSINST_OFPIT11_APPLY_ACTIONS: {
1721
1980
            const size_t ofs = openflow->size;
1722
1981
            const size_t ofpacts_len_left =
1723
1982
                (uint8_t*)ofpact_end(ofpacts, ofpacts_len) - (uint8_t*)a;
1726
1985
 
1727
1986
            instruction_put_OFPIT11_APPLY_ACTIONS(openflow);
1728
1987
            OFPACT_FOR_EACH(action, a, ofpacts_len_left) {
1729
 
                if (ofpact_is_instruction(action)) {
 
1988
                if (ovs_instruction_type_from_ofpact_type(action->type)
 
1989
                    != OVSINST_OFPIT11_APPLY_ACTIONS) {
1730
1990
                    break;
1731
1991
                }
1732
1992
                ofpact_to_openflow11(action, openflow);
1734
1994
            }
1735
1995
            ofpacts_update_instruction_actions(openflow, ofs);
1736
1996
            a = processed;
 
1997
            break;
 
1998
        }
 
1999
 
 
2000
        case OVSINST_OFPIT11_WRITE_ACTIONS:
 
2001
            NOT_REACHED();
1737
2002
        }
1738
2003
    }
1739
2004
}
1740
2005
 
1741
2006
/* Returns true if 'action' outputs to 'port', false otherwise. */
1742
2007
static bool
1743
 
ofpact_outputs_to_port(const struct ofpact *ofpact, uint16_t port)
 
2008
ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
1744
2009
{
1745
2010
    switch (ofpact->type) {
1746
2011
    case OFPACT_OUTPUT:
1765
2030
    case OFPACT_SET_L4_DST_PORT:
1766
2031
    case OFPACT_REG_MOVE:
1767
2032
    case OFPACT_REG_LOAD:
 
2033
    case OFPACT_STACK_PUSH:
 
2034
    case OFPACT_STACK_POP:
1768
2035
    case OFPACT_DEC_TTL:
 
2036
    case OFPACT_SET_MPLS_TTL:
 
2037
    case OFPACT_DEC_MPLS_TTL:
1769
2038
    case OFPACT_SET_TUNNEL:
1770
2039
    case OFPACT_WRITE_METADATA:
1771
2040
    case OFPACT_SET_QUEUE:
1774
2043
    case OFPACT_RESUBMIT:
1775
2044
    case OFPACT_LEARN:
1776
2045
    case OFPACT_MULTIPATH:
1777
 
    case OFPACT_AUTOPATH:
1778
2046
    case OFPACT_NOTE:
1779
2047
    case OFPACT_EXIT:
 
2048
    case OFPACT_PUSH_MPLS:
 
2049
    case OFPACT_POP_MPLS:
 
2050
    case OFPACT_SAMPLE:
1780
2051
    case OFPACT_CLEAR_ACTIONS:
1781
2052
    case OFPACT_GOTO_TABLE:
 
2053
    case OFPACT_METER:
1782
2054
    default:
1783
2055
        return false;
1784
2056
    }
1788
2060
 * to 'port', false otherwise. */
1789
2061
bool
1790
2062
ofpacts_output_to_port(const struct ofpact *ofpacts, size_t ofpacts_len,
1791
 
                       uint16_t port)
 
2063
                       ofp_port_t port)
1792
2064
{
1793
2065
    const struct ofpact *a;
1794
2066
 
1865
2137
{
1866
2138
    const struct ofpact_enqueue *enqueue;
1867
2139
    const struct ofpact_resubmit *resubmit;
1868
 
    const struct ofpact_autopath *autopath;
1869
2140
    const struct ofpact_controller *controller;
1870
2141
    const struct ofpact_metadata *metadata;
1871
2142
    const struct ofpact_tunnel *tunnel;
1872
 
    uint16_t port;
 
2143
    const struct ofpact_sample *sample;
 
2144
    ofp_port_t port;
1873
2145
 
1874
2146
    switch (a->type) {
1875
2147
    case OFPACT_OUTPUT:
1876
2148
        port = ofpact_get_OUTPUT(a)->port;
1877
 
        if (port < OFPP_MAX) {
 
2149
        if (ofp_to_u16(port) < ofp_to_u16(OFPP_MAX)) {
1878
2150
            ds_put_format(s, "output:%"PRIu16, port);
1879
2151
        } else {
1880
2152
            ofputil_format_port(port, s);
1895
2167
 
1896
2168
            ds_put_cstr(s, "controller(");
1897
2169
            if (reason != OFPR_ACTION) {
 
2170
                char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
 
2171
 
1898
2172
                ds_put_format(s, "reason=%s,",
1899
 
                              ofputil_packet_in_reason_to_string(reason));
 
2173
                              ofputil_packet_in_reason_to_string(
 
2174
                                  reason, reasonbuf, sizeof reasonbuf));
1900
2175
            }
1901
2176
            if (controller->max_len != UINT16_MAX) {
1902
2177
                ds_put_format(s, "max_len=%"PRIu16",", controller->max_len);
1984
2259
        nxm_format_reg_load(ofpact_get_REG_LOAD(a), s);
1985
2260
        break;
1986
2261
 
 
2262
    case OFPACT_STACK_PUSH:
 
2263
        nxm_format_stack_push(ofpact_get_STACK_PUSH(a), s);
 
2264
        break;
 
2265
 
 
2266
    case OFPACT_STACK_POP:
 
2267
        nxm_format_stack_pop(ofpact_get_STACK_POP(a), s);
 
2268
        break;
 
2269
 
1987
2270
    case OFPACT_DEC_TTL:
1988
2271
        print_dec_ttl(ofpact_get_DEC_TTL(a), s);
1989
2272
        break;
1990
2273
 
 
2274
    case OFPACT_SET_MPLS_TTL:
 
2275
        ds_put_format(s, "set_mpls_ttl(%"PRIu8")",
 
2276
                      ofpact_get_SET_MPLS_TTL(a)->ttl);
 
2277
        break;
 
2278
 
 
2279
    case OFPACT_DEC_MPLS_TTL:
 
2280
        ds_put_cstr(s, "dec_mpls_ttl");
 
2281
        break;
 
2282
 
1991
2283
    case OFPACT_SET_TUNNEL:
1992
2284
        tunnel = ofpact_get_SET_TUNNEL(a);
1993
2285
        ds_put_format(s, "set_tunnel%s:%#"PRIx64,
2035
2327
        multipath_format(ofpact_get_MULTIPATH(a), s);
2036
2328
        break;
2037
2329
 
2038
 
    case OFPACT_AUTOPATH:
2039
 
        autopath = ofpact_get_AUTOPATH(a);
2040
 
        ds_put_cstr(s, "autopath(");
2041
 
        ofputil_format_port(autopath->port, s);
2042
 
        ds_put_char(s, ',');
2043
 
        mf_format_subfield(&autopath->dst, s);
2044
 
        ds_put_char(s, ')');
2045
 
        break;
2046
 
 
2047
2330
    case OFPACT_NOTE:
2048
2331
        print_note(ofpact_get_NOTE(a), s);
2049
2332
        break;
2050
2333
 
 
2334
    case OFPACT_PUSH_MPLS:
 
2335
        ds_put_format(s, "push_mpls:0x%04"PRIx16,
 
2336
                      ntohs(ofpact_get_PUSH_MPLS(a)->ethertype));
 
2337
        break;
 
2338
 
 
2339
    case OFPACT_POP_MPLS:
 
2340
        ds_put_format(s, "pop_mpls:0x%04"PRIx16,
 
2341
                      ntohs(ofpact_get_POP_MPLS(a)->ethertype));
 
2342
        break;
 
2343
 
2051
2344
    case OFPACT_EXIT:
2052
2345
        ds_put_cstr(s, "exit");
2053
2346
        break;
2054
2347
 
 
2348
    case OFPACT_SAMPLE:
 
2349
        sample = ofpact_get_SAMPLE(a);
 
2350
        ds_put_format(
 
2351
            s, "sample(probability=%"PRIu16",collector_set_id=%"PRIu32
 
2352
            ",obs_domain_id=%"PRIu32",obs_point_id=%"PRIu32")",
 
2353
            sample->probability, sample->collector_set_id,
 
2354
            sample->obs_domain_id, sample->obs_point_id);
 
2355
        break;
 
2356
 
2055
2357
    case OFPACT_CLEAR_ACTIONS:
2056
2358
        ds_put_format(s, "%s",
2057
 
                      ofpact_instruction_name_from_type(
 
2359
                      ovs_instruction_name_from_type(
2058
2360
                          OVSINST_OFPIT11_CLEAR_ACTIONS));
2059
2361
        break;
2060
2362
 
2061
2363
    case OFPACT_WRITE_METADATA:
2062
2364
        metadata = ofpact_get_WRITE_METADATA(a);
2063
2365
        ds_put_format(s, "%s:%#"PRIx64,
2064
 
                      ofpact_instruction_name_from_type(
 
2366
                      ovs_instruction_name_from_type(
2065
2367
                          OVSINST_OFPIT11_WRITE_METADATA),
2066
2368
                      ntohll(metadata->metadata));
2067
2369
        if (metadata->mask != htonll(UINT64_MAX)) {
2071
2373
 
2072
2374
    case OFPACT_GOTO_TABLE:
2073
2375
        ds_put_format(s, "%s:%"PRIu8,
2074
 
                      ofpact_instruction_name_from_type(
 
2376
                      ovs_instruction_name_from_type(
2075
2377
                          OVSINST_OFPIT11_GOTO_TABLE),
2076
2378
                      ofpact_get_GOTO_TABLE(a)->table_id);
2077
2379
        break;
 
2380
 
 
2381
    case OFPACT_METER:
 
2382
        ds_put_format(s, "%s:%"PRIu32,
 
2383
                      ovs_instruction_name_from_type(OVSINST_OFPIT13_METER),
 
2384
                      ofpact_get_METER(a)->meter_id);
 
2385
        break;
2078
2386
    }
2079
2387
}
2080
2388