datapath: handle recirculation loop detection
[sliver-openvswitch.git] / datapath / datapath.h
index 64920de..a847bd9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2012 Nicira, Inc.
+ * Copyright (c) 2007-2014 Nicira, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
  * @n_lost: Number of received packets that had no matching flow in the flow
  * table that could not be sent to userspace (normally due to an overflow in
  * one of the datapath's queues).
+ * @n_mask_hit: Number of masks looked up for flow match.
+ *   @n_mask_hit / (@n_hit + @n_missed)  will be the average masks looked
+ *   up per packet.
  */
 struct dp_stats_percpu {
        u64 n_hit;
        u64 n_missed;
        u64 n_lost;
+       u64 n_mask_hit;
        struct u64_stats_sync sync;
 };
 
@@ -86,6 +90,8 @@ struct datapath {
        /* Network namespace ref. */
        struct net *net;
 #endif
+
+       u32 user_features;
 };
 
 /**
@@ -93,12 +99,14 @@ struct datapath {
  * @flow: The flow associated with this packet.  May be %NULL if no flow.
  * @pkt_key: The flow information extracted from the packet.  Must be nonnull.
  * @tun_key: Key for the tunnel that encapsulated this packet. NULL if the
- * packet is not being tunneled.
+ * @input_vport: The original vport packet came in on. This value is cached
+ * when a packet is received by OVS.
  */
 struct ovs_skb_cb {
        struct sw_flow          *flow;
        struct sw_flow_key      *pkt_key;
        struct ovs_key_ipv4_tunnel  *tun_key;
+       struct vport    *input_vport;
 };
 #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
 
@@ -144,6 +152,8 @@ int lockdep_ovsl_is_held(void);
 #define ASSERT_OVSL()          WARN_ON(unlikely(!lockdep_ovsl_is_held()))
 #define ovsl_dereference(p)                                    \
        rcu_dereference_protected(p, lockdep_ovsl_is_held())
+#define rcu_dereference_ovsl(p)                                        \
+       rcu_dereference_check(p, lockdep_ovsl_is_held())
 
 static inline struct net *ovs_dp_get_net(struct datapath *dp)
 {
@@ -176,9 +186,12 @@ static inline struct vport *ovs_vport_ovsl(const struct datapath *dp, int port_n
 }
 
 extern struct notifier_block ovs_dp_device_notifier;
+extern struct genl_family dp_vport_genl_family;
 extern struct genl_multicast_group ovs_dp_vport_multicast_group;
 
 void ovs_dp_process_received_packet(struct vport *, struct sk_buff *);
+void ovs_dp_process_packet_with_key(struct sk_buff *,
+                                   struct sw_flow_key *pkt_key, bool recirc);
 void ovs_dp_detach_port(struct vport *);
 int ovs_dp_upcall(struct datapath *, struct sk_buff *,
                  const struct dp_upcall_info *);
@@ -187,10 +200,12 @@ const char *ovs_dp_name(const struct datapath *dp);
 struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 portid, u32 seq,
                                         u8 cmd);
 
-int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb);
+int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, bool recirc);
 void ovs_dp_notify_wq(struct work_struct *work);
 
-#define OVS_NLERR(fmt, ...) \
-       pr_info_once("netlink: " fmt, ##__VA_ARGS__)
-
+#define OVS_NLERR(fmt, ...)                                    \
+do {                                                           \
+       if (net_ratelimit())                                    \
+               pr_info("netlink: " fmt, ##__VA_ARGS__);        \
+} while (0)
 #endif /* datapath.h */