| 284 | } |
| 285 | |
| 286 | void |
| 287 | sctp_addr_change(struct ifaddr *ifa, int cmd) |
| 288 | { |
| 289 | uint32_t ifa_flags = 0; |
| 290 | |
| 291 | if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { |
| 292 | return; |
| 293 | } |
| 294 | /* |
| 295 | * BSD only has one VRF, if this changes we will need to hook in the |
| 296 | * right things here to get the id to pass to the address management |
| 297 | * routine. |
| 298 | */ |
| 299 | if (SCTP_BASE_VAR(first_time) == 0) { |
| 300 | /* Special test to see if my ::1 will showup with this */ |
| 301 | SCTP_BASE_VAR(first_time) = 1; |
| 302 | sctp_init_ifns_for_vrf(SCTP_DEFAULT_VRFID); |
| 303 | } |
| 304 | |
| 305 | if ((cmd != RTM_ADD) && (cmd != RTM_DELETE)) { |
| 306 | /* don't know what to do with this */ |
| 307 | return; |
| 308 | } |
| 309 | |
| 310 | if (ifa->ifa_addr == NULL) { |
| 311 | return; |
| 312 | } |
| 313 | if (sctp_is_desired_interface_type(ifa->ifa_ifp) == 0) { |
| 314 | /* non desired type */ |
| 315 | return; |
| 316 | } |
| 317 | switch (ifa->ifa_addr->sa_family) { |
| 318 | #ifdef INET |
| 319 | case AF_INET: |
| 320 | if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) { |
| 321 | return; |
| 322 | } |
| 323 | break; |
| 324 | #endif |
| 325 | #ifdef INET6 |
| 326 | case AF_INET6: |
| 327 | ifa_flags = ((struct in6_ifaddr *)ifa)->ia6_flags; |
| 328 | if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) { |
| 329 | /* skip unspecifed addresses */ |
| 330 | return; |
| 331 | } |
| 332 | break; |
| 333 | #endif |
| 334 | default: |
| 335 | /* non inet/inet6 skip */ |
| 336 | return; |
| 337 | } |
| 338 | if (cmd == RTM_ADD) { |
| 339 | (void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, (void *)ifa->ifa_ifp, |
| 340 | ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname, |
| 341 | (void *)ifa, ifa->ifa_addr, ifa_flags, 1); |
| 342 | } else { |
| 343 | sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, |
no test coverage detected