Skip to content

Commit

Permalink
ofp-util: Add flow metadata to ofputil_packet_out
Browse files Browse the repository at this point in the history
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]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
YiHungWei authored and blp committed May 31, 2017
1 parent 07ed329 commit 35eb632
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 26 deletions.
2 changes: 1 addition & 1 deletion include/openvswitch/ofp-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
};
Expand Down
3 changes: 2 additions & 1 deletion lib/learning-switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
14 changes: 8 additions & 6 deletions lib/ofp-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,8 +621,8 @@ 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,
};
match_set_in_port(&po->flow_metadata, OFPP_CONTROLLER);

act_str = extract_actions(string);

Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions lib/ofp-print.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
23 changes: 15 additions & 8 deletions lib/ofp-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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) {
ofp_port_t in_port = po->flow_metadata.flow.in_port.ofp_port;
if (ofp_to_u16(in_port) >= ofp_to_u16(OFPP_MAX)
&& in_port != OFPP_LOCAL
&& in_port != OFPP_NONE
&& in_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;
}

Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions ofproto/ofproto.c
Original file line number Diff line number Diff line change
Expand Up @@ -3459,8 +3459,8 @@ 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)) {
uint16_t in_port = ofp_to_u16(po->flow_metadata.flow.in_port.ofp_port);
if (in_port >= ofproto->max_ports && in_port < ofp_to_u16(OFPP_MAX)) {
return OFPERR_OFPBRC_BAD_PORT;
}

Expand All @@ -3475,7 +3475,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
Expand Down
2 changes: 1 addition & 1 deletion ovn/controller/ofctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,10 +1165,10 @@ 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,
.ofpacts = ofpacts.data,
.ofpacts_len = ofpacts.size,
};
match_set_in_port(&po.flow_metadata, uflow.in_port.ofp_port);
enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
queue_msg(ofputil_encode_packet_out(&po, proto));
dp_packet_uninit(&packet);
Expand Down
6 changes: 3 additions & 3 deletions ovn/controller/pinctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,10 @@ 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,
.ofpacts = ofpacts.data,
.ofpacts_len = ofpacts.size,
};
match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER);
enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
queue_msg(ofputil_encode_packet_out(&po, proto));

Expand Down Expand Up @@ -1391,10 +1391,10 @@ 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,
.ofpacts = ofpacts.data,
.ofpacts_len = ofpacts.size,
};
match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER);
enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
queue_msg(ofputil_encode_packet_out(&po, proto));
dp_packet_uninit(&packet);
Expand Down Expand Up @@ -1790,10 +1790,10 @@ 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,
.ofpacts = ofpacts.data,
.ofpacts_len = ofpacts.size,
};
match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER);

queue_msg(ofputil_encode_packet_out(&po, proto));

Expand Down
4 changes: 3 additions & 1 deletion utilities/ovs-ofctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down

0 comments on commit 35eb632

Please sign in to comment.