【OVS2.5.0源码分析】dpif向dp发送netlink消息分析

OVS用户态进程与内核模块是通过netlink进行通信的,本篇分析下用户态向内核态发送netlink消息的方法,发送消息入口有两个函数nl_transact和nl_transact_multiple,本篇以nl_transact_multiple为例进行分析。

1、nl_transact_multiple函数

void
nl_transact_multiple(int protocol,
                     struct nl_transaction **transactions, size_t n)
{
    struct nl_sock *sock;
    int error;

    error = nl_pool_alloc(protocol, &sock);   //创建socket
    if (!error) {
        nl_sock_transact_multiple(sock, transactions, n);   //通过socket发送消息
        nl_pool_release(sock);
    } else {
        nl_sock_record_errors__(transactions, n, error);
    }
}
2、nl_pool_alloc函数

static int
nl_pool_alloc(int protocol, struct nl_sock **sockp)
{
    struct nl_sock *sock = NULL;
    struct nl_pool *pool;

    ovs_assert(protocol >= 0 && protocol < ARRAY_SIZE(pools));

    ovs_mutex_lock(&pool_mutex);
    pool = &pools[protocol];<span style="white-space:pre">		</span>//根据协议检索,OVS2.5.0未看到初始化,所以不会进此流程
    if (pool->n > 0) {
        sock = pool->socks[--pool->n];
    }
    ovs_mutex_unlock(&pool_mutex);

    if (sock) {
        *sockp = sock;
        return 0;
    } else {
        return nl_sock_create(protocol, sockp);    //创建socket
    }
}
3、nl_sock_create函数

/* Creates a new netlink socket for the given netlink 'protocol'
 * (NETLINK_ROUTE, NETLINK_GENERIC, ...).  Returns 0 and sets '*sockp' to the
 * new socket if successful, otherwise returns a positive errno value. */
int
nl_sock_create(int protocol, struct nl_sock **sockp)
{
    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
    struct nl_sock *sock;
#ifndef _WIN32
    struct sockaddr_nl local, remote;
#endif
    socklen_t local_size;
    int rcvbuf;
    int retval = 0;

    if (ovsthread_once_start(&once)) {
        int save_errno = errno;
        errno = 0;

        max_iovs = sysconf(_SC_UIO_MAXIOV);
        if (max_iovs < _XOPEN_IOV_MAX) {
            if (max_iovs == -1 && errno) {
                VLOG_WARN("sysconf(_SC_UIO_MAXIOV): %s", ovs_strerror(errno));
            }
            max_iovs = _XOPEN_IOV_MAX;
        } else if (max_iovs > MAX_IOVS) {
            max_iovs = MAX_IOVS;
        }

        errno = save_errno;
        ovsthread_once_done(&once);
    }

    *sockp = NULL;
    sock = xmalloc(sizeof *sock);

#ifdef _WIN32
    sock->handle = CreateFile(OVS_DEVICE_NAME_USER,
                              GENERIC_READ | GENERIC_WRITE,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              NULL, OPEN_EXISTING,
                              FILE_FLAG_OVERLAPPED, NULL);

    if (sock->handle == INVALID_HANDLE_VALUE) {
        VLOG_ERR("fcntl: %s", ovs_lasterror_to_string());
        goto error;
    }

    memset(&sock->overlapped, 0, sizeof sock->overlapped);
    sock->overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (sock->overlapped.hEvent == NULL) {
        VLOG_ERR("fcntl: %s", ovs_lasterror_to_string());
        goto error;
    }
    /* Initialize the type/ioctl to Generic */
    sock->read_ioctl = OVS_IOCTL_READ;
#else
    sock->fd = socket(AF_NETLINK, SOCK_RAW, protocol);		//创建socket
    if (sock->fd < 0) {
        VLOG_ERR("fcntl: %s", ovs_strerror(errno));
        goto error;
    }
#endif

    sock->protocol = protocol;
    sock->next_seq = 1;

    rcvbuf = 1024 * 1024;
#ifdef _WIN32
    sock->rcvbuf = rcvbuf;
    retval = get_sock_pid_from_kernel(sock);
    if (retval != 0) {
        goto error;
    }
#else
    if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUFFORCE,
                   &rcvbuf, sizeof rcvbuf)) {
        /* Only ro
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值