Page MenuHomeFreeBSD

D39848.id121128.diff
No OneTemporary

D39848.id121128.diff

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,17 +139,6 @@
/* 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
@@ -240,7 +232,7 @@
struct flow_hash_node
{
uint16_t counter;
- uint8_t key[FLOW_KEY_LEN];
+ uint32_t key;
LIST_ENTRY(flow_hash_node) nodes;
};
@@ -319,42 +311,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 +322,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,15 +333,34 @@
* 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->key == id) {
+ return hash_node;
}
}
}
+ return NULL;
+}
+
+static void
+siftr_process_pkt(struct pkt_node * pkt_node)
+{
+ struct flow_hash_node *hash_node;
+ struct listhead *counter_list;
+ struct siftr_stats *ss;
+ struct ale *log_buf;
+
+ ss = DPCPU_PTR(ss);
+
+ 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 this flow hash hasn't been seen before or we have a collision. */
- if (hash_node == NULL || !found_match) {
+ if (hash_node == NULL) {
/* Create a new hash node to store the flow's counter. */
hash_node = malloc(sizeof(struct flow_hash_node),
M_SIFTR_HASHNODE, M_WAITOK);
@@ -391,7 +368,7 @@
if (hash_node != NULL) {
/* Initialise our new hash node list entry. */
hash_node->counter = 0;
- memcpy(hash_node->key, key, sizeof(key));
+ hash_node->key = pkt_node->flowid;
LIST_INSERT_HEAD(counter_list, hash_node, nodes);
} else {
/* Malloc failed. */
@@ -708,6 +685,36 @@
return (inp);
}
+static inline uint32_t
+siftr_get_flowid(struct inpcb *inp, int ipver, uint32_t *phashtype)
+{
+ if (!inp->inp_flowid) {
+#ifdef SIFTR_IPV6
+ if (ipver == INP_IPV4) {
+#else
+ return fib4_calc_packet_hash(inp->inp_laddr,
+ inp->inp_faddr,
+ inp->inp_lport,
+ inp->inp_fport,
+ IPPROTO_TCP,
+ phashtype);
+#endif
+#ifdef SIFTR_IPV6
+ } else {
+ return fib6_calc_packet_hash(&inp->in6p_laddr,
+ &inp->in6p_faddr,
+ inp->inp_lport,
+ inp->inp_fport,
+ IPPROTO_TCP,
+ phashtype);
+ }
+#endif
+ } else {
+ *phashtype = inp->inp_flowtype;
+ return inp->inp_flowid;
+ }
+}
+
static inline void
siftr_siftdata(struct pkt_node *pn, struct inpcb *inp, struct tcpcb *tp,
int ipver, int dir, int inp_locally_locked)
@@ -753,8 +760,6 @@
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)
@@ -770,7 +775,6 @@
*/
microtime(&pn->tval);
TCP_PROBE1(siftr, &pn);
-
}
/*
@@ -792,6 +796,7 @@
struct siftr_stats *ss;
unsigned int ip_hl;
int inp_locally_locked, dir;
+ uint32_t hash_id, hash_type;
inp_locally_locked = 0;
dir = PFIL_DIR(flags);
@@ -872,6 +877,7 @@
goto inp_unlock;
}
+ hash_id = siftr_get_flowid(inp, INP_IPV4, &hash_type);
pn = malloc(sizeof(struct pkt_node), M_SIFTR_PKTNODE, M_NOWAIT|M_ZERO);
@@ -884,6 +890,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 +920,7 @@
struct siftr_stats *ss;
unsigned int ip6_hl;
int inp_locally_locked, dir;
+ uint32_t hash_id, hash_type;
inp_locally_locked = 0;
dir = PFIL_DIR(flags);
@@ -993,6 +1003,7 @@
goto inp_unlock6;
}
+ hash_id = siftr_get_flowid(inp, INP_IPV6, &hash_type);
pn = malloc(sizeof(struct pkt_node), M_SIFTR_PKTNODE, M_NOWAIT|M_ZERO);
@@ -1005,6 +1016,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 +1136,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;
@@ -1227,7 +1231,7 @@
"num_outbound_skipped_pkts_tcpcb=%u\t"
"num_inbound_skipped_pkts_inpcb=%u\t"
"num_outbound_skipped_pkts_inpcb=%u\t"
- "total_skipped_tcp_pkts=%u\tflow_list=",
+ "total_skipped_tcp_pkts=%u\tflowid_list=",
(intmax_t)tval.tv_sec,
tval.tv_usec,
(uintmax_t)totalss.n_in,
@@ -1243,84 +1247,13 @@
/*
* Iterate over the flow hash, printing a summary of each
- * flow seen and freeing any malloc'd memory.
+ * flowid seen and freeing any malloc'd memory.
* The hash consists of an array of LISTs (man 3 queue).
*/
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, "%u,", counter->key);
free(counter, M_SIFTR_HASHNODE);
}

File Metadata

Mime Type
text/plain
Expires
Thu, Aug 20, 5:47 PM (10 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37004997
Default Alt Text
D39848.id121128.diff (9 KB)

Event Timeline