--- openflow-2012-03-09.h	2015-07-23 09:54:16.932479353 -0700
+++ openflow-2011-09-20.h	2015-07-23 09:54:16.936479353 -0700
@@ -150,6 +150,9 @@
     OFPT_GET_ASYNC_REQUEST  = 26, /* Controller/switch message */
     OFPT_GET_ASYNC_REPLY    = 27, /* Controller/switch message */
     OFPT_SET_ASYNC          = 28, /* Controller/switch message */
+
+    /* Meters and rate limiters configuration messages. */
+    OFPT_METER_SET_REQUEST  = 29, /* Controller/switch message */
 };
 
 /* Header on all OpenFlow packets. */
@@ -1003,6 +1006,7 @@
     OFPIT_APPLY_ACTIONS = 4,    /* Applies the action(s) immediately */
     OFPIT_CLEAR_ACTIONS = 5,    /* Clears all actions from the datapath
                                    action set */
+    OFPIT_METER = 6;            /* Apply meter (rate limiter) */
 
     OFPIT_EXPERIMENTER = 0xFFFF  /* Experimenter instruction */
 };
@@ -1045,6 +1049,14 @@
 };
 OFP_ASSERT(sizeof(struct ofp_instruction_actions) == 8);
 
+/* Instruction structure for OFPIT_METER */
+struct ofp_instruction_meter {
+    uint16_t type;                /* OFPIT_METER */
+    uint16_t len;                 /* Length is 8. */
+    uint32_t meter_id;            /* Meter instance. */
+};
+OFP_ASSERT(sizeof(struct ofp_instruction_meter) == 8);
+
 /* Instruction structure for experimental instructions */
 struct ofp_instruction_experimenter {
     uint16_t type;		/* OFPIT_EXPERIMENTER */
@@ -1271,6 +1283,7 @@
     OFPET_QUEUE_OP_FAILED      = 9,  /* Queue operation failed. */
     OFPET_SWITCH_CONFIG_FAILED = 10, /* Switch config request failed. */
     OFPET_ROLE_REQUEST_FAILED  = 11, /* Controller Role request failed. */
+    OFPET_BAD_METER            = 12, /* Error in meter. */
     OFPET_EXPERIMENTER = 0xffff      /* Experimenter error messages. */
 };
 
@@ -1454,6 +1467,17 @@
     OFPRRFC_BAD_ROLE   = 2,      /* Invalid role. */
 };
 
