Skip to content

Commit

Permalink
flow: Split flow_extract
Browse files Browse the repository at this point in the history
Split the L3 and above portion of flow_extract() out into
flow_extract_l3_onwards() and call flow_extract_l3_onwards()
from flow_extract().

This is to allow re-extraction of l3 and higher information using
flow->encap_dl_type which may be set using information contained
in actions.

Signed-off-by: Simon Horman <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
horms authored and blp committed Dec 27, 2012
1 parent e0c91c0 commit ad128cc
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
34 changes: 29 additions & 5 deletions lib/flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,33 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
}
flow->dl_type = parse_ethertype(&b);

/* Network layer. */
packet->l3 = b.data;
if (flow->dl_type == htons(ETH_TYPE_IP)) {
flow_extract_l3_onwards(packet, flow, flow->dl_type);
}

/* Initializes l3 and higher 'flow' members from 'packet'
*
* This should be called by or after flow_extract()
*
* Initializes 'packet' header pointers as follows:
*
* - packet->l4 to just past the IPv4 header, if one is present and has a
* correct length, and otherwise NULL.
*
* - packet->l7 to just past the TCP or UDP or ICMP header, if one is
* present and has a correct length, and otherwise NULL.
*/
void
flow_extract_l3_onwards(struct ofpbuf *packet, struct flow *flow,
ovs_be16 dl_type)
{
struct ofpbuf b;

ofpbuf_use_const(&b, packet->l3, packet->size -
(size_t)((char *)packet->l3 - (char *)packet->l2));

/* Network layer. */
if (dl_type == htons(ETH_TYPE_IP)) {
const struct ip_header *nh = pull_ip(&b);
if (nh) {
packet->l4 = b.data;
Expand Down Expand Up @@ -410,7 +434,7 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
}
}
}
} else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
} else if (dl_type == htons(ETH_TYPE_IPV6)) {
if (parse_ipv6(&b, flow)) {
return;
}
Expand All @@ -425,8 +449,8 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
packet->l7 = b.data;
}
}
} else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
flow->dl_type == htons(ETH_TYPE_RARP)) {
} else if (dl_type == htons(ETH_TYPE_ARP) ||
dl_type == htons(ETH_TYPE_RARP)) {
const struct arp_eth_header *arp = pull_arp(&b);
if (arp && arp->ar_hrd == htons(1)
&& arp->ar_pro == htons(ETH_TYPE_IP)
Expand Down
2 changes: 2 additions & 0 deletions lib/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ struct flow_metadata {

void flow_extract(struct ofpbuf *, uint32_t priority, uint32_t mark,
const struct flow_tnl *, uint16_t in_port, struct flow *);
void flow_extract_l3_onwards(struct ofpbuf *, struct flow *,
ovs_be16 dl_type);
void flow_zero_wildcards(struct flow *, const struct flow_wildcards *);
void flow_get_metadata(const struct flow *, struct flow_metadata *);

Expand Down

0 comments on commit ad128cc

Please sign in to comment.