+ if (ap->ip4_address_set)
+ {
+ struct sockaddr_in sin;
+ /* ip4: mask defaults to /24 */
+ u32 mask = clib_host_to_net_u32 (0xFFFFFF00);
+
+ clib_memset (&sin, 0, sizeof (sin));
+ sin.sin_family = AF_INET;
+ /* sin.sin_port = 0; */
+ sin.sin_addr.s_addr = ap->ip4_address->as_u32;
+ memcpy (&ifr.ifr_ifru.ifru_addr, &sin, sizeof (sin));
+
+ if (ioctl (dev_tap_fd, SIOCSIFADDR, &ifr) < 0)
+ {
+ rv = VNET_API_ERROR_SYSCALL_ERROR_10;
+ goto error;
+ }
+
+ if (ap->ip4_mask_width > 0 && ap->ip4_mask_width < 33)
+ {
+ mask = ~0;
+ mask <<= (32 - ap->ip4_mask_width);
+ }
+
+ mask = clib_host_to_net_u32 (mask);
+ sin.sin_family = AF_INET;
+ sin.sin_port = 0;
+ sin.sin_addr.s_addr = mask;
+ memcpy (&ifr.ifr_ifru.ifru_addr, &sin, sizeof (sin));
+
+ if (ioctl (dev_tap_fd, SIOCSIFNETMASK, &ifr) < 0)
+ {
+ rv = VNET_API_ERROR_SYSCALL_ERROR_10;
+ goto error;
+ }
+ }
+
+ if (ap->ip6_address_set)
+ {
+ struct ifreq ifr2;
+ ip6_ifreq_t ifr6;
+ int sockfd6;
+
+ sockfd6 = socket (AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+ if (sockfd6 < 0)
+ {
+ rv = VNET_API_ERROR_SYSCALL_ERROR_10;
+ goto error;
+ }
+
+ clib_memset (&ifr2, 0, sizeof (ifr));
+ strncpy (ifr2.ifr_name, (char *) ap->intfc_name,
+ sizeof (ifr2.ifr_name) - 1);
+ if (ioctl (sockfd6, SIOCGIFINDEX, &ifr2) < 0)
+ {
+ close (sockfd6);
+ rv = VNET_API_ERROR_SYSCALL_ERROR_4;
+ goto error;
+ }
+
+ memcpy (&ifr6.addr, ap->ip6_address, sizeof (ip6_address_t));
+ ifr6.mask_width = ap->ip6_mask_width;
+ ifr6.ifindex = ifr2.ifr_ifindex;
+
+ if (ioctl (sockfd6, SIOCSIFADDR, &ifr6) < 0)
+ {
+ close (sockfd6);
+ clib_unix_warning ("ifr6");
+ rv = VNET_API_ERROR_SYSCALL_ERROR_10;
+ goto error;
+ }
+ close (sockfd6);
+ }
+
+ ti = tapcli_get_new_tapif ();