secchan: Make netflow expiration arguments more sensible.
authorBen Pfaff <blp@nicira.com>
Mon, 9 Mar 2009 21:12:25 +0000 (14:12 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 9 Mar 2009 22:45:14 +0000 (15:45 -0700)
This cleanup is useful preparation for adding a flow expiration hook for
vswitchd to use, since that hook wants to receive essentially the same
information.

secchan/netflow.c
secchan/netflow.h
secchan/ofproto.c
secchan/ofproto.h

index 4996bcd01abc45f56018c7a246ca6afcb7c7447b..b8e4d4379a5b87d1f53f76490c8e484d3d2e332e 100644 (file)
@@ -40,6 +40,7 @@
 #include "cfg.h"
 #include "flow.h"
 #include "netflow.h"
+#include "ofproto.h"
 #include "packets.h"
 #include "socket-util.h"
 #include "svec.h"
@@ -169,14 +170,11 @@ open_collector(char *dst)
 }
 
 void
-netflow_expire(struct netflow *nf, const flow_t *flow,
-               const struct odp_flow_stats *stats,
-               long long int created)
+netflow_expire(struct netflow *nf, const struct ofexpired *expired)
 {
     struct netflow_v5_header nf_hdr;
     struct netflow_v5_record nf_rec;
     struct timeval now;
-    long long int used;
     int i;
 
     time_timeval(&now);
@@ -193,33 +191,32 @@ netflow_expire(struct netflow *nf, const flow_t *flow,
     nf_hdr.sampling_interval = htons(0);
 
     memset(&nf_rec, 0, sizeof nf_rec);
-    nf_rec.src_addr = flow->nw_src;
-    nf_rec.dst_addr = flow->nw_dst;
+    nf_rec.src_addr = expired->flow.nw_src;
+    nf_rec.dst_addr = expired->flow.nw_dst;
     nf_rec.nexthop = htons(0);
-    nf_rec.input = htons(flow->in_port);
+    nf_rec.input = htons(expired->flow.in_port);
     nf_rec.output = htons(0);
-    nf_rec.packet_count = htonl(stats->n_packets);
-    nf_rec.byte_count = htonl(stats->n_bytes);
-    nf_rec.init_time = htonl(created - nf->boot_time);
-    used = stats->used_sec * 1000 + stats->used_nsec / 1000000;
-    nf_rec.used_time = htonl((used > created ? used : created)
+    nf_rec.packet_count = htonl(expired->packet_count);
+    nf_rec.byte_count = htonl(expired->byte_count);
+    nf_rec.init_time = htonl(expired->created - nf->boot_time);
+    nf_rec.used_time = htonl(MAX(expired->created, expired->used)
                              - nf->boot_time);
 
-    if (flow->nw_proto == IP_TYPE_ICMP) {
+    if (expired->flow.nw_proto == IP_TYPE_ICMP) {
         /* In NetFlow, the ICMP type and code are concatenated and
          * placed in the 'dst_port' field. */
-        uint8_t type = ntohs(flow->tp_src);
-        uint8_t code = ntohs(flow->tp_dst);
+        uint8_t type = ntohs(expired->flow.tp_src);
+        uint8_t code = ntohs(expired->flow.tp_dst);
         nf_rec.src_port = htons(0);
         nf_rec.dst_port = htons((type << 8) | code);
     } else {
-        nf_rec.src_port = flow->tp_src;
-        nf_rec.dst_port = flow->tp_dst;
+        nf_rec.src_port = expired->flow.tp_src;
+        nf_rec.dst_port = expired->flow.tp_dst;
     }
 
-    nf_rec.tcp_flags = stats->tcp_flags;
-    nf_rec.ip_proto = flow->nw_proto;
-    nf_rec.ip_tos = stats->ip_tos;
+    nf_rec.tcp_flags = expired->tcp_flags;
+    nf_rec.ip_proto = expired->flow.nw_proto;
+    nf_rec.ip_tos = expired->ip_tos;
 
     nf_rec.src_as = htons(0);
     nf_rec.dst_as = htons(0);
index 6ccca66614975512187eb4408400d3ec0f730a33..a8b7076e2afc846f189b0effb05bf39cb28da62c 100644 (file)
 
 #include "flow.h"
 
-struct odp_flow_stats;
+struct ofexpired;
 struct svec;
 
 struct netflow *netflow_create(void);
 void netflow_destroy(struct netflow *);
 int netflow_set_collectors(struct netflow *, const struct svec *collectors);
-void netflow_expire(struct netflow *, const flow_t *,
-                    const struct odp_flow_stats *,
-                    long long int created);
+void netflow_expire(struct netflow *, const struct ofexpired *);
 
 #endif /* netflow.h */
index 9e32d3df3bb3162cc7b13c56edd5fd8749de6e98..df5458c967f24384c7ba21a8ae1e17ba9ace9671 100644 (file)
@@ -2579,17 +2579,16 @@ send_flow_exp(struct ofproto *p, struct rule *rule,
         queue_tx(buf, prev);
     }
 
-    if (p->netflow && !rule->cr.wc.wildcards) {
-        /* XXX this interface isn't so great */
-        struct odp_flow_stats stats;
-        stats.n_packets = rule->packet_count;
-        stats.n_bytes = rule->byte_count;
-        stats.used_sec = rule->used / 1000;
-        stats.used_nsec = rule->used % 1000 * 1000000;
-        stats.tcp_flags = rule->tcp_flags;
-        stats.ip_tos = rule->ip_tos;
-        stats.reserved = 0;
-        netflow_expire(p->netflow, &rule->cr.flow, &stats, rule->created);
+    if (!rule->cr.wc.wildcards && p->netflow) {
+        struct ofexpired expired;
+        expired.flow = rule->cr.flow;
+        expired.packet_count = rule->packet_count;
+        expired.byte_count = rule->byte_count;
+        expired.used = rule->used;
+        expired.created = rule->created;
+        expired.tcp_flags = rule->tcp_flags;
+        expired.ip_tos = rule->ip_tos;
+        netflow_expire(p->netflow, &expired);
     }
 }
 
index e3f5768331ec0690b13430c7a9253f8105e9d1f2..8a498e2d92d767da8fee311ad3b4469fb73531b5 100644 (file)
@@ -43,6 +43,16 @@ struct odp_actions;
 struct ofproto;
 struct svec;
 
+struct ofexpired {
+    flow_t flow;
+    uint64_t packet_count;      /* Packets from *expired* subrules. */
+    uint64_t byte_count;        /* Bytes from *expired* subrules. */
+    long long int used;         /* Last-used time (0 if never used). */
+    long long int created;      /* Creation time. */
+    uint8_t tcp_flags;          /* Bitwise-OR of all TCP flags seen. */
+    uint8_t ip_tos;             /* Last-seen IP type-of-service. */
+};
+
 int ofproto_create(const char *datapath, struct ofproto **ofprotop);
 void ofproto_destroy(struct ofproto *);
 int ofproto_run(struct ofproto *);