diff options
author | glebius <glebius@FreeBSD.org> | 2004-11-12 22:17:42 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2004-11-12 22:17:42 +0000 |
commit | a4a6b8f0c49e6a5ba44b5c5b06e96b1689ca7975 (patch) | |
tree | 88222400a548aafb1628c72dbb75405caea04b4c /sys/netinet/ip_divert.c | |
parent | ac7d3d8927f9e5a1e69af488a0d96ceb36089972 (diff) | |
download | FreeBSD-src-a4a6b8f0c49e6a5ba44b5c5b06e96b1689ca7975.zip FreeBSD-src-a4a6b8f0c49e6a5ba44b5c5b06e96b1689ca7975.tar.gz |
Fix ng_ksocket(4) operation as a divert socket, which is pretty useful
and has been broken twice:
- in the beginning of div_output() replace KASSERT with assignment, as
it was in rev. 1.83. [1] [to be MFCed]
- refactor changes introduced in rev. 1.100: do not prepend a new tag
unconditionally. Before doing this check whether we have one. [2]
A small note for all hacking in this area:
when divert socket is not a real userland, but ng_ksocket(4), we receive
_the same_ mbufs, that we transmitted to socket. These mbufs have rcvif,
the tags we've put on them. And we should treat them correctly.
Discussed with: mlaier [1]
Silence from: green [2]
Reviewed by: maxim
Approved by: julian (mentor)
MFC after: 1 week
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r-- | sys/netinet/ip_divert.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index b391fd2..8d2b61b 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -277,21 +277,22 @@ div_output(struct socket *so, struct mbuf *m, struct divert_tag *dt; int error = 0; - KASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null")); + m->m_pkthdr.rcvif = NULL; if (control) m_freem(control); /* XXX */ - mtag = m_tag_get(PACKET_TAG_DIVERT, - sizeof(struct divert_tag), M_NOWAIT); - if (mtag == NULL) { - error = ENOBUFS; - goto cantsend; - } - dt = (struct divert_tag *)(mtag+1); - dt->info = 0; - dt->cookie = 0; - m_tag_prepend(m, mtag); + if ((mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL)) == NULL) { + mtag = m_tag_get(PACKET_TAG_DIVERT, sizeof(struct divert_tag), + M_NOWAIT | M_ZERO); + if (mtag == NULL) { + error = ENOBUFS; + goto cantsend; + } + dt = (struct divert_tag *)(mtag+1); + m_tag_prepend(m, mtag); + } else + dt = (struct divert_tag *)(mtag+1); /* Loopback avoidance and state recovery */ if (sin) { |