Ejemplo n.º 1
0
static int
lookup_brc_multicast_group(int *multicast_group)
{
    struct nl_sock *sock;
    struct ofpbuf request, *reply;
    struct nlattr *attrs[ARRAY_SIZE(brc_multicast_policy)];
    int retval;

    retval = nl_sock_create(NETLINK_GENERIC, &sock);
    if (retval) {
        return retval;
    }
    ofpbuf_init(&request, 0);
    nl_msg_put_genlmsghdr(&request, 0, brc_family,
                          NLM_F_REQUEST, BRC_GENL_C_QUERY_MC, 1);
    retval = nl_sock_transact(sock, &request, &reply);
    ofpbuf_uninit(&request);
    if (retval) {
        nl_sock_destroy(sock);
        return retval;
    }
    if (!nl_policy_parse(reply, NLMSG_HDRLEN + GENL_HDRLEN,
                         brc_multicast_policy, attrs,
                         ARRAY_SIZE(brc_multicast_policy))) {
        nl_sock_destroy(sock);
        ofpbuf_delete(reply);
        return EPROTO;
    }
    *multicast_group = nl_attr_get_u32(attrs[BRC_GENL_A_MC_GROUP]);
    nl_sock_destroy(sock);
    ofpbuf_delete(reply);

    return 0;
}
Ejemplo n.º 2
0
/* Closes 'dp'. */
void
dpif_close(struct dpif *dp) 
{
    if (dp) {
        nl_sock_destroy(dp->sock);
    }
}
Ejemplo n.º 3
0
/* Opens a socket for brcompat notifications.  Returns 0 if successful,
 * otherwise a positive errno value. */
static int
brc_open(struct nl_sock **sock)
{
    int multicast_group = 0;
    int retval;

    retval = nl_lookup_genl_family(BRC_GENL_FAMILY_NAME, &brc_family);
    if (retval) {
        return retval;
    }

    retval = lookup_brc_multicast_group(&multicast_group);
    if (retval) {
        return retval;
    }

    retval = nl_sock_create(NETLINK_GENERIC, sock);
    if (retval) {
        return retval;
    }

    retval = nl_sock_join_mcgroup(*sock, multicast_group);
    if (retval) {
        nl_sock_destroy(*sock);
        *sock = NULL;
    }
    return retval;
}
Ejemplo n.º 4
0
/* Looks up the Netlink multicast group and datapath index of a datapath
 * by either the datapath index or name.  If 'dp_idx' points to a value 
 * of '-1', then 'dp_name' is used to lookup the datapath.  If successful, 
 * stores the multicast group in '*multicast_group' and the index in
 * '*dp_idx' and returns 0. Otherwise, returns a positive errno value. */
static int
query_datapath(int *dp_idx, int *multicast_group, const char *dp_name)
{
    struct nl_sock *sock;
    struct ofpbuf request, *reply;
    struct nlattr *attrs[ARRAY_SIZE(openflow_multicast_policy)];
    int retval;

    retval = nl_sock_create(NETLINK_GENERIC, 0, 0, 0, &sock);
    if (retval) {
        return retval;
    }
    ofpbuf_init(&request, 0);
    nl_msg_put_genlmsghdr(&request, sock, 0, openflow_family, NLM_F_REQUEST,
                          DP_GENL_C_QUERY_DP, 1);
    if (*dp_idx != -1) {
        nl_msg_put_u32(&request, DP_GENL_A_DP_IDX, *dp_idx);
    }
    if (dp_name) {
        nl_msg_put_string(&request, DP_GENL_A_DP_NAME, dp_name);
    }
    retval = nl_sock_transact(sock, &request, &reply);
    ofpbuf_uninit(&request);
    if (retval) {
        nl_sock_destroy(sock);
        return retval;
    }
    if (!nl_policy_parse(reply, NLMSG_HDRLEN + GENL_HDRLEN,
                         openflow_multicast_policy, attrs,
                         ARRAY_SIZE(openflow_multicast_policy))) {
        nl_sock_destroy(sock);
        ofpbuf_delete(reply);
        return EPROTO;
    }
    *dp_idx = nl_attr_get_u32(attrs[DP_GENL_A_DP_IDX]);
    *multicast_group = nl_attr_get_u32(attrs[DP_GENL_A_MC_GROUP]);
    nl_sock_destroy(sock);
    ofpbuf_delete(reply);

    return 0;
}
Ejemplo n.º 5
0
/* Completes Netlink dump operation 'dump', which must have been initialized
 * with nl_dump_start().  Returns 0 if the dump operation was error-free,
 * otherwise a positive errno value describing the problem. */
int
nl_dump_done(struct nl_dump *dump)
{
    /* Drain any remaining messages that the client didn't read.  Otherwise the
     * kernel will continue to queue them up and waste buffer space. */
    while (!dump->status) {
        struct ofpbuf reply;
        if (!nl_dump_next(dump, &reply)) {
            assert(dump->status);
        }
    }

    if (dump->sock) {
        if (dump->sock->dump) {
            dump->sock->dump = NULL;
        } else {
            nl_sock_destroy(dump->sock);
        }
    }
    ofpbuf_uninit(&dump->buffer);
    return dump->status == EOF ? 0 : dump->status;
}