+static void
+random_ifaceid(struct in6_addr *addr)
+{
+ static bool initialized = false;
+ struct timeval t;
+
+ if (!initialized) {
+ long int seed = 0;
+ gettimeofday(&t, NULL);
+ seed = t.tv_sec ^ t.tv_usec ^ getpid();
+ srand48(seed);
+ initialized = true;
+ }
+ addr->s6_addr32[2] = (uint32_t)mrand48();
+ addr->s6_addr32[3] = (uint32_t)mrand48();
+}
+
+static void
+eui64_ifaceid(struct interface *iface, struct in6_addr *addr)
+{
+ /* get mac address */
+ uint8_t *macaddr = iface->l3_dev.dev->settings.macaddr;
+ uint8_t *ifaceid = addr->s6_addr + 8;
+ memcpy(ifaceid,macaddr,3);
+ memcpy(ifaceid + 5,macaddr + 3, 3);
+ ifaceid[3] = 0xff;
+ ifaceid[4] = 0xfe;
+ ifaceid[0] ^= 0x02;
+}
+
+static void
+generate_ifaceid(struct interface *iface, struct in6_addr *addr)
+{
+ /* generate new iface id */
+ switch (iface->assignment_iface_id_selection) {
+ case IFID_FIXED:
+ /* fixed */
+ /* copy host part from assignment_fixed_iface_id */
+ memcpy(addr->s6_addr + 8, iface->assignment_fixed_iface_id.s6_addr + 8, 8);
+ break;
+ case IFID_RANDOM:
+ /* randomize last 64 bits */
+ random_ifaceid(addr);
+ break;
+ case IFID_EUI64:
+ /* eui64 */
+ eui64_ifaceid(iface, addr);
+ break;
+ }
+}