datapath: Free up flow_extract() return value for reporting errors.
[sliver-openvswitch.git] / datapath / flow.c
index f01071c..5e362e3 100644 (file)
@@ -49,13 +49,13 @@ struct arp_eth_header
        unsigned char       ar_tip[4];          /* target IP address        */
 } __attribute__((packed));
 
-static inline int arphdr_ok(struct sk_buff *skb)
+static inline bool arphdr_ok(struct sk_buff *skb)
 {
        int nh_ofs = skb_network_offset(skb);
        return pskb_may_pull(skb, nh_ofs + sizeof(struct arp_eth_header));
 }
 
-static inline int iphdr_ok(struct sk_buff *skb)
+static inline bool iphdr_ok(struct sk_buff *skb)
 {
        int nh_ofs = skb_network_offset(skb);
        if (skb->len >= nh_ofs + sizeof(struct iphdr)) {
@@ -63,10 +63,10 @@ static inline int iphdr_ok(struct sk_buff *skb)
                return (ip_len >= sizeof(struct iphdr)
                        && pskb_may_pull(skb, nh_ofs + ip_len));
        }
-       return 0;
+       return false;
 }
 
-static inline int tcphdr_ok(struct sk_buff *skb)
+static inline bool tcphdr_ok(struct sk_buff *skb)
 {
        int th_ofs = skb_transport_offset(skb);
        if (pskb_may_pull(skb, th_ofs + sizeof(struct tcphdr))) {
@@ -74,16 +74,16 @@ static inline int tcphdr_ok(struct sk_buff *skb)
                return (tcp_len >= sizeof(struct tcphdr)
                        && skb->len >= th_ofs + tcp_len);
        }
-       return 0;
+       return false;
 }
 
-static inline int udphdr_ok(struct sk_buff *skb)
+static inline bool udphdr_ok(struct sk_buff *skb)
 {
        int th_ofs = skb_transport_offset(skb);
        return pskb_may_pull(skb, th_ofs + sizeof(struct udphdr));
 }
 
-static inline int icmphdr_ok(struct sk_buff *skb)
+static inline bool icmphdr_ok(struct sk_buff *skb)
 {
        int th_ofs = skb_transport_offset(skb);
        return pskb_may_pull(skb, th_ofs + sizeof(struct icmphdr));
@@ -219,21 +219,28 @@ static __be16 parse_ethertype(struct sk_buff *skb)
        return llc->ethertype;
 }
 
-/* Parses the Ethernet frame in 'skb', which was received on 'in_port',
- * and initializes 'key' to match.  Returns 1 if 'skb' contains an IP
- * fragment, 0 otherwise. */
+/**
+ * flow_extract - extracts a flow key from an Ethernet frame.
+ * @skb: sk_buff that contains the frame, with skb->data pointing to the
+ * Ethernet header
+ * @in_port: port number on which @skb was received.
+ * @key: output flow key
+ *
+ * The caller must ensure that skb->len >= ETH_HLEN.
+ *
+ * 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)
 {
        struct ethhdr *eth;
-       int retval = 0;
 
        memset(key, 0, sizeof *key);
        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;
 
-       if (skb->len < sizeof *eth)
-               return 0;
        if (!pskb_may_pull(skb, min(skb->len, 64u)))
                return 0;
 
@@ -302,7 +309,7 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct odp_flow_key *key)
                                }
                        }
                } else {
-                       retval = 1;
+                       OVS_CB(skb)->is_frag = true;
                }
        } else if (key->dl_type == htons(ETH_P_ARP) && arphdr_ok(skb)) {
                struct arp_eth_header *arp;
@@ -328,7 +335,7 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct odp_flow_key *key)
        } else {
                skb_reset_transport_header(skb);
        }
-       return retval;
+       return 0;
 }
 
 u32 flow_hash(const struct odp_flow_key *key)