}
/* 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,
if (!error) {
struct pkt_metadata md
= PKT_METADATA_INITIALIZER(port->port_no);
- dp_netdev_port_input(dp, &packet, &md);
+ dp_netdev_port_input(dp, &packet, &md);
received_anything = true;
} else if (error != EAGAIN && error != EOPNOTSUPP) {
static struct vlog_rate_limit rl
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;
#include "ofpbuf.h"
#include "openflow/openflow.h"
#include "packets.h"
+#include "odp-util.h"
#include "random.h"
#include "unaligned.h"
}
-/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
- * 'in_port'.
+/* Initializes 'flow' members from 'packet' and 'md'
*
* Initializes 'packet' header pointers as follows:
*
* 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;
memset(flow, 0, sizeof *flow);
- if (tnl) {
- ovs_assert(tnl != &flow->tunnel);
- flow->tunnel = *tnl;
- }
- if (in_port) {
- flow->in_port = *in_port;
+ if (md) {
+ flow->tunnel = md->tunnel;
+ if (md->in_port.odp_port != ODPP_NONE) {
+ flow->in_port = md->in_port;
+ };
+ flow->skb_priority = md->skb_priority;
+ flow->pkt_mark = md->pkt_mark;
}
- flow->skb_priority = skb_priority;
- flow->pkt_mark = pkt_mark;
packet->l2 = b.data;
packet->l2_5 = NULL;
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
* numbers and other times datapath (dpif) port numbers. This union allows
* access to both. */
union flow_in_port {
- ofp_port_t ofp_port;
odp_port_t odp_port;
+ ofp_port_t ofp_port;
};
/* Maximum number of supported MPLS labels. */
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 *);
struct ofpbuf pkt;
struct flow flow;
- union flow_in_port in_port_;
error = ofputil_decode_packet_in(&pi, oh);
if (error) {
/* 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);
+ flow_extract(&pkt, NULL, &flow);
+ flow.in_port.ofp_port = pi.fmd.in_port;
flow.tunnel.tun_id = pi.fmd.tun_id;
/* Choose output port. */
/* Add an ingress port attribute if 'odp_in_port' is not the magical
* value "ODPP_NONE". */
- if (md->in_port != ODPP_NONE) {
- nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, md->in_port);
+ if (md->in_port.odp_port != ODPP_NONE) {
+ nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, md->in_port.odp_port);
}
}
1u << OVS_KEY_ATTR_SKB_MARK | 1u << OVS_KEY_ATTR_TUNNEL |
1u << OVS_KEY_ATTR_IN_PORT;
- memset(md, 0, sizeof *md);
- md->in_port = ODPP_NONE;
+ *md = PKT_METADATA_INITIALIZER(ODPP_NONE);
NL_ATTR_FOR_EACH (nla, left, key, key_len) {
uint16_t type = nl_attr_type(nla);
wanted_attrs &= ~(1u << OVS_KEY_ATTR_TUNNEL);
}
} else if (type == OVS_KEY_ATTR_IN_PORT) {
- md->in_port = nl_attr_get_odp_port(nla);
+ md->in_port.odp_port = nl_attr_get_odp_port(nla);
wanted_attrs &= ~(1u << OVS_KEY_ATTR_IN_PORT);
}
#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);
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) {
#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;
ds_put_cstr(s, "[800]");
}
}
+
+void pkt_metadata_init(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.odp_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(md, &flow->tunnel, flow->skb_priority,
+ flow->pkt_mark, &flow->in_port);
+}
struct flow_tnl tunnel; /* Encapsulating tunnel parameters. */
uint32_t skb_priority; /* Packet priority for QoS. */
uint32_t pkt_mark; /* Packet mark. */
- odp_port_t in_port; /* Input port. */
+ union flow_in_port in_port; /* Input port. */
};
#define PKT_METADATA_INITIALIZER(PORT) \
- (struct pkt_metadata){ { 0, 0, 0, 0, 0, 0}, 0, 0, (PORT) }
+ (struct pkt_metadata){ { 0, 0, 0, 0, 0, 0}, 0, 0, {(PORT)} }
+
+void pkt_metadata_init(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);
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,
struct xport *xport;
struct ofpact_output output;
struct flow flow;
- 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);
+ flow_extract(packet, NULL, &flow);
+ flow.in_port.ofp_port = OFPP_NONE;
ovs_rwlock_rdlock(&xlate_rwlock);
xport = xport_lookup(ofport);
execute.md.tunnel = flow->tunnel;
execute.md.skb_priority = flow->skb_priority;
execute.md.pkt_mark = flow->pkt_mark;
- execute.md.in_port = ofp_port_to_odp_port(ofproto, in_port);
+ execute.md.in_port.odp_port = ofp_port_to_odp_port(ofproto, in_port);
execute.needs_help = (xout.slow & SLOW_ACTION) != 0;
error = dpif_execute(ofproto->backer->dpif, &execute);
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(&md, NULL, flow->skb_priority,
+ flow->pkt_mark, &in_port);
+
+ flow_extract(packet, &md, flow);
}
}
guarded_list_pop_all(&ofproto->rule_executes, &executes);
LIST_FOR_EACH_SAFE (e, next, list_node, &executes) {
- union flow_in_port in_port_;
struct flow flow;
- in_port_.ofp_port = e->in_port;
- flow_extract(e->packet, 0, 0, NULL, &in_port_, &flow);
+ flow_extract(e->packet, NULL, &flow);
+ flow.in_port.ofp_port = e->in_port;
ofproto->ofproto_class->rule_execute(e->rule, &flow, e->packet);
rule_execute_destroy(e);
uint64_t ofpacts_stub[1024 / 8];
struct ofpbuf ofpacts;
struct flow flow;
- union flow_in_port in_port_;
enum ofperr error;
COVERAGE_INC(ofproto_packet_out);
}
/* 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);
+ flow_extract(payload, NULL, &flow);
+ flow.in_port.ofp_port = po.in_port;
error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len);
if (!error) {
error = p->ofproto_class->packet_out(p, payload, &flow,
struct ofp10_match extracted_match;
struct match match;
struct flow flow;
- union flow_in_port in_port_;
n++;
retval = ovs_pcap_read(pcap, &packet, NULL);
ovs_fatal(retval, "error reading pcap file");
}
- in_port_.ofp_port = u16_to_ofp(1);
- flow_extract(packet, 0, 0, NULL, &in_port_, &flow);
+ flow_extract(packet, NULL, &flow);
+ flow.in_port.ofp_port = u16_to_ofp(1);
+
match_wc_init(&match, &flow);
ofputil_match_to_ofp10_match(&match, &extracted_match);
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) ||
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);
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);