Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167186087
D39848.id121128.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D39848.id121128.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D39848: siftr: use inp_flowid or a new packet hash for a flow identification
Attached
Detach File
Event Timeline
Log In to Comment