second try
[vsorcdistro/.git] / ryu / ryu / tests / packet_data_generator2 / gen.c
1 /*
2  * Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
3  * Copyright (C) 2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *    http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14  * implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <lib/learn.h>
20 #include <lib/list.h>
21 #include <lib/ofpbuf.h>
22 #include <lib/ofp-actions.h>
23 #include <lib/ofp-errors.h>
24 #include <lib/ofp-msgs.h>
25 #include <lib/ofp-util.h>
26 #include <lib/packets.h>
27
28 #include <assert.h>
29 #include <err.h>
30 #include <stdio.h>
31
32 /*
33  * OpenFlow Common
34  */
35
36 void
37 clear_xid(struct ofpbuf *buf)
38 {
39     /*
40      * some of libofproto message encoding routines automatically
41      * allocate XID for the message.  e.g. ofputil_encode_flow_mod
42      * zero-out the XID so that test_parser can perform a simple
43      * bit-wise comparison.
44      */
45
46     struct ofp_header *oh = ofpbuf_at_assert(buf, 0, sizeof(*oh));
47
48     oh->xid = htonl(0);
49 }
50
51 void
52 fill_match(struct match *match)
53 {
54     const struct eth_addr dl_dst =
55         { { { 0xaa, 0xbb, 0xcc, 0x99, 0x88, 0x77 } } };
56     match_init_catchall(match);
57     match_set_in_port(match, 0xabcd);
58     match_set_dl_vlan(match, htons(999));
59     match_set_dl_dst(match, dl_dst);
60     match_set_dl_type(match, htons(ETH_TYPE_IP));
61     match_set_nw_dst(match, inet_addr("192.168.2.1"));
62     match_set_tun_src(match, inet_addr("192.168.2.3"));
63     match_set_tun_dst(match, inet_addr("192.168.2.4"));
64     match_set_tun_id(match, htonll(50000));
65 }
66
67 /*
68  * Controller-to-Switch Messages
69  */
70
71 /*
72  * Handshake
73  */
74
75 struct ofpbuf *
76 features_reply(enum ofputil_protocol proto)
77 {
78     struct ofputil_switch_features sf;
79
80     memset(&sf, 0, sizeof(sf));
81     sf.datapath_id = 1;
82     sf.n_buffers = 255;
83     sf.n_tables = 255;
84     sf.auxiliary_id = 0;
85     sf.capabilities = OFPUTIL_C_FLOW_STATS | OFPUTIL_C_TABLE_STATS |
86                       OFPUTIL_C_PORT_STATS | OFPUTIL_C_GROUP_STATS |
87                       OFPUTIL_C_QUEUE_STATS;
88     // sf.ofpacts is for only OFP10
89
90     ovs_be32 xid = 0;
91
92     return ofputil_encode_switch_features(&sf, proto, xid);
93 }
94
95 /*
96  * Switch Configuration
97  */
98
99 struct ofpbuf *
100 set_config(enum ofputil_protocol proto)
101 {
102     struct ofputil_switch_config sc;
103
104     memset(&sc, 0, sizeof(sc));
105     sc.frag = OFPUTIL_FRAG_NORMAL;
106     // sc.invalid_ttl_to_controller is for only OFP11 and OFP12
107     sc.miss_send_len = 128;  // The default of OpenFlow Spec
108
109     return ofputil_encode_set_config(
110         &sc, ofputil_protocol_to_ofp_version(proto));
111 }
112
113 struct ofpbuf *
114 get_config_reply(enum ofputil_protocol proto)
115 {
116     struct ofputil_switch_config sc;
117     struct ofp_header oh;
118
119     memset(&oh, 0, sizeof(oh));
120     oh.xid = 0;
121     oh.version = ofputil_protocol_to_ofp_version(proto);
122     memset(&sc, 0, sizeof(sc));
123     sc.frag = OFPUTIL_FRAG_NORMAL;
124     // sc.invalid_ttl_to_controller is for only OFP11 and OFP12
125     sc.miss_send_len = 128;  // The default of OpenFlow Spec
126
127     return ofputil_encode_get_config_reply(&oh, &sc);
128 }
129
130 /*
131  * Modify State Messages
132  */
133
134 struct ofpbuf *
135 table_mod(enum ofputil_protocol proto)
136 {
137     struct ofputil_table_mod tm;
138
139     memset(&tm, 0, sizeof(tm));
140     tm.table_id = 0xff;  // OFPTT_ALL
141     // OpenFlow 1.1 and 1.2 only.
142     // For other versions, ignored on encoding.
143     tm.miss = OFPUTIL_TABLE_MISS_DEFAULT;  // Protocol default behavior.
144     // OpenFlow 1.4+ only.
145     // For other versions, ignored on encoding.
146     tm.eviction = OFPUTIL_TABLE_EVICTION_ON;    // Enable eviction.
147     tm.eviction_flags = OFPTMPEF14_IMPORTANCE;  // Using flow entry importance.
148
149     return ofputil_encode_table_mod(&tm, proto);
150 }
151
152 struct ofpbuf *
153 flow_mod(enum ofputil_protocol proto)
154 {
155     struct ofputil_flow_mod fm;
156     struct ofpbuf acts;
157     struct ofpact_ipv4 *a_set_field;
158     struct ofpact_goto_table *a_goto;
159     char *error;
160
161     /*
162      * Taken from neutron OVS-agent,
163      * modified for OF>=1.3. (NXM -> OXM)
164      * NOTE(yamamoto): This needs to be writable.  learn_parse() modifies it.
165      */
166     char learn_args[] =
167         "table=99,"
168         "priority=1,"
169         "hard_timeout=300,"
170         "OXM_OF_VLAN_VID[0..11],"
171         "OXM_OF_ETH_DST[]=OXM_OF_ETH_SRC[],"
172         "load:0->OXM_OF_VLAN_VID[],"
173         "load:OXM_OF_TUNNEL_ID[]->OXM_OF_TUNNEL_ID[],"
174         "output:OXM_OF_IN_PORT[]";
175
176     memset(&fm, 0, sizeof(fm));
177     fm.command = OFPFC_ADD;
178     fm.table_id = 2;
179     fm.new_cookie = htonll(0x123456789abcdef0);
180     fm.cookie_mask = OVS_BE64_MAX;
181     fm.importance = 0x9878;
182
183     fill_match(&fm.match);
184
185     ofpbuf_init(&acts, 64);
186     ofpact_put_STRIP_VLAN(&acts);
187     a_set_field = ofpact_put_SET_IPV4_DST(&acts);
188     a_set_field->ipv4 = inet_addr("192.168.2.9");
189     error = learn_parse(learn_args, &acts);
190     assert(error == NULL);
191     a_goto = ofpact_put_GOTO_TABLE(&acts);
192     a_goto->table_id = 100;
193
194     fm.ofpacts = acts.data;
195     fm.ofpacts_len = acts.size;
196     return ofputil_encode_flow_mod(&fm, proto);
197 }
198
199 struct ofpbuf *
200 flow_mod_match_conj(enum ofputil_protocol proto)
201 {
202     struct ofputil_flow_mod fm;
203     struct ofpbuf acts;
204     struct ofpact_ipv4 *a_set_field;
205     struct ofpact_goto_table *a_goto;
206
207     memset(&fm, 0, sizeof(fm));
208     fm.command = OFPFC_ADD;
209     fm.table_id = 3;
210     fm.new_cookie = htonll(0x123456789abcdef0);
211     fm.cookie_mask = OVS_BE64_MAX;
212     fm.importance = 0x9878;
213
214     match_init_catchall(&fm.match);
215     match_set_conj_id(&fm.match, 0xabcdef);
216
217     ofpbuf_init(&acts, 64);
218     ofpact_put_STRIP_VLAN(&acts);
219     a_set_field = ofpact_put_SET_IPV4_DST(&acts);
220     a_set_field->ipv4 = inet_addr("192.168.2.9");
221     a_goto = ofpact_put_GOTO_TABLE(&acts);
222     a_goto->table_id = 100;
223
224     fm.ofpacts = acts.data;
225     fm.ofpacts_len = acts.size;
226     return ofputil_encode_flow_mod(&fm, proto);
227 }
228
229 struct ofpbuf *
230 flow_mod_conjunction(enum ofputil_protocol proto)
231 {
232     struct ofputil_flow_mod fm;
233     struct ofpbuf acts;
234     struct ofpact_conjunction *a_conj;
235
236     memset(&fm, 0, sizeof(fm));
237     fm.command = OFPFC_ADD;
238     fm.table_id = 4;
239     fm.new_cookie = htonll(0x123456789abcdef0);
240     fm.cookie_mask = OVS_BE64_MAX;
241     fm.importance = 0x9878;
242
243     fill_match(&fm.match);
244
245     ofpbuf_init(&acts, 64);
246     a_conj = ofpact_put_CONJUNCTION(&acts);
247     a_conj->id = 0xabcdef;
248     a_conj->clause = 1;
249     a_conj->n_clauses = 2;
250
251     fm.ofpacts = acts.data;
252     fm.ofpacts_len = acts.size;
253     return ofputil_encode_flow_mod(&fm, proto);
254 }
255
256 struct ofpbuf *
257 group_mod(enum ofputil_protocol proto)
258 {
259     struct ofputil_group_mod gm;
260     struct ofpbuf acts;
261     struct ofpact_ipv4 *a_set_field;
262     struct ofpact_goto_table *a_goto;
263     struct ofputil_bucket bckt;
264
265     memset(&gm, 0, sizeof(gm));
266     gm.command = OFPGC15_INSERT_BUCKET;
267     gm.type = OFPGT11_SELECT;
268     gm.group_id = 0xaaaaaaaa;
269     gm.command_bucket_id = 0xbbbbbbbb;
270
271     ofpbuf_init(&acts, 0x18);
272     ofpact_put_STRIP_VLAN(&acts);
273     a_set_field = ofpact_put_SET_IPV4_DST(&acts);
274     a_set_field->ipv4 = inet_addr("192.168.2.9");
275
276     bckt.weight = 0xcccc;
277     bckt.watch_port = 0xdddd;
278     bckt.watch_group = 0xeeeeeeee;
279     bckt.bucket_id = 0x12345678;
280     bckt.ofpacts = acts.data;
281     bckt.ofpacts_len = acts.size;
282
283     list_init(&(gm.buckets));
284     list_push_back(&(gm.buckets), &(bckt.list_node));
285
286     return ofputil_encode_group_mod(
287         ofputil_protocol_to_ofp_version(proto), &gm);
288 }
289
290 struct ofpbuf *
291 port_mod(enum ofputil_protocol proto)
292 {
293     struct ofputil_port_mod pm;
294     const struct eth_addr hw_addr =
295         { { { 0xaa, 0xbb, 0xcc, 0x99, 0x88, 0x77 } } };
296
297     memset(&pm, 0, sizeof(pm));
298     pm.port_no = 1;
299     pm.hw_addr = hw_addr;
300     pm.config = OFPPC_PORT_DOWN;
301     pm.mask = OFPPC_PORT_DOWN;
302     pm.advertise = 10248;  // OFPPF_100MB_FD, OFPPF_COPPER, OFPPF_AUTONEG
303
304     return ofputil_encode_port_mod(&pm, proto);
305 }
306
307 struct ofpbuf *
308 meter_mod(enum ofputil_protocol proto)
309 {
310     const int N_BANDS = 2;
311     struct ofputil_meter_mod mm;
312     struct ofputil_meter_band bands[N_BANDS];
313
314     memset(bands, 0, sizeof(*bands)*2);
315     bands[0].type = 1;         // OFPMBT_DROP
316     bands[0].rate = 1000;
317     bands[0].burst_size = 10;
318     bands[1].type = 2;         // OFPMBT_DSCP_REMARK
319     bands[1].prec_level = 1;
320     bands[1].rate = 1000;
321     bands[1].burst_size = 10;
322
323     memset(&mm, 0, sizeof(mm));
324     mm.command = 0;              // OFPMC_ADD
325     mm.meter.meter_id = 100;
326     mm.meter.flags = 14;         // OFPMF_PKTPS, OFPMF_BURST, OFPMF_STATS
327     mm.meter.n_bands = N_BANDS;
328     mm.meter.bands = bands;
329
330     return ofputil_encode_meter_mod(
331         ofputil_protocol_to_ofp_version(proto), &mm);
332 }
333
334 /*
335  * Multipart Messages
336  */
337
338 struct ofpbuf *
339 aggregate_stats_request(enum ofputil_protocol proto)
340 {
341     struct ofputil_flow_stats_request fsr;
342
343     memset(&fsr, 0, sizeof(fsr));
344     fsr.aggregate = true;
345     match_init_catchall(&fsr.match);
346     fsr.out_port = OFPP_ANY;
347     fsr.out_group = OFPG_ANY;
348     fsr.table_id = OFPTT_ALL;
349     fsr.cookie = fsr.cookie_mask = htonll(0);
350
351     return ofputil_encode_flow_stats_request(&fsr, proto);
352 }
353
354 struct ofpbuf *
355 port_stats_request(enum ofputil_protocol proto)
356 {
357     uint32_t port_no = 0xffffffff;
358     return ofputil_encode_dump_ports_request(
359         ofputil_protocol_to_ofp_version(proto), port_no);
360 }
361
362 struct ofpbuf *
363 port_desc_request(enum ofputil_protocol proto)
364 {
365     uint32_t port_no = 0xbcda;
366
367     return ofputil_encode_port_desc_stats_request(
368         ofputil_protocol_to_ofp_version(proto), port_no);
369 }
370
371 struct ofpbuf *
372 queue_stats_request(enum ofputil_protocol proto)
373 {
374     struct ofputil_queue_stats_request oqsr;
375     memset(&oqsr, 0, sizeof(oqsr));
376     oqsr.port_no = 0xabcd;
377     oqsr.queue_id = 0xffffffff;
378     return ofputil_encode_queue_stats_request(
379         ofputil_protocol_to_ofp_version(proto), &oqsr);
380 }
381
382 struct ofpbuf *
383 group_stats_request(enum ofputil_protocol proto)
384 {
385     uint32_t group_id = 0xfffffffc;
386     return ofputil_encode_group_stats_request(
387         ofputil_protocol_to_ofp_version(proto), group_id);
388 }
389
390 struct ofpbuf *
391 group_desc_request(enum ofputil_protocol proto)
392 {
393     uint32_t group_id = 0xcdab;
394
395     return ofputil_encode_group_desc_request(
396         ofputil_protocol_to_ofp_version(proto), group_id);
397 }
398
399 struct ofpbuf *
400 group_features_request(enum ofputil_protocol proto)
401 {
402     return ofputil_encode_group_features_request(
403         ofputil_protocol_to_ofp_version(proto));
404 }
405
406 struct ofpbuf *
407 meter_stats_request(enum ofputil_protocol proto)
408 {
409     uint32_t meter_id = 0xffffffff;
410     return ofputil_encode_meter_request(
411         ofputil_protocol_to_ofp_version(proto),
412         OFPUTIL_METER_STATS, meter_id);
413 }
414
415 struct ofpbuf *
416 table_desc_request(enum ofputil_protocol proto)
417 {
418     return ofputil_encode_table_desc_request(
419         ofputil_protocol_to_ofp_version(proto));
420 }
421
422 /*
423  * Barrier Message
424  */
425
426 struct ofpbuf *
427 barrier_request(enum ofputil_protocol proto)
428 {
429     return ofputil_encode_barrier_request(
430         ofputil_protocol_to_ofp_version(proto));
431 }
432
433 /*
434  * Bundle messages
435  */
436
437 struct ofpbuf *
438 bundle_ctrl(enum ofputil_protocol proto)
439 {
440     struct ofputil_bundle_ctrl_msg msg;
441     struct ofp_header oh;
442
443     memset(&oh, 0, sizeof(oh));
444     oh.xid = 0;
445     oh.version = ofputil_protocol_to_ofp_version(proto);
446     memset(&msg, 0, sizeof(msg));
447     msg.bundle_id = 99999999;
448     msg.type = OFPBCT_OPEN_REPLY;
449     msg.flags = OFPBF_ATOMIC;
450     return ofputil_encode_bundle_ctrl_reply(&oh, &msg);
451 }
452
453 struct ofpbuf *
454 bundle_add(enum ofputil_protocol proto)
455 {
456     struct ofputil_bundle_add_msg msg;
457     struct ofpbuf *fm;
458     struct ofpbuf *add;
459
460     memset(&msg, 0, sizeof(msg));
461     msg.bundle_id = 99999999;
462     msg.flags = OFPBF_ATOMIC;
463     fm = flow_mod(proto);
464     clear_xid(fm);
465     msg.msg = fm->data;
466     add = ofputil_encode_bundle_add(
467         ofputil_protocol_to_ofp_version(proto), &msg);
468     ofpbuf_delete(fm);
469     return add;
470 }
471
472 /*
473  * Asynchronous Messages
474  */
475
476 struct ofpbuf *
477 packet_in(enum ofputil_protocol proto)
478 {
479     struct ofputil_packet_in pin;
480     struct match match;
481     struct ofpbuf *buf;
482
483     memset(&pin, 0, sizeof(pin));
484     pin.packet = "hoge";
485     pin.packet_len = 4;
486     pin.total_len = 1000;
487     pin.table_id = 100;
488     pin.buffer_id = 200;
489
490     fill_match(&match);
491     flow_get_metadata(&match.flow, &pin.flow_metadata);
492
493     return ofputil_encode_packet_in(&pin, proto, NXPIF_OPENFLOW10);
494 }
495
496 struct ofpbuf *
497 flow_removed(enum ofputil_protocol proto)
498 {
499     struct ofputil_flow_removed fr;
500
501     memset(&fr, 0, sizeof(fr));
502     fill_match(&fr.match);
503     fr.cookie = htonll(0x123456789abcdef0);
504     fr.priority = 100;
505     fr.reason = 0;           // OFPRR_IDLE_TIMEOUT
506     fr.table_id = 1;
507     fr.duration_sec = 600;
508     fr.duration_nsec = 500;
509     fr.idle_timeout = 400;
510     fr.hard_timeout = 300;
511     fr.packet_count = 200;
512     fr.byte_count = 100;
513
514     return ofputil_encode_flow_removed(&fr, proto);
515 }
516
517 struct ofpbuf *
518 port_status(enum ofputil_protocol proto)
519 {
520     struct ofputil_port_status ps;
521
522     memset(&ps, 0, sizeof(ps));
523     ps.reason = 2;               // OFPPR_MODIFY
524     ps.desc.port_no = 1;
525     memset(&ps.desc.hw_addr, 0xff, sizeof(ps.desc.hw_addr));
526     sprintf(ps.desc.name, "eth0");
527     ps.desc.config = 0;
528     ps.desc.state = 4;
529     ps.desc.curr = 10248;        // OFPPF_100MB_FD, OFPPF_COPPER, OFPPF_AUTONEG
530     ps.desc.advertised = 10248;
531     ps.desc.supported = 10248;
532     ps.desc.peer = 10248;
533     ps.desc.curr_speed = 50000;  // kbps
534     ps.desc.max_speed = 100000;  // kbps
535
536     return ofputil_encode_port_status(&ps, proto);
537 }
538
539
540 struct ofpbuf *
541 role_status(enum ofputil_protocol proto)
542 {
543     struct ofputil_role_status rs;
544
545     memset(&rs, 0, sizeof(rs));
546     rs.role = OFPCR12_ROLE_SLAVE;       // OFPCR_ROLE_SLAVE
547     rs.reason = OFPCRR_MASTER_REQUEST;  // OFPCRR_MASTER_REQUEST
548     rs.generation_id = htonll(0x123456789abcdef0);
549
550     return ofputil_encode_role_status(&rs, proto);
551 }
552
553
554 struct ofpbuf *
555 requestforward(enum ofputil_protocol proto)
556 {
557     struct ofputil_requestforward rf;
558
559     memset(&rf, 0, sizeof(rf));
560     rf.reason = OFPRFR_GROUP_MOD;
561
562     struct ofputil_group_mod gm;
563     struct ofpbuf acts;
564     struct ofpact_ipv4 *a_set_field;
565     struct ofpact_goto_table *a_goto;
566     struct ofputil_bucket bckt;
567
568     memset(&gm, 0, sizeof(gm));
569     gm.command = OFPGC15_INSERT_BUCKET;
570     gm.type = OFPGT11_SELECT;
571     gm.group_id = 0xaaaaaaaa;
572     gm.command_bucket_id = 0xbbbbbbbb;
573
574     ofpbuf_init(&acts, 0x18);
575     ofpact_put_STRIP_VLAN(&acts);
576     a_set_field = ofpact_put_SET_IPV4_DST(&acts);
577     a_set_field->ipv4 = inet_addr("192.168.2.9");
578
579     bckt.weight = 0xcccc;
580     bckt.watch_port = 0xdddd;
581     bckt.watch_group = 0xeeeeeeee;
582     bckt.bucket_id = 0x12345678;
583     bckt.ofpacts = acts.data;
584     bckt.ofpacts_len = acts.size;
585
586     list_init(&(gm.buckets));
587     list_push_back(&(gm.buckets), &(bckt.list_node));
588
589     rf.group_mod = &gm;
590
591     return ofputil_encode_requestforward(&rf, proto);
592 }
593
594 /*
595  * Symmetric Messages
596  */
597
598 struct ofpbuf *
599 hello(enum ofputil_protocol proto)
600 {
601     return ofputil_encode_hello(ofputil_protocols_to_version_bitmap(proto));
602 }
603
604 struct ofpbuf *
605 echo_request(enum ofputil_protocol proto)
606 {
607     return make_echo_request(ofputil_protocol_to_ofp_version(proto));
608 }
609
610 struct ofpbuf *
611 echo_reply(enum ofputil_protocol proto)
612 {
613     struct ofp_header oh;
614
615     memset(&oh, 0, sizeof(oh));
616     oh.version = ofputil_protocol_to_ofp_version(proto);
617     oh.type = 3;           // OFPT_ECHO_REPLY
618     oh.length = htons(8);  // lenght of ofp_header
619     oh.xid = 0;
620
621     return make_echo_reply(&oh);
622 }
623
624 struct ofpbuf *
625 error_msg(enum ofputil_protocol proto)
626 {
627     struct ofp_header oh;
628
629     memset(&oh, 0, sizeof(oh));
630     oh.version = ofputil_protocol_to_ofp_version(proto);
631     oh.type = 14;          // OFPT_FLOW_MOD
632     oh.length = htons(8);  // lenght of ofp_header
633     oh.xid = 0;
634
635     // OFPERR_OFPBMC_BAD_FIELD means
636     // "Unsupported field in the match."
637     //  - type: OFPET_BAD_MATCH = 4
638     //  - code: OFPBMC_BAD_FIELD = 6
639     return ofperr_encode_reply(OFPERR_OFPBMC_BAD_FIELD, &oh);
640 }
641
642 /*
643  * Utilities
644  */
645
646 void
647 dump_ofpbuf(const char *name, const struct ofpbuf *buf)
648 {
649     FILE *fp;
650     size_t written;
651
652     fp = fopen(name, "wb");
653     if (fp == NULL) {
654         err(1, "fopen");
655     }
656     written = fwrite(buf->data, buf->size, 1, fp);
657     if (written != 1) {
658         err(1, "fwrite");
659     }
660     if (fclose(fp) != 0) {
661         err(1, "fclose");
662     }
663 }
664
665 void
666 dump_message(const char *name, struct ofpbuf *buf)
667 {
668
669     ofpmsg_update_length(buf);
670     dump_ofpbuf(name, buf);
671 }
672
673 struct protocol_version {
674     const char *name;
675     const char *dir_name;
676     enum ofp_version version;
677 };
678
679 #define P(v) {.name = "OFP" #v, .dir_name = "of" #v, \
680               .version = OFP ## v ## _VERSION,}
681
682 const struct protocol_version p13 = P(13);
683 const struct protocol_version p15 = P(15);
684
685 struct message {
686     const char *name;
687     struct ofpbuf *(*gen)(enum ofputil_protocol);
688     const struct protocol_version **protocols;
689 };
690
691 #define M(m, p) {.name = #m, .gen = m, .protocols = p,}
692
693 const struct message messages[] = {
694     /* Controller-to-Switch Messages */
695     /* Handshake */
696     // TODO:
697     // The following messages are not supported in Open vSwitch 2.5.90,
698     // re-generate the packet data, later.
699     //  - OFP10+ Features Request Message
700     // M(features_request,
701     //   ((const struct protocol_version *[]){&p13, &p15, NULL})),
702     M(features_reply,
703       ((const struct protocol_version *[]){&p13, &p15, NULL})),
704     /* Switch Configuration */
705     // TODO:
706     // The following messages are not supported in Open vSwitch 2.5.90,
707     // re-generate the packet data, later.
708     //  - OFP10+ Get Switch Configuration Request Message
709     M(set_config,
710       ((const struct protocol_version *[]){&p13, &p15, NULL})),
711     // M(get_config_request,
712     //   ((const struct protocol_version *[]){&p13, &p15, NULL})),
713     M(get_config_reply,
714       ((const struct protocol_version *[]){&p13, &p15, NULL})),
715     /* Modify State Messages */
716     // TODO:
717     // The following messages are not supported in Open vSwitch 2.4.90,
718     // re-generate the packet data, later.
719     //  - OFP14+ Port Modification Message [EXT-154]
720     M(table_mod,
721       ((const struct protocol_version *[]){&p13, &p15, NULL})),
722     M(flow_mod,
723       ((const struct protocol_version *[]){&p13, &p15, NULL})),
724     M(flow_mod_match_conj,
725       ((const struct protocol_version *[]){&p13, &p15, NULL})),
726     M(flow_mod_conjunction,
727       ((const struct protocol_version *[]){&p13, &p15, NULL})),
728     M(group_mod,
729       ((const struct protocol_version *[]){&p15, NULL})),
730     M(port_mod,
731       ((const struct protocol_version *[]){&p13, NULL})),
732     M(meter_mod,
733       ((const struct protocol_version *[]){&p13, &p15, NULL})),
734     /* Multipart Messages */
735     // TODO:
736     // The following messages are not supported in Open vSwitch 2.4.90,
737     // re-generate the packet data, later.
738     // - OFP10+ Desc Stats Request Message
739     // - OFP10+ Desc Stats Reply Message
740     // - OFP15+ Flow Desc Request Message [EXT-334]
741     // - OFP15+ Flow Desc Reply Message [EXT-334]
742     // - OFP15+ Flow Stats Request Message [EXT-302]
743     // - OFP15+ Flow Stats Reply Message [EXT-334]
744     // - OFP15+ Aggregate Stats Reply Message [EXT-334]
745     // - OFP14+ Port Stats Reply Message [EXT-262]
746     // - OFP14+ Port Desc Reply Message [EXT-262]
747     // - OFP14+ Queue Stats Reply Message [EXT-262]
748     // - OFP14+ Queue Desc Request Message [EXT-262]
749     // - OFP14+ Queue Desc Reply Message [EXT-262]
750     // - OFP13+ Group Stats Reply Message [EXT-102]
751     // - OFP15+ Group Desc Reply Message [EXT-350]
752     // - OFP12+ Group Features Reply Message [EXT-61]
753     // - OFP15+ Meter Stats Reply Message [EXT-374]
754     // - OFP15+ Meter Desc Request Message [EXT-302]
755     // - OFP15+ Meter Desc Reply Message [EXT-302]
756     // - OFP13+ Meter Features Stats Request Message [EXT-14]
757     // - OFP13+ Meter Features Stats Reply Message [EXT-14]
758     // - OFP15+ Controller Status Stats Request Message [EXT-454]
759     // - OFP15+ Controller Status Stats Reply Message [EXT-454]
760     // - OFP14+ Table Desc Reply Message [EXT-262]
761     // - OFP15+ Table Features Stats Request Message [EXT-306]
762     // - OFP15+ Table Features Stats Reply Message [EXT-306]
763     // - OFP14+ Flow Monitor Request Message [EXT-187]
764     // - OFP14+ Flow Monitor Reply Message [EXT-187]
765     // - OFP15+ Bundle Features Stats Request Message [EXT-340]
766     // - OFP15+ Bundle Features Stats Reply Message [EXT-340]
767     // - OFP11+ Experimenter Stats Request
768     // - OFP11+ Experimenter Stats Reply
769     // M(desc_stats_request,
770     //   ((const struct protocol_version *[]){&p15, NULL})),
771     // M(desc_stats_reply,
772     //   ((const struct protocol_version *[]){&p15, NULL})),
773     // M(flow_desc_request,
774     //   ((const struct protocol_version *[]){&p15, NULL})),
775     // M(flow_desc_reply,
776     //   ((const struct protocol_version *[]){&p15, NULL})),
777     // M(flow_stats_request,
778     //   ((const struct protocol_version *[]){&p15, NULL})),
779     // M(flow_stats_reply,
780     //   ((const struct protocol_version *[]){&p15, NULL})),
781     M(aggregate_stats_request,
782       ((const struct protocol_version *[]){&p15, NULL})),
783     // M(aggregate_stats_reply,
784     //   ((const struct protocol_version *[]){&p15, NULL})),
785     M(port_stats_request,
786       ((const struct protocol_version *[]){&p15, NULL})),
787     // M(port_stats_reply,
788     //   ((const struct protocol_version *[]){&p15, NULL})),
789     M(port_desc_request,
790       ((const struct protocol_version *[]){&p15, NULL})),
791     // M(port_desc_reply,
792     //   ((const struct protocol_version *[]){&p15, NULL})),
793     M(queue_stats_request,
794       ((const struct protocol_version *[]){&p15, NULL})),
795     // M(queue_stats_reply,
796     //   ((const struct protocol_version *[]){&p15, NULL})),
797     // M(queue_desc_request,
798     //   ((const struct protocol_version *[]){&p15, NULL})),
799     // M(queue_desc_reply,
800     //   ((const struct protocol_version *[]){&p15, NULL})),
801     M(group_stats_request,
802       ((const struct protocol_version *[]){&p15, NULL})),
803     // M(group_stats_reply,
804     //   ((const struct protocol_version *[]){&p15, NULL})),
805     M(group_desc_request,
806       ((const struct protocol_version *[]){&p15, NULL})),
807     // M(group_desc_reply,
808     //   ((const struct protocol_version *[]){&p15, NULL})),
809     M(group_features_request,
810       ((const struct protocol_version *[]){&p15, NULL})),
811     // M(group_features_reply,
812     //   ((const struct protocol_version *[]){&p15, NULL})),
813     M(meter_stats_request,
814       ((const struct protocol_version *[]){&p15, NULL})),
815     // M(meter_stats_reply,
816     //   ((const struct protocol_version *[]){&p15, NULL})),
817     // M(meter_desc_request,
818     //   ((const struct protocol_version *[]){&p15, NULL})),
819     // M(meter_desc_reply,
820     //   ((const struct protocol_version *[]){&p15, NULL})),
821     // M(meter_features_stats_request,
822     //   ((const struct protocol_version *[]){&p15, NULL})),
823     // M(meter_features_stats_reply,
824     //   ((const struct protocol_version *[]){&p15, NULL})),
825     // M(controller_status_stats_request,
826     //   ((const struct protocol_version *[]){&p15, NULL})),
827     // M(controller_status_stats_reply,
828     //   ((const struct protocol_version *[]){&p15, NULL})),
829     M(table_desc_request,
830       ((const struct protocol_version *[]){&p15, NULL})),
831     // M(table_desc_reply,
832     //   ((const struct protocol_version *[]){&p15, NULL})),
833     // M(table_features_stats_request,
834     //   ((const struct protocol_version *[]){&p15, NULL})),
835     // M(table_features_stats_reply,
836     //   ((const struct protocol_version *[]){&p15, NULL})),
837     // M(flow_monitor_request,
838     //   ((const struct protocol_version *[]){&p15, NULL})),
839     // M(flow_monitor_reply,
840     //   ((const struct protocol_version *[]){&p15, NULL})),
841     // M(bundle_features_stats_request,
842     //   ((const struct protocol_version *[]){&p15, NULL})),
843     // M(bundle_features_stats_reply,
844     //   ((const struct protocol_version *[]){&p15, NULL})),
845     // M(experimenter_stats_request,
846     //   ((const struct protocol_version *[]){&p15, NULL})),
847     // M(experimenter_stats_reply,
848     //   ((const struct protocol_version *[]){&p15, NULL})),
849     /* Packet-Out Message */
850     // TODO:
851     // The following message are not supported in Open vSwitch 2.4.90,
852     // re-generate the packet data, later.
853     // - OFP15+ Packet Out Message [EXT-427]
854     // M(packet_out,
855     //   ((const struct protocol_version *[]){&p15, NULL})),
856     /* Barrier Message */
857     // TODO:
858     // The following message are not supported in Open vSwitch 2.4.90,
859     // re-generate the packet data, later.
860     // - OFP10+ Barrier Reply Message
861     M(barrier_request,
862       ((const struct protocol_version *[]){&p15, NULL})),
863     // M(barrier_reply,
864     //   ((const struct protocol_version *[]){&p15, NULL})),
865     /* Role Request Message */
866     // TODO:
867     // The following messages are not supported in Open vSwitch 2.4.90,
868     // re-generate the packet data, later.
869     // - OFP15+ Role Request Message [EXT-275]
870     // - OFP15+ Role Reply Message [EXT-275]
871     // M(role_request,
872     //   ((const struct protocol_version *[]){&p15, NULL})),
873     // M(role_reply,
874     //   ((const struct protocol_version *[]){&p15, NULL})),
875     /* Bundle messages */
876     M(bundle_ctrl,
877       ((const struct protocol_version *[]){&p15, NULL})),
878     M(bundle_add,
879       ((const struct protocol_version *[]){&p15, NULL})),
880     /* Set Asynchronous Configuration Message */
881     // TODO:
882     // The following messages are not supported in Open vSwitch 2.4.90,
883     // re-generate the packet data, later.
884     // - OFP14+ Set Async Message [EXT-262]
885     // - OFP14+ Get Async Request Message [EXT-262]
886     // - OFP14+ Get Async Reply Message [EXT-262]
887     // M(set_async,
888     //   ((const struct protocol_version *[]){&p15, NULL})),
889     // M(get_async_request,
890     //   ((const struct protocol_version *[]){&p15, NULL})),
891     // M(get_async_reply,
892     //   ((const struct protocol_version *[]){&p15, NULL})),
893     /* Asynchronous Messages */
894     // TODO:
895     // The following messages are not supported in Open vSwitch 2.4.90,
896     // re-generate the packet data, later.
897     //  - OFP15 Flow Removed Message [EXT-334]
898     //  - OFP14+ Port Status Message [EXT-154]
899     //  - OFP14+ Table Status Message [EXT-232]
900     //  - OFP15+ Controller Status Message [EXT-454]
901     M(packet_in,
902       ((const struct protocol_version *[]){&p13, &p15, NULL})),
903     M(flow_removed,
904       ((const struct protocol_version *[]){&p13, NULL})),
905     M(port_status,
906       ((const struct protocol_version *[]){&p13, NULL})),
907     // M(table_status,
908     //  ((const struct protocol_version *[]){&p15, NULL})),
909     M(role_status,
910       ((const struct protocol_version *[]){&p15, NULL})),
911     M(requestforward,
912       ((const struct protocol_version *[]){&p15, NULL})),
913     // M(controller_status,
914     //  ((const struct protocol_version *[]){&p15, NULL})),
915     /* Symmetric Messages */
916     M(hello,
917       ((const struct protocol_version *[]){&p13, &p15, NULL})),
918     M(echo_request,
919       ((const struct protocol_version *[]){&p13, &p15, NULL})),
920     M(echo_reply,
921       ((const struct protocol_version *[]){&p13, &p15, NULL})),
922     M(error_msg,
923       ((const struct protocol_version *[]){&p13, &p15, NULL})),
924 };
925
926 #if !defined(__arraycount)
927 #define __arraycount(a) (sizeof(a) / sizeof(a[0]))
928 #endif
929
930 /*
931  * Main
932  */
933
934 int
935 main(int argc, char *argv[])
936 {
937     struct ofpbuf *buf;
938     unsigned int i, j;
939
940     for (i = 0; i < __arraycount(messages); i++) {
941         const struct message * const m = &messages[i];
942         char name[255];
943
944         for (j = 0;; j++) {
945             const struct protocol_version * const p = m->protocols[j];
946
947             if (p == NULL) {
948                 break;
949             }
950             const enum ofputil_protocol proto =
951                 ofputil_protocol_from_ofp_version(p->version);
952
953             buf = (*m->gen)(proto);
954             snprintf(name, sizeof(name),
955                 "../packet_data/%s/libofproto-%s-%s.packet",
956                 p->dir_name, p->name, m->name);
957             printf("generating %s ...\n", name);
958             clear_xid(buf);
959             dump_message(name, buf);
960             ofpbuf_delete(buf);
961         }
962     }
963 }