mirror of
https://github.com/openvswitch/ovs
synced 2025-10-17 14:28:02 +00:00
flow: Split flow_extract
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 <horms@verge.net.au> Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
34
lib/flow.c
34
lib/flow.c
@@ -375,9 +375,33 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
|
|||||||
}
|
}
|
||||||
flow->dl_type = parse_ethertype(&b);
|
flow->dl_type = parse_ethertype(&b);
|
||||||
|
|
||||||
/* Network layer. */
|
|
||||||
packet->l3 = b.data;
|
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);
|
const struct ip_header *nh = pull_ip(&b);
|
||||||
if (nh) {
|
if (nh) {
|
||||||
packet->l4 = b.data;
|
packet->l4 = b.data;
|
||||||
@@ -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)) {
|
if (parse_ipv6(&b, flow)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -425,8 +449,8 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
|
|||||||
packet->l7 = b.data;
|
packet->l7 = b.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
|
} else if (dl_type == htons(ETH_TYPE_ARP) ||
|
||||||
flow->dl_type == htons(ETH_TYPE_RARP)) {
|
dl_type == htons(ETH_TYPE_RARP)) {
|
||||||
const struct arp_eth_header *arp = pull_arp(&b);
|
const struct arp_eth_header *arp = pull_arp(&b);
|
||||||
if (arp && arp->ar_hrd == htons(1)
|
if (arp && arp->ar_hrd == htons(1)
|
||||||
&& arp->ar_pro == htons(ETH_TYPE_IP)
|
&& arp->ar_pro == htons(ETH_TYPE_IP)
|
||||||
|
@@ -123,6 +123,8 @@ struct flow_metadata {
|
|||||||
|
|
||||||
void flow_extract(struct ofpbuf *, uint32_t priority, uint32_t mark,
|
void flow_extract(struct ofpbuf *, uint32_t priority, uint32_t mark,
|
||||||
const struct flow_tnl *, uint16_t in_port, struct flow *);
|
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_zero_wildcards(struct flow *, const struct flow_wildcards *);
|
||||||
void flow_get_metadata(const struct flow *, struct flow_metadata *);
|
void flow_get_metadata(const struct flow *, struct flow_metadata *);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user