Support SSL in secchan and controller.
[sliver-openvswitch.git] / lib / vconn-netlink.c
1 /* Copyright (C) 2007 Board of Trustees, Leland Stanford Jr. University.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21
22 #include "vconn.h"
23 #include <arpa/inet.h>
24 #include <assert.h>
25 #include <errno.h>
26 #include <netdb.h>
27 #include <poll.h>
28 #include <netinet/in.h>
29 #include <netinet/tcp.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include "openflow-netlink.h"
34 #include "buffer.h"
35 #include "dpif.h"
36 #include "netlink.h"
37 #include "socket-util.h"
38 #include "util.h"
39 #include "openflow.h"
40
41 #include "vlog.h"
42 #define THIS_MODULE VLM_VCONN_NETLINK
43
44 struct netlink_vconn
45 {
46     struct vconn vconn;
47     struct dpif dp;
48 };
49
50 static struct netlink_vconn *
51 netlink_vconn_cast(struct vconn *vconn) 
52 {
53     assert(vconn->class == &netlink_vconn_class);
54     return CONTAINER_OF(vconn, struct netlink_vconn, vconn); 
55 }
56
57 static int
58 netlink_open(const char *name, char *suffix, struct vconn **vconnp)
59 {
60     struct netlink_vconn *netlink;
61     int dp_idx;
62     int retval;
63
64     if (sscanf(suffix, "%d", &dp_idx) != 1) {
65         fatal(0, "%s: bad peer name format", name);
66     }
67
68     netlink = xmalloc(sizeof *netlink);
69     netlink->vconn.class = &netlink_vconn_class;
70     retval = dpif_open(dp_idx, true, &netlink->dp);
71     if (retval) {
72         free(netlink);
73         *vconnp = NULL;
74         return retval;
75     }
76     *vconnp = &netlink->vconn;
77     return 0;
78 }
79
80 static void
81 netlink_close(struct vconn *vconn) 
82 {
83     struct netlink_vconn *netlink = netlink_vconn_cast(vconn);
84     dpif_close(&netlink->dp);
85     free(netlink);
86 }
87
88 static bool
89 netlink_prepoll(struct vconn *vconn, int want, struct pollfd *pfd) 
90 {
91     struct netlink_vconn *netlink = netlink_vconn_cast(vconn);
92     pfd->fd = nl_sock_fd(netlink->dp.sock);
93     if (want & WANT_RECV) {
94         pfd->events |= POLLIN;
95     }
96     if (want & WANT_SEND) {
97         pfd->events |= POLLOUT;
98     }
99     return false;
100 }
101
102 static int
103 netlink_recv(struct vconn *vconn, struct buffer **bufferp)
104 {
105     struct netlink_vconn *netlink = netlink_vconn_cast(vconn);
106     return dpif_recv_openflow(&netlink->dp, bufferp, false);
107 }
108
109 static int
110 netlink_send(struct vconn *vconn, struct buffer *buffer) 
111 {
112     struct netlink_vconn *netlink = netlink_vconn_cast(vconn);
113     int retval = dpif_send_openflow(&netlink->dp, buffer, false);
114     if (!retval) {
115         buffer_delete(buffer);
116     }
117     return retval;
118 }
119
120 struct vconn_class netlink_vconn_class = {
121     .name = "nl",
122     .open = netlink_open,
123     .close = netlink_close,
124     .prepoll = netlink_prepoll,
125     .recv = netlink_recv,
126     .send = netlink_send,
127 };