~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to lib/odp-util.c

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
 * from another. */
49
49
static const char *delimiters = ", \t\r\n";
50
50
 
51
 
static int parse_odp_key_attr(const char *, const struct simap *port_names,
52
 
                              struct ofpbuf *);
53
 
static void format_odp_key_attr(const struct nlattr *a, struct ds *ds);
 
51
static int parse_odp_key_mask_attr(const char *, const struct simap *port_names,
 
52
                              struct ofpbuf *, struct ofpbuf *);
 
53
static void format_odp_key_attr(const struct nlattr *a,
 
54
                                const struct nlattr *ma, struct ds *ds);
54
55
 
55
56
/* Returns one the following for the action with the given OVS_ACTION_ATTR_*
56
57
 * 'type':
73
74
    case OVS_ACTION_ATTR_USERSPACE: return -2;
74
75
    case OVS_ACTION_ATTR_PUSH_VLAN: return sizeof(struct ovs_action_push_vlan);
75
76
    case OVS_ACTION_ATTR_POP_VLAN: return 0;
 
77
    case OVS_ACTION_ATTR_PUSH_MPLS: return sizeof(struct ovs_action_push_mpls);
 
78
    case OVS_ACTION_ATTR_POP_MPLS: return sizeof(ovs_be16);
76
79
    case OVS_ACTION_ATTR_SET: return -2;
77
80
    case OVS_ACTION_ATTR_SAMPLE: return -2;
78
81
 
84
87
    return -1;
85
88
}
86
89
 
 
90
/* Returns a string form of 'attr'.  The return value is either a statically
 
91
 * allocated constant string or the 'bufsize'-byte buffer 'namebuf'.  'bufsize'
 
92
 * should be at least OVS_KEY_ATTR_BUFSIZE. */
 
93
enum { OVS_KEY_ATTR_BUFSIZE = 3 + INT_STRLEN(unsigned int) + 1 };
87
94
static const char *
88
 
ovs_key_attr_to_string(enum ovs_key_attr attr)
 
95
ovs_key_attr_to_string(enum ovs_key_attr attr, char *namebuf, size_t bufsize)
89
96
{
90
 
    static char unknown_attr[3 + INT_STRLEN(unsigned int) + 1];
91
 
 
92
97
    switch (attr) {
93
98
    case OVS_KEY_ATTR_UNSPEC: return "unspec";
94
99
    case OVS_KEY_ATTR_ENCAP: return "encap";
107
112
    case OVS_KEY_ATTR_ICMPV6: return "icmpv6";
108
113
    case OVS_KEY_ATTR_ARP: return "arp";
109
114
    case OVS_KEY_ATTR_ND: return "nd";
 
115
    case OVS_KEY_ATTR_MPLS: return "mpls";
110
116
 
111
117
    case __OVS_KEY_ATTR_MAX:
112
118
    default:
113
 
        snprintf(unknown_attr, sizeof unknown_attr, "key%u",
114
 
                 (unsigned int) attr);
115
 
        return unknown_attr;
 
119
        snprintf(namebuf, bufsize, "key%u", (unsigned int) attr);
 
120
        return namebuf;
116
121
    }
117
122
}
118
123
 
139
144
format_odp_sample_action(struct ds *ds, const struct nlattr *attr)
140
145
{
141
146
    static const struct nl_policy ovs_sample_policy[] = {
142
 
        [OVS_SAMPLE_ATTR_PROBABILITY] = { .type = NL_A_U32 },
143
 
        [OVS_SAMPLE_ATTR_ACTIONS] = { .type = NL_A_NESTED }
 
147
        { NL_A_NO_ATTR, 0, 0, false }, /* OVS_SAMPLE_ATTR_UNSPEC */
 
148
        { NL_A_U32, 0, 0, false },     /* OVS_SAMPLE_ATTR_PROBABILITY */
 
149
        { NL_A_NESTED, 0, 0, false },  /* OVS_SAMPLE_ATTR_ACTIONS */
144
150
    };
145
151
    struct nlattr *a[ARRAY_SIZE(ovs_sample_policy)];
146
152
    double percentage;
167
173
}
168
174
 
169
175
static const char *
170
 
slow_path_reason_to_string(uint32_t data)
 
176
slow_path_reason_to_string(enum slow_path_reason reason)
171
177
{
172
 
    enum slow_path_reason bit = (enum slow_path_reason) data;
173
 
 
174
 
    switch (bit) {
 
178
    switch (reason) {
175
179
    case SLOW_CFM:
176
180
        return "cfm";
177
181
    case SLOW_LACP:
178
182
        return "lacp";
179
183
    case SLOW_STP:
180
184
        return "stp";
181
 
    case SLOW_IN_BAND:
182
 
        return "in_band";
 
185
    case SLOW_BFD:
 
186
        return "bfd";
183
187
    case SLOW_CONTROLLER:
184
188
        return "controller";
185
 
    case SLOW_MATCH:
186
 
        return "match";
 
189
    case __SLOW_MAX:
187
190
    default:
188
191
        return NULL;
189
192
    }
190
193
}
191
194
 
 
195
static enum slow_path_reason
 
196
string_to_slow_path_reason(const char *string)
 
197
{
 
198
    enum slow_path_reason i;
 
199
 
 
200
    for (i = 1; i < __SLOW_MAX; i++) {
 
201
        if (!strcmp(string, slow_path_reason_to_string(i))) {
 
202
            return i;
 
203
        }
 
204
    }
 
205
 
 
206
    return 0;
 
207
}
 
208
 
192
209
static int
193
210
parse_flags(const char *s, const char *(*bit_to_string)(uint32_t),
194
211
            uint32_t *res)
243
260
format_odp_userspace_action(struct ds *ds, const struct nlattr *attr)
244
261
{
245
262
    static const struct nl_policy ovs_userspace_policy[] = {
246
 
        [OVS_USERSPACE_ATTR_PID] = { .type = NL_A_U32 },
247
 
        [OVS_USERSPACE_ATTR_USERDATA] = { .type = NL_A_U64, .optional = true },
 
263
        { NL_A_NO_ATTR, 0, 0, false }, /* OVS_USERSPACE_ATTR_UNSPEC */
 
264
        { NL_A_U32, 0, 0, false },     /* OVS_USERSPACE_ATTR_PID */
 
265
        { NL_A_UNSPEC, 0, 0, true },   /* OVS_USERSPACE_ATTR_USERDATA */
248
266
    };
249
267
    struct nlattr *a[ARRAY_SIZE(ovs_userspace_policy)];
 
268
    const struct nlattr *userdata_attr;
250
269
 
251
270
    if (!nl_parse_nested(attr, ovs_userspace_policy, a, ARRAY_SIZE(a))) {
252
271
        ds_put_cstr(ds, "userspace(error)");
256
275
    ds_put_format(ds, "userspace(pid=%"PRIu32,
257
276
                  nl_attr_get_u32(a[OVS_USERSPACE_ATTR_PID]));
258
277
 
259
 
    if (a[OVS_USERSPACE_ATTR_USERDATA]) {
260
 
        uint64_t userdata = nl_attr_get_u64(a[OVS_USERSPACE_ATTR_USERDATA]);
 
278
    userdata_attr = a[OVS_USERSPACE_ATTR_USERDATA];
 
279
 
 
280
    if (userdata_attr) {
 
281
        const uint8_t *userdata = nl_attr_get(userdata_attr);
 
282
        size_t userdata_len = nl_attr_get_size(userdata_attr);
 
283
        bool userdata_unspec = true;
261
284
        union user_action_cookie cookie;
262
285
 
263
 
        memcpy(&cookie, &userdata, sizeof cookie);
264
 
 
265
 
        switch (cookie.type) {
266
 
        case USER_ACTION_COOKIE_SFLOW:
267
 
            ds_put_format(ds, ",sFlow("
268
 
                          "vid=%"PRIu16",pcp=%"PRIu8",output=%"PRIu32")",
269
 
                          vlan_tci_to_vid(cookie.sflow.vlan_tci),
270
 
                          vlan_tci_to_pcp(cookie.sflow.vlan_tci),
271
 
                          cookie.sflow.output);
272
 
            break;
273
 
 
274
 
        case USER_ACTION_COOKIE_SLOW_PATH:
275
 
            ds_put_cstr(ds, ",slow_path(");
276
 
            format_flags(ds, slow_path_reason_to_string,
277
 
                         cookie.slow_path.reason, ',');
278
 
            ds_put_format(ds, ")");
279
 
            break;
280
 
 
281
 
        case USER_ACTION_COOKIE_UNSPEC:
282
 
        default:
283
 
            ds_put_format(ds, ",userdata=0x%"PRIx64, userdata);
284
 
            break;
 
286
        if (userdata_len >= sizeof cookie.type
 
287
            && userdata_len <= sizeof cookie) {
 
288
 
 
289
            memset(&cookie, 0, sizeof cookie);
 
290
            memcpy(&cookie, userdata, userdata_len);
 
291
 
 
292
            userdata_unspec = false;
 
293
 
 
294
            if (userdata_len == sizeof cookie.sflow
 
295
                && cookie.type == USER_ACTION_COOKIE_SFLOW) {
 
296
                ds_put_format(ds, ",sFlow("
 
297
                              "vid=%"PRIu16",pcp=%"PRIu8",output=%"PRIu32")",
 
298
                              vlan_tci_to_vid(cookie.sflow.vlan_tci),
 
299
                              vlan_tci_to_pcp(cookie.sflow.vlan_tci),
 
300
                              cookie.sflow.output);
 
301
            } else if (userdata_len == sizeof cookie.slow_path
 
302
                       && cookie.type == USER_ACTION_COOKIE_SLOW_PATH) {
 
303
                const char *reason;
 
304
                reason = slow_path_reason_to_string(cookie.slow_path.reason);
 
305
                reason = reason ? reason : "";
 
306
                ds_put_format(ds, ",slow_path(%s)", reason);
 
307
            } else if (userdata_len == sizeof cookie.flow_sample
 
308
                       && cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) {
 
309
                ds_put_format(ds, ",flow_sample(probability=%"PRIu16
 
310
                              ",collector_set_id=%"PRIu32
 
311
                              ",obs_domain_id=%"PRIu32
 
312
                              ",obs_point_id=%"PRIu32")",
 
313
                              cookie.flow_sample.probability,
 
314
                              cookie.flow_sample.collector_set_id,
 
315
                              cookie.flow_sample.obs_domain_id,
 
316
                              cookie.flow_sample.obs_point_id);
 
317
            } else if (userdata_len == sizeof cookie.ipfix
 
318
                       && cookie.type == USER_ACTION_COOKIE_IPFIX) {
 
319
                ds_put_format(ds, ",ipfix");
 
320
            } else {
 
321
                userdata_unspec = true;
 
322
            }
 
323
        }
 
324
 
 
325
        if (userdata_unspec) {
 
326
            size_t i;
 
327
            ds_put_format(ds, ",userdata(");
 
328
            for (i = 0; i < userdata_len; i++) {
 
329
                ds_put_format(ds, "%02x", userdata[i]);
 
330
            }
 
331
            ds_put_char(ds, ')');
285
332
        }
286
333
    }
287
334
 
300
347
}
301
348
 
302
349
static void
 
350
format_mpls_lse(struct ds *ds, ovs_be32 mpls_lse)
 
351
{
 
352
    ds_put_format(ds, "label=%"PRIu32",tc=%d,ttl=%d,bos=%d",
 
353
                  mpls_lse_to_label(mpls_lse),
 
354
                  mpls_lse_to_tc(mpls_lse),
 
355
                  mpls_lse_to_ttl(mpls_lse),
 
356
                  mpls_lse_to_bos(mpls_lse));
 
357
}
 
358
 
 
359
static void
 
360
format_mpls(struct ds *ds, const struct ovs_key_mpls *mpls_key,
 
361
            const struct ovs_key_mpls *mpls_mask)
 
362
{
 
363
    ovs_be32 key = mpls_key->mpls_lse;
 
364
 
 
365
    if (mpls_mask == NULL) {
 
366
        format_mpls_lse(ds, key);
 
367
    } else {
 
368
        ovs_be32 mask = mpls_mask->mpls_lse;
 
369
 
 
370
        ds_put_format(ds, "label=%"PRIu32"/0x%x,tc=%d/%x,ttl=%d/0x%x,bos=%d/%x",
 
371
                  mpls_lse_to_label(key), mpls_lse_to_label(mask),
 
372
                  mpls_lse_to_tc(key), mpls_lse_to_tc(mask),
 
373
                  mpls_lse_to_ttl(key), mpls_lse_to_ttl(mask),
 
374
                  mpls_lse_to_bos(key), mpls_lse_to_bos(mask));
 
375
    }
 
376
}
 
377
 
 
378
static void
303
379
format_odp_action(struct ds *ds, const struct nlattr *a)
304
380
{
305
381
    int expected_len;
323
399
        break;
324
400
    case OVS_ACTION_ATTR_SET:
325
401
        ds_put_cstr(ds, "set(");
326
 
        format_odp_key_attr(nl_attr_get(a), ds);
 
402
        format_odp_key_attr(nl_attr_get(a), NULL, ds);
327
403
        ds_put_cstr(ds, ")");
328
404
        break;
329
405
    case OVS_ACTION_ATTR_PUSH_VLAN:
338
414
    case OVS_ACTION_ATTR_POP_VLAN:
339
415
        ds_put_cstr(ds, "pop_vlan");
340
416
        break;
 
417
    case OVS_ACTION_ATTR_PUSH_MPLS: {
 
418
        const struct ovs_action_push_mpls *mpls = nl_attr_get(a);
 
419
        ds_put_cstr(ds, "push_mpls(");
 
420
        format_mpls_lse(ds, mpls->mpls_lse);
 
421
        ds_put_format(ds, ",eth_type=0x%"PRIx16")", ntohs(mpls->mpls_ethertype));
 
422
        break;
 
423
    }
 
424
    case OVS_ACTION_ATTR_POP_MPLS: {
 
425
        ovs_be16 ethertype = nl_attr_get_be16(a);
 
426
        ds_put_format(ds, "pop_mpls(eth_type=0x%"PRIx16")", ntohs(ethertype));
 
427
        break;
 
428
    }
341
429
    case OVS_ACTION_ATTR_SAMPLE:
342
430
        format_odp_sample_action(ds, a);
343
431
        break;
418
506
    {
419
507
        unsigned long long int pid;
420
508
        unsigned long long int output;
421
 
        char userdata_s[32];
 
509
        unsigned long long int probability;
 
510
        unsigned long long int collector_set_id;
 
511
        unsigned long long int obs_domain_id;
 
512
        unsigned long long int obs_point_id;
422
513
        int vid, pcp;
423
514
        int n = -1;
424
515
 
425
516
        if (sscanf(s, "userspace(pid=%lli)%n", &pid, &n) > 0 && n > 0) {
426
 
            odp_put_userspace_action(pid, NULL, actions);
 
517
            odp_put_userspace_action(pid, NULL, 0, actions);
427
518
            return n;
428
519
        } else if (sscanf(s, "userspace(pid=%lli,sFlow(vid=%i,"
429
520
                          "pcp=%i,output=%lli))%n",
439
530
            cookie.type = USER_ACTION_COOKIE_SFLOW;
440
531
            cookie.sflow.vlan_tci = htons(tci);
441
532
            cookie.sflow.output = output;
442
 
            odp_put_userspace_action(pid, &cookie, actions);
 
533
            odp_put_userspace_action(pid, &cookie, sizeof cookie.sflow,
 
534
                                     actions);
443
535
            return n;
444
 
        } else if (sscanf(s, "userspace(pid=%lli,slow_path%n", &pid, &n) > 0
 
536
        } else if (sscanf(s, "userspace(pid=%lli,slow_path(%n", &pid, &n) > 0
445
537
                   && n > 0) {
446
538
            union user_action_cookie cookie;
447
 
            int res;
 
539
            char reason[32];
 
540
 
 
541
            if (s[n] == ')' && s[n + 1] == ')') {
 
542
                reason[0] = '\0';
 
543
                n += 2;
 
544
            } else if (sscanf(s + n, "%31[^)]))", reason) > 0) {
 
545
                n += strlen(reason) + 2;
 
546
            } else {
 
547
                return -EINVAL;
 
548
            }
448
549
 
449
550
            cookie.type = USER_ACTION_COOKIE_SLOW_PATH;
450
551
            cookie.slow_path.unused = 0;
451
 
            cookie.slow_path.reason = 0;
 
552
            cookie.slow_path.reason = string_to_slow_path_reason(reason);
452
553
 
453
 
            res = parse_flags(&s[n], slow_path_reason_to_string,
454
 
                              &cookie.slow_path.reason);
455
 
            if (res < 0) {
456
 
                return res;
457
 
            }
458
 
            n += res;
459
 
            if (s[n] != ')') {
 
554
            if (reason[0] && !cookie.slow_path.reason) {
460
555
                return -EINVAL;
461
556
            }
462
 
            n++;
463
 
 
464
 
            odp_put_userspace_action(pid, &cookie, actions);
465
 
            return n;
466
 
        } else if (sscanf(s, "userspace(pid=%lli,userdata="
467
 
                          "%31[x0123456789abcdefABCDEF])%n", &pid, userdata_s,
468
 
                          &n) > 0 && n > 0) {
469
 
            union user_action_cookie cookie;
470
 
            uint64_t userdata;
471
 
 
472
 
            userdata = strtoull(userdata_s, NULL, 0);
473
 
            memcpy(&cookie, &userdata, sizeof cookie);
474
 
            odp_put_userspace_action(pid, &cookie, actions);
475
 
            return n;
 
557
 
 
558
            odp_put_userspace_action(pid, &cookie, sizeof cookie.slow_path,
 
559
                                     actions);
 
560
            return n;
 
561
        } else if (sscanf(s, "userspace(pid=%lli,flow_sample(probability=%lli,"
 
562
                          "collector_set_id=%lli,obs_domain_id=%lli,"
 
563
                          "obs_point_id=%lli))%n",
 
564
                          &pid, &probability, &collector_set_id,
 
565
                          &obs_domain_id, &obs_point_id, &n) > 0 && n > 0) {
 
566
            union user_action_cookie cookie;
 
567
 
 
568
            cookie.type = USER_ACTION_COOKIE_FLOW_SAMPLE;
 
569
            cookie.flow_sample.probability = probability;
 
570
            cookie.flow_sample.collector_set_id = collector_set_id;
 
571
            cookie.flow_sample.obs_domain_id = obs_domain_id;
 
572
            cookie.flow_sample.obs_point_id = obs_point_id;
 
573
            odp_put_userspace_action(pid, &cookie, sizeof cookie.flow_sample,
 
574
                                     actions);
 
575
            return n;
 
576
        } else if (sscanf(s, "userspace(pid=%lli,ipfix)%n", &pid, &n) > 0
 
577
                   && n > 0) {
 
578
            union user_action_cookie cookie;
 
579
 
 
580
            cookie.type = USER_ACTION_COOKIE_IPFIX;
 
581
            odp_put_userspace_action(pid, &cookie, sizeof cookie.ipfix,
 
582
                                     actions);
 
583
            return n;
 
584
        } else if (sscanf(s, "userspace(pid=%lli,userdata(%n", &pid, &n) > 0
 
585
                   && n > 0) {
 
586
            struct ofpbuf buf;
 
587
            char *end;
 
588
 
 
589
            ofpbuf_init(&buf, 16);
 
590
            end = ofpbuf_put_hex(&buf, &s[n], NULL);
 
591
            if (end[0] == ')' && end[1] == ')') {
 
592
                odp_put_userspace_action(pid, buf.data, buf.size, actions);
 
593
                ofpbuf_uninit(&buf);
 
594
                return (end + 2) - s;
 
595
            }
476
596
        }
477
597
    }
478
598
 
481
601
        int retval;
482
602
 
483
603
        start_ofs = nl_msg_start_nested(actions, OVS_ACTION_ATTR_SET);
484
 
        retval = parse_odp_key_attr(s + 4, port_names, actions);
 
604
        retval = parse_odp_key_mask_attr(s + 4, port_names, actions, NULL);
485
605
        if (retval < 0) {
486
606
            return retval;
487
607
        }
620
740
    case OVS_KEY_ATTR_ETHERNET: return sizeof(struct ovs_key_ethernet);
621
741
    case OVS_KEY_ATTR_VLAN: return sizeof(ovs_be16);
622
742
    case OVS_KEY_ATTR_ETHERTYPE: return 2;
 
743
    case OVS_KEY_ATTR_MPLS: return sizeof(struct ovs_key_mpls);
623
744
    case OVS_KEY_ATTR_IPV4: return sizeof(struct ovs_key_ipv4);
624
745
    case OVS_KEY_ATTR_IPV6: return sizeof(struct ovs_key_ipv6);
625
746
    case OVS_KEY_ATTR_TCP: return sizeof(struct ovs_key_tcp);
647
768
 
648
769
        unspec = nl_attr_get(a);
649
770
        for (i = 0; i < len; i++) {
650
 
            ds_put_char(ds, i ? ' ': '(');
 
771
            if (i) {
 
772
                ds_put_char(ds, ' ');
 
773
            }
651
774
            ds_put_format(ds, "%02x", unspec[i]);
652
775
        }
653
 
        ds_put_char(ds, ')');
654
776
    }
655
777
}
656
778
 
687
809
    return -1;
688
810
}
689
811
 
690
 
static enum odp_key_fitness
691
 
tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
 
812
enum odp_key_fitness
 
813
odp_tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
692
814
{
693
815
    unsigned int left;
694
816
    const struct nlattr *a;
775
897
    nl_msg_end_nested(a, tun_key_ofs);
776
898
}
777
899
 
 
900
static bool
 
901
odp_mask_attr_is_exact(const struct nlattr *ma)
 
902
{
 
903
    bool is_exact = false;
 
904
    enum ovs_key_attr attr = nl_attr_type(ma);
 
905
 
 
906
    if (attr == OVS_KEY_ATTR_TUNNEL) {
 
907
        /* XXX this is a hack for now. Should change
 
908
         * the exact match dection to per field
 
909
         * instead of per attribute.
 
910
         */
 
911
        struct flow_tnl tun_mask;
 
912
        memset(&tun_mask, 0, sizeof tun_mask);
 
913
        odp_tun_key_from_attr(ma, &tun_mask);
 
914
        if (tun_mask.flags == (FLOW_TNL_F_KEY
 
915
                               | FLOW_TNL_F_DONT_FRAGMENT
 
916
                               | FLOW_TNL_F_CSUM)) {
 
917
            /* The flags are exact match, check the remaining fields. */
 
918
            tun_mask.flags = 0xffff;
 
919
            is_exact = is_all_ones((uint8_t *)&tun_mask,
 
920
                                   offsetof(struct flow_tnl, ip_ttl));
 
921
        }
 
922
    } else {
 
923
        is_exact = is_all_ones(nl_attr_get(ma), nl_attr_get_size(ma));
 
924
    }
 
925
 
 
926
    return is_exact;
 
927
}
 
928
 
 
929
 
778
930
static void
779
 
format_odp_key_attr(const struct nlattr *a, struct ds *ds)
 
931
format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma,
 
932
                    struct ds *ds)
780
933
{
781
 
    const struct ovs_key_ethernet *eth_key;
782
 
    const struct ovs_key_ipv4 *ipv4_key;
783
 
    const struct ovs_key_ipv6 *ipv6_key;
784
 
    const struct ovs_key_tcp *tcp_key;
785
 
    const struct ovs_key_udp *udp_key;
786
 
    const struct ovs_key_icmp *icmp_key;
787
 
    const struct ovs_key_icmpv6 *icmpv6_key;
788
 
    const struct ovs_key_arp *arp_key;
789
 
    const struct ovs_key_nd *nd_key;
790
934
    struct flow_tnl tun_key;
791
935
    enum ovs_key_attr attr = nl_attr_type(a);
 
936
    char namebuf[OVS_KEY_ATTR_BUFSIZE];
792
937
    int expected_len;
793
 
 
794
 
    ds_put_cstr(ds, ovs_key_attr_to_string(attr));
795
 
    expected_len = odp_flow_key_attr_len(nl_attr_type(a));
796
 
    if (expected_len != -2 && nl_attr_get_size(a) != expected_len) {
797
 
        ds_put_format(ds, "(bad length %zu, expected %d)",
798
 
                      nl_attr_get_size(a),
799
 
                      odp_flow_key_attr_len(nl_attr_type(a)));
800
 
        format_generic_odp_key(a, ds);
801
 
        return;
 
938
    bool is_exact;
 
939
 
 
940
    is_exact = ma ? odp_mask_attr_is_exact(ma) : true;
 
941
 
 
942
    ds_put_cstr(ds, ovs_key_attr_to_string(attr, namebuf, sizeof namebuf));
 
943
 
 
944
    {
 
945
        expected_len = odp_flow_key_attr_len(nl_attr_type(a));
 
946
        if (expected_len != -2) {
 
947
            bool bad_key_len = nl_attr_get_size(a) != expected_len;
 
948
            bool bad_mask_len = ma && nl_attr_get_size(a) != expected_len;
 
949
 
 
950
            if (bad_key_len || bad_mask_len) {
 
951
                if (bad_key_len) {
 
952
                    ds_put_format(ds, "(bad key length %zu, expected %d)(",
 
953
                                  nl_attr_get_size(a),
 
954
                                  odp_flow_key_attr_len(nl_attr_type(a)));
 
955
                }
 
956
                format_generic_odp_key(a, ds);
 
957
                if (bad_mask_len) {
 
958
                    ds_put_char(ds, '/');
 
959
                    ds_put_format(ds, "(bad mask length %zu, expected %d)(",
 
960
                                  nl_attr_get_size(ma),
 
961
                                  odp_flow_key_attr_len(nl_attr_type(ma)));
 
962
                }
 
963
                format_generic_odp_key(ma, ds);
 
964
                ds_put_char(ds, ')');
 
965
                return;
 
966
            }
 
967
        }
802
968
    }
803
969
 
 
970
    ds_put_char(ds, '(');
804
971
    switch (attr) {
805
972
    case OVS_KEY_ATTR_ENCAP:
806
 
        ds_put_cstr(ds, "(");
807
 
        if (nl_attr_get_size(a)) {
808
 
            odp_flow_key_format(nl_attr_get(a), nl_attr_get_size(a), ds);
 
973
        if (ma && nl_attr_get_size(ma) && nl_attr_get_size(a)) {
 
974
            odp_flow_format(nl_attr_get(a), nl_attr_get_size(a),
 
975
                            nl_attr_get(ma), nl_attr_get_size(ma), ds);
 
976
        } else if (nl_attr_get_size(a)) {
 
977
            odp_flow_format(nl_attr_get(a), nl_attr_get_size(a), NULL, 0, ds);
809
978
        }
810
 
        ds_put_char(ds, ')');
811
979
        break;
812
980
 
813
981
    case OVS_KEY_ATTR_PRIORITY:
814
 
        ds_put_format(ds, "(%#"PRIx32")", nl_attr_get_u32(a));
815
 
        break;
816
 
 
817
982
    case OVS_KEY_ATTR_SKB_MARK:
818
 
        ds_put_format(ds, "(%#"PRIx32")", nl_attr_get_u32(a));
 
983
        ds_put_format(ds, "%#"PRIx32, nl_attr_get_u32(a));
 
984
        if (!is_exact) {
 
985
            ds_put_format(ds, "/%#"PRIx32, nl_attr_get_u32(ma));
 
986
        }
819
987
        break;
820
988
 
821
989
    case OVS_KEY_ATTR_TUNNEL:
822
990
        memset(&tun_key, 0, sizeof tun_key);
823
 
        if (tun_key_from_attr(a, &tun_key) == ODP_FIT_ERROR) {
824
 
            ds_put_format(ds, "(error)");
 
991
        if (odp_tun_key_from_attr(a, &tun_key) == ODP_FIT_ERROR) {
 
992
            ds_put_format(ds, "error");
 
993
        } else if (!is_exact) {
 
994
            struct flow_tnl tun_mask;
 
995
 
 
996
            memset(&tun_mask, 0, sizeof tun_mask);
 
997
            odp_tun_key_from_attr(ma, &tun_mask);
 
998
            ds_put_format(ds, "tun_id=%#"PRIx64"/%#"PRIx64
 
999
                          ",src="IP_FMT"/"IP_FMT",dst="IP_FMT"/"IP_FMT
 
1000
                          ",tos=%#"PRIx8"/%#"PRIx8",ttl=%"PRIu8"/%#"PRIx8
 
1001
                          ",flags(",
 
1002
                          ntohll(tun_key.tun_id), ntohll(tun_mask.tun_id),
 
1003
                          IP_ARGS(tun_key.ip_src), IP_ARGS(tun_mask.ip_src),
 
1004
                          IP_ARGS(tun_key.ip_dst), IP_ARGS(tun_mask.ip_dst),
 
1005
                          tun_key.ip_tos, tun_mask.ip_tos,
 
1006
                          tun_key.ip_ttl, tun_mask.ip_ttl);
 
1007
 
 
1008
            format_flags(ds, flow_tun_flag_to_string, tun_key.flags, ',');
 
1009
 
 
1010
            /* XXX This code is correct, but enabling it would break the unit
 
1011
               test. Disable it for now until the input parser is fixed.
 
1012
 
 
1013
                ds_put_char(ds, '/');
 
1014
                format_flags(ds, flow_tun_flag_to_string, tun_mask.flags, ',');
 
1015
            */
 
1016
            ds_put_char(ds, ')');
825
1017
        } else {
826
 
            ds_put_format(ds, "(tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT","
 
1018
            ds_put_format(ds, "tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT","
827
1019
                          "tos=0x%"PRIx8",ttl=%"PRIu8",flags(",
828
1020
                          ntohll(tun_key.tun_id),
829
1021
                          IP_ARGS(tun_key.ip_src),
830
1022
                          IP_ARGS(tun_key.ip_dst),
831
1023
                          tun_key.ip_tos, tun_key.ip_ttl);
832
1024
 
833
 
            format_flags(ds, flow_tun_flag_to_string,
834
 
                         (uint32_t) tun_key.flags, ',');
835
 
            ds_put_format(ds, "))");
 
1025
            format_flags(ds, flow_tun_flag_to_string, tun_key.flags, ',');
 
1026
            ds_put_char(ds, ')');
836
1027
        }
837
1028
        break;
838
1029
 
839
1030
    case OVS_KEY_ATTR_IN_PORT:
840
 
        ds_put_format(ds, "(%"PRIu32")", nl_attr_get_u32(a));
 
1031
        ds_put_format(ds, "%"PRIu32, nl_attr_get_u32(a));
 
1032
        if (!is_exact) {
 
1033
            ds_put_format(ds, "/%#"PRIx32, nl_attr_get_u32(ma));
 
1034
        }
841
1035
        break;
842
1036
 
843
1037
    case OVS_KEY_ATTR_ETHERNET:
844
 
        eth_key = nl_attr_get(a);
845
 
        ds_put_format(ds, "(src="ETH_ADDR_FMT",dst="ETH_ADDR_FMT")",
846
 
                      ETH_ADDR_ARGS(eth_key->eth_src),
847
 
                      ETH_ADDR_ARGS(eth_key->eth_dst));
 
1038
        if (!is_exact) {
 
1039
            const struct ovs_key_ethernet *eth_mask = nl_attr_get(ma);
 
1040
            const struct ovs_key_ethernet *eth_key = nl_attr_get(a);
 
1041
 
 
1042
            ds_put_format(ds, "src="ETH_ADDR_FMT"/"ETH_ADDR_FMT
 
1043
                          ",dst="ETH_ADDR_FMT"/"ETH_ADDR_FMT,
 
1044
                          ETH_ADDR_ARGS(eth_key->eth_src),
 
1045
                          ETH_ADDR_ARGS(eth_mask->eth_src),
 
1046
                          ETH_ADDR_ARGS(eth_key->eth_dst),
 
1047
                          ETH_ADDR_ARGS(eth_mask->eth_dst));
 
1048
        } else {
 
1049
            const struct ovs_key_ethernet *eth_key = nl_attr_get(a);
 
1050
 
 
1051
            ds_put_format(ds, "src="ETH_ADDR_FMT",dst="ETH_ADDR_FMT,
 
1052
                          ETH_ADDR_ARGS(eth_key->eth_src),
 
1053
                          ETH_ADDR_ARGS(eth_key->eth_dst));
 
1054
        }
848
1055
        break;
849
1056
 
850
1057
    case OVS_KEY_ATTR_VLAN:
851
 
        ds_put_char(ds, '(');
852
 
        format_vlan_tci(ds, nl_attr_get_be16(a));
853
 
        ds_put_char(ds, ')');
854
 
        break;
 
1058
        {
 
1059
            ovs_be16 vlan_tci = nl_attr_get_be16(a);
 
1060
            if (!is_exact) {
 
1061
                ovs_be16 mask = nl_attr_get_be16(ma);
 
1062
                ds_put_format(ds, "vid=%"PRIu16"/0x%"PRIx16",pcp=%d/0x%x,cfi=%d/%d",
 
1063
                              vlan_tci_to_vid(vlan_tci),
 
1064
                              vlan_tci_to_vid(mask),
 
1065
                              vlan_tci_to_pcp(vlan_tci),
 
1066
                              vlan_tci_to_pcp(mask),
 
1067
                              vlan_tci_to_cfi(vlan_tci),
 
1068
                              vlan_tci_to_cfi(mask));
 
1069
            } else {
 
1070
                format_vlan_tci(ds, vlan_tci);
 
1071
            }
 
1072
        }
 
1073
        break;
 
1074
 
 
1075
    case OVS_KEY_ATTR_MPLS: {
 
1076
        const struct ovs_key_mpls *mpls_key = nl_attr_get(a);
 
1077
        const struct ovs_key_mpls *mpls_mask = NULL;
 
1078
        if (!is_exact) {
 
1079
            mpls_mask = nl_attr_get(ma);
 
1080
        }
 
1081
        format_mpls(ds, mpls_key, mpls_mask);
 
1082
        break;
 
1083
    }
855
1084
 
856
1085
    case OVS_KEY_ATTR_ETHERTYPE:
857
 
        ds_put_format(ds, "(0x%04"PRIx16")",
858
 
                      ntohs(nl_attr_get_be16(a)));
 
1086
        ds_put_format(ds, "0x%04"PRIx16, ntohs(nl_attr_get_be16(a)));
 
1087
        if (!is_exact) {
 
1088
            ds_put_format(ds, "/0x%04"PRIx16, ntohs(nl_attr_get_be16(ma)));
 
1089
        }
859
1090
        break;
860
1091
 
861
1092
    case OVS_KEY_ATTR_IPV4:
862
 
        ipv4_key = nl_attr_get(a);
863
 
        ds_put_format(ds, "(src="IP_FMT",dst="IP_FMT",proto=%"PRIu8
864
 
                      ",tos=%#"PRIx8",ttl=%"PRIu8",frag=%s)",
865
 
                      IP_ARGS(ipv4_key->ipv4_src),
866
 
                      IP_ARGS(ipv4_key->ipv4_dst),
867
 
                      ipv4_key->ipv4_proto, ipv4_key->ipv4_tos,
868
 
                      ipv4_key->ipv4_ttl,
869
 
                      ovs_frag_type_to_string(ipv4_key->ipv4_frag));
870
 
        break;
871
 
 
872
 
    case OVS_KEY_ATTR_IPV6: {
873
 
        char src_str[INET6_ADDRSTRLEN];
874
 
        char dst_str[INET6_ADDRSTRLEN];
875
 
 
876
 
        ipv6_key = nl_attr_get(a);
877
 
        inet_ntop(AF_INET6, ipv6_key->ipv6_src, src_str, sizeof src_str);
878
 
        inet_ntop(AF_INET6, ipv6_key->ipv6_dst, dst_str, sizeof dst_str);
879
 
 
880
 
        ds_put_format(ds, "(src=%s,dst=%s,label=%#"PRIx32",proto=%"PRIu8
881
 
                      ",tclass=%#"PRIx8",hlimit=%"PRIu8",frag=%s)",
882
 
                      src_str, dst_str, ntohl(ipv6_key->ipv6_label),
883
 
                      ipv6_key->ipv6_proto, ipv6_key->ipv6_tclass,
884
 
                      ipv6_key->ipv6_hlimit,
885
 
                      ovs_frag_type_to_string(ipv6_key->ipv6_frag));
886
 
        break;
887
 
    }
 
1093
        if (!is_exact) {
 
1094
            const struct ovs_key_ipv4 *ipv4_key = nl_attr_get(a);
 
1095
            const struct ovs_key_ipv4 *ipv4_mask = nl_attr_get(ma);
 
1096
 
 
1097
            ds_put_format(ds, "src="IP_FMT"/"IP_FMT",dst="IP_FMT"/"IP_FMT
 
1098
                          ",proto=%"PRIu8"/%#"PRIx8",tos=%#"PRIx8"/%#"PRIx8
 
1099
                          ",ttl=%"PRIu8"/%#"PRIx8",frag=%s/%#"PRIx8,
 
1100
                          IP_ARGS(ipv4_key->ipv4_src),
 
1101
                          IP_ARGS(ipv4_mask->ipv4_src),
 
1102
                          IP_ARGS(ipv4_key->ipv4_dst),
 
1103
                          IP_ARGS(ipv4_mask->ipv4_dst),
 
1104
                          ipv4_key->ipv4_proto, ipv4_mask->ipv4_proto,
 
1105
                          ipv4_key->ipv4_tos, ipv4_mask->ipv4_tos,
 
1106
                          ipv4_key->ipv4_ttl, ipv4_mask->ipv4_ttl,
 
1107
                          ovs_frag_type_to_string(ipv4_key->ipv4_frag),
 
1108
                          ipv4_mask->ipv4_frag);
 
1109
        } else {
 
1110
            const struct ovs_key_ipv4 *ipv4_key = nl_attr_get(a);
 
1111
 
 
1112
            ds_put_format(ds, "src="IP_FMT",dst="IP_FMT",proto=%"PRIu8
 
1113
                          ",tos=%#"PRIx8",ttl=%"PRIu8",frag=%s",
 
1114
                          IP_ARGS(ipv4_key->ipv4_src),
 
1115
                          IP_ARGS(ipv4_key->ipv4_dst),
 
1116
                          ipv4_key->ipv4_proto, ipv4_key->ipv4_tos,
 
1117
                          ipv4_key->ipv4_ttl,
 
1118
                          ovs_frag_type_to_string(ipv4_key->ipv4_frag));
 
1119
        }
 
1120
        break;
 
1121
 
 
1122
    case OVS_KEY_ATTR_IPV6:
 
1123
        if (!is_exact) {
 
1124
            const struct ovs_key_ipv6 *ipv6_key, *ipv6_mask;
 
1125
            char src_str[INET6_ADDRSTRLEN];
 
1126
            char dst_str[INET6_ADDRSTRLEN];
 
1127
            char src_mask[INET6_ADDRSTRLEN];
 
1128
            char dst_mask[INET6_ADDRSTRLEN];
 
1129
 
 
1130
            ipv6_key = nl_attr_get(a);
 
1131
            inet_ntop(AF_INET6, ipv6_key->ipv6_src, src_str, sizeof src_str);
 
1132
            inet_ntop(AF_INET6, ipv6_key->ipv6_dst, dst_str, sizeof dst_str);
 
1133
 
 
1134
            ipv6_mask = nl_attr_get(ma);
 
1135
            inet_ntop(AF_INET6, ipv6_mask->ipv6_src, src_mask, sizeof src_mask);
 
1136
            inet_ntop(AF_INET6, ipv6_mask->ipv6_dst, dst_mask, sizeof dst_mask);
 
1137
 
 
1138
            ds_put_format(ds, "src=%s/%s,dst=%s/%s,label=%#"PRIx32"/%#"PRIx32
 
1139
                          ",proto=%"PRIu8"/%#"PRIx8",tclass=%#"PRIx8"/%#"PRIx8
 
1140
                          ",hlimit=%"PRIu8"/%#"PRIx8",frag=%s/%#"PRIx8,
 
1141
                          src_str, src_mask, dst_str, dst_mask,
 
1142
                          ntohl(ipv6_key->ipv6_label),
 
1143
                          ntohl(ipv6_mask->ipv6_label),
 
1144
                          ipv6_key->ipv6_proto, ipv6_mask->ipv6_proto,
 
1145
                          ipv6_key->ipv6_tclass, ipv6_mask->ipv6_tclass,
 
1146
                          ipv6_key->ipv6_hlimit, ipv6_mask->ipv6_hlimit,
 
1147
                          ovs_frag_type_to_string(ipv6_key->ipv6_frag),
 
1148
                          ipv6_mask->ipv6_frag);
 
1149
        } else {
 
1150
            const struct ovs_key_ipv6 *ipv6_key;
 
1151
            char src_str[INET6_ADDRSTRLEN];
 
1152
            char dst_str[INET6_ADDRSTRLEN];
 
1153
 
 
1154
            ipv6_key = nl_attr_get(a);
 
1155
            inet_ntop(AF_INET6, ipv6_key->ipv6_src, src_str, sizeof src_str);
 
1156
            inet_ntop(AF_INET6, ipv6_key->ipv6_dst, dst_str, sizeof dst_str);
 
1157
 
 
1158
            ds_put_format(ds, "src=%s,dst=%s,label=%#"PRIx32",proto=%"PRIu8
 
1159
                          ",tclass=%#"PRIx8",hlimit=%"PRIu8",frag=%s",
 
1160
                          src_str, dst_str, ntohl(ipv6_key->ipv6_label),
 
1161
                          ipv6_key->ipv6_proto, ipv6_key->ipv6_tclass,
 
1162
                          ipv6_key->ipv6_hlimit,
 
1163
                          ovs_frag_type_to_string(ipv6_key->ipv6_frag));
 
1164
        }
 
1165
        break;
888
1166
 
889
1167
    case OVS_KEY_ATTR_TCP:
890
 
        tcp_key = nl_attr_get(a);
891
 
        ds_put_format(ds, "(src=%"PRIu16",dst=%"PRIu16")",
892
 
                      ntohs(tcp_key->tcp_src), ntohs(tcp_key->tcp_dst));
 
1168
        if (!is_exact) {
 
1169
            const struct ovs_key_tcp *tcp_mask = nl_attr_get(ma);
 
1170
            const struct ovs_key_tcp *tcp_key = nl_attr_get(a);
 
1171
 
 
1172
            ds_put_format(ds, "src=%"PRIu16"/%#"PRIx16
 
1173
                          ",dst=%"PRIu16"/%#"PRIx16,
 
1174
                          ntohs(tcp_key->tcp_src), ntohs(tcp_mask->tcp_src),
 
1175
                          ntohs(tcp_key->tcp_dst), ntohs(tcp_mask->tcp_dst));
 
1176
        } else {
 
1177
            const struct ovs_key_tcp *tcp_key = nl_attr_get(a);
 
1178
 
 
1179
            ds_put_format(ds, "src=%"PRIu16",dst=%"PRIu16,
 
1180
                          ntohs(tcp_key->tcp_src), ntohs(tcp_key->tcp_dst));
 
1181
        }
893
1182
        break;
894
1183
 
895
1184
    case OVS_KEY_ATTR_UDP:
896
 
        udp_key = nl_attr_get(a);
897
 
        ds_put_format(ds, "(src=%"PRIu16",dst=%"PRIu16")",
898
 
                      ntohs(udp_key->udp_src), ntohs(udp_key->udp_dst));
 
1185
        if (!is_exact) {
 
1186
            const struct ovs_key_udp *udp_mask = nl_attr_get(ma);
 
1187
            const struct ovs_key_udp *udp_key = nl_attr_get(a);
 
1188
 
 
1189
            ds_put_format(ds, "src=%"PRIu16"/%#"PRIx16
 
1190
                          ",dst=%"PRIu16"/%#"PRIx16,
 
1191
                          ntohs(udp_key->udp_src), ntohs(udp_mask->udp_src),
 
1192
                          ntohs(udp_key->udp_dst), ntohs(udp_mask->udp_dst));
 
1193
        } else {
 
1194
            const struct ovs_key_udp *udp_key = nl_attr_get(a);
 
1195
 
 
1196
            ds_put_format(ds, "src=%"PRIu16",dst=%"PRIu16,
 
1197
                          ntohs(udp_key->udp_src), ntohs(udp_key->udp_dst));
 
1198
        }
899
1199
        break;
900
1200
 
901
1201
    case OVS_KEY_ATTR_ICMP:
902
 
        icmp_key = nl_attr_get(a);
903
 
        ds_put_format(ds, "(type=%"PRIu8",code=%"PRIu8")",
904
 
                      icmp_key->icmp_type, icmp_key->icmp_code);
 
1202
        if (!is_exact) {
 
1203
            const struct ovs_key_icmp *icmp_mask = nl_attr_get(ma);
 
1204
            const struct ovs_key_icmp *icmp_key = nl_attr_get(a);
 
1205
 
 
1206
            ds_put_format(ds, "type=%"PRIu8"/%#"PRIx8",code=%"PRIu8"/%#"PRIx8,
 
1207
                          icmp_key->icmp_type, icmp_mask->icmp_type,
 
1208
                          icmp_key->icmp_code, icmp_mask->icmp_code);
 
1209
        } else {
 
1210
            const struct ovs_key_icmp *icmp_key = nl_attr_get(a);
 
1211
 
 
1212
            ds_put_format(ds, "type=%"PRIu8",code=%"PRIu8,
 
1213
                          icmp_key->icmp_type, icmp_key->icmp_code);
 
1214
        }
905
1215
        break;
906
1216
 
907
1217
    case OVS_KEY_ATTR_ICMPV6:
908
 
        icmpv6_key = nl_attr_get(a);
909
 
        ds_put_format(ds, "(type=%"PRIu8",code=%"PRIu8")",
910
 
                      icmpv6_key->icmpv6_type, icmpv6_key->icmpv6_code);
 
1218
        if (!is_exact) {
 
1219
            const struct ovs_key_icmpv6 *icmpv6_mask = nl_attr_get(ma);
 
1220
            const struct ovs_key_icmpv6 *icmpv6_key = nl_attr_get(a);
 
1221
 
 
1222
            ds_put_format(ds, "type=%"PRIu8"/%#"PRIx8",code=%"PRIu8"/%#"PRIx8,
 
1223
                          icmpv6_key->icmpv6_type, icmpv6_mask->icmpv6_type,
 
1224
                          icmpv6_key->icmpv6_code, icmpv6_mask->icmpv6_code);
 
1225
        } else {
 
1226
            const struct ovs_key_icmpv6 *icmpv6_key = nl_attr_get(a);
 
1227
 
 
1228
            ds_put_format(ds, "type=%"PRIu8",code=%"PRIu8,
 
1229
                          icmpv6_key->icmpv6_type, icmpv6_key->icmpv6_code);
 
1230
        }
911
1231
        break;
912
1232
 
913
1233
    case OVS_KEY_ATTR_ARP:
914
 
        arp_key = nl_attr_get(a);
915
 
        ds_put_format(ds, "(sip="IP_FMT",tip="IP_FMT",op=%"PRIu16","
916
 
                      "sha="ETH_ADDR_FMT",tha="ETH_ADDR_FMT")",
917
 
                      IP_ARGS(arp_key->arp_sip), IP_ARGS(arp_key->arp_tip),
918
 
                      ntohs(arp_key->arp_op), ETH_ADDR_ARGS(arp_key->arp_sha),
919
 
                      ETH_ADDR_ARGS(arp_key->arp_tha));
 
1234
        if (!is_exact) {
 
1235
            const struct ovs_key_arp *arp_mask = nl_attr_get(ma);
 
1236
            const struct ovs_key_arp *arp_key = nl_attr_get(a);
 
1237
 
 
1238
            ds_put_format(ds, "sip="IP_FMT"/"IP_FMT",tip="IP_FMT"/"IP_FMT
 
1239
                          ",op=%"PRIu16"/%#"PRIx16
 
1240
                          ",sha="ETH_ADDR_FMT"/"ETH_ADDR_FMT
 
1241
                          ",tha="ETH_ADDR_FMT"/"ETH_ADDR_FMT,
 
1242
                          IP_ARGS(arp_key->arp_sip),
 
1243
                          IP_ARGS(arp_mask->arp_sip),
 
1244
                          IP_ARGS(arp_key->arp_tip),
 
1245
                          IP_ARGS(arp_mask->arp_tip),
 
1246
                          ntohs(arp_key->arp_op), ntohs(arp_mask->arp_op),
 
1247
                          ETH_ADDR_ARGS(arp_key->arp_sha),
 
1248
                          ETH_ADDR_ARGS(arp_mask->arp_sha),
 
1249
                          ETH_ADDR_ARGS(arp_key->arp_tha),
 
1250
                          ETH_ADDR_ARGS(arp_mask->arp_tha));
 
1251
        } else {
 
1252
            const struct ovs_key_arp *arp_key = nl_attr_get(a);
 
1253
 
 
1254
            ds_put_format(ds, "sip="IP_FMT",tip="IP_FMT",op=%"PRIu16","
 
1255
                          "sha="ETH_ADDR_FMT",tha="ETH_ADDR_FMT,
 
1256
                          IP_ARGS(arp_key->arp_sip), IP_ARGS(arp_key->arp_tip),
 
1257
                          ntohs(arp_key->arp_op),
 
1258
                          ETH_ADDR_ARGS(arp_key->arp_sha),
 
1259
                          ETH_ADDR_ARGS(arp_key->arp_tha));
 
1260
        }
920
1261
        break;
921
1262
 
922
1263
    case OVS_KEY_ATTR_ND: {
 
1264
        const struct ovs_key_nd *nd_key, *nd_mask = NULL;
923
1265
        char target[INET6_ADDRSTRLEN];
924
1266
 
925
1267
        nd_key = nl_attr_get(a);
 
1268
        if (!is_exact) {
 
1269
            nd_mask = nl_attr_get(ma);
 
1270
        }
 
1271
 
926
1272
        inet_ntop(AF_INET6, nd_key->nd_target, target, sizeof target);
 
1273
        ds_put_format(ds, "target=%s", target);
 
1274
        if (!is_exact) {
 
1275
            inet_ntop(AF_INET6, nd_mask->nd_target, target, sizeof target);
 
1276
            ds_put_format(ds, "/%s", target);
 
1277
        }
927
1278
 
928
 
        ds_put_format(ds, "(target=%s", target);
929
1279
        if (!eth_addr_is_zero(nd_key->nd_sll)) {
930
1280
            ds_put_format(ds, ",sll="ETH_ADDR_FMT,
931
1281
                          ETH_ADDR_ARGS(nd_key->nd_sll));
 
1282
            if (!is_exact) {
 
1283
                ds_put_format(ds, "/"ETH_ADDR_FMT,
 
1284
                              ETH_ADDR_ARGS(nd_mask->nd_sll));
 
1285
            }
932
1286
        }
933
1287
        if (!eth_addr_is_zero(nd_key->nd_tll)) {
934
1288
            ds_put_format(ds, ",tll="ETH_ADDR_FMT,
935
1289
                          ETH_ADDR_ARGS(nd_key->nd_tll));
 
1290
            if (!is_exact) {
 
1291
                ds_put_format(ds, "/"ETH_ADDR_FMT,
 
1292
                              ETH_ADDR_ARGS(nd_mask->nd_tll));
 
1293
            }
936
1294
        }
937
 
        ds_put_char(ds, ')');
938
1295
        break;
939
1296
    }
940
1297
 
942
1299
    case __OVS_KEY_ATTR_MAX:
943
1300
    default:
944
1301
        format_generic_odp_key(a, ds);
 
1302
        if (!is_exact) {
 
1303
            ds_put_char(ds, '/');
 
1304
            format_generic_odp_key(ma, ds);
 
1305
        }
945
1306
        break;
946
1307
    }
 
1308
    ds_put_char(ds, ')');
 
1309
}
 
1310
 
 
1311
static struct nlattr *
 
1312
generate_all_wildcard_mask(struct ofpbuf *ofp, const struct nlattr *key)
 
1313
{
 
1314
    const struct nlattr *a;
 
1315
    unsigned int left;
 
1316
    int type = nl_attr_type(key);
 
1317
    int size = nl_attr_get_size(key);
 
1318
 
 
1319
    if (odp_flow_key_attr_len(type) >=0) {
 
1320
        memset(nl_msg_put_unspec_uninit(ofp, type, size), 0, size);
 
1321
    } else {
 
1322
        size_t nested_mask;
 
1323
 
 
1324
        nested_mask = nl_msg_start_nested(ofp, type);
 
1325
        NL_ATTR_FOR_EACH(a, left, key, nl_attr_get_size(key)) {
 
1326
            generate_all_wildcard_mask(ofp, nl_attr_get(a));
 
1327
        }
 
1328
        nl_msg_end_nested(ofp, nested_mask);
 
1329
    }
 
1330
 
 
1331
    return ofp->base;
947
1332
}
948
1333
 
949
1334
/* Appends to 'ds' a string representation of the 'key_len' bytes of
950
 
 * OVS_KEY_ATTR_* attributes in 'key'. */
 
1335
 * OVS_KEY_ATTR_* attributes in 'key'. If non-null, additionally formats the
 
1336
 * 'mask_len' bytes of 'mask' which apply to 'key'. */
951
1337
void
952
 
odp_flow_key_format(const struct nlattr *key, size_t key_len, struct ds *ds)
 
1338
odp_flow_format(const struct nlattr *key, size_t key_len,
 
1339
                const struct nlattr *mask, size_t mask_len,
 
1340
                struct ds *ds)
953
1341
{
954
1342
    if (key_len) {
955
1343
        const struct nlattr *a;
956
1344
        unsigned int left;
 
1345
        bool has_ethtype_key = false;
 
1346
        const struct nlattr *ma = NULL;
 
1347
        struct ofpbuf ofp;
957
1348
 
 
1349
        ofpbuf_init(&ofp, 100);
958
1350
        NL_ATTR_FOR_EACH (a, left, key, key_len) {
959
1351
            if (a != key) {
960
1352
                ds_put_char(ds, ',');
961
1353
            }
962
 
            format_odp_key_attr(a, ds);
 
1354
            if (nl_attr_type(a) == OVS_KEY_ATTR_ETHERTYPE) {
 
1355
                has_ethtype_key = true;
 
1356
            }
 
1357
            if (mask && mask_len) {
 
1358
                ma = nl_attr_find__(mask, mask_len, nl_attr_type(a));
 
1359
                if (!ma) {
 
1360
                    ma = generate_all_wildcard_mask(&ofp, a);
 
1361
                }
 
1362
            }
 
1363
            format_odp_key_attr(a, ma, ds);
 
1364
            ofpbuf_clear(&ofp);
963
1365
        }
 
1366
        ofpbuf_uninit(&ofp);
 
1367
 
964
1368
        if (left) {
965
1369
            int i;
966
1370
            
973
1377
            }
974
1378
            ds_put_char(ds, ')');
975
1379
        }
 
1380
        if (!has_ethtype_key) {
 
1381
            ma = nl_attr_find__(mask, mask_len, OVS_KEY_ATTR_ETHERTYPE);
 
1382
            if (ma) {
 
1383
                ds_put_format(ds, ",eth_type(0/0x%04"PRIx16")",
 
1384
                              ntohs(nl_attr_get_be16(ma)));
 
1385
            }
 
1386
        }
976
1387
    } else {
977
1388
        ds_put_cstr(ds, "<empty>");
978
1389
    }
979
1390
}
980
1391
 
 
1392
/* Appends to 'ds' a string representation of the 'key_len' bytes of
 
1393
 * OVS_KEY_ATTR_* attributes in 'key'. */
 
1394
void
 
1395
odp_flow_key_format(const struct nlattr *key,
 
1396
                    size_t key_len, struct ds *ds)
 
1397
{
 
1398
    odp_flow_format(key, key_len, NULL, 0, ds);
 
1399
}
 
1400
 
 
1401
static void
 
1402
put_nd(struct ovs_key_nd* nd_key, const uint8_t *nd_sll,
 
1403
       const uint8_t *nd_tll, struct ofpbuf *key)
 
1404
{
 
1405
    if (nd_sll) {
 
1406
        memcpy(nd_key->nd_sll, nd_sll, ETH_ADDR_LEN);
 
1407
    }
 
1408
 
 
1409
    if (nd_tll) {
 
1410
        memcpy(nd_key->nd_tll, nd_tll, ETH_ADDR_LEN);
 
1411
    }
 
1412
 
 
1413
    nl_msg_put_unspec(key, OVS_KEY_ATTR_ND, nd_key, sizeof *nd_key);
 
1414
}
 
1415
 
981
1416
static int
982
 
put_nd_key(int n, const char *nd_target_s,
983
 
           const uint8_t *nd_sll, const uint8_t *nd_tll, struct ofpbuf *key)
 
1417
put_nd_key(int n, const char *nd_target_s, const uint8_t *nd_sll,
 
1418
           const uint8_t *nd_tll, struct ofpbuf *key)
984
1419
{
985
1420
    struct ovs_key_nd nd_key;
986
1421
 
987
1422
    memset(&nd_key, 0, sizeof nd_key);
 
1423
 
988
1424
    if (inet_pton(AF_INET6, nd_target_s, nd_key.nd_target) != 1) {
989
1425
        return -EINVAL;
990
1426
    }
991
 
    if (nd_sll) {
992
 
        memcpy(nd_key.nd_sll, nd_sll, ETH_ADDR_LEN);
993
 
    }
994
 
    if (nd_tll) {
995
 
        memcpy(nd_key.nd_tll, nd_tll, ETH_ADDR_LEN);
996
 
    }
997
 
    nl_msg_put_unspec(key, OVS_KEY_ATTR_ND, &nd_key, sizeof nd_key);
 
1427
 
 
1428
    put_nd(&nd_key, nd_sll, nd_tll, key);
 
1429
    return n;
 
1430
}
 
1431
 
 
1432
static int
 
1433
put_nd_mask(int n, const char *nd_target_s,
 
1434
           const uint8_t *nd_sll, const uint8_t *nd_tll, struct ofpbuf *mask)
 
1435
{
 
1436
    struct ovs_key_nd nd_mask;
 
1437
 
 
1438
    memset(&nd_mask, 0xff, sizeof nd_mask);
 
1439
 
 
1440
    if (strlen(nd_target_s) != 0 &&
 
1441
            inet_pton(AF_INET6, nd_target_s, nd_mask.nd_target) != 1) {
 
1442
        return -EINVAL;
 
1443
    }
 
1444
 
 
1445
    put_nd(&nd_mask, nd_sll, nd_tll, mask);
998
1446
    return n;
999
1447
}
1000
1448
 
1013
1461
    return true;
1014
1462
}
1015
1463
 
 
1464
static ovs_be32
 
1465
mpls_lse_from_components(int mpls_label, int mpls_tc, int mpls_ttl, int mpls_bos)
 
1466
{
 
1467
    return (htonl((mpls_label << MPLS_LABEL_SHIFT) |
 
1468
                  (mpls_tc << MPLS_TC_SHIFT)       |
 
1469
                  (mpls_ttl << MPLS_TTL_SHIFT)     |
 
1470
                  (mpls_bos << MPLS_BOS_SHIFT)));
 
1471
}
 
1472
 
1016
1473
static int
1017
 
parse_odp_key_attr(const char *s, const struct simap *port_names,
1018
 
                   struct ofpbuf *key)
 
1474
parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
 
1475
                        struct ofpbuf *key, struct ofpbuf *mask)
1019
1476
{
1020
1477
    /* Many of the sscanf calls in this function use oversized destination
1021
1478
     * fields because some sscanf() implementations truncate the range of %i
1029
1486
 
1030
1487
    {
1031
1488
        unsigned long long int priority;
 
1489
        unsigned long long int priority_mask;
1032
1490
        int n = -1;
1033
1491
 
1034
 
        if (sscanf(s, "skb_priority(%llx)%n", &priority, &n) > 0 && n > 0) {
1035
 
            nl_msg_put_u32(key, OVS_KEY_ATTR_PRIORITY, priority);
 
1492
        if (mask && sscanf(s, "skb_priority(%lli/%lli)%n", &priority,
 
1493
                   &priority_mask, &n) > 0 && n > 0) {
 
1494
            nl_msg_put_u32(key, OVS_KEY_ATTR_PRIORITY, priority);
 
1495
            nl_msg_put_u32(mask, OVS_KEY_ATTR_PRIORITY, priority_mask);
 
1496
            return n;
 
1497
        } else if (sscanf(s, "skb_priority(%lli)%n",
 
1498
                          &priority, &n) > 0 && n > 0) {
 
1499
            nl_msg_put_u32(key, OVS_KEY_ATTR_PRIORITY, priority);
 
1500
            if (mask) {
 
1501
                nl_msg_put_u32(mask, OVS_KEY_ATTR_PRIORITY, UINT32_MAX);
 
1502
            }
1036
1503
            return n;
1037
1504
        }
1038
1505
    }
1039
1506
 
1040
1507
    {
1041
1508
        unsigned long long int mark;
 
1509
        unsigned long long int mark_mask;
1042
1510
        int n = -1;
1043
1511
 
1044
 
        if (sscanf(s, "skb_mark(%llx)%n", &mark, &n) > 0 && n > 0) {
1045
 
            nl_msg_put_u32(key, OVS_KEY_ATTR_SKB_MARK, mark);
 
1512
        if (mask && sscanf(s, "skb_mark(%lli/%lli)%n", &mark,
 
1513
                   &mark_mask, &n) > 0 && n > 0) {
 
1514
            nl_msg_put_u32(key, OVS_KEY_ATTR_SKB_MARK, mark);
 
1515
            nl_msg_put_u32(mask, OVS_KEY_ATTR_SKB_MARK, mark_mask);
 
1516
            return n;
 
1517
        } else if (sscanf(s, "skb_mark(%lli)%n", &mark, &n) > 0 && n > 0) {
 
1518
            nl_msg_put_u32(key, OVS_KEY_ATTR_SKB_MARK, mark);
 
1519
            if (mask) {
 
1520
                nl_msg_put_u32(mask, OVS_KEY_ATTR_SKB_MARK, UINT32_MAX);
 
1521
            }
1046
1522
            return n;
1047
1523
        }
1048
1524
    }
1049
1525
 
1050
1526
    {
1051
1527
        char tun_id_s[32];
1052
 
        int tos, ttl;
1053
 
        struct flow_tnl tun_key;
 
1528
        int tos, tos_mask, ttl, ttl_mask;
 
1529
        struct flow_tnl tun_key, tun_key_mask;
 
1530
        unsigned long long tun_id_mask;
1054
1531
        int n = -1;
1055
1532
 
1056
 
        if (sscanf(s, "tunnel(tun_id=%31[x0123456789abcdefABCDEF],"
 
1533
        if (mask && sscanf(s, "tunnel(tun_id=%31[x0123456789abcdefABCDEF]/%llx,"
 
1534
                   "src="IP_SCAN_FMT"/"IP_SCAN_FMT",dst="IP_SCAN_FMT
 
1535
                   "/"IP_SCAN_FMT",tos=%i/%i,ttl=%i/%i,flags%n",
 
1536
                   tun_id_s, &tun_id_mask,
 
1537
                   IP_SCAN_ARGS(&tun_key.ip_src),
 
1538
                   IP_SCAN_ARGS(&tun_key_mask.ip_src),
 
1539
                   IP_SCAN_ARGS(&tun_key.ip_dst),
 
1540
                   IP_SCAN_ARGS(&tun_key_mask.ip_dst),
 
1541
                   &tos, &tos_mask, &ttl, &ttl_mask,
 
1542
                   &n) > 0 && n > 0) {
 
1543
            int res;
 
1544
            uint32_t flags;
 
1545
 
 
1546
            tun_key.tun_id = htonll(strtoull(tun_id_s, NULL, 0));
 
1547
            tun_key_mask.tun_id = htonll(tun_id_mask);
 
1548
            tun_key.ip_tos = tos;
 
1549
            tun_key_mask.ip_tos = tos_mask;
 
1550
            tun_key.ip_ttl = ttl;
 
1551
            tun_key_mask.ip_ttl = ttl_mask;
 
1552
            res = parse_flags(&s[n], flow_tun_flag_to_string, &flags);
 
1553
            tun_key.flags = flags;
 
1554
            tun_key_mask.flags = UINT16_MAX;
 
1555
 
 
1556
            if (res < 0) {
 
1557
                return res;
 
1558
            }
 
1559
            n += res;
 
1560
            if (s[n] != ')') {
 
1561
                return -EINVAL;
 
1562
            }
 
1563
            n++;
 
1564
            tun_key_to_attr(key, &tun_key);
 
1565
            if (mask) {
 
1566
                tun_key_to_attr(mask, &tun_key_mask);
 
1567
            }
 
1568
            return n;
 
1569
        } else if (sscanf(s, "tunnel(tun_id=%31[x0123456789abcdefABCDEF],"
1057
1570
                   "src="IP_SCAN_FMT",dst="IP_SCAN_FMT
1058
1571
                   ",tos=%i,ttl=%i,flags%n", tun_id_s,
1059
1572
                    IP_SCAN_ARGS(&tun_key.ip_src),
1066
1579
            tun_key.ip_tos = tos;
1067
1580
            tun_key.ip_ttl = ttl;
1068
1581
            res = parse_flags(&s[n], flow_tun_flag_to_string, &flags);
1069
 
            tun_key.flags = (uint16_t) flags;
 
1582
            tun_key.flags = flags;
1070
1583
 
1071
1584
            if (res < 0) {
1072
1585
                return res;
1077
1590
            }
1078
1591
            n++;
1079
1592
            tun_key_to_attr(key, &tun_key);
 
1593
 
 
1594
            if (mask) {
 
1595
                memset(&tun_key, 0xff, sizeof tun_key);
 
1596
                tun_key_to_attr(mask, &tun_key);
 
1597
            }
1080
1598
            return n;
1081
1599
        }
1082
1600
    }
1083
1601
 
1084
1602
    {
1085
1603
        unsigned long long int in_port;
 
1604
        unsigned long long int in_port_mask;
1086
1605
        int n = -1;
1087
1606
 
1088
 
        if (sscanf(s, "in_port(%lli)%n", &in_port, &n) > 0 && n > 0) {
1089
 
            nl_msg_put_u32(key, OVS_KEY_ATTR_IN_PORT, in_port);
 
1607
        if (mask && sscanf(s, "in_port(%lli/%lli)%n", &in_port,
 
1608
                   &in_port_mask, &n) > 0 && n > 0) {
 
1609
            nl_msg_put_u32(key, OVS_KEY_ATTR_IN_PORT, in_port);
 
1610
            nl_msg_put_u32(mask, OVS_KEY_ATTR_IN_PORT, in_port_mask);
 
1611
            return n;
 
1612
        } else if (sscanf(s, "in_port(%lli)%n", &in_port, &n) > 0 && n > 0) {
 
1613
            nl_msg_put_u32(key, OVS_KEY_ATTR_IN_PORT, in_port);
 
1614
            if (mask) {
 
1615
                nl_msg_put_u32(mask, OVS_KEY_ATTR_IN_PORT, UINT32_MAX);
 
1616
            }
1090
1617
            return n;
1091
1618
        }
1092
1619
    }
1093
1620
 
 
1621
 
1094
1622
    if (port_names && !strncmp(s, "in_port(", 8)) {
1095
1623
        const char *name;
1096
1624
        const struct simap_node *node;
1101
1629
        node = simap_find_len(port_names, name, name_len);
1102
1630
        if (node) {
1103
1631
            nl_msg_put_u32(key, OVS_KEY_ATTR_IN_PORT, node->data);
 
1632
 
 
1633
            if (mask) {
 
1634
                nl_msg_put_u32(mask, OVS_KEY_ATTR_IN_PORT, UINT32_MAX);
 
1635
            }
1104
1636
            return 8 + name_len + 1;
1105
1637
        }
1106
1638
    }
1107
1639
 
1108
1640
    {
1109
1641
        struct ovs_key_ethernet eth_key;
 
1642
        struct ovs_key_ethernet eth_key_mask;
1110
1643
        int n = -1;
1111
1644
 
1112
 
        if (sscanf(s,
 
1645
        if (mask && sscanf(s,
 
1646
                   "eth(src="ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT","
 
1647
                        "dst="ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT")%n",
 
1648
                ETH_ADDR_SCAN_ARGS(eth_key.eth_src),
 
1649
                ETH_ADDR_SCAN_ARGS(eth_key_mask.eth_src),
 
1650
                ETH_ADDR_SCAN_ARGS(eth_key.eth_dst),
 
1651
                ETH_ADDR_SCAN_ARGS(eth_key_mask.eth_dst), &n) > 0 && n > 0) {
 
1652
 
 
1653
            nl_msg_put_unspec(key, OVS_KEY_ATTR_ETHERNET,
 
1654
                              &eth_key, sizeof eth_key);
 
1655
            nl_msg_put_unspec(mask, OVS_KEY_ATTR_ETHERNET,
 
1656
                              &eth_key_mask, sizeof eth_key_mask);
 
1657
            return n;
 
1658
        } else if (sscanf(s,
1113
1659
                   "eth(src="ETH_ADDR_SCAN_FMT",dst="ETH_ADDR_SCAN_FMT")%n",
1114
1660
                   ETH_ADDR_SCAN_ARGS(eth_key.eth_src),
1115
1661
                   ETH_ADDR_SCAN_ARGS(eth_key.eth_dst), &n) > 0 && n > 0) {
1116
1662
            nl_msg_put_unspec(key, OVS_KEY_ATTR_ETHERNET,
1117
1663
                              &eth_key, sizeof eth_key);
 
1664
 
 
1665
            if (mask) {
 
1666
                memset(&eth_key, 0xff, sizeof eth_key);
 
1667
                nl_msg_put_unspec(mask, OVS_KEY_ATTR_ETHERNET,
 
1668
                              &eth_key, sizeof eth_key);
 
1669
            }
1118
1670
            return n;
1119
1671
        }
1120
1672
    }
1121
1673
 
1122
1674
    {
1123
 
        uint16_t vid;
1124
 
        int pcp;
1125
 
        int cfi;
 
1675
        uint16_t vid, vid_mask;
 
1676
        int pcp, pcp_mask;
 
1677
        int cfi, cfi_mask;
1126
1678
        int n = -1;
1127
1679
 
1128
 
        if ((sscanf(s, "vlan(vid=%"SCNi16",pcp=%i)%n", &vid, &pcp, &n) > 0
1129
 
             && n > 0)) {
1130
 
            nl_msg_put_be16(key, OVS_KEY_ATTR_VLAN,
1131
 
                            htons((vid << VLAN_VID_SHIFT) |
1132
 
                                  (pcp << VLAN_PCP_SHIFT) |
1133
 
                                  VLAN_CFI));
 
1680
        if (mask && (sscanf(s, "vlan(vid=%"SCNi16"/%"SCNi16",pcp=%i/%i)%n",
 
1681
                            &vid, &vid_mask, &pcp, &pcp_mask, &n) > 0 && n > 0)) {
 
1682
            nl_msg_put_be16(key, OVS_KEY_ATTR_VLAN,
 
1683
                            htons((vid << VLAN_VID_SHIFT) |
 
1684
                                  (pcp << VLAN_PCP_SHIFT) |
 
1685
                                  VLAN_CFI));
 
1686
            nl_msg_put_be16(mask, OVS_KEY_ATTR_VLAN,
 
1687
                            htons((vid_mask << VLAN_VID_SHIFT) |
 
1688
                                  (pcp_mask << VLAN_PCP_SHIFT) |
 
1689
                                  (1 << VLAN_CFI_SHIFT)));
 
1690
            return n;
 
1691
        } else if ((sscanf(s, "vlan(vid=%"SCNi16",pcp=%i)%n",
 
1692
                           &vid, &pcp, &n) > 0 && n > 0)) {
 
1693
            nl_msg_put_be16(key, OVS_KEY_ATTR_VLAN,
 
1694
                            htons((vid << VLAN_VID_SHIFT) |
 
1695
                                  (pcp << VLAN_PCP_SHIFT) |
 
1696
                                  VLAN_CFI));
 
1697
            if (mask) {
 
1698
                nl_msg_put_be16(mask, OVS_KEY_ATTR_VLAN, htons(UINT16_MAX));
 
1699
            }
 
1700
            return n;
 
1701
        } else if (mask && (sscanf(s, "vlan(vid=%"SCNi16"/%"SCNi16",pcp=%i/%i,cfi=%i/%i)%n",
 
1702
                                   &vid, &vid_mask, &pcp, &pcp_mask, &cfi, &cfi_mask, &n) > 0 && n > 0)) {
 
1703
            nl_msg_put_be16(key, OVS_KEY_ATTR_VLAN,
 
1704
                            htons((vid << VLAN_VID_SHIFT) |
 
1705
                                  (pcp << VLAN_PCP_SHIFT) |
 
1706
                                  (cfi ? VLAN_CFI : 0)));
 
1707
            nl_msg_put_be16(mask, OVS_KEY_ATTR_VLAN,
 
1708
                            htons((vid_mask << VLAN_VID_SHIFT) |
 
1709
                                  (pcp_mask << VLAN_PCP_SHIFT) |
 
1710
                                  (cfi_mask << VLAN_CFI_SHIFT)));
1134
1711
            return n;
1135
1712
        } else if ((sscanf(s, "vlan(vid=%"SCNi16",pcp=%i,cfi=%i)%n",
1136
 
                           &vid, &pcp, &cfi, &n) > 0
1137
 
             && n > 0)) {
 
1713
                           &vid, &pcp, &cfi, &n) > 0 && n > 0)) {
1138
1714
            nl_msg_put_be16(key, OVS_KEY_ATTR_VLAN,
1139
1715
                            htons((vid << VLAN_VID_SHIFT) |
1140
1716
                                  (pcp << VLAN_PCP_SHIFT) |
1141
1717
                                  (cfi ? VLAN_CFI : 0)));
 
1718
            if (mask) {
 
1719
                nl_msg_put_be16(mask, OVS_KEY_ATTR_VLAN, htons(UINT16_MAX));
 
1720
            }
1142
1721
            return n;
1143
1722
        }
1144
1723
    }
1145
1724
 
1146
1725
    {
1147
1726
        int eth_type;
 
1727
        int eth_type_mask;
1148
1728
        int n = -1;
1149
1729
 
1150
 
        if (sscanf(s, "eth_type(%i)%n", &eth_type, &n) > 0 && n > 0) {
 
1730
        if (mask && sscanf(s, "eth_type(%i/%i)%n",
 
1731
                   &eth_type, &eth_type_mask, &n) > 0 && n > 0) {
 
1732
            if (eth_type != 0) {
 
1733
                nl_msg_put_be16(key, OVS_KEY_ATTR_ETHERTYPE, htons(eth_type));
 
1734
            }
 
1735
            nl_msg_put_be16(mask, OVS_KEY_ATTR_ETHERTYPE, htons(eth_type_mask));
 
1736
            return n;
 
1737
        } else if (sscanf(s, "eth_type(%i)%n", &eth_type, &n) > 0 && n > 0) {
1151
1738
            nl_msg_put_be16(key, OVS_KEY_ATTR_ETHERTYPE, htons(eth_type));
1152
 
            return n;
1153
 
        }
1154
 
    }
1155
 
 
1156
 
    {
1157
 
        ovs_be32 ipv4_src;
1158
 
        ovs_be32 ipv4_dst;
1159
 
        int ipv4_proto;
1160
 
        int ipv4_tos;
1161
 
        int ipv4_ttl;
 
1739
            if (mask) {
 
1740
                nl_msg_put_be16(mask, OVS_KEY_ATTR_ETHERTYPE,
 
1741
                                htons(UINT16_MAX));
 
1742
            }
 
1743
            return n;
 
1744
        }
 
1745
    }
 
1746
 
 
1747
    {
 
1748
        int label, tc, ttl, bos;
 
1749
        int label_mask, tc_mask, ttl_mask, bos_mask;
 
1750
        int n = -1;
 
1751
 
 
1752
        if (mask && sscanf(s, "mpls(label=%"SCNi32"/%"SCNi32",tc=%i/%i,ttl=%i/%i,bos=%i/%i)%n",
 
1753
                    &label, &label_mask, &tc, &tc_mask, &ttl, &ttl_mask, &bos, &bos_mask, &n) > 0 && n > 0) {
 
1754
            struct ovs_key_mpls *mpls, *mpls_mask;
 
1755
 
 
1756
            mpls = nl_msg_put_unspec_uninit(key, OVS_KEY_ATTR_MPLS,
 
1757
                                            sizeof *mpls);
 
1758
            mpls->mpls_lse = mpls_lse_from_components(label, tc, ttl, bos);
 
1759
 
 
1760
            mpls_mask = nl_msg_put_unspec_uninit(mask, OVS_KEY_ATTR_MPLS,
 
1761
                                            sizeof *mpls_mask);
 
1762
            mpls_mask->mpls_lse = mpls_lse_from_components(
 
1763
                                  label_mask, tc_mask, ttl_mask, bos_mask);
 
1764
            return n;
 
1765
        } else if (sscanf(s, "mpls(label=%"SCNi32",tc=%i,ttl=%i,bos=%i)%n",
 
1766
                    &label, &tc, &ttl, &bos, &n) > 0 &&
 
1767
                    n > 0) {
 
1768
            struct ovs_key_mpls *mpls;
 
1769
 
 
1770
            mpls = nl_msg_put_unspec_uninit(key, OVS_KEY_ATTR_MPLS,
 
1771
                                            sizeof *mpls);
 
1772
            mpls->mpls_lse = mpls_lse_from_components(label, tc, ttl, bos);
 
1773
            if (mask) {
 
1774
                mpls = nl_msg_put_unspec_uninit(mask, OVS_KEY_ATTR_MPLS,
 
1775
                                            sizeof *mpls);
 
1776
                mpls->mpls_lse = htonl(UINT32_MAX);
 
1777
            }
 
1778
            return n;
 
1779
        }
 
1780
    }
 
1781
 
 
1782
 
 
1783
    {
 
1784
        ovs_be32 ipv4_src, ipv4_src_mask;
 
1785
        ovs_be32 ipv4_dst, ipv4_dst_mask;
 
1786
        int ipv4_proto, ipv4_proto_mask;
 
1787
        int ipv4_tos, ipv4_tos_mask;
 
1788
        int ipv4_ttl, ipv4_ttl_mask;
1162
1789
        char frag[8];
 
1790
        int  ipv4_frag_mask;
1163
1791
        enum ovs_frag_type ipv4_frag;
1164
1792
        int n = -1;
1165
1793
 
1166
 
        if (sscanf(s, "ipv4(src="IP_SCAN_FMT",dst="IP_SCAN_FMT","
 
1794
        if (mask && sscanf(s, "ipv4(src="IP_SCAN_FMT"/"IP_SCAN_FMT","
 
1795
                      "dst="IP_SCAN_FMT"/"IP_SCAN_FMT","
 
1796
                      "proto=%i/%i,tos=%i/%i,ttl=%i/%i,"
 
1797
                      "frag=%7[a-z]/%i)%n",
 
1798
                      IP_SCAN_ARGS(&ipv4_src), IP_SCAN_ARGS(&ipv4_src_mask),
 
1799
                      IP_SCAN_ARGS(&ipv4_dst), IP_SCAN_ARGS(&ipv4_dst_mask),
 
1800
                      &ipv4_proto, &ipv4_proto_mask,
 
1801
                      &ipv4_tos, &ipv4_tos_mask, &ipv4_ttl, &ipv4_ttl_mask,
 
1802
                      frag, &ipv4_frag_mask, &n) > 0
 
1803
            && n > 0
 
1804
            && ovs_frag_type_from_string(frag, &ipv4_frag)) {
 
1805
            struct ovs_key_ipv4 ipv4_key;
 
1806
            struct ovs_key_ipv4 ipv4_mask;
 
1807
 
 
1808
            ipv4_key.ipv4_src = ipv4_src;
 
1809
            ipv4_key.ipv4_dst = ipv4_dst;
 
1810
            ipv4_key.ipv4_proto = ipv4_proto;
 
1811
            ipv4_key.ipv4_tos = ipv4_tos;
 
1812
            ipv4_key.ipv4_ttl = ipv4_ttl;
 
1813
            ipv4_key.ipv4_frag = ipv4_frag;
 
1814
            nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV4,
 
1815
                              &ipv4_key, sizeof ipv4_key);
 
1816
 
 
1817
            ipv4_mask.ipv4_src = ipv4_src_mask;
 
1818
            ipv4_mask.ipv4_dst = ipv4_dst_mask;
 
1819
            ipv4_mask.ipv4_proto = ipv4_proto_mask;
 
1820
            ipv4_mask.ipv4_tos = ipv4_tos_mask;
 
1821
            ipv4_mask.ipv4_ttl = ipv4_ttl_mask;
 
1822
            ipv4_mask.ipv4_frag = ipv4_frag_mask;
 
1823
            nl_msg_put_unspec(mask, OVS_KEY_ATTR_IPV4,
 
1824
                              &ipv4_mask, sizeof ipv4_mask);
 
1825
            return n;
 
1826
        } else if (sscanf(s, "ipv4(src="IP_SCAN_FMT",dst="IP_SCAN_FMT","
1167
1827
                   "proto=%i,tos=%i,ttl=%i,frag=%7[a-z])%n",
1168
1828
                   IP_SCAN_ARGS(&ipv4_src), IP_SCAN_ARGS(&ipv4_dst),
1169
1829
                   &ipv4_proto, &ipv4_tos, &ipv4_ttl, frag, &n) > 0
1179
1839
            ipv4_key.ipv4_frag = ipv4_frag;
1180
1840
            nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV4,
1181
1841
                              &ipv4_key, sizeof ipv4_key);
 
1842
 
 
1843
            if (mask) {
 
1844
                memset(&ipv4_key, 0xff, sizeof ipv4_key);
 
1845
                nl_msg_put_unspec(mask, OVS_KEY_ATTR_IPV4,
 
1846
                              &ipv4_key, sizeof ipv4_key);
 
1847
            }
1182
1848
            return n;
1183
1849
        }
1184
1850
    }
1185
1851
 
1186
1852
    {
1187
1853
        char ipv6_src_s[IPV6_SCAN_LEN + 1];
 
1854
        char ipv6_src_mask_s[IPV6_SCAN_LEN + 1];
1188
1855
        char ipv6_dst_s[IPV6_SCAN_LEN + 1];
1189
 
        int ipv6_label;
1190
 
        int ipv6_proto;
1191
 
        int ipv6_tclass;
1192
 
        int ipv6_hlimit;
 
1856
        char ipv6_dst_mask_s[IPV6_SCAN_LEN + 1];
 
1857
        int ipv6_label, ipv6_label_mask;
 
1858
        int ipv6_proto, ipv6_proto_mask;
 
1859
        int ipv6_tclass, ipv6_tclass_mask;
 
1860
        int ipv6_hlimit, ipv6_hlimit_mask;
1193
1861
        char frag[8];
1194
1862
        enum ovs_frag_type ipv6_frag;
 
1863
        int ipv6_frag_mask;
1195
1864
        int n = -1;
1196
1865
 
1197
 
        if (sscanf(s, "ipv6(src="IPV6_SCAN_FMT",dst="IPV6_SCAN_FMT","
 
1866
        if (mask && sscanf(s, "ipv6(src="IPV6_SCAN_FMT"/"IPV6_SCAN_FMT",dst="
 
1867
                   IPV6_SCAN_FMT"/"IPV6_SCAN_FMT","
 
1868
                   "label=%i/%i,proto=%i/%i,tclass=%i/%i,"
 
1869
                   "hlimit=%i/%i,frag=%7[a-z]/%i)%n",
 
1870
                   ipv6_src_s, ipv6_src_mask_s, ipv6_dst_s, ipv6_dst_mask_s,
 
1871
                   &ipv6_label, &ipv6_label_mask, &ipv6_proto,
 
1872
                   &ipv6_proto_mask, &ipv6_tclass, &ipv6_tclass_mask,
 
1873
                   &ipv6_hlimit, &ipv6_hlimit_mask, frag,
 
1874
                   &ipv6_frag_mask, &n) > 0
 
1875
            && n > 0
 
1876
            && ovs_frag_type_from_string(frag, &ipv6_frag)) {
 
1877
            struct ovs_key_ipv6 ipv6_key;
 
1878
            struct ovs_key_ipv6 ipv6_mask;
 
1879
 
 
1880
            if (inet_pton(AF_INET6, ipv6_src_s, &ipv6_key.ipv6_src) != 1 ||
 
1881
                inet_pton(AF_INET6, ipv6_dst_s, &ipv6_key.ipv6_dst) != 1 ||
 
1882
                inet_pton(AF_INET6, ipv6_src_mask_s, &ipv6_mask.ipv6_src) != 1 ||
 
1883
                inet_pton(AF_INET6, ipv6_dst_mask_s, &ipv6_mask.ipv6_dst) != 1) {
 
1884
                return -EINVAL;
 
1885
            }
 
1886
 
 
1887
            ipv6_key.ipv6_label = htonl(ipv6_label);
 
1888
            ipv6_key.ipv6_proto = ipv6_proto;
 
1889
            ipv6_key.ipv6_tclass = ipv6_tclass;
 
1890
            ipv6_key.ipv6_hlimit = ipv6_hlimit;
 
1891
            ipv6_key.ipv6_frag = ipv6_frag;
 
1892
            nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV6,
 
1893
                              &ipv6_key, sizeof ipv6_key);
 
1894
 
 
1895
            ipv6_mask.ipv6_label = htonl(ipv6_label_mask);
 
1896
            ipv6_mask.ipv6_proto = ipv6_proto_mask;
 
1897
            ipv6_mask.ipv6_tclass = ipv6_tclass_mask;
 
1898
            ipv6_mask.ipv6_hlimit = ipv6_hlimit_mask;
 
1899
            ipv6_mask.ipv6_frag = ipv6_frag_mask;
 
1900
            nl_msg_put_unspec(mask, OVS_KEY_ATTR_IPV6,
 
1901
                              &ipv6_mask, sizeof ipv6_mask);
 
1902
            return n;
 
1903
        } else if (sscanf(s, "ipv6(src="IPV6_SCAN_FMT",dst="IPV6_SCAN_FMT","
1198
1904
                   "label=%i,proto=%i,tclass=%i,hlimit=%i,frag=%7[a-z])%n",
1199
1905
                   ipv6_src_s, ipv6_dst_s, &ipv6_label,
1200
1906
                   &ipv6_proto, &ipv6_tclass, &ipv6_hlimit, frag, &n) > 0
1213
1919
            ipv6_key.ipv6_frag = ipv6_frag;
1214
1920
            nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV6,
1215
1921
                              &ipv6_key, sizeof ipv6_key);
 
1922
 
 
1923
            if (mask) {
 
1924
                memset(&ipv6_key, 0xff, sizeof ipv6_key);
 
1925
                nl_msg_put_unspec(mask, OVS_KEY_ATTR_IPV6,
 
1926
                              &ipv6_key, sizeof ipv6_key);
 
1927
            }
1216
1928
            return n;
1217
1929
        }
1218
1930
    }
1220
1932
    {
1221
1933
        int tcp_src;
1222
1934
        int tcp_dst;
 
1935
        int tcp_src_mask;
 
1936
        int tcp_dst_mask;
1223
1937
        int n = -1;
1224
1938
 
1225
 
        if (sscanf(s, "tcp(src=%i,dst=%i)%n",&tcp_src, &tcp_dst, &n) > 0
1226
 
            && n > 0) {
1227
 
            struct ovs_key_tcp tcp_key;
1228
 
 
1229
 
            tcp_key.tcp_src = htons(tcp_src);
1230
 
            tcp_key.tcp_dst = htons(tcp_dst);
1231
 
            nl_msg_put_unspec(key, OVS_KEY_ATTR_TCP, &tcp_key, sizeof tcp_key);
 
1939
        if (mask && sscanf(s, "tcp(src=%i/%i,dst=%i/%i)%n",
 
1940
                   &tcp_src, &tcp_src_mask, &tcp_dst, &tcp_dst_mask, &n) > 0
 
1941
            && n > 0) {
 
1942
            struct ovs_key_tcp tcp_key;
 
1943
            struct ovs_key_tcp tcp_mask;
 
1944
 
 
1945
            tcp_key.tcp_src = htons(tcp_src);
 
1946
            tcp_key.tcp_dst = htons(tcp_dst);
 
1947
            nl_msg_put_unspec(key, OVS_KEY_ATTR_TCP, &tcp_key, sizeof tcp_key);
 
1948
 
 
1949
            tcp_mask.tcp_src = htons(tcp_src_mask);
 
1950
            tcp_mask.tcp_dst = htons(tcp_dst_mask);
 
1951
            nl_msg_put_unspec(mask, OVS_KEY_ATTR_TCP,
 
1952
                              &tcp_mask, sizeof tcp_mask);
 
1953
            return n;
 
1954
        } else if (sscanf(s, "tcp(src=%i,dst=%i)%n",&tcp_src, &tcp_dst, &n) > 0
 
1955
            && n > 0) {
 
1956
            struct ovs_key_tcp tcp_key;
 
1957
 
 
1958
            tcp_key.tcp_src = htons(tcp_src);
 
1959
            tcp_key.tcp_dst = htons(tcp_dst);
 
1960
            nl_msg_put_unspec(key, OVS_KEY_ATTR_TCP, &tcp_key, sizeof tcp_key);
 
1961
 
 
1962
            if (mask) {
 
1963
                memset(&tcp_key, 0xff, sizeof tcp_key);
 
1964
                nl_msg_put_unspec(mask, OVS_KEY_ATTR_TCP,
 
1965
                              &tcp_key, sizeof tcp_key);
 
1966
            }
1232
1967
            return n;
1233
1968
        }
1234
1969
    }
1236
1971
    {
1237
1972
        int udp_src;
1238
1973
        int udp_dst;
 
1974
        int udp_src_mask;
 
1975
        int udp_dst_mask;
1239
1976
        int n = -1;
1240
1977
 
 
1978
        if (mask && sscanf(s, "udp(src=%i/%i,dst=%i/%i)%n",
 
1979
                   &udp_src, &udp_src_mask,
 
1980
                   &udp_dst, &udp_dst_mask, &n) > 0 && n > 0) {
 
1981
            struct ovs_key_udp udp_key;
 
1982
            struct ovs_key_udp udp_mask;
 
1983
 
 
1984
            udp_key.udp_src = htons(udp_src);
 
1985
            udp_key.udp_dst = htons(udp_dst);
 
1986
            nl_msg_put_unspec(key, OVS_KEY_ATTR_UDP, &udp_key, sizeof udp_key);
 
1987
 
 
1988
            udp_mask.udp_src = htons(udp_src_mask);
 
1989
            udp_mask.udp_dst = htons(udp_dst_mask);
 
1990
            nl_msg_put_unspec(mask, OVS_KEY_ATTR_UDP,
 
1991
                              &udp_mask, sizeof udp_mask);
 
1992
            return n;
 
1993
        }
1241
1994
        if (sscanf(s, "udp(src=%i,dst=%i)%n", &udp_src, &udp_dst, &n) > 0
1242
1995
            && n > 0) {
1243
1996
            struct ovs_key_udp udp_key;
1245
1998
            udp_key.udp_src = htons(udp_src);
1246
1999
            udp_key.udp_dst = htons(udp_dst);
1247
2000
            nl_msg_put_unspec(key, OVS_KEY_ATTR_UDP, &udp_key, sizeof udp_key);
 
2001
 
 
2002
            if (mask) {
 
2003
                memset(&udp_key, 0xff, sizeof udp_key);
 
2004
                nl_msg_put_unspec(mask, OVS_KEY_ATTR_UDP, &udp_key, sizeof udp_key);
 
2005
            }
1248
2006
            return n;
1249
2007
        }
1250
2008
    }
1252
2010
    {
1253
2011
        int icmp_type;
1254
2012
        int icmp_code;
 
2013
        int icmp_type_mask;
 
2014
        int icmp_code_mask;
1255
2015
        int n = -1;
1256
2016
 
1257
 
        if (sscanf(s, "icmp(type=%i,code=%i)%n",
 
2017
        if (mask && sscanf(s, "icmp(type=%i/%i,code=%i/%i)%n",
 
2018
                   &icmp_type, &icmp_type_mask,
 
2019
                   &icmp_code, &icmp_code_mask, &n) > 0 && n > 0) {
 
2020
            struct ovs_key_icmp icmp_key;
 
2021
            struct ovs_key_icmp icmp_mask;
 
2022
 
 
2023
            icmp_key.icmp_type = icmp_type;
 
2024
            icmp_key.icmp_code = icmp_code;
 
2025
            nl_msg_put_unspec(key, OVS_KEY_ATTR_ICMP,
 
2026
                              &icmp_key, sizeof icmp_key);
 
2027
 
 
2028
            icmp_mask.icmp_type = icmp_type_mask;
 
2029
            icmp_mask.icmp_code = icmp_code_mask;
 
2030
            nl_msg_put_unspec(mask, OVS_KEY_ATTR_ICMP,
 
2031
                              &icmp_mask, sizeof icmp_mask);
 
2032
            return n;
 
2033
        } else if (sscanf(s, "icmp(type=%i,code=%i)%n",
1258
2034
                   &icmp_type, &icmp_code, &n) > 0
1259
2035
            && n > 0) {
1260
2036
            struct ovs_key_icmp icmp_key;
1263
2039
            icmp_key.icmp_code = icmp_code;
1264
2040
            nl_msg_put_unspec(key, OVS_KEY_ATTR_ICMP,
1265
2041
                              &icmp_key, sizeof icmp_key);
 
2042
            if (mask) {
 
2043
                memset(&icmp_key, 0xff, sizeof icmp_key);
 
2044
                nl_msg_put_unspec(mask, OVS_KEY_ATTR_ICMP, &icmp_key,
 
2045
                              sizeof icmp_key);
 
2046
            }
1266
2047
            return n;
1267
2048
        }
1268
2049
    }
1269
2050
 
1270
2051
    {
1271
2052
        struct ovs_key_icmpv6 icmpv6_key;
 
2053
        struct ovs_key_icmpv6 icmpv6_mask;
 
2054
        int icmpv6_type_mask;
 
2055
        int icmpv6_code_mask;
1272
2056
        int n = -1;
1273
2057
 
1274
 
        if (sscanf(s, "icmpv6(type=%"SCNi8",code=%"SCNi8")%n",
 
2058
        if (mask && sscanf(s, "icmpv6(type=%"SCNi8"/%i,code=%"SCNi8"/%i)%n",
 
2059
                   &icmpv6_key.icmpv6_type, &icmpv6_type_mask,
 
2060
                   &icmpv6_key.icmpv6_code, &icmpv6_code_mask, &n) > 0
 
2061
            && n > 0) {
 
2062
            nl_msg_put_unspec(key, OVS_KEY_ATTR_ICMPV6,
 
2063
                              &icmpv6_key, sizeof icmpv6_key);
 
2064
 
 
2065
            icmpv6_mask.icmpv6_type = icmpv6_type_mask;
 
2066
            icmpv6_mask.icmpv6_code = icmpv6_code_mask;
 
2067
            nl_msg_put_unspec(mask, OVS_KEY_ATTR_ICMPV6, &icmpv6_mask,
 
2068
                              sizeof icmpv6_mask);
 
2069
            return n;
 
2070
        } else if (sscanf(s, "icmpv6(type=%"SCNi8",code=%"SCNi8")%n",
1275
2071
                   &icmpv6_key.icmpv6_type, &icmpv6_key.icmpv6_code,&n) > 0
1276
2072
            && n > 0) {
1277
2073
            nl_msg_put_unspec(key, OVS_KEY_ATTR_ICMPV6,
1278
2074
                              &icmpv6_key, sizeof icmpv6_key);
 
2075
 
 
2076
            if (mask) {
 
2077
                memset(&icmpv6_key, 0xff, sizeof icmpv6_key);
 
2078
                nl_msg_put_unspec(mask, OVS_KEY_ATTR_ICMPV6, &icmpv6_key,
 
2079
                              sizeof icmpv6_key);
 
2080
            }
1279
2081
            return n;
1280
2082
        }
1281
2083
    }
1282
2084
 
1283
2085
    {
1284
 
        ovs_be32 arp_sip;
1285
 
        ovs_be32 arp_tip;
1286
 
        int arp_op;
 
2086
        ovs_be32 arp_sip, arp_sip_mask;
 
2087
        ovs_be32 arp_tip, arp_tip_mask;
 
2088
        int arp_op, arp_op_mask;
1287
2089
        uint8_t arp_sha[ETH_ADDR_LEN];
 
2090
        uint8_t arp_sha_mask[ETH_ADDR_LEN];
1288
2091
        uint8_t arp_tha[ETH_ADDR_LEN];
 
2092
        uint8_t arp_tha_mask[ETH_ADDR_LEN];
1289
2093
        int n = -1;
1290
2094
 
1291
 
        if (sscanf(s, "arp(sip="IP_SCAN_FMT",tip="IP_SCAN_FMT","
 
2095
        if (mask && sscanf(s, "arp(sip="IP_SCAN_FMT"/"IP_SCAN_FMT","
 
2096
                   "tip="IP_SCAN_FMT"/"IP_SCAN_FMT","
 
2097
                   "op=%i/%i,sha="ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT","
 
2098
                   "tha="ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT")%n",
 
2099
                   IP_SCAN_ARGS(&arp_sip), IP_SCAN_ARGS(&arp_sip_mask),
 
2100
                   IP_SCAN_ARGS(&arp_tip), IP_SCAN_ARGS(&arp_tip_mask),
 
2101
                   &arp_op, &arp_op_mask,
 
2102
                   ETH_ADDR_SCAN_ARGS(arp_sha),
 
2103
                   ETH_ADDR_SCAN_ARGS(arp_sha_mask),
 
2104
                   ETH_ADDR_SCAN_ARGS(arp_tha),
 
2105
                   ETH_ADDR_SCAN_ARGS(arp_tha_mask), &n) > 0 && n > 0) {
 
2106
            struct ovs_key_arp arp_key;
 
2107
            struct ovs_key_arp arp_mask;
 
2108
 
 
2109
            memset(&arp_key, 0, sizeof arp_key);
 
2110
            arp_key.arp_sip = arp_sip;
 
2111
            arp_key.arp_tip = arp_tip;
 
2112
            arp_key.arp_op = htons(arp_op);
 
2113
            memcpy(arp_key.arp_sha, arp_sha, ETH_ADDR_LEN);
 
2114
            memcpy(arp_key.arp_tha, arp_tha, ETH_ADDR_LEN);
 
2115
            nl_msg_put_unspec(key, OVS_KEY_ATTR_ARP, &arp_key, sizeof arp_key);
 
2116
 
 
2117
            arp_mask.arp_sip = arp_sip_mask;
 
2118
            arp_mask.arp_tip = arp_tip_mask;
 
2119
            arp_mask.arp_op = htons(arp_op_mask);
 
2120
            memcpy(arp_mask.arp_sha, arp_sha_mask, ETH_ADDR_LEN);
 
2121
            memcpy(arp_mask.arp_tha, arp_tha_mask, ETH_ADDR_LEN);
 
2122
            nl_msg_put_unspec(mask, OVS_KEY_ATTR_ARP,
 
2123
                              &arp_mask, sizeof arp_mask);
 
2124
            return n;
 
2125
        } else if (sscanf(s, "arp(sip="IP_SCAN_FMT",tip="IP_SCAN_FMT","
1292
2126
                   "op=%i,sha="ETH_ADDR_SCAN_FMT",tha="ETH_ADDR_SCAN_FMT")%n",
1293
2127
                   IP_SCAN_ARGS(&arp_sip),
1294
2128
                   IP_SCAN_ARGS(&arp_tip),
1304
2138
            memcpy(arp_key.arp_sha, arp_sha, ETH_ADDR_LEN);
1305
2139
            memcpy(arp_key.arp_tha, arp_tha, ETH_ADDR_LEN);
1306
2140
            nl_msg_put_unspec(key, OVS_KEY_ATTR_ARP, &arp_key, sizeof arp_key);
 
2141
 
 
2142
            if (mask) {
 
2143
                memset(&arp_key, 0xff, sizeof arp_key);
 
2144
                nl_msg_put_unspec(mask, OVS_KEY_ATTR_ARP,
 
2145
                                  &arp_key, sizeof arp_key);
 
2146
            }
1307
2147
            return n;
1308
2148
        }
1309
2149
    }
1310
2150
 
1311
2151
    {
1312
2152
        char nd_target_s[IPV6_SCAN_LEN + 1];
 
2153
        char nd_target_mask_s[IPV6_SCAN_LEN + 1];
1313
2154
        uint8_t nd_sll[ETH_ADDR_LEN];
 
2155
        uint8_t nd_sll_mask[ETH_ADDR_LEN];
1314
2156
        uint8_t nd_tll[ETH_ADDR_LEN];
 
2157
        uint8_t nd_tll_mask[ETH_ADDR_LEN];
1315
2158
        int n = -1;
1316
2159
 
1317
 
        if (sscanf(s, "nd(target="IPV6_SCAN_FMT")%n",
 
2160
        nd_target_mask_s[0] = 0;
 
2161
        memset(nd_sll_mask, 0xff, sizeof nd_sll_mask);
 
2162
        memset(nd_tll_mask, 0xff, sizeof nd_tll_mask);
 
2163
 
 
2164
        if (mask && sscanf(s, "nd(target="IPV6_SCAN_FMT"/"IPV6_SCAN_FMT")%n",
 
2165
                   nd_target_s, nd_target_mask_s, &n) > 0 && n > 0) {
 
2166
                put_nd_key(n, nd_target_s, NULL, NULL, key);
 
2167
                put_nd_mask(n, nd_target_mask_s, NULL, NULL, mask);
 
2168
        } else if (sscanf(s, "nd(target="IPV6_SCAN_FMT")%n",
1318
2169
                   nd_target_s, &n) > 0 && n > 0) {
1319
 
            return put_nd_key(n, nd_target_s, NULL, NULL, key);
1320
 
        }
1321
 
        if (sscanf(s, "nd(target="IPV6_SCAN_FMT",sll="ETH_ADDR_SCAN_FMT")%n",
 
2170
                put_nd_key(n, nd_target_s, NULL, NULL, key);
 
2171
                if (mask) {
 
2172
                    put_nd_mask(n, nd_target_mask_s, NULL, NULL, mask);
 
2173
                }
 
2174
        } else if (mask && sscanf(s, "nd(target="IPV6_SCAN_FMT"/"IPV6_SCAN_FMT
 
2175
                         ",sll="ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT")%n",
 
2176
                   nd_target_s, nd_target_mask_s,
 
2177
                   ETH_ADDR_SCAN_ARGS(nd_sll),
 
2178
                   ETH_ADDR_SCAN_ARGS(nd_sll_mask), &n) > 0 && n > 0) {
 
2179
            put_nd_key(n, nd_target_s, nd_sll, NULL, key);
 
2180
            put_nd_mask(n, nd_target_mask_s, nd_sll_mask, NULL, mask);
 
2181
        } else if (sscanf(s, "nd(target="IPV6_SCAN_FMT",sll="ETH_ADDR_SCAN_FMT")%n",
1322
2182
                   nd_target_s, ETH_ADDR_SCAN_ARGS(nd_sll), &n) > 0
1323
2183
            && n > 0) {
1324
 
            return put_nd_key(n, nd_target_s, nd_sll, NULL, key);
1325
 
        }
1326
 
        if (sscanf(s, "nd(target="IPV6_SCAN_FMT",tll="ETH_ADDR_SCAN_FMT")%n",
 
2184
            put_nd_key(n, nd_target_s, nd_sll, NULL, key);
 
2185
            if (mask) {
 
2186
                put_nd_mask(n, nd_target_mask_s, nd_sll_mask, NULL, mask);
 
2187
            }
 
2188
        } else if (mask && sscanf(s, "nd(target="IPV6_SCAN_FMT"/"IPV6_SCAN_FMT
 
2189
                         ",tll="ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT")%n",
 
2190
                   nd_target_s, nd_target_mask_s,
 
2191
                   ETH_ADDR_SCAN_ARGS(nd_tll),
 
2192
                   ETH_ADDR_SCAN_ARGS(nd_tll_mask), &n) > 0 && n > 0) {
 
2193
            put_nd_key(n, nd_target_s, NULL, nd_tll, key);
 
2194
            put_nd_mask(n, nd_target_mask_s, NULL, nd_tll_mask, mask);
 
2195
        } else if (sscanf(s, "nd(target="IPV6_SCAN_FMT",tll="ETH_ADDR_SCAN_FMT")%n",
1327
2196
                   nd_target_s, ETH_ADDR_SCAN_ARGS(nd_tll), &n) > 0
1328
2197
            && n > 0) {
1329
 
            return put_nd_key(n, nd_target_s, NULL, nd_tll, key);
1330
 
        }
1331
 
        if (sscanf(s, "nd(target="IPV6_SCAN_FMT",sll="ETH_ADDR_SCAN_FMT","
 
2198
            put_nd_key(n, nd_target_s, NULL, nd_tll, key);
 
2199
            if (mask) {
 
2200
                put_nd_mask(n, nd_target_mask_s, NULL, nd_tll_mask, mask);
 
2201
            }
 
2202
        } else if (mask && sscanf(s, "nd(target="IPV6_SCAN_FMT"/"IPV6_SCAN_FMT
 
2203
                   ",sll="ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT","
 
2204
                   "tll="ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT")%n",
 
2205
                   nd_target_s, nd_target_mask_s,
 
2206
                   ETH_ADDR_SCAN_ARGS(nd_sll), ETH_ADDR_SCAN_ARGS(nd_sll_mask),
 
2207
                   ETH_ADDR_SCAN_ARGS(nd_tll), ETH_ADDR_SCAN_ARGS(nd_tll_mask),
 
2208
                   &n) > 0
 
2209
            && n > 0) {
 
2210
            put_nd_key(n, nd_target_s, nd_sll, nd_tll, key);
 
2211
            put_nd_mask(n, nd_target_mask_s, nd_sll_mask, nd_tll_mask, mask);
 
2212
        } else if (sscanf(s, "nd(target="IPV6_SCAN_FMT",sll="ETH_ADDR_SCAN_FMT","
1332
2213
                   "tll="ETH_ADDR_SCAN_FMT")%n",
1333
2214
                   nd_target_s, ETH_ADDR_SCAN_ARGS(nd_sll),
1334
2215
                   ETH_ADDR_SCAN_ARGS(nd_tll), &n) > 0
1335
2216
            && n > 0) {
1336
 
            return put_nd_key(n, nd_target_s, nd_sll, nd_tll, key);
 
2217
            put_nd_key(n, nd_target_s, nd_sll, nd_tll, key);
 
2218
            if (mask) {
 
2219
                put_nd_mask(n, nd_target_mask_s,
 
2220
                            nd_sll_mask, nd_tll_mask, mask);
 
2221
            }
1337
2222
        }
 
2223
 
 
2224
        if (n != -1)
 
2225
            return n;
 
2226
 
1338
2227
    }
1339
2228
 
1340
2229
    if (!strncmp(s, "encap(", 6)) {
1341
2230
        const char *start = s;
1342
 
        size_t encap;
 
2231
        size_t encap, encap_mask = 0;
1343
2232
 
1344
2233
        encap = nl_msg_start_nested(key, OVS_KEY_ATTR_ENCAP);
 
2234
        if (mask) {
 
2235
            encap_mask = nl_msg_start_nested(mask, OVS_KEY_ATTR_ENCAP);
 
2236
        }
1345
2237
 
1346
2238
        s += 6;
1347
2239
        for (;;) {
1354
2246
                break;
1355
2247
            }
1356
2248
 
1357
 
            retval = parse_odp_key_attr(s, port_names, key);
 
2249
            retval = parse_odp_key_mask_attr(s, port_names, key, mask);
1358
2250
            if (retval < 0) {
1359
2251
                return retval;
1360
2252
            }
1363
2255
        s++;
1364
2256
 
1365
2257
        nl_msg_end_nested(key, encap);
 
2258
        if (mask) {
 
2259
            nl_msg_end_nested(mask, encap_mask);
 
2260
        }
1366
2261
 
1367
2262
        return s - start;
1368
2263
    }
1385
2280
 * valid, but they may not be valid as a sequence.  'key' might, for example,
1386
2281
 * have duplicated keys.  odp_flow_key_to_flow() will detect those errors. */
1387
2282
int
1388
 
odp_flow_key_from_string(const char *s, const struct simap *port_names,
1389
 
                         struct ofpbuf *key)
 
2283
odp_flow_from_string(const char *s, const struct simap *port_names,
 
2284
                     struct ofpbuf *key, struct ofpbuf *mask)
1390
2285
{
1391
2286
    const size_t old_size = key->size;
1392
2287
    for (;;) {
1397
2292
            return 0;
1398
2293
        }
1399
2294
 
1400
 
        retval = parse_odp_key_attr(s, port_names, key);
 
2295
        retval = parse_odp_key_mask_attr(s, port_names, key, mask);
1401
2296
        if (retval < 0) {
1402
2297
            key->size = old_size;
1403
2298
            return -retval;
1416
2311
          : OVS_FRAG_TYPE_LATER);
1417
2312
}
1418
2313
 
1419
 
/* Appends a representation of 'flow' as OVS_KEY_ATTR_* attributes to 'buf'.
1420
 
 * 'flow->in_port' is ignored (since it is likely to be an OpenFlow port
1421
 
 * number rather than a datapath port number).  Instead, if 'odp_in_port'
1422
 
 * is anything other than OVSP_NONE, it is included in 'buf' as the input
1423
 
 * port.
1424
 
 *
1425
 
 * 'buf' must have at least ODPUTIL_FLOW_KEY_BYTES bytes of space, or be
1426
 
 * capable of being expanded to allow for that much space. */
1427
 
void
1428
 
odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
1429
 
                       uint32_t odp_in_port)
1430
 
{
 
2314
static uint8_t
 
2315
ovs_to_odp_frag_mask(uint8_t nw_frag_mask)
 
2316
{
 
2317
    uint8_t frag_mask = ~(OVS_FRAG_TYPE_FIRST | OVS_FRAG_TYPE_LATER);
 
2318
 
 
2319
    frag_mask |= (nw_frag_mask & FLOW_NW_FRAG_ANY) ? OVS_FRAG_TYPE_FIRST : 0;
 
2320
    frag_mask |= (nw_frag_mask & FLOW_NW_FRAG_LATER) ? OVS_FRAG_TYPE_LATER : 0;
 
2321
 
 
2322
    return frag_mask;
 
2323
}
 
2324
 
 
2325
static void
 
2326
odp_flow_key_from_flow__(struct ofpbuf *buf, const struct flow *data,
 
2327
                         const struct flow *flow, odp_port_t odp_in_port)
 
2328
{
 
2329
    bool is_mask;
1431
2330
    struct ovs_key_ethernet *eth_key;
1432
2331
    size_t encap;
1433
2332
 
 
2333
    /* We assume that if 'data' and 'flow' are not the same, we should
 
2334
     * treat 'data' as a mask. */
 
2335
    is_mask = (data != flow);
 
2336
 
1434
2337
    if (flow->skb_priority) {
1435
 
        nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, flow->skb_priority);
 
2338
        nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, data->skb_priority);
1436
2339
    }
1437
2340
 
1438
 
    if (flow->tunnel.ip_dst) {
1439
 
        tun_key_to_attr(buf, &flow->tunnel);
 
2341
    if (flow->tunnel.ip_dst || is_mask) {
 
2342
        tun_key_to_attr(buf, &data->tunnel);
1440
2343
    }
1441
2344
 
1442
2345
    if (flow->skb_mark) {
1443
 
        nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, flow->skb_mark);
 
2346
        nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, data->skb_mark);
1444
2347
    }
1445
2348
 
1446
 
    if (odp_in_port != OVSP_NONE) {
1447
 
        nl_msg_put_u32(buf, OVS_KEY_ATTR_IN_PORT, odp_in_port);
 
2349
    /* Add an ingress port attribute if this is a mask or 'odp_in_port'
 
2350
     * is not the magical value "ODPP_NONE". */
 
2351
    if (is_mask || odp_in_port != ODPP_NONE) {
 
2352
        nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, odp_in_port);
1448
2353
    }
1449
2354
 
1450
2355
    eth_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ETHERNET,
1451
2356
                                       sizeof *eth_key);
1452
 
    memcpy(eth_key->eth_src, flow->dl_src, ETH_ADDR_LEN);
1453
 
    memcpy(eth_key->eth_dst, flow->dl_dst, ETH_ADDR_LEN);
 
2357
    memcpy(eth_key->eth_src, data->dl_src, ETH_ADDR_LEN);
 
2358
    memcpy(eth_key->eth_dst, data->dl_dst, ETH_ADDR_LEN);
1454
2359
 
1455
2360
    if (flow->vlan_tci != htons(0) || flow->dl_type == htons(ETH_TYPE_VLAN)) {
1456
 
        nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, htons(ETH_TYPE_VLAN));
1457
 
        nl_msg_put_be16(buf, OVS_KEY_ATTR_VLAN, flow->vlan_tci);
 
2361
        if (is_mask) {
 
2362
            nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, htons(UINT16_MAX));
 
2363
        } else {
 
2364
            nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, htons(ETH_TYPE_VLAN));
 
2365
        }
 
