master
  1/*-
  2 * Copyright (c) 2021
  3 * 	Alexander V. Chernikov <melifaro@FreeBSD.org>
  4 *
  5 * Redistribution and use in source and binary forms, with or without
  6 * modification, are permitted provided that the following conditions
  7 * are met:
  8 * 1. Redistributions of source code must retain the above copyright
  9 *    notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 *    notice, this list of conditions and the following disclaimer in the
 12 *    documentation and/or other materials provided with the distribution.
 13 * 3. Neither the name of the University nor the names of its contributors
 14 *    may be used to endorse or promote products derived from this software
 15 *    without specific prior written permission.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 27 * SUCH DAMAGE.
 28 */
 29
 30#ifndef _NET_ROUTE_DEBUG_H_
 31#define _NET_ROUTE_DEBUG_H_
 32
 33#include <sys/sysctl.h>
 34#include <sys/syslog.h>
 35
 36/* DEBUG logic */
 37#if defined(DEBUG_MOD_NAME) && defined(DEBUG_MAX_LEVEL)
 38
 39#ifndef	_DEBUG_SYSCTL_OID
 40#define	_DEBUG_SYSCTL_OID	_net_route_debug
 41SYSCTL_DECL(_net_route_debug);
 42#endif
 43
 44#define DEBUG_VAR_NAME                  	_DEBUG_VAR_NAME(DEBUG_MOD_NAME)
 45#define _DEBUG_VAR_NAME(a)			_DEBUG_VAR_NAME_INDIRECT(a)
 46#define _DEBUG_VAR_NAME_INDIRECT(prefix)	prefix##_debug_level
 47
 48#define DEBUG_PREFIX_NAME			_DEBUG_PREFIX_NAME(DEBUG_MOD_NAME)
 49#define _DEBUG_PREFIX_NAME(n)			__DEBUG_PREFIX_NAME(n)
 50#define __DEBUG_PREFIX_NAME(n)			#n
 51
 52#define	_DECLARE_DEBUG(_default_level)  	        		\
 53	static int DEBUG_VAR_NAME = _default_level;	                \
 54        SYSCTL_INT(_DEBUG_SYSCTL_OID, OID_AUTO, DEBUG_VAR_NAME,          \
 55		CTLFLAG_RW | CTLFLAG_RWTUN,				\
 56                &(DEBUG_VAR_NAME), 0, "debuglevel")
 57
 58/* Additional tracing levels not defined by log.h */
 59#ifndef	LOG_DEBUG2
 60#define	LOG_DEBUG2	8
 61#endif
 62#ifndef LOG_DEBUG3
 63#define LOG_DEBUG3      9
 64#endif
 65
 66/*
 67 * Severity usage guidelines:
 68 *
 69 * LOG_WARNING - subsystem-global errors ("multipath init failed")
 70 *
 71 * LOG_INFO - subsystem non-transient errors ("Failed to unlink nexhop").
 72 *  All logging <= LOG_INFO by default will be written to syslog.
 73 *
 74 * LOG_DEBUG - subsystem debug. Not-too often events (hash resizes, recoverable failures).
 75 *  These are compiled in by default on production. Turning it it should NOT notable affect
 76 *  performance
 77 * LOG_DEBUG2 - more debug. Per-item level (nhg,nh,route) debug, up to multiple lines per item.
 78 *  This is NOT compiled in by default. Turning it on should NOT seriously impact performance
 79 * LOG_DEBUG3 - last debug level. Per-item large debug outputs.
 80 *  This is NOT compiled in by default. All performance bets are off.
 81 */
 82
 83#define	_output			printf
 84#define	_DEBUG_PASS_MSG(_l)	(DEBUG_VAR_NAME >= (_l))
 85
 86#define	IF_DEBUG_LEVEL(_l)	\
 87	if ((DEBUG_MAX_LEVEL >= (_l)) && (__predict_false(DEBUG_VAR_NAME >= (_l))))
 88
 89/*
 90 * Logging for events specific for particular family and fib
 91 * Example: [nhop_neigh] inet.0 find_lle: <message>
 92 */
 93#define	FIB_LOG(_l, _fib, _fam, _fmt, ...)				\
 94	FIB_LOG_##_l(_l, _fib, _fam, _fmt, ## __VA_ARGS__)
 95#define	_FIB_LOG(_l, _fib, _fam, _fmt, ...)				\
 96	if (_DEBUG_PASS_MSG(_l)) {					\
 97		_output("[" DEBUG_PREFIX_NAME "] %s.%u %s: " _fmt "\n",	\
 98		    rib_print_family(_fam), _fib, __func__, ##__VA_ARGS__); \
 99	}
100
101/* Same as FIB_LOG, but uses nhop to get fib and family */
102#define	FIB_NH_LOG(_l, _nh, _fmt, ...)					\
103	FIB_LOG_##_l(_l, nhop_get_fibnum(_nh), nhop_get_upper_family(_nh), \
104	    _fmt, ## __VA_ARGS__)
105/* Same as FIB_LOG, but uses rib_head to get fib and family */
106#define	FIB_RH_LOG(_l, _rh, _fmt, ...)					\
107	FIB_LOG_##_l(_l, (_rh)->rib_fibnum, (_rh)->rib_family, _fmt,	\
108	    ## __VA_ARGS__)
109/* Same as FIB_LOG, but uses nh_control to get fib and family from linked rib */
110#define	FIB_CTL_LOG(_l, _ctl, _fmt, ...)				\
111	FIB_LOG_##_l(_l, (_ctl)->ctl_rh->rib_fibnum,			\
112	    (_ctl)->ctl_rh->rib_family, _fmt, ## __VA_ARGS__)
113
114/*
115 * Generic logging for routing subsystem
116 * Example: [nhop_neigh] nhops_update_neigh: <message>
117 */
118#define	RT_LOG(_l, _fmt, ...)	RT_LOG_##_l(_l, _fmt, ## __VA_ARGS__)
119#define	_RT_LOG(_l, _fmt, ...)	if (_DEBUG_PASS_MSG(_l)) {	\
120	_output("[" DEBUG_PREFIX_NAME "] %s: " _fmt "\n",  __func__, ##__VA_ARGS__);	\
121}
122
123
124/*
125 * Wrapper logic to avoid compiling high levels of debugging messages for
126 * production systems.
127 */
128#if DEBUG_MAX_LEVEL>=LOG_DEBUG3
129#define	FIB_LOG_LOG_DEBUG3	_FIB_LOG
130#define	RT_LOG_LOG_DEBUG3	_RT_LOG
131#else
132#define	FIB_LOG_LOG_DEBUG3(_l, _fib, _fam, _fmt, ...)
133#define	RT_LOG_LOG_DEBUG3(_l, _fmt, ...)
134#endif
135#if DEBUG_MAX_LEVEL>=LOG_DEBUG2
136#define	FIB_LOG_LOG_DEBUG2	_FIB_LOG
137#define	RT_LOG_LOG_DEBUG2	_RT_LOG
138#else
139#define	FIB_LOG_LOG_DEBUG2(_l, _fib, _fam, _fmt, ...)
140#define	RT_LOG_LOG_DEBUG2(_l, _fmt, ...)
141#endif
142#if DEBUG_MAX_LEVEL>=LOG_DEBUG
143#define	FIB_LOG_LOG_DEBUG	_FIB_LOG
144#define	RT_LOG_LOG_DEBUG	_RT_LOG
145#else
146#define	FIB_LOG_LOG_DEBUG(_l, _fib, _fam, _fmt, ...)
147#define	RT_LOG_LOG_DEBUG(_l, _fmt, ...)
148#endif
149#if DEBUG_MAX_LEVEL>=LOG_INFO
150#define	FIB_LOG_LOG_INFO	_FIB_LOG
151#define	RT_LOG_LOG_INFO	_RT_LOG
152#else
153#define	FIB_LOG_LOG_INFO(_l, _fib, _fam, _fmt, ...)
154#define	RT_LOG_LOG_INFO(_l, _fmt, ...)
155#endif
156#define	FIB_LOG_LOG_NOTICE	_FIB_LOG
157#define	FIB_LOG_LOG_ERR         _FIB_LOG
158#define	FIB_LOG_LOG_WARNING	_FIB_LOG
159#define	RT_LOG_LOG_NOTICE	_RT_LOG
160#define	RT_LOG_LOG_ERR          _RT_LOG
161#define	RT_LOG_LOG_WARNING	_RT_LOG
162
163#endif
164
165/* Helpers for fancy-printing various objects */
166struct nhop_object;
167struct nhgrp_object;
168struct llentry;
169struct nhop_neigh;
170struct rtentry;
171struct ifnet;
172
173#define	NHOP_PRINT_BUFSIZE	48
174char *nhop_print_buf(const struct nhop_object *nh, char *buf, size_t bufsize);
175char *nhop_print_buf_any(const struct nhop_object *nh, char *buf, size_t bufsize);
176char *nhgrp_print_buf(const struct nhgrp_object *nhg, char *buf, size_t bufsize);
177char *llentry_print_buf(const struct llentry *lle, struct ifnet *ifp, int family, char *buf,
178    size_t bufsize);
179char *llentry_print_buf_lltable(const struct llentry *lle, char *buf, size_t bufsize);
180char *neigh_print_buf(const struct nhop_neigh *nn, char *buf, size_t bufsize);
181char *rt_print_buf(const struct rtentry *rt, char *buf, size_t bufsize);
182const char *rib_print_cmd(int rib_cmd);
183
184#endif