| 153 | |
| 154 | #ifdef INET |
| 155 | void |
| 156 | sctp_notify(struct sctp_inpcb *inp, |
| 157 | struct sctp_tcb *stcb, |
| 158 | struct sctp_nets *net, |
| 159 | uint8_t icmp_type, |
| 160 | uint8_t icmp_code, |
| 161 | uint16_t ip_len, |
| 162 | uint32_t next_mtu) |
| 163 | { |
| 164 | int timer_stopped; |
| 165 | |
| 166 | if (icmp_type != ICMP_UNREACH) { |
| 167 | /* We only care about unreachable */ |
| 168 | SCTP_TCB_UNLOCK(stcb); |
| 169 | return; |
| 170 | } |
| 171 | if ((icmp_code == ICMP_UNREACH_NET) || |
| 172 | (icmp_code == ICMP_UNREACH_HOST) || |
| 173 | (icmp_code == ICMP_UNREACH_NET_UNKNOWN) || |
| 174 | (icmp_code == ICMP_UNREACH_HOST_UNKNOWN) || |
| 175 | (icmp_code == ICMP_UNREACH_ISOLATED) || |
| 176 | (icmp_code == ICMP_UNREACH_NET_PROHIB) || |
| 177 | (icmp_code == ICMP_UNREACH_HOST_PROHIB) || |
| 178 | (icmp_code == ICMP_UNREACH_FILTER_PROHIB)) { |
| 179 | /* Mark the net unreachable. */ |
| 180 | if (net->dest_state & SCTP_ADDR_REACHABLE) { |
| 181 | /* OK, that destination is NOT reachable. */ |
| 182 | net->dest_state &= ~SCTP_ADDR_REACHABLE; |
| 183 | net->dest_state &= ~SCTP_ADDR_PF; |
| 184 | sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, |
| 185 | stcb, 0, |
| 186 | (void *)net, SCTP_SO_NOT_LOCKED); |
| 187 | } |
| 188 | SCTP_TCB_UNLOCK(stcb); |
| 189 | } else if ((icmp_code == ICMP_UNREACH_PROTOCOL) || |
| 190 | (icmp_code == ICMP_UNREACH_PORT)) { |
| 191 | /* Treat it like an ABORT. */ |
| 192 | sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED); |
| 193 | (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, |
| 194 | SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2); |
| 195 | /* no need to unlock here, since the TCB is gone */ |
| 196 | } else if (icmp_code == ICMP_UNREACH_NEEDFRAG) { |
| 197 | if (net->dest_state & SCTP_ADDR_NO_PMTUD) { |
| 198 | SCTP_TCB_UNLOCK(stcb); |
| 199 | return; |
| 200 | } |
| 201 | /* Find the next (smaller) MTU */ |
| 202 | if (next_mtu == 0) { |
| 203 | /* |
| 204 | * Old type router that does not tell us what the |
| 205 | * next MTU is. Rats we will have to guess (in a |
| 206 | * educated fashion of course). |
| 207 | */ |
| 208 | next_mtu = sctp_get_prev_mtu(ip_len); |
| 209 | } |
| 210 | /* Stop the PMTU timer. */ |
| 211 | if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { |
| 212 | timer_stopped = 1; |
no test coverage detected