aboutsummaryrefslogtreecommitdiff
path: root/sys/netgraph
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2009-01-20 22:26:09 +0000
committerAlexander Motin <mav@FreeBSD.org>2009-01-20 22:26:09 +0000
commit575573fb083cb977f31265c88204309b56490329 (patch)
tree7cb1bb23448b9cf474c0ee12f64ee7538de87870 /sys/netgraph
parent127a7d3f89cf6dc3f7ccacccdd058a0491f59e99 (diff)
Notes
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/ng_iface.c18
-rw-r--r--sys/netgraph/ng_iface.h3
2 files changed, 21 insertions, 0 deletions
diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c
index 2295004336db..a22b85a581dd 100644
--- a/sys/netgraph/ng_iface.c
+++ b/sys/netgraph/ng_iface.c
@@ -356,6 +356,7 @@ static int
ng_iface_output(struct ifnet *ifp, struct mbuf *m,
struct sockaddr *dst, struct rtentry *rt0)
{
+ struct m_tag *mtag;
uint32_t af;
int error;
@@ -366,6 +367,23 @@ ng_iface_output(struct ifnet *ifp, struct mbuf *m,
return (ENETDOWN);
}
+ /* Protect from deadly infinite recursion. */
+ while ((mtag = m_tag_locate(m, MTAG_NGIF, MTAG_NGIF_CALLED, NULL))) {
+ if (*(struct ifnet **)(mtag + 1) == ifp) {
+ log(LOG_NOTICE, "Loop detected on %s\n", ifp->if_xname);
+ m_freem(m);
+ return (EDEADLK);
+ }
+ }
+ mtag = m_tag_alloc(MTAG_NGIF, MTAG_NGIF_CALLED, sizeof(struct ifnet *),
+ M_NOWAIT);
+ if (mtag == NULL) {
+ m_freem(m);
+ return (ENOMEM);
+ }
+ *(struct ifnet **)(mtag + 1) = ifp;
+ m_tag_prepend(m, mtag);
+
/* BPF writes need to be handled specially. */
if (dst->sa_family == AF_UNSPEC) {
bcopy(dst->sa_data, &af, sizeof(af));
diff --git a/sys/netgraph/ng_iface.h b/sys/netgraph/ng_iface.h
index 54dfa8c78690..58fb44230582 100644
--- a/sys/netgraph/ng_iface.h
+++ b/sys/netgraph/ng_iface.h
@@ -72,4 +72,7 @@ enum {
NGM_IFACE_GET_IFINDEX,
};
+#define MTAG_NGIF NGM_IFACE_COOKIE
+#define MTAG_NGIF_CALLED 0 | MTAG_PERSISTENT
+
#endif /* _NETGRAPH_NG_IFACE_H_ */