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

Reply via email to