| 210 | } |
| 211 | |
| 212 | static int |
| 213 | ip_output_send(struct inpcb *inp, struct ifnet *ifp, struct mbuf *m, |
| 214 | const struct sockaddr_in *gw, struct route *ro, bool stamp_tag) |
| 215 | { |
| 216 | #ifdef KERN_TLS |
| 217 | struct ktls_session *tls = NULL; |
| 218 | #endif |
| 219 | struct m_snd_tag *mst; |
| 220 | int error; |
| 221 | |
| 222 | MPASS((m->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0); |
| 223 | mst = NULL; |
| 224 | |
| 225 | #ifdef KERN_TLS |
| 226 | /* |
| 227 | * If this is an unencrypted TLS record, save a reference to |
| 228 | * the record. This local reference is used to call |
| 229 | * ktls_output_eagain after the mbuf has been freed (thus |
| 230 | * dropping the mbuf's reference) in if_output. |
| 231 | */ |
| 232 | if (m->m_next != NULL && mbuf_has_tls_session(m->m_next)) { |
| 233 | tls = ktls_hold(m->m_next->m_epg_tls); |
| 234 | mst = tls->snd_tag; |
| 235 | |
| 236 | /* |
| 237 | * If a TLS session doesn't have a valid tag, it must |
| 238 | * have had an earlier ifp mismatch, so drop this |
| 239 | * packet. |
| 240 | */ |
| 241 | if (mst == NULL) { |
| 242 | error = EAGAIN; |
| 243 | goto done; |
| 244 | } |
| 245 | /* |
| 246 | * Always stamp tags that include NIC ktls. |
| 247 | */ |
| 248 | stamp_tag = true; |
| 249 | } |
| 250 | #endif |
| 251 | #ifdef RATELIMIT |
| 252 | if (inp != NULL && mst == NULL) { |
| 253 | if ((inp->inp_flags2 & INP_RATE_LIMIT_CHANGED) != 0 || |
| 254 | (inp->inp_snd_tag != NULL && |
| 255 | inp->inp_snd_tag->ifp != ifp)) |
| 256 | in_pcboutput_txrtlmt(inp, ifp, m); |
| 257 | |
| 258 | if (inp->inp_snd_tag != NULL) |
| 259 | mst = inp->inp_snd_tag; |
| 260 | } |
| 261 | #endif |
| 262 | if (stamp_tag && mst != NULL) { |
| 263 | KASSERT(m->m_pkthdr.rcvif == NULL, |
| 264 | ("trying to add a send tag to a forwarded packet")); |
| 265 | if (mst->ifp != ifp) { |
| 266 | error = EAGAIN; |
| 267 | goto done; |
| 268 | } |
| 269 |
no test coverage detected