Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144418950
D40302.id122560.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D40302.id122560.diff
View Options
diff --git a/share/man/man4/siftr.4 b/share/man/man4/siftr.4
--- a/share/man/man4/siftr.4
+++ b/share/man/man4/siftr.4
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 26, 2023
+.Dd May 27, 2023
.Dt SIFTR 4
.Os
.Sh NAME
@@ -83,10 +83,7 @@
"136.186.229.95") is used to format IPv4 addresses for logging.
In IPv6 mode, standard dotted decimal notation is used to format IPv4 addresses,
and standard colon-separated hex notation (see RFC 4291) is used to format IPv6
-addresses for logging.
-Note that SIFTR uses uncompressed notation to format IPv6 addresses.
-For example, the address "fe80::20f:feff:fea2:531b" would be logged as
-"fe80:0:0:0:20f:feff:fea2:531b".
+addresses (e.g. "fd00::2") for logging.
.Ss Run-time Configuration
.Nm
utilises the
@@ -746,7 +743,4 @@
does not take into account bytes that have been
.No SACK Ap ed
by the receiving host.
-.It
-Compressed notation is not used for IPv6 address representation.
-This consumes more bytes than is necessary in log output.
.El
diff --git a/sys/netinet/siftr.c b/sys/netinet/siftr.c
--- a/sys/netinet/siftr.c
+++ b/sys/netinet/siftr.c
@@ -87,9 +87,11 @@
#include <net/if.h>
#include <net/if_var.h>
#include <net/pfil.h>
+#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_kdtrace.h>
+#include <netinet/in_fib.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
@@ -100,6 +102,7 @@
#ifdef SIFTR_IPV6
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
+#include <netinet6/in6_fib.h>
#include <netinet6/in6_pcb.h>
#endif /* SIFTR_IPV6 */
@@ -136,32 +139,12 @@
/* XXX: Make this a sysctl tunable. */
#define SIFTR_ALQ_BUFLEN (1000*MAX_LOG_MSG_LEN)
-/*
- * 1 byte for IP version
- * IPv4: src/dst IP (4+4) + src/dst port (2+2) = 12 bytes
- * IPv6: src/dst IP (16+16) + src/dst port (2+2) = 36 bytes
- */
-#ifdef SIFTR_IPV6
-#define FLOW_KEY_LEN 37
-#else
-#define FLOW_KEY_LEN 13
-#endif
-
#ifdef SIFTR_IPV6
#define SIFTR_IPMODE 6
#else
#define SIFTR_IPMODE 4
#endif
-/* useful macros */
-#define UPPER_SHORT(X) (((X) & 0xFFFF0000) >> 16)
-#define LOWER_SHORT(X) ((X) & 0x0000FFFF)
-
-#define FIRST_OCTET(X) (((X) & 0xFF000000) >> 24)
-#define SECOND_OCTET(X) (((X) & 0x00FF0000) >> 16)
-#define THIRD_OCTET(X) (((X) & 0x0000FF00) >> 8)
-#define FOURTH_OCTET(X) ((X) & 0x000000FF)
-
static MALLOC_DEFINE(M_SIFTR, "siftr", "dynamic memory used by SIFTR");
static MALLOC_DEFINE(M_SIFTR_PKTNODE, "siftr_pktnode",
"SIFTR pkt_node struct");
@@ -177,20 +160,6 @@
DIR_IN = 0,
DIR_OUT = 1,
} direction;
- /* IP version pkt_node relates to; either INP_IPV4 or INP_IPV6. */
- uint8_t ipver;
- /* Local/foreign IP address. */
-#ifdef SIFTR_IPV6
- uint32_t ip_laddr[4];
- uint32_t ip_faddr[4];
-#else
- uint8_t ip_laddr[4];
- uint8_t ip_faddr[4];
-#endif
- /* Local TCP port. */
- uint16_t tcp_localport;
- /* Foreign TCP port. */
- uint16_t tcp_foreignport;
/* Congestion Window (bytes). */
uint32_t snd_cwnd;
/* Sending Window (bytes). */
@@ -237,10 +206,25 @@
STAILQ_ENTRY(pkt_node) nodes;
};
+struct flow_info
+{
+#ifdef SIFTR_IPV6
+ char laddr[INET6_ADDRSTRLEN]; /* local IP address */
+ char faddr[INET6_ADDRSTRLEN]; /* foreign IP address */
+#else
+ char laddr[INET_ADDRSTRLEN]; /* local IP address */
+ char faddr[INET_ADDRSTRLEN]; /* foreign IP address */
+#endif
+ uint16_t lport; /* local TCP port */
+ uint16_t fport; /* foreign TCP port */
+ uint8_t ipver; /* IP version */
+ uint32_t key; /* flowid of the connection */
+};
+
struct flow_hash_node
{
uint16_t counter;
- uint8_t key[FLOW_KEY_LEN];
+ struct flow_info const_info; /* constant connection info */
LIST_ENTRY(flow_hash_node) nodes;
};
@@ -319,42 +303,10 @@
/* Begin functions. */
-static void
-siftr_process_pkt(struct pkt_node * pkt_node)
+static inline struct flow_hash_node *
+siftr_find_flow(struct listhead *counter_list, uint32_t id)
{
struct flow_hash_node *hash_node;
- struct listhead *counter_list;
- struct siftr_stats *ss;
- struct ale *log_buf;
- uint8_t key[FLOW_KEY_LEN];
- uint8_t found_match, key_offset;
-
- hash_node = NULL;
- ss = DPCPU_PTR(ss);
- found_match = 0;
- key_offset = 1;
-
- /*
- * Create the key that will be used to create a hash index
- * into our hash table. Our key consists of:
- * ipversion, localip, localport, foreignip, foreignport
- */
- key[0] = pkt_node->ipver;
- memcpy(key + key_offset, &pkt_node->ip_laddr,
- sizeof(pkt_node->ip_laddr));
- key_offset += sizeof(pkt_node->ip_laddr);
- memcpy(key + key_offset, &pkt_node->tcp_localport,
- sizeof(pkt_node->tcp_localport));
- key_offset += sizeof(pkt_node->tcp_localport);
- memcpy(key + key_offset, &pkt_node->ip_faddr,
- sizeof(pkt_node->ip_faddr));
- key_offset += sizeof(pkt_node->ip_faddr);
- memcpy(key + key_offset, &pkt_node->tcp_foreignport,
- sizeof(pkt_node->tcp_foreignport));
-
- counter_list = counter_hash +
- (hash32_buf(key, sizeof(key), 0) & siftr_hashmask);
-
/*
* If the list is not empty i.e. the hash index has
* been used by another flow previously.
@@ -362,9 +314,7 @@
if (LIST_FIRST(counter_list) != NULL) {
/*
* Loop through the hash nodes in the list.
- * There should normally only be 1 hash node in the list,
- * except if there have been collisions at the hash index
- * computed by hash32_buf().
+ * There should normally only be 1 hash node in the list.
*/
LIST_FOREACH(hash_node, counter_list, nodes) {
/*
@@ -375,50 +325,60 @@
* hash node that stores the counter for the flow
* the pkt belongs to.
*/
- if (memcmp(hash_node->key, key, sizeof(key)) == 0) {
- found_match = 1;
- break;
+ if (hash_node->const_info.key == id) {
+ return hash_node;
}
}
}
- /* If this flow hash hasn't been seen before or we have a collision. */
- if (hash_node == NULL || !found_match) {
- /* Create a new hash node to store the flow's counter. */
- hash_node = malloc(sizeof(struct flow_hash_node),
- M_SIFTR_HASHNODE, M_WAITOK);
-
- if (hash_node != NULL) {
- /* Initialise our new hash node list entry. */
- hash_node->counter = 0;
- memcpy(hash_node->key, key, sizeof(key));
- LIST_INSERT_HEAD(counter_list, hash_node, nodes);
- } else {
- /* Malloc failed. */
- if (pkt_node->direction == DIR_IN)
- ss->nskip_in_malloc++;
- else
- ss->nskip_out_malloc++;
+ return NULL;
+}
- return;
- }
- } else if (siftr_pkts_per_log > 1) {
- /*
- * Taking the remainder of the counter divided
- * by the current value of siftr_pkts_per_log
- * and storing that in counter provides a neat
- * way to modulate the frequency of log
- * messages being written to the log file.
- */
- hash_node->counter = (hash_node->counter + 1) %
- siftr_pkts_per_log;
+static inline struct flow_hash_node *
+siftr_new_hash_node(struct flow_info info, int dir,
+ struct siftr_stats *ss)
+{
+ struct flow_hash_node *hash_node;
+ struct listhead *counter_list;
- /*
- * If we have not seen enough packets since the last time
- * we wrote a log message for this connection, return.
- */
- if (hash_node->counter > 0)
- return;
+ counter_list = counter_hash + (info.key & siftr_hashmask);
+ /* Create a new hash node to store the flow's constant info. */
+ hash_node = malloc(sizeof(struct flow_hash_node), M_SIFTR_HASHNODE,
+ M_NOWAIT|M_ZERO);
+
+ if (hash_node != NULL) {
+ /* Initialise our new hash node list entry. */
+ hash_node->counter = 0;
+ hash_node->const_info = info;
+ LIST_INSERT_HEAD(counter_list, hash_node, nodes);
+ return hash_node;
+ } else {
+ /* malloc failed */
+ if (dir == DIR_IN)
+ ss->nskip_in_malloc++;
+ else
+ ss->nskip_out_malloc++;
+
+ return NULL;
+ }
+}
+
+static void
+siftr_process_pkt(struct pkt_node * pkt_node)
+{
+ struct flow_hash_node *hash_node;
+ struct listhead *counter_list;
+ struct ale *log_buf;
+
+ if (pkt_node->flowid == 0) {
+ panic("%s: flowid not available", __func__);
+ }
+
+ counter_list = counter_hash + (pkt_node->flowid & siftr_hashmask);
+ hash_node = siftr_find_flow(counter_list, pkt_node->flowid);
+
+ if (hash_node == NULL) {
+ return;
}
log_buf = alq_getn(siftr_alq, MAX_LOG_MSG_LEN, ALQ_WAITOK);
@@ -426,119 +386,38 @@
if (log_buf == NULL)
return; /* Should only happen if the ALQ is shutting down. */
-#ifdef SIFTR_IPV6
- pkt_node->ip_laddr[3] = ntohl(pkt_node->ip_laddr[3]);
- pkt_node->ip_faddr[3] = ntohl(pkt_node->ip_faddr[3]);
-
- if (pkt_node->ipver == INP_IPV6) { /* IPv6 packet */
- pkt_node->ip_laddr[0] = ntohl(pkt_node->ip_laddr[0]);
- pkt_node->ip_laddr[1] = ntohl(pkt_node->ip_laddr[1]);
- pkt_node->ip_laddr[2] = ntohl(pkt_node->ip_laddr[2]);
- pkt_node->ip_faddr[0] = ntohl(pkt_node->ip_faddr[0]);
- pkt_node->ip_faddr[1] = ntohl(pkt_node->ip_faddr[1]);
- pkt_node->ip_faddr[2] = ntohl(pkt_node->ip_faddr[2]);
-
- /* Construct an IPv6 log message. */
- log_buf->ae_bytesused = snprintf(log_buf->ae_data,
- MAX_LOG_MSG_LEN,
- "%c,%zd.%06ld,%x:%x:%x:%x:%x:%x:%x:%x,%u,%x:%x:%x:"
- "%x:%x:%x:%x:%x,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,"
- "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
- direction[pkt_node->direction],
- pkt_node->tval.tv_sec,
- pkt_node->tval.tv_usec,
- UPPER_SHORT(pkt_node->ip_laddr[0]),
- LOWER_SHORT(pkt_node->ip_laddr[0]),
- UPPER_SHORT(pkt_node->ip_laddr[1]),
- LOWER_SHORT(pkt_node->ip_laddr[1]),
- UPPER_SHORT(pkt_node->ip_laddr[2]),
- LOWER_SHORT(pkt_node->ip_laddr[2]),
- UPPER_SHORT(pkt_node->ip_laddr[3]),
- LOWER_SHORT(pkt_node->ip_laddr[3]),
- ntohs(pkt_node->tcp_localport),
- UPPER_SHORT(pkt_node->ip_faddr[0]),
- LOWER_SHORT(pkt_node->ip_faddr[0]),
- UPPER_SHORT(pkt_node->ip_faddr[1]),
- LOWER_SHORT(pkt_node->ip_faddr[1]),
- UPPER_SHORT(pkt_node->ip_faddr[2]),
- LOWER_SHORT(pkt_node->ip_faddr[2]),
- UPPER_SHORT(pkt_node->ip_faddr[3]),
- LOWER_SHORT(pkt_node->ip_faddr[3]),
- ntohs(pkt_node->tcp_foreignport),
- pkt_node->snd_ssthresh,
- pkt_node->snd_cwnd,
- pkt_node->t_flags2,
- pkt_node->snd_wnd,
- pkt_node->rcv_wnd,
- pkt_node->snd_scale,
- pkt_node->rcv_scale,
- pkt_node->conn_state,
- pkt_node->max_seg_size,
- pkt_node->srtt,
- pkt_node->sack_enabled,
- pkt_node->flags,
- pkt_node->rto,
- pkt_node->snd_buf_hiwater,
- pkt_node->snd_buf_cc,
- pkt_node->rcv_buf_hiwater,
- pkt_node->rcv_buf_cc,
- pkt_node->sent_inflight_bytes,
- pkt_node->t_segqlen,
- pkt_node->flowid,
- pkt_node->flowtype);
- } else { /* IPv4 packet */
- pkt_node->ip_laddr[0] = FIRST_OCTET(pkt_node->ip_laddr[3]);
- pkt_node->ip_laddr[1] = SECOND_OCTET(pkt_node->ip_laddr[3]);
- pkt_node->ip_laddr[2] = THIRD_OCTET(pkt_node->ip_laddr[3]);
- pkt_node->ip_laddr[3] = FOURTH_OCTET(pkt_node->ip_laddr[3]);
- pkt_node->ip_faddr[0] = FIRST_OCTET(pkt_node->ip_faddr[3]);
- pkt_node->ip_faddr[1] = SECOND_OCTET(pkt_node->ip_faddr[3]);
- pkt_node->ip_faddr[2] = THIRD_OCTET(pkt_node->ip_faddr[3]);
- pkt_node->ip_faddr[3] = FOURTH_OCTET(pkt_node->ip_faddr[3]);
-#endif /* SIFTR_IPV6 */
-
- /* Construct an IPv4 log message. */
- log_buf->ae_bytesused = snprintf(log_buf->ae_data,
- MAX_LOG_MSG_LEN,
- "%c,%jd.%06ld,%u.%u.%u.%u,%u,%u.%u.%u.%u,%u,%u,%u,"
- "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
- direction[pkt_node->direction],
- (intmax_t)pkt_node->tval.tv_sec,
- pkt_node->tval.tv_usec,
- pkt_node->ip_laddr[0],
- pkt_node->ip_laddr[1],
- pkt_node->ip_laddr[2],
- pkt_node->ip_laddr[3],
- ntohs(pkt_node->tcp_localport),
- pkt_node->ip_faddr[0],
- pkt_node->ip_faddr[1],
- pkt_node->ip_faddr[2],
- pkt_node->ip_faddr[3],
- ntohs(pkt_node->tcp_foreignport),
- pkt_node->snd_ssthresh,
- pkt_node->snd_cwnd,
- pkt_node->t_flags2,
- pkt_node->snd_wnd,
- pkt_node->rcv_wnd,
- pkt_node->snd_scale,
- pkt_node->rcv_scale,
- pkt_node->conn_state,
- pkt_node->max_seg_size,
- pkt_node->srtt,
- pkt_node->sack_enabled,
- pkt_node->flags,
- pkt_node->rto,
- pkt_node->snd_buf_hiwater,
- pkt_node->snd_buf_cc,
- pkt_node->rcv_buf_hiwater,
- pkt_node->rcv_buf_cc,
- pkt_node->sent_inflight_bytes,
- pkt_node->t_segqlen,
- pkt_node->flowid,
- pkt_node->flowtype);
-#ifdef SIFTR_IPV6
- }
-#endif
+ /* Construct a log message. */
+ log_buf->ae_bytesused = snprintf(log_buf->ae_data, MAX_LOG_MSG_LEN,
+ "%c,%zd.%06ld,%s,%hu,%s,%hu,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,"
+ "%u,%u,%u,%u,%u,%u,%u,%u\n",
+ direction[pkt_node->direction],
+ pkt_node->tval.tv_sec,
+ pkt_node->tval.tv_usec,
+ hash_node->const_info.laddr,
+ hash_node->const_info.lport,
+ hash_node->const_info.faddr,
+ hash_node->const_info.fport,
+ pkt_node->snd_ssthresh,
+ pkt_node->snd_cwnd,
+ pkt_node->t_flags2,
+ pkt_node->snd_wnd,
+ pkt_node->rcv_wnd,
+ pkt_node->snd_scale,
+ pkt_node->rcv_scale,
+ pkt_node->conn_state,
+ pkt_node->max_seg_size,
+ pkt_node->srtt,
+ pkt_node->sack_enabled,
+ pkt_node->flags,
+ pkt_node->rto,
+ pkt_node->snd_buf_hiwater,
+ pkt_node->snd_buf_cc,
+ pkt_node->rcv_buf_hiwater,
+ pkt_node->rcv_buf_cc,
+ pkt_node->sent_inflight_bytes,
+ pkt_node->t_segqlen,
+ pkt_node->flowid,
+ pkt_node->flowtype);
alq_post_flags(siftr_alq, log_buf, 0);
}
@@ -708,32 +587,38 @@
return (inp);
}
-static inline void
-siftr_siftdata(struct pkt_node *pn, struct inpcb *inp, struct tcpcb *tp,
- int ipver, int dir, int inp_locally_locked)
+static inline uint32_t
+siftr_get_flowid(struct inpcb *inp, int ipver, uint32_t *phashtype)
{
+ if (inp->inp_flowid == 0) {
#ifdef SIFTR_IPV6
- if (ipver == INP_IPV4) {
- pn->ip_laddr[3] = inp->inp_laddr.s_addr;
- pn->ip_faddr[3] = inp->inp_faddr.s_addr;
-#else
- *((uint32_t *)pn->ip_laddr) = inp->inp_laddr.s_addr;
- *((uint32_t *)pn->ip_faddr) = inp->inp_faddr.s_addr;
+ if (ipver == INP_IPV6) {
+ return fib6_calc_packet_hash(&inp->in6p_laddr,
+ &inp->in6p_faddr,
+ inp->inp_lport,
+ inp->inp_fport,
+ IPPROTO_TCP,
+ phashtype);
+ } else
#endif
-#ifdef SIFTR_IPV6
+ {
+ return fib4_calc_packet_hash(inp->inp_laddr,
+ inp->inp_faddr,
+ inp->inp_lport,
+ inp->inp_fport,
+ IPPROTO_TCP,
+ phashtype);
+ }
} else {
- pn->ip_laddr[0] = inp->in6p_laddr.s6_addr32[0];
- pn->ip_laddr[1] = inp->in6p_laddr.s6_addr32[1];
- pn->ip_laddr[2] = inp->in6p_laddr.s6_addr32[2];
- pn->ip_laddr[3] = inp->in6p_laddr.s6_addr32[3];
- pn->ip_faddr[0] = inp->in6p_faddr.s6_addr32[0];
- pn->ip_faddr[1] = inp->in6p_faddr.s6_addr32[1];
- pn->ip_faddr[2] = inp->in6p_faddr.s6_addr32[2];
- pn->ip_faddr[3] = inp->in6p_faddr.s6_addr32[3];
+ *phashtype = inp->inp_flowtype;
+ return inp->inp_flowid;
}
-#endif
- pn->tcp_localport = inp->inp_lport;
- pn->tcp_foreignport = inp->inp_fport;
+}
+
+static inline void
+siftr_siftdata(struct pkt_node *pn, struct inpcb *inp, struct tcpcb *tp,
+ int ipver, int dir, int inp_locally_locked)
+{
pn->snd_cwnd = tp->snd_cwnd;
pn->snd_wnd = tp->snd_wnd;
pn->rcv_wnd = tp->rcv_wnd;
@@ -743,7 +628,7 @@
pn->rcv_scale = tp->rcv_scale;
pn->conn_state = tp->t_state;
pn->max_seg_size = tp->t_maxseg;
- pn->srtt = ((u_int64_t)tp->t_srtt * tick) >> TCP_RTT_SHIFT;
+ pn->srtt = ((uint64_t)tp->t_srtt * tick) >> TCP_RTT_SHIFT;
pn->sack_enabled = (tp->t_flags & TF_SACK_PERMIT) != 0;
pn->flags = tp->t_flags;
pn->rto = tp->t_rxtcur * tick;
@@ -753,14 +638,11 @@
pn->rcv_buf_cc = sbused(&inp->inp_socket->so_rcv);
pn->sent_inflight_bytes = tp->snd_max - tp->snd_una;
pn->t_segqlen = tp->t_segqlen;
- pn->flowid = inp->inp_flowid;
- pn->flowtype = inp->inp_flowtype;
/* We've finished accessing the tcb so release the lock. */
if (inp_locally_locked)
INP_RUNLOCK(inp);
- pn->ipver = ipver;
pn->direction = (dir == PFIL_IN ? DIR_IN : DIR_OUT);
/*
@@ -770,7 +652,6 @@
*/
microtime(&pn->tval);
TCP_PROBE1(siftr, &pn);
-
}
/*
@@ -792,6 +673,9 @@
struct siftr_stats *ss;
unsigned int ip_hl;
int inp_locally_locked, dir;
+ uint32_t hash_id, hash_type;
+ struct listhead *counter_list;
+ struct flow_hash_node *hash_node;
inp_locally_locked = 0;
dir = PFIL_DIR(flags);
@@ -861,9 +745,11 @@
/*
* If we can't find the TCP control block (happens occasionaly for a
- * packet sent during the shutdown phase of a TCP connection), bail
+ * packet sent during the shutdown phase of a TCP connection), or the
+ * TCP control block has not initialized (happens during TCPS_SYN_SENT),
+ * bail.
*/
- if (tp == NULL) {
+ if (tp == NULL || tp->t_state < TCPS_ESTABLISHED) {
if (dir == PFIL_IN)
ss->nskip_in_tcpcb++;
else
@@ -872,6 +758,27 @@
goto inp_unlock;
}
+ hash_id = siftr_get_flowid(inp, INP_IPV4, &hash_type);
+ counter_list = counter_hash + (hash_id & siftr_hashmask);
+ hash_node = siftr_find_flow(counter_list, hash_id);
+
+ /* If this flow hasn't been seen before, we create a new entry. */
+ if (hash_node == NULL) {
+ struct flow_info info;
+
+ inet_ntoa_r(inp->inp_laddr, info.laddr);
+ inet_ntoa_r(inp->inp_faddr, info.faddr);
+ info.lport = ntohs(inp->inp_lport);
+ info.fport = ntohs(inp->inp_fport);
+ info.key = hash_id;
+ info.ipver = INP_IPV4;
+
+ hash_node = siftr_new_hash_node(info, dir, ss);
+ }
+
+ if (hash_node == NULL) {
+ goto inp_unlock;
+ }
pn = malloc(sizeof(struct pkt_node), M_SIFTR_PKTNODE, M_NOWAIT|M_ZERO);
@@ -884,6 +791,9 @@
goto inp_unlock;
}
+ pn->flowid = hash_id;
+ pn->flowtype = hash_type;
+
siftr_siftdata(pn, inp, tp, INP_IPV4, dir, inp_locally_locked);
mtx_lock(&siftr_pkt_queue_mtx);
@@ -911,6 +821,9 @@
struct siftr_stats *ss;
unsigned int ip6_hl;
int inp_locally_locked, dir;
+ uint32_t hash_id, hash_type;
+ struct listhead *counter_list;
+ struct flow_hash_node *hash_node;
inp_locally_locked = 0;
dir = PFIL_DIR(flags);
@@ -982,9 +895,11 @@
/*
* If we can't find the TCP control block (happens occasionaly for a
- * packet sent during the shutdown phase of a TCP connection), bail
+ * packet sent during the shutdown phase of a TCP connection), or the
+ * TCP control block has not initialized (happens during TCPS_SYN_SENT),
+ * bail.
*/
- if (tp == NULL) {
+ if (tp == NULL || tp->t_state < TCPS_ESTABLISHED) {
if (dir == PFIL_IN)
ss->nskip_in_tcpcb++;
else
@@ -993,6 +908,27 @@
goto inp_unlock6;
}
+ hash_id = siftr_get_flowid(inp, INP_IPV6, &hash_type);
+ counter_list = counter_hash + (hash_id & siftr_hashmask);
+ hash_node = siftr_find_flow(counter_list, hash_id);
+
+ /* If this flow hasn't been seen before, we create a new entry. */
+ if (!hash_node) {
+ struct flow_info info;
+
+ ip6_sprintf(info.laddr, &inp->in6p_laddr);
+ ip6_sprintf(info.faddr, &inp->in6p_faddr);
+ info.lport = ntohs(inp->inp_lport);
+ info.fport = ntohs(inp->inp_fport);
+ info.key = hash_id;
+ info.ipver = INP_IPV6;
+
+ hash_node = siftr_new_hash_node(info, dir, ss);
+ }
+
+ if (!hash_node) {
+ goto inp_unlock6;
+ }
pn = malloc(sizeof(struct pkt_node), M_SIFTR_PKTNODE, M_NOWAIT|M_ZERO);
@@ -1005,6 +941,9 @@
goto inp_unlock6;
}
+ pn->flowid = hash_id;
+ pn->flowtype = hash_type;
+
siftr_siftdata(pn, inp, tp, INP_IPV6, dir, inp_locally_locked);
/* XXX: Figure out how to generate hashes for IPv6 packets. */
@@ -1122,18 +1061,8 @@
struct timeval tval;
struct flow_hash_node *counter, *tmp_counter;
struct sbuf *s;
- int i, key_index, error;
+ int i, error;
uint32_t bytes_to_write, total_skipped_pkts;
- uint16_t lport, fport;
- uint8_t *key, ipver __unused;
-
-#ifdef SIFTR_IPV6
- uint32_t laddr[4];
- uint32_t faddr[4];
-#else
- uint8_t laddr[4];
- uint8_t faddr[4];
-#endif
error = 0;
total_skipped_pkts = 0;
@@ -1249,77 +1178,11 @@
for (i = 0; i <= siftr_hashmask; i++) {
LIST_FOREACH_SAFE(counter, counter_hash + i, nodes,
tmp_counter) {
- key = counter->key;
- key_index = 1;
-
- ipver = key[0];
-
- memcpy(laddr, key + key_index, sizeof(laddr));
- key_index += sizeof(laddr);
- memcpy(&lport, key + key_index, sizeof(lport));
- key_index += sizeof(lport);
- memcpy(faddr, key + key_index, sizeof(faddr));
- key_index += sizeof(faddr);
- memcpy(&fport, key + key_index, sizeof(fport));
-
-#ifdef SIFTR_IPV6
- laddr[3] = ntohl(laddr[3]);
- faddr[3] = ntohl(faddr[3]);
-
- if (ipver == INP_IPV6) {
- laddr[0] = ntohl(laddr[0]);
- laddr[1] = ntohl(laddr[1]);
- laddr[2] = ntohl(laddr[2]);
- faddr[0] = ntohl(faddr[0]);
- faddr[1] = ntohl(faddr[1]);
- faddr[2] = ntohl(faddr[2]);
-
- sbuf_printf(s,
- "%x:%x:%x:%x:%x:%x:%x:%x;%u-"
- "%x:%x:%x:%x:%x:%x:%x:%x;%u,",
- UPPER_SHORT(laddr[0]),
- LOWER_SHORT(laddr[0]),
- UPPER_SHORT(laddr[1]),
- LOWER_SHORT(laddr[1]),
- UPPER_SHORT(laddr[2]),
- LOWER_SHORT(laddr[2]),
- UPPER_SHORT(laddr[3]),
- LOWER_SHORT(laddr[3]),
- ntohs(lport),
- UPPER_SHORT(faddr[0]),
- LOWER_SHORT(faddr[0]),
- UPPER_SHORT(faddr[1]),
- LOWER_SHORT(faddr[1]),
- UPPER_SHORT(faddr[2]),
- LOWER_SHORT(faddr[2]),
- UPPER_SHORT(faddr[3]),
- LOWER_SHORT(faddr[3]),
- ntohs(fport));
- } else {
- laddr[0] = FIRST_OCTET(laddr[3]);
- laddr[1] = SECOND_OCTET(laddr[3]);
- laddr[2] = THIRD_OCTET(laddr[3]);
- laddr[3] = FOURTH_OCTET(laddr[3]);
- faddr[0] = FIRST_OCTET(faddr[3]);
- faddr[1] = SECOND_OCTET(faddr[3]);
- faddr[2] = THIRD_OCTET(faddr[3]);
- faddr[3] = FOURTH_OCTET(faddr[3]);
-#endif
- sbuf_printf(s,
- "%u.%u.%u.%u;%u-%u.%u.%u.%u;%u,",
- laddr[0],
- laddr[1],
- laddr[2],
- laddr[3],
- ntohs(lport),
- faddr[0],
- faddr[1],
- faddr[2],
- faddr[3],
- ntohs(fport));
-#ifdef SIFTR_IPV6
- }
-#endif
+ sbuf_printf(s, "%s;%hu-%s;%hu,",
+ counter->const_info.laddr,
+ counter->const_info.lport,
+ counter->const_info.faddr,
+ counter->const_info.fport);
free(counter, M_SIFTR_HASHNODE);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 8:28 AM (6 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28475842
Default Alt Text
D40302.id122560.diff (21 KB)
Attached To
Mode
D40302: siftr: three changes that improve performance
Attached
Detach File
Event Timeline
Log In to Comment