[PATCH v4 05/14] net-lwip: add DHCP support and dhcp commmand

Ilias Apalodimas ilias.apalodimas at linaro.org
Wed Jun 19 12:07:48 CEST 2024


[...]


> >> +
> >> +static struct netif *new_netif(bool with_ip)
> >> +{
> >> +    unsigned char enetaddr[ARP_HLEN];
> >> +    char hwstr[MAC_ADDR_STRLEN];
> >> +    ip4_addr_t ip, mask, gw;
> >> +    struct udevice *dev;
> >> +    struct netif *netif;
> >
> > This does not fit into the driver model.
> >
> > In the EFI subsystem we want to implement network protocols like the
> > EFI_DHCP4_PROTOCOL.
> >
> > Please, carve out functions to which we can pass a UCLASS_ETH udevice to
> > execute DHCP.
>
> v6 will have:
>
> static struct netif *new_netif(struct udevice *udev, bool with_ip)
> struct netif *net_lwip_new_netif(struct udevice *udev)
> struct netif *net_lwip_new_netif_noip(struct udevice *udev)

Heinrich, any other EFI protocols you have in mind that would require
similar tweaking? e.g the EFI_TCP4 and HTTP protocols?


>
> static int dhcp_loop(struct udevice *udev)
>
> >
> >> +    int ret;
> >> +    static bool first_call = true;
> >> +
> >> +    eth_init_rings();
> >> +
> >> +    if (first_call) {
> >> +        if (eth_init()) {
> >> +            printf("eth_init() error\n");
> >> +            return NULL;
> >> +        }
> >> +        first_call = false;
> >> +    }
> >> +
> >> +    netif_remove(net_lwip_get_netif());
> >> +
> >> +    eth_set_current();
> >> +
> >> +    dev = eth_get_dev();
> >> +    if (!dev)
> >> +        return NULL;
> >> +
> >> +    ip4_addr_set_zero(&ip);
> >> +    ip4_addr_set_zero(&mask);
> >> +    ip4_addr_set_zero(&gw);
> >> +
> >> +    if (with_ip)
> >> +        if (get_udev_ipv4_info(dev, &ip, &mask, &gw) < 0)
> >> +            return NULL;
> >> +
> >> +    eth_env_get_enetaddr_by_index("eth", dev_seq(dev), enetaddr);
> >> +    ret = snprintf(hwstr, MAC_ADDR_STRLEN, "%pM",  enetaddr);
> >> +    if (ret < 0 || ret >= MAC_ADDR_STRLEN)
> >> +        return NULL;
> >> +
> >> +    netif = calloc(1, sizeof(struct netif));
> >> +    if (!netif)
> >> +        return NULL;
> >> +
> >> +    netif->name[0] = 'e';
> >> +    netif->name[1] = 't';
> >> +
> >> +    string_to_enetaddr(hwstr, netif->hwaddr);
> >> +    netif->hwaddr_len = ETHARP_HWADDR_LEN;
> >> +
> >> +    if (!netif_add(netif, &ip, &mask, &gw, netif, net_lwip_if_init,
> >> +               netif_input)) {
> >> +        printf("error: netif_add() failed\n");
> >> +        free(netif);
> >> +        return NULL;
> >> +    }
> >> +
> >> +    netif_set_up(netif);
> >> +    netif_set_link_up(netif);
> >> +    /* Routing: use this interface to reach the default gateway */
> >> +    netif_set_default(netif);
> >> +
> >> +    return netif;
> >> +}
> >> +
> >> +/* Configure lwIP to use the currently active network device */
> >> +struct netif *net_lwip_new_netif()
> >> +{
> >> +    return new_netif(true);
> >> +}
> >> +
> >> +struct netif *net_lwip_new_netif_noip()
> >> +{
> >> +
> >> +    return new_netif(false);
> >> +}
> >> +
> >> +void net_lwip_remove_netif(struct netif *netif)
> >> +{
> >> +    netif_remove(netif);
> >> +    free(netif);
> >> +}
> >> +
> >> +int net_init(void)
> >> +{
> >> +    net_lwip_new_netif();
> >> +
> >> +    return 0;
> >> +}
> >> +
> >> +static struct pbuf *alloc_pbuf_and_copy(uchar *data, int len)
> >> +{
> >> +        struct pbuf *p, *q;
> >> +
> >> +        /* We allocate a pbuf chain of pbufs from the pool. */
> >> +        p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
> >> +        if (!p) {
> >> +                LINK_STATS_INC(link.memerr);
> >> +                LINK_STATS_INC(link.drop);
> >> +                return NULL;
> >> +        }
> >> +
> >> +        for (q = p; q != NULL; q = q->next) {
> >> +                memcpy(q->payload, data, q->len);
> >> +                data += q->len;
> >> +        }
> >> +
> >> +        LINK_STATS_INC(link.recv);
> >> +
> >> +        return p;
> >> +}
> >> +
> >> +void net_process_received_packet(uchar *in_packet, int len)
> >
> > Library functions should take a udevice as an argument. Please, do not
> > use the concept of "active device" in these library functions.
>
> OK, I have unified the naming in v6 and all functions will take a udevice:
>
> static int dhcp_loop(struct udevice *udev)
> static int dns_loop(struct udevice *udev, const char *name, const char *var)
> static int ping_loop(struct udevice *udev, const ip_addr_t* addr)
> static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
>                      ip_addr_t srvip)
> static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
>
> >
> > The command line interface may implement such a concept for backwards
> > compatibility.
>
> Sure.
>
> Thanks,
> --
> Jerome
>
> >
> > Best regards
> >
> > Heinrich
> >
> >> +{
> >> +    struct netif *netif;
> >> +    struct pbuf *pbuf;
> >> +
> >> +    if (len < ETHER_HDR_SIZE)
> >> +        return;
> >> +
> >> +#if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
> >> +    if (push_packet) {
> >> +        (*push_packet)(in_packet, len);
> >> +        return;
> >> +    }
> >> +#endif
> >> +
> >> +    netif = net_lwip_get_netif();
> >> +    if (!netif)
> >> +        return;
> >> +
> >> +    pbuf = alloc_pbuf_and_copy(in_packet, len);
> >> +    if (!pbuf)
> >> +        return;
> >> +
> >> +    netif->input(pbuf, netif);
> >> +}
> >> +
> >> +u32_t sys_now(void)
> >> +{
> >> +    return get_timer(0);
> >> +}
> >> diff --git a/net-lwip/tftp.c b/net-lwip/tftp.c
> >> new file mode 100644
> >> index 00000000000..1fa246f55d9
> >> --- /dev/null
> >> +++ b/net-lwip/tftp.c
> >> @@ -0,0 +1,11 @@
> >> +// SPDX-License-Identifier: GPL-2.0+
> >> +/* Copyright (C) 2024 Linaro Ltd. */
> >> +
> >> +#include <command.h>
> >> +#include <net-lwip.h>
> >> +
> >> +int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
> >> +{
> >> +    /* Not implemented */
> >> +    return CMD_RET_FAILURE;
> >> +}
> >


More information about the U-Boot mailing list