net/eui_provider: prohibit use of NETDEV_ANY for EUI device type

The EUI provider function only gets the index of a device within it's
device type.
Using NETDEV_ANY with two devices of different type causes the EUI
provider to be used for both (since both interfaces are index 0 of
their type).

To prevent this, require EUI providers to be locked to an interface type.
This commit is contained in:
Benjamin Valentin 2021-06-08 12:02:08 +02:00
parent 204b80c6bf
commit 118e08607a
2 changed files with 24 additions and 10 deletions

View File

@ -75,10 +75,13 @@
* Recommendations * Recommendations
* =============== * ===============
* *
* While it is possible to match EUIs with any netdev in a first come, first serve * Do not use `NETDEV_ANY` as EUI device type. Otherwise if you have two
* fashion (`NETDEV_ANY`, `NETDEV_INDEX_ANY`) it is recommended to fix the EUI * interfaces both will match the same EUI.
* providers to a device and interface to avoid them being used for 'virtual' *
* interfaces. * It is however possible to use `NETDEV_INDEX_ANY` if you have multiple
* interfaces of the same type and your EUI provider function takes the index
* into account (or returns error if the index is out of bounds with the
* available ids).
* *
* Fixed addresses are only guaranteed if the network devices are also fixed. * Fixed addresses are only guaranteed if the network devices are also fixed.
* E.g. if you usually have two netdevs and disable the first one at compile-time * E.g. if you usually have two netdevs and disable the first one at compile-time
@ -132,7 +135,7 @@ typedef int (*netdev_get_eui64_cb_t)(uint8_t index, eui64_t *addr);
*/ */
typedef struct { typedef struct {
netdev_get_eui48_cb_t provider; /**< function to provide an EUI-48 */ netdev_get_eui48_cb_t provider; /**< function to provide an EUI-48 */
netdev_type_t type; /**< device type to match or `NETDEV_ANY` */ netdev_type_t type; /**< device type to match */
uint8_t index; /**< device index to match or `NETDEV_INDEX_ANY` */ uint8_t index; /**< device index to match or `NETDEV_INDEX_ANY` */
} eui48_conf_t; } eui48_conf_t;
@ -141,7 +144,7 @@ typedef struct {
*/ */
typedef struct { typedef struct {
netdev_get_eui64_cb_t provider; /**< function to provide an EUI-64 */ netdev_get_eui64_cb_t provider; /**< function to provide an EUI-64 */
netdev_type_t type; /**< device type to match or `NETDEV_ANY` */ netdev_type_t type; /**< device type to match */
uint8_t index; /**< device index to match or `NETDEV_INDEX_ANY` */ uint8_t index; /**< device index to match or `NETDEV_INDEX_ANY` */
} eui64_conf_t; } eui64_conf_t;

View File

@ -13,6 +13,7 @@
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com> * @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*/ */
#include "assert.h"
#include "eui48_provider_params.h" #include "eui48_provider_params.h"
#include "eui64_provider_params.h" #include "eui64_provider_params.h"
#include "luid.h" #include "luid.h"
@ -23,8 +24,13 @@ void netdev_eui48_get(netdev_t *netdev, eui48_t *addr)
unsigned i = EUI48_PROVIDER_NUMOF; unsigned i = EUI48_PROVIDER_NUMOF;
while (i--) { while (i--) {
#ifdef MODULE_NETDEV_REGISTER #ifdef MODULE_NETDEV_REGISTER
if (eui48_conf[i].type != netdev->type && /* using NETDEV_ANY causes conflicts if there is another interface
eui48_conf[i].type != NETDEV_ANY) { * of a different type. Require EUI providers to be locked to an
* interface type for uniqueness.
*/
assert(eui48_conf[i].type != NETDEV_ANY);
if (eui48_conf[i].type != netdev->type) {
continue; continue;
} }
@ -48,8 +54,13 @@ void netdev_eui64_get(netdev_t *netdev, eui64_t *addr)
unsigned i = EUI64_PROVIDER_NUMOF; unsigned i = EUI64_PROVIDER_NUMOF;
while (i--) { while (i--) {
#ifdef MODULE_NETDEV_REGISTER #ifdef MODULE_NETDEV_REGISTER
if (eui64_conf[i].type != netdev->type && /* using NETDEV_ANY causes conflicts if there is another interface
eui64_conf[i].type != NETDEV_ANY) { * of a different type. Require EUI providers to be locked to an
* interface type for uniqueness.
*/
assert(eui64_conf[i].type != NETDEV_ANY);
if (eui64_conf[i].type != netdev->type) {
continue; continue;
} }