odp-util: Avoid returning static data in ovs_key_attr_to_string().
[sliver-openvswitch.git] / lib / ofp-util.c
index 06e149a..cc2dc36 100644 (file)
@@ -84,7 +84,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask)
 void
 ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
 {
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 19);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 20);
 
     /* Initialize most of wc. */
     flow_wildcards_init_catchall(wc);
@@ -922,7 +922,7 @@ ofputil_version_from_string(const char *s)
 }
 
 static bool
-is_delimiter(char c)
+is_delimiter(unsigned char c)
 {
     return isspace(c) || c == ',';
 }
@@ -1039,16 +1039,6 @@ regs_fully_wildcarded(const struct flow_wildcards *wc)
     return true;
 }
 
-static bool
-tun_parms_fully_wildcarded(const struct flow_wildcards *wc)
-{
-    return (!wc->masks.tunnel.ip_src &&
-            !wc->masks.tunnel.ip_dst &&
-            !wc->masks.tunnel.ip_ttl &&
-            !wc->masks.tunnel.ip_tos &&
-            !wc->masks.tunnel.flags);
-}
-
 /* Returns a bit-mask of ofputil_protocols that can be used for sending 'match'
  * to a switch (e.g. to add or remove a flow).  Only NXM can handle tunnel IDs,
  * registers, or fixing the Ethernet multicast bit.  Otherwise, it's better to
@@ -1058,10 +1048,11 @@ ofputil_usable_protocols(const struct match *match)
 {
     const struct flow_wildcards *wc = &match->wc;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 19);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 20);
 
-    /* tunnel params other than tun_id can't be sent in a flow_mod */
-    if (!tun_parms_fully_wildcarded(wc)) {
+    /* These tunnel params can't be sent in a flow_mod */
+    if (wc->masks.tunnel.ip_ttl
+        || wc->masks.tunnel.ip_tos || wc->masks.tunnel.flags) {
         return OFPUTIL_P_NONE;
     }
 
@@ -1107,8 +1098,10 @@ ofputil_usable_protocols(const struct match *match)
             | OFPUTIL_P_OF13_OXM;
     }
 
-    /* NXM and OXM support matching tun_id. */
-    if (wc->masks.tunnel.tun_id != htonll(0)) {
+    /* NXM and OXM support matching tun_id, tun_src, and tun_dst. */
+    if (wc->masks.tunnel.tun_id != htonll(0)
+        || wc->masks.tunnel.ip_src != htonl(0)
+        || wc->masks.tunnel.ip_dst != htonl(0)) {
         return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM
             | OFPUTIL_P_OF13_OXM;
     }
@@ -1509,7 +1502,8 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
             return error;
         }
 
-        error = ofpacts_pull_openflow11_instructions(&b, b.size, ofpacts);
+        error = ofpacts_pull_openflow11_instructions(&b, b.size, ofm->table_id,
+                                                     ofpacts);
         if (error) {
             return error;
         }
@@ -2021,7 +2015,8 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
         }
 
         if (ofpacts_pull_openflow11_instructions(msg, length - sizeof *ofs -
-                                                 padded_match_len, ofpacts)) {
+                                                 padded_match_len,
+                                                 ofs->table_id, ofpacts)) {
             VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad instructions");
             return EINVAL;
         }
@@ -2450,6 +2445,8 @@ ofputil_decode_packet_in_finish(struct ofputil_packet_in *pin,
 
     pin->fmd.in_port = match->flow.in_port;
     pin->fmd.tun_id = match->flow.tunnel.tun_id;
+    pin->fmd.tun_src = match->flow.tunnel.ip_src;
+    pin->fmd.tun_dst = match->flow.tunnel.ip_dst;
     pin->fmd.metadata = match->flow.metadata;
     memcpy(pin->fmd.regs, match->flow.regs, sizeof pin->fmd.regs);
 }
