diff options
Diffstat (limited to 'sys/netinet/sctp_output.c')
-rw-r--r-- | sys/netinet/sctp_output.c | 151 |
1 files changed, 69 insertions, 82 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 515ee13..3ef837c 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -3389,7 +3389,7 @@ sctp_source_address_selection(struct sctp_inpcb *inp, /* * Need a route to cache. */ - SCTP_RTALLOC(ro, vrf_id); + SCTP_RTALLOC(ro, vrf_id, inp->fibnum); } if (ro->ro_rt == NULL) { return (NULL); @@ -4170,7 +4170,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, sctp_free_ifa(_lsrc); } else { ip->ip_src = over_addr->sin.sin_addr; - SCTP_RTALLOC(ro, vrf_id); + SCTP_RTALLOC(ro, vrf_id, inp->fibnum); } } if (port) { @@ -4484,7 +4484,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, sctp_free_ifa(_lsrc); } else { lsa6->sin6_addr = over_addr->sin6.sin6_addr; - SCTP_RTALLOC(ro, vrf_id); + SCTP_RTALLOC(ro, vrf_id, inp->fibnum); } (void)sa6_recoverscope(sin6); } @@ -5511,7 +5511,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), "Address added"); sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, port); return; } @@ -5530,7 +5530,7 @@ do_a_abort: } sctp_send_abort(init_pkt, iphlen, src, dst, sh, init_chk->init.initiate_tag, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, port); return; } @@ -7985,6 +7985,7 @@ again_one_more_time: } else { r_mtu = mtu; } + error = 0; /************************/ /* ASCONF transmission */ /************************/ @@ -8108,6 +8109,12 @@ again_one_more_time: * it is used to do appropriate * source address selection. */ + if (*now_filled == 0) { + (void)SCTP_GETTIME_TIMEVAL(now); + *now_filled = 1; + } + net->last_sent_time = *now; + hbflag = 0; if ((error = sctp_lowlevel_chunk_output(inp, stcb, net, (struct sockaddr *)&net->ro._l_addr, outchain, auth_offset, auth, @@ -8118,21 +8125,18 @@ again_one_more_time: net->port, NULL, 0, 0, so_locked))) { - if (error == ENOBUFS) { - asoc->ifp_had_enobuf = 1; - SCTP_STAT_INCR(sctps_lowlevelerr); - } + /* + * error, we could not + * output + */ + SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error); if (from_where == 0) { SCTP_STAT_INCR(sctps_lowlevelerrusr); } - if (*now_filled == 0) { - (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); - *now_filled = 1; - *now = net->last_sent_time; - } else { - net->last_sent_time = *now; + if (error == ENOBUFS) { + asoc->ifp_had_enobuf = 1; + SCTP_STAT_INCR(sctps_lowlevelerr); } - hbflag = 0; /* error, could not output */ if (error == EHOSTUNREACH) { /* @@ -8143,17 +8147,10 @@ again_one_more_time: sctp_move_chunks_from_net(stcb, net); } *reason_code = 7; - continue; - } else - asoc->ifp_had_enobuf = 0; - if (*now_filled == 0) { - (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); - *now_filled = 1; - *now = net->last_sent_time; + break; } else { - net->last_sent_time = *now; + asoc->ifp_had_enobuf = 0; } - hbflag = 0; /* * increase the number we sent, if a * cookie is sent we don't tell them @@ -8186,6 +8183,10 @@ again_one_more_time: } } } + if (error != 0) { + /* try next net */ + continue; + } /************************/ /* Control transmission */ /************************/ @@ -8382,6 +8383,15 @@ again_one_more_time: sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net); cookie = 0; } + /* Only HB or ASCONF advances time */ + if (hbflag) { + if (*now_filled == 0) { + (void)SCTP_GETTIME_TIMEVAL(now); + *now_filled = 1; + } + net->last_sent_time = *now; + hbflag = 0; + } if ((error = sctp_lowlevel_chunk_output(inp, stcb, net, (struct sockaddr *)&net->ro._l_addr, outchain, @@ -8393,23 +8403,17 @@ again_one_more_time: net->port, NULL, 0, 0, so_locked))) { - if (error == ENOBUFS) { - asoc->ifp_had_enobuf = 1; - SCTP_STAT_INCR(sctps_lowlevelerr); - } + /* + * error, we could not + * output + */ + SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error); if (from_where == 0) { SCTP_STAT_INCR(sctps_lowlevelerrusr); } - /* error, could not output */ - if (hbflag) { - if (*now_filled == 0) { - (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); - *now_filled = 1; - *now = net->last_sent_time; - } else { - net->last_sent_time = *now; - } - hbflag = 0; + if (error == ENOBUFS) { + asoc->ifp_had_enobuf = 1; + SCTP_STAT_INCR(sctps_lowlevelerr); } if (error == EHOSTUNREACH) { /* @@ -8420,19 +8424,9 @@ again_one_more_time: sctp_move_chunks_from_net(stcb, net); } *reason_code = 7; - continue; - } else + break; + } else { asoc->ifp_had_enobuf = 0; - /* Only HB or ASCONF advances time */ - if (hbflag) { - if (*now_filled == 0) { - (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); - *now_filled = 1; - *now = net->last_sent_time; - } else { - net->last_sent_time = *now; - } - hbflag = 0; } /* * increase the number we sent, if a @@ -8466,6 +8460,10 @@ again_one_more_time: } } } + if (error != 0) { + /* try next net */ + continue; + } /* JRI: if dest is in PF state, do not send data to it */ if ((asoc->sctp_cmt_on_off > 0) && (net != stcb->asoc.alternate) && @@ -8720,6 +8718,14 @@ no_data_fill: */ sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net); } + if (bundle_at || hbflag) { + /* For data/asconf and hb set time */ + if (*now_filled == 0) { + (void)SCTP_GETTIME_TIMEVAL(now); + *now_filled = 1; + } + net->last_sent_time = *now; + } /* Now send it, if there is anything to send :> */ if ((error = sctp_lowlevel_chunk_output(inp, stcb, @@ -8738,23 +8744,13 @@ no_data_fill: 0, 0, so_locked))) { /* error, we could not output */ - if (error == ENOBUFS) { - SCTP_STAT_INCR(sctps_lowlevelerr); - asoc->ifp_had_enobuf = 1; - } + SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error); if (from_where == 0) { SCTP_STAT_INCR(sctps_lowlevelerrusr); } - SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error); - if (hbflag) { - if (*now_filled == 0) { - (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); - *now_filled = 1; - *now = net->last_sent_time; - } else { - net->last_sent_time = *now; - } - hbflag = 0; + if (error == ENOBUFS) { + SCTP_STAT_INCR(sctps_lowlevelerr); + asoc->ifp_had_enobuf = 1; } if (error == EHOSTUNREACH) { /* @@ -8779,16 +8775,6 @@ no_data_fill: endoutchain = NULL; auth = NULL; auth_offset = 0; - if (bundle_at || hbflag) { - /* For data/asconf and hb set time */ - if (*now_filled == 0) { - (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); - *now_filled = 1; - *now = net->last_sent_time; - } else { - net->last_sent_time = *now; - } - } if (!no_out_cnt) { *num_out += (ctl_cnt + bundle_at); } @@ -10853,7 +10839,7 @@ static void sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vtag, uint8_t type, struct mbuf *cause, - uint8_t mflowtype, uint32_t mflowid, + uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port) { struct mbuf *o_pak; @@ -10933,6 +10919,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, SCTP_BUF_RESV_UF(mout, max_linkhdr); SCTP_BUF_LEN(mout) = len; SCTP_BUF_NEXT(mout) = cause; + M_SETFIB(mout, fibnum); mout->m_pkthdr.flowid = mflowid; M_HASHTYPE_SET(mout, mflowtype); #ifdef INET @@ -11120,11 +11107,11 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, void sctp_send_shutdown_complete2(struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, - uint8_t mflowtype, uint32_t mflowid, + uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port) { sctp_send_resp_msg(src, dst, sh, 0, SCTP_SHUTDOWN_COMPLETE, NULL, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); } @@ -11943,7 +11930,7 @@ skip_stuff: void sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vtag, struct mbuf *cause, - uint8_t mflowtype, uint32_t mflowid, + uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port) { /* Don't respond to an ABORT with an ABORT. */ @@ -11953,7 +11940,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockadd return; } sctp_send_resp_msg(src, dst, sh, vtag, SCTP_ABORT_ASSOCIATION, cause, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); return; } @@ -11961,11 +11948,11 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockadd void sctp_send_operr_to(struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vtag, struct mbuf *cause, - uint8_t mflowtype, uint32_t mflowid, + uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port) { sctp_send_resp_msg(src, dst, sh, vtag, SCTP_OPERATION_ERROR, cause, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); return; } |