hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/net/openvswitch/flow_netlink.c
....@@ -1,19 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2007-2017 Nicira, Inc.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of version 2 of the GNU General Public
6
- * License as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful, but
9
- * WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
- * General Public License for more details.
12
- *
13
- * You should have received a copy of the GNU General Public License
14
- * along with this program; if not, write to the Free Software
15
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16
- * 02110-1301, USA
174 */
185
196 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -91,6 +78,9 @@
9178 case OVS_ACTION_ATTR_SET:
9279 case OVS_ACTION_ATTR_SET_MASKED:
9380 case OVS_ACTION_ATTR_METER:
81
+ case OVS_ACTION_ATTR_CHECK_PKT_LEN:
82
+ case OVS_ACTION_ATTR_ADD_MPLS:
83
+ case OVS_ACTION_ATTR_DEC_TTL:
9484 default:
9585 return true;
9686 }
....@@ -403,6 +393,7 @@
403393 [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = sizeof(struct in6_addr) },
404394 [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) },
405395 [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = OVS_ATTR_VARIABLE },
396
+ [OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE] = { .len = 0 },
406397 };
407398
408399 static const struct ovs_len_tbl
....@@ -435,7 +426,7 @@
435426 [OVS_KEY_ATTR_DP_HASH] = { .len = sizeof(u32) },
436427 [OVS_KEY_ATTR_TUNNEL] = { .len = OVS_ATTR_NESTED,
437428 .next = ovs_tunnel_key_lens, },
438
- [OVS_KEY_ATTR_MPLS] = { .len = sizeof(struct ovs_key_mpls) },
429
+ [OVS_KEY_ATTR_MPLS] = { .len = OVS_ATTR_VARIABLE },
439430 [OVS_KEY_ATTR_CT_STATE] = { .len = sizeof(u32) },
440431 [OVS_KEY_ATTR_CT_ZONE] = { .len = sizeof(u16) },
441432 [OVS_KEY_ATTR_CT_MARK] = { .len = sizeof(u32) },
....@@ -666,6 +657,7 @@
666657 bool log)
667658 {
668659 bool ttl = false, ipv4 = false, ipv6 = false;
660
+ bool info_bridge_mode = false;
669661 __be16 tun_flags = 0;
670662 int opts_type = 0;
671663 struct nlattr *a;
....@@ -782,6 +774,10 @@
782774 tun_flags |= TUNNEL_ERSPAN_OPT;
783775 opts_type = type;
784776 break;
777
+ case OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE:
778
+ info_bridge_mode = true;
779
+ ipv4 = true;
780
+ break;
785781 default:
786782 OVS_NLERR(log, "Unknown IP tunnel attribute %d",
787783 type);
....@@ -812,16 +808,29 @@
812808 OVS_NLERR(log, "IP tunnel dst address not specified");
813809 return -EINVAL;
814810 }
815
- if (ipv4 && !match->key->tun_key.u.ipv4.dst) {
816
- OVS_NLERR(log, "IPv4 tunnel dst address is zero");
817
- return -EINVAL;
811
+ if (ipv4) {
812
+ if (info_bridge_mode) {
813
+ if (match->key->tun_key.u.ipv4.src ||
814
+ match->key->tun_key.u.ipv4.dst ||
815
+ match->key->tun_key.tp_src ||
816
+ match->key->tun_key.tp_dst ||
817
+ match->key->tun_key.ttl ||
818
+ match->key->tun_key.tos ||
819
+ tun_flags & ~TUNNEL_KEY) {
820
+ OVS_NLERR(log, "IPv4 tun info is not correct");
821
+ return -EINVAL;
822
+ }
823
+ } else if (!match->key->tun_key.u.ipv4.dst) {
824
+ OVS_NLERR(log, "IPv4 tunnel dst address is zero");
825
+ return -EINVAL;
826
+ }
818827 }
819828 if (ipv6 && ipv6_addr_any(&match->key->tun_key.u.ipv6.dst)) {
820829 OVS_NLERR(log, "IPv6 tunnel dst address is zero");
821830 return -EINVAL;
822831 }
823832
824
- if (!ttl) {
833
+ if (!ttl && !info_bridge_mode) {
825834 OVS_NLERR(log, "IP tunnel TTL not specified.");
826835 return -EINVAL;
827836 }
....@@ -836,7 +845,7 @@
836845 const struct vxlan_metadata *opts = tun_opts;
837846 struct nlattr *nla;
838847
839
- nla = nla_nest_start(skb, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
848
+ nla = nla_nest_start_noflag(skb, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
840849 if (!nla)
841850 return -EMSGSIZE;
842851
....@@ -850,12 +859,17 @@
850859 static int __ip_tun_to_nlattr(struct sk_buff *skb,
851860 const struct ip_tunnel_key *output,
852861 const void *tun_opts, int swkey_tun_opts_len,
853
- unsigned short tun_proto)
862
+ unsigned short tun_proto, u8 mode)
854863 {
855864 if (output->tun_flags & TUNNEL_KEY &&
856865 nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id,
857866 OVS_TUNNEL_KEY_ATTR_PAD))
858867 return -EMSGSIZE;
868
+
869
+ if (mode & IP_TUNNEL_INFO_BRIDGE)
870
+ return nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE)
871
+ ? -EMSGSIZE : 0;
872
+
859873 switch (tun_proto) {
860874 case AF_INET:
861875 if (output->u.ipv4.src &&
....@@ -918,17 +932,17 @@
918932 static int ip_tun_to_nlattr(struct sk_buff *skb,
919933 const struct ip_tunnel_key *output,
920934 const void *tun_opts, int swkey_tun_opts_len,
921
- unsigned short tun_proto)
935
+ unsigned short tun_proto, u8 mode)
922936 {
923937 struct nlattr *nla;
924938 int err;
925939
926
- nla = nla_nest_start(skb, OVS_KEY_ATTR_TUNNEL);
940
+ nla = nla_nest_start_noflag(skb, OVS_KEY_ATTR_TUNNEL);
927941 if (!nla)
928942 return -EMSGSIZE;
929943
930944 err = __ip_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len,
931
- tun_proto);
945
+ tun_proto, mode);
932946 if (err)
933947 return err;
934948
....@@ -942,7 +956,7 @@
942956 return __ip_tun_to_nlattr(skb, &tun_info->key,
943957 ip_tunnel_info_opts(tun_info),
944958 tun_info->options_len,
945
- ip_tunnel_info_af(tun_info));
959
+ ip_tunnel_info_af(tun_info), tun_info->mode);
946960 }
947961
948962 static int encode_vlan_from_nlattrs(struct sw_flow_match *match,
....@@ -990,9 +1004,9 @@
9901004 if (a[OVS_KEY_ATTR_VLAN])
9911005 tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
9921006
993
- if (!(tci & htons(VLAN_TAG_PRESENT))) {
1007
+ if (!(tci & htons(VLAN_CFI_MASK))) {
9941008 if (tci) {
995
- OVS_NLERR(log, "%s TCI does not have VLAN_TAG_PRESENT bit set.",
1009
+ OVS_NLERR(log, "%s TCI does not have VLAN_CFI_MASK bit set.",
9961010 (inner) ? "C-VLAN" : "VLAN");
9971011 return -EINVAL;
9981012 } else if (nla_len(a[OVS_KEY_ATTR_ENCAP])) {
....@@ -1013,9 +1027,9 @@
10131027 __be16 tci = 0;
10141028 __be16 tpid = 0;
10151029 bool encap_valid = !!(match->key->eth.vlan.tci &
1016
- htons(VLAN_TAG_PRESENT));
1030
+ htons(VLAN_CFI_MASK));
10171031 bool i_encap_valid = !!(match->key->eth.cvlan.tci &
1018
- htons(VLAN_TAG_PRESENT));
1032
+ htons(VLAN_CFI_MASK));
10191033
10201034 if (!(key_attrs & (1 << OVS_KEY_ATTR_ENCAP))) {
10211035 /* Not a VLAN. */
....@@ -1039,8 +1053,8 @@
10391053 (inner) ? "C-VLAN" : "VLAN", ntohs(tpid));
10401054 return -EINVAL;
10411055 }
1042
- if (!(tci & htons(VLAN_TAG_PRESENT))) {
1043
- OVS_NLERR(log, "%s TCI mask does not have exact match for VLAN_TAG_PRESENT bit.",
1056
+ if (!(tci & htons(VLAN_CFI_MASK))) {
1057
+ OVS_NLERR(log, "%s TCI mask does not have exact match for VLAN_CFI_MASK bit.",
10441058 (inner) ? "C-VLAN" : "VLAN");
10451059 return -EINVAL;
10461060 }
....@@ -1095,7 +1109,7 @@
10951109 if (err)
10961110 return err;
10971111
1098
- encap_valid = !!(match->key->eth.vlan.tci & htons(VLAN_TAG_PRESENT));
1112
+ encap_valid = !!(match->key->eth.vlan.tci & htons(VLAN_CFI_MASK));
10991113 if (encap_valid) {
11001114 err = __parse_vlan_from_nlattrs(match, key_attrs, true, a,
11011115 is_mask, log);
....@@ -1616,10 +1630,25 @@
16161630
16171631 if (attrs & (1 << OVS_KEY_ATTR_MPLS)) {
16181632 const struct ovs_key_mpls *mpls_key;
1633
+ u32 hdr_len;
1634
+ u32 label_count, label_count_mask, i;
16191635
16201636 mpls_key = nla_data(a[OVS_KEY_ATTR_MPLS]);
1621
- SW_FLOW_KEY_PUT(match, mpls.top_lse,
1622
- mpls_key->mpls_lse, is_mask);
1637
+ hdr_len = nla_len(a[OVS_KEY_ATTR_MPLS]);
1638
+ label_count = hdr_len / sizeof(struct ovs_key_mpls);
1639
+
1640
+ if (label_count == 0 || label_count > MPLS_LABEL_DEPTH ||
1641
+ hdr_len % sizeof(struct ovs_key_mpls))
1642
+ return -EINVAL;
1643
+
1644
+ label_count_mask = GENMASK(label_count - 1, 0);
1645
+
1646
+ for (i = 0 ; i < label_count; i++)
1647
+ SW_FLOW_KEY_PUT(match, mpls.lse[i],
1648
+ mpls_key[i].mpls_lse, is_mask);
1649
+
1650
+ SW_FLOW_KEY_PUT(match, mpls.num_labels_mask,
1651
+ label_count_mask, is_mask);
16231652
16241653 attrs &= ~(1 << OVS_KEY_ATTR_MPLS);
16251654 }
....@@ -1734,11 +1763,11 @@
17341763 * does not include any don't care bit.
17351764 * @net: Used to determine per-namespace field support.
17361765 * @match: receives the extracted flow match information.
1737
- * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
1766
+ * @nla_key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
17381767 * sequence. The fields should of the packet that triggered the creation
17391768 * of this flow.
1740
- * @mask: Optional. Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink
1741
- * attribute specifies the mask field of the wildcarded flow.
1769
+ * @nla_mask: Optional. Netlink attribute holding nested %OVS_KEY_ATTR_*
1770
+ * Netlink attribute specifies the mask field of the wildcarded flow.
17421771 * @log: Boolean to allow kernel error logging. Normally true, but when
17431772 * probing for feature compatibility this should be passed in as false to
17441773 * suppress unnecessary error logging.
....@@ -1932,7 +1961,7 @@
19321961 {
19331962 struct nlattr *start;
19341963
1935
- start = nla_nest_start(skb, OVS_KEY_ATTR_NSH);
1964
+ start = nla_nest_start_noflag(skb, OVS_KEY_ATTR_NSH);
19361965 if (!start)
19371966 return -EMSGSIZE;
19381967
....@@ -1980,7 +2009,7 @@
19802009 opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len);
19812010
19822011 if (ip_tun_to_nlattr(skb, &output->tun_key, opts,
1983
- swkey->tun_opts_len, swkey->tun_proto))
2012
+ swkey->tun_opts_len, swkey->tun_proto, 0))
19842013 goto nla_put_failure;
19852014 }
19862015
....@@ -2015,14 +2044,15 @@
20152044 if (swkey->eth.vlan.tci || eth_type_vlan(swkey->eth.type)) {
20162045 if (ovs_nla_put_vlan(skb, &output->eth.vlan, is_mask))
20172046 goto nla_put_failure;
2018
- encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP);
2047
+ encap = nla_nest_start_noflag(skb, OVS_KEY_ATTR_ENCAP);
20192048 if (!swkey->eth.vlan.tci)
20202049 goto unencap;
20212050
20222051 if (swkey->eth.cvlan.tci || eth_type_vlan(swkey->eth.type)) {
20232052 if (ovs_nla_put_vlan(skb, &output->eth.cvlan, is_mask))
20242053 goto nla_put_failure;
2025
- in_encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP);
2054
+ in_encap = nla_nest_start_noflag(skb,
2055
+ OVS_KEY_ATTR_ENCAP);
20262056 if (!swkey->eth.cvlan.tci)
20272057 goto unencap;
20282058 }
....@@ -2101,13 +2131,18 @@
21012131 ether_addr_copy(arp_key->arp_sha, output->ipv4.arp.sha);
21022132 ether_addr_copy(arp_key->arp_tha, output->ipv4.arp.tha);
21032133 } else if (eth_p_mpls(swkey->eth.type)) {
2134
+ u8 i, num_labels;
21042135 struct ovs_key_mpls *mpls_key;
21052136
2106
- nla = nla_reserve(skb, OVS_KEY_ATTR_MPLS, sizeof(*mpls_key));
2137
+ num_labels = hweight_long(output->mpls.num_labels_mask);
2138
+ nla = nla_reserve(skb, OVS_KEY_ATTR_MPLS,
2139
+ num_labels * sizeof(*mpls_key));
21072140 if (!nla)
21082141 goto nla_put_failure;
2142
+
21092143 mpls_key = nla_data(nla);
2110
- mpls_key->mpls_lse = output->mpls.top_lse;
2144
+ for (i = 0; i < num_labels; i++)
2145
+ mpls_key[i].mpls_lse = output->mpls.lse[i];
21112146 }
21122147
21132148 if ((swkey->eth.type == htons(ETH_P_IP) ||
....@@ -2166,8 +2201,8 @@
21662201 icmpv6_key->icmpv6_type = ntohs(output->tp.src);
21672202 icmpv6_key->icmpv6_code = ntohs(output->tp.dst);
21682203
2169
- if (icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_SOLICITATION ||
2170
- icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) {
2204
+ if (swkey->tp.src == htons(NDISC_NEIGHBOUR_SOLICITATION) ||
2205
+ swkey->tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT)) {
21712206 struct ovs_key_nd *nd_key;
21722207
21732208 nla = nla_reserve(skb, OVS_KEY_ATTR_ND, sizeof(*nd_key));
....@@ -2201,7 +2236,7 @@
22012236 int err;
22022237 struct nlattr *nla;
22032238
2204
- nla = nla_nest_start(skb, attr);
2239
+ nla = nla_nest_start_noflag(skb, attr);
22052240 if (!nla)
22062241 return -EMSGSIZE;
22072242 err = __ovs_nla_put_key(swkey, output, is_mask, skb);
....@@ -2253,6 +2288,62 @@
22532288 return sfa;
22542289 }
22552290
2291
+static void ovs_nla_free_nested_actions(const struct nlattr *actions, int len);
2292
+
2293
+static void ovs_nla_free_check_pkt_len_action(const struct nlattr *action)
2294
+{
2295
+ const struct nlattr *a;
2296
+ int rem;
2297
+
2298
+ nla_for_each_nested(a, action, rem) {
2299
+ switch (nla_type(a)) {
2300
+ case OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL:
2301
+ case OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER:
2302
+ ovs_nla_free_nested_actions(nla_data(a), nla_len(a));
2303
+ break;
2304
+ }
2305
+ }
2306
+}
2307
+
2308
+static void ovs_nla_free_clone_action(const struct nlattr *action)
2309
+{
2310
+ const struct nlattr *a = nla_data(action);
2311
+ int rem = nla_len(action);
2312
+
2313
+ switch (nla_type(a)) {
2314
+ case OVS_CLONE_ATTR_EXEC:
2315
+ /* The real list of actions follows this attribute. */
2316
+ a = nla_next(a, &rem);
2317
+ ovs_nla_free_nested_actions(a, rem);
2318
+ break;
2319
+ }
2320
+}
2321
+
2322
+static void ovs_nla_free_dec_ttl_action(const struct nlattr *action)
2323
+{
2324
+ const struct nlattr *a = nla_data(action);
2325
+
2326
+ switch (nla_type(a)) {
2327
+ case OVS_DEC_TTL_ATTR_ACTION:
2328
+ ovs_nla_free_nested_actions(nla_data(a), nla_len(a));
2329
+ break;
2330
+ }
2331
+}
2332
+
2333
+static void ovs_nla_free_sample_action(const struct nlattr *action)
2334
+{
2335
+ const struct nlattr *a = nla_data(action);
2336
+ int rem = nla_len(action);
2337
+
2338
+ switch (nla_type(a)) {
2339
+ case OVS_SAMPLE_ATTR_ARG:
2340
+ /* The real list of actions follows this attribute. */
2341
+ a = nla_next(a, &rem);
2342
+ ovs_nla_free_nested_actions(a, rem);
2343
+ break;
2344
+ }
2345
+}
2346
+
22562347 static void ovs_nla_free_set_action(const struct nlattr *a)
22572348 {
22582349 const struct nlattr *ovs_key = nla_data(a);
....@@ -2266,25 +2357,54 @@
22662357 }
22672358 }
22682359
2269
-void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts)
2360
+static void ovs_nla_free_nested_actions(const struct nlattr *actions, int len)
22702361 {
22712362 const struct nlattr *a;
22722363 int rem;
22732364
2274
- if (!sf_acts)
2365
+ /* Whenever new actions are added, the need to update this
2366
+ * function should be considered.
2367
+ */
2368
+ BUILD_BUG_ON(OVS_ACTION_ATTR_MAX != 23);
2369
+
2370
+ if (!actions)
22752371 return;
22762372
2277
- nla_for_each_attr(a, sf_acts->actions, sf_acts->actions_len, rem) {
2373
+ nla_for_each_attr(a, actions, len, rem) {
22782374 switch (nla_type(a)) {
2279
- case OVS_ACTION_ATTR_SET:
2280
- ovs_nla_free_set_action(a);
2375
+ case OVS_ACTION_ATTR_CHECK_PKT_LEN:
2376
+ ovs_nla_free_check_pkt_len_action(a);
22812377 break;
2378
+
2379
+ case OVS_ACTION_ATTR_CLONE:
2380
+ ovs_nla_free_clone_action(a);
2381
+ break;
2382
+
22822383 case OVS_ACTION_ATTR_CT:
22832384 ovs_ct_free_action(a);
22842385 break;
2386
+
2387
+ case OVS_ACTION_ATTR_DEC_TTL:
2388
+ ovs_nla_free_dec_ttl_action(a);
2389
+ break;
2390
+
2391
+ case OVS_ACTION_ATTR_SAMPLE:
2392
+ ovs_nla_free_sample_action(a);
2393
+ break;
2394
+
2395
+ case OVS_ACTION_ATTR_SET:
2396
+ ovs_nla_free_set_action(a);
2397
+ break;
22852398 }
22862399 }
2400
+}
22872401
2402
+void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts)
2403
+{
2404
+ if (!sf_acts)
2405
+ return;
2406
+
2407
+ ovs_nla_free_nested_actions(sf_acts->actions, sf_acts->actions_len);
22882408 kfree(sf_acts);
22892409 }
22902410
....@@ -2316,7 +2436,7 @@
23162436 new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2);
23172437
23182438 if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
2319
- if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) {
2439
+ if ((next_offset + req_size) > MAX_ACTIONS_BUFSIZE) {
23202440 OVS_NLERR(log, "Flow action size exceeds max %u",
23212441 MAX_ACTIONS_BUFSIZE);
23222442 return ERR_PTR(-EMSGSIZE);
....@@ -2393,13 +2513,14 @@
23932513 static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
23942514 const struct sw_flow_key *key,
23952515 struct sw_flow_actions **sfa,
2396
- __be16 eth_type, __be16 vlan_tci, bool log);
2516
+ __be16 eth_type, __be16 vlan_tci,
2517
+ u32 mpls_label_count, bool log);
23972518
23982519 static int validate_and_copy_sample(struct net *net, const struct nlattr *attr,
23992520 const struct sw_flow_key *key,
24002521 struct sw_flow_actions **sfa,
24012522 __be16 eth_type, __be16 vlan_tci,
2402
- bool log, bool last)
2523
+ u32 mpls_label_count, bool log, bool last)
24032524 {
24042525 const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1];
24052526 const struct nlattr *probability, *actions;
....@@ -2450,7 +2571,7 @@
24502571 return err;
24512572
24522573 err = __ovs_nla_copy_actions(net, actions, key, sfa,
2453
- eth_type, vlan_tci, log);
2574
+ eth_type, vlan_tci, mpls_label_count, log);
24542575
24552576 if (err)
24562577 return err;
....@@ -2460,12 +2581,59 @@
24602581 return 0;
24612582 }
24622583
2584
+static int validate_and_copy_dec_ttl(struct net *net,
2585
+ const struct nlattr *attr,
2586
+ const struct sw_flow_key *key,
2587
+ struct sw_flow_actions **sfa,
2588
+ __be16 eth_type, __be16 vlan_tci,
2589
+ u32 mpls_label_count, bool log)
2590
+{
2591
+ const struct nlattr *attrs[OVS_DEC_TTL_ATTR_MAX + 1];
2592
+ int start, action_start, err, rem;
2593
+ const struct nlattr *a, *actions;
2594
+
2595
+ memset(attrs, 0, sizeof(attrs));
2596
+ nla_for_each_nested(a, attr, rem) {
2597
+ int type = nla_type(a);
2598
+
2599
+ /* Ignore unknown attributes to be future proof. */
2600
+ if (type > OVS_DEC_TTL_ATTR_MAX)
2601
+ continue;
2602
+
2603
+ if (!type || attrs[type])
2604
+ return -EINVAL;
2605
+
2606
+ attrs[type] = a;
2607
+ }
2608
+
2609
+ actions = attrs[OVS_DEC_TTL_ATTR_ACTION];
2610
+ if (rem || !actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
2611
+ return -EINVAL;
2612
+
2613
+ start = add_nested_action_start(sfa, OVS_ACTION_ATTR_DEC_TTL, log);
2614
+ if (start < 0)
2615
+ return start;
2616
+
2617
+ action_start = add_nested_action_start(sfa, OVS_DEC_TTL_ATTR_ACTION, log);
2618
+ if (action_start < 0)
2619
+ return action_start;
2620
+
2621
+ err = __ovs_nla_copy_actions(net, actions, key, sfa, eth_type,
2622
+ vlan_tci, mpls_label_count, log);
2623
+ if (err)
2624
+ return err;
2625
+
2626
+ add_nested_action_end(*sfa, action_start);
2627
+ add_nested_action_end(*sfa, start);
2628
+ return 0;
2629
+}
2630
+
24632631 static int validate_and_copy_clone(struct net *net,
24642632 const struct nlattr *attr,
24652633 const struct sw_flow_key *key,
24662634 struct sw_flow_actions **sfa,
24672635 __be16 eth_type, __be16 vlan_tci,
2468
- bool log, bool last)
2636
+ u32 mpls_label_count, bool log, bool last)
24692637 {
24702638 int start, err;
24712639 u32 exec;
....@@ -2485,7 +2653,7 @@
24852653 return err;
24862654
24872655 err = __ovs_nla_copy_actions(net, attr, key, sfa,
2488
- eth_type, vlan_tci, log);
2656
+ eth_type, vlan_tci, mpls_label_count, log);
24892657 if (err)
24902658 return err;
24912659
....@@ -2605,6 +2773,8 @@
26052773 tun_info->mode = IP_TUNNEL_INFO_TX;
26062774 if (key.tun_proto == AF_INET6)
26072775 tun_info->mode |= IP_TUNNEL_INFO_IPV6;
2776
+ else if (key.tun_proto == AF_INET && key.tun_key.u.ipv4.dst == 0)
2777
+ tun_info->mode |= IP_TUNNEL_INFO_BRIDGE;
26082778 tun_info->key = key.tun_key;
26092779
26102780 /* We need to store the options in the action itself since
....@@ -2671,10 +2841,6 @@
26712841 return -EINVAL;
26722842
26732843 switch (key_type) {
2674
- const struct ovs_key_ipv4 *ipv4_key;
2675
- const struct ovs_key_ipv6 *ipv6_key;
2676
- int err;
2677
-
26782844 case OVS_KEY_ATTR_PRIORITY:
26792845 case OVS_KEY_ATTR_SKB_MARK:
26802846 case OVS_KEY_ATTR_CT_MARK:
....@@ -2686,7 +2852,9 @@
26862852 return -EINVAL;
26872853 break;
26882854
2689
- case OVS_KEY_ATTR_TUNNEL:
2855
+ case OVS_KEY_ATTR_TUNNEL: {
2856
+ int err;
2857
+
26902858 if (masked)
26912859 return -EINVAL; /* Masked tunnel set not supported. */
26922860
....@@ -2695,8 +2863,10 @@
26952863 if (err)
26962864 return err;
26972865 break;
2866
+ }
2867
+ case OVS_KEY_ATTR_IPV4: {
2868
+ const struct ovs_key_ipv4 *ipv4_key;
26982869
2699
- case OVS_KEY_ATTR_IPV4:
27002870 if (eth_type != htons(ETH_P_IP))
27012871 return -EINVAL;
27022872
....@@ -2716,8 +2886,10 @@
27162886 return -EINVAL;
27172887 }
27182888 break;
2889
+ }
2890
+ case OVS_KEY_ATTR_IPV6: {
2891
+ const struct ovs_key_ipv6 *ipv6_key;
27192892
2720
- case OVS_KEY_ATTR_IPV6:
27212893 if (eth_type != htons(ETH_P_IPV6))
27222894 return -EINVAL;
27232895
....@@ -2744,7 +2916,7 @@
27442916 return -EINVAL;
27452917
27462918 break;
2747
-
2919
+ }
27482920 case OVS_KEY_ATTR_TCP:
27492921 if ((eth_type != htons(ETH_P_IP) &&
27502922 eth_type != htons(ETH_P_IPV6)) ||
....@@ -2826,8 +2998,8 @@
28262998 struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1];
28272999 int error;
28283000
2829
- error = nla_parse_nested(a, OVS_USERSPACE_ATTR_MAX, attr,
2830
- userspace_policy, NULL);
3001
+ error = nla_parse_nested_deprecated(a, OVS_USERSPACE_ATTR_MAX, attr,
3002
+ userspace_policy, NULL);
28313003 if (error)
28323004 return error;
28333005
....@@ -2835,6 +3007,89 @@
28353007 !nla_get_u32(a[OVS_USERSPACE_ATTR_PID]))
28363008 return -EINVAL;
28373009
3010
+ return 0;
3011
+}
3012
+
3013
+static const struct nla_policy cpl_policy[OVS_CHECK_PKT_LEN_ATTR_MAX + 1] = {
3014
+ [OVS_CHECK_PKT_LEN_ATTR_PKT_LEN] = {.type = NLA_U16 },
3015
+ [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER] = {.type = NLA_NESTED },
3016
+ [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL] = {.type = NLA_NESTED },
3017
+};
3018
+
3019
+static int validate_and_copy_check_pkt_len(struct net *net,
3020
+ const struct nlattr *attr,
3021
+ const struct sw_flow_key *key,
3022
+ struct sw_flow_actions **sfa,
3023
+ __be16 eth_type, __be16 vlan_tci,
3024
+ u32 mpls_label_count,
3025
+ bool log, bool last)
3026
+{
3027
+ const struct nlattr *acts_if_greater, *acts_if_lesser_eq;
3028
+ struct nlattr *a[OVS_CHECK_PKT_LEN_ATTR_MAX + 1];
3029
+ struct check_pkt_len_arg arg;
3030
+ int nested_acts_start;
3031
+ int start, err;
3032
+
3033
+ err = nla_parse_deprecated_strict(a, OVS_CHECK_PKT_LEN_ATTR_MAX,
3034
+ nla_data(attr), nla_len(attr),
3035
+ cpl_policy, NULL);
3036
+ if (err)
3037
+ return err;
3038
+
3039
+ if (!a[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN] ||
3040
+ !nla_get_u16(a[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN]))
3041
+ return -EINVAL;
3042
+
3043
+ acts_if_lesser_eq = a[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL];
3044
+ acts_if_greater = a[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER];
3045
+
3046
+ /* Both the nested action should be present. */
3047
+ if (!acts_if_greater || !acts_if_lesser_eq)
3048
+ return -EINVAL;
3049
+
3050
+ /* validation done, copy the nested actions. */
3051
+ start = add_nested_action_start(sfa, OVS_ACTION_ATTR_CHECK_PKT_LEN,
3052
+ log);
3053
+ if (start < 0)
3054
+ return start;
3055
+
3056
+ arg.pkt_len = nla_get_u16(a[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN]);
3057
+ arg.exec_for_lesser_equal =
3058
+ last || !actions_may_change_flow(acts_if_lesser_eq);
3059
+ arg.exec_for_greater =
3060
+ last || !actions_may_change_flow(acts_if_greater);
3061
+
3062
+ err = ovs_nla_add_action(sfa, OVS_CHECK_PKT_LEN_ATTR_ARG, &arg,
3063
+ sizeof(arg), log);
3064
+ if (err)
3065
+ return err;
3066
+
3067
+ nested_acts_start = add_nested_action_start(sfa,
3068
+ OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL, log);
3069
+ if (nested_acts_start < 0)
3070
+ return nested_acts_start;
3071
+
3072
+ err = __ovs_nla_copy_actions(net, acts_if_lesser_eq, key, sfa,
3073
+ eth_type, vlan_tci, mpls_label_count, log);
3074
+
3075
+ if (err)
3076
+ return err;
3077
+
3078
+ add_nested_action_end(*sfa, nested_acts_start);
3079
+
3080
+ nested_acts_start = add_nested_action_start(sfa,
3081
+ OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER, log);
3082
+ if (nested_acts_start < 0)
3083
+ return nested_acts_start;
3084
+
3085
+ err = __ovs_nla_copy_actions(net, acts_if_greater, key, sfa,
3086
+ eth_type, vlan_tci, mpls_label_count, log);
3087
+
3088
+ if (err)
3089
+ return err;
3090
+
3091
+ add_nested_action_end(*sfa, nested_acts_start);
3092
+ add_nested_action_end(*sfa, start);
28383093 return 0;
28393094 }
28403095
....@@ -2855,7 +3110,8 @@
28553110 static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
28563111 const struct sw_flow_key *key,
28573112 struct sw_flow_actions **sfa,
2858
- __be16 eth_type, __be16 vlan_tci, bool log)
3113
+ __be16 eth_type, __be16 vlan_tci,
3114
+ u32 mpls_label_count, bool log)
28593115 {
28603116 u8 mac_proto = ovs_key_mac_proto(key);
28613117 const struct nlattr *a;
....@@ -2884,6 +3140,9 @@
28843140 [OVS_ACTION_ATTR_POP_NSH] = 0,
28853141 [OVS_ACTION_ATTR_METER] = sizeof(u32),
28863142 [OVS_ACTION_ATTR_CLONE] = (u32)-1,
3143
+ [OVS_ACTION_ATTR_CHECK_PKT_LEN] = (u32)-1,
3144
+ [OVS_ACTION_ATTR_ADD_MPLS] = sizeof(struct ovs_action_add_mpls),
3145
+ [OVS_ACTION_ATTR_DEC_TTL] = (u32)-1,
28873146 };
28883147 const struct ovs_action_push_vlan *vlan;
28893148 int type = nla_type(a);
....@@ -2943,13 +3202,40 @@
29433202 vlan = nla_data(a);
29443203 if (!eth_type_vlan(vlan->vlan_tpid))
29453204 return -EINVAL;
2946
- if (!(vlan->vlan_tci & htons(VLAN_TAG_PRESENT)))
3205
+ if (!(vlan->vlan_tci & htons(VLAN_CFI_MASK)))
29473206 return -EINVAL;
29483207 vlan_tci = vlan->vlan_tci;
29493208 break;
29503209
29513210 case OVS_ACTION_ATTR_RECIRC:
29523211 break;
3212
+
3213
+ case OVS_ACTION_ATTR_ADD_MPLS: {
3214
+ const struct ovs_action_add_mpls *mpls = nla_data(a);
3215
+
3216
+ if (!eth_p_mpls(mpls->mpls_ethertype))
3217
+ return -EINVAL;
3218
+
3219
+ if (mpls->tun_flags & OVS_MPLS_L3_TUNNEL_FLAG_MASK) {
3220
+ if (vlan_tci & htons(VLAN_CFI_MASK) ||
3221
+ (eth_type != htons(ETH_P_IP) &&
3222
+ eth_type != htons(ETH_P_IPV6) &&
3223
+ eth_type != htons(ETH_P_ARP) &&
3224
+ eth_type != htons(ETH_P_RARP) &&
3225
+ !eth_p_mpls(eth_type)))
3226
+ return -EINVAL;
3227
+ mpls_label_count++;
3228
+ } else {
3229
+ if (mac_proto == MAC_PROTO_ETHERNET) {
3230
+ mpls_label_count = 1;
3231
+ mac_proto = MAC_PROTO_NONE;
3232
+ } else {
3233
+ mpls_label_count++;
3234
+ }
3235
+ }
3236
+ eth_type = mpls->mpls_ethertype;
3237
+ break;
3238
+ }
29533239
29543240 case OVS_ACTION_ATTR_PUSH_MPLS: {
29553241 const struct ovs_action_push_mpls *mpls = nla_data(a);
....@@ -2959,7 +3245,7 @@
29593245 /* Prohibit push MPLS other than to a white list
29603246 * for packets that have a known tag order.
29613247 */
2962
- if (vlan_tci & htons(VLAN_TAG_PRESENT) ||
3248
+ if (vlan_tci & htons(VLAN_CFI_MASK) ||
29633249 (eth_type != htons(ETH_P_IP) &&
29643250 eth_type != htons(ETH_P_IPV6) &&
29653251 eth_type != htons(ETH_P_ARP) &&
....@@ -2967,25 +3253,41 @@
29673253 !eth_p_mpls(eth_type)))
29683254 return -EINVAL;
29693255 eth_type = mpls->mpls_ethertype;
3256
+ mpls_label_count++;
29703257 break;
29713258 }
29723259
2973
- case OVS_ACTION_ATTR_POP_MPLS:
2974
- if (vlan_tci & htons(VLAN_TAG_PRESENT) ||
3260
+ case OVS_ACTION_ATTR_POP_MPLS: {
3261
+ __be16 proto;
3262
+ if (vlan_tci & htons(VLAN_CFI_MASK) ||
29753263 !eth_p_mpls(eth_type))
29763264 return -EINVAL;
29773265
2978
- /* Disallow subsequent L2.5+ set and mpls_pop actions
2979
- * as there is no check here to ensure that the new
2980
- * eth_type is valid and thus set actions could
2981
- * write off the end of the packet or otherwise
2982
- * corrupt it.
3266
+ /* Disallow subsequent L2.5+ set actions and mpls_pop
3267
+ * actions once the last MPLS label in the packet is
3268
+ * is popped as there is no check here to ensure that
3269
+ * the new eth type is valid and thus set actions could
3270
+ * write off the end of the packet or otherwise corrupt
3271
+ * it.
29833272 *
29843273 * Support for these actions is planned using packet
29853274 * recirculation.
29863275 */
2987
- eth_type = htons(0);
3276
+ proto = nla_get_be16(a);
3277
+
3278
+ if (proto == htons(ETH_P_TEB) &&
3279
+ mac_proto != MAC_PROTO_NONE)
3280
+ return -EINVAL;
3281
+
3282
+ mpls_label_count--;
3283
+
3284
+ if (!eth_p_mpls(proto) || !mpls_label_count)
3285
+ eth_type = htons(0);
3286
+ else
3287
+ eth_type = proto;
3288
+
29883289 break;
3290
+ }
29893291
29903292 case OVS_ACTION_ATTR_SET:
29913293 err = validate_set(a, key, sfa,
....@@ -3008,6 +3310,7 @@
30083310
30093311 err = validate_and_copy_sample(net, a, key, sfa,
30103312 eth_type, vlan_tci,
3313
+ mpls_label_count,
30113314 log, last);
30123315 if (err)
30133316 return err;
....@@ -3036,7 +3339,7 @@
30363339 case OVS_ACTION_ATTR_POP_ETH:
30373340 if (mac_proto != MAC_PROTO_ETHERNET)
30383341 return -EINVAL;
3039
- if (vlan_tci & htons(VLAN_TAG_PRESENT))
3342
+ if (vlan_tci & htons(VLAN_CFI_MASK))
30403343 return -EINVAL;
30413344 mac_proto = MAC_PROTO_NONE;
30423345 break;
....@@ -3078,12 +3381,36 @@
30783381
30793382 err = validate_and_copy_clone(net, a, key, sfa,
30803383 eth_type, vlan_tci,
3384
+ mpls_label_count,
30813385 log, last);
30823386 if (err)
30833387 return err;
30843388 skip_copy = true;
30853389 break;
30863390 }
3391
+
3392
+ case OVS_ACTION_ATTR_CHECK_PKT_LEN: {
3393
+ bool last = nla_is_last(a, rem);
3394
+
3395
+ err = validate_and_copy_check_pkt_len(net, a, key, sfa,
3396
+ eth_type,
3397
+ vlan_tci,
3398
+ mpls_label_count,
3399
+ log, last);
3400
+ if (err)
3401
+ return err;
3402
+ skip_copy = true;
3403
+ break;
3404
+ }
3405
+
3406
+ case OVS_ACTION_ATTR_DEC_TTL:
3407
+ err = validate_and_copy_dec_ttl(net, a, key, sfa,
3408
+ eth_type, vlan_tci,
3409
+ mpls_label_count, log);
3410
+ if (err)
3411
+ return err;
3412
+ skip_copy = true;
3413
+ break;
30873414
30883415 default:
30893416 OVS_NLERR(log, "Unknown Action type %d", type);
....@@ -3108,14 +3435,18 @@
31083435 struct sw_flow_actions **sfa, bool log)
31093436 {
31103437 int err;
3438
+ u32 mpls_label_count = 0;
31113439
31123440 *sfa = nla_alloc_flow_actions(min(nla_len(attr), MAX_ACTIONS_BUFSIZE));
31133441 if (IS_ERR(*sfa))
31143442 return PTR_ERR(*sfa);
31153443
3444
+ if (eth_p_mpls(key->eth.type))
3445
+ mpls_label_count = hweight_long(key->mpls.num_labels_mask);
3446
+
31163447 (*sfa)->orig_len = nla_len(attr);
31173448 err = __ovs_nla_copy_actions(net, attr, key, sfa, key->eth.type,
3118
- key->eth.vlan.tci, log);
3449
+ key->eth.vlan.tci, mpls_label_count, log);
31193450 if (err)
31203451 ovs_nla_free_flow_actions(*sfa);
31213452
....@@ -3130,7 +3461,7 @@
31303461 const struct sample_arg *arg;
31313462 struct nlattr *actions;
31323463
3133
- start = nla_nest_start(skb, OVS_ACTION_ATTR_SAMPLE);
3464
+ start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_SAMPLE);
31343465 if (!start)
31353466 return -EMSGSIZE;
31363467
....@@ -3143,7 +3474,7 @@
31433474 goto out;
31443475 }
31453476
3146
- ac_start = nla_nest_start(skb, OVS_SAMPLE_ATTR_ACTIONS);
3477
+ ac_start = nla_nest_start_noflag(skb, OVS_SAMPLE_ATTR_ACTIONS);
31473478 if (!ac_start) {
31483479 err = -EMSGSIZE;
31493480 goto out;
....@@ -3169,17 +3500,130 @@
31693500 struct nlattr *start;
31703501 int err = 0, rem = nla_len(attr);
31713502
3172
- start = nla_nest_start(skb, OVS_ACTION_ATTR_CLONE);
3503
+ start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_CLONE);
31733504 if (!start)
31743505 return -EMSGSIZE;
31753506
3176
- err = ovs_nla_put_actions(nla_data(attr), rem, skb);
3507
+ /* Skipping the OVS_CLONE_ATTR_EXEC that is always the first attribute. */
3508
+ attr = nla_next(nla_data(attr), &rem);
3509
+ err = ovs_nla_put_actions(attr, rem, skb);
31773510
31783511 if (err)
31793512 nla_nest_cancel(skb, start);
31803513 else
31813514 nla_nest_end(skb, start);
31823515
3516
+ return err;
3517
+}
3518
+
3519
+static int check_pkt_len_action_to_attr(const struct nlattr *attr,
3520
+ struct sk_buff *skb)
3521
+{
3522
+ struct nlattr *start, *ac_start = NULL;
3523
+ const struct check_pkt_len_arg *arg;
3524
+ const struct nlattr *a, *cpl_arg;
3525
+ int err = 0, rem = nla_len(attr);
3526
+
3527
+ start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_CHECK_PKT_LEN);
3528
+ if (!start)
3529
+ return -EMSGSIZE;
3530
+
3531
+ /* The first nested attribute in 'attr' is always
3532
+ * 'OVS_CHECK_PKT_LEN_ATTR_ARG'.
3533
+ */
3534
+ cpl_arg = nla_data(attr);
3535
+ arg = nla_data(cpl_arg);
3536
+
3537
+ if (nla_put_u16(skb, OVS_CHECK_PKT_LEN_ATTR_PKT_LEN, arg->pkt_len)) {
3538
+ err = -EMSGSIZE;
3539
+ goto out;
3540
+ }
3541
+
3542
+ /* Second nested attribute in 'attr' is always
3543
+ * 'OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL'.
3544
+ */
3545
+ a = nla_next(cpl_arg, &rem);
3546
+ ac_start = nla_nest_start_noflag(skb,
3547
+ OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL);
3548
+ if (!ac_start) {
3549
+ err = -EMSGSIZE;
3550
+ goto out;
3551
+ }
3552
+
3553
+ err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb);
3554
+ if (err) {
3555
+ nla_nest_cancel(skb, ac_start);
3556
+ goto out;
3557
+ } else {
3558
+ nla_nest_end(skb, ac_start);
3559
+ }
3560
+
3561
+ /* Third nested attribute in 'attr' is always
3562
+ * OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER.
3563
+ */
3564
+ a = nla_next(a, &rem);
3565
+ ac_start = nla_nest_start_noflag(skb,
3566
+ OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER);
3567
+ if (!ac_start) {
3568
+ err = -EMSGSIZE;
3569
+ goto out;
3570
+ }
3571
+
3572
+ err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb);
3573
+ if (err) {
3574
+ nla_nest_cancel(skb, ac_start);
3575
+ goto out;
3576
+ } else {
3577
+ nla_nest_end(skb, ac_start);
3578
+ }
3579
+
3580
+ nla_nest_end(skb, start);
3581
+ return 0;
3582
+
3583
+out:
3584
+ nla_nest_cancel(skb, start);
3585
+ return err;
3586
+}
3587
+
3588
+static int dec_ttl_action_to_attr(const struct nlattr *attr,
3589
+ struct sk_buff *skb)
3590
+{
3591
+ struct nlattr *start, *action_start;
3592
+ const struct nlattr *a;
3593
+ int err = 0, rem;
3594
+
3595
+ start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_DEC_TTL);
3596
+ if (!start)
3597
+ return -EMSGSIZE;
3598
+
3599
+ nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) {
3600
+ switch (nla_type(a)) {
3601
+ case OVS_DEC_TTL_ATTR_ACTION:
3602
+
3603
+ action_start = nla_nest_start_noflag(skb, OVS_DEC_TTL_ATTR_ACTION);
3604
+ if (!action_start) {
3605
+ err = -EMSGSIZE;
3606
+ goto out;
3607
+ }
3608
+
3609
+ err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb);
3610
+ if (err)
3611
+ goto out;
3612
+
3613
+ nla_nest_end(skb, action_start);
3614
+ break;
3615
+
3616
+ default:
3617
+ /* Ignore all other option to be future compatible */
3618
+ break;
3619
+ }
3620
+ }
3621
+
3622
+ nla_nest_end(skb, start);
3623
+ return 0;
3624
+
3625
+out:
3626
+ nla_nest_cancel(skb, start);
31833627 return err;
31843628 }
31853629
....@@ -3195,14 +3639,14 @@
31953639 struct ovs_tunnel_info *ovs_tun = nla_data(ovs_key);
31963640 struct ip_tunnel_info *tun_info = &ovs_tun->tun_dst->u.tun_info;
31973641
3198
- start = nla_nest_start(skb, OVS_ACTION_ATTR_SET);
3642
+ start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_SET);
31993643 if (!start)
32003644 return -EMSGSIZE;
32013645
32023646 err = ip_tun_to_nlattr(skb, &tun_info->key,
32033647 ip_tunnel_info_opts(tun_info),
32043648 tun_info->options_len,
3205
- ip_tunnel_info_af(tun_info));
3649
+ ip_tunnel_info_af(tun_info), tun_info->mode);
32063650 if (err)
32073651 return err;
32083652 nla_nest_end(skb, start);
....@@ -3227,7 +3671,7 @@
32273671 /* Revert the conversion we did from a non-masked set action to
32283672 * masked set action.
32293673 */
3230
- nla = nla_nest_start(skb, OVS_ACTION_ATTR_SET);
3674
+ nla = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_SET);
32313675 if (!nla)
32323676 return -EMSGSIZE;
32333677
....@@ -3277,6 +3721,18 @@
32773721 return err;
32783722 break;
32793723
3724
+ case OVS_ACTION_ATTR_CHECK_PKT_LEN:
3725
+ err = check_pkt_len_action_to_attr(a, skb);
3726
+ if (err)
3727
+ return err;
3728
+ break;
3729
+
3730
+ case OVS_ACTION_ATTR_DEC_TTL:
3731
+ err = dec_ttl_action_to_attr(a, skb);
3732
+ if (err)
3733
+ return err;
3734
+ break;
3735
+
32803736 default:
32813737 if (nla_put(skb, type, nla_len(a), nla_data(a)))
32823738 return -EMSGSIZE;