aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/ip_divert.c
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2004-11-12 22:17:42 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2004-11-12 22:17:42 +0000
commitea0bd5761508835aed189f97e18c9ab49d0daf1c (patch)
tree88222400a548aafb1628c72dbb75405caea04b4c /sys/netinet/ip_divert.c
parent8e10380a9f9daedceae1b106e44a3bd3ec2e434a (diff)
downloadsrc-ea0bd5761508835aed189f97e18c9ab49d0daf1c.tar.gz
src-ea0bd5761508835aed189f97e18c9ab49d0daf1c.zip
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
Notes
Notes: svn path=/head/; revision=137630
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r--sys/netinet/ip_divert.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index b391fd252906..8d2b61b07742 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) {