Date: Wed, 17 Jun 2015 15:20:15 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r284515 - in head/sys: netinet netinet6 Message-ID: <201506171520.t5HFKFXg048980@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Wed Jun 17 15:20:14 2015 New Revision: 284515 URL: https://svnweb.freebsd.org/changeset/base/284515 Log: Add FIB support for SCTP. This fixes https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=200379 MFC after: 3 days Modified: head/sys/netinet/sctp_asconf.c head/sys/netinet/sctp_input.c head/sys/netinet/sctp_input.h head/sys/netinet/sctp_os_bsd.h head/sys/netinet/sctp_output.c head/sys/netinet/sctp_output.h head/sys/netinet/sctp_pcb.c head/sys/netinet/sctp_pcb.h head/sys/netinet/sctp_usrreq.c head/sys/netinet/sctputil.c head/sys/netinet/sctputil.h head/sys/netinet6/sctp6_usrreq.c Modified: head/sys/netinet/sctp_asconf.c ============================================================================== --- head/sys/netinet/sctp_asconf.c Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_asconf.c Wed Jun 17 15:20:14 2015 (r284515) @@ -1109,7 +1109,8 @@ sctp_path_check_and_react(struct sctp_tc * 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; Modified: head/sys/netinet/sctp_input.c ============================================================================== --- head/sys/netinet/sctp_input.c Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_input.c Wed Jun 17 15:20:14 2015 (r284515) @@ -186,7 +186,7 @@ sctp_handle_init(struct mbuf *m, int iph 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 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 */ 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, 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, 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 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 } 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 "Out of the blue"); sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); } } @@ -5775,7 +5776,7 @@ sctp_common_input_processing(struct mbuf 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; } @@ -5786,7 +5787,7 @@ sctp_common_input_processing(struct mbuf 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) { /* @@ -5827,7 +5828,7 @@ sctp_common_input_processing(struct mbuf 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; } @@ -5899,7 +5900,7 @@ sctp_common_input_processing(struct mbuf 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 */ @@ -6023,6 +6024,7 @@ sctp_input_with_port(struct mbuf *i_pak, #endif uint32_t mflowid; uint8_t mflowtype; + uint16_t fibnum; iphlen = off; if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) { @@ -6048,6 +6050,7 @@ sctp_input_with_port(struct mbuf *i_pak, (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. */ @@ -6107,7 +6110,7 @@ sctp_input_with_port(struct mbuf *i_pak, compute_crc, #endif ecn_bits, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); out: if (m) { Modified: head/sys/netinet/sctp_input.h ============================================================================== --- head/sys/netinet/sctp_input.h Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_input.h Wed Jun 17 15:20:14 2015 (r284515) @@ -45,7 +45,7 @@ sctp_common_input_processing(struct mbuf uint8_t, #endif uint8_t, - uint8_t, uint32_t, + uint8_t, uint32_t, uint16_t, uint32_t, uint16_t); struct sctp_stream_reset_request * Modified: head/sys/netinet/sctp_os_bsd.h ============================================================================== --- head/sys/netinet/sctp_os_bsd.h Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_os_bsd.h Wed Jun 17 15:20:14 2015 (r284515) @@ -413,13 +413,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) Modified: head/sys/netinet/sctp_output.c ============================================================================== --- head/sys/netinet/sctp_output.c Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_output.c Wed Jun 17 15:20:14 2015 (r284515) @@ -3389,7 +3389,7 @@ sctp_source_address_selection(struct sct /* * 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_i 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_i 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 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; } @@ -10839,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; @@ -10919,6 +10919,7 @@ sctp_send_resp_msg(struct sockaddr *src, 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 @@ -11106,11 +11107,11 @@ sctp_send_resp_msg(struct sockaddr *src, 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); } @@ -11929,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. */ @@ -11939,7 +11940,7 @@ sctp_send_abort(struct mbuf *m, int iphl return; } sctp_send_resp_msg(src, dst, sh, vtag, SCTP_ABORT_ASSOCIATION, cause, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); return; } @@ -11947,11 +11948,11 @@ sctp_send_abort(struct mbuf *m, int iphl 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; } Modified: head/sys/netinet/sctp_output.h ============================================================================== --- head/sys/netinet/sctp_output.h Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_output.h Wed Jun 17 15:20:14 2015 (r284515) @@ -117,7 +117,7 @@ void sctp_send_shutdown_complete(struct 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 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__ */ Modified: head/sys/netinet/sctp_pcb.c ============================================================================== --- head/sys/netinet/sctp_pcb.c Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_pcb.c Wed Jun 17 15:20:14 2015 (r284515) @@ -2485,6 +2485,7 @@ sctp_inpcb_alloc(struct socket *so, uint 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) { @@ -3949,7 +3950,9 @@ sctp_add_remote_addr(struct sctp_tcb *st 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 */ Modified: head/sys/netinet/sctp_pcb.h ============================================================================== --- head/sys/netinet/sctp_pcb.h Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_pcb.h Wed Jun 17 15:20:14 2015 (r284515) @@ -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; Modified: head/sys/netinet/sctp_usrreq.c ============================================================================== --- head/sys/netinet/sctp_usrreq.c Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctp_usrreq.c Wed Jun 17 15:20:14 2015 (r284515) @@ -6712,7 +6712,20 @@ sctp_ctloutput(struct socket *so, struct 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 Modified: head/sys/netinet/sctputil.c ============================================================================== --- head/sys/netinet/sctputil.c Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctputil.c Wed Jun 17 15:20:14 2015 (r284515) @@ -3895,7 +3895,7 @@ sctp_abort_association(struct sctp_inpcb 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 iph 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 iph 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 iph ((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); } } Modified: head/sys/netinet/sctputil.h ============================================================================== --- head/sys/netinet/sctputil.h Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet/sctputil.h Wed Jun 17 15:20:14 2015 (r284515) @@ -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 Modified: head/sys/netinet6/sctp6_usrreq.c ============================================================================== --- head/sys/netinet6/sctp6_usrreq.c Wed Jun 17 13:15:54 2015 (r284514) +++ head/sys/netinet6/sctp6_usrreq.c Wed Jun 17 15:20:14 2015 (r284515) @@ -84,6 +84,7 @@ sctp6_input_with_port(struct mbuf **i_pa #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_pa (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. */ @@ -169,7 +171,7 @@ sctp6_input_with_port(struct mbuf **i_pa compute_crc, #endif ecn_bits, - mflowtype, mflowid, + mflowtype, mflowid, fibnum, vrf_id, port); out: if (m) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506171520.t5HFKFXg048980>