X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetlink-socket.h;h=dd324090759af85d4852f6dacb0ef7698fe6e4bb;hb=003ce655b7116d18c86a74c50391e54990346931;hp=43b4b023da046fef490c8258ea47c191bc56b0a9;hpb=5e9fd01b6ec0c488a4a24e481486557f97057bff;p=sliver-openvswitch.git diff --git a/lib/netlink-socket.h b/lib/netlink-socket.h index 43b4b023d..dd3240907 100644 --- a/lib/netlink-socket.h +++ b/lib/netlink-socket.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,13 +30,29 @@ * are Linux-specific. For Netlink protocol definitions, see * netlink-protocol.h. For helper functions for working with Netlink messages, * see netlink.h. + * + * + * Thread-safety + * ============= + * + * Most of the netlink functions are not fully thread-safe: Only a single + * thread may use a given nl_sock or nl_dump at one time. The exceptions are: + * + * - nl_sock_recv() is conditionally thread-safe: it may be called from + * different threads with the same nl_sock, but each caller must provide + * an independent receive buffer. + * + * - nl_dump_next() is conditionally thread-safe: it may be called from + * different threads with the same nl_dump, but each caller must provide + * independent buffers. */ #include #include #include +#include "ofpbuf.h" +#include "ovs-atomic.h" -struct ofpbuf; struct nl_sock; #ifndef HAVE_NETLINK @@ -52,28 +68,62 @@ int nl_sock_join_mcgroup(struct nl_sock *, unsigned int multicast_group); int nl_sock_leave_mcgroup(struct nl_sock *, unsigned int multicast_group); 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_send_seq(struct nl_sock *, const struct ofpbuf *, + uint32_t nlmsg_seq, 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); + struct ofpbuf **replyp); int nl_sock_drain(struct nl_sock *); void nl_sock_wait(const struct nl_sock *, short int events); +int nl_sock_fd(const struct nl_sock *); + +uint32_t nl_sock_pid(const struct nl_sock *); + +/* Batching transactions. */ +struct nl_transaction { + /* Filled in by client. */ + struct ofpbuf *request; /* Request to send. */ + + /* The client must initialize 'reply' to one of: + * + * - NULL, if it does not care to examine the reply. + * + * - Otherwise, to an ofpbuf with a memory allocation of at least + * NLMSG_HDRLEN bytes. + */ + struct ofpbuf *reply; /* Reply (empty 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); + +/* Transactions without an allocated socket. */ +int nl_transact(int protocol, const struct ofpbuf *request, + struct ofpbuf **replyp); +void nl_transact_multiple(int protocol, struct nl_transaction **, size_t n); /* Table dumping. */ +#define NL_DUMP_BUFSIZE 4096 + 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. */ + uint32_t nl_seq; /* Expected nlmsg_seq for replies. */ + atomic_uint status; /* Low bit set if we read final message. + * Other bits hold an errno (0 for success). */ + struct seq *status_seq; /* Tracks changes to the above 'status'. */ }; -void nl_dump_start(struct nl_dump *, struct nl_sock *, +void nl_dump_start(struct nl_dump *, int protocol, const struct ofpbuf *request); -bool nl_dump_next(struct nl_dump *, struct ofpbuf *reply); +bool nl_dump_next(struct nl_dump *, struct ofpbuf *reply, struct ofpbuf *buf); int nl_dump_done(struct nl_dump *); /* Miscellaneous */ int nl_lookup_genl_family(const char *name, int *number); +int nl_lookup_genl_mcgroup(const char *family_name, const char *group_name, + unsigned int *multicast_group); #endif /* netlink-socket.h */