2366
        nl_msg_put_be16(buf, OVS_KEY_ATTR_VLAN, data->vlan_tci);
1458
2367
        encap = nl_msg_start_nested(buf, OVS_KEY_ATTR_ENCAP);
1459
2368
        if (flow->vlan_tci == htons(0)) {
1460
2369
            goto unencap;
1464
2373
    }
1465
2374
 
1466
2375
    if (ntohs(flow->dl_type) < ETH_TYPE_MIN) {
 
2376
        /* For backwards compatibility with kernels that don't support
 
2377
         * wildcarding, the following convention is used to encode the
 
2378
         * OVS_KEY_ATTR_ETHERTYPE for key and mask:
 
2379
         *
 
2380
         *   key      mask    matches
 
2381
         * -------- --------  -------
 
2382
         *  >0x5ff   0xffff   Specified Ethernet II Ethertype.
 
2383
         *  >0x5ff      0     Any Ethernet II or non-Ethernet II frame.
 
2384
         *  <none>   0xffff   Any non-Ethernet II frame (except valid
 
2385
         *                    802.3 SNAP packet with valid eth_type).
 
2386
         */
 
2387
        if (is_mask) {
 
2388
            nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, htons(UINT16_MAX));
 
2389
        }
1467
2390
        goto unencap;
