2 * Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
3 * Copyright (C) 2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #include <lib/learn.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>
37 clear_xid(struct ofpbuf *buf)
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.
46 struct ofp_header *oh = ofpbuf_at_assert(buf, 0, sizeof(*oh));
52 fill_match(struct match *match)
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));
68 * Controller-to-Switch Messages
76 features_reply(enum ofputil_protocol proto)
78 struct ofputil_switch_features sf;
80 memset(&sf, 0, sizeof(sf));
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
92 return ofputil_encode_switch_features(&sf, proto, xid);
96 * Switch Configuration
100 set_config(enum ofputil_protocol proto)
102 struct ofputil_switch_config sc;
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
109 return ofputil_encode_set_config(
110 &sc, ofputil_protocol_to_ofp_version(proto));
114 get_config_reply(enum ofputil_protocol proto)
116 struct ofputil_switch_config sc;
117 struct ofp_header oh;
119 memset(&oh, 0, sizeof(oh));
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
127 return ofputil_encode_get_config_reply(&oh, &sc);
131 * Modify State Messages
135 table_mod(enum ofputil_protocol proto)
137 struct ofputil_table_mod tm;
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.
149 return ofputil_encode_table_mod(&tm, proto);
153 flow_mod(enum ofputil_protocol proto)
155 struct ofputil_flow_mod fm;
157 struct ofpact_ipv4 *a_set_field;
158 struct ofpact_goto_table *a_goto;
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.
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[]";
176 memset(&fm, 0, sizeof(fm));
177 fm.command = OFPFC_ADD;
179 fm.new_cookie = htonll(0x123456789abcdef0);
180 fm.cookie_mask = OVS_BE64_MAX;
181 fm.importance = 0x9878;
183 fill_match(&fm.match);
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;
194 fm.ofpacts = acts.data;
195 fm.ofpacts_len = acts.size;
196 return ofputil_encode_flow_mod(&fm, proto);
200 flow_mod_match_conj(enum ofputil_protocol proto)
202 struct ofputil_flow_mod fm;
204 struct ofpact_ipv4 *a_set_field;
205 struct ofpact_goto_table *a_goto;
207 memset(&fm, 0, sizeof(fm));
208 fm.command = OFPFC_ADD;
210 fm.new_cookie = htonll(0x123456789abcdef0);
211 fm.cookie_mask = OVS_BE64_MAX;
212 fm.importance = 0x9878;
214 match_init_catchall(&fm.match);
215 match_set_conj_id(&fm.match, 0xabcdef);
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;
224 fm.ofpacts = acts.data;
225 fm.ofpacts_len = acts.size;
226 return ofputil_encode_flow_mod(&fm, proto);
230 flow_mod_conjunction(enum ofputil_protocol proto)
232 struct ofputil_flow_mod fm;
234 struct ofpact_conjunction *a_conj;
236 memset(&fm, 0, sizeof(fm));
237 fm.command = OFPFC_ADD;
239 fm.new_cookie = htonll(0x123456789abcdef0);
240 fm.cookie_mask = OVS_BE64_MAX;
241 fm.importance = 0x9878;
243 fill_match(&fm.match);
245 ofpbuf_init(&acts, 64);
246 a_conj = ofpact_put_CONJUNCTION(&acts);
247 a_conj->id = 0xabcdef;
249 a_conj->n_clauses = 2;
251 fm.ofpacts = acts.data;
252 fm.ofpacts_len = acts.size;
253 return ofputil_encode_flow_mod(&fm, proto);
257 group_mod(enum ofputil_protocol proto)
259 struct ofputil_group_mod gm;
261 struct ofpact_ipv4 *a_set_field;
262 struct ofpact_goto_table *a_goto;
263 struct ofputil_bucket bckt;
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;
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");
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;
283 list_init(&(gm.buckets));
284 list_push_back(&(gm.buckets), &(bckt.list_node));
286 return ofputil_encode_group_mod(
287 ofputil_protocol_to_ofp_version(proto), &gm);
291 port_mod(enum ofputil_protocol proto)
293 struct ofputil_port_mod pm;
294 const struct eth_addr hw_addr =
295 { { { 0xaa, 0xbb, 0xcc, 0x99, 0x88, 0x77 } } };
297 memset(&pm, 0, sizeof(pm));
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
304 return ofputil_encode_port_mod(&pm, proto);
308 meter_mod(enum ofputil_protocol proto)
310 const int N_BANDS = 2;
311 struct ofputil_meter_mod mm;
312 struct ofputil_meter_band bands[N_BANDS];
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;
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;
330 return ofputil_encode_meter_mod(
331 ofputil_protocol_to_ofp_version(proto), &mm);
339 aggregate_stats_request(enum ofputil_protocol proto)
341 struct ofputil_flow_stats_request fsr;
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);
351 return ofputil_encode_flow_stats_request(&fsr, proto);
355 port_stats_request(enum ofputil_protocol proto)
357 uint32_t port_no = 0xffffffff;
358 return ofputil_encode_dump_ports_request(
359 ofputil_protocol_to_ofp_version(proto), port_no);
363 port_desc_request(enum ofputil_protocol proto)
365 uint32_t port_no = 0xbcda;
367 return ofputil_encode_port_desc_stats_request(
368 ofputil_protocol_to_ofp_version(proto), port_no);
372 queue_stats_request(enum ofputil_protocol proto)
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);
383 group_stats_request(enum ofputil_protocol proto)
385 uint32_t group_id = 0xfffffffc;
386 return ofputil_encode_group_stats_request(
387 ofputil_protocol_to_ofp_version(proto), group_id);
391 group_desc_request(enum ofputil_protocol proto)
393 uint32_t group_id = 0xcdab;
395 return ofputil_encode_group_desc_request(
396 ofputil_protocol_to_ofp_version(proto), group_id);
400 group_features_request(enum ofputil_protocol proto)
402 return ofputil_encode_group_features_request(
403 ofputil_protocol_to_ofp_version(proto));
407 meter_stats_request(enum ofputil_protocol proto)
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);
416 table_desc_request(enum ofputil_protocol proto)
418 return ofputil_encode_table_desc_request(
419 ofputil_protocol_to_ofp_version(proto));
427 barrier_request(enum ofputil_protocol proto)
429 return ofputil_encode_barrier_request(
430 ofputil_protocol_to_ofp_version(proto));
438 bundle_ctrl(enum ofputil_protocol proto)
440 struct ofputil_bundle_ctrl_msg msg;
441 struct ofp_header oh;
443 memset(&oh, 0, sizeof(oh));
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);
454 bundle_add(enum ofputil_protocol proto)
456 struct ofputil_bundle_add_msg msg;
460 memset(&msg, 0, sizeof(msg));
461 msg.bundle_id = 99999999;
462 msg.flags = OFPBF_ATOMIC;
463 fm = flow_mod(proto);
466 add = ofputil_encode_bundle_add(
467 ofputil_protocol_to_ofp_version(proto), &msg);
473 * Asynchronous Messages
477 packet_in(enum ofputil_protocol proto)
479 struct ofputil_packet_in pin;
483 memset(&pin, 0, sizeof(pin));
486 pin.total_len = 1000;
491 flow_get_metadata(&match.flow, &pin.flow_metadata);
493 return ofputil_encode_packet_in(&pin, proto, NXPIF_OPENFLOW10);
497 flow_removed(enum ofputil_protocol proto)
499 struct ofputil_flow_removed fr;
501 memset(&fr, 0, sizeof(fr));
502 fill_match(&fr.match);
503 fr.cookie = htonll(0x123456789abcdef0);
505 fr.reason = 0; // OFPRR_IDLE_TIMEOUT
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;
514 return ofputil_encode_flow_removed(&fr, proto);
518 port_status(enum ofputil_protocol proto)
520 struct ofputil_port_status ps;
522 memset(&ps, 0, sizeof(ps));
523 ps.reason = 2; // OFPPR_MODIFY
525 memset(&ps.desc.hw_addr, 0xff, sizeof(ps.desc.hw_addr));
526 sprintf(ps.desc.name, "eth0");
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
536 return ofputil_encode_port_status(&ps, proto);
541 role_status(enum ofputil_protocol proto)
543 struct ofputil_role_status rs;
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);
550 return ofputil_encode_role_status(&rs, proto);
555 requestforward(enum ofputil_protocol proto)
557 struct ofputil_requestforward rf;
559 memset(&rf, 0, sizeof(rf));
560 rf.reason = OFPRFR_GROUP_MOD;
562 struct ofputil_group_mod gm;
564 struct ofpact_ipv4 *a_set_field;
565 struct ofpact_goto_table *a_goto;
566 struct ofputil_bucket bckt;
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;
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");
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;
586 list_init(&(gm.buckets));
587 list_push_back(&(gm.buckets), &(bckt.list_node));
591 return ofputil_encode_requestforward(&rf, proto);
599 hello(enum ofputil_protocol proto)
601 return ofputil_encode_hello(ofputil_protocols_to_version_bitmap(proto));
605 echo_request(enum ofputil_protocol proto)
607 return make_echo_request(ofputil_protocol_to_ofp_version(proto));
611 echo_reply(enum ofputil_protocol proto)
613 struct ofp_header oh;
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
621 return make_echo_reply(&oh);
625 error_msg(enum ofputil_protocol proto)
627 struct ofp_header oh;
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
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);
647 dump_ofpbuf(const char *name, const struct ofpbuf *buf)
652 fp = fopen(name, "wb");
656 written = fwrite(buf->data, buf->size, 1, fp);
660 if (fclose(fp) != 0) {
666 dump_message(const char *name, struct ofpbuf *buf)
669 ofpmsg_update_length(buf);
670 dump_ofpbuf(name, buf);
673 struct protocol_version {
675 const char *dir_name;
676 enum ofp_version version;
679 #define P(v) {.name = "OFP" #v, .dir_name = "of" #v, \
680 .version = OFP ## v ## _VERSION,}
682 const struct protocol_version p13 = P(13);
683 const struct protocol_version p15 = P(15);
687 struct ofpbuf *(*gen)(enum ofputil_protocol);
688 const struct protocol_version **protocols;
691 #define M(m, p) {.name = #m, .gen = m, .protocols = p,}
693 const struct message messages[] = {
694 /* Controller-to-Switch Messages */
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})),
703 ((const struct protocol_version *[]){&p13, &p15, NULL})),
704 /* Switch Configuration */
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
710 ((const struct protocol_version *[]){&p13, &p15, NULL})),
711 // M(get_config_request,
712 // ((const struct protocol_version *[]){&p13, &p15, NULL})),
714 ((const struct protocol_version *[]){&p13, &p15, NULL})),
715 /* Modify State Messages */
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]
721 ((const struct protocol_version *[]){&p13, &p15, NULL})),
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})),
729 ((const struct protocol_version *[]){&p15, NULL})),
731 ((const struct protocol_version *[]){&p13, NULL})),
733 ((const struct protocol_version *[]){&p13, &p15, NULL})),
734 /* Multipart Messages */
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})),
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 */
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]
855 // ((const struct protocol_version *[]){&p15, NULL})),
856 /* Barrier Message */
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
862 ((const struct protocol_version *[]){&p15, NULL})),
864 // ((const struct protocol_version *[]){&p15, NULL})),
865 /* Role Request Message */
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]
872 // ((const struct protocol_version *[]){&p15, NULL})),
874 // ((const struct protocol_version *[]){&p15, NULL})),
875 /* Bundle messages */
877 ((const struct protocol_version *[]){&p15, NULL})),
879 ((const struct protocol_version *[]){&p15, NULL})),
880 /* Set Asynchronous Configuration Message */
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]
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 */
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]
902 ((const struct protocol_version *[]){&p13, &p15, NULL})),
904 ((const struct protocol_version *[]){&p13, NULL})),
906 ((const struct protocol_version *[]){&p13, NULL})),
908 // ((const struct protocol_version *[]){&p15, NULL})),
910 ((const struct protocol_version *[]){&p15, NULL})),
912 ((const struct protocol_version *[]){&p15, NULL})),
913 // M(controller_status,
914 // ((const struct protocol_version *[]){&p15, NULL})),
915 /* Symmetric Messages */
917 ((const struct protocol_version *[]){&p13, &p15, NULL})),
919 ((const struct protocol_version *[]){&p13, &p15, NULL})),
921 ((const struct protocol_version *[]){&p13, &p15, NULL})),
923 ((const struct protocol_version *[]){&p13, &p15, NULL})),
926 #if !defined(__arraycount)
927 #define __arraycount(a) (sizeof(a) / sizeof(a[0]))
935 main(int argc, char *argv[])
940 for (i = 0; i < __arraycount(messages); i++) {
941 const struct message * const m = &messages[i];
945 const struct protocol_version * const p = m->protocols[j];
950 const enum ofputil_protocol proto =
951 ofputil_protocol_from_ofp_version(p->version);
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);
959 dump_message(name, buf);