Add Nicira extension to OpenFlow for dropping spoofed ARP packets.
[sliver-openvswitch.git] / datapath / flow.c
index 7b1f23b..c37c8e0 100644 (file)
 struct kmem_cache *flow_cache;
 static unsigned int hash_seed;
 
-struct arp_eth_header
-{
-       __be16      ar_hrd;     /* format of hardware address   */
-       __be16      ar_pro;     /* format of protocol address   */
-       unsigned char   ar_hln; /* length of hardware address   */
-       unsigned char   ar_pln; /* length of protocol address   */
-       __be16      ar_op;      /* ARP opcode (command)     */
-
-       /* Ethernet+IPv4 specific members. */
-       unsigned char       ar_sha[ETH_ALEN];   /* sender hardware address  */
-       unsigned char       ar_sip[4];          /* sender IP address        */
-       unsigned char       ar_tha[ETH_ALEN];   /* target hardware address  */
-       unsigned char       ar_tip[4];          /* target IP address        */
-} __attribute__((packed));
-
 static inline bool arphdr_ok(struct sk_buff *skb)
 {
        int nh_ofs = skb_network_offset(skb);
@@ -228,17 +213,18 @@ static __be16 parse_ethertype(struct sk_buff *skb)
  *
  * The caller must ensure that skb->len >= ETH_HLEN.
  *
- * Returns 1 if @skb contains an IPv4 fragment, 0 otherwise.
+ * 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 (!pskb_may_pull(skb, min(skb->len, 64u)))
                return 0;
@@ -308,7 +294,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;
@@ -334,7 +320,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)