Lines Matching +full:state +full:- +full:labels
1 // SPDX-License-Identifier: GPL-2.0-only
72 struct md_labels labels; member
87 /* Elements in ovs_ct_limit_info->limits hash table */
105 static bool labels_nonzero(const struct ovs_key_ct_labels *labels);
111 switch (ntohs(key->eth.type)) { in key_to_nfproto()
121 /* Map SKB connection state into the values used by flow definition. */
157 return ct ? READ_ONCE(ct->mark) : 0; in ovs_ct_get_mark()
163 /* Guard against conntrack labels max size shrinking below 128 bits. */
169 struct ovs_key_ct_labels *labels) in ovs_ct_get_labels() argument
174 if (ct->master && !nf_ct_is_confirmed(ct)) in ovs_ct_get_labels()
175 ct = ct->master; in ovs_ct_get_labels()
179 memcpy(labels, cl->bits, OVS_CT_LABELS_LEN); in ovs_ct_get_labels()
181 memset(labels, 0, OVS_CT_LABELS_LEN); in ovs_ct_get_labels()
188 key->ct_orig_proto = orig->dst.protonum; in __ovs_ct_update_key_orig_tp()
189 if (orig->dst.protonum == icmp_proto) { in __ovs_ct_update_key_orig_tp()
190 key->ct.orig_tp.src = htons(orig->dst.u.icmp.type); in __ovs_ct_update_key_orig_tp()
191 key->ct.orig_tp.dst = htons(orig->dst.u.icmp.code); in __ovs_ct_update_key_orig_tp()
193 key->ct.orig_tp.src = orig->src.u.all; in __ovs_ct_update_key_orig_tp()
194 key->ct.orig_tp.dst = orig->dst.u.all; in __ovs_ct_update_key_orig_tp()
198 static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state, in __ovs_ct_update_key() argument
202 key->ct_state = state; in __ovs_ct_update_key()
203 key->ct_zone = zone->id; in __ovs_ct_update_key()
204 key->ct.mark = ovs_ct_get_mark(ct); in __ovs_ct_update_key()
205 ovs_ct_get_labels(ct, &key->ct.labels); in __ovs_ct_update_key()
211 if (ct->master) in __ovs_ct_update_key()
212 ct = ct->master; in __ovs_ct_update_key()
213 orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; in __ovs_ct_update_key()
216 if (key->eth.type == htons(ETH_P_IP) && in __ovs_ct_update_key()
218 key->ipv4.ct_orig.src = orig->src.u3.ip; in __ovs_ct_update_key()
219 key->ipv4.ct_orig.dst = orig->dst.u3.ip; in __ovs_ct_update_key()
222 } else if (key->eth.type == htons(ETH_P_IPV6) && in __ovs_ct_update_key()
225 key->ipv6.ct_orig.src = orig->src.u3.in6; in __ovs_ct_update_key()
226 key->ipv6.ct_orig.dst = orig->dst.u3.in6; in __ovs_ct_update_key()
231 /* Clear 'ct_orig_proto' to mark the non-existence of conntrack in __ovs_ct_update_key()
234 key->ct_orig_proto = 0; in __ovs_ct_update_key()
237 /* Update 'key' based on skb->_nfct. If 'post_ct' is true, then OVS has
250 u8 state = 0; in ovs_ct_update_key() local
254 state = ovs_ct_get_state(ctinfo); in ovs_ct_update_key()
257 state |= OVS_CS_F_NEW; in ovs_ct_update_key()
261 if (ct->master) in ovs_ct_update_key()
262 state |= OVS_CS_F_RELATED; in ovs_ct_update_key()
264 state |= key->ct_state & OVS_CS_F_NAT_MASK; in ovs_ct_update_key()
266 if (ct->status & IPS_SRC_NAT) in ovs_ct_update_key()
267 state |= OVS_CS_F_SRC_NAT; in ovs_ct_update_key()
268 if (ct->status & IPS_DST_NAT) in ovs_ct_update_key()
269 state |= OVS_CS_F_DST_NAT; in ovs_ct_update_key()
273 state = OVS_CS_F_TRACKED | OVS_CS_F_INVALID; in ovs_ct_update_key()
275 zone = &info->zone; in ovs_ct_update_key()
277 __ovs_ct_update_key(key, state, zone, ct); in ovs_ct_update_key()
293 if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, output->ct_state)) in ovs_ct_put_key()
294 return -EMSGSIZE; in ovs_ct_put_key()
297 nla_put_u16(skb, OVS_KEY_ATTR_CT_ZONE, output->ct_zone)) in ovs_ct_put_key()
298 return -EMSGSIZE; in ovs_ct_put_key()
301 nla_put_u32(skb, OVS_KEY_ATTR_CT_MARK, output->ct.mark)) in ovs_ct_put_key()
302 return -EMSGSIZE; in ovs_ct_put_key()
305 nla_put(skb, OVS_KEY_ATTR_CT_LABELS, sizeof(output->ct.labels), in ovs_ct_put_key()
306 &output->ct.labels)) in ovs_ct_put_key()
307 return -EMSGSIZE; in ovs_ct_put_key()
309 if (swkey->ct_orig_proto) { in ovs_ct_put_key()
310 if (swkey->eth.type == htons(ETH_P_IP)) { in ovs_ct_put_key()
314 orig.ipv4_src = output->ipv4.ct_orig.src; in ovs_ct_put_key()
315 orig.ipv4_dst = output->ipv4.ct_orig.dst; in ovs_ct_put_key()
316 orig.src_port = output->ct.orig_tp.src; in ovs_ct_put_key()
317 orig.dst_port = output->ct.orig_tp.dst; in ovs_ct_put_key()
318 orig.ipv4_proto = output->ct_orig_proto; in ovs_ct_put_key()
322 return -EMSGSIZE; in ovs_ct_put_key()
323 } else if (swkey->eth.type == htons(ETH_P_IPV6)) { in ovs_ct_put_key()
327 memcpy(orig.ipv6_src, output->ipv6.ct_orig.src.s6_addr32, in ovs_ct_put_key()
329 memcpy(orig.ipv6_dst, output->ipv6.ct_orig.dst.s6_addr32, in ovs_ct_put_key()
331 orig.src_port = output->ct.orig_tp.src; in ovs_ct_put_key()
332 orig.dst_port = output->ct.orig_tp.dst; in ovs_ct_put_key()
333 orig.ipv6_proto = output->ct_orig_proto; in ovs_ct_put_key()
337 return -EMSGSIZE; in ovs_ct_put_key()
350 new_mark = ct_mark | (READ_ONCE(ct->mark) & ~(mask)); in ovs_ct_set_mark()
351 if (READ_ONCE(ct->mark) != new_mark) { in ovs_ct_set_mark()
352 WRITE_ONCE(ct->mark, new_mark); in ovs_ct_set_mark()
355 key->ct.mark = new_mark; in ovs_ct_set_mark()
360 return -ENOTSUPP; in ovs_ct_set_mark()
377 /* Initialize labels for a new, yet to be committed conntrack entry. Note that
378 * since the new connection is not yet confirmed, and thus no-one else has
379 * access to it's labels, we simply write them over.
382 const struct ovs_key_ct_labels *labels, in ovs_ct_init_labels() argument
388 /* Inherit master's labels to the related connection? */ in ovs_ct_init_labels()
389 master_cl = ct->master ? nf_ct_labels_find(ct->master) : NULL; in ovs_ct_init_labels()
396 return -ENOSPC; in ovs_ct_init_labels()
398 /* Inherit the master's labels, if any. */ in ovs_ct_init_labels()
403 u32 *dst = (u32 *)cl->bits; in ovs_ct_init_labels()
407 dst[i] = (dst[i] & ~mask->ct_labels_32[i]) | in ovs_ct_init_labels()
408 (labels->ct_labels_32[i] in ovs_ct_init_labels()
409 & mask->ct_labels_32[i]); in ovs_ct_init_labels()
412 /* Labels are included in the IPCTNL_MSG_CT_NEW event only if the in ovs_ct_init_labels()
417 memcpy(&key->ct.labels, cl->bits, OVS_CT_LABELS_LEN); in ovs_ct_init_labels()
423 const struct ovs_key_ct_labels *labels, in ovs_ct_set_labels() argument
431 return -ENOSPC; in ovs_ct_set_labels()
433 err = nf_connlabels_replace(ct, labels->ct_labels_32, in ovs_ct_set_labels()
434 mask->ct_labels_32, in ovs_ct_set_labels()
439 memcpy(&key->ct.labels, cl->bits, OVS_CT_LABELS_LEN); in ovs_ct_set_labels()
450 err = nf_ct_handle_fragments(net, skb, zone, family, &key->ip.proto, &ovs_cb.mru); in ovs_ct_handle_fragments()
458 key->ip.frag = OVS_FRAG_TYPE_NONE; in ovs_ct_handle_fragments()
473 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) in ovs_ct_get_info()
475 if (test_bit(IPS_EXPECTED_BIT, &ct->status)) in ovs_ct_get_info()
481 * re-attributing statistics or modifying the connection state. This allows an
482 * skb->_nfct lost due to an upcall to be recovered during actions execution.
486 * On success, populates skb->_nfct and returns the connection. Returns NULL
526 h = &ct->tuplehash[!h->tuple.dst.dir]; in ovs_ct_find_existing()
542 * might be found for this skb. This happens when we lose a skb->_nfct in ovs_ct_executed()
547 *ct_executed = (key->ct_state & OVS_CS_F_TRACKED) && in ovs_ct_executed()
548 !(key->ct_state & OVS_CS_F_INVALID) && in ovs_ct_executed()
549 (key->ct_zone == info->zone.id); in ovs_ct_executed()
551 if (*ct_executed || (!key->ct_state && info->force)) { in ovs_ct_executed()
552 ct = ovs_ct_find_existing(net, &info->zone, info->family, skb, in ovs_ct_executed()
553 !!(key->ct_state & in ovs_ct_executed()
560 /* Determine whether skb->_nfct is equal to the result of conntrack lookup. */
579 if (!net_eq(net, read_pnet(&ct->ct_net))) in skb_nfct_cached()
581 if (!nf_ct_zone_equal_any(info->ct, nf_ct_zone(ct))) in skb_nfct_cached()
583 if (info->helper) { in skb_nfct_cached()
587 if (help && rcu_access_pointer(help->helper) != info->helper) in skb_nfct_cached()
590 if (info->nf_ct_timeout) { in skb_nfct_cached()
594 if (!timeout_ext || info->nf_ct_timeout != in skb_nfct_cached()
595 rcu_dereference(timeout_ext->timeout)) in skb_nfct_cached()
599 if (info->force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { in skb_nfct_cached()
622 key->ct_state |= OVS_CS_F_SRC_NAT; in ovs_nat_update_key()
623 if (key->eth.type == htons(ETH_P_IP)) in ovs_nat_update_key()
624 key->ipv4.addr.src = ip_hdr(skb)->saddr; in ovs_nat_update_key()
625 else if (key->eth.type == htons(ETH_P_IPV6)) in ovs_nat_update_key()
626 memcpy(&key->ipv6.addr.src, &ipv6_hdr(skb)->saddr, in ovs_nat_update_key()
627 sizeof(key->ipv6.addr.src)); in ovs_nat_update_key()
631 if (key->ip.proto == IPPROTO_UDP) in ovs_nat_update_key()
632 src = udp_hdr(skb)->source; in ovs_nat_update_key()
633 else if (key->ip.proto == IPPROTO_TCP) in ovs_nat_update_key()
634 src = tcp_hdr(skb)->source; in ovs_nat_update_key()
635 else if (key->ip.proto == IPPROTO_SCTP) in ovs_nat_update_key()
636 src = sctp_hdr(skb)->source; in ovs_nat_update_key()
640 key->tp.src = src; in ovs_nat_update_key()
644 key->ct_state |= OVS_CS_F_DST_NAT; in ovs_nat_update_key()
645 if (key->eth.type == htons(ETH_P_IP)) in ovs_nat_update_key()
646 key->ipv4.addr.dst = ip_hdr(skb)->daddr; in ovs_nat_update_key()
647 else if (key->eth.type == htons(ETH_P_IPV6)) in ovs_nat_update_key()
648 memcpy(&key->ipv6.addr.dst, &ipv6_hdr(skb)->daddr, in ovs_nat_update_key()
649 sizeof(key->ipv6.addr.dst)); in ovs_nat_update_key()
653 if (key->ip.proto == IPPROTO_UDP) in ovs_nat_update_key()
654 dst = udp_hdr(skb)->dest; in ovs_nat_update_key()
655 else if (key->ip.proto == IPPROTO_TCP) in ovs_nat_update_key()
656 dst = tcp_hdr(skb)->dest; in ovs_nat_update_key()
657 else if (key->ip.proto == IPPROTO_SCTP) in ovs_nat_update_key()
658 dst = sctp_hdr(skb)->dest; in ovs_nat_update_key()
662 key->tp.dst = dst; in ovs_nat_update_key()
674 if (!(info->nat & OVS_CT_NAT)) in ovs_ct_nat()
676 if (info->nat & OVS_CT_SRC_NAT) in ovs_ct_nat()
678 if (info->nat & OVS_CT_DST_NAT) in ovs_ct_nat()
681 err = nf_ct_nat(skb, ct, ctinfo, &action, &info->range, info->commit); in ovs_ct_nat()
708 return -EINVAL; in verdict_to_errno()
710 return -EINPROGRESS; in verdict_to_errno()
715 return -EINVAL; in verdict_to_errno()
719 * not done already. Update key with new CT state after passing the packet
721 * Note that if the packet is deemed invalid by conntrack, skb->_nfct will be
738 struct nf_hook_state state = { in __ovs_ct_lookup() local
740 .pf = info->family, in __ovs_ct_lookup()
743 struct nf_conn *tmpl = info->ct; in __ovs_ct_lookup()
750 nf_conntrack_get(&tmpl->ct_general); in __ovs_ct_lookup()
754 err = nf_conntrack_in(skb, &state); in __ovs_ct_lookup()
758 /* Clear CT state NAT flags to mark that we have not yet done in __ovs_ct_lookup()
760 * the whole state, as it will be re-initialized below. in __ovs_ct_lookup()
762 key->ct_state = 0; in __ovs_ct_lookup()
780 * the key->ct_state. in __ovs_ct_lookup()
782 if (info->nat && !(key->ct_state & OVS_CS_F_NAT_MASK) && in __ovs_ct_lookup()
783 (nf_ct_is_confirmed(ct) || info->commit)) { in __ovs_ct_lookup()
797 if (!nf_ct_is_confirmed(ct) && info->commit && in __ovs_ct_lookup()
798 info->helper && !nfct_help(ct)) { in __ovs_ct_lookup()
799 int err = __nf_ct_try_assign_helper(ct, info->ct, in __ovs_ct_lookup()
806 if (info->nat && !nfct_seqadj(ct)) { in __ovs_ct_lookup()
808 return -EINVAL; in __ovs_ct_lookup()
813 * - nf_conntrack_in() was executed above ("!cached") or a in __ovs_ct_lookup()
816 * - When committing an unconfirmed connection. in __ovs_ct_lookup()
819 info->commit)) { in __ovs_ct_lookup()
820 int err = nf_ct_helper(skb, ct, ctinfo, info->family); in __ovs_ct_lookup()
829 /* Be liberal for tcp packets so that out-of-window in __ovs_ct_lookup()
860 static bool labels_nonzero(const struct ovs_key_ct_labels *labels) in labels_nonzero() argument
865 if (labels->ct_labels_32[i]) in labels_nonzero()
875 return &info->limits[zone & (CT_LIMIT_HASH_BUCKETS - 1)]; in ct_limit_hash_bucket()
885 head = ct_limit_hash_bucket(info, new_ct_limit->zone); in ct_limit_set()
887 if (ct_limit->zone == new_ct_limit->zone) { in ct_limit_set()
888 hlist_replace_rcu(&ct_limit->hlist_node, in ct_limit_set()
889 &new_ct_limit->hlist_node); in ct_limit_set()
895 hlist_add_head_rcu(&new_ct_limit->hlist_node, head); in ct_limit_set()
907 if (ct_limit->zone == zone) { in ct_limit_del()
908 hlist_del_rcu(&ct_limit->hlist_node); in ct_limit_del()
923 if (ct_limit->zone == zone) in ct_limit_get()
924 return ct_limit->limit; in ct_limit_get()
927 return info->default_limit; in ct_limit_get()
935 const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; in ovs_ct_check_limit()
939 conncount_key = info->zone.id; in ovs_ct_check_limit()
941 per_zone_limit = ct_limit_get(ct_limit_info, info->zone.id); in ovs_ct_check_limit()
945 connections = nf_conncount_count(net, ct_limit_info->data, in ovs_ct_check_limit()
946 &conncount_key, tuple, &info->zone); in ovs_ct_check_limit()
948 return -ENOMEM; in ovs_ct_check_limit()
967 /* The connection could be invalid, in which case this is a no-op.*/ in ovs_ct_commit()
976 &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); in ovs_ct_commit()
980 info->zone.id); in ovs_ct_commit()
994 if (info->have_eventmask) { in ovs_ct_commit()
998 cache->ctmask = info->eventmask; in ovs_ct_commit()
1005 if (info->mark.mask) { in ovs_ct_commit()
1006 err = ovs_ct_set_mark(ct, key, info->mark.value, in ovs_ct_commit()
1007 info->mark.mask); in ovs_ct_commit()
1012 err = ovs_ct_init_labels(ct, key, &info->labels.value, in ovs_ct_commit()
1013 &info->labels.mask); in ovs_ct_commit()
1019 labels_nonzero(&info->labels.mask)) { in ovs_ct_commit()
1020 err = ovs_ct_set_labels(ct, key, &info->labels.value, in ovs_ct_commit()
1021 &info->labels.mask); in ovs_ct_commit()
1033 /* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero
1047 err = nf_ct_skb_network_trim(skb, info->family); in ovs_ct_execute()
1053 if (key->ip.frag != OVS_FRAG_TYPE_NONE) { in ovs_ct_execute()
1054 err = ovs_ct_handle_fragments(net, key, info->zone.id, in ovs_ct_execute()
1055 info->family, skb); in ovs_ct_execute()
1060 if (info->commit) in ovs_ct_execute()
1066 if (err == -EINPROGRESS) in ovs_ct_execute()
1099 bool ip_vers = (info->family == NFPROTO_IPV6); in parse_nat()
1120 return -EINVAL; in parse_nat()
1127 return -EINVAL; in parse_nat()
1133 if (info->nat) { in parse_nat()
1135 return -ERANGE; in parse_nat()
1137 info->nat |= OVS_CT_NAT; in parse_nat()
1138 info->nat |= ((type == OVS_NAT_ATTR_SRC) in parse_nat()
1143 nla_memcpy(&info->range.min_addr, a, in parse_nat()
1144 sizeof(info->range.min_addr)); in parse_nat()
1145 info->range.flags |= NF_NAT_RANGE_MAP_IPS; in parse_nat()
1150 nla_memcpy(&info->range.max_addr, a, in parse_nat()
1151 sizeof(info->range.max_addr)); in parse_nat()
1152 info->range.flags |= NF_NAT_RANGE_MAP_IPS; in parse_nat()
1156 info->range.min_proto.all = htons(nla_get_u16(a)); in parse_nat()
1157 info->range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; in parse_nat()
1162 info->range.max_proto.all = htons(nla_get_u16(a)); in parse_nat()
1163 info->range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; in parse_nat()
1167 info->range.flags |= NF_NAT_RANGE_PERSISTENT; in parse_nat()
1171 info->range.flags |= NF_NAT_RANGE_PROTO_RANDOM; in parse_nat()
1175 info->range.flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; in parse_nat()
1180 return -EINVAL; in parse_nat()
1186 return -EINVAL; in parse_nat()
1188 if (!info->nat) { in parse_nat()
1190 if (info->range.flags) { in parse_nat()
1194 return -EINVAL; in parse_nat()
1196 info->nat = OVS_CT_NAT; /* NAT existing connections. */ in parse_nat()
1197 } else if (!info->commit) { in parse_nat()
1201 return -EINVAL; in parse_nat()
1204 if (info->range.flags & NF_NAT_RANGE_MAP_IPS && !have_ip_max) { in parse_nat()
1205 memcpy(&info->range.max_addr, &info->range.min_addr, in parse_nat()
1206 sizeof(info->range.max_addr)); in parse_nat()
1209 if (info->range.flags & NF_NAT_RANGE_PROTO_SPECIFIED && in parse_nat()
1211 info->range.max_proto.all = info->range.min_proto.all; in parse_nat()
1253 return -EINVAL; in parse_ct()
1262 return -EINVAL; in parse_ct()
1267 info->force = true; in parse_ct()
1270 info->commit = true; in parse_ct()
1274 info->zone.id = nla_get_u16(a); in parse_ct()
1281 if (!mark->mask) { in parse_ct()
1283 return -EINVAL; in parse_ct()
1285 info->mark = *mark; in parse_ct()
1291 struct md_labels *labels = nla_data(a); in parse_ct() local
1293 if (!labels_nonzero(&labels->mask)) { in parse_ct()
1295 return -EINVAL; in parse_ct()
1297 info->labels = *labels; in parse_ct()
1305 return -EINVAL; in parse_ct()
1318 info->have_eventmask = true; in parse_ct()
1319 info->eventmask = nla_get_u32(a); in parse_ct()
1323 memcpy(info->timeout, nla_data(a), nla_len(a)); in parse_ct()
1324 if (!string_is_terminated(info->timeout, nla_len(a))) { in parse_ct()
1326 return -EINVAL; in parse_ct()
1334 return -EINVAL; in parse_ct()
1339 if (!info->commit && info->mark.mask) { in parse_ct()
1342 return -EINVAL; in parse_ct()
1346 if (!info->commit && labels_nonzero(&info->labels.mask)) { in parse_ct()
1348 "Setting conntrack labels requires 'commit' flag."); in parse_ct()
1349 return -EINVAL; in parse_ct()
1354 return -EINVAL; in parse_ct()
1390 return -EINVAL; in ovs_ct_copy_action()
1407 return -ENOMEM; in ovs_ct_copy_action()
1410 if (nf_connlabels_get(net, n_bits - 1)) { in ovs_ct_copy_action()
1413 return -EOPNOTSUPP; in ovs_ct_copy_action()
1417 if (nf_ct_set_timeout(net, ct_info.ct, family, key->ip.proto, in ovs_ct_copy_action()
1424 nf_ct_timeout_find(ct_info.ct)->timeout); in ovs_ct_copy_action()
1430 key->ip.proto, ct_info.nat, &ct_info.helper); in ovs_ct_copy_action()
1443 __set_bit(IPS_CONFIRMED_BIT, &ct_info.ct->status); in ovs_ct_copy_action()
1460 if (info->nat & OVS_CT_SRC_NAT) { in ovs_ct_nat_to_attr()
1463 } else if (info->nat & OVS_CT_DST_NAT) { in ovs_ct_nat_to_attr()
1470 if (info->range.flags & NF_NAT_RANGE_MAP_IPS) { in ovs_ct_nat_to_attr()
1472 info->family == NFPROTO_IPV4) { in ovs_ct_nat_to_attr()
1474 info->range.min_addr.ip) || in ovs_ct_nat_to_attr()
1475 (info->range.max_addr.ip in ovs_ct_nat_to_attr()
1476 != info->range.min_addr.ip && in ovs_ct_nat_to_attr()
1478 info->range.max_addr.ip)))) in ovs_ct_nat_to_attr()
1481 info->family == NFPROTO_IPV6) { in ovs_ct_nat_to_attr()
1483 &info->range.min_addr.in6) || in ovs_ct_nat_to_attr()
1484 (memcmp(&info->range.max_addr.in6, in ovs_ct_nat_to_attr()
1485 &info->range.min_addr.in6, in ovs_ct_nat_to_attr()
1486 sizeof(info->range.max_addr.in6)) && in ovs_ct_nat_to_attr()
1488 &info->range.max_addr.in6)))) in ovs_ct_nat_to_attr()
1494 if (info->range.flags & NF_NAT_RANGE_PROTO_SPECIFIED && in ovs_ct_nat_to_attr()
1496 ntohs(info->range.min_proto.all)) || in ovs_ct_nat_to_attr()
1497 (info->range.max_proto.all != info->range.min_proto.all && in ovs_ct_nat_to_attr()
1499 ntohs(info->range.max_proto.all))))) in ovs_ct_nat_to_attr()
1502 if (info->range.flags & NF_NAT_RANGE_PERSISTENT && in ovs_ct_nat_to_attr()
1505 if (info->range.flags & NF_NAT_RANGE_PROTO_RANDOM && in ovs_ct_nat_to_attr()
1508 if (info->range.flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY && in ovs_ct_nat_to_attr()
1525 return -EMSGSIZE; in ovs_ct_action_to_attr()
1527 if (ct_info->commit && nla_put_flag(skb, ct_info->force in ovs_ct_action_to_attr()
1530 return -EMSGSIZE; in ovs_ct_action_to_attr()
1532 nla_put_u16(skb, OVS_CT_ATTR_ZONE, ct_info->zone.id)) in ovs_ct_action_to_attr()
1533 return -EMSGSIZE; in ovs_ct_action_to_attr()
1534 if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) && ct_info->mark.mask && in ovs_ct_action_to_attr()
1535 nla_put(skb, OVS_CT_ATTR_MARK, sizeof(ct_info->mark), in ovs_ct_action_to_attr()
1536 &ct_info->mark)) in ovs_ct_action_to_attr()
1537 return -EMSGSIZE; in ovs_ct_action_to_attr()
1539 labels_nonzero(&ct_info->labels.mask) && in ovs_ct_action_to_attr()
1540 nla_put(skb, OVS_CT_ATTR_LABELS, sizeof(ct_info->labels), in ovs_ct_action_to_attr()
1541 &ct_info->labels)) in ovs_ct_action_to_attr()
1542 return -EMSGSIZE; in ovs_ct_action_to_attr()
1543 if (ct_info->helper) { in ovs_ct_action_to_attr()
1545 ct_info->helper->name)) in ovs_ct_action_to_attr()
1546 return -EMSGSIZE; in ovs_ct_action_to_attr()
1548 if (ct_info->have_eventmask && in ovs_ct_action_to_attr()
1549 nla_put_u32(skb, OVS_CT_ATTR_EVENTMASK, ct_info->eventmask)) in ovs_ct_action_to_attr()
1550 return -EMSGSIZE; in ovs_ct_action_to_attr()
1551 if (ct_info->timeout[0]) { in ovs_ct_action_to_attr()
1552 if (nla_put_string(skb, OVS_CT_ATTR_TIMEOUT, ct_info->timeout)) in ovs_ct_action_to_attr()
1553 return -EMSGSIZE; in ovs_ct_action_to_attr()
1557 if (ct_info->nat && !ovs_ct_nat_to_attr(ct_info, skb)) in ovs_ct_action_to_attr()
1558 return -EMSGSIZE; in ovs_ct_action_to_attr()
1574 if (ct_info->helper) { in __ovs_ct_free_action()
1576 if (ct_info->nat) in __ovs_ct_free_action()
1577 nf_nat_helper_put(ct_info->helper); in __ovs_ct_free_action()
1579 nf_conntrack_helper_put(ct_info->helper); in __ovs_ct_free_action()
1581 if (ct_info->ct) { in __ovs_ct_free_action()
1582 if (ct_info->timeout[0]) in __ovs_ct_free_action()
1583 nf_ct_destroy_timeout(ct_info->ct); in __ovs_ct_free_action()
1584 nf_connlabels_put(nf_ct_net(ct_info->ct)); in __ovs_ct_free_action()
1585 nf_ct_tmpl_free(ct_info->ct); in __ovs_ct_free_action()
1594 ovs_net->ct_limit_info = kmalloc(sizeof(*ovs_net->ct_limit_info), in ovs_ct_limit_init()
1596 if (!ovs_net->ct_limit_info) in ovs_ct_limit_init()
1597 return -ENOMEM; in ovs_ct_limit_init()
1599 ovs_net->ct_limit_info->default_limit = OVS_CT_LIMIT_DEFAULT; in ovs_ct_limit_init()
1600 ovs_net->ct_limit_info->limits = in ovs_ct_limit_init()
1603 if (!ovs_net->ct_limit_info->limits) { in ovs_ct_limit_init()
1604 kfree(ovs_net->ct_limit_info); in ovs_ct_limit_init()
1605 return -ENOMEM; in ovs_ct_limit_init()
1609 INIT_HLIST_HEAD(&ovs_net->ct_limit_info->limits[i]); in ovs_ct_limit_init()
1611 ovs_net->ct_limit_info->data = nf_conncount_init(net, sizeof(u32)); in ovs_ct_limit_init()
1613 if (IS_ERR(ovs_net->ct_limit_info->data)) { in ovs_ct_limit_init()
1614 err = PTR_ERR(ovs_net->ct_limit_info->data); in ovs_ct_limit_init()
1615 kfree(ovs_net->ct_limit_info->limits); in ovs_ct_limit_init()
1616 kfree(ovs_net->ct_limit_info); in ovs_ct_limit_init()
1625 const struct ovs_ct_limit_info *info = ovs_net->ct_limit_info; in ovs_ct_limit_exit()
1628 nf_conncount_destroy(net, info->data); in ovs_ct_limit_exit()
1630 struct hlist_head *head = &info->limits[i]; in ovs_ct_limit_exit()
1637 kfree(info->limits); in ovs_ct_limit_exit()
1650 return ERR_PTR(-ENOMEM); in ovs_ct_limit_cmd_reply_start()
1652 *ovs_reply_header = genlmsg_put(skb, info->snd_portid, in ovs_ct_limit_cmd_reply_start()
1653 info->snd_seq, in ovs_ct_limit_cmd_reply_start()
1658 return ERR_PTR(-EMSGSIZE); in ovs_ct_limit_cmd_reply_start()
1660 (*ovs_reply_header)->dp_ifindex = ovs_header->dp_ifindex; in ovs_ct_limit_cmd_reply_start()
1685 if (unlikely(zone_limit->zone_id == in ovs_ct_limit_set_zone_limit()
1688 info->default_limit = zone_limit->limit; in ovs_ct_limit_set_zone_limit()
1691 zone_limit->zone_id, &zone))) { in ovs_ct_limit_set_zone_limit()
1699 return -ENOMEM; in ovs_ct_limit_set_zone_limit()
1701 ct_limit->zone = zone; in ovs_ct_limit_set_zone_limit()
1702 ct_limit->limit = zone_limit->limit; in ovs_ct_limit_set_zone_limit()
1708 rem -= NLA_ALIGN(sizeof(*zone_limit)); in ovs_ct_limit_set_zone_limit()
1730 if (unlikely(zone_limit->zone_id == in ovs_ct_limit_del_zone_limit()
1733 info->default_limit = OVS_CT_LIMIT_DEFAULT; in ovs_ct_limit_del_zone_limit()
1736 zone_limit->zone_id, &zone))) { in ovs_ct_limit_del_zone_limit()
1743 rem -= NLA_ALIGN(sizeof(*zone_limit)); in ovs_ct_limit_del_zone_limit()
1759 .limit = info->default_limit, in ovs_ct_limit_get_default_limit()
1797 if (unlikely(zone_limit->zone_id == in ovs_ct_limit_get_zone_limit()
1802 } else if (unlikely(!check_zone_id(zone_limit->zone_id, in ovs_ct_limit_get_zone_limit()
1811 net, info->data, zone, limit, reply); in ovs_ct_limit_get_zone_limit()
1815 rem -= NLA_ALIGN(sizeof(*zone_limit)); in ovs_ct_limit_get_zone_limit()
1840 head = &info->limits[i]; in ovs_ct_limit_get_all_zone_limit()
1842 err = __ovs_ct_limit_get_zone_limit(net, info->data, in ovs_ct_limit_get_all_zone_limit()
1843 ct_limit->zone, ct_limit->limit, reply); in ovs_ct_limit_get_all_zone_limit()
1856 struct nlattr **a = info->attrs; in ovs_ct_limit_cmd_set()
1859 struct ovs_net *ovs_net = net_generic(sock_net(skb->sk), ovs_net_id); in ovs_ct_limit_cmd_set()
1860 struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; in ovs_ct_limit_cmd_set()
1869 err = -EINVAL; in ovs_ct_limit_cmd_set()
1890 struct nlattr **a = info->attrs; in ovs_ct_limit_cmd_del()
1893 struct ovs_net *ovs_net = net_generic(sock_net(skb->sk), ovs_net_id); in ovs_ct_limit_cmd_del()
1894 struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; in ovs_ct_limit_cmd_del()
1903 err = -EINVAL; in ovs_ct_limit_cmd_del()
1922 struct nlattr **a = info->attrs; in ovs_ct_limit_cmd_get()
1926 struct net *net = sock_net(skb->sk); in ovs_ct_limit_cmd_get()
1928 struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; in ovs_ct_limit_cmd_get()
1938 err = -EMSGSIZE; in ovs_ct_limit_cmd_get()