1468
2391
    }
1469
2392
 
1470
 
    nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, flow->dl_type);
 
2393
    nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, data->dl_type);
1471
2394
 
1472
2395
    if (flow->dl_type == htons(ETH_TYPE_IP)) {
1473
2396
        struct ovs_key_ipv4 *ipv4_key;
1474
2397
 
1475
2398
        ipv4_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV4,
1476
2399
                                            sizeof *ipv4_key);
1477
 
        ipv4_key->ipv4_src = flow->nw_src;
1478
 
        ipv4_key->ipv4_dst = flow->nw_dst;
1479
 
        ipv4_key->ipv4_proto = flow->nw_proto;
1480
 
        ipv4_key->ipv4_tos = flow->nw_tos;
1481
 
        ipv4_key->ipv4_ttl = flow->nw_ttl;
1482
 
        ipv4_key->ipv4_frag = ovs_to_odp_frag(flow->nw_frag);
 
2400
        ipv4_key->ipv4_src = data->nw_src;
 
2401
        ipv4_key->ipv4_dst = data->nw_dst;
 
2402
        ipv4_key->ipv4_proto = data->nw_proto;
 
2403
        ipv4_key->ipv4_tos = data->nw_tos;
 
2404
        ipv4_key->ipv4_ttl = data->nw_ttl;
 