+/* ofp_error_msg 'code' values for OFPET_BAD_METER.  'data' contains at least
+ * the first 64 bytes of the failed request. */
+enum ofp_bad_meter_code {
+    OFPBMRC_UNKNOWN      = 0,   /* Unspecified error. */
+    OFPBMRC_BAD_METER_ID = 1,   /* Meter does not exist, or already exist. */
+    OFPBMRC_BAD_COMMAND  = 2,   /* Unsupported or unknown command. */
+    OFPBMRC_BAD_FLAGS    = 3,   /* Flag configuration unsupported. */
+    OFPBMRC_BAD_RATE     = 4,   /* Rate unsupported. */
+    OFPBMRC_BAD_BURST    = 5,   /* Burst size unsupported. */
+};
+
 /* OFPT_ERROR: Error message (datapath -> controller). */
 struct ofp_error_msg {
     struct ofp_header header;
@@ -1524,6 +1548,21 @@
      * The reply body is struct ofp_group_features_stats. */
     OFPST_GROUP_FEATURES = 8,
 
+    /* Meter statistics.
+     * The request body is struct ofp_meter_stats_requests.
+     * The reply body is struct ofp_meter_stats. */
+    OFPST_METER,
+
+    /* Meter configuration.
+     * The request body is struct ofp_meter_stats_requests.
+     * The reply body is struct ofp_meter_config_stats. */
+    OFPST_METER_CONFIG,
+
+    /* Meter features.
+     * The request body is empty.
+     * The reply body is struct ofp_meter_features_stats. */
+    OFPST_METER_FEATURES,
+
     /* Experimenter extension.
      * The request and reply bodies begin with
      * struct ofp_experimenter_stats_header.
@@ -1758,6 +1797,50 @@
 };
 OFP_ASSERT(sizeof(struct ofp_group_features_stats) == 40);
 
+/* Body of OFPST_METER request. */
+struct ofp_meter_stats_request {
+    uint32_t meter_id;       /* Meter instance, or OFPM_ALL. */
+    uint8_t pad[4];          /* Align to 64 bits. */
+};
+OFP_ASSERT(sizeof(struct ofp_meter_stats_request) == 8);
+
+/* Body of reply to OFPST_METER request. Meter statistics. */
+struct ofp_meter_stats {
+    uint32_t        meter_id;         /* Meter instance. */
+    uint32_t        flow_count;       /* Number of flows bound to meter. */
+    uint64_t        packet_count;     /* Number of packets in input. */
+    uint64_t        byte_count;	      /* Number of bytes in input. */
+    uint64_t        packet_drop;      /* Number of packets dropped. */
+    uint64_t        byte_drop;        /* Number of bytes dropped. */
+    uint64_t        packet_actions;   /* Number of packets for actions. */
+    uint64_t        byte_actions;     /* Number of bytes for actions. */
+};
+OFP_ASSERT(sizeof(struct ofp_meter_stats) == 56);
+
+/* Body of reply to OFPST_METER_CONFIG request. Meter configuration. */
+struct ofp_meter_config_stats {
+    uint16_t        length;           /* Length of this entry. */
+    uint8_t         pad[2];
+    uint32_t        meter_id;         /* Meter instance. */
+    uint32_t        flags;            /* All OFPMC_* that apply. */
+    uint32_t        drop_rate;        /* Rate for dropping packets. */
+    uint32_t        actions_rate;     /* Rate for writing actions. */
+    uint32_t        burst_size;	      /* Size of bursts. */
+    struct ofp_action_header actions[0]; /* The action length is inferred
+                                           from the length field in the
+                                           entry. */
+};
+OFP_ASSERT(sizeof(struct ofp_meter_config_stats) == 24);
+
+/* Body of reply to OFPST_METER_FEATURES request. Meter features. */
+struct ofp_meter_features_stats {
+    uint32_t        max_meter;    /* Maximum number of meters. */
+    uint32_t        capabilities; /* Bitmaps of "ofp_meter_capabilities". */
+    uint32_t        actions;      /* Bitmap of OFPAT_* that are supported. */
+    uint8_t         pad[4];
+};
+OFP_ASSERT(sizeof(struct ofp_meter_features_stats) == 16);
+
 /* Body for ofp_stats_request/reply of type OFPST_EXPERIMENTER. */
 struct ofp_experimenter_stats_header {
     uint32_t experimenter;    /* Experimenter ID which takes the same form
@@ -1927,4 +2010,41 @@
 };
 OFP_ASSERT(sizeof(struct ofp_async_config) == 32);
 
+/* Meter numbering. Flow meters can use any number up to OFPM_MAX. */
+enum ofp_meter {
+    /* Last usable meter. */
+    OFPM_MAX        = 0xffff0000,
+
+    /* Virtual meters. */
+    OFPM_SLOWPATH   = 0xfffffffd;  /* Meter for slow datapath. */
+    OFPM_CONTROLLER = 0xfffffffe;  /* Meter for controller datapath. */
+    OFPM_ALL        = 0xffffffff,  /* Represents all meters for stat requests
+                                      commands. */
+};
+
+/* Meter capability flags and configuration flags */
+enum ofp_meter_capabilities {
+    OFPMC_KBPS    = 1 << 0,     /* Rate value in kb/s (kilo-bit per second) */
+    OFPMC_PKTPS   = 1 << 1,     /* Rate value in packet/sec */
+    OFPMC_DROP    = 1 << 2,     /* Drop packet if rate exceeded */
+    OFPMC_ACTIONS = 1 << 3,     /* Write actions if rate exceeded */
+    OFPMC_BURST   = 1 << 4,     /* Do burst size */
+    OFPMC_STATS   = 1 << 5,     /* Collect statistics */
+};
+
+/* Meter configuration. OFPT_METER_SET_REQUEST. */
+struct ofp_meter_set_request {
+    struct ofp_header	header;
+    uint16_t            command;        /* One of OFPGC_*. */
+    uint8_t             pad[2];
+    uint32_t            meter_id;       /* Meter instance. */
+    uint32_t            flags;          /* One of OFPMC_*. */
+    uint32_t            drop_rate;      /* Rate for dropping packets */
+    uint32_t            actions_rate;   /* Rate for writing actions */
+    uint32_t            burst_size;     /* Size of bursts */
+    struct ofp_action_header actions[0]; /* The action length is inferred
+                                           from the length field in the
+                                           header. */
+};
+
 #endif /* openflow/openflow.h */
