2010-12-10 09:51:03 -08:00
|
|
|
/*
|
2011-01-09 16:57:45 -08:00
|
|
|
* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
|
2010-12-10 09:51:03 -08:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at:
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef NETLINK_SOCKET_H
|
|
|
|
#define NETLINK_SOCKET_H 1
|
|
|
|
|
|
|
|
/* Netlink socket definitions.
|
|
|
|
*
|
|
|
|
* Netlink is a datagram-based network protocol primarily for communication
|
|
|
|
* between user processes and the kernel, and mainly on Linux. Netlink is
|
|
|
|
* specified in RFC 3549, "Linux Netlink as an IP Services Protocol".
|
|
|
|
*
|
|
|
|
* Netlink is not suitable for use in physical networks of heterogeneous
|
|
|
|
* machines because host byte order is used throughout.
|
|
|
|
*
|
|
|
|
* This header file defines functions for working with Netlink sockets, which
|
|
|
|
* are Linux-specific. For Netlink protocol definitions, see
|
|
|
|
* netlink-protocol.h. For helper functions for working with Netlink messages,
|
|
|
|
* see netlink.h.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
2011-10-14 13:55:00 -07:00
|
|
|
#include "list.h"
|
2010-12-10 09:51:03 -08:00
|
|
|
|
|
|
|
struct ofpbuf;
|
|
|
|
struct nl_sock;
|
|
|
|
|
|
|
|
#ifndef HAVE_NETLINK
|
|
|
|
#error "netlink-socket.h is only for hosts that support Netlink sockets"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Netlink sockets. */
|
2011-01-09 16:57:45 -08:00
|
|
|
int nl_sock_create(int protocol, struct nl_sock **);
|
netlink-socket: Make dumping and doing transactions on same nl_sock safe.
It's not safe to use a single Netlink fd to do multiple operations in an
synchronous way. Some of the limitations are fundamental; for example, the
kernel only supports a single "dump" operation at a time. Others are
limitations imposed by the OVS coding style; for example, our Netlink
library is not callback based, so nothing can be done about incoming
messages that can't be handled immediately. Regardless, in OVS multicast
groups, transactions, and dumps cannot coexist on a single nl_sock.
This is only mildly irritating at the moment, but it will become much worse
later on, when dpif-linux shifts to using Netlink dumps for listing various
kinds of datapath entities. When that happens, a dump will be in progress
in situations where the dpif-linux client might want to do other
operations. For example, it is reasonable for the client to list flows
and, in the middle, look up information on vports mentioned in those flows.
It might be possible to simply ban and avoid such nested operations--I have
not even audited the source tree to find out whether we do anything like
that already--but that seems like an unnecessary cramp on our coding style.
Furthermore, it's difficult to explain and justify without understanding
the implementation.
This patch takes another approach, by improving the Netlink socket library
to avoid artificial constraints. When an operation, or a dump, or joining
a multicast group would cause a problem, this patch makes the library
transparently create a separate Netlink socket. This solves the problem
without putting any onerous restrictions on use.
This commit also slightly simplifies netdev_vport_reset_names(). It had
been written to destroy the dump object before the Netlink socket that it
used, but this is no longer necessary and doing it in the opposite order
saved a few lines of code.
Reviewed by Ethan Jackson <ethan@nicira.com>.
2011-01-22 15:23:10 -08:00
|
|
|
int nl_sock_clone(const struct nl_sock *, struct nl_sock **);
|
2010-12-10 09:51:03 -08:00
|
|
|
void nl_sock_destroy(struct nl_sock *);
|
|
|
|
|
2011-01-09 16:57:45 -08:00
|
|
|
int nl_sock_join_mcgroup(struct nl_sock *, unsigned int multicast_group);
|
|
|
|
int nl_sock_leave_mcgroup(struct nl_sock *, unsigned int multicast_group);
|
|
|
|
|
2010-12-10 09:51:03 -08:00
|
|
|
int nl_sock_send(struct nl_sock *, const struct ofpbuf *, bool wait);
|
|
|
|
int nl_sock_recv(struct nl_sock *, struct ofpbuf **, bool wait);
|
|
|
|
int nl_sock_transact(struct nl_sock *, const struct ofpbuf *request,
|
|
|
|
struct ofpbuf **reply);
|
|
|
|
|
2011-01-11 16:05:37 -08:00
|
|
|
int nl_sock_drain(struct nl_sock *);
|
|
|
|
|
2010-12-10 09:51:03 -08:00
|
|
|
void nl_sock_wait(const struct nl_sock *, short int events);
|
|
|
|
|
2011-09-16 09:37:16 -07:00
|
|
|
uint32_t nl_sock_pid(const struct nl_sock *);
|
|
|
|
|
2011-10-14 13:55:00 -07:00
|
|
|
/* Batching transactions. */
|
|
|
|
struct nl_transaction {
|
|
|
|
/* Filled in by client. */
|
|
|
|
struct ofpbuf *request; /* Request to send. */
|
|
|
|
|
|
|
|
/* Filled in by nl_sock_transact_batch(). */
|
|
|
|
struct ofpbuf *reply; /* Reply (NULL if reply was an error code). */
|
|
|
|
int error; /* Positive errno value, 0 if no error. */
|
|
|
|
};
|
|
|
|
|
|
|
|
void nl_sock_transact_multiple(struct nl_sock *,
|
|
|
|
struct nl_transaction **, size_t n);
|
|
|
|
|
2010-12-10 09:51:03 -08:00
|
|
|
/* Table dumping. */
|
|
|
|
struct nl_dump {
|
|
|
|
struct nl_sock *sock; /* Socket being dumped. */
|
|
|
|
uint32_t seq; /* Expected nlmsg_seq for replies. */
|
|
|
|
struct ofpbuf *buffer; /* Receive buffer currently being iterated. */
|
|
|
|
int status; /* 0=OK, EOF=done, or positive errno value. */
|
|
|
|
};
|
|
|
|
|
|
|
|
void nl_dump_start(struct nl_dump *, struct nl_sock *,
|
|
|
|
const struct ofpbuf *request);
|
|
|
|
bool nl_dump_next(struct nl_dump *, struct ofpbuf *reply);
|
|
|
|
int nl_dump_done(struct nl_dump *);
|
|
|
|
|
|
|
|
/* Miscellaneous */
|
|
|
|
int nl_lookup_genl_family(const char *name, int *number);
|
2011-08-23 13:13:34 -07:00
|
|
|
int nl_lookup_genl_mcgroup(const char *family_name, const char *group_name,
|
2011-09-12 18:57:50 -07:00
|
|
|
unsigned int *multicast_group,
|
|
|
|
unsigned int fallback);
|
2010-12-10 09:51:03 -08:00
|
|
|
|
|
|
|
#endif /* netlink-socket.h */
|