2 * Copyright (c) 2015 Mohamed Aslan <maslan@sce.carleton.ca>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <sys/event.h>
28 #include <netinet/in.h>
34 #define TCPBACKLOG 500
40 of_print_header(struct ofp_header
*hdr
)
44 printf("header -> {version = %d, type = %d, length = %d, xid = %x}\n",
45 (unsigned int)hdr
->version
,
46 (unsigned int)hdr
->type
,
47 (unsigned int)be16toh(hdr
->length
),
48 (unsigned int)be32toh(hdr
->xid
));
53 sendtosocket(int skt
, struct ofp_header
*hdr
)
55 assert(be16toh(hdr
->length
) >= sizeof(struct ofp_header
));
56 if (be16toh(hdr
->length
) >= sizeof(struct ofp_header
))
57 write(skt
, hdr
, (size_t)be16toh(hdr
->length
)); // FIXME: error check
61 send_msg(struct of_controller
*controller
, struct of_dataplane
*dp
, struct ofp_header
*hdr
)
63 if (controller
== NULL
|| dp
== NULL
|| hdr
== NULL
)
65 sendtosocket(dp
->socket
, hdr
);
69 heartbeat(struct of_controller
*controller
)
71 size_t iter
, ksz
, vsz
;
75 struct of_dataplane
*dp
;
78 /* TODO: something smarter */
79 HASHTAB_FOREACH(controller
->dpids
, iter
, dpid
, ksz
, ptr
, vsz
) {
80 hashtab_at(&(controller
->dpids
), iter
, (void **)(&dpid
), &ksz
, (void **)(&ptr
), &vsz
);
81 dp
= (struct of_dataplane
*)(*ptr
);
82 if (dp
->ready
&& (now
>= (dp
->lastmsg_ts
+ HEARTBEAT
))) {
84 printf("last pinged %ju, now is %ju (%ju)\n", dp
->lastmsg_ts
, now
, (now
- dp
->lastmsg_ts
));
85 printf("heartbeating: dpid 0x%llx\n", *dpid
);
87 dp
->protocol
->ping(controller
, dp
);
93 timer(struct of_controller
*controller
, unsigned int period
, void (*callback
)(struct of_controller
*))
99 if (controller
->n_timers
>= MAXTIMERS
)
101 tid
= controller
->n_timers
;
102 ptr
= (uintptr_t)callback
;
103 EV_SET(&kev
, tid
, EVFILT_TIMER
, EV_ADD
| EV_ENABLE
, 0, period
, NULL
);
104 if ((kevent(controller
->ev_queue
, &kev
, 1, NULL
, 0, NULL
)) == -1)
106 /*printf("callback: 0x%llx (%zu)\n", ptr, sizeof(uintptr_t));*/
107 if (!hashtab_put(&(controller
->timer_callbacks
), (void *)(&tid
), sizeof(int), (void *)(&ptr
), sizeof(uintptr_t)))
108 errx(1, "hashtab_put");
109 controller
->n_timers
++;
113 handler(struct of_controller
*controller
, void (*callback
)(struct of_controller
*, struct of_event
*))
115 controller
->of_handler
= callback
;
119 event_loop(struct of_controller
*controller
)
121 char buf
[BUFSIZ
+ 1];
126 struct sockaddr_in sa
;
127 struct sockaddr_storage sw_addr
;
128 struct of_dataplane
*dp
;
129 struct ofp_header
*recv
;
130 socklen_t addr_len
= sizeof(struct sockaddr_storage
);
132 void (*callback
)(struct of_controller
*);
134 if (controller
== NULL
)
136 if ((controller
->socket
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0)
138 memset(&sa
, 0, sizeof sa
);
139 sa
.sin_family
= AF_INET
;
140 sa
.sin_port
= htons(controller
->port
);
141 sa
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
143 if (bind(controller
->socket
, (struct sockaddr
*)&sa
, sizeof(sa
)) == -1) {
144 close(controller
->socket
);
148 if (listen(controller
->socket
, TCPBACKLOG
) == -1) {
149 close(controller
->socket
);
153 EV_SET(&kev
, controller
->socket
, EVFILT_READ
, EV_ADD
, 0, 0, NULL
);
154 if ((kevent(controller
->ev_queue
, &kev
, 1, NULL
, 0, NULL
)) == -1) {
155 close(controller
->socket
);
160 n
= kevent(controller
->ev_queue
, NULL
, 0, &kev
, 1, NULL
); /* TODO: use bigger eventlist */
162 errx(1, "event_loop");
165 if (kev
.filter
== EVFILT_TIMER
) { /* timers */
166 s
= (int)(kev
.ident
); /* uintptr_t != int */
167 if (!hashtab_get(&(controller
->timer_callbacks
), (void *)(&s
), sizeof(int), (void **)(&ptr
), &sz
))
168 errx(1, "hashtab_get");
169 callback
= (void (*)(struct of_controller
*))(*ptr
);
170 //printf("callback: 0x%llx (%zu) for timer %d\n", callback, sz, s);
171 callback(controller
);
172 } else if (kev
.filter
== EVFILT_READ
) { /* sockets */
173 s
= (int)(kev
.ident
); /* uintptr_t != int */
174 if (s
== controller
->socket
) { /* server socket: new connection */
175 dp
= (struct of_dataplane
*)calloc(1, sizeof(struct of_dataplane
));
176 dp
->socket
= accept(controller
->socket
, (struct sockaddr
*)&sw_addr
, &addr_len
);
177 if (fcntl(dp
->socket
, F_SETFL
, O_NONBLOCK
) == -1)
180 if (!hashtab_put(&(controller
->conns
), (void *)(&(dp
->socket
)), sizeof(dp
->socket
), (void *)(&p
), sizeof(uintptr_t)))
181 errx(1, "hashtab_put");
182 printf("new connection.\n");
183 EV_SET(&kev
, dp
->socket
, EVFILT_READ
, EV_ADD
| EV_CLEAR
, 0, 0, NULL
);
184 if ((kevent(controller
->ev_queue
, &kev
, 1, NULL
, 0, NULL
)) == -1) {
188 controller
->protocol
->handshake(controller
, dp
);
189 } else { /* a client socket */
190 bytes
= read(s
, buf
, sizeof(buf
));
192 printf("connection closed.\n");
193 EV_SET(&kev
, s
, EVFILT_READ
, EV_DELETE
, 0, 0, NULL
);
194 if ((kevent(controller
->ev_queue
, &kev
, 1, NULL
, 0, NULL
)) == -1) {
199 /* TODO: remove from hashtabs and free structs */
201 else if (bytes
< sizeof(struct ofp_header
)) {
202 printf("error! %zd\n", bytes
);
206 if (!hashtab_get(&(controller
->conns
), (void *)&s
, sizeof(s
), (void **)(&ptr
), &sz
))
207 errx(1, "hashtab_get");
208 assert(sz
== sizeof(uintptr_t));
209 dp
= (struct of_dataplane
*)(*ptr
);
211 printf("read %zd bytes.\n", bytes
);
213 recv
= (struct ofp_header
*)buf
;
214 dp
->lastmsg_ts
= time(NULL
);
215 controller
->protocol
->recv(controller
, dp
, recv
);
223 of_controller_init(struct of_controller
*controller
, int port
, const struct of_protocol
*proto
)
225 if ((controller
->socket
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
227 controller
->port
= port
;
228 controller
->n_timers
= 0;
229 controller
->protocol
= proto
;
230 controller
->send
= send_msg
;
231 controller
->loop
= event_loop
;
232 controller
->timer
= timer
;
233 controller
->handler
= handler
;
234 controller
->of_handler
= NULL
;
235 if ((controller
->ev_queue
= kqueue()) == -1)
237 if (!hashtab_init(&(controller
->conns
), 8, NULL
))
238 errx(1, "hashtab_init");
239 if (!hashtab_init(&(controller
->dpids
), 8, NULL
))
240 errx(1, "hashtab_init");
241 if (!hashtab_init(&(controller
->timer_callbacks
), 8, NULL
))
242 errx(1, "hashtab_init");
243 controller
->timer(controller
, 3000, heartbeat
);