Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152743423
D22866.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D22866.diff
View Options
Index: head/sys/netinet/tcp_log_buf.h
===================================================================
--- head/sys/netinet/tcp_log_buf.h
+++ head/sys/netinet/tcp_log_buf.h
@@ -31,7 +31,8 @@
#define __tcp_log_buf_h__
#define TCP_LOG_REASON_LEN 32
-#define TCP_LOG_BUF_VER (6)
+#define TCP_LOG_TAG_LEN 32
+#define TCP_LOG_BUF_VER (7)
/*
* Because the (struct tcp_log_buffer) includes 8-byte uint64_t's, it requires
@@ -263,6 +264,7 @@
struct timeval tlh_offset; /* Uptime -> UTC offset */
char tlh_id[TCP_LOG_ID_LEN];
char tlh_reason[TCP_LOG_REASON_LEN];
+ char tlh_tag[TCP_LOG_TAG_LEN];
uint8_t tlh_af;
uint8_t _pad[7];
} ALIGN_TCP_LOG;
@@ -272,6 +274,7 @@
struct tcp_log_dev_queue tldl_common;
char tldl_id[TCP_LOG_ID_LEN];
char tldl_reason[TCP_LOG_REASON_LEN];
+ char tldl_tag[TCP_LOG_TAG_LEN];
struct in_endpoints tldl_ie;
struct tcp_log_stailq tldl_entries;
int tldl_count;
@@ -349,10 +352,12 @@
union tcp_log_stackspecific *stackinfo, int th_hostorder,
const char *output_caller, const char *func, int line, const struct timeval *tv);
size_t tcp_log_get_id(struct tcpcb *tp, char *buf);
+size_t tcp_log_get_tag(struct tcpcb *tp, char *buf);
u_int tcp_log_get_id_cnt(struct tcpcb *tp);
int tcp_log_getlogbuf(struct sockopt *sopt, struct tcpcb *tp);
void tcp_log_init(void);
int tcp_log_set_id(struct tcpcb *tp, char *id);
+int tcp_log_set_tag(struct tcpcb *tp, char *tag);
int tcp_log_state_change(struct tcpcb *tp, int state);
void tcp_log_tcpcbinit(struct tcpcb *tp);
void tcp_log_tcpcbfini(struct tcpcb *tp);
Index: head/sys/netinet/tcp_log_buf.c
===================================================================
--- head/sys/netinet/tcp_log_buf.c
+++ head/sys/netinet/tcp_log_buf.c
@@ -43,7 +43,7 @@
#include <sys/socketvar.h>
#include <sys/sysctl.h>
#include <sys/tree.h>
-#include <sys/stats.h>
+#include <sys/stats.h> /* Must come after qmath.h and tree.h */
#include <sys/counter.h>
#include <dev/tcp_log/tcp_log_dev.h>
@@ -78,6 +78,7 @@
static volatile u_long tcp_log_auto_ratio_cur = 0;
static uint32_t tcp_log_auto_mode = TCP_LOG_STATE_TAIL;
static bool tcp_log_auto_all = false;
+static uint32_t tcp_disable_all_bb_logs = 0;
RB_PROTOTYPE_STATIC(tcp_log_id_tree, tcp_log_id_bucket, tlb_rb, tcp_log_id_cmp)
@@ -111,6 +112,10 @@
SYSCTL_U32(_net_inet_tcp_bb, OID_AUTO, log_version, CTLFLAG_RD, &tcp_log_version,
0, "Version of log formats exported");
+SYSCTL_U32(_net_inet_tcp_bb, OID_AUTO, disable_all, CTLFLAG_RW,
+ &tcp_disable_all_bb_logs, TCP_LOG_STATE_HEAD_AUTO,
+ "Disable all BB logging for all connections");
+
SYSCTL_ULONG(_net_inet_tcp_bb, OID_AUTO, log_auto_ratio, CTLFLAG_RW,
&tcp_log_auto_ratio, 0, "Do auto capturing for 1 out of N sessions");
@@ -156,7 +161,18 @@
#ifdef INVARIANTS
#define TCPLOG_DEBUG_RINGBUF
#endif
+/* Number of requests to consider a PBCID "active". */
+#define ACTIVE_REQUEST_COUNT 10
+/* Statistic tracking for "active" PBCIDs. */
+static counter_u64_t tcp_log_pcb_ids_cur;
+static counter_u64_t tcp_log_pcb_ids_tot;
+
+SYSCTL_COUNTER_U64(_net_inet_tcp_bb, OID_AUTO, pcb_ids_cur, CTLFLAG_RD,
+ &tcp_log_pcb_ids_cur, "Number of pcb IDs allocated in the system");
+SYSCTL_COUNTER_U64(_net_inet_tcp_bb, OID_AUTO, pcb_ids_tot, CTLFLAG_RD,
+ &tcp_log_pcb_ids_tot, "Total number of pcb IDs that have been allocated");
+
struct tcp_log_mem
{
STAILQ_ENTRY(tcp_log_mem) tlm_queue;
@@ -240,10 +256,14 @@
* (struct tcp_log_id_bucket *) and (char *) interchangeably.
*/
char tlb_id[TCP_LOG_ID_LEN];
+ char tlb_tag[TCP_LOG_TAG_LEN];
RB_ENTRY(tcp_log_id_bucket) tlb_rb;
struct tcp_log_id_head tlb_head;
struct mtx tlb_mtx;
volatile u_int tlb_refcnt;
+ volatile u_int tlb_reqcnt;
+ uint32_t tlb_loglimit;
+ uint8_t tlb_logstate;
};
struct tcp_log_id_node
@@ -285,6 +305,7 @@
* this session.
*/
if (tcp_log_auto_ratio &&
+ (tcp_disable_all_bb_logs == 0) &&
(atomic_fetchadd_long(&tcp_log_auto_ratio_cur, 1) %
tcp_log_auto_ratio) == 0)
return (true);
@@ -337,6 +358,7 @@
#endif
}
TCPID_BUCKET_LOCK_DESTROY(tlb);
+ counter_u64_add(tcp_log_pcb_ids_cur, (int64_t)-1);
uma_zfree(tcp_log_bucket_zone, tlb);
}
@@ -484,7 +506,53 @@
#endif
}
+static void
+tcp_log_increment_reqcnt(struct tcp_log_id_bucket *tlb)
+{
+
+ atomic_fetchadd_int(&tlb->tlb_reqcnt, 1);
+}
+
/*
+ * Associate the specified tag with a particular TCP log ID.
+ * Called with INPCB locked. Returns with it unlocked.
+ * Returns 0 on success or EOPNOTSUPP if the connection has no TCP log ID.
+ */
+int
+tcp_log_set_tag(struct tcpcb *tp, char *tag)
+{
+ struct tcp_log_id_bucket *tlb;
+ int tree_locked;
+
+ INP_WLOCK_ASSERT(tp->t_inpcb);
+
+ tree_locked = TREE_UNLOCKED;
+ tlb = tp->t_lib;
+ if (tlb == NULL) {
+ INP_WUNLOCK(tp->t_inpcb);
+ return (EOPNOTSUPP);
+ }
+
+ TCPID_BUCKET_REF(tlb);
+ INP_WUNLOCK(tp->t_inpcb);
+ TCPID_BUCKET_LOCK(tlb);
+ strlcpy(tlb->tlb_tag, tag, TCP_LOG_TAG_LEN);
+ if (!tcp_log_unref_bucket(tlb, &tree_locked, NULL))
+ TCPID_BUCKET_UNLOCK(tlb);
+
+ if (tree_locked == TREE_WLOCKED) {
+ TCPID_TREE_WLOCK_ASSERT();
+ TCPID_TREE_WUNLOCK();
+ } else if (tree_locked == TREE_RLOCKED) {
+ TCPID_TREE_RLOCK_ASSERT();
+ TCPID_TREE_RUNLOCK();
+ } else
+ TCPID_TREE_UNLOCK_ASSERT();
+
+ return (0);
+}
+
+/*
* Set the TCP log ID for a TCPCB.
* Called with INPCB locked. Returns with it unlocked.
*/
@@ -509,6 +577,21 @@
/* See if the ID is unchanged. */
if ((tp->t_lib != NULL && !strcmp(tp->t_lib->tlb_id, id)) ||
(tp->t_lib == NULL && *id == 0)) {
+ if (tp->t_lib != NULL) {
+ tcp_log_increment_reqcnt(tp->t_lib);
+ if ((tp->t_lib->tlb_logstate) &&
+ (tp->t_log_state_set == 0)) {
+ /* Clone in any logging */
+
+ tp->t_logstate = tp->t_lib->tlb_logstate;
+ }
+ if ((tp->t_lib->tlb_loglimit) &&
+ (tp->t_log_state_set == 0)) {
+ /* We also have a limit set */
+
+ tp->t_loglimit = tp->t_lib->tlb_loglimit;
+ }
+ }
rv = 0;
goto done;
}
@@ -677,7 +760,19 @@
rv = ENOBUFS;
goto done_noinp;
}
+ counter_u64_add(tcp_log_pcb_ids_cur, 1);
+ counter_u64_add(tcp_log_pcb_ids_tot, 1);
+ if ((tcp_log_auto_all == false) &&
+ tcp_log_auto_mode &&
+ tcp_log_selectauto()) {
+ /* Save off the log state */
+ tlb->tlb_logstate = tcp_log_auto_mode;
+ } else
+ tlb->tlb_logstate = TCP_LOG_STATE_OFF;
+ tlb->tlb_loglimit = 0;
+ tlb->tlb_tag[0] = '\0'; /* Default to an empty tag. */
+
/*
* Copy the ID to the bucket.
* NB: Don't use strlcpy() unless you are sure
@@ -699,6 +794,7 @@
*/
SLIST_INIT(&tlb->tlb_head);
refcount_init(&tlb->tlb_refcnt, 1);
+ tlb->tlb_reqcnt = 1;
memset(&tlb->tlb_mtx, 0, sizeof(struct mtx));
TCPID_BUCKET_LOCK_INIT(tlb);
TCPID_BUCKET_LOCK(tlb);
@@ -707,6 +803,8 @@
#define FREE_NEW_TLB() do { \
TCPID_BUCKET_LOCK_DESTROY(tlb); \
uma_zfree(tcp_log_bucket_zone, tlb); \
+ counter_u64_add(tcp_log_pcb_ids_cur, (int64_t)-1); \
+ counter_u64_add(tcp_log_pcb_ids_tot, (int64_t)-1); \
bucket_locked = false; \
tlb = NULL; \
} while (0)
@@ -762,6 +860,9 @@
/* Take a reference on the bucket. */
TCPID_BUCKET_REF(tlb);
+
+ /* Record the request. */
+ tcp_log_increment_reqcnt(tlb);
}
tcp_log_grow_tlb(tlb->tlb_id, tp);
@@ -770,6 +871,16 @@
SLIST_INSERT_HEAD(&tlb->tlb_head, tln, tln_list);
tp->t_lib = tlb;
tp->t_lin = tln;
+ if (tp->t_lib->tlb_logstate) {
+ /* Clone in any logging */
+
+ tp->t_logstate = tp->t_lib->tlb_logstate;
+ }
+ if (tp->t_lib->tlb_loglimit) {
+ /* The loglimit too */
+
+ tp->t_loglimit = tp->t_lib->tlb_loglimit;
+ }
tln = NULL;
}
@@ -823,6 +934,52 @@
}
/*
+ * Get the tag associated with the TCPCB's log ID.
+ * Called with INPCB locked. Returns with it unlocked.
+ * 'buf' must point to a buffer that is at least TCP_LOG_TAG_LEN bytes long.
+ * Returns number of bytes copied.
+ */
+size_t
+tcp_log_get_tag(struct tcpcb *tp, char *buf)
+{
+ struct tcp_log_id_bucket *tlb;
+ size_t len;
+ int tree_locked;
+
+ INP_WLOCK_ASSERT(tp->t_inpcb);
+
+ tree_locked = TREE_UNLOCKED;
+ tlb = tp->t_lib;
+
+ if (tlb != NULL) {
+ TCPID_BUCKET_REF(tlb);
+ INP_WUNLOCK(tp->t_inpcb);
+ TCPID_BUCKET_LOCK(tlb);
+ len = strlcpy(buf, tlb->tlb_tag, TCP_LOG_TAG_LEN);
+ KASSERT(len < TCP_LOG_TAG_LEN,
+ ("%s:%d: tp->t_lib->tlb_tag too long (%zu)",
+ __func__, __LINE__, len));
+ if (!tcp_log_unref_bucket(tlb, &tree_locked, NULL))
+ TCPID_BUCKET_UNLOCK(tlb);
+
+ if (tree_locked == TREE_WLOCKED) {
+ TCPID_TREE_WLOCK_ASSERT();
+ TCPID_TREE_WUNLOCK();
+ } else if (tree_locked == TREE_RLOCKED) {
+ TCPID_TREE_RLOCK_ASSERT();
+ TCPID_TREE_RUNLOCK();
+ } else
+ TCPID_TREE_UNLOCK_ASSERT();
+ } else {
+ INP_WUNLOCK(tp->t_inpcb);
+ *buf = '\0';
+ len = 0;
+ }
+
+ return (len);
+}
+
+/*
* Get number of connections with the same log ID.
* Log ID is taken from given TCPCB.
* Called with INPCB locked.
@@ -1005,6 +1162,8 @@
tcp_log_que_read = counter_u64_alloc(M_WAITOK);
tcp_log_que_freed = counter_u64_alloc(M_WAITOK);
#endif
+ tcp_log_pcb_ids_cur = counter_u64_alloc(M_WAITOK);
+ tcp_log_pcb_ids_tot = counter_u64_alloc(M_WAITOK);
rw_init_flags(&tcp_id_tree_lock, "TCP ID tree", RW_NEW);
mtx_init(&tcp_log_expireq_mtx, "TCP log expireq", NULL, MTX_DEF);
@@ -1023,7 +1182,10 @@
* If we are doing auto-capturing, figure out whether we will capture
* this session.
*/
- if (tcp_log_selectauto()) {
+ tp->t_loglimit = tcp_log_session_limit;
+ if ((tcp_log_auto_all == true) &&
+ tcp_log_auto_mode &&
+ tcp_log_selectauto()) {
tp->t_logstate = tcp_log_auto_mode;
tp->t_flags2 |= TF2_LOG_AUTO;
}
@@ -1162,6 +1324,8 @@
INP_WLOCK_ASSERT(tp->t_inpcb);
+ TCP_LOG_EVENT(tp, NULL, NULL, NULL, TCP_LOG_CONNEND, 0, 0, NULL, false);
+
/*
* If we were gathering packets to be automatically dumped, try to do
* it now. If this succeeds, the log information in the TCPCB will be
@@ -1327,6 +1491,25 @@
tp->t_logstate = TCP_LOG_STATE_OFF;
}
+static void
+tcp_log_purge_tp_logbuf(struct tcpcb *tp)
+{
+ struct tcp_log_mem *log_entry;
+ struct inpcb *inp;
+
+ inp = tp->t_inpcb;
+ INP_WLOCK_ASSERT(inp);
+ if (tp->t_lognum == 0)
+ return;
+
+ while ((log_entry = STAILQ_FIRST(&tp->t_logs)) != NULL)
+ tcp_log_remove_log_head(tp, log_entry);
+ KASSERT(tp->t_lognum == 0,
+ ("%s: After freeing entries, tp->t_lognum=%d (expected 0)",
+ __func__, tp->t_lognum));
+ tp->t_logstate = TCP_LOG_STATE_OFF;
+}
+
/*
* This logs an event for a TCP socket. Normally, this is called via
* TCP_LOG_EVENT or TCP_LOG_EVENT_VERBOSE. See the documentation for
@@ -1350,7 +1533,17 @@
__func__, func, line));
INP_WLOCK_ASSERT(tp->t_inpcb);
-
+ if (tcp_disable_all_bb_logs) {
+ /*
+ * The global shutdown logging
+ * switch has been thrown. Call
+ * the purge function that frees
+ * purges out the logs and
+ * turns off logging.
+ */
+ tcp_log_purge_tp_logbuf(tp);
+ return (NULL);
+ }
KASSERT(tp->t_logstate == TCP_LOG_STATE_HEAD ||
tp->t_logstate == TCP_LOG_STATE_TAIL ||
tp->t_logstate == TCP_LOG_STATE_CONTINUAL ||
@@ -1371,7 +1564,7 @@
* here.
*/
retry:
- if (tp->t_lognum < tcp_log_session_limit) {
+ if (tp->t_lognum < tp->t_loglimit) {
if ((log_entry = uma_zalloc(tcp_log_zone, M_NOWAIT)) != NULL)
tp->t_lognum++;
} else
@@ -1574,7 +1767,10 @@
default:
return (EINVAL);
}
-
+ if (tcp_disable_all_bb_logs) {
+ /* We are prohibited from doing any logs */
+ tp->t_logstate = TCP_LOG_STATE_OFF;
+ }
tp->t_flags2 &= ~(TF2_LOG_AUTO);
return (0);
@@ -1934,6 +2130,7 @@
hdr->tlh_af = entry->tldl_af;
getboottime(&hdr->tlh_offset);
strlcpy(hdr->tlh_id, entry->tldl_id, TCP_LOG_ID_LEN);
+ strlcpy(hdr->tlh_tag, entry->tldl_tag, TCP_LOG_TAG_LEN);
strlcpy(hdr->tlh_reason, entry->tldl_reason, TCP_LOG_REASON_LEN);
return ((struct tcp_log_common_header *)hdr);
}
@@ -2026,10 +2223,13 @@
}
/* Fill in the unique parts of the queue entry. */
- if (tp->t_lib != NULL)
+ if (tp->t_lib != NULL) {
strlcpy(entry->tldl_id, tp->t_lib->tlb_id, TCP_LOG_ID_LEN);
- else
+ strlcpy(entry->tldl_tag, tp->t_lib->tlb_tag, TCP_LOG_TAG_LEN);
+ } else {
strlcpy(entry->tldl_id, "UNKNOWN", TCP_LOG_ID_LEN);
+ strlcpy(entry->tldl_tag, "UNKNOWN", TCP_LOG_TAG_LEN);
+ }
if (reason != NULL)
strlcpy(entry->tldl_reason, reason, TCP_LOG_REASON_LEN);
else
@@ -2119,6 +2319,7 @@
/* Fill in the unique parts of the queue entry. */
strlcpy(entry->tldl_id, tlb->tlb_id, TCP_LOG_ID_LEN);
+ strlcpy(entry->tldl_tag, tlb->tlb_tag, TCP_LOG_TAG_LEN);
if (reason != NULL)
strlcpy(entry->tldl_reason, reason, TCP_LOG_REASON_LEN);
else
Index: head/sys/netinet/tcp_var.h
===================================================================
--- head/sys/netinet/tcp_var.h
+++ head/sys/netinet/tcp_var.h
@@ -103,7 +103,8 @@
t_idle_reduce : 1,
t_delayed_ack: 7, /* Delayed ack variable */
t_fin_is_rst: 1, /* Are fin's treated as resets */
- bits_spare : 3;
+ t_log_state_set: 1,
+ bits_spare : 2;
u_int t_flags;
tcp_seq snd_una; /* sent but unacknowledged */
tcp_seq snd_max; /* highest sequence number sent;
@@ -206,6 +207,7 @@
u_int t_keepcnt; /* number of keepalives before close */
int t_dupacks; /* consecutive dup acks recd */
int t_lognum; /* Number of log entries */
+ int t_loglimit; /* Maximum number of log entries */
struct tcp_log_stailq t_logs; /* Log buffer */
struct tcp_log_id_node *t_lin;
struct tcp_log_id_bucket *t_lib;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 17, 8:34 PM (36 m, 33 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31679003
Default Alt Text
D22866.diff (13 KB)
Attached To
Mode
D22866: Update tcp_logging to have two new features
Attached
Detach File
Event Timeline
Log In to Comment