* Tunnel interfaces can nest, also they may cause infinite recursion * calls when misconfigured. We'll prevent this by detecting loops. * High nesting level may cause stack exhaustion. We'll prevent this * by introducing upper limit. * * Return 0, if tunnel nesting count is equal or less than limit. */
| 3879 | * Return 0, if tunnel nesting count is equal or less than limit. |
| 3880 | */ |
| 3881 | int |
| 3882 | if_tunnel_check_nesting(struct ifnet *ifp, struct mbuf *m, uint32_t cookie, |
| 3883 | int limit) |
| 3884 | { |
| 3885 | struct m_tag *mtag; |
| 3886 | int count; |
| 3887 | |
| 3888 | count = 1; |
| 3889 | mtag = NULL; |
| 3890 | while ((mtag = m_tag_locate(m, cookie, 0, mtag)) != NULL) { |
| 3891 | if (*(struct ifnet **)(mtag + 1) == ifp) { |
| 3892 | log(LOG_NOTICE, "%s: loop detected\n", if_name(ifp)); |
| 3893 | return (EIO); |
| 3894 | } |
| 3895 | count++; |
| 3896 | } |
| 3897 | if (count > limit) { |
| 3898 | log(LOG_NOTICE, |
| 3899 | "%s: if_output recursively called too many times(%d)\n", |
| 3900 | if_name(ifp), count); |
| 3901 | return (EIO); |
| 3902 | } |
| 3903 | mtag = m_tag_alloc(cookie, 0, sizeof(struct ifnet *), M_NOWAIT); |
| 3904 | if (mtag == NULL) |
| 3905 | return (ENOMEM); |
| 3906 | *(struct ifnet **)(mtag + 1) = ifp; |
| 3907 | m_tag_prepend(m, mtag); |
| 3908 | return (0); |
| 3909 | } |
| 3910 | |
| 3911 | /* |
| 3912 | * Get the link layer address that was read from the hardware at attach. |
no test coverage detected