Have NetFlow account for first buffered packet of new flow (Bug #1162).
authorJustin Pettit <jpettit@nicira.com>
Wed, 22 Apr 2009 00:23:37 +0000 (17:23 -0700)
committerJustin Pettit <jpettit@nicira.com>
Wed, 22 Apr 2009 00:26:07 +0000 (17:26 -0700)
The record-keeping for NetFlow didn't track the buffered packet
associated with a flow add command.  We now pull the relevant data from
the buffered packet and add it to the flow rule stats.

lib/flow.c
lib/flow.h
secchan/ofproto.c

index f2eb356418c7e799b1bc357cc60a2b4d58331a69..156416a171a9d647deae430d27421bb5b14d6c80 100644 (file)
@@ -204,6 +204,28 @@ flow_extract(struct ofpbuf *packet, uint16_t in_port, flow_t *flow)
     return retval;
 }
 
+/* Extracts the flow stats for a packet.  The 'flow' and 'packet'
+ * arguments must have been initialized through a call to flow_extract().
+ */
+void
+flow_extract_stats(const flow_t *flow, struct ofpbuf *packet, 
+        struct odp_flow_stats *stats)
+{
+    memset(stats, '\0', sizeof(*stats));
+
+    if ((flow->dl_type == htons(ETH_TYPE_IP)) && packet->l4) {
+        struct ip_header *ip = packet->l3;
+        stats->ip_tos = ip->ip_tos;
+        if ((flow->nw_proto == IP_TYPE_TCP) && packet->l7) {
+            struct tcp_header *tcp = packet->l4;
+            stats->tcp_flags = TCP_FLAGS(tcp->tcp_ctl);
+        }
+    }
+
+    stats->n_bytes = packet->size;
+    stats->n_packets = 1;
+}
+
 void
 flow_to_match(const flow_t *flow, uint32_t wildcards, struct ofp_match *match)
 {
index 0b65df881446f8dfacd1c539204824ea988ac219..59d6f36e9ec7f9161f2bcfdeedfd7e0ed6a2f49e 100644 (file)
@@ -50,6 +50,8 @@ struct ofpbuf;
 typedef struct odp_flow_key flow_t;
 
 int flow_extract(struct ofpbuf *, uint16_t in_port, flow_t *);
+void flow_extract_stats(const flow_t *flow, struct ofpbuf *packet, 
+        struct odp_flow_stats *stats);
 void flow_to_match(const flow_t *, uint32_t wildcards, struct ofp_match *);
 void flow_from_match(flow_t *, uint32_t *wildcards, const struct ofp_match *);
 char *flow_to_string(const flow_t *);
index c8a5e8b3782653a007148ffd96085e5d4fbd6e01..07629a935cbfd5e974b50f3226879631f7352e44 100644 (file)
@@ -2390,8 +2390,7 @@ update_stats(struct rule *rule, const struct odp_flow_stats *stats)
 
 static int
 send_buffered(struct ofproto *p, struct ofconn *ofconn, uint32_t buffer_id,
-              const struct rule *rule,
-              struct ofpbuf **packetp, int *byte_count)
+              struct rule *rule, struct ofpbuf **packetp)
 {
     struct odp_actions actions;
     struct ofpbuf *packet;
@@ -2421,7 +2420,10 @@ send_buffered(struct ofproto *p, struct ofconn *ofconn, uint32_t buffer_id,
     error = dpif_execute(&p->dpif, in_port,
                          actions.actions, actions.n_actions, packet);
     if (!error) {
-        *byte_count = packet->size;
+        struct odp_flow_stats stats;
+
+        flow_extract_stats(&flow, packet, &stats);
+        update_stats(rule, &stats);
     }
 
     return 0;
@@ -2441,11 +2443,7 @@ add_flow(struct ofproto *p, struct ofconn *ofconn,
     cls_rule_from_match(&rule->cr, &ofm->match, ntohs(ofm->priority));
 
     if (ofm->buffer_id != htonl(UINT32_MAX)) {
-        int byte_count = 0;
-        error = send_buffered(p, ofconn, ntohl(ofm->buffer_id),
-                              rule, &packet, &byte_count);
-        rule->byte_count += byte_count;
-        rule->packet_count += byte_count > 0;
+        error = send_buffered(p, ofconn, ntohl(ofm->buffer_id), rule, &packet);
     }
 
     displaced_rule = rule_from_cls_rule(classifier_insert(&p->cls, &rule->cr));