* sctp_bindx() support */
| 3158 | * sctp_bindx() support |
| 3159 | */ |
| 3160 | uint32_t |
| 3161 | sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa, |
| 3162 | uint32_t type, uint32_t vrf_id) |
| 3163 | { |
| 3164 | struct sctp_ifa *ifa; |
| 3165 | struct sctp_laddr *laddr, *nladdr; |
| 3166 | |
| 3167 | if (sa->sa_len == 0) { |
| 3168 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL); |
| 3169 | return (EINVAL); |
| 3170 | } |
| 3171 | if (type == SCTP_ADD_IP_ADDRESS) { |
| 3172 | /* For an add the address MUST be on the system */ |
| 3173 | ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED); |
| 3174 | } else if (type == SCTP_DEL_IP_ADDRESS) { |
| 3175 | /* For a delete we need to find it in the inp */ |
| 3176 | ifa = sctp_find_ifa_in_ep(inp, sa, SCTP_ADDR_NOT_LOCKED); |
| 3177 | } else { |
| 3178 | ifa = NULL; |
| 3179 | } |
| 3180 | if (ifa != NULL) { |
| 3181 | if (type == SCTP_ADD_IP_ADDRESS) { |
| 3182 | sctp_add_local_addr_ep(inp, ifa, type); |
| 3183 | } else if (type == SCTP_DEL_IP_ADDRESS) { |
| 3184 | if (inp->laddr_count < 2) { |
| 3185 | /* can't delete the last local address */ |
| 3186 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL); |
| 3187 | return (EINVAL); |
| 3188 | } |
| 3189 | LIST_FOREACH(laddr, &inp->sctp_addr_list, |
| 3190 | sctp_nxt_addr) { |
| 3191 | if (ifa == laddr->ifa) { |
| 3192 | /* Mark in the delete */ |
| 3193 | laddr->action = type; |
| 3194 | } |
| 3195 | } |
| 3196 | } |
| 3197 | if (LIST_EMPTY(&inp->sctp_asoc_list)) { |
| 3198 | /* |
| 3199 | * There is no need to start the iterator if the inp |
| 3200 | * has no associations. |
| 3201 | */ |
| 3202 | if (type == SCTP_DEL_IP_ADDRESS) { |
| 3203 | LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) { |
| 3204 | if (laddr->ifa == ifa) { |
| 3205 | sctp_del_local_addr_ep(inp, ifa); |
| 3206 | } |
| 3207 | } |
| 3208 | } |
| 3209 | } else { |
| 3210 | struct sctp_asconf_iterator *asc; |
| 3211 | struct sctp_laddr *wi; |
| 3212 | int ret; |
| 3213 | |
| 3214 | SCTP_MALLOC(asc, struct sctp_asconf_iterator *, |
| 3215 | sizeof(struct sctp_asconf_iterator), |
| 3216 | SCTP_M_ASC_IT); |
| 3217 | if (asc == NULL) { |
no test coverage detected