* Allocate a new ifaddr and link it into chains. */
| 1060 | * Allocate a new ifaddr and link it into chains. |
| 1061 | */ |
| 1062 | static struct in6_ifaddr * |
| 1063 | in6_alloc_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, int flags) |
| 1064 | { |
| 1065 | struct in6_ifaddr *ia; |
| 1066 | |
| 1067 | /* |
| 1068 | * When in6_alloc_ifa() is called in a process of a received |
| 1069 | * RA, it is called under an interrupt context. So, we should |
| 1070 | * call malloc with M_NOWAIT. |
| 1071 | */ |
| 1072 | ia = (struct in6_ifaddr *)ifa_alloc(sizeof(*ia), M_NOWAIT); |
| 1073 | if (ia == NULL) |
| 1074 | return (NULL); |
| 1075 | LIST_INIT(&ia->ia6_memberships); |
| 1076 | /* Initialize the address and masks, and put time stamp */ |
| 1077 | ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; |
| 1078 | ia->ia_addr.sin6_family = AF_INET6; |
| 1079 | ia->ia_addr.sin6_len = sizeof(ia->ia_addr); |
| 1080 | /* XXX: Can we assign ,sin6_addr and skip the rest? */ |
| 1081 | ia->ia_addr = ifra->ifra_addr; |
| 1082 | ia->ia6_createtime = time_uptime; |
| 1083 | if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) { |
| 1084 | /* |
| 1085 | * Some functions expect that ifa_dstaddr is not |
| 1086 | * NULL for p2p interfaces. |
| 1087 | */ |
| 1088 | ia->ia_ifa.ifa_dstaddr = |
| 1089 | (struct sockaddr *)&ia->ia_dstaddr; |
| 1090 | } else { |
| 1091 | ia->ia_ifa.ifa_dstaddr = NULL; |
| 1092 | } |
| 1093 | |
| 1094 | /* set prefix mask if any */ |
| 1095 | ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask; |
| 1096 | if (ifra->ifra_prefixmask.sin6_len != 0) { |
| 1097 | ia->ia_prefixmask.sin6_family = AF_INET6; |
| 1098 | ia->ia_prefixmask.sin6_len = ifra->ifra_prefixmask.sin6_len; |
| 1099 | ia->ia_prefixmask.sin6_addr = ifra->ifra_prefixmask.sin6_addr; |
| 1100 | } |
| 1101 | |
| 1102 | ia->ia_ifp = ifp; |
| 1103 | ifa_ref(&ia->ia_ifa); /* if_addrhead */ |
| 1104 | IF_ADDR_WLOCK(ifp); |
| 1105 | CK_STAILQ_INSERT_TAIL(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); |
| 1106 | IF_ADDR_WUNLOCK(ifp); |
| 1107 | |
| 1108 | ifa_ref(&ia->ia_ifa); /* in6_ifaddrhead */ |
| 1109 | IN6_IFADDR_WLOCK(); |
| 1110 | CK_STAILQ_INSERT_TAIL(&V_in6_ifaddrhead, ia, ia_link); |
| 1111 | CK_LIST_INSERT_HEAD(IN6ADDR_HASH(&ia->ia_addr.sin6_addr), ia, ia6_hash); |
| 1112 | IN6_IFADDR_WUNLOCK(); |
| 1113 | |
| 1114 | return (ia); |
| 1115 | } |
| 1116 | |
| 1117 | /* |
| 1118 | * Update/configure interface address parameters: |
no test coverage detected