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