2405
        ipv4_key->ipv4_frag = is_mask ? ovs_to_odp_frag_mask(data->nw_frag)
 
2406
                                      : ovs_to_odp_frag(data->nw_frag);
1483
2407
    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
1484
2408
        struct ovs_key_ipv6 *ipv6_key;
1485
2409
 
1486
2410
        ipv6_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV6,
1487
2411
                                            sizeof *ipv6_key);
1488
 
        memcpy(ipv6_key->ipv6_src, &flow->ipv6_src, sizeof ipv6_key->ipv6_src);
1489
 
        memcpy(ipv6_key->ipv6_dst, &flow->ipv6_dst, sizeof ipv6_key->ipv6_dst);
1490
 
        ipv6_key->ipv6_label = flow->ipv6_label;
1491
 
        ipv6_key->ipv6_proto = flow->nw_proto;
1492
 
        ipv6_key->ipv6_tclass = flow->nw_tos;
1493
 
        ipv6_key->ipv6_hlimit = flow->nw_ttl;
1494
 
        ipv6_key->ipv6_frag = ovs_to_odp_frag(flow->nw_frag);
 
2412
        memcpy(ipv6_key->ipv6_src, &data->ipv6_src, sizeof ipv6_key->ipv6_src);
 
2413
        memcpy(ipv6_key->ipv6_dst, &data->ipv6_dst, sizeof ipv6_key->ipv6_dst);
 
