lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] multiple IP addresses on network interface


From: Artem Pisarenko
Subject: Re: [lwip-users] multiple IP addresses on network interface
Date: Mon, 10 Dec 2012 09:44:20 +0700
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20121026 Thunderbird/16.0.2

09.12.2012 17:00, Simon Goldschmidt wrote:
I'm aware though that supporting multiple addresses on one netif would be the 
cleaner solution. Since we already will be needing this feature for IPv6, we 
could implement it for v4, too, one day...

Simon
Thank you. I'll look forward to get updates.
During last days I've prepared workaround which should work for most cases. It assumes that application will not delete or reconfigure assigned interfaces during runtime (also DHCP isn't allowed, although it's allowed on 32bit systems where netif->ip_addr change is atomic operation).

#define ETH_MAX_NETIFS_COUNT    10
/* ... */
static struct netif *assigned_netifs[ETH_MAX_NETIFS_COUNT];
static int assigned_netifs_count;
/* ... */
err_t ethernetif_init(struct netif *netif) {
    if (assigned_netifs_count >= ETH_MAX_NETIFS_COUNT) return ERR_MEM;
    // ...
    assigned_netifs[assigned_netifs_count] = netif;
    assigned_netifs_count++;
    // ...
}
/* ... */
static void smart_pass_incoming_packet_to_lwip(struct pbuf *input_pbuf) {
    if (input_pbuf->len > SIZEOF_ETH_HDR) {
        switch (((struct eth_hdr *)input_pbuf->payload)->type) {
        case PP_HTONS(ETHTYPE_IP): {
            /* smart search of matching netif */
            struct ip_hdr *iphdr;
            u16_t iphdr_hlen;
            ipX_addr_t iphdr_dest;
            SYS_ARCH_DECL_PROTECT(old_level);
            struct netif *xnetif;
            char netif_found;

if (input_pbuf->len < (SIZEOF_ETH_HDR + IP_HLEN)) goto ip_netif_search_end; iphdr = (struct ip_hdr *)((char *)input_pbuf->payload + SIZEOF_ETH_HDR);
            if (IPH_V(iphdr) != 4) goto ip_netif_search_end;
            iphdr_hlen = IPH_HL(iphdr)*4;
if (iphdr_hlen > (input_pbuf->len - SIZEOF_ETH_HDR)) goto ip_netif_search_end;

            ip_addr_copy(*ipX_2_ip(&iphdr_dest), iphdr->dest);

            netif_found = 0;
            SYS_ARCH_PROTECT(old_level);
            for (int i = 0; i < assigned_netifs_count; i++) {
                xnetif = assigned_netifs[i];
#if LWIP_IGMP
                if (ip_addr_ismulticast(&iphdr_dest)) {
                    if (igmp_lookfor_group(xnetif, &iphdr_dest)) {
                        netif_found = 1;
                    }
                } else
#endif /* LWIP_IGMP */
                {
                    /* interface is configured? */
                    if (!ip_addr_isany(&(xnetif->ip_addr))) {
                        /* unicast to this interface address? */
                        if (ip_addr_cmp(&iphdr_dest, &(xnetif->ip_addr)) ||
/* or broadcast on this interface network address? */
                                ip_addr_isbroadcast(&iphdr_dest, xnetif)) {
                            netif_found = 1;
                        }
#if LWIP_AUTOIP
/* connections to link-local addresses must persist after changing
                           the netif's address (RFC3927 ch. 1.9) */
                        if ((xnetif->autoip != NULL) &&
ip_addr_cmp(&iphdr_dest, &(xnetif->autoip->llipaddr))) {
                            netif_found = 1;
                        }
#endif /* LWIP_AUTOIP */
                    } else {
// only one of assined interfaces may not be configured (dhcp ?)
                        netif_found = 1;
                    }
                }
                if (netif_found) break;
            }
            SYS_ARCH_UNPROTECT(old_level);

            if (netif_found) {
                if (xnetif->input(input_pbuf, xnetif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, (DEBUG_HDR"IP packet input error\n"));
                    pbuf_free(input_pbuf);
                }
            }
            break;

ip_netif_search_end:
            pbuf_free(input_pbuf);
            break;
        }
        case PP_HTONS(ETHTYPE_ARP):{
            /* to all assigned netifs */
            for (int i = 0; i < assigned_netifs_count; i++) {
                pbuf_ref(input_pbuf);
if (assigned_netifs[i]->input(input_pbuf, assigned_netifs[i]) != ERR_OK) { LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, (DEBUG_HDR"ARP packet input error on assigned netif #%u\n", i));
                    pbuf_free(input_pbuf);
                    break;
                }
            }
            pbuf_free(input_pbuf);
            break;
        }
        default:
            pbuf_free(input_pbuf);
            break;
        }
    } else {
        pbuf_free(input_pbuf);
    }
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]