}
-/* Initializes 'flow' members from 'packet', 'skb_priority', 'tun_id', and
+/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
* 'ofp_in_port'.
*
* 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, ovs_be64 tun_id,
- uint16_t ofp_in_port, struct flow *flow)
+flow_extract(struct ofpbuf *packet, uint32_t skb_priority,
+ const struct flow_tnl *tnl, uint16_t ofp_in_port,
+ struct flow *flow)
{
struct ofpbuf b = *packet;
struct eth_header *eth;
COVERAGE_INC(flow_extract);
memset(flow, 0, sizeof *flow);
- flow->tun_id = tun_id;
+
+ if (tnl) {
+ assert(tnl != &flow->tunnel);
+ flow->tunnel = *tnl;
+ }
flow->in_port = ofp_in_port;
flow->skb_priority = skb_priority;
{
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
- fmd->tun_id = flow->tun_id;
+ fmd->tun_id = flow->tunnel.tun_id;
fmd->metadata = flow->metadata;
memcpy(fmd->regs, flow->regs, sizeof fmd->regs);
fmd->in_port = flow->in_port;
return ds_cstr(&ds);
}
+static void format_tunnel_flags(uint16_t flags, struct ds *ds)
+{
+ flags &= ~FLOW_TNL_F_KEY;
+
+ if (flags & FLOW_TNL_F_DONT_FRAGMENT) {
+ ds_put_cstr(ds, ",df");
+ flags &= ~FLOW_TNL_F_DONT_FRAGMENT;
+ }
+
+ if (flags & FLOW_TNL_F_CSUM) {
+ ds_put_cstr(ds, ",csum");
+ flags &= ~FLOW_TNL_F_CSUM;
+ }
+
+ if (flags) {
+ ds_put_format(ds, ",flags:%#"PRIx16, flags);
+ }
+}
+
void
flow_format(struct ds *ds, const struct flow *flow)
{
- ds_put_format(ds, "priority:%"PRIu32
- ",tunnel:%#"PRIx64
- ",metadata:%#"PRIx64
+ ds_put_format(ds, "priority:%"PRIu32, flow->skb_priority);
+
+ if (flow->tunnel.ip_dst || flow->tunnel.tun_id) {
+ ds_put_cstr(ds, ",tunnel(");
+ ds_put_format(ds, IP_FMT"->"IP_FMT, IP_ARGS(&flow->tunnel.ip_src),
+ IP_ARGS(&flow->tunnel.ip_dst));
+
+ if (flow->tunnel.flags & FLOW_TNL_F_KEY) {
+ ds_put_format(ds, ",key:%#"PRIx64, ntohll(flow->tunnel.tun_id));
+ }
+ ds_put_format(ds, ",tos:%#"PRIx8",ttl:%"PRIu8, flow->tunnel.ip_tos,
+ flow->tunnel.ip_ttl);
+ format_tunnel_flags(flow->tunnel.flags, ds);
+ ds_put_char(ds, ')');
+ }
+
+ ds_put_format(ds, ",metadata:%#"PRIx64
",in_port:%04"PRIx16,
- flow->skb_priority,
- ntohll(flow->tun_id),
ntohll(flow->metadata),
flow->in_port);
ds_put_cstr(ds, "->");
print_ipv6_addr(ds, &flow->ipv6_dst);
ds_put_char(ds, ')');
- } else {
+ } else if (flow->dl_type == htons(ETH_TYPE_IP) ||
+ flow->dl_type == htons(ETH_TYPE_ARP)) {
ds_put_format(ds, " proto:%"PRIu8" tos:%#"PRIx8" ttl:%"PRIu8
" ip("IP_FMT"->"IP_FMT")",
flow->nw_proto, flow->nw_tos, flow->nw_ttl,