2414
        ipv6_key->ipv6_label = data->ipv6_label;
 
2415
        ipv6_key->ipv6_proto = data->nw_proto;
 
2416
        ipv6_key->ipv6_tclass = data->nw_tos;
 
2417
        ipv6_key->ipv6_hlimit = data->nw_ttl;
 
2418
        ipv6_key->ipv6_frag = is_mask ? ovs_to_odp_frag_mask(data->nw_frag)
 
2419
                                      : ovs_to_odp_frag(data->nw_frag);
1495
2420
    } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
1496
2421
               flow->dl_type == htons(ETH_TYPE_RARP)) {
1497
2422
        struct ovs_key_arp *arp_key;
1499
2424
        arp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ARP,
1500
2425
                                           sizeof *arp_key);
1501
2426
        memset(arp_key, 0, sizeof *arp_key);
1502
 
        arp_key->arp_sip = flow->nw_src;
1503
 
        arp_key->arp_tip = flow->nw_dst;
1504
 
        arp_key->arp_op = htons(flow->nw_proto);
1505
 
        memcpy(arp_key->arp_sha, flow->arp_sha, ETH_ADDR_LEN);
1506
 
        memcpy(arp_key->arp_tha, flow->arp_tha, ETH_ADDR_LEN);
 
2427
        arp_key->arp_sip = data->nw_src;
 
