e698cc628504d4ebf2f15728ac0109d6f9a6275c
[sliver-openvswitch.git] / lib / nx-match.c
1 /*
2  * Copyright (c) 2010, 2011 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18
19 #include "nx-match.h"
20
21 #include <netinet/icmp6.h>
22
23 #include "classifier.h"
24 #include "dynamic-string.h"
25 #include "ofp-util.h"
26 #include "ofpbuf.h"
27 #include "openflow/nicira-ext.h"
28 #include "packets.h"
29 #include "unaligned.h"
30 #include "vlog.h"
31
32 VLOG_DEFINE_THIS_MODULE(nx_match);
33
34 /* Rate limit for nx_match parse errors.  These always indicate a bug in the
35  * peer and so there's not much point in showing a lot of them. */
36 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
37
38 enum {
39     NXM_INVALID = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_INVALID),
40     NXM_BAD_TYPE = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_TYPE),
41     NXM_BAD_VALUE = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_VALUE),
42     NXM_BAD_MASK = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_MASK),
43     NXM_BAD_PREREQ = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_PREREQ),
44     NXM_DUP_TYPE = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_DUP_TYPE),
45     BAD_ARGUMENT = OFP_MKERR(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT)
46 };
47
48 /* For each NXM_* field, define NFI_NXM_* as consecutive integers starting from
49  * zero. */
50 enum nxm_field_index {
51 #define DEFINE_FIELD(HEADER, WILDCARD, DL_TYPES, NW_PROTO, WRITABLE) \
52         NFI_NXM_##HEADER,
53 #include "nx-match.def"
54     N_NXM_FIELDS
55 };
56
57 struct nxm_field {
58     struct hmap_node hmap_node;
59     enum nxm_field_index index;       /* NFI_* value. */
60     uint32_t header;                  /* NXM_* value. */
61     flow_wildcards_t wildcard;        /* FWW_* bit, if exactly one. */
62     ovs_be16 dl_type[N_NXM_DL_TYPES]; /* dl_type prerequisites. */
63     uint8_t nw_proto;                 /* nw_proto prerequisite, if nonzero. */
64     const char *name;                 /* "NXM_*" string. */
65     bool writable;                    /* Writable with NXAST_REG_{MOVE,LOAD}? */
66 };
67
68
69 /* All the known fields. */
70 static struct nxm_field nxm_fields[N_NXM_FIELDS] = {
71 #define DEFINE_FIELD(HEADER, WILDCARD, DL_TYPES, NW_PROTO, WRITABLE)     \
72     { HMAP_NODE_NULL_INITIALIZER, NFI_NXM_##HEADER, NXM_##HEADER, WILDCARD, \
73         DL_CONVERT DL_TYPES, NW_PROTO, "NXM_" #HEADER, WRITABLE },
74 #define DL_CONVERT(T1, T2) { CONSTANT_HTONS(T1), CONSTANT_HTONS(T2) }
75 #include "nx-match.def"
76 };
77
78 /* Hash table of 'nxm_fields'. */
79 static struct hmap all_nxm_fields = HMAP_INITIALIZER(&all_nxm_fields);
80
81 static void
82 nxm_init(void)
83 {
84     if (hmap_is_empty(&all_nxm_fields)) {
85         int i;
86
87         for (i = 0; i < N_NXM_FIELDS; i++) {
88             struct nxm_field *f = &nxm_fields[i];
89             hmap_insert(&all_nxm_fields, &f->hmap_node,
90                         hash_int(f->header, 0));
91         }
92
93         /* Verify that the header values are unique (duplicate "case" values
94          * cause a compile error). */
95         switch (0) {
96 #define DEFINE_FIELD(HEADER, WILDCARD, DL_TYPE, NW_PROTO, WRITABLE)  \
97         case NXM_##HEADER: break;
98 #include "nx-match.def"
99         }
100     }
101 }
102
103 static const struct nxm_field *
104 nxm_field_lookup(uint32_t header)
105 {
106     struct nxm_field *f;
107
108     nxm_init();
109
110     HMAP_FOR_EACH_WITH_HASH (f, hmap_node, hash_int(header, 0),
111                              &all_nxm_fields) {
112         if (f->header == header) {
113             return f;
114         }
115     }
116
117     return NULL;
118 }
119
120 /* Returns the width of the data for a field with the given 'header', in
121  * bytes. */
122 int
123 nxm_field_bytes(uint32_t header)
124 {
125     unsigned int length = NXM_LENGTH(header);
126     return NXM_HASMASK(header) ? length / 2 : length;
127 }
128
129 /* Returns the width of the data for a field with the given 'header', in
130  * bits. */
131 int
132 nxm_field_bits(uint32_t header)
133 {
134     return nxm_field_bytes(header) * 8;
135 }
136 \f
137 /* nx_pull_match() and helpers. */
138
139 static int
140 parse_nx_reg(const struct nxm_field *f,
141              struct flow *flow, struct flow_wildcards *wc,
142              const void *value, const void *maskp)
143 {
144     int idx = NXM_NX_REG_IDX(f->header);
145     if (wc->reg_masks[idx]) {
146         return NXM_DUP_TYPE;
147     } else {
148         flow_wildcards_set_reg_mask(wc, idx,
149                                     (NXM_HASMASK(f->header)
150                                      ? ntohl(get_unaligned_be32(maskp))
151                                      : UINT32_MAX));
152         flow->regs[idx] = ntohl(get_unaligned_be32(value));
153         flow->regs[idx] &= wc->reg_masks[idx];
154         return 0;
155     }
156 }
157
158 static int
159 parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
160                 const void *value, const void *mask)
161 {
162     struct flow_wildcards *wc = &rule->wc;
163     struct flow *flow = &rule->flow;
164
165     switch (f->index) {
166         /* Metadata. */
167     case NFI_NXM_OF_IN_PORT:
168         flow->in_port = ntohs(get_unaligned_be16(value));
169         return 0;
170
171         /* Ethernet header. */
172     case NFI_NXM_OF_ETH_DST:
173         if ((wc->wildcards & (FWW_DL_DST | FWW_ETH_MCAST))
174             != (FWW_DL_DST | FWW_ETH_MCAST)) {
175             return NXM_DUP_TYPE;
176         } else {
177             wc->wildcards &= ~(FWW_DL_DST | FWW_ETH_MCAST);
178             memcpy(flow->dl_dst, value, ETH_ADDR_LEN);
179             return 0;
180         }
181     case NFI_NXM_OF_ETH_DST_W:
182         if ((wc->wildcards & (FWW_DL_DST | FWW_ETH_MCAST))
183             != (FWW_DL_DST | FWW_ETH_MCAST)) {
184             return NXM_DUP_TYPE;
185         } else if (flow_wildcards_is_dl_dst_mask_valid(mask)) {
186             cls_rule_set_dl_dst_masked(rule, value, mask);
187             return 0;
188         } else {
189             return NXM_BAD_MASK;
190         }
191     case NFI_NXM_OF_ETH_SRC:
192         memcpy(flow->dl_src, value, ETH_ADDR_LEN);
193         return 0;
194     case NFI_NXM_OF_ETH_TYPE:
195         flow->dl_type = ofputil_dl_type_from_openflow(get_unaligned_be16(value));
196         return 0;
197
198         /* 802.1Q header. */
199     case NFI_NXM_OF_VLAN_TCI:
200         if (wc->vlan_tci_mask) {
201             return NXM_DUP_TYPE;
202         } else {
203             cls_rule_set_dl_tci(rule, get_unaligned_be16(value));
204             return 0;
205         }
206     case NFI_NXM_OF_VLAN_TCI_W:
207         if (wc->vlan_tci_mask) {
208             return NXM_DUP_TYPE;
209         } else {
210             cls_rule_set_dl_tci_masked(rule, get_unaligned_be16(value),
211                                        get_unaligned_be16(mask));
212             return 0;
213         }
214
215         /* IP header. */
216     case NFI_NXM_OF_IP_TOS:
217         if (*(uint8_t *) value & 0x03) {
218             return NXM_BAD_VALUE;
219         } else {
220             flow->nw_tos = *(uint8_t *) value;
221             return 0;
222         }
223     case NFI_NXM_OF_IP_PROTO:
224         flow->nw_proto = *(uint8_t *) value;
225         return 0;
226
227         /* IP addresses in IP and ARP headers. */
228     case NFI_NXM_OF_IP_SRC:
229     case NFI_NXM_OF_ARP_SPA:
230         if (wc->nw_src_mask) {
231             return NXM_DUP_TYPE;
232         } else {
233             cls_rule_set_nw_src(rule, get_unaligned_be32(value));
234             return 0;
235         }
236     case NFI_NXM_OF_IP_SRC_W:
237     case NFI_NXM_OF_ARP_SPA_W:
238         if (wc->nw_src_mask) {
239             return NXM_DUP_TYPE;
240         } else {
241             ovs_be32 ip = get_unaligned_be32(value);
242             ovs_be32 netmask = get_unaligned_be32(mask);
243             if (!cls_rule_set_nw_src_masked(rule, ip, netmask)) {
244                 return NXM_BAD_MASK;
245             }
246             return 0;
247         }
248     case NFI_NXM_OF_IP_DST:
249     case NFI_NXM_OF_ARP_TPA:
250         if (wc->nw_dst_mask) {
251             return NXM_DUP_TYPE;
252         } else {
253             cls_rule_set_nw_dst(rule, get_unaligned_be32(value));
254             return 0;
255         }
256     case NFI_NXM_OF_IP_DST_W:
257     case NFI_NXM_OF_ARP_TPA_W:
258         if (wc->nw_dst_mask) {
259             return NXM_DUP_TYPE;
260         } else {
261             ovs_be32 ip = get_unaligned_be32(value);
262             ovs_be32 netmask = get_unaligned_be32(mask);
263             if (!cls_rule_set_nw_dst_masked(rule, ip, netmask)) {
264                 return NXM_BAD_MASK;
265             }
266             return 0;
267         }
268
269         /* IPv6 addresses. */
270     case NFI_NXM_NX_IPV6_SRC:
271         if (!ipv6_mask_is_any(&wc->ipv6_src_mask)) {
272             return NXM_DUP_TYPE;
273         } else {
274             struct in6_addr ipv6;
275             memcpy(&ipv6, value, sizeof ipv6);
276             cls_rule_set_ipv6_src(rule, &ipv6);
277             return 0;
278         }
279     case NFI_NXM_NX_IPV6_SRC_W:
280         if (!ipv6_mask_is_any(&wc->ipv6_src_mask)) {
281             return NXM_DUP_TYPE;
282         } else {
283             struct in6_addr ipv6, netmask;
284             memcpy(&ipv6, value, sizeof ipv6);
285             memcpy(&netmask, mask, sizeof netmask);
286             if (!cls_rule_set_ipv6_src_masked(rule, &ipv6, &netmask)) {
287                 return NXM_BAD_MASK;
288             }
289             return 0;
290         }
291     case NFI_NXM_NX_IPV6_DST:
292         if (!ipv6_mask_is_any(&wc->ipv6_dst_mask)) {
293             return NXM_DUP_TYPE;
294         } else {
295             struct in6_addr ipv6;
296             memcpy(&ipv6, value, sizeof ipv6);
297             cls_rule_set_ipv6_dst(rule, &ipv6);
298             return 0;
299         }
300     case NFI_NXM_NX_IPV6_DST_W:
301         if (!ipv6_mask_is_any(&wc->ipv6_dst_mask)) {
302             return NXM_DUP_TYPE;
303         } else {
304             struct in6_addr ipv6, netmask;
305             memcpy(&ipv6, value, sizeof ipv6);
306             memcpy(&netmask, mask, sizeof netmask);
307             if (!cls_rule_set_ipv6_dst_masked(rule, &ipv6, &netmask)) {
308                 return NXM_BAD_MASK;
309             }
310             return 0;
311         }
312
313         /* TCP header. */
314     case NFI_NXM_OF_TCP_SRC:
315         flow->tp_src = get_unaligned_be16(value);
316         return 0;
317     case NFI_NXM_OF_TCP_DST:
318         flow->tp_dst = get_unaligned_be16(value);
319         return 0;
320
321         /* UDP header. */
322     case NFI_NXM_OF_UDP_SRC:
323         flow->tp_src = get_unaligned_be16(value);
324         return 0;
325     case NFI_NXM_OF_UDP_DST:
326         flow->tp_dst = get_unaligned_be16(value);
327         return 0;
328
329         /* ICMP header. */
330     case NFI_NXM_OF_ICMP_TYPE:
331         flow->tp_src = htons(*(uint8_t *) value);
332         return 0;
333     case NFI_NXM_OF_ICMP_CODE:
334         flow->tp_dst = htons(*(uint8_t *) value);
335         return 0;
336
337         /* ICMPv6 header. */
338     case NFI_NXM_NX_ICMPV6_TYPE:
339         flow->tp_src = htons(*(uint8_t *) value);
340         return 0;
341     case NFI_NXM_NX_ICMPV6_CODE:
342         flow->tp_dst = htons(*(uint8_t *) value);
343         return 0;
344
345         /* IPv6 Neighbor Discovery. */
346     case NFI_NXM_NX_ND_TARGET:
347         /* We've already verified that it's an ICMPv6 message. */
348         if ((flow->tp_src != htons(ND_NEIGHBOR_SOLICIT))
349                     && (flow->tp_src != htons(ND_NEIGHBOR_ADVERT))) {
350             return NXM_BAD_PREREQ;
351         }
352         memcpy(&flow->nd_target, value, sizeof flow->nd_target);
353         return 0;
354     case NFI_NXM_NX_ND_SLL:
355         /* We've already verified that it's an ICMPv6 message. */
356         if (flow->tp_src != htons(ND_NEIGHBOR_SOLICIT)) {
357             return NXM_BAD_PREREQ;
358         }
359         memcpy(flow->arp_sha, value, ETH_ADDR_LEN);
360         return 0;
361     case NFI_NXM_NX_ND_TLL:
362         /* We've already verified that it's an ICMPv6 message. */
363         if (flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) {
364             return NXM_BAD_PREREQ;
365         }
366         memcpy(flow->arp_tha, value, ETH_ADDR_LEN);
367         return 0;
368
369         /* ARP header. */
370     case NFI_NXM_OF_ARP_OP:
371         if (ntohs(get_unaligned_be16(value)) > 255) {
372             return NXM_BAD_VALUE;
373         } else {
374             flow->nw_proto = ntohs(get_unaligned_be16(value));
375             return 0;
376         }
377
378     case NFI_NXM_NX_ARP_SHA:
379         memcpy(flow->arp_sha, value, ETH_ADDR_LEN);
380         return 0;
381     case NFI_NXM_NX_ARP_THA:
382         memcpy(flow->arp_tha, value, ETH_ADDR_LEN);
383         return 0;
384
385         /* Tunnel ID. */
386     case NFI_NXM_NX_TUN_ID:
387         if (wc->tun_id_mask) {
388             return NXM_DUP_TYPE;
389         } else {
390             cls_rule_set_tun_id(rule, get_unaligned_be64(value));
391             return 0;
392         }
393     case NFI_NXM_NX_TUN_ID_W:
394         if (wc->tun_id_mask) {
395             return NXM_DUP_TYPE;
396         } else {
397             ovs_be64 tun_id = get_unaligned_be64(value);
398             ovs_be64 tun_mask = get_unaligned_be64(mask);
399             cls_rule_set_tun_id_masked(rule, tun_id, tun_mask);
400             return 0;
401         }
402
403         /* Registers. */
404     case NFI_NXM_NX_REG0:
405     case NFI_NXM_NX_REG0_W:
406 #if FLOW_N_REGS >= 2
407     case NFI_NXM_NX_REG1:
408     case NFI_NXM_NX_REG1_W:
409 #endif
410 #if FLOW_N_REGS >= 3
411     case NFI_NXM_NX_REG2:
412     case NFI_NXM_NX_REG2_W:
413 #endif
414 #if FLOW_N_REGS >= 4
415     case NFI_NXM_NX_REG3:
416     case NFI_NXM_NX_REG3_W:
417 #endif
418 #if FLOW_N_REGS > 4
419 #error
420 #endif
421         return parse_nx_reg(f, flow, wc, value, mask);
422
423     case N_NXM_FIELDS:
424         NOT_REACHED();
425     }
426     NOT_REACHED();
427 }
428
429 static bool
430 nxm_prereqs_ok(const struct nxm_field *field, const struct flow *flow)
431 {
432     if (field->nw_proto && field->nw_proto != flow->nw_proto) {
433         return false;
434     }
435
436     if (!field->dl_type[0]) {
437         return true;
438     } else if (field->dl_type[0] == flow->dl_type) {
439         return true;
440     } else if (field->dl_type[1] && field->dl_type[1] == flow->dl_type) {
441         return true;
442     }
443
444     return false;
445 }
446
447 static uint32_t
448 nx_entry_ok(const void *p, unsigned int match_len)
449 {
450     unsigned int payload_len;
451     ovs_be32 header_be;
452     uint32_t header;
453
454     if (match_len < 4) {
455         if (match_len) {
456             VLOG_DBG_RL(&rl, "nx_match ends with partial nxm_header");
457         }
458         return 0;
459     }
460     memcpy(&header_be, p, 4);
461     header = ntohl(header_be);
462
463     payload_len = NXM_LENGTH(header);
464     if (!payload_len) {
465         VLOG_DBG_RL(&rl, "nxm_entry %08"PRIx32" has invalid payload "
466                     "length 0", header);
467         return 0;
468     }
469     if (match_len < payload_len + 4) {
470         VLOG_DBG_RL(&rl, "%"PRIu32"-byte nxm_entry but only "
471                     "%u bytes left in nx_match", payload_len + 4, match_len);
472         return 0;
473     }
474
475     return header;
476 }
477
478 int
479 nx_pull_match(struct ofpbuf *b, unsigned int match_len, uint16_t priority,
480               struct cls_rule *rule)
481 {
482     uint32_t header;
483     uint8_t *p;
484
485     p = ofpbuf_try_pull(b, ROUND_UP(match_len, 8));
486     if (!p) {
487         VLOG_DBG_RL(&rl, "nx_match length %u, rounded up to a "
488                     "multiple of 8, is longer than space in message (max "
489                     "length %zu)", match_len, b->size);
490         return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
491     }
492
493     cls_rule_init_catchall(rule, priority);
494     while ((header = nx_entry_ok(p, match_len)) != 0) {
495         unsigned length = NXM_LENGTH(header);
496         const struct nxm_field *f;
497         int error;
498
499         f = nxm_field_lookup(header);
500         if (!f) {
501             error = NXM_BAD_TYPE;
502         } else if (!nxm_prereqs_ok(f, &rule->flow)) {
503             error = NXM_BAD_PREREQ;
504         } else if (f->wildcard && !(rule->wc.wildcards & f->wildcard)) {
505             error = NXM_DUP_TYPE;
506         } else {
507             /* 'hasmask' and 'length' are known to be correct at this point
508              * because they are included in 'header' and nxm_field_lookup()
509              * checked them already. */
510             rule->wc.wildcards &= ~f->wildcard;
511             error = parse_nxm_entry(rule, f, p + 4, p + 4 + length / 2);
512         }
513         if (error) {
514             VLOG_DBG_RL(&rl, "bad nxm_entry with vendor=%"PRIu32", "
515                         "field=%"PRIu32", hasmask=%"PRIu32", type=%"PRIu32" "
516                         "(error %x)",
517                         NXM_VENDOR(header), NXM_FIELD(header),
518                         NXM_HASMASK(header), NXM_TYPE(header),
519                         error);
520             return error;
521         }
522
523
524         p += 4 + length;
525         match_len -= 4 + length;
526     }
527
528     return match_len ? NXM_INVALID : 0;
529 }
530 \f
531 /* nx_put_match() and helpers.
532  *
533  * 'put' functions whose names end in 'w' add a wildcarded field.
534  * 'put' functions whose names end in 'm' add a field that might be wildcarded.
535  * Other 'put' functions add exact-match fields.
536  */
537
538 static void
539 nxm_put_header(struct ofpbuf *b, uint32_t header)
540 {
541     ovs_be32 n_header = htonl(header);
542     ofpbuf_put(b, &n_header, sizeof n_header);
543 }
544
545 static void
546 nxm_put_8(struct ofpbuf *b, uint32_t header, uint8_t value)
547 {
548     nxm_put_header(b, header);
549     ofpbuf_put(b, &value, sizeof value);
550 }
551
552 static void
553 nxm_put_16(struct ofpbuf *b, uint32_t header, ovs_be16 value)
554 {
555     nxm_put_header(b, header);
556     ofpbuf_put(b, &value, sizeof value);
557 }
558
559 static void
560 nxm_put_16w(struct ofpbuf *b, uint32_t header, ovs_be16 value, ovs_be16 mask)
561 {
562     nxm_put_header(b, header);
563     ofpbuf_put(b, &value, sizeof value);
564     ofpbuf_put(b, &mask, sizeof mask);
565 }
566
567 static void
568 nxm_put_16m(struct ofpbuf *b, uint32_t header, ovs_be16 value, ovs_be16 mask)
569 {
570     switch (mask) {
571     case 0:
572         break;
573
574     case CONSTANT_HTONS(UINT16_MAX):
575         nxm_put_16(b, header, value);
576         break;
577
578     default:
579         nxm_put_16w(b, NXM_MAKE_WILD_HEADER(header), value, mask);
580         break;
581     }
582 }
583
584 static void
585 nxm_put_32(struct ofpbuf *b, uint32_t header, ovs_be32 value)
586 {
587     nxm_put_header(b, header);
588     ofpbuf_put(b, &value, sizeof value);
589 }
590
591 static void
592 nxm_put_32w(struct ofpbuf *b, uint32_t header, ovs_be32 value, ovs_be32 mask)
593 {
594     nxm_put_header(b, header);
595     ofpbuf_put(b, &value, sizeof value);
596     ofpbuf_put(b, &mask, sizeof mask);
597 }
598
599 static void
600 nxm_put_32m(struct ofpbuf *b, uint32_t header, ovs_be32 value, ovs_be32 mask)
601 {
602     switch (mask) {
603     case 0:
604         break;
605
606     case CONSTANT_HTONL(UINT32_MAX):
607         nxm_put_32(b, header, value);
608         break;
609
610     default:
611         nxm_put_32w(b, NXM_MAKE_WILD_HEADER(header), value, mask);
612         break;
613     }
614 }
615
616 static void
617 nxm_put_64(struct ofpbuf *b, uint32_t header, ovs_be64 value)
618 {
619     nxm_put_header(b, header);
620     ofpbuf_put(b, &value, sizeof value);
621 }
622
623 static void
624 nxm_put_64w(struct ofpbuf *b, uint32_t header, ovs_be64 value, ovs_be64 mask)
625 {
626     nxm_put_header(b, header);
627     ofpbuf_put(b, &value, sizeof value);
628     ofpbuf_put(b, &mask, sizeof mask);
629 }
630
631 static void
632 nxm_put_64m(struct ofpbuf *b, uint32_t header, ovs_be64 value, ovs_be64 mask)
633 {
634     switch (mask) {
635     case 0:
636         break;
637
638     case CONSTANT_HTONLL(UINT64_MAX):
639         nxm_put_64(b, header, value);
640         break;
641
642     default:
643         nxm_put_64w(b, NXM_MAKE_WILD_HEADER(header), value, mask);
644         break;
645     }
646 }
647
648 static void
649 nxm_put_eth(struct ofpbuf *b, uint32_t header,
650             const uint8_t value[ETH_ADDR_LEN])
651 {
652     nxm_put_header(b, header);
653     ofpbuf_put(b, value, ETH_ADDR_LEN);
654 }
655
656 static void
657 nxm_put_eth_dst(struct ofpbuf *b,
658                 flow_wildcards_t wc, const uint8_t value[ETH_ADDR_LEN])
659 {
660     switch (wc & (FWW_DL_DST | FWW_ETH_MCAST)) {
661     case FWW_DL_DST | FWW_ETH_MCAST:
662         break;
663     default:
664         nxm_put_header(b, NXM_OF_ETH_DST_W);
665         ofpbuf_put(b, value, ETH_ADDR_LEN);
666         ofpbuf_put(b, flow_wildcards_to_dl_dst_mask(wc), ETH_ADDR_LEN);
667         break;
668     case 0:
669         nxm_put_eth(b, NXM_OF_ETH_DST, value);
670         break;
671     }
672 }
673
674 static void
675 nxm_put_ipv6(struct ofpbuf *b, uint32_t header,
676              const struct in6_addr *value, const struct in6_addr *mask)
677 {
678     if (ipv6_mask_is_any(mask)) {
679         return;
680     } else if (ipv6_mask_is_exact(mask)) {
681         nxm_put_header(b, header);
682         ofpbuf_put(b, value, sizeof *value);
683     } else {
684         nxm_put_header(b, NXM_MAKE_WILD_HEADER(header));
685         ofpbuf_put(b, value, sizeof *value);
686         ofpbuf_put(b, mask, sizeof *mask);
687     }
688 }
689
690 /* Appends to 'b' the nx_match format that expresses 'cr' (except for
691  * 'cr->priority', because priority is not part of nx_match), plus enough
692  * zero bytes to pad the nx_match out to a multiple of 8.
693  *
694  * This function can cause 'b''s data to be reallocated.
695  *
696  * Returns the number of bytes appended to 'b', excluding padding.
697  *
698  * If 'cr' is a catch-all rule that matches every packet, then this function
699  * appends nothing to 'b' and returns 0. */
700 int
701 nx_put_match(struct ofpbuf *b, const struct cls_rule *cr)
702 {
703     const flow_wildcards_t wc = cr->wc.wildcards;
704     const struct flow *flow = &cr->flow;
705     const size_t start_len = b->size;
706     int match_len;
707     int i;
708
709     /* Metadata. */
710     if (!(wc & FWW_IN_PORT)) {
711         uint16_t in_port = flow->in_port;
712         nxm_put_16(b, NXM_OF_IN_PORT, htons(in_port));
713     }
714
715     /* Ethernet. */
716     nxm_put_eth_dst(b, wc, flow->dl_dst);
717     if (!(wc & FWW_DL_SRC)) {
718         nxm_put_eth(b, NXM_OF_ETH_SRC, flow->dl_src);
719     }
720     if (!(wc & FWW_DL_TYPE)) {
721         nxm_put_16(b, NXM_OF_ETH_TYPE,
722                    ofputil_dl_type_to_openflow(flow->dl_type));
723     }
724
725     /* 802.1Q. */
726     nxm_put_16m(b, NXM_OF_VLAN_TCI, flow->vlan_tci, cr->wc.vlan_tci_mask);
727
728     /* L3. */
729     if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_IP)) {
730         /* IP. */
731         if (!(wc & FWW_NW_TOS)) {
732             nxm_put_8(b, NXM_OF_IP_TOS, flow->nw_tos & 0xfc);
733         }
734         nxm_put_32m(b, NXM_OF_IP_SRC, flow->nw_src, cr->wc.nw_src_mask);
735         nxm_put_32m(b, NXM_OF_IP_DST, flow->nw_dst, cr->wc.nw_dst_mask);
736
737         if (!(wc & FWW_NW_PROTO)) {
738             nxm_put_8(b, NXM_OF_IP_PROTO, flow->nw_proto);
739             switch (flow->nw_proto) {
740                 /* TCP. */
741             case IPPROTO_TCP:
742                 if (!(wc & FWW_TP_SRC)) {
743                     nxm_put_16(b, NXM_OF_TCP_SRC, flow->tp_src);
744                 }
745                 if (!(wc & FWW_TP_DST)) {
746                     nxm_put_16(b, NXM_OF_TCP_DST, flow->tp_dst);
747                 }
748                 break;
749
750                 /* UDP. */
751             case IPPROTO_UDP:
752                 if (!(wc & FWW_TP_SRC)) {
753                     nxm_put_16(b, NXM_OF_UDP_SRC, flow->tp_src);
754                 }
755                 if (!(wc & FWW_TP_DST)) {
756                     nxm_put_16(b, NXM_OF_UDP_DST, flow->tp_dst);
757                 }
758                 break;
759
760                 /* ICMP. */
761             case IPPROTO_ICMP:
762                 if (!(wc & FWW_TP_SRC)) {
763                     nxm_put_8(b, NXM_OF_ICMP_TYPE, ntohs(flow->tp_src));
764                 }
765                 if (!(wc & FWW_TP_DST)) {
766                     nxm_put_8(b, NXM_OF_ICMP_CODE, ntohs(flow->tp_dst));
767                 }
768                 break;
769             }
770         }
771     } else if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_IPV6)) {
772         /* IPv6. */
773
774         if (!(wc & FWW_NW_TOS)) {
775             nxm_put_8(b, NXM_OF_IP_TOS, flow->nw_tos & 0xfc);
776         }
777         nxm_put_ipv6(b, NXM_NX_IPV6_SRC, &flow->ipv6_src,
778                 &cr->wc.ipv6_src_mask);
779         nxm_put_ipv6(b, NXM_NX_IPV6_DST, &flow->ipv6_dst,
780                 &cr->wc.ipv6_dst_mask);
781
782         if (!(wc & FWW_NW_PROTO)) {
783             nxm_put_8(b, NXM_OF_IP_PROTO, flow->nw_proto);
784             switch (flow->nw_proto) {
785                 /* TCP. */
786             case IPPROTO_TCP:
787                 if (!(wc & FWW_TP_SRC)) {
788                     nxm_put_16(b, NXM_OF_TCP_SRC, flow->tp_src);
789                 }
790                 if (!(wc & FWW_TP_DST)) {
791                     nxm_put_16(b, NXM_OF_TCP_DST, flow->tp_dst);
792                 }
793                 break;
794
795                 /* UDP. */
796             case IPPROTO_UDP:
797                 if (!(wc & FWW_TP_SRC)) {
798                     nxm_put_16(b, NXM_OF_UDP_SRC, flow->tp_src);
799                 }
800                 if (!(wc & FWW_TP_DST)) {
801                     nxm_put_16(b, NXM_OF_UDP_DST, flow->tp_dst);
802                 }
803                 break;
804
805                 /* ICMPv6. */
806             case IPPROTO_ICMPV6:
807                 if (!(wc & FWW_TP_SRC)) {
808                     nxm_put_8(b, NXM_NX_ICMPV6_TYPE, ntohs(flow->tp_src));
809
810                     if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) ||
811                         flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) {
812                         if (!(wc & FWW_ND_TARGET)) {
813                             nxm_put_ipv6(b, NXM_NX_ND_TARGET, &flow->nd_target,
814                                          &in6addr_exact);
815                         }
816                         if (!(wc & FWW_ARP_SHA)
817                             && flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) {
818                             nxm_put_eth(b, NXM_NX_ND_SLL, flow->arp_sha);
819                         }
820                         if (!(wc & FWW_ARP_THA)
821                             && flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) {
822                             nxm_put_eth(b, NXM_NX_ND_TLL, flow->arp_tha);
823                         }
824                     }
825                 }
826                 if (!(wc & FWW_TP_DST)) {
827                     nxm_put_8(b, NXM_NX_ICMPV6_CODE, ntohs(flow->tp_dst));
828                 }
829                 break;
830             }
831         }
832     } else if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_ARP)) {
833         /* ARP. */
834         if (!(wc & FWW_NW_PROTO)) {
835             nxm_put_16(b, NXM_OF_ARP_OP, htons(flow->nw_proto));
836         }
837         nxm_put_32m(b, NXM_OF_ARP_SPA, flow->nw_src, cr->wc.nw_src_mask);
838         nxm_put_32m(b, NXM_OF_ARP_TPA, flow->nw_dst, cr->wc.nw_dst_mask);
839         if (!(wc & FWW_ARP_SHA)) {
840             nxm_put_eth(b, NXM_NX_ARP_SHA, flow->arp_sha);
841         }
842         if (!(wc & FWW_ARP_THA)) {
843             nxm_put_eth(b, NXM_NX_ARP_THA, flow->arp_tha);
844         }
845     }
846
847     /* Tunnel ID. */
848     nxm_put_64m(b, NXM_NX_TUN_ID, flow->tun_id, cr->wc.tun_id_mask);
849
850     /* Registers. */
851     for (i = 0; i < FLOW_N_REGS; i++) {
852         nxm_put_32m(b, NXM_NX_REG(i),
853                     htonl(flow->regs[i]), htonl(cr->wc.reg_masks[i]));
854     }
855
856     match_len = b->size - start_len;
857     ofpbuf_put_zeros(b, ROUND_UP(match_len, 8) - match_len);
858     return match_len;
859 }
860 \f
861 /* nx_match_to_string() and helpers. */
862
863 static void format_nxm_field_name(struct ds *, uint32_t header);
864
865 char *
866 nx_match_to_string(const uint8_t *p, unsigned int match_len)
867 {
868     uint32_t header;
869     struct ds s;
870
871     if (!match_len) {
872         return xstrdup("<any>");
873     }
874
875     ds_init(&s);
876     while ((header = nx_entry_ok(p, match_len)) != 0) {
877         unsigned int length = NXM_LENGTH(header);
878         unsigned int value_len = nxm_field_bytes(header);
879         const uint8_t *value = p + 4;
880         const uint8_t *mask = value + value_len;
881         unsigned int i;
882
883         if (s.length) {
884             ds_put_cstr(&s, ", ");
885         }
886
887         format_nxm_field_name(&s, header);
888         ds_put_char(&s, '(');
889
890         for (i = 0; i < value_len; i++) {
891             ds_put_format(&s, "%02x", value[i]);
892         }
893         if (NXM_HASMASK(header)) {
894             ds_put_char(&s, '/');
895             for (i = 0; i < value_len; i++) {
896                 ds_put_format(&s, "%02x", mask[i]);
897             }
898         }
899         ds_put_char(&s, ')');
900
901         p += 4 + length;
902         match_len -= 4 + length;
903     }
904
905     if (match_len) {
906         if (s.length) {
907             ds_put_cstr(&s, ", ");
908         }
909
910         ds_put_format(&s, "<%u invalid bytes>", match_len);
911     }
912
913     return ds_steal_cstr(&s);
914 }
915
916 static void
917 format_nxm_field_name(struct ds *s, uint32_t header)
918 {
919     const struct nxm_field *f = nxm_field_lookup(header);
920     if (f) {
921         ds_put_cstr(s, f->name);
922     } else {
923         ds_put_format(s, "%d:%d", NXM_VENDOR(header), NXM_FIELD(header));
924     }
925 }
926
927 static uint32_t
928 parse_nxm_field_name(const char *name, int name_len)
929 {
930     const struct nxm_field *f;
931
932     /* Check whether it's a field name. */
933     for (f = nxm_fields; f < &nxm_fields[ARRAY_SIZE(nxm_fields)]; f++) {
934         if (!strncmp(f->name, name, name_len) && f->name[name_len] == '\0') {
935             return f->header;
936         }
937     }
938
939     /* Check whether it's a 32-bit field header value as hex.
940      * (This isn't ordinarily useful except for testing error behavior.) */
941     if (name_len == 8) {
942         uint32_t header = hexits_value(name, name_len, NULL);
943         if (header != UINT_MAX) {
944             return header;
945         }
946     }
947
948     return 0;
949 }
950 \f
951 /* nx_match_from_string(). */
952
953 int
954 nx_match_from_string(const char *s, struct ofpbuf *b)
955 {
956     const char *full_s = s;
957     const size_t start_len = b->size;
958     int match_len;
959
960     if (!strcmp(s, "<any>")) {
961         /* Ensure that 'b->data' isn't actually null. */
962         ofpbuf_prealloc_tailroom(b, 1);
963         return 0;
964     }
965
966     for (s += strspn(s, ", "); *s; s += strspn(s, ", ")) {
967         const char *name;
968         uint32_t header;
969         int name_len;
970         size_t n;
971
972         name = s;
973         name_len = strcspn(s, "(");
974         if (s[name_len] != '(') {
975             ovs_fatal(0, "%s: missing ( at end of nx_match", full_s);
976         }
977
978         header = parse_nxm_field_name(name, name_len);
979         if (!header) {
980             ovs_fatal(0, "%s: unknown field `%.*s'", full_s, name_len, s);
981         }
982
983         s += name_len + 1;
984
985         nxm_put_header(b, header);
986         s = ofpbuf_put_hex(b, s, &n);
987         if (n != nxm_field_bytes(header)) {
988             ovs_fatal(0, "%.2s: hex digits expected", s);
989         }
990         if (NXM_HASMASK(header)) {
991             s += strspn(s, " ");
992             if (*s != '/') {
993                 ovs_fatal(0, "%s: missing / in masked field %.*s",
994                           full_s, name_len, name);
995             }
996             s = ofpbuf_put_hex(b, s + 1, &n);
997             if (n != nxm_field_bytes(header)) {
998                 ovs_fatal(0, "%.2s: hex digits expected", s);
999             }
1000         }
1001
1002         s += strspn(s, " ");
1003         if (*s != ')') {
1004             ovs_fatal(0, "%s: missing ) following field %.*s",
1005                       full_s, name_len, name);
1006         }
1007         s++;
1008     }
1009
1010     match_len = b->size - start_len;
1011     ofpbuf_put_zeros(b, ROUND_UP(match_len, 8) - match_len);
1012     return match_len;
1013 }
1014 \f
1015 const char *
1016 nxm_parse_field_bits(const char *s, uint32_t *headerp, int *ofsp, int *n_bitsp)
1017 {
1018     const char *full_s = s;
1019     const char *name;
1020     uint32_t header;
1021     int start, end;
1022     int name_len;
1023     int width;
1024
1025     name = s;
1026     name_len = strcspn(s, "[");
1027     if (s[name_len] != '[') {
1028         ovs_fatal(0, "%s: missing [ looking for field name", full_s);
1029     }
1030
1031     header = parse_nxm_field_name(name, name_len);
1032     if (!header) {
1033         ovs_fatal(0, "%s: unknown field `%.*s'", full_s, name_len, s);
1034     }
1035     width = nxm_field_bits(header);
1036
1037     s += name_len;
1038     if (sscanf(s, "[%d..%d]", &start, &end) == 2) {
1039         /* Nothing to do. */
1040     } else if (sscanf(s, "[%d]", &start) == 1) {
1041         end = start;
1042     } else if (!strncmp(s, "[]", 2)) {
1043         start = 0;
1044         end = width - 1;
1045     } else {
1046         ovs_fatal(0, "%s: syntax error expecting [] or [<bit>] or "
1047                   "[<start>..<end>]", full_s);
1048     }
1049     s = strchr(s, ']') + 1;
1050
1051     if (start > end) {
1052         ovs_fatal(0, "%s: starting bit %d is after ending bit %d",
1053                   full_s, start, end);
1054     } else if (start >= width) {
1055         ovs_fatal(0, "%s: starting bit %d is not valid because field is only "
1056                   "%d bits wide", full_s, start, width);
1057     } else if (end >= width){
1058         ovs_fatal(0, "%s: ending bit %d is not valid because field is only "
1059                   "%d bits wide", full_s, end, width);
1060     }
1061
1062     *headerp = header;
1063     *ofsp = start;
1064     *n_bitsp = end - start + 1;
1065
1066     return s;
1067 }
1068
1069 void
1070 nxm_parse_reg_move(struct nx_action_reg_move *move, const char *s)
1071 {
1072     const char *full_s = s;
1073     uint32_t src, dst;
1074     int src_ofs, dst_ofs;
1075     int src_n_bits, dst_n_bits;
1076
1077     s = nxm_parse_field_bits(s, &src, &src_ofs, &src_n_bits);
1078     if (strncmp(s, "->", 2)) {
1079         ovs_fatal(0, "%s: missing `->' following source", full_s);
1080     }
1081     s += 2;
1082     s = nxm_parse_field_bits(s, &dst, &dst_ofs, &dst_n_bits);
1083     if (*s != '\0') {
1084         ovs_fatal(0, "%s: trailing garbage following destination", full_s);
1085     }
1086
1087     if (src_n_bits != dst_n_bits) {
1088         ovs_fatal(0, "%s: source field is %d bits wide but destination is "
1089                   "%d bits wide", full_s, src_n_bits, dst_n_bits);
1090     }
1091
1092     move->type = htons(OFPAT_VENDOR);
1093     move->len = htons(sizeof *move);
1094     move->vendor = htonl(NX_VENDOR_ID);
1095     move->subtype = htons(NXAST_REG_MOVE);
1096     move->n_bits = htons(src_n_bits);
1097     move->src_ofs = htons(src_ofs);
1098     move->dst_ofs = htons(dst_ofs);
1099     move->src = htonl(src);
1100     move->dst = htonl(dst);
1101 }
1102
1103 void
1104 nxm_parse_reg_load(struct nx_action_reg_load *load, const char *s)
1105 {
1106     const char *full_s = s;
1107     uint32_t dst;
1108     int ofs, n_bits;
1109     uint64_t value;
1110
1111     value = strtoull(s, (char **) &s, 0);
1112     if (strncmp(s, "->", 2)) {
1113         ovs_fatal(0, "%s: missing `->' following value", full_s);
1114     }
1115     s += 2;
1116     s = nxm_parse_field_bits(s, &dst, &ofs, &n_bits);
1117     if (*s != '\0') {
1118         ovs_fatal(0, "%s: trailing garbage following destination", full_s);
1119     }
1120
1121     if (n_bits < 64 && (value >> n_bits) != 0) {
1122         ovs_fatal(0, "%s: value %"PRIu64" does not fit into %d bits",
1123                   full_s, value, n_bits);
1124     }
1125
1126     load->type = htons(OFPAT_VENDOR);
1127     load->len = htons(sizeof *load);
1128     load->vendor = htonl(NX_VENDOR_ID);
1129     load->subtype = htons(NXAST_REG_LOAD);
1130     load->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits);
1131     load->dst = htonl(dst);
1132     load->value = htonll(value);
1133 }
1134 \f
1135 /* nxm_format_reg_move(), nxm_format_reg_load(). */
1136
1137 void
1138 nxm_format_field_bits(struct ds *s, uint32_t header, int ofs, int n_bits)
1139 {
1140     format_nxm_field_name(s, header);
1141     if (ofs == 0 && n_bits == nxm_field_bits(header)) {
1142         ds_put_cstr(s, "[]");
1143     } else if (n_bits == 1) {
1144         ds_put_format(s, "[%d]", ofs);
1145     } else {
1146         ds_put_format(s, "[%d..%d]", ofs, ofs + n_bits - 1);
1147     }
1148 }
1149
1150 void
1151 nxm_format_reg_move(const struct nx_action_reg_move *move, struct ds *s)
1152 {
1153     int n_bits = ntohs(move->n_bits);
1154     int src_ofs = ntohs(move->src_ofs);
1155     int dst_ofs = ntohs(move->dst_ofs);
1156     uint32_t src = ntohl(move->src);
1157     uint32_t dst = ntohl(move->dst);
1158
1159     ds_put_format(s, "move:");
1160     nxm_format_field_bits(s, src, src_ofs, n_bits);
1161     ds_put_cstr(s, "->");
1162     nxm_format_field_bits(s, dst, dst_ofs, n_bits);
1163 }
1164
1165 void
1166 nxm_format_reg_load(const struct nx_action_reg_load *load, struct ds *s)
1167 {
1168     int ofs = nxm_decode_ofs(load->ofs_nbits);
1169     int n_bits = nxm_decode_n_bits(load->ofs_nbits);
1170     uint32_t dst = ntohl(load->dst);
1171     uint64_t value = ntohll(load->value);
1172
1173     ds_put_format(s, "load:%#"PRIx64"->", value);
1174     nxm_format_field_bits(s, dst, ofs, n_bits);
1175 }
1176 \f
1177 /* nxm_check_reg_move(), nxm_check_reg_load(). */
1178
1179 static bool
1180 field_ok(const struct nxm_field *f, const struct flow *flow, int size)
1181 {
1182     return (f && !NXM_HASMASK(f->header)
1183             && nxm_prereqs_ok(f, flow) && size <= nxm_field_bits(f->header));
1184 }
1185
1186 int
1187 nxm_check_reg_move(const struct nx_action_reg_move *action,
1188                    const struct flow *flow)
1189 {
1190     const struct nxm_field *src;
1191     const struct nxm_field *dst;
1192
1193     if (action->n_bits == htons(0)) {
1194         return BAD_ARGUMENT;
1195     }
1196
1197     src = nxm_field_lookup(ntohl(action->src));
1198     if (!field_ok(src, flow, ntohs(action->src_ofs) + ntohs(action->n_bits))) {
1199         return BAD_ARGUMENT;
1200     }
1201
1202     dst = nxm_field_lookup(ntohl(action->dst));
1203     if (!field_ok(dst, flow, ntohs(action->dst_ofs) + ntohs(action->n_bits))) {
1204         return BAD_ARGUMENT;
1205     }
1206
1207     if (!dst->writable) {
1208         return BAD_ARGUMENT;
1209     }
1210
1211     return 0;
1212 }
1213
1214 /* Given a flow, checks that the destination field represented by 'dst_header'
1215  * and 'ofs_nbits' is valid and large enough for 'min_n_bits' bits of data. */
1216 int
1217 nxm_dst_check(ovs_be32 dst_header, ovs_be16 ofs_nbits, size_t min_n_bits,
1218               const struct flow *flow)
1219 {
1220     const struct nxm_field *dst;
1221     int ofs, n_bits;
1222
1223     ofs = nxm_decode_ofs(ofs_nbits);
1224     n_bits = nxm_decode_n_bits(ofs_nbits);
1225     dst = nxm_field_lookup(ntohl(dst_header));
1226
1227     if (!field_ok(dst, flow, ofs + n_bits)) {
1228         VLOG_WARN_RL(&rl, "invalid destination field");
1229     } else if (!dst->writable) {
1230         VLOG_WARN_RL(&rl, "destination field is not writable");
1231     } else if (n_bits < min_n_bits) {
1232         VLOG_WARN_RL(&rl, "insufficient bits in destination");
1233     } else {
1234         return 0;
1235     }
1236
1237     return BAD_ARGUMENT;
1238 }
1239
1240 int
1241 nxm_check_reg_load(const struct nx_action_reg_load *action,
1242                    const struct flow *flow)
1243 {
1244     int n_bits;
1245     int error;
1246
1247     error = nxm_dst_check(action->dst, action->ofs_nbits, 0, flow);
1248     if (error) {
1249         return error;
1250     }
1251
1252     /* Reject 'action' if a bit numbered 'n_bits' or higher is set to 1 in
1253      * action->value. */
1254     n_bits = nxm_decode_n_bits(action->ofs_nbits);
1255     if (n_bits < 64 && ntohll(action->value) >> n_bits) {
1256         return BAD_ARGUMENT;
1257     }
1258
1259     return 0;
1260 }
1261 \f
1262 /* nxm_execute_reg_move(), nxm_execute_reg_load(). */
1263
1264 static uint64_t
1265 nxm_read_field(const struct nxm_field *src, const struct flow *flow)
1266 {
1267     switch (src->index) {
1268     case NFI_NXM_OF_IN_PORT:
1269         return flow->in_port;
1270
1271     case NFI_NXM_OF_ETH_DST:
1272         return eth_addr_to_uint64(flow->dl_dst);
1273
1274     case NFI_NXM_OF_ETH_SRC:
1275         return eth_addr_to_uint64(flow->dl_src);
1276
1277     case NFI_NXM_OF_ETH_TYPE:
1278         return ntohs(ofputil_dl_type_to_openflow(flow->dl_type));
1279
1280     case NFI_NXM_OF_VLAN_TCI:
1281         return ntohs(flow->vlan_tci);
1282
1283     case NFI_NXM_OF_IP_TOS:
1284         return flow->nw_tos;
1285
1286     case NFI_NXM_OF_IP_PROTO:
1287     case NFI_NXM_OF_ARP_OP:
1288         return flow->nw_proto;
1289
1290     case NFI_NXM_OF_IP_SRC:
1291     case NFI_NXM_OF_ARP_SPA:
1292         return ntohl(flow->nw_src);
1293
1294     case NFI_NXM_OF_IP_DST:
1295     case NFI_NXM_OF_ARP_TPA:
1296         return ntohl(flow->nw_dst);
1297
1298     case NFI_NXM_OF_TCP_SRC:
1299     case NFI_NXM_OF_UDP_SRC:
1300         return ntohs(flow->tp_src);
1301
1302     case NFI_NXM_OF_TCP_DST:
1303     case NFI_NXM_OF_UDP_DST:
1304         return ntohs(flow->tp_dst);
1305
1306     case NFI_NXM_OF_ICMP_TYPE:
1307     case NFI_NXM_NX_ICMPV6_TYPE:
1308         return ntohs(flow->tp_src) & 0xff;
1309
1310     case NFI_NXM_OF_ICMP_CODE:
1311     case NFI_NXM_NX_ICMPV6_CODE:
1312         return ntohs(flow->tp_dst) & 0xff;
1313
1314     case NFI_NXM_NX_TUN_ID:
1315         return ntohll(flow->tun_id);
1316
1317 #define NXM_READ_REGISTER(IDX)                  \
1318     case NFI_NXM_NX_REG##IDX:                   \
1319         return flow->regs[IDX];                 \
1320     case NFI_NXM_NX_REG##IDX##_W:               \
1321         NOT_REACHED();
1322
1323     NXM_READ_REGISTER(0);
1324 #if FLOW_N_REGS >= 2
1325     NXM_READ_REGISTER(1);
1326 #endif
1327 #if FLOW_N_REGS >= 3
1328     NXM_READ_REGISTER(2);
1329 #endif
1330 #if FLOW_N_REGS >= 4
1331     NXM_READ_REGISTER(3);
1332 #endif
1333 #if FLOW_N_REGS > 4
1334 #error
1335 #endif
1336
1337     case NFI_NXM_NX_ARP_SHA:
1338     case NFI_NXM_NX_ND_SLL:
1339         return eth_addr_to_uint64(flow->arp_sha);
1340
1341     case NFI_NXM_NX_ARP_THA:
1342     case NFI_NXM_NX_ND_TLL:
1343         return eth_addr_to_uint64(flow->arp_tha);
1344
1345     case NFI_NXM_NX_TUN_ID_W:
1346     case NFI_NXM_OF_ETH_DST_W:
1347     case NFI_NXM_OF_VLAN_TCI_W:
1348     case NFI_NXM_OF_IP_SRC_W:
1349     case NFI_NXM_OF_IP_DST_W:
1350     case NFI_NXM_OF_ARP_SPA_W:
1351     case NFI_NXM_OF_ARP_TPA_W:
1352     case NFI_NXM_NX_IPV6_SRC:
1353     case NFI_NXM_NX_IPV6_SRC_W:
1354     case NFI_NXM_NX_IPV6_DST:
1355     case NFI_NXM_NX_IPV6_DST_W:
1356     case NFI_NXM_NX_ND_TARGET:
1357     case N_NXM_FIELDS:
1358         NOT_REACHED();
1359     }
1360
1361     NOT_REACHED();
1362 }
1363
1364 static void
1365 nxm_write_field(const struct nxm_field *dst, struct flow *flow,
1366                 uint64_t new_value)
1367 {
1368     switch (dst->index) {
1369     case NFI_NXM_OF_ETH_DST:
1370         eth_addr_from_uint64(new_value, flow->dl_dst);
1371         break;
1372
1373     case NFI_NXM_OF_ETH_SRC:
1374         eth_addr_from_uint64(new_value, flow->dl_src);
1375         break;
1376
1377     case NFI_NXM_OF_VLAN_TCI:
1378         flow->vlan_tci = htons(new_value);
1379         break;
1380
1381     case NFI_NXM_NX_TUN_ID:
1382         flow->tun_id = htonll(new_value);
1383         break;
1384
1385 #define NXM_WRITE_REGISTER(IDX)                 \
1386     case NFI_NXM_NX_REG##IDX:                   \
1387         flow->regs[IDX] = new_value;            \
1388         break;                                  \
1389     case NFI_NXM_NX_REG##IDX##_W:               \
1390         NOT_REACHED();
1391
1392     NXM_WRITE_REGISTER(0);
1393 #if FLOW_N_REGS >= 2
1394     NXM_WRITE_REGISTER(1);
1395 #endif
1396 #if FLOW_N_REGS >= 3
1397     NXM_WRITE_REGISTER(2);
1398 #endif
1399 #if FLOW_N_REGS >= 4
1400     NXM_WRITE_REGISTER(3);
1401 #endif
1402 #if FLOW_N_REGS > 4
1403 #error
1404 #endif
1405
1406     case NFI_NXM_OF_IP_TOS:
1407         flow->nw_tos = new_value & IP_DSCP_MASK;
1408         break;
1409
1410     case NFI_NXM_OF_IP_SRC:
1411         flow->nw_src = htonl(new_value);
1412         break;
1413
1414     case NFI_NXM_OF_IP_DST:
1415         flow->nw_dst = htonl(new_value);
1416         break;
1417
1418     case NFI_NXM_OF_TCP_SRC:
1419     case NFI_NXM_OF_UDP_SRC:
1420         flow->tp_src = htons(new_value);
1421         break;
1422
1423     case NFI_NXM_OF_TCP_DST:
1424     case NFI_NXM_OF_UDP_DST:
1425         flow->tp_dst = htons(new_value);
1426         break;
1427
1428     case NFI_NXM_OF_IN_PORT:
1429     case NFI_NXM_OF_ETH_TYPE:
1430     case NFI_NXM_OF_IP_PROTO:
1431     case NFI_NXM_OF_ARP_OP:
1432     case NFI_NXM_OF_ARP_SPA:
1433     case NFI_NXM_OF_ARP_TPA:
1434     case NFI_NXM_OF_ICMP_TYPE:
1435     case NFI_NXM_OF_ICMP_CODE:
1436     case NFI_NXM_NX_TUN_ID_W:
1437     case NFI_NXM_OF_ETH_DST_W:
1438     case NFI_NXM_OF_VLAN_TCI_W:
1439     case NFI_NXM_OF_IP_SRC_W:
1440     case NFI_NXM_OF_IP_DST_W:
1441     case NFI_NXM_OF_ARP_SPA_W:
1442     case NFI_NXM_OF_ARP_TPA_W:
1443     case NFI_NXM_NX_ARP_SHA:
1444     case NFI_NXM_NX_ARP_THA:
1445     case NFI_NXM_NX_IPV6_SRC:
1446     case NFI_NXM_NX_IPV6_SRC_W:
1447     case NFI_NXM_NX_IPV6_DST:
1448     case NFI_NXM_NX_IPV6_DST_W:
1449     case NFI_NXM_NX_ICMPV6_TYPE:
1450     case NFI_NXM_NX_ICMPV6_CODE:
1451     case NFI_NXM_NX_ND_TARGET:
1452     case NFI_NXM_NX_ND_SLL:
1453     case NFI_NXM_NX_ND_TLL:
1454     case N_NXM_FIELDS:
1455         NOT_REACHED();
1456     }
1457 }
1458
1459 void
1460 nxm_execute_reg_move(const struct nx_action_reg_move *action,
1461                      struct flow *flow)
1462 {
1463     /* Preparation. */
1464     int n_bits = ntohs(action->n_bits);
1465     uint64_t mask = n_bits == 64 ? UINT64_MAX : (UINT64_C(1) << n_bits) - 1;
1466
1467     /* Get the interesting bits of the source field. */
1468     const struct nxm_field *src = nxm_field_lookup(ntohl(action->src));
1469     int src_ofs = ntohs(action->src_ofs);
1470     uint64_t src_data = nxm_read_field(src, flow) & (mask << src_ofs);
1471
1472     nxm_reg_load(action->dst,
1473                  nxm_encode_ofs_nbits(ntohs(action->dst_ofs), n_bits),
1474                  src_data, flow);
1475 }
1476
1477 void
1478 nxm_execute_reg_load(const struct nx_action_reg_load *action,
1479                      struct flow *flow)
1480 {
1481     nxm_reg_load(action->dst, action->ofs_nbits, ntohll(action->value), flow);
1482 }
1483
1484 /* Calculates ofs and n_bits from the given 'ofs_nbits' parameter, and copies
1485  * 'src_data'[0:n_bits] to 'dst_header'[ofs:ofs+n_bits] in the given 'flow'. */
1486 void
1487 nxm_reg_load(ovs_be32 dst_header, ovs_be16 ofs_nbits, uint64_t src_data,
1488              struct flow *flow)
1489 {
1490     int n_bits = nxm_decode_n_bits(ofs_nbits);
1491     int dst_ofs = nxm_decode_ofs(ofs_nbits);
1492     uint64_t mask = n_bits == 64 ? UINT64_MAX : (UINT64_C(1) << n_bits) - 1;
1493
1494     /* Get remaining bits of the destination field. */
1495     const struct nxm_field *dst = nxm_field_lookup(ntohl(dst_header));
1496     uint64_t dst_data = nxm_read_field(dst, flow) & ~(mask << dst_ofs);
1497
1498     /* Get the final value. */
1499     uint64_t new_data = dst_data | (src_data << dst_ofs);
1500
1501     nxm_write_field(dst, flow, new_data);
1502 }