From: Justin Pettit Date: Wed, 22 Apr 2009 00:23:37 +0000 (-0700) Subject: Have NetFlow account for first buffered packet of new flow (Bug #1162). X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=43bdbfd1b033189593ef473423c392663f29a61c;p=openvswitch Have NetFlow account for first buffered packet of new flow (Bug #1162). 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. --- diff --git a/lib/flow.c b/lib/flow.c index f2eb3564..156416a1 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -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) { diff --git a/lib/flow.h b/lib/flow.h index 0b65df88..59d6f36e 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -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 *); diff --git a/secchan/ofproto.c b/secchan/ofproto.c index c8a5e8b3..07629a93 100644 --- a/secchan/ofproto.c +++ b/secchan/ofproto.c @@ -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));