2428
        arp_key->arp_tip = data->nw_dst;
 
2429
        arp_key->arp_op = htons(data->nw_proto);
 
2430
        memcpy(arp_key->arp_sha, data->arp_sha, ETH_ADDR_LEN);
 
2431
        memcpy(arp_key->arp_tha, data->arp_tha, ETH_ADDR_LEN);
 
2432
    }
 
2433
 
 
2434
    if (flow->mpls_depth) {
 
2435
        struct ovs_key_mpls *mpls_key;
 
2436
 
 
2437
        mpls_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_MPLS,
 
2438
                                            sizeof *mpls_key);
 
2439
        mpls_key->mpls_lse = data->mpls_lse;
1507
2440
    }
1508
2441
 
1509
2442
    if (is_ip_any(flow) && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
1512
2445
 
1513
2446
            tcp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_TCP,
1514
2447
                                               sizeof *tcp_key);
1515
 
            tcp_key->tcp_src = flow->tp_src;
1516
 
            tcp_key->tcp_dst = flow->tp_dst;
 
2448
            tcp_key->tcp_src = data->tp_src;
 
2449
            tcp_key->tcp_dst = data->tp_dst;
1517
2450
        } else if (flow->nw_proto == IPPROTO_UDP) {
1518
2451
            struct ovs_key_udp *udp_key;
1519
2452
 
1520
2453
            udp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_UDP,
1521
2454
                                               sizeof *udp_key);
1522
 
            udp_key->udp_src = flow->tp_src;
1523
 
            udp_key->udp_dst = flow->tp_dst;
 
2455
            udp_key->udp_src = data->tp_src;
 
2456
            udp_key->udp_dst = data->tp_dst;
1524
2457
        } else if (flow->dl_type == htons(ETH_TYPE_IP)
1525
2458
                && flow->nw_proto == IPPROTO_ICMP) {
1526
2459
            struct ovs_key_icmp *icmp_key;
1527
2460
 
1528
2461
            icmp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ICMP,
1529
2462
                                                sizeof *icmp_key);
1530
 
            icmp_key->icmp_type = ntohs(flow->tp_src);
1531
 
            icmp_key->icmp_code = ntohs(flow->tp_dst);
 
2463
            icmp_key->icmp_type = ntohs(data->tp_src);
 
2464
            icmp_key->icmp_code = ntohs(data->tp_dst);
1532
2465
        } else if (flow->dl_type == htons(ETH_TYPE_IPV6)
1533
2466
                && flow->nw_proto == IPPROTO_ICMPV6) {
1534
2467
            struct ovs_key_icmpv6 *icmpv6_key;
1535
2468
 
1536
2469
            icmpv6_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ICMPV6,
1537
2470
                                                  sizeof *icmpv6_key);
1538
 
            icmpv6_key->icmpv6_type = ntohs(flow->tp_src);
1539
 
            icmpv6_key->icmpv6_code = ntohs(flow->tp_dst);
 
2471
            icmpv6_key->icmpv6_type = ntohs(data->tp_src);
 
2472
            icmpv6_key->icmpv6_code = ntohs(data->tp_dst);
1540
2473
 
1541
2474
            if (icmpv6_key->icmpv6_type == ND_NEIGHBOR_SOLICIT
1542
2475
                    || icmpv6_key->icmpv6_type == ND_NEIGHBOR_ADVERT) {
1544
2477
 
1545
2478
                nd_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ND,
1546
2479
                                                    sizeof *nd_key);
1547
 
                memcpy(nd_key->nd_target, &flow->nd_target,
 
2480
                memcpy(nd_key->nd_target, &data->nd_target,
1548
2481
                        sizeof nd_key->nd_target);
1549
 
                memcpy(nd_key->nd_sll, flow->arp_sha, ETH_ADDR_LEN);
1550
 
                memcpy(nd_key->nd_tll, flow->arp_tha, ETH_ADDR_LEN);
 
2482
                memcpy(nd_key->nd_sll, data->arp_sha, ETH_ADDR_LEN);
 
2483
                memcpy(nd_key->nd_tll, data->arp_tha, ETH_ADDR_LEN);
1551
2484
            }
1552
2485
        }
1553
2486
    }
1558
2491
    }
1559
2492
}
1560
2493
 
 
2494
/* Appends a representation of 'flow' as OVS_KEY_ATTR_* attributes to 'buf'.
 
2495
 * 'flow->in_port' is ignored (since it is likely to be an OpenFlow port
 
2496
 * number rather than a datapath port number).  Instead, if 'odp_in_port'
 
2497
 * is anything other than ODPP_NONE, it is included in 'buf' as the input
 
2498
 * port.
 
2499
 *
 
2500
 * 'buf' must have at least ODPUTIL_FLOW_KEY_BYTES bytes of space, or be
 
2501
 * capable of being expanded to allow for that much space. */
 
2502
void
 
2503
odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
 
2504
                       odp_port_t odp_in_port)
 
2505
{
 
2506
    odp_flow_key_from_flow__(buf, flow, flow, odp_in_port);
 
2507
}
 
2508
 
 
2509
/* Appends a representation of 'mask' as OVS_KEY_ATTR_* attributes to
 
2510
 * 'buf'.  'flow' is used as a template to determine how to interpret
 
2511
 * 'mask'.  For example, the 'dl_type' of 'mask' describes the mask, but
 
2512
 * it doesn't indicate whether the other fields should be interpreted as
 
2513
 * ARP, IPv4, IPv6, etc.
 
2514
 *
 
2515
 * 'buf' must have at least ODPUTIL_FLOW_KEY_BYTES bytes of space, or be
 
2516
 * capable of being expanded to allow for that much space. */
 
2517
void
 
2518
odp_flow_key_from_mask(struct ofpbuf *buf, const struct flow *mask,
 
2519
                       const struct flow *flow, uint32_t odp_in_port_mask)
 
2520
{
 
2521
    odp_flow_key_from_flow__(buf, mask, flow, u32_to_odp(odp_in_port_mask));
 
2522
}
 
2523
 
1561
2524
uint32_t
1562
2525
odp_flow_key_hash(const struct nlattr *key, size_t key_len)
1563
2526
{
1564
2527
    BUILD_ASSERT_DECL(!(NLA_ALIGNTO % sizeof(uint32_t)));
1565
 
    return hash_words((const uint32_t *) key, key_len / sizeof(uint32_t), 0);
 
2528
    return hash_words(ALIGNED_CAST(const uint32_t *, key),
 
2529
                      key_len / sizeof(uint32_t), 0);
1566
2530
}
1567
2531
 
1568
2532
static void
1580
2544
    ds_init(&s);
1581
2545
    for (i = 0; i < 64; i++) {
1582
2546
        if (attrs & (UINT64_C(1) << i)) {
1583
 
            ds_put_format(&s, " %s", ovs_key_attr_to_string(i));
 
2547
            char namebuf[OVS_KEY_ATTR_BUFSIZE];
 
2548
 
 
2549
            ds_put_format(&s, " %s",
 
2550
                          ovs_key_attr_to_string(i, namebuf, sizeof namebuf));
1584
2551
        }
1585
2552
    }
1586
2553
    if (out_of_range_attr) {
1632
2599
        int expected_len = odp_flow_key_attr_len(type);
1633
2600
 
1634
2601
        if (len != expected_len && expected_len >= 0) {
 
2602
            char namebuf[OVS_KEY_ATTR_BUFSIZE];
 
2603
 
1635
2604
            VLOG_ERR_RL(&rl, "attribute %s has length %zu but should have "
1636
 
                        "length %d", ovs_key_attr_to_string(type),
 
2605
                        "length %d", ovs_key_attr_to_string(type, namebuf,
 
2606
                                                            sizeof namebuf),
1637
2607
                        len, expected_len);
1638
2608
            return false;
1639
2609
        }
1642
2612
            *out_of_range_attrp = type;
1643
2613
        } else {
1644
2614
            if (present_attrs & (UINT64_C(1) << type)) {
 
2615
                char namebuf[OVS_KEY_ATTR_BUFSIZE];
 
2616
 
1645
2617
                VLOG_ERR_RL(&rl, "duplicate %s attribute in flow key",
1646
 
                            ovs_key_attr_to_string(type));
 
2618
                            ovs_key_attr_to_string(type,
 
2619
                                                   namebuf, sizeof namebuf));
1647
2620
                return false;
1648
2621
            }
1649
2622
 
1709
2682
}
1710
2683
 
1711
2684
static enum odp_key_fitness
1712
 
parse_l3_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
1713
 
                uint64_t present_attrs, int out_of_range_attr,
1714
 
                uint64_t expected_attrs, struct flow *flow,
1715
 
                const struct nlattr *key, size_t key_len)
 
2685
parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
 
2686
                  uint64_t present_attrs, int out_of_range_attr,
 
2687
                  uint64_t expected_attrs, struct flow *flow,
 
2688
                  const struct nlattr *key, size_t key_len)
1716
2689
{
1717
2690
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
1718
2691
 
1719
 
    if (flow->dl_type == htons(ETH_TYPE_IP)) {
 
2692
    if (eth_type_mpls(flow->dl_type)) {
 
2693
        expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_MPLS);
 
2694
 
 
2695
        if (!(present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS))) {
 
2696
            return ODP_FIT_TOO_LITTLE;
 
2697
        }
 
2698
        flow->mpls_lse = nl_attr_get_be32(attrs[OVS_KEY_ATTR_MPLS]);
 
2699
        flow->mpls_depth++;
 
2700
    } else if (flow->dl_type == htons(ETH_TYPE_IP)) {
1720
2701
        expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV4;
1721
2702
        if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV4)) {
1722
2703
            const struct ovs_key_ipv4 *ipv4_key;
1768
2749
    }
