예제 #1
0
/* Schedules 'msg' to be sent on 'rpc' and returns 'rpc''s status (as with
 * jsonrpc_get_status()).
 *
 * If 'msg' cannot be sent immediately, it is appended to a buffer.  The caller
 * is responsible for ensuring that the amount of buffered data is somehow
 * limited.  (jsonrpc_get_backlog() returns the amount of data currently
 * buffered in 'rpc'.)
 *
 * Always takes ownership of 'msg', regardless of success. */
int
jsonrpc_send(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
{
    struct ofpbuf *buf;
    struct json *json;
    size_t length;
    char *s;

    if (rpc->status) {
        jsonrpc_msg_destroy(msg);
        return rpc->status;
    }

    jsonrpc_log_msg(rpc, "send", msg);

    json = jsonrpc_msg_to_json(msg);
    s = json_to_string(json, 0);
    length = strlen(s);
    json_destroy(json);

    buf = xmalloc(sizeof *buf);
    ofpbuf_use(buf, s, length);
    buf->size = length;
    list_push_back(&rpc->output, &buf->list_node);
    rpc->backlog += length;

    if (rpc->backlog == length) {
        jsonrpc_run(rpc);
    }
    return rpc->status;
}
예제 #2
0
/* Encapsulates 'msg', which must contain an OpenFlow message, in a Netlink
 * message, and sends it to the OpenFlow local datapath numbered 'dp_idx' via
 * 'sock'.
 *
 * Returns 0 if successful, otherwise a positive errno value.  Returns EAGAIN
 * if the 'sock' send buffer is full.
 *
 * If the send is successful, then the kernel module will receive it, but there
 * is no guarantee that any reply will not be dropped (see nl_sock_transact()
 * for details). 
 */
int
dpif_send_openflow(struct dpif *dp, int dp_idx, struct ofpbuf *buffer)
{
    struct ofp_header *oh;
    unsigned int dump_flag;
    struct ofpbuf hdr;
    struct nlattr *nla;
    uint32_t fixed_buffer[64 / 4];
    struct iovec iov[3];
    int pad_bytes;
    int n_iov;
    int retval;

    /* The reply to OFPT_STATS_REQUEST may be multiple segments long, so we
     * need to specify NLM_F_DUMP in the request. */
    oh = ofpbuf_at_assert(buffer, 0, sizeof *oh);
    dump_flag = oh->type == OFPT_STATS_REQUEST ? NLM_F_DUMP : 0;

    ofpbuf_use(&hdr, fixed_buffer, sizeof fixed_buffer);
    nl_msg_put_genlmsghdr(&hdr, dp->sock, 32, openflow_family,
                          NLM_F_REQUEST | dump_flag, DP_GENL_C_OPENFLOW, 1);
    nl_msg_put_u32(&hdr, DP_GENL_A_DP_IDX, dp_idx);
    nla = ofpbuf_put_uninit(&hdr, sizeof *nla);
    nla->nla_len = sizeof *nla + buffer->size;
    nla->nla_type = DP_GENL_A_OPENFLOW;
    pad_bytes = NLA_ALIGN(nla->nla_len) - nla->nla_len;
    nl_msg_nlmsghdr(&hdr)->nlmsg_len = hdr.size + buffer->size + pad_bytes;
    n_iov = 2;
    iov[0].iov_base = hdr.data;
    iov[0].iov_len = hdr.size;
    iov[1].iov_base = buffer->data;
    iov[1].iov_len = buffer->size;
    if (pad_bytes) {
        static char zeros[NLA_ALIGNTO];
        n_iov++;
        iov[2].iov_base = zeros;
        iov[2].iov_len = pad_bytes; 
    }
    retval = nl_sock_sendv(dp->sock, iov, n_iov, false);
    if (retval && retval != EAGAIN) {
        VLOG_WARN_RL(&rl, "dpif_send_openflow: %s", strerror(retval));
    }
    return retval;
}
예제 #3
0
파일: jsonrpc.c 프로젝트: rafaelfonte/ovs
/* Schedules 'msg' to be sent on 'rpc' and returns 'rpc''s status (as with
 * jsonrpc_get_status()).
 *
 * If 'msg' cannot be sent immediately, it is appended to a buffer.  The caller
 * is responsible for ensuring that the amount of buffered data is somehow
 * limited.  (jsonrpc_get_backlog() returns the amount of data currently
 * buffered in 'rpc'.)
 *
 * Always takes ownership of 'msg', regardless of success. */
int
jsonrpc_send(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
{
    struct ofpbuf *buf;
    struct json *json;
    size_t length;
    char *s;

    if (rpc->status) {
        jsonrpc_msg_destroy(msg);
        return rpc->status;
    }

    jsonrpc_log_msg(rpc, "send", msg);

    json = jsonrpc_msg_to_json(msg);
    s = json_to_string(json, 0);
    length = strlen(s);
    json_destroy(json);

    buf = xmalloc(sizeof *buf);
    ofpbuf_use(buf, s, length);
    buf->size = length;
    list_push_back(&rpc->output, &buf->list_node);
    rpc->output_count++;
    rpc->backlog += length;

    if (rpc->output_count >= 50) {
        VLOG_INFO_RL(&rl, "excessive sending backlog, jsonrpc: %s, num of"
                     " msgs: %"PRIuSIZE", backlog: %"PRIuSIZE".", rpc->name,
                     rpc->output_count, rpc->backlog);
    }

    if (rpc->backlog == length) {
        jsonrpc_run(rpc);
    }
    return rpc->status;
}
예제 #4
0
파일: ofpbuf.c 프로젝트: cho4036/MyProject
/* Initializes 'b' as an empty ofpbuf with an initial capacity of 'size'
 * bytes. */
void
ofpbuf_init(struct ofpbuf *b, size_t size)
{
    ofpbuf_use(b, size ? xmalloc(size) : NULL, size);
}