diff options
-rw-r--r-- | sys/netinet/sctp_asconf.c | 3 | ||||
-rw-r--r-- | sys/netinet/sctp_input.c | 33 | ||||
-rw-r--r-- | sys/netinet/sctp_input.h | 2 | ||||
-rw-r--r-- | sys/netinet/sctp_os_bsd.h | 9 | ||||
-rw-r--r-- | sys/netinet/sctp_output.c | 25 | ||||
-rw-r--r-- | sys/netinet/sctp_output.h | 6 | ||||
-rw-r--r-- | sys/netinet/sctp_pcb.c | 5 | ||||
-rw-r--r-- | sys/netinet/sctp_pcb.h | 1 | ||||
-rw-r--r-- | sys/netinet/sctp_usrreq.c | 13 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 8 | ||||
-rw-r--r-- | sys/netinet/sctputil.h | 2 | ||||
-rw-r--r-- | sys/netinet6/sctp6_usrreq.c | 4 |
12 files changed, 65 insertions, 46 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index 9015d80..a64e7f9 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -1109,7 +1109,8 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa) * not be changed. */ SCTP_RTALLOC((sctp_route_t *) & net->ro, - stcb->sctp_ep->def_vrf_id); + stcb->sctp_ep->def_vrf_id, + stcb->sctp_ep->fibnum); if (net->ro.ro_rt == NULL) continue; diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index c808bcb..1fcca92 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -186,7 +186,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), "No listener"); sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, port); } goto outnow; @@ -1484,7 +1484,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination); op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, ""); sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, net->port); if (how_indx < sizeof(asoc->cookie_how)) asoc->cookie_how[how_indx] = 2; @@ -1694,7 +1694,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, */ op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, ""); sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, port); return (NULL); } @@ -2572,7 +2572,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, tim = now.tv_usec - cookie->time_entered.tv_usec; scm->time_usec = htonl(tim); sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err, - mflowtype, mflowid, + mflowtype, mflowid, l_inp->fibnum, vrf_id, port); return (NULL); } @@ -2794,6 +2794,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, inp->partial_delivery_point = (*inp_p)->partial_delivery_point; inp->sctp_context = (*inp_p)->sctp_context; inp->local_strreset_support = (*inp_p)->local_strreset_support; + inp->fibnum = (*inp_p)->fibnum; inp->inp_starting_point_for_iterator = NULL; /* * copy in the authentication parameters from the @@ -4404,7 +4405,7 @@ __attribute__((noinline)) struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_chunkhdr *ch, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets **netp, int *fwd_tsn_seen, - uint8_t mflowtype, uint32_t mflowid, + uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port) { struct sctp_association *asoc; @@ -4568,7 +4569,7 @@ __attribute__((noinline)) msg); /* no association, so it's out of the blue... */ sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, port); *offset = length; if (locked_tcb) { @@ -4612,7 +4613,7 @@ __attribute__((noinline)) msg); sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); return (NULL); } @@ -5622,7 +5623,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt uint8_t compute_crc, #endif uint8_t ecn_bits, - uint8_t mflowtype, uint32_t mflowid, + uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port) { uint32_t high_tsn; @@ -5701,7 +5702,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt } if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { sctp_send_shutdown_complete2(src, dst, sh, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); goto out; } @@ -5716,7 +5717,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt "Out of the blue"); sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); } } @@ -5777,7 +5778,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, port); goto out; } @@ -5788,7 +5789,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt stcb = sctp_process_control(m, iphlen, &offset, length, src, dst, sh, ch, inp, stcb, &net, &fwd_tsn_seen, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); if (stcb) { /* @@ -5829,7 +5830,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); goto out; } @@ -5901,7 +5902,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, port); goto out; /* sa_ignore NOTREACHED */ @@ -6038,6 +6039,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) #endif uint32_t mflowid; uint8_t mflowtype; + uint16_t fibnum; iphlen = off; if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) { @@ -6063,6 +6065,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) (int)m->m_pkthdr.csum_flags, CSUM_BITS); mflowid = m->m_pkthdr.flowid; mflowtype = M_HASHTYPE_GET(m); + fibnum = M_GETFIB(m); SCTP_STAT_INCR(sctps_recvpackets); SCTP_STAT_INCR_COUNTER64(sctps_inpackets); /* Get IP, SCTP, and first chunk header together in the first mbuf. */ @@ -6122,7 +6125,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) compute_crc, #endif ecn_bits, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); out: if (m) { diff --git a/sys/netinet/sctp_input.h b/sys/netinet/sctp_input.h index 0c3f8a5..148864b 100644 --- a/sys/netinet/sctp_input.h +++ b/sys/netinet/sctp_input.h @@ -45,7 +45,7 @@ sctp_common_input_processing(struct mbuf **, int, int, int, uint8_t, #endif uint8_t, - uint8_t, uint32_t, + uint8_t, uint32_t, uint16_t, uint32_t, uint16_t); struct sctp_stream_reset_request * diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index e926808..7ae332a 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -412,13 +412,8 @@ typedef struct callout sctp_os_timer_t; typedef struct route sctp_route_t; typedef struct rtentry sctp_rtentry_t; -/* - * XXX multi-FIB support was backed out in r179783 and it seems clear that the - * VRF support as currently in FreeBSD is not ready to support multi-FIB. - * It might be best to implement multi-FIB support for both v4 and v6 indepedent - * of VRFs and leave those to a real MPLS stack. - */ -#define SCTP_RTALLOC(ro, vrf_id) rtalloc_ign((struct route *)ro, 0UL) +#define SCTP_RTALLOC(ro, vrf_id, fibnum) \ + rtalloc_ign_fib((struct route *)ro, 0UL, fibnum) /* Future zero copy wakeup/send function */ #define SCTP_ZERO_COPY_EVENT(inp, so) diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 7f0307b..0cdeb94 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; } @@ -10855,7 +10855,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; @@ -10935,6 +10935,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 @@ -11122,11 +11123,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); } @@ -11945,7 +11946,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. */ @@ -11955,7 +11956,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; } @@ -11963,11 +11964,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; } diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h index 8789df9..8e45e5c 100644 --- a/sys/netinet/sctp_output.h +++ b/sys/netinet/sctp_output.h @@ -117,7 +117,7 @@ void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *, int); void sctp_send_shutdown_complete2(struct sockaddr *, struct sockaddr *, struct sctphdr *, - uint8_t, uint32_t, + uint8_t, uint32_t, uint16_t, uint32_t, uint16_t); void sctp_send_asconf(struct sctp_tcb *, struct sctp_nets *, int addr_locked); @@ -187,13 +187,13 @@ sctp_send_str_reset_req(struct sctp_tcb *, uint16_t, uint16_t *, uint8_t, void sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *, struct sctphdr *, uint32_t, struct mbuf *, - uint8_t, uint32_t, + uint8_t, uint32_t, uint16_t, uint32_t, uint16_t); void sctp_send_operr_to(struct sockaddr *, struct sockaddr *, struct sctphdr *, uint32_t, struct mbuf *, - uint8_t, uint32_t, + uint8_t, uint32_t, uint16_t, uint32_t, uint16_t); #endif /* _KERNEL || __Userspace__ */ diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 1d79f02..344cdfc 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -2489,6 +2489,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) inp->reconfig_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_reconfig_enable); inp->nrsack_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_nrsack_enable); inp->pktdrop_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_pktdrop_enable); + inp->fibnum = so->so_fibnum; /* init the small hash table we use to track asocid <-> tcb */ inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark); if (inp->sctp_asocidhash == NULL) { @@ -3953,7 +3954,9 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, sin6->sin6_scope_id = 0; } #endif - SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id); + SCTP_RTALLOC((sctp_route_t *) & net->ro, + stcb->asoc.vrf_id, + stcb->sctp_ep->fibnum); if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) { /* Get source address */ diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h index 963b89f..f5ede2a 100644 --- a/sys/netinet/sctp_pcb.h +++ b/sys/netinet/sctp_pcb.h @@ -430,6 +430,7 @@ struct sctp_inpcb { struct mtx inp_rdata_mtx; int32_t refcount; uint32_t def_vrf_id; + uint16_t fibnum; uint32_t total_sends; uint32_t total_recvs; uint32_t last_abort_code; diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 3d06a52..78bfe5e 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -6712,7 +6712,20 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt) size_t optsize = 0; void *p; int error = 0; + struct sctp_inpcb *inp; + if ((sopt->sopt_level == SOL_SOCKET) && + (sopt->sopt_name == SO_SETFIB)) { + inp = (struct sctp_inpcb *)so->so_pcb; + if (inp == NULL) { + SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS); + return (EINVAL); + } + SCTP_INP_WLOCK(inp); + inp->fibnum = so->so_fibnum; + SCTP_INP_WUNLOCK(inp); + return (0); + } if (sopt->sopt_level != IPPROTO_SCTP) { /* wrong proto level... send back up to IP */ #ifdef INET6 diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 24110dd..c25ec39 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -3895,7 +3895,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, stcb->asoc.state |= SCTP_STATE_WAS_ABORTED; } sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err, - mflowtype, mflowid, + mflowtype, mflowid, inp->fibnum, vrf_id, port); if (stcb != NULL) { /* Ok, now lets free it */ @@ -4051,7 +4051,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_inpcb *inp, 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 sctp_chunkhdr *ch, chunk_buf; @@ -4093,7 +4093,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, return; case SCTP_SHUTDOWN_ACK: sctp_send_shutdown_complete2(src, dst, sh, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); return; default: @@ -4107,7 +4107,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && (contains_init_chunk == 0))) { sctp_send_abort(m, iphlen, src, dst, sh, 0, cause, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); } } diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index 2ffbc2a..7df0a6c 100644 --- a/sys/netinet/sctputil.h +++ b/sys/netinet/sctputil.h @@ -208,7 +208,7 @@ sctp_handle_ootb(struct mbuf *, int, int, struct sockaddr *, struct sockaddr *, struct sctphdr *, struct sctp_inpcb *, struct mbuf *, - uint8_t, uint32_t, + uint8_t, uint32_t, uint16_t, uint32_t, uint16_t); int diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index e82ea77..536cc91 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -84,6 +84,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) #endif uint32_t mflowid; uint8_t mflowtype; + uint16_t fibnum; iphlen = *offp; if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) { @@ -109,6 +110,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) (int)m->m_pkthdr.csum_flags, CSUM_BITS); mflowid = m->m_pkthdr.flowid; mflowtype = M_HASHTYPE_GET(m); + fibnum = M_GETFIB(m); SCTP_STAT_INCR(sctps_recvpackets); SCTP_STAT_INCR_COUNTER64(sctps_inpackets); /* Get IP, SCTP, and first chunk header together in the first mbuf. */ @@ -173,7 +175,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) compute_crc, #endif ecn_bits, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); out: if (m) { |