From c0562a32e198d66f76f07c73912241b36728d81b Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 9 Mar 2009 14:12:25 -0700 Subject: [PATCH] secchan: Make netflow expiration arguments more sensible. 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 | 37 +++++++++++++++++-------------------- secchan/netflow.h | 6 ++---- secchan/ofproto.c | 21 ++++++++++----------- secchan/ofproto.h | 10 ++++++++++ 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/secchan/netflow.c b/secchan/netflow.c index 4996bcd0..b8e4d437 100644 --- a/secchan/netflow.c +++ b/secchan/netflow.c @@ -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); diff --git a/secchan/netflow.h b/secchan/netflow.h index 6ccca666..a8b7076e 100644 --- a/secchan/netflow.h +++ b/secchan/netflow.h @@ -36,14 +36,12 @@ #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 */ diff --git a/secchan/ofproto.c b/secchan/ofproto.c index 9e32d3df..df5458c9 100644 --- a/secchan/ofproto.c +++ b/secchan/ofproto.c @@ -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); } } diff --git a/secchan/ofproto.h b/secchan/ofproto.h index e3f57683..8a498e2d 100644 --- a/secchan/ofproto.h +++ b/secchan/ofproto.h @@ -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 *); -- 2.30.2