net,loopback: small fix
[barrelfish] / lib / net / net.c
1 /*
2  * Copyright (c) 2017, ETH Zurich.
3  * All rights reserved.
4  *
5  * This file is distributed under the terms in the attached LICENSE file.
6  * If you do not find this file, copies can be found by writing to:
7  * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8  */
9
10 // stdlib includes
11
12 // barrelfish includes
13
14 // lwip includes
15 #include "lwip/init.h"
16 #include "lwip/netif.h"
17 #include "lwip/ip.h"
18 #include "lwip/dhcp.h"
19 #include "lwip/prot/ethernet.h"
20 #include "lwip/timeouts.h"
21
22 #include <barrelfish/barrelfish.h>
23 #include <barrelfish/deferred.h>
24 #include <barrelfish/waitset.h>
25 #include <barrelfish/waitset_chan.h>
26
27 #include <net/net_filter.h>
28 #include <net_interfaces/flags.h>
29 #include "networking_internal.h"
30
31 struct net_state state = {0};
32 struct waitset_chanstate net_loopback_poll_channel;
33 struct deferred_event net_lwip_timer;
34
35 #define NETWORKING_DEFAULT_QUEUE_ID 0
36 #define NETWORKING_BUFFER_COUNT (4096 * 3)
37 #define NETWORKING_BUFFER_RX_POPULATE (4096 - 10)
38 #define NETWORKING_BUFFER_SIZE  2048
39
40
41 #define NETDEBUG_SUBSYSTEM "net"
42
43 /**
44  * @brief obtains the default setting for initializaion of the driver
45  *
46  * @param queue     returns the queue to be used
47  * @param cardname  returns the card name to be used
48  *
49  * @return SYS_ERR_OK on success, SKB_ERR_* on failure
50  */
51 errval_t networking_get_defaults(uint64_t *queue, const char **cardname, uint32_t *flags)
52 {
53     /* TODO: get the values from the SKB */
54
55     *queue = NETWORKING_DEFAULT_QUEUE_ID;
56     //*cardname = "e10k";
57     *cardname = "sfn5122f";
58     *flags = NET_FLAGS_POLLING | NET_FLAGS_BLOCKING_INIT;
59     //*flags = NET_FLAGS_POLLING;
60
61     return SYS_ERR_OK;
62 }
63
64 static void int_handler(void* args)
65 {
66     struct net_state *st = devq_get_state(args);
67
68     net_if_poll(&st->netif);
69     net_lwip_timeout();
70 }
71
72 static void net_loopback_poll(void *arg)
73 {
74     netif_poll_all();
75     net_lwip_timeout();
76 }
77
78 void net_if_trigger_loopback(void)
79 {
80     errval_t err;
81     
82     err = waitset_chan_trigger(&net_loopback_poll_channel);
83     assert(err_is_ok(err));
84 }
85
86 void net_lwip_timeout(void)
87 {
88     errval_t err;
89
90     sys_check_timeouts();
91     deferred_event_cancel(&net_lwip_timer);
92     uint32_t delay = sys_timeouts_sleeptime();
93     if (delay != 0xffffffff) {
94         err = deferred_event_register(&net_lwip_timer, get_default_waitset(),
95             delay * 1000, MKCLOSURE((void (*)(void *))net_lwip_timeout, NULL));
96         assert(err_is_ok(err));
97     }
98 }
99
100 static errval_t create_loopback_queue (struct net_state *st, uint64_t* queueid,
101                                        struct devq **retqueue)
102 {
103     errval_t err;
104
105     debug_printf("net: creating loopback queue.\n");
106
107     *queueid = 0;
108     err = loopback_queue_create((struct loopback_queue **)retqueue);
109     if (err_is_fail(err)) {
110         return err;
111     }
112
113     return SYS_ERR_OK;
114 }
115
116 static errval_t create_driver_queue (struct net_state *st, uint64_t* queueid,
117                                      struct devq **retqueue)
118 {
119     *queueid = 0;
120     return SYS_ERR_OK;
121 }
122
123 // cardname - "e1000:vendor:deviceid:bus:device:function"
124 static errval_t create_e1000_queue(struct net_state *st, uint64_t *queueid,
125                                    struct devq **retqueue)
126 {
127     if (st->cardname[5] != ':') {
128         return SYS_ERR_OK;
129     }
130     uint32_t vendor, deviceid, bus, device, function;
131     unsigned parsed = sscanf(st->cardname + 6, "%x:%x:%x:%x:%x", &vendor,
132                              &deviceid, &bus, &device, &function);
133     if (parsed != 5) {
134         return SYS_ERR_OK;
135     }
136
137     return e1000_queue_create((struct e1000_queue**)retqueue, vendor, deviceid,
138                               bus, device, function, 1, int_handler);
139 }
140
141 static errval_t create_e10k_queue (struct net_state *st, uint64_t* queueid,
142                                    struct devq **retqueue)
143 {
144     errval_t err;
145     err = e10k_queue_create((struct e10k_queue**)retqueue, int_handler,
146                             false /*virtual functions*/,
147                             !(st->flags & NET_FLAGS_POLLING), /* user interrupts*/
148                             (st->flags & NET_FLAGS_DEFAULT_QUEUE));
149     *queueid = e10k_queue_get_id((struct e10k_queue*)*retqueue);
150     return err;
151 }
152
153 static errval_t create_sfn5122f_queue (struct net_state *st, uint64_t* queueid,
154                                        struct devq **retqueue)
155 {
156     errval_t err;
157     err = sfn5122f_queue_create((struct sfn5122f_queue**)retqueue, int_handler,
158                                 false /*userlevel network feature*/,
159                                 !(st->flags & NET_FLAGS_POLLING) /* user interrupts*/,
160                                 (st->flags & NET_FLAGS_DEFAULT_QUEUE));
161     *queueid = sfn5122f_queue_get_id((struct sfn5122f_queue*)*retqueue);
162     return err;
163 }
164
165
166 typedef errval_t (*queue_create_fn)(struct net_state *, uint64_t*, struct devq **);
167 struct networking_card
168 {
169     char *cardname;
170     queue_create_fn createfn;
171 } networking_cards [] = {
172     { "loopback", create_loopback_queue},
173     { "driver", create_driver_queue},
174     { "e1000", create_e1000_queue},
175     { "e10k", create_e10k_queue},
176     { "sfn5122f", create_sfn5122f_queue},
177     { NULL, NULL}
178 };
179
180
181 /**
182  * @brief creates a queue to the given card and the queueid
183  *
184  * @param cardname  network card to create the queue for
185  * @param queueid   queueid of the network card
186  * @param retqueue  returns the pointer to the queue
187  *
188  * @return SYS_ERR_OK on success, errval on failure
189  */
190 static errval_t net_create_queue(struct net_state *st, const char *cardname,
191                                  uint64_t* queueid, struct devq **retqueue)
192 {
193     debug_printf("net: creating queue for card='%s'...\n",
194                   cardname);
195
196     struct networking_card *nc = networking_cards;
197     while(nc->cardname != NULL) {
198         if (strncmp(cardname, nc->cardname, strlen(nc->cardname)) == 0) {
199             return nc->createfn(st, queueid, retqueue);
200         }
201         nc++;
202     }
203
204     debug_printf("net: ERROR unknown queue. card='%s', queueid=%" PRIu64 "\n",
205                   cardname, *queueid);
206
207     return -1;
208 }
209
210 /**
211  * @brief creates a queue to the given card and the queueid
212  *
213  * @param cardname  network card to create the queue for
214  * @param queueid   queueid of the network card
215  * @param retqueue  returns the pointer to the queue
216  *
217  * @return SYS_ERR_OK on success, errval on failure
218  */
219 errval_t networking_create_queue(const char *cardname, uint64_t* queueid,
220                                  struct devq **retqueue)
221 {
222     struct net_state *st = get_default_net_state();
223
224     return net_create_queue(st, cardname, queueid, retqueue);
225 }
226
227
228
229 static errval_t networking_poll_st(struct net_state *st)
230 {
231     event_dispatch_non_block(get_default_waitset());
232     if (st->flags & NET_FLAGS_POLLING) {
233         return net_if_poll(&st->netif);
234     } else {
235         return event_dispatch_non_block(get_default_waitset());
236     }
237 }
238
239
240
241
242 /**
243  * @brief initializes the networking library with a given device queue
244  *
245  * @param st        the networking state to initialize
246  * @param q         the device queue to initialize the networking on
247  * @param flags     supplied initialization flags
248  *
249  * @return SYS_ERR_OK on success, errval on failure
250  */
251 static errval_t networking_init_with_queue_st(struct net_state *st, struct devq *q,
252                                               net_flags_t flags)
253 {
254     errval_t err;
255
256     NETDEBUG("initializing networking with devq=%p, flags=%" PRIx32 "...\n", q,
257              flags);
258
259     if (st->initialized) {
260         debug_printf("WARNING. initialize called twice. Ignoring\n");
261         return SYS_ERR_OK;
262     }
263
264     /* set the variables */
265     st->flags = flags;
266     st->queue = q;
267     st->initialized = true;
268     st->waitset = get_default_waitset();
269
270     /* associate the net state with the device queue */
271     devq_set_state(st->queue, st);
272
273     /* create buffers and add them to the interface*/
274     err = net_buf_pool_alloc(st->queue, NETWORKING_BUFFER_COUNT,
275                              NETWORKING_BUFFER_SIZE, &st->pool);
276     if (err_is_fail(err)) {
277         //net_if_destroy(&st->netif);
278         goto out_err1;
279     }
280
281     deferred_event_init(&net_lwip_timer);
282     /* initialize the device queue */
283     NETDEBUG("initializing LWIP...\n");
284     lwip_init();
285
286     /* create the LWIP network interface and initialize it */
287     NETDEBUG("creating netif for LWIP...\n");
288     err = net_if_init_devq(&st->netif, st->queue);
289     if (err_is_fail(err)) {
290         goto out_err1;
291     }
292
293     err = net_if_add(&st->netif, st);
294     if (err_is_fail(err)) {
295         goto out_err1;
296     }
297
298     if (!(flags & NET_FLAGS_NO_NET_FILTER)) {
299         NETDEBUG("initializing hw filter...\n");
300
301         err = net_filter_init(&st->filter, st->cardname);
302         if (err_is_fail(err)) {
303             USER_PANIC("Init filter infrastructure failed: %s \n", err_getstring(err));
304         }
305     }
306
307     NETDEBUG("setting default netif...\n");
308     netif_set_default(&st->netif);
309
310     NETDEBUG("adding RX buffers\n");
311     for (int i = 0; i < NETWORKING_BUFFER_RX_POPULATE; i++) {
312         struct pbuf *p = net_buf_alloc(st->pool);
313         if (p == NULL) {
314             NETDEBUG("net: WARNING there was no buffer\n");
315             break;
316         }
317         err = net_if_add_rx_buf(&st->netif, p);
318         if (err_is_fail(err)) {
319             break;
320         }
321     }
322
323     if (flags & NET_FLAGS_DO_DHCP) {
324         err = dhcpd_start(flags);
325         if (err_is_fail(err)) {
326             DEBUG_ERR(err, "failed to start DHCP.\n");
327         }
328
329         err = arp_service_start();
330         if (err_is_fail(err)) {
331             DEBUG_ERR(err,  "failed to start the ARP service\n");
332         }
333     } else {
334         /* get static IP config */
335         err = net_config_static_ip_query(flags);
336         if (err_is_fail(err)) {
337             DEBUG_ERR(err, "failed to set IP.\n");
338         }
339
340         err = arp_service_subscribe();
341         if (err_is_fail(err)) {
342             DEBUG_ERR(err, "failed to subscribte the ARP service\n");
343         }
344     }
345
346     waitset_chanstate_init(&net_loopback_poll_channel, CHANTYPE_OTHER);
347     net_loopback_poll_channel.persistent = true;
348     err = waitset_chan_register(get_default_waitset(), &net_loopback_poll_channel,
349                                MKCLOSURE(net_loopback_poll, NULL));
350
351     NETDEBUG("initialization complete.\n");
352
353     return SYS_ERR_OK;
354
355     out_err1:
356     st->initialized = false;
357
358     return err;
359
360 }
361
362 /**
363  * @brief initializes the networking library
364  *
365  * @param st        the networking state to be initalized
366  * @param nic       the nic to use with the networking library
367  * @param flags     flags to use to initialize the networking library
368  *
369  * @return SYS_ERR_OK on success, errval on failure
370  */
371 static errval_t networking_init_st(struct net_state *st, const char *nic,
372                                    net_flags_t flags)
373 {
374     errval_t err;
375
376     NETDEBUG("initializing networking with nic=%s, flags=%" PRIx32 "...\n", nic,
377              flags);
378
379     if(st->initialized) {
380         NETDEBUG("WARNING. initialize called twice. Ignoring\n");
381         return SYS_ERR_OK;
382     }
383
384     st->cardname = nic;
385     st->flags = flags;
386
387     /* create the queue wit the given nic and card name */
388     err = networking_create_queue(st->cardname, &st->queueid, &st->queue);
389     if (err_is_fail(err)) {
390         return err;
391     }
392
393     err = networking_init_with_queue_st(st, st->queue, flags);
394     if (err_is_fail(err)) {
395        // devq_destroy(st->queue);
396     }
397
398     return err;
399 }
400
401 /**
402  * @brief initializes the networking with the defaults
403  *
404  * @param st    the networking state to be initialized
405  *
406  * @return SYS_ERR_OK on sucess, errval on failure
407  */
408 static errval_t networking_init_default_st(struct net_state *st)
409 {
410     errval_t err;
411
412     NETDEBUG("initializing networking with default options...\n");
413
414     if(st->initialized) {
415         NETDEBUG("WARNING. initialize called twice. Ignoring\n");
416         return SYS_ERR_OK;
417     }
418
419     // obtain the settings to create the queue
420     err = networking_get_defaults(&st->queueid, &st->cardname, &st->flags);
421     if (err_is_fail(err)) {
422         return err;
423     }
424
425     return networking_init_st(st, st->cardname, st->flags);
426 }
427
428
429
430 /*
431  * ===========================================================================
432  * Public interface
433  * ===========================================================================
434  */
435
436 /**
437  * @brief initializes the networking library with a given device queue
438  *
439  * @param q         the device queue to initialize the networking on
440  * @param flags     supplied initialization flags
441  *
442  * @return SYS_ERR_OK on success, errval on failure
443  */
444 errval_t networking_init_with_queue(struct devq *q, net_flags_t flags)
445 {
446     struct net_state *st = get_default_net_state();
447     return networking_init_with_queue_st(st, q, flags);
448 }
449
450 /**
451  * @brief initializes the networking library
452  *
453  * @param nic       the nic to use with the networking library
454  * @param flags     flags to use to initialize the networking library
455  *
456  * @return SYS_ERR_OK on success, errval on failure
457  */
458 errval_t networking_init(const char *nic, net_flags_t flags)
459 {
460     struct net_state *st = get_default_net_state();
461     return networking_init_st(st, nic, flags);
462 }
463
464
465 /**
466  * @brief initializes the networking with the defaults
467  *
468  * @return SYS_ERR_OK on success, errval on failure
469  */
470 errval_t networking_init_default(void)
471 {
472     struct net_state *st = get_default_net_state();
473     return networking_init_default_st(st);
474 }
475
476
477 /**
478  * @brief polls the network for new packets
479  *
480  * @return SYS_ERR_OK on success, errval on failure
481  */
482 errval_t networking_poll(void)
483 {
484     struct net_state *st = &state;
485     return networking_poll_st(st);
486 }
487
488
489 /**
490  * @brief Install L3/L4 filter
491  *
492  * @param tcp       should TCP packets be filtered or UPD
493  * @param src_ip    source ip of the filter, 0 for wildcard
494  * @param src_port  source port of the filter, 0 for wildcard
495  * @param dst_port  destination port fo the filter
496  *
497  * @return SYS_ERR_OK on success, NET_FILTER_ERR_* on failure
498  */
499 errval_t networking_install_ip_filter(bool tcp, struct in_addr *src,
500                                       uint16_t src_port, uint16_t dst_port)
501 {
502     errval_t err;
503     if (state.filter == NULL) {
504         return NET_FILTER_ERR_NOT_INITIALIZED;
505     }
506
507     struct net_filter_state *st = state.filter;
508
509     // get current config
510     struct in_addr dst_ip;
511     err = netif_get_ipconfig(&dst_ip, NULL, NULL);
512     if (err_is_fail(err)) {
513         return err;
514     }
515     
516     struct net_filter_ip ip = {
517         .qid = state.queueid,
518         .ip_src = (uint32_t) src->s_addr,
519         .ip_dst = (uint32_t) dst_ip.s_addr,
520         .port_dst = dst_port,
521         .port_src = src_port,
522     };
523
524     if (tcp) {
525         ip.type = NET_FILTER_TCP;
526     } else {
527         ip.type = NET_FILTER_UDP;
528     }
529     
530     return net_filter_ip_install(st, &ip);
531 }
532
533 /**
534  * @brief Remove L3/L4 filter
535  *
536  * @param tcp       should TCP packets be filtered or UPD
537  * @param src_ip    source ip of the filter, 0 for wildcard
538  * @param src_port  source port of the filter, 0 for wildcard
539  * @param dst_port  destination port fo the filter
540  *
541  * @return SYS_ERR_OK on success, NET_FILTER_ERR_* on failure
542  */
543 errval_t networking_remove_ip_filter(bool tcp, struct in_addr *src,
544                                      uint16_t src_port, uint16_t dst_port)
545 {
546
547     errval_t err;
548     if (state.filter == NULL) {
549         return NET_FILTER_ERR_NOT_INITIALIZED;
550     }
551
552     struct net_filter_state *st = state.filter;
553
554     // get current config
555     struct in_addr dst_ip;
556     err = netif_get_ipconfig(&dst_ip, NULL, NULL);
557     if (err_is_fail(err)) {
558         return err;
559     }
560     
561     struct net_filter_ip ip = {
562         .qid = state.queueid,
563         .ip_src = (uint32_t) src->s_addr,
564         .ip_dst = (uint32_t) dst_ip.s_addr,
565         .port_dst = dst_port,
566         .port_src = src_port,
567     };
568
569     if (tcp) {
570         ip.type = NET_FILTER_TCP;
571     } else {
572         ip.type = NET_FILTER_UDP;
573     }
574     
575     return net_filter_ip_remove(st, &ip);
576 }