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