Hi All,
I am really new in OVS. I have problems decoding an ofp_packet_out
message that my virtual switch receives. Specifically, the packet_out
message received from the controller is (I get this information from
wireshark):
-Header
-Version: 0x01
-Type: Packet Out (CSM) (13)
-Length: 24
-Transaction ID: 17
-Packet Out:
-Buffer ID: 267
-Frame Recv Port: 1
-Size of action array in bytes: 8
-Output Action(s):
-Type: Output to switch port (0)
-Len: 8
-Output port: 1
-Max bytes to send: 0
# of Actions: 1
I would like to extract all this fields inside the function
handle_packet_out() in the ofproto/ofproto.c file. My virtual switch is
installed on a Raspberry Pi, and I need to know the output port in order
to transmit the proper signals to an optical switch wired with the
Raspberry. The handle_packet_out() function is:
handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
{
struct ofproto *p = ofconn_get_ofproto(ofconn);
struct ofputil_packet_out po;
struct dp_packet *payload;
uint64_t ofpacts_stub[1024 / 8];
struct ofpbuf ofpacts;
struct flow flow;
enum ofperr error;
COVERAGE_INC(ofproto_packet_out);
error = reject_slave_controller(ofconn);
if (error) {
goto exit;
}
/* Decode message. */
ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
error = ofputil_decode_packet_out(&po, oh, &ofpacts);
if (error) {
goto exit_free_ofpacts;
}
if (ofp_to_u16(po.in_port) >= p->max_ports
&& ofp_to_u16(po.in_port) < ofp_to_u16(OFPP_MAX)) {
error = OFPERR_OFPBRC_BAD_PORT;
goto exit_free_ofpacts;
}
/* Get payload. */
if (po.buffer_id != UINT32_MAX) {
error = ofconn_pktbuf_retrieve(ofconn, po.buffer_id, &payload,
NULL);
if (error || !payload) {
goto exit_free_ofpacts;
}
} else {
/* Ensure that the L3 header is 32-bit aligned. */
payload = dp_packet_clone_data_with_headroom(po.packet,
po.packet_len, 2);
}
/* Verify actions against packet, then send packet if successful. */
flow_extract(payload, &flow);
flow.in_port.ofp_port = po.in_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
* actions aren't in any table. This is OK as 'table_id' is only
used to
* check instructions (e.g., goto-table), which can't appear on the
action
* list of a packet-out. */
error = ofpacts_check_consistency(po.ofpacts, po.ofpacts_len,
&flow, u16_to_ofp(p->max_ports),
0, p->n_tables,
ofconn_get_protocol(ofconn));
if (!error) {
error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len);
if (!error) {
error = p->ofproto_class->packet_out(p, payload, &flow,
po.ofpacts,
po.ofpacts_len);
}
}
dp_packet_delete(payload);
exit_free_ofpacts:
ofpbuf_uninit(&ofpacts);
exit:
return error;
}
I can get all the fields except for the actions with the po variable
(struct ofputil_packet_out) like po.packet_len, po.in_port… I have also
tried with ofpacts variable (struct ofpbuf) which creates a buffer to
store the actions list (without success). To sum up, what I need is to
get the output port as an integer or as a char.
-Struct ofputil_packet_out:
/* Abstract packet-out message.
*
* ofputil_decode_packet_out() will ensure that 'in_port' is a physical
port
* (OFPP_MAX or less) or one of OFPP_LOCAL, OFPP_NONE, or
OFPP_CONTROLLER. */
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 ofpact *ofpacts; /* Actions. */
size_t ofpacts_len; /* Size of ofpacts in bytes. */
};
- Struct ofpbuf:
/* Buffer for holding arbitrary data. An ofpbuf is automatically
reallocated
* as necessary if it grows too large for the available memory.
*
* 'header' and 'msg' conventions:
*
* OpenFlow messages: 'header' points to the start of the OpenFlow
* header, while 'msg' is the OpenFlow msg bofy.
* When parsing, the 'data' will move past these, as data is being
* pulled from the OpenFlow message.
*
* Caution: buffer manipulation of 'struct ofpbuf' must always update
* the 'header' and 'msg' pointers.
*
*
* Actions: When encoding OVS action lists, the 'header' is used
* as a pointer to the beginning of the current action (see
ofpact_put()).
*
* rconn: Reuses 'header' as a private pointer while queuing.
*/
struct ofpbuf {
void *base; /* First byte of allocated space. */
void *data; /* First byte actually in use. */
uint32_t size; /* Number of bytes in use. */
uint32_t allocated; /* Number of bytes allocated. */
void *header; /* OpenFlow header. */
void *msg; /* message's body */
struct ovs_list list_node; /* Private list element for use by
owner. */
enum ofpbuf_source source; /* Source of memory allocated as 'base'.
*/
};
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev