Skip to content

Conversation

miri64
Copy link
Member

@miri64 miri64 commented Jun 4, 2016

This PR introduces a new common network interface API. Interfaces are identified by a unique ID. Currently this ID is their position in a global list, that is why interfaces can't be deleted. Alternatively we could add the ID as a field to netif_t, but I don't think that deleting an interface is a use-case we need.

Things to do as a follow-up PR:

  • add option handling
  • implement for existing network stacks
  • port ifconfig to this API

Depends on #5510. (merged)

@miri64 miri64 added Area: network Area: Networking Type: new feature The issue requests / The PR implemements a new feature for RIOT Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR State: waiting for other PR State: The PR requires another PR to be merged first labels Jun 4, 2016
@miri64
Copy link
Member Author

miri64 commented Jun 4, 2016

I changed it so the ID is now starting with 1. This leaves 0 for special cases (e.g. any or no interface), which is easier to handle, because if such a value is in set of variables one can simply call memset().

@miri64 miri64 force-pushed the netif/api/initial branch from 062b719 to 26bf426 Compare June 8, 2016 16:55
@miri64
Copy link
Member Author

miri64 commented Jun 8, 2016

Rebased and squashed to current master.

@miri64 miri64 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed State: waiting for other PR State: The PR requires another PR to be merged first labels Jun 8, 2016
@kaspar030
Copy link
Contributor

Whats the use-case for this?

@miri64
Copy link
Member Author

miri64 commented Jun 8, 2016

E.g. selecting a specific interface to send over for conn. Also fixing #4852 and helpful for solving #5055.

@miri64
Copy link
Member Author

miri64 commented Jun 8, 2016

Another one could be implementing POSIX net/if.h with it.

@miri64 miri64 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Jun 8, 2016
@miri64
Copy link
Member Author

miri64 commented Jun 8, 2016

Oh, and making ifconfig stack independent ;-).

@miri64
Copy link
Member Author

miri64 commented Aug 30, 2016

Except for some setting/getting options (which only would be required for implementing ifconfig at the moment anyway), but especially for #5772 this could provide a common interface, that is currently very GNRC specific.

@miri64
Copy link
Member Author

miri64 commented Aug 30, 2016

Oh, I just saw, that an ANY_INTERFACE ID is still missing from this PR. Will do.

@miri64
Copy link
Member Author

miri64 commented Aug 30, 2016

Done.

@kaspar030
Copy link
Contributor

@miri64 IMHO this is way too fat...

@kaspar030 kaspar030 added bloat Discussion: contested The item of discussion was contested labels Aug 30, 2016
@miri64
Copy link
Member Author

miri64 commented Aug 30, 2016

@miri64 IMHO this is way too fat...

Interesting what counts as bloat these days (3 functions, 44 loc, mainly consting of very short loops...; without the DEVELHELP stuff)

@miri64
Copy link
Member Author

miri64 commented Aug 30, 2016

With NETIF_NAMED unset:

  • netif struct 3 words long (I guess if it were an array we could get it down to 2, one for the device, one for the stack internal structure).
$ arm-none-eabi-size tests/unittests/bin/iotlab-m3/netif.a 
   text    data     bss     dec     hex filename
     96       0       4     100      64 netif.o (ex tests/unittests/bin/iotlab-m3/netif.a)

With NETIF_NAMED set:

  • netif struct 3 words + 4 byte long.
$ arm-none-eabi-size tests/unittests/bin/iotlab-m3/netif.a 
   text    data     bss     dec     hex filename
    244       0       4     248      f8 netif.o (ex tests/unittests/bin/iotlab-m3/netif.a)

@miri64
Copy link
Member Author

miri64 commented Aug 30, 2016

Without the option requirement we can even drop the internal pointer.

@kaspar030
Copy link
Contributor

240bytes brings it at eye-level with all shell commands, the saul registry or the mutex implementation.

Don't all network stacks have their own list of network devices, anyways? Be it an array or a linked list. IMHO wrapping another type over that is more than clumsy.

A common interface for enumerating interfaces might be nice, but why another type, a forced new set of 5 functions containing custom linked list operations, ...

@kaspar030
Copy link
Contributor

netif struct 3 words long (I guess if it were an array we could get it down to 2, one for the device, one for the stack internal structure).

netdev2 is 3 words long, and it also contains a pointer to the stack internal structure. Will they point to the same location?

@miri64 It is just that, we fight for every needed byte, try to avoid every struct member. All of netif_t is unnecessary, and in that light, the 96 or 244 bytes of additional code seems wasted.

@miri64
Copy link
Member Author

miri64 commented Aug 30, 2016

240bytes brings it at eye-level with all shell commands, the saul registry or the mutex implementation.

Where do you get this number from? For the ones pulled in by gnrc_networking alone I have

arm-none-eabi-size examples/gnrc_networking/bin/iotlab-m3/shell_commands.a 
   text    data     bss     dec     hex filename
    595       0       0     595     253 shell_commands.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
     10       0       0      10       a sc_sys.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
     10       0       0      10       a sc_ps.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
    169       0       0     169      a9 sc_random.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
   8995       0       0    8995    2323 sc_netif.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
   2233       0      40    2273     8e1 sc_fib.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
   1716       0       0    1716     6b4 sc_ipv6_nc.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
   2313       2      44    2359     937 sc_icmpv6_echo.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
   3339       0       0    3339     d0b sc_gnrc_rpl.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)
     32       0       0      32      20 sc_rtc.o (ex examples/gnrc_networking/bin/iotlab-m3/shell_commands.a)

Don't all network stacks have their own list of network devices, anyways? Be it an array or a linked list. IMHO wrapping another type over that is more than clumsy.

Yes, but the way they are addressed in each are vastly different: GNRC uses PIDs, lwIP uses names, emb6 doesn't even have interfaces (a slip interface optionally, but its not really addressable like the radio), and as far as I can see is OpenThread using its own interface identifier. For truely stack independent sock code or ifconfig I don't see a way around a common enumeration.

A common interface for enumerating interfaces might be nice, but why another type, a forced new set of 5 functions containing custom linked list operations, ...

3 functions, the other two are just for shell user shine (and can be removed if you really hate them) and they are just checking for duplicates (I could use clist though, granted)

netif struct 3 words long (I guess if it were an array we could get it down to 2, one for the device, one for the stack internal structure).

netdev2 is 3 words long, and it also contains a pointer to the stack internal structure. Will they point to the same location?

netdev2 has no pointer to the internal interface, but to the internal state of the device. For GNRC this would point to the PID in the gnrc_netif array. For others like e.g. OpenThread a pointer to the Netif class (if that is possible).

@miri64 It is just that, we fight for every needed byte, try to avoid every struct member. All of netif_t is unnecessary, and in that light, the 96 or 244 bytes of additional code seems wasted.

I don't see it as unnecessary (see common euumeration argument).

@kaspar030
Copy link
Contributor

Where do you get this number from? For the ones pulled in by gnrc_networking alone I have

Sorry, I just looked at shell_commands.o.

Yes, but the way they are addressed in each are vastly different: GNRC uses PIDs, lwIP uses names, emb6 doesn't even have interfaces (a slip interface optionally, but its not really addressable like the radio), and as far as I can see is OpenThread using its own interface identifier.

Exactly. So use those identifiers. Let gnrc enumerate PIDs, lwIP names (or pointers to the name strings), stackX pointers to it's interface structs. If a stack cannot enumerate it's interfaces easily, it is just a couple of lines to create a simple clist.

For truely stack independent sock code or ifconfig I don't see a way around a common enumeration.

There might be no way around a common enumeration API, but certainly a way around the same enumeration implementation.

@kaspar030 kaspar030 removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Aug 31, 2016
@miri64
Copy link
Member Author

miri64 commented Aug 31, 2016

So how would your wrapper look like then?

@kaspar030
Copy link
Contributor

So how would your wrapper look like then?

#define NETIF_INVALID   (0x0-1)
#define NETIF_MAXNAMELEN (8U)

typedef intptr_t netif_t;

/**
 * interface *after* last. use for enumeration, start with last==NETIF_INVALID,
 * returns next netif, or NETIF_INVALID if no more netifs
 */
netif_t netif_get_next(netif_t last);

/* write name (or id/ptr as decimal or hex) to dst.
 * dst must hold at least NETIF_MAXNAMELEN bytes.
 * return nr of bytes written or 0 on invalid netif */
int netif_get_name(netif_t netif, char *dst);

/* given textual name (or id/ptr as hex), convert to netif_t */
netif_t netif_get_by_name(const char *name);

@miri64
Copy link
Member Author

miri64 commented Sep 27, 2016

Why restrict the name length via macro?

@kaspar030
Copy link
Contributor

Why restrict the name length via macro?

In order to not have to deal with variable length names.

@miri64
Copy link
Member Author

miri64 commented Sep 27, 2016

But what if the stack has those?

@kaspar030
Copy link
Contributor

Well, linux limits interface names to 16 characters. If one of our stacks uses more, fix it.

@miri64
Copy link
Member Author

miri64 commented Jan 18, 2017

Will provide an alternative with @kaspar030's proposal.

@miri64 miri64 added the State: archived State: The PR has been archived for possible future re-adaptation label Jan 18, 2017
@miri64 miri64 closed this Jan 18, 2017
@miri64 miri64 deleted the netif/api/initial branch January 18, 2017 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: network Area: Networking Discussion: contested The item of discussion was contested Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR State: archived State: The PR has been archived for possible future re-adaptation Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants