[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