ipv6: Factor out global cache of mac/ip addresses.
Since there may be multiple connections which use different network devices,
there can't be a universal cache of the mac and ips derived from it.
Change-Id: Ibfae6804643ee491bfe0f23e9f38816af7a2f067
diff --git a/src/net/ipv6/inet6.c b/src/net/ipv6/inet6.c
index ca2f546..0fbee3c 100644
--- a/src/net/ipv6/inet6.c
+++ b/src/net/ipv6/inet6.c
@@ -19,7 +19,7 @@
// Convert MAC Address to IPv6 Link Local Address.
// aa:bb:cc:dd:ee:ff => FF80::aabb:ccFF:FEdd:eeff
// Bit 2 (U/L) of the mac is inverted.
-static void inet6_ll6addr_from_mac(Ipv6Address *_ip, const MacAddress *_mac)
+static void inet6_lladdr_from_mac(Ipv6Address *_ip, const MacAddress *_mac)
{
uint8_t *ip = _ip->x;
const uint8_t *mac = _mac->octet;
@@ -70,12 +70,6 @@
mac[5] = ip[15];
}
-// Ip6 stack configuration.
-static MacAddress inet6_ll_mac_addr;
-static Ipv6Address inet6_ll_ip_addr;
-static MacAddress inet6_snm_mac_addr;
-static Ipv6Address inet6_snm_ip_addr;
-
// Cache for the last source addresses we've seen.
static MacAddress inet6_rx_mac_addr;
static Ipv6Address inet6_rx_ip_addr;
@@ -134,28 +128,31 @@
return;
}
-void ipv6_init(const void *macaddr)
+void ipv6_init(NetDevice *dev)
{
- // Save our ethernet MAC and synthesize link layer addresses.
- memcpy(&inet6_ll_mac_addr, macaddr, sizeof(inet6_ll_mac_addr));
- inet6_ll6addr_from_mac(&inet6_ll_ip_addr, &inet6_ll_mac_addr);
- inet6_snmaddr_from_mac(&inet6_snm_ip_addr, &inet6_ll_mac_addr);
- inet6_multicast_from_ipv6(&inet6_snm_mac_addr, &inet6_snm_ip_addr);
+ const MacAddress *mac = dev->get_mac(dev);
- eth_add_mcast_filter(&inet6_snm_mac_addr);
+ // Save our ethernet MAC and synthesize link layer addresses.
+ Ipv6Address ip;
+ inet6_lladdr_from_mac(&ip, mac);
+ Ipv6Address snm_ip;
+ inet6_snmaddr_from_mac(&snm_ip, mac);
+ MacAddress snm_mac;
+ inet6_multicast_from_ipv6(&snm_mac, &snm_ip);
+
+ eth_add_mcast_filter(dev, &snm_mac);
MacAddress all;
inet6_multicast_from_ipv6(&all, &Ipv6LlAllNodes);
- eth_add_mcast_filter(&all);
+ eth_add_mcast_filter(dev, &all);
printf("macaddr: %02x:%02x:%02x:%02x:%02x:%02x\n",
- inet6_ll_mac_addr.octet[0], inet6_ll_mac_addr.octet[1],
- inet6_ll_mac_addr.octet[2], inet6_ll_mac_addr.octet[3],
- inet6_ll_mac_addr.octet[4], inet6_ll_mac_addr.octet[5]);
+ mac->octet[0], mac->octet[1], mac->octet[2], mac->octet[3],
+ mac->octet[4], mac->octet[5]);
printf("ipv6addr: ");
- ipv6_print_addr(&inet6_ll_ip_addr);
+ ipv6_print_addr(&ip);
printf("\nsnmaddr: ");
- ipv6_print_addr(&inet6_snm_ip_addr);
+ ipv6_print_addr(&snm_ip);
printf("\n");
}
@@ -238,7 +235,7 @@
return sum == 0xffff ? sum : ~sum;
}
-static int ipv6_setup(Ipv6Pkt *p, const Ipv6Address *daddr,
+static int ipv6_setup(Ipv6Pkt *p, NetDevice *dev, const Ipv6Address *daddr,
size_t length, uint8_t type)
{
MacAddress dmac;
@@ -247,8 +244,9 @@
return -1;
// Ethernet header.
+ const MacAddress *ll_mac = dev->get_mac(dev);
memcpy(p->eth + 2, &dmac, sizeof(dmac));
- memcpy(p->eth + 8, &inet6_ll_mac_addr, sizeof(inet6_ll_mac_addr));
+ memcpy(p->eth + 8, ll_mac, sizeof(*ll_mac));
p->eth[14] = (EthType_Ipv6 >> 8) & 0xFF;
p->eth[15] = EthType_Ipv6 & 0xFF;
@@ -257,8 +255,10 @@
p->ipv6.length = htonw(length);
p->ipv6.next_header = type;
p->ipv6.hop_limit = 255;
- memcpy(p->ipv6.src, &inet6_ll_ip_addr, sizeof(Ipv6Address));
- memcpy(p->ipv6.dst, daddr, sizeof(Ipv6Address));
+ Ipv6Address saddr;
+ inet6_lladdr_from_mac(&saddr, ll_mac);
+ memcpy(p->ipv6.src, &saddr, sizeof(saddr));
+ memcpy(p->ipv6.dst, daddr, sizeof(*daddr));
return 0;
}
@@ -290,7 +290,7 @@
UdpPkt *p = xmalloc(CONFIG_NET_LINK_MTU + 2);
size_t length = dlen + Udp_HdrLen;
- if (ipv6_setup((void *)p, &con->dest_ip, length, HdrUdp)) {
+ if (ipv6_setup((void *)p, con->dev, &con->dest_ip, length, HdrUdp)) {
printf("ipv6_setup failed.\n");
free(p);
return -1;
@@ -343,7 +343,7 @@
Ipv6Pkt *p = xmalloc(CONFIG_NET_LINK_MTU + 2);
- if (ipv6_setup((void *)p, dest_ip, length, HdrIcmpv6)) {
+ if (ipv6_setup((void *)p, dev, dest_ip, length, HdrIcmpv6)) {
free(p);
return -1;
}
@@ -428,18 +428,22 @@
printf("error: Bogus NDP Message\n");
if (ndp->code != 0)
printf("error: Bogus NDP Code\n");
- if (memcmp(ndp->target, &inet6_ll_ip_addr, Ipv6_AddrLen))
+
+ const MacAddress *mac = dev->get_mac(dev);
+
+ Ipv6Address ll_ip_addr;
+ inet6_lladdr_from_mac(&ll_ip_addr, mac);
+ if (memcmp(ndp->target, &ll_ip_addr, sizeof(ll_ip_addr)))
printf("error: NDP Not For Me\n");
msg.hdr.type = Icmpv6_NdpNAdvertise;
msg.hdr.code = 0;
msg.hdr.checksum = 0;
msg.hdr.flags = 0x60; // (S)olicited and (O)verride flags.
- memcpy(msg.hdr.target, &inet6_ll_ip_addr, Ipv6_AddrLen);
+ memcpy(msg.hdr.target, &ll_ip_addr, sizeof(ll_ip_addr));
msg.opt[0] = NdpNTgtLlAddr;
msg.opt[1] = 1;
- memcpy(msg.opt + 2, &inet6_ll_mac_addr,
- sizeof(inet6_ll_mac_addr));
+ memcpy(msg.opt + 2, mac, sizeof(MacAddress));
icmpv6_send(dev, (void *)ip->src, &msg, sizeof(msg));
return;
@@ -479,8 +483,14 @@
len = n;
// Require that we are the destination.
- if (memcmp(&inet6_ll_ip_addr, ip->dst, Ipv6_AddrLen) &&
- memcmp(&inet6_snm_ip_addr, ip->dst, Ipv6_AddrLen)) {
+ const MacAddress *mac = dev->get_mac(dev);
+ Ipv6Address ll_ip_addr;
+ inet6_lladdr_from_mac(&ll_ip_addr, mac);
+ Ipv6Address snm_ip_addr;
+ inet6_snmaddr_from_mac(&snm_ip_addr, mac);
+
+ if (memcmp(&ll_ip_addr, ip->dst, sizeof(ll_ip_addr)) &&
+ memcmp(&snm_ip_addr, ip->dst, sizeof(snm_ip_addr))) {
return 1;
}
diff --git a/src/net/ipv6/inet6.h b/src/net/ipv6/inet6.h
index d1f0579..2ee20bf 100644
--- a/src/net/ipv6/inet6.h
+++ b/src/net/ipv6/inet6.h
@@ -10,11 +10,11 @@
#include "net/ipv6/ipv6.h"
// provided by inet6.c
-void ipv6_init(const void *macaddr);
+void ipv6_init(NetDevice *dev);
int eth_recv(NetDevice *dev, void *data, size_t len);
// provided by interface driver
-int eth_add_mcast_filter(const MacAddress *addr);
+int eth_add_mcast_filter(NetDevice *dev, const MacAddress *addr);
// call to transmit a UDP packet
int udpv6_send(Ipv6UdpCon *con, const void *data, size_t len);
diff --git a/src/net/ipv6/ipv6.c b/src/net/ipv6/ipv6.c
index 8fa25ca..d3d7d4a 100644
--- a/src/net/ipv6/ipv6.c
+++ b/src/net/ipv6/ipv6.c
@@ -46,8 +46,7 @@
static int ipv6_udp_con_init(Ipv6UdpCon *con)
{
NetDevice *dev = con->dev;
- const MacAddress *mac = dev->get_mac(dev);
- ipv6_init(mac);
+ ipv6_init(dev);
list_insert_after(&con->list_node, &ipv6_udp_connections);
con->initialized = 1;
return 0;
@@ -143,7 +142,7 @@
return con;
}
-int eth_add_mcast_filter(const MacAddress *addr)
+int eth_add_mcast_filter(NetDevice *dev, const MacAddress *addr)
{
return 0;
}