@@ -2550,6 +2547,12 @@ ofputil_packet_in_to_match(const struct ofputil_packet_in *pin,
     if (pin->fmd.tun_id != htonll(0)) {
         match_set_tun_id(match, pin->fmd.tun_id);
     }
+    if (pin->fmd.tun_src != htonl(0)) {
+        match_set_tun_src(match, pin->fmd.tun_src);
+    }
+    if (pin->fmd.tun_dst != htonl(0)) {
+        match_set_tun_dst(match, pin->fmd.tun_dst);
+    }
     if (pin->fmd.metadata != htonll(0)) {
         match_set_metadata(match, pin->fmd.metadata);
     }
@@ -4028,7 +4031,7 @@ ofputil_frag_handling_from_string(const char *s, enum ofp_config_flags *flags)
 /* Converts the OpenFlow 1.1+ port number 'ofp11_port' into an OpenFlow 1.0
  * port number and stores the latter in '*ofp10_port', for the purpose of
  * decoding OpenFlow 1.1+ protocol messages.  Returns 0 if successful,
- * otherwise an OFPERR_* number.
+ * otherwise an OFPERR_* number.  On error, stores OFPP_NONE in '*ofp10_port'.
  *
  * See the definition of OFP11_MAX for an explanation of the mapping. */
 enum ofperr
@@ -4043,6 +4046,7 @@ ofputil_port_from_ofp11(ovs_be32 ofp11_port, uint16_t *ofp10_port)
         *ofp10_port = ofp11_port_h - OFPP11_OFFSET;
         return 0;
     } else {
+        *ofp10_port = OFPP_NONE;
         VLOG_WARN_RL(&bad_ofmsg_rl, "port %"PRIu32" is outside the supported "
                      "range 0 through %d or 0x%"PRIx32" through 0x%"PRIx32,
                      ofp11_port_h, OFPP_MAX - 1,
@@ -4235,7 +4239,7 @@ size_t ofputil_count_phy_ports(uint8_t ofp_version, struct ofpbuf *b)
 int
 ofputil_action_code_from_name(const char *name)
 {
-    static const char *names[OFPUTIL_N_ACTIONS] = {
+    static const char *const names[OFPUTIL_N_ACTIONS] = {
         NULL,
 #define OFPAT10_ACTION(ENUM, STRUCT, NAME)             NAME,
 #define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) NAME,
@@ -4243,7 +4247,7 @@ ofputil_action_code_from_name(const char *name)
 #include "ofp-util.def"
     };
 
-    const char **p;
+    const char *const *p;
 
     for (p = names; p < &names[ARRAY_SIZE(names)]; p++) {
         if (*p && !strcasecmp(name, *p)) {
@@ -4520,7 +4524,7 @@ ofputil_parse_key_value(char **stringp, char **keyp, char **valuep)
  * will be for Open Flow version 'ofp_version'. Returns message
  * as a struct ofpbuf. Returns encoded message on success, NULL on error */
 struct ofpbuf *
-ofputil_encode_dump_ports_request(enum ofp_version ofp_version, int16_t port)
+ofputil_encode_dump_ports_request(enum ofp_version ofp_version, uint16_t port)
 {
     struct ofpbuf *request;
 
@@ -4593,11 +4597,8 @@ ofputil_port_stats_to_ofp13(const struct ofputil_port_stats *ops,
                             struct ofp13_port_stats *ps13)
 {
     ofputil_port_stats_to_ofp11(ops, &ps13->ps);
-
-    /* OF 1.3 adds duration fields */
-    /* FIXME: Need to implement port alive duration (sec + nsec) */
-    ps13->duration_sec = htonl(~0);
-    ps13->duration_nsec = htonl(~0);
+    ps13->duration_sec = htonl(ops->duration_sec);
+    ps13->duration_nsec = htonl(ops->duration_nsec);
 }
 
 
@@ -4653,6 +4654,7 @@ ofputil_port_stats_from_ofp10(struct ofputil_port_stats *ops,
     ops->stats.rx_over_errors = ntohll(get_32aligned_be64(&ps10->rx_over_err));
     ops->stats.rx_crc_errors = ntohll(get_32aligned_be64(&ps10->rx_crc_err));
     ops->stats.collisions = ntohll(get_32aligned_be64(&ps10->collisions));
+    ops->duration_sec = ops->duration_nsec = UINT32_MAX;
 
     return 0;
 }
@@ -4681,6 +4683,7 @@ ofputil_port_stats_from_ofp11(struct ofputil_port_stats *ops,
     ops->stats.rx_over_errors = ntohll(ps11->rx_over_err);
     ops->stats.rx_crc_errors = ntohll(ps11->rx_crc_err);
     ops->stats.collisions = ntohll(ps11->collisions);
+    ops->duration_sec = ops->duration_nsec = UINT32_MAX;
 
     return 0;
 }
@@ -4689,13 +4692,11 @@ static enum ofperr
 ofputil_port_stats_from_ofp13(struct ofputil_port_stats *ops,
                               const struct ofp13_port_stats *ps13)
 {
-    enum ofperr error =
-        ofputil_port_stats_from_ofp11(ops, &ps13->ps);
+    enum ofperr error = ofputil_port_stats_from_ofp11(ops, &ps13->ps);
     if (!error) {
-        /* FIXME: Get ps13->duration_sec and ps13->duration_nsec,
-         * Add to netdev_stats? */
+        ops->duration_sec = ntohl(ps13->duration_sec);
+        ops->duration_nsec = ntohl(ps13->duration_nsec);
     }
-
     return error;
 }