| 214 | |
| 215 | template <typename T> |
| 216 | CommandResponse WildcardMatch::ExtractKeyMask(const T &arg, wm_hkey_t *key, |
| 217 | wm_hkey_t *mask) { |
| 218 | if ((size_t)arg.values_size() != fields_.size()) { |
| 219 | return CommandFailure(EINVAL, "must specify %zu values", fields_.size()); |
| 220 | } else if ((size_t)arg.masks_size() != fields_.size()) { |
| 221 | return CommandFailure(EINVAL, "must specify %zu masks", fields_.size()); |
| 222 | } |
| 223 | |
| 224 | memset(key, 0, sizeof(*key)); |
| 225 | memset(mask, 0, sizeof(*mask)); |
| 226 | |
| 227 | for (size_t i = 0; i < fields_.size(); i++) { |
| 228 | int field_size = fields_[i].size; |
| 229 | int field_pos = fields_[i].pos; |
| 230 | |
| 231 | uint64_t v = 0; |
| 232 | uint64_t m = 0; |
| 233 | |
| 234 | bess::pb::FieldData valuedata = arg.values(i); |
| 235 | if (valuedata.encoding_case() == bess::pb::FieldData::kValueInt) { |
| 236 | if (!bess::utils::uint64_to_bin(&v, valuedata.value_int(), field_size, |
| 237 | true)) { |
| 238 | return CommandFailure(EINVAL, "idx %zu: not a correct %d-byte value", i, |
| 239 | field_size); |
| 240 | } |
| 241 | } else if (valuedata.encoding_case() == bess::pb::FieldData::kValueBin) { |
| 242 | bess::utils::Copy(reinterpret_cast<uint8_t *>(&v), |
| 243 | valuedata.value_bin().c_str(), |
| 244 | valuedata.value_bin().size()); |
| 245 | } |
| 246 | |
| 247 | bess::pb::FieldData maskdata = arg.masks(i); |
| 248 | if (maskdata.encoding_case() == bess::pb::FieldData::kValueInt) { |
| 249 | if (!bess::utils::uint64_to_bin(&m, maskdata.value_int(), field_size, |
| 250 | true)) { |
| 251 | return CommandFailure(EINVAL, "idx %zu: not a correct %d-byte mask", i, |
| 252 | field_size); |
| 253 | } |
| 254 | } else if (maskdata.encoding_case() == bess::pb::FieldData::kValueBin) { |
| 255 | bess::utils::Copy(reinterpret_cast<uint8_t *>(&m), |
| 256 | maskdata.value_bin().c_str(), |
| 257 | maskdata.value_bin().size()); |
| 258 | } |
| 259 | |
| 260 | if (v & ~m) { |
| 261 | return CommandFailure(EINVAL, |
| 262 | "idx %zu: invalid pair of " |
| 263 | "value 0x%0*" PRIx64 |
| 264 | " and " |
| 265 | "mask 0x%0*" PRIx64, |
| 266 | i, field_size * 2, v, field_size * 2, m); |
| 267 | } |
| 268 | |
| 269 | // Use memcpy, not utils::Copy, to workaround the false positive warning |
| 270 | // in g++-8 |
| 271 | memcpy(reinterpret_cast<uint8_t *>(key) + field_pos, &v, field_size); |
| 272 | memcpy(reinterpret_cast<uint8_t *>(mask) + field_pos, &m, field_size); |
| 273 | } |
nothing calls this directly
no test coverage detected