[SLOF] [PATCH] ipv6: Add support for sending packets through a router

Nikunj A Dadhania nikunj at linux.vnet.ibm.com
Mon Apr 11 14:51:17 AEST 2016


Thomas Huth <thuth at redhat.com> writes:

> The network boot over IPv6 currently fails if the TFTP server
> is not in the same subnet as the SLOF client. In that case we
> have to fill in the MAC address of a router into our packets
> to get them to the right place.
>
> Signed-off-by: Thomas Huth <thuth at redhat.com>

Looks good, one small nit below.

Reviewed-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>

> ---
>  clients/net-snk/app/netlib/ipv6.c | 23 +++++++++++++++++++++++
>  clients/net-snk/app/netlib/ndp.c  | 17 +++++++++++++++++
>  clients/net-snk/app/netlib/ndp.h  |  1 +
>  3 files changed, 41 insertions(+)
>
> diff --git a/clients/net-snk/app/netlib/ipv6.c b/clients/net-snk/app/netlib/ipv6.c
> index 62d29ea..348e79d 100644
> --- a/clients/net-snk/app/netlib/ipv6.c
> +++ b/clients/net-snk/app/netlib/ipv6.c
> @@ -13,6 +13,7 @@
>  #include <string.h>
>  #include <stdlib.h>
>  #include <stdio.h>
> +#include <stdbool.h>
>  #include <time.h>
>  #include <ctype.h>
>  #include <sys/socket.h>
> @@ -417,6 +418,21 @@ static uint8_t *ip6_to_multicast_mac(ip6_addr_t * ip, uint8_t *mc_mac)
>  }
>
>  /**
> + * Check whether an IPv6 address is on the same network as we are
> + */
> +static bool is_ip6addr_in_my_net(ip6_addr_t *ip)
> +{
> +	struct ip6addr_list_entry *n = NULL;
> +
> +	for (n = first_ip6; n != NULL; n = n->next) {
> +		if (n->addr.part.prefix == ip->part.prefix)
> +			return true;  /* IPv6 address is in our neighborhood */
> +	}
> +
> +	return false;    /* not in our neighborhood */
> +}
> +
> +/**
>   * NET: calculate checksum over IPv6 header and upper-layer protocol
>   *      (e.g. UDP or ICMPv6)
>   *
> @@ -517,6 +533,10 @@ int send_ipv6(int fd, void* buffer, int len)
>  		if (n) {
>  			if (memcmp(n->mac, null_mac, ETH_ALEN) != 0)
>  				memcpy (mac_addr, &(n->mac), ETH_ALEN); /* found it */
> +		} else if (!is_ip6addr_in_my_net(&ip_dst)) {
> +			struct router *gw;
> +			gw = ipv6_get_default_router(&ip6h->src);
> +			mac_addr = gw ? gw->mac : null_mac;
>  		} else {
>  			mac_addr = null_mac;
>  			n = malloc(sizeof(struct neighbor));
> @@ -547,6 +567,9 @@ int send_ipv6(int fd, void* buffer, int len)
>  		}
>  	}
>
> +	if (mac_addr == null_mac)
> +		return -1;
> +
>  	fill_ethhdr (n->eth_frame, htons(ETHERTYPE_IPv6), get_mac_address(),
>  		     mac_addr);
>  	memcpy (&(n->eth_frame[sizeof(struct ethhdr)]), buffer, len);
> diff --git a/clients/net-snk/app/netlib/ndp.c b/clients/net-snk/app/netlib/ndp.c
> index 96faa87..7a8dfda 100644
> --- a/clients/net-snk/app/netlib/ndp.c
> +++ b/clients/net-snk/app/netlib/ndp.c
> @@ -84,6 +84,23 @@ find_router( ip6_addr_t *ip )
>  	return NULL; /* router is unknown */
>  }
>
> +/**
> + * Find a router for a given host address
> + * @param  ip - IPv6 address with the prefered prefix
> + * @return pointer to router, or NULL if none is available
> + */
> +struct router *ipv6_get_default_router(ip6_addr_t *ip)

Did you think of returning mac-address directly?

ipv6_get_default_router_mac() ?

> +{
> +	struct router *n = NULL;
> +
> +	for (n = first_router; n != NULL; n = n->next) {
> +		if (n->ip.part.prefix == ip->part.prefix)
> +			return n;
> +	}
> +
> +	return first_router;
> +}
> +
>  /*
>   * NET: add new neighbor to list
>   * @param  struct neighbor nghb  - new neighbor
> diff --git a/clients/net-snk/app/netlib/ndp.h b/clients/net-snk/app/netlib/ndp.h
> index c785c48..74fbd8b 100644
> --- a/clients/net-snk/app/netlib/ndp.h
> +++ b/clients/net-snk/app/netlib/ndp.h
> @@ -67,5 +67,6 @@ struct neighbor * find_neighbor (ip6_addr_t *);
>  int8_t router_add(struct router*);
>  void * router_create(uint8_t *mac, ip6_addr_t *ip);
>  struct router * find_router(ip6_addr_t *);
> +struct router *ipv6_get_default_router(ip6_addr_t *ip);
>
>  #endif //_NDP_H_
> -- 
> 1.8.3.1



More information about the SLOF mailing list