This patch adds flow metadata to ofputil_packet_out. It does not make any functional change. The flow metadata will be useful to support new packet-out message format in OpenFlow 1.5.
Signed-off-by: Yi-Hung Wei <[email protected]> --- include/openvswitch/ofp-util.h | 2 +- lib/learning-switch.c | 3 ++- lib/ofp-parse.c | 14 ++++++++------ lib/ofp-print.c | 4 ++-- lib/ofp-util.c | 23 +++++++++++++++-------- ofproto/ofproto.c | 8 +++++--- ovn/controller/ofctrl.c | 2 +- ovn/controller/pinctrl.c | 6 +++--- utilities/ovs-ofctl.c | 4 +++- 9 files changed, 40 insertions(+), 26 deletions(-) diff --git a/include/openvswitch/ofp-util.h b/include/openvswitch/ofp-util.h index f37d181599b2..a0a61cfac23a 100644 --- a/include/openvswitch/ofp-util.h +++ b/include/openvswitch/ofp-util.h @@ -526,7 +526,7 @@ struct ofputil_packet_out { const void *packet; /* Packet data, if buffer_id == UINT32_MAX. */ size_t packet_len; /* Length of packet data in bytes. */ uint32_t buffer_id; /* Buffer id or UINT32_MAX if no buffer. */ - ofp_port_t in_port; /* Packet's input port. */ + struct match flow_metadata; /* Packet's input port and other metadata. */ struct ofpact *ofpacts; /* Actions. */ size_t ofpacts_len; /* Size of ofpacts in bytes. */ }; diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 77155d04fcc0..4ff4e0db38be 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -570,7 +570,8 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) po.packet = NULL; po.packet_len = 0; } - po.in_port = pi.flow_metadata.flow.in_port.ofp_port; + match_set_in_port(&po.flow_metadata, + pi.flow_metadata.flow.in_port.ofp_port); po.ofpacts = ofpacts.data; po.ofpacts_len = ofpacts.size; diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index c8cac5b4765c..4fc352e03c4f 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -621,7 +621,7 @@ parse_ofp_packet_out_str__(struct ofputil_packet_out *po, char *string, *po = (struct ofputil_packet_out) { .buffer_id = UINT32_MAX, - .in_port = OFPP_CONTROLLER, + .flow_metadata.flow.in_port.ofp_port = OFPP_CONTROLLER, }; act_str = extract_actions(string); @@ -633,19 +633,21 @@ parse_ofp_packet_out_str__(struct ofputil_packet_out *po, char *string, } if (!strcmp(name, "in_port")) { - if (!ofputil_port_from_string(value, &po->in_port)) { + ofp_port_t in_port; + if (!ofputil_port_from_string(value, &in_port)) { error = xasprintf("%s is not a valid OpenFlow port", value); goto out; } - if (ofp_to_u16(po->in_port) > ofp_to_u16(OFPP_MAX) - && po->in_port != OFPP_LOCAL - && po->in_port != OFPP_NONE - && po->in_port != OFPP_CONTROLLER) { + if (ofp_to_u16(in_port) > ofp_to_u16(OFPP_MAX) + && in_port != OFPP_LOCAL + && in_port != OFPP_NONE + && in_port != OFPP_CONTROLLER) { error = xasprintf( "%s is not a valid OpenFlow port for PACKET_OUT", value); goto out; } + match_set_in_port(&po->flow_metadata, in_port); } else if (!strcmp(name, "packet")) { const char *error_msg = eth_from_hex(value, &packet); if (error_msg) { diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 7ca953100539..98cbf9c4b13c 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -247,8 +247,8 @@ ofp_print_packet_out(struct ds *string, const struct ofp_header *oh, return; } - ds_put_cstr(string, " in_port="); - ofputil_format_port(po.in_port, string); + ds_put_char(string, ' '); + match_format(&po.flow_metadata, string, OFP_DEFAULT_PRIORITY); ds_put_cstr(string, " actions="); ofpacts_format(po.ofpacts, po.ofpacts_len, string); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index bdf89b6c3017..f79be7389585 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -4204,15 +4204,18 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po, enum ofpraw raw = ofpraw_pull_assert(&b); ofpbuf_clear(ofpacts); + match_init_catchall(&po->flow_metadata); if (raw == OFPRAW_OFPT11_PACKET_OUT) { enum ofperr error; + ofp_port_t in_port; const struct ofp11_packet_out *opo = ofpbuf_pull(&b, sizeof *opo); po->buffer_id = ntohl(opo->buffer_id); - error = ofputil_port_from_ofp11(opo->in_port, &po->in_port); + error = ofputil_port_from_ofp11(opo->in_port, &in_port); if (error) { return error; } + match_set_in_port(&po->flow_metadata, in_port); error = ofpacts_pull_openflow_actions(&b, ntohs(opo->actions_len), oh->version, NULL, NULL, @@ -4225,7 +4228,7 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po, const struct ofp10_packet_out *opo = ofpbuf_pull(&b, sizeof *opo); po->buffer_id = ntohl(opo->buffer_id); - po->in_port = u16_to_ofp(ntohs(opo->in_port)); + match_set_in_port(&po->flow_metadata, u16_to_ofp(ntohs(opo->in_port))); error = ofpacts_pull_openflow_actions(&b, ntohs(opo->actions_len), oh->version, NULL, NULL, @@ -4237,11 +4240,13 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po, OVS_NOT_REACHED(); } - if (ofp_to_u16(po->in_port) >= ofp_to_u16(OFPP_MAX) - && po->in_port != OFPP_LOCAL - && po->in_port != OFPP_NONE && po->in_port != OFPP_CONTROLLER) { + if (ofp_to_u16(po->flow_metadata.flow.in_port.ofp_port) >= + ofp_to_u16(OFPP_MAX) + && po->flow_metadata.flow.in_port.ofp_port != OFPP_LOCAL + && po->flow_metadata.flow.in_port.ofp_port != OFPP_NONE + && po->flow_metadata.flow.in_port.ofp_port != OFPP_CONTROLLER) { VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out has bad input port %#"PRIx32, - po->in_port); + po->flow_metadata.flow.in_port.ofp_port); return OFPERR_OFPBRC_BAD_PORT; } @@ -7051,7 +7056,8 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po, opo = msg->msg; opo->buffer_id = htonl(po->buffer_id); - opo->in_port = htons(ofp_to_u16(po->in_port)); + opo->in_port = + htons(ofp_to_u16(po->flow_metadata.flow.in_port.ofp_port)); opo->actions_len = htons(msg->size - actions_ofs); break; } @@ -7071,7 +7077,8 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po, ofp_version); opo = msg->msg; opo->buffer_id = htonl(po->buffer_id); - opo->in_port = ofputil_port_to_ofp11(po->in_port); + opo->in_port = + ofputil_port_to_ofp11(po->flow_metadata.flow.in_port.ofp_port); opo->actions_len = htons(len); break; } diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index d5410fd1b20f..2020fe85df7a 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3459,8 +3459,10 @@ ofproto_packet_out_init(struct ofproto *ofproto, enum ofperr error; struct match match; - if (ofp_to_u16(po->in_port) >= ofproto->max_ports - && ofp_to_u16(po->in_port) < ofp_to_u16(OFPP_MAX)) { + if (ofp_to_u16(po->flow_metadata.flow.in_port.ofp_port) >= + ofproto->max_ports + && ofp_to_u16(po->flow_metadata.flow.in_port.ofp_port) < + ofp_to_u16(OFPP_MAX)) { return OFPERR_OFPBRC_BAD_PORT; } @@ -3475,7 +3477,7 @@ ofproto_packet_out_init(struct ofproto *ofproto, /* Store struct flow. */ opo->flow = xmalloc(sizeof *opo->flow); flow_extract(opo->packet, opo->flow); - opo->flow->in_port.ofp_port = po->in_port; + opo->flow->in_port.ofp_port = po->flow_metadata.flow.in_port.ofp_port; /* Check actions like for flow mods. We pass a 'table_id' of 0 to * ofproto_check_consistency(), which isn't strictly correct because these diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c index 417fdc9f52b2..e1077782bd00 100644 --- a/ovn/controller/ofctrl.c +++ b/ovn/controller/ofctrl.c @@ -1165,7 +1165,7 @@ ofctrl_inject_pkt(const struct ovsrec_bridge *br_int, const char *flow_s, .packet = dp_packet_data(&packet), .packet_len = dp_packet_size(&packet), .buffer_id = UINT32_MAX, - .in_port = uflow.in_port.ofp_port, + .flow_metadata.flow.in_port.ofp_port = uflow.in_port.ofp_port, .ofpacts = ofpacts.data, .ofpacts_len = ofpacts.size, }; diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c index 9ad413376736..caa2f8a989f4 100644 --- a/ovn/controller/pinctrl.c +++ b/ovn/controller/pinctrl.c @@ -183,7 +183,7 @@ pinctrl_handle_arp(const struct flow *ip_flow, const struct match *md, .packet = dp_packet_data(&packet), .packet_len = dp_packet_size(&packet), .buffer_id = UINT32_MAX, - .in_port = OFPP_CONTROLLER, + .flow_metadata.flow.in_port.ofp_port = OFPP_CONTROLLER, .ofpacts = ofpacts.data, .ofpacts_len = ofpacts.size, }; @@ -1382,7 +1382,7 @@ send_garp(struct garp_data *garp, long long int current_time) .packet = dp_packet_data(&packet), .packet_len = dp_packet_size(&packet), .buffer_id = UINT32_MAX, - .in_port = OFPP_CONTROLLER, + .flow_metadata.flow.in_port.ofp_port = OFPP_CONTROLLER, .ofpacts = ofpacts.data, .ofpacts_len = ofpacts.size, }; @@ -1781,7 +1781,7 @@ pinctrl_handle_nd_na(const struct flow *ip_flow, const struct match *md, .packet = dp_packet_data(&packet), .packet_len = dp_packet_size(&packet), .buffer_id = UINT32_MAX, - .in_port = OFPP_CONTROLLER, + .flow_metadata.flow.in_port.ofp_port = OFPP_CONTROLLER, .ofpacts = ofpacts.data, .ofpacts_len = ofpacts.size, }; diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 1a5e2345b7d4..17ee64649f7f 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -2078,6 +2078,7 @@ ofctl_packet_out(struct ovs_cmdl_context *ctx) struct ofpbuf *opo; char *error; + match_init_catchall(&po.flow_metadata); /* Use the old syntax when more than 4 arguments are given. */ if (ctx->argc > 4) { struct ofpbuf ofpacts; @@ -2091,7 +2092,8 @@ ofctl_packet_out(struct ovs_cmdl_context *ctx) } po.buffer_id = UINT32_MAX; - po.in_port = str_to_port_no(ctx->argv[1], ctx->argv[2]); + match_set_in_port(&po.flow_metadata, + str_to_port_no(ctx->argv[1], ctx->argv[2])); po.ofpacts = ofpacts.data; po.ofpacts_len = ofpacts.size; -- 2.7.4 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
