Change the flow_extract() API to accept struct pkt_metadta, instead of individual metadata fields. It will make the API more logical and easier to maintain when we need to expand metadata down the road.
Signed-off-by: Andy Zhou <az...@nicira.com> --- lib/dpif-netdev.c | 6 ++---- lib/flow.c | 20 ++++++++------------ lib/flow.h | 4 ++-- lib/learning-switch.c | 4 +++- lib/ofp-print.c | 4 +++- lib/packets.c | 28 ++++++++++++++++++++++++++++ lib/packets.h | 7 +++++++ ofproto/ofproto-dpif-upcall.c | 5 +++-- ofproto/ofproto-dpif-xlate.c | 5 ++++- ofproto/ofproto-dpif.c | 7 +++++-- ofproto/ofproto.c | 8 ++++++-- tests/test-flows.c | 4 +++- utilities/ovs-ofctl.c | 6 ++++-- 13 files changed, 78 insertions(+), 30 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index c4ba646..6b07817 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1419,8 +1419,7 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) } /* Extract flow key. */ - flow_extract(execute->packet, md->skb_priority, md->pkt_mark, &md->tunnel, - (union flow_in_port *)&md->in_port, &key); + flow_extract(execute->packet, md, &key); ovs_rwlock_rdlock(&dp->port_rwlock); dp_netdev_execute_actions(dp, &key, execute->packet, md, execute->actions, @@ -1693,8 +1692,7 @@ dp_netdev_port_input(struct dp_netdev *dp, struct ofpbuf *packet, if (packet->size < ETH_HEADER_LEN) { return; } - flow_extract(packet, md->skb_priority, md->pkt_mark, &md->tunnel, - (union flow_in_port *)&md->in_port, &key); + flow_extract(packet, md, &key); netdev_flow = dp_netdev_lookup_flow(dp, &key); if (netdev_flow) { struct dp_netdev_actions *actions; diff --git a/lib/flow.c b/lib/flow.c index e7fe4d3..3fa61a8 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -35,6 +35,7 @@ #include "ofpbuf.h" #include "openflow/openflow.h" #include "packets.h" +#include "odp-util.h" #include "random.h" #include "unaligned.h" @@ -361,8 +362,7 @@ invalid: } -/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and - * 'in_port'. +/* Initializes 'flow' members from 'packet' and 'md' * * Initializes 'packet' header pointers as follows: * @@ -381,8 +381,7 @@ invalid: * present and has a correct length, and otherwise NULL. */ void -flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark, - const struct flow_tnl *tnl, const union flow_in_port *in_port, +flow_extract(struct ofpbuf *packet, const struct pkt_metadata *md, struct flow *flow) { struct ofpbuf b = *packet; @@ -392,15 +391,12 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark, memset(flow, 0, sizeof *flow); - if (tnl) { - ovs_assert(tnl != &flow->tunnel); - flow->tunnel = *tnl; + flow->tunnel = md->tunnel; + if (md->in_port != ODPP_NONE) { + flow->in_port.odp_port = md->in_port; } - if (in_port) { - flow->in_port = *in_port; - } - flow->skb_priority = skb_priority; - flow->pkt_mark = pkt_mark; + flow->skb_priority = md->skb_priority; + flow->pkt_mark = md->pkt_mark; packet->l2 = b.data; packet->l2_5 = NULL; diff --git a/lib/flow.h b/lib/flow.h index 3109a84..1e8d137 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -32,6 +32,7 @@ struct ds; struct flow_wildcards; struct minimask; struct ofpbuf; +struct pkt_metadata; /* This sequence number should be incremented whenever anything involving flows * or the wildcarding of flows changes. This will cause build assertion @@ -173,8 +174,7 @@ struct flow_metadata { ofp_port_t in_port; /* OpenFlow port or zero. */ }; -void flow_extract(struct ofpbuf *, uint32_t priority, uint32_t mark, - const struct flow_tnl *, const union flow_in_port *in_port, +void flow_extract(struct ofpbuf *, const struct pkt_metadata *md, struct flow *); void flow_zero_wildcards(struct flow *, const struct flow_wildcards *); diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 8efbce1..ef2976f 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -547,6 +547,7 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) struct ofputil_packet_in pi; uint32_t queue_id; ofp_port_t out_port; + struct pkt_metadata md; uint64_t ofpacts_stub[64 / 8]; struct ofpbuf ofpacts; @@ -575,7 +576,8 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) /* Extract flow data from 'opi' into 'flow'. */ ofpbuf_use_const(&pkt, pi.packet, pi.packet_len); in_port_.ofp_port = pi.fmd.in_port; - flow_extract(&pkt, 0, 0, NULL, &in_port_, &flow); + pkt_metadata_init(&md, &in_port_); + flow_extract(&pkt, &md, &flow); flow.tunnel.tun_id = pi.fmd.tun_id; /* Choose output port. */ diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 4c89b36..06e64f6 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -46,6 +46,7 @@ #include "packets.h" #include "type-props.h" #include "unaligned.h" +#include "odp-util.h" #include "util.h" static void ofp_print_queue_name(struct ds *string, uint32_t port); @@ -58,11 +59,12 @@ char * ofp_packet_to_string(const void *data, size_t len) { struct ds ds = DS_EMPTY_INITIALIZER; + const struct pkt_metadata md = PKT_METADATA_INITIALIZER(ODPP_NONE); struct ofpbuf buf; struct flow flow; ofpbuf_use_const(&buf, data, len); - flow_extract(&buf, 0, 0, NULL, NULL, &flow); + flow_extract(&buf, &md, &flow); flow_format(&ds, &flow); if (buf.l7) { diff --git a/lib/packets.c b/lib/packets.c index 7238f42..0286954 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -29,6 +29,7 @@ #include "dynamic-string.h" #include "ofpbuf.h" #include "ovs-thread.h" +#include "odp-util.h" #include "unaligned.h" const struct in6_addr in6addr_exact = IN6ADDR_EXACT_INIT; @@ -991,3 +992,30 @@ packet_format_tcp_flags(struct ds *s, uint16_t tcp_flags) ds_put_cstr(s, "[800]"); } } + +void pkt_metadata_init(struct pkt_metadata *md, + const union flow_in_port* in_port) +{ + pkt_metadata_init_full(md, NULL, 0, 0, in_port); +} + +void pkt_metadata_init_full(struct pkt_metadata *md, const struct flow_tnl *tnl, + const uint32_t skb_priority, + const uint32_t pkt_mark, + const union flow_in_port *in_port) +{ + + tnl ? memcpy(&md->tunnel, tnl, sizeof(md->tunnel)) + : memset(&md->tunnel, 0, sizeof(md->tunnel)); + + md->skb_priority = skb_priority; + md->pkt_mark = pkt_mark; + md->in_port = in_port ? in_port->odp_port : ODPP_NONE; +} + +void pkt_metadata_from_flow(struct pkt_metadata *md, const struct flow *flow) +{ + + pkt_metadata_init_full(md, &flow->tunnel, flow->skb_priority, + flow->pkt_mark, &flow->in_port); +} diff --git a/lib/packets.h b/lib/packets.h index 1855a1c..5e1d52d 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -42,6 +42,13 @@ struct pkt_metadata { #define PKT_METADATA_INITIALIZER(PORT) \ (struct pkt_metadata){ { 0, 0, 0, 0, 0, 0}, 0, 0, (PORT) } +void pkt_metadata_init(struct pkt_metadata *md, const union flow_in_port *in_port); +void pkt_metadata_init_full(struct pkt_metadata *md, const struct flow_tnl *tnl, + const uint32_t skb_priority, + const uint32_t pkt_mark, + const union flow_in_port *in_port); +void pkt_metadata_from_flow(struct pkt_metadata *md, const struct flow *flow); + bool dpid_from_string(const char *s, uint64_t *dpidp); #define ETH_ADDR_LEN 6 diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index e4f81a1..6cc0b67 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -983,9 +983,10 @@ handle_upcalls(struct handler *handler, struct list *upcalls) type = classify_upcall(upcall); if (type == MISS_UPCALL) { uint32_t hash; + struct pkt_metadata md; - flow_extract(packet, flow.skb_priority, flow.pkt_mark, - &flow.tunnel, &flow.in_port, &miss->flow); + pkt_metadata_from_flow(&md, &flow); + flow_extract(packet, &md, &miss->flow); hash = flow_hash(&miss->flow, 0); existing_miss = flow_miss_find(&misses, ofproto, &miss->flow, diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 89d92af..0955d64 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3184,12 +3184,15 @@ xlate_send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet) struct xport *xport; struct ofpact_output output; struct flow flow; + struct pkt_metadata md; union flow_in_port in_port_; ofpact_init(&output.ofpact, OFPACT_OUTPUT, sizeof output); /* Use OFPP_NONE as the in_port to avoid special packet processing. */ in_port_.ofp_port = OFPP_NONE; - flow_extract(packet, 0, 0, NULL, &in_port_, &flow); + + pkt_metadata_init(&md, &in_port_); + flow_extract(packet, &md, &flow); ovs_rwlock_rdlock(&xlate_rwlock); xport = xport_lookup(ofport); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index c597114..6c48c18 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -3784,11 +3784,14 @@ parse_flow_and_packet(int argc, const char *argv[], flow_compose(packet, flow); } else { union flow_in_port in_port = flow->in_port; + struct pkt_metadata md; /* Use the metadata from the flow and the packet argument * to reconstruct the flow. */ - flow_extract(packet, flow->skb_priority, flow->pkt_mark, NULL, - &in_port, flow); + pkt_metadata_init_full(&md, NULL, flow->skb_priority, + flow->pkt_mark, &in_port); + + flow_extract(packet, &md, flow); } } diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 7117e1f..e400b32 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2715,9 +2715,11 @@ run_rule_executes(struct ofproto *ofproto) LIST_FOR_EACH_SAFE (e, next, list_node, &executes) { union flow_in_port in_port_; struct flow flow; + struct pkt_metadata md; in_port_.ofp_port = e->in_port; - flow_extract(e->packet, 0, 0, NULL, &in_port_, &flow); + pkt_metadata_init(&md, &in_port_); + flow_extract(e->packet, &md, &flow); ofproto->ofproto_class->rule_execute(e->rule, &flow, e->packet); rule_execute_destroy(e); @@ -2928,6 +2930,7 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) struct flow flow; union flow_in_port in_port_; enum ofperr error; + struct pkt_metadata md; COVERAGE_INC(ofproto_packet_out); @@ -2961,7 +2964,8 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) /* Verify actions against packet, then send packet if successful. */ in_port_.ofp_port = po.in_port; - flow_extract(payload, 0, 0, NULL, &in_port_, &flow); + pkt_metadata_init(&md, &in_port_); + flow_extract(payload, &md, &flow); error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len); if (!error) { error = p->ofproto_class->packet_out(p, payload, &flow, diff --git a/tests/test-flows.c b/tests/test-flows.c index 2910035..7907523 100644 --- a/tests/test-flows.c +++ b/tests/test-flows.c @@ -58,6 +58,7 @@ main(int argc OVS_UNUSED, char *argv[]) struct ofp10_match extracted_match; struct match match; struct flow flow; + struct pkt_metadata md; union flow_in_port in_port_; n++; @@ -69,7 +70,8 @@ main(int argc OVS_UNUSED, char *argv[]) } in_port_.ofp_port = u16_to_ofp(1); - flow_extract(packet, 0, 0, NULL, &in_port_, &flow); + pkt_metadata_init(&md, &in_port_); + flow_extract(packet, &md, &flow); match_wc_init(&match, &flow); ofputil_match_to_ofp10_match(&match, &extracted_match); diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 4ab9ca4..e62e646 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -1864,12 +1864,13 @@ ofctl_ofp_parse_pcap(int argc OVS_UNUSED, char *argv[]) struct ofpbuf *packet; long long int when; struct flow flow; + const struct pkt_metadata md = PKT_METADATA_INITIALIZER(ODPP_NONE); error = ovs_pcap_read(file, &packet, &when); if (error) { break; } - flow_extract(packet, 0, 0, NULL, NULL, &flow); + flow_extract(packet, &md, &flow); if (flow.dl_type == htons(ETH_TYPE_IP) && flow.nw_proto == IPPROTO_TCP && (is_openflow_port(flow.tp_src, argv + 2) || @@ -3208,6 +3209,7 @@ ofctl_parse_pcap(int argc OVS_UNUSED, char *argv[]) for (;;) { struct ofpbuf *packet; struct flow flow; + const struct pkt_metadata md = PKT_METADATA_INITIALIZER(ODPP_NONE); int error; error = ovs_pcap_read(pcap, &packet, NULL); @@ -3217,7 +3219,7 @@ ofctl_parse_pcap(int argc OVS_UNUSED, char *argv[]) ovs_fatal(error, "%s: read failed", argv[1]); } - flow_extract(packet, 0, 0, NULL, NULL, &flow); + flow_extract(packet, &md, &flow); flow_print(stdout, &flow); putchar('\n'); ofpbuf_delete(packet); -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev