if (!OVS_CB(skb)->flow) {
struct odp_flow_key key;
struct tbl_node *flow_node;
+ bool is_frag;
/* Extract flow from 'skb' into 'key'. */
- error = flow_extract(skb, p ? p->port_no : ODPP_NONE, &key);
+ error = flow_extract(skb, p ? p->port_no : ODPP_NONE, &key, &is_frag);
if (unlikely(error)) {
kfree_skb(skb);
return;
}
- if (OVS_CB(skb)->is_frag && dp->drop_frags) {
+ if (is_frag && dp->drop_frags) {
kfree_skb(skb);
stats_counter_off = offsetof(struct dp_stats_percpu, n_frags);
goto out;
struct sk_buff *skb;
struct sw_flow_actions *actions;
struct ethhdr *eth;
+ bool is_frag;
int err;
err = -EINVAL;
else
skb->protocol = htons(ETH_P_802_2);
- err = flow_extract(skb, execute->in_port, &key);
+ err = flow_extract(skb, execute->in_port, &key, &is_frag);
if (err)
goto error_free_skb;
* struct ovs_skb_cb - OVS data in skb CB
* @dp_port: The datapath port on which the skb entered the switch.
* @flow: The flow associated with this packet. May be %NULL if no flow.
- * @is_frag: %true if this packet is an IPv4 fragment, %false otherwise.
* @ip_summed: Consistently stores L4 checksumming status across different
* kernel versions.
* @tun_id: ID (in network byte order) of the tunnel that encapsulated this
struct ovs_skb_cb {
struct dp_port *dp_port;
struct sw_flow *flow;
- bool is_frag;
enum csum_type ip_summed;
__be32 tun_id;
};
* Sets OVS_CB(skb)->is_frag to %true if @skb is an IPv4 fragment, otherwise to
* %false.
*/
-int flow_extract(struct sk_buff *skb, u16 in_port, struct odp_flow_key *key)
+int flow_extract(struct sk_buff *skb, u16 in_port, struct odp_flow_key *key,
+ bool *is_frag)
{
struct ethhdr *eth;
key->tun_id = OVS_CB(skb)->tun_id;
key->in_port = in_port;
key->dl_vlan = htons(ODP_VLAN_NONE);
- OVS_CB(skb)->is_frag = false;
+ *is_frag = false;
/*
* We would really like to pull as many bytes as we could possibly
key->tp_dst = htons(icmp->code);
}
}
- } else {
- OVS_CB(skb)->is_frag = true;
- }
+ } else
+ *is_frag = true;
+
} else if (key->dl_type == htons(ETH_P_ARP) && arphdr_ok(skb)) {
struct arp_eth_header *arp;
&& arp->ar_pln == 4) {
/* We only match on the lower 8 bits of the opcode. */
- if (ntohs(arp->ar_op) <= 0xff) {
+ if (ntohs(arp->ar_op) <= 0xff)
key->nw_proto = ntohs(arp->ar_op);
- }
if (key->nw_proto == ARPOP_REQUEST
|| key->nw_proto == ARPOP_REPLY) {
void flow_hold(struct sw_flow *);
void flow_put(struct sw_flow *);
-int flow_extract(struct sk_buff *, u16 in_port, struct odp_flow_key *);
+int flow_extract(struct sk_buff *, u16 in_port, struct odp_flow_key *, bool *is_frag);
void flow_used(struct sw_flow *, struct sk_buff *);
u32 flow_hash(const struct odp_flow_key *key);