Lines Matching +full:stream +full:- +full:match +full:- +full:mask
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2007-2017 Nicira, Inc.
48 #define OVS_ATTR_NESTED -1
49 #define OVS_ATTR_VARIABLE -2
91 static void update_range(struct sw_flow_match *match, in update_range() argument
99 range = &match->range; in update_range()
101 range = &match->mask->range; in update_range()
103 if (range->start == range->end) { in update_range()
104 range->start = start; in update_range()
105 range->end = end; in update_range()
109 if (range->start > start) in update_range()
110 range->start = start; in update_range()
112 if (range->end < end) in update_range()
113 range->end = end; in update_range()
116 #define SW_FLOW_KEY_PUT(match, field, value, is_mask) \ argument
118 update_range(match, offsetof(struct sw_flow_key, field), \
119 sizeof((match)->key->field), is_mask); \
121 (match)->mask->key.field = value; \
123 (match)->key->field = value; \
126 #define SW_FLOW_KEY_MEMCPY_OFFSET(match, offset, value_p, len, is_mask) \ argument
128 update_range(match, offset, len, is_mask); \
130 memcpy((u8 *)&(match)->mask->key + offset, value_p, \
133 memcpy((u8 *)(match)->key + offset, value_p, len); \
136 #define SW_FLOW_KEY_MEMCPY(match, field, value_p, len, is_mask) \ argument
137 SW_FLOW_KEY_MEMCPY_OFFSET(match, offsetof(struct sw_flow_key, field), \
140 #define SW_FLOW_KEY_MEMSET_FIELD(match, field, value, is_mask) \ argument
142 update_range(match, offsetof(struct sw_flow_key, field), \
143 sizeof((match)->key->field), is_mask); \
145 memset((u8 *)&(match)->mask->key.field, value, \
146 sizeof((match)->mask->key.field)); \
148 memset((u8 *)&(match)->key->field, value, \
149 sizeof((match)->key->field)); \
152 static bool match_validate(const struct sw_flow_match *match, in match_validate() argument
158 /* The following mask attributes allowed only if they in match_validate()
175 /* Always allowed mask fields. */ in match_validate()
181 if (match->key->eth.type == htons(ETH_P_ARP) in match_validate()
182 || match->key->eth.type == htons(ETH_P_RARP)) { in match_validate()
184 if (match->mask && (match->mask->key.eth.type == htons(0xffff))) in match_validate()
188 if (eth_p_mpls(match->key->eth.type)) { in match_validate()
190 if (match->mask && (match->mask->key.eth.type == htons(0xffff))) in match_validate()
194 if (match->key->eth.type == htons(ETH_P_IP)) { in match_validate()
196 if (match->mask && match->mask->key.eth.type == htons(0xffff)) { in match_validate()
201 if (match->key->ip.frag != OVS_FRAG_TYPE_LATER) { in match_validate()
202 if (match->key->ip.proto == IPPROTO_UDP) { in match_validate()
204 if (match->mask && (match->mask->key.ip.proto == 0xff)) in match_validate()
208 if (match->key->ip.proto == IPPROTO_SCTP) { in match_validate()
210 if (match->mask && (match->mask->key.ip.proto == 0xff)) in match_validate()
214 if (match->key->ip.proto == IPPROTO_TCP) { in match_validate()
217 if (match->mask && (match->mask->key.ip.proto == 0xff)) { in match_validate()
223 if (match->key->ip.proto == IPPROTO_ICMP) { in match_validate()
225 if (match->mask && (match->mask->key.ip.proto == 0xff)) in match_validate()
231 if (match->key->eth.type == htons(ETH_P_IPV6)) { in match_validate()
233 if (match->mask && match->mask->key.eth.type == htons(0xffff)) { in match_validate()
238 if (match->key->ip.frag != OVS_FRAG_TYPE_LATER) { in match_validate()
239 if (match->key->ip.proto == IPPROTO_UDP) { in match_validate()
241 if (match->mask && (match->mask->key.ip.proto == 0xff)) in match_validate()
245 if (match->key->ip.proto == IPPROTO_SCTP) { in match_validate()
247 if (match->mask && (match->mask->key.ip.proto == 0xff)) in match_validate()
251 if (match->key->ip.proto == IPPROTO_TCP) { in match_validate()
254 if (match->mask && (match->mask->key.ip.proto == 0xff)) { in match_validate()
260 if (match->key->ip.proto == IPPROTO_ICMPV6) { in match_validate()
262 if (match->mask && (match->mask->key.ip.proto == 0xff)) in match_validate()
265 if (match->key->tp.src == in match_validate()
267 match->key->tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT)) { in match_validate()
275 if (match->mask && (match->mask->key.tp.src == htons(0xff))) in match_validate()
282 if (match->key->eth.type == htons(ETH_P_NSH)) { in match_validate()
284 if (match->mask && in match_validate()
285 match->mask->key.eth.type == htons(0xffff)) { in match_validate()
299 /* Mask attributes check failed. */ in match_validate()
300 OVS_NLERR(log, "Unexpected mask (mask=%llx, allowed=%llx)", in match_validate()
479 return -EINVAL; in __parse_flow_nlattrs()
484 return -EINVAL; in __parse_flow_nlattrs()
491 return -EINVAL; in __parse_flow_nlattrs()
501 return -EINVAL; in __parse_flow_nlattrs()
522 struct sw_flow_match *match, bool is_mask, in genev_tun_opt_from_nlattr() argument
527 if (nla_len(a) > sizeof(match->key->tun_opts)) { in genev_tun_opt_from_nlattr()
529 nla_len(a), sizeof(match->key->tun_opts)); in genev_tun_opt_from_nlattr()
530 return -EINVAL; in genev_tun_opt_from_nlattr()
536 return -EINVAL; in genev_tun_opt_from_nlattr()
544 SW_FLOW_KEY_PUT(match, tun_opts_len, nla_len(a), in genev_tun_opt_from_nlattr()
548 * both the key and mask while parsing the in genev_tun_opt_from_nlattr()
557 if (match->key->tun_opts_len != nla_len(a)) { in genev_tun_opt_from_nlattr()
558 OVS_NLERR(log, "Geneve option len %d != mask len %d", in genev_tun_opt_from_nlattr()
559 match->key->tun_opts_len, nla_len(a)); in genev_tun_opt_from_nlattr()
560 return -EINVAL; in genev_tun_opt_from_nlattr()
563 SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true); in genev_tun_opt_from_nlattr()
567 SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a), in genev_tun_opt_from_nlattr()
573 struct sw_flow_match *match, bool is_mask, in vxlan_tun_opt_from_nlattr() argument
581 BUILD_BUG_ON(sizeof(opts) > sizeof(match->key->tun_opts)); in vxlan_tun_opt_from_nlattr()
590 return -EINVAL; in vxlan_tun_opt_from_nlattr()
598 return -EINVAL; in vxlan_tun_opt_from_nlattr()
608 return -EINVAL; in vxlan_tun_opt_from_nlattr()
614 return -EINVAL; in vxlan_tun_opt_from_nlattr()
618 SW_FLOW_KEY_PUT(match, tun_opts_len, sizeof(opts), false); in vxlan_tun_opt_from_nlattr()
620 SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true); in vxlan_tun_opt_from_nlattr()
623 SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, &opts, sizeof(opts), in vxlan_tun_opt_from_nlattr()
629 struct sw_flow_match *match, bool is_mask, in erspan_tun_opt_from_nlattr() argument
635 sizeof(match->key->tun_opts)); in erspan_tun_opt_from_nlattr()
637 if (nla_len(a) > sizeof(match->key->tun_opts)) { in erspan_tun_opt_from_nlattr()
639 nla_len(a), sizeof(match->key->tun_opts)); in erspan_tun_opt_from_nlattr()
640 return -EINVAL; in erspan_tun_opt_from_nlattr()
644 SW_FLOW_KEY_PUT(match, tun_opts_len, in erspan_tun_opt_from_nlattr()
647 SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true); in erspan_tun_opt_from_nlattr()
650 SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a), in erspan_tun_opt_from_nlattr()
656 struct sw_flow_match *match, bool is_mask, in ip_tun_from_nlattr() argument
673 return -EINVAL; in ip_tun_from_nlattr()
680 return -EINVAL; in ip_tun_from_nlattr()
685 SW_FLOW_KEY_PUT(match, tun_key.tun_id, in ip_tun_from_nlattr()
690 SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.src, in ip_tun_from_nlattr()
695 SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.dst, in ip_tun_from_nlattr()
700 SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.src, in ip_tun_from_nlattr()
705 SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst, in ip_tun_from_nlattr()
710 SW_FLOW_KEY_PUT(match, tun_key.tos, in ip_tun_from_nlattr()
714 SW_FLOW_KEY_PUT(match, tun_key.ttl, in ip_tun_from_nlattr()
725 SW_FLOW_KEY_PUT(match, tun_key.tp_src, in ip_tun_from_nlattr()
729 SW_FLOW_KEY_PUT(match, tun_key.tp_dst, in ip_tun_from_nlattr()
738 return -EINVAL; in ip_tun_from_nlattr()
741 err = genev_tun_opt_from_nlattr(a, match, is_mask, log); in ip_tun_from_nlattr()
751 return -EINVAL; in ip_tun_from_nlattr()
754 err = vxlan_tun_opt_from_nlattr(a, match, is_mask, log); in ip_tun_from_nlattr()
766 return -EINVAL; in ip_tun_from_nlattr()
769 err = erspan_tun_opt_from_nlattr(a, match, is_mask, in ip_tun_from_nlattr()
784 return -EINVAL; in ip_tun_from_nlattr()
788 SW_FLOW_KEY_PUT(match, tun_key.tun_flags, tun_flags, is_mask); in ip_tun_from_nlattr()
790 SW_FLOW_KEY_MEMSET_FIELD(match, tun_proto, 0xff, true); in ip_tun_from_nlattr()
792 SW_FLOW_KEY_PUT(match, tun_proto, ipv6 ? AF_INET6 : AF_INET, in ip_tun_from_nlattr()
798 return -EINVAL; in ip_tun_from_nlattr()
803 return -EINVAL; in ip_tun_from_nlattr()
809 return -EINVAL; in ip_tun_from_nlattr()
813 if (match->key->tun_key.u.ipv4.src || in ip_tun_from_nlattr()
814 match->key->tun_key.u.ipv4.dst || in ip_tun_from_nlattr()
815 match->key->tun_key.tp_src || in ip_tun_from_nlattr()
816 match->key->tun_key.tp_dst || in ip_tun_from_nlattr()
817 match->key->tun_key.ttl || in ip_tun_from_nlattr()
818 match->key->tun_key.tos || in ip_tun_from_nlattr()
821 return -EINVAL; in ip_tun_from_nlattr()
823 } else if (!match->key->tun_key.u.ipv4.dst) { in ip_tun_from_nlattr()
825 return -EINVAL; in ip_tun_from_nlattr()
828 if (ipv6 && ipv6_addr_any(&match->key->tun_key.u.ipv6.dst)) { in ip_tun_from_nlattr()
830 return -EINVAL; in ip_tun_from_nlattr()
835 return -EINVAL; in ip_tun_from_nlattr()
850 return -EMSGSIZE; in vxlan_opt_to_nlattr()
852 if (nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0) in vxlan_opt_to_nlattr()
853 return -EMSGSIZE; in vxlan_opt_to_nlattr()
864 if (output->tun_flags & TUNNEL_KEY && in __ip_tun_to_nlattr()
865 nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id, in __ip_tun_to_nlattr()
867 return -EMSGSIZE; in __ip_tun_to_nlattr()
871 ? -EMSGSIZE : 0; in __ip_tun_to_nlattr()
875 if (output->u.ipv4.src && in __ip_tun_to_nlattr()
877 output->u.ipv4.src)) in __ip_tun_to_nlattr()
878 return -EMSGSIZE; in __ip_tun_to_nlattr()
879 if (output->u.ipv4.dst && in __ip_tun_to_nlattr()
881 output->u.ipv4.dst)) in __ip_tun_to_nlattr()
882 return -EMSGSIZE; in __ip_tun_to_nlattr()
885 if (!ipv6_addr_any(&output->u.ipv6.src) && in __ip_tun_to_nlattr()
887 &output->u.ipv6.src)) in __ip_tun_to_nlattr()
888 return -EMSGSIZE; in __ip_tun_to_nlattr()
889 if (!ipv6_addr_any(&output->u.ipv6.dst) && in __ip_tun_to_nlattr()
891 &output->u.ipv6.dst)) in __ip_tun_to_nlattr()
892 return -EMSGSIZE; in __ip_tun_to_nlattr()
895 if (output->tos && in __ip_tun_to_nlattr()
896 nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TOS, output->tos)) in __ip_tun_to_nlattr()
897 return -EMSGSIZE; in __ip_tun_to_nlattr()
898 if (nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TTL, output->ttl)) in __ip_tun_to_nlattr()
899 return -EMSGSIZE; in __ip_tun_to_nlattr()
900 if ((output->tun_flags & TUNNEL_DONT_FRAGMENT) && in __ip_tun_to_nlattr()
902 return -EMSGSIZE; in __ip_tun_to_nlattr()
903 if ((output->tun_flags & TUNNEL_CSUM) && in __ip_tun_to_nlattr()
905 return -EMSGSIZE; in __ip_tun_to_nlattr()
906 if (output->tp_src && in __ip_tun_to_nlattr()
907 nla_put_be16(skb, OVS_TUNNEL_KEY_ATTR_TP_SRC, output->tp_src)) in __ip_tun_to_nlattr()
908 return -EMSGSIZE; in __ip_tun_to_nlattr()
909 if (output->tp_dst && in __ip_tun_to_nlattr()
910 nla_put_be16(skb, OVS_TUNNEL_KEY_ATTR_TP_DST, output->tp_dst)) in __ip_tun_to_nlattr()
911 return -EMSGSIZE; in __ip_tun_to_nlattr()
912 if ((output->tun_flags & TUNNEL_OAM) && in __ip_tun_to_nlattr()
914 return -EMSGSIZE; in __ip_tun_to_nlattr()
916 if (output->tun_flags & TUNNEL_GENEVE_OPT && in __ip_tun_to_nlattr()
919 return -EMSGSIZE; in __ip_tun_to_nlattr()
920 else if (output->tun_flags & TUNNEL_VXLAN_OPT && in __ip_tun_to_nlattr()
922 return -EMSGSIZE; in __ip_tun_to_nlattr()
923 else if (output->tun_flags & TUNNEL_ERSPAN_OPT && in __ip_tun_to_nlattr()
926 return -EMSGSIZE; in __ip_tun_to_nlattr()
942 return -EMSGSIZE; in ip_tun_to_nlattr()
956 return __ip_tun_to_nlattr(skb, &tun_info->key, in ovs_nla_put_tunnel_info()
958 tun_info->options_len, in ovs_nla_put_tunnel_info()
959 ip_tunnel_info_af(tun_info), tun_info->mode); in ovs_nla_put_tunnel_info()
962 static int encode_vlan_from_nlattrs(struct sw_flow_match *match, in encode_vlan_from_nlattrs() argument
976 SW_FLOW_KEY_PUT(match, eth.vlan.tpid, tpid, is_mask); in encode_vlan_from_nlattrs()
977 SW_FLOW_KEY_PUT(match, eth.vlan.tci, tci, is_mask); in encode_vlan_from_nlattrs()
979 SW_FLOW_KEY_PUT(match, eth.cvlan.tpid, tpid, is_mask); in encode_vlan_from_nlattrs()
980 SW_FLOW_KEY_PUT(match, eth.cvlan.tci, tci, is_mask); in encode_vlan_from_nlattrs()
985 static int validate_vlan_from_nlattrs(const struct sw_flow_match *match, in validate_vlan_from_nlattrs() argument
1000 OVS_NLERR(log, "Invalid %s frame", (inner) ? "C-VLAN" : "VLAN"); in validate_vlan_from_nlattrs()
1001 return -EINVAL; in validate_vlan_from_nlattrs()
1010 (inner) ? "C-VLAN" : "VLAN"); in validate_vlan_from_nlattrs()
1011 return -EINVAL; in validate_vlan_from_nlattrs()
1014 OVS_NLERR(log, "Truncated %s header has non-zero encap attribute.", in validate_vlan_from_nlattrs()
1015 (inner) ? "C-VLAN" : "VLAN"); in validate_vlan_from_nlattrs()
1016 return -EINVAL; in validate_vlan_from_nlattrs()
1023 static int validate_vlan_mask_from_nlattrs(const struct sw_flow_match *match, in validate_vlan_mask_from_nlattrs() argument
1029 bool encap_valid = !!(match->key->eth.vlan.tci & in validate_vlan_mask_from_nlattrs()
1031 bool i_encap_valid = !!(match->key->eth.cvlan.tci & in validate_vlan_mask_from_nlattrs()
1040 OVS_NLERR(log, "Encap mask attribute is set for non-%s frame.", in validate_vlan_mask_from_nlattrs()
1041 (inner) ? "C-VLAN" : "VLAN"); in validate_vlan_mask_from_nlattrs()
1042 return -EINVAL; in validate_vlan_mask_from_nlattrs()
1052 OVS_NLERR(log, "Must have an exact match on %s TPID (mask=%x).", in validate_vlan_mask_from_nlattrs()
1053 (inner) ? "C-VLAN" : "VLAN", ntohs(tpid)); in validate_vlan_mask_from_nlattrs()
1054 return -EINVAL; in validate_vlan_mask_from_nlattrs()
1057 OVS_NLERR(log, "%s TCI mask does not have exact match for VLAN_CFI_MASK bit.", in validate_vlan_mask_from_nlattrs()
1058 (inner) ? "C-VLAN" : "VLAN"); in validate_vlan_mask_from_nlattrs()
1059 return -EINVAL; in validate_vlan_mask_from_nlattrs()
1065 static int __parse_vlan_from_nlattrs(struct sw_flow_match *match, in __parse_vlan_from_nlattrs() argument
1074 err = validate_vlan_from_nlattrs(match, *key_attrs, inner, in __parse_vlan_from_nlattrs()
1077 err = validate_vlan_mask_from_nlattrs(match, *key_attrs, inner, in __parse_vlan_from_nlattrs()
1082 err = encode_vlan_from_nlattrs(match, a, is_mask, inner); in __parse_vlan_from_nlattrs()
1100 static int parse_vlan_from_nlattrs(struct sw_flow_match *match, in parse_vlan_from_nlattrs() argument
1107 err = __parse_vlan_from_nlattrs(match, key_attrs, false, a, in parse_vlan_from_nlattrs()
1112 encap_valid = !!(match->key->eth.vlan.tci & htons(VLAN_CFI_MASK)); in parse_vlan_from_nlattrs()
1114 err = __parse_vlan_from_nlattrs(match, key_attrs, true, a, in parse_vlan_from_nlattrs()
1123 static int parse_eth_type_from_nlattrs(struct sw_flow_match *match, in parse_eth_type_from_nlattrs() argument
1131 /* Always exact match EtherType. */ in parse_eth_type_from_nlattrs()
1136 return -EINVAL; in parse_eth_type_from_nlattrs()
1139 SW_FLOW_KEY_PUT(match, eth.type, eth_type, is_mask); in parse_eth_type_from_nlattrs()
1144 static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match, in metadata_from_nlattrs() argument
1153 SW_FLOW_KEY_PUT(match, ovs_flow_hash, hash_val, is_mask); in metadata_from_nlattrs()
1160 SW_FLOW_KEY_PUT(match, recirc_id, recirc_id, is_mask); in metadata_from_nlattrs()
1165 SW_FLOW_KEY_PUT(match, phy.priority, in metadata_from_nlattrs()
1174 in_port = 0xffffffff; /* Always exact match in_port. */ in metadata_from_nlattrs()
1178 return -EINVAL; in metadata_from_nlattrs()
1181 SW_FLOW_KEY_PUT(match, phy.in_port, in_port, is_mask); in metadata_from_nlattrs()
1184 SW_FLOW_KEY_PUT(match, phy.in_port, DP_MAX_PORTS, is_mask); in metadata_from_nlattrs()
1190 SW_FLOW_KEY_PUT(match, phy.skb_mark, mark, is_mask); in metadata_from_nlattrs()
1194 if (ip_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match, in metadata_from_nlattrs()
1196 return -EINVAL; in metadata_from_nlattrs()
1207 return -EINVAL; in metadata_from_nlattrs()
1210 SW_FLOW_KEY_PUT(match, ct_state, ct_state, is_mask); in metadata_from_nlattrs()
1217 SW_FLOW_KEY_PUT(match, ct_zone, ct_zone, is_mask); in metadata_from_nlattrs()
1224 SW_FLOW_KEY_PUT(match, ct.mark, mark, is_mask); in metadata_from_nlattrs()
1232 SW_FLOW_KEY_MEMCPY(match, ct.labels, cl->ct_labels, in metadata_from_nlattrs()
1241 SW_FLOW_KEY_PUT(match, ipv4.ct_orig.src, ct->ipv4_src, is_mask); in metadata_from_nlattrs()
1242 SW_FLOW_KEY_PUT(match, ipv4.ct_orig.dst, ct->ipv4_dst, is_mask); in metadata_from_nlattrs()
1243 SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask); in metadata_from_nlattrs()
1244 SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask); in metadata_from_nlattrs()
1245 SW_FLOW_KEY_PUT(match, ct_orig_proto, ct->ipv4_proto, is_mask); in metadata_from_nlattrs()
1253 SW_FLOW_KEY_MEMCPY(match, ipv6.ct_orig.src, &ct->ipv6_src, in metadata_from_nlattrs()
1254 sizeof(match->key->ipv6.ct_orig.src), in metadata_from_nlattrs()
1256 SW_FLOW_KEY_MEMCPY(match, ipv6.ct_orig.dst, &ct->ipv6_dst, in metadata_from_nlattrs()
1257 sizeof(match->key->ipv6.ct_orig.dst), in metadata_from_nlattrs()
1259 SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask); in metadata_from_nlattrs()
1260 SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask); in metadata_from_nlattrs()
1261 SW_FLOW_KEY_PUT(match, ct_orig_proto, ct->ipv6_proto, is_mask); in metadata_from_nlattrs()
1272 /* Always exact match mac_proto */ in metadata_from_nlattrs()
1273 SW_FLOW_KEY_PUT(match, mac_proto, is_mask ? 0xff : mac_proto, is_mask); in metadata_from_nlattrs()
1276 return parse_eth_type_from_nlattrs(match, attrs, a, is_mask, in metadata_from_nlattrs()
1294 return -ENOBUFS; in nsh_hdr_from_nlattr()
1303 flags = base->flags; in nsh_hdr_from_nlattr()
1304 ttl = base->ttl; in nsh_hdr_from_nlattr()
1305 nh->np = base->np; in nsh_hdr_from_nlattr()
1306 nh->mdtype = base->mdtype; in nsh_hdr_from_nlattr()
1307 nh->path_hdr = base->path_hdr; in nsh_hdr_from_nlattr()
1312 if (mdlen > size - NSH_BASE_HDR_LEN) in nsh_hdr_from_nlattr()
1313 return -ENOBUFS; in nsh_hdr_from_nlattr()
1314 memcpy(&nh->md1, nla_data(a), mdlen); in nsh_hdr_from_nlattr()
1319 if (mdlen > size - NSH_BASE_HDR_LEN) in nsh_hdr_from_nlattr()
1320 return -ENOBUFS; in nsh_hdr_from_nlattr()
1321 memcpy(&nh->md2, nla_data(a), mdlen); in nsh_hdr_from_nlattr()
1325 return -EINVAL; in nsh_hdr_from_nlattr()
1330 nh->ver_flags_ttl_len = 0; in nsh_hdr_from_nlattr()
1352 nsh->base = *base; in nsh_key_from_nlattr()
1353 nsh_mask->base = *base_mask; in nsh_key_from_nlattr()
1360 memcpy(nsh->context, md1->context, sizeof(*md1)); in nsh_key_from_nlattr()
1361 memcpy(nsh_mask->context, md1_mask->context, in nsh_key_from_nlattr()
1367 return -ENOTSUPP; in nsh_key_from_nlattr()
1369 return -EINVAL; in nsh_key_from_nlattr()
1377 struct sw_flow_match *match, bool is_mask, in nsh_key_put_from_nlattr() argument
1389 return -EINVAL; in nsh_key_put_from_nlattr()
1398 return -EINVAL; in nsh_key_put_from_nlattr()
1410 return -EINVAL; in nsh_key_put_from_nlattr()
1418 mdtype = base->mdtype; in nsh_key_put_from_nlattr()
1419 SW_FLOW_KEY_PUT(match, nsh.base.flags, in nsh_key_put_from_nlattr()
1420 base->flags, is_mask); in nsh_key_put_from_nlattr()
1421 SW_FLOW_KEY_PUT(match, nsh.base.ttl, in nsh_key_put_from_nlattr()
1422 base->ttl, is_mask); in nsh_key_put_from_nlattr()
1423 SW_FLOW_KEY_PUT(match, nsh.base.mdtype, in nsh_key_put_from_nlattr()
1424 base->mdtype, is_mask); in nsh_key_put_from_nlattr()
1425 SW_FLOW_KEY_PUT(match, nsh.base.np, in nsh_key_put_from_nlattr()
1426 base->np, is_mask); in nsh_key_put_from_nlattr()
1427 SW_FLOW_KEY_PUT(match, nsh.base.path_hdr, in nsh_key_put_from_nlattr()
1428 base->path_hdr, is_mask); in nsh_key_put_from_nlattr()
1436 SW_FLOW_KEY_PUT(match, nsh.context[i], in nsh_key_put_from_nlattr()
1437 md1->context[i], is_mask); in nsh_key_put_from_nlattr()
1442 return -ENOTSUPP; in nsh_key_put_from_nlattr()
1453 return -EINVAL; in nsh_key_put_from_nlattr()
1459 return -EINVAL; in nsh_key_put_from_nlattr()
1465 return -EINVAL; in nsh_key_put_from_nlattr()
1473 return -EINVAL; in nsh_key_put_from_nlattr()
1481 return -EINVAL; in nsh_key_put_from_nlattr()
1490 return -EINVAL; in nsh_key_put_from_nlattr()
1497 static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match, in ovs_key_from_nlattrs() argument
1503 err = metadata_from_nlattrs(net, match, &attrs, a, is_mask, log); in ovs_key_from_nlattrs()
1511 SW_FLOW_KEY_MEMCPY(match, eth.src, in ovs_key_from_nlattrs()
1512 eth_key->eth_src, ETH_ALEN, is_mask); in ovs_key_from_nlattrs()
1513 SW_FLOW_KEY_MEMCPY(match, eth.dst, in ovs_key_from_nlattrs()
1514 eth_key->eth_dst, ETH_ALEN, is_mask); in ovs_key_from_nlattrs()
1522 return -EINVAL; in ovs_key_from_nlattrs()
1526 err = parse_eth_type_from_nlattrs(match, &attrs, a, is_mask, in ovs_key_from_nlattrs()
1531 SW_FLOW_KEY_PUT(match, eth.type, htons(ETH_P_802_2), is_mask); in ovs_key_from_nlattrs()
1533 } else if (!match->key->eth.type) { in ovs_key_from_nlattrs()
1535 return -EINVAL; in ovs_key_from_nlattrs()
1542 if (!is_mask && ipv4_key->ipv4_frag > OVS_FRAG_TYPE_MAX) { in ovs_key_from_nlattrs()
1544 ipv4_key->ipv4_frag, OVS_FRAG_TYPE_MAX); in ovs_key_from_nlattrs()
1545 return -EINVAL; in ovs_key_from_nlattrs()
1547 SW_FLOW_KEY_PUT(match, ip.proto, in ovs_key_from_nlattrs()
1548 ipv4_key->ipv4_proto, is_mask); in ovs_key_from_nlattrs()
1549 SW_FLOW_KEY_PUT(match, ip.tos, in ovs_key_from_nlattrs()
1550 ipv4_key->ipv4_tos, is_mask); in ovs_key_from_nlattrs()
1551 SW_FLOW_KEY_PUT(match, ip.ttl, in ovs_key_from_nlattrs()
1552 ipv4_key->ipv4_ttl, is_mask); in ovs_key_from_nlattrs()
1553 SW_FLOW_KEY_PUT(match, ip.frag, in ovs_key_from_nlattrs()
1554 ipv4_key->ipv4_frag, is_mask); in ovs_key_from_nlattrs()
1555 SW_FLOW_KEY_PUT(match, ipv4.addr.src, in ovs_key_from_nlattrs()
1556 ipv4_key->ipv4_src, is_mask); in ovs_key_from_nlattrs()
1557 SW_FLOW_KEY_PUT(match, ipv4.addr.dst, in ovs_key_from_nlattrs()
1558 ipv4_key->ipv4_dst, is_mask); in ovs_key_from_nlattrs()
1566 if (!is_mask && ipv6_key->ipv6_frag > OVS_FRAG_TYPE_MAX) { in ovs_key_from_nlattrs()
1568 ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); in ovs_key_from_nlattrs()
1569 return -EINVAL; in ovs_key_from_nlattrs()
1572 if (!is_mask && ipv6_key->ipv6_label & htonl(0xFFF00000)) { in ovs_key_from_nlattrs()
1574 ntohl(ipv6_key->ipv6_label), (1 << 20) - 1); in ovs_key_from_nlattrs()
1575 return -EINVAL; in ovs_key_from_nlattrs()
1578 SW_FLOW_KEY_PUT(match, ipv6.label, in ovs_key_from_nlattrs()
1579 ipv6_key->ipv6_label, is_mask); in ovs_key_from_nlattrs()
1580 SW_FLOW_KEY_PUT(match, ip.proto, in ovs_key_from_nlattrs()
1581 ipv6_key->ipv6_proto, is_mask); in ovs_key_from_nlattrs()
1582 SW_FLOW_KEY_PUT(match, ip.tos, in ovs_key_from_nlattrs()
1583 ipv6_key->ipv6_tclass, is_mask); in ovs_key_from_nlattrs()
1584 SW_FLOW_KEY_PUT(match, ip.ttl, in ovs_key_from_nlattrs()
1585 ipv6_key->ipv6_hlimit, is_mask); in ovs_key_from_nlattrs()
1586 SW_FLOW_KEY_PUT(match, ip.frag, in ovs_key_from_nlattrs()
1587 ipv6_key->ipv6_frag, is_mask); in ovs_key_from_nlattrs()
1588 SW_FLOW_KEY_MEMCPY(match, ipv6.addr.src, in ovs_key_from_nlattrs()
1589 ipv6_key->ipv6_src, in ovs_key_from_nlattrs()
1590 sizeof(match->key->ipv6.addr.src), in ovs_key_from_nlattrs()
1592 SW_FLOW_KEY_MEMCPY(match, ipv6.addr.dst, in ovs_key_from_nlattrs()
1593 ipv6_key->ipv6_dst, in ovs_key_from_nlattrs()
1594 sizeof(match->key->ipv6.addr.dst), in ovs_key_from_nlattrs()
1604 if (!is_mask && (arp_key->arp_op & htons(0xff00))) { in ovs_key_from_nlattrs()
1606 arp_key->arp_op); in ovs_key_from_nlattrs()
1607 return -EINVAL; in ovs_key_from_nlattrs()
1610 SW_FLOW_KEY_PUT(match, ipv4.addr.src, in ovs_key_from_nlattrs()
1611 arp_key->arp_sip, is_mask); in ovs_key_from_nlattrs()
1612 SW_FLOW_KEY_PUT(match, ipv4.addr.dst, in ovs_key_from_nlattrs()
1613 arp_key->arp_tip, is_mask); in ovs_key_from_nlattrs()
1614 SW_FLOW_KEY_PUT(match, ip.proto, in ovs_key_from_nlattrs()
1615 ntohs(arp_key->arp_op), is_mask); in ovs_key_from_nlattrs()
1616 SW_FLOW_KEY_MEMCPY(match, ipv4.arp.sha, in ovs_key_from_nlattrs()
1617 arp_key->arp_sha, ETH_ALEN, is_mask); in ovs_key_from_nlattrs()
1618 SW_FLOW_KEY_MEMCPY(match, ipv4.arp.tha, in ovs_key_from_nlattrs()
1619 arp_key->arp_tha, ETH_ALEN, is_mask); in ovs_key_from_nlattrs()
1625 if (nsh_key_put_from_nlattr(a[OVS_KEY_ATTR_NSH], match, in ovs_key_from_nlattrs()
1627 return -EINVAL; in ovs_key_from_nlattrs()
1642 return -EINVAL; in ovs_key_from_nlattrs()
1644 label_count_mask = GENMASK(label_count - 1, 0); in ovs_key_from_nlattrs()
1647 SW_FLOW_KEY_PUT(match, mpls.lse[i], in ovs_key_from_nlattrs()
1650 SW_FLOW_KEY_PUT(match, mpls.num_labels_mask, in ovs_key_from_nlattrs()
1660 SW_FLOW_KEY_PUT(match, tp.src, tcp_key->tcp_src, is_mask); in ovs_key_from_nlattrs()
1661 SW_FLOW_KEY_PUT(match, tp.dst, tcp_key->tcp_dst, is_mask); in ovs_key_from_nlattrs()
1666 SW_FLOW_KEY_PUT(match, tp.flags, in ovs_key_from_nlattrs()
1676 SW_FLOW_KEY_PUT(match, tp.src, udp_key->udp_src, is_mask); in ovs_key_from_nlattrs()
1677 SW_FLOW_KEY_PUT(match, tp.dst, udp_key->udp_dst, is_mask); in ovs_key_from_nlattrs()
1685 SW_FLOW_KEY_PUT(match, tp.src, sctp_key->sctp_src, is_mask); in ovs_key_from_nlattrs()
1686 SW_FLOW_KEY_PUT(match, tp.dst, sctp_key->sctp_dst, is_mask); in ovs_key_from_nlattrs()
1694 SW_FLOW_KEY_PUT(match, tp.src, in ovs_key_from_nlattrs()
1695 htons(icmp_key->icmp_type), is_mask); in ovs_key_from_nlattrs()
1696 SW_FLOW_KEY_PUT(match, tp.dst, in ovs_key_from_nlattrs()
1697 htons(icmp_key->icmp_code), is_mask); in ovs_key_from_nlattrs()
1705 SW_FLOW_KEY_PUT(match, tp.src, in ovs_key_from_nlattrs()
1706 htons(icmpv6_key->icmpv6_type), is_mask); in ovs_key_from_nlattrs()
1707 SW_FLOW_KEY_PUT(match, tp.dst, in ovs_key_from_nlattrs()
1708 htons(icmpv6_key->icmpv6_code), is_mask); in ovs_key_from_nlattrs()
1716 SW_FLOW_KEY_MEMCPY(match, ipv6.nd.target, in ovs_key_from_nlattrs()
1717 nd_key->nd_target, in ovs_key_from_nlattrs()
1718 sizeof(match->key->ipv6.nd.target), in ovs_key_from_nlattrs()
1720 SW_FLOW_KEY_MEMCPY(match, ipv6.nd.sll, in ovs_key_from_nlattrs()
1721 nd_key->nd_sll, ETH_ALEN, is_mask); in ovs_key_from_nlattrs()
1722 SW_FLOW_KEY_MEMCPY(match, ipv6.nd.tll, in ovs_key_from_nlattrs()
1723 nd_key->nd_tll, ETH_ALEN, is_mask); in ovs_key_from_nlattrs()
1730 return -EINVAL; in ovs_key_from_nlattrs()
1742 /* The nlattr stream should already have been validated */ in nlattr_set()
1760 * ovs_nla_get_match - parses Netlink attributes into a flow key and
1761 * mask. In case the 'mask' is NULL, the flow is treated as exact match
1762 * flow. Otherwise, it is treated as a wildcarded flow, except the mask
1764 * @net: Used to determine per-namespace field support.
1765 * @match: receives the extracted flow match information.
1770 * Netlink attribute specifies the mask field of the wildcarded flow.
1775 int ovs_nla_get_match(struct net *net, struct sw_flow_match *match, in ovs_nla_get_match() argument
1790 err = parse_vlan_from_nlattrs(match, &key_attrs, a, false, log); in ovs_nla_get_match()
1794 err = ovs_key_from_nlattrs(net, match, key_attrs, a, false, log); in ovs_nla_get_match()
1798 if (match->mask) { in ovs_nla_get_match()
1800 /* Create an exact match mask. We need to set to 0xff in ovs_nla_get_match()
1801 * all the 'match->mask' fields that have been touched in ovs_nla_get_match()
1802 * in 'match->key'. We cannot simply memset in ovs_nla_get_match()
1803 * 'match->mask', because padding bytes and fields not in ovs_nla_get_match()
1804 * specified in 'match->key' should be left to 0. in ovs_nla_get_match()
1805 * Instead, we use a stream of netlink attributes, in ovs_nla_get_match()
1808 * 'match->mask' appropriately. in ovs_nla_get_match()
1814 return -ENOMEM; in ovs_nla_get_match()
1821 if (match->key->tun_proto) in ovs_nla_get_match()
1822 SW_FLOW_KEY_MEMSET_FIELD(match, tun_key, in ovs_nla_get_match()
1832 /* Always match on tci. */ in ovs_nla_get_match()
1833 SW_FLOW_KEY_PUT(match, eth.vlan.tci, htons(0xffff), true); in ovs_nla_get_match()
1834 SW_FLOW_KEY_PUT(match, eth.cvlan.tci, htons(0xffff), true); in ovs_nla_get_match()
1836 err = parse_vlan_from_nlattrs(match, &mask_attrs, a, true, log); in ovs_nla_get_match()
1840 err = ovs_key_from_nlattrs(net, match, mask_attrs, a, true, in ovs_nla_get_match()
1846 if (!match_validate(match, key_attrs, mask_attrs, log)) in ovs_nla_get_match()
1847 err = -EINVAL; in ovs_nla_get_match()
1871 /* Initializes 'flow->ufid', returning true if 'attr' contains a valid UFID,
1877 sfid->ufid_len = get_ufid_len(attr, log); in ovs_nla_get_ufid()
1878 if (sfid->ufid_len) in ovs_nla_get_ufid()
1879 memcpy(sfid->ufid, nla_data(attr), sfid->ufid_len); in ovs_nla_get_ufid()
1881 return sfid->ufid_len; in ovs_nla_get_ufid()
1895 return -ENOMEM; in ovs_nla_get_identifier()
1897 sfid->unmasked_key = new_key; in ovs_nla_get_identifier()
1908 * ovs_nla_get_flow_metadata - parses Netlink attributes into a flow key.
1914 * @attrs: Bit mask for the netlink attributes included in @a.
1931 struct sw_flow_match match; in ovs_nla_get_flow_metadata() local
1933 memset(&match, 0, sizeof(match)); in ovs_nla_get_flow_metadata()
1934 match.key = key; in ovs_nla_get_flow_metadata()
1936 key->ct_state = 0; in ovs_nla_get_flow_metadata()
1937 key->ct_zone = 0; in ovs_nla_get_flow_metadata()
1938 key->ct_orig_proto = 0; in ovs_nla_get_flow_metadata()
1939 memset(&key->ct, 0, sizeof(key->ct)); in ovs_nla_get_flow_metadata()
1940 memset(&key->ipv4.ct_orig, 0, sizeof(key->ipv4.ct_orig)); in ovs_nla_get_flow_metadata()
1941 memset(&key->ipv6.ct_orig, 0, sizeof(key->ipv6.ct_orig)); in ovs_nla_get_flow_metadata()
1943 key->phy.in_port = DP_MAX_PORTS; in ovs_nla_get_flow_metadata()
1945 return metadata_from_nlattrs(net, &match, &attrs, a, false, log); in ovs_nla_get_flow_metadata()
1951 __be16 eth_type = !is_mask ? vh->tpid : htons(0xffff); in ovs_nla_put_vlan()
1954 nla_put_be16(skb, OVS_KEY_ATTR_VLAN, vh->tci)) in ovs_nla_put_vlan()
1955 return -EMSGSIZE; in ovs_nla_put_vlan()
1966 return -EMSGSIZE; in nsh_key_to_nlattr()
1968 if (nla_put(skb, OVS_NSH_KEY_ATTR_BASE, sizeof(nsh->base), &nsh->base)) in nsh_key_to_nlattr()
1971 if (is_mask || nsh->base.mdtype == NSH_M_TYPE1) { in nsh_key_to_nlattr()
1973 sizeof(nsh->context), nsh->context)) in nsh_key_to_nlattr()
1984 return -EMSGSIZE; in nsh_key_to_nlattr()
1996 if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id)) in __ovs_nla_put_key()
1999 if (nla_put_u32(skb, OVS_KEY_ATTR_DP_HASH, output->ovs_flow_hash)) in __ovs_nla_put_key()
2002 if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority)) in __ovs_nla_put_key()
2005 if ((swkey->tun_proto || is_mask)) { in __ovs_nla_put_key()
2008 if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT) in __ovs_nla_put_key()
2009 opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len); in __ovs_nla_put_key()
2011 if (ip_tun_to_nlattr(skb, &output->tun_key, opts, in __ovs_nla_put_key()
2012 swkey->tun_opts_len, swkey->tun_proto, 0)) in __ovs_nla_put_key()
2016 if (swkey->phy.in_port == DP_MAX_PORTS) { in __ovs_nla_put_key()
2017 if (is_mask && (output->phy.in_port == 0xffff)) in __ovs_nla_put_key()
2025 (upper_u16 << 16) | output->phy.in_port)) in __ovs_nla_put_key()
2029 if (nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, output->phy.skb_mark)) in __ovs_nla_put_key()
2041 ether_addr_copy(eth_key->eth_src, output->eth.src); in __ovs_nla_put_key()
2042 ether_addr_copy(eth_key->eth_dst, output->eth.dst); in __ovs_nla_put_key()
2044 if (swkey->eth.vlan.tci || eth_type_vlan(swkey->eth.type)) { in __ovs_nla_put_key()
2045 if (ovs_nla_put_vlan(skb, &output->eth.vlan, is_mask)) in __ovs_nla_put_key()
2048 if (!swkey->eth.vlan.tci) in __ovs_nla_put_key()
2051 if (swkey->eth.cvlan.tci || eth_type_vlan(swkey->eth.type)) { in __ovs_nla_put_key()
2052 if (ovs_nla_put_vlan(skb, &output->eth.cvlan, is_mask)) in __ovs_nla_put_key()
2056 if (!swkey->eth.cvlan.tci) in __ovs_nla_put_key()
2061 if (swkey->eth.type == htons(ETH_P_802_2)) { in __ovs_nla_put_key()
2065 * 0xffff in the mask attribute. Ethertype can also in __ovs_nla_put_key()
2068 if (is_mask && output->eth.type) in __ovs_nla_put_key()
2070 output->eth.type)) in __ovs_nla_put_key()
2076 if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, output->eth.type)) in __ovs_nla_put_key()
2079 if (eth_type_vlan(swkey->eth.type)) { in __ovs_nla_put_key()
2087 if (swkey->eth.type == htons(ETH_P_IP)) { in __ovs_nla_put_key()
2094 ipv4_key->ipv4_src = output->ipv4.addr.src; in __ovs_nla_put_key()
2095 ipv4_key->ipv4_dst = output->ipv4.addr.dst; in __ovs_nla_put_key()
2096 ipv4_key->ipv4_proto = output->ip.proto; in __ovs_nla_put_key()
2097 ipv4_key->ipv4_tos = output->ip.tos; in __ovs_nla_put_key()
2098 ipv4_key->ipv4_ttl = output->ip.ttl; in __ovs_nla_put_key()
2099 ipv4_key->ipv4_frag = output->ip.frag; in __ovs_nla_put_key()
2100 } else if (swkey->eth.type == htons(ETH_P_IPV6)) { in __ovs_nla_put_key()
2107 memcpy(ipv6_key->ipv6_src, &output->ipv6.addr.src, in __ovs_nla_put_key()
2108 sizeof(ipv6_key->ipv6_src)); in __ovs_nla_put_key()
2109 memcpy(ipv6_key->ipv6_dst, &output->ipv6.addr.dst, in __ovs_nla_put_key()
2110 sizeof(ipv6_key->ipv6_dst)); in __ovs_nla_put_key()
2111 ipv6_key->ipv6_label = output->ipv6.label; in __ovs_nla_put_key()
2112 ipv6_key->ipv6_proto = output->ip.proto; in __ovs_nla_put_key()
2113 ipv6_key->ipv6_tclass = output->ip.tos; in __ovs_nla_put_key()
2114 ipv6_key->ipv6_hlimit = output->ip.ttl; in __ovs_nla_put_key()
2115 ipv6_key->ipv6_frag = output->ip.frag; in __ovs_nla_put_key()
2116 } else if (swkey->eth.type == htons(ETH_P_NSH)) { in __ovs_nla_put_key()
2117 if (nsh_key_to_nlattr(&output->nsh, is_mask, skb)) in __ovs_nla_put_key()
2119 } else if (swkey->eth.type == htons(ETH_P_ARP) || in __ovs_nla_put_key()
2120 swkey->eth.type == htons(ETH_P_RARP)) { in __ovs_nla_put_key()
2128 arp_key->arp_sip = output->ipv4.addr.src; in __ovs_nla_put_key()
2129 arp_key->arp_tip = output->ipv4.addr.dst; in __ovs_nla_put_key()
2130 arp_key->arp_op = htons(output->ip.proto); in __ovs_nla_put_key()
2131 ether_addr_copy(arp_key->arp_sha, output->ipv4.arp.sha); in __ovs_nla_put_key()
2132 ether_addr_copy(arp_key->arp_tha, output->ipv4.arp.tha); in __ovs_nla_put_key()
2133 } else if (eth_p_mpls(swkey->eth.type)) { in __ovs_nla_put_key()
2137 num_labels = hweight_long(output->mpls.num_labels_mask); in __ovs_nla_put_key()
2145 mpls_key[i].mpls_lse = output->mpls.lse[i]; in __ovs_nla_put_key()
2148 if ((swkey->eth.type == htons(ETH_P_IP) || in __ovs_nla_put_key()
2149 swkey->eth.type == htons(ETH_P_IPV6)) && in __ovs_nla_put_key()
2150 swkey->ip.frag != OVS_FRAG_TYPE_LATER) { in __ovs_nla_put_key()
2152 if (swkey->ip.proto == IPPROTO_TCP) { in __ovs_nla_put_key()
2159 tcp_key->tcp_src = output->tp.src; in __ovs_nla_put_key()
2160 tcp_key->tcp_dst = output->tp.dst; in __ovs_nla_put_key()
2162 output->tp.flags)) in __ovs_nla_put_key()
2164 } else if (swkey->ip.proto == IPPROTO_UDP) { in __ovs_nla_put_key()
2171 udp_key->udp_src = output->tp.src; in __ovs_nla_put_key()
2172 udp_key->udp_dst = output->tp.dst; in __ovs_nla_put_key()
2173 } else if (swkey->ip.proto == IPPROTO_SCTP) { in __ovs_nla_put_key()
2180 sctp_key->sctp_src = output->tp.src; in __ovs_nla_put_key()
2181 sctp_key->sctp_dst = output->tp.dst; in __ovs_nla_put_key()
2182 } else if (swkey->eth.type == htons(ETH_P_IP) && in __ovs_nla_put_key()
2183 swkey->ip.proto == IPPROTO_ICMP) { in __ovs_nla_put_key()
2190 icmp_key->icmp_type = ntohs(output->tp.src); in __ovs_nla_put_key()
2191 icmp_key->icmp_code = ntohs(output->tp.dst); in __ovs_nla_put_key()
2192 } else if (swkey->eth.type == htons(ETH_P_IPV6) && in __ovs_nla_put_key()
2193 swkey->ip.proto == IPPROTO_ICMPV6) { in __ovs_nla_put_key()
2201 icmpv6_key->icmpv6_type = ntohs(output->tp.src); in __ovs_nla_put_key()
2202 icmpv6_key->icmpv6_code = ntohs(output->tp.dst); in __ovs_nla_put_key()
2204 if (icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_SOLICITATION || in __ovs_nla_put_key()
2205 icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) { in __ovs_nla_put_key()
2212 memcpy(nd_key->nd_target, &output->ipv6.nd.target, in __ovs_nla_put_key()
2213 sizeof(nd_key->nd_target)); in __ovs_nla_put_key()
2214 ether_addr_copy(nd_key->nd_sll, output->ipv6.nd.sll); in __ovs_nla_put_key()
2215 ether_addr_copy(nd_key->nd_tll, output->ipv6.nd.tll); in __ovs_nla_put_key()
2229 return -EMSGSIZE; in __ovs_nla_put_key()
2241 return -EMSGSIZE; in ovs_nla_put_key()
2253 if (ovs_identifier_is_ufid(&flow->id)) in ovs_nla_put_identifier()
2254 return nla_put(skb, OVS_FLOW_ATTR_UFID, flow->id.ufid_len, in ovs_nla_put_identifier()
2255 flow->id.ufid); in ovs_nla_put_identifier()
2257 return ovs_nla_put_key(flow->id.unmasked_key, flow->id.unmasked_key, in ovs_nla_put_identifier()
2264 return ovs_nla_put_key(&flow->key, &flow->key, in ovs_nla_put_masked_key()
2271 return ovs_nla_put_key(&flow->key, &flow->mask->key, in ovs_nla_put_mask()
2285 return ERR_PTR(-ENOMEM); in nla_alloc_flow_actions()
2287 sfa->actions_len = 0; in nla_alloc_flow_actions()
2299 dst_release((struct dst_entry *)ovs_tun->tun_dst); in ovs_nla_free_set_action()
2312 nla_for_each_attr(a, sf_acts->actions, sf_acts->actions_len, rem) { in ovs_nla_free_flow_actions()
2335 call_rcu(&sf_acts->rcu, __ovs_nla_free_flow_actions); in ovs_nla_free_flow_actions_rcu()
2346 (*sfa)->actions_len; in reserve_sfa_size()
2348 if (req_size <= (ksize(*sfa) - next_offset)) in reserve_sfa_size()
2354 if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) { in reserve_sfa_size()
2357 return ERR_PTR(-EMSGSIZE); in reserve_sfa_size()
2366 memcpy(acts->actions, (*sfa)->actions, (*sfa)->actions_len); in reserve_sfa_size()
2367 acts->actions_len = (*sfa)->actions_len; in reserve_sfa_size()
2368 acts->orig_len = (*sfa)->orig_len; in reserve_sfa_size()
2373 (*sfa)->actions_len += req_size; in reserve_sfa_size()
2386 a->nla_type = attrtype; in __add_action()
2387 a->nla_len = nla_attr_size(len); in __add_action()
2391 memset((unsigned char *) a + a->nla_len, 0, nla_padlen(len)); in __add_action()
2409 int used = (*sfa)->actions_len; in add_nested_action_start()
2422 struct nlattr *a = (struct nlattr *) ((unsigned char *)sfa->actions + in add_nested_action_end()
2425 a->nla_len = sfa->actions_len - st_offset; in add_nested_action_end()
2450 return -EINVAL; in validate_and_copy_sample()
2454 return -EINVAL; in validate_and_copy_sample()
2458 return -EINVAL; in validate_and_copy_sample()
2462 return -EINVAL; in validate_and_copy_sample()
2474 * Set 'clone_action->exec' to true if the actions can be in validate_and_copy_sample()
2519 return -EINVAL; in validate_and_copy_dec_ttl()
2526 return -EINVAL; in validate_and_copy_dec_ttl()
2557 return -EINVAL; in validate_and_copy_clone()
2580 void ovs_match_init(struct sw_flow_match *match, in ovs_match_init() argument
2583 struct sw_flow_mask *mask) in ovs_match_init() argument
2585 memset(match, 0, sizeof(*match)); in ovs_match_init()
2586 match->key = key; in ovs_match_init()
2587 match->mask = mask; in ovs_match_init()
2592 if (mask) { in ovs_match_init()
2593 memset(&mask->key, 0, sizeof(mask->key)); in ovs_match_init()
2594 mask->range.start = mask->range.end = 0; in ovs_match_init()
2601 int opts_len = key->tun_opts_len; in validate_geneve_opts()
2604 option = (struct geneve_opt *)TUN_METADATA_OPTS(key, key->tun_opts_len); in validate_geneve_opts()
2609 return -EINVAL; in validate_geneve_opts()
2611 len = sizeof(*option) + option->length * 4; in validate_geneve_opts()
2613 return -EINVAL; in validate_geneve_opts()
2615 crit_opt |= !!(option->type & GENEVE_CRIT_OPT_TYPE); in validate_geneve_opts()
2618 opts_len -= len; in validate_geneve_opts()
2621 key->tun_key.tun_flags |= crit_opt ? TUNNEL_CRIT_OPT : 0; in validate_geneve_opts()
2629 struct sw_flow_match match; in validate_and_copy_set_tun() local
2639 ovs_match_init(&match, &key, true, NULL); in validate_and_copy_set_tun()
2640 opts_type = ip_tun_from_nlattr(nla_data(attr), &match, false, log); in validate_and_copy_set_tun()
2669 return -ENOMEM; in validate_and_copy_set_tun()
2671 err = dst_cache_init(&tun_dst->u.tun_info.dst_cache, GFP_KERNEL); in validate_and_copy_set_tun()
2685 ovs_tun->tun_dst = tun_dst; in validate_and_copy_set_tun()
2687 tun_info = &tun_dst->u.tun_info; in validate_and_copy_set_tun()
2688 tun_info->mode = IP_TUNNEL_INFO_TX; in validate_and_copy_set_tun()
2690 tun_info->mode |= IP_TUNNEL_INFO_IPV6; in validate_and_copy_set_tun()
2692 tun_info->mode |= IP_TUNNEL_INFO_BRIDGE; in validate_and_copy_set_tun()
2693 tun_info->key = key.tun_key; in validate_and_copy_set_tun()
2710 struct sw_flow_match match; in validate_nsh() local
2714 ovs_match_init(&match, &key, true, NULL); in validate_nsh()
2715 ret = nsh_key_put_from_nlattr(attr, &match, is_mask, in validate_nsh()
2720 /* Return false if there are any non-masked bits set.
2721 * Mask follows data immediately, before any netlink padding.
2725 u8 *mask = data + len; in validate_masked() local
2727 while (len--) in validate_masked()
2728 if (*data++ & ~*mask++) in validate_masked()
2745 return -EINVAL; in validate_set()
2753 return -EINVAL; in validate_set()
2756 return -EINVAL; in validate_set()
2767 return -EINVAL; in validate_set()
2774 return -EINVAL; /* Masked tunnel set not supported. */ in validate_set()
2786 return -EINVAL; in validate_set()
2791 const struct ovs_key_ipv4 *mask = ipv4_key + 1; in validate_set() local
2793 /* Non-writeable fields. */ in validate_set()
2794 if (mask->ipv4_proto || mask->ipv4_frag) in validate_set()
2795 return -EINVAL; in validate_set()
2797 if (ipv4_key->ipv4_proto != flow_key->ip.proto) in validate_set()
2798 return -EINVAL; in validate_set()
2800 if (ipv4_key->ipv4_frag != flow_key->ip.frag) in validate_set()
2801 return -EINVAL; in validate_set()
2809 return -EINVAL; in validate_set()
2814 const struct ovs_key_ipv6 *mask = ipv6_key + 1; in validate_set() local
2816 /* Non-writeable fields. */ in validate_set()
2817 if (mask->ipv6_proto || mask->ipv6_frag) in validate_set()
2818 return -EINVAL; in validate_set()
2820 /* Invalid bits in the flow label mask? */ in validate_set()
2821 if (ntohl(mask->ipv6_label) & 0xFFF00000) in validate_set()
2822 return -EINVAL; in validate_set()
2824 if (ipv6_key->ipv6_proto != flow_key->ip.proto) in validate_set()
2825 return -EINVAL; in validate_set()
2827 if (ipv6_key->ipv6_frag != flow_key->ip.frag) in validate_set()
2828 return -EINVAL; in validate_set()
2830 if (ntohl(ipv6_key->ipv6_label) & 0xFFF00000) in validate_set()
2831 return -EINVAL; in validate_set()
2838 flow_key->ip.proto != IPPROTO_TCP) in validate_set()
2839 return -EINVAL; in validate_set()
2846 flow_key->ip.proto != IPPROTO_UDP) in validate_set()
2847 return -EINVAL; in validate_set()
2853 return -EINVAL; in validate_set()
2859 flow_key->ip.proto != IPPROTO_SCTP) in validate_set()
2860 return -EINVAL; in validate_set()
2866 return -EINVAL; in validate_set()
2868 return -EINVAL; in validate_set()
2872 return -EINVAL; in validate_set()
2875 /* Convert non-masked non-tunnel set actions to masked set actions. */ in validate_set()
2893 memset(nla_data(at) + key_len, 0xff, key_len); /* Mask. */ in validate_set()
2894 /* Clear non-writeable bits from otherwise writeable fields. */ in validate_set()
2896 struct ovs_key_ipv6 *mask = nla_data(at) + key_len; in validate_set() local
2898 mask->ipv6_label &= htonl(0x000FFFFF); in validate_set()
2923 return -EINVAL; in validate_userspace()
2956 return -EINVAL; in validate_and_copy_check_pkt_len()
2963 return -EINVAL; in validate_and_copy_check_pkt_len()
3014 int totlen = NLA_ALIGN(from->nla_len); in copy_action()
3017 to = reserve_sfa_size(sfa, from->nla_len, log); in copy_action()
3036 /* Expected argument lengths, (u32)-1 for variable length. */ in __ovs_nla_copy_actions()
3040 [OVS_ACTION_ATTR_USERSPACE] = (u32)-1, in __ovs_nla_copy_actions()
3045 [OVS_ACTION_ATTR_SET] = (u32)-1, in __ovs_nla_copy_actions()
3046 [OVS_ACTION_ATTR_SET_MASKED] = (u32)-1, in __ovs_nla_copy_actions()
3047 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1, in __ovs_nla_copy_actions()
3049 [OVS_ACTION_ATTR_CT] = (u32)-1, in __ovs_nla_copy_actions()
3054 [OVS_ACTION_ATTR_PUSH_NSH] = (u32)-1, in __ovs_nla_copy_actions()
3057 [OVS_ACTION_ATTR_CLONE] = (u32)-1, in __ovs_nla_copy_actions()
3058 [OVS_ACTION_ATTR_CHECK_PKT_LEN] = (u32)-1, in __ovs_nla_copy_actions()
3060 [OVS_ACTION_ATTR_DEC_TTL] = (u32)-1, in __ovs_nla_copy_actions()
3068 action_lens[type] != (u32)-1)) in __ovs_nla_copy_actions()
3069 return -EINVAL; in __ovs_nla_copy_actions()
3074 return -EINVAL; in __ovs_nla_copy_actions()
3084 return -EINVAL; in __ovs_nla_copy_actions()
3090 if (trunc->max_len < ETH_HLEN) in __ovs_nla_copy_actions()
3091 return -EINVAL; in __ovs_nla_copy_actions()
3098 switch (act_hash->hash_alg) { in __ovs_nla_copy_actions()
3102 return -EINVAL; in __ovs_nla_copy_actions()
3110 return -EINVAL; in __ovs_nla_copy_actions()
3116 return -EINVAL; in __ovs_nla_copy_actions()
3118 if (!eth_type_vlan(vlan->vlan_tpid)) in __ovs_nla_copy_actions()
3119 return -EINVAL; in __ovs_nla_copy_actions()
3120 if (!(vlan->vlan_tci & htons(VLAN_CFI_MASK))) in __ovs_nla_copy_actions()
3121 return -EINVAL; in __ovs_nla_copy_actions()
3122 vlan_tci = vlan->vlan_tci; in __ovs_nla_copy_actions()
3131 if (!eth_p_mpls(mpls->mpls_ethertype)) in __ovs_nla_copy_actions()
3132 return -EINVAL; in __ovs_nla_copy_actions()
3134 if (mpls->tun_flags & OVS_MPLS_L3_TUNNEL_FLAG_MASK) { in __ovs_nla_copy_actions()
3141 return -EINVAL; in __ovs_nla_copy_actions()
3151 eth_type = mpls->mpls_ethertype; in __ovs_nla_copy_actions()
3158 if (!eth_p_mpls(mpls->mpls_ethertype)) in __ovs_nla_copy_actions()
3159 return -EINVAL; in __ovs_nla_copy_actions()
3169 return -EINVAL; in __ovs_nla_copy_actions()
3170 eth_type = mpls->mpls_ethertype; in __ovs_nla_copy_actions()
3179 return -EINVAL; in __ovs_nla_copy_actions()
3195 return -EINVAL; in __ovs_nla_copy_actions()
3197 mpls_label_count--; in __ovs_nla_copy_actions()
3250 return -EINVAL; in __ovs_nla_copy_actions()
3256 return -EINVAL; in __ovs_nla_copy_actions()
3258 return -EINVAL; in __ovs_nla_copy_actions()
3268 return -EINVAL; in __ovs_nla_copy_actions()
3272 return -EINVAL; in __ovs_nla_copy_actions()
3279 return -EINVAL; in __ovs_nla_copy_actions()
3280 inner_proto = tun_p_to_eth_p(key->nsh.base.np); in __ovs_nla_copy_actions()
3282 return -EINVAL; in __ovs_nla_copy_actions()
3283 if (key->nsh.base.np == TUN_P_ETHERNET) in __ovs_nla_copy_actions()
3291 /* Non-existent meters are simply ignored. */ in __ovs_nla_copy_actions()
3332 return -EINVAL; in __ovs_nla_copy_actions()
3342 return -EINVAL; in __ovs_nla_copy_actions()
3359 if (eth_p_mpls(key->eth.type)) in ovs_nla_copy_actions()
3360 mpls_label_count = hweight_long(key->mpls.num_labels_mask); in ovs_nla_copy_actions()
3362 (*sfa)->orig_len = nla_len(attr); in ovs_nla_copy_actions()
3363 err = __ovs_nla_copy_actions(net, attr, key, sfa, key->eth.type, in ovs_nla_copy_actions()
3364 key->eth.vlan.tci, mpls_label_count, log); in ovs_nla_copy_actions()
3381 return -EMSGSIZE; in sample_action_to_attr()
3387 if (nla_put_u32(skb, OVS_SAMPLE_ATTR_PROBABILITY, arg->probability)) { in sample_action_to_attr()
3388 err = -EMSGSIZE; in sample_action_to_attr()
3394 err = -EMSGSIZE; in sample_action_to_attr()
3420 return -EMSGSIZE; in clone_action_to_attr()
3442 return -EMSGSIZE; in check_pkt_len_action_to_attr()
3450 if (nla_put_u16(skb, OVS_CHECK_PKT_LEN_ATTR_PKT_LEN, arg->pkt_len)) { in check_pkt_len_action_to_attr()
3451 err = -EMSGSIZE; in check_pkt_len_action_to_attr()
3462 err = -EMSGSIZE; in check_pkt_len_action_to_attr()
3481 err = -EMSGSIZE; in check_pkt_len_action_to_attr()
3510 return -EMSGSIZE; in dec_ttl_action_to_attr()
3518 err = -EMSGSIZE; in dec_ttl_action_to_attr()
3553 struct ip_tunnel_info *tun_info = &ovs_tun->tun_dst->u.tun_info; in set_action_to_attr()
3557 return -EMSGSIZE; in set_action_to_attr()
3559 err = ip_tun_to_nlattr(skb, &tun_info->key, in set_action_to_attr()
3561 tun_info->options_len, in set_action_to_attr()
3562 ip_tunnel_info_af(tun_info), tun_info->mode); in set_action_to_attr()
3570 return -EMSGSIZE; in set_action_to_attr()
3584 /* Revert the conversion we did from a non-masked set action to in masked_set_action_to_set_action_attr()
3589 return -EMSGSIZE; in masked_set_action_to_set_action_attr()
3592 return -EMSGSIZE; in masked_set_action_to_set_action_attr()
3651 return -EMSGSIZE; in ovs_nla_put_actions()