1769
2750
 
1770
2751
    if (flow->nw_proto == IPPROTO_TCP
1771
 
        && is_ip_any(flow)
 
2752
        && (flow->dl_type == htons(ETH_TYPE_IP) ||
 
2753
            flow->dl_type == htons(ETH_TYPE_IPV6))
1772
2754
        && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
1773
2755
        expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TCP;
1774
2756
        if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TCP)) {
1779
2761
            flow->tp_dst = tcp_key->tcp_dst;
1780
2762
        }
1781
2763
    } else if (flow->nw_proto == IPPROTO_UDP
1782
 
               && is_ip_any(flow)
 
2764
               && (flow->dl_type == htons(ETH_TYPE_IP) ||
 
2765
                   flow->dl_type == htons(ETH_TYPE_IPV6))
1783
2766
               && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
1784
2767
        expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_UDP;
1785
2768
        if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_UDP)) {
1847
2830
    enum odp_key_fitness fitness;
1848
2831
    ovs_be16 tci;
1849
2832
 
1850
 
    /* Calulate fitness of outer attributes. */
 
2833
    /* Calculate fitness of outer attributes. */
1851
2834
    expected_attrs |= ((UINT64_C(1) << OVS_KEY_ATTR_VLAN) |
1852
2835
                       (UINT64_C(1) << OVS_KEY_ATTR_ENCAP));
1853
2836
    fitness = check_expectations(present_attrs, out_of_range_attr,
1885
2868
    if (!parse_ethertype(attrs, present_attrs, &expected_attrs, flow)) {
1886
2869
        return ODP_FIT_ERROR;
1887
2870
    }
1888
 
    encap_fitness = parse_l3_onward(attrs, present_attrs, out_of_range_attr,
1889
 
                                    expected_attrs, flow, key, key_len);
 
2871
    encap_fitness = parse_l2_5_onward(attrs, present_attrs, out_of_range_attr,
 
2872
                                      expected_attrs, flow, key, key_len);
1890
2873
 
1891
2874
    /* The overall fitness is the worse of the outer and inner attributes. */
1892
2875
    return MAX(fitness, encap_fitness);
1939
2922
    if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TUNNEL)) {
1940
2923
        enum odp_key_fitness res;
1941
2924
 
1942
 
        res = tun_key_from_attr(attrs[OVS_KEY_ATTR_TUNNEL], &flow->tunnel);
 
2925
        res = odp_tun_key_from_attr(attrs[OVS_KEY_ATTR_TUNNEL], &flow->tunnel);
1943
2926
        if (res == ODP_FIT_ERROR) {
1944
2927
            return ODP_FIT_ERROR;
1945
2928
        } else if (res == ODP_FIT_PERFECT) {
1948
2931
    }
1949
2932
 
1950
2933
    if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IN_PORT)) {
1951
 
        flow->in_port = nl_attr_get_u32(attrs[OVS_KEY_ATTR_IN_PORT]);
 
2934
        flow->in_port.odp_port
 
2935
            = nl_attr_get_odp_port(attrs[OVS_KEY_ATTR_IN_PORT]);
1952
2936
        expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IN_PORT;
1953
2937
    } else {
1954
 
        flow->in_port = OVSP_NONE;
 
2938
        flow->in_port.odp_port = ODPP_NONE;
1955
2939
    }
1956
2940
 
1957
2941
    /* Ethernet header. */
1973
2957
        return parse_8021q_onward(attrs, present_attrs, out_of_range_attr,
1974
2958
                                  expected_attrs, flow, key, key_len);
1975
2959
    }
1976
 
    return parse_l3_onward(attrs, present_attrs, out_of_range_attr,
1977
 
                           expected_attrs, flow, key, key_len);
 
2960
    return parse_l2_5_onward(attrs, present_attrs, out_of_range_attr,
 
2961
                             expected_attrs, flow, key, key_len);
1978
2962
}
1979
2963
 
1980
2964
/* Returns 'fitness' as a string, for use in debug messages. */
1996
2980
}
1997
2981
 
1998
2982
/* Appends an OVS_ACTION_ATTR_USERSPACE action to 'odp_actions' that specifies
1999
 
 * Netlink PID 'pid'.  If 'cookie' is nonnull, adds a userdata attribute whose
2000
 
 * contents contains 'cookie' and returns the offset within 'odp_actions' of
2001
 
 * the start of the cookie.  (If 'cookie' is null, then the return value is not
2002
 
 * meaningful.) */
 
2983
 * Netlink PID 'pid'.  If 'userdata' is nonnull, adds a userdata attribute
 
2984
 * whose contents are the 'userdata_size' bytes at 'userdata' and returns the
 
2985
 * offset within 'odp_actions' of the start of the cookie.  (If 'userdata' is
 
2986
 * null, then the return value is not meaningful.) */
2003
2987
size_t
2004
 
odp_put_userspace_action(uint32_t pid, const union user_action_cookie *cookie,
 
2988
odp_put_userspace_action(uint32_t pid,
 
2989
                         const void *userdata, size_t userdata_size,
2005
2990
                         struct ofpbuf *odp_actions)
2006
2991
{
 
2992
    size_t userdata_ofs;
2007
2993
    size_t offset;
2008
2994
 
2009
2995
    offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_USERSPACE);
2010
2996
    nl_msg_put_u32(odp_actions, OVS_USERSPACE_ATTR_PID, pid);
2011
 
    if (cookie) {
 
2997
    if (userdata) {
 
2998
        userdata_ofs = odp_actions->size + NLA_HDRLEN;
2012
2999
        nl_msg_put_unspec(odp_actions, OVS_USERSPACE_ATTR_USERDATA,
2013
 
                          cookie, sizeof *cookie);
 
3000
                          userdata, userdata_size);
 
3001
    } else {
 
3002
        userdata_ofs = 0;
2014
3003
    }
2015
3004
    nl_msg_end_nested(odp_actions, offset);
2016
3005
 
2017
 
    return cookie ? odp_actions->size - NLA_ALIGN(sizeof *cookie) : 0;
 
3006
    return userdata_ofs;
2018
3007
}
2019
3008
 
2020
3009
void
2055
3044
commit_odp_tunnel_action(const struct flow *flow, struct flow *base,
2056
3045
                         struct ofpbuf *odp_actions)
2057
3046
{
2058
 
    if (!memcmp(&base->tunnel, &flow->tunnel, sizeof base->tunnel)) {
2059
 
        return;
2060
 
    }
2061
 
    memcpy(&base->tunnel, &flow->tunnel, sizeof base->tunnel);
2062
 
 
2063
3047
    /* A valid IPV4_TUNNEL must have non-zero ip_dst. */
2064
3048
    if (flow->tunnel.ip_dst) {
 
3049
        if (!memcmp(&base->tunnel, &flow->tunnel, sizeof base->tunnel)) {
 
3050
            return;
 
3051
        }
 
3052
        memcpy(&base->tunnel, &flow->tunnel, sizeof base->tunnel);
2065
3053
        odp_put_tunnel_action(&base->tunnel, odp_actions);
2066
3054
    }
2067
3055
}
2068
3056
 
2069
3057
static void
2070
3058
commit_set_ether_addr_action(const struct flow *flow, struct flow *base,
2071
 
                             struct ofpbuf *odp_actions)
 
3059
                             struct ofpbuf *odp_actions,
 
3060
                             struct flow_wildcards *wc)
2072
3061
{
2073
3062
    struct ovs_key_ethernet eth_key;
2074
3063
 
2077
3066
        return;
2078
3067
    }
2079
3068
 
 
3069
    memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src);
 
3070
    memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
 
3071
 
2080
3072
    memcpy(base->dl_src, flow->dl_src, ETH_ADDR_LEN);
2081
3073
    memcpy(base->dl_dst, flow->dl_dst, ETH_ADDR_LEN);
2082
3074
 
2089
3081
 
2090
3082
static void
2091
3083
commit_vlan_action(const struct flow *flow, struct flow *base,
2092
 
                   struct ofpbuf *odp_actions)
 
3084
                   struct ofpbuf *odp_actions, struct flow_wildcards *wc)
2093
3085
{
2094
3086
    if (base->vlan_tci == flow->vlan_tci) {
2095
3087
        return;
2096
3088
    }
2097
3089
 
 
3090
    memset(&wc->masks.vlan_tci, 0xff, sizeof wc->masks.vlan_tci);
 
3091
 
2098
3092
    if (base->vlan_tci & htons(VLAN_CFI)) {
2099
3093
        nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_POP_VLAN);
2100
3094
    }
2111
3105
}
2112
3106
 
2113
3107
static void
 
3108
commit_mpls_action(const struct flow *flow, struct flow *base,
 
3109
                   struct ofpbuf *odp_actions, struct flow_wildcards *wc)
 
3110
{
 
3111
    if (flow->mpls_lse == base->mpls_lse &&
 
3112
        flow->mpls_depth == base->mpls_depth) {
 
3113
        return;
 
3114
    }
 
3115
 
 
3116
    memset(&wc->masks.mpls_lse, 0xff, sizeof wc->masks.mpls_lse);
 
3117
 
 
3118
    if (flow->mpls_depth < base->mpls_depth) {
 
3119
        if (base->mpls_depth - flow->mpls_depth > 1) {
 
3120
            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10);
 
3121
            VLOG_WARN_RL(&rl, "Multiple mpls_pop actions reduced to "
 
3122
                         " a single mpls_pop action");
 
3123
        }
 
3124
 
 
3125
        nl_msg_put_be16(odp_actions, OVS_ACTION_ATTR_POP_MPLS, flow->dl_type);
 
3126
    } else if (flow->mpls_depth > base->mpls_depth) {
 
3127
        struct ovs_action_push_mpls *mpls;
 
3128
 
 
3129
        if (flow->mpls_depth - base->mpls_depth > 1) {
 
3130
            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10);
 
3131
            VLOG_WARN_RL(&rl, "Multiple mpls_push actions reduced to "
 
3132
                         " a single mpls_push action");
 
3133
        }
 
3134
 
 
3135
        mpls = nl_msg_put_unspec_uninit(odp_actions, OVS_ACTION_ATTR_PUSH_MPLS,
 
3136
                                        sizeof *mpls);
 
3137
        memset(mpls, 0, sizeof *mpls);
 
3138
        mpls->mpls_ethertype = flow->dl_type;
 
3139
        mpls->mpls_lse = flow->mpls_lse;
 
3140
    } else {
 
3141
        struct ovs_key_mpls mpls_key;
 
3142
 
 
3143
        mpls_key.mpls_lse = flow->mpls_lse;
 
3144
        commit_set_action(odp_actions, OVS_KEY_ATTR_MPLS,
 
3145
                          &mpls_key, sizeof(mpls_key));
 
3146
    }
 
3147
 
 
3148
    base->dl_type = flow->dl_type;
 
3149
    base->mpls_lse = flow->mpls_lse;
 
3150
    base->mpls_depth = flow->mpls_depth;
 
3151
}
 
3152
 
 
3153
static void
2114
3154
commit_set_ipv4_action(const struct flow *flow, struct flow *base,
2115
 
                     struct ofpbuf *odp_actions)
 
3155
                     struct ofpbuf *odp_actions, struct flow_wildcards *wc)
2116
3156
{
2117
3157
    struct ovs_key_ipv4 ipv4_key;
2118
3158
 
2124
3164
        return;
2125
3165
    }
2126
3166
 
 
3167
    memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
 
3168
    memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
 
3169
    memset(&wc->masks.nw_tos, 0xff, sizeof wc->masks.nw_tos);
 
3170
    memset(&wc->masks.nw_ttl, 0xff, sizeof wc->masks.nw_ttl);
 
3171
    memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
 
3172
    memset(&wc->masks.nw_frag, 0xff, sizeof wc->masks.nw_frag);
 
3173
 
2127
3174
    ipv4_key.ipv4_src = base->nw_src = flow->nw_src;
2128
3175
    ipv4_key.ipv4_dst = base->nw_dst = flow->nw_dst;
2129
3176
    ipv4_key.ipv4_tos = base->nw_tos = flow->nw_tos;
2137
3184
 
2138
3185
static void
2139
3186
commit_set_ipv6_action(const struct flow *flow, struct flow *base,
2140
 
                       struct ofpbuf *odp_actions)
 
3187
                       struct ofpbuf *odp_actions, struct flow_wildcards *wc)
2141
3188
{
2142
3189
    struct ovs_key_ipv6 ipv6_key;
2143
3190
 
2150
3197
        return;
2151
3198
    }
2152
3199
 
 
3200
    memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src);
 
3201
    memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
 
3202
    memset(&wc->masks.ipv6_label, 0xff, sizeof wc->masks.ipv6_label);
 
3203
    memset(&wc->masks.nw_tos, 0xff, sizeof wc->masks.nw_tos);
 
3204
    memset(&wc->masks.nw_ttl, 0xff, sizeof wc->masks.nw_ttl);
 
3205
    memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
 
3206
    memset(&wc->masks.nw_frag, 0xff, sizeof wc->masks.nw_frag);
 
3207
 
2153
3208
    base->ipv6_src = flow->ipv6_src;
2154
3209
    memcpy(&ipv6_key.ipv6_src, &base->ipv6_src, sizeof(ipv6_key.ipv6_src));
2155
3210
    base->ipv6_dst = flow->ipv6_dst;
2167
3222
 
2168
3223
static void
2169
3224
commit_set_nw_action(const struct flow *flow, struct flow *base,
2170
 
                     struct ofpbuf *odp_actions)
 
3225
                     struct ofpbuf *odp_actions, struct flow_wildcards *wc)
2171
3226
{
2172
3227
    /* Check if flow really have an IP header. */
2173
3228
    if (!flow->nw_proto) {
2175
3230
    }
2176
3231
 
2177
3232
    if (base->dl_type == htons(ETH_TYPE_IP)) {
2178
 
        commit_set_ipv4_action(flow, base, odp_actions);
 
3233
        commit_set_ipv4_action(flow, base, odp_actions, wc);
2179
3234
    } else if (base->dl_type == htons(ETH_TYPE_IPV6)) {
2180
 
        commit_set_ipv6_action(flow, base, odp_actions);
 
3235
        commit_set_ipv6_action(flow, base, odp_actions, wc);
2181
3236
    }
2182
3237
}
2183
3238
 
2184
3239
static void
2185
3240
commit_set_port_action(const struct flow *flow, struct flow *base,
2186
 
                       struct ofpbuf *odp_actions)
 
3241
                       struct ofpbuf *odp_actions, struct flow_wildcards *wc)
2187
3242
{
2188
 
    if (!base->tp_src && !base->tp_dst) {
 
3243
    if (!is_ip_any(base) || (!base->tp_src && !base->tp_dst)) {
2189
3244
        return;
2190
3245
    }
2191
3246
 
2194
3249
        return;
2195
3250
    }
2196
3251
 
 
3252
    memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
 
3253
    memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
 
3254
 
2197
3255
    if (flow->nw_proto == IPPROTO_TCP) {
2198
3256
        struct ovs_key_tcp port_key;
2199
3257
 
2216
3274
 
2217
3275
static void
2218
3276
commit_set_priority_action(const struct flow *flow, struct flow *base,
2219
 
                           struct ofpbuf *odp_actions)
 
3277
                           struct ofpbuf *odp_actions,
 
3278
                           struct flow_wildcards *wc)
2220
3279
{
2221
3280
    if (base->skb_priority == flow->skb_priority) {
2222
3281
        return;
2223
3282
    }
 
3283
 
 
3284
    memset(&wc->masks.skb_priority, 0xff, sizeof wc->masks.skb_priority);
2224
3285
    base->skb_priority = flow->skb_priority;
2225
3286
 
2226
3287
    commit_set_action(odp_actions, OVS_KEY_ATTR_PRIORITY,
2229
3290
 
2230
3291
static void
2231
3292
commit_set_skb_mark_action(const struct flow *flow, struct flow *base,
2232
 
                           struct ofpbuf *odp_actions)
 
3293
                           struct ofpbuf *odp_actions,
 
3294
                           struct flow_wildcards *wc)
2233
3295
{
2234
3296
    if (base->skb_mark == flow->skb_mark) {
2235
3297
        return;
2236
3298
    }
 
3299
 
 
3300
    memset(&wc->masks.skb_mark, 0xff, sizeof wc->masks.skb_mark);
2237
3301
    base->skb_mark = flow->skb_mark;
2238
3302
 
2239
3303
    odp_put_skb_mark_action(base->skb_mark, odp_actions);
2242
3306
 * 'base' and 'flow', appends ODP actions to 'odp_actions' that change the flow
2243
3307
 * key from 'base' into 'flow', and then changes 'base' the same way.  Does not
2244
3308
 * commit set_tunnel actions.  Users should call commit_odp_tunnel_action()
2245
 
 * in addition to this function if needed. */
 
3309
 * in addition to this function if needed.  Sets fields in 'wc' that are
 
3310
 * used as part of the action. */
2246
3311
void
2247
3312
commit_odp_actions(const struct flow *flow, struct flow *base,
2248
 
                   struct ofpbuf *odp_actions)
 
3313
                   struct ofpbuf *odp_actions, struct flow_wildcards *wc)
2249
3314
{
2250
 
    commit_set_ether_addr_action(flow, base, odp_actions);
2251
 
    commit_vlan_action(flow, base, odp_actions);
2252
 
    commit_set_nw_action(flow, base, odp_actions);
2253
 
    commit_set_port_action(flow, base, odp_actions);
2254
 
    commit_set_priority_action(flow, base, odp_actions);
2255
 
    commit_set_skb_mark_action(flow, base, odp_actions);
 
3315
    commit_set_ether_addr_action(flow, base, odp_actions, wc);
 
3316
    commit_vlan_action(flow, base, odp_actions, wc);
 
3317
    commit_set_nw_action(flow, base, odp_actions, wc);
 
3318
    commit_set_port_action(flow, base, odp_actions, wc);
 
3319
    /* Committing MPLS actions should occur after committing nw and port
 
3320
     * actions. This is because committing MPLS actions may alter a packet so
 
3321
     * that it is no longer IP and thus nw and port actions are no longer valid.
 
3322
     */
 
3323
    commit_mpls_action(flow, base, odp_actions, wc);
 
3324
    commit_set_priority_action(flow, base, odp_actions, wc);
 
3325
    commit_set_skb_mark_action(flow, base, odp_actions, wc);
2256
3326
}